ai-sprint-kit 2.1.45 → 2.1.48

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/README.md CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  ## What is AI Sprint?
8
8
 
9
- AI Sprint transforms Claude Code into a team of **12 specialized AI agents** with **17 powerful commands**. Build production-grade software with security-first, autonomous development.
9
+ AI Sprint transforms Claude Code into a team of **15 specialized AI agents** with **21 powerful commands**. Build production-grade software with security-first, autonomous development.
10
10
 
11
11
  **Features:**
12
- - 12 AI Agents (planner, implementer, tester, reviewer, security, devops, docs, debugger, researcher, verifier, browser-tester, deployment-smoke)
13
- - 17 Slash Commands for full development lifecycle
12
+ - 15 AI Agents (prd-writer, business-analyst, architect, planner, implementer, tester, reviewer, security, devops, docs, debugger, researcher, verifier, browser-tester, deployment-smoke)
13
+ - 21 Slash Commands for full development lifecycle
14
14
  - Automation Hooks (auto-format, lint-check, sound notifications)
15
15
  - Memory System for persistent context
16
16
  - Security-First with built-in SAST, secrets scanning, dependency audit
package/bin/ai-sprint.js CHANGED
@@ -16,7 +16,12 @@ const {
16
16
  copyProContent,
17
17
  createAiContextStructure,
18
18
  cleanup,
19
- checkExisting
19
+ checkExisting,
20
+ commandExists,
21
+ installBun,
22
+ installRalphTui,
23
+ checkRalphTui,
24
+ setupRalphTuiConfig
20
25
  } = require('../lib/installer');
21
26
  const {
22
27
  validateInstallation,
@@ -61,6 +66,62 @@ function question(prompt) {
61
66
  });
62
67
  }
63
68
 
69
+ // Shared function for ralph-tui installation with UI feedback
70
+ // Returns: { success: boolean, bunInstalled: boolean, ralphInstalled: boolean }
71
+ async function installRalphTuiWithUI(targetDir, options = {}) {
72
+ const { exitOnFail = false } = options;
73
+
74
+ // Check if bun is installed
75
+ const bunSpinner = ora('Checking Bun runtime...').start();
76
+ const hasBun = await commandExists('bun');
77
+
78
+ if (!hasBun) {
79
+ bunSpinner.text = 'Installing Bun runtime...';
80
+ const bunInstalled = await installBun();
81
+ if (bunInstalled) {
82
+ bunSpinner.succeed('Bun runtime installed');
83
+ } else {
84
+ if (exitOnFail) {
85
+ bunSpinner.fail('Bun installation failed');
86
+ console.log(chalk.yellow('\nInstall manually: curl -fsSL https://bun.sh/install | bash\n'));
87
+ process.exit(1);
88
+ } else {
89
+ bunSpinner.warn('Bun installation failed. Install manually: curl -fsSL https://bun.sh/install | bash');
90
+ return { success: false, bunInstalled: false, ralphInstalled: false };
91
+ }
92
+ }
93
+ } else {
94
+ bunSpinner.succeed('Bun runtime found');
95
+ }
96
+
97
+ // Install ralph-tui
98
+ const ralphSpinner = ora('Installing ralph-tui...').start();
99
+ const hasRalph = await checkRalphTui();
100
+
101
+ if (!hasRalph) {
102
+ const ralphInstalled = await installRalphTui();
103
+ if (ralphInstalled) {
104
+ ralphSpinner.succeed('ralph-tui installed');
105
+ } else {
106
+ if (exitOnFail) {
107
+ ralphSpinner.fail('ralph-tui installation failed');
108
+ console.log(chalk.yellow('\nInstall manually: bun install -g ralph-tui\n'));
109
+ process.exit(1);
110
+ } else {
111
+ ralphSpinner.warn('ralph-tui installation failed. Install manually: bun install -g ralph-tui');
112
+ return { success: false, bunInstalled: true, ralphInstalled: false };
113
+ }
114
+ }
115
+ } else {
116
+ ralphSpinner.succeed('ralph-tui already installed');
117
+ }
118
+
119
+ // Setup project config
120
+ await setupRalphTuiConfig(targetDir);
121
+
122
+ return { success: true, bunInstalled: !hasBun, ralphInstalled: !hasRalph };
123
+ }
124
+
64
125
  program
65
126
  .name('ai-sprint')
66
127
  .description('AI Sprint - Autonomous development framework for Claude Code')
@@ -199,6 +260,26 @@ program
199
260
  } else {
200
261
  console.log(chalk.gray('\nRun later: ai-sprint setup-mcp\n'));
201
262
  }
263
+
264
+ // Ask if user wants to install ralph-tui for autonomous loops
265
+ console.log(chalk.cyan('šŸ”„ Ralph TUI - Autonomous Agent Loop (Optional)\n'));
266
+ console.log(chalk.gray('Ralph TUI runs AI agents autonomously through task lists'));
267
+ console.log(chalk.gray('with session persistence, TUI dashboard, and crash recovery.\n'));
268
+
269
+ const setupRalph = await question('Install ralph-tui now? (Y/n): ');
270
+ if (setupRalph.toLowerCase() !== 'n') {
271
+ console.log();
272
+ const result = await installRalphTuiWithUI(targetDir, { exitOnFail: false });
273
+ if (result.success) {
274
+ console.log(chalk.green('\nāœ… ralph-tui configured\n'));
275
+ console.log(chalk.cyan('Quick start:'));
276
+ console.log(chalk.gray(' 1. Create PRD: ralph-tui create-prd --chat'));
277
+ console.log(chalk.gray(' 2. Run loop: ralph-tui run --prd ./prd.json'));
278
+ console.log(chalk.gray(' 3. Check docs: https://ralph-tui.com/docs\n'));
279
+ }
280
+ } else {
281
+ console.log(chalk.gray('\nRun later: ai-sprint setup-ralph\n'));
282
+ }
202
283
  } catch (error) {
203
284
  progress.failStep(2, error.message);
204
285
  cloneSpinner.fail('Installation failed');
@@ -216,19 +297,24 @@ program
216
297
  .description('Show AI Sprint Pro features')
217
298
  .action(() => {
218
299
  console.log(chalk.blue.bold('\nAI Sprint Pro Framework\n'));
219
- console.log(chalk.cyan('Agents (12):'));
220
- console.log(chalk.gray(' planner, implementer, tester, reviewer, security'));
221
- console.log(chalk.gray(' devops, docs, debugger, researcher, verifier'));
300
+ console.log(chalk.cyan('Agents (15):'));
301
+ console.log(chalk.gray(' prd-writer, business-analyst, architect, planner'));
302
+ console.log(chalk.gray(' implementer, tester, reviewer, security, devops'));
303
+ console.log(chalk.gray(' docs, debugger, researcher, verifier'));
222
304
  console.log(chalk.gray(' browser-tester, deployment-smoke'));
223
- console.log(chalk.cyan('\nCommands (15):'));
224
- console.log(chalk.gray(' /ai-sprint-plan, /ai-sprint-code, /ai-sprint-test'));
225
- console.log(chalk.gray(' /ai-sprint-review, /ai-sprint-secure, /ai-sprint-deploy'));
226
- console.log(chalk.gray(' /ai-sprint-docs, /ai-sprint-debug, /ai-sprint-scan'));
227
- console.log(chalk.gray(' /ai-sprint-validate, /ai-sprint-browser-test'));
228
- console.log(chalk.gray(' /ai-sprint-orchestrate, /ai-sprint-setup, /ai-sprint-auto'));
305
+ console.log(chalk.cyan('\nCommands (20):'));
306
+ console.log(chalk.gray(' /ai-sprint-prd, /ai-sprint-analyze, /ai-sprint-architect'));
307
+ console.log(chalk.gray(' /ai-sprint-init, /ai-sprint-plan, /ai-sprint-code'));
308
+ console.log(chalk.gray(' /ai-sprint-test, /ai-sprint-review, /ai-sprint-secure'));
309
+ console.log(chalk.gray(' /ai-sprint-deploy, /ai-sprint-docs, /ai-sprint-debug'));
310
+ console.log(chalk.gray(' /ai-sprint-fix, /ai-sprint-scan, /ai-sprint-validate'));
311
+ console.log(chalk.gray(' /ai-sprint-browser-test, /ai-sprint-orchestrate'));
312
+ console.log(chalk.gray(' /ai-sprint-setup, /ai-sprint-auto, /ai-sprint-full-cycle'));
313
+ console.log(chalk.cyan('\nAutonomous Loop:'));
314
+ console.log(chalk.gray(' ralph-tui (external) - https://ralph-tui.com'));
229
315
  console.log(chalk.cyan('\nCLI Commands:'));
230
316
  console.log(chalk.gray(' init, list, validate, doctor, update, check-update'));
231
- console.log(chalk.gray(' setup-env, setup-mcp, repair, reinstall, init-ci\n'));
317
+ console.log(chalk.gray(' setup-env, setup-mcp, setup-ralph, repair, reinstall, init-ci\n'));
232
318
  });
233
319
 
234
320
  program
@@ -530,6 +616,28 @@ program
530
616
  }
531
617
  });
532
618
 
619
+ program
620
+ .command('setup-ralph')
621
+ .description('Install and configure ralph-tui for autonomous loops')
622
+ .option('-d, --dir <directory>', 'Target directory', process.cwd())
623
+ .action(async (options) => {
624
+ console.log(chalk.blue.bold('\nšŸ”„ Ralph TUI Setup\n'));
625
+
626
+ // Use shared installation function (exits on failure)
627
+ await installRalphTuiWithUI(options.dir, { exitOnFail: true });
628
+
629
+ console.log(chalk.green.bold('\nāœ… ralph-tui configured\n'));
630
+ console.log(chalk.cyan('Quick start:'));
631
+ console.log(chalk.gray(' 1. Create PRD: ralph-tui create-prd --chat'));
632
+ console.log(chalk.gray(' 2. Run loop: ralph-tui run --prd ./prd.json'));
633
+ console.log(chalk.gray(' 3. Check docs: https://ralph-tui.com/docs\n'));
634
+
635
+ console.log(chalk.cyan('AI Sprint integration:'));
636
+ console.log(chalk.gray(' • Custom skill: ai_context/ralph-tui/skills/ai-sprint-prd/'));
637
+ console.log(chalk.gray(' • Custom template: ai_context/ralph-tui/ai-sprint-template.hbs'));
638
+ console.log(chalk.gray(' • Config: .ralph-tui/config.toml\n'));
639
+ });
640
+
533
641
  program
534
642
  .command('reinstall')
535
643
  .description('Clean reinstall AI Sprint Kit')
package/lib/installer.js CHANGED
@@ -35,7 +35,9 @@ async function copyProContent(sourceDir, targetDir, force = false) {
35
35
  const items = [
36
36
  { src: '.claude', dest: '.claude' },
37
37
  // ai_context is NOT copied - preserve user's plans, reports, memory
38
- { src: 'CLAUDE.md', dest: 'CLAUDE.md' },
38
+ // EXCEPT ralph-tui config which contains skills and templates for ralph-tui integration
39
+ { src: 'ai_context/ralph-tui', dest: 'ai_context/ralph-tui' },
40
+ // CLAUDE.md handled specially below - append instead of replace
39
41
  { src: 'README.md', dest: 'AI-SPRINT-README.md' },
40
42
  { src: 'docs', dest: '.claude/docs' },
41
43
  { src: 'scripts', dest: '.claude/scripts' }
@@ -61,6 +63,47 @@ async function copyProContent(sourceDir, targetDir, force = false) {
61
63
 
62
64
  await fs.cp(srcPath, destPath, { recursive: true, force: true });
63
65
  }
66
+
67
+ // Handle CLAUDE.md specially - append if exists, create if not
68
+ await handleClaudeMd(sourceDir, targetDir);
69
+ }
70
+
71
+ /**
72
+ * Handle CLAUDE.md - append AI Sprint content if file exists, create if not
73
+ * @param {string} sourceDir - Cloned repo path
74
+ * @param {string} targetDir - User's project directory
75
+ */
76
+ async function handleClaudeMd(sourceDir, targetDir) {
77
+ const srcPath = path.join(sourceDir, 'CLAUDE.md');
78
+ const destPath = path.join(targetDir, 'CLAUDE.md');
79
+
80
+ try {
81
+ await fs.access(srcPath);
82
+ } catch {
83
+ return; // Source doesn't exist, skip
84
+ }
85
+
86
+ const aiSprintContent = await fs.readFile(srcPath, 'utf-8');
87
+ const separator = '\n\n---\n\n# AI Sprint Kit Framework\n\n';
88
+
89
+ try {
90
+ // Check if CLAUDE.md exists
91
+ const existingContent = await fs.readFile(destPath, 'utf-8');
92
+
93
+ // Check if AI Sprint content already added
94
+ if (existingContent.includes('# AI Sprint Kit Framework') ||
95
+ existingContent.includes('AI Sprint - Security-first')) {
96
+ // Already has AI Sprint content, skip
97
+ return;
98
+ }
99
+
100
+ // Append AI Sprint content to existing file
101
+ const mergedContent = existingContent.trimEnd() + separator + aiSprintContent;
102
+ await fs.writeFile(destPath, mergedContent);
103
+ } catch {
104
+ // CLAUDE.md doesn't exist, create new
105
+ await fs.copyFile(srcPath, destPath);
106
+ }
64
107
  }
65
108
 
66
109
  /**
@@ -74,7 +117,9 @@ async function createAiContextStructure(targetDir) {
74
117
  'plans',
75
118
  'reports',
76
119
  'codebase',
77
- 'memory'
120
+ 'memory',
121
+ 'ralph-tui',
122
+ 'ralph-tui/sessions'
78
123
  ];
79
124
 
80
125
  for (const dir of dirs) {
@@ -132,10 +177,114 @@ async function checkExisting(targetDir) {
132
177
  }
133
178
  }
134
179
 
180
+ /**
181
+ * Check if a command exists
182
+ * @param {string} cmd - Command to check
183
+ * @returns {Promise<boolean>}
184
+ */
185
+ async function commandExists(cmd) {
186
+ try {
187
+ await execFileAsync('which', [cmd]);
188
+ return true;
189
+ } catch {
190
+ return false;
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Install Bun runtime
196
+ * @returns {Promise<boolean>} - Whether installation succeeded
197
+ */
198
+ async function installBun() {
199
+ try {
200
+ // Use curl to install bun
201
+ const { exec } = require('child_process');
202
+ const { promisify } = require('util');
203
+ const execAsync = promisify(exec);
204
+
205
+ await execAsync('curl -fsSL https://bun.sh/install | bash');
206
+
207
+ // Check if bun is now available
208
+ const bunPath = path.join(process.env.HOME, '.bun', 'bin', 'bun');
209
+ try {
210
+ await fs.access(bunPath);
211
+ return true;
212
+ } catch {
213
+ return false;
214
+ }
215
+ } catch {
216
+ return false;
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Install ralph-tui globally via bun
222
+ * @returns {Promise<boolean>} - Whether installation succeeded
223
+ */
224
+ async function installRalphTui() {
225
+ try {
226
+ // Try system bun first
227
+ let bunCmd = 'bun';
228
+ if (!await commandExists('bun')) {
229
+ // Try home directory bun
230
+ bunCmd = path.join(process.env.HOME, '.bun', 'bin', 'bun');
231
+ try {
232
+ await fs.access(bunCmd);
233
+ } catch {
234
+ return false;
235
+ }
236
+ }
237
+
238
+ await execFileAsync(bunCmd, ['install', '-g', 'ralph-tui']);
239
+ return true;
240
+ } catch {
241
+ return false;
242
+ }
243
+ }
244
+
245
+ /**
246
+ * Check if ralph-tui is installed
247
+ * @returns {Promise<boolean>}
248
+ */
249
+ async function checkRalphTui() {
250
+ return commandExists('ralph-tui');
251
+ }
252
+
253
+ /**
254
+ * Setup ralph-tui configuration in project
255
+ * @param {string} targetDir - User's project directory
256
+ */
257
+ async function setupRalphTuiConfig(targetDir) {
258
+ const ralphTuiDir = path.join(targetDir, '.ralph-tui');
259
+ const configSource = path.join(targetDir, 'ai_context', 'ralph-tui', 'config.toml');
260
+ const configDest = path.join(ralphTuiDir, 'config.toml');
261
+
262
+ // Create .ralph-tui directory
263
+ await fs.mkdir(ralphTuiDir, { recursive: true });
264
+
265
+ // Copy config if source exists and dest doesn't
266
+ try {
267
+ await fs.access(configSource);
268
+ try {
269
+ await fs.access(configDest);
270
+ // Config exists, don't overwrite
271
+ } catch {
272
+ await fs.copyFile(configSource, configDest);
273
+ }
274
+ } catch {
275
+ // Source doesn't exist, skip
276
+ }
277
+ }
278
+
135
279
  module.exports = {
136
280
  cloneProRepo,
137
281
  copyProContent,
138
282
  createAiContextStructure,
139
283
  cleanup,
140
- checkExisting
284
+ checkExisting,
285
+ commandExists,
286
+ installBun,
287
+ installRalphTui,
288
+ checkRalphTui,
289
+ setupRalphTuiConfig
141
290
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-sprint-kit",
3
- "version": "2.1.45",
3
+ "version": "2.1.48",
4
4
  "description": "CLI installer for AI Sprint autonomous development framework - requires license",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {