@seanmars/tospec 0.12.0 → 0.14.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.
Files changed (201) hide show
  1. package/CHANGELOG.md +233 -0
  2. package/README.md +20 -7
  3. package/assets/dashboard/app.js +6 -0
  4. package/assets/dashboard/style.css +42 -5
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +39 -16
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/commands/config.d.ts.map +1 -1
  9. package/dist/commands/config.js +21 -16
  10. package/dist/commands/config.js.map +1 -1
  11. package/dist/commands/dashboard.d.ts +95 -8
  12. package/dist/commands/dashboard.d.ts.map +1 -1
  13. package/dist/commands/dashboard.js +256 -31
  14. package/dist/commands/dashboard.js.map +1 -1
  15. package/dist/commands/decision.d.ts.map +1 -1
  16. package/dist/commands/decision.js +1 -13
  17. package/dist/commands/decision.js.map +1 -1
  18. package/dist/commands/validate.d.ts.map +1 -1
  19. package/dist/commands/validate.js +80 -44
  20. package/dist/commands/validate.js.map +1 -1
  21. package/dist/commands/workflow/instructions.d.ts +0 -2
  22. package/dist/commands/workflow/instructions.d.ts.map +1 -1
  23. package/dist/commands/workflow/instructions.js +3 -38
  24. package/dist/commands/workflow/instructions.js.map +1 -1
  25. package/dist/commands/workflow/shared.d.ts +0 -3
  26. package/dist/commands/workflow/shared.d.ts.map +1 -1
  27. package/dist/commands/workflow/shared.js.map +1 -1
  28. package/dist/core/archive.d.ts +11 -2
  29. package/dist/core/archive.d.ts.map +1 -1
  30. package/dist/core/archive.js +110 -111
  31. package/dist/core/archive.js.map +1 -1
  32. package/dist/core/artifact-graph/instruction-loader.d.ts +0 -5
  33. package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -1
  34. package/dist/core/artifact-graph/instruction-loader.js +37 -40
  35. package/dist/core/artifact-graph/instruction-loader.js.map +1 -1
  36. package/dist/core/artifact-graph/resolver.d.ts +27 -1
  37. package/dist/core/artifact-graph/resolver.d.ts.map +1 -1
  38. package/dist/core/artifact-graph/resolver.js +114 -127
  39. package/dist/core/artifact-graph/resolver.js.map +1 -1
  40. package/dist/core/artifact-graph/schema.d.ts.map +1 -1
  41. package/dist/core/artifact-graph/schema.js +22 -0
  42. package/dist/core/artifact-graph/schema.js.map +1 -1
  43. package/dist/core/change-metadata/schema.d.ts +1 -0
  44. package/dist/core/change-metadata/schema.d.ts.map +1 -1
  45. package/dist/core/change-metadata/schema.js +7 -0
  46. package/dist/core/change-metadata/schema.js.map +1 -1
  47. package/dist/core/change-presenter.d.ts +0 -1
  48. package/dist/core/change-presenter.d.ts.map +1 -1
  49. package/dist/core/change-presenter.js +4 -21
  50. package/dist/core/change-presenter.js.map +1 -1
  51. package/dist/core/command-generation/adapters/index.d.ts +9 -1
  52. package/dist/core/command-generation/adapters/index.d.ts.map +1 -1
  53. package/dist/core/command-generation/adapters/index.js +10 -1
  54. package/dist/core/command-generation/adapters/index.js.map +1 -1
  55. package/dist/core/command-generation/index.d.ts +2 -2
  56. package/dist/core/command-generation/index.d.ts.map +1 -1
  57. package/dist/core/command-generation/index.js +2 -2
  58. package/dist/core/command-generation/index.js.map +1 -1
  59. package/dist/core/config.d.ts +0 -4
  60. package/dist/core/config.d.ts.map +1 -1
  61. package/dist/core/config.js +0 -4
  62. package/dist/core/config.js.map +1 -1
  63. package/dist/core/converters/json-converter.d.ts +0 -1
  64. package/dist/core/converters/json-converter.d.ts.map +1 -1
  65. package/dist/core/converters/json-converter.js +3 -17
  66. package/dist/core/converters/json-converter.js.map +1 -1
  67. package/dist/core/dashboard-activity.d.ts.map +1 -1
  68. package/dist/core/dashboard-activity.js +2 -8
  69. package/dist/core/dashboard-activity.js.map +1 -1
  70. package/dist/core/dashboard-data.d.ts +12 -6
  71. package/dist/core/dashboard-data.d.ts.map +1 -1
  72. package/dist/core/dashboard-data.js +13 -44
  73. package/dist/core/dashboard-data.js.map +1 -1
  74. package/dist/core/global-config.d.ts +59 -16
  75. package/dist/core/global-config.d.ts.map +1 -1
  76. package/dist/core/global-config.js +99 -41
  77. package/dist/core/global-config.js.map +1 -1
  78. package/dist/core/id.d.ts +0 -8
  79. package/dist/core/id.d.ts.map +1 -1
  80. package/dist/core/id.js +0 -19
  81. package/dist/core/id.js.map +1 -1
  82. package/dist/core/init.d.ts +0 -1
  83. package/dist/core/init.d.ts.map +1 -1
  84. package/dist/core/init.js +13 -23
  85. package/dist/core/init.js.map +1 -1
  86. package/dist/core/list.d.ts.map +1 -1
  87. package/dist/core/list.js +3 -34
  88. package/dist/core/list.js.map +1 -1
  89. package/dist/core/migrate.js +9 -15
  90. package/dist/core/migrate.js.map +1 -1
  91. package/dist/core/parsers/markdown-parser.d.ts +11 -1
  92. package/dist/core/parsers/markdown-parser.d.ts.map +1 -1
  93. package/dist/core/parsers/markdown-parser.js +25 -13
  94. package/dist/core/parsers/markdown-parser.js.map +1 -1
  95. package/dist/core/planning-home.d.ts +6 -0
  96. package/dist/core/planning-home.d.ts.map +1 -1
  97. package/dist/core/planning-home.js +6 -1
  98. package/dist/core/planning-home.js.map +1 -1
  99. package/dist/core/project-config.d.ts +17 -26
  100. package/dist/core/project-config.d.ts.map +1 -1
  101. package/dist/core/project-config.js +24 -138
  102. package/dist/core/project-config.js.map +1 -1
  103. package/dist/core/root-selection.d.ts.map +1 -1
  104. package/dist/core/root-selection.js +2 -15
  105. package/dist/core/root-selection.js.map +1 -1
  106. package/dist/core/shared/index.d.ts +1 -1
  107. package/dist/core/shared/index.d.ts.map +1 -1
  108. package/dist/core/shared/index.js +1 -1
  109. package/dist/core/shared/index.js.map +1 -1
  110. package/dist/core/shared/skill-generation.js +3 -3
  111. package/dist/core/shared/skill-generation.js.map +1 -1
  112. package/dist/core/shared/tool-detection.d.ts +9 -6
  113. package/dist/core/shared/tool-detection.d.ts.map +1 -1
  114. package/dist/core/shared/tool-detection.js +9 -9
  115. package/dist/core/shared/tool-detection.js.map +1 -1
  116. package/dist/core/spec-presenter.d.ts.map +1 -1
  117. package/dist/core/spec-presenter.js.map +1 -1
  118. package/dist/core/specs-apply.d.ts +0 -31
  119. package/dist/core/specs-apply.d.ts.map +1 -1
  120. package/dist/core/specs-apply.js +0 -102
  121. package/dist/core/specs-apply.js.map +1 -1
  122. package/dist/core/templates/fragments/verify.d.ts +12 -11
  123. package/dist/core/templates/fragments/verify.d.ts.map +1 -1
  124. package/dist/core/templates/fragments/verify.js +22 -15
  125. package/dist/core/templates/fragments/verify.js.map +1 -1
  126. package/dist/core/templates/workflows/apply.d.ts +2 -2
  127. package/dist/core/templates/workflows/apply.js +10 -10
  128. package/dist/core/templates/workflows/apply.js.map +1 -1
  129. package/dist/core/templates/workflows/archive.d.ts.map +1 -1
  130. package/dist/core/templates/workflows/archive.js +30 -20
  131. package/dist/core/templates/workflows/archive.js.map +1 -1
  132. package/dist/core/templates/workflows/propose.js +2 -2
  133. package/dist/core/templates/workflows/sync.d.ts +4 -3
  134. package/dist/core/templates/workflows/sync.d.ts.map +1 -1
  135. package/dist/core/templates/workflows/sync.js +30 -13
  136. package/dist/core/templates/workflows/sync.js.map +1 -1
  137. package/dist/core/templates/workflows/update.js +1 -1
  138. package/dist/core/update.d.ts.map +1 -1
  139. package/dist/core/update.js +10 -15
  140. package/dist/core/update.js.map +1 -1
  141. package/dist/core/user-state-migration.d.ts +58 -0
  142. package/dist/core/user-state-migration.d.ts.map +1 -0
  143. package/dist/core/user-state-migration.js +107 -0
  144. package/dist/core/user-state-migration.js.map +1 -0
  145. package/dist/core/validation/section-validator.d.ts.map +1 -1
  146. package/dist/core/validation/section-validator.js +3 -16
  147. package/dist/core/validation/section-validator.js.map +1 -1
  148. package/dist/core/validation/validator.d.ts +0 -9
  149. package/dist/core/validation/validator.d.ts.map +1 -1
  150. package/dist/core/validation/validator.js +86 -115
  151. package/dist/core/validation/validator.js.map +1 -1
  152. package/dist/utils/change-metadata.d.ts +18 -0
  153. package/dist/utils/change-metadata.d.ts.map +1 -1
  154. package/dist/utils/change-metadata.js +39 -0
  155. package/dist/utils/change-metadata.js.map +1 -1
  156. package/dist/utils/change-utils.d.ts.map +1 -1
  157. package/dist/utils/change-utils.js +3 -6
  158. package/dist/utils/change-utils.js.map +1 -1
  159. package/dist/utils/file-system.d.ts +17 -19
  160. package/dist/utils/file-system.d.ts.map +1 -1
  161. package/dist/utils/file-system.js +41 -189
  162. package/dist/utils/file-system.js.map +1 -1
  163. package/dist/utils/frontmatter.d.ts +22 -0
  164. package/dist/utils/frontmatter.d.ts.map +1 -0
  165. package/dist/utils/frontmatter.js +39 -0
  166. package/dist/utils/frontmatter.js.map +1 -0
  167. package/dist/utils/item-discovery.d.ts +7 -0
  168. package/dist/utils/item-discovery.d.ts.map +1 -1
  169. package/dist/utils/item-discovery.js +13 -23
  170. package/dist/utils/item-discovery.js.map +1 -1
  171. package/dist/utils/link.d.ts +3 -1
  172. package/dist/utils/link.d.ts.map +1 -1
  173. package/dist/utils/link.js +4 -14
  174. package/dist/utils/link.js.map +1 -1
  175. package/dist/utils/spec-files.d.ts +19 -0
  176. package/dist/utils/spec-files.d.ts.map +1 -0
  177. package/dist/utils/spec-files.js +44 -0
  178. package/dist/utils/spec-files.js.map +1 -0
  179. package/dist/utils/task-progress.d.ts +0 -1
  180. package/dist/utils/task-progress.d.ts.map +1 -1
  181. package/dist/utils/task-progress.js +5 -6
  182. package/dist/utils/task-progress.js.map +1 -1
  183. package/package.json +11 -2
  184. package/schemas/issue/schema.yaml +6 -3
  185. package/schemas/sdd/schema.yaml +15 -2
  186. package/dist/core/references.d.ts +0 -40
  187. package/dist/core/references.d.ts.map +0 -1
  188. package/dist/core/references.js +0 -11
  189. package/dist/core/references.js.map +0 -1
  190. package/dist/utils/command-references.d.ts +0 -18
  191. package/dist/utils/command-references.d.ts.map +0 -1
  192. package/dist/utils/command-references.js +0 -20
  193. package/dist/utils/command-references.js.map +0 -1
  194. package/dist/utils/index.d.ts +0 -6
  195. package/dist/utils/index.d.ts.map +0 -1
  196. package/dist/utils/index.js +0 -9
  197. package/dist/utils/index.js.map +0 -1
  198. package/dist/utils/shell-detection.d.ts +0 -20
  199. package/dist/utils/shell-detection.d.ts.map +0 -1
  200. package/dist/utils/shell-detection.js +0 -41
  201. package/dist/utils/shell-detection.js.map +0 -1
@@ -14,7 +14,9 @@ export declare class SchemaLoadError extends Error {
14
14
  */
15
15
  export declare function getPackageSchemasDir(): string;
16
16
  /**
17
- * Gets the user's schema override directory path.
17
+ * The user's schema override directory: inside the config directory, unless
18
+ * XDG_DATA_HOME names one — in which case it *replaces* this location rather
19
+ * than adding to it, so exactly one user-level override directory is ever live.
18
20
  */
19
21
  export declare function getUserSchemasDir(): string;
20
22
  /**
@@ -47,6 +49,12 @@ export declare function isSchemaDir(parentDir: string, entry: fs.Dirent): boolea
47
49
  * @param projectRoot - Optional project root directory for project-local schema resolution
48
50
  * @returns The path to the schema directory, or null if not found
49
51
  */
52
+ /**
53
+ * Identity of a file's current contents, for cache invalidation. Null when the
54
+ * file cannot be stat'd, which disables caching for that path rather than
55
+ * risking a stale hit.
56
+ */
57
+ export declare function fileStamp(filePath: string): string | null;
50
58
  export declare function getSchemaDir(name: string, projectRoot?: string): string | null;
51
59
  /**
52
60
  * Resolves a schema name to a SchemaYaml object.
@@ -80,6 +88,12 @@ export interface SchemaInfo {
80
88
  description: string;
81
89
  artifacts: string[];
82
90
  source: 'project' | 'user' | 'package';
91
+ /**
92
+ * Absolute path to the directory holding schema.yaml (and its templates/).
93
+ * `source` says which of the three layers won; this says which file to open —
94
+ * the question a schema author actually has when a resolution surprises them.
95
+ */
96
+ path: string;
83
97
  }
84
98
  /**
85
99
  * Lists all available schemas with their descriptions and artifact lists.
@@ -88,4 +102,16 @@ export interface SchemaInfo {
88
102
  * @param projectRoot - Optional project root directory for project-local schema resolution
89
103
  */
90
104
  export declare function listSchemasWithInfo(projectRoot?: string): SchemaInfo[];
105
+ /**
106
+ * Union of every artifact ID across every available schema.
107
+ *
108
+ * Config keys that are scoped per-artifact but stored globally (`rules:`) can
109
+ * legitimately name an artifact from any schema, so they must be checked
110
+ * against the union rather than whichever schema the current change uses.
111
+ *
112
+ * Built on listSchemasWithInfo so it inherits that function's precedence
113
+ * handling and its tolerance for a schema that fails to parse — one broken
114
+ * custom schema must not turn every rules key into an unknown ID.
115
+ */
116
+ export declare function collectAllArtifactIds(projectRoot?: string): Set<string>;
91
117
  //# sourceMappingURL=resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAK9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,UAAU,EAAE,MAAM;aAClB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,OAAO,CAYxE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,IAAI,CAyBf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CA4C5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CA6C1D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;CACxC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CA8EtE"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAK9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,UAAU,EAAE,MAAM;aAClB,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C;AAWD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,GAAG,OAAO,CAYxE;AAED;;;;;;;;;;;;;;GAcG;AACH;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOzD;AAoCD,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CA0D5E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CA2BtE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAEvE"}
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { getGlobalDataDir } from '../global-config.js';
4
+ import { getGlobalConfigDir, getLegacyDataDir } from '../global-config.js';
5
5
  import { parseSchema, SchemaValidationError } from './schema.js';
6
6
  /**
7
7
  * Error thrown when loading a schema fails.
@@ -26,10 +26,23 @@ export function getPackageSchemasDir() {
26
26
  return path.join(path.dirname(currentFile), '..', '..', '..', 'schemas');
27
27
  }
28
28
  /**
29
- * Gets the user's schema override directory path.
29
+ * The user's schema override directory: inside the config directory, unless
30
+ * XDG_DATA_HOME names one — in which case it *replaces* this location rather
31
+ * than adding to it, so exactly one user-level override directory is ever live.
30
32
  */
31
33
  export function getUserSchemasDir() {
32
- return path.join(getGlobalDataDir(), 'schemas');
34
+ const xdgDataHome = process.env.XDG_DATA_HOME;
35
+ return xdgDataHome
36
+ ? path.join(xdgDataHome, 'tospec', 'schemas')
37
+ : path.join(getGlobalConfigDir(), 'schemas');
38
+ }
39
+ /**
40
+ * Where overrides sit until an install migrates. Ranked below the current user
41
+ * directory, so a migrated copy wins and a not-yet-migrated one still applies —
42
+ * per schema name, because every lookup walks this list name by name.
43
+ */
44
+ function getLegacySchemasDir() {
45
+ return path.join(getLegacyDataDir(), 'schemas');
33
46
  }
34
47
  /**
35
48
  * Gets the project-local schemas directory path.
@@ -76,26 +89,56 @@ export function isSchemaDir(parentDir, entry) {
76
89
  * @param projectRoot - Optional project root directory for project-local schema resolution
77
90
  * @returns The path to the schema directory, or null if not found
78
91
  */
79
- export function getSchemaDir(name, projectRoot) {
80
- // 1. Check project-local directory (if projectRoot provided)
81
- if (projectRoot) {
82
- const projectDir = path.join(getProjectSchemasDir(projectRoot), name);
83
- const projectSchemaPath = path.join(projectDir, 'schema.yaml');
84
- if (fs.existsSync(projectSchemaPath)) {
85
- return projectDir;
86
- }
92
+ /**
93
+ * Identity of a file's current contents, for cache invalidation. Null when the
94
+ * file cannot be stat'd, which disables caching for that path rather than
95
+ * risking a stale hit.
96
+ */
97
+ export function fileStamp(filePath) {
98
+ try {
99
+ const { mtimeMs, size } = fs.statSync(filePath);
100
+ return `${mtimeMs}:${size}`;
87
101
  }
88
- // 2. Check user override directory
89
- const userDir = path.join(getUserSchemasDir(), name);
90
- const userSchemaPath = path.join(userDir, 'schema.yaml');
91
- if (fs.existsSync(userSchemaPath)) {
92
- return userDir;
102
+ catch {
103
+ return null;
93
104
  }
94
- // 3. Check package built-in directory
95
- const packageDir = path.join(getPackageSchemasDir(), name);
96
- const packageSchemaPath = path.join(packageDir, 'schema.yaml');
97
- if (fs.existsSync(packageSchemaPath)) {
98
- return packageDir;
105
+ }
106
+ /** Parsed schemas keyed by path, invalidated when the file's stamp changes. */
107
+ const schemaCache = new Map();
108
+ /**
109
+ * The schema search path, **lowest precedence first** (package → user →
110
+ * project). Every lookup and listing walks this one list, so adding a source
111
+ * is a single edit rather than one per function.
112
+ */
113
+ function schemaSources(projectRoot) {
114
+ return [
115
+ { dir: getPackageSchemasDir(), source: 'package' },
116
+ // Both report 'user' — the legacy entry is one address for the same layer,
117
+ // and a 'legacy' value would widen the agent-facing JSON contract with
118
+ // something that stops existing once migration runs.
119
+ { dir: getLegacySchemasDir(), source: 'user' },
120
+ { dir: getUserSchemasDir(), source: 'user' },
121
+ ...(projectRoot
122
+ ? [{ dir: getProjectSchemasDir(projectRoot), source: 'project' }]
123
+ : []),
124
+ ];
125
+ }
126
+ /** Names of the directories under `dir` that actually contain a schema.yaml. */
127
+ function scanSchemaDir(dir) {
128
+ if (!fs.existsSync(dir))
129
+ return [];
130
+ return fs
131
+ .readdirSync(dir, { withFileTypes: true })
132
+ .filter((entry) => isSchemaDir(dir, entry) && fs.existsSync(path.join(dir, entry.name, 'schema.yaml')))
133
+ .map((entry) => entry.name);
134
+ }
135
+ export function getSchemaDir(name, projectRoot) {
136
+ // Highest precedence first: project overrides user overrides package.
137
+ for (const { dir } of schemaSources(projectRoot).reverse()) {
138
+ const candidate = path.join(dir, name);
139
+ if (fs.existsSync(path.join(candidate, 'schema.yaml'))) {
140
+ return candidate;
141
+ }
99
142
  }
100
143
  return null;
101
144
  }
@@ -124,6 +167,15 @@ export function resolveSchema(name, projectRoot) {
124
167
  throw new Error(`Schema '${normalizedName}' not found. Available schemas: ${availableSchemas.join(', ')}`);
125
168
  }
126
169
  const schemaPath = path.join(schemaDir, 'schema.yaml');
170
+ // A single status/list run resolves the same schema once per change, and the
171
+ // dashboard re-resolves on every refresh; the yaml + Zod + cycle-check parse
172
+ // dominates that cost. One statSync decides whether it can be skipped.
173
+ const stamp = fileStamp(schemaPath);
174
+ const cached = stamp === null ? undefined : schemaCache.get(schemaPath);
175
+ if (cached && cached.stamp === stamp) {
176
+ // Cloned so a caller mutating its schema cannot corrupt later resolutions.
177
+ return structuredClone(cached.schema);
178
+ }
127
179
  // Load and parse the schema
128
180
  let content;
129
181
  try {
@@ -134,7 +186,11 @@ export function resolveSchema(name, projectRoot) {
134
186
  throw new SchemaLoadError(`Failed to read schema at '${schemaPath}': ${ioError.message}`, schemaPath, ioError);
135
187
  }
136
188
  try {
137
- return parseSchema(content);
189
+ const schema = parseSchema(content);
190
+ if (stamp !== null) {
191
+ schemaCache.set(schemaPath, { stamp, schema: structuredClone(schema) });
192
+ }
193
+ return schema;
138
194
  }
139
195
  catch (err) {
140
196
  if (err instanceof SchemaValidationError) {
@@ -152,42 +208,9 @@ export function resolveSchema(name, projectRoot) {
152
208
  */
153
209
  export function listSchemas(projectRoot) {
154
210
  const schemas = new Set();
155
- // Add package built-in schemas
156
- const packageDir = getPackageSchemasDir();
157
- if (fs.existsSync(packageDir)) {
158
- for (const entry of fs.readdirSync(packageDir, { withFileTypes: true })) {
159
- if (isSchemaDir(packageDir, entry)) {
160
- const schemaPath = path.join(packageDir, entry.name, 'schema.yaml');
161
- if (fs.existsSync(schemaPath)) {
162
- schemas.add(entry.name);
163
- }
164
- }
165
- }
166
- }
167
- // Add user override schemas (may override package schemas)
168
- const userDir = getUserSchemasDir();
169
- if (fs.existsSync(userDir)) {
170
- for (const entry of fs.readdirSync(userDir, { withFileTypes: true })) {
171
- if (isSchemaDir(userDir, entry)) {
172
- const schemaPath = path.join(userDir, entry.name, 'schema.yaml');
173
- if (fs.existsSync(schemaPath)) {
174
- schemas.add(entry.name);
175
- }
176
- }
177
- }
178
- }
179
- // Add project-local schemas (if projectRoot provided)
180
- if (projectRoot) {
181
- const projectDir = getProjectSchemasDir(projectRoot);
182
- if (fs.existsSync(projectDir)) {
183
- for (const entry of fs.readdirSync(projectDir, { withFileTypes: true })) {
184
- if (isSchemaDir(projectDir, entry)) {
185
- const schemaPath = path.join(projectDir, entry.name, 'schema.yaml');
186
- if (fs.existsSync(schemaPath)) {
187
- schemas.add(entry.name);
188
- }
189
- }
190
- }
211
+ for (const { dir } of schemaSources(projectRoot)) {
212
+ for (const name of scanSchemaDir(dir)) {
213
+ schemas.add(name);
191
214
  }
192
215
  }
193
216
  return Array.from(schemas).sort();
@@ -201,79 +224,43 @@ export function listSchemas(projectRoot) {
201
224
  export function listSchemasWithInfo(projectRoot) {
202
225
  const schemas = [];
203
226
  const seenNames = new Set();
204
- // Add project-local schemas first (highest priority, if projectRoot provided)
205
- if (projectRoot) {
206
- const projectDir = getProjectSchemasDir(projectRoot);
207
- if (fs.existsSync(projectDir)) {
208
- for (const entry of fs.readdirSync(projectDir, { withFileTypes: true })) {
209
- if (isSchemaDir(projectDir, entry)) {
210
- const schemaPath = path.join(projectDir, entry.name, 'schema.yaml');
211
- if (fs.existsSync(schemaPath)) {
212
- try {
213
- const schema = parseSchema(fs.readFileSync(schemaPath, 'utf-8'));
214
- schemas.push({
215
- name: entry.name,
216
- description: schema.description || '',
217
- artifacts: schema.artifacts.map((a) => a.id),
218
- source: 'project',
219
- });
220
- seenNames.add(entry.name);
221
- }
222
- catch {
223
- // Skip invalid schemas
224
- }
225
- }
226
- }
227
+ // Highest precedence first, so an overridden schema is skipped rather than
228
+ // replaced. A schema that fails to parse is not marked seen — the next
229
+ // source down still gets a chance to supply it.
230
+ for (const { dir, source } of schemaSources(projectRoot).reverse()) {
231
+ for (const name of scanSchemaDir(dir)) {
232
+ if (seenNames.has(name))
233
+ continue;
234
+ try {
235
+ const schema = parseSchema(fs.readFileSync(path.join(dir, name, 'schema.yaml'), 'utf-8'));
236
+ schemas.push({
237
+ name,
238
+ description: schema.description || '',
239
+ artifacts: schema.artifacts.map((a) => a.id),
240
+ source,
241
+ path: path.join(dir, name),
242
+ });
243
+ seenNames.add(name);
227
244
  }
228
- }
229
- }
230
- // Add user override schemas (if not overridden by project)
231
- const userDir = getUserSchemasDir();
232
- if (fs.existsSync(userDir)) {
233
- for (const entry of fs.readdirSync(userDir, { withFileTypes: true })) {
234
- if (isSchemaDir(userDir, entry) && !seenNames.has(entry.name)) {
235
- const schemaPath = path.join(userDir, entry.name, 'schema.yaml');
236
- if (fs.existsSync(schemaPath)) {
237
- try {
238
- const schema = parseSchema(fs.readFileSync(schemaPath, 'utf-8'));
239
- schemas.push({
240
- name: entry.name,
241
- description: schema.description || '',
242
- artifacts: schema.artifacts.map((a) => a.id),
243
- source: 'user',
244
- });
245
- seenNames.add(entry.name);
246
- }
247
- catch {
248
- // Skip invalid schemas
249
- }
250
- }
251
- }
252
- }
253
- }
254
- // Add package built-in schemas (if not overridden by project or user)
255
- const packageDir = getPackageSchemasDir();
256
- if (fs.existsSync(packageDir)) {
257
- for (const entry of fs.readdirSync(packageDir, { withFileTypes: true })) {
258
- if (isSchemaDir(packageDir, entry) && !seenNames.has(entry.name)) {
259
- const schemaPath = path.join(packageDir, entry.name, 'schema.yaml');
260
- if (fs.existsSync(schemaPath)) {
261
- try {
262
- const schema = parseSchema(fs.readFileSync(schemaPath, 'utf-8'));
263
- schemas.push({
264
- name: entry.name,
265
- description: schema.description || '',
266
- artifacts: schema.artifacts.map((a) => a.id),
267
- source: 'package',
268
- });
269
- }
270
- catch {
271
- // Skip invalid schemas
272
- }
273
- }
245
+ catch {
246
+ // Skip invalid schemas
274
247
  }
275
248
  }
276
249
  }
277
250
  return schemas.sort((a, b) => a.name.localeCompare(b.name));
278
251
  }
252
+ /**
253
+ * Union of every artifact ID across every available schema.
254
+ *
255
+ * Config keys that are scoped per-artifact but stored globally (`rules:`) can
256
+ * legitimately name an artifact from any schema, so they must be checked
257
+ * against the union rather than whichever schema the current change uses.
258
+ *
259
+ * Built on listSchemasWithInfo so it inherits that function's precedence
260
+ * handling and its tolerance for a schema that fails to parse — one broken
261
+ * custom schema must not turn every rules key into an unknown ID.
262
+ */
263
+ export function collectAllArtifactIds(projectRoot) {
264
+ return new Set(listSchemasWithInfo(projectRoot).flatMap((schema) => schema.artifacts));
265
+ }
279
266
  //# sourceMappingURL=resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/core/artifact-graph/resolver.ts"],"names":[],"mappings":"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"}
@@ -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;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAGvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CAsB3D"}
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;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAGvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CA4B3D"}
@@ -32,8 +32,30 @@ export function parseSchema(yamlContent) {
32
32
  validateRequiresReferences(schema.artifacts);
33
33
  // Check for cycles
34
34
  validateNoCycles(schema.artifacts);
35
+ // apply.requires names artifacts too, and was the one dependency list nobody
36
+ // checked: an unknown id reached `status --json` verbatim as
37
+ // applyRequires: ["ghost"], sending agents to look for an artifact the schema
38
+ // never defines.
39
+ validateApplyReferences(schema);
35
40
  return schema;
36
41
  }
42
+ /**
43
+ * Validates that `apply.requires` points at artifacts that exist.
44
+ *
45
+ * `tracks` is deliberately not checked here: it names a file inside the change
46
+ * directory, not an artifact id, and that file legitimately does not exist until
47
+ * the change is scaffolded.
48
+ */
49
+ function validateApplyReferences(schema) {
50
+ if (!schema.apply)
51
+ return;
52
+ const validIds = new Set(schema.artifacts.map((a) => a.id));
53
+ for (const req of schema.apply.requires) {
54
+ if (!validIds.has(req)) {
55
+ throw new SchemaValidationError(`Invalid dependency reference in apply.requires: '${req}' does not exist`);
56
+ }
57
+ }
58
+ }
37
59
  /**
38
60
  * Validates that there are no duplicate artifact IDs.
39
61
  */
@@ -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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"}
@@ -8,6 +8,7 @@ export declare const ChangeMetadataSchema: z.ZodObject<{
8
8
  created: z.ZodOptional<z.ZodString>;
9
9
  goal: z.ZodOptional<z.ZodString>;
10
10
  decisions: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
+ skip_specs: z.ZodOptional<z.ZodBoolean>;
11
12
  }, z.core.$strip>;
12
13
  export type ChangeMetadata = z.infer<typeof ChangeMetadataSchema>;
13
14
  //# sourceMappingURL=schema.d.ts.map
@@ -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;AAIxB,eAAO,MAAM,oBAAoB;;;;;;;;;iBAc/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,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;AAIxB,eAAO,MAAM,oBAAoB;;;;;;;;;;iBAqB/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -15,5 +15,12 @@ export const ChangeMetadataSchema = z.object({
15
15
  // "20260722_161825-topic.md" under tospec/decisions/. Optional so existing
16
16
  // metadata files without the field stay valid; absent means none.
17
17
  decisions: z.array(z.string().min(1)).optional(),
18
+ // Declares that this change intentionally has no behavioral effect, so the
19
+ // "at least one delta" rule is waived. A property of the change, deliberately
20
+ // not the same thing as archive's one-shot --skip-specs flag: making the flag
21
+ // imply this would leave `tospec validate` answering differently depending on
22
+ // how someone last ran archive. Read via readSkipSpecsMarker, which reports a
23
+ // non-boolean value as a validation error instead of silently ignoring it.
24
+ skip_specs: z.boolean().optional(),
18
25
  });
19
26
  //# sourceMappingURL=schema.js.map
@@ -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;AAExB,8EAA8E;AAC9E,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,EAAE;QAC5B,OAAO,EAAE,mCAAmC;KAC7C,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;CACjD,CAAC,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;AAExB,8EAA8E;AAC9E,qDAAqD;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,KAAK,CAAC,qBAAqB,EAAE;QAC5B,OAAO,EAAE,mCAAmC;KAC7C,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,2EAA2E;IAC3E,8EAA8E;IAC9E,8EAA8E;IAC9E,8EAA8E;IAC9E,8EAA8E;IAC9E,2EAA2E;IAC3E,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
@@ -19,6 +19,5 @@ export declare class ChangePresenter {
19
19
  }): Promise<void>;
20
20
  private fileExists;
21
21
  private extractTitle;
22
- private extractFrontmatterTitle;
23
22
  }
24
23
  //# sourceMappingURL=change-presenter.d.ts.map
@@ -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;AAKtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAId,QAAQ,CAAC,EAAE,MAAM;IAK7B,OAAO,CAAC,cAAc;IAItB;;;;;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,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YA0ElK,UAAU;IASxB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,uBAAuB;CAchC"}
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;AAKtD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAId,QAAQ,CAAC,EAAE,MAAM;IAK7B,OAAO,CAAC,cAAc;IAItB;;;;;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,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YA0ElK,UAAU;IASxB,OAAO,CAAC,YAAY;CAOrB"}
@@ -1,6 +1,6 @@
1
1
  import { promises as fs } from 'fs';
2
2
  import path from 'path';
3
- import { parse as parseYaml } from 'yaml';
3
+ import { frontmatterString } from '../utils/frontmatter.js';
4
4
  import { JsonConverter } from './converters/json-converter.js';
5
5
  import { ChangeParser } from './parsers/change-parser.js';
6
6
  import { emitSuccess } from '../commands/shared-output.js';
@@ -44,7 +44,7 @@ export class ChangePresenter {
44
44
  else {
45
45
  console.error(`No change specified. Available IDs: ${changes.join(', ')}`);
46
46
  }
47
- console.error('Hint: use "tospec change list" to view available changes.');
47
+ console.error('Hint: use "tospec list" to view available changes.');
48
48
  process.exitCode = 1;
49
49
  return;
50
50
  }
@@ -101,29 +101,12 @@ export class ChangePresenter {
101
101
  }
102
102
  }
103
103
  extractTitle(content, changeName) {
104
- // Prefer the ticket/proposal yaml frontmatter `title:`.
105
- const fmTitle = this.extractFrontmatterTitle(content);
104
+ // Prefer the ticket/proposal yaml frontmatter `title:`, then the H1.
105
+ const fmTitle = frontmatterString(content, 'title')?.trim();
106
106
  if (fmTitle)
107
107
  return fmTitle;
108
108
  const match = content.match(/^#\s+(?:Change:\s+)?(.+)$/im);
109
109
  return match ? match[1].trim() : changeName;
110
110
  }
111
- extractFrontmatterTitle(content) {
112
- if (!content.startsWith('---'))
113
- return null;
114
- const end = content.indexOf('\n---', 3);
115
- if (end === -1)
116
- return null;
117
- try {
118
- const parsed = parseYaml(content.slice(3, end));
119
- if (parsed && typeof parsed === 'object' && typeof parsed.title === 'string' && parsed.title.trim()) {
120
- return parsed.title.trim();
121
- }
122
- }
123
- catch {
124
- // Malformed frontmatter — fall through to H1/changeName.
125
- }
126
- return null;
127
- }
128
111
  }
129
112
  //# sourceMappingURL=change-presenter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"change-presenter.js","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"change-presenter.js","sourceRoot":"","sources":["../../src/core/change-presenter.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,13 @@
3
3
  *
4
4
  * Re-exports the tool command adapters tospec ships (claude only).
5
5
  */
6
- export { claudeAdapter } from './claude.js';
6
+ import type { ToolCommandAdapter } from '../types.js';
7
+ import { claudeAdapter } from './claude.js';
8
+ export { claudeAdapter };
9
+ /**
10
+ * The adapter registry. Adding a tool means adding it here — callers resolve by
11
+ * `toolId` rather than testing the tool name, so no generation code changes.
12
+ */
13
+ export declare const COMMAND_ADAPTERS: readonly ToolCommandAdapter[];
14
+ export declare function findCommandAdapter(toolId: string): ToolCommandAdapter | undefined;
7
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/command-generation/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/command-generation/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,kBAAkB,EAAoB,CAAC;AAE/E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEjF"}
@@ -3,5 +3,14 @@
3
3
  *
4
4
  * Re-exports the tool command adapters tospec ships (claude only).
5
5
  */
6
- export { claudeAdapter } from './claude.js';
6
+ import { claudeAdapter } from './claude.js';
7
+ export { claudeAdapter };
8
+ /**
9
+ * The adapter registry. Adding a tool means adding it here — callers resolve by
10
+ * `toolId` rather than testing the tool name, so no generation code changes.
11
+ */
12
+ export const COMMAND_ADAPTERS = [claudeAdapter];
13
+ export function findCommandAdapter(toolId) {
14
+ return COMMAND_ADAPTERS.find((adapter) => adapter.toolId === toolId);
15
+ }
7
16
  //# sourceMappingURL=index.js.map