@dedesfr/prompter 0.9.0 → 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 (216) hide show
  1. package/CHANGELOG.md +21 -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.map +1 -1
  6. package/dist/commands/init.js +32 -9
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/login.d.ts +4 -0
  9. package/dist/commands/login.d.ts.map +1 -0
  10. package/dist/commands/login.js +56 -0
  11. package/dist/commands/login.js.map +1 -0
  12. package/dist/commands/logout.d.ts +4 -0
  13. package/dist/commands/logout.d.ts.map +1 -0
  14. package/dist/commands/logout.js +14 -0
  15. package/dist/commands/logout.js.map +1 -0
  16. package/dist/commands/update.d.ts.map +1 -1
  17. package/dist/commands/update.js +18 -5
  18. package/dist/commands/update.js.map +1 -1
  19. package/dist/commands/whoami.d.ts +4 -0
  20. package/dist/commands/whoami.d.ts.map +1 -0
  21. package/dist/commands/whoami.js +42 -0
  22. package/dist/commands/whoami.js.map +1 -0
  23. package/dist/core/auth-store.d.ts +10 -0
  24. package/dist/core/auth-store.d.ts.map +1 -0
  25. package/dist/core/auth-store.js +39 -0
  26. package/dist/core/auth-store.js.map +1 -0
  27. package/dist/core/registry.d.ts +18 -0
  28. package/dist/core/registry.d.ts.map +1 -0
  29. package/dist/core/registry.js +94 -0
  30. package/dist/core/registry.js.map +1 -0
  31. package/package.json +7 -1
  32. package/AGENTS.md +0 -123
  33. package/CLAUDE.md +0 -17
  34. package/build.js +0 -20
  35. package/convex-setup.md +0 -403
  36. package/prompt/ai-humanizer.md +0 -45
  37. package/prompt/api-contract-generator.md +0 -234
  38. package/prompt/apply.md +0 -17
  39. package/prompt/archive.md +0 -21
  40. package/prompt/design-system.md +0 -210
  41. package/prompt/document-explainer.md +0 -149
  42. package/prompt/epic-generator.md +0 -198
  43. package/prompt/epic-single.md +0 -47
  44. package/prompt/erd-generator.md +0 -130
  45. package/prompt/fsd-generator.md +0 -157
  46. package/prompt/prd-agent-generator.md +0 -147
  47. package/prompt/prd-generator.md +0 -195
  48. package/prompt/product-brief.md +0 -289
  49. package/prompt/proposal.md +0 -22
  50. package/prompt/qa-test-scenario.md +0 -133
  51. package/prompt/skill-creator.md +0 -350
  52. package/prompt/story-generator.md +0 -278
  53. package/prompt/story-single.md +0 -70
  54. package/prompt/tdd-generator.md +0 -294
  55. package/prompt/tdd-lite-generator.md +0 -224
  56. package/prompt/wireframe-generator.md +0 -219
  57. package/skills/ai-context-generator/SKILL.md +0 -54
  58. package/skills/ai-context-generator/references/AGENTS.template.md +0 -83
  59. package/skills/ai-context-generator/references/CLAUDE.template.md +0 -39
  60. package/skills/ai-context-generator/references/behavioral-guidelines.md +0 -71
  61. package/skills/ai-context-generator/references/discovery-checklist.md +0 -40
  62. package/skills/ai-context-generator/references/examples/AGENTS.good.md +0 -103
  63. package/skills/ai-context-generator/references/extraction-checklist.md +0 -23
  64. package/skills/ai-context-generator/references/overlays/laravel.md +0 -44
  65. package/skills/ai-humanizer/SKILL.md +0 -50
  66. package/skills/api-contract-generator/SKILL.md +0 -243
  67. package/skills/apply/SKILL.md +0 -23
  68. package/skills/archive/SKILL.md +0 -27
  69. package/skills/cerebro/SKILL.md +0 -187
  70. package/skills/cerebro/references/agents.md +0 -213
  71. package/skills/code-review/SKILL.md +0 -373
  72. package/skills/code-review/assets/report-template-agent.md +0 -212
  73. package/skills/code-review/assets/report-template-compact.md +0 -81
  74. package/skills/code-review/assets/report-template-full.md +0 -264
  75. package/skills/code-review/assets/report-template-human.md +0 -168
  76. package/skills/code-review/references/universal-patterns.md +0 -495
  77. package/skills/design-md/README.md +0 -34
  78. package/skills/design-md/SKILL.md +0 -172
  79. package/skills/design-md/examples/DESIGN.md +0 -154
  80. package/skills/design-system/SKILL.md +0 -216
  81. package/skills/design-system-generator/SKILL.md +0 -324
  82. package/skills/design-system-generator/assets/design-system-template.md +0 -348
  83. package/skills/design-system-generator/references/extraction-patterns.md +0 -321
  84. package/skills/doc-builder/SKILL.md +0 -115
  85. package/skills/doc-builder/references/ui-patterns.md +0 -394
  86. package/skills/document-explainer/SKILL.md +0 -155
  87. package/skills/document-translator/SKILL.md +0 -58
  88. package/skills/enhance/SKILL.md +0 -47
  89. package/skills/enhance-prompt/README.md +0 -34
  90. package/skills/enhance-prompt/SKILL.md +0 -204
  91. package/skills/enhance-prompt/references/KEYWORDS.md +0 -114
  92. package/skills/epic-generator/SKILL.md +0 -204
  93. package/skills/epic-single/SKILL.md +0 -63
  94. package/skills/erd-generator/SKILL.md +0 -138
  95. package/skills/feature-planner/SKILL.md +0 -305
  96. package/skills/feature-planner/assets/implementation-plan-template.md +0 -85
  97. package/skills/frontend-design/LICENSE.txt +0 -177
  98. package/skills/frontend-design/SKILL.md +0 -42
  99. package/skills/fsd-generator/SKILL.md +0 -163
  100. package/skills/gamma-builder/SKILL.md +0 -134
  101. package/skills/laravel-code-review/SKILL.md +0 -383
  102. package/skills/laravel-code-review/assets/report-template-agent.md +0 -195
  103. package/skills/laravel-code-review/assets/report-template-compact.md +0 -79
  104. package/skills/laravel-code-review/assets/report-template-full.md +0 -253
  105. package/skills/laravel-code-review/assets/report-template-human.md +0 -159
  106. package/skills/laravel-code-review/references/laravel-patterns.md +0 -571
  107. package/skills/laravel-code-review/references/php84-features.md +0 -442
  108. package/skills/mcp-builder/LICENSE.txt +0 -202
  109. package/skills/mcp-builder/SKILL.md +0 -236
  110. package/skills/mcp-builder/reference/evaluation.md +0 -602
  111. package/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  112. package/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  113. package/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  114. package/skills/mcp-builder/scripts/connections.py +0 -151
  115. package/skills/mcp-builder/scripts/evaluation.py +0 -373
  116. package/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  117. package/skills/mcp-builder/scripts/requirements.txt +0 -2
  118. package/skills/meeting-notes/SKILL.md +0 -159
  119. package/skills/meeting-notes/evals/evals.json +0 -23
  120. package/skills/prd-agent-generator/SKILL.md +0 -132
  121. package/skills/prd-generator/SKILL.md +0 -211
  122. package/skills/product-brief/SKILL.md +0 -141
  123. package/skills/project-orchestrator/SKILL.md +0 -487
  124. package/skills/project-orchestrator/assets/caddy-vps-setup.md +0 -180
  125. package/skills/project-orchestrator/assets/plan-summary-template.md +0 -159
  126. package/skills/prompter-specs/SKILL.md +0 -115
  127. package/skills/prompter-workflow/SKILL.md +0 -166
  128. package/skills/prompter-workflow/evals/evals.json +0 -89
  129. package/skills/proposal/SKILL.md +0 -28
  130. package/skills/qa-test-scenario/SKILL.md +0 -149
  131. package/skills/skill-creator/SKILL.md +0 -173
  132. package/skills/sph-generator/SKILL.md +0 -488
  133. package/skills/story-generator/SKILL.md +0 -285
  134. package/skills/story-single/SKILL.md +0 -86
  135. package/skills/tdd-generator/SKILL.md +0 -300
  136. package/skills/tdd-lite-generator/SKILL.md +0 -230
  137. package/skills/ui-ux-pro/SKILL.md +0 -199
  138. package/skills/ui-ux-pro/assets/design-spec-template.md +0 -173
  139. package/skills/ui-ux-pro/references/component-patterns.md +0 -255
  140. package/skills/ui-ux-pro/references/design-principles.md +0 -167
  141. package/skills/wireframe-generator/SKILL.md +0 -227
  142. package/src/cli/index.ts +0 -223
  143. package/src/commands/archive.ts +0 -302
  144. package/src/commands/change.ts +0 -292
  145. package/src/commands/config.ts +0 -233
  146. package/src/commands/guide.ts +0 -50
  147. package/src/commands/init.ts +0 -597
  148. package/src/commands/list.ts +0 -194
  149. package/src/commands/show.ts +0 -138
  150. package/src/commands/spec.ts +0 -251
  151. package/src/commands/update.ts +0 -129
  152. package/src/commands/upgrade.ts +0 -30
  153. package/src/commands/validate.ts +0 -326
  154. package/src/core/artifact-graph/graph.ts +0 -167
  155. package/src/core/artifact-graph/index.ts +0 -44
  156. package/src/core/artifact-graph/instruction-loader.ts +0 -302
  157. package/src/core/artifact-graph/resolver.ts +0 -226
  158. package/src/core/artifact-graph/schema.ts +0 -124
  159. package/src/core/artifact-graph/state.ts +0 -64
  160. package/src/core/artifact-graph/types.ts +0 -65
  161. package/src/core/completions/command-registry.ts +0 -382
  162. package/src/core/completions/completion-provider.ts +0 -128
  163. package/src/core/completions/generators/bash-generator.ts +0 -191
  164. package/src/core/completions/generators/fish-generator.ts +0 -188
  165. package/src/core/completions/generators/powershell-generator.ts +0 -223
  166. package/src/core/completions/generators/zsh-generator.ts +0 -281
  167. package/src/core/completions/templates/bash-templates.ts +0 -24
  168. package/src/core/completions/templates/fish-templates.ts +0 -40
  169. package/src/core/completions/templates/powershell-templates.ts +0 -25
  170. package/src/core/completions/templates/zsh-templates.ts +0 -36
  171. package/src/core/completions/types.ts +0 -90
  172. package/src/core/config-schema.ts +0 -230
  173. package/src/core/config.ts +0 -181
  174. package/src/core/configurators/slash/antigravity.ts +0 -10
  175. package/src/core/configurators/slash/base.ts +0 -109
  176. package/src/core/configurators/slash/claude.ts +0 -10
  177. package/src/core/configurators/slash/codex.ts +0 -10
  178. package/src/core/configurators/slash/droid.ts +0 -10
  179. package/src/core/configurators/slash/forge.ts +0 -10
  180. package/src/core/configurators/slash/github-copilot.ts +0 -10
  181. package/src/core/configurators/slash/index.ts +0 -10
  182. package/src/core/configurators/slash/kilocode.ts +0 -10
  183. package/src/core/configurators/slash/opencode.ts +0 -10
  184. package/src/core/configurators/slash/registry.ts +0 -51
  185. package/src/core/converters/json-converter.ts +0 -62
  186. package/src/core/global-config.ts +0 -136
  187. package/src/core/parsers/change-parser.ts +0 -234
  188. package/src/core/parsers/markdown-parser.ts +0 -237
  189. package/src/core/parsers/requirement-blocks.ts +0 -234
  190. package/src/core/prompt-templates.ts +0 -3504
  191. package/src/core/schemas/base.schema.ts +0 -20
  192. package/src/core/schemas/change.schema.ts +0 -42
  193. package/src/core/schemas/index.ts +0 -20
  194. package/src/core/schemas/spec.schema.ts +0 -17
  195. package/src/core/skill-discovery.ts +0 -68
  196. package/src/core/specs-apply.ts +0 -483
  197. package/src/core/styles/palette.ts +0 -8
  198. package/src/core/templates/agents-template.ts +0 -459
  199. package/src/core/templates/claude-template.ts +0 -2
  200. package/src/core/templates/index.ts +0 -3
  201. package/src/core/templates/project-template.ts +0 -32
  202. package/src/core/validation/constants.ts +0 -48
  203. package/src/core/validation/types.ts +0 -19
  204. package/src/core/validation/validator.ts +0 -449
  205. package/src/core/view.ts +0 -219
  206. package/src/index.ts +0 -1
  207. package/src/utils/change-metadata.ts +0 -171
  208. package/src/utils/change-utils.ts +0 -131
  209. package/src/utils/file-system.ts +0 -252
  210. package/src/utils/index.ts +0 -12
  211. package/src/utils/interactive.ts +0 -29
  212. package/src/utils/item-discovery.ts +0 -66
  213. package/src/utils/match.ts +0 -26
  214. package/src/utils/shell-detection.ts +0 -62
  215. package/src/utils/task-progress.ts +0 -43
  216. package/tsconfig.json +0 -28
@@ -1,191 +0,0 @@
1
- import { CompletionGenerator, CommandDefinition, FlagDefinition } from '../types.js';
2
- import { BASH_DYNAMIC_HELPERS } from '../templates/bash-templates.js';
3
-
4
- /**
5
- * Generates Bash completion scripts for the Prompter CLI.
6
- * Follows Bash completion conventions using complete builtin and COMPREPLY array.
7
- */
8
- export class BashGenerator implements CompletionGenerator {
9
- readonly shell = 'bash' as const;
10
-
11
- /**
12
- * Generate a Bash completion script
13
- *
14
- * @param commands - Command definitions to generate completions for
15
- * @returns Bash completion script as a string
16
- */
17
- generate(commands: CommandDefinition[]): string {
18
- // Build command list for top-level completions
19
- const commandList = commands.map(c => this.escapeCommandName(c.name)).join(' ');
20
-
21
- // Build command cases using push() for loop clarity
22
- const caseLines: string[] = [];
23
- for (const cmd of commands) {
24
- caseLines.push(` ${cmd.name})`);
25
- caseLines.push(...this.generateCommandCase(cmd, ' '));
26
- caseLines.push(' ;;');
27
- }
28
- const commandCases = caseLines.join('\n');
29
-
30
- // Dynamic completion helpers from template
31
- const helpers = BASH_DYNAMIC_HELPERS;
32
-
33
- // Assemble final script with template literal
34
- return `# Bash completion script for Prompter CLI
35
- # Auto-generated - do not edit manually
36
-
37
- _prompter_completion() {
38
- local cur prev words cword
39
-
40
- # Use _init_completion if available (from bash-completion package)
41
- # The -n : option prevents colons from being treated as word separators
42
- # (important for spec/change IDs that may contain colons)
43
- # Otherwise, fall back to manual initialization
44
- if declare -F _init_completion >/dev/null 2>&1; then
45
- _init_completion -n : || return
46
- else
47
- # Manual fallback when bash-completion is not installed
48
- COMPREPLY=()
49
- cur="\${COMP_WORDS[COMP_CWORD]}"
50
- prev="\${COMP_WORDS[COMP_CWORD-1]}"
51
- words=("\${COMP_WORDS[@]}")
52
- cword=$COMP_CWORD
53
- fi
54
-
55
- local cmd="\${words[1]}"
56
- local subcmd="\${words[2]}"
57
-
58
- # Top-level commands
59
- if [[ $cword -eq 1 ]]; then
60
- local commands="${commandList}"
61
- COMPREPLY=($(compgen -W "$commands" -- "$cur"))
62
- return 0
63
- fi
64
-
65
- # Command-specific completion
66
- case "$cmd" in
67
- ${commandCases}
68
- esac
69
-
70
- return 0
71
- }
72
-
73
- ${helpers}
74
- complete -F _prompter_completion prompter
75
- `;
76
- }
77
-
78
- /**
79
- * Generate completion case logic for a command
80
- */
81
- private generateCommandCase(cmd: CommandDefinition, indent: string): string[] {
82
- const lines: string[] = [];
83
-
84
- // Handle subcommands
85
- if (cmd.subcommands && cmd.subcommands.length > 0) {
86
- // First, check if user is typing a flag for the parent command
87
- if (cmd.flags.length > 0) {
88
- lines.push(`${indent}if [[ "$cur" == -* ]]; then`);
89
- const flags = cmd.flags.map(f => {
90
- const parts: string[] = [];
91
- if (f.short) parts.push(`-${f.short}`);
92
- parts.push(`--${f.name}`);
93
- return parts.join(' ');
94
- }).join(' ');
95
- lines.push(`${indent} local flags="${flags}"`);
96
- lines.push(`${indent} COMPREPLY=($(compgen -W "$flags" -- "$cur"))`);
97
- lines.push(`${indent} return 0`);
98
- lines.push(`${indent}fi`);
99
- lines.push('');
100
- }
101
-
102
- lines.push(`${indent}if [[ $cword -eq 2 ]]; then`);
103
- lines.push(`${indent} local subcommands="` + cmd.subcommands.map(s => this.escapeCommandName(s.name)).join(' ') + '"');
104
- lines.push(`${indent} COMPREPLY=($(compgen -W "$subcommands" -- "$cur"))`);
105
- lines.push(`${indent} return 0`);
106
- lines.push(`${indent}fi`);
107
- lines.push('');
108
- lines.push(`${indent}case "$subcmd" in`);
109
-
110
- for (const subcmd of cmd.subcommands) {
111
- lines.push(`${indent} ${subcmd.name})`);
112
- lines.push(...this.generateArgumentCompletion(subcmd, indent + ' '));
113
- lines.push(`${indent} ;;`);
114
- }
115
-
116
- lines.push(`${indent}esac`);
117
- } else {
118
- // No subcommands, just complete arguments
119
- lines.push(...this.generateArgumentCompletion(cmd, indent));
120
- }
121
-
122
- return lines;
123
- }
124
-
125
- /**
126
- * Generate argument completion (flags and positional arguments)
127
- */
128
- private generateArgumentCompletion(cmd: CommandDefinition, indent: string): string[] {
129
- const lines: string[] = [];
130
-
131
- // Check for flag completion
132
- if (cmd.flags.length > 0) {
133
- lines.push(`${indent}if [[ "$cur" == -* ]]; then`);
134
- const flags = cmd.flags.map(f => {
135
- const parts: string[] = [];
136
- if (f.short) parts.push(`-${f.short}`);
137
- parts.push(`--${f.name}`);
138
- return parts.join(' ');
139
- }).join(' ');
140
- lines.push(`${indent} local flags="${flags}"`);
141
- lines.push(`${indent} COMPREPLY=($(compgen -W "$flags" -- "$cur"))`);
142
- lines.push(`${indent} return 0`);
143
- lines.push(`${indent}fi`);
144
- lines.push('');
145
- }
146
-
147
- // Handle positional completions
148
- if (cmd.acceptsPositional) {
149
- lines.push(...this.generatePositionalCompletion(cmd.positionalType, indent));
150
- }
151
-
152
- return lines;
153
- }
154
-
155
- /**
156
- * Generate positional argument completion based on type
157
- */
158
- private generatePositionalCompletion(positionalType: string | undefined, indent: string): string[] {
159
- const lines: string[] = [];
160
-
161
- switch (positionalType) {
162
- case 'change-id':
163
- lines.push(`${indent}_prompter_complete_changes`);
164
- break;
165
- case 'spec-id':
166
- lines.push(`${indent}_prompter_complete_specs`);
167
- break;
168
- case 'change-or-spec-id':
169
- lines.push(`${indent}_prompter_complete_items`);
170
- break;
171
- case 'shell':
172
- lines.push(`${indent}local shells="zsh bash fish powershell"`);
173
- lines.push(`${indent}COMPREPLY=($(compgen -W "$shells" -- "$cur"))`);
174
- break;
175
- case 'path':
176
- lines.push(`${indent}COMPREPLY=($(compgen -f -- "$cur"))`);
177
- break;
178
- }
179
-
180
- return lines;
181
- }
182
-
183
-
184
- /**
185
- * Escape command/subcommand names for safe use in Bash scripts
186
- */
187
- private escapeCommandName(name: string): string {
188
- // Escape shell metacharacters to prevent command injection
189
- return name.replace(/["\$`\\]/g, '\\$&');
190
- }
191
- }
@@ -1,188 +0,0 @@
1
- import { CompletionGenerator, CommandDefinition, FlagDefinition } from '../types.js';
2
- import { FISH_STATIC_HELPERS, FISH_DYNAMIC_HELPERS } from '../templates/fish-templates.js';
3
-
4
- /**
5
- * Generates Fish completion scripts for the Prompter CLI.
6
- * Follows Fish completion conventions using the complete command.
7
- */
8
- export class FishGenerator implements CompletionGenerator {
9
- readonly shell = 'fish' as const;
10
-
11
- /**
12
- * Generate a Fish completion script
13
- *
14
- * @param commands - Command definitions to generate completions for
15
- * @returns Fish completion script as a string
16
- */
17
- generate(commands: CommandDefinition[]): string {
18
- // Build top-level commands using push() for loop clarity
19
- const topLevelLines: string[] = [];
20
- for (const cmd of commands) {
21
- topLevelLines.push(`# ${cmd.name} command`);
22
- topLevelLines.push(
23
- `complete -c prompter -n '__fish_prompter_no_subcommand' -a '${cmd.name}' -d '${this.escapeDescription(cmd.description)}'`
24
- );
25
- }
26
- const topLevelCommands = topLevelLines.join('\n');
27
-
28
- // Build command-specific completions using push() for loop clarity
29
- const commandCompletionLines: string[] = [];
30
- for (const cmd of commands) {
31
- commandCompletionLines.push(...this.generateCommandCompletions(cmd));
32
- commandCompletionLines.push('');
33
- }
34
- const commandCompletions = commandCompletionLines.join('\n');
35
-
36
- // Static helper functions from template
37
- const helperFunctions = FISH_STATIC_HELPERS;
38
-
39
- // Dynamic completion helpers from template
40
- const dynamicHelpers = FISH_DYNAMIC_HELPERS;
41
-
42
- // Assemble final script with template literal
43
- return `# Fish completion script for Prompter CLI
44
- # Auto-generated - do not edit manually
45
-
46
- ${helperFunctions}
47
- ${dynamicHelpers}
48
- ${topLevelCommands}
49
-
50
- ${commandCompletions}`;
51
- }
52
-
53
- /**
54
- * Generate completions for a specific command
55
- */
56
- private generateCommandCompletions(cmd: CommandDefinition): string[] {
57
- const lines: string[] = [];
58
-
59
- // If command has subcommands
60
- if (cmd.subcommands && cmd.subcommands.length > 0) {
61
- // Add subcommand completions
62
- for (const subcmd of cmd.subcommands) {
63
- lines.push(
64
- `complete -c prompter -n '__fish_prompter_using_subcommand ${cmd.name}; and not __fish_prompter_using_subcommand ${subcmd.name}' -a '${subcmd.name}' -d '${this.escapeDescription(subcmd.description)}'`
65
- );
66
- }
67
- lines.push('');
68
-
69
- // Add flags for parent command
70
- for (const flag of cmd.flags) {
71
- lines.push(...this.generateFlagCompletion(flag, `__fish_prompter_using_subcommand ${cmd.name}`));
72
- }
73
-
74
- // Add completions for each subcommand
75
- for (const subcmd of cmd.subcommands) {
76
- lines.push(`# ${cmd.name} ${subcmd.name} flags`);
77
- for (const flag of subcmd.flags) {
78
- lines.push(...this.generateFlagCompletion(flag, `__fish_prompter_using_subcommand ${cmd.name}; and __fish_prompter_using_subcommand ${subcmd.name}`));
79
- }
80
-
81
- // Add positional completions for subcommand
82
- if (subcmd.acceptsPositional) {
83
- lines.push(...this.generatePositionalCompletion(subcmd.positionalType, `__fish_prompter_using_subcommand ${cmd.name}; and __fish_prompter_using_subcommand ${subcmd.name}`));
84
- }
85
- }
86
- } else {
87
- // Command without subcommands
88
- lines.push(`# ${cmd.name} flags`);
89
- for (const flag of cmd.flags) {
90
- lines.push(...this.generateFlagCompletion(flag, `__fish_prompter_using_subcommand ${cmd.name}`));
91
- }
92
-
93
- // Add positional completions
94
- if (cmd.acceptsPositional) {
95
- lines.push(...this.generatePositionalCompletion(cmd.positionalType, `__fish_prompter_using_subcommand ${cmd.name}`));
96
- }
97
- }
98
-
99
- return lines;
100
- }
101
-
102
- /**
103
- * Generate flag completion
104
- */
105
- private generateFlagCompletion(flag: FlagDefinition, condition: string): string[] {
106
- const lines: string[] = [];
107
- const longFlag = `--${flag.name}`;
108
- const shortFlag = flag.short ? `-${flag.short}` : undefined;
109
-
110
- if (flag.takesValue && flag.values) {
111
- // Flag with enum values
112
- for (const value of flag.values) {
113
- if (shortFlag) {
114
- lines.push(
115
- `complete -c prompter -n '${condition}' -s ${flag.short} -l ${flag.name} -a '${value}' -d '${this.escapeDescription(flag.description)}'`
116
- );
117
- } else {
118
- lines.push(
119
- `complete -c prompter -n '${condition}' -l ${flag.name} -a '${value}' -d '${this.escapeDescription(flag.description)}'`
120
- );
121
- }
122
- }
123
- } else if (flag.takesValue) {
124
- // Flag that takes a value but no specific values defined
125
- if (shortFlag) {
126
- lines.push(
127
- `complete -c prompter -n '${condition}' -s ${flag.short} -l ${flag.name} -r -d '${this.escapeDescription(flag.description)}'`
128
- );
129
- } else {
130
- lines.push(
131
- `complete -c prompter -n '${condition}' -l ${flag.name} -r -d '${this.escapeDescription(flag.description)}'`
132
- );
133
- }
134
- } else {
135
- // Boolean flag
136
- if (shortFlag) {
137
- lines.push(
138
- `complete -c prompter -n '${condition}' -s ${flag.short} -l ${flag.name} -d '${this.escapeDescription(flag.description)}'`
139
- );
140
- } else {
141
- lines.push(
142
- `complete -c prompter -n '${condition}' -l ${flag.name} -d '${this.escapeDescription(flag.description)}'`
143
- );
144
- }
145
- }
146
-
147
- return lines;
148
- }
149
-
150
- /**
151
- * Generate positional argument completion
152
- */
153
- private generatePositionalCompletion(positionalType: string | undefined, condition: string): string[] {
154
- const lines: string[] = [];
155
-
156
- switch (positionalType) {
157
- case 'change-id':
158
- lines.push(`complete -c prompter -n '${condition}' -a '(__fish_prompter_changes)' -f`);
159
- break;
160
- case 'spec-id':
161
- lines.push(`complete -c prompter -n '${condition}' -a '(__fish_prompter_specs)' -f`);
162
- break;
163
- case 'change-or-spec-id':
164
- lines.push(`complete -c prompter -n '${condition}' -a '(__fish_prompter_items)' -f`);
165
- break;
166
- case 'shell':
167
- lines.push(`complete -c prompter -n '${condition}' -a 'zsh bash fish powershell' -f`);
168
- break;
169
- case 'path':
170
- // Fish automatically completes files, no need to specify
171
- break;
172
- }
173
-
174
- return lines;
175
- }
176
-
177
-
178
- /**
179
- * Escape description text for Fish
180
- */
181
- private escapeDescription(description: string): string {
182
- return description
183
- .replace(/\\/g, '\\\\') // Backslashes first
184
- .replace(/'/g, "\\'") // Single quotes
185
- .replace(/\$/g, '\\$') // Dollar signs (prevents $())
186
- .replace(/`/g, '\\`'); // Backticks
187
- }
188
- }
@@ -1,223 +0,0 @@
1
- import { CompletionGenerator, CommandDefinition, FlagDefinition } from '../types.js';
2
- import { POWERSHELL_DYNAMIC_HELPERS } from '../templates/powershell-templates.js';
3
-
4
- /**
5
- * Generates PowerShell completion scripts for the Prompter CLI.
6
- * Uses Register-ArgumentCompleter for command completion.
7
- */
8
- export class PowerShellGenerator implements CompletionGenerator {
9
- readonly shell = 'powershell' as const;
10
-
11
- private stripTrailingCommaFromLastLine(lines: string[]): void {
12
- if (lines.length === 0) return;
13
- lines[lines.length - 1] = lines[lines.length - 1].replace(/,\s*$/, '');
14
- }
15
-
16
- /**
17
- * Generate a PowerShell completion script
18
- *
19
- * @param commands - Command definitions to generate completions for
20
- * @returns PowerShell completion script as a string
21
- */
22
- generate(commands: CommandDefinition[]): string {
23
- // Build top-level commands using push() for loop clarity
24
- const commandLines: string[] = [];
25
- for (const cmd of commands) {
26
- commandLines.push(` @{Name="${cmd.name}"; Description="${this.escapeDescription(cmd.description)}"},`);
27
- }
28
- this.stripTrailingCommaFromLastLine(commandLines);
29
- const topLevelCommands = commandLines.join('\n');
30
-
31
- // Build command cases using push() for loop clarity
32
- const commandCaseLines: string[] = [];
33
- for (const cmd of commands) {
34
- commandCaseLines.push(` "${cmd.name}" {`);
35
- commandCaseLines.push(...this.generateCommandCase(cmd, ' '));
36
- commandCaseLines.push(' }');
37
- }
38
- const commandCases = commandCaseLines.join('\n');
39
-
40
- // Dynamic completion helpers from template
41
- const helpers = POWERSHELL_DYNAMIC_HELPERS;
42
-
43
- // Assemble final script with template literal
44
- return `# PowerShell completion script for Prompter CLI
45
- # Auto-generated - do not edit manually
46
-
47
- ${helpers}
48
- $prompterCompleter = {
49
- param($wordToComplete, $commandAst, $cursorPosition)
50
-
51
- $tokens = $commandAst.ToString() -split "\\s+"
52
- $commandCount = ($tokens | Measure-Object).Count
53
-
54
- # Top-level commands
55
- if ($commandCount -eq 1 -or ($commandCount -eq 2 -and $wordToComplete)) {
56
- $commands = @(
57
- ${topLevelCommands}
58
- )
59
- $commands | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {
60
- [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, "ParameterValue", $_.Description)
61
- }
62
- return
63
- }
64
-
65
- $command = $tokens[1]
66
-
67
- switch ($command) {
68
- ${commandCases}
69
- }
70
- }
71
-
72
- Register-ArgumentCompleter -CommandName prompter -ScriptBlock $prompterCompleter
73
- `;
74
- }
75
-
76
- /**
77
- * Generate completion case for a command
78
- */
79
- private generateCommandCase(cmd: CommandDefinition, indent: string): string[] {
80
- const lines: string[] = [];
81
-
82
- if (cmd.subcommands && cmd.subcommands.length > 0) {
83
- // First, check if user is typing a flag for the parent command
84
- if (cmd.flags.length > 0) {
85
- lines.push(`${indent}if ($wordToComplete -like "-*") {`);
86
- lines.push(`${indent} $flags = @(`);
87
- for (const flag of cmd.flags) {
88
- const longFlag = `--${flag.name}`;
89
- const shortFlag = flag.short ? `-${flag.short}` : undefined;
90
- if (shortFlag) {
91
- lines.push(`${indent} @{Name="${longFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
92
- lines.push(`${indent} @{Name="${shortFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
93
- } else {
94
- lines.push(`${indent} @{Name="${longFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
95
- }
96
- }
97
- this.stripTrailingCommaFromLastLine(lines);
98
- lines.push(`${indent} )`);
99
- lines.push(`${indent} $flags | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {`);
100
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, "ParameterName", $_.Description)`);
101
- lines.push(`${indent} }`);
102
- lines.push(`${indent} return`);
103
- lines.push(`${indent}}`);
104
- lines.push('');
105
- }
106
-
107
- // Handle subcommands
108
- lines.push(`${indent}if ($commandCount -eq 2 -or ($commandCount -eq 3 -and $wordToComplete)) {`);
109
- lines.push(`${indent} $subcommands = @(`);
110
- for (const subcmd of cmd.subcommands) {
111
- lines.push(`${indent} @{Name="${subcmd.name}"; Description="${this.escapeDescription(subcmd.description)}"},`);
112
- }
113
- this.stripTrailingCommaFromLastLine(lines);
114
- lines.push(`${indent} )`);
115
- lines.push(`${indent} $subcommands | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {`);
116
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, "ParameterValue", $_.Description)`);
117
- lines.push(`${indent} }`);
118
- lines.push(`${indent} return`);
119
- lines.push(`${indent}}`);
120
- lines.push('');
121
- lines.push(`${indent}$subcommand = if ($commandCount -gt 2) { $tokens[2] } else { "" }`);
122
- lines.push(`${indent}switch ($subcommand) {`);
123
-
124
- for (const subcmd of cmd.subcommands) {
125
- lines.push(`${indent} "${subcmd.name}" {`);
126
- lines.push(...this.generateArgumentCompletion(subcmd, indent + ' '));
127
- lines.push(`${indent} }`);
128
- }
129
-
130
- lines.push(`${indent}}`);
131
- } else {
132
- // No subcommands
133
- lines.push(...this.generateArgumentCompletion(cmd, indent));
134
- }
135
-
136
- return lines;
137
- }
138
-
139
- /**
140
- * Generate argument completion (flags and positional)
141
- */
142
- private generateArgumentCompletion(cmd: CommandDefinition, indent: string): string[] {
143
- const lines: string[] = [];
144
-
145
- // Flag completion
146
- if (cmd.flags.length > 0) {
147
- lines.push(`${indent}if ($wordToComplete -like "-*") {`);
148
- lines.push(`${indent} $flags = @(`);
149
- for (const flag of cmd.flags) {
150
- const longFlag = `--${flag.name}`;
151
- const shortFlag = flag.short ? `-${flag.short}` : undefined;
152
- if (shortFlag) {
153
- lines.push(`${indent} @{Name="${longFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
154
- lines.push(`${indent} @{Name="${shortFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
155
- } else {
156
- lines.push(`${indent} @{Name="${longFlag}"; Description="${this.escapeDescription(flag.description)}"},`);
157
- }
158
- }
159
- this.stripTrailingCommaFromLastLine(lines);
160
- lines.push(`${indent} )`);
161
- lines.push(`${indent} $flags | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object {`);
162
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, "ParameterName", $_.Description)`);
163
- lines.push(`${indent} }`);
164
- lines.push(`${indent} return`);
165
- lines.push(`${indent}}`);
166
- lines.push('');
167
- }
168
-
169
- // Positional completion
170
- if (cmd.acceptsPositional) {
171
- lines.push(...this.generatePositionalCompletion(cmd.positionalType, indent));
172
- }
173
-
174
- return lines;
175
- }
176
-
177
- /**
178
- * Generate positional argument completion
179
- */
180
- private generatePositionalCompletion(positionalType: string | undefined, indent: string): string[] {
181
- const lines: string[] = [];
182
-
183
- switch (positionalType) {
184
- case 'change-id':
185
- lines.push(`${indent}Get-PrompterChanges | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {`);
186
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", "Change: $_")`);
187
- lines.push(`${indent}}`);
188
- break;
189
- case 'spec-id':
190
- lines.push(`${indent}Get-PrompterSpecs | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {`);
191
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", "Spec: $_")`);
192
- lines.push(`${indent}}`);
193
- break;
194
- case 'change-or-spec-id':
195
- lines.push(`${indent}$items = @(Get-PrompterChanges) + @(Get-PrompterSpecs)`);
196
- lines.push(`${indent}$items | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {`);
197
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", $_)`);
198
- lines.push(`${indent}}`);
199
- break;
200
- case 'shell':
201
- lines.push(`${indent}$shells = @("zsh", "bash", "fish", "powershell")`);
202
- lines.push(`${indent}$shells | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {`);
203
- lines.push(`${indent} [System.Management.Automation.CompletionResult]::new($_, $_, "ParameterValue", "Shell: $_")`);
204
- lines.push(`${indent}}`);
205
- break;
206
- case 'path':
207
- // PowerShell handles file path completion automatically
208
- break;
209
- }
210
-
211
- return lines;
212
- }
213
-
214
- /**
215
- * Escape description text for PowerShell
216
- */
217
- private escapeDescription(description: string): string {
218
- return description
219
- .replace(/`/g, '``') // Backticks (escape sequences)
220
- .replace(/\$/g, '`$') // Dollar signs (prevents $())
221
- .replace(/"/g, '""'); // Double quotes
222
- }
223
- }