ai-sprint-kit 1.3.1 ā 2.0.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.
- package/LICENSE +35 -123
- package/README.md +39 -207
- package/bin/ai-sprint.js +105 -0
- package/lib/auth.js +73 -0
- package/lib/installer.js +59 -195
- package/lib/messages.js +53 -0
- package/package.json +15 -18
- package/bin/cli.js +0 -135
- package/lib/scanner.js +0 -321
- package/templates/.claude/.env.example +0 -13
- package/templates/.claude/agents/debugger.md +0 -668
- package/templates/.claude/agents/devops.md +0 -728
- package/templates/.claude/agents/docs.md +0 -662
- package/templates/.claude/agents/implementer.md +0 -288
- package/templates/.claude/agents/planner.md +0 -273
- package/templates/.claude/agents/researcher.md +0 -454
- package/templates/.claude/agents/reviewer.md +0 -644
- package/templates/.claude/agents/security.md +0 -203
- package/templates/.claude/agents/tester.md +0 -647
- package/templates/.claude/commands/ai-sprint-auto.md +0 -150
- package/templates/.claude/commands/ai-sprint-code.md +0 -316
- package/templates/.claude/commands/ai-sprint-debug.md +0 -453
- package/templates/.claude/commands/ai-sprint-deploy.md +0 -475
- package/templates/.claude/commands/ai-sprint-docs.md +0 -519
- package/templates/.claude/commands/ai-sprint-plan.md +0 -136
- package/templates/.claude/commands/ai-sprint-review.md +0 -433
- package/templates/.claude/commands/ai-sprint-scan.md +0 -146
- package/templates/.claude/commands/ai-sprint-secure.md +0 -88
- package/templates/.claude/commands/ai-sprint-test.md +0 -352
- package/templates/.claude/commands/ai-sprint-validate.md +0 -253
- package/templates/.claude/settings.json +0 -27
- package/templates/.claude/skills/codebase-context/SKILL.md +0 -68
- package/templates/.claude/skills/codebase-context/references/reading-context.md +0 -68
- package/templates/.claude/skills/codebase-context/references/refresh-triggers.md +0 -82
- package/templates/.claude/skills/implementation/SKILL.md +0 -70
- package/templates/.claude/skills/implementation/references/error-handling.md +0 -106
- package/templates/.claude/skills/implementation/references/security-patterns.md +0 -73
- package/templates/.claude/skills/implementation/references/validation-patterns.md +0 -107
- package/templates/.claude/skills/memory/SKILL.md +0 -67
- package/templates/.claude/skills/memory/references/decisions-format.md +0 -68
- package/templates/.claude/skills/memory/references/learning-format.md +0 -74
- package/templates/.claude/skills/planning/SKILL.md +0 -72
- package/templates/.claude/skills/planning/references/plan-templates.md +0 -81
- package/templates/.claude/skills/planning/references/research-phase.md +0 -62
- package/templates/.claude/skills/planning/references/solution-design.md +0 -66
- package/templates/.claude/skills/quality-assurance/SKILL.md +0 -79
- package/templates/.claude/skills/quality-assurance/references/review-checklist.md +0 -72
- package/templates/.claude/skills/quality-assurance/references/security-checklist.md +0 -70
- package/templates/.claude/skills/quality-assurance/references/testing-strategy.md +0 -85
- package/templates/.claude/skills/quality-assurance/scripts/check-size.py +0 -333
- package/templates/.claude/statusline.sh +0 -126
- package/templates/.claude/workflows/development-rules.md +0 -133
- package/templates/.claude/workflows/orchestration-protocol.md +0 -194
- package/templates/.mcp.json.example +0 -36
- package/templates/CLAUDE.md +0 -412
- package/templates/README.md +0 -331
- package/templates/ai_context/codebase/.gitkeep +0 -0
- package/templates/ai_context/memory/active.md +0 -15
- package/templates/ai_context/memory/decisions.md +0 -18
- package/templates/ai_context/memory/learning.md +0 -22
- package/templates/ai_context/plans/.gitkeep +0 -0
- package/templates/ai_context/reports/.gitkeep +0 -0
- package/templates/docs/user-guide-th.md +0 -454
- package/templates/docs/user-guide.md +0 -595
package/lib/installer.js
CHANGED
|
@@ -1,229 +1,93 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { execFile } = require('child_process');
|
|
2
|
+
const { promisify } = require('util');
|
|
3
|
+
const fs = require('fs/promises');
|
|
2
4
|
const path = require('path');
|
|
3
|
-
const
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
const execa = require('execa');
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
* Check if .claude/ directory exists in target
|
|
9
|
-
*/
|
|
10
|
-
async function checkExisting(targetDir) {
|
|
11
|
-
const claudeDir = path.join(targetDir, '.claude');
|
|
12
|
-
return await fs.pathExists(claudeDir);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Install autonomous agent framework
|
|
17
|
-
*/
|
|
18
|
-
async function install(targetDir, options = {}) {
|
|
19
|
-
const { force = false, skipInstall = false } = options;
|
|
20
|
-
const templateDir = path.join(__dirname, '../templates');
|
|
21
|
-
const claudeDir = path.join(targetDir, '.claude');
|
|
22
|
-
|
|
23
|
-
await removeExistingIfForce(claudeDir, force);
|
|
24
|
-
|
|
25
|
-
const spinner = ora('Installing framework...').start();
|
|
26
|
-
try {
|
|
27
|
-
await copyTemplateFiles(templateDir, targetDir, claudeDir, force);
|
|
28
|
-
spinner.succeed('Framework installed');
|
|
29
|
-
|
|
30
|
-
if (!skipInstall) {
|
|
31
|
-
await installSkillDependencies(claudeDir);
|
|
32
|
-
}
|
|
33
|
-
await createInitialDirs(targetDir);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
spinner.fail('Installation failed');
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Remove existing .claude/ directory if force flag is set
|
|
42
|
-
*/
|
|
43
|
-
async function removeExistingIfForce(claudeDir, force) {
|
|
44
|
-
if (force && await fs.pathExists(claudeDir)) {
|
|
45
|
-
const spinner = ora('Removing existing .claude/ directory...').start();
|
|
46
|
-
await fs.remove(claudeDir);
|
|
47
|
-
spinner.succeed('Removed existing .claude/ directory');
|
|
48
|
-
}
|
|
49
|
-
}
|
|
7
|
+
const { PRIVATE_REPO } = require('./auth');
|
|
50
8
|
|
|
51
9
|
/**
|
|
52
|
-
*
|
|
10
|
+
* Clone private repo to temp directory
|
|
11
|
+
* @param {string} targetDir - User's project directory
|
|
12
|
+
* @returns {Promise<string>} - Path to cloned repo
|
|
53
13
|
*/
|
|
54
|
-
async function
|
|
55
|
-
|
|
56
|
-
|
|
14
|
+
async function cloneProRepo(targetDir) {
|
|
15
|
+
const { owner, name } = PRIVATE_REPO;
|
|
16
|
+
const tempDir = path.join(targetDir, '.ai-sprint-temp');
|
|
57
17
|
|
|
58
|
-
//
|
|
59
|
-
await
|
|
18
|
+
// Remove existing temp dir if present
|
|
19
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
60
20
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
await fs.copy(docsDir, path.join(claudeDir, 'docs'), { overwrite: force });
|
|
65
|
-
}
|
|
66
|
-
}
|
|
21
|
+
await execFileAsync('gh', [
|
|
22
|
+
'repo', 'clone', `${owner}/${name}`, tempDir, '--', '--depth=1'
|
|
23
|
+
]);
|
|
67
24
|
|
|
68
|
-
|
|
69
|
-
* Copy root template files (CLAUDE.md, README.md, etc.)
|
|
70
|
-
*/
|
|
71
|
-
async function copyRootFiles(templateDir, targetDir, force) {
|
|
72
|
-
const rootFiles = ['CLAUDE.md', 'README.md', '.mcp.json.example'];
|
|
73
|
-
|
|
74
|
-
for (const file of rootFiles) {
|
|
75
|
-
const srcPath = path.join(templateDir, file);
|
|
76
|
-
const destPath = path.join(targetDir, file);
|
|
77
|
-
|
|
78
|
-
if (await fs.pathExists(srcPath)) {
|
|
79
|
-
if (!await fs.pathExists(destPath) || force) {
|
|
80
|
-
await fs.copy(srcPath, destPath);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
25
|
+
return tempDir;
|
|
84
26
|
}
|
|
85
27
|
|
|
86
28
|
/**
|
|
87
|
-
*
|
|
29
|
+
* Copy Pro content to target directory
|
|
30
|
+
* @param {string} sourceDir - Cloned repo path
|
|
31
|
+
* @param {string} targetDir - User's project directory
|
|
32
|
+
* @param {boolean} force - Overwrite existing
|
|
88
33
|
*/
|
|
89
|
-
async function
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
34
|
+
async function copyProContent(sourceDir, targetDir, force = false) {
|
|
35
|
+
const items = [
|
|
36
|
+
{ src: '.claude', dest: '.claude' },
|
|
37
|
+
{ src: 'ai_context', dest: 'ai_context' },
|
|
38
|
+
{ src: 'CLAUDE.md', dest: 'CLAUDE.md' },
|
|
39
|
+
{ src: 'README.md', dest: 'AI-SPRINT-README.md' },
|
|
40
|
+
{ src: 'docs', dest: '.claude/docs' }
|
|
41
|
+
];
|
|
96
42
|
|
|
97
|
-
const
|
|
43
|
+
for (const item of items) {
|
|
44
|
+
const srcPath = path.join(sourceDir, item.src);
|
|
45
|
+
const destPath = path.join(targetDir, item.dest);
|
|
98
46
|
|
|
99
|
-
try {
|
|
100
|
-
// Check if Python 3 is available
|
|
101
47
|
try {
|
|
102
|
-
await
|
|
103
|
-
} catch
|
|
104
|
-
|
|
105
|
-
return;
|
|
48
|
+
await fs.access(srcPath);
|
|
49
|
+
} catch {
|
|
50
|
+
continue; // Source doesn't exist, skip
|
|
106
51
|
}
|
|
107
52
|
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
53
|
+
// Check if dest exists
|
|
54
|
+
try {
|
|
55
|
+
await fs.access(destPath);
|
|
56
|
+
if (!force) continue; // Don't overwrite
|
|
57
|
+
} catch {
|
|
58
|
+
// Dest doesn't exist, will create
|
|
114
59
|
}
|
|
115
60
|
|
|
116
|
-
|
|
117
|
-
const pythonPath = process.platform === 'win32'
|
|
118
|
-
? path.join(venvDir, 'Scripts', 'python.exe')
|
|
119
|
-
: path.join(venvDir, 'bin', 'python3');
|
|
120
|
-
|
|
121
|
-
await execa(pythonPath, ['-m', 'pip', 'install', '-r', 'requirements.txt'], {
|
|
122
|
-
cwd: skillsDir
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
spinner.succeed('Skill dependencies installed');
|
|
126
|
-
} catch (error) {
|
|
127
|
-
spinner.warn('Failed to install skill dependencies. You can install manually later.');
|
|
61
|
+
await fs.cp(srcPath, destPath, { recursive: true, force: true });
|
|
128
62
|
}
|
|
129
63
|
}
|
|
130
64
|
|
|
131
65
|
/**
|
|
132
|
-
*
|
|
66
|
+
* Cleanup temp directory
|
|
67
|
+
* @param {string} targetDir
|
|
133
68
|
*/
|
|
134
|
-
async function
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
'ai_context/plans',
|
|
138
|
-
'ai_context/docs',
|
|
139
|
-
'ai_context/reports',
|
|
140
|
-
'ai_context/reports/research',
|
|
141
|
-
'ai_context/reports/review',
|
|
142
|
-
'ai_context/reports/security',
|
|
143
|
-
'ai_context/reports/test',
|
|
144
|
-
'ai_context/reports/debug',
|
|
145
|
-
'ai_context/reports/deploy',
|
|
146
|
-
'ai_context/reports/docs',
|
|
147
|
-
'ai_context/memory'
|
|
148
|
-
];
|
|
149
|
-
|
|
150
|
-
for (const dir of dirs) {
|
|
151
|
-
await fs.ensureDir(path.join(targetDir, dir));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
await createMemoryFiles(targetDir);
|
|
69
|
+
async function cleanup(targetDir) {
|
|
70
|
+
const tempDir = path.join(targetDir, '.ai-sprint-temp');
|
|
71
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
155
72
|
}
|
|
156
73
|
|
|
157
74
|
/**
|
|
158
|
-
*
|
|
75
|
+
* Check if .claude/ exists in target
|
|
76
|
+
* @param {string} targetDir
|
|
77
|
+
* @returns {Promise<boolean>}
|
|
159
78
|
*/
|
|
160
|
-
async function
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
await fs.writeFile(filePath, content);
|
|
167
|
-
}
|
|
79
|
+
async function checkExisting(targetDir) {
|
|
80
|
+
try {
|
|
81
|
+
await fs.access(path.join(targetDir, '.claude'));
|
|
82
|
+
return true;
|
|
83
|
+
} catch {
|
|
84
|
+
return false;
|
|
168
85
|
}
|
|
169
86
|
}
|
|
170
87
|
|
|
171
|
-
/**
|
|
172
|
-
* Get memory file templates
|
|
173
|
-
*/
|
|
174
|
-
function getMemoryFileTemplates() {
|
|
175
|
-
return {
|
|
176
|
-
'ai_context/memory/learning.md': `# Learning Log
|
|
177
|
-
|
|
178
|
-
Lessons learned from past development sessions.
|
|
179
|
-
|
|
180
|
-
## Format
|
|
181
|
-
|
|
182
|
-
\`\`\`markdown
|
|
183
|
-
### [Date] - Lesson Title
|
|
184
|
-
**Context:** What happened
|
|
185
|
-
**Lesson:** What we learned
|
|
186
|
-
**Action:** How to avoid/apply in future
|
|
187
|
-
\`\`\`
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
_No lessons recorded yet._
|
|
192
|
-
`,
|
|
193
|
-
'ai_context/memory/decisions.md': `# Architecture Decisions
|
|
194
|
-
|
|
195
|
-
Key technical and design decisions made during development.
|
|
196
|
-
|
|
197
|
-
## Format
|
|
198
|
-
|
|
199
|
-
\`\`\`markdown
|
|
200
|
-
### [Date] - Decision Title
|
|
201
|
-
**Context:** Why this decision was needed
|
|
202
|
-
**Decision:** What was decided
|
|
203
|
-
**Consequences:** Trade-offs and implications
|
|
204
|
-
\`\`\`
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
_No decisions recorded yet._
|
|
209
|
-
`,
|
|
210
|
-
'ai_context/memory/active.md': `# Active Session Context
|
|
211
|
-
|
|
212
|
-
Current development focus and session state.
|
|
213
|
-
|
|
214
|
-
## Current Focus
|
|
215
|
-
_Not set_
|
|
216
|
-
|
|
217
|
-
## Recent Actions
|
|
218
|
-
_None_
|
|
219
|
-
|
|
220
|
-
## Next Steps
|
|
221
|
-
_None_
|
|
222
|
-
`
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
88
|
module.exports = {
|
|
227
|
-
|
|
89
|
+
cloneProRepo,
|
|
90
|
+
copyProContent,
|
|
91
|
+
cleanup,
|
|
228
92
|
checkExisting
|
|
229
93
|
};
|
package/lib/messages.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
const PURCHASE_URL = 'https://ai-sprint-kit.com';
|
|
4
|
+
|
|
5
|
+
const messages = {
|
|
6
|
+
ghNotInstalled: () => `
|
|
7
|
+
${chalk.red.bold('GitHub CLI not installed')}
|
|
8
|
+
|
|
9
|
+
AI Sprint requires the GitHub CLI (gh) to verify your license.
|
|
10
|
+
|
|
11
|
+
${chalk.cyan('Install gh:')}
|
|
12
|
+
macOS: ${chalk.gray('brew install gh')}
|
|
13
|
+
Windows: ${chalk.gray('winget install GitHub.cli')}
|
|
14
|
+
Linux: ${chalk.gray('https://cli.github.com/manual/installation')}
|
|
15
|
+
|
|
16
|
+
Then run ${chalk.yellow('ai-sprint init')} again.
|
|
17
|
+
`,
|
|
18
|
+
|
|
19
|
+
notAuthenticated: () => `
|
|
20
|
+
${chalk.red.bold('Not authenticated with GitHub')}
|
|
21
|
+
|
|
22
|
+
Please log in to GitHub CLI:
|
|
23
|
+
|
|
24
|
+
${chalk.cyan('gh auth login')}
|
|
25
|
+
|
|
26
|
+
Then run ${chalk.yellow('ai-sprint init')} again.
|
|
27
|
+
`,
|
|
28
|
+
|
|
29
|
+
noRepoAccess: (username) => `
|
|
30
|
+
${chalk.red.bold('License Required')}
|
|
31
|
+
|
|
32
|
+
${username ? `Logged in as: ${chalk.cyan(username)}` : ''}
|
|
33
|
+
|
|
34
|
+
You don't have access to AI Sprint Pro.
|
|
35
|
+
|
|
36
|
+
${chalk.cyan('Get your license:')}
|
|
37
|
+
${chalk.underline(PURCHASE_URL)}
|
|
38
|
+
|
|
39
|
+
After purchase, you'll receive a GitHub invitation.
|
|
40
|
+
Accept it, then run ${chalk.yellow('ai-sprint init')} again.
|
|
41
|
+
`,
|
|
42
|
+
|
|
43
|
+
success: () => `
|
|
44
|
+
${chalk.green.bold('AI Sprint Pro installed!')}
|
|
45
|
+
|
|
46
|
+
${chalk.cyan('Next steps:')}
|
|
47
|
+
1. Review ${chalk.gray('.claude/README.md')} for overview
|
|
48
|
+
2. Start Claude Code: ${chalk.gray('claude')}
|
|
49
|
+
3. Try: ${chalk.gray('/plan, /code, /test, /secure')}
|
|
50
|
+
`
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
module.exports = messages;
|
package/package.json
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-sprint-kit",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "CLI installer for autonomous
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "CLI installer for AI Sprint autonomous development framework - requires license",
|
|
5
5
|
"main": "lib/installer.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"ai-sprint": "bin/
|
|
7
|
+
"ai-sprint": "bin/ai-sprint.js",
|
|
8
|
+
"ai-sprint-kit": "bin/ai-sprint.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
|
-
"test": "node bin/
|
|
11
|
+
"test": "node bin/ai-sprint.js --help",
|
|
11
12
|
"link": "npm link",
|
|
12
|
-
"unlink": "npm unlink -g ai-sprint"
|
|
13
|
+
"unlink": "npm unlink -g ai-sprint-kit"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"claude-code",
|
|
16
17
|
"autonomous-agents",
|
|
17
18
|
"ai-development",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"ai-sprint"
|
|
19
|
+
"claude",
|
|
20
|
+
"anthropic",
|
|
21
|
+
"ai-sprint",
|
|
22
|
+
"devtools"
|
|
23
23
|
],
|
|
24
24
|
"author": "Apipoj Piasak <https://data-espresso.com>",
|
|
25
|
-
"license": "
|
|
25
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/apiasak/ai-sprint-kit.git"
|
|
28
|
+
"url": "https://github.com/apiasak/ai-sprint-kit.git",
|
|
29
|
+
"directory": "ai-sprint-kit/packages/cli"
|
|
29
30
|
},
|
|
30
31
|
"bugs": {
|
|
31
32
|
"url": "https://github.com/apiasak/ai-sprint-kit/issues"
|
|
32
33
|
},
|
|
33
|
-
"homepage": "https://
|
|
34
|
+
"homepage": "https://ai-sprint-kit.com",
|
|
34
35
|
"files": [
|
|
35
36
|
"bin/",
|
|
36
37
|
"lib/",
|
|
37
|
-
"templates/",
|
|
38
38
|
"README.md",
|
|
39
39
|
"LICENSE"
|
|
40
40
|
],
|
|
@@ -44,10 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"commander": "^11.1.0",
|
|
46
46
|
"chalk": "^4.1.2",
|
|
47
|
-
"ora": "^5.4.1"
|
|
48
|
-
"inquirer": "^8.2.6",
|
|
49
|
-
"fs-extra": "^11.2.0",
|
|
50
|
-
"execa": "^5.1.1"
|
|
47
|
+
"ora": "^5.4.1"
|
|
51
48
|
},
|
|
52
49
|
"publishConfig": {
|
|
53
50
|
"access": "public"
|
package/bin/cli.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { program } = require('commander');
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
const { install, checkExisting } = require('../lib/installer');
|
|
6
|
-
const { scanCodebase, detectSourceCode } = require('../lib/scanner');
|
|
7
|
-
const packageJson = require('../package.json');
|
|
8
|
-
|
|
9
|
-
program
|
|
10
|
-
.name('ai-sprint')
|
|
11
|
-
.description('AI Sprint - Autonomous development framework for Claude Code')
|
|
12
|
-
.version(packageJson.version);
|
|
13
|
-
|
|
14
|
-
program
|
|
15
|
-
.command('init')
|
|
16
|
-
.description('Initialize .claude/ directory with agents, commands, and skills')
|
|
17
|
-
.option('-d, --dir <directory>', 'Target directory (default: current directory)', process.cwd())
|
|
18
|
-
.option('-f, --force', 'Overwrite existing .claude/ directory', false)
|
|
19
|
-
.option('--skip-install', 'Skip npm install for skill dependencies', false)
|
|
20
|
-
.option('-s, --scan', 'Scan existing codebase after init', false)
|
|
21
|
-
.option('--no-scan', 'Skip automatic codebase scanning')
|
|
22
|
-
.action(async (options) => {
|
|
23
|
-
console.log(chalk.blue.bold('\nš AI Sprint Installer\n'));
|
|
24
|
-
|
|
25
|
-
const targetDir = options.dir;
|
|
26
|
-
|
|
27
|
-
// Check if .claude/ already exists
|
|
28
|
-
const existing = await checkExisting(targetDir);
|
|
29
|
-
if (existing && !options.force) {
|
|
30
|
-
console.log(chalk.yellow('ā ļø .claude/ directory already exists!'));
|
|
31
|
-
console.log(chalk.gray('Use --force to overwrite\n'));
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
await install(targetDir, {
|
|
37
|
-
force: options.force,
|
|
38
|
-
skipInstall: options.skipInstall
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
console.log(chalk.green.bold('\nā
Installation complete!\n'));
|
|
42
|
-
|
|
43
|
-
// Handle codebase scanning
|
|
44
|
-
let shouldScan = options.scan;
|
|
45
|
-
|
|
46
|
-
// Auto-detect if neither --scan nor --no-scan specified
|
|
47
|
-
if (!options.scan && options.scan !== false) {
|
|
48
|
-
const hasSource = await detectSourceCode(targetDir);
|
|
49
|
-
if (hasSource) {
|
|
50
|
-
console.log(chalk.cyan('š Source code detected. Scanning codebase...\n'));
|
|
51
|
-
shouldScan = true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (shouldScan) {
|
|
56
|
-
const result = await scanCodebase(targetDir);
|
|
57
|
-
if (result.success) {
|
|
58
|
-
console.log(chalk.gray(` Output: ai_context/codebase/\n`));
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
console.log(chalk.cyan('Next steps:'));
|
|
63
|
-
console.log(chalk.gray(' 1. Review .claude/README.md for framework overview'));
|
|
64
|
-
console.log(chalk.gray(' 2. Start Claude Code: claude'));
|
|
65
|
-
console.log(chalk.gray(' 3. Try commands: /plan, /code, /test, /secure'));
|
|
66
|
-
if (!shouldScan) {
|
|
67
|
-
console.log(chalk.gray(' 4. Run /scan to analyze existing codebase\n'));
|
|
68
|
-
} else {
|
|
69
|
-
console.log('');
|
|
70
|
-
}
|
|
71
|
-
} catch (error) {
|
|
72
|
-
console.error(chalk.red.bold('\nā Installation failed:\n'));
|
|
73
|
-
console.error(chalk.red(error.message));
|
|
74
|
-
console.error(chalk.gray('\nStack trace:'));
|
|
75
|
-
console.error(chalk.gray(error.stack));
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
program
|
|
81
|
-
.command('scan')
|
|
82
|
-
.description('Scan codebase and generate AI context documents')
|
|
83
|
-
.option('-d, --dir <directory>', 'Target directory (default: current directory)', process.cwd())
|
|
84
|
-
.action(async (options) => {
|
|
85
|
-
console.log(chalk.blue.bold('\nš AI Sprint Codebase Scanner\n'));
|
|
86
|
-
|
|
87
|
-
const targetDir = options.dir;
|
|
88
|
-
|
|
89
|
-
const result = await scanCodebase(targetDir);
|
|
90
|
-
|
|
91
|
-
if (result.success) {
|
|
92
|
-
console.log(chalk.green.bold('\nā
Scan complete!\n'));
|
|
93
|
-
console.log(chalk.gray(` Files: ${result.stats.totalFiles}`));
|
|
94
|
-
console.log(chalk.gray(` Duration: ${result.stats.scanDuration}s`));
|
|
95
|
-
console.log(chalk.gray(` Output: ai_context/codebase/\n`));
|
|
96
|
-
} else if (result.skipped) {
|
|
97
|
-
console.log(chalk.yellow(`\nā ļø Scan skipped: ${result.reason}\n`));
|
|
98
|
-
} else {
|
|
99
|
-
console.error(chalk.red.bold('\nā Scan failed\n'));
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
program
|
|
105
|
-
.command('list')
|
|
106
|
-
.description('List available agents and commands')
|
|
107
|
-
.action(() => {
|
|
108
|
-
console.log(chalk.blue.bold('\nš AI Sprint Framework\n'));
|
|
109
|
-
|
|
110
|
-
console.log(chalk.cyan('Agents (9):'));
|
|
111
|
-
console.log(chalk.gray(' ⢠planner - Research & architecture'));
|
|
112
|
-
console.log(chalk.gray(' ⢠implementer - Code generation & refactoring'));
|
|
113
|
-
console.log(chalk.gray(' ⢠tester - Test generation & automation'));
|
|
114
|
-
console.log(chalk.gray(' ⢠reviewer - Code quality review'));
|
|
115
|
-
console.log(chalk.gray(' ⢠security - SAST, secrets, dependencies'));
|
|
116
|
-
console.log(chalk.gray(' ⢠devops - CI/CD & deployment'));
|
|
117
|
-
console.log(chalk.gray(' ⢠docs - Documentation generation'));
|
|
118
|
-
console.log(chalk.gray(' ⢠debugger - Root cause analysis'));
|
|
119
|
-
console.log(chalk.gray(' ⢠researcher - Technology research'));
|
|
120
|
-
|
|
121
|
-
console.log(chalk.cyan('\nCommands (11):'));
|
|
122
|
-
console.log(chalk.gray(' ⢠/plan - Create implementation plan'));
|
|
123
|
-
console.log(chalk.gray(' ⢠/code - Generate/refactor code'));
|
|
124
|
-
console.log(chalk.gray(' ⢠/test - Generate and run tests'));
|
|
125
|
-
console.log(chalk.gray(' ⢠/review - Code quality review'));
|
|
126
|
-
console.log(chalk.gray(' ⢠/secure - Security scan (SAST + secrets + deps)'));
|
|
127
|
-
console.log(chalk.gray(' ⢠/deploy - CI/CD setup and deployment'));
|
|
128
|
-
console.log(chalk.gray(' ⢠/docs - Generate/update documentation'));
|
|
129
|
-
console.log(chalk.gray(' ⢠/debug - Investigate issues'));
|
|
130
|
-
console.log(chalk.gray(' ⢠/scan - Scan codebase for AI context'));
|
|
131
|
-
console.log(chalk.gray(' ⢠/validate - Pre-commit validation'));
|
|
132
|
-
console.log(chalk.gray(' ⢠/auto - Automatic full development cycle\n'));
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
program.parse();
|