@speclife/core 0.9.2 → 0.11.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 (89) hide show
  1. package/dist/completions/bash-generator.d.ts +13 -0
  2. package/dist/completions/bash-generator.d.ts.map +1 -0
  3. package/dist/completions/bash-generator.js +148 -0
  4. package/dist/completions/bash-generator.js.map +1 -0
  5. package/dist/completions/commands.d.ts +14 -0
  6. package/dist/completions/commands.d.ts.map +1 -0
  7. package/dist/completions/commands.js +114 -0
  8. package/dist/completions/commands.js.map +1 -0
  9. package/dist/completions/fish-generator.d.ts +15 -0
  10. package/dist/completions/fish-generator.d.ts.map +1 -0
  11. package/dist/completions/fish-generator.js +152 -0
  12. package/dist/completions/fish-generator.js.map +1 -0
  13. package/dist/completions/index.d.ts +34 -0
  14. package/dist/completions/index.d.ts.map +1 -0
  15. package/dist/completions/index.js +52 -0
  16. package/dist/completions/index.js.map +1 -0
  17. package/dist/completions/types.d.ts +61 -0
  18. package/dist/completions/types.d.ts.map +1 -0
  19. package/dist/completions/types.js +5 -0
  20. package/dist/completions/types.js.map +1 -0
  21. package/dist/completions/zsh-generator.d.ts +16 -0
  22. package/dist/completions/zsh-generator.d.ts.map +1 -0
  23. package/dist/completions/zsh-generator.js +199 -0
  24. package/dist/completions/zsh-generator.js.map +1 -0
  25. package/dist/configurators/antigravity.d.ts +22 -0
  26. package/dist/configurators/antigravity.d.ts.map +1 -0
  27. package/dist/configurators/antigravity.js +100 -0
  28. package/dist/configurators/antigravity.js.map +1 -0
  29. package/dist/configurators/base.d.ts +67 -0
  30. package/dist/configurators/base.d.ts.map +1 -0
  31. package/dist/configurators/base.js +18 -0
  32. package/dist/configurators/base.js.map +1 -0
  33. package/dist/configurators/claude-code.d.ts +16 -0
  34. package/dist/configurators/claude-code.d.ts.map +1 -0
  35. package/dist/configurators/claude-code.js +91 -0
  36. package/dist/configurators/claude-code.js.map +1 -0
  37. package/dist/configurators/cursor.d.ts +17 -0
  38. package/dist/configurators/cursor.d.ts.map +1 -0
  39. package/dist/configurators/cursor.js +140 -0
  40. package/dist/configurators/cursor.js.map +1 -0
  41. package/dist/configurators/detector.d.ts +36 -0
  42. package/dist/configurators/detector.d.ts.map +1 -0
  43. package/dist/configurators/detector.js +131 -0
  44. package/dist/configurators/detector.js.map +1 -0
  45. package/dist/configurators/gemini.d.ts +17 -0
  46. package/dist/configurators/gemini.d.ts.map +1 -0
  47. package/dist/configurators/gemini.js +92 -0
  48. package/dist/configurators/gemini.js.map +1 -0
  49. package/dist/configurators/index.d.ts +20 -0
  50. package/dist/configurators/index.d.ts.map +1 -0
  51. package/dist/configurators/index.js +43 -0
  52. package/dist/configurators/index.js.map +1 -0
  53. package/dist/configurators/qwen.d.ts +18 -0
  54. package/dist/configurators/qwen.d.ts.map +1 -0
  55. package/dist/configurators/qwen.js +141 -0
  56. package/dist/configurators/qwen.js.map +1 -0
  57. package/dist/configurators/registry.d.ts +55 -0
  58. package/dist/configurators/registry.d.ts.map +1 -0
  59. package/dist/configurators/registry.js +82 -0
  60. package/dist/configurators/registry.js.map +1 -0
  61. package/dist/configurators/vscode.d.ts +18 -0
  62. package/dist/configurators/vscode.d.ts.map +1 -0
  63. package/dist/configurators/vscode.js +142 -0
  64. package/dist/configurators/vscode.js.map +1 -0
  65. package/dist/configurators/windsurf.d.ts +17 -0
  66. package/dist/configurators/windsurf.d.ts.map +1 -0
  67. package/dist/configurators/windsurf.js +89 -0
  68. package/dist/configurators/windsurf.js.map +1 -0
  69. package/dist/global-config.d.ts +76 -0
  70. package/dist/global-config.d.ts.map +1 -0
  71. package/dist/global-config.js +212 -0
  72. package/dist/global-config.js.map +1 -0
  73. package/dist/index.d.ts +3 -0
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +6 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/utils/index.d.ts +2 -0
  78. package/dist/utils/index.d.ts.map +1 -1
  79. package/dist/utils/index.js +2 -0
  80. package/dist/utils/index.js.map +1 -1
  81. package/dist/utils/progress.d.ts +77 -0
  82. package/dist/utils/progress.d.ts.map +1 -0
  83. package/dist/utils/progress.js +83 -0
  84. package/dist/utils/progress.js.map +1 -0
  85. package/dist/utils/task-progress.d.ts +72 -0
  86. package/dist/utils/task-progress.d.ts.map +1 -0
  87. package/dist/utils/task-progress.js +165 -0
  88. package/dist/utils/task-progress.js.map +1 -0
  89. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/configurators/claude-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Cursor editor configurator
3
+ */
4
+ import { EditorConfigurator, type ConfigureResult, type ConfigureOptions } from './base.js';
5
+ export declare class CursorConfigurator extends EditorConfigurator {
6
+ readonly name = "Cursor";
7
+ readonly id = "cursor";
8
+ readonly description = "AI-first code editor with Claude integration";
9
+ readonly configDir = ".cursor";
10
+ readonly supportsDashPrefix = true;
11
+ isAvailable(_projectPath: string): Promise<boolean>;
12
+ isConfigured(projectPath: string): Promise<boolean>;
13
+ configure(options: ConfigureOptions): Promise<ConfigureResult>;
14
+ unconfigure(projectPath: string): Promise<void>;
15
+ private discoverCommands;
16
+ }
17
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/configurators/cursor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE5F,qBAAa,kBAAmB,SAAQ,kBAAkB;IACxD,QAAQ,CAAC,IAAI,YAAY;IACzB,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,WAAW,kDAAkD;IACtE,QAAQ,CAAC,SAAS,aAAa;IAC/B,QAAQ,CAAC,kBAAkB,QAAQ;IAE7B,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnD,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6E9D,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BvC,gBAAgB;CAU/B"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Cursor editor configurator
3
+ */
4
+ import { access, mkdir, symlink, unlink, readdir, lstat, readlink } from 'fs/promises';
5
+ import { join } from 'path';
6
+ import { EditorConfigurator } from './base.js';
7
+ export class CursorConfigurator extends EditorConfigurator {
8
+ name = 'Cursor';
9
+ id = 'cursor';
10
+ description = 'AI-first code editor with Claude integration';
11
+ configDir = '.cursor';
12
+ supportsDashPrefix = true;
13
+ async isAvailable(_projectPath) {
14
+ // Cursor is always "available" as a supported editor
15
+ return true;
16
+ }
17
+ async isConfigured(projectPath) {
18
+ try {
19
+ const commandsDir = join(projectPath, this.configDir, 'commands', 'speclife');
20
+ await access(commandsDir);
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ async configure(options) {
28
+ const { projectPath, specDir, force = false } = options;
29
+ const result = {
30
+ success: true,
31
+ filesModified: [],
32
+ filesSkipped: [],
33
+ warnings: [],
34
+ };
35
+ const sourceDir = join(projectPath, specDir, 'commands', 'speclife');
36
+ const editorCommandsBase = join(projectPath, this.configDir, 'commands');
37
+ const editorCommandsDir = join(editorCommandsBase, 'speclife');
38
+ try {
39
+ // Ensure editor commands directory exists
40
+ await mkdir(editorCommandsBase, { recursive: true });
41
+ // Create symlink for speclife/ directory
42
+ try {
43
+ const stats = await lstat(editorCommandsDir);
44
+ if (stats.isSymbolicLink()) {
45
+ if (force) {
46
+ await unlink(editorCommandsDir);
47
+ await symlink(sourceDir, editorCommandsDir);
48
+ result.filesModified.push(editorCommandsDir);
49
+ }
50
+ else {
51
+ // Check if symlink points to correct location
52
+ const target = await readlink(editorCommandsDir);
53
+ if (target !== sourceDir) {
54
+ result.warnings.push(`Existing symlink points to ${target}, not ${sourceDir}`);
55
+ }
56
+ result.filesSkipped.push(editorCommandsDir);
57
+ }
58
+ }
59
+ else {
60
+ result.warnings.push(`${editorCommandsDir} exists but is not a symlink`);
61
+ result.filesSkipped.push(editorCommandsDir);
62
+ }
63
+ }
64
+ catch {
65
+ // Symlink doesn't exist, create it
66
+ await symlink(sourceDir, editorCommandsDir);
67
+ result.filesModified.push(editorCommandsDir);
68
+ }
69
+ // Create dash-prefixed symlinks for Cursor
70
+ const slashCommands = await this.discoverCommands(sourceDir);
71
+ for (const cmd of slashCommands) {
72
+ const dashFile = join(editorCommandsBase, `speclife-${cmd}.md`);
73
+ const targetFile = join('speclife', `${cmd}.md`);
74
+ try {
75
+ await access(dashFile);
76
+ if (force) {
77
+ await unlink(dashFile);
78
+ await symlink(targetFile, dashFile);
79
+ result.filesModified.push(dashFile);
80
+ }
81
+ else {
82
+ result.filesSkipped.push(dashFile);
83
+ }
84
+ }
85
+ catch {
86
+ // File doesn't exist, create symlink
87
+ try {
88
+ await symlink(targetFile, dashFile);
89
+ result.filesModified.push(dashFile);
90
+ }
91
+ catch (err) {
92
+ result.warnings.push(`Failed to create ${dashFile}: ${err}`);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ catch (err) {
98
+ result.success = false;
99
+ result.warnings.push(`Configuration failed: ${err}`);
100
+ }
101
+ return result;
102
+ }
103
+ async unconfigure(projectPath) {
104
+ const editorCommandsBase = join(projectPath, this.configDir, 'commands');
105
+ const editorCommandsDir = join(editorCommandsBase, 'speclife');
106
+ try {
107
+ // Remove speclife directory symlink
108
+ const stats = await lstat(editorCommandsDir);
109
+ if (stats.isSymbolicLink()) {
110
+ await unlink(editorCommandsDir);
111
+ }
112
+ // Remove dash-prefixed symlinks
113
+ const files = await readdir(editorCommandsBase);
114
+ for (const file of files) {
115
+ if (file.startsWith('speclife-') && file.endsWith('.md')) {
116
+ const filePath = join(editorCommandsBase, file);
117
+ const fileStats = await lstat(filePath);
118
+ if (fileStats.isSymbolicLink()) {
119
+ await unlink(filePath);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ catch {
125
+ // Ignore errors during cleanup
126
+ }
127
+ }
128
+ async discoverCommands(sourceDir) {
129
+ try {
130
+ const files = await readdir(sourceDir);
131
+ return files
132
+ .filter(f => f.endsWith('.md'))
133
+ .map(f => f.replace('.md', ''));
134
+ }
135
+ catch {
136
+ return [];
137
+ }
138
+ }
139
+ }
140
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/configurators/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Editor detection utilities
3
+ * Auto-detect which editors are installed and configured
4
+ */
5
+ import type { EditorConfigurator } from './base.js';
6
+ /** Detection result for a single editor */
7
+ export interface EditorDetectionResult {
8
+ /** Editor configurator */
9
+ editor: EditorConfigurator;
10
+ /** Whether the editor appears to be installed */
11
+ installed: boolean;
12
+ /** Whether SpecLife is configured for this editor */
13
+ configured: boolean;
14
+ /** Detection method used */
15
+ detectionMethod: 'config-dir' | 'cli' | 'process';
16
+ }
17
+ /**
18
+ * Detect all editors that appear to be installed/available
19
+ * @param projectPath Project root path
20
+ * @returns Array of detection results for available editors
21
+ */
22
+ export declare function detectEditors(projectPath: string): Promise<EditorDetectionResult[]>;
23
+ /**
24
+ * Get editors sorted by likely preference
25
+ * Detected editors first, then alphabetical
26
+ * @param results Detection results
27
+ * @returns Sorted results
28
+ */
29
+ export declare function sortByPreference(results: EditorDetectionResult[]): EditorDetectionResult[];
30
+ /**
31
+ * Get a summary of detected editors for display
32
+ * @param results Detection results
33
+ * @returns Human-readable summary
34
+ */
35
+ export declare function formatDetectionSummary(results: EditorDetectionResult[]): string;
36
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/configurators/detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpD,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IACpC,0BAA0B;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,qDAAqD;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB,4BAA4B;IAC5B,eAAe,EAAE,YAAY,GAAG,KAAK,GAAG,SAAS,CAAC;CACnD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAUzF;AAyED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,qBAAqB,EAAE,CAa1F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAsB/E"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Editor detection utilities
3
+ * Auto-detect which editors are installed and configured
4
+ */
5
+ import { access } from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { execSync } from 'child_process';
8
+ import { EditorRegistry } from './registry.js';
9
+ /**
10
+ * Detect all editors that appear to be installed/available
11
+ * @param projectPath Project root path
12
+ * @returns Array of detection results for available editors
13
+ */
14
+ export async function detectEditors(projectPath) {
15
+ const results = [];
16
+ const editors = EditorRegistry.getAll();
17
+ for (const editor of editors) {
18
+ const result = await detectEditor(editor, projectPath);
19
+ results.push(result);
20
+ }
21
+ return results;
22
+ }
23
+ /**
24
+ * Detect a single editor
25
+ * @param editor Editor configurator to check
26
+ * @param projectPath Project root path
27
+ * @returns Detection result
28
+ */
29
+ async function detectEditor(editor, projectPath) {
30
+ let installed = false;
31
+ let detectionMethod = 'config-dir';
32
+ // Method 1: Check for config directory in project
33
+ const configDir = join(projectPath, editor.configDir);
34
+ try {
35
+ await access(configDir);
36
+ installed = true;
37
+ detectionMethod = 'config-dir';
38
+ }
39
+ catch {
40
+ // Config dir doesn't exist, try other methods
41
+ }
42
+ // Method 2: Check for CLI if not detected yet
43
+ if (!installed) {
44
+ installed = await checkEditorCLI(editor.id);
45
+ if (installed) {
46
+ detectionMethod = 'cli';
47
+ }
48
+ }
49
+ // Check if configured
50
+ const configured = await editor.isConfigured(projectPath);
51
+ return {
52
+ editor,
53
+ installed,
54
+ configured,
55
+ detectionMethod,
56
+ };
57
+ }
58
+ /**
59
+ * Check if editor CLI is available in PATH
60
+ * @param editorId Editor identifier
61
+ * @returns true if CLI found
62
+ */
63
+ function checkEditorCLI(editorId) {
64
+ const cliCommands = {
65
+ cursor: ['cursor'],
66
+ 'claude-code': ['claude'],
67
+ vscode: ['code'],
68
+ windsurf: ['windsurf'],
69
+ };
70
+ const commands = cliCommands[editorId] ?? [];
71
+ for (const cmd of commands) {
72
+ try {
73
+ // Check if command exists using 'which' on Unix or 'where' on Windows
74
+ const checkCmd = process.platform === 'win32' ? 'where' : 'which';
75
+ execSync(`${checkCmd} ${cmd}`, { stdio: 'ignore' });
76
+ return Promise.resolve(true);
77
+ }
78
+ catch {
79
+ // Command not found
80
+ }
81
+ }
82
+ return Promise.resolve(false);
83
+ }
84
+ /**
85
+ * Get editors sorted by likely preference
86
+ * Detected editors first, then alphabetical
87
+ * @param results Detection results
88
+ * @returns Sorted results
89
+ */
90
+ export function sortByPreference(results) {
91
+ return [...results].sort((a, b) => {
92
+ // Installed editors first
93
+ if (a.installed && !b.installed)
94
+ return -1;
95
+ if (!a.installed && b.installed)
96
+ return 1;
97
+ // Among installed, configured first
98
+ if (a.configured && !b.configured)
99
+ return -1;
100
+ if (!a.configured && b.configured)
101
+ return 1;
102
+ // Alphabetical by name
103
+ return a.editor.name.localeCompare(b.editor.name);
104
+ });
105
+ }
106
+ /**
107
+ * Get a summary of detected editors for display
108
+ * @param results Detection results
109
+ * @returns Human-readable summary
110
+ */
111
+ export function formatDetectionSummary(results) {
112
+ const lines = [];
113
+ const installed = results.filter(r => r.installed);
114
+ const configured = results.filter(r => r.configured);
115
+ if (installed.length === 0) {
116
+ lines.push('No editors detected. You can still configure any supported editor.');
117
+ }
118
+ else {
119
+ lines.push(`Detected ${installed.length} editor(s):`);
120
+ for (const result of installed) {
121
+ const status = result.configured ? ' (configured)' : '';
122
+ lines.push(` • ${result.editor.name}${status}`);
123
+ }
124
+ }
125
+ if (configured.length > 0 && configured.length < installed.length) {
126
+ const unconfigured = installed.filter(r => !r.configured);
127
+ lines.push(`\nNot yet configured: ${unconfigured.map(r => r.editor.name).join(', ')}`);
128
+ }
129
+ return lines.join('\n');
130
+ }
131
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/configurators/detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Gemini CLI editor configurator
3
+ * Google's AI-powered CLI tool
4
+ */
5
+ import { EditorConfigurator, type ConfigureResult, type ConfigureOptions } from './base.js';
6
+ export declare class GeminiConfigurator extends EditorConfigurator {
7
+ readonly name = "Gemini CLI";
8
+ readonly id = "gemini";
9
+ readonly description = "Google's AI-powered command-line coding assistant";
10
+ readonly configDir = ".gemini";
11
+ readonly supportsDashPrefix = false;
12
+ isAvailable(_projectPath: string): Promise<boolean>;
13
+ isConfigured(projectPath: string): Promise<boolean>;
14
+ configure(options: ConfigureOptions): Promise<ConfigureResult>;
15
+ unconfigure(projectPath: string): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/configurators/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE5F,qBAAa,kBAAmB,SAAQ,kBAAkB;IACxD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,YAAY;IACvB,QAAQ,CAAC,WAAW,uDAAuD;IAC3E,QAAQ,CAAC,SAAS,aAAa;IAC/B,QAAQ,CAAC,kBAAkB,SAAS;IAE9B,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnD,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAsD9D,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYtD"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Gemini CLI editor configurator
3
+ * Google's AI-powered CLI tool
4
+ */
5
+ import { access, mkdir, symlink, unlink, lstat, readlink } from 'fs/promises';
6
+ import { join } from 'path';
7
+ import { EditorConfigurator } from './base.js';
8
+ export class GeminiConfigurator extends EditorConfigurator {
9
+ name = 'Gemini CLI';
10
+ id = 'gemini';
11
+ description = "Google's AI-powered command-line coding assistant";
12
+ configDir = '.gemini';
13
+ supportsDashPrefix = false; // Gemini CLI uses subdirectory format
14
+ async isAvailable(_projectPath) {
15
+ // Gemini CLI is always available as a supported editor
16
+ return true;
17
+ }
18
+ async isConfigured(projectPath) {
19
+ try {
20
+ const commandsDir = join(projectPath, this.configDir, 'commands', 'speclife');
21
+ await access(commandsDir);
22
+ return true;
23
+ }
24
+ catch {
25
+ return false;
26
+ }
27
+ }
28
+ async configure(options) {
29
+ const { projectPath, specDir, force = false } = options;
30
+ const result = {
31
+ success: true,
32
+ filesModified: [],
33
+ filesSkipped: [],
34
+ warnings: [],
35
+ };
36
+ const sourceDir = join(projectPath, specDir, 'commands', 'speclife');
37
+ const editorCommandsBase = join(projectPath, this.configDir, 'commands');
38
+ const editorCommandsDir = join(editorCommandsBase, 'speclife');
39
+ try {
40
+ // Ensure editor commands directory exists
41
+ await mkdir(editorCommandsBase, { recursive: true });
42
+ // Create symlink for speclife/ directory
43
+ try {
44
+ const stats = await lstat(editorCommandsDir);
45
+ if (stats.isSymbolicLink()) {
46
+ if (force) {
47
+ await unlink(editorCommandsDir);
48
+ await symlink(sourceDir, editorCommandsDir);
49
+ result.filesModified.push(editorCommandsDir);
50
+ }
51
+ else {
52
+ // Check if symlink points to correct location
53
+ const target = await readlink(editorCommandsDir);
54
+ if (target !== sourceDir) {
55
+ result.warnings.push(`Existing symlink points to ${target}, not ${sourceDir}`);
56
+ }
57
+ result.filesSkipped.push(editorCommandsDir);
58
+ }
59
+ }
60
+ else {
61
+ result.warnings.push(`${editorCommandsDir} exists but is not a symlink`);
62
+ result.filesSkipped.push(editorCommandsDir);
63
+ }
64
+ }
65
+ catch {
66
+ // Symlink doesn't exist, create it
67
+ await symlink(sourceDir, editorCommandsDir);
68
+ result.filesModified.push(editorCommandsDir);
69
+ }
70
+ // Gemini CLI doesn't need dash-prefixed symlinks
71
+ // It uses the subdirectory format: /speclife/command
72
+ }
73
+ catch (err) {
74
+ result.success = false;
75
+ result.warnings.push(`Configuration failed: ${err}`);
76
+ }
77
+ return result;
78
+ }
79
+ async unconfigure(projectPath) {
80
+ const editorCommandsDir = join(projectPath, this.configDir, 'commands', 'speclife');
81
+ try {
82
+ const stats = await lstat(editorCommandsDir);
83
+ if (stats.isSymbolicLink()) {
84
+ await unlink(editorCommandsDir);
85
+ }
86
+ }
87
+ catch {
88
+ // Ignore errors during cleanup
89
+ }
90
+ }
91
+ }
92
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/configurators/gemini.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Editor configurator module
3
+ * Provides registry and implementations for supported editors
4
+ */
5
+ export { EditorConfigurator, type ConfigureResult, type ConfigureOptions, } from './base.js';
6
+ export { EditorRegistry } from './registry.js';
7
+ export { CursorConfigurator } from './cursor.js';
8
+ export { ClaudeCodeConfigurator } from './claude-code.js';
9
+ export { VSCodeConfigurator } from './vscode.js';
10
+ export { WindsurfConfigurator } from './windsurf.js';
11
+ export { QwenConfigurator } from './qwen.js';
12
+ export { GeminiConfigurator } from './gemini.js';
13
+ export { AntigravityConfigurator } from './antigravity.js';
14
+ export { detectEditors, sortByPreference, formatDetectionSummary, type EditorDetectionResult, } from './detector.js';
15
+ /**
16
+ * Initialize the editor registry with default editors
17
+ * Call this once at startup
18
+ */
19
+ export declare function initializeEditorRegistry(): void;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/configurators/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAG3D,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,eAAe,CAAC;AAYvB;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAQ/C"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Editor configurator module
3
+ * Provides registry and implementations for supported editors
4
+ */
5
+ // Export base interface and types
6
+ export { EditorConfigurator, } from './base.js';
7
+ // Export registry
8
+ export { EditorRegistry } from './registry.js';
9
+ // Export implementations
10
+ export { CursorConfigurator } from './cursor.js';
11
+ export { ClaudeCodeConfigurator } from './claude-code.js';
12
+ export { VSCodeConfigurator } from './vscode.js';
13
+ export { WindsurfConfigurator } from './windsurf.js';
14
+ export { QwenConfigurator } from './qwen.js';
15
+ export { GeminiConfigurator } from './gemini.js';
16
+ export { AntigravityConfigurator } from './antigravity.js';
17
+ // Export detection utilities
18
+ export { detectEditors, sortByPreference, formatDetectionSummary, } from './detector.js';
19
+ // Auto-register default editors
20
+ import { EditorRegistry } from './registry.js';
21
+ import { CursorConfigurator } from './cursor.js';
22
+ import { ClaudeCodeConfigurator } from './claude-code.js';
23
+ import { VSCodeConfigurator } from './vscode.js';
24
+ import { WindsurfConfigurator } from './windsurf.js';
25
+ import { QwenConfigurator } from './qwen.js';
26
+ import { GeminiConfigurator } from './gemini.js';
27
+ import { AntigravityConfigurator } from './antigravity.js';
28
+ /**
29
+ * Initialize the editor registry with default editors
30
+ * Call this once at startup
31
+ */
32
+ export function initializeEditorRegistry() {
33
+ EditorRegistry.register(new CursorConfigurator());
34
+ EditorRegistry.register(new ClaudeCodeConfigurator());
35
+ EditorRegistry.register(new VSCodeConfigurator());
36
+ EditorRegistry.register(new WindsurfConfigurator());
37
+ EditorRegistry.register(new QwenConfigurator());
38
+ EditorRegistry.register(new GeminiConfigurator());
39
+ EditorRegistry.register(new AntigravityConfigurator());
40
+ }
41
+ // Auto-initialize on import
42
+ initializeEditorRegistry();
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/configurators/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kCAAkC;AAClC,OAAO,EACL,kBAAkB,GAGnB,MAAM,WAAW,CAAC;AAEnB,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,yBAAyB;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,6BAA6B;AAC7B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,sBAAsB,GAEvB,MAAM,eAAe,CAAC;AAEvB,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,cAAc,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAClD,cAAc,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IACtD,cAAc,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAClD,cAAc,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACpD,cAAc,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,CAAC,CAAC;IAChD,cAAc,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAClD,cAAc,CAAC,QAAQ,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,4BAA4B;AAC5B,wBAAwB,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Qwen Code editor configurator
3
+ * Alibaba's AI-powered code editor
4
+ */
5
+ import { EditorConfigurator, type ConfigureResult, type ConfigureOptions } from './base.js';
6
+ export declare class QwenConfigurator extends EditorConfigurator {
7
+ readonly name = "Qwen Code";
8
+ readonly id = "qwen";
9
+ readonly description = "Alibaba's AI-powered code editor with Qwen integration";
10
+ readonly configDir = ".qwen";
11
+ readonly supportsDashPrefix = true;
12
+ isAvailable(_projectPath: string): Promise<boolean>;
13
+ isConfigured(projectPath: string): Promise<boolean>;
14
+ configure(options: ConfigureOptions): Promise<ConfigureResult>;
15
+ unconfigure(projectPath: string): Promise<void>;
16
+ private discoverCommands;
17
+ }
18
+ //# sourceMappingURL=qwen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwen.d.ts","sourceRoot":"","sources":["../../src/configurators/qwen.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE5F,qBAAa,gBAAiB,SAAQ,kBAAkB;IACtD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,EAAE,UAAU;IACrB,QAAQ,CAAC,WAAW,4DAA4D;IAChF,QAAQ,CAAC,SAAS,WAAW;IAC7B,QAAQ,CAAC,kBAAkB,QAAQ;IAE7B,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnD,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IA6E9D,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YA2BvC,gBAAgB;CAU/B"}