@specsafe/cli 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/commands/apply.d.ts +3 -0
  2. package/dist/commands/apply.d.ts.map +1 -0
  3. package/dist/commands/apply.js +182 -0
  4. package/dist/commands/apply.js.map +1 -0
  5. package/dist/commands/constitution.d.ts +3 -0
  6. package/dist/commands/constitution.d.ts.map +1 -0
  7. package/dist/commands/constitution.js +192 -0
  8. package/dist/commands/constitution.js.map +1 -0
  9. package/dist/commands/delta.d.ts +3 -0
  10. package/dist/commands/delta.d.ts.map +1 -0
  11. package/dist/commands/delta.js +82 -0
  12. package/dist/commands/delta.js.map +1 -0
  13. package/dist/commands/diff.d.ts +3 -0
  14. package/dist/commands/diff.d.ts.map +1 -0
  15. package/dist/commands/diff.js +102 -0
  16. package/dist/commands/diff.js.map +1 -0
  17. package/dist/commands/extend.d.ts +6 -0
  18. package/dist/commands/extend.d.ts.map +1 -0
  19. package/dist/commands/extend.js +167 -0
  20. package/dist/commands/extend.js.map +1 -0
  21. package/dist/commands/init-old.d.ts +3 -0
  22. package/dist/commands/init-old.d.ts.map +1 -0
  23. package/dist/commands/init-old.js +146 -0
  24. package/dist/commands/init-old.js.map +1 -0
  25. package/dist/commands/init.d.ts.map +1 -1
  26. package/dist/commands/init.js +195 -43
  27. package/dist/commands/init.js.map +1 -1
  28. package/dist/commands/new.d.ts.map +1 -1
  29. package/dist/commands/new.js +26 -8
  30. package/dist/commands/new.js.map +1 -1
  31. package/dist/commands/qa.d.ts.map +1 -1
  32. package/dist/commands/qa.js +37 -1
  33. package/dist/commands/qa.js.map +1 -1
  34. package/dist/commands/rules.d.ts.map +1 -1
  35. package/dist/commands/rules.js +182 -97
  36. package/dist/commands/rules.js.map +1 -1
  37. package/dist/index.js +15 -0
  38. package/dist/index.js.map +1 -1
  39. package/package.json +3 -3
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extension management commands
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare const extendCommand: Command;
6
+ //# sourceMappingURL=extend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../src/commands/extend.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,aAAa,SAkMvB,CAAC"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Extension management commands
3
+ */
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import { listExtensions, listEnabledExtensions, enableExtension, disableExtension, getExtension, loadBuiltinExtensions, } from '@specsafe/core';
7
+ export const extendCommand = new Command('extend')
8
+ .description('Manage SpecSafe extensions')
9
+ .addCommand(new Command('list')
10
+ .description('List all available extensions')
11
+ .option('-e, --enabled-only', 'Show only enabled extensions')
12
+ .action(async (options) => {
13
+ try {
14
+ // Load builtins first
15
+ await loadBuiltinExtensions();
16
+ const extensions = options.enabledOnly
17
+ ? listEnabledExtensions()
18
+ : listExtensions();
19
+ if (extensions.length === 0) {
20
+ console.log(chalk.yellow('No extensions found.'));
21
+ return;
22
+ }
23
+ console.log(chalk.bold('\nšŸ“¦ Extensions:\n'));
24
+ for (const ext of extensions) {
25
+ const status = ext.enabled === false
26
+ ? chalk.red('disabled')
27
+ : chalk.green('enabled');
28
+ console.log(chalk.bold(` ${ext.name}`) + ` (${status})`);
29
+ console.log(chalk.gray(` ID: ${ext.id}`));
30
+ console.log(chalk.gray(` Version: ${ext.version}`));
31
+ if (ext.author) {
32
+ console.log(chalk.gray(` Author: ${ext.author}`));
33
+ }
34
+ console.log(` ${ext.description}`);
35
+ const hookPhases = Object.keys(ext.hooks);
36
+ if (hookPhases.length > 0) {
37
+ console.log(chalk.cyan(` Hooks: ${hookPhases.join(', ')}`));
38
+ }
39
+ console.log();
40
+ }
41
+ console.log(chalk.gray(`Total: ${extensions.length} extension(s)\n`));
42
+ }
43
+ catch (error) {
44
+ console.error(chalk.red('Failed to list extensions:'), error);
45
+ process.exit(1);
46
+ }
47
+ }))
48
+ .addCommand(new Command('enable')
49
+ .description('Enable an extension')
50
+ .argument('<name>', 'Extension ID or name')
51
+ .action(async (name) => {
52
+ try {
53
+ // Load builtins first
54
+ await loadBuiltinExtensions();
55
+ // Try to find by ID first
56
+ let extension = getExtension(name);
57
+ // If not found, search by name
58
+ if (!extension) {
59
+ const allExtensions = listExtensions();
60
+ extension = allExtensions.find((ext) => ext.name.toLowerCase() === name.toLowerCase());
61
+ }
62
+ if (!extension) {
63
+ console.error(chalk.red(`Extension "${name}" not found.`));
64
+ console.log(chalk.gray('Run "specsafe extend list" to see available extensions.'));
65
+ process.exit(1);
66
+ }
67
+ const success = enableExtension(extension.id);
68
+ if (success) {
69
+ console.log(chalk.green(`āœ“ Enabled extension: ${extension.name}`));
70
+ }
71
+ else {
72
+ console.error(chalk.red(`Failed to enable extension: ${extension.name}`));
73
+ process.exit(1);
74
+ }
75
+ }
76
+ catch (error) {
77
+ console.error(chalk.red('Failed to enable extension:'), error);
78
+ process.exit(1);
79
+ }
80
+ }))
81
+ .addCommand(new Command('disable')
82
+ .description('Disable an extension')
83
+ .argument('<name>', 'Extension ID or name')
84
+ .action(async (name) => {
85
+ try {
86
+ // Load builtins first
87
+ await loadBuiltinExtensions();
88
+ // Try to find by ID first
89
+ let extension = getExtension(name);
90
+ // If not found, search by name
91
+ if (!extension) {
92
+ const allExtensions = listExtensions();
93
+ extension = allExtensions.find((ext) => ext.name.toLowerCase() === name.toLowerCase());
94
+ }
95
+ if (!extension) {
96
+ console.error(chalk.red(`Extension "${name}" not found.`));
97
+ console.log(chalk.gray('Run "specsafe extend list" to see available extensions.'));
98
+ process.exit(1);
99
+ }
100
+ const success = disableExtension(extension.id);
101
+ if (success) {
102
+ console.log(chalk.green(`āœ“ Disabled extension: ${extension.name}`));
103
+ }
104
+ else {
105
+ console.error(chalk.red(`Failed to disable extension: ${extension.name}`));
106
+ process.exit(1);
107
+ }
108
+ }
109
+ catch (error) {
110
+ console.error(chalk.red('Failed to disable extension:'), error);
111
+ process.exit(1);
112
+ }
113
+ }))
114
+ .addCommand(new Command('info')
115
+ .description('Show detailed information about an extension')
116
+ .argument('<name>', 'Extension ID or name')
117
+ .action(async (name) => {
118
+ try {
119
+ // Load builtins first
120
+ await loadBuiltinExtensions();
121
+ // Try to find by ID first
122
+ let extension = getExtension(name);
123
+ // If not found, search by name
124
+ if (!extension) {
125
+ const allExtensions = listExtensions();
126
+ extension = allExtensions.find((ext) => ext.name.toLowerCase() === name.toLowerCase());
127
+ }
128
+ if (!extension) {
129
+ console.error(chalk.red(`Extension "${name}" not found.`));
130
+ console.log(chalk.gray('Run "specsafe extend list" to see available extensions.'));
131
+ process.exit(1);
132
+ }
133
+ console.log();
134
+ console.log(chalk.bold(extension.name));
135
+ console.log(chalk.gray('─'.repeat(50)));
136
+ console.log(chalk.gray(`ID: ${extension.id}`));
137
+ console.log(chalk.gray(`Version: ${extension.version}`));
138
+ if (extension.author) {
139
+ console.log(chalk.gray(`Author: ${extension.author}`));
140
+ }
141
+ const status = extension.enabled === false
142
+ ? chalk.red('disabled')
143
+ : chalk.green('enabled');
144
+ console.log(chalk.gray(`Status: ${status}`));
145
+ console.log();
146
+ console.log(extension.description);
147
+ console.log();
148
+ const hookPhases = Object.keys(extension.hooks);
149
+ if (hookPhases.length > 0) {
150
+ console.log(chalk.bold('Hooks:'));
151
+ for (const phase of hookPhases) {
152
+ console.log(chalk.cyan(` • ${phase}`));
153
+ }
154
+ }
155
+ if (extension.config && Object.keys(extension.config).length > 0) {
156
+ console.log();
157
+ console.log(chalk.bold('Configuration:'));
158
+ console.log(JSON.stringify(extension.config, null, 2));
159
+ }
160
+ console.log();
161
+ }
162
+ catch (error) {
163
+ console.error(chalk.red('Failed to get extension info:'), error);
164
+ process.exit(1);
165
+ }
166
+ }));
167
+ //# sourceMappingURL=extend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend.js","sourceRoot":"","sources":["../../src/commands/extend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const initCommand: Command;
3
+ //# sourceMappingURL=init-old.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-old.d.ts","sourceRoot":"","sources":["../../src/commands/init-old.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SAyJpB,CAAC"}
@@ -0,0 +1,146 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { writeFile, mkdir } from 'fs/promises';
5
+ import { ProjectTracker } from '@specsafe/core';
6
+ import { checkbox, select, confirm, input } from '@inquirer/prompts';
7
+ import { detectInstalledTools, availableTools } from '../utils/detectTools.js';
8
+ import { generateToolConfig, generateGitHooks } from '../utils/generateToolConfig.js';
9
+ export const initCommand = new Command('init')
10
+ .description('Initialize a new SpecSafe project')
11
+ .argument('[name]', 'Project name', 'my-project')
12
+ .action(async (defaultName) => {
13
+ const spinner = ora('Initializing SpecSafe project...').start();
14
+ try {
15
+ // Interactive prompts for project name
16
+ spinner.stop();
17
+ const name = await input({
18
+ message: 'Project name:',
19
+ default: defaultName,
20
+ });
21
+ // 1. Detect existing tools
22
+ const detectedTools = detectInstalledTools();
23
+ // 2. Prompt user to confirm/select tools
24
+ const toolChoices = availableTools.map((tool) => ({
25
+ name: tool.displayName + (detectedTools.includes(tool.name) ? ' (detected)' : ''),
26
+ value: tool.name,
27
+ checked: detectedTools.includes(tool.name),
28
+ }));
29
+ const selectedTools = await checkbox({
30
+ message: 'Which AI coding assistants do you use?',
31
+ choices: toolChoices,
32
+ });
33
+ // 3. Prompt for test framework
34
+ const testFramework = await select({
35
+ message: 'Select testing framework:',
36
+ choices: [
37
+ { name: 'Vitest (recommended)', value: 'vitest' },
38
+ { name: 'Jest', value: 'jest' },
39
+ { name: 'Playwright (E2E)', value: 'playwright' },
40
+ ],
41
+ default: 'vitest',
42
+ });
43
+ // 4. Prompt for git hooks
44
+ const useGitHooks = await confirm({
45
+ message: 'Enable git hooks for spec validation?',
46
+ default: true,
47
+ });
48
+ spinner.start('Creating project structure...');
49
+ // Create directory structure
50
+ await mkdir('specs/active', { recursive: true });
51
+ await mkdir('specs/completed', { recursive: true });
52
+ await mkdir('specs/archive', { recursive: true });
53
+ await mkdir('src', { recursive: true });
54
+ await mkdir('tests', { recursive: true });
55
+ // Create PROJECT_STATE.md
56
+ const tracker = new ProjectTracker(process.cwd());
57
+ await tracker.initialize(name);
58
+ // Create spec template
59
+ const template = `# Spec Template
60
+
61
+ ## Metadata
62
+ - **ID**: SPEC-{YYYYMMDD}-{NNN}
63
+ - **Status**: draft
64
+ - **Priority**: P1
65
+
66
+ ## 1. Purpose (WHY)
67
+
68
+ ## 2. Scope (WHAT)
69
+ ### In Scope
70
+ -
71
+
72
+ ### Out of Scope
73
+ -
74
+
75
+ ## 3. Requirements
76
+ | ID | Requirement | Priority | Acceptance Criteria |
77
+ |----|-------------|----------|---------------------|
78
+ | | | | |
79
+
80
+ ## 4. Technical Approach (HOW)
81
+
82
+ ## 5. Test Strategy
83
+
84
+ ## 6. Implementation Plan
85
+
86
+ ## 7. Success Criteria
87
+ - [ ]
88
+
89
+ ## 8. Risks & Mitigations
90
+
91
+ ## 9. Notes & References
92
+ `;
93
+ await writeFile('specs/template.md', template);
94
+ // Create config file with selected tools
95
+ const toolsConfig = {};
96
+ for (const tool of selectedTools) {
97
+ toolsConfig[tool] = { enabled: true };
98
+ }
99
+ const config = {
100
+ project: name,
101
+ version: '1.0.0',
102
+ stages: ['spec', 'test', 'code', 'qa', 'complete'],
103
+ testFramework,
104
+ language: 'typescript',
105
+ tools: toolsConfig,
106
+ gitHooks: {
107
+ enabled: useGitHooks,
108
+ },
109
+ };
110
+ await writeFile('specsafe.config.json', JSON.stringify(config, null, 2));
111
+ spinner.text = 'Generating tool configurations...';
112
+ // Generate tool configs for selected tools
113
+ for (const tool of selectedTools) {
114
+ await generateToolConfig(tool, '.');
115
+ }
116
+ // Generate git hooks if enabled
117
+ if (useGitHooks) {
118
+ await generateGitHooks('.');
119
+ }
120
+ spinner.succeed(chalk.green(`Initialized SpecSafe project: ${name}`));
121
+ console.log('\n' + chalk.blue('Generated configurations:'));
122
+ for (const tool of selectedTools) {
123
+ console.log(chalk.green(` āœ“ ${tool} configuration`));
124
+ }
125
+ if (useGitHooks) {
126
+ console.log(chalk.green(' āœ“ Git hooks enabled'));
127
+ }
128
+ console.log(chalk.green(` āœ“ ${testFramework} configuration`));
129
+ console.log('\n' + chalk.blue('Next steps:'));
130
+ console.log(' 1. specsafe new <spec-name> - Create a new spec');
131
+ console.log(' 2. specsafe status - View project status');
132
+ console.log(' 3. Edit specs/active/ to define requirements');
133
+ }
134
+ catch (error) {
135
+ spinner.fail(chalk.red(`Failed to initialize: ${error.message}`));
136
+ if (error.message.includes('EEXIST')) {
137
+ console.log(chalk.gray("šŸ’” Tip: Directory already exists. Use 'specsafe init <name>' to create elsewhere."));
138
+ }
139
+ if (error.message.includes('User force closed')) {
140
+ console.log(chalk.gray('šŸ’” Tip: Init was cancelled by user.'));
141
+ process.exit(0);
142
+ }
143
+ process.exit(1);
144
+ }
145
+ });
146
+ //# sourceMappingURL=init-old.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-old.js","sourceRoot":"","sources":["../../src/commands/init-old.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,eAAO,MAAM,WAAW,SAyJpB,CAAC"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyFpC,eAAO,MAAM,WAAW,SA4PpB,CAAC"}