@hasna/loops 0.4.8 → 0.4.10

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.
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@hasna/loops",
6
- version: "0.4.8",
6
+ version: "0.4.10",
7
7
  description: "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
8
8
  type: "module",
9
9
  main: "dist/index.js",
@@ -365,7 +365,7 @@ function scrubSecretsDeep(value) {
365
365
  }
366
366
 
367
367
  // src/lib/agent-adapter.ts
368
- var UNSAFE_CODEWITH_DURABLE_EXTRA_ARGS = new Set([
368
+ var UNSAFE_CODEWITH_EXEC_EXTRA_ARGS = new Set([
369
369
  "e",
370
370
  "exec",
371
371
  "agent",
@@ -414,12 +414,12 @@ function validateAgentOptions(target, label, capabilities) {
414
414
  throw new Error(`${label}.agent is not supported for provider codex`);
415
415
  }
416
416
  if (provider === "codewith" && target.agent !== undefined) {
417
- throw new Error(`${label}.agent is not supported for provider codewith durable background-agent execution`);
417
+ throw new Error(`${label}.agent is not supported for provider codewith`);
418
418
  }
419
419
  if (provider === "codewith") {
420
- const unsafe = target.extraArgs?.find((arg) => UNSAFE_CODEWITH_DURABLE_EXTRA_ARGS.has(arg));
420
+ const unsafe = target.extraArgs?.find((arg) => UNSAFE_CODEWITH_EXEC_EXTRA_ARGS.has(arg));
421
421
  if (unsafe) {
422
- throw new Error(`${label}.extraArgs cannot include ${unsafe}; codewith agent steps use durable agent start, not exec/ephemeral flags`);
422
+ throw new Error(`${label}.extraArgs cannot include ${unsafe}; codewith exec launch flags are managed by the adapter`);
423
423
  }
424
424
  }
425
425
  if (target.addDirs?.length && !["codewith", "codex"].includes(provider)) {
@@ -502,7 +502,10 @@ function buildAgentInvocation(target) {
502
502
  args.push(...target.authProfile ? ["--auth-profile", target.authProfile] : []);
503
503
  if (target.variant)
504
504
  args.push("-c", `model_reasoning_effort=${configStringValue(target.variant)}`);
505
- args.push("--ask-for-approval", "never", "--sandbox", codewithLikeSandbox(target));
505
+ const sandbox = codewithLikeSandbox(target);
506
+ if (sandbox === "workspace-write")
507
+ args.push("-c", "sandbox_workspace_write.network_access=true");
508
+ args.push("--ask-for-approval", "never", "exec", "--json", "--ephemeral", "--sandbox", sandbox, "--skip-git-repo-check");
506
509
  if (target.cwd)
507
510
  args.push("--cd", target.cwd);
508
511
  for (const dir of target.addDirs ?? [])
@@ -510,11 +513,7 @@ function buildAgentInvocation(target) {
510
513
  if (target.model)
511
514
  args.push("--model", target.model);
512
515
  args.push(...target.extraArgs ?? []);
513
- args.push("agent", "start", "--json");
514
- if (target.cwd)
515
- args.push("--cwd", target.cwd);
516
- args.push(target.prompt);
517
- return { command: "codewith", args };
516
+ return { command: "codewith", args, stdin: target.prompt };
518
517
  }
519
518
  case "codex": {
520
519
  if (target.variant)
@@ -567,7 +566,7 @@ function adapterFor(provider, capabilities) {
567
566
  var PROVIDER_ADAPTERS = {
568
567
  claude: adapterFor("claude", { sandbox: [], durable: false, remote: true, promptChannel: "stdin" }),
569
568
  cursor: adapterFor("cursor", { sandbox: CURSOR_SANDBOXES, durable: false, remote: true, promptChannel: "stdin" }),
570
- codewith: adapterFor("codewith", { sandbox: CODEX_LIKE_SANDBOXES, durable: true, remote: false, promptChannel: "argv" }),
569
+ codewith: adapterFor("codewith", { sandbox: CODEX_LIKE_SANDBOXES, durable: false, remote: true, promptChannel: "stdin" }),
571
570
  codex: adapterFor("codex", { sandbox: CODEX_LIKE_SANDBOXES, durable: false, remote: true, promptChannel: "stdin" }),
572
571
  aicopilot: adapterFor("aicopilot", { sandbox: [], durable: false, remote: true, promptChannel: "stdin" }),
573
572
  opencode: adapterFor("opencode", { sandbox: [], durable: false, remote: true, promptChannel: "stdin" })
@@ -1041,11 +1040,6 @@ var TRANSPORT_ENV_KEYS = new Set([
1041
1040
  "USER",
1042
1041
  "XDG_RUNTIME_DIR"
1043
1042
  ]);
1044
- function boundedText(text, maxBytes) {
1045
- const buffer = new BoundedOutputBuffer(maxBytes);
1046
- buffer.append(text);
1047
- return buffer.value();
1048
- }
1049
1043
  function buildResult(status, startedAt, fields = {}) {
1050
1044
  const finishedAt = fields.finishedAt ?? nowIso();
1051
1045
  return {
@@ -1083,6 +1077,20 @@ function notifySpawn(pid, opts) {
1083
1077
  function shellQuote(value) {
1084
1078
  return `'${value.replace(/'/g, `'\\''`)}'`;
1085
1079
  }
1080
+ function codewithProfileCandidateFromLine(line) {
1081
+ const cols = line.trim().split(/\s+/);
1082
+ if (cols[0] === "*")
1083
+ return cols[1];
1084
+ return cols[0];
1085
+ }
1086
+ function codewithProfileForError(profile) {
1087
+ return /[\u0000-\u001F\u007F]/.test(profile) ? JSON.stringify(profile) ?? profile : profile;
1088
+ }
1089
+ function assertCodewithAuthProfileSupported(profile) {
1090
+ if (profile.includes("\x00")) {
1091
+ throw new Error(`codewith auth profile contains unsupported NUL byte: ${codewithProfileForError(profile)}`);
1092
+ }
1093
+ }
1086
1094
  function metadataEnv(metadata) {
1087
1095
  const env = {};
1088
1096
  if (metadata.loopId)
@@ -1109,21 +1117,6 @@ function metadataEnv(metadata) {
1109
1117
  env.LOOPS_GOAL_NODE_KEY = metadata.goalNodeKey;
1110
1118
  return env;
1111
1119
  }
1112
- function codewithAgentIdempotencyKey(metadata) {
1113
- const parts = [
1114
- "openloops",
1115
- metadata.workflowRunId ? `workflow-run:${metadata.workflowRunId}` : undefined,
1116
- metadata.workflowStepId ? `step:${metadata.workflowStepId}` : undefined,
1117
- metadata.runId ? `loop-run:${metadata.runId}` : undefined,
1118
- metadata.loopId ? `loop:${metadata.loopId}` : undefined,
1119
- metadata.scheduledFor ? `scheduled:${metadata.scheduledFor}` : undefined,
1120
- metadata.goalId ? `goal:${metadata.goalId}` : undefined,
1121
- metadata.goalNodeKey ? `node:${metadata.goalNodeKey}` : undefined
1122
- ].filter(Boolean);
1123
- if (parts.length > 1)
1124
- return parts.join(":");
1125
- return `openloops:adhoc:${randomBytes2(16).toString("hex")}`;
1126
- }
1127
1120
  function allowlistEnv(allowlist) {
1128
1121
  const env = {};
1129
1122
  if (allowlist?.tools?.length)
@@ -1164,6 +1157,9 @@ function commandSpec(target, opts) {
1164
1157
  };
1165
1158
  }
1166
1159
  const agentTarget = target;
1160
+ if (agentTarget.provider === "codewith" && agentTarget.authProfile) {
1161
+ assertCodewithAuthProfileSupported(agentTarget.authProfile);
1162
+ }
1167
1163
  const adapter = providerAdapter(agentTarget.provider);
1168
1164
  const invocation = adapter.buildInvocation(agentTarget);
1169
1165
  return {
@@ -1178,8 +1174,7 @@ function commandSpec(target, opts) {
1178
1174
  preflightAnyOf: invocation.preflightAnyOf,
1179
1175
  stdin: invocation.stdin,
1180
1176
  allowlist: agentTarget.allowlist,
1181
- worktree: agentTarget.worktree,
1182
- codewithDurableAgent: adapter.capabilities.durable ? { target: agentTarget } : undefined
1177
+ worktree: agentTarget.worktree
1183
1178
  };
1184
1179
  }
1185
1180
  function composeExecutionEnv(spec, metadata, opts, accountEnv) {
@@ -1337,7 +1332,8 @@ function remotePreflightScript(spec, metadata) {
1337
1332
  lines.push(`if ! ${spec.preflightAnyOf.map((command) => `command -v ${shellQuote(command)} >/dev/null 2>&1`).join(" && ! ")}; then`, ` echo 'none of required executables found: ${spec.preflightAnyOf.join(", ")}' >&2`, " exit 127", "fi");
1338
1333
  }
1339
1334
  if (spec.nativeAuthProfile?.provider === "codewith") {
1340
- lines.push(`__OPENLOOPS_CODEWITH_PROFILES="$(${shellQuote(spec.command)} profile list)" || {`, ` printf '%s\\n' ${shellQuote("codewith auth profile preflight failed")} >&2`, " exit 1", "}", `if ! printf '%s\\n' "$__OPENLOOPS_CODEWITH_PROFILES" | awk 'NR > 1 { print $1 }' | grep -Fx ${shellQuote(spec.nativeAuthProfile.profile)} >/dev/null; then`, ` printf '%s\\n' ${shellQuote(`codewith auth profile not found: ${spec.nativeAuthProfile.profile}`)} >&2`, " exit 1", "fi");
1335
+ const profileForError = codewithProfileForError(spec.nativeAuthProfile.profile);
1336
+ lines.push(`__OPENLOOPS_CODEWITH_PROFILE=${shellQuote(spec.nativeAuthProfile.profile)}`, "export __OPENLOOPS_CODEWITH_PROFILE", `__OPENLOOPS_CODEWITH_PROFILES="$(${shellQuote(spec.command)} profile list)" || {`, ` printf '%s\\n' ${shellQuote("codewith auth profile preflight failed")} >&2`, " exit 1", "}", `if ! printf '%s\\n' "$__OPENLOOPS_CODEWITH_PROFILES" | awk 'NR > 1 { candidate = ($1 == "*" ? $2 : $1); if (candidate == ENVIRON["__OPENLOOPS_CODEWITH_PROFILE"]) found = 1 } END { exit(found ? 0 : 1) }'; then`, ` printf '%s\\n' ${shellQuote(`codewith auth profile not found: ${profileForError}`)} >&2`, " exit 1", "fi");
1341
1337
  }
1342
1338
  return lines.join(`
1343
1339
  `);
@@ -1362,9 +1358,9 @@ function assertCodewithProfileListed(profile, result) {
1362
1358
  const detail = (result.stderr || result.stdout || `exit ${result.status ?? "unknown"}`).trim();
1363
1359
  throw new Error(`codewith auth profile preflight failed${detail ? `: ${detail}` : ""}`);
1364
1360
  }
1365
- const profiles = new Set((result.stdout || "").split(/\r?\n/).slice(1).map((line) => line.trim().split(/\s+/)[0]).filter(Boolean));
1361
+ const profiles = new Set((result.stdout || "").split(/\r?\n/).slice(1).map(codewithProfileCandidateFromLine).filter(Boolean));
1366
1362
  if (!profiles.has(profile)) {
1367
- throw new Error(`codewith auth profile not found: ${profile}`);
1363
+ throw new Error(`codewith auth profile not found: ${codewithProfileForError(profile)}`);
1368
1364
  }
1369
1365
  }
1370
1366
  function preflightNativeAuthProfileSync(spec, env) {
@@ -1389,266 +1385,6 @@ async function preflightNativeAuthProfile(spec, env) {
1389
1385
  const result = await spawnCapture(spec.command, ["profile", "list"], { env, timeoutMs: 15000 });
1390
1386
  assertCodewithProfileListed(spec.nativeAuthProfile.profile, result);
1391
1387
  }
1392
- function codewithAgentStartArgs(target, idempotencyKey) {
1393
- const args = providerAdapter(target.provider).buildInvocation(target).args;
1394
- const startIndex = args.findIndex((arg, index) => arg === "start" && args[index - 1] === "agent");
1395
- if (startIndex === -1)
1396
- throw new Error("internal error: codewith durable agent args missing agent start");
1397
- args.splice(startIndex + 1, 0, "--idempotency-key", idempotencyKey);
1398
- return args;
1399
- }
1400
- function codewithAgentControlArgs(target, command, agentId) {
1401
- return [
1402
- ...target.authProfile ? ["--auth-profile", target.authProfile] : [],
1403
- "agent",
1404
- command,
1405
- ...command === "logs" ? ["--limit", "20"] : [],
1406
- "--json",
1407
- agentId
1408
- ];
1409
- }
1410
- function extractFirstJsonObject(text) {
1411
- let depth = 0;
1412
- let start = -1;
1413
- let inString = false;
1414
- let escaped = false;
1415
- for (let i = 0;i < text.length; i += 1) {
1416
- const ch = text[i];
1417
- if (inString) {
1418
- if (escaped)
1419
- escaped = false;
1420
- else if (ch === "\\")
1421
- escaped = true;
1422
- else if (ch === '"')
1423
- inString = false;
1424
- continue;
1425
- }
1426
- if (ch === '"') {
1427
- inString = true;
1428
- } else if (ch === "{") {
1429
- if (depth === 0)
1430
- start = i;
1431
- depth += 1;
1432
- } else if (ch === "}") {
1433
- if (depth > 0) {
1434
- depth -= 1;
1435
- if (depth === 0 && start !== -1)
1436
- return text.slice(start, i + 1);
1437
- }
1438
- }
1439
- }
1440
- return;
1441
- }
1442
- function parseJsonOutput(stdout, label) {
1443
- const raw = stdout || "{}";
1444
- const candidates = [raw.trim()];
1445
- const scanned = extractFirstJsonObject(raw);
1446
- if (scanned && scanned !== raw.trim())
1447
- candidates.push(scanned);
1448
- let lastError;
1449
- for (const candidate of candidates) {
1450
- try {
1451
- const value = JSON.parse(candidate);
1452
- if (!value || typeof value !== "object" || Array.isArray(value))
1453
- throw new Error("not an object");
1454
- return value;
1455
- } catch (error) {
1456
- lastError = error;
1457
- }
1458
- }
1459
- throw new Error(`${label} did not return JSON${lastError instanceof Error ? `: ${lastError.message}` : ""}`);
1460
- }
1461
- function recordField(value, key) {
1462
- if (!value || typeof value !== "object" || Array.isArray(value))
1463
- return;
1464
- const field = value[key];
1465
- return field && typeof field === "object" && !Array.isArray(field) ? field : undefined;
1466
- }
1467
- function stringField(value, key) {
1468
- const field = value?.[key];
1469
- return typeof field === "string" ? field : undefined;
1470
- }
1471
- function numberField(value, key) {
1472
- const field = value?.[key];
1473
- return typeof field === "number" && Number.isFinite(field) ? field : undefined;
1474
- }
1475
- function codewithAgentStatus(readJson) {
1476
- return stringField(recordField(readJson, "agent"), "status") ?? stringField(recordField(readJson, "statusSnapshot"), "status");
1477
- }
1478
- function codewithAgentLastEventSeq(readJson) {
1479
- const agentSeq = numberField(recordField(readJson, "agent"), "lastEventSeq");
1480
- const snapshotSeq = numberField(recordField(readJson, "statusSnapshot"), "lastEventSeq");
1481
- if (agentSeq !== undefined && snapshotSeq !== undefined)
1482
- return Math.max(agentSeq, snapshotSeq);
1483
- return agentSeq ?? snapshotSeq;
1484
- }
1485
- function codewithAgentEvidence(startJson, readJson, logsJson) {
1486
- const agent = recordField(readJson, "agent") ?? recordField(startJson, "agent");
1487
- const statusSnapshot = recordField(readJson, "statusSnapshot");
1488
- const events = Array.isArray(logsJson?.data) ? logsJson.data.filter((event) => Boolean(event) && typeof event === "object" && !Array.isArray(event)).map((event) => ({
1489
- seq: numberField(event, "seq"),
1490
- eventType: stringField(event, "eventType"),
1491
- createdAt: numberField(event, "createdAt")
1492
- })) : undefined;
1493
- return JSON.stringify({
1494
- codewithAgent: {
1495
- agentId: stringField(agent, "agentId"),
1496
- status: stringField(agent, "status"),
1497
- desiredState: stringField(agent, "desiredState"),
1498
- statusReason: stringField(agent, "statusReason"),
1499
- threadId: stringField(agent, "threadId"),
1500
- rolloutPath: stringField(agent, "rolloutPath"),
1501
- pid: numberField(agent, "pid"),
1502
- exitCode: numberField(agent, "exitCode"),
1503
- created: typeof startJson.created === "boolean" ? startJson.created : undefined
1504
- },
1505
- statusSnapshot: statusSnapshot ? {
1506
- seq: numberField(statusSnapshot, "seq"),
1507
- status: stringField(statusSnapshot, "status"),
1508
- summary: stringField(statusSnapshot, "summary"),
1509
- pendingInteractionCount: numberField(statusSnapshot, "pendingInteractionCount"),
1510
- lastEventSeq: numberField(statusSnapshot, "lastEventSeq")
1511
- } : undefined,
1512
- events
1513
- }, null, 2);
1514
- }
1515
- function codewithAgentProgress(readJson) {
1516
- const agent = recordField(readJson, "agent");
1517
- const statusSnapshot = recordField(readJson, "statusSnapshot");
1518
- return {
1519
- provider: "codewith",
1520
- agentId: stringField(agent, "agentId"),
1521
- status: stringField(agent, "status") ?? stringField(statusSnapshot, "status"),
1522
- summary: stringField(statusSnapshot, "summary"),
1523
- statusReason: stringField(agent, "statusReason"),
1524
- threadId: stringField(agent, "threadId"),
1525
- rolloutPath: stringField(agent, "rolloutPath"),
1526
- pid: numberField(agent, "pid"),
1527
- lastEventSeq: codewithAgentLastEventSeq(readJson)
1528
- };
1529
- }
1530
- function sleep(ms) {
1531
- return new Promise((resolve2) => setTimeout(resolve2, ms));
1532
- }
1533
- async function executeCodewithDurableAgent(spec, metadata, opts, env, startedAt) {
1534
- const target = spec.codewithDurableAgent?.target;
1535
- if (!target)
1536
- throw new Error("internal error: missing codewith durable target");
1537
- const maxOutputBytes = opts.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
1538
- const idempotencyKey = codewithAgentIdempotencyKey(metadata);
1539
- const start = await spawnCapture(spec.command, codewithAgentStartArgs(target, idempotencyKey), {
1540
- cwd: spec.cwd,
1541
- env,
1542
- timeoutMs: 30000,
1543
- maxOutputBytes
1544
- });
1545
- const stderr = new BoundedOutputBuffer(maxOutputBytes);
1546
- stderr.append(start.stderr);
1547
- if (start.error || (start.status ?? 1) !== 0) {
1548
- return failureResult(startedAt, start.error ?? `codewith agent start exited with code ${start.status ?? "unknown"}`, {
1549
- exitCode: start.status ?? undefined,
1550
- stdout: start.stdout,
1551
- stderr: stderr.value()
1552
- });
1553
- }
1554
- let startJson;
1555
- try {
1556
- startJson = parseJsonOutput(start.stdout || "{}", "codewith agent start");
1557
- } catch (error) {
1558
- return failureResult(startedAt, error instanceof Error ? error.message : String(error), { stdout: start.stdout, stderr: stderr.value() });
1559
- }
1560
- const agentId = stringField(recordField(startJson, "agent"), "agentId");
1561
- if (!agentId) {
1562
- return failureResult(startedAt, "codewith agent start did not return agent.agentId", { stdout: start.stdout, stderr: stderr.value() });
1563
- }
1564
- opts.onAgentProgress?.(codewithAgentProgress(startJson));
1565
- const stopAgent = async () => {
1566
- await spawnCapture(spec.command, codewithAgentControlArgs(target, "stop", agentId), {
1567
- cwd: spec.cwd,
1568
- env,
1569
- timeoutMs: 15000,
1570
- maxOutputBytes
1571
- });
1572
- };
1573
- const pollMs = Math.max(100, Number(opts.env?.LOOPS_CODEWITH_AGENT_POLL_MS ?? process.env.LOOPS_CODEWITH_AGENT_POLL_MS ?? 2000) || 2000);
1574
- let lastReadJson = startJson;
1575
- let lastLogsJson;
1576
- let lastFingerprint;
1577
- let lastProgressAt = Date.now();
1578
- const evidence = () => boundedText(codewithAgentEvidence(startJson, lastReadJson, lastLogsJson), maxOutputBytes);
1579
- while (true) {
1580
- if (opts.signal?.aborted) {
1581
- await stopAgent();
1582
- return failureResult(startedAt, "cancelled", { stdout: evidence(), stderr: stderr.value() });
1583
- }
1584
- const read = await spawnCapture(spec.command, codewithAgentControlArgs(target, "read", agentId), {
1585
- cwd: spec.cwd,
1586
- env,
1587
- timeoutMs: 30000,
1588
- maxOutputBytes
1589
- });
1590
- stderr.append(read.stderr);
1591
- if (read.error || (read.status ?? 1) !== 0) {
1592
- return failureResult(startedAt, read.error ?? `codewith agent read exited with code ${read.status ?? "unknown"}`, {
1593
- exitCode: read.status ?? undefined,
1594
- stdout: evidence(),
1595
- stderr: stderr.value()
1596
- });
1597
- }
1598
- try {
1599
- lastReadJson = parseJsonOutput(read.stdout || "{}", "codewith agent read");
1600
- } catch (error) {
1601
- return failureResult(startedAt, error instanceof Error ? error.message : String(error), {
1602
- stdout: boundedText(read.stdout, maxOutputBytes),
1603
- stderr: stderr.value()
1604
- });
1605
- }
1606
- const status = codewithAgentStatus(lastReadJson);
1607
- const fingerprint = JSON.stringify({
1608
- status,
1609
- agentLastEventSeq: numberField(recordField(lastReadJson, "agent"), "lastEventSeq"),
1610
- snapshot: recordField(lastReadJson, "statusSnapshot") ?? null
1611
- });
1612
- if (fingerprint !== lastFingerprint) {
1613
- lastFingerprint = fingerprint;
1614
- lastProgressAt = Date.now();
1615
- opts.onAgentProgress?.(codewithAgentProgress(lastReadJson));
1616
- }
1617
- if (status === "completed" || status === "failed" || status === "cancelled") {
1618
- const logs = await spawnCapture(spec.command, codewithAgentControlArgs(target, "logs", agentId), {
1619
- cwd: spec.cwd,
1620
- env,
1621
- timeoutMs: 30000,
1622
- maxOutputBytes
1623
- });
1624
- if (!logs.error && (logs.status ?? 1) === 0) {
1625
- try {
1626
- lastLogsJson = parseJsonOutput(logs.stdout || "{}", "codewith agent logs");
1627
- } catch {
1628
- lastLogsJson = undefined;
1629
- }
1630
- } else {
1631
- stderr.append(logs.stderr || logs.error || "");
1632
- }
1633
- if (status === "completed") {
1634
- return successResult(startedAt, { exitCode: 0, stdout: evidence(), stderr: stderr.value() });
1635
- }
1636
- return failureResult(startedAt, stringField(recordField(lastReadJson, "agent"), "statusReason") ?? `codewith agent ${status}`, { exitCode: 1, stdout: evidence(), stderr: stderr.value() });
1637
- }
1638
- if (typeof spec.timeoutMs === "number" && new Date(nowIso()).getTime() - new Date(startedAt).getTime() >= spec.timeoutMs) {
1639
- await stopAgent();
1640
- return timeoutResult(startedAt, `timed out after ${spec.timeoutMs}ms`, { stdout: evidence(), stderr: stderr.value() });
1641
- }
1642
- if (typeof spec.idleTimeoutMs === "number" && Date.now() - lastProgressAt >= spec.idleTimeoutMs) {
1643
- await stopAgent();
1644
- return timeoutResult(startedAt, `idle timed out after ${spec.idleTimeoutMs}ms without agent progress`, {
1645
- stdout: evidence(),
1646
- stderr: stderr.value()
1647
- });
1648
- }
1649
- await sleep(pollMs);
1650
- }
1651
- }
1652
1388
  function resolvedDirEquals(left, right) {
1653
1389
  try {
1654
1390
  return realpathSync(left) === realpathSync(right);
@@ -1882,9 +1618,6 @@ function preflightTarget(target, metadata = {}, opts = {}) {
1882
1618
  async function executeTarget(target, metadata = {}, opts = {}) {
1883
1619
  let spec = commandSpec(target, opts);
1884
1620
  const machine = resolvedMachine(opts);
1885
- if (machine && !machine.local && spec.codewithDurableAgent) {
1886
- return failureResult(nowIso(), "remote Codewith durable background-agent steps require remote status polling support; run this Codewith step locally or add remote durable readback before dispatch");
1887
- }
1888
1621
  if (machine && !machine.local) {
1889
1622
  const remoteFallbackSpec = spec.worktree?.enabled && spec.worktree.mode === "auto" ? worktreeFallbackSpec(target, opts, spec.worktree.originalCwd) : undefined;
1890
1623
  return executeRemoteSpec(spec, machine, metadata, opts, remoteFallbackSpec);
@@ -1915,9 +1648,6 @@ async function executeTarget(target, metadata = {}, opts = {}) {
1915
1648
  if (worktreeEntry?.fallbackCwd) {
1916
1649
  spec = worktreeFallbackSpec(target, opts, worktreeEntry.fallbackCwd) ?? spec;
1917
1650
  }
1918
- if (spec.codewithDurableAgent) {
1919
- return executeCodewithDurableAgent(spec, metadata, opts, env, startedAt);
1920
- }
1921
1651
  const child = spawn2(spec.command, spec.args, {
1922
1652
  cwd: spec.cwd,
1923
1653
  env,