taskplane 0.23.2 → 0.23.4

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.
@@ -11,8 +11,9 @@ import { userInfo } from "os";
11
11
  import { DONE_GRACE_MS, EXECUTION_POLL_INTERVAL_MS, ExecutionError, SESSION_SPAWN_RETRY_MAX } from "./types.ts";
12
12
  import type { AllocatedLane, AllocatedTask, DependencyGraph, LaneExecutionResult, LaneMonitorSnapshot, LaneTaskOutcome, LaneTaskStatus, MonitorState, MtimeTracker, OrchestratorConfig, ParsedTask, TaskMonitorSnapshot, WaveExecutionResult, WorkspaceConfig, ExecutionUnit, PacketPaths, RuntimeAgentId, RuntimeAgentRole, SupervisorAlertCallback } from "./types.ts";
13
13
  import { resolvePacketPaths, buildRuntimeAgentId } from "./types.ts";
14
- import { readRegistrySnapshot, isTerminalStatus, isProcessAlive } from "./process-registry.ts";
14
+ import { readRegistrySnapshot, readLaneSnapshot, isTerminalStatus, isProcessAlive } from "./process-registry.ts";
15
15
  import { allocateLanes } from "./waves.ts";
16
+ import { resolveOperatorId } from "./naming.ts";
16
17
  import { runGit } from "./git.ts";
17
18
 
18
19
  // ── Taskplane Package File Resolution ────────────────────────────────
@@ -1752,11 +1753,24 @@ export async function resolveTaskMonitorState(
1752
1753
  stallTimeoutMs: number,
1753
1754
  now: number,
1754
1755
  runtimeBackend?: RuntimeBackend,
1756
+ v2Context?: { stateRoot: string; batchId: string; laneNumber: number },
1755
1757
  ): Promise<TaskMonitorSnapshot> {
1756
- // TP-112: Backend-aware liveness check.
1757
- // V2: check process registry (PID liveness). Legacy: check TMUX session.
1758
+ // TP-115: Backend-aware liveness check.
1759
+ // V2: read the lane snapshot file written by lane-runner every second.
1760
+ // Snapshot status is authoritative — no PID probing needed.
1761
+ // If snapshot doesn't exist yet, assume alive (lane-runner startup race).
1762
+ // Legacy: check TMUX session.
1758
1763
  let sessionAlive: boolean;
1759
- if (runtimeBackend === "v2") {
1764
+ if (runtimeBackend === "v2" && v2Context) {
1765
+ const snap = readLaneSnapshot(v2Context.stateRoot, v2Context.batchId, v2Context.laneNumber);
1766
+ if (snap == null) {
1767
+ // Snapshot not written yet — lane-runner is still starting up.
1768
+ // Assume alive to avoid false "failed" from monitor racing lane startup.
1769
+ sessionAlive = true;
1770
+ } else {
1771
+ sessionAlive = snap.status === "running";
1772
+ }
1773
+ } else if (runtimeBackend === "v2") {
1760
1774
  sessionAlive = isV2AgentAlive(sessionName, runtimeBackend);
1761
1775
  } else {
1762
1776
  sessionAlive = await tmuxHasSessionAsync(sessionName);
@@ -2080,6 +2094,11 @@ export async function monitorLanes(
2080
2094
  stallTimeoutMs,
2081
2095
  now,
2082
2096
  runtimeBackend,
2097
+ (runtimeBackend === "v2" && batchId) ? {
2098
+ stateRoot: stateRootForRegistry ?? repoRoot,
2099
+ batchId,
2100
+ laneNumber: lane.laneNumber,
2101
+ } : undefined,
2083
2102
  );
2084
2103
 
2085
2104
  currentTaskSnapshot = snapshot;
@@ -2957,9 +2976,10 @@ export async function executeLaneV2(
2957
2976
  const stateRoot = resolveRuntimeStateRoot(repoRoot, workspaceRoot);
2958
2977
  const batchId = config.orchestrator?.batchId || extraEnvVars?.ORCH_BATCH_ID || String(Date.now());
2959
2978
 
2960
- // Build agent ID prefix from orchestrator config
2979
+ // Build agent ID prefix must match the wave planner's naming (TP-115).
2980
+ // Uses resolveOperatorId() so agent registry keys align with tmuxSessionName.
2961
2981
  const tmuxPrefix = config.orchestrator?.tmux_prefix ?? "orch";
2962
- const opId = config.orchestrator?.operatorId || "op";
2982
+ const opId = resolveOperatorId(config);
2963
2983
  const agentIdPrefix = `${tmuxPrefix}-${opId}`;
2964
2984
 
2965
2985
  // Load worker agent definition for system prompt
@@ -343,3 +343,22 @@ export function writeLaneSnapshot(
343
343
  writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2) + "\n", "utf-8");
344
344
  renameSync(tmpPath, path);
345
345
  }
346
+
347
+ /**
348
+ * Read a V2 lane snapshot from disk.
349
+ * Returns null if the file doesn't exist or is unreadable.
350
+ * @since TP-115
351
+ */
352
+ export function readLaneSnapshot(
353
+ stateRoot: string,
354
+ batchId: string,
355
+ laneNumber: number,
356
+ ): { status: string; updatedAt?: number } | null {
357
+ try {
358
+ const p = runtimeLaneSnapshotPath(stateRoot, batchId, laneNumber);
359
+ if (!existsSync(p)) return null;
360
+ return JSON.parse(readFileSync(p, "utf-8"));
361
+ } catch {
362
+ return null;
363
+ }
364
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskplane",
3
- "version": "0.23.2",
3
+ "version": "0.23.4",
4
4
  "description": "AI agent orchestration for pi — parallel task execution with checkpoint discipline",
5
5
  "keywords": [
6
6
  "pi-package",