@seanmars/tospec 0.19.0-beta.7 → 0.19.0-beta.8
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/CHANGELOG.md +80 -1
- package/assets/dashboard/app.js +3 -3
- package/assets/rules/tospec/decision.md +3 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +191 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +135 -24
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +2 -2
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +75 -10
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +11 -0
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +164 -26
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/shared-output.d.ts +12 -0
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +50 -1
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts +10 -0
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +13 -3
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +23 -1
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +61 -12
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/index.d.ts +5 -5
- package/dist/commands/workflow/index.d.ts.map +1 -1
- package/dist/commands/workflow/index.js +5 -5
- package/dist/commands/workflow/index.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts +23 -0
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +84 -16
- package/dist/commands/workflow/instructions.js.map +1 -1
- package/dist/commands/workflow/new-change.d.ts +2 -0
- package/dist/commands/workflow/new-change.d.ts.map +1 -1
- package/dist/commands/workflow/new-change.js +32 -4
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/schemas.d.ts +2 -0
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +38 -1
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +34 -2
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +37 -3
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +62 -8
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/commands/workflow/templates.d.ts +7 -0
- package/dist/commands/workflow/templates.d.ts.map +1 -1
- package/dist/commands/workflow/templates.js +13 -0
- package/dist/commands/workflow/templates.js.map +1 -1
- package/dist/core/archive.d.ts +14 -0
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +151 -21
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/index.d.ts +1 -1
- package/dist/core/artifact-graph/index.d.ts.map +1 -1
- package/dist/core/artifact-graph/index.js +1 -1
- package/dist/core/artifact-graph/index.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +63 -3
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +35 -26
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/resolver.d.ts +26 -0
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
- package/dist/core/artifact-graph/resolver.js +44 -4
- package/dist/core/artifact-graph/resolver.js.map +1 -1
- package/dist/core/artifact-graph/stub-detection.d.ts +20 -0
- package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -0
- package/dist/core/artifact-graph/stub-detection.js +42 -0
- package/dist/core/artifact-graph/stub-detection.js.map +1 -0
- package/dist/core/change-presenter.d.ts +16 -0
- package/dist/core/change-presenter.d.ts.map +1 -1
- package/dist/core/change-presenter.js +68 -9
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts +12 -1
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/change-status-policy.js +33 -1
- package/dist/core/change-status-policy.js.map +1 -1
- package/dist/core/codex-residue.js +1 -1
- package/dist/core/config-schema.d.ts +1 -12
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +27 -1
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/config.d.ts +37 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +37 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/dashboard-activity.js +2 -2
- package/dist/core/dashboard-activity.js.map +1 -1
- package/dist/core/dashboard-data.d.ts +5 -0
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +15 -8
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/init.d.ts +22 -0
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +107 -42
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +68 -17
- package/dist/core/list.js.map +1 -1
- package/dist/core/markdown-render.d.ts +33 -0
- package/dist/core/markdown-render.d.ts.map +1 -0
- package/dist/core/markdown-render.js +103 -0
- package/dist/core/markdown-render.js.map +1 -0
- package/dist/core/migrate.d.ts +17 -5
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +48 -2
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.js +1 -1
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +16 -0
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/root-selection.d.ts +11 -1
- package/dist/core/root-selection.d.ts.map +1 -1
- package/dist/core/root-selection.js +4 -2
- package/dist/core/root-selection.js.map +1 -1
- package/dist/core/rules.d.ts +6 -1
- package/dist/core/rules.d.ts.map +1 -1
- package/dist/core/rules.js +24 -2
- package/dist/core/rules.js.map +1 -1
- package/dist/core/schemas/base.schema.d.ts +3 -0
- package/dist/core/schemas/base.schema.d.ts.map +1 -1
- package/dist/core/schemas/base.schema.js +22 -0
- package/dist/core/schemas/base.schema.js.map +1 -1
- package/dist/core/schemas/change.schema.d.ts +8 -0
- package/dist/core/schemas/change.schema.d.ts.map +1 -1
- package/dist/core/schemas/spec.schema.d.ts +2 -0
- package/dist/core/schemas/spec.schema.d.ts.map +1 -1
- package/dist/core/shared/index.d.ts +1 -1
- package/dist/core/shared/index.d.ts.map +1 -1
- package/dist/core/shared/index.js +1 -1
- package/dist/core/shared/index.js.map +1 -1
- package/dist/core/shared/rules-generation.d.ts +27 -6
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +115 -44
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +19 -0
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +30 -2
- package/dist/core/shared/tool-detection.js.map +1 -1
- package/dist/core/spec-presenter.d.ts.map +1 -1
- package/dist/core/spec-presenter.js +5 -0
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts +15 -1
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +33 -11
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/workflows/apply.js +1 -1
- package/dist/core/templates/workflows/apply.js.map +1 -1
- package/dist/core/templates/workflows/archive.d.ts.map +1 -1
- package/dist/core/templates/workflows/archive.js +4 -2
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.js +1 -1
- package/dist/core/update.d.ts +26 -0
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +111 -23
- package/dist/core/update.js.map +1 -1
- package/dist/core/validation/constants.d.ts +1 -1
- package/dist/core/validation/constants.d.ts.map +1 -1
- package/dist/core/validation/constants.js +6 -1
- package/dist/core/validation/constants.js.map +1 -1
- package/dist/core/validation/section-validator.d.ts.map +1 -1
- package/dist/core/validation/section-validator.js +21 -3
- package/dist/core/validation/section-validator.js.map +1 -1
- package/dist/core/validation/validator.d.ts +9 -3
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +58 -8
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/utils/change-utils.d.ts +28 -0
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +115 -26
- package/dist/utils/change-utils.js.map +1 -1
- package/dist/utils/file-system.d.ts +1 -1
- package/dist/utils/file-system.js +1 -1
- package/dist/utils/item-discovery.d.ts +20 -5
- package/dist/utils/item-discovery.d.ts.map +1 -1
- package/dist/utils/item-discovery.js +28 -9
- package/dist/utils/item-discovery.js.map +1 -1
- package/dist/utils/task-progress.js +1 -1
- package/package.json +1 -1
- package/schemas/decision/templates/decision.md +3 -1
- package/schemas/decision/templates/index.md +2 -2
- package/schemas/issue/templates/spec.md +8 -0
- package/schemas/sdd/templates/spec.md +8 -0
- /package/assets/rules/tospec/{single-sourc-of-truth.md → single-source-of-truth.md} +0 -0
|
@@ -16,6 +16,20 @@ export interface StatusOptions {
|
|
|
16
16
|
* reference this one constant rather than each spelling the shape out.
|
|
17
17
|
*/
|
|
18
18
|
export declare const BATCH_STATUS_FAILURE_PAYLOAD: Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* The single-change `--json` failure null-shape.
|
|
21
|
+
*
|
|
22
|
+
* Flat payload, like `instructions` and `show`: it spreads `changeName`,
|
|
23
|
+
* `artifacts` and a dozen siblings at the top level rather than nesting them
|
|
24
|
+
* under a wrapper. Per
|
|
25
|
+
* decisions/20260917_155623-flat-json-payloads-null-a-real-success-key.md, such
|
|
26
|
+
* a command nulls a key its success output really carries — `changeName` here,
|
|
27
|
+
* as `instruction` and `id` do there. It previously nulled nothing at all, which
|
|
28
|
+
* left this the one envelope a caller could not tell apart from an unrelated
|
|
29
|
+
* error document; the ADR's two tests both pass vacuously on an empty key set,
|
|
30
|
+
* so the rule had to be asserted directly (see json-failure.test.ts).
|
|
31
|
+
*/
|
|
32
|
+
export declare const STATUS_FAILURE_PAYLOAD: Record<string, unknown>;
|
|
19
33
|
export declare function statusCommand(options: StatusOptions): Promise<void>;
|
|
20
34
|
export declare function printStatusText(status: ChangeStatus): void;
|
|
21
35
|
//# sourceMappingURL=status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oCAAoC,CAAC;AAe5C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AASD;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAiC,CAAC;AAEnG;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAoC,CAAC;AAMhG,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmJzE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CA6C1D"}
|
|
@@ -6,14 +6,29 @@
|
|
|
6
6
|
import { getChangeDir } from '../../core/planning-home.js';
|
|
7
7
|
import { resolveRootForCommand, toPlanningHome, toRootOutput, } from '../../core/root-selection.js';
|
|
8
8
|
import { loadChangeContext, formatChangeStatus, } from '../../core/artifact-graph/index.js';
|
|
9
|
-
import { validateChangeExists, validateSchemaExists, getAvailableChanges, getStatusIndicator, } from './shared.js';
|
|
9
|
+
import { validateChangeExists, validateSchemaExists, assertChangeSchema, getAvailableChanges, getStatusIndicator, } from './shared.js';
|
|
10
10
|
import { emitSuccess, asStatus } from '../shared-output.js';
|
|
11
|
+
import { findTicketPath } from '../../utils/item-discovery.js';
|
|
11
12
|
/**
|
|
12
13
|
* The `--all --json` failure null-shape. Root selection resolves inside this
|
|
13
14
|
* module while thrown errors are caught by the CLI wrapper, so both call sites
|
|
14
15
|
* reference this one constant rather than each spelling the shape out.
|
|
15
16
|
*/
|
|
16
|
-
export const BATCH_STATUS_FAILURE_PAYLOAD = { changes: null };
|
|
17
|
+
export const BATCH_STATUS_FAILURE_PAYLOAD = { changes: null, root: null };
|
|
18
|
+
/**
|
|
19
|
+
* The single-change `--json` failure null-shape.
|
|
20
|
+
*
|
|
21
|
+
* Flat payload, like `instructions` and `show`: it spreads `changeName`,
|
|
22
|
+
* `artifacts` and a dozen siblings at the top level rather than nesting them
|
|
23
|
+
* under a wrapper. Per
|
|
24
|
+
* decisions/20260917_155623-flat-json-payloads-null-a-real-success-key.md, such
|
|
25
|
+
* a command nulls a key its success output really carries — `changeName` here,
|
|
26
|
+
* as `instruction` and `id` do there. It previously nulled nothing at all, which
|
|
27
|
+
* left this the one envelope a caller could not tell apart from an unrelated
|
|
28
|
+
* error document; the ADR's two tests both pass vacuously on an empty key set,
|
|
29
|
+
* so the rule had to be asserted directly (see json-failure.test.ts).
|
|
30
|
+
*/
|
|
31
|
+
export const STATUS_FAILURE_PAYLOAD = { changeName: null, root: null };
|
|
17
32
|
// -----------------------------------------------------------------------------
|
|
18
33
|
// Command Implementation
|
|
19
34
|
// -----------------------------------------------------------------------------
|
|
@@ -23,9 +38,16 @@ export async function statusCommand(options) {
|
|
|
23
38
|
}
|
|
24
39
|
// The batch null-shape rides along so a root-selection failure under
|
|
25
40
|
// --all --json still carries `changes: null` rather than an empty payload.
|
|
41
|
+
//
|
|
42
|
+
// No implicit root: it resolves only when no ancestor holds a `tospec/` dir,
|
|
43
|
+
// and status would then answer "No active changes." with exit 0 about a
|
|
44
|
+
// directory that is not a project at all — the same vacuous pass `validate`
|
|
45
|
+
// refuses implicit roots to avoid. `list` and `archive` refuse it too, so all
|
|
46
|
+
// four now report the one `no_tospec_root` diagnostic for the one condition.
|
|
26
47
|
const root = await resolveRootForCommand(options, {
|
|
27
48
|
json: options.json,
|
|
28
|
-
|
|
49
|
+
allowImplicitRoot: false,
|
|
50
|
+
failurePayload: options.all ? BATCH_STATUS_FAILURE_PAYLOAD : STATUS_FAILURE_PAYLOAD,
|
|
29
51
|
});
|
|
30
52
|
if (!root) {
|
|
31
53
|
return;
|
|
@@ -40,6 +62,15 @@ export async function statusCommand(options) {
|
|
|
40
62
|
changeDir: getChangeDir(planningHome, changeName),
|
|
41
63
|
planningHome,
|
|
42
64
|
}));
|
|
65
|
+
// The ticket lives outside the change dir under a CLI-generated timestamp, so
|
|
66
|
+
// it appears in no artifact path — an agent asked to fill in its Summary had
|
|
67
|
+
// to glob `tospec/tickets/` and match frontmatter by hand. Added here, inside
|
|
68
|
+
// the shared loader, so the batch and single-change payloads keep reporting
|
|
69
|
+
// the same fields.
|
|
70
|
+
const loadStatusWithTicket = async (changeName) => ({
|
|
71
|
+
...loadStatus(changeName),
|
|
72
|
+
ticketPath: (await findTicketPath(projectRoot, changeName)) ?? null,
|
|
73
|
+
});
|
|
43
74
|
// Handle no-changes case gracefully — status is informational,
|
|
44
75
|
// so "no changes" is a valid state, not an error.
|
|
45
76
|
if (!options.change) {
|
|
@@ -47,6 +78,7 @@ export async function statusCommand(options) {
|
|
|
47
78
|
// the same way whether or not any change exists yet.
|
|
48
79
|
if (options.all && options.schema) {
|
|
49
80
|
validateSchemaExists(options.schema, projectRoot);
|
|
81
|
+
assertChangeSchema(options.schema);
|
|
50
82
|
}
|
|
51
83
|
const available = await getAvailableChanges(projectRoot, root.changesDir);
|
|
52
84
|
if (available.length === 0) {
|
|
@@ -63,7 +95,7 @@ export async function statusCommand(options) {
|
|
|
63
95
|
const entries = [];
|
|
64
96
|
for (const changeName of available.sort((a, b) => a.localeCompare(b))) {
|
|
65
97
|
try {
|
|
66
|
-
entries.push(
|
|
98
|
+
entries.push(await loadStatusWithTicket(changeName));
|
|
67
99
|
}
|
|
68
100
|
catch (error) {
|
|
69
101
|
entries.push({ changeName, status: [asStatus(error, 'change_error')] });
|
|
@@ -101,17 +133,31 @@ export async function statusCommand(options) {
|
|
|
101
133
|
// every change should not have to find it in --help.
|
|
102
134
|
throw new Error(`Missing required option --change (or --all for every active change). Available changes:\n ${available.join('\n ')}`);
|
|
103
135
|
}
|
|
104
|
-
|
|
105
|
-
//
|
|
136
|
+
// Validate schema if explicitly provided.
|
|
137
|
+
//
|
|
138
|
+
// Guarded for the same reason as `instructions` and `new change`, and with
|
|
139
|
+
// more force: `status --schema decision` planned an artifact at
|
|
140
|
+
// tospec/changes/<change>/decision.md — the orphan file those two already
|
|
141
|
+
// refuse — and then handed back a nextSteps line telling the caller to run
|
|
142
|
+
// `tospec instructions decision`, which refuses. The two commands together
|
|
143
|
+
// formed a closed loop: the one that issues the instruction was the one
|
|
144
|
+
// without the check.
|
|
145
|
+
//
|
|
146
|
+
// Before change resolution, not after (round 4 report 15). Sitting after it,
|
|
147
|
+
// the guard never fired in an empty project: the caller got "Create one with:
|
|
148
|
+
// tospec new change <name>", did exactly that, and only then learned the
|
|
149
|
+
// schema was never usable — the misdirection this guard was added to remove.
|
|
106
150
|
if (options.schema) {
|
|
107
151
|
validateSchemaExists(options.schema, projectRoot);
|
|
152
|
+
assertChangeSchema(options.schema);
|
|
108
153
|
}
|
|
154
|
+
const changeName = await validateChangeExists(options.change, projectRoot, root.changesDir, { newChangeHint });
|
|
109
155
|
// loadChangeContext will auto-detect schema from metadata if not provided
|
|
110
|
-
const status = loadStatus(changeName);
|
|
111
156
|
if (options.json) {
|
|
112
|
-
emitSuccess({ ...
|
|
157
|
+
emitSuccess({ ...(await loadStatusWithTicket(changeName)) }, rootOutput);
|
|
113
158
|
return;
|
|
114
159
|
}
|
|
160
|
+
const status = loadStatus(changeName);
|
|
115
161
|
printStatusText(status);
|
|
116
162
|
}
|
|
117
163
|
export function printStatusText(status) {
|
|
@@ -133,6 +179,14 @@ export function printStatusText(status) {
|
|
|
133
179
|
if (artifact.status === 'stub') {
|
|
134
180
|
line += ' (stub: file exists but is empty or template-identical — fill it in)';
|
|
135
181
|
}
|
|
182
|
+
// The two share a marker; the label is what tells them apart, and the
|
|
183
|
+
// difference is whether writing it is still on the table.
|
|
184
|
+
if (artifact.status === 'optional') {
|
|
185
|
+
line += ' (optional: not written — write it if this change needs it)';
|
|
186
|
+
}
|
|
187
|
+
if (artifact.status === 'skipped') {
|
|
188
|
+
line += ' (skipped: this change declared it away)';
|
|
189
|
+
}
|
|
136
190
|
console.log(line);
|
|
137
191
|
}
|
|
138
192
|
for (const diagnostic of status.status ?? []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,YAAY,GACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAEnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAA0B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Shows resolved template paths for all artifacts in a schema.
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* The `--json` null-shape. Exported so the commander-level shape table and this
|
|
8
|
+
* command's own catch block read the same object instead of two literals that
|
|
9
|
+
* drifted — the catch block's copy was missing `root`, which every success
|
|
10
|
+
* payload carries.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TEMPLATES_FAILURE_PAYLOAD: Record<string, unknown>;
|
|
6
13
|
export interface TemplatesOptions {
|
|
7
14
|
schema?: string;
|
|
8
15
|
json?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAMD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE/E"}
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAG7D,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAMD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiE/E"}
|
|
@@ -10,6 +10,19 @@ import { validateSchemaExists, DEFAULT_SCHEMA } from './shared.js';
|
|
|
10
10
|
import { emitSuccess } from '../shared-output.js';
|
|
11
11
|
import { resolveRootForCommand, toRootOutput } from '../../core/root-selection.js';
|
|
12
12
|
// -----------------------------------------------------------------------------
|
|
13
|
+
// Types
|
|
14
|
+
// -----------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* The `--json` null-shape. Exported so the commander-level shape table and this
|
|
17
|
+
* command's own catch block read the same object instead of two literals that
|
|
18
|
+
* drifted — the catch block's copy was missing `root`, which every success
|
|
19
|
+
* payload carries.
|
|
20
|
+
*/
|
|
21
|
+
export const TEMPLATES_FAILURE_PAYLOAD = {
|
|
22
|
+
templates: null,
|
|
23
|
+
root: null,
|
|
24
|
+
};
|
|
25
|
+
// -----------------------------------------------------------------------------
|
|
13
26
|
// Command Implementation
|
|
14
27
|
// -----------------------------------------------------------------------------
|
|
15
28
|
export async function templatesCommand(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,GACd,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEnF,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA4B;IAChE,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,IAAI;CACX,CAAC;AAaF,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAyB;IAC9D,oEAAoE;IACpE,2EAA2E;IAC3E,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE;QAChD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;KACpC,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,IAAI,cAAc,EAAE,WAAW,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,EAAE,WAAW,CAAE,CAAC;IAEzD,mDAAmD;IACnD,MAAM,EACJ,iBAAiB,EACjB,oBAAoB,GACrB,GAAG,MAAM,MAAM,CAAC,uCAAuC,CAAC,CAAC;IAC1D,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;IAE3C,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,MAAc,EAAW,EAAE;QAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC,CAAC;IAEF,IAAI,MAAsC,CAAC;IAC3C,IAAI,WAAW,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;SAAM,IAAI,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,CAAC;QAClD,MAAM,GAAG,MAAM,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,SAAS,GAAmB,KAAK,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC3E,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,YAAY,EAAE,eAAe,CAAC,wBAAwB,CACpD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CACrD;QACD,MAAM;KACP,CAAC,CAAC,CAAC;IAEJ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,MAAM,GAAqD,EAAE,CAAC;QACpE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACpE,CAAC;QACD,WAAW,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IACrC,CAAC;AACH,CAAC"}
|
package/dist/core/archive.d.ts
CHANGED
|
@@ -40,6 +40,20 @@ export declare class ArchiveCommand {
|
|
|
40
40
|
* step by hand for the "every blocked path throws in JSON mode" invariant.
|
|
41
41
|
*/
|
|
42
42
|
private gate;
|
|
43
|
+
/**
|
|
44
|
+
* Required artifacts the change never produced, in schema order.
|
|
45
|
+
*
|
|
46
|
+
* Reads the same graph `tospec status` does, so the two can never disagree
|
|
47
|
+
* about what "required" means. `skipped` covers the legitimate opt-out
|
|
48
|
+
* (`skip_specs: true`), and optional artifacts are the schema's own statement
|
|
49
|
+
* that their absence is fine — neither is reported here.
|
|
50
|
+
*
|
|
51
|
+
* A change whose graph cannot be loaded at all (unreadable metadata, unknown
|
|
52
|
+
* schema) returns nothing rather than throwing: this gate exists to describe
|
|
53
|
+
* a change, not to become a second way for archive to fail on one. Whatever
|
|
54
|
+
* broke the load is already validation's to report.
|
|
55
|
+
*/
|
|
56
|
+
private findMissingRequiredArtifacts;
|
|
43
57
|
/**
|
|
44
58
|
* Shared archive flow. In human mode (json=false) prompts and prose match
|
|
45
59
|
* the historical behavior and cancellations return null. In JSON mode no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,wBAAkB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAYjF;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AA2DD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5E;AAgED,2FAA2F;AAC3F,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYvE;AAED,qBAAa,cAAc;IACnB,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC9E;IAED,OAAO,CAAC,gBAAgB;IAiBxB;;;;;;;OAOG;YACW,IAAI;IAoClB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,4BAA4B;IAuBpC;;;;OAIG;YACW,GAAG;YAweH,YAAY;CAwC3B"}
|
package/dist/core/archive.js
CHANGED
|
@@ -5,11 +5,12 @@ import { Validator } from './validation/validator.js';
|
|
|
5
5
|
import { validateChangeArtifacts } from '../commands/validate.js';
|
|
6
6
|
import { isRootSelectionError, resolveRootForCommand, toRootOutput, } from './root-selection.js';
|
|
7
7
|
import { findSpecUpdates, buildUpdatedSpec, writeUpdatedSpec, retireSpec, } from './specs-apply.js';
|
|
8
|
+
import { loadChangeContext, formatChangeStatus } from './artifact-graph/index.js';
|
|
8
9
|
import { formatTimestamp } from '../utils/timestamp.js';
|
|
9
10
|
import { findSpecFiles } from '../utils/spec-files.js';
|
|
10
11
|
import { FileSystemUtils, isMissingPathError } from '../utils/file-system.js';
|
|
11
12
|
import { isKebabId, KEBAB_ID_DESCRIPTION } from './id.js';
|
|
12
|
-
import {
|
|
13
|
+
import { findTicketPaths, listActiveChangeDirs } from '../utils/item-discovery.js';
|
|
13
14
|
import { METADATA_FILENAME, readChangeMetadata } from '../utils/change-metadata.js';
|
|
14
15
|
import { emitSuccess, emitFailureStatus } from '../commands/shared-output.js';
|
|
15
16
|
/**
|
|
@@ -169,7 +170,12 @@ export class ArchiveCommand {
|
|
|
169
170
|
// Same root resolution adapter as every other command (report 4.3).
|
|
170
171
|
const root = await resolveRootForCommand(options, {
|
|
171
172
|
json,
|
|
172
|
-
|
|
173
|
+
// See workflow/status.ts: an implicit root means no ancestor holds a
|
|
174
|
+
// `tospec/` dir, and archiving there can only fail — but with a plain
|
|
175
|
+
// "no changes directory" message rather than the shared no_tospec_root
|
|
176
|
+
// diagnostic its sibling commands report for the same condition.
|
|
177
|
+
allowImplicitRoot: false,
|
|
178
|
+
failurePayload: { archive: null, root: null },
|
|
173
179
|
});
|
|
174
180
|
if (!root) {
|
|
175
181
|
return;
|
|
@@ -178,32 +184,32 @@ export class ArchiveCommand {
|
|
|
178
184
|
// A gate overridden by --yes has something to report but did not fail —
|
|
179
185
|
// exit 0 stands, and the warning rides on `status` instead of being
|
|
180
186
|
// dropped, since prose on stdout would corrupt the JSON document.
|
|
181
|
-
const
|
|
187
|
+
const jsonWarnings = [];
|
|
182
188
|
try {
|
|
183
|
-
const result = await this.run(changeName, options, root, true,
|
|
189
|
+
const result = await this.run(changeName, options, root, true, jsonWarnings);
|
|
184
190
|
if (!result) {
|
|
185
191
|
return;
|
|
186
192
|
}
|
|
187
|
-
emitSuccess({ archive: result, ...(
|
|
193
|
+
emitSuccess({ archive: result, ...(jsonWarnings.length ? { status: jsonWarnings } : {}) }, toRootOutput(root));
|
|
188
194
|
}
|
|
189
195
|
catch (error) {
|
|
190
196
|
// The gates that were overridden before the failure still happened, and
|
|
191
197
|
// a run that both skipped validation *and* then failed is exactly when
|
|
192
198
|
// the reader needs to know. Dropping them here reproduced, on the
|
|
193
199
|
// failure path, the discard this collection exists to prevent.
|
|
194
|
-
this.printJsonFailure(root, toArchiveDiagnostic(error),
|
|
200
|
+
this.printJsonFailure(root, toArchiveDiagnostic(error), jsonWarnings);
|
|
195
201
|
}
|
|
196
202
|
return;
|
|
197
203
|
}
|
|
198
204
|
await this.run(changeName, options, root, false, []);
|
|
199
205
|
}
|
|
200
|
-
printJsonFailure(root, diagnostic,
|
|
206
|
+
printJsonFailure(root, diagnostic, jsonWarnings = []) {
|
|
201
207
|
// emitFailureStatus appends the error to any `status` already in the
|
|
202
208
|
// payload, so the warnings keep their order and precede the failure.
|
|
203
209
|
emitFailureStatus({
|
|
204
210
|
archive: null,
|
|
205
211
|
...(root ? { root: toRootOutput(root) } : {}),
|
|
206
|
-
...(
|
|
212
|
+
...(jsonWarnings.length ? { status: jsonWarnings } : {}),
|
|
207
213
|
}, diagnostic);
|
|
208
214
|
}
|
|
209
215
|
/**
|
|
@@ -217,7 +223,12 @@ export class ArchiveCommand {
|
|
|
217
223
|
async gate(opts) {
|
|
218
224
|
if (opts.yes) {
|
|
219
225
|
if (opts.json) {
|
|
220
|
-
|
|
226
|
+
// No `fix`. Every gate's fix is phrased for the caller who is being
|
|
227
|
+
// blocked and ends in "or rerun with --yes" — advice that read as
|
|
228
|
+
// nonsense in the output of a run that already passed `--yes`, telling
|
|
229
|
+
// the reader to do the thing they just did. The archive has happened;
|
|
230
|
+
// there is nothing left to act on, so the message stands alone.
|
|
231
|
+
opts.warnings.push({ severity: 'warning', code: opts.code, message: opts.message });
|
|
221
232
|
}
|
|
222
233
|
else {
|
|
223
234
|
console.error(opts.warning);
|
|
@@ -235,12 +246,42 @@ export class ArchiveCommand {
|
|
|
235
246
|
}
|
|
236
247
|
return true;
|
|
237
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Required artifacts the change never produced, in schema order.
|
|
251
|
+
*
|
|
252
|
+
* Reads the same graph `tospec status` does, so the two can never disagree
|
|
253
|
+
* about what "required" means. `skipped` covers the legitimate opt-out
|
|
254
|
+
* (`skip_specs: true`), and optional artifacts are the schema's own statement
|
|
255
|
+
* that their absence is fine — neither is reported here.
|
|
256
|
+
*
|
|
257
|
+
* A change whose graph cannot be loaded at all (unreadable metadata, unknown
|
|
258
|
+
* schema) returns nothing rather than throwing: this gate exists to describe
|
|
259
|
+
* a change, not to become a second way for archive to fail on one. Whatever
|
|
260
|
+
* broke the load is already validation's to report.
|
|
261
|
+
*/
|
|
262
|
+
findMissingRequiredArtifacts(projectRoot, changeName, changeDir) {
|
|
263
|
+
try {
|
|
264
|
+
// Schema left undefined on purpose: loadChangeContext reads it from the
|
|
265
|
+
// change's own metadata, the same way `status` does.
|
|
266
|
+
const status = formatChangeStatus(loadChangeContext(projectRoot, changeName, undefined, { changeDir }));
|
|
267
|
+
return status.artifacts
|
|
268
|
+
.filter((artifact) => !artifact.optional && artifact.status !== 'done' && artifact.status !== 'skipped')
|
|
269
|
+
// A stub's file is on disk and still holds the template, so reporting it
|
|
270
|
+
// the same way as an absent one sent the reader to look for a file that
|
|
271
|
+
// was right there. The status is what distinguishes the two, and it is
|
|
272
|
+
// already in hand here.
|
|
273
|
+
.map((artifact) => (artifact.status === 'stub' ? `${artifact.id} (stub)` : artifact.id));
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
}
|
|
238
279
|
/**
|
|
239
280
|
* Shared archive flow. In human mode (json=false) prompts and prose match
|
|
240
281
|
* the historical behavior and cancellations return null. In JSON mode no
|
|
241
282
|
* prose reaches stdout and every blocked path throws.
|
|
242
283
|
*/
|
|
243
|
-
async run(changeName, options, root, json,
|
|
284
|
+
async run(changeName, options, root, json, jsonWarnings) {
|
|
244
285
|
const changesDir = root.changesDir;
|
|
245
286
|
const archiveDir = root.archiveDir;
|
|
246
287
|
const mainSpecsDir = root.specsDir;
|
|
@@ -249,7 +290,7 @@ export class ArchiveCommand {
|
|
|
249
290
|
await fs.access(changesDir);
|
|
250
291
|
}
|
|
251
292
|
catch {
|
|
252
|
-
throw new
|
|
293
|
+
throw new ArchiveBlockedError('changes_dir_missing', 'No Tospec changes directory found.', "Run 'tospec init' first.");
|
|
253
294
|
}
|
|
254
295
|
// Captured before the interactive branch can overwrite `changeName`: the
|
|
255
296
|
// kebab guard below applies to the argument only, and provenance is the
|
|
@@ -323,11 +364,11 @@ export class ArchiveCommand {
|
|
|
323
364
|
syncReportContent = await fs.readFile(syncReportPath, 'utf-8');
|
|
324
365
|
}
|
|
325
366
|
catch {
|
|
326
|
-
throw new ArchiveBlockedError('
|
|
367
|
+
throw new ArchiveBlockedError('sync_report_missing', `sync-report.md not found for change '${changeName}'.`, 'Run tospec-sync first, or omit --require-sync.');
|
|
327
368
|
}
|
|
328
369
|
const conclusion = parseSyncReportConclusion(syncReportContent);
|
|
329
370
|
if (conclusion !== 'PASS') {
|
|
330
|
-
throw new ArchiveBlockedError('
|
|
371
|
+
throw new ArchiveBlockedError('sync_report_failed', `sync-report.md for change '${changeName}' does not report a PASS conclusion (found: ${conclusion ?? 'unparseable'}).`, 'Resolve the flagged Requirement(s) via tospec-apply, then re-run tospec-sync.');
|
|
331
372
|
}
|
|
332
373
|
}
|
|
333
374
|
const skipValidation = options.validate === false || options.noValidate === true;
|
|
@@ -376,11 +417,18 @@ export class ArchiveCommand {
|
|
|
376
417
|
json,
|
|
377
418
|
yes: !!options.yes,
|
|
378
419
|
code: 'archive_confirmation_required',
|
|
379
|
-
|
|
420
|
+
// States the condition, not the remedy. A gate's `message` is reused
|
|
421
|
+
// verbatim when `--yes` overrides the gate, where "rerun with --yes"
|
|
422
|
+
// told the reader to do the thing they had just done — the same defect
|
|
423
|
+
// that removing `fix` from overridden gates was meant to end. The other
|
|
424
|
+
// two gates were already written this way ("N incomplete task(s) found"),
|
|
425
|
+
// which is why only this one carried it. Remedies belong in `fix`, which
|
|
426
|
+
// an overridden gate drops.
|
|
427
|
+
message: `Validation is disabled for change '${changeName}' (--no-validate).`,
|
|
380
428
|
fix: 'tospec archive <change-name> --json --no-validate --yes',
|
|
381
429
|
prompt: '⚠️ WARNING: Skipping validation may archive invalid specs. Continue? (y/N)',
|
|
382
430
|
warning: '\n⚠️ WARNING: Skipping validation may archive invalid specs.',
|
|
383
|
-
warnings:
|
|
431
|
+
warnings: jsonWarnings,
|
|
384
432
|
});
|
|
385
433
|
if (!proceed)
|
|
386
434
|
return null;
|
|
@@ -390,6 +438,36 @@ export class ArchiveCommand {
|
|
|
390
438
|
console.error(`Affected files: ${changeDir}`);
|
|
391
439
|
}
|
|
392
440
|
}
|
|
441
|
+
// The artifact graph already knows which artifacts a schema requires, and
|
|
442
|
+
// `status` reports it as isComplete — but nothing consulted that before
|
|
443
|
+
// archiving, so a change carrying only a delta spec archived clean with no
|
|
444
|
+
// proposal and no design. Validation cannot catch it: it checks the content
|
|
445
|
+
// of files that exist, and these do not exist.
|
|
446
|
+
//
|
|
447
|
+
// Archive is the last moment this is recoverable. Afterwards the change is
|
|
448
|
+
// in archive/ and its deltas are merged, so the why and the how the schema
|
|
449
|
+
// asked for are gone for good — and the person who had the answers has
|
|
450
|
+
// moved on. Overridable like every other gate, because a schema artifact is
|
|
451
|
+
// a planning obligation rather than a correctness one.
|
|
452
|
+
const missingArtifacts = this.findMissingRequiredArtifacts(root.path, changeName, changeDir);
|
|
453
|
+
if (missingArtifacts.length > 0) {
|
|
454
|
+
const names = missingArtifacts.join(', ');
|
|
455
|
+
// "missing or incomplete", because the list holds both: an artifact with no
|
|
456
|
+
// file, and one whose file is still the unfilled template. Saying "missing"
|
|
457
|
+
// of the second sent the reader looking for a file already on disk.
|
|
458
|
+
const proceed = await this.gate({
|
|
459
|
+
json,
|
|
460
|
+
yes: !!options.yes,
|
|
461
|
+
code: 'archive_artifacts_incomplete',
|
|
462
|
+
message: `Change '${changeName}' is missing or has incomplete required artifact(s): ${names}.`,
|
|
463
|
+
fix: `Run tospec status --change ${changeName} for the next step, or rerun with --yes.`,
|
|
464
|
+
prompt: `Warning: missing or incomplete required artifact(s): ${names}. Continue?`,
|
|
465
|
+
warning: `Warning: missing or incomplete required artifact(s): ${names}. Continuing due to --yes flag.`,
|
|
466
|
+
warnings: jsonWarnings,
|
|
467
|
+
});
|
|
468
|
+
if (!proceed)
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
393
471
|
// Show progress and check for incomplete tasks
|
|
394
472
|
// Use the already-resolved root rather than re-deriving it from changesDir:
|
|
395
473
|
// the '..','..' hop silently encodes the tospec/changes layout.
|
|
@@ -408,7 +486,7 @@ export class ArchiveCommand {
|
|
|
408
486
|
fix: 'Create the schema-tracked tasks file with checkboxes, or rerun with --yes.',
|
|
409
487
|
prompt: 'Warning: no tracked task checkboxes were found. Continue?',
|
|
410
488
|
warning: 'Warning: no tracked task checkboxes were found. Continuing due to --yes flag.',
|
|
411
|
-
warnings:
|
|
489
|
+
warnings: jsonWarnings,
|
|
412
490
|
});
|
|
413
491
|
if (!proceed)
|
|
414
492
|
return null;
|
|
@@ -422,16 +500,39 @@ export class ArchiveCommand {
|
|
|
422
500
|
fix: 'Complete the tasks or rerun with --yes.',
|
|
423
501
|
prompt: `Warning: ${incompleteTasks} incomplete task(s) found. Continue?`,
|
|
424
502
|
warning: `Warning: ${incompleteTasks} incomplete task(s) found. Continuing due to --yes flag.`,
|
|
425
|
-
warnings:
|
|
503
|
+
warnings: jsonWarnings,
|
|
426
504
|
});
|
|
427
505
|
if (!proceed)
|
|
428
506
|
return null;
|
|
429
507
|
}
|
|
430
508
|
// Handle spec updates unless skipSpecs flag is set
|
|
431
509
|
let specsUpdated = false;
|
|
432
|
-
let totals;
|
|
510
|
+
let totals = { added: 0, modified: 0, removed: 0, renamed: 0, retired: 0 };
|
|
433
511
|
if (options.skipSpecs) {
|
|
434
|
-
|
|
512
|
+
// Round 4 report 2. `--skip-specs` is documented for changes that have no
|
|
513
|
+
// deltas, so pointing it at one that does is user error — but archiving in
|
|
514
|
+
// silence made the mistake unrecoverable: the change moved to archive/ and
|
|
515
|
+
// the capability never reached the main specs, with nothing in the output
|
|
516
|
+
// saying so. The metadata spelling of the same intent (`skip_specs: true`)
|
|
517
|
+
// is an ERROR under exactly this shape; this at least names what was left
|
|
518
|
+
// behind. It stays a warning rather than a block because the flag is an
|
|
519
|
+
// explicit instruction and `--yes` already means "I confirm".
|
|
520
|
+
const discarded = await findSpecUpdates(changeDir, mainSpecsDir);
|
|
521
|
+
if (discarded.length > 0) {
|
|
522
|
+
// source is <changeDir>/specs/<capability>/spec.md — the capability is
|
|
523
|
+
// the directory that names it, the same level findSpecUpdates walks.
|
|
524
|
+
const listed = discarded
|
|
525
|
+
.map((update) => path.basename(path.dirname(update.source)))
|
|
526
|
+
.join(', ');
|
|
527
|
+
const message = `--skip-specs discarded ${discarded.length} delta spec(s); these capabilities were not merged into the main specs: ${listed}.`;
|
|
528
|
+
if (json) {
|
|
529
|
+
jsonWarnings.push({ severity: 'warning', code: 'archive_deltas_discarded', message });
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
console.log(`Warning: ${message}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
else if (!json) {
|
|
435
536
|
console.log('Skipping spec updates (--skip-specs flag provided).');
|
|
436
537
|
}
|
|
437
538
|
}
|
|
@@ -482,6 +583,15 @@ export class ArchiveCommand {
|
|
|
482
583
|
try {
|
|
483
584
|
for (const update of specUpdates) {
|
|
484
585
|
const built = await buildUpdatedSpec(update, changeName, { silent: json });
|
|
586
|
+
// In human mode buildUpdatedSpec already printed these. In JSON mode
|
|
587
|
+
// it stayed silent, so `status[]` is where they have to land — a
|
|
588
|
+
// dangling REMOVED used to be a completely invisible no-op for
|
|
589
|
+
// agent callers.
|
|
590
|
+
if (json) {
|
|
591
|
+
for (const n of built.notices) {
|
|
592
|
+
jsonWarnings.push({ severity: 'warning', code: n.code, message: n.message });
|
|
593
|
+
}
|
|
594
|
+
}
|
|
485
595
|
prepared.push({ update, rebuilt: built.rebuilt, crlf: built.crlf, retired: built.retired, counts: built.counts });
|
|
486
596
|
}
|
|
487
597
|
}
|
|
@@ -559,7 +669,27 @@ export class ArchiveCommand {
|
|
|
559
669
|
// The change's ticket lives in the global tospec/tickets/ index (outside the
|
|
560
670
|
// change dir), so move it alongside into tickets/archive/ to keep the active
|
|
561
671
|
// index limited to in-flight changes.
|
|
562
|
-
const
|
|
672
|
+
const ticketPaths = await findTicketPaths(root.path, changeName);
|
|
673
|
+
// Newest wins. A second ticket exists only because the change was recreated
|
|
674
|
+
// before this was fixed, so the later stamp is the one describing the change
|
|
675
|
+
// being archived — taking `readdir` order filed the run under the abandoned
|
|
676
|
+
// attempt's ticket and stranded the real one (round 4 report 6). Reported
|
|
677
|
+
// rather than cleaned up: the leftovers are the user's to keep or delete,
|
|
678
|
+
// and archive must not silently remove a record.
|
|
679
|
+
const ticketPath = ticketPaths[ticketPaths.length - 1];
|
|
680
|
+
if (ticketPaths.length > 1) {
|
|
681
|
+
const stranded = ticketPaths
|
|
682
|
+
.slice(0, -1)
|
|
683
|
+
.map((file) => path.basename(file))
|
|
684
|
+
.join(', ');
|
|
685
|
+
const message = `${ticketPaths.length} active tickets name change '${changeName}'; archived ${path.basename(ticketPath)} and left the rest in tospec/tickets/: ${stranded}.`;
|
|
686
|
+
if (json) {
|
|
687
|
+
jsonWarnings.push({ severity: 'warning', code: 'ticket_duplicates_left', message });
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
690
|
+
console.log(`Warning: ${message}`);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
563
693
|
if (ticketPath) {
|
|
564
694
|
const ticketArchiveDir = path.join(root.path, 'tospec', 'tickets', 'archive');
|
|
565
695
|
await fs.mkdir(ticketArchiveDir, { recursive: true });
|
|
@@ -576,7 +706,7 @@ export class ArchiveCommand {
|
|
|
576
706
|
archivedAs: archiveName,
|
|
577
707
|
path: archivePath,
|
|
578
708
|
specsUpdated,
|
|
579
|
-
|
|
709
|
+
totals,
|
|
580
710
|
};
|
|
581
711
|
}
|
|
582
712
|
async selectChange(changesDir, projectRoot) {
|