@seanmars/tospec 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/assets/dashboard/app.js +168 -0
- package/assets/dashboard/index.html +4 -0
- package/assets/dashboard/style.css +158 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +18 -31
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts +1 -2
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +8 -13
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +36 -3
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +8 -0
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +9 -10
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/shared-output.d.ts +18 -4
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +16 -3
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +9 -13
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +10 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +48 -32
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +20 -6
- 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 +15 -7
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +12 -3
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +1 -3
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +2 -14
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +6 -2
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/commands/workflow/templates.d.ts.map +1 -1
- package/dist/commands/workflow/templates.js +13 -2
- package/dist/commands/workflow/templates.js.map +1 -1
- package/dist/core/archive.d.ts +9 -0
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +63 -114
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +4 -2
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +54 -0
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/change-metadata/schema.d.ts +1 -0
- package/dist/core/change-metadata/schema.d.ts.map +1 -1
- package/dist/core/change-metadata/schema.js +4 -0
- package/dist/core/change-metadata/schema.js.map +1 -1
- package/dist/core/change-presenter.d.ts.map +1 -1
- package/dist/core/change-presenter.js +2 -8
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts +1 -1
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/index.d.ts +1 -2
- package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
- package/dist/core/command-generation/adapters/index.js +1 -2
- package/dist/core/command-generation/adapters/index.js.map +1 -1
- package/dist/core/command-generation/index.d.ts +4 -15
- package/dist/core/command-generation/index.d.ts.map +1 -1
- package/dist/core/command-generation/index.js +5 -17
- package/dist/core/command-generation/index.js.map +1 -1
- package/dist/core/config-schema.d.ts +0 -14
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +0 -57
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/config.d.ts +0 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +0 -4
- package/dist/core/config.js.map +1 -1
- package/dist/core/dashboard-data.d.ts +19 -1
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +24 -1
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/global-config.d.ts +0 -5
- package/dist/core/global-config.d.ts.map +1 -1
- package/dist/core/global-config.js +3 -20
- package/dist/core/global-config.js.map +1 -1
- package/dist/core/init.d.ts +0 -1
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +18 -62
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +6 -5
- package/dist/core/list.js.map +1 -1
- package/dist/core/migrate.d.ts +20 -3
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +140 -40
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.d.ts +0 -2
- package/dist/core/parsers/change-parser.d.ts.map +1 -1
- package/dist/core/parsers/change-parser.js +7 -72
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts +1 -1
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +13 -4
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +19 -0
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
- package/dist/core/parsers/requirement-blocks.js +56 -26
- package/dist/core/parsers/requirement-blocks.js.map +1 -1
- package/dist/core/parsers/requirement-text.d.ts +33 -0
- package/dist/core/parsers/requirement-text.d.ts.map +1 -1
- package/dist/core/parsers/requirement-text.js +55 -13
- package/dist/core/parsers/requirement-text.js.map +1 -1
- package/dist/core/profiles.d.ts +2 -10
- package/dist/core/profiles.d.ts.map +1 -1
- package/dist/core/profiles.js +5 -9
- package/dist/core/profiles.js.map +1 -1
- package/dist/core/project-config.d.ts +0 -22
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +5 -75
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/root-selection.d.ts.map +1 -1
- package/dist/core/root-selection.js +2 -2
- package/dist/core/root-selection.js.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/skill-generation.d.ts +47 -1
- package/dist/core/shared/skill-generation.d.ts.map +1 -1
- package/dist/core/shared/skill-generation.js +37 -33
- package/dist/core/shared/skill-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +4 -10
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +5 -27
- 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 +3 -4
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +1 -0
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/skill-templates.d.ts +1 -0
- package/dist/core/templates/skill-templates.d.ts.map +1 -1
- package/dist/core/templates/skill-templates.js +1 -0
- package/dist/core/templates/skill-templates.js.map +1 -1
- package/dist/core/templates/workflows/apply.d.ts.map +1 -1
- package/dist/core/templates/workflows/apply.js +35 -57
- 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 +5 -3
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.js +3 -3
- package/dist/core/templates/workflows/decision.js.map +1 -1
- package/dist/core/templates/workflows/explore.js +1 -1
- package/dist/core/templates/workflows/grill.d.ts +12 -0
- package/dist/core/templates/workflows/grill.d.ts.map +1 -0
- package/dist/core/templates/workflows/grill.js +61 -0
- package/dist/core/templates/workflows/grill.js.map +1 -0
- package/dist/core/templates/workflows/propose.d.ts.map +1 -1
- package/dist/core/templates/workflows/propose.js +3 -1
- package/dist/core/templates/workflows/propose.js.map +1 -1
- package/dist/core/templates/workflows/update.js +2 -2
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +0 -9
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +9 -55
- package/dist/core/update.js.map +1 -1
- package/dist/core/validation/validator.d.ts +7 -1
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +98 -17
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/ui/welcome-screen.d.ts.map +1 -1
- package/dist/ui/welcome-screen.js +6 -3
- package/dist/ui/welcome-screen.js.map +1 -1
- package/dist/utils/change-utils.d.ts +1 -1
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/link.d.ts +2 -18
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +2 -65
- package/dist/utils/link.js.map +1 -1
- package/package.json +1 -1
- package/schemas/decision/templates/decision.md +12 -3
- package/dist/core/command-generation/adapters/cursor.d.ts +0 -14
- package/dist/core/command-generation/adapters/cursor.d.ts.map +0 -1
- package/dist/core/command-generation/adapters/cursor.js +0 -31
- package/dist/core/command-generation/adapters/cursor.js.map +0 -1
- package/dist/core/command-generation/registry.d.ts +0 -24
- package/dist/core/command-generation/registry.d.ts.map +0 -1
- package/dist/core/command-generation/registry.js +0 -38
- package/dist/core/command-generation/registry.js.map +0 -1
|
@@ -4,14 +4,23 @@
|
|
|
4
4
|
* Lists available workflow schemas with descriptions.
|
|
5
5
|
*/
|
|
6
6
|
import { listSchemasWithInfo } from '../../core/artifact-graph/index.js';
|
|
7
|
+
import { emitSuccess } from '../shared-output.js';
|
|
8
|
+
import { resolveRootForCommand, toRootOutput } from '../../core/root-selection.js';
|
|
7
9
|
// -----------------------------------------------------------------------------
|
|
8
10
|
// Command Implementation
|
|
9
11
|
// -----------------------------------------------------------------------------
|
|
10
12
|
export async function schemasCommand(options) {
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
+
// Same root resolution as every other command (report 4.3).
|
|
14
|
+
const root = await resolveRootForCommand(options, {
|
|
15
|
+
json: options.json,
|
|
16
|
+
failurePayload: { schemas: null },
|
|
17
|
+
});
|
|
18
|
+
if (!root) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const schemas = listSchemasWithInfo(root.path);
|
|
13
22
|
if (options.json) {
|
|
14
|
-
|
|
23
|
+
emitSuccess({ schemas }, toRootOutput(root));
|
|
15
24
|
return;
|
|
16
25
|
}
|
|
17
26
|
console.log('Available schemas:');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/commands/workflow/schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/commands/workflow/schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAUnF,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,4DAA4D;IAC5D,MAAM,IAAI,GAAG,MAAM,qBAAqB,CAAC,OAAO,EAAE;QAChD,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;KAClC,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE/C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,WAAW,CAAC,EAAE,OAAO,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,WAAW,GAAG,YAAY,CAAC;QAC7B,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACpC,WAAW,GAAG,kBAAkB,CAAC;QACnC,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -35,12 +35,10 @@ export interface ApplyInstructions {
|
|
|
35
35
|
references?: ReferenceIndexEntry[];
|
|
36
36
|
}
|
|
37
37
|
export declare const DEFAULT_SCHEMA = "sdd";
|
|
38
|
-
export declare function printJson(payload: unknown): void;
|
|
39
|
-
export declare function statusFromError(error: unknown): ChangeCommandStatus;
|
|
40
38
|
/**
|
|
41
39
|
* Gets the status indicator for an artifact.
|
|
42
40
|
*/
|
|
43
|
-
export declare function getStatusIndicator(status: 'done' | 'ready' | 'blocked' | 'skipped'): string;
|
|
41
|
+
export declare function getStatusIndicator(status: 'done' | 'ready' | 'blocked' | 'skipped' | 'stub'): string;
|
|
44
42
|
/**
|
|
45
43
|
* Returns the list of available change directory names under tospec/changes/.
|
|
46
44
|
* Excludes the archive directory and hidden directories.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAOpE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AAMD,eAAO,MAAM,cAAc,QAAQ,CAAC;AAMpC;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAapG;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,UAAU,SAA8C,GACvD,OAAO,CAAC,MAAM,EAAE,CAAC,CAWnB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,EACnB,UAAU,SAA8C,EACxD,KAAK,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACrC,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CASrF"}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import * as fs from 'fs';
|
|
9
9
|
import { getSchemaDir, listSchemas } from '../../core/artifact-graph/index.js';
|
|
10
|
-
import { isRootSelectionError } from '../../core/root-selection.js';
|
|
11
10
|
import { validateChangeName } from '../../utils/change-utils.js';
|
|
12
11
|
// -----------------------------------------------------------------------------
|
|
13
12
|
// Constants
|
|
@@ -16,19 +15,6 @@ export const DEFAULT_SCHEMA = 'sdd';
|
|
|
16
15
|
// -----------------------------------------------------------------------------
|
|
17
16
|
// Utility Functions
|
|
18
17
|
// -----------------------------------------------------------------------------
|
|
19
|
-
export function printJson(payload) {
|
|
20
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
21
|
-
}
|
|
22
|
-
export function statusFromError(error) {
|
|
23
|
-
if (isRootSelectionError(error)) {
|
|
24
|
-
return { ...error.diagnostic };
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
severity: 'error',
|
|
28
|
-
code: 'change_error',
|
|
29
|
-
message: error instanceof Error ? error.message : String(error),
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
18
|
/**
|
|
33
19
|
* Gets the status indicator for an artifact.
|
|
34
20
|
*/
|
|
@@ -42,6 +28,8 @@ export function getStatusIndicator(status) {
|
|
|
42
28
|
return '[-]';
|
|
43
29
|
case 'skipped':
|
|
44
30
|
return '[~]';
|
|
31
|
+
case 'stub':
|
|
32
|
+
return '[!]';
|
|
45
33
|
}
|
|
46
34
|
}
|
|
47
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/workflow/shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAE/E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/workflow/shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;AAa5C,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAMD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CA+B1D"}
|
|
@@ -7,6 +7,7 @@ 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
9
|
import { validateChangeExists, validateSchemaExists, getAvailableChanges, getStatusIndicator, } from './shared.js';
|
|
10
|
+
import { emitSuccess } from '../shared-output.js';
|
|
10
11
|
// -----------------------------------------------------------------------------
|
|
11
12
|
// Command Implementation
|
|
12
13
|
// -----------------------------------------------------------------------------
|
|
@@ -25,7 +26,7 @@ export async function statusCommand(options) {
|
|
|
25
26
|
const available = await getAvailableChanges(projectRoot, root.changesDir);
|
|
26
27
|
if (available.length === 0) {
|
|
27
28
|
if (options.json) {
|
|
28
|
-
|
|
29
|
+
emitSuccess({ changes: [], message: 'No active changes.' }, rootOutput);
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
32
|
console.log(`No active changes. Create one with: ${newChangeHint}`);
|
|
@@ -46,7 +47,7 @@ export async function statusCommand(options) {
|
|
|
46
47
|
});
|
|
47
48
|
const status = formatChangeStatus(context);
|
|
48
49
|
if (options.json) {
|
|
49
|
-
|
|
50
|
+
emitSuccess({ ...status }, rootOutput);
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
53
|
printStatusText(status);
|
|
@@ -67,6 +68,9 @@ export function printStatusText(status) {
|
|
|
67
68
|
if (artifact.status === 'blocked' && artifact.missingDeps && artifact.missingDeps.length > 0) {
|
|
68
69
|
line += ` (blocked by: ${artifact.missingDeps.join(', ')})`;
|
|
69
70
|
}
|
|
71
|
+
if (artifact.status === 'stub') {
|
|
72
|
+
line += ' (stub: file exists but is empty or template-identical — fill it in)';
|
|
73
|
+
}
|
|
70
74
|
console.log(line);
|
|
71
75
|
}
|
|
72
76
|
if (status.isComplete) {
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/workflow/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/commands/workflow/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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"}
|
|
@@ -7,11 +7,22 @@ import path from 'path';
|
|
|
7
7
|
import { resolveSchema, getSchemaDir, ArtifactGraph, } from '../../core/artifact-graph/index.js';
|
|
8
8
|
import { FileSystemUtils } from '../../utils/file-system.js';
|
|
9
9
|
import { validateSchemaExists, DEFAULT_SCHEMA } from './shared.js';
|
|
10
|
+
import { emitSuccess } from '../shared-output.js';
|
|
11
|
+
import { resolveRootForCommand, toRootOutput } from '../../core/root-selection.js';
|
|
10
12
|
// -----------------------------------------------------------------------------
|
|
11
13
|
// Command Implementation
|
|
12
14
|
// -----------------------------------------------------------------------------
|
|
13
15
|
export async function templatesCommand(options) {
|
|
14
|
-
|
|
16
|
+
// Same root resolution as every other command — a subdirectory of a
|
|
17
|
+
// tospec project resolves the project root, not the bare cwd (report 4.3).
|
|
18
|
+
const root = await resolveRootForCommand(options, {
|
|
19
|
+
json: options.json,
|
|
20
|
+
failurePayload: { templates: null },
|
|
21
|
+
});
|
|
22
|
+
if (!root) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const projectRoot = root.path;
|
|
15
26
|
const schemaName = validateSchemaExists(options.schema ?? DEFAULT_SCHEMA, projectRoot);
|
|
16
27
|
const schema = resolveSchema(schemaName, projectRoot);
|
|
17
28
|
const graph = ArtifactGraph.fromSchema(schema);
|
|
@@ -46,7 +57,7 @@ export async function templatesCommand(options) {
|
|
|
46
57
|
for (const t of templates) {
|
|
47
58
|
output[t.artifactId] = { path: t.templatePath, source: t.source };
|
|
48
59
|
}
|
|
49
|
-
|
|
60
|
+
emitSuccess({ templates: output }, toRootOutput(root));
|
|
50
61
|
return;
|
|
51
62
|
}
|
|
52
63
|
console.log(`Schema: ${schemaName}`);
|
|
@@ -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;
|
|
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;AAiBnF,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
|
@@ -19,6 +19,15 @@ export interface ArchiveOptions {
|
|
|
19
19
|
requireSync?: boolean;
|
|
20
20
|
json?: boolean;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Move a directory from src to dest. On Windows, fs.rename() often fails with
|
|
24
|
+
* EPERM when the directory is non-empty or another process has it open (IDE,
|
|
25
|
+
* file watcher, antivirus). Fall back to copy-then-remove when rename fails
|
|
26
|
+
* with EPERM or EXDEV. Exported for migrate's two-phase promotion.
|
|
27
|
+
*/
|
|
28
|
+
export declare function moveDirectory(src: string, dest: string): Promise<void>;
|
|
29
|
+
/** Like moveDirectory but for a single file (copyFile fallback on Windows EPERM/EXDEV). */
|
|
30
|
+
export declare function moveFile(src: string, dest: string): Promise<void>;
|
|
22
31
|
export declare class ArchiveCommand {
|
|
23
32
|
execute(changeName?: string, options?: ArchiveOptions): Promise<void>;
|
|
24
33
|
private printJsonFailure;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKxD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,wBAAkB,CAAC;AAElD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAYjF;AAcD,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;AAoED;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5E;AA0CD,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;IA2B/E,OAAO,CAAC,gBAAgB;IAOxB;;;;OAIG;YACW,GAAG;YA8VH,YAAY;CA6C3B"}
|
package/dist/core/archive.js
CHANGED
|
@@ -2,11 +2,13 @@ import { promises as fs } from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
|
|
4
4
|
import { Validator } from './validation/validator.js';
|
|
5
|
-
import {
|
|
6
|
-
import { isRootSelectionError,
|
|
5
|
+
import { validateChangeArtifacts } from '../commands/validate.js';
|
|
6
|
+
import { isRootSelectionError, resolveRootForCommand, toRootOutput, } from './root-selection.js';
|
|
7
7
|
import { findSpecUpdates, buildUpdatedSpec, writeUpdatedSpec, } from './specs-apply.js';
|
|
8
8
|
import { formatTimestamp } from '../utils/timestamp.js';
|
|
9
9
|
import { findTicketPath } from '../utils/item-discovery.js';
|
|
10
|
+
import { readChangeMetadata } from '../utils/change-metadata.js';
|
|
11
|
+
import { emitSuccess, emitFailureStatus } from '../commands/shared-output.js';
|
|
10
12
|
/**
|
|
11
13
|
* Archive directory names are always CLI-generated from this — agents must
|
|
12
14
|
* never assemble the timestamp themselves. Alias of the shared
|
|
@@ -95,9 +97,9 @@ async function copyDirRecursive(src, dest) {
|
|
|
95
97
|
* Move a directory from src to dest. On Windows, fs.rename() often fails with
|
|
96
98
|
* EPERM when the directory is non-empty or another process has it open (IDE,
|
|
97
99
|
* file watcher, antivirus). Fall back to copy-then-remove when rename fails
|
|
98
|
-
* with EPERM or EXDEV.
|
|
100
|
+
* with EPERM or EXDEV. Exported for migrate's two-phase promotion.
|
|
99
101
|
*/
|
|
100
|
-
async function moveDirectory(src, dest) {
|
|
102
|
+
export async function moveDirectory(src, dest) {
|
|
101
103
|
try {
|
|
102
104
|
await fs.rename(src, dest);
|
|
103
105
|
}
|
|
@@ -118,6 +120,26 @@ async function moveDirectory(src, dest) {
|
|
|
118
120
|
* archived change path (project-root-relative), keeping the referenced filename
|
|
119
121
|
* (proposal.md or task.md). No-op if the line is absent or has no path.
|
|
120
122
|
*/
|
|
123
|
+
/**
|
|
124
|
+
* Appends a `## 關聯決策` section to the archived ticket linking the ADRs the
|
|
125
|
+
* change's metadata records (`decisions`), so the permanent archive record can
|
|
126
|
+
* be traced back to the decisions that drove it. Best-effort: unreadable
|
|
127
|
+
* metadata or no decisions → no section, never blocks the archive.
|
|
128
|
+
*/
|
|
129
|
+
async function appendDecisionLinks(ticketFile, archivedChangeDir, projectRoot) {
|
|
130
|
+
let decisions;
|
|
131
|
+
try {
|
|
132
|
+
decisions = readChangeMetadata(archivedChangeDir, projectRoot)?.decisions;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!decisions || decisions.length === 0)
|
|
138
|
+
return;
|
|
139
|
+
// Ticket lives in tospec/tickets/archive/, decisions in tospec/decisions/.
|
|
140
|
+
const lines = decisions.map((d) => `- [${d}](../../decisions/${d})`);
|
|
141
|
+
await fs.appendFile(ticketFile, `\n## 關聯決策\n\n${lines.join('\n')}\n`);
|
|
142
|
+
}
|
|
121
143
|
async function retargetTicketRef(ticketFile, archiveName) {
|
|
122
144
|
const content = await fs.readFile(ticketFile, 'utf-8');
|
|
123
145
|
const updated = content.replace(/^(ref:[ \t]*).*\/([^/\r\n]+)[ \t]*$/m, `$1tospec/changes/archive/${archiveName}/$2`);
|
|
@@ -126,7 +148,7 @@ async function retargetTicketRef(ticketFile, archiveName) {
|
|
|
126
148
|
}
|
|
127
149
|
}
|
|
128
150
|
/** Like moveDirectory but for a single file (copyFile fallback on Windows EPERM/EXDEV). */
|
|
129
|
-
async function moveFile(src, dest) {
|
|
151
|
+
export async function moveFile(src, dest) {
|
|
130
152
|
try {
|
|
131
153
|
await fs.rename(src, dest);
|
|
132
154
|
}
|
|
@@ -144,16 +166,13 @@ async function moveFile(src, dest) {
|
|
|
144
166
|
export class ArchiveCommand {
|
|
145
167
|
async execute(changeName, options = {}) {
|
|
146
168
|
const json = !!options.json;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
throw error;
|
|
169
|
+
// Same root resolution adapter as every other command (report 4.3).
|
|
170
|
+
const root = await resolveRootForCommand(options, {
|
|
171
|
+
json,
|
|
172
|
+
failurePayload: { archive: null },
|
|
173
|
+
});
|
|
174
|
+
if (!root) {
|
|
175
|
+
return;
|
|
157
176
|
}
|
|
158
177
|
if (json) {
|
|
159
178
|
try {
|
|
@@ -161,7 +180,7 @@ export class ArchiveCommand {
|
|
|
161
180
|
if (!result) {
|
|
162
181
|
return;
|
|
163
182
|
}
|
|
164
|
-
|
|
183
|
+
emitSuccess({ archive: result }, toRootOutput(root));
|
|
165
184
|
}
|
|
166
185
|
catch (error) {
|
|
167
186
|
this.printJsonFailure(root, toArchiveDiagnostic(error));
|
|
@@ -171,12 +190,7 @@ export class ArchiveCommand {
|
|
|
171
190
|
await this.run(changeName, options, root, false);
|
|
172
191
|
}
|
|
173
192
|
printJsonFailure(root, diagnostic) {
|
|
174
|
-
|
|
175
|
-
archive: null,
|
|
176
|
-
...(root ? { root: toRootOutput(root) } : {}),
|
|
177
|
-
status: [diagnostic],
|
|
178
|
-
}, null, 2));
|
|
179
|
-
process.exitCode = 1;
|
|
193
|
+
emitFailureStatus({ archive: null, ...(root ? { root: toRootOutput(root) } : {}) }, diagnostic);
|
|
180
194
|
}
|
|
181
195
|
/**
|
|
182
196
|
* Shared archive flow. In human mode (json=false) prompts and prose match
|
|
@@ -201,7 +215,7 @@ export class ArchiveCommand {
|
|
|
201
215
|
}
|
|
202
216
|
const selectedChange = await this.selectChange(changesDir);
|
|
203
217
|
if (!selectedChange) {
|
|
204
|
-
console.
|
|
218
|
+
console.error('No change selected. Aborting.');
|
|
205
219
|
return null;
|
|
206
220
|
}
|
|
207
221
|
changeName = selectedChange;
|
|
@@ -238,89 +252,23 @@ export class ArchiveCommand {
|
|
|
238
252
|
}
|
|
239
253
|
}
|
|
240
254
|
const skipValidation = options.validate === false || options.noValidate === true;
|
|
241
|
-
// Validate specs and change before archiving
|
|
255
|
+
// Validate specs and change before archiving — the exact same pipeline
|
|
256
|
+
// `tospec validate` runs, so validate green ⟺ archive passes validation.
|
|
242
257
|
if (!skipValidation) {
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
await fs.access(changeFile);
|
|
250
|
-
const changeReport = await validator.validateChange(changeFile);
|
|
251
|
-
// Proposal validation is informative only (do not block archive)
|
|
252
|
-
if (!changeReport.valid) {
|
|
253
|
-
console.log(`\nProposal warnings in proposal.md (non-blocking):`);
|
|
254
|
-
for (const issue of changeReport.issues) {
|
|
255
|
-
const symbol = issue.level === 'ERROR' ? '⚠' : (issue.level === 'WARNING' ? '⚠' : 'ℹ');
|
|
256
|
-
console.log(` ${symbol} ${issue.message}`);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
// Change file doesn't exist, skip validation
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
// Run the same schema-driven structural validation as `tospec validate`.
|
|
265
|
-
// Archive must not bypass required sections merely because it historically
|
|
266
|
-
// validated only proposal.md and delta specs.
|
|
267
|
-
const sectionIssues = await validateArtifactSections(root.path, changeDir);
|
|
268
|
-
const sectionErrors = sectionIssues.filter((issue) => issue.level === 'ERROR');
|
|
269
|
-
if (sectionErrors.length > 0) {
|
|
270
|
-
hasValidationErrors = true;
|
|
271
|
-
if (!json) {
|
|
272
|
-
console.log(`\nValidation errors in change artifacts:`);
|
|
273
|
-
for (const issue of sectionErrors) {
|
|
274
|
-
console.log(` ✗ ${issue.path}: ${issue.message}`);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
// Validate delta-formatted spec files. A required specs artifact must be
|
|
279
|
-
// present; an optional one (issue workflow) may legitimately be absent.
|
|
280
|
-
const changeSpecsDir = path.join(changeDir, 'specs');
|
|
281
|
-
let hasDeltaSpecs = false;
|
|
282
|
-
try {
|
|
283
|
-
const candidates = await fs.readdir(changeSpecsDir, { withFileTypes: true });
|
|
284
|
-
for (const c of candidates) {
|
|
285
|
-
if (c.isDirectory()) {
|
|
286
|
-
try {
|
|
287
|
-
const candidatePath = path.join(changeSpecsDir, c.name, 'spec.md');
|
|
288
|
-
await fs.access(candidatePath);
|
|
289
|
-
const content = await fs.readFile(candidatePath, 'utf-8');
|
|
290
|
-
if (/^##\s+(ADDED|MODIFIED|REMOVED|RENAMED)\s+Requirements/m.test(content)) {
|
|
291
|
-
hasDeltaSpecs = true;
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
catch { }
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
catch { }
|
|
300
|
-
const requireDeltaSpecs = await deltaSpecsRequired(root.path, changeDir);
|
|
301
|
-
if (hasDeltaSpecs || requireDeltaSpecs) {
|
|
302
|
-
const deltaReport = await validator.validateChangeDeltaSpecs(changeDir);
|
|
303
|
-
if (!deltaReport.valid) {
|
|
304
|
-
hasValidationErrors = true;
|
|
305
|
-
if (!json) {
|
|
306
|
-
console.log(`\nValidation errors in change delta specs:`);
|
|
307
|
-
for (const issue of deltaReport.issues) {
|
|
308
|
-
if (issue.level === 'ERROR') {
|
|
309
|
-
console.log(` ✗ ${issue.message}`);
|
|
310
|
-
}
|
|
311
|
-
else if (issue.level === 'WARNING') {
|
|
312
|
-
console.log(` ⚠ ${issue.message}`);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
258
|
+
const report = await validateChangeArtifacts(root.path, changeDir);
|
|
259
|
+
if (!json && report.issues.length > 0) {
|
|
260
|
+
console.error(`\nValidation issues for change '${changeName}':`);
|
|
261
|
+
for (const issue of report.issues) {
|
|
262
|
+
const symbol = issue.level === 'ERROR' ? '✗' : issue.level === 'WARNING' ? '⚠' : 'ℹ';
|
|
263
|
+
console.error(` ${symbol} ${issue.path}: ${issue.message}`);
|
|
316
264
|
}
|
|
317
265
|
}
|
|
318
|
-
if (
|
|
266
|
+
if (!report.valid) {
|
|
319
267
|
if (json) {
|
|
320
268
|
throw new ArchiveBlockedError('archive_validation_failed', `Validation failed for change '${changeName}'.`, `Run ${`tospec validate ${changeName}`} for details, fix the errors, or rerun with --no-validate.`);
|
|
321
269
|
}
|
|
322
|
-
console.
|
|
323
|
-
console.
|
|
270
|
+
console.error('\nValidation failed. Please fix the errors before archiving.');
|
|
271
|
+
console.error('To skip validation (not recommended), use --no-validate flag.');
|
|
324
272
|
process.exitCode = 1;
|
|
325
273
|
return null;
|
|
326
274
|
}
|
|
@@ -340,15 +288,15 @@ export class ArchiveCommand {
|
|
|
340
288
|
default: false
|
|
341
289
|
});
|
|
342
290
|
if (!proceed) {
|
|
343
|
-
console.
|
|
291
|
+
console.error('Archive cancelled.');
|
|
344
292
|
return null;
|
|
345
293
|
}
|
|
346
294
|
}
|
|
347
295
|
else {
|
|
348
|
-
console.
|
|
296
|
+
console.error(`\n⚠️ WARNING: Skipping validation may archive invalid specs.`);
|
|
349
297
|
}
|
|
350
|
-
console.
|
|
351
|
-
console.
|
|
298
|
+
console.error(`[${timestamp}] Validation skipped for change: ${changeName}`);
|
|
299
|
+
console.error(`Affected files: ${changeDir}`);
|
|
352
300
|
}
|
|
353
301
|
// Show progress and check for incomplete tasks
|
|
354
302
|
const progress = await getTaskProgressForChange(changesDir, changeName, path.resolve(changesDir, '..', '..'));
|
|
@@ -371,12 +319,12 @@ export class ArchiveCommand {
|
|
|
371
319
|
default: false
|
|
372
320
|
});
|
|
373
321
|
if (!proceed) {
|
|
374
|
-
console.
|
|
322
|
+
console.error('Archive cancelled.');
|
|
375
323
|
return null;
|
|
376
324
|
}
|
|
377
325
|
}
|
|
378
326
|
else {
|
|
379
|
-
console.
|
|
327
|
+
console.error('Warning: no tracked task checkboxes were found. Continuing due to --yes flag.');
|
|
380
328
|
}
|
|
381
329
|
}
|
|
382
330
|
else if (incompleteTasks > 0) {
|
|
@@ -392,12 +340,12 @@ export class ArchiveCommand {
|
|
|
392
340
|
default: false
|
|
393
341
|
});
|
|
394
342
|
if (!proceed) {
|
|
395
|
-
console.
|
|
343
|
+
console.error('Archive cancelled.');
|
|
396
344
|
return null;
|
|
397
345
|
}
|
|
398
346
|
}
|
|
399
347
|
else {
|
|
400
|
-
console.
|
|
348
|
+
console.error(`Warning: ${incompleteTasks} incomplete task(s) found. Continuing due to --yes flag.`);
|
|
401
349
|
}
|
|
402
350
|
}
|
|
403
351
|
// Handle spec updates unless skipSpecs flag is set
|
|
@@ -447,8 +395,8 @@ export class ArchiveCommand {
|
|
|
447
395
|
if (json) {
|
|
448
396
|
throw new ArchiveBlockedError('archive_spec_update_failed', String(err.message || err), 'Fix the change delta specs and rerun. No files were changed.');
|
|
449
397
|
}
|
|
450
|
-
console.
|
|
451
|
-
console.
|
|
398
|
+
console.error(String(err.message || err));
|
|
399
|
+
console.error('Aborted. No files were changed.');
|
|
452
400
|
process.exitCode = 1;
|
|
453
401
|
return null;
|
|
454
402
|
}
|
|
@@ -462,14 +410,14 @@ export class ArchiveCommand {
|
|
|
462
410
|
if (json) {
|
|
463
411
|
throw new ArchiveBlockedError('archive_spec_validation_failed', `Rebuilt spec for '${specName}' failed validation. No files were changed.`, `Run ${`tospec validate ${specName}`} after fixing the change deltas.`);
|
|
464
412
|
}
|
|
465
|
-
console.
|
|
413
|
+
console.error(`\nValidation errors in rebuilt spec for ${specName} (will not write changes):`);
|
|
466
414
|
for (const issue of report.issues) {
|
|
467
415
|
if (issue.level === 'ERROR')
|
|
468
|
-
console.
|
|
416
|
+
console.error(` ✗ ${issue.message}`);
|
|
469
417
|
else if (issue.level === 'WARNING')
|
|
470
|
-
console.
|
|
418
|
+
console.error(` ⚠ ${issue.message}`);
|
|
471
419
|
}
|
|
472
|
-
console.
|
|
420
|
+
console.error('Aborted. No files were changed.');
|
|
473
421
|
process.exitCode = 1;
|
|
474
422
|
return null;
|
|
475
423
|
}
|
|
@@ -526,6 +474,7 @@ export class ArchiveCommand {
|
|
|
526
474
|
const archivedTicketPath = path.join(ticketArchiveDir, path.basename(ticketPath));
|
|
527
475
|
await moveFile(ticketPath, archivedTicketPath);
|
|
528
476
|
await retargetTicketRef(archivedTicketPath, archiveName);
|
|
477
|
+
await appendDecisionLinks(archivedTicketPath, archivePath, root.path);
|
|
529
478
|
}
|
|
530
479
|
if (!json) {
|
|
531
480
|
console.log(`Change '${changeName}' archived as '${archiveName}'.`);
|