ai-sprint-kit 2.1.62 → 2.1.64

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 **16 specialized AI agents** with **22 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
- - 16 AI Agents (prd-writer, business-analyst, architect, planner, implementer, tester, reviewer, security, devops, docs, debugger, researcher, verifier, browser-tester, deployment-smoke, tdd-developer)
13
- - 22 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
@@ -18,10 +18,9 @@ const {
18
18
  cleanup,
19
19
  checkExisting,
20
20
  commandExists,
21
- installBun,
22
- installRalphTui,
23
- checkRalphTui,
24
- setupRalphTuiConfig,
21
+ checkDocker,
22
+ setupRalphTemplate,
23
+ checkRalphTemplate,
25
24
  installAgentBrowser,
26
25
  checkAgentBrowser
27
26
  } = require('../lib/installer');
@@ -68,60 +67,39 @@ function question(prompt) {
68
67
  });
69
68
  }
70
69
 
71
- // Shared function for ralph-tui installation with UI feedback
72
- // Returns: { success: boolean, bunInstalled: boolean, ralphInstalled: boolean }
73
- async function installRalphTuiWithUI(targetDir, options = {}) {
70
+ // Shared function for ralph-template setup with UI feedback
71
+ // Returns: { success: boolean, dockerAvailable: boolean }
72
+ async function setupRalphWithUI(targetDir, options = {}) {
74
73
  const { exitOnFail = false } = options;
75
74
 
76
- // Check if bun is installed
77
- const bunSpinner = ora('Checking Bun runtime...').start();
78
- const hasBun = await commandExists('bun');
75
+ // Check if Docker is available (optional but recommended)
76
+ const dockerSpinner = ora('Checking Docker...').start();
77
+ const hasDocker = await checkDocker();
79
78
 
80
- if (!hasBun) {
81
- bunSpinner.text = 'Installing Bun runtime...';
82
- const bunInstalled = await installBun();
83
- if (bunInstalled) {
84
- bunSpinner.succeed('Bun runtime installed');
85
- } else {
86
- if (exitOnFail) {
87
- bunSpinner.fail('Bun installation failed');
88
- console.log(chalk.yellow('\nInstall manually: curl -fsSL https://bun.sh/install | bash\n'));
89
- process.exit(1);
90
- } else {
91
- bunSpinner.warn('Bun installation failed. Install manually: curl -fsSL https://bun.sh/install | bash');
92
- return { success: false, bunInstalled: false, ralphInstalled: false };
93
- }
94
- }
79
+ if (hasDocker) {
80
+ dockerSpinner.succeed('Docker available (sandbox mode enabled)');
95
81
  } else {
96
- bunSpinner.succeed('Bun runtime found');
82
+ dockerSpinner.warn('Docker not found (manual mode only)');
83
+ console.log(chalk.gray(' Install Docker for sandboxed execution: https://docker.com\n'));
97
84
  }
98
85
 
99
- // Install ralph-tui
100
- const ralphSpinner = ora('Installing ralph-tui...').start();
101
- const hasRalph = await checkRalphTui();
86
+ // Setup ralph-template files
87
+ const setupSpinner = ora('Setting up ralph-template...').start();
88
+ const setupSuccess = await setupRalphTemplate(targetDir);
102
89
 
103
- if (!hasRalph) {
104
- const ralphInstalled = await installRalphTui();
105
- if (ralphInstalled) {
106
- ralphSpinner.succeed('ralph-tui installed');
90
+ if (setupSuccess) {
91
+ setupSpinner.succeed('ralph-template configured');
92
+ } else {
93
+ if (exitOnFail) {
94
+ setupSpinner.fail('ralph-template setup failed');
95
+ process.exit(1);
107
96
  } else {
108
- if (exitOnFail) {
109
- ralphSpinner.fail('ralph-tui installation failed');
110
- console.log(chalk.yellow('\nInstall manually: bun install -g ralph-tui\n'));
111
- process.exit(1);
112
- } else {
113
- ralphSpinner.warn('ralph-tui installation failed. Install manually: bun install -g ralph-tui');
114
- return { success: false, bunInstalled: true, ralphInstalled: false };
115
- }
97
+ setupSpinner.warn('ralph-template setup incomplete');
98
+ return { success: false, dockerAvailable: hasDocker };
116
99
  }
117
- } else {
118
- ralphSpinner.succeed('ralph-tui already installed');
119
100
  }
120
101
 
121
- // Setup project config
122
- await setupRalphTuiConfig(targetDir);
123
-
124
- return { success: true, bunInstalled: !hasBun, ralphInstalled: !hasRalph };
102
+ return { success: true, dockerAvailable: hasDocker };
125
103
  }
126
104
 
127
105
  program
@@ -277,21 +255,21 @@ program
277
255
  console.log(chalk.gray('\nRun later: ai-sprint setup-mcp\n'));
278
256
  }
279
257
 
280
- // Ask if user wants to install ralph-tui for autonomous loops
281
- console.log(chalk.cyan('🔄 Ralph TUI - Autonomous Agent Loop (Optional)\n'));
282
- console.log(chalk.gray('Ralph TUI runs AI agents autonomously through task lists'));
283
- console.log(chalk.gray('with session persistence, TUI dashboard, and crash recovery.\n'));
258
+ // Ask if user wants to setup ralph-template for autonomous loops
259
+ console.log(chalk.cyan('🔄 Ralph Template - Autonomous Agent Loop (Optional)\n'));
260
+ console.log(chalk.gray('Ralph runs Claude in autonomous loops, completing tasks one-by-one'));
261
+ console.log(chalk.gray('with Docker sandbox isolation (recommended) or manual mode.\n'));
284
262
 
285
- const setupRalph = await question('Install ralph-tui now? (Y/n): ');
263
+ const setupRalph = await question('Setup ralph-template now? (Y/n): ');
286
264
  if (setupRalph.toLowerCase() !== 'n') {
287
265
  console.log();
288
- const result = await installRalphTuiWithUI(targetDir, { exitOnFail: false });
266
+ const result = await setupRalphWithUI(targetDir, { exitOnFail: false });
289
267
  if (result.success) {
290
- console.log(chalk.green('\n✅ ralph-tui configured\n'));
268
+ console.log(chalk.green('\n✅ ralph-template configured\n'));
291
269
  console.log(chalk.cyan('Quick start:'));
292
- console.log(chalk.gray(' 1. Create PRD: ralph-tui create-prd --chat'));
293
- console.log(chalk.gray(' 2. Run loop: ralph-tui run --prd ./prd.json'));
294
- console.log(chalk.gray(' 3. Check docs: https://ralph-tui.com/docs\n'));
270
+ console.log(chalk.gray(' 1. Create PRD: cd ralph && claude @START_PROMPT.md "your idea"'));
271
+ console.log(chalk.gray(' 2. Run loop: ./ralph/afk-ralph.sh 10'));
272
+ console.log(chalk.gray(' 3. Manual mode: claude @ralph/PROMPT_MANUAL.md\n'));
295
273
  }
296
274
  } else {
297
275
  console.log(chalk.gray('\nRun later: ai-sprint setup-ralph\n'));
@@ -327,7 +305,7 @@ program
327
305
  console.log(chalk.gray(' /ai-sprint-browser-test, /ai-sprint-orchestrate'));
328
306
  console.log(chalk.gray(' /ai-sprint-setup, /ai-sprint-auto, /ai-sprint-full-cycle'));
329
307
  console.log(chalk.cyan('\nAutonomous Loop:'));
330
- console.log(chalk.gray(' ralph-tui (external) - https://ralph-tui.com'));
308
+ console.log(chalk.gray(' ralph-template (built-in) - ./ralph/afk-ralph.sh'));
331
309
  console.log(chalk.cyan('\nCLI Commands:'));
332
310
  console.log(chalk.gray(' init, list, validate, doctor, update, check-update'));
333
311
  console.log(chalk.gray(' setup-env, setup-mcp, setup-ralph, repair, reinstall, init-ci\n'));
@@ -634,24 +612,25 @@ program
634
612
 
635
613
  program
636
614
  .command('setup-ralph')
637
- .description('Install and configure ralph-tui for autonomous loops')
615
+ .description('Setup ralph-template for autonomous loops')
638
616
  .option('-d, --dir <directory>', 'Target directory', process.cwd())
639
617
  .action(async (options) => {
640
- console.log(chalk.blue.bold('\n🔄 Ralph TUI Setup\n'));
618
+ console.log(chalk.blue.bold('\n🔄 Ralph Template Setup\n'));
641
619
 
642
- // Use shared installation function (exits on failure)
643
- await installRalphTuiWithUI(options.dir, { exitOnFail: true });
620
+ // Use shared setup function (exits on failure)
621
+ await setupRalphWithUI(options.dir, { exitOnFail: true });
644
622
 
645
- console.log(chalk.green.bold('\n✅ ralph-tui configured\n'));
623
+ console.log(chalk.green.bold('\n✅ ralph-template configured\n'));
646
624
  console.log(chalk.cyan('Quick start:'));
647
- console.log(chalk.gray(' 1. Create PRD: ralph-tui create-prd --chat'));
648
- console.log(chalk.gray(' 2. Run loop: ralph-tui run --prd ./prd.json'));
649
- console.log(chalk.gray(' 3. Check docs: https://ralph-tui.com/docs\n'));
650
-
651
- console.log(chalk.cyan('AI Sprint integration:'));
652
- console.log(chalk.gray(' • Custom skill: ai_context/ralph-tui/skills/ai-sprint-prd/'));
653
- console.log(chalk.gray(' • Custom template: ai_context/ralph-tui/ai-sprint-template.hbs'));
654
- console.log(chalk.gray(' • Config: .ralph-tui/config.toml\n'));
625
+ console.log(chalk.gray(' 1. Create PRD: cd ralph && claude @START_PROMPT.md "your idea"'));
626
+ console.log(chalk.gray(' 2. Run loop: ./ralph/afk-ralph.sh 10'));
627
+ console.log(chalk.gray(' 3. Manual mode: claude @ralph/PROMPT_MANUAL.md\n'));
628
+
629
+ console.log(chalk.cyan('Files:'));
630
+ console.log(chalk.gray(' • Loop script: ralph/afk-ralph.sh'));
631
+ console.log(chalk.gray(' • Loop prompt: ralph/PROMPT.md'));
632
+ console.log(chalk.gray(' • Manual prompt: ralph/PROMPT_MANUAL.md'));
633
+ console.log(chalk.gray(' • PRD kickstart: ralph/START_PROMPT.md\n'));
655
634
  });
656
635
 
657
636
  program
package/lib/installer.js CHANGED
@@ -35,8 +35,8 @@ 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
- // EXCEPT ralph-tui config which contains skills and templates for ralph-tui integration
39
- { src: 'ai_context/ralph-tui', dest: 'ai_context/ralph-tui' },
38
+ // ralph-template files (bash scripts + prompts)
39
+ { src: 'ralph', dest: 'ralph' },
40
40
  // CLAUDE.md handled specially below - append instead of replace
41
41
  { src: 'README.md', dest: 'AI-SPRINT-README.md' },
42
42
  { src: 'docs', dest: '.claude/docs' },
@@ -117,9 +117,7 @@ async function createAiContextStructure(targetDir) {
117
117
  'plans',
118
118
  'reports',
119
119
  'codebase',
120
- 'memory',
121
- 'ralph-tui',
122
- 'ralph-tui/sessions'
120
+ 'memory'
123
121
  ];
124
122
 
125
123
  for (const dir of dirs) {
@@ -192,50 +190,59 @@ async function commandExists(cmd) {
192
190
  }
193
191
 
194
192
  /**
195
- * Install Bun runtime
196
- * @returns {Promise<boolean>} - Whether installation succeeded
193
+ * Check if Docker is available
194
+ * @returns {Promise<boolean>}
197
195
  */
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
- }
196
+ async function checkDocker() {
197
+ return commandExists('docker');
218
198
  }
219
199
 
220
200
  /**
221
- * Install ralph-tui globally via bun
222
- * @returns {Promise<boolean>} - Whether installation succeeded
201
+ * Setup ralph-template in project (copy bash scripts and prompts)
202
+ * @param {string} targetDir - User's project directory
203
+ * @returns {Promise<boolean>} - Whether setup succeeded
223
204
  */
224
- async function installRalphTui() {
205
+ async function setupRalphTemplate(targetDir) {
225
206
  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');
207
+ const ralphDir = path.join(targetDir, 'ralph');
208
+
209
+ // Create ralph directory if not exists
210
+ await fs.mkdir(ralphDir, { recursive: true });
211
+
212
+ // The ralph files should already be copied from pro/ralph/ during install
213
+ // Just verify they exist
214
+ const requiredFiles = ['afk-ralph.sh', 'PROMPT.md', 'START_PROMPT.md'];
215
+ for (const file of requiredFiles) {
231
216
  try {
232
- await fs.access(bunCmd);
217
+ await fs.access(path.join(ralphDir, file));
233
218
  } catch {
234
- return false;
219
+ // File missing, copy from .claude/templates/ralph if available
220
+ const templatePath = path.join(targetDir, '.claude', 'templates', 'ralph', file);
221
+ try {
222
+ await fs.access(templatePath);
223
+ await fs.copyFile(templatePath, path.join(ralphDir, file));
224
+ } catch {
225
+ // Template not found either, this is OK - files will be added later
226
+ }
235
227
  }
236
228
  }
237
-
238
- await execFileAsync(bunCmd, ['install', '-g', 'ralph-tui']);
229
+
230
+ // Make afk-ralph.sh executable
231
+ const scriptPath = path.join(ralphDir, 'afk-ralph.sh');
232
+ try {
233
+ await fs.chmod(scriptPath, 0o755);
234
+ } catch {
235
+ // Ignore chmod errors on Windows
236
+ }
237
+
238
+ // Create progress.txt if not exists
239
+ const progressPath = path.join(ralphDir, 'progress.txt');
240
+ try {
241
+ await fs.access(progressPath);
242
+ } catch {
243
+ await fs.writeFile(progressPath, '# Progress Log\n\nAutomatically updated by Ralph loop.\n');
244
+ }
245
+
239
246
  return true;
240
247
  } catch {
241
248
  return false;
@@ -243,11 +250,18 @@ async function installRalphTui() {
243
250
  }
244
251
 
245
252
  /**
246
- * Check if ralph-tui is installed
253
+ * Check if ralph-template is set up
254
+ * @param {string} targetDir - User's project directory
247
255
  * @returns {Promise<boolean>}
248
256
  */
249
- async function checkRalphTui() {
250
- return commandExists('ralph-tui');
257
+ async function checkRalphTemplate(targetDir) {
258
+ try {
259
+ const scriptPath = path.join(targetDir, 'ralph', 'afk-ralph.sh');
260
+ await fs.access(scriptPath);
261
+ return true;
262
+ } catch {
263
+ return false;
264
+ }
251
265
  }
252
266
 
253
267
  /**
@@ -272,32 +286,6 @@ async function checkAgentBrowser() {
272
286
  return commandExists('agent-browser');
273
287
  }
274
288
 
275
- /**
276
- * Setup ralph-tui configuration in project
277
- * @param {string} targetDir - User's project directory
278
- */
279
- async function setupRalphTuiConfig(targetDir) {
280
- const ralphTuiDir = path.join(targetDir, '.ralph-tui');
281
- const configSource = path.join(targetDir, 'ai_context', 'ralph-tui', 'config.toml');
282
- const configDest = path.join(ralphTuiDir, 'config.toml');
283
-
284
- // Create .ralph-tui directory
285
- await fs.mkdir(ralphTuiDir, { recursive: true });
286
-
287
- // Copy config if source exists and dest doesn't
288
- try {
289
- await fs.access(configSource);
290
- try {
291
- await fs.access(configDest);
292
- // Config exists, don't overwrite
293
- } catch {
294
- await fs.copyFile(configSource, configDest);
295
- }
296
- } catch {
297
- // Source doesn't exist, skip
298
- }
299
- }
300
-
301
289
  module.exports = {
302
290
  cloneProRepo,
303
291
  copyProContent,
@@ -305,10 +293,9 @@ module.exports = {
305
293
  cleanup,
306
294
  checkExisting,
307
295
  commandExists,
308
- installBun,
309
- installRalphTui,
310
- checkRalphTui,
311
- setupRalphTuiConfig,
296
+ checkDocker,
297
+ setupRalphTemplate,
298
+ checkRalphTemplate,
312
299
  installAgentBrowser,
313
300
  checkAgentBrowser
314
301
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-sprint-kit",
3
- "version": "2.1.62",
3
+ "version": "2.1.64",
4
4
  "description": "CLI installer for AI Sprint autonomous development framework - requires license",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {