taskplane 0.22.6 → 0.22.8
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.
|
@@ -2148,6 +2148,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
2148
2148
|
|
|
2149
2149
|
// ── review_step Tool (orchestrated mode only) ───────────────────
|
|
2150
2150
|
|
|
2151
|
+
/** Per-step code review cycle counter. Reset when reviewer is killed after APPROVE. */
|
|
2152
|
+
const stepCodeReviewCounts = new Map<number, number>();
|
|
2153
|
+
|
|
2151
2154
|
/**
|
|
2152
2155
|
* Reset reviewer telemetry fields on state to idle/zero.
|
|
2153
2156
|
* Called after a review completes to clear dashboard metrics.
|
|
@@ -2291,6 +2294,30 @@ export default function (pi: ExtensionAPI) {
|
|
|
2291
2294
|
const reviewsDir = join(task.taskFolder, ".reviews");
|
|
2292
2295
|
if (!existsSync(reviewsDir)) mkdirSync(reviewsDir, { recursive: true });
|
|
2293
2296
|
|
|
2297
|
+
// Per-step code review cycle limit
|
|
2298
|
+
if (reviewType === "code") {
|
|
2299
|
+
const codeCount = (stepCodeReviewCounts.get(stepNum) || 0) + 1;
|
|
2300
|
+
stepCodeReviewCounts.set(stepNum, codeCount);
|
|
2301
|
+
const maxCycles = config.context.max_review_cycles || 2;
|
|
2302
|
+
if (codeCount > maxCycles) {
|
|
2303
|
+
logExecution(statusPath, `Skip code review`,
|
|
2304
|
+
`Step ${stepNum} code review cycle limit reached (${codeCount}/${maxCycles}) — auto-approving`);
|
|
2305
|
+
// Kill reviewer to free context for next step
|
|
2306
|
+
if (state.persistentReviewerKill) {
|
|
2307
|
+
try { state.persistentReviewerKill(); } catch {}
|
|
2308
|
+
}
|
|
2309
|
+
state.persistentReviewerSession = null;
|
|
2310
|
+
state.persistentReviewerKill = null;
|
|
2311
|
+
state.persistentReviewerSignalNum = 0;
|
|
2312
|
+
state.reviewerRespawnCount = 0;
|
|
2313
|
+
stepCodeReviewCounts.delete(stepNum);
|
|
2314
|
+
return {
|
|
2315
|
+
content: [{ type: "text" as const, text: `APPROVE — Code review cycle limit reached (${maxCycles}). Auto-approved to prevent context exhaustion.` }],
|
|
2316
|
+
details: undefined,
|
|
2317
|
+
};
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2294
2321
|
// Low-risk step check (safety net — worker template also skips)
|
|
2295
2322
|
if (isLowRiskStep(stepNum, task.steps.length)) {
|
|
2296
2323
|
const label = stepNum === 0 ? "Preflight" : "final step";
|
|
@@ -2551,17 +2578,19 @@ export default function (pi: ExtensionAPI) {
|
|
|
2551
2578
|
updateWidgets();
|
|
2552
2579
|
|
|
2553
2580
|
// Extract verdict and build result
|
|
2554
|
-
const { resultText } = processReviewVerdict(
|
|
2581
|
+
const { resultText, verdict } = processReviewVerdict(
|
|
2555
2582
|
reviewContent, statusPath, num, reviewType, stepNum, state.reviewCounter,
|
|
2556
2583
|
);
|
|
2557
2584
|
|
|
2558
|
-
// After code review: kill the persistent reviewer to free context.
|
|
2559
|
-
// The reviewer persists through
|
|
2560
|
-
//
|
|
2561
|
-
|
|
2562
|
-
|
|
2585
|
+
// After code review APPROVE: kill the persistent reviewer to free context.
|
|
2586
|
+
// The reviewer persists through plan+code for one step, and through
|
|
2587
|
+
// REVISE→fix→re-review cycles (it knows what it asked to be fixed).
|
|
2588
|
+
// Only kill on APPROVE — a REVISE means the worker needs to fix and
|
|
2589
|
+
// re-submit, and the same reviewer should evaluate the follow-up.
|
|
2590
|
+
if (reviewType === "code" && (verdict === "APPROVE" || verdict === "UNAVAILABLE")) {
|
|
2591
|
+
console.error(`[task-runner] code review ${verdict} for step ${stepNum} — killing reviewer for fresh context on next step`);
|
|
2563
2592
|
logExecution(statusPath, `Reviewer R${num}`,
|
|
2564
|
-
`code review
|
|
2593
|
+
`code review ${verdict} — killing persistent reviewer (step ${stepNum} cycle done)`);
|
|
2565
2594
|
if (state.persistentReviewerKill) {
|
|
2566
2595
|
try { state.persistentReviewerKill(); } catch {}
|
|
2567
2596
|
}
|
|
@@ -2569,6 +2598,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
2569
2598
|
state.persistentReviewerKill = null;
|
|
2570
2599
|
state.persistentReviewerSignalNum = 0;
|
|
2571
2600
|
state.reviewerRespawnCount = 0;
|
|
2601
|
+
stepCodeReviewCounts.delete(stepNum);
|
|
2572
2602
|
}
|
|
2573
2603
|
|
|
2574
2604
|
state.reviewerStatus = "idle";
|
|
@@ -2824,6 +2854,26 @@ export default function (pi: ExtensionAPI) {
|
|
|
2824
2854
|
}
|
|
2825
2855
|
}
|
|
2826
2856
|
|
|
2857
|
+
// ── Step transition: kill persistent reviewer for fresh context ──
|
|
2858
|
+
// When a step completes, the reviewer's context from that step is stale.
|
|
2859
|
+
// Kill it so the next step gets a clean reviewer session.
|
|
2860
|
+
if (newlyCompleted.length > 0 && state.persistentReviewerSession) {
|
|
2861
|
+
console.error(`[task-runner] step(s) completed — killing reviewer for fresh context`);
|
|
2862
|
+
logExecution(statusPath, "Reviewer cleanup",
|
|
2863
|
+
`killing persistent reviewer on step transition (${newlyCompleted.map(s => `Step ${s.number}`).join(", ")} completed)`);
|
|
2864
|
+
if (state.persistentReviewerKill) {
|
|
2865
|
+
try { state.persistentReviewerKill(); } catch {}
|
|
2866
|
+
}
|
|
2867
|
+
state.persistentReviewerSession = null;
|
|
2868
|
+
state.persistentReviewerKill = null;
|
|
2869
|
+
state.persistentReviewerSignalNum = 0;
|
|
2870
|
+
state.reviewerRespawnCount = 0;
|
|
2871
|
+
// Reset per-step code review counters for completed steps
|
|
2872
|
+
for (const step of newlyCompleted) {
|
|
2873
|
+
stepCodeReviewCounts.delete(step.number);
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2827
2877
|
// Log iteration summary with progress delta and completed steps
|
|
2828
2878
|
const completedNames = newlyCompleted.map(s => `Step ${s.number}`).join(", ");
|
|
2829
2879
|
if (newlyCompleted.length > 0) {
|
package/package.json
CHANGED
|
@@ -205,7 +205,8 @@ value.
|
|
|
205
205
|
- **APPROVE** → proceed to next step
|
|
206
206
|
- **RETHINK** → reconsider your plan approach, adjust, then implement
|
|
207
207
|
- **REVISE** → read the review file in `.reviews/` for detailed feedback,
|
|
208
|
-
address the issues, commit fixes, then
|
|
208
|
+
address the issues, commit fixes, then **call `review_step` again** for re-review.
|
|
209
|
+
The same reviewer evaluates whether your fixes address its concerns.
|
|
209
210
|
- **UNAVAILABLE** → reviewer failed, proceed with caution
|
|
210
211
|
|
|
211
212
|
**Example flow for a Review Level 2 task, Step 3:**
|
|
@@ -215,8 +216,9 @@ value.
|
|
|
215
216
|
4. Implement Step 3
|
|
216
217
|
5. Commit changes
|
|
217
218
|
6. Call `review_step(step=3, type="code", baseline="<saved SHA>")` → get code feedback
|
|
218
|
-
7. If REVISE: fix issues, commit again
|
|
219
|
-
8.
|
|
219
|
+
7. If REVISE: fix issues, commit, call `review_step(step=3, type="code")` again
|
|
220
|
+
8. Repeat 7 until APPROVE (max 2 code review cycles per step)
|
|
221
|
+
9. Move to Step 4
|
|
220
222
|
|
|
221
223
|
If the `review_step` tool is not available (e.g., non-orchestrated mode), skip
|
|
222
224
|
this protocol entirely — the task-runner handles reviews externally.
|