synarcx 0.1.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 +23 -0
- package/README.md +90 -0
- package/bin/synarcx.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +474 -0
- package/dist/commands/change.d.ts +35 -0
- package/dist/commands/change.js +278 -0
- package/dist/commands/completion.d.ts +72 -0
- package/dist/commands/completion.js +264 -0
- package/dist/commands/config.d.ts +36 -0
- package/dist/commands/config.js +552 -0
- package/dist/commands/feedback.d.ts +9 -0
- package/dist/commands/feedback.js +170 -0
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/schema.js +870 -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 +226 -0
- package/dist/commands/validate.d.ts +24 -0
- package/dist/commands/validate.js +295 -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 +327 -0
- package/dist/commands/workflow/new-change.d.ts +11 -0
- package/dist/commands/workflow/new-change.js +45 -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 +57 -0
- package/dist/commands/workflow/shared.js +117 -0
- package/dist/commands/workflow/status.d.ts +14 -0
- package/dist/commands/workflow/status.js +75 -0
- package/dist/commands/workflow/templates.d.ts +16 -0
- package/dist/commands/workflow/templates.js +69 -0
- package/dist/commands/workspace/open.d.ts +29 -0
- package/dist/commands/workspace/open.js +84 -0
- package/dist/commands/workspace/operations.d.ts +18 -0
- package/dist/commands/workspace/operations.js +461 -0
- package/dist/commands/workspace/selection.d.ts +5 -0
- package/dist/commands/workspace/selection.js +90 -0
- package/dist/commands/workspace/types.d.ts +83 -0
- package/dist/commands/workspace/types.js +36 -0
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.js +635 -0
- package/dist/core/archive.d.ts +11 -0
- package/dist/core/archive.js +319 -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 +8 -0
- package/dist/core/artifact-graph/index.js +14 -0
- package/dist/core/artifact-graph/instruction-loader.d.ts +143 -0
- package/dist/core/artifact-graph/instruction-loader.js +217 -0
- package/dist/core/artifact-graph/outputs.d.ts +14 -0
- package/dist/core/artifact-graph/outputs.js +39 -0
- package/dist/core/artifact-graph/resolver.d.ts +81 -0
- package/dist/core/artifact-graph/resolver.js +258 -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 +31 -0
- package/dist/core/artifact-graph/types.d.ts +45 -0
- package/dist/core/artifact-graph/types.js +43 -0
- package/dist/core/available-tools.d.ts +17 -0
- package/dist/core/available-tools.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/bob.d.ts +14 -0
- package/dist/core/command-generation/adapters/bob.js +45 -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 +16 -0
- package/dist/core/command-generation/adapters/codex.js +39 -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 +32 -0
- package/dist/core/command-generation/adapters/index.js +32 -0
- package/dist/core/command-generation/adapters/junie.d.ts +13 -0
- package/dist/core/command-generation/adapters/junie.js +26 -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/kiro.d.ts +13 -0
- package/dist/core/command-generation/adapters/kiro.js +26 -0
- package/dist/core/command-generation/adapters/lingma.d.ts +13 -0
- package/dist/core/command-generation/adapters/lingma.js +30 -0
- package/dist/core/command-generation/adapters/opencode.d.ts +13 -0
- package/dist/core/command-generation/adapters/opencode.js +27 -0
- package/dist/core/command-generation/adapters/pi.d.ts +18 -0
- package/dist/core/command-generation/adapters/pi.js +55 -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 +98 -0
- package/dist/core/command-generation/types.d.ts +56 -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 +596 -0
- package/dist/core/completions/completion-provider.d.ts +71 -0
- package/dist/core/completions/completion-provider.js +129 -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 +35 -0
- package/dist/core/completions/generators/bash-generator.js +230 -0
- package/dist/core/completions/generators/fish-generator.d.ts +32 -0
- package/dist/core/completions/generators/fish-generator.js +160 -0
- package/dist/core/completions/generators/powershell-generator.d.ts +36 -0
- package/dist/core/completions/generators/powershell-generator.js +266 -0
- package/dist/core/completions/generators/zsh-generator.d.ts +47 -0
- package/dist/core/completions/generators/zsh-generator.js +274 -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 +102 -0
- package/dist/core/completions/installers/powershell-installer.js +387 -0
- package/dist/core/completions/installers/zsh-installer.d.ts +117 -0
- package/dist/core/completions/installers/zsh-installer.js +421 -0
- package/dist/core/completions/templates/bash-templates.d.ts +6 -0
- package/dist/core/completions/templates/bash-templates.js +30 -0
- package/dist/core/completions/templates/fish-templates.d.ts +7 -0
- package/dist/core/completions/templates/fish-templates.js +45 -0
- package/dist/core/completions/templates/powershell-templates.d.ts +6 -0
- package/dist/core/completions/templates/powershell-templates.js +34 -0
- package/dist/core/completions/templates/zsh-templates.d.ts +6 -0
- package/dist/core/completions/templates/zsh-templates.js +45 -0
- package/dist/core/completions/types.d.ts +101 -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 +86 -0
- package/dist/core/config-schema.js +213 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.js +38 -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 +49 -0
- package/dist/core/global-config.js +124 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +4 -0
- package/dist/core/init.d.ts +37 -0
- package/dist/core/init.js +585 -0
- package/dist/core/legacy-cleanup.d.ts +169 -0
- package/dist/core/legacy-cleanup.js +578 -0
- package/dist/core/list.d.ts +9 -0
- package/dist/core/list.js +172 -0
- package/dist/core/migration.d.ts +23 -0
- package/dist/core/migration.js +108 -0
- package/dist/core/parsers/change-parser.d.ts +13 -0
- package/dist/core/parsers/change-parser.js +197 -0
- package/dist/core/parsers/markdown-parser.d.ts +26 -0
- package/dist/core/parsers/markdown-parser.js +227 -0
- package/dist/core/parsers/requirement-blocks.d.ts +37 -0
- package/dist/core/parsers/requirement-blocks.js +201 -0
- package/dist/core/parsers/spec-structure.d.ts +9 -0
- package/dist/core/parsers/spec-structure.js +88 -0
- package/dist/core/profile-sync-drift.d.ts +38 -0
- package/dist/core/profile-sync-drift.js +197 -0
- package/dist/core/profiles.d.ts +26 -0
- package/dist/core/profiles.js +37 -0
- package/dist/core/project-config.d.ts +64 -0
- package/dist/core/project-config.js +224 -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 +49 -0
- package/dist/core/shared/skill-generation.js +90 -0
- package/dist/core/shared/tool-detection.d.ts +71 -0
- package/dist/core/shared/tool-detection.js +152 -0
- package/dist/core/specs-apply.d.ts +73 -0
- package/dist/core/specs-apply.js +393 -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 +15 -0
- package/dist/core/templates/skill-templates.js +14 -0
- package/dist/core/templates/types.d.ts +19 -0
- package/dist/core/templates/types.js +5 -0
- package/dist/core/templates/workflows/analyze.d.ts +4 -0
- package/dist/core/templates/workflows/analyze.js +101 -0
- package/dist/core/templates/workflows/apply-change.d.ts +10 -0
- package/dist/core/templates/workflows/apply-change.js +308 -0
- package/dist/core/templates/workflows/archive-change.d.ts +10 -0
- package/dist/core/templates/workflows/archive-change.js +271 -0
- package/dist/core/templates/workflows/clarify.d.ts +4 -0
- package/dist/core/templates/workflows/clarify.js +108 -0
- package/dist/core/templates/workflows/debug.d.ts +4 -0
- package/dist/core/templates/workflows/debug.js +117 -0
- package/dist/core/templates/workflows/explore.d.ts +10 -0
- package/dist/core/templates/workflows/explore.js +479 -0
- package/dist/core/templates/workflows/propose.d.ts +10 -0
- package/dist/core/templates/workflows/propose.js +216 -0
- package/dist/core/templates/workflows/sync.d.ts +4 -0
- package/dist/core/templates/workflows/sync.js +108 -0
- package/dist/core/update.d.ts +82 -0
- package/dist/core/update.js +555 -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 +418 -0
- package/dist/core/view.d.ts +8 -0
- package/dist/core/view.js +169 -0
- package/dist/core/workspace/foundation.d.ts +79 -0
- package/dist/core/workspace/foundation.js +367 -0
- package/dist/core/workspace/index.d.ts +5 -0
- package/dist/core/workspace/index.js +5 -0
- package/dist/core/workspace/link-input.d.ts +9 -0
- package/dist/core/workspace/link-input.js +32 -0
- package/dist/core/workspace/open-surface.d.ts +24 -0
- package/dist/core/workspace/open-surface.js +137 -0
- package/dist/core/workspace/openers.d.ts +21 -0
- package/dist/core/workspace/openers.js +119 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/prompts/searchable-multi-select.d.ts +28 -0
- package/dist/prompts/searchable-multi-select.js +159 -0
- package/dist/ui/ascii-patterns.d.ts +25 -0
- package/dist/ui/ascii-patterns.js +140 -0
- package/dist/ui/welcome-screen.d.ts +10 -0
- package/dist/ui/welcome-screen.js +144 -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 +122 -0
- package/dist/utils/command-references.d.ts +18 -0
- package/dist/utils/command-references.js +20 -0
- package/dist/utils/file-system.d.ts +41 -0
- package/dist/utils/file-system.js +301 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +9 -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 +73 -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 +76 -0
- package/schemas/synarcx/schema.yaml +153 -0
- package/schemas/synarcx/templates/design.md +19 -0
- package/schemas/synarcx/templates/proposal.md +23 -0
- package/schemas/synarcx/templates/spec.md +8 -0
- package/schemas/synarcx/templates/tasks.md +9 -0
- package/scripts/postinstall.js +83 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { ZSH_DYNAMIC_HELPERS } from '../templates/zsh-templates.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates Zsh completion scripts for the synarcx CLI.
|
|
4
|
+
* Follows Zsh completion system conventions using the _synarcx function.
|
|
5
|
+
*/
|
|
6
|
+
export class ZshGenerator {
|
|
7
|
+
shell = 'zsh';
|
|
8
|
+
/**
|
|
9
|
+
* Generate a Zsh completion script
|
|
10
|
+
*
|
|
11
|
+
* @param commands - Command definitions to generate completions for
|
|
12
|
+
* @returns Zsh completion script as a string
|
|
13
|
+
*/
|
|
14
|
+
generate(commands) {
|
|
15
|
+
// Build command list using push() for loop clarity
|
|
16
|
+
const commandLines = [];
|
|
17
|
+
for (const cmd of commands) {
|
|
18
|
+
const escapedDesc = this.escapeDescription(cmd.description);
|
|
19
|
+
commandLines.push(` '${cmd.name}:${escapedDesc}'`);
|
|
20
|
+
}
|
|
21
|
+
const commandList = commandLines.join('\n');
|
|
22
|
+
// Build command cases using push() for loop clarity
|
|
23
|
+
const commandCaseLines = [];
|
|
24
|
+
for (const cmd of commands) {
|
|
25
|
+
commandCaseLines.push(` ${cmd.name})`);
|
|
26
|
+
commandCaseLines.push(` _synarcx_${this.sanitizeFunctionName(cmd.name)}`);
|
|
27
|
+
commandCaseLines.push(' ;;');
|
|
28
|
+
}
|
|
29
|
+
const commandCases = commandCaseLines.join('\n');
|
|
30
|
+
// Build command functions using push() for loop clarity
|
|
31
|
+
const commandFunctionLines = [];
|
|
32
|
+
for (const cmd of commands) {
|
|
33
|
+
commandFunctionLines.push(...this.generateCommandFunction(cmd));
|
|
34
|
+
commandFunctionLines.push('');
|
|
35
|
+
}
|
|
36
|
+
const commandFunctions = commandFunctionLines.join('\n');
|
|
37
|
+
// Dynamic completion helpers from template
|
|
38
|
+
const helpers = ZSH_DYNAMIC_HELPERS;
|
|
39
|
+
// Assemble final script with template literal
|
|
40
|
+
return `#compdef synarcx
|
|
41
|
+
|
|
42
|
+
# Zsh completion script for synarcx CLI
|
|
43
|
+
# Auto-generated - do not edit manually
|
|
44
|
+
|
|
45
|
+
_synarcx() {
|
|
46
|
+
local context state line
|
|
47
|
+
typeset -A opt_args
|
|
48
|
+
|
|
49
|
+
local -a commands
|
|
50
|
+
commands=(
|
|
51
|
+
${commandList}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
_arguments -C \\
|
|
55
|
+
"1: :->command" \\
|
|
56
|
+
"*::arg:->args"
|
|
57
|
+
|
|
58
|
+
case $state in
|
|
59
|
+
command)
|
|
60
|
+
_describe "synarcx command" commands
|
|
61
|
+
;;
|
|
62
|
+
args)
|
|
63
|
+
case $words[1] in
|
|
64
|
+
${commandCases}
|
|
65
|
+
esac
|
|
66
|
+
;;
|
|
67
|
+
esac
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
${commandFunctions}
|
|
71
|
+
${helpers}
|
|
72
|
+
compdef _synarcx synarcx
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Generate completion function for a specific command
|
|
77
|
+
*/
|
|
78
|
+
generateCommandFunction(cmd) {
|
|
79
|
+
const funcName = `_synarcx_${this.sanitizeFunctionName(cmd.name)}`;
|
|
80
|
+
const lines = [];
|
|
81
|
+
lines.push(`${funcName}() {`);
|
|
82
|
+
// If command has subcommands, handle them
|
|
83
|
+
if (cmd.subcommands && cmd.subcommands.length > 0) {
|
|
84
|
+
lines.push(' local context state line');
|
|
85
|
+
lines.push(' typeset -A opt_args');
|
|
86
|
+
lines.push('');
|
|
87
|
+
lines.push(' local -a subcommands');
|
|
88
|
+
lines.push(' subcommands=(');
|
|
89
|
+
for (const subcmd of cmd.subcommands) {
|
|
90
|
+
const escapedDesc = this.escapeDescription(subcmd.description);
|
|
91
|
+
lines.push(` '${subcmd.name}:${escapedDesc}'`);
|
|
92
|
+
}
|
|
93
|
+
lines.push(' )');
|
|
94
|
+
lines.push('');
|
|
95
|
+
lines.push(' _arguments -C \\');
|
|
96
|
+
// Add command flags
|
|
97
|
+
for (const flag of cmd.flags) {
|
|
98
|
+
lines.push(' ' + this.generateFlagSpec(flag) + ' \\');
|
|
99
|
+
}
|
|
100
|
+
lines.push(' "1: :->subcommand" \\');
|
|
101
|
+
lines.push(' "*::arg:->args"');
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push(' case $state in');
|
|
104
|
+
lines.push(' subcommand)');
|
|
105
|
+
lines.push(' _describe "subcommand" subcommands');
|
|
106
|
+
lines.push(' ;;');
|
|
107
|
+
lines.push(' args)');
|
|
108
|
+
lines.push(' case $words[1] in');
|
|
109
|
+
for (const subcmd of cmd.subcommands) {
|
|
110
|
+
lines.push(` ${subcmd.name})`);
|
|
111
|
+
lines.push(` _synarcx_${this.sanitizeFunctionName(cmd.name)}_${this.sanitizeFunctionName(subcmd.name)}`);
|
|
112
|
+
lines.push(' ;;');
|
|
113
|
+
}
|
|
114
|
+
lines.push(' esac');
|
|
115
|
+
lines.push(' ;;');
|
|
116
|
+
lines.push(' esac');
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Command without subcommands
|
|
120
|
+
lines.push(' _arguments \\');
|
|
121
|
+
// Add flags
|
|
122
|
+
for (const flag of cmd.flags) {
|
|
123
|
+
lines.push(' ' + this.generateFlagSpec(flag) + ' \\');
|
|
124
|
+
}
|
|
125
|
+
this.appendPositionalSpecs(lines, cmd);
|
|
126
|
+
}
|
|
127
|
+
lines.push('}');
|
|
128
|
+
// Generate subcommand functions if they exist
|
|
129
|
+
if (cmd.subcommands) {
|
|
130
|
+
for (const subcmd of cmd.subcommands) {
|
|
131
|
+
lines.push('');
|
|
132
|
+
lines.push(...this.generateSubcommandFunction(cmd.name, subcmd));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return lines;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Generate completion function for a subcommand
|
|
139
|
+
*/
|
|
140
|
+
generateSubcommandFunction(parentName, subcmd) {
|
|
141
|
+
const funcName = `_synarcx_${this.sanitizeFunctionName(parentName)}_${this.sanitizeFunctionName(subcmd.name)}`;
|
|
142
|
+
const lines = [];
|
|
143
|
+
lines.push(`${funcName}() {`);
|
|
144
|
+
lines.push(' _arguments \\');
|
|
145
|
+
// Add flags
|
|
146
|
+
for (const flag of subcmd.flags) {
|
|
147
|
+
lines.push(' ' + this.generateFlagSpec(flag) + ' \\');
|
|
148
|
+
}
|
|
149
|
+
this.appendPositionalSpecs(lines, subcmd);
|
|
150
|
+
lines.push('}');
|
|
151
|
+
return lines;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Generate flag specification for _arguments
|
|
155
|
+
*/
|
|
156
|
+
generateFlagSpec(flag) {
|
|
157
|
+
const parts = [];
|
|
158
|
+
// Handle mutually exclusive short and long forms
|
|
159
|
+
if (flag.short) {
|
|
160
|
+
parts.push(`'(-${flag.short} --${flag.name})'{-${flag.short},--${flag.name}}'`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
parts.push(`'--${flag.name}`);
|
|
164
|
+
}
|
|
165
|
+
// Add description
|
|
166
|
+
const escapedDesc = this.escapeDescription(flag.description);
|
|
167
|
+
parts.push(`[${escapedDesc}]`);
|
|
168
|
+
// Add value completion if flag takes a value
|
|
169
|
+
if (flag.takesValue) {
|
|
170
|
+
if (flag.values && flag.values.length > 0) {
|
|
171
|
+
// Provide specific value completions
|
|
172
|
+
const valueList = flag.values.map(v => this.escapeValue(v)).join(' ');
|
|
173
|
+
parts.push(`:value:(${valueList})`);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// Generic value placeholder
|
|
177
|
+
parts.push(':value:');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Close the quote (needed for both short and long forms)
|
|
181
|
+
parts.push("'");
|
|
182
|
+
return parts.join('');
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Generate positional argument specification
|
|
186
|
+
*/
|
|
187
|
+
generatePositionalSpec(positionalType) {
|
|
188
|
+
switch (positionalType) {
|
|
189
|
+
case 'change-id':
|
|
190
|
+
return "'*: :_synarcx_complete_changes'";
|
|
191
|
+
case 'spec-id':
|
|
192
|
+
return "'*: :_synarcx_complete_specs'";
|
|
193
|
+
case 'change-or-spec-id':
|
|
194
|
+
return "'*: :_synarcx_complete_items'";
|
|
195
|
+
case 'schema-name':
|
|
196
|
+
return "'*: :_synarcx_complete_schemas'";
|
|
197
|
+
case 'path':
|
|
198
|
+
return "'*:path:_files'";
|
|
199
|
+
case 'shell':
|
|
200
|
+
return "'*:shell:(zsh bash fish powershell)'";
|
|
201
|
+
default:
|
|
202
|
+
return "'*: :_default'";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
appendPositionalSpecs(lines, cmd) {
|
|
206
|
+
const positionalSpecs = this.generatePositionalSpecs(cmd);
|
|
207
|
+
if (positionalSpecs.length === 0) {
|
|
208
|
+
if (lines[lines.length - 1].endsWith(' \\')) {
|
|
209
|
+
lines[lines.length - 1] = lines[lines.length - 1].slice(0, -2);
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
for (const [index, spec] of positionalSpecs.entries()) {
|
|
214
|
+
const suffix = index === positionalSpecs.length - 1 ? '' : ' \\';
|
|
215
|
+
lines.push(' ' + spec + suffix);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
generatePositionalSpecs(cmd) {
|
|
219
|
+
if (cmd.positionals && cmd.positionals.length > 0) {
|
|
220
|
+
return cmd.positionals.map((positional, index) => this.generateIndexedPositionalSpec(positional, index + 1));
|
|
221
|
+
}
|
|
222
|
+
if (cmd.acceptsPositional) {
|
|
223
|
+
return [this.generatePositionalSpec(cmd.positionalType)];
|
|
224
|
+
}
|
|
225
|
+
return [];
|
|
226
|
+
}
|
|
227
|
+
generateIndexedPositionalSpec(positional, index) {
|
|
228
|
+
const name = this.escapeDescription(positional.name);
|
|
229
|
+
const separator = positional.optional ? '::' : ':';
|
|
230
|
+
switch (positional.type) {
|
|
231
|
+
case 'change-id':
|
|
232
|
+
return `'${index}${separator}${name}:_synarcx_complete_changes'`;
|
|
233
|
+
case 'spec-id':
|
|
234
|
+
return `'${index}${separator}${name}:_synarcx_complete_specs'`;
|
|
235
|
+
case 'change-or-spec-id':
|
|
236
|
+
return `'${index}${separator}${name}:_synarcx_complete_items'`;
|
|
237
|
+
case 'schema-name':
|
|
238
|
+
return `'${index}${separator}${name}:_synarcx_complete_schemas'`;
|
|
239
|
+
case 'path':
|
|
240
|
+
return `'${index}${separator}${name}:_files'`;
|
|
241
|
+
case 'shell':
|
|
242
|
+
return `'${index}${separator}${name}:(zsh bash fish powershell)'`;
|
|
243
|
+
default:
|
|
244
|
+
return `'${index}${separator}${name}:'`;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Escape special characters in descriptions
|
|
249
|
+
*/
|
|
250
|
+
escapeDescription(desc) {
|
|
251
|
+
return desc
|
|
252
|
+
.replace(/\\/g, '\\\\')
|
|
253
|
+
.replace(/'/g, "\\'")
|
|
254
|
+
.replace(/\[/g, '\\[')
|
|
255
|
+
.replace(/]/g, '\\]')
|
|
256
|
+
.replace(/:/g, '\\:');
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Escape special characters in values
|
|
260
|
+
*/
|
|
261
|
+
escapeValue(value) {
|
|
262
|
+
return value
|
|
263
|
+
.replace(/\\/g, '\\\\')
|
|
264
|
+
.replace(/'/g, "\\'")
|
|
265
|
+
.replace(/ /g, '\\ ');
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Sanitize command names for use in function names
|
|
269
|
+
*/
|
|
270
|
+
sanitizeFunctionName(name) {
|
|
271
|
+
return name.replace(/-/g, '_');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=zsh-generator.js.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { InstallationResult } from '../factory.js';
|
|
2
|
+
/**
|
|
3
|
+
* Installer for Bash completion scripts.
|
|
4
|
+
* Supports bash-completion package and standalone installations.
|
|
5
|
+
*/
|
|
6
|
+
export declare class BashInstaller {
|
|
7
|
+
private readonly homeDir;
|
|
8
|
+
/**
|
|
9
|
+
* Markers for .bashrc configuration management
|
|
10
|
+
*/
|
|
11
|
+
private readonly BASHRC_MARKERS;
|
|
12
|
+
constructor(homeDir?: string);
|
|
13
|
+
/**
|
|
14
|
+
* Check if bash-completion is installed
|
|
15
|
+
*
|
|
16
|
+
* @returns true if bash-completion directories exist
|
|
17
|
+
*/
|
|
18
|
+
isBashCompletionInstalled(): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the appropriate installation path for the completion script
|
|
21
|
+
*
|
|
22
|
+
* @returns Installation path
|
|
23
|
+
*/
|
|
24
|
+
getInstallationPath(): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Backup an existing completion file if it exists
|
|
27
|
+
*
|
|
28
|
+
* @param targetPath - Path to the file to backup
|
|
29
|
+
* @returns Path to the backup file, or undefined if no backup was needed
|
|
30
|
+
*/
|
|
31
|
+
backupExistingFile(targetPath: string): Promise<string | undefined>;
|
|
32
|
+
/**
|
|
33
|
+
* Get the path to .bashrc file
|
|
34
|
+
*
|
|
35
|
+
* @returns Path to .bashrc
|
|
36
|
+
*/
|
|
37
|
+
private getBashrcPath;
|
|
38
|
+
/**
|
|
39
|
+
* Generate .bashrc configuration content
|
|
40
|
+
*
|
|
41
|
+
* @param completionsDir - Directory containing completion scripts
|
|
42
|
+
* @returns Configuration content
|
|
43
|
+
*/
|
|
44
|
+
private generateBashrcConfig;
|
|
45
|
+
/**
|
|
46
|
+
* Configure .bashrc to enable completions
|
|
47
|
+
*
|
|
48
|
+
* @param completionsDir - Directory containing completion scripts
|
|
49
|
+
* @returns true if configured successfully, false otherwise
|
|
50
|
+
*/
|
|
51
|
+
configureBashrc(completionsDir: string): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Remove .bashrc configuration
|
|
54
|
+
* Used during uninstallation
|
|
55
|
+
*
|
|
56
|
+
* @returns true if removed successfully, false otherwise
|
|
57
|
+
*/
|
|
58
|
+
removeBashrcConfig(): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Install the completion script
|
|
61
|
+
*
|
|
62
|
+
* @param completionScript - The completion script content to install
|
|
63
|
+
* @returns Installation result with status and instructions
|
|
64
|
+
*/
|
|
65
|
+
install(completionScript: string): Promise<InstallationResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Generate user instructions for enabling completions
|
|
68
|
+
*
|
|
69
|
+
* @param installedPath - Path where the script was installed
|
|
70
|
+
* @returns Array of instruction strings
|
|
71
|
+
*/
|
|
72
|
+
private generateInstructions;
|
|
73
|
+
/**
|
|
74
|
+
* Uninstall the completion script
|
|
75
|
+
*
|
|
76
|
+
* @param options - Optional uninstall options
|
|
77
|
+
* @param options.yes - Skip confirmation prompt (handled by command layer)
|
|
78
|
+
* @returns Uninstallation result
|
|
79
|
+
*/
|
|
80
|
+
uninstall(options?: {
|
|
81
|
+
yes?: boolean;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
success: boolean;
|
|
84
|
+
message: string;
|
|
85
|
+
}>;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=bash-installer.d.ts.map
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { FileSystemUtils } from '../../../utils/file-system.js';
|
|
5
|
+
/**
|
|
6
|
+
* Installer for Bash completion scripts.
|
|
7
|
+
* Supports bash-completion package and standalone installations.
|
|
8
|
+
*/
|
|
9
|
+
export class BashInstaller {
|
|
10
|
+
homeDir;
|
|
11
|
+
/**
|
|
12
|
+
* Markers for .bashrc configuration management
|
|
13
|
+
*/
|
|
14
|
+
BASHRC_MARKERS = {
|
|
15
|
+
start: '# OPENSPEC:START',
|
|
16
|
+
end: '# OPENSPEC:END',
|
|
17
|
+
};
|
|
18
|
+
constructor(homeDir = os.homedir()) {
|
|
19
|
+
this.homeDir = homeDir;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check if bash-completion is installed
|
|
23
|
+
*
|
|
24
|
+
* @returns true if bash-completion directories exist
|
|
25
|
+
*/
|
|
26
|
+
async isBashCompletionInstalled() {
|
|
27
|
+
const paths = [
|
|
28
|
+
'/usr/share/bash-completion', // Linux system-wide
|
|
29
|
+
'/usr/local/share/bash-completion', // Homebrew Intel (main)
|
|
30
|
+
'/opt/homebrew/etc/bash_completion.d', // Homebrew Apple Silicon
|
|
31
|
+
'/usr/local/etc/bash_completion.d', // Homebrew Intel (alt path)
|
|
32
|
+
'/etc/bash_completion.d', // Legacy fallback
|
|
33
|
+
];
|
|
34
|
+
for (const p of paths) {
|
|
35
|
+
try {
|
|
36
|
+
const stat = await fs.stat(p);
|
|
37
|
+
if (stat.isDirectory()) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Continue checking other paths
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the appropriate installation path for the completion script
|
|
49
|
+
*
|
|
50
|
+
* @returns Installation path
|
|
51
|
+
*/
|
|
52
|
+
async getInstallationPath() {
|
|
53
|
+
// Try user-local bash-completion directory first
|
|
54
|
+
const localCompletionDir = path.join(this.homeDir, '.local', 'share', 'bash-completion', 'completions');
|
|
55
|
+
// For user installation, use local directory
|
|
56
|
+
return path.join(localCompletionDir, 'synarcx');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Backup an existing completion file if it exists
|
|
60
|
+
*
|
|
61
|
+
* @param targetPath - Path to the file to backup
|
|
62
|
+
* @returns Path to the backup file, or undefined if no backup was needed
|
|
63
|
+
*/
|
|
64
|
+
async backupExistingFile(targetPath) {
|
|
65
|
+
try {
|
|
66
|
+
await fs.access(targetPath);
|
|
67
|
+
// File exists, create a backup
|
|
68
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
69
|
+
const backupPath = `${targetPath}.backup-${timestamp}`;
|
|
70
|
+
await fs.copyFile(targetPath, backupPath);
|
|
71
|
+
return backupPath;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// File doesn't exist, no backup needed
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the path to .bashrc file
|
|
80
|
+
*
|
|
81
|
+
* @returns Path to .bashrc
|
|
82
|
+
*/
|
|
83
|
+
getBashrcPath() {
|
|
84
|
+
return path.join(this.homeDir, '.bashrc');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generate .bashrc configuration content
|
|
88
|
+
*
|
|
89
|
+
* @param completionsDir - Directory containing completion scripts
|
|
90
|
+
* @returns Configuration content
|
|
91
|
+
*/
|
|
92
|
+
generateBashrcConfig(completionsDir) {
|
|
93
|
+
return [
|
|
94
|
+
'# synarcx shell completions configuration',
|
|
95
|
+
`if [ -d "${completionsDir}" ]; then`,
|
|
96
|
+
` for f in "${completionsDir}"/*; do`,
|
|
97
|
+
' [ -f "$f" ] && . "$f"',
|
|
98
|
+
' done',
|
|
99
|
+
'fi',
|
|
100
|
+
].join('\n');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Configure .bashrc to enable completions
|
|
104
|
+
*
|
|
105
|
+
* @param completionsDir - Directory containing completion scripts
|
|
106
|
+
* @returns true if configured successfully, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
async configureBashrc(completionsDir) {
|
|
109
|
+
// Check if auto-configuration is disabled
|
|
110
|
+
if (process.env.OPENSPEC_NO_AUTO_CONFIG === '1') {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
const bashrcPath = this.getBashrcPath();
|
|
115
|
+
const config = this.generateBashrcConfig(completionsDir);
|
|
116
|
+
// Check write permissions
|
|
117
|
+
const canWrite = await FileSystemUtils.canWriteFile(bashrcPath);
|
|
118
|
+
if (!canWrite) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
// Use marker-based update
|
|
122
|
+
await FileSystemUtils.updateFileWithMarkers(bashrcPath, config, this.BASHRC_MARKERS.start, this.BASHRC_MARKERS.end);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
// Fail gracefully - don't break installation
|
|
127
|
+
console.debug(`Unable to configure .bashrc for completions: ${error.message}`);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Remove .bashrc configuration
|
|
133
|
+
* Used during uninstallation
|
|
134
|
+
*
|
|
135
|
+
* @returns true if removed successfully, false otherwise
|
|
136
|
+
*/
|
|
137
|
+
async removeBashrcConfig() {
|
|
138
|
+
try {
|
|
139
|
+
const bashrcPath = this.getBashrcPath();
|
|
140
|
+
// Check if file exists
|
|
141
|
+
try {
|
|
142
|
+
await fs.access(bashrcPath);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// File doesn't exist, nothing to remove
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
// Read file content
|
|
149
|
+
const content = await fs.readFile(bashrcPath, 'utf-8');
|
|
150
|
+
// Check if markers exist
|
|
151
|
+
if (!content.includes(this.BASHRC_MARKERS.start) || !content.includes(this.BASHRC_MARKERS.end)) {
|
|
152
|
+
// Markers don't exist, nothing to remove
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
// Remove content between markers (including markers)
|
|
156
|
+
const lines = content.split('\n');
|
|
157
|
+
const startIndex = lines.findIndex((line) => line.trim() === this.BASHRC_MARKERS.start);
|
|
158
|
+
const endIndex = lines.findIndex((line) => line.trim() === this.BASHRC_MARKERS.end);
|
|
159
|
+
if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
|
|
160
|
+
// Invalid marker placement
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
// Remove lines between markers (inclusive)
|
|
164
|
+
lines.splice(startIndex, endIndex - startIndex + 1);
|
|
165
|
+
// Remove trailing empty lines
|
|
166
|
+
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
|
|
167
|
+
lines.pop();
|
|
168
|
+
}
|
|
169
|
+
// Write back
|
|
170
|
+
await fs.writeFile(bashrcPath, lines.join('\n'), 'utf-8');
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
// Fail gracefully
|
|
175
|
+
console.debug(`Unable to remove .bashrc configuration: ${error.message}`);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Install the completion script
|
|
181
|
+
*
|
|
182
|
+
* @param completionScript - The completion script content to install
|
|
183
|
+
* @returns Installation result with status and instructions
|
|
184
|
+
*/
|
|
185
|
+
async install(completionScript) {
|
|
186
|
+
try {
|
|
187
|
+
const targetPath = await this.getInstallationPath();
|
|
188
|
+
// Check for bash-completion package
|
|
189
|
+
const hasBashCompletion = await this.isBashCompletionInstalled();
|
|
190
|
+
// Check if already installed with same content
|
|
191
|
+
let isUpdate = false;
|
|
192
|
+
try {
|
|
193
|
+
const existingContent = await fs.readFile(targetPath, 'utf-8');
|
|
194
|
+
if (existingContent === completionScript) {
|
|
195
|
+
// Already installed and up to date
|
|
196
|
+
return {
|
|
197
|
+
success: true,
|
|
198
|
+
installedPath: targetPath,
|
|
199
|
+
message: 'Completion script is already installed (up to date)',
|
|
200
|
+
instructions: [
|
|
201
|
+
'The completion script is already installed and up to date.',
|
|
202
|
+
'If completions are not working, try: exec bash',
|
|
203
|
+
],
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// File exists but content is different - this is an update
|
|
207
|
+
isUpdate = true;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
// File doesn't exist or can't be read, proceed with installation
|
|
211
|
+
console.debug(`Unable to read existing completion file at ${targetPath}: ${error.message}`);
|
|
212
|
+
}
|
|
213
|
+
// Ensure the directory exists
|
|
214
|
+
const targetDir = path.dirname(targetPath);
|
|
215
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
216
|
+
// Backup existing file if updating
|
|
217
|
+
const backupPath = isUpdate ? await this.backupExistingFile(targetPath) : undefined;
|
|
218
|
+
// Write the completion script
|
|
219
|
+
await fs.writeFile(targetPath, completionScript, 'utf-8');
|
|
220
|
+
// Auto-configure .bashrc
|
|
221
|
+
const bashrcConfigured = await this.configureBashrc(targetDir);
|
|
222
|
+
// Generate instructions if .bashrc wasn't auto-configured
|
|
223
|
+
const instructions = bashrcConfigured ? undefined : this.generateInstructions(targetPath);
|
|
224
|
+
// Collect warnings
|
|
225
|
+
const warnings = [];
|
|
226
|
+
if (!hasBashCompletion) {
|
|
227
|
+
warnings.push('⚠️ Warning: bash-completion package not detected', '', 'The completion script requires bash-completion to function.', 'Install it with:', ' brew install bash-completion@2', '', 'Then add to your ~/.bash_profile:', ' [[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ]] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"');
|
|
228
|
+
}
|
|
229
|
+
// Determine appropriate message
|
|
230
|
+
let message;
|
|
231
|
+
if (isUpdate) {
|
|
232
|
+
message = backupPath
|
|
233
|
+
? 'Completion script updated successfully (previous version backed up)'
|
|
234
|
+
: 'Completion script updated successfully';
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
message = bashrcConfigured
|
|
238
|
+
? 'Completion script installed and .bashrc configured successfully'
|
|
239
|
+
: 'Completion script installed successfully for Bash';
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
installedPath: targetPath,
|
|
244
|
+
backupPath,
|
|
245
|
+
bashrcConfigured,
|
|
246
|
+
message,
|
|
247
|
+
instructions,
|
|
248
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
return {
|
|
253
|
+
success: false,
|
|
254
|
+
message: `Failed to install completion script: ${error instanceof Error ? error.message : String(error)}`,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Generate user instructions for enabling completions
|
|
260
|
+
*
|
|
261
|
+
* @param installedPath - Path where the script was installed
|
|
262
|
+
* @returns Array of instruction strings
|
|
263
|
+
*/
|
|
264
|
+
generateInstructions(installedPath) {
|
|
265
|
+
const completionsDir = path.dirname(installedPath);
|
|
266
|
+
return [
|
|
267
|
+
'Completion script installed successfully.',
|
|
268
|
+
'',
|
|
269
|
+
'To enable completions, add the following to your ~/.bashrc file:',
|
|
270
|
+
'',
|
|
271
|
+
` # Source synarcx completions`,
|
|
272
|
+
` if [ -d "${completionsDir}" ]; then`,
|
|
273
|
+
` for f in "${completionsDir}"/*; do`,
|
|
274
|
+
' [ -f "$f" ] && . "$f"',
|
|
275
|
+
' done',
|
|
276
|
+
' fi',
|
|
277
|
+
'',
|
|
278
|
+
'Then restart your shell or run: exec bash',
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Uninstall the completion script
|
|
283
|
+
*
|
|
284
|
+
* @param options - Optional uninstall options
|
|
285
|
+
* @param options.yes - Skip confirmation prompt (handled by command layer)
|
|
286
|
+
* @returns Uninstallation result
|
|
287
|
+
*/
|
|
288
|
+
async uninstall(options) {
|
|
289
|
+
try {
|
|
290
|
+
const targetPath = await this.getInstallationPath();
|
|
291
|
+
// Check if installed
|
|
292
|
+
try {
|
|
293
|
+
await fs.access(targetPath);
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
return {
|
|
297
|
+
success: false,
|
|
298
|
+
message: 'Completion script is not installed',
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
// Remove the completion script
|
|
302
|
+
await fs.unlink(targetPath);
|
|
303
|
+
// Remove .bashrc configuration
|
|
304
|
+
await this.removeBashrcConfig();
|
|
305
|
+
return {
|
|
306
|
+
success: true,
|
|
307
|
+
message: 'Completion script uninstalled successfully',
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
return {
|
|
312
|
+
success: false,
|
|
313
|
+
message: `Failed to uninstall completion script: ${error instanceof Error ? error.message : String(error)}`,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=bash-installer.js.map
|