@rehpic/vcli 0.1.0-beta.102.1 → 0.1.0-beta.103.1

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/dist/index.js CHANGED
@@ -1463,13 +1463,14 @@ function discoverAttachableSessions() {
1463
1463
  ...discoverClaudeSessions()
1464
1464
  ]);
1465
1465
  }
1466
- async function launchProviderSession(provider, cwd, prompt2, onEvent) {
1466
+ async function launchProviderSession(provider, cwd, prompt2, onEvent, signal) {
1467
1467
  if (provider === "codex") {
1468
1468
  return runCodexAppServerTurn({
1469
1469
  cwd,
1470
1470
  prompt: prompt2,
1471
1471
  launchCommand: "codex app-server",
1472
- onEvent
1472
+ onEvent,
1473
+ signal
1473
1474
  });
1474
1475
  }
1475
1476
  if (provider === "claude_code") {
@@ -1477,7 +1478,8 @@ async function launchProviderSession(provider, cwd, prompt2, onEvent) {
1477
1478
  cwd,
1478
1479
  prompt: prompt2,
1479
1480
  launchCommand: "@anthropic-ai/claude-agent-sdk query()",
1480
- onEvent
1481
+ onEvent,
1482
+ signal
1481
1483
  });
1482
1484
  }
1483
1485
  return runGenericCliAgentTurn({
@@ -1485,17 +1487,19 @@ async function launchProviderSession(provider, cwd, prompt2, onEvent) {
1485
1487
  cwd,
1486
1488
  prompt: prompt2,
1487
1489
  launchCommand: genericProviderLaunchCommand(provider),
1488
- onEvent
1490
+ onEvent,
1491
+ signal
1489
1492
  });
1490
1493
  }
1491
- async function resumeProviderSession(provider, sessionKey, cwd, prompt2, onEvent) {
1494
+ async function resumeProviderSession(provider, sessionKey, cwd, prompt2, onEvent, signal) {
1492
1495
  if (provider === "codex") {
1493
1496
  return runCodexAppServerTurn({
1494
1497
  cwd,
1495
1498
  prompt: prompt2,
1496
1499
  sessionKey,
1497
1500
  launchCommand: "codex app-server (thread/resume)",
1498
- onEvent
1501
+ onEvent,
1502
+ signal
1499
1503
  });
1500
1504
  }
1501
1505
  if (provider === "claude_code") {
@@ -1504,7 +1508,8 @@ async function resumeProviderSession(provider, sessionKey, cwd, prompt2, onEvent
1504
1508
  prompt: prompt2,
1505
1509
  sessionKey,
1506
1510
  launchCommand: "@anthropic-ai/claude-agent-sdk query(resume)",
1507
- onEvent
1511
+ onEvent,
1512
+ signal
1508
1513
  });
1509
1514
  }
1510
1515
  return runGenericCliAgentTurn({
@@ -1513,10 +1518,12 @@ async function resumeProviderSession(provider, sessionKey, cwd, prompt2, onEvent
1513
1518
  prompt: prompt2,
1514
1519
  sessionKey,
1515
1520
  launchCommand: genericProviderLaunchCommand(provider),
1516
- onEvent
1521
+ onEvent,
1522
+ signal
1517
1523
  });
1518
1524
  }
1519
1525
  async function runGenericCliAgentTurn(args) {
1526
+ throwIfAborted(args.signal);
1520
1527
  const command = genericProviderCommand(args.provider);
1521
1528
  const child = spawn2(command.bin, [...command.args, args.prompt], {
1522
1529
  cwd: args.cwd,
@@ -1525,6 +1532,8 @@ async function runGenericCliAgentTurn(args) {
1525
1532
  });
1526
1533
  let stdout = "";
1527
1534
  let stderr = "";
1535
+ const abort = () => child.kill("SIGTERM");
1536
+ args.signal?.addEventListener("abort", abort, { once: true });
1528
1537
  await Promise.resolve(
1529
1538
  args.onEvent?.({
1530
1539
  provider: args.provider,
@@ -1542,7 +1551,10 @@ async function runGenericCliAgentTurn(args) {
1542
1551
  const exit = await new Promise((resolve, reject) => {
1543
1552
  child.on("error", reject);
1544
1553
  child.on("close", (code, signal) => resolve({ code, signal }));
1554
+ }).finally(() => {
1555
+ args.signal?.removeEventListener("abort", abort);
1545
1556
  });
1557
+ throwIfAborted(args.signal);
1546
1558
  if (exit.code && exit.code !== 0) {
1547
1559
  const message = stderr.trim() || `${providerLabel(args.provider)} exited with code ${exit.code}`;
1548
1560
  await Promise.resolve(
@@ -1600,6 +1612,7 @@ function providerLabel(provider) {
1600
1612
  return "Pi";
1601
1613
  }
1602
1614
  async function runCodexAppServerTurn(args) {
1615
+ throwIfAborted(args.signal);
1603
1616
  const child = spawn2("codex", ["app-server"], {
1604
1617
  cwd: args.cwd,
1605
1618
  env: { ...process.env },
@@ -1616,6 +1629,7 @@ async function runCodexAppServerTurn(args) {
1616
1629
  const pending = /* @__PURE__ */ new Map();
1617
1630
  let completeTurn;
1618
1631
  let failTurn;
1632
+ let activeTurnId;
1619
1633
  const turnCompleted = new Promise((resolve, reject) => {
1620
1634
  completeTurn = () => {
1621
1635
  completed = true;
@@ -1743,6 +1757,10 @@ async function runCodexAppServerTurn(args) {
1743
1757
  completeTurn?.();
1744
1758
  }
1745
1759
  }
1760
+ if (method === "turn/started") {
1761
+ const turn = asObject(params.turn);
1762
+ activeTurnId = asString(turn?.id) ?? asString(turn?.turnId) ?? activeTurnId;
1763
+ }
1746
1764
  }
1747
1765
  });
1748
1766
  child.stderr.on("data", (chunk) => {
@@ -1758,6 +1776,17 @@ async function runCodexAppServerTurn(args) {
1758
1776
  child.stdin.write(`${JSON.stringify({ method, params })}
1759
1777
  `);
1760
1778
  };
1779
+ const abort = () => {
1780
+ if (sessionKey && activeTurnId) {
1781
+ notify("turn/interrupt", {
1782
+ threadId: sessionKey,
1783
+ turnId: activeTurnId
1784
+ });
1785
+ }
1786
+ child.kill("SIGTERM");
1787
+ failTurn?.(new Error("Agent turn interrupted"));
1788
+ };
1789
+ args.signal?.addEventListener("abort", abort, { once: true });
1761
1790
  const waitForExit = new Promise((_, reject) => {
1762
1791
  child.on("error", (error) => reject(error));
1763
1792
  child.on("close", (code) => {
@@ -1809,6 +1838,7 @@ async function runCodexAppServerTurn(args) {
1809
1838
  }),
1810
1839
  waitForExit
1811
1840
  ]);
1841
+ throwIfAborted(args.signal);
1812
1842
  await Promise.race([turnCompleted, waitForExit]);
1813
1843
  await Promise.allSettled(eventWrites);
1814
1844
  const gitInfo = getGitInfo(args.cwd);
@@ -1826,6 +1856,7 @@ async function runCodexAppServerTurn(args) {
1826
1856
  launchCommand: args.launchCommand
1827
1857
  };
1828
1858
  } finally {
1859
+ args.signal?.removeEventListener("abort", abort);
1829
1860
  for (const entry of pending.values()) {
1830
1861
  entry.reject(
1831
1862
  new Error("codex app-server closed before request resolved")
@@ -1836,6 +1867,7 @@ async function runCodexAppServerTurn(args) {
1836
1867
  }
1837
1868
  }
1838
1869
  async function runClaudeSdkTurn(args) {
1870
+ throwIfAborted(args.signal);
1839
1871
  const { query } = await import("@anthropic-ai/claude-agent-sdk");
1840
1872
  const stream = query({
1841
1873
  prompt: args.prompt,
@@ -1854,8 +1886,13 @@ async function runClaudeSdkTurn(args) {
1854
1886
  let sessionKey = args.sessionKey;
1855
1887
  let responseText = "";
1856
1888
  let model;
1889
+ const abort = () => {
1890
+ stream.close();
1891
+ };
1892
+ args.signal?.addEventListener("abort", abort, { once: true });
1857
1893
  try {
1858
1894
  for await (const message of stream) {
1895
+ throwIfAborted(args.signal);
1859
1896
  if (!message || typeof message !== "object") {
1860
1897
  continue;
1861
1898
  }
@@ -1897,6 +1934,7 @@ async function runClaudeSdkTurn(args) {
1897
1934
  throw new Error(detail);
1898
1935
  }
1899
1936
  } finally {
1937
+ args.signal?.removeEventListener("abort", abort);
1900
1938
  stream.close();
1901
1939
  }
1902
1940
  if (!sessionKey) {
@@ -1918,6 +1956,11 @@ async function runClaudeSdkTurn(args) {
1918
1956
  launchCommand: args.launchCommand
1919
1957
  };
1920
1958
  }
1959
+ function throwIfAborted(signal) {
1960
+ if (signal?.aborted) {
1961
+ throw new Error("Agent turn interrupted");
1962
+ }
1963
+ }
1921
1964
  function discoverCodexSessions() {
1922
1965
  const historyBySession = buildCodexHistoryIndex();
1923
1966
  return listLiveProcessIds("codex").flatMap((pid) => {
@@ -2536,6 +2579,7 @@ var BridgeService = class {
2536
2579
  this.terminalPeer = null;
2537
2580
  this.stopping = false;
2538
2581
  this.runningLoops = /* @__PURE__ */ new Set();
2582
+ this.activeAgentRuns = /* @__PURE__ */ new Map();
2539
2583
  this.deviceLiveActivities = [];
2540
2584
  this.config = config;
2541
2585
  this.client = new ConvexHttpClient2(config.convexUrl);
@@ -2610,14 +2654,31 @@ var BridgeService = class {
2610
2654
  return;
2611
2655
  }
2612
2656
  console.log(` ${cmd.kind}: ${cmd._id}`);
2657
+ if (cmd.kind === "launch" || cmd.kind === "message") {
2658
+ this.runAgentCommandInBackground(cmd);
2659
+ return;
2660
+ }
2661
+ await this.runClaimedCommand(cmd);
2662
+ }
2663
+ runAgentCommandInBackground(cmd) {
2664
+ const runKey = this.agentRunKey(cmd);
2665
+ const controller = new AbortController();
2666
+ this.activeAgentRuns.set(runKey, controller);
2667
+ void this.runClaimedCommand(cmd, controller.signal).finally(() => {
2668
+ if (this.activeAgentRuns.get(runKey) === controller) {
2669
+ this.activeAgentRuns.delete(runKey);
2670
+ }
2671
+ });
2672
+ }
2673
+ async runClaimedCommand(cmd, signal) {
2613
2674
  try {
2614
2675
  switch (cmd.kind) {
2615
2676
  case "message":
2616
- await this.handleMessageCommand(cmd);
2677
+ await this.handleMessageCommand(cmd, signal);
2617
2678
  await this.completeCommand(cmd._id, "delivered");
2618
2679
  return;
2619
2680
  case "launch":
2620
- await this.handleLaunchCommand(cmd);
2681
+ await this.handleLaunchCommand(cmd, signal);
2621
2682
  await this.completeCommand(cmd._id, "delivered");
2622
2683
  return;
2623
2684
  case "resize":
@@ -2629,11 +2690,18 @@ var BridgeService = class {
2629
2690
  }
2630
2691
  } catch (error) {
2631
2692
  const message = error instanceof Error ? error.message : "Unknown bridge error";
2693
+ if (message === "Agent turn interrupted") {
2694
+ await this.completeCommand(cmd._id, "delivered");
2695
+ return;
2696
+ }
2632
2697
  console.error(` ! ${message}`);
2633
2698
  await this.postCommandError(cmd, message);
2634
2699
  await this.completeCommand(cmd._id, "failed");
2635
2700
  }
2636
2701
  }
2702
+ agentRunKey(cmd) {
2703
+ return cmd.liveActivityId ?? cmd.workSession?._id ?? cmd.process?._id ?? cmd._id;
2704
+ }
2637
2705
  async reportProcesses() {
2638
2706
  const processes = discoverAttachableSessions();
2639
2707
  const activeSessionKeys = processes.map((proc) => proc.sessionKey).filter((value) => Boolean(value));
@@ -2894,7 +2962,7 @@ var BridgeService = class {
2894
2962
  await new Promise(() => {
2895
2963
  });
2896
2964
  }
2897
- async handleMessageCommand(cmd) {
2965
+ async handleMessageCommand(cmd, signal) {
2898
2966
  if (!cmd.liveActivityId) {
2899
2967
  throw new Error("Message command is missing liveActivityId");
2900
2968
  }
@@ -2970,7 +3038,8 @@ var BridgeService = class {
2970
3038
  (event) => {
2971
3039
  if (event.role === "assistant") emittedAssistantEvent = true;
2972
3040
  return this.postAgentSessionEvent(liveActivityId, event);
2973
- }
3041
+ },
3042
+ signal
2974
3043
  );
2975
3044
  const processId = await this.reportProcess(result);
2976
3045
  if (result.responseText && !emittedAssistantEvent) {
@@ -3031,14 +3100,17 @@ var BridgeService = class {
3031
3100
  return;
3032
3101
  }
3033
3102
  if (cmd.kind === "stop") {
3103
+ const runKey = this.agentRunKey(cmd);
3104
+ const activeRun = this.activeAgentRuns.get(runKey);
3105
+ activeRun?.abort();
3034
3106
  await this.updateLiveActivity(cmd.liveActivityId, {
3035
3107
  status: "paused",
3036
- latestSummary: "Agent turn stop requested"
3108
+ latestSummary: activeRun ? "Agent turn paused" : "Agent turn stop requested"
3037
3109
  });
3038
3110
  await this.postAgentMessage(
3039
3111
  cmd.liveActivityId,
3040
3112
  "status",
3041
- "Stop requested for the local agent session"
3113
+ activeRun ? "Paused the local agent session" : "Stop requested for the local agent session"
3042
3114
  );
3043
3115
  return;
3044
3116
  }
@@ -3056,7 +3128,7 @@ var BridgeService = class {
3056
3128
  `Received ${label}; the provider runtime will continue when supported`
3057
3129
  );
3058
3130
  }
3059
- async handleLaunchCommand(cmd) {
3131
+ async handleLaunchCommand(cmd, signal) {
3060
3132
  if (!cmd.liveActivityId) {
3061
3133
  throw new Error("Launch command is missing liveActivityId");
3062
3134
  }
@@ -3120,7 +3192,8 @@ var BridgeService = class {
3120
3192
  provider,
3121
3193
  workspacePath,
3122
3194
  prompt2,
3123
- (event) => this.postAgentSessionEvent(liveActivityId, event)
3195
+ (event) => this.postAgentSessionEvent(liveActivityId, event),
3196
+ signal
3124
3197
  );
3125
3198
  const processId = await this.reportProcess(result);
3126
3199
  await this.refreshWorkSessionTerminal(cmd.workSession?._id, {