@seanmars/tospec 0.23.0 → 0.26.0-beta
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 +281 -0
- package/README.md +27 -9
- package/assets/claude-mod/tospec-dashboard/.claude-plugin/plugin.json +7 -0
- package/assets/claude-mod/tospec-dashboard/hooks/hooks.json +1 -0
- package/assets/claude-mod/tospec-dashboard/hooks/register.ts +695 -0
- package/assets/claude-mod/tospec-dashboard/tests/register.test.ts +448 -0
- package/assets/claude-mod/tospec-dashboard/types/index.d.ts +8 -0
- package/assets/dashboard/app.js +218 -1180
- package/assets/dashboard/index.html +31 -22
- package/assets/dashboard/lib/charts.js +355 -0
- package/assets/dashboard/lib/derive.js +375 -0
- package/assets/dashboard/lib/dom.js +121 -0
- package/assets/dashboard/lib/routes.js +52 -0
- package/assets/dashboard/lib/store.js +326 -0
- package/assets/dashboard/style.css +3103 -664
- package/assets/dashboard/views/alerts.js +170 -0
- package/assets/dashboard/views/change.js +234 -0
- package/assets/dashboard/views/docs.js +214 -0
- package/assets/dashboard/views/home.js +357 -0
- package/assets/dashboard/views/project.js +168 -0
- package/assets/dashboard/views/session.js +270 -0
- package/assets/dashboard/views/sidebar.js +131 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +116 -102
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +213 -100
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dashboard-relay.d.ts +11 -0
- package/dist/commands/dashboard-relay.d.ts.map +1 -0
- package/dist/commands/dashboard-relay.js +88 -0
- package/dist/commands/dashboard-relay.js.map +1 -0
- package/dist/commands/dashboard.d.ts +69 -100
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +420 -598
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/decision.d.ts +38 -1
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +303 -27
- package/dist/commands/decision.js.map +1 -1
- package/dist/commands/metrics.d.ts +3 -4
- package/dist/commands/metrics.d.ts.map +1 -1
- package/dist/commands/metrics.js +3 -5
- package/dist/commands/metrics.js.map +1 -1
- package/dist/commands/shared-output.d.ts +24 -0
- package/dist/commands/shared-output.d.ts.map +1 -1
- package/dist/commands/shared-output.js +21 -2
- package/dist/commands/shared-output.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +12 -9
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/validate.d.ts +19 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +243 -64
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/workflow/instructions.d.ts +7 -1
- package/dist/commands/workflow/instructions.d.ts.map +1 -1
- package/dist/commands/workflow/instructions.js +299 -81
- package/dist/commands/workflow/instructions.js.map +1 -1
- package/dist/commands/workflow/new-change.d.ts.map +1 -1
- package/dist/commands/workflow/new-change.js +26 -17
- package/dist/commands/workflow/new-change.js.map +1 -1
- package/dist/commands/workflow/prompt-escape.d.ts +25 -0
- package/dist/commands/workflow/prompt-escape.d.ts.map +1 -0
- package/dist/commands/workflow/prompt-escape.js +62 -0
- package/dist/commands/workflow/prompt-escape.js.map +1 -0
- package/dist/commands/workflow/schemas.d.ts.map +1 -1
- package/dist/commands/workflow/schemas.js +34 -16
- package/dist/commands/workflow/schemas.js.map +1 -1
- package/dist/commands/workflow/shared.d.ts +46 -10
- package/dist/commands/workflow/shared.d.ts.map +1 -1
- package/dist/commands/workflow/shared.js +66 -30
- package/dist/commands/workflow/shared.js.map +1 -1
- package/dist/commands/workflow/status.d.ts +5 -2
- package/dist/commands/workflow/status.d.ts.map +1 -1
- package/dist/commands/workflow/status.js +62 -28
- package/dist/commands/workflow/status.js.map +1 -1
- package/dist/core/archive.d.ts +38 -0
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +492 -75
- package/dist/core/archive.js.map +1 -1
- package/dist/core/artifact-graph/index.d.ts +2 -2
- package/dist/core/artifact-graph/index.d.ts.map +1 -1
- package/dist/core/artifact-graph/index.js +2 -2
- package/dist/core/artifact-graph/index.js.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.d.ts +8 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +58 -36
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
- package/dist/core/artifact-graph/resolver.d.ts +39 -12
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
- package/dist/core/artifact-graph/resolver.js +82 -36
- package/dist/core/artifact-graph/resolver.js.map +1 -1
- package/dist/core/artifact-graph/schema.d.ts +24 -0
- package/dist/core/artifact-graph/schema.d.ts.map +1 -1
- package/dist/core/artifact-graph/schema.js +32 -1
- package/dist/core/artifact-graph/schema.js.map +1 -1
- package/dist/core/artifact-graph/stub-detection.d.ts +10 -2
- package/dist/core/artifact-graph/stub-detection.d.ts.map +1 -1
- package/dist/core/artifact-graph/stub-detection.js +18 -11
- package/dist/core/artifact-graph/stub-detection.js.map +1 -1
- package/dist/core/artifact-graph/types.d.ts +2 -2
- package/dist/core/artifact-graph/types.d.ts.map +1 -1
- package/dist/core/artifact-graph/types.js +10 -1
- package/dist/core/artifact-graph/types.js.map +1 -1
- package/dist/core/change-metadata/schema.d.ts.map +1 -1
- package/dist/core/change-metadata/schema.js +18 -4
- 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 +13 -8
- package/dist/core/change-presenter.js.map +1 -1
- package/dist/core/change-status-policy.d.ts.map +1 -1
- package/dist/core/change-status-policy.js +3 -1
- package/dist/core/change-status-policy.js.map +1 -1
- package/dist/core/codex-metrics.d.ts +1 -1
- package/dist/core/codex-metrics.js +1 -1
- package/dist/core/config-schema.d.ts +8 -0
- package/dist/core/config-schema.d.ts.map +1 -1
- package/dist/core/config-schema.js +10 -0
- package/dist/core/config-schema.js.map +1 -1
- package/dist/core/dashboard-activity.d.ts +4 -4
- package/dist/core/dashboard-activity.js +4 -4
- package/dist/core/dashboard-data.d.ts +11 -5
- package/dist/core/dashboard-data.d.ts.map +1 -1
- package/dist/core/dashboard-data.js +54 -28
- package/dist/core/dashboard-data.js.map +1 -1
- package/dist/core/dashboard-hub.d.ts +258 -0
- package/dist/core/dashboard-hub.d.ts.map +1 -0
- package/dist/core/dashboard-hub.js +655 -0
- package/dist/core/dashboard-hub.js.map +1 -0
- package/dist/core/dashboard-routes.d.ts +57 -0
- package/dist/core/dashboard-routes.d.ts.map +1 -0
- package/dist/core/dashboard-routes.js +398 -0
- package/dist/core/dashboard-routes.js.map +1 -0
- package/dist/core/global-config.d.ts +71 -2
- package/dist/core/global-config.d.ts.map +1 -1
- package/dist/core/global-config.js +149 -4
- package/dist/core/global-config.js.map +1 -1
- package/dist/core/id.d.ts +9 -0
- package/dist/core/id.d.ts.map +1 -1
- package/dist/core/id.js +37 -0
- package/dist/core/id.js.map +1 -1
- package/dist/core/init.d.ts +9 -2
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +119 -33
- package/dist/core/init.js.map +1 -1
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +69 -45
- package/dist/core/list.js.map +1 -1
- package/dist/core/local-server.d.ts +10 -3
- package/dist/core/local-server.d.ts.map +1 -1
- package/dist/core/local-server.js +25 -5
- package/dist/core/local-server.js.map +1 -1
- package/dist/core/markdown-render.d.ts.map +1 -1
- package/dist/core/markdown-render.js +7 -2
- package/dist/core/markdown-render.js.map +1 -1
- package/dist/core/migrate.d.ts +24 -2
- package/dist/core/migrate.d.ts.map +1 -1
- package/dist/core/migrate.js +335 -59
- package/dist/core/migrate.js.map +1 -1
- package/dist/core/parsers/change-parser.d.ts +20 -1
- package/dist/core/parsers/change-parser.d.ts.map +1 -1
- package/dist/core/parsers/change-parser.js +76 -73
- package/dist/core/parsers/change-parser.js.map +1 -1
- package/dist/core/parsers/markdown-parser.d.ts +24 -0
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
- package/dist/core/parsers/markdown-parser.js +65 -10
- package/dist/core/parsers/markdown-parser.js.map +1 -1
- package/dist/core/parsers/requirement-blocks.d.ts +127 -6
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -1
- package/dist/core/parsers/requirement-blocks.js +349 -56
- package/dist/core/parsers/requirement-blocks.js.map +1 -1
- package/dist/core/parsers/requirement-text.d.ts +25 -1
- package/dist/core/parsers/requirement-text.d.ts.map +1 -1
- package/dist/core/parsers/requirement-text.js +62 -6
- package/dist/core/parsers/requirement-text.js.map +1 -1
- package/dist/core/parsers/spec-structure.d.ts.map +1 -1
- package/dist/core/parsers/spec-structure.js +36 -24
- package/dist/core/parsers/spec-structure.js.map +1 -1
- package/dist/core/project-config.d.ts +9 -2
- package/dist/core/project-config.d.ts.map +1 -1
- package/dist/core/project-config.js +30 -7
- package/dist/core/project-config.js.map +1 -1
- package/dist/core/project-layout.d.ts +26 -0
- package/dist/core/project-layout.d.ts.map +1 -1
- package/dist/core/project-layout.js +51 -1
- package/dist/core/project-layout.js.map +1 -1
- package/dist/core/schema-names.d.ts +17 -0
- package/dist/core/schema-names.d.ts.map +1 -1
- package/dist/core/schema-names.js +24 -0
- package/dist/core/schema-names.js.map +1 -1
- package/dist/core/shared/dashboard-mod.d.ts +24 -0
- package/dist/core/shared/dashboard-mod.d.ts.map +1 -0
- package/dist/core/shared/dashboard-mod.js +44 -0
- package/dist/core/shared/dashboard-mod.js.map +1 -0
- package/dist/core/shared/index.d.ts +2 -1
- package/dist/core/shared/index.d.ts.map +1 -1
- package/dist/core/shared/index.js +2 -1
- package/dist/core/shared/index.js.map +1 -1
- package/dist/core/shared/rules-generation.d.ts +12 -0
- package/dist/core/shared/rules-generation.d.ts.map +1 -1
- package/dist/core/shared/rules-generation.js +26 -2
- package/dist/core/shared/rules-generation.js.map +1 -1
- package/dist/core/shared/skill-generation.d.ts +7 -0
- package/dist/core/shared/skill-generation.d.ts.map +1 -1
- package/dist/core/shared/skill-generation.js +19 -0
- package/dist/core/shared/skill-generation.js.map +1 -1
- package/dist/core/shared/tool-detection.d.ts +10 -1
- package/dist/core/shared/tool-detection.d.ts.map +1 -1
- package/dist/core/shared/tool-detection.js +37 -6
- 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 +23 -1
- package/dist/core/spec-presenter.js.map +1 -1
- package/dist/core/specs-apply.d.ts +98 -1
- package/dist/core/specs-apply.d.ts.map +1 -1
- package/dist/core/specs-apply.js +426 -63
- package/dist/core/specs-apply.js.map +1 -1
- package/dist/core/templates/fragments/change-diff.d.ts +37 -0
- package/dist/core/templates/fragments/change-diff.d.ts.map +1 -0
- package/dist/core/templates/fragments/change-diff.js +37 -0
- package/dist/core/templates/fragments/change-diff.js.map +1 -0
- package/dist/core/templates/fragments/sync-fail.d.ts +8 -0
- package/dist/core/templates/fragments/sync-fail.d.ts.map +1 -0
- package/dist/core/templates/fragments/sync-fail.js +8 -0
- package/dist/core/templates/fragments/sync-fail.js.map +1 -0
- package/dist/core/templates/fragments/validate.d.ts +14 -1
- package/dist/core/templates/fragments/validate.d.ts.map +1 -1
- package/dist/core/templates/fragments/validate.js +14 -1
- package/dist/core/templates/fragments/validate.js.map +1 -1
- package/dist/core/templates/fragments/verify.d.ts +2 -2
- package/dist/core/templates/fragments/verify.d.ts.map +1 -1
- package/dist/core/templates/fragments/verify.js +8 -5
- package/dist/core/templates/fragments/verify.js.map +1 -1
- package/dist/core/templates/workflows/apply.d.ts +1 -1
- package/dist/core/templates/workflows/apply.d.ts.map +1 -1
- package/dist/core/templates/workflows/apply.js +29 -10
- 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 +27 -9
- package/dist/core/templates/workflows/archive.js.map +1 -1
- package/dist/core/templates/workflows/decision.d.ts.map +1 -1
- package/dist/core/templates/workflows/decision.js +10 -4
- package/dist/core/templates/workflows/decision.js.map +1 -1
- package/dist/core/templates/workflows/explore.d.ts +2 -2
- package/dist/core/templates/workflows/explore.d.ts.map +1 -1
- package/dist/core/templates/workflows/explore.js +7 -3
- package/dist/core/templates/workflows/explore.js.map +1 -1
- package/dist/core/templates/workflows/grill.d.ts +2 -2
- package/dist/core/templates/workflows/grill.d.ts.map +1 -1
- package/dist/core/templates/workflows/grill.js +5 -4
- package/dist/core/templates/workflows/grill.js.map +1 -1
- package/dist/core/templates/workflows/issue.d.ts.map +1 -1
- package/dist/core/templates/workflows/issue.js +9 -3
- package/dist/core/templates/workflows/issue.js.map +1 -1
- package/dist/core/templates/workflows/propose.d.ts.map +1 -1
- package/dist/core/templates/workflows/propose.js +4 -1
- package/dist/core/templates/workflows/propose.js.map +1 -1
- package/dist/core/templates/workflows/sync.d.ts.map +1 -1
- package/dist/core/templates/workflows/sync.js +25 -11
- package/dist/core/templates/workflows/sync.js.map +1 -1
- package/dist/core/templates/workflows/update.d.ts.map +1 -1
- package/dist/core/templates/workflows/update.js +17 -10
- package/dist/core/templates/workflows/update.js.map +1 -1
- package/dist/core/update.d.ts +5 -0
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +69 -29
- package/dist/core/update.js.map +1 -1
- package/dist/core/validation/constants.d.ts +7 -1
- package/dist/core/validation/constants.d.ts.map +1 -1
- package/dist/core/validation/constants.js +16 -2
- package/dist/core/validation/constants.js.map +1 -1
- package/dist/core/validation/purpose-placeholder.d.ts.map +1 -1
- package/dist/core/validation/purpose-placeholder.js +35 -11
- package/dist/core/validation/purpose-placeholder.js.map +1 -1
- package/dist/core/validation/section-validator.d.ts +7 -0
- package/dist/core/validation/section-validator.d.ts.map +1 -1
- package/dist/core/validation/section-validator.js +22 -2
- package/dist/core/validation/section-validator.js.map +1 -1
- package/dist/core/validation/sister-changes.d.ts +93 -0
- package/dist/core/validation/sister-changes.d.ts.map +1 -0
- package/dist/core/validation/sister-changes.js +180 -0
- package/dist/core/validation/sister-changes.js.map +1 -0
- package/dist/core/validation/task-markers.d.ts +9 -0
- package/dist/core/validation/task-markers.d.ts.map +1 -0
- package/dist/core/validation/task-markers.js +71 -0
- package/dist/core/validation/task-markers.js.map +1 -0
- package/dist/core/validation/types.d.ts +58 -0
- package/dist/core/validation/types.d.ts.map +1 -1
- package/dist/core/validation/types.js +22 -0
- package/dist/core/validation/types.js.map +1 -1
- package/dist/core/validation/validator.d.ts +79 -2
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +565 -84
- package/dist/core/validation/validator.js.map +1 -1
- package/dist/utils/change-metadata.d.ts +62 -5
- package/dist/utils/change-metadata.d.ts.map +1 -1
- package/dist/utils/change-metadata.js +193 -31
- package/dist/utils/change-metadata.js.map +1 -1
- package/dist/utils/change-utils.d.ts +21 -0
- package/dist/utils/change-utils.d.ts.map +1 -1
- package/dist/utils/change-utils.js +168 -53
- package/dist/utils/change-utils.js.map +1 -1
- package/dist/utils/command-line.d.ts +11 -0
- package/dist/utils/command-line.d.ts.map +1 -0
- package/dist/utils/command-line.js +43 -0
- package/dist/utils/command-line.js.map +1 -0
- package/dist/utils/display-width.d.ts +10 -0
- package/dist/utils/display-width.d.ts.map +1 -0
- package/dist/utils/display-width.js +15 -0
- package/dist/utils/display-width.js.map +1 -0
- package/dist/utils/file-system.d.ts +16 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +49 -2
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +11 -5
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/interactive.d.ts.map +1 -1
- package/dist/utils/interactive.js +3 -1
- package/dist/utils/interactive.js.map +1 -1
- package/dist/utils/item-discovery.d.ts +3 -2
- package/dist/utils/item-discovery.d.ts.map +1 -1
- package/dist/utils/item-discovery.js +34 -16
- package/dist/utils/item-discovery.js.map +1 -1
- package/dist/utils/link.d.ts +0 -1
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +0 -1
- package/dist/utils/link.js.map +1 -1
- package/dist/utils/match.d.ts.map +1 -1
- package/dist/utils/match.js +10 -1
- package/dist/utils/match.js.map +1 -1
- package/dist/utils/option-flags.d.ts +9 -0
- package/dist/utils/option-flags.d.ts.map +1 -0
- package/dist/utils/option-flags.js +12 -0
- package/dist/utils/option-flags.js.map +1 -0
- package/dist/utils/sentence.d.ts +9 -0
- package/dist/utils/sentence.d.ts.map +1 -0
- package/dist/utils/sentence.js +12 -0
- package/dist/utils/sentence.js.map +1 -0
- package/dist/utils/spec-files.d.ts +84 -1
- package/dist/utils/spec-files.d.ts.map +1 -1
- package/dist/utils/spec-files.js +192 -3
- package/dist/utils/spec-files.js.map +1 -1
- package/dist/utils/task-progress.d.ts.map +1 -1
- package/dist/utils/task-progress.js +32 -9
- package/dist/utils/task-progress.js.map +1 -1
- package/dist/utils/timestamp.d.ts +27 -0
- package/dist/utils/timestamp.d.ts.map +1 -1
- package/dist/utils/timestamp.js +37 -0
- package/dist/utils/timestamp.js.map +1 -1
- package/package.json +6 -2
- package/schemas/decision/templates/decision.md +2 -2
- package/schemas/issue/schema.yaml +12 -6
- package/schemas/issue/templates/task.md +1 -1
- package/schemas/sdd/schema.yaml +21 -10
- package/schemas/sdd/templates/proposal.md +1 -1
- package/assets/dashboard/chart.umd.js +0 -14
|
@@ -2,7 +2,9 @@ import * as fs from 'node:fs';
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { getGlobalConfigDir, getLegacyDataDir } from '../global-config.js';
|
|
5
|
-
import { parseSchema, SchemaValidationError } from './schema.js';
|
|
5
|
+
import { findSchemaWarnings, parseSchema, SchemaValidationError } from './schema.js';
|
|
6
|
+
import { isChangeSchema } from '../schema-names.js';
|
|
7
|
+
import { isDirectoryEntry } from '../../utils/file-system.js';
|
|
6
8
|
export class SchemaLoadError extends Error {
|
|
7
9
|
schemaPath;
|
|
8
10
|
cause;
|
|
@@ -39,25 +41,6 @@ function getLegacySchemasDir() {
|
|
|
39
41
|
export function getProjectSchemasDir(projectRoot) {
|
|
40
42
|
return path.join(projectRoot, 'tospec', 'schemas');
|
|
41
43
|
}
|
|
42
|
-
/**
|
|
43
|
-
* True for real directories and for symlinks pointing at one. `Dirent`'s
|
|
44
|
-
* `isDirectory()` reports the raw entry type, so a symlinked schema dir needs
|
|
45
|
-
* the `statSync` dereference below.
|
|
46
|
-
*/
|
|
47
|
-
export function isSchemaDir(parentDir, entry) {
|
|
48
|
-
if (entry.isDirectory()) {
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
if (entry.isSymbolicLink()) {
|
|
52
|
-
try {
|
|
53
|
-
return fs.statSync(path.join(parentDir, entry.name)).isDirectory();
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
44
|
/**
|
|
62
45
|
* Identity of a file's current contents, for cache invalidation. Null when the
|
|
63
46
|
* file cannot be stat'd, which disables caching for that path rather than
|
|
@@ -108,9 +91,24 @@ function scanSchemaDir(dir) {
|
|
|
108
91
|
return [];
|
|
109
92
|
return fs
|
|
110
93
|
.readdirSync(dir, { withFileTypes: true })
|
|
111
|
-
.filter((entry) =>
|
|
94
|
+
.filter((entry) => isDirectoryEntry(dir, entry) && fs.existsSync(path.join(dir, entry.name, 'schema.yaml')))
|
|
112
95
|
.map((entry) => entry.name);
|
|
113
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* A schema name is one directory inside a layer. `path.join` reads `../x` or
|
|
99
|
+
* `a/b` as a walk out of that layer, so `--schema ../../elsewhere/evil` (or the
|
|
100
|
+
* same value in `tospec/config.yaml`) loaded a schema from outside all three.
|
|
101
|
+
* `readdir` never yields `/`, `\`, `.` or `..`, so no listed schema is refused.
|
|
102
|
+
*/
|
|
103
|
+
export function isSchemaName(name) {
|
|
104
|
+
return name !== '' && name !== '.' && name !== '..' && !/[\\/]/u.test(name);
|
|
105
|
+
}
|
|
106
|
+
/** @throws Error when `name` is a path rather than a schema name. */
|
|
107
|
+
export function assertSchemaName(name) {
|
|
108
|
+
if (!isSchemaName(name)) {
|
|
109
|
+
throw new Error(`Schema '${name}' is a path, not a schema name. Use the name of a schema directory; tospec schemas lists them.`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
114
112
|
/**
|
|
115
113
|
* The directory holding `<name>/schema.yaml` and the layer it came from, or
|
|
116
114
|
* null when no layer has one. Project-local wins over the user override, which
|
|
@@ -122,6 +120,9 @@ function scanSchemaDir(dir) {
|
|
|
122
120
|
* won" is what explains a file the winning layer does not have.
|
|
123
121
|
*/
|
|
124
122
|
export function getSchemaDirWithSource(name, projectRoot) {
|
|
123
|
+
// The floor under every lookup, for a caller that skips assertSchemaName.
|
|
124
|
+
if (!isSchemaName(name))
|
|
125
|
+
return null;
|
|
125
126
|
// Highest precedence first: project overrides user overrides package.
|
|
126
127
|
for (const { dir, source } of schemaSources(projectRoot).reverse()) {
|
|
127
128
|
const candidate = path.join(dir, name);
|
|
@@ -131,6 +132,42 @@ export function getSchemaDirWithSource(name, projectRoot) {
|
|
|
131
132
|
}
|
|
132
133
|
return null;
|
|
133
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* The layer `name` would resolve from once the winning layer's directory is
|
|
137
|
+
* removed, or null when no lower layer has one. A broken override hides that
|
|
138
|
+
* layer from the list entirely, so this is how its fix can still say what
|
|
139
|
+
* deleting the override restores without a second entry in the JSON contract.
|
|
140
|
+
*/
|
|
141
|
+
export function getShadowedSchemaSource(name, projectRoot) {
|
|
142
|
+
// Deduplicated by path: with XDG_DATA_HOME=~/.local/share the user and legacy
|
|
143
|
+
// entries are one directory, which counted a user-only schema as shadowing
|
|
144
|
+
// itself.
|
|
145
|
+
const seen = new Set();
|
|
146
|
+
const layers = schemaSources(projectRoot)
|
|
147
|
+
.reverse()
|
|
148
|
+
.filter(({ dir }) => {
|
|
149
|
+
const key = path.resolve(dir);
|
|
150
|
+
if (seen.has(key))
|
|
151
|
+
return false;
|
|
152
|
+
seen.add(key);
|
|
153
|
+
return fs.existsSync(path.join(dir, name, 'schema.yaml'));
|
|
154
|
+
});
|
|
155
|
+
return layers[1]?.source ?? null;
|
|
156
|
+
}
|
|
157
|
+
const SCHEMA_SOURCE_LABELS = { project: 'project', user: 'user override', package: 'package' };
|
|
158
|
+
/**
|
|
159
|
+
* The fix for a schema.yaml that does not load, shared by `schemas` and by the
|
|
160
|
+
* commands that read a change running under it. A broken override shadows the
|
|
161
|
+
* lower layer's schema, which `schemas` no longer lists, so removing the
|
|
162
|
+
* directory has to be named as the way back to it. "Its directory", not "the
|
|
163
|
+
* directory": next to a change, the bare phrase reads as the change's own.
|
|
164
|
+
*/
|
|
165
|
+
export function unreadableSchemaFix(name, projectRoot) {
|
|
166
|
+
const fallback = getShadowedSchemaSource(name, projectRoot);
|
|
167
|
+
if (fallback === null)
|
|
168
|
+
return `Fix ${name}'s schema.yaml, or remove its directory.`;
|
|
169
|
+
return `Fix ${name}'s schema.yaml, or remove its directory to use the ${SCHEMA_SOURCE_LABELS[fallback]} schema of that name.`;
|
|
170
|
+
}
|
|
134
171
|
/** As `getSchemaDirWithSource`, for callers that only need the path. */
|
|
135
172
|
export function getSchemaDir(name, projectRoot) {
|
|
136
173
|
return getSchemaDirWithSource(name, projectRoot)?.dir ?? null;
|
|
@@ -141,12 +178,24 @@ export function getSchemaDir(name, projectRoot) {
|
|
|
141
178
|
* @throws SchemaLoadError when the file cannot be read or does not parse.
|
|
142
179
|
*/
|
|
143
180
|
export function resolveSchema(name, projectRoot) {
|
|
181
|
+
return resolveSchemaOffering(name, projectRoot, () => true);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* `resolveSchema` for the schema a change runs under. Only the "Available"
|
|
185
|
+
* list differs: a change whose name came from `tospec/config.yaml` and does not
|
|
186
|
+
* exist was offered `decision`, which no change may use.
|
|
187
|
+
*/
|
|
188
|
+
export function resolveChangeSchema(name, projectRoot) {
|
|
189
|
+
return resolveSchemaOffering(name, projectRoot, isChangeSchema);
|
|
190
|
+
}
|
|
191
|
+
function resolveSchemaOffering(name, projectRoot, offered) {
|
|
144
192
|
const normalizedName = name.replace(/\.ya?ml$/, '');
|
|
193
|
+
assertSchemaName(normalizedName);
|
|
145
194
|
const schemaDir = getSchemaDir(normalizedName, projectRoot);
|
|
146
195
|
if (!schemaDir) {
|
|
147
196
|
// Loadable, not merely present: a name whose schema.yaml does not parse is
|
|
148
197
|
// a choice that cannot work.
|
|
149
|
-
const availableSchemas = listLoadableSchemas(projectRoot);
|
|
198
|
+
const availableSchemas = listLoadableSchemas(projectRoot).filter(offered);
|
|
150
199
|
throw new Error(`Schema '${normalizedName}' not found. Available schemas: ${availableSchemas.join(', ')}`);
|
|
151
200
|
}
|
|
152
201
|
const schemaPath = path.join(schemaDir, 'schema.yaml');
|
|
@@ -204,39 +253,36 @@ export function listLoadableSchemas(projectRoot) {
|
|
|
204
253
|
* Every schema with its description and artifact list, for agent skills that
|
|
205
254
|
* present a schema choice.
|
|
206
255
|
*
|
|
207
|
-
* A schema that fails to parse is reported with `error` set,
|
|
208
|
-
*
|
|
209
|
-
*
|
|
256
|
+
* A schema that fails to parse is reported with `error` set, even when a lower
|
|
257
|
+
* layer has a working schema of that name. Resolution picks the highest layer
|
|
258
|
+
* whose schema.yaml exists and does not fall back past one that fails to parse,
|
|
259
|
+
* so listing the layer below as working would advertise a schema every command
|
|
260
|
+
* then refuses.
|
|
210
261
|
*/
|
|
211
262
|
export function listSchemasWithInfo(projectRoot) {
|
|
212
263
|
const schemas = [];
|
|
213
264
|
const seenNames = new Set();
|
|
214
|
-
// Keyed by name so the highest-precedence failure is the one reported, and a
|
|
215
|
-
// later success removes it.
|
|
216
|
-
const broken = new Map();
|
|
217
265
|
// Highest precedence first, so an overridden schema is skipped rather than
|
|
218
|
-
// replaced
|
|
219
|
-
// down still gets a chance to supply it.
|
|
266
|
+
// replaced — broken or not, the way `getSchemaDirWithSource` chooses.
|
|
220
267
|
for (const { dir, source } of schemaSources(projectRoot).reverse()) {
|
|
221
268
|
for (const name of scanSchemaDir(dir)) {
|
|
222
269
|
if (seenNames.has(name))
|
|
223
270
|
continue;
|
|
271
|
+
seenNames.add(name);
|
|
224
272
|
try {
|
|
225
273
|
const schema = parseSchema(fs.readFileSync(path.join(dir, name, 'schema.yaml'), 'utf-8'));
|
|
274
|
+
const warnings = findSchemaWarnings(schema);
|
|
226
275
|
schemas.push({
|
|
227
276
|
name,
|
|
228
277
|
description: schema.description || '',
|
|
229
278
|
artifacts: schema.artifacts.map((a) => a.id),
|
|
230
279
|
source,
|
|
231
280
|
path: path.join(dir, name),
|
|
281
|
+
...(warnings.length ? { warnings } : {}),
|
|
232
282
|
});
|
|
233
|
-
seenNames.add(name);
|
|
234
|
-
broken.delete(name);
|
|
235
283
|
}
|
|
236
284
|
catch (error) {
|
|
237
|
-
|
|
238
|
-
continue;
|
|
239
|
-
broken.set(name, {
|
|
285
|
+
schemas.push({
|
|
240
286
|
name,
|
|
241
287
|
description: '',
|
|
242
288
|
artifacts: [],
|
|
@@ -247,7 +293,7 @@ export function listSchemasWithInfo(projectRoot) {
|
|
|
247
293
|
}
|
|
248
294
|
}
|
|
249
295
|
}
|
|
250
|
-
return
|
|
296
|
+
return schemas.sort((a, b) => a.name.localeCompare(b.name));
|
|
251
297
|
}
|
|
252
298
|
/**
|
|
253
299
|
* Union of every artifact ID across every available schema.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAAsB,MAAM,aAAa,CAAC;AAEzG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE9D,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAGtB,UAAU;IACV,KAAK;IAHvB,YACE,OAAe,EACC,UAAkB,EAClB,KAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;0BAHC,UAAU;qBACV,KAAK;QAGrB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB;IAClC,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC9C,OAAO,WAAW;QAChB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC;QAC7C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,SAAS,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB;IAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChD,OAAO,GAAG,OAAO,IAAI,IAAI,EAAE,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,WAAW,GAAG,IAAI,GAAG,EAAiD,CAAC;AAE7E;;;GAGG;AACH,SAAS,yBAAyB,CAAC,UAAkB,EAAE,KAAc;IACnE,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,OAAO,KAAK,YAAY,qBAAqB;QAC3C,CAAC,CAAC,sBAAsB,UAAU,MAAM,MAAM,EAAE;QAChD,CAAC,CAAC,8BAA8B,UAAU,MAAM,MAAM,EAAE,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,WAAoB;IACzC,OAAO;QACL,EAAE,GAAG,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;QAClD,uEAAuE;QACvE,yEAAyE;QACzE,0DAA0D;QAC1D,EAAE,GAAG,EAAE,mBAAmB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;QAC9C,EAAE,GAAG,EAAE,iBAAiB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;QAC5C,GAAG,CAAC,WAAW;YACb,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,SAAkB,EAAE,CAAC;YAC1E,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,EAAE;SACN,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SACzC,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAC3F;SACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,WAAW,IAAI,gGAAgG,CAChH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAY,EACZ,WAAoB;IAEpB,0EAA0E;IAC1E,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,sEAAsE;IACtE,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAAY,EACZ,WAAoB;IAEpB,8EAA8E;IAC9E,2EAA2E;IAC3E,UAAU;IACV,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC;SACtC,OAAO,EAAE;SACT,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QAClB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IACL,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,MAAM,oBAAoB,GAAE,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAW,CAAC;AAEvG;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,WAAoB;IACpE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC5D,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,OAAO,IAAI,0CAA0C,CAAC;IACpF,OAAO,OAAO,IAAI,sDAAsD,oBAAoB,CAAC,QAAQ,CAAC,uBAAuB,CAAC;AAChI,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,WAAoB;IAEpB,OAAO,sBAAsB,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,WAAoB;IAC9D,OAAO,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,WAAoB;IACpE,OAAO,qBAAqB,CAAC,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAY,EACZ,WAA+B,EAC/B,OAAwC;IAExC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACpD,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAEjC,MAAM,SAAS,GAAG,YAAY,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,2EAA2E;QAC3E,6BAA6B;QAC7B,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,WAAW,cAAc,mCAAmC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAEvD,+EAA+E;IAC/E,yEAAyE;IACzE,6DAA6D;IAC7D,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxE,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QACrC,2EAA2E;QAC3E,OAAO,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACpE,MAAM,IAAI,eAAe,CACvB,6BAA6B,UAAU,MAAM,OAAO,CAAC,OAAO,EAAE,EAC9D,UAAU,EACV,OAAO,CACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,MAAM,IAAI,eAAe,CAAC,yBAAyB,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,WAAW,CAAC,WAAoB;IAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAoB;IACtD,OAAO,mBAAmB,CAAC,WAAW,CAAC;SACpC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC;SAC9C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAsBD;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAoB;IACtD,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,2EAA2E;IAC3E,sEAAsE;IACtE,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,aAAa,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QACnE,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAClC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC1F,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC5C,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI;oBACJ,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;oBACrC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5C,MAAM;oBACN,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;oBAC1B,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI;oBACJ,WAAW,EAAE,EAAE;oBACf,SAAS,EAAE,EAAE;oBACb,MAAM;oBACN,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC;oBAC1B,KAAK,EAAE,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,EAAE,KAAK,CAAC;iBAC7E,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAoB;IACxD,OAAO,IAAI,GAAG,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -4,4 +4,28 @@ export declare class SchemaValidationError extends Error {
|
|
|
4
4
|
}
|
|
5
5
|
export declare function loadSchema(filePath: string): SchemaYaml;
|
|
6
6
|
export declare function parseSchema(yamlContent: string): SchemaYaml;
|
|
7
|
+
/**
|
|
8
|
+
* Every code `findSchemaWarnings` can emit. A batch command uses it to print a
|
|
9
|
+
* schema's warning once rather than once per change on that schema; a
|
|
10
|
+
* per-change diagnostic such as `skip_specs_invalid` must not be folded that way.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SCHEMA_WARNING_CODES: ReadonlySet<string>;
|
|
13
|
+
/** A schema problem that still loads: reported alongside the command's output. */
|
|
14
|
+
export interface SchemaWarning {
|
|
15
|
+
code: string;
|
|
16
|
+
message: string;
|
|
17
|
+
fix: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Problems that leave the schema usable but make some command misreport.
|
|
21
|
+
*
|
|
22
|
+
* `apply.tracks` selects the tracked artifact by its `generates` value. One that
|
|
23
|
+
* matches no artifact made task progress fall back to `tasks.md`, so apply said
|
|
24
|
+
* "The TODO.md file is missing" while TODO.md sat in the change. A warning, not
|
|
25
|
+
* a load error: the schema's other workflows still work, and refusing to load it
|
|
26
|
+
* would break every change already on it. Reading `tracks` as a literal path
|
|
27
|
+
* instead was rejected: that is a second resolution rule `list`, the dashboard
|
|
28
|
+
* and the archive gate would not share.
|
|
29
|
+
*/
|
|
30
|
+
export declare function findSchemaWarnings(schema: SchemaYaml): SchemaWarning[];
|
|
7
31
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AAE9E,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAmB3D"}
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,UAAU,EAAiB,MAAM,YAAY,CAAC;AAE9E,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAEvD;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAmB3D;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAwC,CAAC;AAE9F,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,EAAE,CAWtE"}
|
|
@@ -26,10 +26,41 @@ export function parseSchema(yamlContent) {
|
|
|
26
26
|
validateApplyReferences(schema);
|
|
27
27
|
return schema;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Every code `findSchemaWarnings` can emit. A batch command uses it to print a
|
|
31
|
+
* schema's warning once rather than once per change on that schema; a
|
|
32
|
+
* per-change diagnostic such as `skip_specs_invalid` must not be folded that way.
|
|
33
|
+
*/
|
|
34
|
+
export const SCHEMA_WARNING_CODES = new Set(['schema_tracks_unmatched']);
|
|
35
|
+
/**
|
|
36
|
+
* Problems that leave the schema usable but make some command misreport.
|
|
37
|
+
*
|
|
38
|
+
* `apply.tracks` selects the tracked artifact by its `generates` value. One that
|
|
39
|
+
* matches no artifact made task progress fall back to `tasks.md`, so apply said
|
|
40
|
+
* "The TODO.md file is missing" while TODO.md sat in the change. A warning, not
|
|
41
|
+
* a load error: the schema's other workflows still work, and refusing to load it
|
|
42
|
+
* would break every change already on it. Reading `tracks` as a literal path
|
|
43
|
+
* instead was rejected: that is a second resolution rule `list`, the dashboard
|
|
44
|
+
* and the archive gate would not share.
|
|
45
|
+
*/
|
|
46
|
+
export function findSchemaWarnings(schema) {
|
|
47
|
+
const tracks = schema.apply?.tracks;
|
|
48
|
+
if (tracks == null || schema.artifacts.some((a) => a.generates === tracks))
|
|
49
|
+
return [];
|
|
50
|
+
const generates = schema.artifacts.map((a) => `'${a.generates}'`).join(', ');
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
code: 'schema_tracks_unmatched',
|
|
54
|
+
message: `Schema '${schema.name}': apply.tracks '${tracks}' matches no artifact's generates value, so task progress falls back to tasks.md.`,
|
|
55
|
+
fix: `Set apply.tracks to the generates value of the artifact that holds the tasks (one of: ${generates}).`,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
29
59
|
/**
|
|
30
60
|
* `tracks` is not checked alongside `requires`: it names a file inside the
|
|
31
61
|
* change directory, not an artifact id, and that file legitimately does not
|
|
32
|
-
* exist until the change is scaffolded.
|
|
62
|
+
* exist until the change is scaffolded. Whether it names an artifact's output
|
|
63
|
+
* is `findSchemaWarnings`'s concern.
|
|
33
64
|
*/
|
|
34
65
|
function validateApplyReferences(schema) {
|
|
35
66
|
if (!schema.apply)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one definition of "this artifact file is still the template": empty,
|
|
3
|
-
* whitespace-only, or
|
|
3
|
+
* whitespace-only, or identical to it once BOM and line endings are set aside.
|
|
4
4
|
*
|
|
5
|
-
* Shared by `status` and `
|
|
5
|
+
* Shared by `status`, `validate` and `instructions apply` (through
|
|
6
|
+
* `loadChangeContext`), which must agree: a change of verbatim
|
|
6
7
|
* templates would otherwise pass the last gate before archive.
|
|
7
8
|
*
|
|
8
9
|
* Cheap on purpose. A deeper "headings replaced, placeholders left" analysis
|
|
9
10
|
* belongs to the section rules in `validation/section-validator.ts`.
|
|
10
11
|
*/
|
|
11
12
|
export declare function isStubArtifactFile(file: string, schemaName: string, templatePath: string, projectRoot: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Which kind of stub the file is, or null when it is not one. Kept apart for
|
|
15
|
+
* the wording only: calling an empty file "the unfilled template" sends the
|
|
16
|
+
* reader to compare it against a template it never held.
|
|
17
|
+
*/
|
|
18
|
+
export type StubKind = 'empty' | 'template';
|
|
19
|
+
export declare function detectStubArtifact(file: string, schemaName: string, templatePath: string, projectRoot: string): StubKind | null;
|
|
12
20
|
//# sourceMappingURL=stub-detection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-detection.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"stub-detection.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5C,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,QAAQ,GAAG,IAAI,CAwBjB"}
|
|
@@ -1,39 +1,46 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
|
-
import {
|
|
2
|
+
import { normalizeDocument } from '../parsers/requirement-text.js';
|
|
3
3
|
import { loadTemplate } from './instruction-loader.js';
|
|
4
4
|
/**
|
|
5
5
|
* The one definition of "this artifact file is still the template": empty,
|
|
6
|
-
* whitespace-only, or
|
|
6
|
+
* whitespace-only, or identical to it once BOM and line endings are set aside.
|
|
7
7
|
*
|
|
8
|
-
* Shared by `status` and `
|
|
8
|
+
* Shared by `status`, `validate` and `instructions apply` (through
|
|
9
|
+
* `loadChangeContext`), which must agree: a change of verbatim
|
|
9
10
|
* templates would otherwise pass the last gate before archive.
|
|
10
11
|
*
|
|
11
12
|
* Cheap on purpose. A deeper "headings replaced, placeholders left" analysis
|
|
12
13
|
* belongs to the section rules in `validation/section-validator.ts`.
|
|
13
14
|
*/
|
|
14
15
|
export function isStubArtifactFile(file, schemaName, templatePath, projectRoot) {
|
|
16
|
+
return detectStubArtifact(file, schemaName, templatePath, projectRoot) !== null;
|
|
17
|
+
}
|
|
18
|
+
export function detectStubArtifact(file, schemaName, templatePath, projectRoot) {
|
|
15
19
|
let content;
|
|
16
20
|
try {
|
|
17
21
|
content = fs.readFileSync(file, 'utf-8');
|
|
18
22
|
}
|
|
19
23
|
catch {
|
|
20
24
|
// Unreadable is not stub: callers report the read failure on its own terms.
|
|
21
|
-
return
|
|
25
|
+
return null;
|
|
22
26
|
}
|
|
23
27
|
if (content.trim().length === 0)
|
|
24
|
-
return
|
|
28
|
+
return 'empty';
|
|
25
29
|
let template;
|
|
26
30
|
try {
|
|
27
31
|
template = loadTemplate(schemaName, templatePath, projectRoot);
|
|
28
32
|
}
|
|
29
33
|
catch {
|
|
30
34
|
// No template to compare against — say nothing rather than guess.
|
|
31
|
-
return
|
|
35
|
+
return null;
|
|
32
36
|
}
|
|
33
|
-
// Compared BOM-free: this is
|
|
34
|
-
// template in a Windows editor and saving it
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
|
|
37
|
+
// Compared BOM-free and LF-only on both sides: this is an identity test, so
|
|
38
|
+
// opening the untouched template in a Windows editor and saving it (which
|
|
39
|
+
// adds a BOM, or turns every newline into CRLF) would otherwise make a
|
|
40
|
+
// verbatim stub look edited — inverting the gate, which exists to stop
|
|
41
|
+
// exactly that file reaching archive. The template side is normalized too:
|
|
42
|
+
// a project override, or a checkout with `core.autocrlf`, can be CRLF while
|
|
43
|
+
// the agent writes its copy with LF.
|
|
44
|
+
return normalizeDocument(content) === normalizeDocument(template) ? 'template' : null;
|
|
38
45
|
}
|
|
39
46
|
//# sourceMappingURL=stub-detection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stub-detection.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"stub-detection.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/stub-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,UAAkB,EAClB,YAAoB,EACpB,WAAmB;IAEnB,OAAO,kBAAkB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;AAClF,CAAC;AASD,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,UAAkB,EAClB,YAAoB,EACpB,WAAmB;IAEnB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,4EAA4E;IAC5E,0EAA0E;IAC1E,uEAAuE;IACvE,uEAAuE;IACvE,2EAA2E;IAC3E,4EAA4E;IAC5E,qCAAqC;IACrC,OAAO,iBAAiB,CAAC,OAAO,CAAC,KAAK,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACxF,CAAC"}
|
|
@@ -20,7 +20,7 @@ export declare const ArtifactSchema: z.ZodObject<{
|
|
|
20
20
|
}, z.core.$strip>;
|
|
21
21
|
export declare const ApplyPhaseSchema: z.ZodObject<{
|
|
22
22
|
requires: z.ZodArray<z.ZodString>;
|
|
23
|
-
tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
23
|
+
tracks: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
|
|
24
24
|
instruction: z.ZodOptional<z.ZodString>;
|
|
25
25
|
}, z.core.$strip>;
|
|
26
26
|
export declare const SchemaYamlSchema: z.ZodObject<{
|
|
@@ -43,7 +43,7 @@ export declare const SchemaYamlSchema: z.ZodObject<{
|
|
|
43
43
|
}, z.core.$strip>>;
|
|
44
44
|
apply: z.ZodOptional<z.ZodObject<{
|
|
45
45
|
requires: z.ZodArray<z.ZodString>;
|
|
46
|
-
tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
46
|
+
tracks: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null | undefined, string | null | undefined>>;
|
|
47
47
|
instruction: z.ZodOptional<z.ZodString>;
|
|
48
48
|
}, z.core.$strip>>;
|
|
49
49
|
}, z.core.$strip>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;iBAMnC,CAAC;AA4CH,eAAO,MAAM,cAAc;;;;;;;;;;;;;iBASzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,wBAAwB;;;;iBAMnC,CAAC;AA4CH,eAAO,MAAM,cAAc;;;;;;;;;;;;;iBASzB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;iBAe3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;iBAM3B,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC"}
|
|
@@ -60,7 +60,16 @@ export const ApplyPhaseSchema = z.object({
|
|
|
60
60
|
/** Artifact IDs that must exist before apply is available. */
|
|
61
61
|
requires: z.array(z.string()).min(1, { error: 'At least one required artifact' }),
|
|
62
62
|
/** Change-relative path to the file holding progress checkboxes; null for none. */
|
|
63
|
-
|
|
63
|
+
// '' becomes null here, once, because readers split on it: apply tested the
|
|
64
|
+
// value for truthiness and saw "no tracks", while task progress and
|
|
65
|
+
// findSchemaWarnings tested `!= null` and saw a filename matching nothing,
|
|
66
|
+
// so list and archive counted tasks.md and the warning claimed that fallback.
|
|
67
|
+
// An empty filename names no file, so "none" is the only reading all agree on.
|
|
68
|
+
tracks: z
|
|
69
|
+
.string()
|
|
70
|
+
.nullable()
|
|
71
|
+
.optional()
|
|
72
|
+
.transform((value) => (value === '' ? null : value)),
|
|
64
73
|
instruction: z.string().optional(),
|
|
65
74
|
});
|
|
66
75
|
export const SchemaYamlSchema = z.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/types.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wEAAwE;AACxE,8EAA8E;AAC9E,gCAAgC;AAChC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACjD,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9D,kEAAkE;IAClE,sEAAsE;IACtE,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,uBAAuB,GAAG,CAAC;KAC9B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;KAChD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IACvE,KAAK,EAAE,qFAAqF;CAC7F,CAAC;KACD,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CACR,CAAC,KAAK;KACH,KAAK,CAAC,OAAO,CAAC;KACd,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EACxC,EAAE,KAAK,EAAE,4EAA4E,EAAE,CACxF,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,0BAA0B,GAAG,CAAC;KACjC,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;KAC/C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;IACvE,KAAK,EAAE,kGAAkG;CAC1G,CAAC;KACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE;IAC5E,KAAK,EAAE,yFAAyF;CACjG,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC3D,SAAS,EAAE,uBAAuB;IAClC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,QAAQ,EAAE,0BAA0B;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACpC,UAAU,EAAE,wBAAwB,CAAC,QAAQ,EAAE;CAChD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,8DAA8D;IAC9D,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;IACjF,mFAAmF;IACnF,4EAA4E;IAC5E,oEAAoE;IACpE,2EAA2E;IAC3E,8EAA8E;IAC9E,+EAA+E;IAC/E,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC7D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACnF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;IACtF,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,oBAAoB;;;;;;;;;;iBAsC/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { CREATED_PATTERN, parseCreated } from '../../utils/timestamp.js';
|
|
2
3
|
// Per-change metadata schema. The schema field is validated against available
|
|
3
4
|
// workflow schemas when metadata is read or written.
|
|
4
5
|
export const ChangeMetadataSchema = z.object({
|
|
@@ -8,10 +9,21 @@ export const ChangeMetadataSchema = z.object({
|
|
|
8
9
|
// the file exists or not: take the project default.
|
|
9
10
|
schema: z.string().min(1, { message: 'schema must be a non-empty string' }).optional(),
|
|
10
11
|
type: z.enum(['requirement', 'issue']).optional(),
|
|
12
|
+
// `new change` writes the local datetime; the day alone is what changes
|
|
13
|
+
// made before it recorded, and it stays valid so they keep reading.
|
|
14
|
+
// The pattern alone let `2026-02-30` through: validate called it valid, and
|
|
15
|
+
// the only check that refused it was sister ordering, which read it as "no
|
|
16
|
+
// order" without saying why. `abort` keeps a misspelled value to the format
|
|
17
|
+
// message instead of also claiming it names no real moment. No `;` in the
|
|
18
|
+
// messages: describeMetadataIssues joins one field's issue to the next's with it.
|
|
11
19
|
created: z
|
|
12
20
|
.string()
|
|
13
|
-
.regex(
|
|
14
|
-
message: 'created must be YYYY-MM-DD format',
|
|
21
|
+
.regex(CREATED_PATTERN, {
|
|
22
|
+
message: 'created must be YYYY-MM-DDTHH:mm:ss (local time) or YYYY-MM-DD format',
|
|
23
|
+
abort: true,
|
|
24
|
+
})
|
|
25
|
+
.refine((value) => parseCreated(value) !== null, {
|
|
26
|
+
message: 'created names a date or time that does not exist (e.g. 2026-02-30 or T25:00:00): use a real YYYY-MM-DDTHH:mm:ss (local time) or YYYY-MM-DD',
|
|
15
27
|
})
|
|
16
28
|
.optional(),
|
|
17
29
|
goal: z.string().min(1).optional(),
|
|
@@ -19,8 +31,10 @@ export const ChangeMetadataSchema = z.object({
|
|
|
19
31
|
// "20260722_161825-topic.md" under tospec/decisions/. Optional so existing
|
|
20
32
|
// metadata files without the field stay valid; absent means none.
|
|
21
33
|
decisions: z.array(z.string().min(1)).optional(),
|
|
22
|
-
//
|
|
23
|
-
// the "at least one delta" rule
|
|
34
|
+
// Records the user's decision that this change needs no delta spec, waiving
|
|
35
|
+
// the "at least one delta" rule; set only on the user's word, and a spec
|
|
36
|
+
// file beside it is a contradiction validate refuses, not a delta the waiver
|
|
37
|
+
// hides. A property of the change, not archive's
|
|
24
38
|
// one-shot --skip-specs flag: letting the flag imply this would make
|
|
25
39
|
// `tospec validate` answer differently depending on how archive was last run.
|
|
26
40
|
// Read via readSkipSpecsMarker, which reports a non-boolean value as an error.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/change-metadata/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEzE,8EAA8E;AAC9E,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtF,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,wEAAwE;IACxE,oEAAoE;IACpE,4EAA4E;IAC5E,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,kFAAkF;IAClF,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,eAAe,EAAE;QACtB,OAAO,EAAE,uEAAuE;QAChF,KAAK,EAAE,IAAI;KACZ,CAAC;SACD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE;QAC/C,OAAO,EACL,4IAA4I;KAC/I,CAAC;SACD,QAAQ,EAAE;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC,qDAAqD;IACrD,2EAA2E;IAC3E,kEAAkE;IAClE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChD,4EAA4E;IAC5E,yEAAyE;IACzE,6EAA6E;IAC7E,iDAAiD;IACjD,qEAAqE;IACrE,8EAA8E;IAC9E,+EAA+E;IAC/E,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-presenter.d.ts","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"change-presenter.d.ts","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA8BtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAS;IAI1B,YAAY,QAAQ,CAAC,EAAE,MAAM,EAG5B;IAED,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAIpB;;;;;OAKG;IACG,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF/L;IAED;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAaxB;;;;iBAIa,SAKC,gBAAgB;IAkB9B;;;;;OAKG;YACW,gBAAgB;IA2F9B;;;;;OAKG;YACW,qBAAqB;IAiCnC,8EAA8E;YAChE,aAAa;IAe3B,OAAO,CAAC,aAAa;YAsDP,UAAU;IASxB,OAAO,CAAC,YAAY;CAWrB"}
|
|
@@ -10,7 +10,8 @@ import { findSpecUpdates } from './specs-apply.js';
|
|
|
10
10
|
import { resolveSchemaForChange } from '../utils/change-metadata.js';
|
|
11
11
|
import { resolveSchema } from './artifact-graph/index.js';
|
|
12
12
|
import { foldRequirementName, parseDeltaSpec } from './parsers/requirement-blocks.js';
|
|
13
|
-
import {
|
|
13
|
+
import { stripClosingHashes } from './parsers/requirement-text.js';
|
|
14
|
+
import { MarkdownParser } from './parsers/markdown-parser.js';
|
|
14
15
|
import { buildRenameMap, diffRequirementBlock, extractRequirementBlock, } from '../utils/requirement-diff.js';
|
|
15
16
|
export class ChangePresenter {
|
|
16
17
|
converter;
|
|
@@ -73,6 +74,11 @@ export class ChangePresenter {
|
|
|
73
74
|
if (!primaryPath || !(await this.fileExists(primaryPath))) {
|
|
74
75
|
throw new Error(`Change "${changeName}" not found (no main artifact in ${changeDir}, no ticket in tospec/tickets/)`);
|
|
75
76
|
}
|
|
77
|
+
// Both modes: printed in the --json branch only, a human run accepted the
|
|
78
|
+
// deprecated flag with no word. stderr, so --json stdout stays one document.
|
|
79
|
+
if (options?.requirementsOnly) {
|
|
80
|
+
console.error('Warning: Flag --requirements-only is deprecated; use --deltas-only instead.');
|
|
81
|
+
}
|
|
76
82
|
if (options?.json) {
|
|
77
83
|
const parser = new ChangeParser('', changeDir);
|
|
78
84
|
let deltas = await parser.parseDeltaSpecs(path.join(changeDir, 'specs'));
|
|
@@ -86,9 +92,6 @@ export class ChangePresenter {
|
|
|
86
92
|
// No inline deltas — proposal is prose only, which is fine.
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
|
-
if (options.requirementsOnly) {
|
|
90
|
-
console.error('Flag --requirements-only is deprecated; use --deltas-only instead.');
|
|
91
|
-
}
|
|
92
95
|
if (options.diff) {
|
|
93
96
|
await this.enrichDeltasWithDiffs(deltas, changeDir);
|
|
94
97
|
}
|
|
@@ -357,10 +360,12 @@ ${body}`;
|
|
|
357
360
|
const fmTitle = frontmatterString(content, 'title')?.trim();
|
|
358
361
|
if (fmTitle)
|
|
359
362
|
return fmTitle;
|
|
360
|
-
// `
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
363
|
+
// The H1 as `decision` reads one: through the parser, so a fenced `# x` is
|
|
364
|
+
// no title, and without the closing `#` run. A local regex kept that run,
|
|
365
|
+
// so `# Use X ##` titled the change `Use X ##`.
|
|
366
|
+
const h1 = new MarkdownParser(content).getSections().find((section) => section.level === 1);
|
|
367
|
+
const title = h1 ? stripClosingHashes(h1.title).replace(/^Change:\s+/i, '') : '';
|
|
368
|
+
return title || changeName;
|
|
364
369
|
}
|
|
365
370
|
}
|
|
366
371
|
//# sourceMappingURL=change-presenter.js.map
|