@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.
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +72 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/rules.d.ts +6 -0
- package/dist/commands/rules.d.ts.map +1 -0
- package/dist/commands/rules.js +147 -0
- package/dist/commands/rules.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/rules/downloader.d.ts +40 -0
- package/dist/rules/downloader.d.ts.map +1 -0
- package/dist/rules/downloader.js +253 -0
- package/dist/rules/downloader.js.map +1 -0
- package/dist/rules/index.d.ts +8 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +8 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/registry.d.ts +45 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +158 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/types.d.ts +86 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +6 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/utils/detectTools.d.ts +15 -0
- package/dist/utils/detectTools.d.ts.map +1 -0
- package/dist/utils/detectTools.js +54 -0
- package/dist/utils/detectTools.js.map +1 -0
- package/dist/utils/generateToolConfig.d.ts +12 -0
- package/dist/utils/generateToolConfig.d.ts.map +1 -0
- package/dist/utils/generateToolConfig.js +200 -0
- package/dist/utils/generateToolConfig.js.map +1 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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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"}
|