@fission-ai/openspec 0.16.0 → 0.17.1

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 (39) hide show
  1. package/README.md +21 -14
  2. package/dist/cli/index.js +67 -2
  3. package/dist/commands/change.js +4 -3
  4. package/dist/commands/completion.d.ts +72 -0
  5. package/dist/commands/completion.js +221 -0
  6. package/dist/commands/config.d.ts +8 -0
  7. package/dist/commands/config.js +198 -0
  8. package/dist/commands/show.js +3 -2
  9. package/dist/commands/spec.js +4 -3
  10. package/dist/commands/validate.js +21 -2
  11. package/dist/core/archive.js +4 -1
  12. package/dist/core/completions/command-registry.d.ts +7 -0
  13. package/dist/core/completions/command-registry.js +362 -0
  14. package/dist/core/completions/completion-provider.d.ts +60 -0
  15. package/dist/core/completions/completion-provider.js +102 -0
  16. package/dist/core/completions/factory.d.ts +51 -0
  17. package/dist/core/completions/factory.js +57 -0
  18. package/dist/core/completions/generators/zsh-generator.d.ts +58 -0
  19. package/dist/core/completions/generators/zsh-generator.js +319 -0
  20. package/dist/core/completions/installers/zsh-installer.d.ts +136 -0
  21. package/dist/core/completions/installers/zsh-installer.js +449 -0
  22. package/dist/core/completions/types.d.ts +78 -0
  23. package/dist/core/completions/types.js +2 -0
  24. package/dist/core/config-schema.d.ts +76 -0
  25. package/dist/core/config-schema.js +200 -0
  26. package/dist/core/configurators/slash/opencode.js +0 -3
  27. package/dist/core/global-config.d.ts +29 -0
  28. package/dist/core/global-config.js +87 -0
  29. package/dist/core/index.d.ts +1 -1
  30. package/dist/core/index.js +2 -1
  31. package/dist/utils/file-system.js +19 -3
  32. package/dist/utils/interactive.d.ts +12 -1
  33. package/dist/utils/interactive.js +7 -2
  34. package/dist/utils/item-discovery.d.ts +1 -0
  35. package/dist/utils/item-discovery.js +23 -0
  36. package/dist/utils/shell-detection.d.ts +20 -0
  37. package/dist/utils/shell-detection.js +41 -0
  38. package/package.json +7 -1
  39. package/scripts/postinstall.js +147 -0
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script for auto-installing shell completions
5
+ *
6
+ * This script runs automatically after npm install unless:
7
+ * - CI=true environment variable is set
8
+ * - OPENSPEC_NO_COMPLETIONS=1 environment variable is set
9
+ * - dist/ directory doesn't exist (dev setup scenario)
10
+ *
11
+ * The script never fails npm install - all errors are caught and handled gracefully.
12
+ */
13
+
14
+ import { promises as fs } from 'fs';
15
+ import path from 'path';
16
+ import { fileURLToPath } from 'url';
17
+
18
+ const __filename = fileURLToPath(import.meta.url);
19
+ const __dirname = path.dirname(__filename);
20
+
21
+ /**
22
+ * Check if we should skip installation
23
+ */
24
+ function shouldSkipInstallation() {
25
+ // Skip in CI environments
26
+ if (process.env.CI === 'true' || process.env.CI === '1') {
27
+ return { skip: true, reason: 'CI environment detected' };
28
+ }
29
+
30
+ // Skip if user opted out
31
+ if (process.env.OPENSPEC_NO_COMPLETIONS === '1') {
32
+ return { skip: true, reason: 'OPENSPEC_NO_COMPLETIONS=1 set' };
33
+ }
34
+
35
+ return { skip: false };
36
+ }
37
+
38
+ /**
39
+ * Check if dist/ directory exists
40
+ */
41
+ async function distExists() {
42
+ const distPath = path.join(__dirname, '..', 'dist');
43
+ try {
44
+ const stat = await fs.stat(distPath);
45
+ return stat.isDirectory();
46
+ } catch {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Detect the user's shell
53
+ */
54
+ async function detectShell() {
55
+ try {
56
+ const { detectShell } = await import('../dist/utils/shell-detection.js');
57
+ const result = detectShell();
58
+ return result.shell;
59
+ } catch (error) {
60
+ // Fail silently if detection module doesn't exist
61
+ return undefined;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Install completions for the detected shell
67
+ */
68
+ async function installCompletions(shell) {
69
+ try {
70
+ const { CompletionFactory } = await import('../dist/core/completions/factory.js');
71
+ const { COMMAND_REGISTRY } = await import('../dist/core/completions/command-registry.js');
72
+
73
+ // Check if shell is supported
74
+ if (!CompletionFactory.isSupported(shell)) {
75
+ console.log(`\nTip: Run 'openspec completion install' for shell completions`);
76
+ return;
77
+ }
78
+
79
+ // Generate completion script
80
+ const generator = CompletionFactory.createGenerator(shell);
81
+ const script = generator.generate(COMMAND_REGISTRY);
82
+
83
+ // Install completion script
84
+ const installer = CompletionFactory.createInstaller(shell);
85
+ const result = await installer.install(script);
86
+
87
+ if (result.success) {
88
+ // Show success message based on installation type
89
+ if (result.isOhMyZsh) {
90
+ console.log(`✓ Shell completions installed`);
91
+ console.log(` Restart shell: exec zsh`);
92
+ } else if (result.zshrcConfigured) {
93
+ console.log(`✓ Shell completions installed and configured`);
94
+ console.log(` Restart shell: exec zsh`);
95
+ } else {
96
+ console.log(`✓ Shell completions installed to ~/.zsh/completions/`);
97
+ console.log(` Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath)`);
98
+ console.log(` Then: exec zsh`);
99
+ }
100
+ } else {
101
+ // Installation failed, show tip for manual install
102
+ console.log(`\nTip: Run 'openspec completion install' for shell completions`);
103
+ }
104
+ } catch (error) {
105
+ // Fail gracefully - show tip for manual install
106
+ console.log(`\nTip: Run 'openspec completion install' for shell completions`);
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Main function
112
+ */
113
+ async function main() {
114
+ try {
115
+ // Check if we should skip
116
+ const skipCheck = shouldSkipInstallation();
117
+ if (skipCheck.skip) {
118
+ // Silent skip - no output
119
+ return;
120
+ }
121
+
122
+ // Check if dist/ exists (skip silently if not - expected during dev setup)
123
+ if (!(await distExists())) {
124
+ return;
125
+ }
126
+
127
+ // Detect shell
128
+ const shell = await detectShell();
129
+ if (!shell) {
130
+ console.log(`\nTip: Run 'openspec completion install' for shell completions`);
131
+ return;
132
+ }
133
+
134
+ // Install completions
135
+ await installCompletions(shell);
136
+ } catch (error) {
137
+ // Fail gracefully - never break npm install
138
+ // Show tip for manual install
139
+ console.log(`\nTip: Run 'openspec completion install' for shell completions`);
140
+ }
141
+ }
142
+
143
+ // Run main and handle any unhandled errors
144
+ main().catch(() => {
145
+ // Silent failure - never break npm install
146
+ process.exit(0);
147
+ });