@dedesfr/prompter 0.8.23 → 1.0.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 (247) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +105 -77
  3. package/dist/cli/index.js +25 -1
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/init.d.ts +1 -7
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +60 -299
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/commands/login.d.ts +4 -0
  10. package/dist/commands/login.d.ts.map +1 -0
  11. package/dist/commands/login.js +56 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/logout.d.ts +4 -0
  14. package/dist/commands/logout.d.ts.map +1 -0
  15. package/dist/commands/logout.js +14 -0
  16. package/dist/commands/logout.js.map +1 -0
  17. package/dist/commands/update.d.ts.map +1 -1
  18. package/dist/commands/update.js +31 -41
  19. package/dist/commands/update.js.map +1 -1
  20. package/dist/commands/whoami.d.ts +4 -0
  21. package/dist/commands/whoami.d.ts.map +1 -0
  22. package/dist/commands/whoami.js +42 -0
  23. package/dist/commands/whoami.js.map +1 -0
  24. package/dist/core/auth-store.d.ts +10 -0
  25. package/dist/core/auth-store.d.ts.map +1 -0
  26. package/dist/core/auth-store.js +39 -0
  27. package/dist/core/auth-store.js.map +1 -0
  28. package/dist/core/configurators/slash/antigravity.d.ts +2 -5
  29. package/dist/core/configurators/slash/antigravity.d.ts.map +1 -1
  30. package/dist/core/configurators/slash/antigravity.js +2 -57
  31. package/dist/core/configurators/slash/antigravity.js.map +1 -1
  32. package/dist/core/configurators/slash/base.d.ts +6 -18
  33. package/dist/core/configurators/slash/base.d.ts.map +1 -1
  34. package/dist/core/configurators/slash/base.js +8 -77
  35. package/dist/core/configurators/slash/base.js.map +1 -1
  36. package/dist/core/configurators/slash/claude.d.ts +2 -5
  37. package/dist/core/configurators/slash/claude.d.ts.map +1 -1
  38. package/dist/core/configurators/slash/claude.js +2 -57
  39. package/dist/core/configurators/slash/claude.js.map +1 -1
  40. package/dist/core/configurators/slash/codex.d.ts +2 -5
  41. package/dist/core/configurators/slash/codex.d.ts.map +1 -1
  42. package/dist/core/configurators/slash/codex.js +2 -57
  43. package/dist/core/configurators/slash/codex.js.map +1 -1
  44. package/dist/core/configurators/slash/droid.d.ts +2 -5
  45. package/dist/core/configurators/slash/droid.d.ts.map +1 -1
  46. package/dist/core/configurators/slash/droid.js +2 -32
  47. package/dist/core/configurators/slash/droid.js.map +1 -1
  48. package/dist/core/configurators/slash/forge.d.ts +2 -5
  49. package/dist/core/configurators/slash/forge.d.ts.map +1 -1
  50. package/dist/core/configurators/slash/forge.js +2 -32
  51. package/dist/core/configurators/slash/forge.js.map +1 -1
  52. package/dist/core/configurators/slash/github-copilot.d.ts +2 -7
  53. package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
  54. package/dist/core/configurators/slash/github-copilot.js +2 -96
  55. package/dist/core/configurators/slash/github-copilot.js.map +1 -1
  56. package/dist/core/configurators/slash/index.d.ts +1 -1
  57. package/dist/core/configurators/slash/index.d.ts.map +1 -1
  58. package/dist/core/configurators/slash/index.js +1 -1
  59. package/dist/core/configurators/slash/index.js.map +1 -1
  60. package/dist/core/configurators/slash/kilocode.d.ts +2 -5
  61. package/dist/core/configurators/slash/kilocode.d.ts.map +1 -1
  62. package/dist/core/configurators/slash/kilocode.js +2 -57
  63. package/dist/core/configurators/slash/kilocode.js.map +1 -1
  64. package/dist/core/configurators/slash/opencode.d.ts +2 -5
  65. package/dist/core/configurators/slash/opencode.d.ts.map +1 -1
  66. package/dist/core/configurators/slash/opencode.js +2 -57
  67. package/dist/core/configurators/slash/opencode.js.map +1 -1
  68. package/dist/core/configurators/slash/registry.d.ts +4 -4
  69. package/dist/core/configurators/slash/registry.d.ts.map +1 -1
  70. package/dist/core/configurators/slash/registry.js.map +1 -1
  71. package/dist/core/registry.d.ts +18 -0
  72. package/dist/core/registry.d.ts.map +1 -0
  73. package/dist/core/registry.js +94 -0
  74. package/dist/core/registry.js.map +1 -0
  75. package/dist/core/templates/index.d.ts +0 -1
  76. package/dist/core/templates/index.d.ts.map +1 -1
  77. package/dist/core/templates/index.js +0 -1
  78. package/dist/core/templates/index.js.map +1 -1
  79. package/package.json +7 -1
  80. package/AGENTS.md +0 -123
  81. package/CLAUDE.md +0 -17
  82. package/build.js +0 -20
  83. package/convex-setup.md +0 -403
  84. package/dist/core/templates/slash-command-templates.d.ts +0 -7
  85. package/dist/core/templates/slash-command-templates.d.ts.map +0 -1
  86. package/dist/core/templates/slash-command-templates.js +0 -1041
  87. package/dist/core/templates/slash-command-templates.js.map +0 -1
  88. package/prompt/ai-humanizer.md +0 -45
  89. package/prompt/api-contract-generator.md +0 -234
  90. package/prompt/apply.md +0 -17
  91. package/prompt/archive.md +0 -21
  92. package/prompt/design-system.md +0 -210
  93. package/prompt/document-explainer.md +0 -149
  94. package/prompt/epic-generator.md +0 -198
  95. package/prompt/epic-single.md +0 -47
  96. package/prompt/erd-generator.md +0 -130
  97. package/prompt/fsd-generator.md +0 -157
  98. package/prompt/prd-agent-generator.md +0 -147
  99. package/prompt/prd-generator.md +0 -195
  100. package/prompt/product-brief.md +0 -289
  101. package/prompt/proposal.md +0 -22
  102. package/prompt/qa-test-scenario.md +0 -133
  103. package/prompt/skill-creator.md +0 -350
  104. package/prompt/story-generator.md +0 -278
  105. package/prompt/story-single.md +0 -70
  106. package/prompt/tdd-generator.md +0 -294
  107. package/prompt/tdd-lite-generator.md +0 -224
  108. package/prompt/wireframe-generator.md +0 -219
  109. package/skills/ai-context-generator/SKILL.md +0 -54
  110. package/skills/ai-context-generator/references/AGENTS.template.md +0 -83
  111. package/skills/ai-context-generator/references/CLAUDE.template.md +0 -39
  112. package/skills/ai-context-generator/references/behavioral-guidelines.md +0 -71
  113. package/skills/ai-context-generator/references/discovery-checklist.md +0 -40
  114. package/skills/ai-context-generator/references/examples/AGENTS.good.md +0 -103
  115. package/skills/ai-context-generator/references/extraction-checklist.md +0 -23
  116. package/skills/ai-context-generator/references/overlays/laravel.md +0 -44
  117. package/skills/cerebro/SKILL.md +0 -187
  118. package/skills/cerebro/references/agents.md +0 -213
  119. package/skills/code-review/SKILL.md +0 -373
  120. package/skills/code-review/assets/report-template-agent.md +0 -212
  121. package/skills/code-review/assets/report-template-compact.md +0 -81
  122. package/skills/code-review/assets/report-template-full.md +0 -264
  123. package/skills/code-review/assets/report-template-human.md +0 -168
  124. package/skills/code-review/references/universal-patterns.md +0 -495
  125. package/skills/design-md/README.md +0 -34
  126. package/skills/design-md/SKILL.md +0 -172
  127. package/skills/design-md/examples/DESIGN.md +0 -154
  128. package/skills/design-system-generator/SKILL.md +0 -324
  129. package/skills/design-system-generator/assets/design-system-template.md +0 -348
  130. package/skills/design-system-generator/references/extraction-patterns.md +0 -321
  131. package/skills/doc-builder/SKILL.md +0 -115
  132. package/skills/doc-builder/references/ui-patterns.md +0 -394
  133. package/skills/document-translator/SKILL.md +0 -58
  134. package/skills/enhance-prompt/README.md +0 -34
  135. package/skills/enhance-prompt/SKILL.md +0 -204
  136. package/skills/enhance-prompt/references/KEYWORDS.md +0 -114
  137. package/skills/feature-planner/SKILL.md +0 -305
  138. package/skills/feature-planner/assets/implementation-plan-template.md +0 -85
  139. package/skills/frontend-design/LICENSE.txt +0 -177
  140. package/skills/frontend-design/SKILL.md +0 -42
  141. package/skills/gamma-builder/SKILL.md +0 -134
  142. package/skills/laravel-code-review/SKILL.md +0 -383
  143. package/skills/laravel-code-review/assets/report-template-agent.md +0 -195
  144. package/skills/laravel-code-review/assets/report-template-compact.md +0 -79
  145. package/skills/laravel-code-review/assets/report-template-full.md +0 -253
  146. package/skills/laravel-code-review/assets/report-template-human.md +0 -159
  147. package/skills/laravel-code-review/references/laravel-patterns.md +0 -571
  148. package/skills/laravel-code-review/references/php84-features.md +0 -442
  149. package/skills/mcp-builder/LICENSE.txt +0 -202
  150. package/skills/mcp-builder/SKILL.md +0 -236
  151. package/skills/mcp-builder/reference/evaluation.md +0 -602
  152. package/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  153. package/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  154. package/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  155. package/skills/mcp-builder/scripts/connections.py +0 -151
  156. package/skills/mcp-builder/scripts/evaluation.py +0 -373
  157. package/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  158. package/skills/mcp-builder/scripts/requirements.txt +0 -2
  159. package/skills/meeting-notes/SKILL.md +0 -159
  160. package/skills/meeting-notes/evals/evals.json +0 -23
  161. package/skills/project-orchestrator/SKILL.md +0 -487
  162. package/skills/project-orchestrator/assets/caddy-vps-setup.md +0 -180
  163. package/skills/project-orchestrator/assets/plan-summary-template.md +0 -159
  164. package/skills/prompter-specs/SKILL.md +0 -115
  165. package/skills/prompter-workflow/SKILL.md +0 -166
  166. package/skills/prompter-workflow/evals/evals.json +0 -89
  167. package/skills/sph-generator/SKILL.md +0 -488
  168. package/skills/ui-ux-pro/SKILL.md +0 -199
  169. package/skills/ui-ux-pro/assets/design-spec-template.md +0 -173
  170. package/skills/ui-ux-pro/references/component-patterns.md +0 -255
  171. package/skills/ui-ux-pro/references/design-principles.md +0 -167
  172. package/src/cli/index.ts +0 -223
  173. package/src/commands/archive.ts +0 -302
  174. package/src/commands/change.ts +0 -292
  175. package/src/commands/config.ts +0 -233
  176. package/src/commands/guide.ts +0 -50
  177. package/src/commands/init.ts +0 -899
  178. package/src/commands/list.ts +0 -194
  179. package/src/commands/show.ts +0 -138
  180. package/src/commands/spec.ts +0 -251
  181. package/src/commands/update.ts +0 -156
  182. package/src/commands/upgrade.ts +0 -30
  183. package/src/commands/validate.ts +0 -326
  184. package/src/core/artifact-graph/graph.ts +0 -167
  185. package/src/core/artifact-graph/index.ts +0 -44
  186. package/src/core/artifact-graph/instruction-loader.ts +0 -302
  187. package/src/core/artifact-graph/resolver.ts +0 -226
  188. package/src/core/artifact-graph/schema.ts +0 -124
  189. package/src/core/artifact-graph/state.ts +0 -64
  190. package/src/core/artifact-graph/types.ts +0 -65
  191. package/src/core/completions/command-registry.ts +0 -382
  192. package/src/core/completions/completion-provider.ts +0 -128
  193. package/src/core/completions/generators/bash-generator.ts +0 -191
  194. package/src/core/completions/generators/fish-generator.ts +0 -188
  195. package/src/core/completions/generators/powershell-generator.ts +0 -223
  196. package/src/core/completions/generators/zsh-generator.ts +0 -281
  197. package/src/core/completions/templates/bash-templates.ts +0 -24
  198. package/src/core/completions/templates/fish-templates.ts +0 -40
  199. package/src/core/completions/templates/powershell-templates.ts +0 -25
  200. package/src/core/completions/templates/zsh-templates.ts +0 -36
  201. package/src/core/completions/types.ts +0 -90
  202. package/src/core/config-schema.ts +0 -230
  203. package/src/core/config.ts +0 -181
  204. package/src/core/configurators/slash/antigravity.ts +0 -70
  205. package/src/core/configurators/slash/base.ts +0 -203
  206. package/src/core/configurators/slash/claude.ts +0 -70
  207. package/src/core/configurators/slash/codex.ts +0 -70
  208. package/src/core/configurators/slash/droid.ts +0 -44
  209. package/src/core/configurators/slash/forge.ts +0 -44
  210. package/src/core/configurators/slash/github-copilot.ts +0 -114
  211. package/src/core/configurators/slash/index.ts +0 -10
  212. package/src/core/configurators/slash/kilocode.ts +0 -70
  213. package/src/core/configurators/slash/opencode.ts +0 -70
  214. package/src/core/configurators/slash/registry.ts +0 -51
  215. package/src/core/converters/json-converter.ts +0 -62
  216. package/src/core/global-config.ts +0 -136
  217. package/src/core/parsers/change-parser.ts +0 -234
  218. package/src/core/parsers/markdown-parser.ts +0 -237
  219. package/src/core/parsers/requirement-blocks.ts +0 -234
  220. package/src/core/prompt-templates.ts +0 -3504
  221. package/src/core/schemas/base.schema.ts +0 -20
  222. package/src/core/schemas/change.schema.ts +0 -42
  223. package/src/core/schemas/index.ts +0 -20
  224. package/src/core/schemas/spec.schema.ts +0 -17
  225. package/src/core/skill-discovery.ts +0 -68
  226. package/src/core/specs-apply.ts +0 -483
  227. package/src/core/styles/palette.ts +0 -8
  228. package/src/core/templates/agents-template.ts +0 -459
  229. package/src/core/templates/claude-template.ts +0 -2
  230. package/src/core/templates/index.ts +0 -4
  231. package/src/core/templates/project-template.ts +0 -32
  232. package/src/core/templates/slash-command-templates.ts +0 -1068
  233. package/src/core/validation/constants.ts +0 -48
  234. package/src/core/validation/types.ts +0 -19
  235. package/src/core/validation/validator.ts +0 -449
  236. package/src/core/view.ts +0 -219
  237. package/src/index.ts +0 -1
  238. package/src/utils/change-metadata.ts +0 -171
  239. package/src/utils/change-utils.ts +0 -131
  240. package/src/utils/file-system.ts +0 -252
  241. package/src/utils/index.ts +0 -12
  242. package/src/utils/interactive.ts +0 -29
  243. package/src/utils/item-discovery.ts +0 -66
  244. package/src/utils/match.ts +0 -26
  245. package/src/utils/shell-detection.ts +0 -62
  246. package/src/utils/task-progress.ts +0 -43
  247. package/tsconfig.json +0 -28
@@ -1,44 +0,0 @@
1
- // Types
2
- export {
3
- ArtifactSchema,
4
- SchemaYamlSchema,
5
- type Artifact,
6
- type SchemaYaml,
7
- type CompletedSet,
8
- type BlockedArtifacts,
9
- } from './types.js';
10
-
11
- // Schema loading and validation
12
- export { loadSchema, parseSchema, SchemaValidationError } from './schema.js';
13
-
14
- // Graph operations
15
- export { ArtifactGraph } from './graph.js';
16
-
17
- // State detection
18
- export { detectCompleted } from './state.js';
19
-
20
- // Schema resolution
21
- export {
22
- resolveSchema,
23
- listSchemas,
24
- listSchemasWithInfo,
25
- getSchemaDir,
26
- getPackageSchemasDir,
27
- getUserSchemasDir,
28
- SchemaLoadError,
29
- type SchemaInfo,
30
- } from './resolver.js';
31
-
32
- // Instruction loading
33
- export {
34
- loadTemplate,
35
- loadChangeContext,
36
- generateInstructions,
37
- formatChangeStatus,
38
- TemplateLoadError,
39
- type ChangeContext,
40
- type ArtifactInstructions,
41
- type DependencyInfo,
42
- type ArtifactStatus,
43
- type ChangeStatus,
44
- } from './instruction-loader.js';
@@ -1,302 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import { getSchemaDir, resolveSchema } from './resolver.js';
4
- import { ArtifactGraph } from './graph.js';
5
- import { detectCompleted } from './state.js';
6
- import { resolveSchemaForChange } from '../../utils/change-metadata.js';
7
- import type { Artifact, CompletedSet } from './types.js';
8
-
9
- /**
10
- * Error thrown when loading a template fails.
11
- */
12
- export class TemplateLoadError extends Error {
13
- constructor(
14
- message: string,
15
- public readonly templatePath: string
16
- ) {
17
- super(message);
18
- this.name = 'TemplateLoadError';
19
- }
20
- }
21
-
22
- /**
23
- * Change context containing graph, completion state, and metadata.
24
- */
25
- export interface ChangeContext {
26
- /** The artifact dependency graph */
27
- graph: ArtifactGraph;
28
- /** Set of completed artifact IDs */
29
- completed: CompletedSet;
30
- /** Schema name being used */
31
- schemaName: string;
32
- /** Change name */
33
- changeName: string;
34
- /** Path to the change directory */
35
- changeDir: string;
36
- }
37
-
38
- /**
39
- * Enriched instructions for creating an artifact.
40
- */
41
- export interface ArtifactInstructions {
42
- /** Change name */
43
- changeName: string;
44
- /** Artifact ID */
45
- artifactId: string;
46
- /** Schema name */
47
- schemaName: string;
48
- /** Full path to change directory */
49
- changeDir: string;
50
- /** Output path pattern (e.g., "proposal.md") */
51
- outputPath: string;
52
- /** Artifact description */
53
- description: string;
54
- /** Guidance on how to create this artifact (from schema instruction field) */
55
- instruction: string | undefined;
56
- /** Template content (structure to follow) */
57
- template: string;
58
- /** Dependencies with completion status and paths */
59
- dependencies: DependencyInfo[];
60
- /** Artifacts that become available after completing this one */
61
- unlocks: string[];
62
- }
63
-
64
- /**
65
- * Dependency information including path and description.
66
- */
67
- export interface DependencyInfo {
68
- /** Artifact ID */
69
- id: string;
70
- /** Whether the dependency is completed */
71
- done: boolean;
72
- /** Relative output path of the dependency (e.g., "proposal.md") */
73
- path: string;
74
- /** Description of the dependency artifact */
75
- description: string;
76
- }
77
-
78
- /**
79
- * Status of a single artifact in the workflow.
80
- */
81
- export interface ArtifactStatus {
82
- /** Artifact ID */
83
- id: string;
84
- /** Output path pattern */
85
- outputPath: string;
86
- /** Status: done, ready, or blocked */
87
- status: 'done' | 'ready' | 'blocked';
88
- /** Missing dependencies (only for blocked) */
89
- missingDeps?: string[];
90
- }
91
-
92
- /**
93
- * Formatted change status.
94
- */
95
- export interface ChangeStatus {
96
- /** Change name */
97
- changeName: string;
98
- /** Schema name */
99
- schemaName: string;
100
- /** Whether all artifacts are complete */
101
- isComplete: boolean;
102
- /** Artifact IDs required before apply phase (from schema's apply.requires) */
103
- applyRequires: string[];
104
- /** Status of each artifact */
105
- artifacts: ArtifactStatus[];
106
- }
107
-
108
- /**
109
- * Loads a template from a schema's templates directory.
110
- *
111
- * @param schemaName - Schema name (e.g., "spec-driven")
112
- * @param templatePath - Relative path within the templates directory (e.g., "proposal.md")
113
- * @returns The template content
114
- * @throws TemplateLoadError if the template cannot be loaded
115
- */
116
- export function loadTemplate(schemaName: string, templatePath: string): string {
117
- const schemaDir = getSchemaDir(schemaName);
118
- if (!schemaDir) {
119
- throw new TemplateLoadError(
120
- `Schema '${schemaName}' not found`,
121
- templatePath
122
- );
123
- }
124
-
125
- const fullPath = path.join(schemaDir, 'templates', templatePath);
126
-
127
- if (!fs.existsSync(fullPath)) {
128
- throw new TemplateLoadError(
129
- `Template not found: ${fullPath}`,
130
- fullPath
131
- );
132
- }
133
-
134
- try {
135
- return fs.readFileSync(fullPath, 'utf-8');
136
- } catch (err) {
137
- const ioError = err instanceof Error ? err : new Error(String(err));
138
- throw new TemplateLoadError(
139
- `Failed to read template: ${ioError.message}`,
140
- fullPath
141
- );
142
- }
143
- }
144
-
145
- /**
146
- * Loads change context combining graph and completion state.
147
- *
148
- * Schema resolution order:
149
- * 1. Explicit schemaName parameter (if provided)
150
- * 2. Schema from .prompter.yaml metadata (if exists in change directory)
151
- * 3. Default 'spec-driven'
152
- *
153
- * @param projectRoot - Project root directory
154
- * @param changeName - Change name
155
- * @param schemaName - Optional schema name override. If not provided, auto-detected from metadata.
156
- * @returns Change context with graph, completed set, and metadata
157
- */
158
- export function loadChangeContext(
159
- projectRoot: string,
160
- changeName: string,
161
- schemaName?: string
162
- ): ChangeContext {
163
- const changeDir = path.join(projectRoot, 'prompter', 'changes', changeName);
164
-
165
- // Resolve schema: explicit > metadata > default
166
- const resolvedSchemaName = resolveSchemaForChange(changeDir, schemaName);
167
-
168
- const schema = resolveSchema(resolvedSchemaName);
169
- const graph = ArtifactGraph.fromSchema(schema);
170
- const completed = detectCompleted(graph, changeDir);
171
-
172
- return {
173
- graph,
174
- completed,
175
- schemaName: resolvedSchemaName,
176
- changeName,
177
- changeDir,
178
- };
179
- }
180
-
181
- /**
182
- * Generates enriched instructions for creating an artifact.
183
- *
184
- * @param context - Change context
185
- * @param artifactId - Artifact ID to generate instructions for
186
- * @returns Enriched artifact instructions
187
- * @throws Error if artifact not found
188
- */
189
- export function generateInstructions(
190
- context: ChangeContext,
191
- artifactId: string
192
- ): ArtifactInstructions {
193
- const artifact = context.graph.getArtifact(artifactId);
194
- if (!artifact) {
195
- throw new Error(`Artifact '${artifactId}' not found in schema '${context.schemaName}'`);
196
- }
197
-
198
- const template = loadTemplate(context.schemaName, artifact.template);
199
- const dependencies = getDependencyInfo(artifact, context.graph, context.completed);
200
- const unlocks = getUnlockedArtifacts(context.graph, artifactId);
201
-
202
- return {
203
- changeName: context.changeName,
204
- artifactId: artifact.id,
205
- schemaName: context.schemaName,
206
- changeDir: context.changeDir,
207
- outputPath: artifact.generates,
208
- description: artifact.description,
209
- instruction: artifact.instruction,
210
- template,
211
- dependencies,
212
- unlocks,
213
- };
214
- }
215
-
216
- /**
217
- * Gets dependency info including paths and descriptions.
218
- */
219
- function getDependencyInfo(
220
- artifact: Artifact,
221
- graph: ArtifactGraph,
222
- completed: CompletedSet
223
- ): DependencyInfo[] {
224
- return artifact.requires.map(id => {
225
- const depArtifact = graph.getArtifact(id);
226
- return {
227
- id,
228
- done: completed.has(id),
229
- path: depArtifact?.generates ?? id,
230
- description: depArtifact?.description ?? '',
231
- };
232
- });
233
- }
234
-
235
- /**
236
- * Gets artifacts that become available after completing the given artifact.
237
- */
238
- function getUnlockedArtifacts(graph: ArtifactGraph, artifactId: string): string[] {
239
- const unlocks: string[] = [];
240
-
241
- for (const artifact of graph.getAllArtifacts()) {
242
- if (artifact.requires.includes(artifactId)) {
243
- unlocks.push(artifact.id);
244
- }
245
- }
246
-
247
- return unlocks.sort();
248
- }
249
-
250
- /**
251
- * Formats the status of all artifacts in a change.
252
- *
253
- * @param context - Change context
254
- * @returns Formatted change status
255
- */
256
- export function formatChangeStatus(context: ChangeContext): ChangeStatus {
257
- // Load schema to get apply phase configuration
258
- const schema = resolveSchema(context.schemaName);
259
- const applyRequires = schema.apply?.requires ?? schema.artifacts.map(a => a.id);
260
-
261
- const artifacts = context.graph.getAllArtifacts();
262
- const ready = new Set(context.graph.getNextArtifacts(context.completed));
263
- const blocked = context.graph.getBlocked(context.completed);
264
-
265
- const artifactStatuses: ArtifactStatus[] = artifacts.map(artifact => {
266
- if (context.completed.has(artifact.id)) {
267
- return {
268
- id: artifact.id,
269
- outputPath: artifact.generates,
270
- status: 'done' as const,
271
- };
272
- }
273
-
274
- if (ready.has(artifact.id)) {
275
- return {
276
- id: artifact.id,
277
- outputPath: artifact.generates,
278
- status: 'ready' as const,
279
- };
280
- }
281
-
282
- return {
283
- id: artifact.id,
284
- outputPath: artifact.generates,
285
- status: 'blocked' as const,
286
- missingDeps: blocked[artifact.id] ?? [],
287
- };
288
- });
289
-
290
- // Sort by build order for consistent output
291
- const buildOrder = context.graph.getBuildOrder();
292
- const orderMap = new Map(buildOrder.map((id, idx) => [id, idx]));
293
- artifactStatuses.sort((a, b) => (orderMap.get(a.id) ?? 0) - (orderMap.get(b.id) ?? 0));
294
-
295
- return {
296
- changeName: context.changeName,
297
- schemaName: context.schemaName,
298
- isComplete: context.graph.isComplete(context.completed),
299
- applyRequires,
300
- artifacts: artifactStatuses,
301
- };
302
- }
@@ -1,226 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- import { getGlobalDataDir } from '../global-config.js';
5
- import { parseSchema, SchemaValidationError } from './schema.js';
6
- import type { SchemaYaml } from './types.js';
7
-
8
- /**
9
- * Error thrown when loading a schema fails.
10
- */
11
- export class SchemaLoadError extends Error {
12
- constructor(
13
- message: string,
14
- public readonly schemaPath: string,
15
- public readonly cause?: Error
16
- ) {
17
- super(message);
18
- this.name = 'SchemaLoadError';
19
- }
20
- }
21
-
22
- /**
23
- * Gets the package's built-in schemas directory path.
24
- * Uses import.meta.url to resolve relative to the current module.
25
- */
26
- export function getPackageSchemasDir(): string {
27
- const currentFile = fileURLToPath(import.meta.url);
28
- // Navigate from dist/core/artifact-graph/ to package root's schemas/
29
- return path.join(path.dirname(currentFile), '..', '..', '..', 'schemas');
30
- }
31
-
32
- /**
33
- * Gets the user's schema override directory path.
34
- */
35
- export function getUserSchemasDir(): string {
36
- return path.join(getGlobalDataDir(), 'schemas');
37
- }
38
-
39
- /**
40
- * Resolves a schema name to its directory path.
41
- *
42
- * Resolution order:
43
- * 1. User override: ${XDG_DATA_HOME}/prompter/schemas/<name>/schema.yaml
44
- * 2. Package built-in: <package>/schemas/<name>/schema.yaml
45
- *
46
- * @param name - Schema name (e.g., "spec-driven")
47
- * @returns The path to the schema directory, or null if not found
48
- */
49
- export function getSchemaDir(name: string): string | null {
50
- // 1. Check user override directory
51
- const userDir = path.join(getUserSchemasDir(), name);
52
- const userSchemaPath = path.join(userDir, 'schema.yaml');
53
- if (fs.existsSync(userSchemaPath)) {
54
- return userDir;
55
- }
56
-
57
- // 2. Check package built-in directory
58
- const packageDir = path.join(getPackageSchemasDir(), name);
59
- const packageSchemaPath = path.join(packageDir, 'schema.yaml');
60
- if (fs.existsSync(packageSchemaPath)) {
61
- return packageDir;
62
- }
63
-
64
- return null;
65
- }
66
-
67
- /**
68
- * Resolves a schema name to a SchemaYaml object.
69
- *
70
- * Resolution order:
71
- * 1. User override: ${XDG_DATA_HOME}/prompter/schemas/<name>/schema.yaml
72
- * 2. Package built-in: <package>/schemas/<name>/schema.yaml
73
- *
74
- * @param name - Schema name (e.g., "spec-driven")
75
- * @returns The resolved schema object
76
- * @throws Error if schema is not found in any location
77
- */
78
- export function resolveSchema(name: string): SchemaYaml {
79
- // Normalize name (remove .yaml extension if provided)
80
- const normalizedName = name.replace(/\.ya?ml$/, '');
81
-
82
- const schemaDir = getSchemaDir(normalizedName);
83
- if (!schemaDir) {
84
- const availableSchemas = listSchemas();
85
- throw new Error(
86
- `Schema '${normalizedName}' not found. Available schemas: ${availableSchemas.join(', ')}`
87
- );
88
- }
89
-
90
- const schemaPath = path.join(schemaDir, 'schema.yaml');
91
-
92
- // Load and parse the schema
93
- let content: string;
94
- try {
95
- content = fs.readFileSync(schemaPath, 'utf-8');
96
- } catch (err) {
97
- const ioError = err instanceof Error ? err : new Error(String(err));
98
- throw new SchemaLoadError(
99
- `Failed to read schema at '${schemaPath}': ${ioError.message}`,
100
- schemaPath,
101
- ioError
102
- );
103
- }
104
-
105
- try {
106
- return parseSchema(content);
107
- } catch (err) {
108
- if (err instanceof SchemaValidationError) {
109
- throw new SchemaLoadError(
110
- `Invalid schema at '${schemaPath}': ${err.message}`,
111
- schemaPath,
112
- err
113
- );
114
- }
115
- const parseError = err instanceof Error ? err : new Error(String(err));
116
- throw new SchemaLoadError(
117
- `Failed to parse schema at '${schemaPath}': ${parseError.message}`,
118
- schemaPath,
119
- parseError
120
- );
121
- }
122
- }
123
-
124
- /**
125
- * Lists all available schema names.
126
- * Combines user override and package built-in schemas.
127
- */
128
- export function listSchemas(): string[] {
129
- const schemas = new Set<string>();
130
-
131
- // Add package built-in schemas
132
- const packageDir = getPackageSchemasDir();
133
- if (fs.existsSync(packageDir)) {
134
- for (const entry of fs.readdirSync(packageDir, { withFileTypes: true })) {
135
- if (entry.isDirectory()) {
136
- const schemaPath = path.join(packageDir, entry.name, 'schema.yaml');
137
- if (fs.existsSync(schemaPath)) {
138
- schemas.add(entry.name);
139
- }
140
- }
141
- }
142
- }
143
-
144
- // Add user override schemas (may override package schemas)
145
- const userDir = getUserSchemasDir();
146
- if (fs.existsSync(userDir)) {
147
- for (const entry of fs.readdirSync(userDir, { withFileTypes: true })) {
148
- if (entry.isDirectory()) {
149
- const schemaPath = path.join(userDir, entry.name, 'schema.yaml');
150
- if (fs.existsSync(schemaPath)) {
151
- schemas.add(entry.name);
152
- }
153
- }
154
- }
155
- }
156
-
157
- return Array.from(schemas).sort();
158
- }
159
-
160
- /**
161
- * Schema info with metadata (name, description, artifacts).
162
- */
163
- export interface SchemaInfo {
164
- name: string;
165
- description: string;
166
- artifacts: string[];
167
- source: 'package' | 'user';
168
- }
169
-
170
- /**
171
- * Lists all available schemas with their descriptions and artifact lists.
172
- * Useful for agent skills to present schema selection to users.
173
- */
174
- export function listSchemasWithInfo(): SchemaInfo[] {
175
- const schemas: SchemaInfo[] = [];
176
- const seenNames = new Set<string>();
177
-
178
- // Add user override schemas first (they take precedence)
179
- const userDir = getUserSchemasDir();
180
- if (fs.existsSync(userDir)) {
181
- for (const entry of fs.readdirSync(userDir, { withFileTypes: true })) {
182
- if (entry.isDirectory()) {
183
- const schemaPath = path.join(userDir, entry.name, 'schema.yaml');
184
- if (fs.existsSync(schemaPath)) {
185
- try {
186
- const schema = parseSchema(fs.readFileSync(schemaPath, 'utf-8'));
187
- schemas.push({
188
- name: entry.name,
189
- description: schema.description || '',
190
- artifacts: schema.artifacts.map((a) => a.id),
191
- source: 'user',
192
- });
193
- seenNames.add(entry.name);
194
- } catch {
195
- // Skip invalid schemas
196
- }
197
- }
198
- }
199
- }
200
- }
201
-
202
- // Add package built-in schemas (if not overridden)
203
- const packageDir = getPackageSchemasDir();
204
- if (fs.existsSync(packageDir)) {
205
- for (const entry of fs.readdirSync(packageDir, { withFileTypes: true })) {
206
- if (entry.isDirectory() && !seenNames.has(entry.name)) {
207
- const schemaPath = path.join(packageDir, entry.name, 'schema.yaml');
208
- if (fs.existsSync(schemaPath)) {
209
- try {
210
- const schema = parseSchema(fs.readFileSync(schemaPath, 'utf-8'));
211
- schemas.push({
212
- name: entry.name,
213
- description: schema.description || '',
214
- artifacts: schema.artifacts.map((a) => a.id),
215
- source: 'package',
216
- });
217
- } catch {
218
- // Skip invalid schemas
219
- }
220
- }
221
- }
222
- }
223
- }
224
-
225
- return schemas.sort((a, b) => a.name.localeCompare(b.name));
226
- }
@@ -1,124 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import { parse as parseYaml } from 'yaml';
3
- import { SchemaYamlSchema, type SchemaYaml, type Artifact } from './types.js';
4
-
5
- export class SchemaValidationError extends Error {
6
- constructor(message: string) {
7
- super(message);
8
- this.name = 'SchemaValidationError';
9
- }
10
- }
11
-
12
- /**
13
- * Loads and validates an artifact schema from a YAML file.
14
- */
15
- export function loadSchema(filePath: string): SchemaYaml {
16
- const content = fs.readFileSync(filePath, 'utf-8');
17
- return parseSchema(content);
18
- }
19
-
20
- /**
21
- * Parses and validates an artifact schema from YAML content.
22
- */
23
- export function parseSchema(yamlContent: string): SchemaYaml {
24
- const parsed = parseYaml(yamlContent);
25
-
26
- // Validate with Zod
27
- const result = SchemaYamlSchema.safeParse(parsed);
28
- if (!result.success) {
29
- const errors = result.error.issues.map(e => `${e.path.join('.')}: ${e.message}`).join(', ');
30
- throw new SchemaValidationError(`Invalid schema: ${errors}`);
31
- }
32
-
33
- const schema = result.data;
34
-
35
- // Check for duplicate artifact IDs
36
- validateNoDuplicateIds(schema.artifacts);
37
-
38
- // Check that all requires references are valid
39
- validateRequiresReferences(schema.artifacts);
40
-
41
- // Check for cycles
42
- validateNoCycles(schema.artifacts);
43
-
44
- return schema;
45
- }
46
-
47
- /**
48
- * Validates that there are no duplicate artifact IDs.
49
- */
50
- function validateNoDuplicateIds(artifacts: Artifact[]): void {
51
- const seen = new Set<string>();
52
- for (const artifact of artifacts) {
53
- if (seen.has(artifact.id)) {
54
- throw new SchemaValidationError(`Duplicate artifact ID: ${artifact.id}`);
55
- }
56
- seen.add(artifact.id);
57
- }
58
- }
59
-
60
- /**
61
- * Validates that all `requires` references point to valid artifact IDs.
62
- */
63
- function validateRequiresReferences(artifacts: Artifact[]): void {
64
- const validIds = new Set(artifacts.map(a => a.id));
65
-
66
- for (const artifact of artifacts) {
67
- for (const req of artifact.requires) {
68
- if (!validIds.has(req)) {
69
- throw new SchemaValidationError(
70
- `Invalid dependency reference in artifact '${artifact.id}': '${req}' does not exist`
71
- );
72
- }
73
- }
74
- }
75
- }
76
-
77
- /**
78
- * Validates that there are no cyclic dependencies.
79
- * Uses DFS to detect cycles and reports the full cycle path.
80
- */
81
- function validateNoCycles(artifacts: Artifact[]): void {
82
- const artifactMap = new Map(artifacts.map(a => [a.id, a]));
83
- const visited = new Set<string>();
84
- const inStack = new Set<string>();
85
- const parent = new Map<string, string>();
86
-
87
- function dfs(id: string): string | null {
88
- visited.add(id);
89
- inStack.add(id);
90
-
91
- const artifact = artifactMap.get(id);
92
- if (!artifact) return null;
93
-
94
- for (const dep of artifact.requires) {
95
- if (!visited.has(dep)) {
96
- parent.set(dep, id);
97
- const cycle = dfs(dep);
98
- if (cycle) return cycle;
99
- } else if (inStack.has(dep)) {
100
- // Found a cycle - reconstruct the path
101
- const cyclePath = [dep];
102
- let current = id;
103
- while (current !== dep) {
104
- cyclePath.unshift(current);
105
- current = parent.get(current)!;
106
- }
107
- cyclePath.unshift(dep);
108
- return cyclePath.join(' → ');
109
- }
110
- }
111
-
112
- inStack.delete(id);
113
- return null;
114
- }
115
-
116
- for (const artifact of artifacts) {
117
- if (!visited.has(artifact.id)) {
118
- const cycle = dfs(artifact.id);
119
- if (cycle) {
120
- throw new SchemaValidationError(`Cyclic dependency detected: ${cycle}`);
121
- }
122
- }
123
- }
124
- }