taskplane 0.22.16 → 0.22.18
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/bin/rpc-wrapper.mjs +30 -1
- package/extensions/task-runner.ts +24 -63
- package/package.json +1 -1
package/bin/rpc-wrapper.mjs
CHANGED
|
@@ -770,10 +770,36 @@ piArgs.push(...args.passthrough);
|
|
|
770
770
|
|
|
771
771
|
// ── Spawn pi process ─────────────────────────────────────────────────
|
|
772
772
|
|
|
773
|
+
// ── System prompt: file-based passthrough to avoid command line limits ────
|
|
774
|
+
// Windows CreateProcess has a ~32K command line limit. Orchestrated worker
|
|
775
|
+
// system prompts routinely exceed this (PROMPT.md + context docs + steps).
|
|
776
|
+
// When the system prompt is large, write it to a temp file and use shell
|
|
777
|
+
// expansion `$(cat file)` to pass it. This works in MSYS2/Git Bash tmux
|
|
778
|
+
// (where the lane sessions run) without hitting the Win32 limit.
|
|
779
|
+
//
|
|
780
|
+
// For small system prompts (< 8K), pass inline for simplicity.
|
|
781
|
+
const SYSTEM_PROMPT_FILE_THRESHOLD = 8192;
|
|
782
|
+
let systemPromptTempFile = null;
|
|
783
|
+
|
|
784
|
+
if (systemPromptContent && systemPromptContent.length >= SYSTEM_PROMPT_FILE_THRESHOLD) {
|
|
785
|
+
// Remove --system-prompt from piArgs (was added above) and use file instead
|
|
786
|
+
const sysIdx = piArgs.indexOf("--system-prompt");
|
|
787
|
+
if (sysIdx >= 0) piArgs.splice(sysIdx, 2);
|
|
788
|
+
// Write to temp file and use --append-system-prompt with @file syntax.
|
|
789
|
+
// Pi's --append-system-prompt accepts @filepath to read from a file.
|
|
790
|
+
// We use --system-prompt "" (empty base) + --append-system-prompt @file
|
|
791
|
+
// to effectively set the system prompt from a file.
|
|
792
|
+
systemPromptTempFile = join(tmpdir(), `pi-rpc-sysprompt-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.txt`);
|
|
793
|
+
writeFileSync(systemPromptTempFile, systemPromptContent, "utf-8");
|
|
794
|
+
piArgs.push("--system-prompt", "");
|
|
795
|
+
piArgs.push("--append-system-prompt", `@${systemPromptTempFile}`);
|
|
796
|
+
process.stderr.write(`[rpc-wrapper] system prompt written to file (${systemPromptContent.length} chars): ${systemPromptTempFile}\n`);
|
|
797
|
+
}
|
|
798
|
+
|
|
773
799
|
const proc = spawn("pi", piArgs, {
|
|
774
800
|
stdio: ["pipe", "pipe", "pipe"],
|
|
775
801
|
env: { ...process.env },
|
|
776
|
-
shell: true,
|
|
802
|
+
shell: true,
|
|
777
803
|
});
|
|
778
804
|
|
|
779
805
|
// ── TP-097: Write PID file for orphan cleanup ──────────────────
|
|
@@ -796,6 +822,9 @@ try {
|
|
|
796
822
|
// Clean up PID file on process exit (best-effort)
|
|
797
823
|
function cleanupPidFile() {
|
|
798
824
|
try { unlinkSync(pidFilePath); } catch { /* ignore */ }
|
|
825
|
+
if (systemPromptTempFile) {
|
|
826
|
+
try { unlinkSync(systemPromptTempFile); } catch { /* ignore */ }
|
|
827
|
+
}
|
|
799
828
|
}
|
|
800
829
|
process.on("exit", cleanupPidFile);
|
|
801
830
|
|
|
@@ -3519,80 +3519,41 @@ export default function (pi: ExtensionAPI) {
|
|
|
3519
3519
|
|| workerDef?.model
|
|
3520
3520
|
|| (ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : "anthropic/claude-sonnet-4-20250514"));
|
|
3521
3521
|
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3522
|
+
// ── Lean worker prompt: pass file paths, not content ──────────
|
|
3523
|
+
// The worker reads PROMPT.md and STATUS.md itself using the read tool.
|
|
3524
|
+
// This keeps the initial prompt small (~500 chars) instead of embedding
|
|
3525
|
+
// 50K+ of compiled content that exceeds Windows command line limits
|
|
3526
|
+
// and wastes initial context window capacity.
|
|
3527
|
+
const promptLines = [
|
|
3528
|
+
`Read your task instructions at: ${task.promptPath}`,
|
|
3529
|
+
`Read your execution state at: ${statusPath}`,
|
|
3530
|
+
``,
|
|
3531
|
+
`Task: ${task.taskId}`,
|
|
3532
|
+
`Task folder: ${task.taskFolder}/`,
|
|
3533
|
+
`Iteration: ${state.totalIterations}`,
|
|
3534
|
+
`Wrap-up signal file: ${wrapUpFile}`,
|
|
3535
|
+
];
|
|
3525
3536
|
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
const archiveSuppression = isOrchestratedMode()
|
|
3530
|
-
? "\n\n⚠️ ORCHESTRATED RUN: Do NOT archive or move the task folder. " +
|
|
3531
|
-
"Do NOT rename, relocate, or reorganize the task folder path. " +
|
|
3532
|
-
"The orchestrator handles post-merge archival. " +
|
|
3533
|
-
"Just create the .DONE file in the task folder when complete."
|
|
3534
|
-
: "";
|
|
3537
|
+
if (isOrchestratedMode()) {
|
|
3538
|
+
promptLines.push(``, `⚠️ ORCHESTRATED RUN: Do NOT archive or move the task folder. The orchestrator handles post-merge archival.`);
|
|
3539
|
+
}
|
|
3535
3540
|
|
|
3536
|
-
// Build step listing for the worker prompt — show ALL steps with status
|
|
3537
|
-
const remainingSet = new Set(remainingSteps.map(s => s.number));
|
|
3538
|
-
const stepListing = task.steps.map(s =>
|
|
3539
|
-
remainingSet.has(s.number)
|
|
3540
|
-
? ` - Step ${s.number}: ${s.name}`
|
|
3541
|
-
: ` - Step ${s.number}: ${s.name} [already complete — skip]`
|
|
3542
|
-
).join("\n");
|
|
3543
|
-
|
|
3544
|
-
// TP-073: Build nudge for subsequent iterations (iter > 0)
|
|
3545
|
-
// When the worker exited without completing all steps, the next iteration
|
|
3546
|
-
// gets an explicit nudge listing completed/remaining steps and a warning
|
|
3547
|
-
// not to exit prematurely again.
|
|
3548
|
-
let iterationNudge = "";
|
|
3549
3541
|
if (state.totalIterations > 1 && remainingSteps.length > 0) {
|
|
3542
|
+
const remainingSet = new Set(remainingSteps.map(s => s.number));
|
|
3550
3543
|
const completedSteps = task.steps.filter(s => !remainingSet.has(s.number));
|
|
3551
3544
|
const completedList = completedSteps.length > 0
|
|
3552
3545
|
? completedSteps.map(s => `Step ${s.number}: ${s.name}`).join(", ")
|
|
3553
3546
|
: "(none)";
|
|
3554
3547
|
const remainingList = remainingSteps.map(s => `Step ${s.number}: ${s.name}`).join(", ");
|
|
3555
|
-
|
|
3556
|
-
``,
|
|
3557
|
-
`IMPORTANT: You exited on your previous iteration without completing all steps.`,
|
|
3558
|
-
`Do NOT repeat this — you must complete all remaining steps before stopping.`,
|
|
3559
|
-
``,
|
|
3560
|
-
`Completed steps (do not redo): ${completedList}`,
|
|
3561
|
-
`Remaining steps (focus here): ${remainingList}`,
|
|
3548
|
+
promptLines.push(
|
|
3562
3549
|
``,
|
|
3563
|
-
`
|
|
3564
|
-
`
|
|
3565
|
-
|
|
3566
|
-
|
|
3550
|
+
`IMPORTANT: You exited previously without completing all steps.`,
|
|
3551
|
+
`Completed (do not redo): ${completedList}`,
|
|
3552
|
+
`Remaining (focus here): ${remainingList}`,
|
|
3553
|
+
);
|
|
3567
3554
|
}
|
|
3568
3555
|
|
|
3569
|
-
const prompt =
|
|
3570
|
-
`Execute all remaining steps for task ${task.taskId}.`,
|
|
3571
|
-
``,
|
|
3572
|
-
`Task: ${task.taskId} — ${task.taskName}`,
|
|
3573
|
-
`Task folder: ${task.taskFolder}/`,
|
|
3574
|
-
`PROMPT: ${task.promptPath}`,
|
|
3575
|
-
`STATUS: ${statusPath}`,
|
|
3576
|
-
``,
|
|
3577
|
-
`This is iteration ${state.totalIterations}.`,
|
|
3578
|
-
`Read STATUS.md FIRST to find where you left off.`,
|
|
3579
|
-
iterationNudge,
|
|
3580
|
-
`Steps:`,
|
|
3581
|
-
stepListing,
|
|
3582
|
-
``,
|
|
3583
|
-
`Work through these steps in order. For each step:`,
|
|
3584
|
-
`1. Read STATUS.md to find unchecked items for that step`,
|
|
3585
|
-
`2. Complete all items for the step`,
|
|
3586
|
-
`3. Update STATUS.md step status to "complete"`,
|
|
3587
|
-
`4. Commit your changes: feat(${task.taskId}): complete Step N — description`,
|
|
3588
|
-
`5. Check for wrap-up signal files before starting the next step`,
|
|
3589
|
-
`6. Proceed to the next incomplete step`,
|
|
3590
|
-
``,
|
|
3591
|
-
`Wrap-up signal file: ${wrapUpFile}`,
|
|
3592
|
-
`Check for this file after each checkpoint. If it exists, stop.`,
|
|
3593
|
-
archiveSuppression,
|
|
3594
|
-
contextDocsList,
|
|
3595
|
-
].join("\n");
|
|
3556
|
+
const prompt = promptLines.join("\n");
|
|
3596
3557
|
|
|
3597
3558
|
state.workerStatus = "running";
|
|
3598
3559
|
state.workerElapsed = 0;
|