Review code for performance from your own scripts
Send code — a module, a component, a request handler, a query layer, or a mixed
grab-bag — and get back one JSON object: an honest verdict, a health check across five
performance areas, findings ranked by severity each with a corrected snippet, the quick wins
worth shipping first, and an optimized rewrite of the worst hotspot. Everything this app does
goes through the SkillSafe App API — plain JSON over HTTPS — so you can wire
review into a CI gate, a pull-request bot, or a pre-deploy check that refuses to ship an
await inside a loop.
Every code step below is shown in cURL, Python, JavaScript, Go, Java, Ruby, PHP and C#;
pick a language once and the whole page follows.
Basics
Base URL: https://api.skillsafe.ai/v1/app-api, app slug
perf-lens. Every request sends
Authorization: Bearer <token> and JSON bodies with
Content-Type: application/json. Responses are wrapped in an envelope:
{"data": …} on success, {"error": {"code", "message"}} on failure.
The review itself is produced by the gpt-terra model. Estimates are free;
runs are metered against your credit balance. There is a single run task — one paste
in, one review out, no follow-up calls and no session state to carry.
| Status | Meaning |
|---|---|
401 | Missing or expired token — create a new session. |
402 | Not enough credits — top up at skillsafe.ai/account/credits. |
403 | The token isn't allowed to do this (e.g. a guest reviewing a very large paste). |
404 | Unknown job or record id. |
5xx | Transient platform error — retry with backoff. |
Browsers enforce CORS for this API, so run these examples from a server, script or terminal — not from another website's frontend.
Step 0 — A tiny client
Every task below is a single HTTP call, so start with a short helper that adds the auth
header, sends JSON and unwraps the data envelope. The later steps reuse it.
export API="https://api.skillsafe.ai/v1/app-api"
export TOKEN="YOUR_TOKEN" # see step 1
# every call looks like:
# curl -s "$API/..." -H "Authorization: Bearer $TOKEN" [-d '{json}']
# jq is used below to pull fields out of the {"data": ...} envelope
import json, requests
API = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "YOUR_TOKEN" # see step 1 — read it from your shell environment in real code
def api(method, path, body=None, **headers):
res = requests.request(method, API + path, json=body,
headers={"Authorization": f"Bearer {TOKEN}", **headers})
payload = res.json()
if not res.ok:
raise RuntimeError(payload.get("error", {}).get("message", res.reason))
return payload["data"]
// Node 18+ (built-in fetch)
const API = "https://api.skillsafe.ai/v1/app-api";
const TOKEN = "YOUR_TOKEN"; // see step 1 — read it from your shell environment in real code
async function api(method, path, body, extraHeaders = {}) {
const res = await fetch(API + path, {
method,
headers: { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json", ...extraHeaders },
body: body === undefined ? undefined : JSON.stringify(body),
});
const json = await res.json();
if (!res.ok) throw new Error(json.error?.message ?? res.statusText);
return json.data;
}
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const API = "https://api.skillsafe.ai/v1/app-api"
var token = os.Getenv("SKILLSAFE_TOKEN") // see step 1
func call(method, path string, body, out any) error {
var buf bytes.Buffer
if body != nil {
json.NewEncoder(&buf).Encode(body)
}
req, _ := http.NewRequest(method, API+path, &buf)
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
var env struct {
Data json.RawMessage `json:"data"`
Error *struct{ Message string `json:"message"` } `json:"error"`
}
json.NewDecoder(res.Body).Decode(&env)
if res.StatusCode >= 400 {
return fmt.Errorf("api %s %s: %s", method, path, env.Error.Message)
}
if out == nil {
return nil
}
return json.Unmarshal(env.Data, out)
}
// Java 17+, no dependencies. Pair with your JSON library (Jackson, Gson…)
// to read fields out of the returned envelope.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class SkillSafe {
static final String API = "https://api.skillsafe.ai/v1/app-api";
static final String TOKEN = System.getenv("SKILLSAFE_TOKEN"); // see step 1
static final HttpClient HTTP = HttpClient.newHttpClient();
static String api(String method, String path, String jsonBody) throws Exception {
var req = HttpRequest.newBuilder(URI.create(API + path))
.header("Authorization", "Bearer " + TOKEN)
.header("Content-Type", "application/json")
.method(method, jsonBody == null
? HttpRequest.BodyPublishers.noBody()
: HttpRequest.BodyPublishers.ofString(jsonBody))
.build();
var res = HTTP.send(req, HttpResponse.BodyHandlers.ofString());
if (res.statusCode() >= 400) throw new RuntimeException(res.body());
return res.body(); // envelope: {"data": …}
}
}
require "net/http"
require "json"
API = "https://api.skillsafe.ai/v1/app-api"
TOKEN = ENV.fetch("SKILLSAFE_TOKEN") # see step 1
def api(method, path, body = nil)
uri = URI(API + path)
req = Net::HTTP.const_get(method.capitalize).new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Content-Type"] = "application/json"
req.body = body.to_json if body
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
payload = JSON.parse(res.body)
raise (payload.dig("error", "message") || res.message) unless res.is_a?(Net::HTTPSuccess)
payload["data"]
end
<?php
const API = "https://api.skillsafe.ai/v1/app-api";
$TOKEN = getenv("SKILLSAFE_TOKEN"); // see step 1
function api(string $method, string $path, ?array $body = null): mixed {
global $TOKEN;
$ch = curl_init(API . $path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $TOKEN",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => $body === null ? null : json_encode($body),
]);
$payload = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 400) {
throw new Exception($payload["error"]["message"] ?? "HTTP $status");
}
return $payload["data"];
}
// .NET 8+
using System.Net.Http.Json;
using System.Text.Json;
static class SkillSafe
{
const string Api = "https://api.skillsafe.ai/v1/app-api";
static readonly HttpClient Http = new();
static SkillSafe() =>
Http.DefaultRequestHeaders.Authorization =
new("Bearer", Environment.GetEnvironmentVariable("SKILLSAFE_TOKEN")); // see step 1
public static async Task<JsonElement> ApiAsync(HttpMethod method, string path, object? body = null)
{
var req = new HttpRequestMessage(method, Api + path);
if (body != null) req.Content = JsonContent.Create(body);
var res = await Http.SendAsync(req);
var json = await res.Content.ReadFromJsonAsync<JsonElement>();
if (!res.IsSuccessStatusCode)
throw new Exception(json.GetProperty("error").GetProperty("message").GetString());
return json.GetProperty("data");
}
}
Step 1 — Get a token
A guest token lets you check balances and estimate costs for free. For metered review runs
billed to your own account, use your personal token: open the
token page, sign in with SkillSafe, and press
Copy shell export — it puts export SKILLSAFE_TOKEN="…" on your
clipboard, which every example below reads. Treat the token like a password: it can spend
your credits. For fully headless scripts, POST /guest mints a guest token with
no browser involved.
curl -s -X POST "$API/guest" \
-H "Content-Type: application/json" \
-d '{"slug":"perf-lens"}' | jq -r '.data.token'
token = api("POST", "/guest", {"slug": "perf-lens"})["token"]
const { token } = await api("POST", "/guest", { slug: "perf-lens" });
var guest struct{ Token string `json:"token"` }
err := call("POST", "/guest", map[string]string{"slug": "perf-lens"}, &guest)
String envelope = api("POST", "/guest", """
{"slug":"perf-lens"}""");
// token is at data.token in the returned JSON
token = api("POST", "/guest", { slug: "perf-lens" })["token"]
$token = api("POST", "/guest", ["slug" => "perf-lens"])["token"];
var guest = await SkillSafe.ApiAsync(HttpMethod.Post, "/guest",
new { slug = "perf-lens" });
var token = guest.GetProperty("token").GetString();
The app stores this browser's token under the localStorage key
skillsafe_app_token:perf-lens, on the app's own origin. The
token page reads and manages it for you — you never need
to open developer tools.
Step 2 — Check who you are and your balance
Returns subject_type ("user" or "guest"),
subject_id and your credits balance. Check this before reviewing
a large paste.
curl -s "$API/me" -H "Authorization: Bearer $TOKEN" | jq '.data'
me = api("GET", "/me")
print(me["subject_type"], me["credits"])
const me = await api("GET", "/me");
console.log(me.subject_type, me.credits);
var me struct {
SubjectType string `json:"subject_type"`
Credits int64 `json:"credits"`
}
err := call("GET", "/me", nil, &me)
String envelope = api("GET", "/me", null);
// data.subject_type, data.credits
me = api("GET", "/me")
puts "#{me["subject_type"]}: #{me["credits"]} credits"
$me = api("GET", "/me");
echo "{$me['subject_type']}: {$me['credits']} credits\n";
var me = await SkillSafe.ApiAsync(HttpMethod.Get, "/me");
Console.WriteLine($"{me.GetProperty("subject_type")}: {me.GetProperty("credits")} credits");
Step 3 — Estimate the cost
Send exactly the input you would send to /run; the response's
hold_credits is the worst-case cost. Nothing is charged and no job is created,
so estimating is free — useful when you are feeding in a whole directory of modules
and want a ceiling before spending credits.
| Input field | Type | Notes |
|---|---|---|
code | string, required | The source code to review: one file or several concatenated. Very long pastes may be clipped middle-out, with a [... clipped ...] marker showing where. |
language | string | auto | javascript | typescript | python | sql | go | java | other. On auto, the language is inferred from the paste and named back to you in the overview. |
surface | string | backend (server handlers, jobs, data access) | frontend (browser and UI rendering) | mixed — calibrates which checklist areas dominate. Rendering findings only make sense for frontend and mixed; connection pooling and N+1 dominate backend. |
slowpath | string, optional | What you say is slow, verbatim, e.g. "the /report endpoint takes 40s". The review is weighted toward it and says whether the pasted code can explain that symptom. |
notes | string, optional | Extra context: data sizes, request rates, framework, environment. |
prescan_facts | object, optional | What a client-side prescan mechanically detected in the code: {"antipatterns": [], "hotspots": [], "signals": []}. Each entry is {id, label} — pattern-matched anti-pattern hits (ap:await-in-loop), function and component names found in the paste (hotspot:loadOrders) and stack signals (sig:react, sig:sql, sig:node). Every id you send comes back in coverage_check. The web UI fills this from its own scan; API callers may omit the field or send the three empty arrays. |
retry_note | string, optional | Only set by the app's automatic reformat retry when a first reply was not valid JSON. Leave it out. |
cat > orders.js <<'JS'
async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}
JS
jq -n --rawfile c orders.js \
'{code: $c, language: "javascript", surface: "backend",
slowpath: "The dashboard takes 8+ seconds for users with many orders.",
notes: "Node 20 with node-postgres; orders is about 12M rows and loadOrders runs on every dashboard render.",
prescan_facts: {antipatterns: [], hotspots: [], signals: []}}' > input.json
curl -s -X POST "$API/estimate" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d @input.json | jq '.data.hold_credits'
CODE = """async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}"""
payload = {
"code": CODE,
"language": "javascript",
"surface": "backend",
"slowpath": "The dashboard takes 8+ seconds for users with many orders.",
"notes": "Node 20 with node-postgres; orders is about 12M rows and loadOrders runs on every dashboard render.",
"prescan_facts": {"antipatterns": [], "hotspots": [], "signals": []},
}
est = api("POST", "/estimate", payload)
print("worst case:", est.get("hold_credits", est.get("credits")), "credits")
const code = `async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}`;
const payload = {
code,
language: "javascript",
surface: "backend",
slowpath: "The dashboard takes 8+ seconds for users with many orders.",
notes: "Node 20 with node-postgres; orders is about 12M rows and loadOrders runs on every dashboard render.",
prescan_facts: { antipatterns: [], hotspots: [], signals: [] },
};
const est = await api("POST", "/estimate", payload);
console.log("worst case:", est.hold_credits ?? est.credits, "credits");
const code = `async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}`
payload := map[string]any{
"code": code,
"language": "javascript",
"surface": "backend",
"slowpath": "The dashboard takes 8+ seconds for users with many orders.",
"notes": "Node 20 with node-postgres; orders is about 12M rows and loadOrders runs on every dashboard render.",
"prescan_facts": map[string]any{
"antipatterns": []any{}, "hotspots": []any{}, "signals": []any{},
},
}
var est struct{ HoldCredits int64 `json:"hold_credits"` }
err := call("POST", "/estimate", payload, &est)
String code = """
async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}""";
String jsonPayload = """
{"code": %s, "language": "javascript", "surface": "backend",
"slowpath": "The dashboard takes 8+ seconds for users with many orders.",
"notes": "Node 20 with node-postgres; orders is about 12M rows.",
"prescan_facts": {"antipatterns": [], "hotspots": [], "signals": []}}
""".formatted(toJsonString(code));
String envelope = api("POST", "/estimate", jsonPayload);
// worst-case cost is at data.hold_credits
CODE_TEXT = <<~JS
async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}
JS
payload = { code: CODE_TEXT, language: "javascript", surface: "backend",
slowpath: "The dashboard takes 8+ seconds for users with many orders.",
notes: "Node 20 with node-postgres; orders is about 12M rows.",
prescan_facts: { antipatterns: [], hotspots: [], signals: [] } }
est = api("POST", "/estimate", payload)
puts "worst case: #{est["hold_credits"] || est["credits"]} credits"
$code = <<<'JS'
async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}
JS;
$payload = [
"code" => $code,
"language" => "javascript",
"surface" => "backend",
"slowpath" => "The dashboard takes 8+ seconds for users with many orders.",
"notes" => "Node 20 with node-postgres; orders is about 12M rows.",
"prescan_facts" => ["antipatterns" => [], "hotspots" => [], "signals" => []],
];
$est = api("POST", "/estimate", $payload);
echo "worst case: " . ($est["hold_credits"] ?? $est["credits"]) . " credits\n";
var code = """
async function loadOrders(userIds) {
const orders = [];
for (const id of userIds) {
const rows = await db.query("SELECT * FROM orders WHERE user_id = $1", [id]);
orders.push(...rows);
}
return orders;
}
""";
var payload = new {
code,
language = "javascript",
surface = "backend",
slowpath = "The dashboard takes 8+ seconds for users with many orders.",
notes = "Node 20 with node-postgres; orders is about 12M rows.",
prescan_facts = new {
antipatterns = Array.Empty<object>(), hotspots = Array.Empty<object>(),
signals = Array.Empty<object>(),
},
};
var est = await SkillSafe.ApiAsync(HttpMethod.Post, "/estimate", payload);
Console.WriteLine($"worst case: {est.GetProperty("hold_credits")} credits");
prescan_facts is how you make the review answer for things you already know
about. Send {"antipatterns": [{"id": "ap:await-in-loop", "label": "await inside a loop"}],
"hotspots": [{"id": "hotspot:loadOrders", "label": "loadOrders"}], "signals": [{"id": "sig:sql",
"label": "SQL queries"}]} and every one of those ids comes back in
coverage_check — addressed, or explained away as a false positive.
Nothing you flag is silently dropped.
Step 4 — Run the review and wait for the result
/run takes the same input as /estimate, places a credit hold and
returns a job_id. Poll /jobs/{job_id} every 1–2 seconds
until status is succeeded or failed (a run typically
takes 30–90 s, since the optimized rewrite is written out in full). Always send an
Idempotency-Key header so a network retry can't start a second,
double-charged run. The review is in output — usually nested as
output.output, and as a JSON string, so parse defensively. The samples
below print the review name and verdict, the five health areas and the findings, then write
rewrite.code to optimized.js.
JOB_ID=$(curl -s -X POST "$API/run" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: review-$(date +%s)" \
-d @input.json | jq -r '.data.job_id')
while :; do
JOB=$(curl -s "$API/jobs/$JOB_ID" -H "Authorization: Bearer $TOKEN")
STATUS=$(echo "$JOB" | jq -r '.data.status')
[ "$STATUS" = "succeeded" ] || [ "$STATUS" = "failed" ] && break
sleep 2
done
# unwrap the review once, then read it
echo "$JOB" | jq -r '.data.output.output' > review.json
jq -r '
"\(.review_name): \(.verdict)",
"",
"HEALTH",
(.health[] | " [\(.status)] \(.area) - \(.note)"),
"",
"FINDINGS",
(.findings[] | " (\(.severity)) \(.category): \(.title)"),
"",
"QUICK WINS",
(.quick_wins[] | " \(.change) -- \(.impact)")' review.json
# and drop the optimized rewrite straight into the repo
jq -r '.rewrite.code' review.json > "$(jq -r '.rewrite.filename' review.json)" # optimized.js
import time
job_id = api("POST", "/run", payload,
**{"Idempotency-Key": "review-001"})["job_id"]
while True:
job = api("GET", f"/jobs/{job_id}")
if job["status"] in ("succeeded", "failed"):
break
time.sleep(1.5)
if job["status"] == "failed":
raise RuntimeError(job.get("error", "run failed"))
raw = job["output"]
if isinstance(raw, dict) and "output" in raw:
raw = raw["output"]
review = json.loads(raw) if isinstance(raw, str) else raw
print(f'{review["review_name"]}: {review["verdict"]}')
for area in review["health"]:
print(f' [{area["status"]:>4}] {area["area"]:<18} {area["note"]}')
for f in review["findings"]:
print(f' ({f["severity"]}) {f["category"]}: {f["title"]}')
if f["fix_code"]:
print(f' {f["fix_code"]}')
for w in review["quick_wins"]:
print(f' {w["change"]} -- {w["impact"]}')
for c in review["coverage_check"]:
print(f' {c["id"]}: {"ok" if c["addressed"] else "SET ASIDE"} - {c["note"]}')
with open(review["rewrite"]["filename"], "w", encoding="utf-8") as fh: # optimized.js
fh.write(review["rewrite"]["code"])
import { writeFileSync } from "node:fs";
const { job_id } = await api("POST", "/run", payload,
{ "Idempotency-Key": crypto.randomUUID() });
let job;
do {
await new Promise((r) => setTimeout(r, 1500));
job = await api("GET", `/jobs/${job_id}`);
} while (job.status !== "succeeded" && job.status !== "failed");
if (job.status === "failed") throw new Error(job.error ?? "run failed");
const raw = job.output?.output ?? job.output;
const review = typeof raw === "string" ? JSON.parse(raw) : raw;
console.log(`${review.review_name}: ${review.verdict}`);
for (const area of review.health) {
console.log(` [${area.status}] ${area.area}: ${area.note}`);
}
for (const f of review.findings) {
console.log(` (${f.severity}) ${f.category}: ${f.title}`);
if (f.fix_code) console.log(` ${f.fix_code}`);
}
for (const w of review.quick_wins) console.log(` ${w.change} -- ${w.impact}`);
for (const c of review.coverage_check) {
console.log(` ${c.id}: ${c.addressed ? "ok" : "SET ASIDE"} - ${c.note}`);
}
writeFileSync(review.rewrite.filename, review.rewrite.code); // optimized.js
var started struct{ JobID string `json:"job_id"` }
if err := call("POST", "/run", payload, &started); err != nil {
log.Fatal(err)
}
var job struct {
Status string `json:"status"`
Error string `json:"error"`
Output json.RawMessage `json:"output"`
}
for {
if err := call("GET", "/jobs/"+started.JobID, nil, &job); err != nil {
log.Fatal(err)
}
if job.Status == "succeeded" || job.Status == "failed" {
break
}
time.Sleep(1500 * time.Millisecond)
}
// job.Output is {"output": "<json string>"} — unwrap, unquote, then unmarshal:
type Review struct {
ReviewName string `json:"review_name"`
Verdict string `json:"verdict"`
Health []struct {
Area, Status, Note string
} `json:"health"`
Findings []struct {
Severity, Category, Title, Detail, Lines string
FixCode string `json:"fix_code"`
} `json:"findings"`
QuickWins []struct {
Change, Impact string
} `json:"quick_wins"`
Rewrite struct {
Filename, Code string
} `json:"rewrite"`
}
var wrapper struct{ Output string `json:"output"` }
json.Unmarshal(job.Output, &wrapper)
var review Review
json.Unmarshal([]byte(wrapper.Output), &review)
fmt.Printf("%s: %s\n", review.ReviewName, review.Verdict)
for _, a := range review.Health {
fmt.Printf(" [%s] %s: %s\n", a.Status, a.Area, a.Note)
}
for _, f := range review.Findings {
fmt.Printf(" (%s) %s: %s\n", f.Severity, f.Category, f.Title)
}
for _, w := range review.QuickWins {
fmt.Printf(" %s -- %s\n", w.Change, w.Impact)
}
os.WriteFile(review.Rewrite.Filename, []byte(review.Rewrite.Code), 0o644) // optimized.js
String envelope = api("POST", "/run", jsonPayload);
String jobId = /* data.job_id via your JSON library */;
while (true) {
String job = api("GET", "/jobs/" + jobId, null);
String status = /* data.status */;
if (status.equals("succeeded") || status.equals("failed")) break;
Thread.sleep(1500);
}
// The review is at data.output.output as a JSON string — parse it again, then read
// review_name, verdict, overview, health[] (five areas with area/status/note),
// findings[] (severity/category/title/detail/lines/fix_code), quick_wins[] (change/impact),
// coverage_check[] (id/addressed/note), rewrite{filename, code}, next_steps[] and summary.
// Finally write the optimized rewrite to disk:
// Files.writeString(Path.of(rewriteFilename), rewriteCode); // optimized.js
started = api("POST", "/run", payload)
job = nil
loop do
job = api("GET", "/jobs/#{started["job_id"]}")
break if %w[succeeded failed].include?(job["status"])
sleep 1.5
end
raise (job["error"] || "run failed") if job["status"] == "failed"
raw = job["output"].is_a?(Hash) ? job["output"].fetch("output", job["output"]) : job["output"]
review = raw.is_a?(String) ? JSON.parse(raw) : raw
puts "#{review["review_name"]}: #{review["verdict"]}"
review["health"].each { |a| puts " [#{a["status"]}] #{a["area"]}: #{a["note"]}" }
review["findings"].each do |f|
puts " (#{f["severity"]}) #{f["category"]}: #{f["title"]}"
puts " #{f["fix_code"]}" unless f["fix_code"].to_s.empty?
end
review["quick_wins"].each { |w| puts " #{w["change"]} -- #{w["impact"]}" }
review["coverage_check"].each { |c| puts " #{c["id"]}: #{c["addressed"] ? "ok" : "SET ASIDE"}" }
File.write(review["rewrite"]["filename"], review["rewrite"]["code"]) # optimized.js
$started = api("POST", "/run", $payload);
do {
sleep(2);
$job = api("GET", "/jobs/" . $started["job_id"]);
} while (!in_array($job["status"], ["succeeded", "failed"]));
if ($job["status"] === "failed") {
throw new Exception($job["error"] ?? "run failed");
}
$raw = is_array($job["output"]) ? ($job["output"]["output"] ?? $job["output"]) : $job["output"];
$review = is_string($raw) ? json_decode($raw, true) : $raw;
echo "{$review['review_name']}: {$review['verdict']}\n";
foreach ($review["health"] as $a) {
echo " [{$a['status']}] {$a['area']}: {$a['note']}\n";
}
foreach ($review["findings"] as $f) {
echo " ({$f['severity']}) {$f['category']}: {$f['title']}\n";
if ($f["fix_code"] !== "") { echo " {$f['fix_code']}\n"; }
}
foreach ($review["quick_wins"] as $w) {
echo " {$w['change']} -- {$w['impact']}\n";
}
foreach ($review["coverage_check"] as $c) {
echo " {$c['id']}: " . ($c["addressed"] ? "ok" : "SET ASIDE") . "\n";
}
file_put_contents($review["rewrite"]["filename"], $review["rewrite"]["code"]); // optimized.js
var started = await SkillSafe.ApiAsync(HttpMethod.Post, "/run", payload);
var jobId = started.GetProperty("job_id").GetString();
JsonElement job;
while (true)
{
job = await SkillSafe.ApiAsync(HttpMethod.Get, $"/jobs/{jobId}");
var status = job.GetProperty("status").GetString();
if (status is "succeeded" or "failed") break;
await Task.Delay(1500);
}
var rawText = job.GetProperty("output").GetProperty("output").GetString();
using var doc = JsonDocument.Parse(rawText!);
var review = doc.RootElement;
Console.WriteLine($"{review.GetProperty("review_name")}: {review.GetProperty("verdict")}");
foreach (var a in review.GetProperty("health").EnumerateArray())
{
Console.WriteLine($" [{a.GetProperty("status")}] {a.GetProperty("area")}: {a.GetProperty("note")}");
}
foreach (var f in review.GetProperty("findings").EnumerateArray())
{
Console.WriteLine($" ({f.GetProperty("severity")}) {f.GetProperty("category")}: " +
$"{f.GetProperty("title")}");
}
foreach (var w in review.GetProperty("quick_wins").EnumerateArray())
{
Console.WriteLine($" {w.GetProperty("change")} -- {w.GetProperty("impact")}");
}
var rewrite = review.GetProperty("rewrite");
await File.WriteAllTextAsync(rewrite.GetProperty("filename").GetString()!, // optimized.js
rewrite.GetProperty("code").GetString()!);
The model is asked for one JSON object and nothing else, but a stray code fence or preamble
is always possible. Strip a leading ```json fence, take the text between the
first { and the last }, and only then parse — that is what
the app does before it falls back to a retry_note reformat run.
The review object — output schema
One JSON object, always the same shape. Every array is present (findings and
quick_wins are empty only if genuinely nothing applies); health
always has exactly the five areas, and rewrite.code is never empty. If the
paste was too thin to review responsibly, you still get this object: what is there gets
reviewed, the verdict says the paste is thin, and what you would need to
show lands in next_steps. If the paste is not code at all, you still get the
object — one critical finding explaining what arrived, every health area
at risk, and a rewrite.code comment block saying what to paste
instead.
| Field | Type | Meaning |
|---|---|---|
review_name | string | A short name for the review, taken from the code's own function or domain naming. |
verdict | string | One or two sentences: the overall state and the single most important fix. |
overview | string | One or two paragraphs: what this code does, the language and stack inferred, the pattern behind what was found, and whether it explains the reported slow path. |
health | array of 5 | {area, status, note} — the five areas listed below, each exactly once. status is good (nothing material), risk (works, with caveats) or bad (a critical or high finding lives here). Each note references something concrete in the pasted code; an area the paste gives no evidence for is good with a note saying it does not apply, never an invented risk. |
findings | array | {severity, category, title, detail, lines, fix_code}. severity is critical | high | medium | low; category is data-access, memory, cpu-algorithms, network-io or rendering. detail quotes the function, variable, query or JSX it concerns; lines is a reference like "lines 12-18" or an empty string; fix_code is a corrected snippet using your own names, or an empty string when the finding is a trade-off rather than a mechanical fix. |
quick_wins | array | {change, impact} — at most five, ordered by impact-per-effort. Each change is a one-line fix you could ship today, drawn from the findings, with the measurable impact it buys. |
coverage_check | array | {id, addressed, note} — one entry per prescan_facts item you sent (ap:await-in-loop, hotspot:loadOrders, …), saying where the review covers it or why it was set aside (a pattern hit can be a false positive; the note says so). Nothing you flagged is silently dropped. |
rewrite | object | {filename, code} — filename matches the language (optimized.js, optimized.py, …), and code is your own worst hotspot optimized: same function, same behaviour, the findings that touch it fixed, your naming and comments preserved. It is a complete drop-in replacement for that function or component, not a fragment. |
next_steps | string[] | Ordered and concrete: profile the named path with a named tool, add the index behind the hot query, measure before and after, and so on. |
summary | string | 3–5 sentences an engineer could paste into a PR review. |
The five health areas, in order, spelled exactly like this:
| area | What its note covers |
|---|---|
Data access | N+1 queries in loops, missing LIMIT or pagination on unbounded reads, SELECT * over the columns actually needed, missing connection pooling. |
Memory & resources | Listeners never removed, intervals never cleared, caches and arrays that grow without bounds, missing unmount and destroy cleanup. |
CPU & algorithms | O(n^2)-or-worse passes over data that can be large, unmemoized repeated computation, string concatenation in loops, redundant sort and filter passes. |
Network & I/O | Missing caching for hot read-mostly data, sequential awaits that could run in parallel with Promise.all, over-fetching, missing request deduplication. |
Rendering & UI | Unnecessary re-renders where the tree is hot, missing memo/useMemo/useCallback, missing list virtualization, synchronous heavy work on the main thread, oversized bundles. |
A small, realistic result for the loadOrders paste above, trimmed for length:
{
"review_name": "loadOrders order fan-out",
"verdict": "loadOrders issues one query per user id and awaits each in turn, so latency
grows linearly with the input; batch the fan-out before anything else.",
"overview": "A Node data-access helper that takes a list of user ids and collects their
orders. The language is JavaScript on a backend surface. The problems are the
classic set: a query inside a loop, sequential awaits, an unbounded SELECT *,
and this fully explains the 8-second dashboard you reported.",
"health": [
{ "area": "Data access", "status": "bad",
"note": "db.query runs once per id inside the for loop over userIds — a textbook N+1." },
{ "area": "Memory & resources", "status": "good",
"note": "orders grows with the result set but nothing is retained past the return." },
{ "area": "CPU & algorithms", "status": "risk",
"note": "orders.push(...rows) spreads whole result arrays; large batches blow the
argument limit and copy more than a concat would." },
{ "area": "Network & I/O", "status": "bad",
"note": "Every await blocks the next query; the round trips are serialized." },
{ "area": "Rendering & UI", "status": "good",
"note": "Backend data-access code with no rendering surface — the area does not apply." }
],
"findings": [
{ "severity": "critical", "category": "data-access",
"title": "loadOrders queries inside a loop",
"detail": "'for (const id of userIds) { const rows = await db.query(...) }' issues one
statement per id; 500 ids means 500 round trips.",
"lines": "lines 3-6",
"fix_code": "const rows = await db.query(
\"SELECT id, user_id, total FROM orders WHERE user_id = ANY($1) LIMIT 1000\",
[userIds]);" },
{ "severity": "high", "category": "network-io",
"title": "Sequential awaits serialize the round trips",
"detail": "Each await inside the loop waits for the previous one, so total latency is
the sum of every query rather than the slowest.",
"lines": "lines 4",
"fix_code": "const results = await Promise.all(userIds.map((id) => db.query(sql, [id])));" },
{ "severity": "medium", "category": "data-access",
"title": "SELECT * with no LIMIT",
"detail": "'SELECT * FROM orders WHERE user_id = $1' reads every column and every row a
user has ever had; the dashboard renders a handful.",
"lines": "lines 4",
"fix_code": "SELECT id, user_id, total FROM orders WHERE user_id = $1
ORDER BY created_at DESC LIMIT 50" }
],
"quick_wins": [
{ "change": "Replace the per-id loop with a single WHERE user_id = ANY($1) query.",
"impact": "Cuts 500 round trips to 1; the dashboard drops from seconds to
tens of milliseconds." },
{ "change": "Name the three columns the dashboard needs instead of SELECT *.",
"impact": "Smaller rows over the wire and an index-only scan becomes possible." }
],
"coverage_check": [
{ "id": "ap:await-in-loop", "addressed": true,
"note": "Confirmed — the critical finding on loadOrders is exactly this hit." },
{ "id": "hotspot:loadOrders", "addressed": true,
"note": "It is the worst hotspot and is the function rewritten below." }
],
"rewrite": { "filename": "optimized.js", "code": "async function loadOrders(userIds) {\n …" },
"next_steps": [
"Add an index on orders (user_id, created_at DESC) to serve the batched query.",
"Measure the endpoint before and after with your APM p95, not a single local run.",
"Cap the batch: chunk userIds so one dashboard cannot ask for 50k rows."
],
"summary": "One critical N+1, one high serialization finding, and an unbounded read. …"
}
The rewrite is a starting point, not a merge: it is written to be a drop-in replacement and self-consistent with the findings, but it is AI-generated and it changes the query shape of a hot path. Review it, run your own tests against it, and measure before and after before it goes anywhere near production.
Step 5 — Stream the review as it is written
/run-stream takes exactly the same body as /run but answers with
server-sent events, so you can show progress instead of a spinner — useful here
because the corrected rewrite makes for a long reply. This app's own progress panel is this
endpoint. Events are separated by a blank line; each has an event: line and a
data: line carrying JSON.
| Event | Payload | Meaning |
|---|---|---|
job | {job_id, status} | Sent once, when the job is accepted — show "starting". |
delta | {text} | A chunk of the reply, in order. Append it; the accumulated length is your only progress signal (the total is not known in advance). |
done | {job_id, status, charged_credits, output} | The final, authoritative result — read the review from output.output rather than trusting concatenated deltas, and the settled price from charged_credits. |
error | {code, message} | Replaces done when the run fails. |
# -N disables buffering so events print as they arrive
curl -N -s -X POST "$API/run-stream" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: review-$(date +%s)" \
-d @input.json
# event: job
# data: {"job_id":"job_...","status":"running"}
#
# event: delta
# data: {"text":"{\"review_name\":\"orders"}
# ...
# event: done
# data: {"job_id":"job_...","status":"succeeded","charged_credits":612,"output":{"output":"{...}"}}
import json, requests
result = None
with requests.post(
API + "/run-stream",
headers={"Authorization": f"Bearer {TOKEN}",
"Idempotency-Key": "review-001"},
json=payload,
stream=True,
) as r:
r.raise_for_status()
event = None
for line in r.iter_lines(decode_unicode=True):
if not line:
continue
if line.startswith("event:"):
event = line[len("event:"):].strip()
elif line.startswith("data:"):
data = json.loads(line[len("data:"):].strip())
if event == "delta":
print(".", end="", flush=True) # live progress
elif event == "done":
result = data
elif event == "error":
raise RuntimeError(data.get("message", "run failed"))
review = json.loads(result["output"]["output"]) # authoritative
print("charged:", result["charged_credits"], "-", review["review_name"])
for area in review["health"]:
print(f' [{area["status"]}] {area["area"]}')
open(review["rewrite"]["filename"], "w", encoding="utf-8").write(review["rewrite"]["code"])
const res = await fetch(API + "/run-stream", {
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify(payload),
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buf = "", done = null;
for (;;) {
const chunk = await reader.read();
if (chunk.done) break;
buf += decoder.decode(chunk.value, { stream: true });
const frames = buf.split("\n\n");
buf = frames.pop();
for (const frame of frames) {
const name = /^event:\s*(.+)$/m.exec(frame)?.[1];
const body = /^data:\s*(.+)$/m.exec(frame)?.[1];
if (!name || !body) continue;
const data = JSON.parse(body);
if (name === "delta") process.stdout.write("."); // live progress
if (name === "done") done = data;
if (name === "error") throw new Error(data.message ?? "run failed");
}
}
const review = JSON.parse(done.output.output);
console.log(`\n${done.charged_credits} credits - ${review.review_name}`);
for (const area of review.health) console.log(` [${area.status}] ${area.area}`);
writeFileSync(review.rewrite.filename, review.rewrite.code); // improved.sql
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", API+"/run-stream", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "review-001")
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var event string
var final map[string]any
sc := bufio.NewScanner(res.Body)
sc.Buffer(make([]byte, 0, 64*1024), 4*1024*1024)
for sc.Scan() {
line := sc.Text()
switch {
case strings.HasPrefix(line, "event:"):
event = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
case strings.HasPrefix(line, "data:"):
var data map[string]any
json.Unmarshal([]byte(strings.TrimPrefix(line, "data:")), &data)
switch event {
case "delta":
fmt.Print(".") // live progress
case "done":
final = data
case "error":
log.Fatal(data["message"])
}
}
}
// final["output"].(map[string]any)["output"].(string) is the review JSON —
// unmarshal it into the Review struct from step 4, then write review.Rewrite.Code to disk.
// Java 17+ — read the stream line by line instead of buffering the body.
var req = HttpRequest.newBuilder(URI.create(API + "/run-stream"))
.header("Authorization", "Bearer " + TOKEN)
.header("Content-Type", "application/json")
.header("Idempotency-Key", "review-001")
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
var res = HTTP.send(req, HttpResponse.BodyHandlers.ofLines());
String event = null, done = null;
for (String line : (Iterable<String>) res.body()::iterator) {
if (line.startsWith("event:")) {
event = line.substring(6).trim();
} else if (line.startsWith("data:")) {
String data = line.substring(5).trim();
if ("delta".equals(event)) System.out.print("."); // live progress
else if ("done".equals(event)) done = data;
else if ("error".equals(event)) throw new RuntimeException(data);
}
}
// parse `done`, then parse data.output.output again — it is a JSON string holding
// review_name, health[], findings[], indexes[], rewrite{filename, code} and the rest.
require "net/http"
require "json"
uri = URI(API + "/run-stream")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "review-001"
req.body = payload.to_json
event = nil
done = nil
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(req) do |res|
res.read_body do |chunk|
chunk.each_line do |line|
line = line.strip
if line.start_with?("event:")
event = line.delete_prefix("event:").strip
elsif line.start_with?("data:")
data = JSON.parse(line.delete_prefix("data:").strip)
case event
when "delta" then print "." # live progress
when "done" then done = data
when "error" then raise (data["message"] || "run failed")
end
end
end
end
end
end
review = JSON.parse(done["output"]["output"])
puts "\n#{done["charged_credits"]} credits - #{review["review_name"]}"
review["health"].each { |a| puts " [#{a["status"]}] #{a["area"]}" }
File.write(review["rewrite"]["filename"], review["rewrite"]["code"]) # improved.sql
$event = null;
$done = null;
$ch = curl_init(API . "/run-stream");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $TOKEN",
"Content-Type: application/json",
"Idempotency-Key: review-001",
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_WRITEFUNCTION => function ($ch, $chunk) use (&$event, &$done) {
foreach (explode("\n", $chunk) as $line) {
$line = trim($line);
if (str_starts_with($line, "event:")) {
$event = trim(substr($line, 6));
} elseif (str_starts_with($line, "data:")) {
$data = json_decode(trim(substr($line, 5)), true);
if ($event === "delta") { echo "."; } // live progress
elseif ($event === "done") { $done = $data; }
elseif ($event === "error") { throw new Exception($data["message"] ?? "run failed"); }
}
}
return strlen($chunk);
},
]);
curl_exec($ch);
curl_close($ch);
$review = json_decode($done["output"]["output"], true);
echo "\n{$done['charged_credits']} credits - {$review['review_name']}\n";
foreach ($review["health"] as $a) { echo " [{$a['status']}] {$a['area']}\n"; }
file_put_contents($review["rewrite"]["filename"], $review["rewrite"]["code"]); // improved.sql
var req = new HttpRequestMessage(HttpMethod.Post, Api + "/run-stream") {
Content = JsonContent.Create(payload),
};
req.Headers.Add("Idempotency-Key", "review-001");
using var res = await Http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
using var reader = new StreamReader(await res.Content.ReadAsStreamAsync());
string? evt = null, done = null;
while (await reader.ReadLineAsync() is { } line)
{
if (line.StartsWith("event:")) evt = line[6..].Trim();
else if (line.StartsWith("data:"))
{
var data = line[5..].Trim();
if (evt == "delta") Console.Write("."); // live progress
else if (evt == "done") done = data;
else if (evt == "error") throw new Exception(data);
}
}
using var final = JsonDocument.Parse(done!);
var text = final.RootElement.GetProperty("output").GetProperty("output").GetString();
using var reviewDoc = JsonDocument.Parse(text!);
var review = reviewDoc.RootElement;
Console.WriteLine(review.GetProperty("review_name"));
foreach (var a in review.GetProperty("health").EnumerateArray())
Console.WriteLine($" [{a.GetProperty("status")}] {a.GetProperty("area")}");
var rewrite = review.GetProperty("rewrite");
await File.WriteAllTextAsync(rewrite.GetProperty("filename").GetString()!, // improved.sql
rewrite.GetProperty("code").GetString()!);
In a browser, the native EventSource only speaks GET, and this endpoint is a
POST — read the fetch response body incrementally, as the JavaScript
sample above does. On an idempotent replay the server may answer with a plain JSON
envelope instead of an event stream; check the Content-Type before you start
parsing frames.