rafcode 1.2.0 → 1.3.2
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/RAF/019-verbose-chronicle/decisions.md +25 -0
- package/RAF/019-verbose-chronicle/input.md +3 -0
- package/RAF/019-verbose-chronicle/outcomes/001-amend-iteration-references.md +25 -0
- package/RAF/019-verbose-chronicle/outcomes/002-verbose-task-name-display.md +31 -0
- package/RAF/019-verbose-chronicle/outcomes/003-verbose-streaming-fix.md +48 -0
- package/RAF/019-verbose-chronicle/outcomes/004-commit-verification-before-halt.md +56 -0
- package/RAF/019-verbose-chronicle/plans/001-amend-iteration-references.md +35 -0
- package/RAF/019-verbose-chronicle/plans/002-verbose-task-name-display.md +38 -0
- package/RAF/019-verbose-chronicle/plans/003-verbose-streaming-fix.md +45 -0
- package/RAF/019-verbose-chronicle/plans/004-commit-verification-before-halt.md +62 -0
- package/dist/commands/do.js +19 -11
- package/dist/commands/do.js.map +1 -1
- package/dist/core/claude-runner.d.ts +52 -1
- package/dist/core/claude-runner.d.ts.map +1 -1
- package/dist/core/claude-runner.js +195 -17
- package/dist/core/claude-runner.js.map +1 -1
- package/dist/core/git.d.ts +15 -0
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +44 -0
- package/dist/core/git.js.map +1 -1
- package/dist/parsers/stream-renderer.d.ts +42 -0
- package/dist/parsers/stream-renderer.d.ts.map +1 -0
- package/dist/parsers/stream-renderer.js +100 -0
- package/dist/parsers/stream-renderer.js.map +1 -0
- package/dist/prompts/amend.d.ts.map +1 -1
- package/dist/prompts/amend.js +13 -2
- package/dist/prompts/amend.js.map +1 -1
- package/dist/prompts/execution.d.ts.map +1 -1
- package/dist/prompts/execution.js +1 -3
- package/dist/prompts/execution.js.map +1 -1
- package/dist/prompts/planning.js +2 -2
- package/package.json +1 -1
- package/src/commands/do.ts +20 -11
- package/src/core/claude-runner.ts +270 -17
- package/src/core/git.ts +44 -0
- package/src/parsers/stream-renderer.ts +139 -0
- package/src/prompts/amend.ts +14 -2
- package/src/prompts/execution.ts +1 -3
- package/src/prompts/planning.ts +2 -2
- package/tests/unit/claude-runner.test.ts +567 -1
- package/tests/unit/git-commit-helpers.test.ts +103 -0
- package/tests/unit/plan-command.test.ts +51 -0
- package/tests/unit/stream-renderer.test.ts +286 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders stream-json events from Claude CLI into human-readable verbose output.
|
|
3
|
+
*
|
|
4
|
+
* Event types from `claude -p --output-format stream-json --verbose`:
|
|
5
|
+
* - system (init): Session initialization info
|
|
6
|
+
* - assistant: Claude's response with text or tool_use content blocks
|
|
7
|
+
* - user: Tool results (tool_result content blocks)
|
|
8
|
+
* - result: Final result with success/failure status
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Describes what a tool is doing in human-readable form.
|
|
12
|
+
*/
|
|
13
|
+
function describeToolUse(name, input) {
|
|
14
|
+
switch (name) {
|
|
15
|
+
case 'Read':
|
|
16
|
+
return `Reading ${input.file_path ?? 'file'}`;
|
|
17
|
+
case 'Write':
|
|
18
|
+
return `Writing ${input.file_path ?? 'file'}`;
|
|
19
|
+
case 'Edit':
|
|
20
|
+
return `Editing ${input.file_path ?? 'file'}`;
|
|
21
|
+
case 'Bash':
|
|
22
|
+
return `Running: ${truncate(String(input.command ?? ''), 120)}`;
|
|
23
|
+
case 'Glob':
|
|
24
|
+
return `Searching files: ${input.pattern ?? ''}`;
|
|
25
|
+
case 'Grep':
|
|
26
|
+
return `Searching for: ${truncate(String(input.pattern ?? ''), 80)}`;
|
|
27
|
+
case 'WebFetch':
|
|
28
|
+
return `Fetching: ${input.url ?? ''}`;
|
|
29
|
+
case 'WebSearch':
|
|
30
|
+
return `Searching web: ${input.query ?? ''}`;
|
|
31
|
+
case 'TodoWrite':
|
|
32
|
+
return 'Updating task list';
|
|
33
|
+
case 'Task':
|
|
34
|
+
return `Launching agent: ${truncate(String(input.description ?? input.prompt ?? ''), 80)}`;
|
|
35
|
+
case 'NotebookEdit':
|
|
36
|
+
return `Editing notebook: ${input.notebook_path ?? ''}`;
|
|
37
|
+
default:
|
|
38
|
+
return `Using tool: ${name}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function truncate(text, maxLen) {
|
|
42
|
+
if (text.length <= maxLen)
|
|
43
|
+
return text;
|
|
44
|
+
return text.substring(0, maxLen - 3) + '...';
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Parse and render a single NDJSON line from stream-json output.
|
|
48
|
+
* Returns display text for stdout and text content for output accumulation.
|
|
49
|
+
*/
|
|
50
|
+
export function renderStreamEvent(line) {
|
|
51
|
+
if (!line.trim()) {
|
|
52
|
+
return { display: '', textContent: '' };
|
|
53
|
+
}
|
|
54
|
+
let event;
|
|
55
|
+
try {
|
|
56
|
+
event = JSON.parse(line);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Not valid JSON - pass through raw
|
|
60
|
+
return { display: line + '\n', textContent: line };
|
|
61
|
+
}
|
|
62
|
+
switch (event.type) {
|
|
63
|
+
case 'system':
|
|
64
|
+
return { display: '', textContent: '' };
|
|
65
|
+
case 'assistant':
|
|
66
|
+
return renderAssistant(event);
|
|
67
|
+
case 'user':
|
|
68
|
+
// Tool results — skip verbose display (the tool_use already described what's happening)
|
|
69
|
+
return { display: '', textContent: '' };
|
|
70
|
+
case 'result':
|
|
71
|
+
return renderResult(event);
|
|
72
|
+
default:
|
|
73
|
+
return { display: '', textContent: '' };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function renderAssistant(event) {
|
|
77
|
+
const content = event.message?.content;
|
|
78
|
+
if (!content || !Array.isArray(content)) {
|
|
79
|
+
return { display: '', textContent: '' };
|
|
80
|
+
}
|
|
81
|
+
let display = '';
|
|
82
|
+
let textContent = '';
|
|
83
|
+
for (const block of content) {
|
|
84
|
+
if (block.type === 'text' && block.text) {
|
|
85
|
+
textContent += block.text;
|
|
86
|
+
display += block.text + '\n';
|
|
87
|
+
}
|
|
88
|
+
else if (block.type === 'tool_use' && block.name) {
|
|
89
|
+
const description = describeToolUse(block.name, block.input ?? {});
|
|
90
|
+
display += ` → ${description}\n`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { display, textContent };
|
|
94
|
+
}
|
|
95
|
+
function renderResult(_event) {
|
|
96
|
+
// The result event's text duplicates the last assistant message,
|
|
97
|
+
// which is already captured. Skip to avoid double-counting.
|
|
98
|
+
return { display: '', textContent: '' };
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=stream-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-renderer.js","sourceRoot":"","sources":["../../src/parsers/stream-renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amend.d.ts","sourceRoot":"","sources":["../../src/prompts/amend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,KAAK,CAAC,WAAW,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"amend.d.ts","sourceRoot":"","sources":["../../src/prompts/amend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,KAAK,CAAC,WAAW,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAuM3E"}
|
package/dist/prompts/amend.js
CHANGED
|
@@ -13,7 +13,10 @@ export function getAmendPrompt(params) {
|
|
|
13
13
|
? '[FAILED]'
|
|
14
14
|
: '[PENDING]';
|
|
15
15
|
const modifiability = task.status === 'completed' ? '[PROTECTED]' : '[MODIFIABLE]';
|
|
16
|
-
|
|
16
|
+
const outcomeRef = task.status === 'completed'
|
|
17
|
+
? `\n Outcome: ${projectPath}/outcomes/${task.planFile.replace('plans/', '').replace(/\.md$/, '')}.md`
|
|
18
|
+
: '';
|
|
19
|
+
return `- Task ${task.id}: ${task.taskName} ${status} ${modifiability}${outcomeRef}`;
|
|
17
20
|
})
|
|
18
21
|
.join('\n');
|
|
19
22
|
const protectedTasks = existingTasks.filter((t) => t.status === 'completed');
|
|
@@ -67,6 +70,13 @@ Read the user's description of new tasks and identify what needs to be added. Co
|
|
|
67
70
|
- Dependencies on completed tasks (check the ## Dependencies section in existing plan files)
|
|
68
71
|
- Whether new tasks should reference existing task outcomes
|
|
69
72
|
|
|
73
|
+
**Identifying Follow-up Tasks**: When a new task is a follow-up, fix, or iteration of a previously completed task, you MUST reference the previous task's outcome in the new plan's Context section. This gives the executing agent full context about what was done before.
|
|
74
|
+
|
|
75
|
+
Use this format in the Context section:
|
|
76
|
+
\`This is a follow-up to task NNN. See outcome: {projectPath}/outcomes/NNN-task-name.md\`
|
|
77
|
+
|
|
78
|
+
The outcome file paths for completed tasks are listed above in the Existing Tasks section.
|
|
79
|
+
|
|
70
80
|
### Step 3: Interview the User
|
|
71
81
|
|
|
72
82
|
For EACH new task you identify, use the AskUserQuestion tool to gather:
|
|
@@ -82,7 +92,7 @@ After EACH interview question is answered, append the Q&A pair to the existing d
|
|
|
82
92
|
|
|
83
93
|
Use this format:
|
|
84
94
|
\`\`\`markdown
|
|
85
|
-
## [
|
|
95
|
+
## [Question asked]
|
|
86
96
|
[User's answer]
|
|
87
97
|
\`\`\`
|
|
88
98
|
|
|
@@ -104,6 +114,7 @@ Each plan file should follow this structure:
|
|
|
104
114
|
## Context
|
|
105
115
|
[Why this task is needed, how it fits into the larger project]
|
|
106
116
|
[Reference relevant existing tasks if applicable]
|
|
117
|
+
[For follow-up/fix tasks: "This is a follow-up to task NNN. See outcome: {projectPath}/outcomes/NNN-task-name.md"]
|
|
107
118
|
|
|
108
119
|
## Dependencies
|
|
109
120
|
[Optional section - omit if task has no dependencies]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"amend.js","sourceRoot":"","sources":["../../src/prompts/amend.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB;IACtD,MAAM,EACJ,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,GAAG,MAAM,CAAC;IAEX,MAAM,oBAAoB,GAAG,aAAa;SACvC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,KAAK,WAAW;YACzB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ;gBACxB,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,WAAW,CAAC;QACpB,MAAM,aAAa,GACjB,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC;QAC/D,OAAO,UAAU,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,QAAQ,IAAI,MAAM,IAAI,aAAa,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"amend.js","sourceRoot":"","sources":["../../src/prompts/amend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/prompts/execution.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2BxD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/prompts/execution.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA2BxD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAsKxE"}
|
|
@@ -119,12 +119,10 @@ First, read the plan file to understand exactly what needs to be done.
|
|
|
119
119
|
### Step 2: Execute the Task
|
|
120
120
|
|
|
121
121
|
Follow the implementation steps in the plan. Key guidelines:
|
|
122
|
-
- **Use the Task tool to delegate work to subagents** - Split complex work into subtasks and use specialized agents (Explore for codebase investigation, Plan for design decisions, general-purpose for implementation)
|
|
123
122
|
- Write clean, maintainable code
|
|
124
123
|
- Follow existing code patterns in the project
|
|
125
124
|
- Add appropriate error handling
|
|
126
|
-
-
|
|
127
|
-
- Follow any CLAUDE.md instructions if present
|
|
125
|
+
- Follow any CLAUDE.md instructions
|
|
128
126
|
${dependencyContextSection}${outcomesSection}
|
|
129
127
|
### Step 3: Verify Completion
|
|
130
128
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/prompts/execution.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/prompts/execution.ts"],"names":[],"mappings":"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"}
|
package/dist/prompts/planning.js
CHANGED
|
@@ -9,7 +9,7 @@ export function getPlanningPrompt(params) {
|
|
|
9
9
|
|
|
10
10
|
## Your Goals
|
|
11
11
|
|
|
12
|
-
1. **Analyze the input** and identify
|
|
12
|
+
1. **Analyze the input** and identify distinct, actionable tasks
|
|
13
13
|
2. **Interview the user** about EACH task to gather specific requirements
|
|
14
14
|
3. **Create plan files** for each task with clear instructions
|
|
15
15
|
|
|
@@ -21,7 +21,7 @@ Project folder: ${projectPath}
|
|
|
21
21
|
|
|
22
22
|
### Step 1: Identify and Order Tasks
|
|
23
23
|
|
|
24
|
-
Based on the project description, identify
|
|
24
|
+
Based on the project description, identify distinct tasks. Each task should:
|
|
25
25
|
- Be independently completable
|
|
26
26
|
- Have a clear outcome
|
|
27
27
|
- Take roughly 10-30 minutes of work for Claude
|
package/package.json
CHANGED
package/src/commands/do.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
import { ProjectManager } from '../core/project-manager.js';
|
|
4
4
|
import { ClaudeRunner } from '../core/claude-runner.js';
|
|
5
5
|
import { shutdownHandler } from '../core/shutdown-handler.js';
|
|
6
|
-
import { stashChanges, hasUncommittedChanges } from '../core/git.js';
|
|
6
|
+
import { stashChanges, hasUncommittedChanges, isGitRepo, getHeadCommitHash } from '../core/git.js';
|
|
7
7
|
import { getExecutionPrompt } from '../prompts/execution.js';
|
|
8
8
|
import { parseOutput, isRetryableFailure } from '../parsers/output-parser.js';
|
|
9
9
|
import { validatePlansExist, resolveModelOption } from '../utils/validation.js';
|
|
@@ -446,6 +446,7 @@ async function executeSingleProject(
|
|
|
446
446
|
const taskName = extractTaskNameFromPlanFile(task.planFile);
|
|
447
447
|
const displayName = taskName ?? task.id;
|
|
448
448
|
const taskId = task.id; // Capture for closure
|
|
449
|
+
const taskLabel = displayName !== task.id ? `${task.id} (${displayName})` : task.id;
|
|
449
450
|
|
|
450
451
|
// Handle blocked tasks separately - skip Claude execution
|
|
451
452
|
if (task.status === 'blocked') {
|
|
@@ -459,7 +460,7 @@ async function executeSingleProject(
|
|
|
459
460
|
if (verbose) {
|
|
460
461
|
const taskContext = `[Task ${taskNumber}/${totalTasks}: ${displayName}]`;
|
|
461
462
|
logger.setContext(taskContext);
|
|
462
|
-
logger.warn(`Task ${
|
|
463
|
+
logger.warn(`Task ${taskLabel} blocked by failed dependency: ${blockingDep}`);
|
|
463
464
|
} else {
|
|
464
465
|
// Minimal mode: show blocked task line with distinct symbol
|
|
465
466
|
logger.info(formatTaskProgress(taskNumber, totalTasks, 'blocked', displayName, undefined, task.id));
|
|
@@ -484,11 +485,11 @@ async function executeSingleProject(
|
|
|
484
485
|
|
|
485
486
|
// Log task execution status
|
|
486
487
|
if (task.status === 'failed') {
|
|
487
|
-
logger.info(`Retrying task ${
|
|
488
|
+
logger.info(`Retrying task ${taskLabel} (previously failed)...`);
|
|
488
489
|
} else if (task.status === 'completed' && force) {
|
|
489
|
-
logger.info(`Re-running task ${
|
|
490
|
+
logger.info(`Re-running task ${taskLabel} (force mode)...`);
|
|
490
491
|
} else {
|
|
491
|
-
logger.info(`Executing task ${
|
|
492
|
+
logger.info(`Executing task ${taskLabel}...`);
|
|
492
493
|
}
|
|
493
494
|
}
|
|
494
495
|
|
|
@@ -527,7 +528,7 @@ async function executeSingleProject(
|
|
|
527
528
|
attempts++;
|
|
528
529
|
|
|
529
530
|
if (verbose && attempts > 1) {
|
|
530
|
-
logger.info(` Retry ${attempts}/${maxRetries}...`);
|
|
531
|
+
logger.info(` Retry ${attempts}/${maxRetries} for task ${taskLabel}...`);
|
|
531
532
|
}
|
|
532
533
|
|
|
533
534
|
// Build execution prompt (inside loop to include retry context on retries)
|
|
@@ -552,10 +553,18 @@ async function executeSingleProject(
|
|
|
552
553
|
dependencyOutcomes,
|
|
553
554
|
});
|
|
554
555
|
|
|
556
|
+
// Capture HEAD hash before execution for commit verification
|
|
557
|
+
const preExecutionHead = isGitRepo() ? getHeadCommitHash() : null;
|
|
558
|
+
const commitContext = preExecutionHead ? {
|
|
559
|
+
preExecutionHead,
|
|
560
|
+
expectedPrefix: `RAF[${projectNumber}:${task.id}]`,
|
|
561
|
+
outcomeFilePath,
|
|
562
|
+
} : undefined;
|
|
563
|
+
|
|
555
564
|
// Run Claude
|
|
556
565
|
const result = verbose
|
|
557
|
-
? await claudeRunner.runVerbose(prompt, { timeout })
|
|
558
|
-
: await claudeRunner.run(prompt, { timeout });
|
|
566
|
+
? await claudeRunner.runVerbose(prompt, { timeout, outcomeFilePath, commitContext })
|
|
567
|
+
: await claudeRunner.run(prompt, { timeout, outcomeFilePath, commitContext });
|
|
559
568
|
|
|
560
569
|
lastOutput = result.output;
|
|
561
570
|
|
|
@@ -667,7 +676,7 @@ Task completed. No detailed report provided.
|
|
|
667
676
|
projectManager.saveOutcome(projectPath, task.id, outcomeContent);
|
|
668
677
|
|
|
669
678
|
if (verbose) {
|
|
670
|
-
logger.success(` Task ${
|
|
679
|
+
logger.success(` Task ${taskLabel} completed (${elapsedFormatted})`);
|
|
671
680
|
} else {
|
|
672
681
|
// Minimal mode: show completed task line
|
|
673
682
|
logger.info(formatTaskProgress(taskNumber, totalTasks, 'completed', displayName, elapsedMs, task.id));
|
|
@@ -681,12 +690,12 @@ Task completed. No detailed report provided.
|
|
|
681
690
|
stashName = `raf-${projectNum}-task-${task.id}-failed`;
|
|
682
691
|
const stashed = stashChanges(stashName);
|
|
683
692
|
if (verbose && stashed) {
|
|
684
|
-
logger.info(` Changes stashed as: ${stashName}`);
|
|
693
|
+
logger.info(` Changes for task ${taskLabel} stashed as: ${stashName}`);
|
|
685
694
|
}
|
|
686
695
|
}
|
|
687
696
|
|
|
688
697
|
if (verbose) {
|
|
689
|
-
logger.error(` Task ${
|
|
698
|
+
logger.error(` Task ${taskLabel} failed: ${failureReason} (${elapsedFormatted})`);
|
|
690
699
|
logger.info(' Analyzing failure...');
|
|
691
700
|
} else {
|
|
692
701
|
// Minimal mode: show failed task line
|