cohorte 3.0.0-dev.6 → 3.0.0-dev.7
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/assets/manifest.json +14 -4
- package/assets/prompts/agents/brainstormer.md +3 -0
- package/assets/prompts/agents/spec-author.md +3 -0
- package/assets/schemas/commands.schema.json +7 -0
- package/dist/bundle-manifest.json +72 -50
- package/dist/chunks/align-ds-r_X_1aQ_.mjs +93 -0
- package/dist/chunks/align-ds-r_X_1aQ_.mjs.map +1 -0
- package/dist/chunks/audit-B4ZWQ_DI.mjs +179 -0
- package/dist/chunks/audit-B4ZWQ_DI.mjs.map +1 -0
- package/dist/chunks/brainstorm-DasVwI1D.mjs +123 -0
- package/dist/chunks/brainstorm-DasVwI1D.mjs.map +1 -0
- package/dist/chunks/build-crOld8gE.mjs +19 -0
- package/dist/chunks/build-crOld8gE.mjs.map +1 -0
- package/dist/chunks/{catalogue-DzsslCSN.mjs → catalogue-IaCJdfB8.mjs} +4 -4
- package/dist/chunks/{catalogue-DzsslCSN.mjs.map → catalogue-IaCJdfB8.mjs.map} +1 -1
- package/dist/chunks/{compose-ckM7eAJ_.mjs → compose-DRKjQcn0.mjs} +42 -23
- package/dist/chunks/compose-DRKjQcn0.mjs.map +1 -0
- package/dist/chunks/{config-DcGPL3i7.mjs → config-Cqu5XQoP.mjs} +2 -2
- package/dist/chunks/{config-DcGPL3i7.mjs.map → config-Cqu5XQoP.mjs.map} +1 -1
- package/dist/chunks/{contract-DiWla5G9.mjs → contract-DjssDPpS.mjs} +45 -25
- package/dist/chunks/contract-DjssDPpS.mjs.map +1 -0
- package/dist/chunks/{diff-D_0hBwHl.mjs → diff-Qw0II0sj.mjs} +2 -2
- package/dist/chunks/{diff-D_0hBwHl.mjs.map → diff-Qw0II0sj.mjs.map} +1 -1
- package/dist/chunks/{discover-BBiluyl4.mjs → discover-BZPolSZG.mjs} +2 -2
- package/dist/chunks/{discover-BBiluyl4.mjs.map → discover-BZPolSZG.mjs.map} +1 -1
- package/dist/chunks/{doctor-BAcemCDr.mjs → doctor-DcDFPvQM.mjs} +6 -6
- package/dist/chunks/{doctor-BAcemCDr.mjs.map → doctor-DcDFPvQM.mjs.map} +1 -1
- package/dist/chunks/fix-B_oGzGVn.mjs +82 -0
- package/dist/chunks/fix-B_oGzGVn.mjs.map +1 -0
- package/dist/chunks/fleet-yWHQY2ya.mjs +297 -0
- package/dist/chunks/fleet-yWHQY2ya.mjs.map +1 -0
- package/dist/chunks/{init-DfOKw-rD.mjs → init--FxxkrcT.mjs} +2 -2
- package/dist/chunks/{init-DfOKw-rD.mjs.map → init--FxxkrcT.mjs.map} +1 -1
- package/dist/chunks/intake-Dd1KVXnO.mjs +12 -0
- package/dist/chunks/intake-Dd1KVXnO.mjs.map +1 -0
- package/dist/chunks/loop-BWsUpyus.mjs +212 -0
- package/dist/chunks/loop-BWsUpyus.mjs.map +1 -0
- package/dist/chunks/{migrate-D3-4beNR.mjs → migrate-DuYCAbE3.mjs} +2 -2
- package/dist/chunks/{migrate-D3-4beNR.mjs.map → migrate-DuYCAbE3.mjs.map} +1 -1
- package/dist/chunks/{obsidian-D1jf1sTR.mjs → obsidian-BHLkXx_H.mjs} +50 -6
- package/dist/chunks/obsidian-BHLkXx_H.mjs.map +1 -0
- package/dist/chunks/patch-sAgVqjpx.mjs +50 -0
- package/dist/chunks/patch-sAgVqjpx.mjs.map +1 -0
- package/dist/chunks/{policy-Y65MYKzn.mjs → policy-Du7WVBFX.mjs} +4 -4
- package/dist/chunks/{policy-Y65MYKzn.mjs.map → policy-Du7WVBFX.mjs.map} +1 -1
- package/dist/chunks/{reconcile-B6mGZWtp.mjs → reconcile-BHn66X3C.mjs} +3 -3
- package/dist/chunks/{reconcile-B6mGZWtp.mjs.map → reconcile-BHn66X3C.mjs.map} +1 -1
- package/dist/chunks/refactor-CoNoqLZr.mjs +153 -0
- package/dist/chunks/refactor-CoNoqLZr.mjs.map +1 -0
- package/dist/chunks/retro-Dr-2RTNN.mjs +78 -0
- package/dist/chunks/retro-Dr-2RTNN.mjs.map +1 -0
- package/dist/chunks/review-ZsBqp3vZ.mjs +35 -0
- package/dist/chunks/review-ZsBqp3vZ.mjs.map +1 -0
- package/dist/chunks/{run-BInPXOcm.mjs → run-NGAxdsIX.mjs} +28 -5
- package/dist/chunks/run-NGAxdsIX.mjs.map +1 -0
- package/dist/chunks/{schema-hSyIURjN.mjs → schema-Bq9qtgsd.mjs} +2 -2
- package/dist/chunks/{schema-hSyIURjN.mjs.map → schema-Bq9qtgsd.mjs.map} +1 -1
- package/dist/chunks/ship-BizfUe62.mjs +140 -0
- package/dist/chunks/ship-BizfUe62.mjs.map +1 -0
- package/dist/chunks/spec-C2h3U64g.mjs +65 -0
- package/dist/chunks/spec-C2h3U64g.mjs.map +1 -0
- package/dist/chunks/spec-path-tptqR7W8.mjs +10 -0
- package/dist/chunks/spec-path-tptqR7W8.mjs.map +1 -0
- package/dist/chunks/{src-C7hs8Bjw.mjs → src-Bfr1yzsn.mjs} +3 -3
- package/dist/chunks/{src-C7hs8Bjw.mjs.map → src-Bfr1yzsn.mjs.map} +1 -1
- package/dist/chunks/{src-Daa5lIcP.mjs → src-CPW2_Ons.mjs} +101 -17
- package/dist/chunks/src-CPW2_Ons.mjs.map +1 -0
- package/dist/chunks/{src-DMrQ5m6I.mjs → src-DNsLSxgm.mjs} +2 -2
- package/dist/chunks/{src-DMrQ5m6I.mjs.map → src-DNsLSxgm.mjs.map} +1 -1
- package/dist/chunks/{src-BnlNkd3S.mjs → src-DbS9gkJy.mjs} +2 -2
- package/dist/chunks/{src-BnlNkd3S.mjs.map → src-DbS9gkJy.mjs.map} +1 -1
- package/dist/chunks/{src-s7YRvk0t.mjs → src-yi5whv3n.mjs} +4 -2
- package/dist/chunks/src-yi5whv3n.mjs.map +1 -0
- package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs +56 -0
- package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs.map +1 -0
- package/dist/cli.mjs +29 -19
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/brainstorm-kBUiZLce.mjs +0 -7
- package/dist/chunks/brainstorm-kBUiZLce.mjs.map +0 -1
- package/dist/chunks/compose-ckM7eAJ_.mjs.map +0 -1
- package/dist/chunks/contract-DiWla5G9.mjs.map +0 -1
- package/dist/chunks/fix-D4Tj8RVA.mjs +0 -18
- package/dist/chunks/fix-D4Tj8RVA.mjs.map +0 -1
- package/dist/chunks/obsidian-D1jf1sTR.mjs.map +0 -1
- package/dist/chunks/review-BDdjb6kB.mjs +0 -17
- package/dist/chunks/review-BDdjb6kB.mjs.map +0 -1
- package/dist/chunks/run-BInPXOcm.mjs.map +0 -1
- package/dist/chunks/ship-DTuLGoaJ.mjs +0 -19
- package/dist/chunks/ship-DTuLGoaJ.mjs.map +0 -1
- package/dist/chunks/spec-MVP9y8dN.mjs +0 -20
- package/dist/chunks/spec-MVP9y8dN.mjs.map +0 -1
- package/dist/chunks/src-Daa5lIcP.mjs.map +0 -1
- package/dist/chunks/src-s7YRvk0t.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as sha256Hex } from "./canonical-C8UxeEmB.mjs";
|
|
2
2
|
import "./src-Cu3TxNob.mjs";
|
|
3
3
|
import { n as createKeyStore, r as createTrustStore } from "./auth-BT5oVp76.mjs";
|
|
4
|
-
import { i as resolveConfig, n as loadConfig } from "./src-
|
|
4
|
+
import { i as resolveConfig, n as loadConfig } from "./src-DbS9gkJy.mjs";
|
|
5
5
|
import { readFile, writeFile } from "node:fs/promises";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { parse, stringify } from "yaml";
|
|
@@ -93,4 +93,4 @@ const config = {
|
|
|
93
93
|
//#endregion
|
|
94
94
|
export { config as default };
|
|
95
95
|
|
|
96
|
-
//# sourceMappingURL=config-
|
|
96
|
+
//# sourceMappingURL=config-Cqu5XQoP.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-
|
|
1
|
+
{"version":3,"file":"config-Cqu5XQoP.mjs","names":[],"sources":["../../../../apps/cli/src/commands/config/index.ts"],"sourcesContent":["// apps/cli/src/commands/config/index.ts — DESIGN §9 verb `config` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/config/**`.\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { sha256Hex } from '@cohorte/base';\nimport { loadConfig, resolveConfig } from '@cohorte/config';\nimport { createKeyStore, createTrustStore } from '@cohorte/security/auth';\nimport { parse, stringify } from 'yaml';\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst config: CommandModule = {\n verb: 'config',\n async run(ctx, args) {\n const path = join(ctx.cwd, '.cohorte', 'config.yaml');\n let value: unknown;\n try {\n value = parse(await readFile(path, 'utf8'));\n } catch (error) {\n ctx.stdio.stderr.write(`cannot read ${path}: ${String(error)}\\n`);\n return 1;\n }\n if (args.subVerb === 'validate') {\n const valid =\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n (value as { schemaVersion?: unknown }).schemaVersion === 1;\n ctx.stdio.stdout.write(`${valid ? 'valid' : 'invalid'}\\n`);\n return valid ? 0 : 1;\n }\n if (args.subVerb === 'set') {\n const [key, rawValue] = args.positionals;\n if (!key || rawValue === undefined || !value || typeof value !== 'object' || Array.isArray(value)) return 2;\n const next: Record<string, unknown> = { ...(value as Record<string, unknown>) };\n const parts = key.split('.').filter(Boolean);\n if (parts.length === 0) return 2;\n let cursor = next;\n for (const part of parts.slice(0, -1)) {\n const child = cursor[part];\n cursor[part] = child && typeof child === 'object' && !Array.isArray(child) ? { ...child } : {};\n cursor = cursor[part] as Record<string, unknown>;\n }\n cursor[parts.at(-1) as string] = parse(rawValue);\n await writeFile(path, stringify(next), 'utf8');\n if (args.json) ctx.stdio.stdout.write(`${JSON.stringify(next)}\\n`);\n else ctx.stdio.stdout.write(`updated ${key}\\n`);\n return 0;\n }\n if (args.subVerb === 'trust') {\n const home = ctx.env.HOME ?? ctx.cwd;\n const projectKeyId = sha256Hex(ctx.cwd).slice(0, 24);\n const keys = createKeyStore({ directory: join(home, '.cohorte', 'keys') });\n const trustStore = createTrustStore({ directory: join(home, '.cohorte', 'trust'), keys });\n const loaded = await loadConfig({ cwd: ctx.cwd, home });\n const resolved = await resolveConfig(loaded, {\n trustStore,\n projectKeyId,\n });\n const policySha256 = resolved.status === 'untrusted' ? resolved.policySha256 : resolved.trust.policySha256;\n const loosenedKeys = resolved.status === 'untrusted' ? resolved.loosenedKeys : resolved.trust.loosenedKeys;\n if (policySha256 === undefined) return 1;\n const flag = args.positionals.find((value) => value.startsWith('--'));\n if (flag === '--revoke') {\n const revoked = await trustStore.revoke(projectKeyId);\n ctx.stdio.stdout.write(`${JSON.stringify({ revoked })}\\n`);\n return 0;\n }\n if (flag === '--grant') {\n const record = await trustStore.grant(projectKeyId, {\n policySha256,\n loosenedKeys,\n grantedBy: ctx.env.USER ?? 'cli',\n });\n ctx.stdio.stdout.write(`${JSON.stringify(record)}\\n`);\n return 0;\n }\n const record = await trustStore.lookup(projectKeyId, policySha256);\n ctx.stdio.stdout.write(\n `${JSON.stringify({ policySha256, loosenedKeys, trusted: record !== undefined, record: record ?? null })}\\n`,\n );\n return 0;\n }\n if (args.subVerb === 'get' || args.subVerb === undefined) {\n ctx.stdio.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n return 0;\n }\n return 10;\n },\n};\n\nexport default config;\n"],"mappings":"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"}
|
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
import { F as EXIT_CODE_BY_CLASS, L as ERROR_CLASSES
|
|
1
|
+
import { F as EXIT_CODE_BY_CLASS, L as ERROR_CLASSES } from "./src-Cu3TxNob.mjs";
|
|
2
2
|
import "./contract-bQ9FJl4N.mjs";
|
|
3
|
-
import {
|
|
4
|
-
//#region src/contract/command-module.ts
|
|
5
|
-
/**
|
|
6
|
-
* The Wave-0 body of every verb (DESIGN §9 "stubbed with a seam" and the plain "not yet built" ones alike): a verb
|
|
7
|
-
* a later wave fills replaces this factory call with a real implementation, never the module's shape.
|
|
8
|
-
*
|
|
9
|
-
* It throws a CLASSIFIED `CohorteError`, not a bare `NotImplemented`: `toErrorInfo` keeps a `CohorteError`'s own
|
|
10
|
-
* code, so the documented `configuration/phase-not-available` (DESIGN §9, exit 10) is what the stub MEANS rather
|
|
11
|
-
* than what `cli.ts`'s unknown-throwable fallback happens to be. `cli.ts`'s fallback is `configuration/unexpected`
|
|
12
|
-
* (DESIGN 2.8 "Unknown throwables -> `<nearest class>/unexpected`"), so a real defect in a filled-in verb can never
|
|
13
|
-
* masquerade as "this phase is not available in this build".
|
|
14
|
-
*/
|
|
15
|
-
function notImplementedCommand(verb) {
|
|
16
|
-
return {
|
|
17
|
-
verb,
|
|
18
|
-
async run(_ctx, _args) {
|
|
19
|
-
throw new CohorteError(errorOf("configuration/phase-not-available", `the verb \`${verb}\` is not available in this build`));
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
//#endregion
|
|
3
|
+
import { h as SUSPENDED_STATES, p as HALTED_STATES, r as CONTROLLER_EXIT_CODES } from "./src-yi5whv3n.mjs";
|
|
24
4
|
//#region src/contract/documents.ts
|
|
25
5
|
const protocolDoc = (name) => ({
|
|
26
6
|
source: "protocol",
|
|
@@ -130,6 +110,42 @@ const VERBS = [
|
|
|
130
110
|
commandType: "start",
|
|
131
111
|
json: true
|
|
132
112
|
},
|
|
113
|
+
{
|
|
114
|
+
name: "loop",
|
|
115
|
+
summary: "Run a feature through the durable V3 workflow"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: "build",
|
|
119
|
+
summary: "Run preflight, build and tests for a frozen feature"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "intake",
|
|
123
|
+
summary: "Triage an idea into the Cohorte workflow"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "audit",
|
|
127
|
+
summary: "Review a project or feature against its frozen contract"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: "refactor",
|
|
131
|
+
summary: "Run a scoped refactor through the pipeline"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "fleet",
|
|
135
|
+
summary: "Run several features through isolated workflow runs"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "retro",
|
|
139
|
+
summary: "Extract recurring review findings into conventions"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "align-ds",
|
|
143
|
+
summary: "Align a configured design system adapter"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "update-pipeline",
|
|
147
|
+
summary: "Refresh the project pipeline assets"
|
|
148
|
+
},
|
|
133
149
|
{
|
|
134
150
|
name: "status",
|
|
135
151
|
summary: "Show a run, or the project, status",
|
|
@@ -286,7 +302,11 @@ const VERBS = [
|
|
|
286
302
|
},
|
|
287
303
|
{
|
|
288
304
|
name: "brainstorm",
|
|
289
|
-
summary: "
|
|
305
|
+
summary: "Create a draft feature spec from an idea"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
name: "patch",
|
|
309
|
+
summary: "Create a minimal regression patch spec"
|
|
290
310
|
},
|
|
291
311
|
{
|
|
292
312
|
name: "run-tool",
|
|
@@ -310,6 +330,6 @@ new Map(VERBS.map((verb) => [verb.name, verb]));
|
|
|
310
330
|
VERBS.map((verb) => verb.name);
|
|
311
331
|
Object.freeze(Object.fromEntries(VERBS.filter((verb) => verb.commandType !== void 0).map((verb) => [verb.commandType, verb.name])));
|
|
312
332
|
//#endregion
|
|
313
|
-
export { formatExitCodesHelp as n,
|
|
333
|
+
export { formatExitCodesHelp as n, VERBS as t };
|
|
314
334
|
|
|
315
|
-
//# sourceMappingURL=contract-
|
|
335
|
+
//# sourceMappingURL=contract-DjssDPpS.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-DjssDPpS.mjs","names":[],"sources":["../../../../apps/cli/src/contract/documents.ts","../../../../apps/cli/src/contract/exit-codes.ts","../../../../apps/cli/src/contract/verbs.ts"],"sourcesContent":["// apps/cli/src/contract/documents.ts — DESIGN 2.3.5 \"one [S] document per --json output\". `JSON_OUTPUTS` is the\n// map a Wave-4 command unit's `--json validates` test reads: verb -> the published document(s) that verb's\n// `--json` can print, each resolvable to a real schema in the protocol, project-model or security contract (PLAN\n// U0.10 test list, 6th row).\n\nimport { ProjectModel, ReconcilePlan } from '@cohorte/project-model/contract';\nimport { DOCUMENTS, type DocumentName } from '@cohorte/protocol';\nimport type { TSchema } from 'typebox';\n\n/** The two project-model documents a `--json` verb may print (DESIGN §9: `reconcile --plan`, `discover`). */\nexport const PROJECT_MODEL_DOCUMENT_NAMES = ['reconcile-plan', 'project-model'] as const;\nexport type ProjectModelDocumentName = (typeof PROJECT_MODEL_DOCUMENT_NAMES)[number];\n\nexport type DocumentRef =\n | { readonly source: 'protocol'; readonly name: DocumentName }\n | { readonly source: 'project-model'; readonly name: ProjectModelDocumentName };\n\n/** Resolves a `DocumentRef` to its real schema; throws when the referenced contract has no such entry (a drift\n * guard, not a runtime path: every entry of `JSON_OUTPUTS` below is checked against this at test time). */\nexport function resolveDocumentSchema(ref: DocumentRef): TSchema {\n if (ref.source === 'protocol') {\n const schema = DOCUMENTS[ref.name];\n if (!schema) throw new RangeError(`resolveDocumentSchema: no protocol document named ${ref.name}`);\n return schema;\n }\n // A plain lookup, not a `switch` with an unreachable default: the ref may come from a Wave-4 unit's data, so an\n // unknown name must throw at run time and not only fail to typecheck.\n // No cast: `TUnsafe<T> extends TSchema`, and there is exactly one typebox install (the `pnpm-workspace.yaml`\n // override pins 1.3.7), so `@cohorte/project-model/contract`'s schemas ARE `TSchema`s here. If this ever stops\n // compiling, the cause is a second typebox identity in the graph — a real defect to report, not to cast away.\n const projectModelSchemas: Record<ProjectModelDocumentName, TSchema> = {\n 'reconcile-plan': ReconcilePlan,\n 'project-model': ProjectModel,\n };\n const schema = projectModelSchemas[ref.name];\n if (!schema) throw new RangeError(`resolveDocumentSchema: no project-model document named ${String(ref.name)}`);\n return schema;\n}\n\nconst protocolDoc = (name: DocumentName): DocumentRef => ({ source: 'protocol', name });\nconst reconcilePlanDoc: DocumentRef = { source: 'project-model', name: 'reconcile-plan' };\n/** DESIGN §9 verb semantics: \"`cohorte discover` prints the deterministic scan as a Project Model document\". */\nconst projectModelDoc: DocumentRef = { source: 'project-model', name: 'project-model' };\n/** DESIGN 2.3.4's inbox route: every mutating command answers with a `CommandResultDocument`. */\nconst commandResult: readonly DocumentRef[] = [protocolDoc('command-result')];\n\n/**\n * Keyed by CLI verb (not by `CommandType`: read-only verbs publish a document with no command behind them).\n *\n * The key set is exactly `{ verb.name | verb.json }` of `contract/verbs.ts`, and `cli.ts` registers `--json` only\n * for those verbs — `apps/cli/test/registry/json-outputs.test.ts` pins both directions. `logs` and `tail` are\n * deliberately absent: DESIGN 4.7 gives an observer `--format=line|json` over an NDJSON *stream* of event\n * envelopes, not a single `--json` document (request U0.10 R1 asks U0.G to confirm that reading).\n */\nexport const JSON_OUTPUTS: Readonly<Record<string, readonly DocumentRef[]>> = Object.freeze({\n // `status <run>` -> run-state; `status` (no run) -> project-status (DESIGN 2.3.4 \"no runId => ProjectStatusDocument\")\n status: [protocolDoc('project-status'), protocolDoc('run-state')],\n inspect: [protocolDoc('inspect')],\n diff: [protocolDoc('run-diff')],\n doctor: [protocolDoc('doctor-report')],\n auth: [protocolDoc('auth-status')],\n reconcile: [reconcilePlanDoc],\n discover: [projectModelDoc],\n // `run` drives `start`; its `--wait`/`--json` prints the same run-state an observer would (DESIGN 4.7).\n run: [protocolDoc('command-result'), protocolDoc('run-state')],\n resume: commandResult,\n pause: commandResult,\n cancel: commandResult,\n approve: commandResult,\n deny: commandResult,\n retry: commandResult,\n skip: commandResult,\n shutdown: commandResult,\n send: commandResult,\n 'run-tool': commandResult,\n});\n","// apps/cli/src/contract/exit-codes.ts — DESIGN 2.8 \"Exit codes of a process that waits for a run\" + DESIGN 4.7 +\n// the controller codes of DESIGN 2.3.4 (`CONTROLLER_EXIT_CODES`). Total over `ErrorClass` because it is built\n// directly from `@cohorte/base`'s `EXIT_CODE_BY_CLASS`, which is itself total (a `satisfies Record<ErrorClass, …>`\n// literal): the totality test in `apps/cli/test/registry` checks that equality holds, it does not re-derive it.\nimport { ERROR_CLASSES, type ErrorClass, EXIT_CODE_BY_CLASS } from '@cohorte/base';\nimport { CONTROLLER_EXIT_CODES, HALTED_STATES, type PipelineState, SUSPENDED_STATES } from '@cohorte/protocol';\n\nexport { CONTROLLER_EXIT_CODES, EXIT_CODE_BY_CLASS };\n\n/** DESIGN 4.7 \"4 on a suspended state\" / DESIGN 2.3.4 \"4 accepted-but-pending at --wait expiry (not an error)\". */\nexport const SUSPENDED_EXIT_CODE = 4;\n/** DESIGN 2.8 \"16 on CANCELLED\" (shares the `conflict` class code, but CANCELLED is not itself an error). */\nexport const CANCELLED_EXIT_CODE = 16;\nexport const COMPLETED_EXIT_CODE = 0;\n\nconst SUSPENDED = new Set<string>(SUSPENDED_STATES);\nconst HALTED = new Set<string>(HALTED_STATES);\n\n/**\n * DESIGN 2.8 / 4.7: \"an observer started by `run`, or any `--wait`, exits 0 on COMPLETED, the class code of\n * `run.lastError` on FAILED/BLOCKED, 4 on a suspended state, 16 on CANCELLED.\" `lastErrorClass` is required\n * exactly when `state` is FAILED or BLOCKED (DESIGN 2.8: every halted run carries a `lastError`).\n */\nexport function waitExitCode(state: PipelineState, lastErrorClass?: ErrorClass): number {\n if (state === 'COMPLETED') return COMPLETED_EXIT_CODE;\n if (state === 'CANCELLED') return CANCELLED_EXIT_CODE;\n if (SUSPENDED.has(state)) return SUSPENDED_EXIT_CODE;\n if (HALTED.has(state)) {\n if (!lastErrorClass) throw new RangeError(`waitExitCode: ${state} requires lastErrorClass (DESIGN 2.8)`);\n return EXIT_CODE_BY_CLASS[lastErrorClass];\n }\n // IDLE and every ACTIVE_PIPELINE_STATE are not terminal/suspended: a waiter never observes them as a final state.\n throw new RangeError(`waitExitCode: ${state} is not a terminal or suspended state (DESIGN 2.8)`);\n}\n\nexport interface ExitCodeHelpRow {\n readonly code: number;\n readonly meaning: string;\n}\n\n/** DESIGN 2.3.4 \"Controller exit codes: 0 completed · 3 rejected · 4 accepted-but-pending · 2 usage.\" */\nexport const CONTROLLER_EXIT_HELP: readonly ExitCodeHelpRow[] = [\n { code: CONTROLLER_EXIT_CODES.completed, meaning: 'completed' },\n { code: CONTROLLER_EXIT_CODES.usage, meaning: 'usage error' },\n { code: CONTROLLER_EXIT_CODES.rejected, meaning: 'rejected' },\n { code: CONTROLLER_EXIT_CODES.pending, meaning: 'accepted, pending at --wait expiry (not an error: durable inbox)' },\n];\n\n/** DESIGN 2.8's table, class by class, in spec order. */\nexport const ERROR_CLASS_EXIT_HELP: readonly ExitCodeHelpRow[] = ERROR_CLASSES.map((errorClass) => ({\n code: EXIT_CODE_BY_CLASS[errorClass],\n meaning: `${errorClass} error`,\n}));\n\nexport const CANCELLED_EXIT_HELP: ExitCodeHelpRow = { code: CANCELLED_EXIT_CODE, meaning: 'cancelled' };\n\n/** Rendered into `--help` (PLAN U0.10 test: \"controller codes 0/2/3/4 documented in --help\"). */\nexport function formatExitCodesHelp(): string {\n const rows = [...CONTROLLER_EXIT_HELP, ...ERROR_CLASS_EXIT_HELP, CANCELLED_EXIT_HELP].reduce<ExitCodeHelpRow[]>(\n (merged, row) => {\n const existing = merged.find((item) => item.code === row.code);\n if (existing) {\n const index = merged.indexOf(existing);\n merged[index] = { code: row.code, meaning: `${existing.meaning} / ${row.meaning}` };\n } else {\n merged.push({ ...row });\n }\n return merged;\n },\n [],\n );\n const width = Math.max(...rows.map((row) => String(row.code).length));\n const lines = rows.map((row) => ` ${String(row.code).padStart(width)} ${row.meaning}`);\n return ['Exit codes:', ...lines].join('\\n');\n}\n","// apps/cli/src/contract/verbs.ts — DESIGN §9 \"V3.0 scope cut\" CLI row + the verb-semantics paragraph, and DESIGN\n// 2.3.4 \"every command type has a CLI verb, because one-shot CLI spawns are the only V3.0 transport\". `cli.ts`\n// builds the whole commander tree from this table and NOTHING ELSE (PLAN §3 rule 3: \"cli.ts pre-registers every\n// verb against commands/<verb>/index.ts\"); a later wave fills a verb's module, never this table's shape.\nimport type { CommandType } from '@cohorte/protocol';\n\nexport interface VerbSpec {\n readonly name: string;\n readonly summary: string;\n /** DESIGN §9: `config get|set|validate|trust`, `auth login|status|logout`, `providers list|test`, ... */\n readonly subVerbs?: readonly string[];\n /** Not listed in `cohorte --help` (the `__host` internal entry point, DESIGN 4.7). */\n readonly hidden?: boolean;\n /**\n * This verb accepts `--json` and publishes a document for it (DESIGN 2.3.5). Set exactly on the verbs that have\n * a `JSON_OUTPUTS` entry — `cli.ts` registers the `--json` option only for those, and\n * `apps/cli/test/registry/json-outputs.test.ts` pins the two sides equal in BOTH directions, so a verb can never\n * be silently flagged `--json` with no document behind it.\n */\n readonly json?: boolean;\n /** The `@cohorte/protocol` `CommandType` this verb drives 1:1, when it drives exactly one (DESIGN 2.3.4). */\n readonly commandType?: CommandType;\n}\n\nexport const VERBS: readonly VerbSpec[] = [\n { name: 'init', summary: 'Scaffold .cohorte/ for this repository' },\n { name: 'doctor', summary: 'Diagnose the installation, configuration and toolchain', json: true },\n { name: 'discover', summary: 'Print the deterministic project scan (no write)', json: true },\n { name: 'run', summary: 'Start a pipeline run', commandType: 'start', json: true },\n { name: 'loop', summary: 'Run a feature through the durable V3 workflow' },\n { name: 'build', summary: 'Run preflight, build and tests for a frozen feature' },\n { name: 'intake', summary: 'Triage an idea into the Cohorte workflow' },\n { name: 'audit', summary: 'Review a project or feature against its frozen contract' },\n { name: 'refactor', summary: 'Run a scoped refactor through the pipeline' },\n { name: 'fleet', summary: 'Run several features through isolated workflow runs' },\n { name: 'retro', summary: 'Extract recurring review findings into conventions' },\n { name: 'align-ds', summary: 'Align a configured design system adapter' },\n { name: 'update-pipeline', summary: 'Refresh the project pipeline assets' },\n { name: 'status', summary: 'Show a run, or the project, status', commandType: 'status', json: true },\n {\n name: 'inspect',\n summary: 'Inspect one agent, context, approval, effect, snapshot, lock, diff or artifact',\n commandType: 'inspect',\n json: true,\n },\n { name: 'resume', summary: 'Resume a suspended run', commandType: 'resume', json: true },\n { name: 'pause', summary: 'Pause an active run', commandType: 'pause', json: true },\n { name: 'cancel', summary: 'Cancel a run', commandType: 'cancel', json: true },\n { name: 'shutdown', summary: 'Ask the detached host to shut down gracefully', commandType: 'shutdown', json: true },\n { name: 'approve', summary: 'Approve a pending approval request', commandType: 'approve', json: true },\n { name: 'deny', summary: 'Deny a pending approval request', commandType: 'deny', json: true },\n { name: 'retry', summary: 'Retry a phase or an agent', commandType: 'retry', json: true },\n { name: 'skip', summary: 'Skip a phase (only if policy.skip lists it)', commandType: 'skip', json: true },\n { name: 'logs', summary: 'Print durable run events' },\n { name: 'tail', summary: 'Follow a run (durable + ephemeral events)', commandType: 'tail' },\n { name: 'diff', summary: 'Show the run diff for a surface', json: true },\n { name: 'review', summary: 'Start a review-profile run over a ref range or a prior run' },\n { name: 'fix', summary: \"Retry a run's FIX phase\" },\n { name: 'ship', summary: 'Show and resolve the pending ship approval' },\n { name: 'auth', summary: 'Manage provider authentication', subVerbs: ['login', 'status', 'logout'], json: true },\n { name: 'providers', summary: 'List or test configured providers', subVerbs: ['list', 'test'] },\n { name: 'models', summary: 'List available models', subVerbs: ['list'] },\n {\n name: 'config',\n summary: 'Read, write, validate or trust the project configuration',\n subVerbs: ['get', 'set', 'validate', 'trust'],\n },\n { name: 'migrate', summary: 'Check or apply state-store migrations' },\n {\n name: 'reconcile',\n summary: 'Plan the project configuration against the discovered state',\n commandType: 'reconcile',\n json: true,\n },\n { name: 'spec', summary: 'Validate or freeze a human-written spec', subVerbs: ['validate', 'freeze'] },\n {\n name: 'obsidian',\n summary: 'Connect and synchronize an Obsidian board',\n subVerbs: ['create', 'connect', 'status', 'move'],\n },\n { name: 'policy', summary: 'Explain the effective security policy', subVerbs: ['explain'] },\n { name: 'gc', summary: 'Garbage-collect worktrees, spools and old runs' },\n {\n name: 'update',\n // DESIGN §9 spells it as a FLAG, `update --check`, not a sub-verb: the Wave-5 unit that fills\n // `commands/update/index.ts` reads `--check` from `args.options`/`args.positionals` like every other verb flag.\n summary: 'Check for a newer pinned install (offline, --check only in V3.0)',\n },\n { name: 'brainstorm', summary: 'Create a draft feature spec from an idea' },\n { name: 'patch', summary: 'Create a minimal regression patch spec' },\n {\n name: 'run-tool',\n summary: 'Run one tool directly (admin; policy.admin.runTool)',\n commandType: 'run-tool',\n json: true,\n },\n {\n name: 'send',\n summary: 'Send text to a running agent (policy.steer.enabled)',\n commandType: 'agent.send',\n json: true,\n },\n { name: '__host', summary: 'Internal: run the detached host in-process', hidden: true },\n];\n\nconst BY_NAME = new Map(VERBS.map((verb) => [verb.name, verb]));\n\nexport function findVerb(name: string): VerbSpec | undefined {\n return BY_NAME.get(name);\n}\n\nexport const VERB_NAMES: readonly string[] = VERBS.map((verb) => verb.name);\n\n/** DESIGN 2.3.4: every `CommandType` has exactly one driving verb. Built from `VERBS`, so it can never drift. */\nexport const COMMAND_TYPE_TO_VERB: Readonly<Record<CommandType, string>> = Object.freeze(\n Object.fromEntries(\n VERBS.filter((verb): verb is VerbSpec & { commandType: CommandType } => verb.commandType !== undefined).map(\n (verb) => [verb.commandType, verb.name],\n ),\n ) as Record<CommandType, string>,\n);\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as sha256Hex } from "./canonical-C8UxeEmB.mjs";
|
|
2
2
|
import "./src-Cu3TxNob.mjs";
|
|
3
|
-
import { execFile } from "node:child_process";
|
|
4
3
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
5
|
import { promisify } from "node:util";
|
|
6
6
|
//#region src/commands/diff/index.ts
|
|
7
7
|
const exec = promisify(execFile);
|
|
@@ -98,4 +98,4 @@ const diff = {
|
|
|
98
98
|
//#endregion
|
|
99
99
|
export { diff as default };
|
|
100
100
|
|
|
101
|
-
//# sourceMappingURL=diff-
|
|
101
|
+
//# sourceMappingURL=diff-Qw0II0sj.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-
|
|
1
|
+
{"version":3,"file":"diff-Qw0II0sj.mjs","names":[],"sources":["../../../../apps/cli/src/commands/diff/index.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { promisify } from 'node:util';\nimport { sha256Hex } from '@cohorte/base';\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst exec = promisify(execFile);\ntype GitRow = { path: string; op: 'create' | 'modify' | 'delete'; added: number; removed: number };\n\nasync function git(cwd: string, args: string[]): Promise<string> {\n const result = await exec('git', args, { cwd, maxBuffer: 4 * 1024 * 1024 });\n return result.stdout;\n}\n\nfunction parseNumstat(text: string): GitRow[] {\n return text\n .split('\\n')\n .filter(Boolean)\n .map((line) => {\n const [addedText, removedText, ...pathParts] = line.split('\\t');\n const path = pathParts.join('\\t');\n const added = addedText === '-' ? 0 : Number(addedText);\n const removed = removedText === '-' ? 0 : Number(removedText);\n return {\n path,\n op: added === 0 && removed > 0 ? 'delete' : added > 0 && removed === 0 ? 'create' : 'modify',\n added,\n removed,\n };\n });\n}\n\nconst diff: CommandModule = {\n verb: 'diff',\n async run(ctx, args) {\n const runId = args.positionals[0];\n if (!runId) return 2;\n const store = await ctx.openStore();\n try {\n const tree = await store.readRunTree(runId as never);\n const run = tree.run;\n const worktree =\n tree.worktrees.find((item) => item.slot === (args.positionals[1] ?? '_integration')) ?? tree.worktrees[0];\n if (!worktree || !run.baseSha) return 3;\n const base = run.baseSha;\n const head = run.integrationHead ?? (await git(worktree.path, ['rev-parse', 'HEAD'])).trim();\n const rows = parseNumstat(await git(worktree.path, ['diff', '--numstat', `${base}..${head}`]));\n const patch = await git(worktree.path, ['diff', '--binary', `${base}..${head}`]);\n const artifactId = ctx.ids.next<'ArtifactId'>('art');\n const artifactDir = `${ctx.cwd}/.cohorte/runs/${runId}/artifacts`;\n const relativePatch = `.cohorte/runs/${runId}/artifacts/${artifactId}.patch`;\n await mkdir(artifactDir, { recursive: true, mode: 0o700 });\n await writeFile(`${ctx.cwd}/${relativePatch}`, patch, 'utf8');\n const document = {\n documentVersion: 1,\n runId,\n base: { branch: run.baseBranch, sha: base },\n head: {\n branch: run.integrationBranch ?? worktree.branch ?? 'HEAD',\n sha: head,\n treeDigest: (await git(worktree.path, ['rev-parse', `${head}^{tree}`])).trim(),\n },\n surfaces: [\n {\n surface: args.positionals[1] ?? 'shared',\n files: rows.map((row) => ({ path: row.path, op: row.op })),\n stat: {\n added: rows.reduce((sum, row) => sum + row.added, 0),\n removed: rows.reduce((sum, row) => sum + row.removed, 0),\n },\n patch: {\n artifactId,\n kind: 'patch',\n path: relativePatch,\n sha256: sha256Hex(patch),\n bytes: Buffer.byteLength(patch),\n },\n },\n ],\n };\n if (args.json) ctx.stdio.stdout.write(`${JSON.stringify(document)}\\n`);\n else ctx.stdio.stdout.write(patch);\n return 0;\n } finally {\n await store.close();\n }\n },\n};\n\nexport default diff;\n"],"mappings":";;;;;;AAMA,MAAM,OAAO,UAAU,QAAQ;AAG/B,eAAe,IAAI,KAAa,MAAiC;CAE/D,QAAO,MADc,KAAK,OAAO,MAAM;EAAE;EAAK,WAAW;CAAgB,CAAC,EAAA,CAC5D;AAChB;AAEA,SAAS,aAAa,MAAwB;CAC5C,OAAO,KACJ,MAAM,IAAI,CAAC,CACX,OAAO,OAAO,CAAC,CACf,KAAK,SAAS;EACb,MAAM,CAAC,WAAW,aAAa,GAAG,aAAa,KAAK,MAAM,GAAI;EAC9D,MAAM,OAAO,UAAU,KAAK,GAAI;EAChC,MAAM,QAAQ,cAAc,MAAM,IAAI,OAAO,SAAS;EACtD,MAAM,UAAU,gBAAgB,MAAM,IAAI,OAAO,WAAW;EAC5D,OAAO;GACL;GACA,IAAI,UAAU,KAAK,UAAU,IAAI,WAAW,QAAQ,KAAK,YAAY,IAAI,WAAW;GACpF;GACA;EACF;CACF,CAAC;AACL;AAEA,MAAM,OAAsB;CAC1B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,QAAQ,KAAK,YAAY;EAC/B,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,QAAQ,MAAM,IAAI,UAAU;EAClC,IAAI;GACF,MAAM,OAAO,MAAM,MAAM,YAAY,KAAc;GACnD,MAAM,MAAM,KAAK;GACjB,MAAM,WACJ,KAAK,UAAU,MAAM,SAAS,KAAK,UAAU,KAAK,YAAY,MAAM,eAAe,KAAK,KAAK,UAAU;GACzG,IAAI,CAAC,YAAY,CAAC,IAAI,SAAS,OAAO;GACtC,MAAM,OAAO,IAAI;GACjB,MAAM,OAAO,IAAI,oBAAoB,MAAM,IAAI,SAAS,MAAM,CAAC,aAAa,MAAM,CAAC,EAAA,CAAG,KAAK;GAC3F,MAAM,OAAO,aAAa,MAAM,IAAI,SAAS,MAAM;IAAC;IAAQ;IAAa,GAAG,KAAK,IAAI;GAAM,CAAC,CAAC;GAC7F,MAAM,QAAQ,MAAM,IAAI,SAAS,MAAM;IAAC;IAAQ;IAAY,GAAG,KAAK,IAAI;GAAM,CAAC;GAC/E,MAAM,aAAa,IAAI,IAAI,KAAmB,KAAK;GACnD,MAAM,cAAc,GAAG,IAAI,IAAI,iBAAiB,MAAM;GACtD,MAAM,gBAAgB,iBAAiB,MAAM,aAAa,WAAW;GACrE,MAAM,MAAM,aAAa;IAAE,WAAW;IAAM,MAAM;GAAM,CAAC;GACzD,MAAM,UAAU,GAAG,IAAI,IAAI,GAAG,iBAAiB,OAAO,MAAM;GAC5D,MAAM,WAAW;IACf,iBAAiB;IACjB;IACA,MAAM;KAAE,QAAQ,IAAI;KAAY,KAAK;IAAK;IAC1C,MAAM;KACJ,QAAQ,IAAI,qBAAqB,SAAS,UAAU;KACpD,KAAK;KACL,aAAa,MAAM,IAAI,SAAS,MAAM,CAAC,aAAa,GAAG,KAAK,QAAQ,CAAC,EAAA,CAAG,KAAK;IAC/E;IACA,UAAU,CACR;KACE,SAAS,KAAK,YAAY,MAAM;KAChC,OAAO,KAAK,KAAK,SAAS;MAAE,MAAM,IAAI;MAAM,IAAI,IAAI;KAAG,EAAE;KACzD,MAAM;MACJ,OAAO,KAAK,QAAQ,KAAK,QAAQ,MAAM,IAAI,OAAO,CAAC;MACnD,SAAS,KAAK,QAAQ,KAAK,QAAQ,MAAM,IAAI,SAAS,CAAC;KACzD;KACA,OAAO;MACL;MACA,MAAM;MACN,MAAM;MACN,QAAQ,UAAU,KAAK;MACvB,OAAO,OAAO,WAAW,KAAK;KAChC;IACF,CACF;GACF;GACA,IAAI,KAAK,MAAM,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,EAAE,GAAG;QAChE,IAAI,MAAM,OAAO,MAAM,KAAK;GACjC,OAAO;EACT,UAAU;GACR,MAAM,MAAM,MAAM;EACpB;CACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { N as errorOf, j as CohorteError } from "./src-Cu3TxNob.mjs";
|
|
2
|
-
import "./src-
|
|
2
|
+
import "./src-DNsLSxgm.mjs";
|
|
3
3
|
import { t as scanRepository } from "./scan-C5uDr7Yq.mjs";
|
|
4
4
|
//#region src/commands/discover/index.ts
|
|
5
5
|
const discover = {
|
|
@@ -18,4 +18,4 @@ const discover = {
|
|
|
18
18
|
//#endregion
|
|
19
19
|
export { discover as default };
|
|
20
20
|
|
|
21
|
-
//# sourceMappingURL=discover-
|
|
21
|
+
//# sourceMappingURL=discover-BZPolSZG.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover-
|
|
1
|
+
{"version":3,"file":"discover-BZPolSZG.mjs","names":[],"sources":["../../../../apps/cli/src/commands/discover/index.ts"],"sourcesContent":["import { CohorteError, errorOf } from '@cohorte/base';\nimport { scanRepository } from '@cohorte/project-model';\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst discover: CommandModule = {\n verb: 'discover',\n async run(ctx, args) {\n if (args.positionals.includes('--semantic')) {\n throw new CohorteError(\n errorOf('configuration/phase-not-available', 'semantic discovery is not available in V3.0'),\n );\n }\n const model = await scanRepository(ctx.cwd, { clock: ctx.clock, toolVersion: '3.0.0' });\n if (args.json) ctx.stdio.stdout.write(`${JSON.stringify(model)}\\n`);\n else ctx.stdio.stdout.write(`${JSON.stringify(model, null, 2)}\\n`);\n return 0;\n },\n};\n\nexport default discover;\n"],"mappings":";;;;AAIA,MAAM,WAA0B;CAC9B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,IAAI,KAAK,YAAY,SAAS,YAAY,GACxC,MAAM,IAAI,aACR,QAAQ,qCAAqC,6CAA6C,CAC5F;EAEF,MAAM,QAAQ,MAAM,eAAe,IAAI,KAAK;GAAE,OAAO,IAAI;GAAO,aAAa;EAAQ,CAAC;EACtF,IAAI,KAAK,MAAM,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;OAC7D,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,GAAG;EACjE,OAAO;CACT;AACF"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { n as sha256Hex } from "./canonical-C8UxeEmB.mjs";
|
|
2
2
|
import "./src-Cu3TxNob.mjs";
|
|
3
3
|
import { n as createKeyStore, r as createTrustStore } from "./auth-BT5oVp76.mjs";
|
|
4
|
-
import "./contract-
|
|
5
|
-
import { i as resolveConfig, n as loadConfig } from "./src-
|
|
6
|
-
import { _ as probeSandbox } from "./src-
|
|
7
|
-
import { l as verifyProjectionAgainstEvents } from "./src-
|
|
8
|
-
import { execFile } from "node:child_process";
|
|
4
|
+
import "./contract-DjssDPpS.mjs";
|
|
5
|
+
import { i as resolveConfig, n as loadConfig } from "./src-DbS9gkJy.mjs";
|
|
6
|
+
import { _ as probeSandbox } from "./src-Bfr1yzsn.mjs";
|
|
7
|
+
import { l as verifyProjectionAgainstEvents } from "./src-CPW2_Ons.mjs";
|
|
9
8
|
import { join } from "node:path";
|
|
9
|
+
import { execFile } from "node:child_process";
|
|
10
10
|
import { promisify } from "node:util";
|
|
11
11
|
//#region src/contract/doctor.ts
|
|
12
12
|
/** DESIGN §9 doctor capabilities + F-1 (ripgrep backend) + F-3 (sandbox availability) + 6.3 (protected roots). */
|
|
@@ -219,4 +219,4 @@ const doctor = {
|
|
|
219
219
|
//#endregion
|
|
220
220
|
export { doctor as default };
|
|
221
221
|
|
|
222
|
-
//# sourceMappingURL=doctor-
|
|
222
|
+
//# sourceMappingURL=doctor-DcDFPvQM.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-BAcemCDr.mjs","names":[],"sources":["../../../../apps/cli/src/contract/doctor.ts","../../../../apps/cli/src/doctor/checks/auth/index.ts","../../../../apps/cli/src/doctor/index.ts","../../../../apps/cli/src/commands/doctor/index.ts"],"sourcesContent":["// apps/cli/src/contract/doctor.ts — the frozen list of doctor check modules (PLAN PC-4 \"DoctorCheck + the frozen\n// list of doctor check modules\"). `doctor/index.ts` (area barrel, U4.05) runs every id of `DOCTOR_CHECK_IDS`\n// through `doctor/checks/<id>/index.ts`; only `auth` is a Wave-0 owned stub (`apps/cli/src/doctor/checks/auth`,\n// filled by U5.05) — the rest are created, under the same shape, by U4.05.\nimport type { DOCTOR_CHECK_STATUSES } from '@cohorte/protocol';\nimport type { CliContext } from './context.ts';\n\nexport type DoctorCheckStatus = (typeof DOCTOR_CHECK_STATUSES)[number];\n\nexport interface DoctorCheckResult {\n readonly id: string;\n readonly status: DoctorCheckStatus;\n readonly summary: string;\n readonly remediation?: string;\n}\n\nexport interface DoctorCheck {\n readonly id: string;\n readonly description: string;\n run(ctx: CliContext): Promise<DoctorCheckResult>;\n}\n\n/** DESIGN §9 doctor capabilities + F-1 (ripgrep backend) + F-3 (sandbox availability) + 6.3 (protected roots). */\nexport const DOCTOR_CHECK_IDS = [\n 'node-version',\n 'git',\n 'sqlite',\n 'search-backend',\n 'sandbox',\n 'auth',\n 'install',\n 'config',\n 'worktree-root',\n] as const;\nexport type DoctorCheckId = (typeof DOCTOR_CHECK_IDS)[number];\n","// apps/cli/src/doctor/checks/auth/index.ts — the `auth` doctor check (spec 10 \"auth status\"). Wave-0 typed stub:\n// filled by `U5.05`, which owns `apps/cli/src/doctor/checks/auth/**`.\nimport type { DoctorCheck } from '../../../contract/index.ts';\n\nconst authDoctorCheck: DoctorCheck = {\n id: 'auth',\n description: \"Checks that the configured provider's authentication is usable, without reading the token.\",\n async run(ctx) {\n try {\n const statuses = await ctx.runtime.resolve().authStatus([]);\n const usable = statuses.every((status) => status.state !== 'absent' && status.state !== 'unknown-transient');\n const accountNote = statuses.some((status) => status.accountLabel === undefined)\n ? '; account: not exposed by the engine'\n : '';\n return {\n id: 'auth',\n status: usable ? 'ok' : 'warning',\n summary: `${usable ? 'runtime authentication is available' : 'runtime authentication needs attention'}${accountNote}`,\n };\n } catch (error) {\n return { id: 'auth', status: 'error', summary: `authentication status unavailable: ${String(error)}` };\n }\n },\n};\n\nexport default authDoctorCheck;\n","// apps/cli/src/doctor/index.ts — AREA barrel: runs every `DOCTOR_CHECK_IDS` entry (contract/doctor.ts) through\n// `doctor/checks/<id>/index.ts` and assembles a `DoctorReport`. Wave-0 stub: filled by `U4.05`, which owns\n// `apps/cli/src/doctor/**` (this file included); only `checks/auth/**` is carved out to `U5.05`.\nimport { execFile } from 'node:child_process';\nimport { join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { sha256Hex } from '@cohorte/base';\nimport { loadConfig, resolveConfig } from '@cohorte/config';\nimport { verifyProjectionAgainstEvents } from '@cohorte/core';\nimport { createKeyStore, createTrustStore } from '@cohorte/security/auth';\nimport { probeSandbox } from '@cohorte/security/exec';\nimport { type CliContext, DOCTOR_CHECK_IDS, type DoctorCheck, type DoctorCheckResult } from '../contract/index.ts';\nimport authDoctorCheck from './checks/auth/index.ts';\n\nconst exec = promisify(execFile);\nconst result = (id: string, summary: string, status: DoctorCheckResult['status'] = 'ok'): DoctorCheckResult => ({\n id,\n summary,\n status,\n});\n\nfunction versionAtLeast(value: string, required: [number, number]): boolean {\n const [major = 0, minor = 0] = value.split('.').map((part) => Number.parseInt(part, 10));\n return major > required[0] || (major === required[0] && minor >= required[1]);\n}\n\nexport async function runDoctor(\n ctx: CliContext,\n options: { readonly verifyState?: boolean } = {},\n): Promise<readonly DoctorCheckResult[]> {\n const checks: DoctorCheck[] = [\n {\n id: 'node-version',\n description: 'Node',\n run: async () =>\n versionAtLeast(process.versions.node, [24, 16])\n ? result('node-version', `Node ${process.versions.node}`)\n : result('node-version', `Node ${process.versions.node} is below 24.16`, 'error'),\n },\n {\n id: 'git',\n description: 'Git',\n run: async () => {\n try {\n const { stdout } = await exec('git', ['--version']);\n const version = stdout.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/)?.[1] ?? '0.0.0';\n return versionAtLeast(version, [2, 38])\n ? result('git', `Git ${version}`)\n : result('git', `Git ${version} is below 2.38`, 'error');\n } catch (error) {\n return result('git', `git unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'sqlite',\n description: 'SQLite',\n run: async () => {\n try {\n const store = await ctx.openStore();\n const info = await store.open();\n const migration = await store.migrate('check');\n await store.close();\n return migration.pending.length === 0\n ? result('sqlite', `${info.kind} schema ${info.schemaVersion}`)\n : result('sqlite', `${migration.pending.length} migration(s) pending`, 'warning');\n } catch (error) {\n return result('sqlite', `state store unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'search-backend',\n description: 'Search',\n run: async () => {\n try {\n const { stdout } = await exec('rg', ['--version']);\n return result('search-backend', `ripgrep ${stdout.split(/\\s+/u)[1] ?? 'available'}`);\n } catch {\n try {\n await exec('git', ['grep', '--version']);\n return result('search-backend', 'git grep fallback');\n } catch {\n return result('search-backend', 'neither rg nor git grep is available', 'error');\n }\n }\n },\n },\n {\n id: 'sandbox',\n description: 'Sandbox',\n run: async () => {\n const capabilities = await probeSandbox();\n return result(\n 'sandbox',\n `level=${capabilities.level}, backend=${capabilities.backend}, filesystem=${capabilities.filesystem}, network=${capabilities.network}`,\n capabilities.level === 'L0-process' ? 'warning' : 'ok',\n );\n },\n },\n authDoctorCheck,\n {\n id: 'install',\n description: 'Install',\n run: async () => {\n try {\n const verified = await ctx.assets.verify();\n return verified.ok\n ? result('install', `${ctx.install.installDir()} (assets verified)`)\n : result('install', `asset verification failed: ${verified.error.message}`, 'error');\n } catch (error) {\n return result('install', `asset verification unavailable: ${String(error)}`, 'warning');\n }\n },\n },\n {\n id: 'config',\n description: 'Config',\n run: async () => {\n try {\n const home = ctx.env.HOME ?? ctx.cwd;\n const keys = createKeyStore({ directory: join(home, '.cohorte', 'keys') });\n const trustStore = createTrustStore({ directory: join(home, '.cohorte', 'trust'), keys });\n const loaded = await loadConfig({ cwd: ctx.cwd, home });\n const resolved = await resolveConfig(loaded, {\n trustStore,\n projectKeyId: sha256Hex(loaded.projectRoot).slice(0, 24),\n });\n return resolved.status === 'resolved'\n ? result('config', `project configuration resolved at ${loaded.projectRoot}`)\n : result('config', `project policy requires trust: ${resolved.loosenedKeys.join(', ')}`, 'warning');\n } catch (error) {\n return result('config', `configuration unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'worktree-root',\n description: 'Worktree',\n run: async () =>\n typeof process.getuid === 'function' && process.getuid() === 0\n ? result('worktree-root', 'refusing to operate as uid 0', 'error')\n : result('worktree-root', ctx.cwd),\n },\n ];\n if (options.verifyState) {\n checks.push({\n id: 'verify-state',\n description: 'State verification',\n run: async () => {\n const store = await ctx.openStore();\n try {\n const runs = await store.listRuns({ limit: 100_000, offset: 0 });\n for (const run of runs) {\n const chain = await store.verifyChain(run.runId);\n if (!chain.ok) return result('verify-state', `run ${run.runId}: event chain is broken`, 'error');\n try {\n await verifyProjectionAgainstEvents(store, run);\n } catch (error) {\n return result('verify-state', `run ${run.runId}: projection mismatch (${String(error)})`, 'error');\n }\n }\n return result('verify-state', `verified ${runs.length} run(s)`);\n } finally {\n await store.close();\n }\n },\n });\n }\n const byId = new Map(checks.map((check) => [check.id, check]));\n return Promise.all(\n DOCTOR_CHECK_IDS.map(async (id) => byId.get(id)?.run(ctx) ?? result(id, 'check unavailable', 'skipped')),\n );\n}\n","// apps/cli/src/commands/doctor/index.ts — DESIGN §9 verb `doctor` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/doctor/**`.\nimport { probeSandbox } from '@cohorte/security/exec';\nimport type { CommandModule } from '../../contract/index.ts';\nimport { runDoctor } from '../../doctor/index.ts';\n\nconst doctor: CommandModule = {\n verb: 'doctor',\n async run(ctx, args) {\n const checks = await runDoctor(ctx, { verifyState: args.positionals.includes('--verify-state') });\n if (args.json) {\n let sandbox: unknown = {};\n let runtimeCapabilities: unknown = {};\n try {\n sandbox = await probeSandbox();\n } catch {\n // The corresponding check already reports the diagnostic; keep JSON stable.\n }\n try {\n runtimeCapabilities = ctx.runtime.capabilities?.() ?? { provider: ctx.runtime.resolve().id };\n } catch {\n // A provider may be unavailable while the rest of doctor remains useful.\n }\n ctx.stdio.stdout.write(\n `${JSON.stringify({ documentVersion: 1, cohorteVersion: '3.0.0', generatedAt: ctx.clock.now(), ok: checks.every((check) => check.status === 'ok' || check.status === 'skipped'), checks, sandbox, runtimeCapabilities })}\\n`,\n );\n } else\n for (const check of checks) ctx.stdio.stdout.write(`${check.status.padEnd(7)} ${check.id}: ${check.summary}\\n`);\n return checks.some((check) => check.status === 'error') ? 1 : 0;\n },\n};\n\nexport default doctor;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"doctor-DcDFPvQM.mjs","names":[],"sources":["../../../../apps/cli/src/contract/doctor.ts","../../../../apps/cli/src/doctor/checks/auth/index.ts","../../../../apps/cli/src/doctor/index.ts","../../../../apps/cli/src/commands/doctor/index.ts"],"sourcesContent":["// apps/cli/src/contract/doctor.ts — the frozen list of doctor check modules (PLAN PC-4 \"DoctorCheck + the frozen\n// list of doctor check modules\"). `doctor/index.ts` (area barrel, U4.05) runs every id of `DOCTOR_CHECK_IDS`\n// through `doctor/checks/<id>/index.ts`; only `auth` is a Wave-0 owned stub (`apps/cli/src/doctor/checks/auth`,\n// filled by U5.05) — the rest are created, under the same shape, by U4.05.\nimport type { DOCTOR_CHECK_STATUSES } from '@cohorte/protocol';\nimport type { CliContext } from './context.ts';\n\nexport type DoctorCheckStatus = (typeof DOCTOR_CHECK_STATUSES)[number];\n\nexport interface DoctorCheckResult {\n readonly id: string;\n readonly status: DoctorCheckStatus;\n readonly summary: string;\n readonly remediation?: string;\n}\n\nexport interface DoctorCheck {\n readonly id: string;\n readonly description: string;\n run(ctx: CliContext): Promise<DoctorCheckResult>;\n}\n\n/** DESIGN §9 doctor capabilities + F-1 (ripgrep backend) + F-3 (sandbox availability) + 6.3 (protected roots). */\nexport const DOCTOR_CHECK_IDS = [\n 'node-version',\n 'git',\n 'sqlite',\n 'search-backend',\n 'sandbox',\n 'auth',\n 'install',\n 'config',\n 'worktree-root',\n] as const;\nexport type DoctorCheckId = (typeof DOCTOR_CHECK_IDS)[number];\n","// apps/cli/src/doctor/checks/auth/index.ts — the `auth` doctor check (spec 10 \"auth status\"). Wave-0 typed stub:\n// filled by `U5.05`, which owns `apps/cli/src/doctor/checks/auth/**`.\nimport type { DoctorCheck } from '../../../contract/index.ts';\n\nconst authDoctorCheck: DoctorCheck = {\n id: 'auth',\n description: \"Checks that the configured provider's authentication is usable, without reading the token.\",\n async run(ctx) {\n try {\n const statuses = await ctx.runtime.resolve().authStatus([]);\n const usable = statuses.every((status) => status.state !== 'absent' && status.state !== 'unknown-transient');\n const accountNote = statuses.some((status) => status.accountLabel === undefined)\n ? '; account: not exposed by the engine'\n : '';\n return {\n id: 'auth',\n status: usable ? 'ok' : 'warning',\n summary: `${usable ? 'runtime authentication is available' : 'runtime authentication needs attention'}${accountNote}`,\n };\n } catch (error) {\n return { id: 'auth', status: 'error', summary: `authentication status unavailable: ${String(error)}` };\n }\n },\n};\n\nexport default authDoctorCheck;\n","// apps/cli/src/doctor/index.ts — AREA barrel: runs every `DOCTOR_CHECK_IDS` entry (contract/doctor.ts) through\n// `doctor/checks/<id>/index.ts` and assembles a `DoctorReport`. Wave-0 stub: filled by `U4.05`, which owns\n// `apps/cli/src/doctor/**` (this file included); only `checks/auth/**` is carved out to `U5.05`.\nimport { execFile } from 'node:child_process';\nimport { join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { sha256Hex } from '@cohorte/base';\nimport { loadConfig, resolveConfig } from '@cohorte/config';\nimport { verifyProjectionAgainstEvents } from '@cohorte/core';\nimport { createKeyStore, createTrustStore } from '@cohorte/security/auth';\nimport { probeSandbox } from '@cohorte/security/exec';\nimport { type CliContext, DOCTOR_CHECK_IDS, type DoctorCheck, type DoctorCheckResult } from '../contract/index.ts';\nimport authDoctorCheck from './checks/auth/index.ts';\n\nconst exec = promisify(execFile);\nconst result = (id: string, summary: string, status: DoctorCheckResult['status'] = 'ok'): DoctorCheckResult => ({\n id,\n summary,\n status,\n});\n\nfunction versionAtLeast(value: string, required: [number, number]): boolean {\n const [major = 0, minor = 0] = value.split('.').map((part) => Number.parseInt(part, 10));\n return major > required[0] || (major === required[0] && minor >= required[1]);\n}\n\nexport async function runDoctor(\n ctx: CliContext,\n options: { readonly verifyState?: boolean } = {},\n): Promise<readonly DoctorCheckResult[]> {\n const checks: DoctorCheck[] = [\n {\n id: 'node-version',\n description: 'Node',\n run: async () =>\n versionAtLeast(process.versions.node, [24, 16])\n ? result('node-version', `Node ${process.versions.node}`)\n : result('node-version', `Node ${process.versions.node} is below 24.16`, 'error'),\n },\n {\n id: 'git',\n description: 'Git',\n run: async () => {\n try {\n const { stdout } = await exec('git', ['--version']);\n const version = stdout.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/)?.[1] ?? '0.0.0';\n return versionAtLeast(version, [2, 38])\n ? result('git', `Git ${version}`)\n : result('git', `Git ${version} is below 2.38`, 'error');\n } catch (error) {\n return result('git', `git unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'sqlite',\n description: 'SQLite',\n run: async () => {\n try {\n const store = await ctx.openStore();\n const info = await store.open();\n const migration = await store.migrate('check');\n await store.close();\n return migration.pending.length === 0\n ? result('sqlite', `${info.kind} schema ${info.schemaVersion}`)\n : result('sqlite', `${migration.pending.length} migration(s) pending`, 'warning');\n } catch (error) {\n return result('sqlite', `state store unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'search-backend',\n description: 'Search',\n run: async () => {\n try {\n const { stdout } = await exec('rg', ['--version']);\n return result('search-backend', `ripgrep ${stdout.split(/\\s+/u)[1] ?? 'available'}`);\n } catch {\n try {\n await exec('git', ['grep', '--version']);\n return result('search-backend', 'git grep fallback');\n } catch {\n return result('search-backend', 'neither rg nor git grep is available', 'error');\n }\n }\n },\n },\n {\n id: 'sandbox',\n description: 'Sandbox',\n run: async () => {\n const capabilities = await probeSandbox();\n return result(\n 'sandbox',\n `level=${capabilities.level}, backend=${capabilities.backend}, filesystem=${capabilities.filesystem}, network=${capabilities.network}`,\n capabilities.level === 'L0-process' ? 'warning' : 'ok',\n );\n },\n },\n authDoctorCheck,\n {\n id: 'install',\n description: 'Install',\n run: async () => {\n try {\n const verified = await ctx.assets.verify();\n return verified.ok\n ? result('install', `${ctx.install.installDir()} (assets verified)`)\n : result('install', `asset verification failed: ${verified.error.message}`, 'error');\n } catch (error) {\n return result('install', `asset verification unavailable: ${String(error)}`, 'warning');\n }\n },\n },\n {\n id: 'config',\n description: 'Config',\n run: async () => {\n try {\n const home = ctx.env.HOME ?? ctx.cwd;\n const keys = createKeyStore({ directory: join(home, '.cohorte', 'keys') });\n const trustStore = createTrustStore({ directory: join(home, '.cohorte', 'trust'), keys });\n const loaded = await loadConfig({ cwd: ctx.cwd, home });\n const resolved = await resolveConfig(loaded, {\n trustStore,\n projectKeyId: sha256Hex(loaded.projectRoot).slice(0, 24),\n });\n return resolved.status === 'resolved'\n ? result('config', `project configuration resolved at ${loaded.projectRoot}`)\n : result('config', `project policy requires trust: ${resolved.loosenedKeys.join(', ')}`, 'warning');\n } catch (error) {\n return result('config', `configuration unavailable: ${String(error)}`, 'error');\n }\n },\n },\n {\n id: 'worktree-root',\n description: 'Worktree',\n run: async () =>\n typeof process.getuid === 'function' && process.getuid() === 0\n ? result('worktree-root', 'refusing to operate as uid 0', 'error')\n : result('worktree-root', ctx.cwd),\n },\n ];\n if (options.verifyState) {\n checks.push({\n id: 'verify-state',\n description: 'State verification',\n run: async () => {\n const store = await ctx.openStore();\n try {\n const runs = await store.listRuns({ limit: 100_000, offset: 0 });\n for (const run of runs) {\n const chain = await store.verifyChain(run.runId);\n if (!chain.ok) return result('verify-state', `run ${run.runId}: event chain is broken`, 'error');\n try {\n await verifyProjectionAgainstEvents(store, run);\n } catch (error) {\n return result('verify-state', `run ${run.runId}: projection mismatch (${String(error)})`, 'error');\n }\n }\n return result('verify-state', `verified ${runs.length} run(s)`);\n } finally {\n await store.close();\n }\n },\n });\n }\n const byId = new Map(checks.map((check) => [check.id, check]));\n return Promise.all(\n DOCTOR_CHECK_IDS.map(async (id) => byId.get(id)?.run(ctx) ?? result(id, 'check unavailable', 'skipped')),\n );\n}\n","// apps/cli/src/commands/doctor/index.ts — DESIGN §9 verb `doctor` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/doctor/**`.\nimport { probeSandbox } from '@cohorte/security/exec';\nimport type { CommandModule } from '../../contract/index.ts';\nimport { runDoctor } from '../../doctor/index.ts';\n\nconst doctor: CommandModule = {\n verb: 'doctor',\n async run(ctx, args) {\n const checks = await runDoctor(ctx, { verifyState: args.positionals.includes('--verify-state') });\n if (args.json) {\n let sandbox: unknown = {};\n let runtimeCapabilities: unknown = {};\n try {\n sandbox = await probeSandbox();\n } catch {\n // The corresponding check already reports the diagnostic; keep JSON stable.\n }\n try {\n runtimeCapabilities = ctx.runtime.capabilities?.() ?? { provider: ctx.runtime.resolve().id };\n } catch {\n // A provider may be unavailable while the rest of doctor remains useful.\n }\n ctx.stdio.stdout.write(\n `${JSON.stringify({ documentVersion: 1, cohorteVersion: '3.0.0', generatedAt: ctx.clock.now(), ok: checks.every((check) => check.status === 'ok' || check.status === 'skipped'), checks, sandbox, runtimeCapabilities })}\\n`,\n );\n } else\n for (const check of checks) ctx.stdio.stdout.write(`${check.status.padEnd(7)} ${check.id}: ${check.summary}\\n`);\n return checks.some((check) => check.status === 'error') ? 1 : 0;\n },\n};\n\nexport default doctor;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { n as moveConfiguredCard } from "./obsidian-BHLkXx_H.mjs";
|
|
2
|
+
import { t as resolveSpecPath } from "./spec-path-tptqR7W8.mjs";
|
|
3
|
+
import { t as run } from "./run-NGAxdsIX.mjs";
|
|
4
|
+
import { access, readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
//#region src/commands/fix/index.ts
|
|
7
|
+
function surfacesFromReport(report) {
|
|
8
|
+
const surfaces = /* @__PURE__ */ new Set();
|
|
9
|
+
for (const match of report.matchAll(/(?:^|\s)(apps|packages)\/([A-Za-z0-9._/-]+)/gu)) {
|
|
10
|
+
const path = `${match[1]}/${match[2]}`.split("/");
|
|
11
|
+
if (path.length >= 3) surfaces.add(path.slice(0, -1).join("-"));
|
|
12
|
+
}
|
|
13
|
+
return [...surfaces].sort();
|
|
14
|
+
}
|
|
15
|
+
const fix = {
|
|
16
|
+
verb: "fix",
|
|
17
|
+
async run(ctx, args) {
|
|
18
|
+
const runId = args.positionals[0];
|
|
19
|
+
if (!runId) return 2;
|
|
20
|
+
const reportPath = args.positionals[1];
|
|
21
|
+
if (reportPath && !runId.startsWith("run_")) {
|
|
22
|
+
let specPath = resolveSpecPath(ctx.cwd, runId);
|
|
23
|
+
try {
|
|
24
|
+
await access(specPath);
|
|
25
|
+
} catch {
|
|
26
|
+
specPath = resolve(ctx.cwd, "specs", `${runId}.md`);
|
|
27
|
+
}
|
|
28
|
+
let report;
|
|
29
|
+
try {
|
|
30
|
+
report = await readFile(reportPath, "utf8");
|
|
31
|
+
} catch {
|
|
32
|
+
ctx.stdio.stderr.write(`review report not found: ${reportPath}\n`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
await access(specPath);
|
|
37
|
+
} catch {
|
|
38
|
+
ctx.stdio.stderr.write(`spec not found: ${specPath}\n`);
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
const source = await readFile(specPath, "utf8");
|
|
42
|
+
const heading = /\n## Remediation\n/u.test(source) ? "" : "\n\n## Remediation\n";
|
|
43
|
+
const entry = `\n\n### ${ctx.clock.now()}\n\n${report.trim()}\n`;
|
|
44
|
+
await writeFile(specPath, `${source.replace(/\s+$/u, "")}${heading}${entry}`, "utf8");
|
|
45
|
+
await moveConfiguredCard(ctx.env.HOME ?? ctx.cwd, runId, "fix");
|
|
46
|
+
const surfaces = surfacesFromReport(report);
|
|
47
|
+
const followUp = await run.run(ctx, {
|
|
48
|
+
...args,
|
|
49
|
+
positionals: [
|
|
50
|
+
runId,
|
|
51
|
+
specPath,
|
|
52
|
+
"--profile",
|
|
53
|
+
"feature",
|
|
54
|
+
"--phases",
|
|
55
|
+
"PREFLIGHT,BUILD,TEST,REVIEW",
|
|
56
|
+
...surfaces.length > 0 ? ["--surfaces", surfaces.join(",")] : [],
|
|
57
|
+
"--with-fix"
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
ctx.stdio.stdout.write(`${JSON.stringify({
|
|
61
|
+
feature: runId,
|
|
62
|
+
specPath,
|
|
63
|
+
reportPath,
|
|
64
|
+
status: "remediation-recorded",
|
|
65
|
+
surfaces,
|
|
66
|
+
followUp
|
|
67
|
+
})}\n`);
|
|
68
|
+
return followUp;
|
|
69
|
+
}
|
|
70
|
+
const result = await ctx.controller.send("retry", { target: {
|
|
71
|
+
kind: "phase",
|
|
72
|
+
state: "FIX"
|
|
73
|
+
} }, { runId });
|
|
74
|
+
ctx.stdio.stdout.write(`${JSON.stringify(result)}\n`);
|
|
75
|
+
if (result.status === "pending" || result.status === "completed") await moveConfiguredCard(ctx.env.HOME ?? ctx.cwd, runId, "fix");
|
|
76
|
+
return result.status === "rejected" ? 3 : result.status === "pending" ? 4 : 0;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { fix as default };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=fix-B_oGzGVn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-B_oGzGVn.mjs","names":[],"sources":["../../../../apps/cli/src/commands/fix/index.ts"],"sourcesContent":["// apps/cli/src/commands/fix/index.ts — DESIGN §9 verb `fix` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/fix/**`.\nimport { access, readFile, writeFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport type { CommandModule } from '../../contract/index.ts';\nimport { resolveSpecPath } from '../../project/spec-path.ts';\nimport { moveConfiguredCard } from '../obsidian/index.ts';\nimport run from '../run/index.ts';\n\nfunction surfacesFromReport(report: string): string[] {\n const surfaces = new Set<string>();\n for (const match of report.matchAll(/(?:^|\\s)(apps|packages)\\/([A-Za-z0-9._/-]+)/gu)) {\n const path = `${match[1]}/${match[2]}`.split('/');\n if (path.length >= 3) surfaces.add(path.slice(0, -1).join('-'));\n }\n return [...surfaces].sort();\n}\n\nconst fix: CommandModule = {\n verb: 'fix',\n async run(ctx, args) {\n const runId = args.positionals[0];\n if (!runId) return 2;\n const reportPath = args.positionals[1];\n if (reportPath && !runId.startsWith('run_')) {\n let specPath = resolveSpecPath(ctx.cwd, runId);\n try {\n await access(specPath);\n } catch {\n specPath = resolve(ctx.cwd, 'specs', `${runId}.md`);\n }\n let report: string;\n try {\n report = await readFile(reportPath, 'utf8');\n } catch {\n ctx.stdio.stderr.write(`review report not found: ${reportPath}\\n`);\n return 1;\n }\n try {\n await access(specPath);\n } catch {\n ctx.stdio.stderr.write(`spec not found: ${specPath}\\n`);\n return 1;\n }\n const source = await readFile(specPath, 'utf8');\n const heading = /\\n## Remediation\\n/u.test(source) ? '' : '\\n\\n## Remediation\\n';\n const entry = `\\n\\n### ${ctx.clock.now()}\\n\\n${report.trim()}\\n`;\n await writeFile(specPath, `${source.replace(/\\s+$/u, '')}${heading}${entry}`, 'utf8');\n await moveConfiguredCard(ctx.env.HOME ?? ctx.cwd, runId, 'fix');\n const surfaces = surfacesFromReport(report);\n const followUp = await run.run(ctx, {\n ...args,\n positionals: [\n runId,\n specPath,\n '--profile',\n 'feature',\n '--phases',\n 'PREFLIGHT,BUILD,TEST,REVIEW',\n ...(surfaces.length > 0 ? ['--surfaces', surfaces.join(',')] : []),\n '--with-fix',\n ],\n });\n ctx.stdio.stdout.write(\n `${JSON.stringify({ feature: runId, specPath, reportPath, status: 'remediation-recorded', surfaces, followUp })}\\n`,\n );\n return followUp;\n }\n const result = await ctx.controller.send('retry', { target: { kind: 'phase', state: 'FIX' } }, { runId });\n ctx.stdio.stdout.write(`${JSON.stringify(result)}\\n`);\n if (result.status === 'pending' || result.status === 'completed')\n await moveConfiguredCard(ctx.env.HOME ?? ctx.cwd, runId, 'fix');\n return result.status === 'rejected' ? 3 : result.status === 'pending' ? 4 : 0;\n },\n};\n\nexport default fix;\n"],"mappings":";;;;;;AAWA,SAAS,mBAAmB,QAA0B;CACpD,MAAM,2BAAW,IAAI,IAAY;CACjC,KAAK,MAAM,SAAS,OAAO,SAAS,+CAA+C,GAAG;EACpF,MAAM,OAAO,GAAG,MAAM,GAAG,GAAG,MAAM,KAAK,MAAM,GAAG;EAChD,IAAI,KAAK,UAAU,GAAG,SAAS,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC;CAChE;CACA,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK;AAC5B;AAEA,MAAM,MAAqB;CACzB,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,QAAQ,KAAK,YAAY;EAC/B,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,aAAa,KAAK,YAAY;EACpC,IAAI,cAAc,CAAC,MAAM,WAAW,MAAM,GAAG;GAC3C,IAAI,WAAW,gBAAgB,IAAI,KAAK,KAAK;GAC7C,IAAI;IACF,MAAM,OAAO,QAAQ;GACvB,QAAQ;IACN,WAAW,QAAQ,IAAI,KAAK,SAAS,GAAG,MAAM,IAAI;GACpD;GACA,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,SAAS,YAAY,MAAM;GAC5C,QAAQ;IACN,IAAI,MAAM,OAAO,MAAM,4BAA4B,WAAW,GAAG;IACjE,OAAO;GACT;GACA,IAAI;IACF,MAAM,OAAO,QAAQ;GACvB,QAAQ;IACN,IAAI,MAAM,OAAO,MAAM,mBAAmB,SAAS,GAAG;IACtD,OAAO;GACT;GACA,MAAM,SAAS,MAAM,SAAS,UAAU,MAAM;GAC9C,MAAM,UAAU,sBAAsB,KAAK,MAAM,IAAI,KAAK;GAC1D,MAAM,QAAQ,WAAW,IAAI,MAAM,IAAI,EAAE,MAAM,OAAO,KAAK,EAAE;GAC7D,MAAM,UAAU,UAAU,GAAG,OAAO,QAAQ,SAAS,EAAE,IAAI,UAAU,SAAS,MAAM;GACpF,MAAM,mBAAmB,IAAI,IAAI,QAAQ,IAAI,KAAK,OAAO,KAAK;GAC9D,MAAM,WAAW,mBAAmB,MAAM;GAC1C,MAAM,WAAW,MAAM,IAAI,IAAI,KAAK;IAClC,GAAG;IACH,aAAa;KACX;KACA;KACA;KACA;KACA;KACA;KACA,GAAI,SAAS,SAAS,IAAI,CAAC,cAAc,SAAS,KAAK,GAAG,CAAC,IAAI,CAAC;KAChE;IACF;GACF,CAAC;GACD,IAAI,MAAM,OAAO,MACf,GAAG,KAAK,UAAU;IAAE,SAAS;IAAO;IAAU;IAAY,QAAQ;IAAwB;IAAU;GAAS,CAAC,EAAE,GAClH;GACA,OAAO;EACT;EACA,MAAM,SAAS,MAAM,IAAI,WAAW,KAAK,SAAS,EAAE,QAAQ;GAAE,MAAM;GAAS,OAAO;EAAM,EAAE,GAAG,EAAE,MAAM,CAAC;EACxG,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;EACpD,IAAI,OAAO,WAAW,aAAa,OAAO,WAAW,aACnD,MAAM,mBAAmB,IAAI,IAAI,QAAQ,IAAI,KAAK,OAAO,KAAK;EAChE,OAAO,OAAO,WAAW,aAAa,IAAI,OAAO,WAAW,YAAY,IAAI;CAC9E;AACF"}
|