repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/the-system/__tests__/the-system.test.ts
Rawimport assert from "node:assert/strict";
import {
chmodSync,
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, it } from "vitest";
import registerTheSystem from "../index.ts";
import { editorCandidates, parseEditorCommand } from "../open-editor.ts";
import { composeSystemSection, runtimeState } from "../system.ts";
import { createSystemCommand } from "../system-command.ts";
import { systemPromptFor } from "../system-prompts.ts";
const roots: string[] = [];
const temp = () => {
const root = mkdtempSync(path.join(tmpdir(), "the-system-command-"));
roots.push(root);
return root;
};
const write = (root: string, relative: string, content: string) => {
const target = path.join(root, relative);
mkdirSync(path.dirname(target), { recursive: true });
writeFileSync(target, content, "utf8");
};
type CapturedTool = {
execute: (
toolCallId: string,
params: unknown,
signal: undefined,
onUpdate: undefined,
ctx: unknown,
) => Promise<unknown>;
};
const validSystem = (root: string) => {
for (const directory of ["specs", "phases", "plans", "issues", "research"])
mkdirSync(path.join(root, ".system", directory), { recursive: true });
for (const file of ["SYSTEM.md", "MISSION.md", "RULES.md"])
write(root, `.system/${file}`, `# ${file}\n`);
write(root, ".system/config.json", '{"prefix":"PX","schemaVersion":0}');
write(root, ".system/board.json", '{"schemaVersion":0,"items":{}}');
write(
root,
".system/specs/PX-SPEC-SPEC0001-contract/index.md",
[
"---",
"id: PX-SPEC-SPEC0001",
"type: spec",
"title: Contract",
"extra:",
" nested: yes",
"---",
"",
"# Contract",
"",
"> [!NOTE]",
"> Alert body.",
"",
"Term",
": Definition",
"",
"```mermaid",
"flowchart TD; A-->B;",
"```",
"",
"Math $x+1$.",
"",
"```ts",
"const ok = true;",
"```",
"",
"[Interactive prototype](./mockup-card.html)",
"",
"[Architecture diagram](./architecture.svg)",
"",
"[Walkthrough](./walkthrough.webm)",
"",
"[Supporting notes](./notes.md)",
"",
"An inline [prototype link](./mockup-card.html) stays inline.",
"",
"<mark>raw</mark>",
].join("\n"),
);
write(
root,
".system/specs/PX-SPEC-SPEC0001-contract/mockup-card.html",
"<section>Mockup card</section>",
);
write(
root,
".system/specs/PX-SPEC-SPEC0001-contract/architecture.svg",
'<svg xmlns="http://www.w3.org/2000/svg"></svg>',
);
write(
root,
".system/specs/PX-SPEC-SPEC0001-contract/walkthrough.webm",
"video",
);
write(
root,
".system/specs/PX-SPEC-SPEC0001-contract/notes.md",
"# Supporting notes\n",
);
write(
root,
".system/phases/PX-PHASE-PHASE001-delivery/index.md",
"---\nid: PX-PHASE-PHASE001\ntype: phase\ntitle: Delivery\nlabel: delivery\n---\n\n# Delivery\n",
);
write(
root,
".system/phases/PX-PHASE-PHASE002-alpha/index.md",
"---\nid: PX-PHASE-PHASE002\ntype: phase\ntitle: Alpha\nlabel: alpha\n---\n\n# Alpha\n",
);
write(
root,
".system/plans/PX-PLAN-PLAN0001-build/index.md",
"---\nid: PX-PLAN-PLAN0001\ntype: plan\ntitle: Build\nspec: PX-SPEC-SPEC0001\nstatus: draft\n---\n\n# Build\n",
);
write(
root,
".system/plans/PX-PLAN-PLAN0002-alpha/index.md",
"---\nid: PX-PLAN-PLAN0002\ntype: plan\ntitle: Alpha\nspec: PX-SPEC-SPEC0001\nstatus: draft\ndepends_on: [PX-PLAN-PLAN0001]\n---\n\n# Alpha\n",
);
};
afterEach(() => {
for (const root of roots.splice(0))
rmSync(root, { recursive: true, force: true });
});
describe("/system command", () => {
it("assigns bundle migration, not machine schema updates, to the agent", () => {
const prompt = systemPromptFor("init", "");
assert.match(prompt, /config and board schema markers mechanically/);
assert.match(prompt, /migrate existing bundles to schema 0/);
});
it("keeps MISSION outside phase authoring", () => {
assert.match(systemPromptFor("phase", ""), /Do not mutate MISSION/);
});
it("requires exec to deliver complete vertical slices", () => {
const prompt = systemPromptFor("exec", "");
assert.match(prompt, /Load the vertical-slices skill/);
assert.match(prompt, /thin vertical slices/);
assert.match(prompt, /complete, observable behavior/);
assert.match(prompt, /Do not batch work horizontally/);
assert.match(prompt, /freshly verify each slice before starting the next/);
assert.match(prompt, /define required outcome, not implementation order/);
assert.match(
prompt,
/Re-sequence layered plan content into vertical slices/,
);
assert.match(prompt, /Do not pause for human approval between slices/);
});
it("plans behavior decomposition with visual models", () => {
const prompt = systemPromptFor("plan", "");
assert.match(
prompt,
/Decompose by observable behavior, not by architectural layer/,
);
assert.match(prompt, /without a layer-by-layer build order/);
assert.match(
prompt,
/Model the module and interface structure, or the behavior sequence, as a diagram/,
);
});
it("defaults System Markdown to visual models", () => {
const prompt = systemPromptFor("spec", "");
assert.match(
prompt,
/Model structure, sequence, state, entities, and decisions visually by default/,
);
assert.match(prompt, /select a format first/);
assert.match(prompt, /Terse governs prose, not models/);
});
it("registers /system and defers scoped extension tools", () => {
const commands: string[] = [];
const tools: string[] = [];
registerTheSystem({
registerCommand: (name: string) => commands.push(name),
registerTool: (tool: { name: string }) => tools.push(tool.name),
on() {},
} as never);
assert.deepEqual(commands, ["system"]);
assert.deepEqual(tools, []);
});
it("keeps scoped tools through clarification until their existing completion signal", async () => {
const project = temp();
validSystem(project);
let activeTools = ["read"];
let command:
| { handler: (args: string, ctx: unknown) => Promise<void> }
| undefined;
let boardTool: CapturedTool | undefined;
let boardUpdateTool: CapturedTool | undefined;
let bundleSlotTool: CapturedTool | undefined;
let agentSettled: ((event: unknown, ctx: unknown) => void) | undefined;
registerTheSystem({
registerCommand(_name: string, definition: typeof command) {
command = definition;
},
registerTool(definition: { name: string }) {
if (definition.name === "system_board_propose")
boardTool = definition as CapturedTool;
if (definition.name === "system_board_update")
boardUpdateTool = definition as CapturedTool;
if (definition.name === "system_bundle_slot")
bundleSlotTool = definition as CapturedTool;
},
on(event: string, handler: (...args: never[]) => unknown) {
if (event === "agent_settled") agentSettled = handler as never;
},
getActiveTools: () => activeTools,
setActiveTools: (tools: string[]) => {
activeTools = tools;
},
sendUserMessage() {},
} as never);
const ctx = {
cwd: project,
mode: "interactive",
hasUI: false,
isIdle: () => true,
abort() {},
sessionManager: {
getSessionId: () => project,
getBranch: () => [],
},
ui: {
notify() {},
setStatus() {},
theme: { fg: (_color: string, text: string) => text },
},
};
assert.ok(command);
await command.handler("assess", ctx);
assert.ok(activeTools.includes("system_board_propose"));
agentSettled?.({}, ctx);
assert.ok(activeTools.includes("system_board_propose"));
assert.ok(boardTool);
await boardTool.execute(
"proposal",
{
items: [
{
id: "PX-SPEC-SPEC0001",
state: "todo",
rationale: "Implementation remains incomplete.",
},
],
},
undefined,
undefined,
ctx,
);
agentSettled?.({}, ctx);
assert.ok(!activeTools.includes("system_board_propose"));
assert.deepEqual(
JSON.parse(
readFileSync(path.join(project, ".system/board.json"), "utf8"),
),
{ schemaVersion: 0, items: {} },
);
await command.handler("exec PX-SPEC-SPEC0001", ctx);
assert.ok(activeTools.includes("system_board_update"));
assert.ok(!activeTools.includes("system_board_propose"));
agentSettled?.({}, ctx);
assert.ok(activeTools.includes("system_board_update"));
assert.ok(boardUpdateTool);
const updateItems = (
items: { id: string; state: string; note: string }[],
) => ({ items });
await assert.rejects(
boardUpdateTool.execute(
"exec-invalid",
updateItems([
{
id: "PX-SPEC-SPEC0001",
state: "done",
note: "Claimed without finished plans.",
},
]),
undefined,
undefined,
ctx,
),
/cannot be done while plans remain todo/,
);
assert.deepEqual(
JSON.parse(
readFileSync(path.join(project, ".system/board.json"), "utf8"),
),
{ schemaVersion: 0, items: {} },
);
agentSettled?.({}, ctx);
assert.ok(activeTools.includes("system_board_update"));
await boardUpdateTool.execute(
"exec-update",
updateItems([
{
id: "PX-PLAN-PLAN0001",
state: "done",
note: "Slice one verified.",
},
{
id: "PX-PLAN-PLAN0002",
state: "done",
note: "Slice two verified.",
},
{
id: "PX-SPEC-SPEC0001",
state: "done",
note: "Fresh verification passed.",
},
]),
undefined,
undefined,
ctx,
);
agentSettled?.({}, ctx);
assert.ok(!activeTools.includes("system_board_update"));
const applied = JSON.parse(
readFileSync(path.join(project, ".system/board.json"), "utf8"),
);
assert.equal(applied.items["PX-SPEC-SPEC0001"].state, "done");
assert.equal(applied.items["PX-SPEC-SPEC0001"].source, "agent");
assert.equal(
applied.items["PX-SPEC-SPEC0001"].note,
"Fresh verification passed.",
);
await command.handler("spec", ctx);
assert.ok(activeTools.includes("system_bundle_slot"));
agentSettled?.({}, ctx);
assert.ok(activeTools.includes("system_bundle_slot"));
assert.ok(bundleSlotTool);
await bundleSlotTool.execute(
"slot-one",
{ type: "spec", title: "First contract" },
undefined,
undefined,
ctx,
);
assert.ok(activeTools.includes("system_bundle_slot"));
await bundleSlotTool.execute(
"slot-two",
{ type: "issue", title: "Second concern" },
undefined,
undefined,
ctx,
);
agentSettled?.({}, ctx);
assert.ok(!activeTools.includes("system_bundle_slot"));
});
it("discovers vertical slicing generally and format skills only in valid projects", async () => {
let discover: ((event: { cwd: string }) => Promise<unknown>) | undefined;
registerTheSystem({
registerCommand() {},
registerTool() {},
on(event: string, handler: (...args: never[]) => unknown) {
if (event === "resources_discover") discover = handler as never;
},
} as never);
const skills = path.resolve(import.meta.dirname, "../skills");
const genericSkills = [path.join(skills, "vertical-slices")];
const inactive = temp();
assert.deepEqual(await discover?.({ cwd: inactive }), {
skillPaths: genericSkills,
});
mkdirSync(path.join(inactive, ".system"));
assert.deepEqual(await discover?.({ cwd: inactive }), {
skillPaths: genericSkills,
});
const active = temp();
validSystem(active);
assert.deepEqual(await discover?.({ cwd: active }), {
skillPaths: [
...genericSkills,
path.join(skills, "the-system-gfm"),
path.join(skills, "the-system-tex"),
path.join(skills, "the-system-mermaid"),
],
});
write(active, ".system/config.json", '{"prefix":"PX","schemaVersion":4}');
assert.deepEqual(await discover?.({ cwd: active }), {
skillPaths: genericSkills,
});
});
it("reports schema mismatches with schema-0 init instructions", () => {
const project = temp();
validSystem(project);
write(project, ".system/config.json", '{"prefix":"PX","schemaVersion":4}');
assert.deepEqual(runtimeState(project), {
active: true,
notice:
"The System schema does not match 0; run /system init to update it.",
});
assert.match(
composeSystemSection(project) ?? "",
/Schema version 4 does not match 0; run \/system init/,
);
});
it("shows an accent System status for initialized and incomplete projects", async () => {
for (const [project, expected] of [
[temp(), undefined],
[temp(), "accent: ?"],
[temp(), "accent: PX"],
[temp(), "accent: PX · delivery"],
] as const) {
if (expected === "accent: ?") mkdirSync(path.join(project, ".system"));
if (expected?.startsWith("accent: PX")) validSystem(project);
if (expected === "accent: PX · delivery")
write(
project,
".system/config.json",
'{"prefix":"PX","schemaVersion":0,"currentPhase":"PX-PHASE-PHASE001"}',
);
let sessionStart: ((event: unknown, ctx: unknown) => void) | undefined;
let resolveStatus: (value: string | undefined) => void = () => {};
const status = new Promise<string | undefined>((resolve) => {
resolveStatus = resolve;
});
registerTheSystem({
registerCommand() {},
registerTool() {},
getActiveTools: () => [],
setActiveTools() {},
on(event: string, handler: (event: unknown, ctx: unknown) => void) {
if (event === "session_start") sessionStart = handler;
},
} as never);
sessionStart?.(
{},
{
cwd: project,
hasUI: true,
isIdle: () => true,
abort() {},
sessionManager: { getSessionId: () => project },
ui: {
notify() {},
setStatus(_key: string, text: string | undefined) {
resolveStatus(text);
},
theme: {
fg: (color: string, text: string) => `${color}:${text}`,
},
},
},
);
assert.equal(await status, expected);
}
});
it("refreshes the footer phase before later agent turns", async () => {
const project = temp();
validSystem(project);
let sessionStart: ((event: unknown, ctx: unknown) => void) | undefined;
let beforeAgentStart:
| ((
event: {
systemPrompt: string;
systemPromptOptions: {
forceSystemPrompt?: string;
sections: Record<string, string>;
};
},
ctx: unknown,
) => Promise<unknown>)
| undefined;
const statuses: (string | undefined)[] = [];
const waiters: Array<{
expected: string | undefined;
resolve: () => void;
}> = [];
const waitForStatus = (expected: string | undefined) => {
if (statuses.includes(expected)) return Promise.resolve();
return new Promise<void>((resolve) =>
waiters.push({ expected, resolve }),
);
};
registerTheSystem({
registerCommand() {},
registerTool() {},
getActiveTools: () => [],
setActiveTools() {},
on(event: string, handler: (...args: never[]) => unknown) {
if (event === "session_start") sessionStart = handler as never;
if (event === "before_agent_start") beforeAgentStart = handler as never;
},
} as never);
const ctx = {
cwd: project,
hasUI: true,
isIdle: () => true,
abort() {},
sessionManager: {
getSessionId: () => project,
getBranch: () => [],
},
ui: {
notify() {},
setStatus(_key: string, text: string | undefined) {
statuses.push(text);
for (const waiter of waiters)
if (waiter.expected === text) waiter.resolve();
},
theme: {
fg: (color: string, text: string) => `${color}:${text}`,
},
},
};
sessionStart?.({}, ctx);
await waitForStatus("accent: PX");
write(
project,
".system/config.json",
'{"prefix":"PX","schemaVersion":0,"currentPhase":"PX-PHASE-PHASE001"}',
);
const systemPromptOptions = { sections: {} as Record<string, string> };
await beforeAgentStart?.(
{ systemPrompt: "BASE", systemPromptOptions },
ctx,
);
assert.match(
systemPromptOptions.sections.the_system,
/# The System project law/,
);
await waitForStatus("accent: PX · delivery");
});
it("offers subcommand completions and help", async () => {
const command = createSystemCommand({ sendUserMessage() {} } as never);
assert.deepEqual(
command.getArgumentCompletions?.("sp")?.map((item) => item.value),
["spec", "spec-verify"],
);
assert.deepEqual(
command.getArgumentCompletions?.("ed")?.map((item) => item.value),
["edit"],
);
assert.deepEqual(
command.getArgumentCompletions?.("bo")?.map((item) => item.value),
["book", "board"],
);
assert.equal(command.getArgumentCompletions?.("doctor"), null);
const notices: string[] = [];
await command.handler("", {
cwd: temp(),
waitForIdle: async () => {},
ui: { notify: (message: string) => notices.push(message) },
} as never);
assert.match(notices[0] ?? "", /\/system <subcommand>/);
});
it("opens the board directly through its runtime", async () => {
const project = temp();
validSystem(project);
const notices: string[] = [];
const command = createSystemCommand({ sendUserMessage() {} } as never, {
openBoard: async (cwd) => {
assert.equal(cwd, project);
return "System board running: http://127.0.0.1:1234";
},
});
await command.handler("board", {
cwd: project,
waitForIdle: async () => {},
ui: { notify: (message: string) => notices.push(message) },
} as never);
assert.match(notices[0] ?? "", /System board running/);
});
it("runs init directly after confirmation", async () => {
const project = temp();
const command = createSystemCommand({ sendUserMessage() {} } as never);
const notices: string[] = [];
await command.handler("init PX", {
cwd: project,
waitForIdle: async () => {},
ui: {
confirm: async () => true,
notify: (message: string) => notices.push(message),
},
} as never);
assert.match(notices[0] ?? "", /Initialized The System/);
assert.match(notices[0] ?? "", /\/reload to activate System format skills/);
assert.deepEqual(
JSON.parse(
readFileSync(path.join(project, ".system/config.json"), "utf8"),
),
{ prefix: "PX", schemaVersion: 0, title: path.basename(project) },
);
assert.match(
readFileSync(path.join(project, ".system/SYSTEM.md"), "utf8"),
/Stable project identity/,
);
});
it("updates machine schema mechanically, then offers agent bundle migration", async () => {
const project = temp();
validSystem(project);
write(
project,
".system/config.json",
'{"prefix":"PX","schemaVersion":4,"title":"Project"}',
);
const sent: string[] = [];
const confirmations: string[] = [];
let idle = false;
let migrations = 0;
const command = createSystemCommand(
{ sendUserMessage: (message: string) => sent.push(message) } as never,
{ activateBundleMigration: () => migrations++ },
);
await command.handler("init", {
cwd: project,
waitForIdle: async () => {
idle = true;
},
ui: {
confirm: async (title: string, summary: string) => {
confirmations.push(title);
if (title === "Initialize The System?")
assert.match(
summary,
/Update: \.system\/config\.json schemaVersion 4 -> 0/,
);
else assert.match(summary, /Machine schema updated mechanically/);
return true;
},
notify() {},
},
} as never);
assert.deepEqual(confirmations, [
"Initialize The System?",
"Should System bundles be migrated by agent?",
]);
assert.equal(idle, true);
assert.equal(migrations, 1);
assert.match(sent[0] ?? "", /# \/system init/);
assert.match(
sent[0] ?? "",
/Source: \.system\/config\.json schemaVersion 4 -> 0/,
);
assert.equal(
JSON.parse(
readFileSync(path.join(project, ".system/config.json"), "utf8"),
).schemaVersion,
0,
);
});
it("updates board schema without offering bundle migration", async () => {
const project = temp();
validSystem(project);
write(project, ".system/board.json", '{"schemaVersion":4,"items":{}}');
const sent: string[] = [];
const confirmations: string[] = [];
const command = createSystemCommand({
sendUserMessage: (message: string) => sent.push(message),
} as never);
await command.handler("init", {
cwd: project,
waitForIdle: async () => {},
ui: {
confirm: async (title: string) => {
confirmations.push(title);
return true;
},
notify() {},
},
} as never);
assert.deepEqual(confirmations, ["Initialize The System?"]);
assert.deepEqual(sent, []);
assert.equal(
JSON.parse(readFileSync(path.join(project, ".system/board.json"), "utf8"))
.schemaVersion,
0,
);
});
it("reuses existing prefix on init rerun", async () => {
const project = temp();
validSystem(project);
const notices: string[] = [];
const command = createSystemCommand({ sendUserMessage() {} } as never);
await command.handler("init", {
cwd: project,
waitForIdle: async () => {},
ui: {
input: async () => assert.fail("must not ask for prefix"),
confirm: async (_title: string, summary: string) => {
assert.match(summary, /Prefix: PX/);
return true;
},
notify: (message: string) => notices.push(message),
},
} as never);
assert.match(notices[0] ?? "", /Initialized The System/);
assert.doesNotMatch(notices[0] ?? "", /\/reload/);
});
it("waits for board activation before sending lifecycle prompts", async () => {
const project = temp();
validSystem(project);
const sent: string[] = [];
let release: (() => void) | undefined;
const activated = new Promise<void>((resolve) => {
release = resolve;
});
const command = createSystemCommand(
{
sendUserMessage: (message: string) => sent.push(message),
} as never,
{ activateBoardProposal: () => activated },
);
const pending = command.handler("assess", {
cwd: project,
ui: { notify() {} },
} as never);
await Promise.resolve();
assert.deepEqual(sent, []);
release?.();
await pending;
assert.equal(sent.length, 1);
});
it("injects lifecycle prompts and activates bundle allocation", async () => {
const project = temp();
validSystem(project);
const sent: string[] = [];
let activations = 0;
let proposalRuns = 0;
let updateRuns = 0;
const command = createSystemCommand(
{
sendUserMessage: (message: string) => sent.push(message),
} as never,
{
activateBundleTool: () => activations++,
activateBoardProposal: () => proposalRuns++,
activateBoardUpdate: () => updateRuns++,
},
);
for (const subcommand of [
"research",
"spec",
"spec-verify",
"assess",
"phase",
"plan",
"issue",
"exec",
])
for (const instruction of ["", "login flow"])
await command.handler(`${subcommand} ${instruction}`, {
cwd: project,
waitForIdle: async () =>
assert.fail("lifecycle command must not wait"),
ui: { notify() {} },
} as never);
for (const message of sent) {
assert.match(message, /The System document contract/);
assert.match(message, /# The System board state/);
assert.match(message, /PX-SPEC-SPEC0001 · Contract · todo · default/);
}
assert.equal(activations, 10);
assert.equal(proposalRuns, 2);
assert.equal(updateRuns, 2);
assert.doesNotMatch(sent.join("\n"), /Extension-generated bundle slot/);
const execPrompt =
sent.find((item) => item.includes("# /system exec")) ?? "";
assert.match(execPrompt, /spec\+plan/);
assert.match(execPrompt, /call system_board_update exactly once/);
assert.match(execPrompt, /The System board contract/);
assert.match(execPrompt, /recorded with source agent/);
const assessPrompt =
sent.find((item) => item.includes("# /system assess")) ?? "";
assert.match(
assessPrompt,
/Submit the assessment through system_board_propose/,
);
assert.doesNotMatch(assessPrompt, /empty items list/);
const phasePrompt =
sent.find((item) => item.includes("# /system phase\n")) ?? "";
assert.match(phasePrompt, /project-wide operating phase/);
assert.match(phasePrompt, /config currentPhase/);
assert.doesNotMatch(phasePrompt, /large specs/);
const specPrompt =
sent.find(
(item) =>
item.includes("# /system spec\n") && item.includes("login flow"),
) ?? "";
assert.match(specPrompt, /login flow/);
assert.match(specPrompt, /a prose-only spec is incomplete/);
assert.match(specPrompt, /Use mockups for visual elements/);
assert.match(specPrompt, /Persist accepted visual assets/);
assert.match(
specPrompt,
/required local dependencies inside the spec bundle/,
);
assert.match(
specPrompt,
/encode accepted feedback as behavior and constraints/,
);
assert.match(
sent.find((item) => item.endsWith("before writing.")) ?? "",
/No instructions were supplied/,
);
});
it("keeps print-mode lifecycle commands alive through the generated turn", async () => {
const order: string[] = [];
const command = createSystemCommand({
sendUserMessage: () => order.push("send"),
} as never);
await command.handler("spec explain only", {
cwd: temp(),
mode: "json",
waitForIdle: async () => {
order.push("settled");
},
ui: { notify() {} },
} as never);
assert.deepEqual(order, ["send", "settled"]);
});
it("runs doctor directly and renders rich browser view/book files", async () => {
const project = temp();
validSystem(project);
const command = createSystemCommand({ sendUserMessage() {} } as never);
const notices: string[] = [];
const severities: string[] = [];
let prompts = 0;
let widgets = 0;
const ctx = {
cwd: project,
hasUI: true,
waitForIdle: async () => {},
ui: {
confirm: async () => {
prompts += 1;
return true;
},
notify: (message: string, severity: string) => {
notices.push(message);
severities.push(severity);
},
setWidget: () => {
widgets += 1;
},
},
} as never;
await command.handler("doctor", ctx);
await command.handler("view PX-SPEC-SPEC0001", ctx);
await command.handler("book", ctx);
await command.handler("view PX-SPEC-SPEC0001 extra", ctx);
await command.handler("edit PX-SPEC-SPEC0001 extra", ctx);
assert.match(notices[0] ?? "", /OK/);
assert.equal(severities[0], "info");
assert.equal(prompts, 0);
assert.equal(widgets, 0);
assert.match(notices[1] ?? "", /System view written:/);
assert.match(notices[1] ?? "", /Open: file:\/\//);
assert.match(notices[2] ?? "", /System book written:/);
assert.match(notices[3] ?? "", /Usage: \/system view/);
assert.match(notices[4] ?? "", /Usage: \/system edit/);
const view = readFileSync(pathFromNotice(notices[1] ?? ""), "utf8");
const docs = readFileSync(pathFromNotice(notices[2] ?? ""), "utf8");
assert.match(view, /class="system-article"/);
assert.match(
view,
/<h1 id="PX-SPEC-SPEC0001-contract"><a href="#PX-SPEC-SPEC0001-contract">Contract<\/a><\/h1>/,
);
assert.match(view, /<summary>Metadata<\/summary>/);
assert.match(view, /nested/);
assert.doesNotMatch(view, /On this page/);
assert.match(view, /class="mermaid"/);
assert.match(view, /mjx-container/);
assert.match(view, /hljs/);
assert.match(
view,
/<iframe src="file:\/\/.*mockup-card\.html" loading="lazy" title="Interactive prototype"><\/iframe>/,
);
assert.doesNotMatch(view, /<iframe[^>]+sandbox/);
assert.match(
view,
/<img src="file:\/\/.*architecture\.svg" alt="Architecture diagram" loading="lazy">/,
);
assert.match(
view,
/<video controls preload="metadata"><source src="file:\/\/.*walkthrough\.webm">/,
);
assert.match(view, /href="file:\/\/.*notes\.md">Supporting notes<\/a>/);
assert.doesNotMatch(view, /notes\.html/);
assert.match(
view,
/An inline <a href="file:\/\/.*mockup-card\.html">prototype link<\/a> stays inline\./,
);
assert.match(view, /class="visual-asset-preview visual-asset-html"/);
assert.match(view, /class="visual-asset-preview visual-asset-image"/);
assert.match(view, /class="visual-asset-preview visual-asset-video"/);
assert.match(view, /<mark>raw<\/mark>/);
assert.match(docs, /the-system-command-.* Dossier/);
assert.match(docs, /<section id="PX-SPEC-SPEC0001" class="book-section">/);
assert.match(docs, /class="book-top"/);
assert.match(docs, /class="book-nav"/);
assert.match(docs, /class="mobile-nav"/);
assert.match(docs, /class="nav-utils"/);
assert.doesNotMatch(docs, /<aside class="book-toc"/);
assert.match(docs, /id="search"/);
assert.doesNotMatch(docs, /0 diagnostics/);
assert.match(docs, /rel="icon"/);
assert.match(docs, /data-search-hit/);
assert.match(docs, /MiniSearch/);
assert.doesNotMatch(view, /<nav class="doc-move"/);
assert.match(docs, /CORE-SYSTEM/);
assert.match(docs, /Reference graph/);
assert.match(docs, /System reference graph/);
assert.match(docs, /href="#PX-SPEC-SPEC0001"/);
assert.doesNotMatch(
docs,
/href="file:[^"]*PX-SPEC-SPEC0001[^"]*index\.html"/,
);
assert.match(docs, /data-graph-svg/);
assert.match(docs, /data-graph-zoom="reset"/);
assert.match(docs, /pointerdown/);
assert.match(docs, /wheel/);
assert.match(docs, /Backlinks/);
assert.match(docs, /Referenced by/);
assert.match(docs, /PX-PLAN-PLAN0001/);
assert.match(docs, /doc-related/);
assert.match(docs, /#ededed/);
assert.match(docs, /#121212/);
assert.match(docs, /prefers-color-scheme:dark/);
assert.match(docs, /PX-PHASE-PHASE001/);
assert.doesNotMatch(docs, /after PX-PHASE/);
assert.ok(
docs.indexOf('<section id="PX-PHASE-PHASE002"') <
docs.indexOf('<section id="PX-PHASE-PHASE001"'),
);
assert.ok(
docs.indexOf('<section id="PX-PHASE-PHASE001"') <
docs.indexOf('<section id="PX-SPEC-SPEC0001"'),
);
assert.ok(
docs.indexOf('<section id="PX-PLAN-PLAN0001"') <
docs.indexOf('<section id="PX-PLAN-PLAN0002"'),
);
assert.match(docs, /spec/);
assert.match(docs, /class="system-article"/);
});
it("opens documents in VISUAL, EDITOR, or a platform editor", async () => {
const project = temp();
validSystem(project);
const editor = path.join(project, "editor.cjs");
const log = path.join(project, "editor.log");
writeFileSync(
editor,
`const { writeFileSync } = require("node:fs"); writeFileSync(process.argv[2], process.argv.slice(3).join("\\n"));`,
"utf8",
);
chmodSync(editor, 0o755);
const previousVisual = process.env.VISUAL;
const previousEditor = process.env.EDITOR;
process.env.VISUAL = `${JSON.stringify(process.execPath)} ${JSON.stringify(editor)} ${JSON.stringify(log)}`;
delete process.env.EDITOR;
try {
const command = createSystemCommand({ sendUserMessage() {} } as never);
const notices: string[] = [];
await command.handler("edit contract", {
cwd: project,
waitForIdle: async () => {},
ui: { notify: (message: string) => notices.push(message) },
} as never);
assert.match(notices[0] ?? "", /System document opened:/);
assert.equal(
readFileSync(log, "utf8"),
path.join(project, ".system/specs/PX-SPEC-SPEC0001-contract/index.md"),
);
} finally {
if (previousVisual === undefined) delete process.env.VISUAL;
else process.env.VISUAL = previousVisual;
if (previousEditor === undefined) delete process.env.EDITOR;
else process.env.EDITOR = previousEditor;
}
});
});
describe("editor opening", () => {
it("parses quoted editor commands and falls back cross-platform", () => {
assert.deepEqual(parseEditorCommand('code --wait "two words"'), {
command: "code",
args: ["--wait", "two words"],
});
assert.deepEqual(
parseEditorCommand(
'"C:\\Program Files\\Editor\\edit.exe" "C:\\work tree\\file.md"',
),
{
command: "C:\\Program Files\\Editor\\edit.exe",
args: ["C:\\work tree\\file.md"],
},
);
assert.deepEqual(
editorCandidates("file.md", { VISUAL: "v", EDITOR: "e" }, "linux").slice(
0,
2,
),
[
{ command: "v", args: ["file.md"], wait: true },
{ command: "e", args: ["file.md"], wait: true },
],
);
assert.deepEqual(editorCandidates("file.md", {}, "win32").at(0), {
command: "notepad.exe",
args: ["file.md"],
wait: false,
});
assert.deepEqual(
editorCandidates("file.md", { TERMUX_VERSION: "0.118" }, "android").at(0),
{
command: "termux-open",
args: ["file.md"],
wait: false,
},
);
});
});
function pathFromNotice(notice: string): string {
const match = notice.match(/written: (.*)$/m);
assert.ok(match?.[1]);
return match[1];
}