live reporting commit requests, resume prints batching
This commit is contained in:
14
index.ts
14
index.ts
@@ -885,6 +885,20 @@ async function handleResume(
|
|||||||
const mode = await selectExecutionMode(ctx, project, taskFile, config);
|
const mode = await selectExecutionMode(ctx, project, taskFile, config);
|
||||||
const plan = buildPlanByMode(mode, project, completed);
|
const plan = buildPlanByMode(mode, project, completed);
|
||||||
|
|
||||||
|
// Print remaining batches before executing
|
||||||
|
const formattedPlan = formatExecutionPlan(plan);
|
||||||
|
if (mode === "parallel") {
|
||||||
|
ctx.ui.notify(
|
||||||
|
`${formattedPlan}\n\nResuming parallel execution...`,
|
||||||
|
"info",
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ctx.ui.notify(
|
||||||
|
`${formattedPlan}\n\nResuming sequential execution...`,
|
||||||
|
"info",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await executePlanBatches(
|
await executePlanBatches(
|
||||||
plan,
|
plan,
|
||||||
project,
|
project,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@mikefreno/ralpi",
|
"name": "@mikefreno/ralpi",
|
||||||
"version": "0.2.4",
|
"version": "0.2.5",
|
||||||
"description": "Execute tasks from task files/PRD's using DAG-based dependency resolution with persistent progress tracking",
|
"description": "Execute tasks from task files/PRD's using DAG-based dependency resolution with persistent progress tracking",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"pi-package",
|
"pi-package",
|
||||||
|
|||||||
104
src/executor.ts
104
src/executor.ts
@@ -706,20 +706,115 @@ async function executeTask(
|
|||||||
"```",
|
"```",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
|
// ── Commit widget setup ──
|
||||||
|
const commitWidgetKey = `ralpi-commit-${task.id}`;
|
||||||
|
let commitFrameIndex = 0;
|
||||||
|
const commitToolCalls: ToolCallEntry[] = [];
|
||||||
|
let commitWidgetTui: { requestRender(): void } | null = null;
|
||||||
|
|
||||||
|
const commitHeader = `commit for ${task.id} · ${task.title}`;
|
||||||
|
|
||||||
|
const buildCommitLines = (
|
||||||
|
t: typeof ctx.ui.theme,
|
||||||
|
width?: number,
|
||||||
|
): string[] => {
|
||||||
|
const effectiveWidth = width || 74;
|
||||||
|
const frame = t.fg(
|
||||||
|
"accent",
|
||||||
|
SPINNER_FRAMES[commitFrameIndex % SPINNER_FRAMES.length],
|
||||||
|
);
|
||||||
|
const lines = [
|
||||||
|
truncateToWidth(`~ ${frame} ${commitHeader}`, effectiveWidth),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (commitToolCalls.length > 0) {
|
||||||
|
if (commitToolCalls.length <= MAX_COLLAPSED) {
|
||||||
|
for (let i = 0; i < commitToolCalls.length; i++) {
|
||||||
|
const entry = commitToolCalls[i];
|
||||||
|
const isLast = i === commitToolCalls.length - 1;
|
||||||
|
const branch = isLast ? " └── " : " ├── ";
|
||||||
|
const tag = t.fg("accent", `[${entry.name}]`);
|
||||||
|
lines.push(
|
||||||
|
truncateToWidth(
|
||||||
|
`${branch}${tag} ${entry.label}`,
|
||||||
|
effectiveWidth,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const shown = commitToolCalls.slice(-MAX_COLLAPSED);
|
||||||
|
const remaining = commitToolCalls.length - shown.length;
|
||||||
|
lines.push(
|
||||||
|
truncateToWidth(
|
||||||
|
t.fg("dim", ` ├── …${remaining} earlier`),
|
||||||
|
effectiveWidth,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
for (let i = 0; i < shown.length; i++) {
|
||||||
|
const entry = shown[i];
|
||||||
|
const isLast = i === shown.length - 1;
|
||||||
|
const branch = isLast ? " └── " : " ├── ";
|
||||||
|
const tag = t.fg("accent", `[${entry.name}]`);
|
||||||
|
lines.push(
|
||||||
|
truncateToWidth(
|
||||||
|
`${branch}${tag} ${entry.label}`,
|
||||||
|
effectiveWidth,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.ui.setWidget(commitWidgetKey, (tui, t) => {
|
||||||
|
commitWidgetTui = tui;
|
||||||
|
return {
|
||||||
|
render: (width?: number) => buildCommitLines(t, width),
|
||||||
|
invalidate: () => commitWidgetTui?.requestRender(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const requestCommitRender = () =>
|
||||||
|
commitWidgetTui?.requestRender();
|
||||||
|
|
||||||
|
const commitSpinnerTimer = setInterval(() => {
|
||||||
|
commitFrameIndex =
|
||||||
|
(commitFrameIndex + 1) % SPINNER_FRAMES.length;
|
||||||
|
requestCommitRender();
|
||||||
|
}, 100);
|
||||||
|
|
||||||
// Use a short timeout for the commit session (60s should be enough)
|
// Use a short timeout for the commit session (60s should be enough)
|
||||||
const commitTimeout = Math.min(
|
const commitTimeout = Math.min(
|
||||||
60_000,
|
60_000,
|
||||||
config.execution.timeoutMs,
|
config.execution.timeoutMs,
|
||||||
);
|
);
|
||||||
const commitResult = await runAgentSession(
|
|
||||||
|
let commitResult: Awaited<ReturnType<typeof runAgentSession>>;
|
||||||
|
|
||||||
|
try {
|
||||||
|
commitResult = await runAgentSession(
|
||||||
commitPrompt,
|
commitPrompt,
|
||||||
projectDir,
|
projectDir,
|
||||||
commitTimeout,
|
commitTimeout,
|
||||||
undefined,
|
(event) => {
|
||||||
|
if (event.type === "tool_execution_start") {
|
||||||
|
const label = formatToolArg(event.toolName, event.args);
|
||||||
|
commitToolCalls.push({
|
||||||
|
name: event.toolName,
|
||||||
|
label,
|
||||||
|
});
|
||||||
|
requestCommitRender();
|
||||||
|
}
|
||||||
|
},
|
||||||
undefined,
|
undefined,
|
||||||
currentModel,
|
currentModel,
|
||||||
config.thinkingLevel,
|
config.thinkingLevel,
|
||||||
);
|
);
|
||||||
|
} finally {
|
||||||
|
clearInterval(commitSpinnerTimer);
|
||||||
|
ctx.ui.setWidget(commitWidgetKey, undefined);
|
||||||
|
}
|
||||||
|
|
||||||
if (commitResult.success) {
|
if (commitResult.success) {
|
||||||
// Re-capture commits made during this follow-up session
|
// Re-capture commits made during this follow-up session
|
||||||
@@ -733,10 +828,13 @@ async function executeTask(
|
|||||||
? `${finalCommitSummary}; ${newCommits.commitSummary}`
|
? `${finalCommitSummary}; ${newCommits.commitSummary}`
|
||||||
: newCommits.commitSummary;
|
: newCommits.commitSummary;
|
||||||
}
|
}
|
||||||
sendChatMessage?.(`✓ commit for ${task.id} · ${task.title}`);
|
sendChatMessage?.(`✓ commit for ${task.id} · ${task.title}`, {
|
||||||
|
toolCalls: commitToolCalls,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
sendChatMessage?.(
|
sendChatMessage?.(
|
||||||
`~ commit for ${task.id} · ${task.title} — follow-up commit session failed: ${commitResult.error}`,
|
`~ commit for ${task.id} · ${task.title} — follow-up commit session failed: ${commitResult.error}`,
|
||||||
|
{ toolCalls: commitToolCalls },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user