mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 20:49:41 +02:00
feat: add research context to CLAUDE.md for Ralph Loop awareness
- After Ralph Wizard completes, updates case CLAUDE.md with links to all research files - Adds /init step before starting Ralph Loop tasks to load research context - Claude now knows where to find external resources, codebase patterns, recommendations - Research knowledge persists across respawn cycles via CLAUDE.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,7 +16,7 @@ When user says "COM":
|
||||
1. Increment version in BOTH `package.json` AND `CLAUDE.md`
|
||||
2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web`
|
||||
|
||||
**Version**: 0.1403 (must match `package.json`)
|
||||
**Version**: 0.1404 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claudeman",
|
||||
"version": "0.1403",
|
||||
"version": "0.1404",
|
||||
"description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
import { Session } from './session.js';
|
||||
import { ScreenManager } from './screen-manager.js';
|
||||
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
||||
import { join, dirname } from 'node:path';
|
||||
|
||||
// ============================================================================
|
||||
// Types
|
||||
@@ -919,11 +919,91 @@ ${prompt}
|
||||
writeFileSync(summaryPath, summary, 'utf-8');
|
||||
|
||||
console.log(`[PlanOrchestrator] Saved final result to ${this.outputDir}`);
|
||||
|
||||
// Update the case CLAUDE.md with research context links
|
||||
this.updateCaseClaudeMd();
|
||||
} catch (err) {
|
||||
console.error('[PlanOrchestrator] Failed to save final result:', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the case folder's CLAUDE.md with links to research and analysis files.
|
||||
* This allows Ralph Loop to `/init` and understand the available knowledge base.
|
||||
*/
|
||||
private updateCaseClaudeMd(): void {
|
||||
if (!this.outputDir) return;
|
||||
|
||||
try {
|
||||
// outputDir is like /path/to/case/ralph-wizard/
|
||||
// CLAUDE.md is in the parent (case folder)
|
||||
const caseDir = dirname(this.outputDir);
|
||||
const claudeMdPath = join(caseDir, 'CLAUDE.md');
|
||||
|
||||
// Get relative path from case folder to ralph-wizard
|
||||
const wizardRelPath = 'ralph-wizard';
|
||||
|
||||
// Build the research context section
|
||||
const contextSection = `
|
||||
## Ralph Wizard Knowledge Base
|
||||
|
||||
The following research and analysis files were generated for this task.
|
||||
Use \`/init\` to load this context, then read specific files as needed.
|
||||
|
||||
### Research Phase
|
||||
- \`${wizardRelPath}/research/result.json\` - External resources, codebase patterns, recommendations
|
||||
- \`${wizardRelPath}/research/prompt.md\` - Research agent instructions
|
||||
|
||||
### Analysis Phase
|
||||
- \`${wizardRelPath}/requirements/result.json\` - Requirements analysis
|
||||
- \`${wizardRelPath}/architecture/result.json\` - Architecture planning
|
||||
- \`${wizardRelPath}/testing/result.json\` - Testing strategy
|
||||
- \`${wizardRelPath}/risks/result.json\` - Risk analysis
|
||||
|
||||
### Synthesis & Optimization
|
||||
- \`${wizardRelPath}/verification/result.json\` - Plan verification and quality scoring
|
||||
- \`${wizardRelPath}/execution-optimizer/result.json\` - Parallelization strategy
|
||||
- \`${wizardRelPath}/final-review/result.json\` - Final review and completeness check
|
||||
|
||||
### Summary
|
||||
- \`${wizardRelPath}/summary.md\` - Human-readable plan summary
|
||||
- \`${wizardRelPath}/final-result.json\` - Complete plan with all metadata
|
||||
|
||||
**Key Research Insights**: Check \`${wizardRelPath}/research/result.json\` for:
|
||||
- External GitHub repos and documentation links
|
||||
- Existing codebase patterns to follow
|
||||
- Technical recommendations from research
|
||||
- Potential challenges to watch for
|
||||
- Recommended tools and libraries
|
||||
`;
|
||||
|
||||
// Read existing CLAUDE.md or create new one
|
||||
let existingContent = '';
|
||||
if (existsSync(claudeMdPath)) {
|
||||
existingContent = readFileSync(claudeMdPath, 'utf-8');
|
||||
|
||||
// Remove any existing Ralph Wizard section to avoid duplicates
|
||||
const sectionStart = existingContent.indexOf('## Ralph Wizard Knowledge Base');
|
||||
if (sectionStart !== -1) {
|
||||
// Find the next ## heading or end of file
|
||||
const nextSectionMatch = existingContent.slice(sectionStart + 1).match(/\n## /);
|
||||
const sectionEnd = nextSectionMatch
|
||||
? sectionStart + 1 + nextSectionMatch.index!
|
||||
: existingContent.length;
|
||||
existingContent = existingContent.slice(0, sectionStart) + existingContent.slice(sectionEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// Append the new section
|
||||
const newContent = existingContent.trimEnd() + '\n' + contextSection;
|
||||
writeFileSync(claudeMdPath, newContent, 'utf-8');
|
||||
|
||||
console.log(`[PlanOrchestrator] Updated CLAUDE.md with research context at ${claudeMdPath}`);
|
||||
} catch (err) {
|
||||
console.error('[PlanOrchestrator] Failed to update CLAUDE.md:', err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a human-readable summary of the plan.
|
||||
*/
|
||||
|
||||
+42
-1
@@ -4124,7 +4124,48 @@ class ClaudemanApp {
|
||||
throw new Error(errorData.error || `Failed to write prompt file: ${writeRes.status}`);
|
||||
}
|
||||
|
||||
console.log('[RalphWizard] Prompt file written, sending read command to Claude...');
|
||||
console.log('[RalphWizard] Prompt file written.');
|
||||
|
||||
// If plan was generated, send /init first to load CLAUDE.md with research context
|
||||
// This gives Claude awareness of all the research files before starting tasks
|
||||
if (hasPlan) {
|
||||
console.log('[RalphWizard] Sending /init to load research context from CLAUDE.md...');
|
||||
const initRes = await fetch(`/api/sessions/${sessionId}/input`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ input: '/init\r', useScreen: true })
|
||||
});
|
||||
|
||||
if (!initRes.ok) {
|
||||
console.warn('[RalphWizard] Failed to send /init, continuing anyway...');
|
||||
} else {
|
||||
// Wait for /init to complete (look for ready indicator or timeout)
|
||||
console.log('[RalphWizard] Waiting for /init to complete...');
|
||||
let initComplete = false;
|
||||
for (let attempt = 0; attempt < 20; attempt++) {
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
try {
|
||||
const statusRes = await fetch(`/api/sessions/${sessionId}`);
|
||||
const statusData = await statusRes.json();
|
||||
// /init is complete when we see the prompt indicator (❯) or status is ready
|
||||
if (statusData.status === 'ready' || statusData.lastOutput?.includes('❯')) {
|
||||
console.log('[RalphWizard] /init complete, Claude now has research context.');
|
||||
initComplete = true;
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[RalphWizard] Status check error:', e);
|
||||
}
|
||||
}
|
||||
if (!initComplete) {
|
||||
console.log('[RalphWizard] /init may still be running, proceeding anyway...');
|
||||
}
|
||||
// Small delay after /init
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[RalphWizard] Sending read command to Claude...');
|
||||
|
||||
// Send a simple command to Claude to read the prompt file
|
||||
// This avoids all the escaping issues with long multi-line prompts
|
||||
|
||||
Reference in New Issue
Block a user