@zhuan-ai/zhuanspec 1.3.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 (210) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +461 -0
  3. package/README.zh.md +434 -0
  4. package/bin/zhuanspec.js +3 -0
  5. package/dist/cli/index.d.ts +2 -0
  6. package/dist/cli/index.js +356 -0
  7. package/dist/commands/artifact-workflow.d.ts +13 -0
  8. package/dist/commands/artifact-workflow.js +916 -0
  9. package/dist/commands/change.d.ts +35 -0
  10. package/dist/commands/change.js +277 -0
  11. package/dist/commands/completion.d.ts +72 -0
  12. package/dist/commands/completion.js +221 -0
  13. package/dist/commands/config.d.ts +8 -0
  14. package/dist/commands/config.js +198 -0
  15. package/dist/commands/show.d.ts +14 -0
  16. package/dist/commands/show.js +132 -0
  17. package/dist/commands/spec.d.ts +15 -0
  18. package/dist/commands/spec.js +225 -0
  19. package/dist/commands/validate.d.ts +24 -0
  20. package/dist/commands/validate.js +294 -0
  21. package/dist/core/archive.d.ts +30 -0
  22. package/dist/core/archive.js +438 -0
  23. package/dist/core/artifact-graph/graph.d.ts +56 -0
  24. package/dist/core/artifact-graph/graph.js +141 -0
  25. package/dist/core/artifact-graph/index.d.ts +7 -0
  26. package/dist/core/artifact-graph/index.js +13 -0
  27. package/dist/core/artifact-graph/instruction-loader.d.ts +134 -0
  28. package/dist/core/artifact-graph/instruction-loader.js +180 -0
  29. package/dist/core/artifact-graph/resolver.d.ts +61 -0
  30. package/dist/core/artifact-graph/resolver.js +187 -0
  31. package/dist/core/artifact-graph/schema.d.ts +13 -0
  32. package/dist/core/artifact-graph/schema.js +108 -0
  33. package/dist/core/artifact-graph/state.d.ts +12 -0
  34. package/dist/core/artifact-graph/state.js +54 -0
  35. package/dist/core/artifact-graph/types.d.ts +45 -0
  36. package/dist/core/artifact-graph/types.js +43 -0
  37. package/dist/core/completions/command-registry.d.ts +7 -0
  38. package/dist/core/completions/command-registry.js +362 -0
  39. package/dist/core/completions/completion-provider.d.ts +60 -0
  40. package/dist/core/completions/completion-provider.js +102 -0
  41. package/dist/core/completions/factory.d.ts +51 -0
  42. package/dist/core/completions/factory.js +57 -0
  43. package/dist/core/completions/generators/zsh-generator.d.ts +58 -0
  44. package/dist/core/completions/generators/zsh-generator.js +319 -0
  45. package/dist/core/completions/installers/zsh-installer.d.ts +136 -0
  46. package/dist/core/completions/installers/zsh-installer.js +449 -0
  47. package/dist/core/completions/types.d.ts +78 -0
  48. package/dist/core/completions/types.js +2 -0
  49. package/dist/core/config-schema.d.ts +76 -0
  50. package/dist/core/config-schema.js +200 -0
  51. package/dist/core/config.d.ts +16 -0
  52. package/dist/core/config.js +29 -0
  53. package/dist/core/configurators/agents.d.ts +8 -0
  54. package/dist/core/configurators/agents.js +15 -0
  55. package/dist/core/configurators/base.d.ts +7 -0
  56. package/dist/core/configurators/base.js +2 -0
  57. package/dist/core/configurators/claude.d.ts +8 -0
  58. package/dist/core/configurators/claude.js +15 -0
  59. package/dist/core/configurators/cline.d.ts +8 -0
  60. package/dist/core/configurators/cline.js +15 -0
  61. package/dist/core/configurators/codebuddy.d.ts +8 -0
  62. package/dist/core/configurators/codebuddy.js +15 -0
  63. package/dist/core/configurators/costrict.d.ts +8 -0
  64. package/dist/core/configurators/costrict.js +15 -0
  65. package/dist/core/configurators/iflow.d.ts +8 -0
  66. package/dist/core/configurators/iflow.js +15 -0
  67. package/dist/core/configurators/qoder.d.ts +30 -0
  68. package/dist/core/configurators/qoder.js +42 -0
  69. package/dist/core/configurators/qwen.d.ts +24 -0
  70. package/dist/core/configurators/qwen.js +37 -0
  71. package/dist/core/configurators/registry.d.ts +9 -0
  72. package/dist/core/configurators/registry.js +43 -0
  73. package/dist/core/configurators/slash/amazon-q.d.ts +9 -0
  74. package/dist/core/configurators/slash/amazon-q.js +46 -0
  75. package/dist/core/configurators/slash/antigravity.d.ts +9 -0
  76. package/dist/core/configurators/slash/antigravity.js +23 -0
  77. package/dist/core/configurators/slash/auggie.d.ts +9 -0
  78. package/dist/core/configurators/slash/auggie.js +31 -0
  79. package/dist/core/configurators/slash/base.d.ts +19 -0
  80. package/dist/core/configurators/slash/base.js +69 -0
  81. package/dist/core/configurators/slash/claude.d.ts +9 -0
  82. package/dist/core/configurators/slash/claude.js +37 -0
  83. package/dist/core/configurators/slash/cline.d.ts +9 -0
  84. package/dist/core/configurators/slash/cline.js +23 -0
  85. package/dist/core/configurators/slash/codebuddy.d.ts +9 -0
  86. package/dist/core/configurators/slash/codebuddy.js +37 -0
  87. package/dist/core/configurators/slash/codex.d.ts +14 -0
  88. package/dist/core/configurators/slash/codex.js +109 -0
  89. package/dist/core/configurators/slash/costrict.d.ts +9 -0
  90. package/dist/core/configurators/slash/costrict.js +31 -0
  91. package/dist/core/configurators/slash/crush.d.ts +9 -0
  92. package/dist/core/configurators/slash/crush.js +37 -0
  93. package/dist/core/configurators/slash/cursor.d.ts +9 -0
  94. package/dist/core/configurators/slash/cursor.js +37 -0
  95. package/dist/core/configurators/slash/factory.d.ts +10 -0
  96. package/dist/core/configurators/slash/factory.js +35 -0
  97. package/dist/core/configurators/slash/gemini.d.ts +9 -0
  98. package/dist/core/configurators/slash/gemini.js +22 -0
  99. package/dist/core/configurators/slash/github-copilot.d.ts +9 -0
  100. package/dist/core/configurators/slash/github-copilot.js +34 -0
  101. package/dist/core/configurators/slash/iflow.d.ts +9 -0
  102. package/dist/core/configurators/slash/iflow.js +37 -0
  103. package/dist/core/configurators/slash/kilocode.d.ts +9 -0
  104. package/dist/core/configurators/slash/kilocode.js +17 -0
  105. package/dist/core/configurators/slash/opencode.d.ts +12 -0
  106. package/dist/core/configurators/slash/opencode.js +72 -0
  107. package/dist/core/configurators/slash/qoder.d.ts +35 -0
  108. package/dist/core/configurators/slash/qoder.js +76 -0
  109. package/dist/core/configurators/slash/qwen.d.ts +32 -0
  110. package/dist/core/configurators/slash/qwen.js +49 -0
  111. package/dist/core/configurators/slash/registry.d.ts +8 -0
  112. package/dist/core/configurators/slash/registry.js +75 -0
  113. package/dist/core/configurators/slash/roocode.d.ts +9 -0
  114. package/dist/core/configurators/slash/roocode.js +23 -0
  115. package/dist/core/configurators/slash/toml-base.d.ts +10 -0
  116. package/dist/core/configurators/slash/toml-base.js +53 -0
  117. package/dist/core/configurators/slash/windsurf.d.ts +9 -0
  118. package/dist/core/configurators/slash/windsurf.js +23 -0
  119. package/dist/core/converters/json-converter.d.ts +6 -0
  120. package/dist/core/converters/json-converter.js +51 -0
  121. package/dist/core/global-config.d.ts +39 -0
  122. package/dist/core/global-config.js +115 -0
  123. package/dist/core/index.d.ts +2 -0
  124. package/dist/core/index.js +3 -0
  125. package/dist/core/init.d.ts +60 -0
  126. package/dist/core/init.js +861 -0
  127. package/dist/core/list.d.ts +9 -0
  128. package/dist/core/list.js +171 -0
  129. package/dist/core/parsers/change-parser.d.ts +13 -0
  130. package/dist/core/parsers/change-parser.js +193 -0
  131. package/dist/core/parsers/markdown-parser.d.ts +22 -0
  132. package/dist/core/parsers/markdown-parser.js +187 -0
  133. package/dist/core/parsers/requirement-blocks.d.ts +37 -0
  134. package/dist/core/parsers/requirement-blocks.js +201 -0
  135. package/dist/core/project-config.d.ts +34 -0
  136. package/dist/core/project-config.js +79 -0
  137. package/dist/core/schemas/base.schema.d.ts +13 -0
  138. package/dist/core/schemas/base.schema.js +13 -0
  139. package/dist/core/schemas/change.schema.d.ts +73 -0
  140. package/dist/core/schemas/change.schema.js +31 -0
  141. package/dist/core/schemas/index.d.ts +4 -0
  142. package/dist/core/schemas/index.js +4 -0
  143. package/dist/core/schemas/spec.schema.d.ts +18 -0
  144. package/dist/core/schemas/spec.schema.js +15 -0
  145. package/dist/core/skill-discovery.d.ts +24 -0
  146. package/dist/core/skill-discovery.js +153 -0
  147. package/dist/core/specs-apply.d.ts +73 -0
  148. package/dist/core/specs-apply.js +384 -0
  149. package/dist/core/styles/palette.d.ts +7 -0
  150. package/dist/core/styles/palette.js +8 -0
  151. package/dist/core/templates/agents-root-stub.d.ts +2 -0
  152. package/dist/core/templates/agents-root-stub.js +17 -0
  153. package/dist/core/templates/agents-template.d.ts +2 -0
  154. package/dist/core/templates/agents-template.js +706 -0
  155. package/dist/core/templates/claude-template.d.ts +2 -0
  156. package/dist/core/templates/claude-template.js +2 -0
  157. package/dist/core/templates/cline-template.d.ts +2 -0
  158. package/dist/core/templates/cline-template.js +2 -0
  159. package/dist/core/templates/costrict-template.d.ts +2 -0
  160. package/dist/core/templates/costrict-template.js +2 -0
  161. package/dist/core/templates/index.d.ts +17 -0
  162. package/dist/core/templates/index.js +37 -0
  163. package/dist/core/templates/project-template.d.ts +8 -0
  164. package/dist/core/templates/project-template.js +32 -0
  165. package/dist/core/templates/skill-templates.d.ts +103 -0
  166. package/dist/core/templates/skill-templates.js +2131 -0
  167. package/dist/core/templates/slash-command-templates.d.ts +4 -0
  168. package/dist/core/templates/slash-command-templates.js +81 -0
  169. package/dist/core/update.d.ts +4 -0
  170. package/dist/core/update.js +88 -0
  171. package/dist/core/validation/constants.d.ts +34 -0
  172. package/dist/core/validation/constants.js +40 -0
  173. package/dist/core/validation/types.d.ts +18 -0
  174. package/dist/core/validation/types.js +2 -0
  175. package/dist/core/validation/validator.d.ts +33 -0
  176. package/dist/core/validation/validator.js +409 -0
  177. package/dist/core/view.d.ts +8 -0
  178. package/dist/core/view.js +168 -0
  179. package/dist/index.d.ts +3 -0
  180. package/dist/index.js +3 -0
  181. package/dist/utils/change-metadata.d.ts +47 -0
  182. package/dist/utils/change-metadata.js +130 -0
  183. package/dist/utils/change-utils.d.ts +51 -0
  184. package/dist/utils/change-utils.js +100 -0
  185. package/dist/utils/file-system.d.ts +19 -0
  186. package/dist/utils/file-system.js +177 -0
  187. package/dist/utils/index.d.ts +4 -0
  188. package/dist/utils/index.js +5 -0
  189. package/dist/utils/interactive.d.ts +18 -0
  190. package/dist/utils/interactive.js +21 -0
  191. package/dist/utils/item-discovery.d.ts +4 -0
  192. package/dist/utils/item-discovery.js +72 -0
  193. package/dist/utils/match.d.ts +3 -0
  194. package/dist/utils/match.js +22 -0
  195. package/dist/utils/shell-detection.d.ts +20 -0
  196. package/dist/utils/shell-detection.js +41 -0
  197. package/dist/utils/task-progress.d.ts +8 -0
  198. package/dist/utils/task-progress.js +36 -0
  199. package/package.json +81 -0
  200. package/schemas/spec-driven/schema.yaml +205 -0
  201. package/schemas/spec-driven/templates/design.md +19 -0
  202. package/schemas/spec-driven/templates/proposal.md +43 -0
  203. package/schemas/spec-driven/templates/spec.md +8 -0
  204. package/schemas/spec-driven/templates/tasks.md +25 -0
  205. package/schemas/tdd/schema.yaml +213 -0
  206. package/schemas/tdd/templates/docs.md +0 -0
  207. package/schemas/tdd/templates/implementation.md +11 -0
  208. package/schemas/tdd/templates/spec.md +11 -0
  209. package/schemas/tdd/templates/test.md +11 -0
  210. package/scripts/postinstall.js +147 -0
@@ -0,0 +1,54 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import fg from 'fast-glob';
4
+ import { FileSystemUtils } from '../../utils/file-system.js';
5
+ /**
6
+ * Detects which artifacts are completed by checking file existence in the change directory.
7
+ * Returns a Set of completed artifact IDs.
8
+ *
9
+ * @param graph - The artifact graph to check
10
+ * @param changeDir - The change directory to scan for files
11
+ * @returns Set of artifact IDs whose generated files exist
12
+ */
13
+ export function detectCompleted(graph, changeDir) {
14
+ const completed = new Set();
15
+ // Handle missing change directory gracefully
16
+ if (!fs.existsSync(changeDir)) {
17
+ return completed;
18
+ }
19
+ for (const artifact of graph.getAllArtifacts()) {
20
+ if (isArtifactComplete(artifact.generates, changeDir)) {
21
+ completed.add(artifact.id);
22
+ }
23
+ }
24
+ return completed;
25
+ }
26
+ /**
27
+ * Checks if an artifact is complete by checking if its generated file(s) exist.
28
+ * Supports both simple paths and glob patterns.
29
+ */
30
+ function isArtifactComplete(generates, changeDir) {
31
+ const fullPattern = path.join(changeDir, generates);
32
+ // Check if it's a glob pattern
33
+ if (isGlobPattern(generates)) {
34
+ return hasGlobMatches(fullPattern);
35
+ }
36
+ // Simple file path - check if file exists
37
+ return fs.existsSync(fullPattern);
38
+ }
39
+ /**
40
+ * Checks if a path contains glob pattern characters.
41
+ */
42
+ function isGlobPattern(pattern) {
43
+ return pattern.includes('*') || pattern.includes('?') || pattern.includes('[');
44
+ }
45
+ /**
46
+ * Checks if a glob pattern has any matches.
47
+ * Normalizes Windows backslashes to forward slashes for cross-platform glob compatibility.
48
+ */
49
+ function hasGlobMatches(pattern) {
50
+ const normalizedPattern = FileSystemUtils.toPosixPath(pattern);
51
+ const matches = fg.sync(normalizedPattern, { onlyFiles: true });
52
+ return matches.length > 0;
53
+ }
54
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ export declare const ArtifactSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ generates: z.ZodString;
5
+ description: z.ZodString;
6
+ template: z.ZodString;
7
+ instruction: z.ZodOptional<z.ZodString>;
8
+ requires: z.ZodDefault<z.ZodArray<z.ZodString>>;
9
+ }, z.core.$strip>;
10
+ export declare const ApplyPhaseSchema: z.ZodObject<{
11
+ requires: z.ZodArray<z.ZodString>;
12
+ tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ instruction: z.ZodOptional<z.ZodString>;
14
+ }, z.core.$strip>;
15
+ export declare const SchemaYamlSchema: z.ZodObject<{
16
+ name: z.ZodString;
17
+ version: z.ZodNumber;
18
+ description: z.ZodOptional<z.ZodString>;
19
+ artifacts: z.ZodArray<z.ZodObject<{
20
+ id: z.ZodString;
21
+ generates: z.ZodString;
22
+ description: z.ZodString;
23
+ template: z.ZodString;
24
+ instruction: z.ZodOptional<z.ZodString>;
25
+ requires: z.ZodDefault<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strip>>;
27
+ apply: z.ZodOptional<z.ZodObject<{
28
+ requires: z.ZodArray<z.ZodString>;
29
+ tracks: z.ZodOptional<z.ZodNullable<z.ZodString>>;
30
+ instruction: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strip>>;
32
+ }, z.core.$strip>;
33
+ export type Artifact = z.infer<typeof ArtifactSchema>;
34
+ export type ApplyPhase = z.infer<typeof ApplyPhaseSchema>;
35
+ export type SchemaYaml = z.infer<typeof SchemaYamlSchema>;
36
+ export declare const ChangeMetadataSchema: z.ZodObject<{
37
+ schema: z.ZodString;
38
+ created: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>;
40
+ export type ChangeMetadata = z.infer<typeof ChangeMetadataSchema>;
41
+ export type CompletedSet = Set<string>;
42
+ export interface BlockedArtifacts {
43
+ [artifactId: string]: string[];
44
+ }
45
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ // Artifact definition schema
3
+ export const ArtifactSchema = z.object({
4
+ id: z.string().min(1, { error: 'Artifact ID is required' }),
5
+ generates: z.string().min(1, { error: 'generates field is required' }),
6
+ description: z.string(),
7
+ template: z.string().min(1, { error: 'template field is required' }),
8
+ instruction: z.string().optional(),
9
+ requires: z.array(z.string()).default([]),
10
+ });
11
+ // Apply phase configuration for schema-aware apply instructions
12
+ export const ApplyPhaseSchema = z.object({
13
+ // Artifact IDs that must exist before apply is available
14
+ requires: z.array(z.string()).min(1, { error: 'At least one required artifact' }),
15
+ // Path to file with checkboxes for progress (relative to change dir), or null if no tracking
16
+ tracks: z.string().nullable().optional(),
17
+ // Custom guidance for the apply phase
18
+ instruction: z.string().optional(),
19
+ });
20
+ // Full schema YAML structure
21
+ export const SchemaYamlSchema = z.object({
22
+ name: z.string().min(1, { error: 'Schema name is required' }),
23
+ version: z.number().int().positive({ error: 'Version must be a positive integer' }),
24
+ description: z.string().optional(),
25
+ artifacts: z.array(ArtifactSchema).min(1, { error: 'At least one artifact required' }),
26
+ // Optional apply phase configuration (for schema-aware apply instructions)
27
+ apply: ApplyPhaseSchema.optional(),
28
+ });
29
+ // Per-change metadata schema
30
+ // Note: schema field is validated at parse time against available schemas
31
+ // using a lazy import to avoid circular dependencies
32
+ export const ChangeMetadataSchema = z.object({
33
+ // Required: which workflow schema this change uses
34
+ schema: z.string().min(1, { message: 'schema is required' }),
35
+ // Optional: creation timestamp (ISO date string)
36
+ created: z
37
+ .string()
38
+ .regex(/^\d{4}-\d{2}-\d{2}$/, {
39
+ message: 'created must be YYYY-MM-DD format',
40
+ })
41
+ .optional(),
42
+ });
43
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,7 @@
1
+ import { CommandDefinition } from './types.js';
2
+ /**
3
+ * Registry of all ZhuanSpec CLI commands with their flags and metadata.
4
+ * This registry is used to generate shell completion scripts.
5
+ */
6
+ export declare const COMMAND_REGISTRY: CommandDefinition[];
7
+ //# sourceMappingURL=command-registry.d.ts.map
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Common flags used across multiple commands
3
+ */
4
+ const COMMON_FLAGS = {
5
+ json: {
6
+ name: 'json',
7
+ description: 'Output as JSON',
8
+ },
9
+ jsonValidation: {
10
+ name: 'json',
11
+ description: 'Output validation results as JSON',
12
+ },
13
+ strict: {
14
+ name: 'strict',
15
+ description: 'Enable strict validation mode',
16
+ },
17
+ noInteractive: {
18
+ name: 'no-interactive',
19
+ description: 'Disable interactive prompts',
20
+ },
21
+ type: {
22
+ name: 'type',
23
+ description: 'Specify item type when ambiguous',
24
+ takesValue: true,
25
+ values: ['change', 'spec'],
26
+ },
27
+ };
28
+ /**
29
+ * Registry of all ZhuanSpec CLI commands with their flags and metadata.
30
+ * This registry is used to generate shell completion scripts.
31
+ */
32
+ export const COMMAND_REGISTRY = [
33
+ {
34
+ name: 'init',
35
+ description: 'Initialize ZhuanSpec in your project',
36
+ acceptsPositional: true,
37
+ positionalType: 'path',
38
+ flags: [
39
+ {
40
+ name: 'tools',
41
+ description: 'Configure AI tools non-interactively (e.g., "all", "none", or comma-separated tool IDs)',
42
+ takesValue: true,
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ name: 'update',
48
+ description: 'Update ZhuanSpec instruction files',
49
+ acceptsPositional: true,
50
+ positionalType: 'path',
51
+ flags: [],
52
+ },
53
+ {
54
+ name: 'list',
55
+ description: 'List items (changes by default, or specs with --specs)',
56
+ flags: [
57
+ {
58
+ name: 'specs',
59
+ description: 'List specs instead of changes',
60
+ },
61
+ {
62
+ name: 'changes',
63
+ description: 'List changes explicitly (default)',
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ name: 'view',
69
+ description: 'Display an interactive dashboard of specs and changes',
70
+ flags: [],
71
+ },
72
+ {
73
+ name: 'validate',
74
+ description: 'Validate changes and specs',
75
+ acceptsPositional: true,
76
+ positionalType: 'change-or-spec-id',
77
+ flags: [
78
+ {
79
+ name: 'all',
80
+ description: 'Validate all changes and specs',
81
+ },
82
+ {
83
+ name: 'changes',
84
+ description: 'Validate all changes',
85
+ },
86
+ {
87
+ name: 'specs',
88
+ description: 'Validate all specs',
89
+ },
90
+ COMMON_FLAGS.type,
91
+ COMMON_FLAGS.strict,
92
+ COMMON_FLAGS.jsonValidation,
93
+ {
94
+ name: 'concurrency',
95
+ description: 'Max concurrent validations (defaults to env OPENSPEC_CONCURRENCY or 6)',
96
+ takesValue: true,
97
+ },
98
+ COMMON_FLAGS.noInteractive,
99
+ ],
100
+ },
101
+ {
102
+ name: 'show',
103
+ description: 'Show a change or spec',
104
+ acceptsPositional: true,
105
+ positionalType: 'change-or-spec-id',
106
+ flags: [
107
+ COMMON_FLAGS.json,
108
+ COMMON_FLAGS.type,
109
+ COMMON_FLAGS.noInteractive,
110
+ {
111
+ name: 'deltas-only',
112
+ description: 'Show only deltas (JSON only, change-specific)',
113
+ },
114
+ {
115
+ name: 'requirements-only',
116
+ description: 'Alias for --deltas-only (deprecated, change-specific)',
117
+ },
118
+ {
119
+ name: 'requirements',
120
+ description: 'Show only requirements, exclude scenarios (JSON only, spec-specific)',
121
+ },
122
+ {
123
+ name: 'no-scenarios',
124
+ description: 'Exclude scenario content (JSON only, spec-specific)',
125
+ },
126
+ {
127
+ name: 'requirement',
128
+ short: 'r',
129
+ description: 'Show specific requirement by ID (JSON only, spec-specific)',
130
+ takesValue: true,
131
+ },
132
+ ],
133
+ },
134
+ {
135
+ name: 'archive',
136
+ description: 'Archive a completed change and update main specs',
137
+ acceptsPositional: true,
138
+ positionalType: 'change-id',
139
+ flags: [
140
+ {
141
+ name: 'yes',
142
+ short: 'y',
143
+ description: 'Skip confirmation prompts',
144
+ },
145
+ {
146
+ name: 'skip-specs',
147
+ description: 'Skip spec update operations',
148
+ },
149
+ {
150
+ name: 'no-validate',
151
+ description: 'Skip validation (not recommended)',
152
+ },
153
+ ],
154
+ },
155
+ {
156
+ name: 'change',
157
+ description: 'Manage ZhuanSpec change proposals (deprecated)',
158
+ flags: [],
159
+ subcommands: [
160
+ {
161
+ name: 'show',
162
+ description: 'Show a change proposal',
163
+ acceptsPositional: true,
164
+ positionalType: 'change-id',
165
+ flags: [
166
+ COMMON_FLAGS.json,
167
+ {
168
+ name: 'deltas-only',
169
+ description: 'Show only deltas (JSON only)',
170
+ },
171
+ {
172
+ name: 'requirements-only',
173
+ description: 'Alias for --deltas-only (deprecated)',
174
+ },
175
+ COMMON_FLAGS.noInteractive,
176
+ ],
177
+ },
178
+ {
179
+ name: 'list',
180
+ description: 'List all active changes (deprecated)',
181
+ flags: [
182
+ COMMON_FLAGS.json,
183
+ {
184
+ name: 'long',
185
+ description: 'Show id and title with counts',
186
+ },
187
+ ],
188
+ },
189
+ {
190
+ name: 'validate',
191
+ description: 'Validate a change proposal',
192
+ acceptsPositional: true,
193
+ positionalType: 'change-id',
194
+ flags: [
195
+ COMMON_FLAGS.strict,
196
+ COMMON_FLAGS.jsonValidation,
197
+ COMMON_FLAGS.noInteractive,
198
+ ],
199
+ },
200
+ ],
201
+ },
202
+ {
203
+ name: 'spec',
204
+ description: 'Manage ZhuanSpec specifications',
205
+ flags: [],
206
+ subcommands: [
207
+ {
208
+ name: 'show',
209
+ description: 'Show a specification',
210
+ acceptsPositional: true,
211
+ positionalType: 'spec-id',
212
+ flags: [
213
+ COMMON_FLAGS.json,
214
+ {
215
+ name: 'requirements',
216
+ description: 'Show only requirements, exclude scenarios (JSON only)',
217
+ },
218
+ {
219
+ name: 'no-scenarios',
220
+ description: 'Exclude scenario content (JSON only)',
221
+ },
222
+ {
223
+ name: 'requirement',
224
+ short: 'r',
225
+ description: 'Show specific requirement by ID (JSON only)',
226
+ takesValue: true,
227
+ },
228
+ COMMON_FLAGS.noInteractive,
229
+ ],
230
+ },
231
+ {
232
+ name: 'list',
233
+ description: 'List all specifications',
234
+ flags: [
235
+ COMMON_FLAGS.json,
236
+ {
237
+ name: 'long',
238
+ description: 'Show id and title with counts',
239
+ },
240
+ ],
241
+ },
242
+ {
243
+ name: 'validate',
244
+ description: 'Validate a specification',
245
+ acceptsPositional: true,
246
+ positionalType: 'spec-id',
247
+ flags: [
248
+ COMMON_FLAGS.strict,
249
+ COMMON_FLAGS.jsonValidation,
250
+ COMMON_FLAGS.noInteractive,
251
+ ],
252
+ },
253
+ ],
254
+ },
255
+ {
256
+ name: 'completion',
257
+ description: 'Manage shell completions for ZhuanSpec CLI',
258
+ flags: [],
259
+ subcommands: [
260
+ {
261
+ name: 'generate',
262
+ description: 'Generate completion script for a shell (outputs to stdout)',
263
+ acceptsPositional: true,
264
+ positionalType: 'shell',
265
+ flags: [],
266
+ },
267
+ {
268
+ name: 'install',
269
+ description: 'Install completion script for a shell',
270
+ acceptsPositional: true,
271
+ positionalType: 'shell',
272
+ flags: [
273
+ {
274
+ name: 'verbose',
275
+ description: 'Show detailed installation output',
276
+ },
277
+ ],
278
+ },
279
+ {
280
+ name: 'uninstall',
281
+ description: 'Uninstall completion script for a shell',
282
+ acceptsPositional: true,
283
+ positionalType: 'shell',
284
+ flags: [],
285
+ },
286
+ ],
287
+ },
288
+ {
289
+ name: 'config',
290
+ description: 'View and modify global ZhuanSpec configuration',
291
+ flags: [
292
+ {
293
+ name: 'scope',
294
+ description: 'Config scope (only "global" supported currently)',
295
+ takesValue: true,
296
+ values: ['global'],
297
+ },
298
+ ],
299
+ subcommands: [
300
+ {
301
+ name: 'path',
302
+ description: 'Show config file location',
303
+ flags: [],
304
+ },
305
+ {
306
+ name: 'list',
307
+ description: 'Show all current settings',
308
+ flags: [
309
+ COMMON_FLAGS.json,
310
+ ],
311
+ },
312
+ {
313
+ name: 'get',
314
+ description: 'Get a specific value (raw, scriptable)',
315
+ acceptsPositional: true,
316
+ flags: [],
317
+ },
318
+ {
319
+ name: 'set',
320
+ description: 'Set a value (auto-coerce types)',
321
+ acceptsPositional: true,
322
+ flags: [
323
+ {
324
+ name: 'string',
325
+ description: 'Force value to be stored as string',
326
+ },
327
+ {
328
+ name: 'allow-unknown',
329
+ description: 'Allow setting unknown keys',
330
+ },
331
+ ],
332
+ },
333
+ {
334
+ name: 'unset',
335
+ description: 'Remove a key (revert to default)',
336
+ acceptsPositional: true,
337
+ flags: [],
338
+ },
339
+ {
340
+ name: 'reset',
341
+ description: 'Reset configuration to defaults',
342
+ flags: [
343
+ {
344
+ name: 'all',
345
+ description: 'Reset all configuration (required)',
346
+ },
347
+ {
348
+ name: 'yes',
349
+ short: 'y',
350
+ description: 'Skip confirmation prompts',
351
+ },
352
+ ],
353
+ },
354
+ {
355
+ name: 'edit',
356
+ description: 'Open config in $EDITOR',
357
+ flags: [],
358
+ },
359
+ ],
360
+ },
361
+ ];
362
+ //# sourceMappingURL=command-registry.js.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Provides dynamic completion suggestions for ZhuanSpec items (changes and specs).
3
+ * Implements a 2-second cache to avoid excessive file system operations during
4
+ * tab completion.
5
+ */
6
+ export declare class CompletionProvider {
7
+ private readonly cacheTTLMs;
8
+ private readonly projectRoot;
9
+ private readonly cacheTTL;
10
+ private changeCache;
11
+ private specCache;
12
+ /**
13
+ * Creates a new completion provider
14
+ *
15
+ * @param cacheTTLMs - Cache time-to-live in milliseconds (default: 2000ms)
16
+ * @param projectRoot - Project root directory (default: process.cwd())
17
+ */
18
+ constructor(cacheTTLMs?: number, projectRoot?: string);
19
+ /**
20
+ * Get all active change IDs for completion
21
+ *
22
+ * @returns Array of change IDs
23
+ */
24
+ getChangeIds(): Promise<string[]>;
25
+ /**
26
+ * Get all spec IDs for completion
27
+ *
28
+ * @returns Array of spec IDs
29
+ */
30
+ getSpecIds(): Promise<string[]>;
31
+ /**
32
+ * Get both change and spec IDs for completion
33
+ *
34
+ * @returns Object with changeIds and specIds arrays
35
+ */
36
+ getAllIds(): Promise<{
37
+ changeIds: string[];
38
+ specIds: string[];
39
+ }>;
40
+ /**
41
+ * Clear all cached data
42
+ */
43
+ clearCache(): void;
44
+ /**
45
+ * Get cache statistics for debugging
46
+ *
47
+ * @returns Cache status information
48
+ */
49
+ getCacheStats(): {
50
+ changeCache: {
51
+ valid: boolean;
52
+ age?: number;
53
+ };
54
+ specCache: {
55
+ valid: boolean;
56
+ age?: number;
57
+ };
58
+ };
59
+ }
60
+ //# sourceMappingURL=completion-provider.d.ts.map
@@ -0,0 +1,102 @@
1
+ import { getActiveChangeIds, getSpecIds } from '../../utils/item-discovery.js';
2
+ /**
3
+ * Provides dynamic completion suggestions for ZhuanSpec items (changes and specs).
4
+ * Implements a 2-second cache to avoid excessive file system operations during
5
+ * tab completion.
6
+ */
7
+ export class CompletionProvider {
8
+ cacheTTLMs;
9
+ projectRoot;
10
+ cacheTTL;
11
+ changeCache = null;
12
+ specCache = null;
13
+ /**
14
+ * Creates a new completion provider
15
+ *
16
+ * @param cacheTTLMs - Cache time-to-live in milliseconds (default: 2000ms)
17
+ * @param projectRoot - Project root directory (default: process.cwd())
18
+ */
19
+ constructor(cacheTTLMs = 2000, projectRoot = process.cwd()) {
20
+ this.cacheTTLMs = cacheTTLMs;
21
+ this.projectRoot = projectRoot;
22
+ this.cacheTTL = cacheTTLMs;
23
+ }
24
+ /**
25
+ * Get all active change IDs for completion
26
+ *
27
+ * @returns Array of change IDs
28
+ */
29
+ async getChangeIds() {
30
+ const now = Date.now();
31
+ // Check if cache is valid
32
+ if (this.changeCache && now - this.changeCache.timestamp < this.cacheTTL) {
33
+ return this.changeCache.data;
34
+ }
35
+ // Fetch fresh data
36
+ const changeIds = await getActiveChangeIds(this.projectRoot);
37
+ // Update cache
38
+ this.changeCache = {
39
+ data: changeIds,
40
+ timestamp: now,
41
+ };
42
+ return changeIds;
43
+ }
44
+ /**
45
+ * Get all spec IDs for completion
46
+ *
47
+ * @returns Array of spec IDs
48
+ */
49
+ async getSpecIds() {
50
+ const now = Date.now();
51
+ // Check if cache is valid
52
+ if (this.specCache && now - this.specCache.timestamp < this.cacheTTL) {
53
+ return this.specCache.data;
54
+ }
55
+ // Fetch fresh data
56
+ const specIds = await getSpecIds(this.projectRoot);
57
+ // Update cache
58
+ this.specCache = {
59
+ data: specIds,
60
+ timestamp: now,
61
+ };
62
+ return specIds;
63
+ }
64
+ /**
65
+ * Get both change and spec IDs for completion
66
+ *
67
+ * @returns Object with changeIds and specIds arrays
68
+ */
69
+ async getAllIds() {
70
+ const [changeIds, specIds] = await Promise.all([
71
+ this.getChangeIds(),
72
+ this.getSpecIds(),
73
+ ]);
74
+ return { changeIds, specIds };
75
+ }
76
+ /**
77
+ * Clear all cached data
78
+ */
79
+ clearCache() {
80
+ this.changeCache = null;
81
+ this.specCache = null;
82
+ }
83
+ /**
84
+ * Get cache statistics for debugging
85
+ *
86
+ * @returns Cache status information
87
+ */
88
+ getCacheStats() {
89
+ const now = Date.now();
90
+ return {
91
+ changeCache: {
92
+ valid: this.changeCache !== null && now - this.changeCache.timestamp < this.cacheTTL,
93
+ age: this.changeCache ? now - this.changeCache.timestamp : undefined,
94
+ },
95
+ specCache: {
96
+ valid: this.specCache !== null && now - this.specCache.timestamp < this.cacheTTL,
97
+ age: this.specCache ? now - this.specCache.timestamp : undefined,
98
+ },
99
+ };
100
+ }
101
+ }
102
+ //# sourceMappingURL=completion-provider.js.map