taskplane 0.22.14 → 0.22.16

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.
@@ -935,9 +935,17 @@ attachJsonlReader(proc.stdout, (line) => {
935
935
  });
936
936
 
937
937
  // Forward stderr from pi to our stderr
938
+ // Capture pi stderr for diagnostics — last 2KB preserved in exit summary.
939
+ // This is critical for diagnosing startup crashes (pi exits code 1 with 0 tokens).
940
+ let piStderrBuffer = "";
941
+ const PI_STDERR_MAX = 2048;
938
942
  proc.stderr?.setEncoding("utf-8");
939
943
  proc.stderr?.on("data", (chunk) => {
940
944
  process.stderr.write(chunk);
945
+ piStderrBuffer += chunk;
946
+ if (piStderrBuffer.length > PI_STDERR_MAX * 2) {
947
+ piStderrBuffer = piStderrBuffer.slice(-PI_STDERR_MAX);
948
+ }
941
949
  });
942
950
 
943
951
  // ── Single-Write Exit Summary Finalization ───────────────────────────
@@ -967,7 +975,8 @@ proc.on("close", (code, signal) => {
967
975
 
968
976
  if (!state.agentEnded && code !== 0) {
969
977
  // Process crashed without agent_end — capture what we have
970
- const crashError = state.error || `pi process exited with code ${code}${signal ? ` (signal: ${signal})` : ""}`;
978
+ const stderrTail = piStderrBuffer.trim().slice(-PI_STDERR_MAX);
979
+ const crashError = state.error || `pi process exited with code ${code}${signal ? ` (signal: ${signal})` : ""}${stderrTail ? `\npi stderr: ${stderrTail}` : ""}`;
971
980
  writeExitSummary(state, code, signal, crashError, startTime);
972
981
  } else {
973
982
  writeExitSummary(state, code, signal, null, startTime);
@@ -173,8 +173,9 @@ export function generateTelemetryPaths(
173
173
  const effectiveBatchId = batchId || String(Date.now());
174
174
  const effectiveRepoId = repoId || "default";
175
175
 
176
- // Extract role from sessionName lane sessions are "worker" role
177
- const role = "worker";
176
+ // Lane sessions are the task-runner orchestration layer, NOT the worker agent.
177
+ // Use "lane" role to avoid filename collisions with worker sidecar files.
178
+ const role = "lane";
178
179
  const laneMatch = sessionName.match(/lane-(\d+)/);
179
180
  const laneSuffix = laneMatch ? `-lane-${laneMatch[1]}` : "";
180
181
 
@@ -588,6 +589,11 @@ export function buildTmuxSpawnArgs(
588
589
  "--exit-summary-path", shellQuote(exitSummaryPath),
589
590
  "--prompt-file", shellQuote(promptTmpFile),
590
591
  "--extensions", shellQuote(taskRunnerExtPath),
592
+ // Prevent pi from auto-discovering extensions from the worktree CWD.
593
+ // Without this, pi loads BOTH the explicit -e extension AND any
594
+ // extensions/ in the worktree, causing duplicate tool registration
595
+ // and unpredictable behavior (two copies of task-runner compete).
596
+ "--", "--no-extensions",
591
597
  ].filter(Boolean).join(" ");
592
598
  } else {
593
599
  // ── Legacy mode: direct pi spawn (no telemetry) ─────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskplane",
3
- "version": "0.22.14",
3
+ "version": "0.22.16",
4
4
  "description": "AI agent orchestration for pi — parallel task execution with checkpoint discipline",
5
5
  "keywords": [
6
6
  "pi-package",