From af6fdababd4c6e0c9d792b0177cb0e540bbf6ba3 Mon Sep 17 00:00:00 2001 From: CodeAlex52 <59381946+CodeAlex52@users.noreply.github.com> Date: Sun, 11 Oct 2026 15:29:54 +0800 Subject: [PATCH] feat: doctor performs real self-checks (node, schema, examples) --- bin/trace.mjs | 41 +++++++++++++++++++++++++++++++++++++++-- test/trace.test.mjs | 5 +++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/bin/trace.mjs b/bin/trace.mjs index 9325d7b..bd249ae 100644 --- a/bin/trace.mjs +++ b/bin/trace.mjs @@ -158,8 +158,45 @@ const jsonOut = rest.includes("--json"); const args = rest.filter((a) => a !== "--json"); if (cmd === "doctor") { - const out = { ok: true, node: process.version, checks: ["schema present", "renderer present", "no deps"] }; - console.log(jsonOut ? JSON.stringify(out, null, 2) : "agent-loop-trace ready."); + const checks = []; + const errors = []; + const major = Number(process.versions.node.split(".")[0]); + if (major >= 18) { + checks.push(`node ${process.version} (>=18 required)`); + } else { + errors.push(`node ${process.version} is below the required >=18`); + } + + try { + JSON.parse(readFileSync(resolve(ROOT, "schemas/loop-trace.schema.json"), "utf8")); + checks.push("schema present and parses"); + } catch { + errors.push("schemas/loop-trace.schema.json missing or invalid JSON"); + } + + let exampleCount = 0; + try { + const names = readdirSync(resolve(ROOT, "examples")) + .filter((f) => f.endsWith(".json")) + .sort(); + for (const name of names) { + const spec = loadJson(resolve(ROOT, "examples", name)); + const { errors: checkErrors } = validateSpec(spec); + if (checkErrors > 0) errors.push(`${name} fails ${checkErrors} validation check(s)`); + exampleCount += 1; + } + if (exampleCount > 0 && errors.length === 0) { + checks.push(`${exampleCount} example spec(s) validate`); + } + } catch { + errors.push("examples/ directory missing or unreadable"); + } + + const out = { ok: errors.length === 0, node: process.version, examples: exampleCount, checks: errors.length ? errors : checks }; + if (jsonOut) console.log(JSON.stringify(out, null, 2)); + else if (errors.length) console.error(`doctor found ${errors.length} issue(s):\n- ${errors.join("\n- ")}`); + else console.log(`agent-loop-trace ready. ${exampleCount} example(s) validated.`); + process.exit(errors.length === 0 ? 0 : 1); } else if (cmd === "validate") { const [input] = args; if (!input) { diff --git a/test/trace.test.mjs b/test/trace.test.mjs index a0fc341..1feb2f9 100644 --- a/test/trace.test.mjs +++ b/test/trace.test.mjs @@ -34,12 +34,13 @@ test("validate reads a spec from stdin via '-'", () => { assert.equal(receipt.input, ""); }); -test("doctor reports a ready toolchain", () => { +test("doctor performs real self-checks and reports ready", () => { const r = run(["doctor", "--json"]); assert.equal(r.code, 0); const out = JSON.parse(r.stdout); assert.equal(out.ok, true); - assert.deepEqual(out.checks, ["schema present", "renderer present", "no deps"]); + assert.ok(out.examples >= 2); + assert.ok(out.checks.some((c) => c.includes("schema present"))); }); for (const example of EXAMPLES) {