Test Forge — API

The same forge the web app drives, from your shell, your script or your CI job.

Open the app Your token

Everything the app does is one of five HTTPS calls against the SkillSafe App API. Paste a module in, get back a plain-text reply in a fixed contract, and pull the test file out of it. Every step below is shown in cURL, Python, JavaScript, Go, Java, Ruby, PHP and C# — pick a language once and the whole page follows.

  1. A tiny client
  2. Get a token
  3. Check the session and balance
  4. Estimate the cost (free)
  5. Run the forge and poll the job
  6. Stream it instead (SSE)
  7. Parse the output contract

Basics

Base URL https://api.skillsafe.ai/v1/app-api. There is no /apps/<slug>/ path segment — the app is bound to the token you mint at /guest, so every later call is just /me, /estimate, /run, /run-stream. Every request carries Authorization: Bearer <token> and, when it has a body, Content-Type: application/json.

Responses use an envelope. Success is {"ok":true,"data":{...},"meta":{...}}; failure is {"ok":false,"error":{"code":"...","message":"..."}}. Read your payload out of data, never off the top level.

Error codeStatusWhat it means
unauthorized401Missing, malformed or expired token. Mint a new one at /guest or sign in again.
not_found404Unknown path or job id. Almost always a URL with an extra /apps/test-forge segment in it.
payment_required402Not enough credits to place the hold. Top up, or call /estimate first.
validation_error422The input object was rejected — usually an empty code or a framework that is neither Vitest nor Jest.
rate_limited429Too many calls too fast. Back off and retry; honour Retry-After when present.
internal_error5xxTransient platform fault. Retry with backoff and the same Idempotency-Key.

Browsers enforce CORS on this API, so run these examples from a terminal, a server or a CI job — not from another site's frontend.

Step 0 — A tiny client

Every later step is one HTTP call, so start with a small helper that sets the auth header, sends JSON and unwraps the data envelope. The rest of the page reuses it.

export API="https://api.skillsafe.ai/v1/app-api"
export SKILLSAFE_TOKEN="YOUR_TOKEN"   # see step 1

# every call below is one of these two shapes:
#   curl -s "$API/<path>" -H "Authorization: Bearer $SKILLSAFE_TOKEN"
#   curl -s -X POST "$API/<path>" -H "Authorization: Bearer $SKILLSAFE_TOKEN" \
#        -H "Content-Type: application/json" -d '{...}'
# jq pulls fields out of the {"ok":true,"data":{...}} envelope
import json, requests

API = "https://api.skillsafe.ai/v1/app-api"
TOKEN = "YOUR_TOKEN"  # see step 1

def api(method, path, body=None, **extra_headers):
    headers = {"Authorization": "Bearer " + TOKEN}
    headers.update(extra_headers)
    res = requests.request(method, API + path, json=body, headers=headers)
    payload = res.json()
    if not res.ok:
        err = payload.get("error") or {}
        raise RuntimeError("%s: %s" % (err.get("code", res.status_code),
                                       err.get("message", res.reason)))
    return payload["data"]
// Node 18+ (built-in fetch). Keep the token out of source control in real code.
const API = "https://api.skillsafe.ai/v1/app-api";
const TOKEN = "YOUR_TOKEN"; // see step 1

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 payload = await res.json();
  if (!res.ok) {
    const e = payload.error || {};
    throw new Error(`${e.code || res.status}: ${e.message || res.statusText}`);
  }
  return payload.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

type apiError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

func call(method, path string, body, out any, extra map[string]string) 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")
	for k, v := range extra {
		req.Header.Set(k, v)
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	var env struct {
		OK    bool            `json:"ok"`
		Data  json.RawMessage `json:"data"`
		Error *apiError       `json:"error"`
	}
	json.NewDecoder(res.Body).Decode(&env)
	if res.StatusCode >= 400 {
		if env.Error != nil {
			return fmt.Errorf("%s: %s", env.Error.Code, env.Error.Message)
		}
		return fmt.Errorf("http %d", res.StatusCode)
	}
	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;
import java.util.Map;

public class TestForge {
    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,
                      Map<String, String> extra) throws Exception {
        var b = 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));
        if (extra != null) extra.forEach(b::header);
        var res = HTTP.send(b.build(), HttpResponse.BodyHandlers.ofString());
        if (res.statusCode() >= 400) throw new RuntimeException(res.body());
        return res.body(); // envelope: {"ok":true,"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, extra = {})
  uri = URI(API + path)
  req = Net::HTTP.const_get(method.capitalize).new(uri)
  req["Authorization"] = "Bearer #{TOKEN}"
  req["Content-Type"] = "application/json"
  extra.each { |k, v| req[k] = v }
  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)
  unless res.is_a?(Net::HTTPSuccess)
    err = payload["error"] || {}
    raise "#{err["code"] || res.code}: #{err["message"] || res.message}"
  end
  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, array $extra = []): mixed {
    global $TOKEN;
    $headers = [
        "Authorization: Bearer $TOKEN",
        "Content-Type: application/json",
    ];
    foreach ($extra as $k => $v) { $headers[] = "$k: $v"; }
    $ch = curl_init(API . $path);
    curl_setopt_array($ch, [
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => $headers,
        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) {
        $err = $payload["error"] ?? [];
        throw new Exception(($err["code"] ?? $status) . ": " . ($err["message"] ?? "request failed"));
    }
    return $payload["data"];
}
// .NET 8+
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

static class TestForge
{
    const string Api = "https://api.skillsafe.ai/v1/app-api";
    static readonly HttpClient Http = new();

    static TestForge() =>
        Http.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer",
                Environment.GetEnvironmentVariable("SKILLSAFE_TOKEN")); // see step 1

    public static async Task<JsonElement> ApiAsync(
        HttpMethod method, string path, object? body = null,
        (string Name, string Value)? extraHeader = null)
    {
        var req = new HttpRequestMessage(method, Api + path);
        if (body != null) req.Content = JsonContent.Create(body);
        if (extraHeader is { } h) req.Headers.Add(h.Name, h.Value);
        var res = await Http.SendAsync(req);
        var payload = await res.Content.ReadFromJsonAsync<JsonElement>();
        if (!res.IsSuccessStatusCode)
        {
            var err = payload.GetProperty("error");
            throw new Exception(err.GetProperty("code").GetString() + ": " +
                                err.GetProperty("message").GetString());
        }
        return payload.GetProperty("data");
    }
}

Step 1 — Get a token

POST /guest

The token carries the app identity: POST /guest with {"slug":"test-forge"} binds it to this app, which is why no later URL mentions the slug. The new token comes back at data.token. This call needs no auth header.

For a token tied to your SkillSafe account and credits, open the token page, sign in, and press Copy shell export — it puts export SKILLSAFE_TOKEN="..." on your clipboard, which is exactly what these examples read. Treat it like a password: it can spend your credits.

export SKILLSAFE_TOKEN=$(curl -s -X POST "$API/guest" \
  -H "Content-Type: application/json" \
  -d '{"slug":"test-forge"}' | jq -r '.data.token')

echo "${SKILLSAFE_TOKEN:0:8}..."
# /guest is the one call that needs no Authorization header.
res = requests.post(API + "/guest", json={"slug": "test-forge"})
res.raise_for_status()
TOKEN = res.json()["data"]["token"]
print(TOKEN[:8] + "...")
// /guest is the one call that needs no Authorization header.
const guestRes = await fetch(API + "/guest", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ slug: "test-forge" }),
});
const guest = (await guestRes.json()).data;
console.log(guest.token.slice(0, 8) + "...");
// assign it to TOKEN (or export it) before the calls below
// /guest is the one call that needs no Authorization header.
var guest struct {
	Token   string `json:"token"`
	GuestID string `json:"guest_id"`
}
body, _ := json.Marshal(map[string]string{"slug": "test-forge"})
res, err := http.Post(API+"/guest", "application/json", bytes.NewReader(body))
if err != nil {
	panic(err)
}
defer res.Body.Close()
var env struct {
	Data json.RawMessage `json:"data"`
}
json.NewDecoder(res.Body).Decode(&env)
json.Unmarshal(env.Data, &guest)
token = guest.Token // the package-level token the helper reads
// /guest is the one call that needs no Authorization header.
var req = HttpRequest.newBuilder(URI.create(API + "/guest"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("{\"slug\":\"test-forge\"}"))
    .build();
var res = HTTP.send(req, HttpResponse.BodyHandlers.ofString());
// the token is at data.token in res.body(); read it with your JSON library
System.out.println(res.body());
# /guest is the one call that needs no Authorization header.
uri = URI(API + "/guest")
res = Net::HTTP.post(uri, { slug: "test-forge" }.to_json,
                     "Content-Type" => "application/json")
TOKEN = JSON.parse(res.body)["data"]["token"]
puts TOKEN[0, 8] + "..."
<?php
// /guest is the one call that needs no Authorization header.
$ch = curl_init(API . "/guest");
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ["Content-Type: application/json"],
    CURLOPT_POSTFIELDS     => json_encode(["slug" => "test-forge"]),
]);
$payload = json_decode(curl_exec($ch), true);
curl_close($ch);
$TOKEN = $payload["data"]["token"];
echo substr($TOKEN, 0, 8) . "...\n";
// /guest is the one call that needs no Authorization header.
using var anon = new HttpClient();
var guestRes = await anon.PostAsJsonAsync(
    "https://api.skillsafe.ai/v1/app-api/guest", new { slug = "test-forge" });
var guest = (await guestRes.Content.ReadFromJsonAsync<JsonElement>())
    .GetProperty("data");
var token = guest.GetProperty("token").GetString();
Console.WriteLine(token![..8] + "...");

A guest token is anonymous and lives on its own small wallet. Signing in on the token page gives you a personal token whose runs bill your account and whose history the app can show you again later.

Step 2 — Check the session and balance

GET /me

Returns subject_type ("user" or "guest"), subject_id and the credits balance this token can spend. It is also the cheapest way to find out whether a token you stored last week is still good — a dead one answers 401 unauthorized.

curl -s "$API/me" -H "Authorization: Bearer $SKILLSAFE_TOKEN" | jq '.data'
# {"subject_type":"guest","subject_id":"g_...","credits":1200}
me = api("GET", "/me")
print(me["subject_type"], me["subject_id"], me["credits"], "credits")
const me = await api("GET", "/me");
console.log(me.subject_type, me.subject_id, me.credits, "credits");
var me struct {
	SubjectType string `json:"subject_type"`
	SubjectID   string `json:"subject_id"`
	Credits     int64  `json:"credits"`
}
if err := call("GET", "/me", nil, &me, nil); err != nil {
	panic(err)
}
fmt.Println(me.SubjectType, me.SubjectID, me.Credits, "credits")
String envelope = api("GET", "/me", null, null);
// data.subject_type, data.subject_id, data.credits
System.out.println(envelope);
me = api("GET", "/me")
puts "#{me["subject_type"]} #{me["subject_id"]}: #{me["credits"]} credits"
$me = api("GET", "/me");
echo "{$me['subject_type']} {$me['subject_id']}: {$me['credits']} credits\n";
var me = await TestForge.ApiAsync(HttpMethod.Get, "/me");
Console.WriteLine($"{me.GetProperty("subject_type")}: {me.GetProperty("credits")} credits");

Step 3 — Estimate the cost (free)

POST /estimate

Send the input object you are about to run. /estimate is free: it creates no job, charges nothing, and returns the worst-case hold so you can decide before spending. The body is the input object directly — there is no {"input": ...} wrapper on either /estimate or /run.

Input fieldTypeNotes
codestring, requiredThe source module exactly as it sits in your repo — TypeScript or JavaScript, ESM or CJS.
notesstring, optionalWhat you care about: the bug that already shipped, the boundary you distrust. Each note becomes its own named test.
frameworkstringExactly "Vitest" or "Jest". Empty defaults to Vitest.
filenamestring, optionalSource path like src/lib/duration.ts. Drives the test filename and the import path.
retry_notestring, optionalSend only after a reply failed to parse: describe what was wrong with the shape. The app sends it on attempt 2 and never on attempt 1.
Estimate fieldMeaning
hold_creditsWorst-case credits reserved when you call /run.
min_creditsFloor for a run that returns almost immediately.
model / model_aliasThe model that would serve the run, and the stable alias the app displays.
markup_bpsPlatform markup in basis points, already folded into the numbers above.
sponsor_enabledTrue when the app sponsors this run, so a guest token can run without signing in.
# input.json holds the input object itself - no {"input": ...} wrapper:
# {"code":"export function toMs(...) {...}","notes":"rounding at .5 bit us once",
#  "framework":"Vitest","filename":"src/lib/duration.ts"}

curl -s -X POST "$API/estimate" \
  -H "Authorization: Bearer $SKILLSAFE_TOKEN" \
  -H "Content-Type: application/json" \
  -d @input.json \
  | jq '.data | {hold_credits, min_credits, model, sponsor_enabled}'
source = open("src/lib/duration.ts").read()

payload = {
    "code": source,
    "notes": "rounding at .5 bit us once",
    "framework": "Vitest",
    "filename": "src/lib/duration.ts",
}

est = api("POST", "/estimate", payload)   # free: no job, no charge
print(est["hold_credits"], "credits held at most on", est["model_alias"])
if est["sponsor_enabled"]:
    print("sponsored - a guest token can run this")
import { readFileSync } from "node:fs";

const payload = {
  code: readFileSync("src/lib/duration.ts", "utf8"),
  notes: "rounding at .5 bit us once",
  framework: "Vitest",
  filename: "src/lib/duration.ts",
};

const est = await api("POST", "/estimate", payload); // free: no job, no charge
console.log(est.hold_credits, "credits at most on", est.model_alias);
source, _ := os.ReadFile("src/lib/duration.ts")

payload := map[string]string{
	"code":      string(source),
	"notes":     "rounding at .5 bit us once",
	"framework": "Vitest",
	"filename":  "src/lib/duration.ts",
}

var est struct {
	HoldCredits    int64  `json:"hold_credits"`
	MinCredits     int64  `json:"min_credits"`
	Model          string `json:"model"`
	ModelAlias     string `json:"model_alias"`
	MarkupBps      int    `json:"markup_bps"`
	SponsorEnabled bool   `json:"sponsor_enabled"`
}
if err := call("POST", "/estimate", payload, &est, nil); err != nil {
	panic(err)
}
fmt.Println(est.HoldCredits, "credits at most on", est.ModelAlias)
// Build the input object with your JSON library; it is sent as the body itself,
// with no {"input": ...} wrapper.
String source = Files.readString(Path.of("src/lib/duration.ts"));
String body = mapper.writeValueAsString(Map.of(
    "code", source,
    "notes", "rounding at .5 bit us once",
    "framework", "Vitest",
    "filename", "src/lib/duration.ts"));

String envelope = api("POST", "/estimate", body, null); // free: no job, no charge
// data.hold_credits, data.min_credits, data.model, data.model_alias,
// data.markup_bps, data.sponsor_enabled
payload = {
  code: File.read("src/lib/duration.ts"),
  notes: "rounding at .5 bit us once",
  framework: "Vitest",
  filename: "src/lib/duration.ts"
}

est = api("POST", "/estimate", payload) # free: no job, no charge
puts "#{est["hold_credits"]} credits at most on #{est["model_alias"]}"
<?php
$payload = [
    "code"      => file_get_contents("src/lib/duration.ts"),
    "notes"     => "rounding at .5 bit us once",
    "framework" => "Vitest",
    "filename"  => "src/lib/duration.ts",
];

$est = api("POST", "/estimate", $payload); // free: no job, no charge
echo "{$est['hold_credits']} credits at most on {$est['model_alias']}\n";
var payload = new {
    code = File.ReadAllText("src/lib/duration.ts"),
    notes = "rounding at .5 bit us once",
    framework = "Vitest",
    filename = "src/lib/duration.ts",
};

var est = await TestForge.ApiAsync(HttpMethod.Post, "/estimate", payload); // free
Console.WriteLine($"{est.GetProperty("hold_credits")} credits at most on " +
                  $"{est.GetProperty("model_alias")}");

The app clips modules longer than 60,000 characters before sending: it removes lines from the middle and keeps both ends, marking the cut in-band with a [code truncated] line that states how many lines went missing. A blind head slice would hide the very export you wanted tested. If you send oversize input yourself, do the same and keep the marker — the skill is told to treat it as a hole and list it under Not covered: rather than invent what was removed.

Step 4 — Run the forge and poll the job

POST /run
GET /jobs/{job_id}

/run takes the same input object as /estimate, places the credit hold and returns a job. Poll /jobs/{job_id} every second or two until status is succeeded or failed; a forge usually takes 20–60 seconds. The reply text lands at output.output.

Always send an Idempotency-Key header. A network blip on the response leaves you unsure whether the run started, and a naive retry bills twice; with the key, the platform replays the first run instead of starting a second. The app derives its key from a hash of the input plus an attempt number — test-forge-<hash(input)>-a1, then -a2 for the one automatic reshape retry — so retrying the same input is free but a deliberate second attempt is not accidentally deduplicated.

KEY="test-forge-$(shasum -a 256 input.json | cut -c1-16)-a1"

JOB_ID=$(curl -s -X POST "$API/run" \
  -H "Authorization: Bearer $SKILLSAFE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $KEY" \
  -d @input.json | jq -r '.data.job_id')

while :; do
  JOB=$(curl -s "$API/jobs/$JOB_ID" -H "Authorization: Bearer $SKILLSAFE_TOKEN")
  STATUS=$(echo "$JOB" | jq -r '.data.status')
  case "$STATUS" in succeeded|failed) break ;; esac
  sleep 2
done

echo "$JOB" | jq -r '.data.output.output' > reply.txt
import hashlib, time

canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))
key = "test-forge-" + hashlib.sha256(canonical.encode()).hexdigest()[:16] + "-a1"

started = api("POST", "/run", payload, **{"Idempotency-Key": key})
job_id = started["job_id"]

while True:
    job = api("GET", "/jobs/" + job_id)
    if job["status"] in ("succeeded", "failed"):
        break
    time.sleep(1.5)

if job["status"] == "failed":
    raise RuntimeError(job.get("error") or "run failed")

reply = job["output"]["output"]   # the plain-text contract; see step 6
import { createHash } from "node:crypto";

const canonical = JSON.stringify(payload);
const key = "test-forge-" +
  createHash("sha256").update(canonical).digest("hex").slice(0, 16) + "-a1";

const started = await api("POST", "/run", payload, { "Idempotency-Key": key });

let job;
do {
  await new Promise((r) => setTimeout(r, 1500));
  job = await api("GET", `/jobs/${started.job_id}`);
} while (job.status !== "succeeded" && job.status !== "failed");

if (job.status === "failed") throw new Error(job.error || "run failed");

const reply = job.output.output; // the plain-text contract; see step 6
canonical, _ := json.Marshal(payload)
sum := sha256.Sum256(canonical)
key := fmt.Sprintf("test-forge-%x-a1", sum[:8])

var started struct {
	JobID string `json:"job_id"`
}
if err := call("POST", "/run", payload, &started,
	map[string]string{"Idempotency-Key": key}); err != nil {
	panic(err)
}

var job struct {
	Status string `json:"status"`
	Error  string `json:"error"`
	Output struct {
		Output string `json:"output"`
	} `json:"output"`
}
for {
	if err := call("GET", "/jobs/"+started.JobID, nil, &job, nil); err != nil {
		panic(err)
	}
	if job.Status == "succeeded" || job.Status == "failed" {
		break
	}
	time.Sleep(1500 * time.Millisecond)
}
reply := job.Output.Output // the plain-text contract; see step 6
var digest = MessageDigest.getInstance("SHA-256").digest(body.getBytes(UTF_8));
String key = "test-forge-" + HexFormat.of().formatHex(digest).substring(0, 16) + "-a1";

String startEnvelope = api("POST", "/run", body, Map.of("Idempotency-Key", key));
String jobId = /* data.job_id, via your JSON library */;

String status;
String jobEnvelope;
do {
    Thread.sleep(1500);
    jobEnvelope = api("GET", "/jobs/" + jobId, null, null);
    status = /* data.status */;
} while (!status.equals("succeeded") && !status.equals("failed"));

if (status.equals("failed")) throw new RuntimeException(jobEnvelope);
String reply = /* data.output.output - the plain-text contract; see step 6 */;
require "digest"

canonical = JSON.generate(payload)
key = "test-forge-#{Digest::SHA256.hexdigest(canonical)[0, 16]}-a1"

started = api("POST", "/run", payload, { "Idempotency-Key" => key })

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"

reply = job["output"]["output"] # the plain-text contract; see step 6
<?php
$canonical = json_encode($payload);
$key = "test-forge-" . substr(hash("sha256", $canonical), 0, 16) . "-a1";

$started = api("POST", "/run", $payload, ["Idempotency-Key" => $key]);

do {
    sleep(2);
    $job = api("GET", "/jobs/" . $started["job_id"]);
} while (!in_array($job["status"], ["succeeded", "failed"], true));

if ($job["status"] === "failed") {
    throw new Exception($job["error"] ?? "run failed");
}

$reply = $job["output"]["output"]; // the plain-text contract; see step 6
using System.Security.Cryptography;
using System.Text;

var canonical = JsonSerializer.Serialize(payload);
var hash = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(canonical)));
var key = $"test-forge-{hash[..16].ToLowerInvariant()}-a1";

var started = await TestForge.ApiAsync(HttpMethod.Post, "/run", payload,
    ("Idempotency-Key", key));
var jobId = started.GetProperty("job_id").GetString();

JsonElement job;
string? status;
do
{
    await Task.Delay(1500);
    job = await TestForge.ApiAsync(HttpMethod.Get, $"/jobs/{jobId}");
    status = job.GetProperty("status").GetString();
} while (status is not ("succeeded" or "failed"));

if (status == "failed") throw new Exception("run failed");
var reply = job.GetProperty("output").GetProperty("output").GetString();

Step 5 — Stream it instead (SSE)

POST /run-stream

Same body, same Idempotency-Key, but the response is text/event-stream. Events are job (the run started), delta with {"text":"..."} chunks, then done carrying the final payload, or error. Treat the done payload as authoritative and the concatenated deltas as a preview — a dropped chunk at the tail is possible, and the app rebuilds from done.output.output for exactly that reason.

The section markers arriving in the stream are a free progress bar: FILENAME:, then PLAN:, then TESTS:, then NOTES:. On an idempotent replay the platform may answer with plain JSON instead of a stream — check the Content-Type before parsing.

curl -N -s -X POST "$API/run-stream" \
  -H "Authorization: Bearer $SKILLSAFE_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $KEY" \
  -d @input.json \
  | while IFS= read -r line; do
      case "$line" in
        "event: "*) EV="${line#event: }" ;;
        "data: "*)
          case "$EV" in
            delta) printf '%s' "$(echo "${line#data: }" | jq -r '.text')" ;;
            done)  echo "${line#data: }" | jq -r '.output.output' > reply.txt ;;
            error) echo "${line#data: }" >&2 ;;
          esac ;;
      esac
    done
import requests

res = requests.post(API + "/run-stream", json=payload, stream=True, headers={
    "Authorization": "Bearer " + TOKEN,
    "Idempotency-Key": key,
})

event, reply, done = "message", "", None
for raw in res.iter_lines(decode_unicode=True):
    if raw is None:
        continue
    if raw.startswith("event:"):
        event = raw[6:].strip()
    elif raw.startswith("data:"):
        data = json.loads(raw[5:].strip())
        if event == "delta":
            reply += data.get("text", "")
        elif event == "done":
            done = data
        elif event == "error":
            raise RuntimeError(data.get("message", "run failed"))

# the done payload wins; deltas can drop the tail
reply = (done or {}).get("output", {}).get("output") or reply
const res = await fetch(API + "/run-stream", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    "Content-Type": "application/json",
    "Idempotency-Key": key,
  },
  body: JSON.stringify(payload),
});

let reply = "", done = null, buffer = "";
const reader = res.body.getReader();
const decoder = new TextDecoder();
for (;;) {
  const chunk = await reader.read();
  if (chunk.done) break;
  buffer += decoder.decode(chunk.value, { stream: true });
  let idx;
  while ((idx = buffer.indexOf("\n\n")) >= 0) {
    const frame = buffer.slice(0, idx);
    buffer = buffer.slice(idx + 2);
    let event = "message", dataStr = "";
    for (const line of frame.split("\n")) {
      if (line.startsWith("event:")) event = line.slice(6).trim();
      else if (line.startsWith("data:")) dataStr += line.slice(5).trim();
    }
    if (!dataStr) continue;
    const data = JSON.parse(dataStr);
    if (event === "delta") reply += data.text || "";
    else if (event === "done") done = data;
    else if (event === "error") throw new Error(data.message || "run failed");
  }
}
reply = done?.output?.output || reply; // done wins; deltas can drop the tail
bodyBytes, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", API+"/run-stream", bytes.NewReader(bodyBytes))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", key)

res, err := http.DefaultClient.Do(req)
if err != nil {
	panic(err)
}
defer res.Body.Close()

var reply strings.Builder
var doneText string
event := "message"
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(line[6:])
	case strings.HasPrefix(line, "data:"):
		var d struct {
			Text    string `json:"text"`
			Message string `json:"message"`
			Output  struct {
				Output string `json:"output"`
			} `json:"output"`
		}
		json.Unmarshal([]byte(strings.TrimSpace(line[5:])), &d)
		switch event {
		case "delta":
			reply.WriteString(d.Text)
		case "done":
			doneText = d.Output.Output
		case "error":
			panic(d.Message)
		}
	}
}
final := doneText // done wins; deltas can drop the tail
if final == "" {
	final = reply.String()
}
var req = HttpRequest.newBuilder(URI.create(API + "/run-stream"))
    .header("Authorization", "Bearer " + TOKEN)
    .header("Content-Type", "application/json")
    .header("Idempotency-Key", key)
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

var res = HTTP.send(req, HttpResponse.BodyHandlers.ofLines());
var reply = new StringBuilder();
String doneText = null;
String event = "message";
for (String line : (Iterable<String>) res.body()::iterator) {
    if (line.startsWith("event:")) {
        event = line.substring(6).trim();
    } else if (line.startsWith("data:")) {
        String json = line.substring(5).trim();
        if (event.equals("delta")) {
            reply.append(/* data.text, via your JSON library */ "");
        } else if (event.equals("done")) {
            doneText = /* data.output.output */ json;
        } else if (event.equals("error")) {
            throw new RuntimeException(json);
        }
    }
}
// the done payload wins; deltas can drop the tail
String finalReply = doneText != null ? doneText : reply.toString();
uri = URI(API + "/run-stream")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = key
req.body = payload.to_json

reply = +""
done = nil
event = "message"
buffer = +""

Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  http.request(req) do |res|
    res.read_body do |chunk|
      buffer << chunk
      while (i = buffer.index("\n\n"))
        frame = buffer.slice!(0, i + 2)
        frame.each_line do |line|
          line = line.chomp
          if line.start_with?("event:")
            event = line[6..].strip
          elsif line.start_with?("data:")
            data = JSON.parse(line[5..].strip)
            case event
            when "delta" then reply << data["text"].to_s
            when "done"  then done = data
            when "error" then raise(data["message"] || "run failed")
            end
          end
        end
      end
    end
  end
end

reply = done&.dig("output", "output") || reply # done wins
<?php
$reply = "";
$doneText = null;
$event = "message";
$buffer = "";

$ch = curl_init(API . "/run-stream");
curl_setopt_array($ch, [
    CURLOPT_POST       => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $TOKEN",
        "Content-Type: application/json",
        "Idempotency-Key: $key",
        "Accept: text/event-stream",
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
    CURLOPT_WRITEFUNCTION => function ($ch, $chunk) use (&$reply, &$doneText, &$event, &$buffer) {
        $buffer .= $chunk;
        while (($i = strpos($buffer, "\n\n")) !== false) {
            $frame  = substr($buffer, 0, $i);
            $buffer = substr($buffer, $i + 2);
            foreach (explode("\n", $frame) as $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")      { $reply .= $data["text"] ?? ""; }
                    elseif ($event === "done")   { $doneText = $data["output"]["output"] ?? null; }
                    elseif ($event === "error")  { throw new Exception($data["message"] ?? "run failed"); }
                }
            }
        }
        return strlen($chunk);
    },
]);
curl_exec($ch);
curl_close($ch);

$reply = $doneText ?? $reply; // done wins; deltas can drop the tail
var req = new HttpRequestMessage(HttpMethod.Post,
    "https://api.skillsafe.ai/v1/app-api/run-stream")
{
    Content = JsonContent.Create(payload),
};
req.Headers.Add("Idempotency-Key", key);

using var res = await Http.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
using var reader = new StreamReader(await res.Content.ReadAsStreamAsync());

var reply = new StringBuilder();
string? doneText = null;
var evt = "message";
while (await reader.ReadLineAsync() is { } line)
{
    if (line.StartsWith("event:")) evt = line[6..].Trim();
    else if (line.StartsWith("data:"))
    {
        var data = JsonSerializer.Deserialize<JsonElement>(line[5..].Trim());
        if (evt == "delta")
            reply.Append(data.GetProperty("text").GetString());
        else if (evt == "done")
            doneText = data.GetProperty("output").GetProperty("output").GetString();
        else if (evt == "error")
            throw new Exception(data.GetProperty("message").GetString());
    }
}
// the done payload wins; deltas can drop the tail
var finalReply = doneText ?? reply.ToString();

Step 6 — Parse the output contract

The reply is plain text, not JSON, in a fixed shape. Read it strictly: the app treats a reply that does not match as a failed parse and retries once with a retry_note.

FILENAME: duration.test.ts
FRAMEWORK: Vitest
SUMMARY: 14 tests across formatDuration and parseDuration, including the .5 rounding boundary

PLAN:
- **formatDuration**
  - formats whole minutes without a seconds part
  - rounds half-open intervals up (edge)
  - throws on a negative input (edge)
- **parseDuration**
  - parses the "1h30m" form (from notes)

TESTS:
import { describe, it, expect } from "vitest";
import { formatDuration, parseDuration } from "./duration";

describe("formatDuration", () => {
  it("formats whole minutes without a seconds part", () => {
    expect(formatDuration(120000)).toBe("2m");
  });
});

NOTES:
**Assumptions:** the .5 boundary rounds up, matching the <= in the source.

**Mocks and setup:** none.

**Not covered:** the module's exported `nowLabel` reads the clock through an
import that is not shown, so it is left untested.

Coverage confidence: 78%, the clock-reading export is untested.
MarkerRule
FILENAME:The first line. Everything after the prefix, trimmed, is the test filename (e.g. duration.test.ts). Required, non-empty.
FRAMEWORK:The first line after that starting with the prefix. Its value must be exactly Vitest or Jest (case-insensitively); anything else is a failed parse.
SUMMARY:The first following line with the prefix, one line, no markdown. Optional — treat a missing summary as an empty string, and stop looking once you hit PLAN: or TESTS:.
PLAN:A line reading exactly PLAN: and nothing else. Everything up to the TESTS: line is a markdown bullet list, grouped per describe block, with (edge) and (from notes) tags. May be empty.
TESTS:A line reading exactly TESTS:. Everything up to NOTES: (or the end) is the raw test file with no code fence. Required, non-empty. Strip a fence if one appears anyway.
NOTES:A line reading exactly NOTES:, after TESTS:. Everything after it is markdown: assumptions, mocks and setup, what is not covered.
ConfidenceThe last line of NOTES reads Coverage confidence: NN%, <clause>. Scan the notes bottom-up for it and strip any surrounding asterisks.

Two defensive details worth copying from the app: strip a single markdown fence wrapped around the whole reply before splitting into lines, and strip one wrapped around just the TESTS block. Also note that no line inside the test code may start with NOTES: at column zero — the contract reserves that, so an unindented comment containing it would cut the file short.

# reply.txt holds the raw reply from step 4 or 5.
awk '/^TESTS:[ \t]*$/{f=1;next} /^NOTES:[ \t]*$/{f=0} f' reply.txt > duration.test.ts

FILENAME=$(sed -n 's/^FILENAME: *//p' reply.txt | head -1)
FRAMEWORK=$(sed -n 's/^FRAMEWORK: *//p' reply.txt | head -1)
CONF=$(grep -o 'Coverage confidence: [0-9]\{1,3\}%' reply.txt | tail -1)

mv duration.test.ts "src/lib/$FILENAME"
echo "$FRAMEWORK - $CONF"
import re

def parse_result(text):
    text = text.strip()
    fence = re.match(r"^```[^\n]*\n([\s\S]*?)\n?```$", text)
    if fence:
        text = fence.group(1).strip()
    lines = text.split("\n")

    def find(prefix, start=0):
        for i in range(start, len(lines)):
            if lines[i].startswith(prefix):
                return i
        return -1

    fi = find("FILENAME:")
    if fi == -1:
        return None
    wi = find("FRAMEWORK:", fi + 1)
    if wi == -1:
        return None
    framework = lines[wi][len("FRAMEWORK:"):].strip().lower()
    framework = {"vitest": "Vitest", "jest": "Jest"}.get(framework)
    if not framework:
        return None

    summary = ""
    for i in range(wi + 1, len(lines)):
        if re.fullmatch(r"(PLAN|TESTS):[ \t]*", lines[i]):
            break
        if lines[i].startswith("SUMMARY:"):
            summary = lines[i][len("SUMMARY:"):].strip()
            break

    pi = ti = ni = -1
    for i in range(wi + 1, len(lines)):
        if pi == -1 and re.fullmatch(r"PLAN:[ \t]*", lines[i]):
            pi = i
        elif ti == -1 and re.fullmatch(r"TESTS:[ \t]*", lines[i]):
            ti = i
        elif ti != -1 and re.fullmatch(r"NOTES:[ \t]*", lines[i]):
            ni = i
            break
    if ti == -1:
        return None

    end = ni if ni != -1 else len(lines)
    tests = "\n".join(lines[ti + 1:end]).strip()
    filename = lines[fi][len("FILENAME:"):].strip()
    if not filename or not tests:
        return None

    notes = "\n".join(lines[ni + 1:]).strip() if ni != -1 else ""
    conf = None
    for line in reversed(notes.split("\n")):
        m = re.match(r"^Coverage confidence:\s*(\d{1,3})%", line.strip().strip("*").strip())
        if m:
            conf = int(m.group(1))
            break

    return {
        "filename": filename,
        "framework": framework,
        "summary": summary,
        "plan": "\n".join(lines[pi + 1:ti]).strip() if -1 < pi < ti else "",
        "tests": tests,
        "notes": notes,
        "confidence": conf,
    }

result = parse_result(reply)
open("src/lib/" + result["filename"], "w").write(result["tests"] + "\n")
print(result["framework"], result["confidence"], "% confidence")
function parseResult(text) {
  let t = String(text ?? "").trim();
  const fence = t.match(/^```[^\n]*\n([\s\S]*?)\n?```$/);
  if (fence) t = fence[1].trim();
  const lines = t.split(/\r?\n/);
  const find = (p, from = 0) => lines.findIndex((l, i) => i >= from && l.startsWith(p));

  const fi = find("FILENAME:");
  if (fi === -1) return null;
  const wi = find("FRAMEWORK:", fi + 1);
  if (wi === -1) return null;
  const fw = lines[wi].slice("FRAMEWORK:".length).trim().toLowerCase();
  const framework = fw === "vitest" ? "Vitest" : fw === "jest" ? "Jest" : "";
  if (!framework) return null;

  let summary = "";
  for (let i = wi + 1; i < lines.length; i++) {
    if (/^(PLAN|TESTS):[ \t]*$/.test(lines[i])) break;
    if (lines[i].startsWith("SUMMARY:")) {
      summary = lines[i].slice("SUMMARY:".length).trim();
      break;
    }
  }

  let pi = -1, ti = -1, ni = -1;
  for (let i = wi + 1; i < lines.length; i++) {
    if (pi === -1 && /^PLAN:[ \t]*$/.test(lines[i])) { pi = i; continue; }
    if (ti === -1 && /^TESTS:[ \t]*$/.test(lines[i])) { ti = i; continue; }
    if (ti !== -1 && /^NOTES:[ \t]*$/.test(lines[i])) { ni = i; break; }
  }
  if (ti === -1) return null;

  const filename = lines[fi].slice("FILENAME:".length).trim();
  const tests = lines.slice(ti + 1, ni === -1 ? lines.length : ni).join("\n").trim();
  if (!filename || !tests) return null;
  const notes = ni === -1 ? "" : lines.slice(ni + 1).join("\n").trim();

  let confidence = null;
  for (const line of notes.split("\n").reverse()) {
    const m = line.trim().replace(/^\*+|\*+$/g, "").trim()
      .match(/^Coverage confidence:\s*(\d{1,3})%/);
    if (m) { confidence = Math.min(100, parseInt(m[1], 10)); break; }
  }

  return {
    filename, framework, summary,
    plan: pi !== -1 && pi < ti ? lines.slice(pi + 1, ti).join("\n").trim() : "",
    tests, notes, confidence,
  };
}

const result = parseResult(reply);
writeFileSync("src/lib/" + result.filename, result.tests + "\n");
console.log(result.framework, result.confidence + "% confidence");
type Result struct {
	Filename   string
	Framework  string
	Summary    string
	Plan       string
	Tests      string
	Notes      string
	Confidence int
}

var (
	planRe   = regexp.MustCompile(`^PLAN:[ \t]*$`)
	testsRe  = regexp.MustCompile(`^TESTS:[ \t]*$`)
	notesRe  = regexp.MustCompile(`^NOTES:[ \t]*$`)
	confRe   = regexp.MustCompile(`^Coverage confidence:\s*(\d{1,3})%`)
	fenceRe  = regexp.MustCompile("(?s)^```[^\n]*\n(.*?)\n?```$")
)

func parseResult(text string) *Result {
	t := strings.TrimSpace(text)
	if m := fenceRe.FindStringSubmatch(t); m != nil {
		t = strings.TrimSpace(m[1])
	}
	lines := strings.Split(t, "\n")

	fi, wi := -1, -1
	for i, l := range lines {
		if strings.HasPrefix(l, "FILENAME:") {
			fi = i
			break
		}
	}
	if fi == -1 {
		return nil
	}
	for i := fi + 1; i < len(lines); i++ {
		if strings.HasPrefix(lines[i], "FRAMEWORK:") {
			wi = i
			break
		}
	}
	if wi == -1 {
		return nil
	}
	var framework string
	switch strings.ToLower(strings.TrimSpace(lines[wi][len("FRAMEWORK:"):])) {
	case "vitest":
		framework = "Vitest"
	case "jest":
		framework = "Jest"
	default:
		return nil
	}

	summary := ""
	for i := wi + 1; i < len(lines); i++ {
		if planRe.MatchString(lines[i]) || testsRe.MatchString(lines[i]) {
			break
		}
		if strings.HasPrefix(lines[i], "SUMMARY:") {
			summary = strings.TrimSpace(lines[i][len("SUMMARY:"):])
			break
		}
	}

	pi, ti, ni := -1, -1, -1
	for i := wi + 1; i < len(lines); i++ {
		switch {
		case pi == -1 && planRe.MatchString(lines[i]):
			pi = i
		case ti == -1 && testsRe.MatchString(lines[i]):
			ti = i
		case ti != -1 && notesRe.MatchString(lines[i]):
			ni = i
		}
		if ni != -1 {
			break
		}
	}
	if ti == -1 {
		return nil
	}
	end := len(lines)
	if ni != -1 {
		end = ni
	}
	res := &Result{
		Filename:  strings.TrimSpace(lines[fi][len("FILENAME:"):]),
		Framework: framework,
		Summary:   summary,
		Tests:     strings.TrimSpace(strings.Join(lines[ti+1:end], "\n")),
	}
	if pi != -1 && pi < ti {
		res.Plan = strings.TrimSpace(strings.Join(lines[pi+1:ti], "\n"))
	}
	if ni != -1 {
		res.Notes = strings.TrimSpace(strings.Join(lines[ni+1:], "\n"))
	}
	if res.Filename == "" || res.Tests == "" {
		return nil
	}
	noteLines := strings.Split(res.Notes, "\n")
	for i := len(noteLines) - 1; i >= 0; i-- {
		l := strings.Trim(strings.TrimSpace(noteLines[i]), "*")
		if m := confRe.FindStringSubmatch(strings.TrimSpace(l)); m != nil {
			res.Confidence, _ = strconv.Atoi(m[1])
			break
		}
	}
	return res
}
record Result(String filename, String framework, String summary,
              String plan, String tests, String notes, int confidence) {}

static Result parseResult(String text) {
    String t = text.strip();
    var fence = Pattern.compile("^```[^\n]*\n(.*?)\n?```$", Pattern.DOTALL).matcher(t);
    if (fence.matches()) t = fence.group(1).strip();
    String[] lines = t.split("\r?\n");

    int fi = -1, wi = -1, pi = -1, ti = -1, ni = -1;
    for (int i = 0; i < lines.length; i++) {
        if (lines[i].startsWith("FILENAME:")) { fi = i; break; }
    }
    if (fi < 0) return null;
    for (int i = fi + 1; i < lines.length; i++) {
        if (lines[i].startsWith("FRAMEWORK:")) { wi = i; break; }
    }
    if (wi < 0) return null;
    String fw = lines[wi].substring("FRAMEWORK:".length()).strip();
    String framework = fw.equalsIgnoreCase("Vitest") ? "Vitest"
                     : fw.equalsIgnoreCase("Jest") ? "Jest" : null;
    if (framework == null) return null;

    String summary = "";
    for (int i = wi + 1; i < lines.length; i++) {
        if (lines[i].matches("(PLAN|TESTS):[ \t]*")) break;
        if (lines[i].startsWith("SUMMARY:")) {
            summary = lines[i].substring("SUMMARY:".length()).strip();
            break;
        }
    }
    for (int i = wi + 1; i < lines.length; i++) {
        if (pi < 0 && lines[i].matches("PLAN:[ \t]*")) { pi = i; continue; }
        if (ti < 0 && lines[i].matches("TESTS:[ \t]*")) { ti = i; continue; }
        if (ti >= 0 && lines[i].matches("NOTES:[ \t]*")) { ni = i; break; }
    }
    if (ti < 0) return null;

    int end = ni < 0 ? lines.length : ni;
    String tests = String.join("\n", Arrays.copyOfRange(lines, ti + 1, end)).strip();
    String filename = lines[fi].substring("FILENAME:".length()).strip();
    if (filename.isEmpty() || tests.isEmpty()) return null;

    String plan = (pi >= 0 && pi < ti)
        ? String.join("\n", Arrays.copyOfRange(lines, pi + 1, ti)).strip() : "";
    String notes = ni < 0 ? ""
        : String.join("\n", Arrays.copyOfRange(lines, ni + 1, lines.length)).strip();

    int confidence = -1;
    var conf = Pattern.compile("^Coverage confidence:\\s*(\\d{1,3})%");
    String[] noteLines = notes.split("\n");
    for (int i = noteLines.length - 1; i >= 0; i--) {
        var m = conf.matcher(noteLines[i].strip().replaceAll("^\\*+|\\*+$", "").strip());
        if (m.find()) { confidence = Integer.parseInt(m.group(1)); break; }
    }
    return new Result(filename, framework, summary, plan, tests, notes, confidence);
}
FRAMEWORKS = { "vitest" => "Vitest", "jest" => "Jest" }.freeze

def parse_result(text)
  t = text.to_s.strip
  t = Regexp.last_match(1).strip if t =~ /\A```[^\n]*\n(.*?)\n?```\z/m
  lines = t.split(/\r?\n/)

  fi = lines.index { |l| l.start_with?("FILENAME:") }
  return nil unless fi

  wi = (fi + 1...lines.size).find { |i| lines[i].start_with?("FRAMEWORK:") }
  return nil unless wi

  framework = FRAMEWORKS[lines[wi].delete_prefix("FRAMEWORK:").strip.downcase]
  return nil unless framework

  summary = ""
  (wi + 1...lines.size).each do |i|
    break if lines[i].match?(/\A(PLAN|TESTS):[ \t]*\z/)
    if lines[i].start_with?("SUMMARY:")
      summary = lines[i].delete_prefix("SUMMARY:").strip
      break
    end
  end

  pi = ti = ni = nil
  (wi + 1...lines.size).each do |i|
    if pi.nil? && lines[i].match?(/\APLAN:[ \t]*\z/) then pi = i
    elsif ti.nil? && lines[i].match?(/\ATESTS:[ \t]*\z/) then ti = i
    elsif ti && lines[i].match?(/\ANOTES:[ \t]*\z/) then ni = i; break
    end
  end
  return nil unless ti

  filename = lines[fi].delete_prefix("FILENAME:").strip
  tests = lines[(ti + 1)...(ni || lines.size)].join("\n").strip
  return nil if filename.empty? || tests.empty?

  notes = ni ? lines[(ni + 1)..].join("\n").strip : ""
  confidence = notes.split("\n").reverse.each do |line|
    m = line.strip.gsub(/\A\*+|\*+\z/, "").strip.match(/\ACoverage confidence:\s*(\d{1,3})%/)
    break m[1].to_i if m
  end
  confidence = nil unless confidence.is_a?(Integer)

  { filename: filename, framework: framework, summary: summary,
    plan: pi && pi < ti ? lines[(pi + 1)...ti].join("\n").strip : "",
    tests: tests, notes: notes, confidence: confidence }
end

result = parse_result(reply)
File.write("src/lib/#{result[:filename]}", result[:tests] + "\n")
<?php
function parse_result(string $text): ?array {
    $t = trim($text);
    if (preg_match('/^```[^\n]*\n([\s\S]*?)\n?```$/', $t, $m)) {
        $t = trim($m[1]);
    }
    $lines = preg_split('/\r?\n/', $t);

    $fi = $wi = $pi = $ti = $ni = -1;
    foreach ($lines as $i => $l) {
        if (str_starts_with($l, "FILENAME:")) { $fi = $i; break; }
    }
    if ($fi < 0) return null;
    for ($i = $fi + 1; $i < count($lines); $i++) {
        if (str_starts_with($lines[$i], "FRAMEWORK:")) { $wi = $i; break; }
    }
    if ($wi < 0) return null;
    $fw = strtolower(trim(substr($lines[$wi], strlen("FRAMEWORK:"))));
    $framework = ["vitest" => "Vitest", "jest" => "Jest"][$fw] ?? null;
    if ($framework === null) return null;

    $summary = "";
    for ($i = $wi + 1; $i < count($lines); $i++) {
        if (preg_match('/^(PLAN|TESTS):[ \t]*$/', $lines[$i])) break;
        if (str_starts_with($lines[$i], "SUMMARY:")) {
            $summary = trim(substr($lines[$i], strlen("SUMMARY:")));
            break;
        }
    }
    for ($i = $wi + 1; $i < count($lines); $i++) {
        if ($pi < 0 && preg_match('/^PLAN:[ \t]*$/', $lines[$i]))  { $pi = $i; continue; }
        if ($ti < 0 && preg_match('/^TESTS:[ \t]*$/', $lines[$i])) { $ti = $i; continue; }
        if ($ti >= 0 && preg_match('/^NOTES:[ \t]*$/', $lines[$i])) { $ni = $i; break; }
    }
    if ($ti < 0) return null;

    $end = $ni < 0 ? count($lines) : $ni;
    $filename = trim(substr($lines[$fi], strlen("FILENAME:")));
    $tests = trim(implode("\n", array_slice($lines, $ti + 1, $end - $ti - 1)));
    if ($filename === "" || $tests === "") return null;

    $notes = $ni < 0 ? "" : trim(implode("\n", array_slice($lines, $ni + 1)));
    $confidence = null;
    foreach (array_reverse(explode("\n", $notes)) as $line) {
        $clean = trim(trim(trim($line), "*"));
        if (preg_match('/^Coverage confidence:\s*(\d{1,3})%/', $clean, $m)) {
            $confidence = (int) $m[1];
            break;
        }
    }

    return [
        "filename"   => $filename,
        "framework"  => $framework,
        "summary"    => $summary,
        "plan"       => ($pi >= 0 && $pi < $ti)
            ? trim(implode("\n", array_slice($lines, $pi + 1, $ti - $pi - 1))) : "",
        "tests"      => $tests,
        "notes"      => $notes,
        "confidence" => $confidence,
    ];
}

$result = parse_result($reply);
file_put_contents("src/lib/" . $result["filename"], $result["tests"] . "\n");
using System.Text.RegularExpressions;

record ForgeResult(string Filename, string Framework, string Summary,
                   string Plan, string Tests, string Notes, int? Confidence);

static ForgeResult? ParseResult(string text)
{
    var t = text.Trim();
    var fence = Regex.Match(t, @"^```[^\n]*\n([\s\S]*?)\n?```$");
    if (fence.Success) t = fence.Groups[1].Value.Trim();
    var lines = t.Split('\n').Select(l => l.TrimEnd('\r')).ToArray();

    int fi = Array.FindIndex(lines, l => l.StartsWith("FILENAME:"));
    if (fi < 0) return null;
    int wi = Array.FindIndex(lines, fi + 1, l => l.StartsWith("FRAMEWORK:"));
    if (wi < 0) return null;
    var fw = lines[wi]["FRAMEWORK:".Length..].Trim();
    var framework = fw.Equals("Vitest", StringComparison.OrdinalIgnoreCase) ? "Vitest"
                  : fw.Equals("Jest", StringComparison.OrdinalIgnoreCase) ? "Jest" : null;
    if (framework is null) return null;

    var summary = "";
    for (int i = wi + 1; i < lines.Length; i++)
    {
        if (Regex.IsMatch(lines[i], @"^(PLAN|TESTS):[ \t]*$")) break;
        if (lines[i].StartsWith("SUMMARY:"))
        {
            summary = lines[i]["SUMMARY:".Length..].Trim();
            break;
        }
    }

    int pi = -1, ti = -1, ni = -1;
    for (int i = wi + 1; i < lines.Length; i++)
    {
        if (pi < 0 && Regex.IsMatch(lines[i], @"^PLAN:[ \t]*$")) { pi = i; continue; }
        if (ti < 0 && Regex.IsMatch(lines[i], @"^TESTS:[ \t]*$")) { ti = i; continue; }
        if (ti >= 0 && Regex.IsMatch(lines[i], @"^NOTES:[ \t]*$")) { ni = i; break; }
    }
    if (ti < 0) return null;

    int end = ni < 0 ? lines.Length : ni;
    var filename = lines[fi]["FILENAME:".Length..].Trim();
    var tests = string.Join("\n", lines[(ti + 1)..end]).Trim();
    if (filename.Length == 0 || tests.Length == 0) return null;

    var plan = pi >= 0 && pi < ti ? string.Join("\n", lines[(pi + 1)..ti]).Trim() : "";
    var notes = ni < 0 ? "" : string.Join("\n", lines[(ni + 1)..]).Trim();

    int? confidence = null;
    foreach (var line in notes.Split('\n').Reverse())
    {
        var m = Regex.Match(line.Trim().Trim('*').Trim(),
                            @"^Coverage confidence:\s*(\d{1,3})%");
        if (m.Success) { confidence = int.Parse(m.Groups[1].Value); break; }
    }
    return new ForgeResult(filename, framework, summary, plan, tests, notes, confidence);
}

Read the NOTES before you keep the tests. The Not covered: list and the coverage confidence line are the honest part of the reply — a test file that admits what it cannot pin down is worth more than one that claims everything. In CI, gating on the confidence number is a reasonable habit.