@specsafe/cli 0.1.0 → 0.3.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 (37) hide show
  1. package/dist/commands/init.d.ts.map +1 -1
  2. package/dist/commands/init.js +72 -6
  3. package/dist/commands/init.js.map +1 -1
  4. package/dist/commands/rules.d.ts +6 -0
  5. package/dist/commands/rules.d.ts.map +1 -0
  6. package/dist/commands/rules.js +147 -0
  7. package/dist/commands/rules.js.map +1 -0
  8. package/dist/config.d.ts +6 -0
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/rules/downloader.d.ts +40 -0
  14. package/dist/rules/downloader.d.ts.map +1 -0
  15. package/dist/rules/downloader.js +253 -0
  16. package/dist/rules/downloader.js.map +1 -0
  17. package/dist/rules/index.d.ts +8 -0
  18. package/dist/rules/index.d.ts.map +1 -0
  19. package/dist/rules/index.js +8 -0
  20. package/dist/rules/index.js.map +1 -0
  21. package/dist/rules/registry.d.ts +45 -0
  22. package/dist/rules/registry.d.ts.map +1 -0
  23. package/dist/rules/registry.js +158 -0
  24. package/dist/rules/registry.js.map +1 -0
  25. package/dist/rules/types.d.ts +86 -0
  26. package/dist/rules/types.d.ts.map +1 -0
  27. package/dist/rules/types.js +6 -0
  28. package/dist/rules/types.js.map +1 -0
  29. package/dist/utils/detectTools.d.ts +15 -0
  30. package/dist/utils/detectTools.d.ts.map +1 -0
  31. package/dist/utils/detectTools.js +54 -0
  32. package/dist/utils/detectTools.js.map +1 -0
  33. package/dist/utils/generateToolConfig.d.ts +12 -0
  34. package/dist/utils/generateToolConfig.d.ts.map +1 -0
  35. package/dist/utils/generateToolConfig.js +200 -0
  36. package/dist/utils/generateToolConfig.js.map +1 -0
  37. package/package.json +4 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/rules/downloader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Rules Module
3
+ * Main entry point for rule management functionality
4
+ */
5
+ export * from './types.js';
6
+ export * from './registry.js';
7
+ export * from './downloader.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Rules Module
3
+ * Main entry point for rule management functionality
4
+ */
5
+ export * from './types.js';
6
+ export * from './registry.js';
7
+ export * from './downloader.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tool Registry
3
+ * Manages available tools and their detection logic
4
+ */
5
+ import type { ToolDefinition, InstalledTool } from './types.js';
6
+ /**
7
+ * Hardcoded list of available rules/tools
8
+ */
9
+ export declare const AVAILABLE_RULES: ToolDefinition[];
10
+ /**
11
+ * Detect if a tool is configured by checking for its config files
12
+ */
13
+ export declare function detectTool(toolName: string, cwd?: string): Promise<boolean>;
14
+ /**
15
+ * Detect all available tools in the project
16
+ */
17
+ export declare function detectAllTools(cwd?: string): Promise<string[]>;
18
+ /**
19
+ * Get tool definition by name
20
+ */
21
+ export declare function getTool(name: string): ToolDefinition | undefined;
22
+ /**
23
+ * Check if a tool name is valid
24
+ */
25
+ export declare function isValidTool(name: string): boolean;
26
+ /**
27
+ * Get all available tools
28
+ */
29
+ export declare function getAllTools(): ToolDefinition[];
30
+ /**
31
+ * Load installed tools from config
32
+ */
33
+ export declare function loadInstalledTools(cwd?: string): Promise<InstalledTool[]>;
34
+ /**
35
+ * Save tool configuration to specsafe.config.json
36
+ */
37
+ export declare function saveToolConfig(toolName: string, config: {
38
+ enabled: boolean;
39
+ version: string;
40
+ }, cwd?: string): Promise<void>;
41
+ /**
42
+ * Remove tool configuration from specsafe.config.json
43
+ */
44
+ export declare function removeToolConfig(toolName: string, cwd?: string): Promise<void>;
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/rules/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAqB,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,EAoC3C,CAAC;AAEF;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAchG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnF;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEhE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAE9C;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAc9F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC7C,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Tool Registry
3
+ * Manages available tools and their detection logic
4
+ */
5
+ import { access, writeFile, readFile } from 'fs/promises';
6
+ import { join } from 'path';
7
+ /**
8
+ * Hardcoded list of available rules/tools
9
+ */
10
+ export const AVAILABLE_RULES = [
11
+ {
12
+ name: 'cursor',
13
+ description: 'Cursor IDE integration',
14
+ files: ['.cursorrules'],
15
+ },
16
+ {
17
+ name: 'continue',
18
+ description: 'Continue.dev for VS Code',
19
+ files: ['.continue/config.yaml'],
20
+ },
21
+ {
22
+ name: 'aider',
23
+ description: 'Aider CLI integration',
24
+ files: ['.aider.conf.yml'],
25
+ },
26
+ {
27
+ name: 'zed',
28
+ description: 'Zed Editor integration',
29
+ files: ['.zed/settings.json'],
30
+ },
31
+ {
32
+ name: 'git-hooks',
33
+ description: 'Pre-commit validation',
34
+ files: ['.githooks/pre-commit'],
35
+ },
36
+ {
37
+ name: 'claude-code',
38
+ description: 'Claude Code by Anthropic',
39
+ files: ['CLAUDE.md'],
40
+ },
41
+ {
42
+ name: 'crush',
43
+ description: 'Crush (formerly OpenCode) by Charmbracelet',
44
+ files: ['CRUSH.md'],
45
+ },
46
+ ];
47
+ /**
48
+ * Detect if a tool is configured by checking for its config files
49
+ */
50
+ export async function detectTool(toolName, cwd = process.cwd()) {
51
+ const tool = AVAILABLE_RULES.find((t) => t.name === toolName);
52
+ if (!tool)
53
+ return false;
54
+ for (const file of tool.files) {
55
+ const filePath = join(cwd, file);
56
+ try {
57
+ await access(filePath);
58
+ return true;
59
+ }
60
+ catch {
61
+ // File doesn't exist, continue checking
62
+ }
63
+ }
64
+ return false;
65
+ }
66
+ /**
67
+ * Detect all available tools in the project
68
+ */
69
+ export async function detectAllTools(cwd = process.cwd()) {
70
+ const detected = [];
71
+ for (const tool of AVAILABLE_RULES) {
72
+ if (await detectTool(tool.name, cwd)) {
73
+ detected.push(tool.name);
74
+ }
75
+ }
76
+ return detected;
77
+ }
78
+ /**
79
+ * Get tool definition by name
80
+ */
81
+ export function getTool(name) {
82
+ return AVAILABLE_RULES.find((t) => t.name === name);
83
+ }
84
+ /**
85
+ * Check if a tool name is valid
86
+ */
87
+ export function isValidTool(name) {
88
+ return AVAILABLE_RULES.some((t) => t.name === name);
89
+ }
90
+ /**
91
+ * Get all available tools
92
+ */
93
+ export function getAllTools() {
94
+ return [...AVAILABLE_RULES];
95
+ }
96
+ /**
97
+ * Load installed tools from config
98
+ */
99
+ export async function loadInstalledTools(cwd = process.cwd()) {
100
+ const configPath = join(cwd, 'specsafe.config.json');
101
+ try {
102
+ const content = await readFile(configPath, 'utf-8');
103
+ const config = JSON.parse(content);
104
+ const tools = config.tools || {};
105
+ return Object.entries(tools).map(([name, toolConfig]) => ({
106
+ name,
107
+ ...toolConfig,
108
+ }));
109
+ }
110
+ catch {
111
+ return [];
112
+ }
113
+ }
114
+ /**
115
+ * Save tool configuration to specsafe.config.json
116
+ */
117
+ export async function saveToolConfig(toolName, config, cwd = process.cwd()) {
118
+ const configPath = join(cwd, 'specsafe.config.json');
119
+ let existingConfig = {};
120
+ try {
121
+ const content = await readFile(configPath, 'utf-8');
122
+ existingConfig = JSON.parse(content);
123
+ }
124
+ catch {
125
+ // Config doesn't exist yet, start fresh
126
+ }
127
+ existingConfig.tools = {
128
+ ...(existingConfig.tools || {}),
129
+ [toolName]: config,
130
+ };
131
+ await writeFile(configPath, JSON.stringify(existingConfig, null, 2));
132
+ }
133
+ /**
134
+ * Remove tool configuration from specsafe.config.json
135
+ */
136
+ export async function removeToolConfig(toolName, cwd = process.cwd()) {
137
+ const configPath = join(cwd, 'specsafe.config.json');
138
+ let content;
139
+ try {
140
+ content = await readFile(configPath, 'utf-8');
141
+ }
142
+ catch {
143
+ return;
144
+ }
145
+ let config;
146
+ try {
147
+ config = JSON.parse(content);
148
+ }
149
+ catch {
150
+ // Config is malformed JSON, nothing safe to do
151
+ return;
152
+ }
153
+ if (config.tools && config.tools[toolName]) {
154
+ delete config.tools[toolName];
155
+ await writeFile(configPath, JSON.stringify(config, null, 2));
156
+ }
157
+ }
158
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/rules/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Types for the rules module
3
+ * TypeScript interfaces for tool registry and rule management
4
+ */
5
+ /**
6
+ * Represents a tool that can be integrated with SpecSafe
7
+ */
8
+ export interface ToolDefinition {
9
+ /** Unique identifier for the tool */
10
+ name: string;
11
+ /** Human-readable description */
12
+ description: string;
13
+ /** Configuration files that this tool uses */
14
+ files: string[];
15
+ /** Optional: Additional metadata */
16
+ metadata?: Record<string, unknown>;
17
+ }
18
+ /**
19
+ * Represents an installed tool configuration
20
+ */
21
+ export interface InstalledTool {
22
+ /** Tool name */
23
+ name: string;
24
+ /** Whether the tool is enabled */
25
+ enabled: boolean;
26
+ /** Installed version of the rules */
27
+ version: string;
28
+ /** When the tool was installed */
29
+ installedAt?: string;
30
+ }
31
+ /**
32
+ * Tool registry entry with detection logic
33
+ */
34
+ export interface ToolRegistryEntry extends ToolDefinition {
35
+ /** Detect if this tool is already configured in the project */
36
+ detect(): Promise<boolean> | boolean;
37
+ /** Install rules for this tool */
38
+ install(cwd: string): Promise<void>;
39
+ /** Remove rules for this tool */
40
+ remove(cwd: string): Promise<void>;
41
+ }
42
+ /**
43
+ * Configuration for tools in specsafe.config.json
44
+ */
45
+ export interface ToolsConfig {
46
+ [toolName: string]: {
47
+ enabled: boolean;
48
+ version: string;
49
+ };
50
+ }
51
+ /**
52
+ * Extended SpecSafe config with tools support
53
+ */
54
+ export interface SpecSafeConfigWithTools {
55
+ projectName: string;
56
+ version: string;
57
+ stages: string[];
58
+ testFramework: 'vitest' | 'jest';
59
+ language: 'typescript';
60
+ tools?: ToolsConfig;
61
+ }
62
+ /**
63
+ * Result of a rule operation
64
+ */
65
+ export interface RuleOperationResult {
66
+ success: boolean;
67
+ message: string;
68
+ tool?: string;
69
+ error?: Error;
70
+ }
71
+ /**
72
+ * Available rule sources
73
+ */
74
+ export type RuleSource = 'github' | 'local';
75
+ /**
76
+ * Download options for rules
77
+ */
78
+ export interface DownloadOptions {
79
+ /** Source to download from */
80
+ source?: RuleSource;
81
+ /** Specific version to download */
82
+ version?: string;
83
+ /** Force overwrite existing files */
84
+ force?: boolean;
85
+ }
86
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,+DAA+D;IAC/D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IACrC,kCAAkC;IAClC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,iCAAiC;IACjC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,QAAQ,EAAE,MAAM,GAAG;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Types for the rules module
3
+ * TypeScript interfaces for tool registry and rule management
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Detects installed AI coding tools by checking for their config files
3
+ * @returns Array of detected tool names
4
+ */
5
+ export declare function detectInstalledTools(): string[];
6
+ /**
7
+ * Tool configuration mapping
8
+ */
9
+ export interface ToolConfig {
10
+ name: string;
11
+ displayName: string;
12
+ configFiles: string[];
13
+ }
14
+ export declare const availableTools: ToolConfig[];
15
+ //# sourceMappingURL=detectTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectTools.d.ts","sourceRoot":"","sources":["../../src/utils/detectTools.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAW/C;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,UAAU,EA+BtC,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { existsSync } from 'fs';
2
+ /**
3
+ * Detects installed AI coding tools by checking for their config files
4
+ * @returns Array of detected tool names
5
+ */
6
+ export function detectInstalledTools() {
7
+ const tools = [];
8
+ if (existsSync('.cursorrules'))
9
+ tools.push('cursor');
10
+ if (existsSync('.continue/config.json'))
11
+ tools.push('continue');
12
+ if (existsSync('.aider.conf.yml'))
13
+ tools.push('aider');
14
+ if (existsSync('.zed/settings.json'))
15
+ tools.push('zed');
16
+ if (existsSync('.claude') || existsSync('CLAUDE.md'))
17
+ tools.push('claude-code');
18
+ if (existsSync('.crush') || existsSync('CRUSH.md'))
19
+ tools.push('crush');
20
+ return tools;
21
+ }
22
+ export const availableTools = [
23
+ {
24
+ name: 'cursor',
25
+ displayName: 'Cursor IDE',
26
+ configFiles: ['.cursorrules', '.cursor/rules.md'],
27
+ },
28
+ {
29
+ name: 'continue',
30
+ displayName: 'Continue.dev',
31
+ configFiles: ['.continue/config.json'],
32
+ },
33
+ {
34
+ name: 'aider',
35
+ displayName: 'Aider CLI',
36
+ configFiles: ['.aider.conf.yml'],
37
+ },
38
+ {
39
+ name: 'zed',
40
+ displayName: 'Zed Editor',
41
+ configFiles: ['.zed/settings.json'],
42
+ },
43
+ {
44
+ name: 'claude-code',
45
+ displayName: 'Claude Code',
46
+ configFiles: ['CLAUDE.md', '.claude/'],
47
+ },
48
+ {
49
+ name: 'crush',
50
+ displayName: 'Crush',
51
+ configFiles: ['CRUSH.md', '.crush/'],
52
+ },
53
+ ];
54
+ //# sourceMappingURL=detectTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectTools.js","sourceRoot":"","sources":["../../src/utils/detectTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAI,UAAU,CAAC,cAAc,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,UAAU,CAAC,uBAAuB,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAChE,IAAI,UAAU,CAAC,iBAAiB,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,UAAU,CAAC,oBAAoB,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAChF,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAExE,OAAO,KAAK,CAAC;AACf,CAAC;AAWD,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,CAAC,cAAc,EAAE,kBAAkB,CAAC;KAClD;IACD;QACE,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE,cAAc;QAC3B,WAAW,EAAE,CAAC,uBAAuB,CAAC;KACvC;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,WAAW;QACxB,WAAW,EAAE,CAAC,iBAAiB,CAAC;KACjC;IACD;QACE,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,CAAC,oBAAoB,CAAC;KACpC;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,aAAa;QAC1B,WAAW,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;KACvC;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,OAAO;QACpB,WAAW,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;KACrC;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generate configuration for a specific tool
3
+ * @param tool - The tool name (cursor, continue, aider, zed)
4
+ * @param projectDir - The project directory path
5
+ */
6
+ export declare function generateToolConfig(tool: string, projectDir?: string): Promise<void>;
7
+ /**
8
+ * Generate git hooks configuration
9
+ * @param projectDir - The project directory path
10
+ */
11
+ export declare function generateGitHooks(projectDir: string): Promise<void>;
12
+ //# sourceMappingURL=generateToolConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateToolConfig.d.ts","sourceRoot":"","sources":["../../src/utils/generateToolConfig.ts"],"names":[],"mappings":"AAsGA;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9F;AAwDD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCxE"}
@@ -0,0 +1,200 @@
1
+ import { writeFile, mkdir } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import chalk from 'chalk';
4
+ /**
5
+ * Generates configuration files for AI coding tools
6
+ */
7
+ const cursorRulesContent = `# SpecSafe Rules for Cursor
8
+
9
+ You are working on a SpecSafe project. Follow these rules:
10
+
11
+ ## Always Check PROJECT_STATE.md
12
+ Before making changes, read PROJECT_STATE.md to understand:
13
+ - Current active specs and their stages
14
+ - Which spec is being worked on
15
+ - Requirements that must be satisfied
16
+
17
+ ## Spec-Driven Workflow
18
+ 1. Specs define WHAT to build (requirements, scenarios)
19
+ 2. Tests define HOW to verify (generated by SpecSafe)
20
+ 3. Implementation satisfies tests
21
+
22
+ ## Stage-Aware Development
23
+ - SPEC stage: Generate tests from requirements
24
+ - TEST stage: Tests exist, implement code to pass them
25
+ - CODE stage: Implementation in progress, maintain tests
26
+ - QA stage: Validate against scenarios
27
+ - COMPLETE: Feature done, archive spec
28
+
29
+ ## Never
30
+ - Skip tests to implement faster
31
+ - Modify specs without updating PROJECT_STATE.md
32
+ - Commit code without corresponding spec entry
33
+
34
+ ## Always
35
+ - Run tests before marking work complete
36
+ - Update spec stage using \`specsafe\` commands
37
+ - Reference spec ID in commit messages
38
+ `;
39
+ const continueConfigContent = {
40
+ customCommands: [
41
+ {
42
+ name: 'specsafe',
43
+ description: 'Show current SpecSafe status',
44
+ prompt: 'Read PROJECT_STATE.md and show me the current active specs, their stages, and what needs to be done next.',
45
+ },
46
+ {
47
+ name: 'spec',
48
+ description: 'Show details for a specific spec',
49
+ prompt: 'Read the spec file for {{input}} from specs/active/ and show me its requirements, scenarios, and current stage.',
50
+ },
51
+ ],
52
+ contextProviders: [
53
+ {
54
+ name: 'specsafe-state',
55
+ params: {
56
+ file: 'PROJECT_STATE.md',
57
+ },
58
+ },
59
+ ],
60
+ };
61
+ const aiderConfigContent = `# Aider configuration for SpecSafe projects
62
+
63
+ # Always read PROJECT_STATE.md for context
64
+ read:
65
+ - PROJECT_STATE.md
66
+
67
+ # Instructions for the AI
68
+ assistant_prompt: |
69
+ You are working on a SpecSafe project. Always:
70
+ 1. Check PROJECT_STATE.md for current specs and stages
71
+ 2. Ensure implementation satisfies test requirements
72
+ 3. Update spec stage using specsafe commands when complete
73
+ 4. Never skip tests or modify specs without tracking
74
+
75
+ # Files to ignore
76
+ ignore:
77
+ - specs/archive/
78
+ - node_modules/
79
+ - dist/
80
+ - .git/
81
+ `;
82
+ const zedSettingsContent = {
83
+ assistant: {
84
+ default_model: {
85
+ provider: 'anthropic',
86
+ model: 'claude-3-5-sonnet-latest',
87
+ },
88
+ version: '2',
89
+ },
90
+ context_servers: {
91
+ specsafe: {
92
+ command: 'cat',
93
+ args: ['PROJECT_STATE.md'],
94
+ },
95
+ },
96
+ };
97
+ /**
98
+ * Generate configuration for a specific tool
99
+ * @param tool - The tool name (cursor, continue, aider, zed)
100
+ * @param projectDir - The project directory path
101
+ */
102
+ export async function generateToolConfig(tool, projectDir = '.') {
103
+ switch (tool) {
104
+ case 'cursor':
105
+ await generateCursorConfig(projectDir);
106
+ break;
107
+ case 'continue':
108
+ await generateContinueConfig(projectDir);
109
+ break;
110
+ case 'aider':
111
+ await generateAiderConfig(projectDir);
112
+ break;
113
+ case 'zed':
114
+ await generateZedConfig(projectDir);
115
+ break;
116
+ default:
117
+ throw new Error(`Unknown tool: ${tool}`);
118
+ }
119
+ }
120
+ async function generateCursorConfig(projectDir) {
121
+ const configPath = `${projectDir}/.cursorrules`;
122
+ if (existsSync(configPath)) {
123
+ console.log(chalk.yellow('⚠ .cursorrules already exists, skipping'));
124
+ return;
125
+ }
126
+ await writeFile(configPath, cursorRulesContent);
127
+ }
128
+ async function generateContinueConfig(projectDir) {
129
+ const configDir = `${projectDir}/.continue`;
130
+ const configPath = `${configDir}/config.json`;
131
+ if (!existsSync(configDir)) {
132
+ await mkdir(configDir, { recursive: true });
133
+ }
134
+ if (existsSync(configPath)) {
135
+ console.log(chalk.yellow('⚠ .continue/config.json already exists, skipping'));
136
+ return;
137
+ }
138
+ await writeFile(configPath, JSON.stringify(continueConfigContent, null, 2));
139
+ }
140
+ async function generateAiderConfig(projectDir) {
141
+ const configPath = `${projectDir}/.aider.conf.yml`;
142
+ if (existsSync(configPath)) {
143
+ console.log(chalk.yellow('⚠ .aider.conf.yml already exists, skipping'));
144
+ return;
145
+ }
146
+ await writeFile(configPath, aiderConfigContent);
147
+ }
148
+ async function generateZedConfig(projectDir) {
149
+ const configDir = `${projectDir}/.zed`;
150
+ const configPath = `${configDir}/settings.json`;
151
+ if (!existsSync(configDir)) {
152
+ await mkdir(configDir, { recursive: true });
153
+ }
154
+ if (existsSync(configPath)) {
155
+ console.log(chalk.yellow('⚠ .zed/settings.json already exists, skipping'));
156
+ return;
157
+ }
158
+ await writeFile(configPath, JSON.stringify(zedSettingsContent, null, 2));
159
+ }
160
+ /**
161
+ * Generate git hooks configuration
162
+ * @param projectDir - The project directory path
163
+ */
164
+ export async function generateGitHooks(projectDir) {
165
+ const hooksDir = `${projectDir}/.githooks`;
166
+ const preCommitPath = `${hooksDir}/pre-commit`;
167
+ if (!existsSync(hooksDir)) {
168
+ await mkdir(hooksDir, { recursive: true });
169
+ }
170
+ const preCommitContent = `#!/bin/bash
171
+ # SpecSafe pre-commit hook
172
+
173
+ echo "🔍 Running SpecSafe pre-commit checks..."
174
+
175
+ # Validate PROJECT_STATE.md exists
176
+ if [ ! -f "PROJECT_STATE.md" ]; then
177
+ echo "❌ PROJECT_STATE.md not found. Run 'specsafe init' first."
178
+ exit 1
179
+ fi
180
+
181
+ # Run spec validation (if we add a validate command)
182
+ # specsafe validate --silent || exit 1
183
+
184
+ echo "✅ Pre-commit checks passed"
185
+ `;
186
+ if (existsSync(preCommitPath)) {
187
+ console.log(chalk.yellow('⚠ .githooks/pre-commit already exists, skipping'));
188
+ return;
189
+ }
190
+ await writeFile(preCommitPath, preCommitContent);
191
+ // Make the hook executable (this won't work on Windows without special handling)
192
+ try {
193
+ const { exec } = await import('child_process');
194
+ exec(`chmod +x ${preCommitPath}`);
195
+ }
196
+ catch {
197
+ // Ignore chmod errors on Windows
198
+ }
199
+ }
200
+ //# sourceMappingURL=generateToolConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateToolConfig.js","sourceRoot":"","sources":["../../src/utils/generateToolConfig.ts"],"names":[],"mappings":"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"}