@claudexor/cli 2.1.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accounts-projection.d.ts +26 -0
- package/dist/accounts-projection.d.ts.map +1 -0
- package/dist/accounts-projection.js +90 -0
- package/dist/accounts-projection.js.map +1 -0
- package/dist/acp-surface-runner.d.ts.map +1 -1
- package/dist/acp-surface-runner.js +12 -16
- package/dist/acp-surface-runner.js.map +1 -1
- package/dist/bridge-serve.d.ts +9 -0
- package/dist/bridge-serve.d.ts.map +1 -1
- package/dist/bridge-serve.js +20 -1
- package/dist/bridge-serve.js.map +1 -1
- package/dist/claude-oauth-usage.d.ts +8 -2
- package/dist/claude-oauth-usage.d.ts.map +1 -1
- package/dist/claude-oauth-usage.js +27 -12
- package/dist/claude-oauth-usage.js.map +1 -1
- package/dist/claude-statusline.d.ts +5 -2
- package/dist/claude-statusline.d.ts.map +1 -1
- package/dist/claude-statusline.js +4 -2
- package/dist/claude-statusline.js.map +1 -1
- package/dist/claudexord.d.ts +7 -1
- package/dist/claudexord.d.ts.map +1 -1
- package/dist/claudexord.js +116 -19
- package/dist/claudexord.js.map +1 -1
- package/dist/cli.js +105 -276
- package/dist/cli.js.map +1 -1
- package/dist/codex-quota-source.d.ts +9 -3
- package/dist/codex-quota-source.d.ts.map +1 -1
- package/dist/codex-quota-source.js +82 -9
- package/dist/codex-quota-source.js.map +1 -1
- package/dist/command-flags.d.ts +1 -1
- package/dist/command-flags.d.ts.map +1 -1
- package/dist/command-flags.js +8 -9
- package/dist/command-flags.js.map +1 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +19 -54
- package/dist/command-registry.js.map +1 -1
- package/dist/control-services.d.ts +163 -356
- package/dist/control-services.d.ts.map +1 -1
- package/dist/control-services.js +80 -126
- package/dist/control-services.js.map +1 -1
- package/dist/credential-commands.d.ts.map +1 -1
- package/dist/credential-commands.js +70 -8
- package/dist/credential-commands.js.map +1 -1
- package/dist/daemon-run.d.ts +49 -7
- package/dist/daemon-run.d.ts.map +1 -1
- package/dist/daemon-run.js +152 -30
- package/dist/daemon-run.js.map +1 -1
- package/dist/decision.js +2 -2
- package/dist/decision.js.map +1 -1
- package/dist/delegation-belt-descriptor.d.ts +43 -0
- package/dist/delegation-belt-descriptor.d.ts.map +1 -0
- package/dist/delegation-belt-descriptor.js +75 -0
- package/dist/delegation-belt-descriptor.js.map +1 -0
- package/dist/live.d.ts +5 -2
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +29 -12
- package/dist/live.js.map +1 -1
- package/dist/mcp-runner.d.ts.map +1 -1
- package/dist/mcp-runner.js +44 -20
- package/dist/mcp-runner.js.map +1 -1
- package/dist/plan-question-loop.d.ts +46 -0
- package/dist/plan-question-loop.d.ts.map +1 -0
- package/dist/plan-question-loop.js +149 -0
- package/dist/plan-question-loop.js.map +1 -0
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +1 -3
- package/dist/plugins.js.map +1 -1
- package/dist/primary-output.d.ts.map +1 -1
- package/dist/primary-output.js +9 -17
- package/dist/primary-output.js.map +1 -1
- package/dist/profile-registration.d.ts.map +1 -1
- package/dist/profile-registration.js +16 -0
- package/dist/profile-registration.js.map +1 -1
- package/dist/project-command.d.ts.map +1 -1
- package/dist/project-command.js +41 -2
- package/dist/project-command.js.map +1 -1
- package/dist/quota-command.js +8 -1
- package/dist/quota-command.js.map +1 -1
- package/dist/release-command.d.ts +12 -0
- package/dist/release-command.d.ts.map +1 -0
- package/dist/release-command.js +70 -0
- package/dist/release-command.js.map +1 -0
- package/dist/release.d.ts +59 -0
- package/dist/release.d.ts.map +1 -1
- package/dist/release.js +181 -0
- package/dist/release.js.map +1 -1
- package/dist/repl.d.ts +4 -3
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +27 -4
- package/dist/repl.js.map +1 -1
- package/dist/request-preflight.d.ts.map +1 -1
- package/dist/request-preflight.js +0 -2
- package/dist/request-preflight.js.map +1 -1
- package/dist/retention-service.d.ts.map +1 -1
- package/dist/retention-service.js +21 -0
- package/dist/retention-service.js.map +1 -1
- package/dist/settings-command.d.ts +38 -0
- package/dist/settings-command.d.ts.map +1 -1
- package/dist/settings-command.js +97 -15
- package/dist/settings-command.js.map +1 -1
- package/dist/settings-service.d.ts +5 -5
- package/dist/settings-service.d.ts.map +1 -1
- package/dist/settings-service.js +4 -1
- package/dist/settings-service.js.map +1 -1
- package/dist/setup-job-store.d.ts +9 -9
- package/dist/setup-job-store.d.ts.map +1 -1
- package/dist/setup-jobs.d.ts +13 -13
- package/dist/setup-jobs.d.ts.map +1 -1
- package/dist/thread-select.d.ts +6 -2
- package/dist/thread-select.d.ts.map +1 -1
- package/dist/thread-select.js +20 -3
- package/dist/thread-select.js.map +1 -1
- package/package.json +23 -24
- package/dist/orchestrate-options.d.ts +0 -9
- package/dist/orchestrate-options.d.ts.map +0 -1
- package/dist/orchestrate-options.js +0 -16
- package/dist/orchestrate-options.js.map +0 -1
- package/dist/spec-thread-scope.d.ts +0 -3
- package/dist/spec-thread-scope.d.ts.map +0 -1
- package/dist/spec-thread-scope.js +0 -9
- package/dist/spec-thread-scope.js.map +0 -1
- package/dist/spec.d.ts +0 -73
- package/dist/spec.d.ts.map +0 -1
- package/dist/spec.js +0 -466
- package/dist/spec.js.map +0 -1
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { OrchestrateAutonomy, } from "@claudexor/schema";
|
|
2
|
-
/**
|
|
3
|
-
* Parse `--autonomy <suggest|auto_safe|auto_full>` into the typed
|
|
4
|
-
* OrchestrateAutonomy. An invalid value FAILS LOUDLY (a typo must never silently
|
|
5
|
-
* fall back to `suggest` and skip the execution the user asked for). Returns
|
|
6
|
-
* undefined when the flag is absent (the daemon/orchestrator default to suggest).
|
|
7
|
-
*/
|
|
8
|
-
export function parseAutonomy(value) {
|
|
9
|
-
if (value === undefined)
|
|
10
|
-
return undefined;
|
|
11
|
-
const parsed = OrchestrateAutonomy.safeParse(value);
|
|
12
|
-
if (!parsed.success)
|
|
13
|
-
throw new Error(`invalid --autonomy '${value}' (expected suggest|auto_safe|auto_full)`);
|
|
14
|
-
return parsed.data;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=orchestrate-options.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrate-options.js","sourceRoot":"","sources":["../src/orchestrate-options.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAEpB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,CAAC,OAAO;QACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,0CAA0C,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec-thread-scope.d.ts","sourceRoot":"","sources":["../src/spec-thread-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export function assertSpecThreadScope(thread, threadId, projectRoot) {
|
|
2
|
-
if (!thread) {
|
|
3
|
-
throw Object.assign(new Error(`no such thread: ${threadId}`), { status: 404 });
|
|
4
|
-
}
|
|
5
|
-
if (thread.repo?.root !== projectRoot) {
|
|
6
|
-
throw Object.assign(new Error("spec session threadId does not belong to the requested project scope"), { status: 400 });
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=spec-thread-scope.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec-thread-scope.js","sourceRoot":"","sources":["../src/spec-thread-scope.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,MAA0B,EAC1B,QAAgB,EAChB,WAAmB;IAEnB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;QACtC,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,sEAAsE,CAAC,EACjF,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/spec.d.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { type SpecDraft, type SpecFieldChange } from "@claudexor/interview";
|
|
2
|
-
import { type InterviewAnswer, type InterviewQuestion, type SpecPack, type TestCommandInvocation } from "@claudexor/schema";
|
|
3
|
-
export interface SpecAnswersFile {
|
|
4
|
-
/** Durable daemon session that owns the questions and grounding plan. */
|
|
5
|
-
sessionId?: string;
|
|
6
|
-
answers: InterviewAnswer[];
|
|
7
|
-
questions?: InterviewQuestion[];
|
|
8
|
-
priorDecisions?: PriorDecision[];
|
|
9
|
-
summary?: string;
|
|
10
|
-
success_criteria?: string[];
|
|
11
|
-
non_goals?: string[];
|
|
12
|
-
forbidden_approaches?: string[];
|
|
13
|
-
decided_tradeoffs?: string[];
|
|
14
|
-
tests?: TestCommandInvocation[];
|
|
15
|
-
}
|
|
16
|
-
export interface LoadedFrozenSpec {
|
|
17
|
-
spec: SpecPack;
|
|
18
|
-
specPath: string;
|
|
19
|
-
specHash: string;
|
|
20
|
-
}
|
|
21
|
-
export declare function loadFrozenSpec(path: string): LoadedFrozenSpec;
|
|
22
|
-
export declare function resolveRunTestCommands(cliTests: TestCommandInvocation[] | undefined, spec: SpecPack | null): TestCommandInvocation[] | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* The grounding-plan instruction that DRIVES extractQuestionsFromPlan: it tells the
|
|
25
|
-
* harness to end its read-only plan with a structured `## Open Questions` block in
|
|
26
|
-
* the exact format the parser below understands. Kept HERE, beside its parser, so the
|
|
27
|
-
* producer instruction and consumer stay a co-located contract pair (the daemon
|
|
28
|
-
* surface just calls this — Bible §1: surfaces stay thin).
|
|
29
|
-
*/
|
|
30
|
-
/** One already-answered decision, carried into a follow-up tier so the interview
|
|
31
|
-
* goes DEEPER instead of re-asking. */
|
|
32
|
-
export interface PriorDecision {
|
|
33
|
-
question: string;
|
|
34
|
-
answer: string;
|
|
35
|
-
}
|
|
36
|
-
export declare function buildGroundingPrompt(prompt: string, priorDecisions?: PriorDecision[]): string;
|
|
37
|
-
/**
|
|
38
|
-
* Parse the grounding plan's "Open Questions" section into an interactive interview.
|
|
39
|
-
*
|
|
40
|
-
* The grounding prompt (see claudexord.specQuestions) asks the harness to end its
|
|
41
|
-
* plan with an `## Open Questions` section, one bullet per decision, in the format:
|
|
42
|
-
*
|
|
43
|
-
* - [single] Which auth flow? :: OAuth :: API key :: Both
|
|
44
|
-
* - [multi] Which platforms? :: iOS :: Android :: Web
|
|
45
|
-
* - [text] Any naming constraints?
|
|
46
|
-
*
|
|
47
|
-
* `[single|multi|text]` is the answer kind; `::` separates the question from each
|
|
48
|
-
* option. Parsing is TOLERANT so the quiz degrades gracefully and old plans still
|
|
49
|
-
* work: an untagged bullet with no `::` becomes a free-text question (the previous
|
|
50
|
-
* behavior); an untagged bullet WITH options defaults to single-choice; a tagged
|
|
51
|
-
* choice question with no options falls back to text. `(none)` is skipped. This is
|
|
52
|
-
* plain delimiter parsing of the harness's own structured output (a data shape we
|
|
53
|
-
* instructed), not a governance signal — it does not infer risk/success/etc.
|
|
54
|
-
*/
|
|
55
|
-
export declare function extractQuestionsFromPlan(plan: string): InterviewQuestion[];
|
|
56
|
-
export declare function readAnswers(path: string): SpecAnswersFile;
|
|
57
|
-
export declare function draftFromPlanAndAnswers(prompt: string, plan: string, questions: InterviewQuestion[], file: SpecAnswersFile): SpecDraft;
|
|
58
|
-
/**
|
|
59
|
-
* Validate submitted answers against the question contract BEFORE freezing — fail
|
|
60
|
-
* loudly (Bible §5: no silent guessing) rather than freeze a malformed SpecPack.
|
|
61
|
-
* Rejects an answer for an unknown question id, unknown option ids, more than one
|
|
62
|
-
* option on a single-choice question, and free text where the question disallows it.
|
|
63
|
-
*/
|
|
64
|
-
export declare function validateAnswers(questions: InterviewQuestion[], answers: InterviewAnswer[]): void;
|
|
65
|
-
export declare function freezeSpecFromGrounding(prompt: string, plan: string, answers: SpecAnswersFile): Promise<SpecPack>;
|
|
66
|
-
export declare function persistSpec(repoRoot: string, spec: SpecPack, plan: string, previous?: SpecPack | null): ReturnType<typeof persistSpecAt>;
|
|
67
|
-
/** Persist a runnable immutable projection outside the user repository. */
|
|
68
|
-
export declare function persistSpecAt(specsRoot: string, spec: SpecPack, plan: string, previous?: SpecPack | null): {
|
|
69
|
-
specDir: string;
|
|
70
|
-
specHash: string;
|
|
71
|
-
changes: SpecFieldChange[];
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=spec.d.ts.map
|
package/dist/spec.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,eAAe,EAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,qBAAqB,EAE3B,MAAM,mBAAmB,CAAC;AAW3B,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAqC7D;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,qBAAqB,EAAE,GAAG,SAAS,EAC7C,IAAI,EAAE,QAAQ,GAAG,IAAI,GACpB,qBAAqB,EAAE,GAAG,SAAS,CAUrC;AAED;;;;;;GAMG;AACH;wCACwC;AACxC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,GAAE,aAAa,EAAO,GAAG,MAAM,CAmCjG;AAqCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA0D1E;AAoED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAQzD;AAmBD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,iBAAiB,EAAE,EAC9B,IAAI,EAAE,eAAe,GACpB,SAAS,CA0DX;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAwBhG;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CAenB;AAyCD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,GACzB,UAAU,CAAC,OAAO,aAAa,CAAC,CAElC;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,GACzB;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAwBA"}
|
package/dist/spec.js
DELETED
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
import { readFileSync, realpathSync, renameSync, rmSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { ArtifactStore } from "@claudexor/artifact-store";
|
|
4
|
-
import { InterviewEngine, diffSpecPacks, } from "@claudexor/interview";
|
|
5
|
-
import { SpecPack as SpecPackSchema, } from "@claudexor/schema";
|
|
6
|
-
import { assertNoInlineSecretValues, ensureDir, hashJson, readJsonSafe, redactSecrets, writeJson, writeText, } from "@claudexor/util";
|
|
7
|
-
const INTERVIEW_KINDS = new Set(["single", "multi", "text"]);
|
|
8
|
-
export function loadFrozenSpec(path) {
|
|
9
|
-
let raw;
|
|
10
|
-
try {
|
|
11
|
-
raw = readFileSync(path, "utf8");
|
|
12
|
-
}
|
|
13
|
-
catch (err) {
|
|
14
|
-
throw new Error(`cannot read --spec '${path}': ${err instanceof Error ? err.message : String(err)}`);
|
|
15
|
-
}
|
|
16
|
-
let parsed;
|
|
17
|
-
try {
|
|
18
|
-
parsed = JSON.parse(raw);
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
throw new Error(`invalid --spec '${path}' JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
22
|
-
}
|
|
23
|
-
const result = SpecPackSchema.safeParse(parsed);
|
|
24
|
-
if (!result.success) {
|
|
25
|
-
const issue = result.error.issues[0];
|
|
26
|
-
const where = issue?.path.length ? issue.path.join(".") : "root";
|
|
27
|
-
const what = issue?.message ?? "schema validation failed";
|
|
28
|
-
throw new Error(`invalid --spec '${path}' schema at ${where}: ${what}`);
|
|
29
|
-
}
|
|
30
|
-
let resolved;
|
|
31
|
-
try {
|
|
32
|
-
resolved = realpathSync(path);
|
|
33
|
-
}
|
|
34
|
-
catch (err) {
|
|
35
|
-
throw new Error(`cannot resolve --spec '${path}': ${err instanceof Error ? err.message : String(err)}`);
|
|
36
|
-
}
|
|
37
|
-
return { spec: result.data, specPath: resolved, specHash: hashJson(result.data) };
|
|
38
|
-
}
|
|
39
|
-
export function resolveRunTestCommands(cliTests, spec) {
|
|
40
|
-
if (cliTests && cliTests.length > 0)
|
|
41
|
-
return cliTests;
|
|
42
|
-
const specTests = spec?.tests.map(({ program, args, cwd, envAllowlist }) => ({
|
|
43
|
-
program,
|
|
44
|
-
args,
|
|
45
|
-
...(cwd === undefined ? {} : { cwd }),
|
|
46
|
-
envAllowlist,
|
|
47
|
-
})) ?? [];
|
|
48
|
-
return specTests.length > 0 ? specTests : undefined;
|
|
49
|
-
}
|
|
50
|
-
export function buildGroundingPrompt(prompt, priorDecisions = []) {
|
|
51
|
-
const deeper = priorDecisions.length > 0;
|
|
52
|
-
const priorSection = deeper
|
|
53
|
-
? `\n\nDECISIONS ALREADY MADE (the user answered these — do NOT re-ask them; treat them as fixed and surface the NEXT, deeper layer of decisions these answers unlock):\n${priorDecisions
|
|
54
|
-
.map((d) => `- ${d.question} => ${d.answer}`)
|
|
55
|
-
.join("\n")}`
|
|
56
|
-
: "";
|
|
57
|
-
const countLine = deeper
|
|
58
|
-
? "List the next 3–6 DEEPER open decisions that the answers above now make relevant"
|
|
59
|
-
: "List 4–8 of the MOST important open decisions";
|
|
60
|
-
const noneLine = deeper
|
|
61
|
-
? "If the spec is now unambiguous and there are genuinely no FURTHER open decisions, write a single bullet: - (none)"
|
|
62
|
-
: "If there are genuinely no open decisions, write a single bullet: - (none)";
|
|
63
|
-
return `${prompt}${priorSection}
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
GROUNDING INSTRUCTION (for Claudexor's spec interview — do this in addition to your plan):
|
|
67
|
-
Identify the material decisions a developer must make BEFORE implementing this${deeper ? ", GIVEN the decisions already made above" : ""}, then
|
|
68
|
-
end your response with a section titled exactly:
|
|
69
|
-
|
|
70
|
-
## Open Questions
|
|
71
|
-
|
|
72
|
-
${countLine}, one per bullet, in EXACTLY this format:
|
|
73
|
-
|
|
74
|
-
- [single] <question> :: <option A> :: <option B> :: <option C>
|
|
75
|
-
- [multi] <question> :: <option A> :: <option B> :: <option C>
|
|
76
|
-
- [text] <question that has no good fixed options>
|
|
77
|
-
|
|
78
|
-
Rules:
|
|
79
|
-
- [single] = pick exactly one; [multi] = pick one or more; [text] = free-form (no "::" options).
|
|
80
|
-
- For [single], make options MUTUALLY EXCLUSIVE; for [multi], make options concrete
|
|
81
|
-
INDEPENDENT selections that can be combined. Ground every option in THIS repository.
|
|
82
|
-
- Prefer [single]/[multi] with real options over [text] whenever sensible choices exist.
|
|
83
|
-
- Do NOT repeat any decision already made above; each question must open NEW ground.
|
|
84
|
-
- ${noneLine}`;
|
|
85
|
-
}
|
|
86
|
-
/** A real markdown ATX heading: 1–6 leading `#` then a space. Used as the
|
|
87
|
-
* open-questions block terminator so an inline `#`-prefixed bullet body (e.g. a
|
|
88
|
-
* shell `#comment`) does not cut the block short. */
|
|
89
|
-
function isMarkdownHeading(line) {
|
|
90
|
-
let i = 0;
|
|
91
|
-
while (i < line.length && line[i] === "#")
|
|
92
|
-
i++;
|
|
93
|
-
return i >= 1 && i <= 6 && line[i] === " ";
|
|
94
|
-
}
|
|
95
|
-
function markdownHeadingText(line) {
|
|
96
|
-
let i = 0;
|
|
97
|
-
while (i < line.length && line[i] === "#")
|
|
98
|
-
i++;
|
|
99
|
-
return line
|
|
100
|
-
.slice(i)
|
|
101
|
-
.trim()
|
|
102
|
-
.replace(/\s+#+\s*$/, "");
|
|
103
|
-
}
|
|
104
|
-
/** A "no open decisions" sentinel bullet body, e.g. `(none)` / `(none — ...)`. */
|
|
105
|
-
function isNoneBullet(body) {
|
|
106
|
-
return !body || body.toLowerCase().startsWith("(none");
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* A leaked grounding-prompt format placeholder — ONLY the exact templates this
|
|
110
|
-
* module's buildGroundingPrompt emits (`<question>`, `<question that ...>`,
|
|
111
|
-
* `<option A>`…). Narrow on purpose so legitimate angle-bracket options a harness
|
|
112
|
-
* may produce (e.g. `<stdio.h>`, `<Button>`, `<input>`) are NOT dropped.
|
|
113
|
-
*/
|
|
114
|
-
function isPlaceholder(text) {
|
|
115
|
-
const t = text.trim().toLowerCase();
|
|
116
|
-
if (t === "<question>" || t === "<question that has no good fixed options>")
|
|
117
|
-
return true;
|
|
118
|
-
return t.startsWith("<option ") && t.endsWith(">");
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Parse the grounding plan's "Open Questions" section into an interactive interview.
|
|
122
|
-
*
|
|
123
|
-
* The grounding prompt (see claudexord.specQuestions) asks the harness to end its
|
|
124
|
-
* plan with an `## Open Questions` section, one bullet per decision, in the format:
|
|
125
|
-
*
|
|
126
|
-
* - [single] Which auth flow? :: OAuth :: API key :: Both
|
|
127
|
-
* - [multi] Which platforms? :: iOS :: Android :: Web
|
|
128
|
-
* - [text] Any naming constraints?
|
|
129
|
-
*
|
|
130
|
-
* `[single|multi|text]` is the answer kind; `::` separates the question from each
|
|
131
|
-
* option. Parsing is TOLERANT so the quiz degrades gracefully and old plans still
|
|
132
|
-
* work: an untagged bullet with no `::` becomes a free-text question (the previous
|
|
133
|
-
* behavior); an untagged bullet WITH options defaults to single-choice; a tagged
|
|
134
|
-
* choice question with no options falls back to text. `(none)` is skipped. This is
|
|
135
|
-
* plain delimiter parsing of the harness's own structured output (a data shape we
|
|
136
|
-
* instructed), not a governance signal — it does not infer risk/success/etc.
|
|
137
|
-
*/
|
|
138
|
-
export function extractQuestionsFromPlan(plan) {
|
|
139
|
-
const lines = plan.split("\n");
|
|
140
|
-
// A grounding plan can contain SEVERAL "open questions" headings:
|
|
141
|
-
// 1. the echoed grounding INSTRUCTION (placeholder template + "Rules:"),
|
|
142
|
-
// 2. the harness's REAL interview section (what we want),
|
|
143
|
-
// 3. an orchestrator-appended REVIEW-findings "Open questions" (e.g. a
|
|
144
|
-
// NEEDS_HUMAN patch-identity error) — NOT interview questions.
|
|
145
|
-
// So we can't take the first or the last block. Parse EVERY block and pick the
|
|
146
|
-
// one with the most STRUCTURED (tagged single/multi) questions; the echoed
|
|
147
|
-
// instruction block is skipped outright by its signature. (Heading match is a
|
|
148
|
-
// REAL markdown heading whose text mentions the section, so a stray
|
|
149
|
-
// `#open questions` non-heading line can't start a block.)
|
|
150
|
-
const blocks = [];
|
|
151
|
-
let afterReviewFindings = false;
|
|
152
|
-
for (let i = 0; i < lines.length; i++) {
|
|
153
|
-
const t = (lines[i] ?? "").trim();
|
|
154
|
-
if (!isMarkdownHeading(t))
|
|
155
|
-
continue;
|
|
156
|
-
const heading = markdownHeadingText(t).toLowerCase();
|
|
157
|
-
if (!heading.includes("open questions")) {
|
|
158
|
-
afterReviewFindings ||= heading.includes("review findings");
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
const blockLines = [];
|
|
162
|
-
for (const raw of lines.slice(i + 1)) {
|
|
163
|
-
if (isMarkdownHeading(raw.trim()))
|
|
164
|
-
break; // next real heading ends the block
|
|
165
|
-
blockLines.push(raw);
|
|
166
|
-
}
|
|
167
|
-
// Skip the echoed grounding instruction itself (it carries the format spec, not
|
|
168
|
-
// real questions). Its placeholder bullets would be dropped anyway, but the
|
|
169
|
-
// "Rules:" lines could otherwise parse as junk questions.
|
|
170
|
-
if (blockLines.some((l) => {
|
|
171
|
-
const low = l.toLowerCase();
|
|
172
|
-
return (low.includes("in exactly this format") || low.includes("[single] = pick exactly one"));
|
|
173
|
-
}))
|
|
174
|
-
continue;
|
|
175
|
-
blocks.push({ questions: parseQuestionBullets(blockLines), afterReviewFindings });
|
|
176
|
-
}
|
|
177
|
-
// Best block: most tagged (single/multi) questions, tie-broken by total count.
|
|
178
|
-
// Prefer blocks before a review-findings section so a legacy free-text interview
|
|
179
|
-
// is not displaced by an appended review error block.
|
|
180
|
-
let best = [];
|
|
181
|
-
let bestScore = [-1, -1];
|
|
182
|
-
const candidates = blocks.some((b) => !b.afterReviewFindings)
|
|
183
|
-
? blocks.filter((b) => !b.afterReviewFindings)
|
|
184
|
-
: blocks;
|
|
185
|
-
for (const { questions: qs } of candidates) {
|
|
186
|
-
const tagged = qs.filter((q) => q.kind === "single" || q.kind === "multi").length;
|
|
187
|
-
const score = [tagged, qs.length];
|
|
188
|
-
if (score[0] > bestScore[0] || (score[0] === bestScore[0] && score[1] > bestScore[1])) {
|
|
189
|
-
bestScore = score;
|
|
190
|
-
best = qs;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return best;
|
|
194
|
-
}
|
|
195
|
-
/** Parse the bullets of ONE "open questions" block into interview questions. */
|
|
196
|
-
function parseQuestionBullets(blockLines) {
|
|
197
|
-
const questions = [];
|
|
198
|
-
for (const raw of blockLines) {
|
|
199
|
-
const line = raw.trim();
|
|
200
|
-
if (!line.startsWith("- ") && !line.startsWith("* "))
|
|
201
|
-
continue;
|
|
202
|
-
let body = line.slice(2).trim();
|
|
203
|
-
if (isNoneBullet(body))
|
|
204
|
-
continue;
|
|
205
|
-
// Optional leading kind tag: [single] | [multi] | [text].
|
|
206
|
-
let kind = "text";
|
|
207
|
-
let kindTagged = false;
|
|
208
|
-
if (body.startsWith("[")) {
|
|
209
|
-
const close = body.indexOf("]");
|
|
210
|
-
if (close > 0) {
|
|
211
|
-
const tag = body.slice(1, close).trim().toLowerCase();
|
|
212
|
-
if (INTERVIEW_KINDS.has(tag)) {
|
|
213
|
-
kind = tag;
|
|
214
|
-
kindTagged = true;
|
|
215
|
-
body = body.slice(close + 1).trim();
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
// Re-check after stripping the tag: `- [text] (none)` must still skip.
|
|
220
|
-
if (isNoneBullet(body))
|
|
221
|
-
continue;
|
|
222
|
-
// "question :: optA :: optB" — `::` separates the prompt from each option.
|
|
223
|
-
// Only treat `::` as an option delimiter when the bullet is TAGGED, or has 2+
|
|
224
|
-
// option segments (a real choice). An untagged legacy bullet with a single `::`
|
|
225
|
-
// (e.g. prose "Session store :: Redis vs Postgres?") is kept as ONE free-text
|
|
226
|
-
// question, not silently turned into a 1-option choice.
|
|
227
|
-
const segments = body
|
|
228
|
-
.split("::")
|
|
229
|
-
.map((p) => p.trim())
|
|
230
|
-
.filter((p) => p.length > 0);
|
|
231
|
-
const splitAsChoice = kindTagged ? segments.length > 1 : segments.length >= 3;
|
|
232
|
-
const promptText = splitAsChoice ? (segments[0] ?? "") : body;
|
|
233
|
-
if (!promptText)
|
|
234
|
-
continue;
|
|
235
|
-
// Skip the prompt's own format example if it ever leaks through (a pure
|
|
236
|
-
// angle-bracket placeholder like "<question>"), so the user never sees template text.
|
|
237
|
-
if (isPlaceholder(promptText))
|
|
238
|
-
continue;
|
|
239
|
-
// Drop any leaked template placeholder option labels (e.g. "<option A>") so a
|
|
240
|
-
// partially-echoed bullet can't show "<option A>" chips. If that empties a choice
|
|
241
|
-
// question's options, the normalization below degrades it to free text.
|
|
242
|
-
const options = (splitAsChoice ? segments.slice(1) : [])
|
|
243
|
-
.filter((label) => !isPlaceholder(label))
|
|
244
|
-
.map((label, i) => ({ id: `o${i + 1}`, label }));
|
|
245
|
-
// Untagged: choice when options were given, else free text. A choice with no
|
|
246
|
-
// options can't be picked, so degrade to text.
|
|
247
|
-
if (!kindTagged)
|
|
248
|
-
kind = options.length > 0 ? "single" : "text";
|
|
249
|
-
if (kind !== "text" && options.length === 0)
|
|
250
|
-
kind = "text";
|
|
251
|
-
// Normalize: text questions are free-form (NO options, accept free text);
|
|
252
|
-
// choice questions are choice-only. Keyed off the final kind so a tagged
|
|
253
|
-
// `[text] ... :: A :: B` can't end up unanswerable (options + allow_text:false).
|
|
254
|
-
const isText = kind === "text";
|
|
255
|
-
questions.push({
|
|
256
|
-
id: `q${questions.length + 1}`,
|
|
257
|
-
tier: 0,
|
|
258
|
-
prompt: promptText,
|
|
259
|
-
kind,
|
|
260
|
-
options: isText ? [] : options,
|
|
261
|
-
allow_text: isText,
|
|
262
|
-
rationale: "Surfaced by the grounding plan's open-questions interview.",
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
return questions;
|
|
266
|
-
}
|
|
267
|
-
export function readAnswers(path) {
|
|
268
|
-
const parsed = readJsonSafe(path);
|
|
269
|
-
if (!parsed)
|
|
270
|
-
throw new Error(`could not parse answers JSON: ${path}`);
|
|
271
|
-
// Same fence as the daemon spec endpoints: answers become part of the
|
|
272
|
-
// durable SpecPack, so secret-like values are refused at ingestion.
|
|
273
|
-
assertNoInlineSecretValues(parsed, "$", "spec answers file");
|
|
274
|
-
if (Array.isArray(parsed))
|
|
275
|
-
return { answers: parsed };
|
|
276
|
-
return { ...parsed, answers: parsed.answers ?? [] };
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* The resolved answer for a question, or null when genuinely unanswered. Counts
|
|
280
|
-
* BOTH selected option_ids (resolved to their labels) and free text — so a
|
|
281
|
-
* choice question answered only via chips (text: null) is NOT treated as missing.
|
|
282
|
-
* Without this, single/multi answers would freeze as unresolved clarifications.
|
|
283
|
-
*/
|
|
284
|
-
function answerText(q, answers) {
|
|
285
|
-
const a = answers.find((x) => x.question_id === q.id);
|
|
286
|
-
if (!a)
|
|
287
|
-
return null;
|
|
288
|
-
const labels = (a.option_ids ?? [])
|
|
289
|
-
.map((id) => q.options.find((o) => o.id === id)?.label)
|
|
290
|
-
.filter((l) => typeof l === "string" && l.length > 0);
|
|
291
|
-
const text = a.text?.trim();
|
|
292
|
-
const parts = text ? [...labels, text] : labels;
|
|
293
|
-
return parts.length > 0 ? parts.join(", ") : null;
|
|
294
|
-
}
|
|
295
|
-
export function draftFromPlanAndAnswers(prompt, plan, questions, file) {
|
|
296
|
-
// Resolve each interview question to its answer (selected option labels + free
|
|
297
|
-
// text), or null when unanswered. RECORD the resolved decisions in the frozen
|
|
298
|
-
// SpecPack — both structurally (open_questions: status resolved + resolution) and
|
|
299
|
-
// human-readably (decided_tradeoffs) — so an Implement run that reads `specPath`
|
|
300
|
-
// knows exactly what the user chose. Unanswered questions stay `open`, which makes
|
|
301
|
-
// freeze fail loudly (a frozen SpecPack cannot carry open clarifications).
|
|
302
|
-
const resolved = questions
|
|
303
|
-
.map((q) => ({ q, answer: answerText(q, file.answers) }))
|
|
304
|
-
.filter((x) => x.answer !== null);
|
|
305
|
-
return {
|
|
306
|
-
summary: file.summary ?? `Spec for: ${prompt}`,
|
|
307
|
-
success_criteria: (file.success_criteria ?? []).map((text, i) => ({
|
|
308
|
-
id: `ac${i + 1}`,
|
|
309
|
-
behavior: text,
|
|
310
|
-
required: true,
|
|
311
|
-
})),
|
|
312
|
-
non_goals: file.non_goals ?? [],
|
|
313
|
-
forbidden_approaches: file.forbidden_approaches ?? [],
|
|
314
|
-
decided_tradeoffs: [
|
|
315
|
-
...(file.decided_tradeoffs ?? []),
|
|
316
|
-
// Provenance lines kept first (stable position) — interview decisions follow.
|
|
317
|
-
"Grounding came from Claudexor plan mode: multi-harness read-only planning plus cross-family plan review.",
|
|
318
|
-
`Plan grounding hash: ${hashJson({ plan })}`,
|
|
319
|
-
...resolved.map(({ q, answer }) => `Interview — ${q.prompt} → ${answer}`),
|
|
320
|
-
],
|
|
321
|
-
tests: (file.tests ?? []).map((command, i) => ({
|
|
322
|
-
id: `gate-${i + 1}`,
|
|
323
|
-
...command,
|
|
324
|
-
required: true,
|
|
325
|
-
trust_required: false,
|
|
326
|
-
trust_grant: null,
|
|
327
|
-
})),
|
|
328
|
-
tasks: [
|
|
329
|
-
{ id: "task-1", title: "Implement against the frozen SpecPack", depends_on: [], done: false },
|
|
330
|
-
{
|
|
331
|
-
id: "task-2",
|
|
332
|
-
title: "Run deterministic gates and cross-family review",
|
|
333
|
-
depends_on: ["task-1"],
|
|
334
|
-
done: false,
|
|
335
|
-
},
|
|
336
|
-
],
|
|
337
|
-
clarifications: questions.map((q) => {
|
|
338
|
-
const answer = answerText(q, file.answers);
|
|
339
|
-
return {
|
|
340
|
-
id: `clarify-${q.id}`,
|
|
341
|
-
claim: q.prompt,
|
|
342
|
-
status: answer ? "resolved" : "open",
|
|
343
|
-
resolution: answer,
|
|
344
|
-
};
|
|
345
|
-
}),
|
|
346
|
-
// The plan grounding hash lives in decided_tradeoffs (above); native exports
|
|
347
|
-
// carry the full plan text. Protected-path approvals are explicit run input,
|
|
348
|
-
// never inferred from interview prose, so frozen specs cannot contain them.
|
|
349
|
-
constraints: {
|
|
350
|
-
protected_paths: [],
|
|
351
|
-
},
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Validate submitted answers against the question contract BEFORE freezing — fail
|
|
356
|
-
* loudly (Bible §5: no silent guessing) rather than freeze a malformed SpecPack.
|
|
357
|
-
* Rejects an answer for an unknown question id, unknown option ids, more than one
|
|
358
|
-
* option on a single-choice question, and free text where the question disallows it.
|
|
359
|
-
*/
|
|
360
|
-
export function validateAnswers(questions, answers) {
|
|
361
|
-
const byId = new Map(questions.map((q) => [q.id, q]));
|
|
362
|
-
const seen = new Set();
|
|
363
|
-
for (const a of answers) {
|
|
364
|
-
if (seen.has(a.question_id)) {
|
|
365
|
-
throw new Error(`spec answer: duplicate answer for question "${a.question_id}"`);
|
|
366
|
-
}
|
|
367
|
-
seen.add(a.question_id);
|
|
368
|
-
const q = byId.get(a.question_id);
|
|
369
|
-
if (!q)
|
|
370
|
-
throw new Error(`spec answer for unknown question "${a.question_id}"`);
|
|
371
|
-
const validIds = new Set(q.options.map((o) => o.id));
|
|
372
|
-
const unknown = (a.option_ids ?? []).filter((id) => !validIds.has(id));
|
|
373
|
-
if (unknown.length > 0) {
|
|
374
|
-
throw new Error(`spec answer for "${q.id}": unknown option id(s): ${unknown.join(", ")}`);
|
|
375
|
-
}
|
|
376
|
-
if (q.kind === "single" && (a.option_ids?.length ?? 0) > 1) {
|
|
377
|
-
throw new Error(`spec answer for "${q.id}": single-choice question accepts at most one option`);
|
|
378
|
-
}
|
|
379
|
-
if (!q.allow_text && (a.text?.trim() ?? "") !== "") {
|
|
380
|
-
throw new Error(`spec answer for "${q.id}": free text is not allowed for this question`);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
export async function freezeSpecFromGrounding(prompt, plan, answers) {
|
|
385
|
-
const questions = extractQuestionsFromPlan(plan);
|
|
386
|
-
validateAnswers(questions, answers.answers);
|
|
387
|
-
const engine = new InterviewEngine({
|
|
388
|
-
intent: prompt,
|
|
389
|
-
generator: async (state) => (state.tier === 0 ? questions : []),
|
|
390
|
-
assembler: async () => draftFromPlanAndAnswers(prompt, plan, questions, answers),
|
|
391
|
-
});
|
|
392
|
-
await engine.runToConvergence((qs) => qs.map((q) => {
|
|
393
|
-
const a = answers.answers.find((x) => x.question_id === q.id);
|
|
394
|
-
return a ?? { question_id: q.id, option_ids: [], text: null };
|
|
395
|
-
}));
|
|
396
|
-
return engine.freeze();
|
|
397
|
-
}
|
|
398
|
-
function renderNativePlanProjection(spec, plan, specHash) {
|
|
399
|
-
return [
|
|
400
|
-
`# Claudexor Spec ${spec.id} v${spec.version}`,
|
|
401
|
-
"",
|
|
402
|
-
`Spec hash: \`${specHash}\``,
|
|
403
|
-
"",
|
|
404
|
-
"## Intent",
|
|
405
|
-
spec.intent.raw,
|
|
406
|
-
"",
|
|
407
|
-
"## Summary",
|
|
408
|
-
spec.summary || "(none)",
|
|
409
|
-
"",
|
|
410
|
-
"## Acceptance Criteria",
|
|
411
|
-
...(spec.success_criteria.length
|
|
412
|
-
? spec.success_criteria.map((c) => `- [${c.id}] ${c.behavior}`)
|
|
413
|
-
: ["- (none)"]),
|
|
414
|
-
"",
|
|
415
|
-
"## Tests",
|
|
416
|
-
...(spec.tests.length
|
|
417
|
-
? spec.tests.map((test) => `- ${JSON.stringify([test.program, ...test.args])}`)
|
|
418
|
-
: ["- (none configured)"]),
|
|
419
|
-
"",
|
|
420
|
-
"## Non-goals",
|
|
421
|
-
...(spec.non_goals.length ? spec.non_goals.map((x) => `- ${x}`) : ["- (none)"]),
|
|
422
|
-
"",
|
|
423
|
-
"## Forbidden approaches",
|
|
424
|
-
...(spec.forbidden_approaches.length
|
|
425
|
-
? spec.forbidden_approaches.map((x) => `- ${x}`)
|
|
426
|
-
: ["- (none)"]),
|
|
427
|
-
"",
|
|
428
|
-
"## Source plan grounding",
|
|
429
|
-
redactSecrets(plan).trim(),
|
|
430
|
-
"",
|
|
431
|
-
"> This file is a generated projection for native harnesses. The canonical SSOT",
|
|
432
|
-
"> is the sibling spec.json (hash above). Regenerate rather than editing this projection.",
|
|
433
|
-
"",
|
|
434
|
-
].join("\n");
|
|
435
|
-
}
|
|
436
|
-
export function persistSpec(repoRoot, spec, plan, previous) {
|
|
437
|
-
return persistSpecAt(join(repoRoot, ".claudexor", "specs"), spec, plan, previous);
|
|
438
|
-
}
|
|
439
|
-
/** Persist a runnable immutable projection outside the user repository. */
|
|
440
|
-
export function persistSpecAt(specsRoot, spec, plan, previous) {
|
|
441
|
-
const canonical = SpecPackSchema.parse(spec);
|
|
442
|
-
const specDir = join(specsRoot, canonical.id);
|
|
443
|
-
ensureDir(specDir);
|
|
444
|
-
const specHash = hashJson(canonical);
|
|
445
|
-
const changes = previous ? diffSpecPacks(previous, canonical) : [];
|
|
446
|
-
// Secondary artifacts first; canonical spec.json LAST and atomically
|
|
447
|
-
// (tmp + rename) as the commit point — downstream hash verification reads
|
|
448
|
-
// spec.json, so a crash mid-persist leaves either no spec or a complete
|
|
449
|
-
// one, never a torn multi-file state fronted by a valid-looking spec.json.
|
|
450
|
-
new ArtifactStore(specsRoot).writeYaml(join(specDir, "spec.yaml"), canonical);
|
|
451
|
-
writeText(join(specDir, "PLANS.md"), renderNativePlanProjection(canonical, plan, specHash));
|
|
452
|
-
writeJson(join(specDir, "changes.json"), changes);
|
|
453
|
-
// Atomic commit point: rename MOVES the tmp file (no leftover on success);
|
|
454
|
-
// a failure between write and rename must not litter the spec dir either.
|
|
455
|
-
const tmp = join(specDir, `spec.json.tmp-${process.pid}`);
|
|
456
|
-
try {
|
|
457
|
-
writeJson(tmp, canonical);
|
|
458
|
-
renameSync(tmp, join(specDir, "spec.json"));
|
|
459
|
-
}
|
|
460
|
-
catch (err) {
|
|
461
|
-
rmSync(tmp, { force: true });
|
|
462
|
-
throw err;
|
|
463
|
-
}
|
|
464
|
-
return { specDir, specHash, changes };
|
|
465
|
-
}
|
|
466
|
-
//# sourceMappingURL=spec.js.map
|
package/dist/spec.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
|