@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 +89 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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, {
|