@dedesfr/prompter 0.6.15 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/cli/index.js +144 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/archive.d.ts +11 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +280 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.d.ts.map +1 -0
- package/dist/commands/change.js +277 -0
- package/dist/commands/change.js.map +1 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +198 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/list.d.ts +2 -2
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +153 -47
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/show.d.ts +14 -0
- package/dist/commands/show.d.ts.map +1 -0
- package/dist/commands/show.js +132 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/spec.d.ts +15 -0
- package/dist/commands/spec.d.ts.map +1 -0
- package/dist/commands/spec.js +225 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +294 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/core/artifact-graph/graph.d.ts +56 -0
- package/dist/core/artifact-graph/graph.d.ts.map +1 -0
- package/dist/core/artifact-graph/graph.js +141 -0
- package/dist/core/artifact-graph/graph.js.map +1 -0
- package/dist/core/artifact-graph/index.d.ts +7 -0
- package/dist/core/artifact-graph/index.d.ts.map +1 -0
- package/dist/core/artifact-graph/index.js +13 -0
- package/dist/core/artifact-graph/index.js.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +130 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts.map +1 -0
- package/dist/core/artifact-graph/instruction-loader.js +173 -0
- package/dist/core/artifact-graph/instruction-loader.js.map +1 -0
- package/dist/core/artifact-graph/resolver.d.ts +61 -0
- package/dist/core/artifact-graph/resolver.d.ts.map +1 -0
- package/dist/core/artifact-graph/resolver.js +187 -0
- package/dist/core/artifact-graph/resolver.js.map +1 -0
- package/dist/core/artifact-graph/schema.d.ts +13 -0
- package/dist/core/artifact-graph/schema.d.ts.map +1 -0
- package/dist/core/artifact-graph/schema.js +108 -0
- package/dist/core/artifact-graph/schema.js.map +1 -0
- package/dist/core/artifact-graph/state.d.ts +12 -0
- package/dist/core/artifact-graph/state.d.ts.map +1 -0
- package/dist/core/artifact-graph/state.js +54 -0
- package/dist/core/artifact-graph/state.js.map +1 -0
- package/dist/core/artifact-graph/types.d.ts +45 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -0
- package/dist/core/artifact-graph/types.js +43 -0
- package/dist/core/artifact-graph/types.js.map +1 -0
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.d.ts.map +1 -0
- package/dist/core/completions/command-registry.js +380 -0
- package/dist/core/completions/command-registry.js.map +1 -0
- package/dist/core/completions/completion-provider.d.ts +60 -0
- package/dist/core/completions/completion-provider.d.ts.map +1 -0
- package/dist/core/completions/completion-provider.js +102 -0
- package/dist/core/completions/completion-provider.js.map +1 -0
- package/dist/core/completions/generators/bash-generator.d.ts +32 -0
- package/dist/core/completions/generators/bash-generator.d.ts.map +1 -0
- package/dist/core/completions/generators/bash-generator.js +174 -0
- package/dist/core/completions/generators/bash-generator.js.map +1 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.d.ts.map +1 -0
- package/dist/core/completions/generators/fish-generator.js +157 -0
- package/dist/core/completions/generators/fish-generator.js.map +1 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
- package/dist/core/completions/generators/powershell-generator.d.ts.map +1 -0
- package/dist/core/completions/generators/powershell-generator.js +207 -0
- package/dist/core/completions/generators/powershell-generator.js.map +1 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
- package/dist/core/completions/generators/zsh-generator.d.ts.map +1 -0
- package/dist/core/completions/generators/zsh-generator.js +250 -0
- package/dist/core/completions/generators/zsh-generator.js.map +1 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.d.ts.map +1 -0
- package/dist/core/completions/templates/bash-templates.js +24 -0
- package/dist/core/completions/templates/bash-templates.js.map +1 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.d.ts.map +1 -0
- package/dist/core/completions/templates/fish-templates.js +39 -0
- package/dist/core/completions/templates/fish-templates.js.map +1 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.d.ts.map +1 -0
- package/dist/core/completions/templates/powershell-templates.js +25 -0
- package/dist/core/completions/templates/powershell-templates.js.map +1 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.d.ts.map +1 -0
- package/dist/core/completions/templates/zsh-templates.js +36 -0
- package/dist/core/completions/templates/zsh-templates.js.map +1 -0
- package/dist/core/completions/types.d.ts +78 -0
- package/dist/core/completions/types.d.ts.map +1 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/completions/types.js.map +1 -0
- package/dist/core/config-schema.d.ts +76 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +200 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +18 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/configurators/slash/antigravity.d.ts.map +1 -1
- package/dist/core/configurators/slash/antigravity.js +6 -0
- package/dist/core/configurators/slash/antigravity.js.map +1 -1
- package/dist/core/configurators/slash/base.js +1 -1
- package/dist/core/configurators/slash/base.js.map +1 -1
- package/dist/core/configurators/slash/claude.d.ts.map +1 -1
- package/dist/core/configurators/slash/claude.js +6 -0
- package/dist/core/configurators/slash/claude.js.map +1 -1
- package/dist/core/configurators/slash/codex.d.ts.map +1 -1
- package/dist/core/configurators/slash/codex.js +6 -0
- package/dist/core/configurators/slash/codex.js.map +1 -1
- package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
- package/dist/core/configurators/slash/github-copilot.js +6 -0
- package/dist/core/configurators/slash/github-copilot.js.map +1 -1
- package/dist/core/configurators/slash/kilocode.d.ts.map +1 -1
- package/dist/core/configurators/slash/kilocode.js +6 -0
- package/dist/core/configurators/slash/kilocode.js.map +1 -1
- package/dist/core/configurators/slash/opencode.d.ts.map +1 -1
- package/dist/core/configurators/slash/opencode.js +6 -0
- package/dist/core/configurators/slash/opencode.js.map +1 -1
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.d.ts.map +1 -0
- package/dist/core/converters/json-converter.js +51 -0
- package/dist/core/converters/json-converter.js.map +1 -0
- package/dist/core/global-config.d.ts +39 -0
- package/dist/core/global-config.d.ts.map +1 -0
- package/dist/core/global-config.js +115 -0
- package/dist/core/global-config.js.map +1 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.d.ts.map +1 -0
- package/dist/core/parsers/change-parser.js +193 -0
- package/dist/core/parsers/change-parser.js.map +1 -0
- package/dist/core/parsers/markdown-parser.d.ts +22 -0
- package/dist/core/parsers/markdown-parser.d.ts.map +1 -0
- package/dist/core/parsers/markdown-parser.js +187 -0
- package/dist/core/parsers/markdown-parser.js.map +1 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.d.ts.map +1 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- package/dist/core/parsers/requirement-blocks.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +3 -0
- package/dist/core/prompt-templates.d.ts.map +1 -1
- package/dist/core/prompt-templates.js +66 -0
- package/dist/core/prompt-templates.js.map +1 -1
- package/dist/core/schemas/base.schema.d.ts +13 -0
- package/dist/core/schemas/base.schema.d.ts.map +1 -0
- package/dist/core/schemas/base.schema.js +13 -0
- package/dist/core/schemas/base.schema.js.map +1 -0
- package/dist/core/schemas/change.schema.d.ts +73 -0
- package/dist/core/schemas/change.schema.d.ts.map +1 -0
- package/dist/core/schemas/change.schema.js +31 -0
- package/dist/core/schemas/change.schema.js.map +1 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.d.ts.map +1 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/index.js.map +1 -0
- package/dist/core/schemas/spec.schema.d.ts +18 -0
- package/dist/core/schemas/spec.schema.d.ts.map +1 -0
- package/dist/core/schemas/spec.schema.js +15 -0
- package/dist/core/schemas/spec.schema.js.map +1 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.d.ts.map +1 -0
- package/dist/core/specs-apply.js +384 -0
- package/dist/core/specs-apply.js.map +1 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.d.ts.map +1 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/styles/palette.js.map +1 -0
- package/dist/core/templates/slash-command-templates.d.ts +1 -1
- package/dist/core/templates/slash-command-templates.d.ts.map +1 -1
- package/dist/core/templates/slash-command-templates.js +4 -1
- package/dist/core/templates/slash-command-templates.js.map +1 -1
- package/dist/core/validation/constants.d.ts +34 -0
- package/dist/core/validation/constants.d.ts.map +1 -0
- package/dist/core/validation/constants.js +40 -0
- package/dist/core/validation/constants.js.map +1 -0
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.d.ts.map +1 -0
- package/dist/core/validation/types.js +2 -0
- package/dist/core/validation/types.js.map +1 -0
- package/dist/core/validation/validator.d.ts +33 -0
- package/dist/core/validation/validator.d.ts.map +1 -0
- package/dist/core/validation/validator.js +409 -0
- package/dist/core/validation/validator.js.map +1 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.d.ts.map +1 -0
- package/dist/core/view.js +168 -0
- package/dist/core/view.js.map +1 -0
- package/dist/utils/change-metadata.d.ts +47 -0
- package/dist/utils/change-metadata.d.ts.map +1 -0
- package/dist/utils/change-metadata.js +130 -0
- package/dist/utils/change-metadata.js.map +1 -0
- package/dist/utils/change-utils.d.ts +51 -0
- package/dist/utils/change-utils.d.ts.map +1 -0
- package/dist/utils/change-utils.js +100 -0
- package/dist/utils/change-utils.js.map +1 -0
- package/dist/utils/file-system.d.ts +25 -0
- package/dist/utils/file-system.d.ts.map +1 -0
- package/dist/utils/file-system.js +218 -0
- package/dist/utils/file-system.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/interactive.d.ts +18 -0
- package/dist/utils/interactive.d.ts.map +1 -0
- package/dist/utils/interactive.js +21 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/item-discovery.d.ts +4 -0
- package/dist/utils/item-discovery.d.ts.map +1 -0
- package/dist/utils/item-discovery.js +72 -0
- package/dist/utils/item-discovery.js.map +1 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.d.ts.map +1 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/match.js.map +1 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.d.ts.map +1 -0
- package/dist/utils/shell-detection.js +41 -0
- package/dist/utils/shell-detection.js.map +1 -0
- package/dist/utils/task-progress.d.ts +8 -0
- package/dist/utils/task-progress.d.ts.map +1 -0
- package/dist/utils/task-progress.js +36 -0
- package/dist/utils/task-progress.js.map +1 -0
- package/docs/tasks.md +1 -1
- package/package.json +6 -2
- package/prompt/apply.md +17 -0
- package/prompt/archive.md +21 -0
- package/prompt/proposal.md +22 -0
- package/src/cli/index.ts +151 -16
- package/src/commands/archive.ts +302 -0
- package/src/commands/change.ts +292 -0
- package/src/commands/config.ts +233 -0
- package/src/commands/list.ts +176 -66
- package/src/commands/show.ts +138 -0
- package/src/commands/spec.ts +251 -0
- package/src/commands/validate.ts +326 -0
- package/src/core/artifact-graph/graph.ts +167 -0
- package/src/core/artifact-graph/index.ts +44 -0
- package/src/core/artifact-graph/instruction-loader.ts +302 -0
- package/src/core/artifact-graph/resolver.ts +226 -0
- package/src/core/artifact-graph/schema.ts +124 -0
- package/src/core/artifact-graph/state.ts +64 -0
- package/src/core/artifact-graph/types.ts +65 -0
- package/src/core/completions/command-registry.ts +382 -0
- package/src/core/completions/completion-provider.ts +128 -0
- package/src/core/completions/generators/bash-generator.ts +191 -0
- package/src/core/completions/generators/fish-generator.ts +188 -0
- package/src/core/completions/generators/powershell-generator.ts +223 -0
- package/src/core/completions/generators/zsh-generator.ts +281 -0
- package/src/core/completions/templates/bash-templates.ts +24 -0
- package/src/core/completions/templates/fish-templates.ts +40 -0
- package/src/core/completions/templates/powershell-templates.ts +25 -0
- package/src/core/completions/templates/zsh-templates.ts +36 -0
- package/src/core/completions/types.ts +90 -0
- package/src/core/config-schema.ts +230 -0
- package/src/core/config.ts +18 -0
- package/src/core/configurators/slash/antigravity.ts +6 -0
- package/src/core/configurators/slash/base.ts +1 -1
- package/src/core/configurators/slash/claude.ts +6 -0
- package/src/core/configurators/slash/codex.ts +6 -0
- package/src/core/configurators/slash/github-copilot.ts +6 -0
- package/src/core/configurators/slash/kilocode.ts +6 -0
- package/src/core/configurators/slash/opencode.ts +6 -0
- package/src/core/converters/json-converter.ts +62 -0
- package/src/core/global-config.ts +136 -0
- package/src/core/parsers/change-parser.ts +234 -0
- package/src/core/parsers/markdown-parser.ts +237 -0
- package/src/core/parsers/requirement-blocks.ts +234 -0
- package/src/core/prompt-templates.ts +69 -0
- package/src/core/schemas/base.schema.ts +20 -0
- package/src/core/schemas/change.schema.ts +42 -0
- package/src/core/schemas/index.ts +20 -0
- package/src/core/schemas/spec.schema.ts +17 -0
- package/src/core/specs-apply.ts +483 -0
- package/src/core/styles/palette.ts +8 -0
- package/src/core/templates/slash-command-templates.ts +7 -1
- package/src/core/validation/constants.ts +48 -0
- package/src/core/validation/types.ts +19 -0
- package/src/core/validation/validator.ts +449 -0
- package/src/core/view.ts +219 -0
- package/src/utils/change-metadata.ts +171 -0
- package/src/utils/change-utils.ts +131 -0
- package/src/utils/file-system.ts +252 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/interactive.ts +29 -0
- package/src/utils/item-discovery.ts +66 -0
- package/src/utils/match.ts +26 -0
- package/src/utils/shell-detection.ts +62 -0
- package/src/utils/task-progress.ts +43 -0
- package/dist/commands/ai-humanizer.d.ts +0 -11
- package/dist/commands/ai-humanizer.d.ts.map +0 -1
- package/dist/commands/ai-humanizer.js +0 -97
- package/dist/commands/ai-humanizer.js.map +0 -1
- package/dist/commands/api-contract-generator.d.ts +0 -11
- package/dist/commands/api-contract-generator.d.ts.map +0 -1
- package/dist/commands/api-contract-generator.js +0 -97
- package/dist/commands/api-contract-generator.js.map +0 -1
- package/dist/commands/design-system.d.ts +0 -11
- package/dist/commands/design-system.d.ts.map +0 -1
- package/dist/commands/design-system.js +0 -97
- package/dist/commands/design-system.js.map +0 -1
- package/dist/commands/document-explainer.d.ts +0 -11
- package/dist/commands/document-explainer.d.ts.map +0 -1
- package/dist/commands/document-explainer.js +0 -97
- package/dist/commands/document-explainer.js.map +0 -1
- package/dist/commands/epic-generator.d.ts +0 -11
- package/dist/commands/epic-generator.d.ts.map +0 -1
- package/dist/commands/epic-generator.js +0 -97
- package/dist/commands/epic-generator.js.map +0 -1
- package/dist/commands/erd-generator.d.ts +0 -11
- package/dist/commands/erd-generator.d.ts.map +0 -1
- package/dist/commands/erd-generator.js +0 -97
- package/dist/commands/erd-generator.js.map +0 -1
- package/dist/commands/fsd-generator.d.ts +0 -11
- package/dist/commands/fsd-generator.d.ts.map +0 -1
- package/dist/commands/fsd-generator.js +0 -97
- package/dist/commands/fsd-generator.js.map +0 -1
- package/dist/commands/prd-agent-generator.d.ts +0 -11
- package/dist/commands/prd-agent-generator.d.ts.map +0 -1
- package/dist/commands/prd-agent-generator.js +0 -95
- package/dist/commands/prd-agent-generator.js.map +0 -1
- package/dist/commands/prd-generator.d.ts +0 -11
- package/dist/commands/prd-generator.d.ts.map +0 -1
- package/dist/commands/prd-generator.js +0 -97
- package/dist/commands/prd-generator.js.map +0 -1
- package/dist/commands/product-brief.d.ts +0 -11
- package/dist/commands/product-brief.d.ts.map +0 -1
- package/dist/commands/product-brief.js +0 -97
- package/dist/commands/product-brief.js.map +0 -1
- package/dist/commands/skill-creator.d.ts +0 -11
- package/dist/commands/skill-creator.d.ts.map +0 -1
- package/dist/commands/skill-creator.js +0 -101
- package/dist/commands/skill-creator.js.map +0 -1
- package/dist/commands/story-generator.d.ts +0 -11
- package/dist/commands/story-generator.d.ts.map +0 -1
- package/dist/commands/story-generator.js +0 -97
- package/dist/commands/story-generator.js.map +0 -1
- package/dist/commands/tdd-generator.d.ts +0 -11
- package/dist/commands/tdd-generator.d.ts.map +0 -1
- package/dist/commands/tdd-generator.js +0 -97
- package/dist/commands/tdd-generator.js.map +0 -1
- package/dist/commands/tdd-lite-generator.d.ts +0 -11
- package/dist/commands/tdd-lite-generator.d.ts.map +0 -1
- package/dist/commands/tdd-lite-generator.js +0 -97
- package/dist/commands/tdd-lite-generator.js.map +0 -1
- package/dist/commands/wireframe-generator.d.ts +0 -11
- package/dist/commands/wireframe-generator.d.ts.map +0 -1
- package/dist/commands/wireframe-generator.js +0 -97
- package/dist/commands/wireframe-generator.js.map +0 -1
- package/src/commands/ai-humanizer.ts +0 -118
- package/src/commands/api-contract-generator.ts +0 -118
- package/src/commands/design-system.ts +0 -118
- package/src/commands/document-explainer.ts +0 -118
- package/src/commands/epic-generator.ts +0 -118
- package/src/commands/erd-generator.ts +0 -118
- package/src/commands/fsd-generator.ts +0 -118
- package/src/commands/prd-agent-generator.ts +0 -115
- package/src/commands/prd-generator.ts +0 -118
- package/src/commands/product-brief.ts +0 -118
- package/src/commands/skill-creator.ts +0 -123
- package/src/commands/story-generator.ts +0 -118
- package/src/commands/tdd-generator.ts +0 -118
- package/src/commands/tdd-lite-generator.ts +0 -118
- package/src/commands/wireframe-generator.ts +0 -118
package/dist/commands/list.js
CHANGED
|
@@ -1,65 +1,171 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { MarkdownParser } from '../core/parsers/markdown-parser.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get the most recent modification time of any file in a directory (recursive).
|
|
9
|
+
* Falls back to the directory's own mtime if no files are found.
|
|
10
|
+
*/
|
|
11
|
+
async function getLastModified(dirPath) {
|
|
12
|
+
let latest = null;
|
|
13
|
+
async function walk(dir) {
|
|
14
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
15
|
+
for (const entry of entries) {
|
|
16
|
+
const fullPath = path.join(dir, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
await walk(fullPath);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const stat = await fs.stat(fullPath);
|
|
22
|
+
if (latest === null || stat.mtime > latest) {
|
|
23
|
+
latest = stat.mtime;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
await walk(dirPath);
|
|
29
|
+
// If no files found, use the directory's own modification time
|
|
30
|
+
if (latest === null) {
|
|
31
|
+
const dirStat = await fs.stat(dirPath);
|
|
32
|
+
return dirStat.mtime;
|
|
33
|
+
}
|
|
34
|
+
return latest;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Format a date as relative time (e.g., "2 hours ago", "3 days ago")
|
|
38
|
+
*/
|
|
39
|
+
function formatRelativeTime(date) {
|
|
40
|
+
const now = new Date();
|
|
41
|
+
const diffMs = now.getTime() - date.getTime();
|
|
42
|
+
const diffSecs = Math.floor(diffMs / 1000);
|
|
43
|
+
const diffMins = Math.floor(diffSecs / 60);
|
|
44
|
+
const diffHours = Math.floor(diffMins / 60);
|
|
45
|
+
const diffDays = Math.floor(diffHours / 24);
|
|
46
|
+
if (diffDays > 30) {
|
|
47
|
+
return date.toLocaleDateString();
|
|
48
|
+
}
|
|
49
|
+
else if (diffDays > 0) {
|
|
50
|
+
return `${diffDays}d ago`;
|
|
51
|
+
}
|
|
52
|
+
else if (diffHours > 0) {
|
|
53
|
+
return `${diffHours}h ago`;
|
|
54
|
+
}
|
|
55
|
+
else if (diffMins > 0) {
|
|
56
|
+
return `${diffMins}m ago`;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return 'just now';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
5
62
|
export class ListCommand {
|
|
6
|
-
async execute(options = {}) {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if
|
|
11
|
-
|
|
63
|
+
async execute(targetPath = '.', mode = 'changes', options = {}) {
|
|
64
|
+
const { sort = 'recent', json = false } = options;
|
|
65
|
+
if (mode === 'changes') {
|
|
66
|
+
const changesDir = path.join(targetPath, 'prompter', 'changes');
|
|
67
|
+
// Check if changes directory exists
|
|
68
|
+
try {
|
|
69
|
+
await fs.access(changesDir);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
throw new Error("No Prompter changes directory found. Run 'prompter init' first.");
|
|
73
|
+
}
|
|
74
|
+
// Get all directories in changes (excluding archive)
|
|
75
|
+
const entries = await fs.readdir(changesDir, { withFileTypes: true });
|
|
76
|
+
const changeDirs = entries
|
|
77
|
+
.filter(entry => entry.isDirectory() && entry.name !== 'archive')
|
|
78
|
+
.map(entry => entry.name);
|
|
79
|
+
if (changeDirs.length === 0) {
|
|
80
|
+
if (json) {
|
|
81
|
+
console.log(JSON.stringify({ changes: [] }));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.log('No active changes found.');
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Collect information about each change
|
|
89
|
+
const changes = [];
|
|
90
|
+
for (const changeDir of changeDirs) {
|
|
91
|
+
const progress = await getTaskProgressForChange(changesDir, changeDir);
|
|
92
|
+
const changePath = path.join(changesDir, changeDir);
|
|
93
|
+
const lastModified = await getLastModified(changePath);
|
|
94
|
+
changes.push({
|
|
95
|
+
name: changeDir,
|
|
96
|
+
completedTasks: progress.completed,
|
|
97
|
+
totalTasks: progress.total,
|
|
98
|
+
lastModified
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// Sort by preference (default: recent first)
|
|
102
|
+
if (sort === 'recent') {
|
|
103
|
+
changes.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
12
104
|
}
|
|
13
105
|
else {
|
|
14
|
-
|
|
15
|
-
|
|
106
|
+
changes.sort((a, b) => a.name.localeCompare(b.name));
|
|
107
|
+
}
|
|
108
|
+
// JSON output for programmatic use
|
|
109
|
+
if (json) {
|
|
110
|
+
const jsonOutput = changes.map(c => ({
|
|
111
|
+
name: c.name,
|
|
112
|
+
completedTasks: c.completedTasks,
|
|
113
|
+
totalTasks: c.totalTasks,
|
|
114
|
+
lastModified: c.lastModified.toISOString(),
|
|
115
|
+
status: c.totalTasks === 0 ? 'no-tasks' : c.completedTasks === c.totalTasks ? 'complete' : 'in-progress'
|
|
116
|
+
}));
|
|
117
|
+
console.log(JSON.stringify({ changes: jsonOutput }, null, 2));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Display results
|
|
121
|
+
console.log('Changes:');
|
|
122
|
+
const padding = ' ';
|
|
123
|
+
const nameWidth = Math.max(...changes.map(c => c.name.length));
|
|
124
|
+
for (const change of changes) {
|
|
125
|
+
const paddedName = change.name.padEnd(nameWidth);
|
|
126
|
+
const status = formatTaskStatus({ total: change.totalTasks, completed: change.completedTasks });
|
|
127
|
+
const timeAgo = formatRelativeTime(change.lastModified);
|
|
128
|
+
console.log(`${padding}${paddedName} ${status.padEnd(12)} ${timeAgo}`);
|
|
16
129
|
}
|
|
17
|
-
process.exitCode = 1;
|
|
18
130
|
return;
|
|
19
131
|
}
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return;
|
|
132
|
+
// specs mode
|
|
133
|
+
const specsDir = path.join(targetPath, 'prompter', 'specs');
|
|
134
|
+
try {
|
|
135
|
+
await fs.access(specsDir);
|
|
25
136
|
}
|
|
26
|
-
|
|
27
|
-
console.log(
|
|
28
|
-
console.log(chalk.gray('Use /prompter-enhance to create one.\n'));
|
|
137
|
+
catch {
|
|
138
|
+
console.log('No specs found.');
|
|
29
139
|
return;
|
|
30
140
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
console.log(
|
|
141
|
+
const entries = await fs.readdir(specsDir, { withFileTypes: true });
|
|
142
|
+
const specDirs = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
143
|
+
if (specDirs.length === 0) {
|
|
144
|
+
console.log('No specs found.');
|
|
145
|
+
return;
|
|
35
146
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
prompts.push({
|
|
49
|
-
id: entry.name,
|
|
50
|
-
path: path.join(PROMPTER_DIR, entry.name, 'enhanced-prompt.md'),
|
|
51
|
-
createdAt: stats.birthtime.toISOString()
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
// No enhanced-prompt.md in this directory, skip
|
|
56
|
-
}
|
|
147
|
+
const specs = [];
|
|
148
|
+
for (const id of specDirs) {
|
|
149
|
+
const specPath = join(specsDir, id, 'spec.md');
|
|
150
|
+
try {
|
|
151
|
+
const content = readFileSync(specPath, 'utf-8');
|
|
152
|
+
const parser = new MarkdownParser(content);
|
|
153
|
+
const spec = parser.parseSpec(id);
|
|
154
|
+
specs.push({ id, requirementCount: spec.requirements.length });
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// If spec cannot be read or parsed, include with 0 count
|
|
158
|
+
specs.push({ id, requirementCount: 0 });
|
|
57
159
|
}
|
|
58
160
|
}
|
|
59
|
-
|
|
60
|
-
|
|
161
|
+
specs.sort((a, b) => a.id.localeCompare(b.id));
|
|
162
|
+
console.log('Specs:');
|
|
163
|
+
const padding = ' ';
|
|
164
|
+
const nameWidth = Math.max(...specs.map(s => s.id.length));
|
|
165
|
+
for (const spec of specs) {
|
|
166
|
+
const padded = spec.id.padEnd(nameWidth);
|
|
167
|
+
console.log(`${padding}${padded} requirements ${spec.requirementCount}`);
|
|
61
168
|
}
|
|
62
|
-
return prompts.sort((a, b) => a.id.localeCompare(b.id));
|
|
63
169
|
}
|
|
64
170
|
}
|
|
65
171
|
//# sourceMappingURL=list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class ShowCommand {
|
|
2
|
+
execute(itemName?: string, options?: {
|
|
3
|
+
json?: boolean;
|
|
4
|
+
type?: string;
|
|
5
|
+
noInteractive?: boolean;
|
|
6
|
+
[k: string]: any;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
private normalizeType;
|
|
9
|
+
private runInteractiveByType;
|
|
10
|
+
private showDirect;
|
|
11
|
+
private printNonInteractiveHint;
|
|
12
|
+
private warnIrrelevantFlags;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=show.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"AAYA,qBAAa,WAAW;IAChB,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3I,OAAO,CAAC,aAAa;YAOP,oBAAoB;YA0BpB,UAAU;IA6CxB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;CAa5B"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { isInteractive } from '../utils/interactive.js';
|
|
2
|
+
import { getActiveChangeIds, getSpecIds } from '../utils/item-discovery.js';
|
|
3
|
+
import { ChangeCommand } from './change.js';
|
|
4
|
+
import { SpecCommand } from './spec.js';
|
|
5
|
+
import { nearestMatches } from '../utils/match.js';
|
|
6
|
+
const CHANGE_FLAG_KEYS = new Set(['deltasOnly', 'requirementsOnly']);
|
|
7
|
+
const SPEC_FLAG_KEYS = new Set(['requirements', 'scenarios', 'requirement']);
|
|
8
|
+
export class ShowCommand {
|
|
9
|
+
async execute(itemName, options = {}) {
|
|
10
|
+
const interactive = isInteractive(options);
|
|
11
|
+
const typeOverride = this.normalizeType(options.type);
|
|
12
|
+
if (!itemName) {
|
|
13
|
+
if (interactive) {
|
|
14
|
+
const { select } = await import('@inquirer/prompts');
|
|
15
|
+
const type = await select({
|
|
16
|
+
message: 'What would you like to show?',
|
|
17
|
+
choices: [
|
|
18
|
+
{ name: 'Change', value: 'change' },
|
|
19
|
+
{ name: 'Spec', value: 'spec' },
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
await this.runInteractiveByType(type, options);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
this.printNonInteractiveHint();
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await this.showDirect(itemName, { typeOverride, options });
|
|
30
|
+
}
|
|
31
|
+
normalizeType(value) {
|
|
32
|
+
if (!value)
|
|
33
|
+
return undefined;
|
|
34
|
+
const v = value.toLowerCase();
|
|
35
|
+
if (v === 'change' || v === 'spec')
|
|
36
|
+
return v;
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
async runInteractiveByType(type, options) {
|
|
40
|
+
const { select } = await import('@inquirer/prompts');
|
|
41
|
+
if (type === 'change') {
|
|
42
|
+
const changes = await getActiveChangeIds();
|
|
43
|
+
if (changes.length === 0) {
|
|
44
|
+
console.error('No changes found.');
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const picked = await select({ message: 'Pick a change', choices: changes.map(id => ({ name: id, value: id })) });
|
|
49
|
+
const cmd = new ChangeCommand();
|
|
50
|
+
await cmd.show(picked, options);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const specs = await getSpecIds();
|
|
54
|
+
if (specs.length === 0) {
|
|
55
|
+
console.error('No specs found.');
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const picked = await select({ message: 'Pick a spec', choices: specs.map(id => ({ name: id, value: id })) });
|
|
60
|
+
const cmd = new SpecCommand();
|
|
61
|
+
await cmd.show(picked, options);
|
|
62
|
+
}
|
|
63
|
+
async showDirect(itemName, params) {
|
|
64
|
+
// Optimize lookups when type is pre-specified
|
|
65
|
+
let isChange = false;
|
|
66
|
+
let isSpec = false;
|
|
67
|
+
let changes = [];
|
|
68
|
+
let specs = [];
|
|
69
|
+
if (params.typeOverride === 'change') {
|
|
70
|
+
changes = await getActiveChangeIds();
|
|
71
|
+
isChange = changes.includes(itemName);
|
|
72
|
+
}
|
|
73
|
+
else if (params.typeOverride === 'spec') {
|
|
74
|
+
specs = await getSpecIds();
|
|
75
|
+
isSpec = specs.includes(itemName);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
[changes, specs] = await Promise.all([getActiveChangeIds(), getSpecIds()]);
|
|
79
|
+
isChange = changes.includes(itemName);
|
|
80
|
+
isSpec = specs.includes(itemName);
|
|
81
|
+
}
|
|
82
|
+
const resolvedType = params.typeOverride ?? (isChange ? 'change' : isSpec ? 'spec' : undefined);
|
|
83
|
+
if (!resolvedType) {
|
|
84
|
+
console.error(`Unknown item '${itemName}'`);
|
|
85
|
+
const suggestions = nearestMatches(itemName, [...changes, ...specs]);
|
|
86
|
+
if (suggestions.length)
|
|
87
|
+
console.error(`Did you mean: ${suggestions.join(', ')}?`);
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!params.typeOverride && isChange && isSpec) {
|
|
92
|
+
console.error(`Ambiguous item '${itemName}' matches both a change and a spec.`);
|
|
93
|
+
console.error('Pass --type change|spec, or use: prompter change show / prompter spec show');
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.warnIrrelevantFlags(resolvedType, params.options);
|
|
98
|
+
if (resolvedType === 'change') {
|
|
99
|
+
const cmd = new ChangeCommand();
|
|
100
|
+
await cmd.show(itemName, params.options);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const cmd = new SpecCommand();
|
|
104
|
+
await cmd.show(itemName, params.options);
|
|
105
|
+
}
|
|
106
|
+
printNonInteractiveHint() {
|
|
107
|
+
console.error('Nothing to show. Try one of:');
|
|
108
|
+
console.error(' prompter show <item>');
|
|
109
|
+
console.error(' prompter change show');
|
|
110
|
+
console.error(' prompter spec show');
|
|
111
|
+
console.error('Or run in an interactive terminal.');
|
|
112
|
+
}
|
|
113
|
+
warnIrrelevantFlags(type, options) {
|
|
114
|
+
const irrelevant = [];
|
|
115
|
+
if (type === 'change') {
|
|
116
|
+
for (const k of SPEC_FLAG_KEYS)
|
|
117
|
+
if (k in options)
|
|
118
|
+
irrelevant.push(k);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
for (const k of CHANGE_FLAG_KEYS)
|
|
122
|
+
if (k in options)
|
|
123
|
+
irrelevant.push(k);
|
|
124
|
+
}
|
|
125
|
+
if (irrelevant.length > 0) {
|
|
126
|
+
console.error(`Warning: Ignoring flags not applicable to ${type}: ${irrelevant.join(', ')}`);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=show.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.js","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { program } from 'commander';
|
|
2
|
+
interface ShowOptions {
|
|
3
|
+
json?: boolean;
|
|
4
|
+
requirements?: boolean;
|
|
5
|
+
scenarios?: boolean;
|
|
6
|
+
requirement?: string;
|
|
7
|
+
noInteractive?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare class SpecCommand {
|
|
10
|
+
private SPECS_DIR;
|
|
11
|
+
show(specId?: string, options?: ShowOptions): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function registerSpecCommand(rootProgram: typeof program): import("commander").Command;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAgDD,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAoB;IAE/B,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAuCtE;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,OAAO,OAAO,+BA4I9D"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { MarkdownParser } from '../core/parsers/markdown-parser.js';
|
|
4
|
+
import { Validator } from '../core/validation/validator.js';
|
|
5
|
+
import { isInteractive } from '../utils/interactive.js';
|
|
6
|
+
import { getSpecIds } from '../utils/item-discovery.js';
|
|
7
|
+
const SPECS_DIR = 'prompter/specs';
|
|
8
|
+
function parseSpecFromFile(specPath, specId) {
|
|
9
|
+
const content = readFileSync(specPath, 'utf-8');
|
|
10
|
+
const parser = new MarkdownParser(content);
|
|
11
|
+
return parser.parseSpec(specId);
|
|
12
|
+
}
|
|
13
|
+
function validateRequirementIndex(spec, requirementOpt) {
|
|
14
|
+
if (!requirementOpt)
|
|
15
|
+
return undefined;
|
|
16
|
+
const index = Number.parseInt(requirementOpt, 10);
|
|
17
|
+
if (!Number.isInteger(index) || index < 1 || index > spec.requirements.length) {
|
|
18
|
+
throw new Error(`Requirement ${requirementOpt} not found`);
|
|
19
|
+
}
|
|
20
|
+
return index - 1; // convert to 0-based
|
|
21
|
+
}
|
|
22
|
+
function filterSpec(spec, options) {
|
|
23
|
+
const requirementIndex = validateRequirementIndex(spec, options.requirement);
|
|
24
|
+
const includeScenarios = options.scenarios !== false && !options.requirements;
|
|
25
|
+
const filteredRequirements = (requirementIndex !== undefined
|
|
26
|
+
? [spec.requirements[requirementIndex]]
|
|
27
|
+
: spec.requirements).map(req => ({
|
|
28
|
+
text: req.text,
|
|
29
|
+
scenarios: includeScenarios ? req.scenarios : [],
|
|
30
|
+
}));
|
|
31
|
+
const metadata = spec.metadata ?? { version: '1.0.0', format: 'prompter' };
|
|
32
|
+
return {
|
|
33
|
+
name: spec.name,
|
|
34
|
+
overview: spec.overview,
|
|
35
|
+
requirements: filteredRequirements,
|
|
36
|
+
metadata,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Print the raw markdown content for a spec file without any formatting.
|
|
41
|
+
* Raw-first behavior ensures text mode is a passthrough for deterministic output.
|
|
42
|
+
*/
|
|
43
|
+
function printSpecTextRaw(specPath) {
|
|
44
|
+
const content = readFileSync(specPath, 'utf-8');
|
|
45
|
+
console.log(content);
|
|
46
|
+
}
|
|
47
|
+
export class SpecCommand {
|
|
48
|
+
SPECS_DIR = 'prompter/specs';
|
|
49
|
+
async show(specId, options = {}) {
|
|
50
|
+
if (!specId) {
|
|
51
|
+
const canPrompt = isInteractive(options);
|
|
52
|
+
const specIds = await getSpecIds();
|
|
53
|
+
if (canPrompt && specIds.length > 0) {
|
|
54
|
+
const { select } = await import('@inquirer/prompts');
|
|
55
|
+
specId = await select({
|
|
56
|
+
message: 'Select a spec to show',
|
|
57
|
+
choices: specIds.map(id => ({ name: id, value: id })),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new Error('Missing required argument <spec-id>');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const specPath = join(this.SPECS_DIR, specId, 'spec.md');
|
|
65
|
+
if (!existsSync(specPath)) {
|
|
66
|
+
throw new Error(`Spec '${specId}' not found at prompter/specs/${specId}/spec.md`);
|
|
67
|
+
}
|
|
68
|
+
if (options.json) {
|
|
69
|
+
if (options.requirements && options.requirement) {
|
|
70
|
+
throw new Error('Options --requirements and --requirement cannot be used together');
|
|
71
|
+
}
|
|
72
|
+
const parsed = parseSpecFromFile(specPath, specId);
|
|
73
|
+
const filtered = filterSpec(parsed, options);
|
|
74
|
+
const output = {
|
|
75
|
+
id: specId,
|
|
76
|
+
title: parsed.name,
|
|
77
|
+
overview: parsed.overview,
|
|
78
|
+
requirementCount: filtered.requirements.length,
|
|
79
|
+
requirements: filtered.requirements,
|
|
80
|
+
metadata: parsed.metadata ?? { version: '1.0.0', format: 'prompter' },
|
|
81
|
+
};
|
|
82
|
+
console.log(JSON.stringify(output, null, 2));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
printSpecTextRaw(specPath);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function registerSpecCommand(rootProgram) {
|
|
89
|
+
const specCommand = rootProgram
|
|
90
|
+
.command('spec')
|
|
91
|
+
.description('Manage and view Prompter specifications');
|
|
92
|
+
// Deprecation notice for noun-based commands
|
|
93
|
+
specCommand.hook('preAction', () => {
|
|
94
|
+
console.error('Warning: The "prompter spec ..." commands are deprecated. Prefer verb-first commands (e.g., "prompter show", "prompter validate --specs").');
|
|
95
|
+
});
|
|
96
|
+
specCommand
|
|
97
|
+
.command('show [spec-id]')
|
|
98
|
+
.description('Display a specific specification')
|
|
99
|
+
.option('--json', 'Output as JSON')
|
|
100
|
+
.option('--requirements', 'JSON only: Show only requirements (exclude scenarios)')
|
|
101
|
+
.option('--no-scenarios', 'JSON only: Exclude scenario content')
|
|
102
|
+
.option('-r, --requirement <id>', 'JSON only: Show specific requirement by ID (1-based)')
|
|
103
|
+
.option('--no-interactive', 'Disable interactive prompts')
|
|
104
|
+
.action(async (specId, options) => {
|
|
105
|
+
try {
|
|
106
|
+
const cmd = new SpecCommand();
|
|
107
|
+
await cmd.show(specId, options);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
111
|
+
process.exitCode = 1;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
specCommand
|
|
115
|
+
.command('list')
|
|
116
|
+
.description('List all available specifications')
|
|
117
|
+
.option('--json', 'Output as JSON')
|
|
118
|
+
.option('--long', 'Show id and title with counts')
|
|
119
|
+
.action((options) => {
|
|
120
|
+
try {
|
|
121
|
+
if (!existsSync(SPECS_DIR)) {
|
|
122
|
+
console.log('No items found');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const specs = readdirSync(SPECS_DIR, { withFileTypes: true })
|
|
126
|
+
.filter(dirent => dirent.isDirectory())
|
|
127
|
+
.map(dirent => {
|
|
128
|
+
const specPath = join(SPECS_DIR, dirent.name, 'spec.md');
|
|
129
|
+
if (existsSync(specPath)) {
|
|
130
|
+
try {
|
|
131
|
+
const spec = parseSpecFromFile(specPath, dirent.name);
|
|
132
|
+
return {
|
|
133
|
+
id: dirent.name,
|
|
134
|
+
title: spec.name,
|
|
135
|
+
requirementCount: spec.requirements.length
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return {
|
|
140
|
+
id: dirent.name,
|
|
141
|
+
title: dirent.name,
|
|
142
|
+
requirementCount: 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
})
|
|
148
|
+
.filter((spec) => spec !== null)
|
|
149
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
150
|
+
if (options.json) {
|
|
151
|
+
console.log(JSON.stringify(specs, null, 2));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
if (specs.length === 0) {
|
|
155
|
+
console.log('No items found');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (!options.long) {
|
|
159
|
+
specs.forEach(spec => console.log(spec.id));
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
specs.forEach(spec => {
|
|
163
|
+
console.log(`${spec.id}: ${spec.title} [requirements ${spec.requirementCount}]`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
169
|
+
process.exitCode = 1;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
specCommand
|
|
173
|
+
.command('validate [spec-id]')
|
|
174
|
+
.description('Validate a specification structure')
|
|
175
|
+
.option('--strict', 'Enable strict validation mode')
|
|
176
|
+
.option('--json', 'Output validation report as JSON')
|
|
177
|
+
.option('--no-interactive', 'Disable interactive prompts')
|
|
178
|
+
.action(async (specId, options) => {
|
|
179
|
+
try {
|
|
180
|
+
if (!specId) {
|
|
181
|
+
const canPrompt = isInteractive(options);
|
|
182
|
+
const specIds = await getSpecIds();
|
|
183
|
+
if (canPrompt && specIds.length > 0) {
|
|
184
|
+
const { select } = await import('@inquirer/prompts');
|
|
185
|
+
specId = await select({
|
|
186
|
+
message: 'Select a spec to validate',
|
|
187
|
+
choices: specIds.map(id => ({ name: id, value: id })),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
throw new Error('Missing required argument <spec-id>');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const specPath = join(SPECS_DIR, specId, 'spec.md');
|
|
195
|
+
if (!existsSync(specPath)) {
|
|
196
|
+
throw new Error(`Spec '${specId}' not found at prompter/specs/${specId}/spec.md`);
|
|
197
|
+
}
|
|
198
|
+
const validator = new Validator(options.strict);
|
|
199
|
+
const report = await validator.validateSpec(specPath);
|
|
200
|
+
if (options.json) {
|
|
201
|
+
console.log(JSON.stringify(report, null, 2));
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
if (report.valid) {
|
|
205
|
+
console.log(`Specification '${specId}' is valid`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
console.error(`Specification '${specId}' has issues`);
|
|
209
|
+
report.issues.forEach(issue => {
|
|
210
|
+
const label = issue.level === 'ERROR' ? 'ERROR' : issue.level;
|
|
211
|
+
const prefix = issue.level === 'ERROR' ? '✗' : issue.level === 'WARNING' ? '⚠' : 'ℹ';
|
|
212
|
+
console.error(`${prefix} [${label}] ${issue.path}: ${issue.message}`);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
process.exitCode = report.valid ? 0 : 1;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
220
|
+
process.exitCode = 1;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
return specCommand;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=spec.js.map
|