openspec-cn 0.23.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/LICENSE +22 -0
- package/README.md +153 -0
- package/bin/openspec.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +480 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.js +277 -0
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +257 -0
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.js +198 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +183 -0
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/schema.js +869 -0
- package/dist/commands/show.d.ts +14 -0
- package/dist/commands/show.js +132 -0
- package/dist/commands/spec.d.ts +15 -0
- package/dist/commands/spec.js +225 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.js +294 -0
- package/dist/commands/workflow/index.d.ts +17 -0
- package/dist/commands/workflow/index.js +12 -0
- package/dist/commands/workflow/instructions.d.ts +29 -0
- package/dist/commands/workflow/instructions.js +381 -0
- package/dist/commands/workflow/new-change.d.ts +11 -0
- package/dist/commands/workflow/new-change.js +44 -0
- package/dist/commands/workflow/schemas.d.ts +10 -0
- package/dist/commands/workflow/schemas.js +34 -0
- package/dist/commands/workflow/shared.d.ts +52 -0
- package/dist/commands/workflow/shared.js +111 -0
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.js +58 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +68 -0
- package/dist/core/archive.d.ts +11 -0
- package/dist/core/archive.js +280 -0
- package/dist/core/artifact-graph/graph.d.ts +56 -0
- package/dist/core/artifact-graph/graph.js +141 -0
- package/dist/core/artifact-graph/index.d.ts +7 -0
- package/dist/core/artifact-graph/index.js +13 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +143 -0
- package/dist/core/artifact-graph/instruction-loader.js +214 -0
- package/dist/core/artifact-graph/resolver.d.ts +81 -0
- package/dist/core/artifact-graph/resolver.js +257 -0
- package/dist/core/artifact-graph/schema.d.ts +13 -0
- package/dist/core/artifact-graph/schema.js +108 -0
- package/dist/core/artifact-graph/state.d.ts +12 -0
- package/dist/core/artifact-graph/state.js +54 -0
- package/dist/core/artifact-graph/types.d.ts +45 -0
- package/dist/core/artifact-graph/types.js +43 -0
- package/dist/core/command-generation/adapters/amazon-q.d.ts +13 -0
- package/dist/core/command-generation/adapters/amazon-q.js +26 -0
- package/dist/core/command-generation/adapters/antigravity.d.ts +13 -0
- package/dist/core/command-generation/adapters/antigravity.js +26 -0
- package/dist/core/command-generation/adapters/auggie.d.ts +13 -0
- package/dist/core/command-generation/adapters/auggie.js +27 -0
- package/dist/core/command-generation/adapters/claude.d.ts +13 -0
- package/dist/core/command-generation/adapters/claude.js +50 -0
- package/dist/core/command-generation/adapters/cline.d.ts +14 -0
- package/dist/core/command-generation/adapters/cline.js +27 -0
- package/dist/core/command-generation/adapters/codebuddy.d.ts +13 -0
- package/dist/core/command-generation/adapters/codebuddy.js +28 -0
- package/dist/core/command-generation/adapters/codex.d.ts +13 -0
- package/dist/core/command-generation/adapters/codex.js +27 -0
- package/dist/core/command-generation/adapters/continue.d.ts +13 -0
- package/dist/core/command-generation/adapters/continue.js +28 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +13 -0
- package/dist/core/command-generation/adapters/costrict.js +27 -0
- package/dist/core/command-generation/adapters/crush.d.ts +13 -0
- package/dist/core/command-generation/adapters/crush.js +30 -0
- package/dist/core/command-generation/adapters/cursor.d.ts +14 -0
- package/dist/core/command-generation/adapters/cursor.js +44 -0
- package/dist/core/command-generation/adapters/factory.d.ts +13 -0
- package/dist/core/command-generation/adapters/factory.js +27 -0
- package/dist/core/command-generation/adapters/gemini.d.ts +13 -0
- package/dist/core/command-generation/adapters/gemini.js +26 -0
- package/dist/core/command-generation/adapters/github-copilot.d.ts +13 -0
- package/dist/core/command-generation/adapters/github-copilot.js +26 -0
- package/dist/core/command-generation/adapters/iflow.d.ts +13 -0
- package/dist/core/command-generation/adapters/iflow.js +29 -0
- package/dist/core/command-generation/adapters/index.d.ts +27 -0
- package/dist/core/command-generation/adapters/index.js +27 -0
- package/dist/core/command-generation/adapters/kilocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/kilocode.js +23 -0
- package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
- package/dist/core/command-generation/adapters/opencode.js +26 -0
- package/dist/core/command-generation/adapters/qoder.d.ts +13 -0
- package/dist/core/command-generation/adapters/qoder.js +30 -0
- package/dist/core/command-generation/adapters/qwen.d.ts +13 -0
- package/dist/core/command-generation/adapters/qwen.js +26 -0
- package/dist/core/command-generation/adapters/roocode.d.ts +14 -0
- package/dist/core/command-generation/adapters/roocode.js +27 -0
- package/dist/core/command-generation/adapters/windsurf.d.ts +14 -0
- package/dist/core/command-generation/adapters/windsurf.js +51 -0
- package/dist/core/command-generation/generator.d.ts +21 -0
- package/dist/core/command-generation/generator.js +27 -0
- package/dist/core/command-generation/index.d.ts +22 -0
- package/dist/core/command-generation/index.js +24 -0
- package/dist/core/command-generation/registry.d.ts +36 -0
- package/dist/core/command-generation/registry.js +88 -0
- package/dist/core/command-generation/types.d.ts +55 -0
- package/dist/core/command-generation/types.js +8 -0
- package/dist/core/completions/command-registry.d.ts +7 -0
- package/dist/core/completions/command-registry.js +456 -0
- package/dist/core/completions/completion-provider.d.ts +60 -0
- package/dist/core/completions/completion-provider.js +102 -0
- package/dist/core/completions/factory.d.ts +64 -0
- package/dist/core/completions/factory.js +75 -0
- package/dist/core/completions/generators/bash-generator.d.ts +32 -0
- package/dist/core/completions/generators/bash-generator.js +174 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.js +157 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +33 -0
- package/dist/core/completions/generators/powershell-generator.js +207 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +44 -0
- package/dist/core/completions/generators/zsh-generator.js +250 -0
- package/dist/core/completions/installers/bash-installer.d.ts +87 -0
- package/dist/core/completions/installers/bash-installer.js +318 -0
- package/dist/core/completions/installers/fish-installer.d.ts +43 -0
- package/dist/core/completions/installers/fish-installer.js +143 -0
- package/dist/core/completions/installers/powershell-installer.d.ts +88 -0
- package/dist/core/completions/installers/powershell-installer.js +327 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +125 -0
- package/dist/core/completions/installers/zsh-installer.js +449 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.js +24 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.js +39 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.js +25 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.js +36 -0
- package/dist/core/completions/types.d.ts +79 -0
- package/dist/core/completions/types.js +2 -0
- package/dist/core/config-prompts.d.ts +9 -0
- package/dist/core/config-prompts.js +34 -0
- package/dist/core/config-schema.d.ts +76 -0
- package/dist/core/config-schema.js +200 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.js +30 -0
- package/dist/core/converters/json-converter.d.ts +6 -0
- package/dist/core/converters/json-converter.js +51 -0
- package/dist/core/global-config.d.ts +39 -0
- package/dist/core/global-config.js +115 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +3 -0
- package/dist/core/init.d.ts +32 -0
- package/dist/core/init.js +433 -0
- package/dist/core/legacy-cleanup.d.ts +162 -0
- package/dist/core/legacy-cleanup.js +501 -0
- package/dist/core/list.d.ts +9 -0
- package/dist/core/list.js +171 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.js +193 -0
- package/dist/core/parsers/markdown-parser.d.ts +22 -0
- package/dist/core/parsers/markdown-parser.js +187 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- package/dist/core/project-config.d.ts +64 -0
- package/dist/core/project-config.js +223 -0
- package/dist/core/schemas/base.schema.d.ts +13 -0
- package/dist/core/schemas/base.schema.js +13 -0
- package/dist/core/schemas/change.schema.d.ts +73 -0
- package/dist/core/schemas/change.schema.js +31 -0
- package/dist/core/schemas/index.d.ts +4 -0
- package/dist/core/schemas/index.js +4 -0
- package/dist/core/schemas/spec.schema.d.ts +18 -0
- package/dist/core/schemas/spec.schema.js +15 -0
- package/dist/core/shared/index.d.ts +8 -0
- package/dist/core/shared/index.js +8 -0
- package/dist/core/shared/skill-generation.d.ts +41 -0
- package/dist/core/shared/skill-generation.js +74 -0
- package/dist/core/shared/tool-detection.d.ts +66 -0
- package/dist/core/shared/tool-detection.js +140 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.js +384 -0
- package/dist/core/styles/palette.d.ts +7 -0
- package/dist/core/styles/palette.js +8 -0
- package/dist/core/templates/index.d.ts +8 -0
- package/dist/core/templates/index.js +9 -0
- package/dist/core/templates/skill-templates.d.ts +112 -0
- package/dist/core/templates/skill-templates.js +2893 -0
- package/dist/core/update.d.ts +42 -0
- package/dist/core/update.js +306 -0
- package/dist/core/validation/constants.d.ts +34 -0
- package/dist/core/validation/constants.js +40 -0
- package/dist/core/validation/types.d.ts +18 -0
- package/dist/core/validation/types.js +2 -0
- package/dist/core/validation/validator.d.ts +33 -0
- package/dist/core/validation/validator.js +409 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +168 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/prompts/searchable-multi-select.d.ts +27 -0
- package/dist/prompts/searchable-multi-select.js +149 -0
- package/dist/telemetry/config.d.ts +32 -0
- package/dist/telemetry/config.js +68 -0
- package/dist/telemetry/index.d.ts +31 -0
- package/dist/telemetry/index.js +145 -0
- package/dist/ui/ascii-patterns.d.ts +16 -0
- package/dist/ui/ascii-patterns.js +133 -0
- package/dist/ui/welcome-screen.d.ts +10 -0
- package/dist/ui/welcome-screen.js +146 -0
- package/dist/utils/change-metadata.d.ts +51 -0
- package/dist/utils/change-metadata.js +147 -0
- package/dist/utils/change-utils.d.ts +62 -0
- package/dist/utils/change-utils.js +121 -0
- package/dist/utils/file-system.d.ts +36 -0
- package/dist/utils/file-system.js +281 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/interactive.d.ts +18 -0
- package/dist/utils/interactive.js +21 -0
- package/dist/utils/item-discovery.d.ts +4 -0
- package/dist/utils/item-discovery.js +72 -0
- package/dist/utils/match.d.ts +3 -0
- package/dist/utils/match.js +22 -0
- package/dist/utils/shell-detection.d.ts +20 -0
- package/dist/utils/shell-detection.js +41 -0
- package/dist/utils/task-progress.d.ts +8 -0
- package/dist/utils/task-progress.js +36 -0
- package/package.json +84 -0
- package/schemas/spec-driven/schema.yaml +148 -0
- package/schemas/spec-driven/templates/design.md +19 -0
- package/schemas/spec-driven/templates/proposal.md +23 -0
- package/schemas/spec-driven/templates/spec.md +8 -0
- package/schemas/spec-driven/templates/tasks.md +9 -0
- package/schemas/tdd/schema.yaml +213 -0
- package/schemas/tdd/templates/docs.md +15 -0
- package/schemas/tdd/templates/implementation.md +11 -0
- package/schemas/tdd/templates/spec.md +11 -0
- package/schemas/tdd/templates/test.md +11 -0
- package/scripts/postinstall.js +147 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ZshGenerator } from './generators/zsh-generator.js';
|
|
2
|
+
import { BashGenerator } from './generators/bash-generator.js';
|
|
3
|
+
import { FishGenerator } from './generators/fish-generator.js';
|
|
4
|
+
import { PowerShellGenerator } from './generators/powershell-generator.js';
|
|
5
|
+
import { ZshInstaller } from './installers/zsh-installer.js';
|
|
6
|
+
import { BashInstaller } from './installers/bash-installer.js';
|
|
7
|
+
import { FishInstaller } from './installers/fish-installer.js';
|
|
8
|
+
import { PowerShellInstaller } from './installers/powershell-installer.js';
|
|
9
|
+
/**
|
|
10
|
+
* Factory for creating completion generators and installers
|
|
11
|
+
* This design makes it easy to add support for additional shells
|
|
12
|
+
*/
|
|
13
|
+
export class CompletionFactory {
|
|
14
|
+
static SUPPORTED_SHELLS = ['zsh', 'bash', 'fish', 'powershell'];
|
|
15
|
+
/**
|
|
16
|
+
* Create a completion generator for the specified shell
|
|
17
|
+
*
|
|
18
|
+
* @param shell - The target shell
|
|
19
|
+
* @returns CompletionGenerator instance
|
|
20
|
+
* @throws Error if shell is not supported
|
|
21
|
+
*/
|
|
22
|
+
static createGenerator(shell) {
|
|
23
|
+
switch (shell) {
|
|
24
|
+
case 'zsh':
|
|
25
|
+
return new ZshGenerator();
|
|
26
|
+
case 'bash':
|
|
27
|
+
return new BashGenerator();
|
|
28
|
+
case 'fish':
|
|
29
|
+
return new FishGenerator();
|
|
30
|
+
case 'powershell':
|
|
31
|
+
return new PowerShellGenerator();
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a completion installer for the specified shell
|
|
38
|
+
*
|
|
39
|
+
* @param shell - The target shell
|
|
40
|
+
* @returns CompletionInstaller instance
|
|
41
|
+
* @throws Error if shell is not supported
|
|
42
|
+
*/
|
|
43
|
+
static createInstaller(shell) {
|
|
44
|
+
switch (shell) {
|
|
45
|
+
case 'zsh':
|
|
46
|
+
return new ZshInstaller();
|
|
47
|
+
case 'bash':
|
|
48
|
+
return new BashInstaller();
|
|
49
|
+
case 'fish':
|
|
50
|
+
return new FishInstaller();
|
|
51
|
+
case 'powershell':
|
|
52
|
+
return new PowerShellInstaller();
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unsupported shell: ${shell}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if a shell is supported
|
|
59
|
+
*
|
|
60
|
+
* @param shell - The shell to check
|
|
61
|
+
* @returns true if the shell is supported
|
|
62
|
+
*/
|
|
63
|
+
static isSupported(shell) {
|
|
64
|
+
return this.SUPPORTED_SHELLS.includes(shell);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get list of all supported shells
|
|
68
|
+
*
|
|
69
|
+
* @returns Array of supported shell names
|
|
70
|
+
*/
|
|
71
|
+
static getSupportedShells() {
|
|
72
|
+
return [...this.SUPPORTED_SHELLS];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CompletionGenerator, CommandDefinition } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Bash completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Follows Bash completion conventions using complete builtin and COMPREPLY array.
|
|
5
|
+
*/
|
|
6
|
+
export declare class BashGenerator implements CompletionGenerator {
|
|
7
|
+
readonly shell: "bash";
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Bash completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Bash completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands: CommandDefinition[]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generate completion case logic for a command
|
|
17
|
+
*/
|
|
18
|
+
private generateCommandCase;
|
|
19
|
+
/**
|
|
20
|
+
* Generate argument completion (flags and positional arguments)
|
|
21
|
+
*/
|
|
22
|
+
private generateArgumentCompletion;
|
|
23
|
+
/**
|
|
24
|
+
* Generate positional argument completion based on type
|
|
25
|
+
*/
|
|
26
|
+
private generatePositionalCompletion;
|
|
27
|
+
/**
|
|
28
|
+
* Escape command/subcommand names for safe use in Bash scripts
|
|
29
|
+
*/
|
|
30
|
+
private escapeCommandName;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=bash-generator.d.ts.map
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { BASH_DYNAMIC_HELPERS } from '../templates/bash-templates.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Bash completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Follows Bash completion conventions using complete builtin and COMPREPLY array.
|
|
5
|
+
*/
|
|
6
|
+
export class BashGenerator {
|
|
7
|
+
shell = 'bash';
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Bash completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Bash completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands) {
|
|
15
|
+
// Build command list for top-level completions
|
|
16
|
+
const commandList = commands.map(c => this.escapeCommandName(c.name)).join(' ');
|
|
17
|
+
// Build command cases using push() for loop clarity
|
|
18
|
+
const caseLines = [];
|
|
19
|
+
for (const cmd of commands) {
|
|
20
|
+
caseLines.push(` ${cmd.name})`);
|
|
21
|
+
caseLines.push(...this.generateCommandCase(cmd, ' '));
|
|
22
|
+
caseLines.push(' ;;');
|
|
23
|
+
}
|
|
24
|
+
const commandCases = caseLines.join('\n');
|
|
25
|
+
// Dynamic completion helpers from template
|
|
26
|
+
const helpers = BASH_DYNAMIC_HELPERS;
|
|
27
|
+
// Assemble final script with template literal
|
|
28
|
+
return `# Bash completion script for OpenSpec CLI
|
|
29
|
+
# Auto-generated - do not edit manually
|
|
30
|
+
|
|
31
|
+
_openspec_completion() {
|
|
32
|
+
local cur prev words cword
|
|
33
|
+
|
|
34
|
+
# Use _init_completion if available (from bash-completion package)
|
|
35
|
+
# The -n : option prevents colons from being treated as word separators
|
|
36
|
+
# (important for spec/change IDs that may contain colons)
|
|
37
|
+
# Otherwise, fall back to manual initialization
|
|
38
|
+
if declare -F _init_completion >/dev/null 2>&1; then
|
|
39
|
+
_init_completion -n : || return
|
|
40
|
+
else
|
|
41
|
+
# Manual fallback when bash-completion is not installed
|
|
42
|
+
COMPREPLY=()
|
|
43
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
44
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
45
|
+
words=("\${COMP_WORDS[@]}")
|
|
46
|
+
cword=$COMP_CWORD
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
local cmd="\${words[1]}"
|
|
50
|
+
local subcmd="\${words[2]}"
|
|
51
|
+
|
|
52
|
+
# Top-level commands
|
|
53
|
+
if [[ $cword -eq 1 ]]; then
|
|
54
|
+
local commands="${commandList}"
|
|
55
|
+
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
56
|
+
return 0
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# Command-specific completion
|
|
60
|
+
case "$cmd" in
|
|
61
|
+
${commandCases}
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
return 0
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
${helpers}
|
|
68
|
+
complete -F _openspec_completion openspec
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generate completion case logic for a command
|
|
73
|
+
*/
|
|
74
|
+
generateCommandCase(cmd, indent) {
|
|
75
|
+
const lines = [];
|
|
76
|
+
// Handle subcommands
|
|
77
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
78
|
+
// First, check if user is typing a flag for the parent command
|
|
79
|
+
if (cmd.flags.length > 0) {
|
|
80
|
+
lines.push(`${indent}if [[ "$cur" == -* ]]; then`);
|
|
81
|
+
const flags = cmd.flags.map(f => {
|
|
82
|
+
const parts = [];
|
|
83
|
+
if (f.short)
|
|
84
|
+
parts.push(`-${f.short}`);
|
|
85
|
+
parts.push(`--${f.name}`);
|
|
86
|
+
return parts.join(' ');
|
|
87
|
+
}).join(' ');
|
|
88
|
+
lines.push(`${indent} local flags="${flags}"`);
|
|
89
|
+
lines.push(`${indent} COMPREPLY=($(compgen -W "$flags" -- "$cur"))`);
|
|
90
|
+
lines.push(`${indent} return 0`);
|
|
91
|
+
lines.push(`${indent}fi`);
|
|
92
|
+
lines.push('');
|
|
93
|
+
}
|
|
94
|
+
lines.push(`${indent}if [[ $cword -eq 2 ]]; then`);
|
|
95
|
+
lines.push(`${indent} local subcommands="` + cmd.subcommands.map(s => this.escapeCommandName(s.name)).join(' ') + '"');
|
|
96
|
+
lines.push(`${indent} COMPREPLY=($(compgen -W "$subcommands" -- "$cur"))`);
|
|
97
|
+
lines.push(`${indent} return 0`);
|
|
98
|
+
lines.push(`${indent}fi`);
|
|
99
|
+
lines.push('');
|
|
100
|
+
lines.push(`${indent}case "$subcmd" in`);
|
|
101
|
+
for (const subcmd of cmd.subcommands) {
|
|
102
|
+
lines.push(`${indent} ${subcmd.name})`);
|
|
103
|
+
lines.push(...this.generateArgumentCompletion(subcmd, indent + ' '));
|
|
104
|
+
lines.push(`${indent} ;;`);
|
|
105
|
+
}
|
|
106
|
+
lines.push(`${indent}esac`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// No subcommands, just complete arguments
|
|
110
|
+
lines.push(...this.generateArgumentCompletion(cmd, indent));
|
|
111
|
+
}
|
|
112
|
+
return lines;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generate argument completion (flags and positional arguments)
|
|
116
|
+
*/
|
|
117
|
+
generateArgumentCompletion(cmd, indent) {
|
|
118
|
+
const lines = [];
|
|
119
|
+
// Check for flag completion
|
|
120
|
+
if (cmd.flags.length > 0) {
|
|
121
|
+
lines.push(`${indent}if [[ "$cur" == -* ]]; then`);
|
|
122
|
+
const flags = cmd.flags.map(f => {
|
|
123
|
+
const parts = [];
|
|
124
|
+
if (f.short)
|
|
125
|
+
parts.push(`-${f.short}`);
|
|
126
|
+
parts.push(`--${f.name}`);
|
|
127
|
+
return parts.join(' ');
|
|
128
|
+
}).join(' ');
|
|
129
|
+
lines.push(`${indent} local flags="${flags}"`);
|
|
130
|
+
lines.push(`${indent} COMPREPLY=($(compgen -W "$flags" -- "$cur"))`);
|
|
131
|
+
lines.push(`${indent} return 0`);
|
|
132
|
+
lines.push(`${indent}fi`);
|
|
133
|
+
lines.push('');
|
|
134
|
+
}
|
|
135
|
+
// Handle positional completions
|
|
136
|
+
if (cmd.acceptsPositional) {
|
|
137
|
+
lines.push(...this.generatePositionalCompletion(cmd.positionalType, indent));
|
|
138
|
+
}
|
|
139
|
+
return lines;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Generate positional argument completion based on type
|
|
143
|
+
*/
|
|
144
|
+
generatePositionalCompletion(positionalType, indent) {
|
|
145
|
+
const lines = [];
|
|
146
|
+
switch (positionalType) {
|
|
147
|
+
case 'change-id':
|
|
148
|
+
lines.push(`${indent}_openspec_complete_changes`);
|
|
149
|
+
break;
|
|
150
|
+
case 'spec-id':
|
|
151
|
+
lines.push(`${indent}_openspec_complete_specs`);
|
|
152
|
+
break;
|
|
153
|
+
case 'change-or-spec-id':
|
|
154
|
+
lines.push(`${indent}_openspec_complete_items`);
|
|
155
|
+
break;
|
|
156
|
+
case 'shell':
|
|
157
|
+
lines.push(`${indent}local shells="zsh bash fish powershell"`);
|
|
158
|
+
lines.push(`${indent}COMPREPLY=($(compgen -W "$shells" -- "$cur"))`);
|
|
159
|
+
break;
|
|
160
|
+
case 'path':
|
|
161
|
+
lines.push(`${indent}COMPREPLY=($(compgen -f -- "$cur"))`);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
return lines;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Escape command/subcommand names for safe use in Bash scripts
|
|
168
|
+
*/
|
|
169
|
+
escapeCommandName(name) {
|
|
170
|
+
// Escape shell metacharacters to prevent command injection
|
|
171
|
+
return name.replace(/["\$`\\]/g, '\\$&');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=bash-generator.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CompletionGenerator, CommandDefinition } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Fish completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Follows Fish completion conventions using the complete command.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FishGenerator implements CompletionGenerator {
|
|
7
|
+
readonly shell: "fish";
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Fish completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Fish completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands: CommandDefinition[]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generate completions for a specific command
|
|
17
|
+
*/
|
|
18
|
+
private generateCommandCompletions;
|
|
19
|
+
/**
|
|
20
|
+
* Generate flag completion
|
|
21
|
+
*/
|
|
22
|
+
private generateFlagCompletion;
|
|
23
|
+
/**
|
|
24
|
+
* Generate positional argument completion
|
|
25
|
+
*/
|
|
26
|
+
private generatePositionalCompletion;
|
|
27
|
+
/**
|
|
28
|
+
* Escape description text for Fish
|
|
29
|
+
*/
|
|
30
|
+
private escapeDescription;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=fish-generator.d.ts.map
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { FISH_STATIC_HELPERS, FISH_DYNAMIC_HELPERS } from '../templates/fish-templates.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Fish completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Follows Fish completion conventions using the complete command.
|
|
5
|
+
*/
|
|
6
|
+
export class FishGenerator {
|
|
7
|
+
shell = 'fish';
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Fish completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Fish completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands) {
|
|
15
|
+
// Build top-level commands using push() for loop clarity
|
|
16
|
+
const topLevelLines = [];
|
|
17
|
+
for (const cmd of commands) {
|
|
18
|
+
topLevelLines.push(`# ${cmd.name} command`);
|
|
19
|
+
topLevelLines.push(`complete -c openspec -n '__fish_openspec_no_subcommand' -a '${cmd.name}' -d '${this.escapeDescription(cmd.description)}'`);
|
|
20
|
+
}
|
|
21
|
+
const topLevelCommands = topLevelLines.join('\n');
|
|
22
|
+
// Build command-specific completions using push() for loop clarity
|
|
23
|
+
const commandCompletionLines = [];
|
|
24
|
+
for (const cmd of commands) {
|
|
25
|
+
commandCompletionLines.push(...this.generateCommandCompletions(cmd));
|
|
26
|
+
commandCompletionLines.push('');
|
|
27
|
+
}
|
|
28
|
+
const commandCompletions = commandCompletionLines.join('\n');
|
|
29
|
+
// Static helper functions from template
|
|
30
|
+
const helperFunctions = FISH_STATIC_HELPERS;
|
|
31
|
+
// Dynamic completion helpers from template
|
|
32
|
+
const dynamicHelpers = FISH_DYNAMIC_HELPERS;
|
|
33
|
+
// Assemble final script with template literal
|
|
34
|
+
return `# Fish completion script for OpenSpec CLI
|
|
35
|
+
# Auto-generated - do not edit manually
|
|
36
|
+
|
|
37
|
+
${helperFunctions}
|
|
38
|
+
${dynamicHelpers}
|
|
39
|
+
${topLevelCommands}
|
|
40
|
+
|
|
41
|
+
${commandCompletions}`;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Generate completions for a specific command
|
|
45
|
+
*/
|
|
46
|
+
generateCommandCompletions(cmd) {
|
|
47
|
+
const lines = [];
|
|
48
|
+
// If command has subcommands
|
|
49
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
50
|
+
// Add subcommand completions
|
|
51
|
+
for (const subcmd of cmd.subcommands) {
|
|
52
|
+
lines.push(`complete -c openspec -n '__fish_openspec_using_subcommand ${cmd.name}; and not __fish_openspec_using_subcommand ${subcmd.name}' -a '${subcmd.name}' -d '${this.escapeDescription(subcmd.description)}'`);
|
|
53
|
+
}
|
|
54
|
+
lines.push('');
|
|
55
|
+
// Add flags for parent command
|
|
56
|
+
for (const flag of cmd.flags) {
|
|
57
|
+
lines.push(...this.generateFlagCompletion(flag, `__fish_openspec_using_subcommand ${cmd.name}`));
|
|
58
|
+
}
|
|
59
|
+
// Add completions for each subcommand
|
|
60
|
+
for (const subcmd of cmd.subcommands) {
|
|
61
|
+
lines.push(`# ${cmd.name} ${subcmd.name} flags`);
|
|
62
|
+
for (const flag of subcmd.flags) {
|
|
63
|
+
lines.push(...this.generateFlagCompletion(flag, `__fish_openspec_using_subcommand ${cmd.name}; and __fish_openspec_using_subcommand ${subcmd.name}`));
|
|
64
|
+
}
|
|
65
|
+
// Add positional completions for subcommand
|
|
66
|
+
if (subcmd.acceptsPositional) {
|
|
67
|
+
lines.push(...this.generatePositionalCompletion(subcmd.positionalType, `__fish_openspec_using_subcommand ${cmd.name}; and __fish_openspec_using_subcommand ${subcmd.name}`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Command without subcommands
|
|
73
|
+
lines.push(`# ${cmd.name} flags`);
|
|
74
|
+
for (const flag of cmd.flags) {
|
|
75
|
+
lines.push(...this.generateFlagCompletion(flag, `__fish_openspec_using_subcommand ${cmd.name}`));
|
|
76
|
+
}
|
|
77
|
+
// Add positional completions
|
|
78
|
+
if (cmd.acceptsPositional) {
|
|
79
|
+
lines.push(...this.generatePositionalCompletion(cmd.positionalType, `__fish_openspec_using_subcommand ${cmd.name}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return lines;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate flag completion
|
|
86
|
+
*/
|
|
87
|
+
generateFlagCompletion(flag, condition) {
|
|
88
|
+
const lines = [];
|
|
89
|
+
const longFlag = `--${flag.name}`;
|
|
90
|
+
const shortFlag = flag.short ? `-${flag.short}` : undefined;
|
|
91
|
+
if (flag.takesValue && flag.values) {
|
|
92
|
+
// Flag with enum values
|
|
93
|
+
for (const value of flag.values) {
|
|
94
|
+
if (shortFlag) {
|
|
95
|
+
lines.push(`complete -c openspec -n '${condition}' -s ${flag.short} -l ${flag.name} -a '${value}' -d '${this.escapeDescription(flag.description)}'`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
lines.push(`complete -c openspec -n '${condition}' -l ${flag.name} -a '${value}' -d '${this.escapeDescription(flag.description)}'`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else if (flag.takesValue) {
|
|
103
|
+
// Flag that takes a value but no specific values defined
|
|
104
|
+
if (shortFlag) {
|
|
105
|
+
lines.push(`complete -c openspec -n '${condition}' -s ${flag.short} -l ${flag.name} -r -d '${this.escapeDescription(flag.description)}'`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push(`complete -c openspec -n '${condition}' -l ${flag.name} -r -d '${this.escapeDescription(flag.description)}'`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Boolean flag
|
|
113
|
+
if (shortFlag) {
|
|
114
|
+
lines.push(`complete -c openspec -n '${condition}' -s ${flag.short} -l ${flag.name} -d '${this.escapeDescription(flag.description)}'`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
lines.push(`complete -c openspec -n '${condition}' -l ${flag.name} -d '${this.escapeDescription(flag.description)}'`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return lines;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Generate positional argument completion
|
|
124
|
+
*/
|
|
125
|
+
generatePositionalCompletion(positionalType, condition) {
|
|
126
|
+
const lines = [];
|
|
127
|
+
switch (positionalType) {
|
|
128
|
+
case 'change-id':
|
|
129
|
+
lines.push(`complete -c openspec -n '${condition}' -a '(__fish_openspec_changes)' -f`);
|
|
130
|
+
break;
|
|
131
|
+
case 'spec-id':
|
|
132
|
+
lines.push(`complete -c openspec -n '${condition}' -a '(__fish_openspec_specs)' -f`);
|
|
133
|
+
break;
|
|
134
|
+
case 'change-or-spec-id':
|
|
135
|
+
lines.push(`complete -c openspec -n '${condition}' -a '(__fish_openspec_items)' -f`);
|
|
136
|
+
break;
|
|
137
|
+
case 'shell':
|
|
138
|
+
lines.push(`complete -c openspec -n '${condition}' -a 'zsh bash fish powershell' -f`);
|
|
139
|
+
break;
|
|
140
|
+
case 'path':
|
|
141
|
+
// Fish automatically completes files, no need to specify
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
return lines;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Escape description text for Fish
|
|
148
|
+
*/
|
|
149
|
+
escapeDescription(description) {
|
|
150
|
+
return description
|
|
151
|
+
.replace(/\\/g, '\\\\') // Backslashes first
|
|
152
|
+
.replace(/'/g, "\\'") // Single quotes
|
|
153
|
+
.replace(/\$/g, '\\$') // Dollar signs (prevents $())
|
|
154
|
+
.replace(/`/g, '\\`'); // Backticks
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=fish-generator.js.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CompletionGenerator, CommandDefinition } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates PowerShell completion scripts for the OpenSpec CLI.
|
|
4
|
+
* Uses Register-ArgumentCompleter for command completion.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PowerShellGenerator implements CompletionGenerator {
|
|
7
|
+
readonly shell: "powershell";
|
|
8
|
+
private stripTrailingCommaFromLastLine;
|
|
9
|
+
/**
|
|
10
|
+
* Generate a PowerShell completion script
|
|
11
|
+
*
|
|
12
|
+
* @param commands - Command definitions to generate completions for
|
|
13
|
+
* @returns PowerShell completion script as a string
|
|
14
|
+
*/
|
|
15
|
+
generate(commands: CommandDefinition[]): string;
|
|
16
|
+
/**
|
|
17
|
+
* Generate completion case for a command
|
|
18
|
+
*/
|
|
19
|
+
private generateCommandCase;
|
|
20
|
+
/**
|
|
21
|
+
* Generate argument completion (flags and positional)
|
|
22
|
+
*/
|
|
23
|
+
private generateArgumentCompletion;
|
|
24
|
+
/**
|
|
25
|
+
* Generate positional argument completion
|
|
26
|
+
*/
|
|
27
|
+
private generatePositionalCompletion;
|
|
28
|
+
/**
|
|
29
|
+
* Escape description text for PowerShell
|
|
30
|
+
*/
|
|
31
|
+
private escapeDescription;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=powershell-generator.d.ts.map
|