very-happy-cli 0.2.175 → 0.2.176
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/{AcpBackend-Sb6N_HcB.cjs → AcpBackend-9_ZI1Bv3.cjs} +3 -3
- package/dist/{AcpBackend-BZrLVcHb.mjs → AcpBackend-COp6D8gl.mjs} +3 -3
- package/dist/{AcpSessionManager-C2MqOirs.cjs → AcpSessionManager-CjdJLofq.cjs} +1 -1
- package/dist/{AcpSessionManager-y1Iy1mzc.mjs → AcpSessionManager-DykjzBM4.mjs} +1 -1
- package/dist/{BasePermissionHandler-DriZLITp.mjs → BasePermissionHandler-ChMkmsGD.mjs} +1 -1
- package/dist/{BasePermissionHandler-BbLYwd13.cjs → BasePermissionHandler-DPvLN7aR.cjs} +1 -1
- package/dist/{BaseReasoningProcessor-_S1PbSvH.cjs → BaseReasoningProcessor-Dnf16mtJ.cjs} +1 -1
- package/dist/{BaseReasoningProcessor-DnykPlPo.mjs → BaseReasoningProcessor-pjvLSTQF.mjs} +1 -1
- package/dist/{agentHome-BoYfpemd.cjs → agentHome-BKi7tsE9.cjs} +4 -4
- package/dist/{agentHome-BtuRubHG.mjs → agentHome-D61ZMLXM.mjs} +4 -4
- package/dist/{api-KZmVqSKO.cjs → api-Buc_ejoA.cjs} +10 -10
- package/dist/{api-D08IEaWa.mjs → api-CbwDDXJt.mjs} +10 -10
- package/dist/{apiMachine-Dct2GDAq.cjs → apiMachine--PXoXwKq.cjs} +14 -14
- package/dist/{apiMachine-Cx9Zn-78.mjs → apiMachine-CS7t3Rg-.mjs} +15 -15
- package/dist/{attachmentContent-PrNJg8gG.mjs → attachmentContent-BQYc8KpE.mjs} +2 -2
- package/dist/{attachmentContent-4L9dO8E3.cjs → attachmentContent-CFzzTeV9.cjs} +2 -2
- package/dist/{attachmentLimits-BLbji11b.mjs → attachmentLimits-Di1Z93lN.mjs} +1 -1
- package/dist/{attachmentLimits-D6bT2jU1.cjs → attachmentLimits-DtFqqiwR.cjs} +1 -1
- package/dist/{auth-D1qHU-i_.mjs → auth-B3xMoveE.mjs} +5 -5
- package/dist/{auth-PY_HGlzz.mjs → auth-CBkmRIGw.mjs} +8 -8
- package/dist/{auth-BGmM3Vlm.cjs → auth-CpO3ZUMz.cjs} +5 -5
- package/dist/{auth-BI0CsMcy.cjs → auth-LPvsVriN.cjs} +8 -8
- package/dist/{auto-COMphIfD.mjs → auto-DHGch_zK.mjs} +16 -16
- package/dist/{auto-DM4_FeKb.cjs → auto-Dm3EIKT7.cjs} +15 -15
- package/dist/{bootstrap-DTJ6-vYT.cjs → bootstrap-BboDz_w2.cjs} +2 -2
- package/dist/{bootstrap-CWjpC5-J.mjs → bootstrap-CxuBAkJU.mjs} +2 -2
- package/dist/{browser-xuW4fiHo.mjs → browser-BvARP-YR.mjs} +1 -1
- package/dist/{browser-DmgVoopB.cjs → browser-GQZJxD2n.cjs} +1 -1
- package/dist/{claudeLocal-B0P-wVJJ.mjs → claudeLocal-B9EhFmD7.mjs} +6 -6
- package/dist/{claudeLocal-CtZVz3ee.cjs → claudeLocal-D-mujSX1.cjs} +5 -5
- package/dist/{claudeLocalLauncher-D4vmjI3c.mjs → claudeLocalLauncher-Bdl-9aU_.mjs} +11 -11
- package/dist/{claudeLocalLauncher-Dnv4CH8r.cjs → claudeLocalLauncher-Tbrx6TXF.cjs} +10 -10
- package/dist/{claudeSessionFork-CxjOBoBh.mjs → claudeSessionFork-D_DKvDKE.mjs} +1 -1
- package/dist/{claudeSessionFork-DQk5-dzR.cjs → claudeSessionFork-sOz97qqW.cjs} +1 -1
- package/dist/{client-eQjOvC55.mjs → client-Cg6ABRe-.mjs} +3 -3
- package/dist/{client-BHZVyQwi.cjs → client-D7sSU04O.cjs} +3 -3
- package/dist/{client-BhLhjj_x.cjs → client-D9pEOhn4.cjs} +2 -2
- package/dist/{client-C4ddTzrD.mjs → client-Ryu9fllj.mjs} +2 -2
- package/dist/codex/happyMcpStdioBridge.cjs +15 -15
- package/dist/codex/happyMcpStdioBridge.mjs +15 -15
- package/dist/{codexAppServerClient-CppPl_R6.mjs → codexAppServerClient-C70pJ-BB.mjs} +285 -28
- package/dist/{codexAppServerClient-D-9z-lWP.cjs → codexAppServerClient-DsIUkVnX.cjs} +281 -24
- package/dist/{codexCommand-AgVJYnFU.cjs → codexCommand-Aycux-B7.cjs} +156 -59
- package/dist/{codexCommand-BdrBNbZu.mjs → codexCommand-DWbA3pJN.mjs} +157 -60
- package/dist/{config-D89sE3wK.cjs → config-BcL0bxO5.cjs} +3 -3
- package/dist/{config-Cr3VUzbE.mjs → config-Bztmzu8z.mjs} +3 -3
- package/dist/{configuration-BNGPXg07.mjs → configuration-BAwOtWFY.mjs} +1 -1
- package/dist/{configuration-UV4EE5ui.cjs → configuration-CpBrilxV.cjs} +1 -1
- package/dist/{connect-B35YXbdZ.cjs → connect-BBNCMTi8.cjs} +13 -13
- package/dist/{connect-C0iLkCiY.mjs → connect-BeWQ4MMA.mjs} +13 -13
- package/dist/{context-BmH2BKip.cjs → context-Hk0j2Y9-.cjs} +1 -1
- package/dist/{context-Ptdnlcv6.mjs → context-j114QJre.mjs} +1 -1
- package/dist/{controlClient-DqtC0pq1.mjs → controlClient-00KYAjsI.mjs} +3 -3
- package/dist/{controlClient-CtsQMw--.cjs → controlClient-bs_YqwDl.cjs} +3 -3
- package/dist/{createSessionMetadata-2IuH5nlA.cjs → createSessionMetadata-D4Sj6H95.cjs} +2 -2
- package/dist/{createSessionMetadata-CtNMvfth.mjs → createSessionMetadata-xlycGog5.mjs} +2 -2
- package/dist/{defaultPermissionMode-DYihjV2g.mjs → defaultPermissionMode-B97ox9p1.mjs} +2 -2
- package/dist/{defaultPermissionMode-Bn4HcU8S.cjs → defaultPermissionMode-CMsiaRzr.cjs} +2 -2
- package/dist/{deterministicJson-je21npNx.cjs → deterministicJson-aHxtYLha.cjs} +9 -9
- package/dist/{deterministicJson-DF4xv6MH.mjs → deterministicJson-ucyv8j6b.mjs} +9 -9
- package/dist/{doctor-BXKcYVGU.cjs → doctor-BXkNXcok.cjs} +7 -7
- package/dist/{doctor-Ba92L7-b.mjs → doctor-D554c6Bg.mjs} +7 -7
- package/dist/{downloadTarget-CUJg8iJV.mjs → downloadTarget-2_zMvt2N.mjs} +6 -6
- package/dist/{downloadTarget-JC7FZl7W.cjs → downloadTarget-CmdlljZW.cjs} +6 -6
- package/dist/{ensureDaemonRunning-bIp6-vgi.cjs → ensureDaemonRunning-CY7iC--U.cjs} +5 -5
- package/dist/{ensureDaemonRunning-JPA9tHNE.mjs → ensureDaemonRunning-DJlziY-m.mjs} +5 -5
- package/dist/{handleResumeCommand-B6lE5DtU.mjs → handleResumeCommand-CNTnXBXA.mjs} +5 -5
- package/dist/{handleResumeCommand-B6b9kIYf.cjs → handleResumeCommand-lSVnvTNC.cjs} +5 -5
- package/dist/{index-CZLwo1FS.mjs → index-59hR7nVz.mjs} +3 -3
- package/dist/{index-DW1ONaGc.mjs → index-CxSLrTPA.mjs} +4 -4
- package/dist/{index-boE-d8CM.mjs → index-DMy3OCBe.mjs} +8 -1
- package/dist/{index-CjE4kBKx.mjs → index-DY3I8j0W.mjs} +37 -37
- package/dist/{index-BZdhwBKa.cjs → index-De8L5lFK.cjs} +8 -0
- package/dist/{index-B1ABQRrB.cjs → index-DhARRePz.cjs} +4 -4
- package/dist/{index-D759ViMU.cjs → index-MwTVbeGW.cjs} +3 -3
- package/dist/{index-B2KL0aPc.cjs → index-jeD70GGH.cjs} +36 -36
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{install-KjIsK_EA.cjs → install-DXUEtGfU.cjs} +3 -3
- package/dist/{install-CmojqnLK.mjs → install-DytIJ_Ia.mjs} +3 -3
- package/dist/lib.cjs +12 -12
- package/dist/lib.mjs +12 -12
- package/dist/{lidState-CL1NdKfQ.mjs → lidState-CduPmrM0.mjs} +1 -1
- package/dist/{lidState-BmJp2pLt.cjs → lidState-UasMvPzw.cjs} +1 -1
- package/dist/{localHappyAgentAuth-9SP7hdiw.cjs → localHappyAgentAuth-CA02WOny.cjs} +1 -1
- package/dist/{localHappyAgentAuth-B7f4Ysn0.mjs → localHappyAgentAuth-DL8JjHTV.mjs} +1 -1
- package/dist/{logger-D5EzMy30.mjs → logger-CihCDWDw.mjs} +2 -2
- package/dist/{logger-C7dRaCkE.cjs → logger-zoO54Zsy.cjs} +2 -2
- package/dist/{machineMetadata-DYYuK_0c.cjs → machineMetadata-BAKVtr-k.cjs} +3 -3
- package/dist/{machineMetadata-DqplCWue.mjs → machineMetadata-DEZcQ_CQ.mjs} +3 -3
- package/dist/{main-kgCQgknK.cjs → main-BIvxyX71.cjs} +44 -44
- package/dist/{main-CnV62agu.mjs → main-DyJfNlL_.mjs} +44 -44
- package/dist/{manager-BEsI4qt3.mjs → manager-2Il8XJVq.mjs} +1 -1
- package/dist/{mcp-BV0vxHtz.cjs → mcp-Dd11vHij.cjs} +14 -14
- package/dist/{mcp-bDPaj-tM.mjs → mcp-yoIdGe6C.mjs} +14 -14
- package/dist/{mirrorProtocol-ClKhNXYe.mjs → mirrorProtocol-BukXB5s3.mjs} +3 -3
- package/dist/{mirrorProtocol-BSHVZ8Nf.cjs → mirrorProtocol-D-hF_SE5.cjs} +3 -3
- package/dist/{package-VqWv7EI5.cjs → package-A7zOGx8B.cjs} +7 -7
- package/dist/{package-D0dxZ-W8.mjs → package-ayqGDKSp.mjs} +7 -7
- package/dist/{peerTools-B_eiNB3P.mjs → peerTools-DDMSViPu.mjs} +4 -4
- package/dist/{peerTools-BktGmlpd.cjs → peerTools-dPc9hRC5.cjs} +4 -4
- package/dist/{persistence-DweHi8xa.cjs → persistence-Cih2AWml.cjs} +2 -2
- package/dist/{persistence-CIIhP0Uw.mjs → persistence-Dy3lmall.mjs} +2 -2
- package/dist/{piRunnerArgs-BNzWTNRV.cjs → piRunnerArgs-BuJgnUI5.cjs} +1 -1
- package/dist/{piRunnerArgs-cQafsadv.mjs → piRunnerArgs-D3z3-1VJ.mjs} +1 -1
- package/dist/{piRuntime-VZLSwW-4.cjs → piRuntime-B-SPcWIr.cjs} +1 -1
- package/dist/{piRuntime-Bel5lOLb.mjs → piRuntime-kVGue-_5.mjs} +1 -1
- package/dist/{piTerminal-DkR8sPv-.cjs → piTerminal-DSxK5aAm.cjs} +16 -16
- package/dist/{piTerminal-CS5SDi_H.mjs → piTerminal-aEtVdCJ2.mjs} +16 -16
- package/dist/{rateLimitWindows-Bp4T21RI.cjs → rateLimitWindows-82izLQy8.cjs} +1 -1
- package/dist/{rateLimitWindows-Bo6XVnie.mjs → rateLimitWindows-E5DRjfE6.mjs} +1 -1
- package/dist/{registerCommonHandlers-CR5jpiSx.mjs → registerCommonHandlers-Bm7CMqMv.mjs} +2 -2
- package/dist/{registerCommonHandlers-B7QZxkCL.cjs → registerCommonHandlers-CqO075-X.cjs} +2 -2
- package/dist/{registerKillSessionHandler-DLiu24CQ.mjs → registerKillSessionHandler-D02OY4vi.mjs} +6 -6
- package/dist/{registerKillSessionHandler-CcX84g-T.cjs → registerKillSessionHandler-WQra3T9B.cjs} +6 -6
- package/dist/{remoteSessionClient-CUjw1COc.mjs → remoteSessionClient-Buh6NejV.mjs} +5 -5
- package/dist/{remoteSessionClient-CL3akj0K.cjs → remoteSessionClient-f3DYorl8.cjs} +5 -5
- package/dist/{reportProgressTool-DzMi4mvH.cjs → reportProgressTool-C2gn_HWD.cjs} +2 -2
- package/dist/{reportProgressTool-BLLwMQrN.mjs → reportProgressTool-C5aSoKYX.mjs} +2 -2
- package/dist/{run-5pmOElaW.cjs → run-CDEmq6Zs.cjs} +34 -34
- package/dist/{run-DGokR_6q.mjs → run-Drxogp0j.mjs} +33 -33
- package/dist/{runClaude-BFlpZQds.mjs → runClaude-BF6U2Js7.mjs} +21 -21
- package/dist/{runClaude-EnYNvkV0.cjs → runClaude-yEcZTCt_.cjs} +21 -21
- package/dist/{runClaudeDeps-D1M1dzlZ.mjs → runClaudeDeps-Bl4ndq7N.mjs} +40 -40
- package/dist/{runClaudeDeps-CUDebE9e.cjs → runClaudeDeps-CnNNFjlI.cjs} +35 -35
- package/dist/{runGemini-Bub8T5cM.mjs → runGemini-C3wt7iv7.mjs} +32 -32
- package/dist/{runGemini-Bu69Zu1u.cjs → runGemini-DDVDRNg4.cjs} +32 -32
- package/dist/{runOpenClaw-Cob5F3FC.cjs → runOpenClaw-BzlVA_9Q.cjs} +18 -18
- package/dist/{runOpenClaw-DVu73F_i.mjs → runOpenClaw-CY6YHAvj.mjs} +18 -18
- package/dist/{sandbox-GDqMagSF.cjs → sandbox-0UNHR3hP.cjs} +4 -4
- package/dist/{sandbox-9EKOFyQF.mjs → sandbox-CX_wLwpq.mjs} +4 -4
- package/dist/selfCheck-ClVv8NK3.mjs +84 -0
- package/dist/{selfCheck-DiNo34da.cjs → selfCheck-FNwMFY8p.cjs} +34 -34
- package/dist/{send-ThC80164.cjs → send-BQkl25g0.cjs} +8 -8
- package/dist/{send-wgtHphq8.mjs → send-CpEGYict.mjs} +8 -8
- package/dist/{server-bidHnstE.cjs → server-BodFZ5sW.cjs} +6 -6
- package/dist/{server-Bb8v2fOj.mjs → server-DnINX_Lm.mjs} +4 -4
- package/dist/{sessionLock-BWBcBZKh.cjs → sessionLock-DOj6mMXn.cjs} +3 -3
- package/dist/{sessionLock-gb32sVPR.mjs → sessionLock-Ddn-fhZ0.mjs} +3 -3
- package/dist/{sessionModeFile-C-fr1M1h.mjs → sessionModeFile-DDbonFR_.mjs} +1 -1
- package/dist/{sessionModeFile-DhuTNcJr.cjs → sessionModeFile-DVukoSp7.cjs} +1 -1
- package/dist/{sessionOps-ByZJbkMq.mjs → sessionOps-B1vQ25GS.mjs} +4 -4
- package/dist/{sessionOps-9MChM9Op.cjs → sessionOps-Nryt1DZt.cjs} +4 -4
- package/dist/{sessionScanner-BpegdnXK.cjs → sessionScanner-D1h-cdte.cjs} +3 -3
- package/dist/{sessionScanner-CxXPAVyS.mjs → sessionScanner-DCr3ofhR.mjs} +3 -3
- package/dist/{sessions-C1X4z_Lm.cjs → sessions-D2HsTbLf.cjs} +9 -9
- package/dist/{sessions-l-UgJGjV.mjs → sessions-DpAN6Ft9.mjs} +9 -9
- package/dist/{setupOfflineReconnection-CS_8Da8R.cjs → setupOfflineReconnection-B9Tw1Ouj.cjs} +2 -2
- package/dist/{setupOfflineReconnection-CgtXlV74.mjs → setupOfflineReconnection-DQHEp330.mjs} +2 -2
- package/dist/{spawn-FyoHqYWo.mjs → spawn-CNjm1yOi.mjs} +14 -14
- package/dist/{spawn-D2BlNdZu.cjs → spawn-CvDZ38hi.cjs} +13 -13
- package/dist/{spawnAgents-BhsbJ253.mjs → spawnAgents-BjtmjBvP.mjs} +1 -1
- package/dist/{spawnAgents-CgMKuOhZ.cjs → spawnAgents-CCjJifAW.cjs} +1 -1
- package/dist/{spawnHappyCLI-DsC256j_.mjs → spawnHappyCLI-C8Vl56wB.mjs} +1 -1
- package/dist/{spawnHappyCLI-DByQcqEN.cjs → spawnHappyCLI-ahi4j6Mh.cjs} +1 -1
- package/dist/{specialCommands-DGUeZqdm.cjs → specialCommands-BpqnGrOP.cjs} +3 -3
- package/dist/{specialCommands-DUUBqzvd.mjs → specialCommands-DfVMGXTl.mjs} +3 -3
- package/dist/{startFileWatcher-CaYRObJu.mjs → startFileWatcher-DXJXY4AE.mjs} +1 -1
- package/dist/{startFileWatcher-BtBaahTn.cjs → startFileWatcher-Ddn3L0u3.cjs} +1 -1
- package/dist/{streamRelay-DqPFsCgx.cjs → streamRelay-Cx01enfe.cjs} +1 -1
- package/dist/{streamRelay-C8zI7OnR.mjs → streamRelay-_qCd873P.mjs} +1 -1
- package/dist/{sync-D5YqUVjS.mjs → sync-BKvgkhPs.mjs} +1 -1
- package/dist/{sync-BK-IBkuB.cjs → sync-BgZuthoS.cjs} +1 -1
- package/dist/{systemPrompt-DaTKLEb-.cjs → systemPrompt-C6O1cHUg.cjs} +2 -2
- package/dist/{systemPrompt-e-qeag_h.mjs → systemPrompt-DuPem6c9.mjs} +2 -2
- package/dist/{teams-ClrppvKu.mjs → teams-CffMBBfU.mjs} +6 -6
- package/dist/{teams-D9xwa_d3.cjs → teams-DifEhhmk.cjs} +6 -6
- package/dist/{time-CvrpeD3S.mjs → time-DxCTiteK.mjs} +1 -1
- package/dist/{time-0szhiPo4.cjs → time-s8CaneqW.cjs} +1 -1
- package/dist/{titleGenerator-BZ5770wq.mjs → titleGenerator-B5T7QSzu.mjs} +1 -1
- package/dist/{titleGenerator-Dz5P7sE1.cjs → titleGenerator-CXr7t6cf.cjs} +2 -2
- package/dist/{todo-CkmNJQey.cjs → todo-B41GKMcI.cjs} +6 -6
- package/dist/{todo-o-miKcN2.mjs → todo-DNO7s8td.mjs} +6 -6
- package/dist/{tools-Cp0qJeBq.mjs → tools-697R1uqn.mjs} +1 -1
- package/dist/{tools-C77-Ssan.cjs → tools-lotMyxIE.cjs} +1 -1
- package/dist/{uninstall-DGUPERDX.cjs → uninstall-CRu96len.cjs} +3 -3
- package/dist/{uninstall-jNJDCLD_.mjs → uninstall-CYO7EDjO.mjs} +3 -3
- package/package.json +7 -7
- package/dist/selfCheck-CNo4uzGB.mjs +0 -84
|
@@ -3,12 +3,100 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var spawn = require('cross-spawn');
|
|
5
5
|
var node_readline = require('node:readline');
|
|
6
|
-
var logger = require('./logger-
|
|
6
|
+
var logger = require('./logger-zoO54Zsy.cjs');
|
|
7
7
|
var contentLogMetadata = require('./contentLogMetadata-ZSFk_NjQ.cjs');
|
|
8
8
|
var manager = require('./manager-HrEj442o.cjs');
|
|
9
|
-
var _package = require('./package-
|
|
10
|
-
var rateLimitWindows = require('./rateLimitWindows-
|
|
9
|
+
var _package = require('./package-A7zOGx8B.cjs');
|
|
10
|
+
var rateLimitWindows = require('./rateLimitWindows-82izLQy8.cjs');
|
|
11
11
|
|
|
12
|
+
const CODEX_HELPER_LABEL_MAX_CHARS = 80;
|
|
13
|
+
function codexHelperLabel(prompt) {
|
|
14
|
+
if (typeof prompt !== "string") return null;
|
|
15
|
+
const collapsed = prompt.replace(/\s+/g, " ").trim();
|
|
16
|
+
if (collapsed.length === 0) return null;
|
|
17
|
+
if (collapsed.length <= CODEX_HELPER_LABEL_MAX_CHARS) return collapsed;
|
|
18
|
+
const keep = CODEX_HELPER_LABEL_MAX_CHARS - 1;
|
|
19
|
+
const last = collapsed.charCodeAt(keep - 1);
|
|
20
|
+
const end = last >= 55296 && last <= 56319 ? keep - 1 : keep;
|
|
21
|
+
return `${collapsed.slice(0, end)}\u2026`;
|
|
22
|
+
}
|
|
23
|
+
function codexAgentPathSegments(agentPath) {
|
|
24
|
+
if (typeof agentPath !== "string") return [];
|
|
25
|
+
return agentPath.split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
26
|
+
}
|
|
27
|
+
function isRootAgentPath(segments) {
|
|
28
|
+
return segments.length === 1 && segments[0] === "root";
|
|
29
|
+
}
|
|
30
|
+
function codexChildAnnouncements(item) {
|
|
31
|
+
if (item.type === "subAgentActivity") {
|
|
32
|
+
const threadId = item.agentThreadId;
|
|
33
|
+
if (typeof threadId !== "string" || threadId.length === 0) return [];
|
|
34
|
+
const segments = codexAgentPathSegments(item.agentPath);
|
|
35
|
+
if (isRootAgentPath(segments)) return [];
|
|
36
|
+
const leaf = segments.at(-1);
|
|
37
|
+
return [{ threadId, label: leaf && leaf.length > 0 ? leaf : null }];
|
|
38
|
+
}
|
|
39
|
+
if (item.type === "collabAgentToolCall") {
|
|
40
|
+
const receivers = Array.isArray(item.receiverThreadIds) ? item.receiverThreadIds.filter((id) => typeof id === "string" && id.length > 0) : [];
|
|
41
|
+
const label = item.tool === "spawnAgent" ? codexHelperLabel(item.prompt) : null;
|
|
42
|
+
return [...new Set(receivers)].map((threadId) => ({ threadId, label }));
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function stopCodexProcess(proc, deps = {}) {
|
|
48
|
+
const platform = deps.platform ?? process.platform;
|
|
49
|
+
try {
|
|
50
|
+
proc.stdin?.end();
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
if (platform === "win32") return;
|
|
54
|
+
try {
|
|
55
|
+
proc.kill("SIGTERM");
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function killCodexProcessTree(proc, deps = {}) {
|
|
60
|
+
if (proc.exitCode != null || proc.signalCode != null) return;
|
|
61
|
+
const killRoot = () => {
|
|
62
|
+
try {
|
|
63
|
+
proc.kill("SIGKILL");
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const pid = proc.pid;
|
|
68
|
+
if (!pid || !("exitCode" in proc)) {
|
|
69
|
+
killRoot();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const platform = deps.platform ?? process.platform;
|
|
73
|
+
const spawn = deps.spawn ?? ((command, args, options) => node_child_process.spawn(command, args, options));
|
|
74
|
+
if (platform === "win32") {
|
|
75
|
+
try {
|
|
76
|
+
const killer = spawn("taskkill", ["/pid", String(pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
77
|
+
killer.on("error", killRoot);
|
|
78
|
+
killer.on("exit", (code) => {
|
|
79
|
+
if (code !== 0) killRoot();
|
|
80
|
+
});
|
|
81
|
+
killer.unref();
|
|
82
|
+
} catch {
|
|
83
|
+
killRoot();
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const reaper = spawn("pkill", ["-KILL", "-P", String(pid)], { stdio: "ignore", windowsHide: true });
|
|
89
|
+
reaper.on("error", () => void 0);
|
|
90
|
+
reaper.unref();
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
killRoot();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function jsonRpcErrorCodeOf(error) {
|
|
97
|
+
const code = error?.jsonRpcCode;
|
|
98
|
+
return typeof code === "number" ? code : null;
|
|
99
|
+
}
|
|
12
100
|
function isAppServerAvailable() {
|
|
13
101
|
try {
|
|
14
102
|
const version = node_child_process.execSync("codex --version", { encoding: "utf8", windowsHide: true }).trim();
|
|
@@ -123,6 +211,18 @@ class CodexAppServerClient {
|
|
|
123
211
|
// Approval / elicitation requests we are still answering: a human may take
|
|
124
212
|
// longer than the watchdog to decide, and that is not Codex going silent.
|
|
125
213
|
inflightServerRequests = 0;
|
|
214
|
+
// B-628: `turn/steer` — a message sent into the running turn (approach from Orca,
|
|
215
|
+
// src/main/codex/codex-structured-turn-start.ts). This app-server has no such
|
|
216
|
+
// method (-32601) until it is respawned; a refusal is per call (the turn it named
|
|
217
|
+
// ended or changed meanwhile, a review/compact turn).
|
|
218
|
+
steerUnsupported = false;
|
|
219
|
+
/** Steered inputs Codex has not echoed back as a `userMessage` item yet: clientId → turnId. */
|
|
220
|
+
steeredAwaitingEcho = /* @__PURE__ */ new Map();
|
|
221
|
+
/** Waiters for the pending turn to open (steerTurn); released when it opens or ends. */
|
|
222
|
+
turnOpenWaiters = [];
|
|
223
|
+
/** B-628: the names Codex gave the child threads it spawned (see codexChildThreads.ts). */
|
|
224
|
+
childThreadLabels = /* @__PURE__ */ new Map();
|
|
225
|
+
static MAX_CHILD_LABELS = 128;
|
|
126
226
|
// Handlers set by the consumer (runCodex.ts)
|
|
127
227
|
eventHandler = null;
|
|
128
228
|
approvalHandler = null;
|
|
@@ -193,6 +293,58 @@ class CodexAppServerClient {
|
|
|
193
293
|
const threadId = this.extractThreadId(params);
|
|
194
294
|
return threadId === null || this._threadId === null || threadId === this._threadId;
|
|
195
295
|
}
|
|
296
|
+
/** B-628: the child thread a frame belongs to, or null for the session's own. */
|
|
297
|
+
childThreadIdOf(params) {
|
|
298
|
+
return this.isOwnThreadFrame(params) ? null : this.extractThreadId(params);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* B-628: what a child thread's item carries so the mapper files it under the child's
|
|
302
|
+
* card (`subagent` → the session protocol's sub-agent envelope, as a Claude Task's
|
|
303
|
+
* children are) instead of in the main conversation as the session's own work.
|
|
304
|
+
*/
|
|
305
|
+
childItemFields(params) {
|
|
306
|
+
const child = this.childThreadIdOf(params);
|
|
307
|
+
if (!child) return {};
|
|
308
|
+
const label = this.childThreadLabels.get(child);
|
|
309
|
+
return { subagent: child, ...label ? { subagent_label: label } : {} };
|
|
310
|
+
}
|
|
311
|
+
rememberChildLabels(item) {
|
|
312
|
+
for (const { threadId, label } of codexChildAnnouncements(item)) {
|
|
313
|
+
if (!label || this.childThreadLabels.has(threadId)) continue;
|
|
314
|
+
if (this.childThreadLabels.size >= CodexAppServerClient.MAX_CHILD_LABELS) {
|
|
315
|
+
const oldest = this.childThreadLabels.keys().next().value;
|
|
316
|
+
if (oldest !== void 0) this.childThreadLabels.delete(oldest);
|
|
317
|
+
}
|
|
318
|
+
this.childThreadLabels.set(threadId, label);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* B-628: steered inputs the ended turn never echoed. `report` = the turn did not complete
|
|
323
|
+
* (interrupted, failed, app-server gone, given up): Codex never read them, tell the runner.
|
|
324
|
+
* A turn that *completed* drains its pending input before it ends (core/src/session/turn.rs),
|
|
325
|
+
* so an unechoed input there is a codex that accepted the steer but echoes no `clientId` —
|
|
326
|
+
* forgotten silently, because a false「not delivered」on a message the model did read would
|
|
327
|
+
* be worse than today's silence.
|
|
328
|
+
*/
|
|
329
|
+
dropUnechoedSteers(turnId, report) {
|
|
330
|
+
const dropped = [];
|
|
331
|
+
for (const [clientId, steeredTurn] of this.steeredAwaitingEcho) {
|
|
332
|
+
if (turnId === null || steeredTurn === turnId) {
|
|
333
|
+
dropped.push(clientId);
|
|
334
|
+
this.steeredAwaitingEcho.delete(clientId);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (dropped.length === 0) return;
|
|
338
|
+
if (!report) {
|
|
339
|
+
logger.logger.debug(`[CodexAppServer] ${dropped.length} steered message(s) completed without an echo; not reported`);
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this.eventHandler?.({
|
|
343
|
+
type: "steer_dropped",
|
|
344
|
+
client_ids: dropped,
|
|
345
|
+
...turnId ? { turn_id: turnId } : {}
|
|
346
|
+
});
|
|
347
|
+
}
|
|
196
348
|
/** Codex's last stderr lines, one line, for a message a person reads. */
|
|
197
349
|
stderrTail() {
|
|
198
350
|
return this.stderrRing.replace(/\x1b\[[0-9;]*m/g, "").replace(/\s+/g, " ").trim();
|
|
@@ -227,6 +379,7 @@ class CodexAppServerClient {
|
|
|
227
379
|
this.completedTurnIds.add(turnId);
|
|
228
380
|
if (failed) this.failedTurnIds.add(turnId);
|
|
229
381
|
}
|
|
382
|
+
this.dropUnechoedSteers(turnId, aborted || failed);
|
|
230
383
|
if (aborted) {
|
|
231
384
|
this.eventHandler?.({
|
|
232
385
|
type: "turn_aborted",
|
|
@@ -266,6 +419,11 @@ class CodexAppServerClient {
|
|
|
266
419
|
if (method === "turn/completed") {
|
|
267
420
|
if (!this.isOwnThreadFrame(params)) {
|
|
268
421
|
logger.logger.debug(`[CodexAppServer] Child thread ${this.extractThreadId(params)} ended a turn`);
|
|
422
|
+
this.eventHandler?.({
|
|
423
|
+
type: "subagent_turn_end",
|
|
424
|
+
...this.childItemFields(params),
|
|
425
|
+
status: this.extractTurnStatus(params)
|
|
426
|
+
});
|
|
269
427
|
return true;
|
|
270
428
|
}
|
|
271
429
|
this.emitRawTurnCompletion(
|
|
@@ -298,6 +456,7 @@ class CodexAppServerClient {
|
|
|
298
456
|
return true;
|
|
299
457
|
}
|
|
300
458
|
if (method === "thread/tokenUsage/updated") {
|
|
459
|
+
if (!this.isOwnThreadFrame(params)) return true;
|
|
301
460
|
const tokenUsage = params?.tokenUsage;
|
|
302
461
|
if (tokenUsage && typeof tokenUsage === "object") {
|
|
303
462
|
this.eventHandler?.({
|
|
@@ -311,8 +470,15 @@ class CodexAppServerClient {
|
|
|
311
470
|
if (!item || typeof item !== "object") {
|
|
312
471
|
return method.startsWith("item/");
|
|
313
472
|
}
|
|
473
|
+
const child = this.childItemFields(params);
|
|
314
474
|
if ((method === "item/started" || method === "item/completed") && (item.type === "collabAgentToolCall" || item.type === "subAgentActivity")) {
|
|
315
|
-
this.
|
|
475
|
+
this.rememberChildLabels(item);
|
|
476
|
+
this.eventHandler?.({ type: "collab_agent_item", item, ...child });
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
if (method === "item/completed" && item.type === "userMessage") {
|
|
480
|
+
const clientId = typeof item.clientId === "string" ? item.clientId : null;
|
|
481
|
+
if (clientId && !child.subagent) this.steeredAwaitingEcho.delete(clientId);
|
|
316
482
|
return true;
|
|
317
483
|
}
|
|
318
484
|
if (method === "item/started" && item.type === "commandExecution") {
|
|
@@ -323,7 +489,8 @@ class CodexAppServerClient {
|
|
|
323
489
|
callId,
|
|
324
490
|
command: item.command,
|
|
325
491
|
cwd: item.cwd,
|
|
326
|
-
description: item.command
|
|
492
|
+
description: item.command,
|
|
493
|
+
...child
|
|
327
494
|
});
|
|
328
495
|
return true;
|
|
329
496
|
}
|
|
@@ -338,7 +505,8 @@ class CodexAppServerClient {
|
|
|
338
505
|
duration_ms: item.durationMs ?? null,
|
|
339
506
|
status: item.status,
|
|
340
507
|
cwd: item.cwd,
|
|
341
|
-
command: item.command
|
|
508
|
+
command: item.command,
|
|
509
|
+
...child
|
|
342
510
|
});
|
|
343
511
|
return true;
|
|
344
512
|
}
|
|
@@ -353,7 +521,8 @@ class CodexAppServerClient {
|
|
|
353
521
|
type: "patch_apply_begin",
|
|
354
522
|
call_id: callId,
|
|
355
523
|
callId,
|
|
356
|
-
changes: changes ?? {}
|
|
524
|
+
changes: changes ?? {},
|
|
525
|
+
...child
|
|
357
526
|
});
|
|
358
527
|
return true;
|
|
359
528
|
}
|
|
@@ -362,7 +531,8 @@ class CodexAppServerClient {
|
|
|
362
531
|
type: "patch_apply_end",
|
|
363
532
|
call_id: callId,
|
|
364
533
|
callId,
|
|
365
|
-
status: item.status
|
|
534
|
+
status: item.status,
|
|
535
|
+
...child
|
|
366
536
|
});
|
|
367
537
|
if (callId && (item.status === "completed" || item.status === "failed" || item.status === "declined")) {
|
|
368
538
|
this.rawFileChangesByItemId.delete(callId);
|
|
@@ -377,7 +547,8 @@ class CodexAppServerClient {
|
|
|
377
547
|
type: "agent_message",
|
|
378
548
|
message: text,
|
|
379
549
|
item_id: item.id,
|
|
380
|
-
phase: item.phase
|
|
550
|
+
phase: item.phase,
|
|
551
|
+
...child
|
|
381
552
|
});
|
|
382
553
|
}
|
|
383
554
|
return true;
|
|
@@ -450,6 +621,7 @@ class CodexAppServerClient {
|
|
|
450
621
|
}
|
|
451
622
|
if (this.pendingTurnCompletion) {
|
|
452
623
|
const turnId = this.pendingTurnCompletion.turnId ?? this._turnId;
|
|
624
|
+
this.dropUnechoedSteers(null, true);
|
|
453
625
|
this.eventHandler?.({
|
|
454
626
|
type: "turn_aborted",
|
|
455
627
|
reason: "process-exit",
|
|
@@ -460,6 +632,9 @@ class CodexAppServerClient {
|
|
|
460
632
|
this.resolvePendingTurn(true);
|
|
461
633
|
});
|
|
462
634
|
this.stderrRing = "";
|
|
635
|
+
this.steerUnsupported = false;
|
|
636
|
+
this.steeredAwaitingEcho.clear();
|
|
637
|
+
this.childThreadLabels.clear();
|
|
463
638
|
proc.stderr?.on("data", (chunk) => {
|
|
464
639
|
if (this.process !== proc || this.processEpoch !== epoch) return;
|
|
465
640
|
const text = chunk.toString().trim();
|
|
@@ -498,20 +673,12 @@ ${text}`.slice(-400);
|
|
|
498
673
|
logger.logger.debug(`[CodexAppServer] Disconnecting; pid=${pid ?? "none"}`);
|
|
499
674
|
this.readline?.close();
|
|
500
675
|
this.readline = null;
|
|
501
|
-
|
|
502
|
-
proc
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
const killTimer = setTimeout(() => {
|
|
508
|
-
try {
|
|
509
|
-
process.kill(pid, 0);
|
|
510
|
-
process.kill(pid, "SIGKILL");
|
|
511
|
-
} catch {
|
|
512
|
-
}
|
|
513
|
-
}, 2e3);
|
|
514
|
-
killTimer.unref();
|
|
676
|
+
if (proc) {
|
|
677
|
+
stopCodexProcess(proc);
|
|
678
|
+
if (pid) {
|
|
679
|
+
const killTimer = setTimeout(() => killCodexProcessTree(proc), CodexAppServerClient.FORCE_KILL_AFTER_MS);
|
|
680
|
+
killTimer.unref();
|
|
681
|
+
}
|
|
515
682
|
}
|
|
516
683
|
this.process = null;
|
|
517
684
|
this.connected = false;
|
|
@@ -530,6 +697,7 @@ ${text}`.slice(-400);
|
|
|
530
697
|
req.reject(new Error(`Codex process disconnected while waiting for ${req.method}`));
|
|
531
698
|
this.pending.delete(id);
|
|
532
699
|
}
|
|
700
|
+
this.dropUnechoedSteers(null, true);
|
|
533
701
|
this.resolvePendingTurn(true);
|
|
534
702
|
if (this.sandboxCleanup) {
|
|
535
703
|
try {
|
|
@@ -733,6 +901,8 @@ ${text}`.slice(-400);
|
|
|
733
901
|
// ─── Turn management ────────────────────────────────────────
|
|
734
902
|
/** Default grace period after interrupt before forcing a restart (ms). */
|
|
735
903
|
static ABORT_GRACE_MS = 3e3;
|
|
904
|
+
/** How long the graceful stop gets before the process tree is killed (disconnectInternal). */
|
|
905
|
+
static FORCE_KILL_AFTER_MS = 2e3;
|
|
736
906
|
hasPendingTurnCompletion() {
|
|
737
907
|
return this.pendingTurnCompletion !== null;
|
|
738
908
|
}
|
|
@@ -742,6 +912,7 @@ ${text}`.slice(-400);
|
|
|
742
912
|
this.clearThreadStopGrace();
|
|
743
913
|
this.pendingTurnCompletion.resolve(aborted);
|
|
744
914
|
this.pendingTurnCompletion = null;
|
|
915
|
+
this.releaseTurnOpenWaiters();
|
|
745
916
|
}
|
|
746
917
|
markPendingTurnStarted(turnId) {
|
|
747
918
|
if (!this.pendingTurnCompletion) return;
|
|
@@ -749,6 +920,86 @@ ${text}`.slice(-400);
|
|
|
749
920
|
if (turnId) {
|
|
750
921
|
this.pendingTurnCompletion.turnId = turnId;
|
|
751
922
|
}
|
|
923
|
+
this.releaseTurnOpenWaiters();
|
|
924
|
+
}
|
|
925
|
+
// ─── B-628: steering the running turn ───────────────────────
|
|
926
|
+
/** How long a steer waits for the pending turn to open before the message is queued instead. */
|
|
927
|
+
static STEER_OPEN_WAIT_MS = 5e3;
|
|
928
|
+
/** A turn Codex has reported running, under an id `turn/steer` can name. */
|
|
929
|
+
turnIsOpen() {
|
|
930
|
+
return this.pendingTurnCompletion?.opened === true && this._turnId !== null;
|
|
931
|
+
}
|
|
932
|
+
releaseTurnOpenWaiters() {
|
|
933
|
+
const waiters = this.turnOpenWaiters;
|
|
934
|
+
this.turnOpenWaiters = [];
|
|
935
|
+
for (const release of waiters) release();
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Waits for the pending turn to open — `turn/start` is in flight, or the runner is still
|
|
939
|
+
* bringing a released app-server back before sending it (B-461) — as Orca's send does
|
|
940
|
+
* (codex-structured-turn-open-wait.ts, 5 s). Resolves early when the turn ends instead.
|
|
941
|
+
*/
|
|
942
|
+
async waitForTurnOpen(timeoutMs) {
|
|
943
|
+
if (this.turnIsOpen()) return true;
|
|
944
|
+
if (timeoutMs <= 0) return false;
|
|
945
|
+
await new Promise((resolve) => {
|
|
946
|
+
const release = () => {
|
|
947
|
+
clearTimeout(timer);
|
|
948
|
+
resolve();
|
|
949
|
+
};
|
|
950
|
+
const timer = setTimeout(release, timeoutMs);
|
|
951
|
+
timer.unref();
|
|
952
|
+
this.turnOpenWaiters.push(release);
|
|
953
|
+
});
|
|
954
|
+
return this.turnIsOpen();
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* B-628: send a message into the turn running right now (`turn/steer`, codex ≥ 0.148 /
|
|
958
|
+
* app-server-protocol v2 `TurnSteerParams`). Codex appends it to that turn's pending input
|
|
959
|
+
* and the model reads it before its next call; the turn keeps its own model, approval
|
|
960
|
+
* policy and sandbox — the runner applies any change on the next `turn/start`. Codex
|
|
961
|
+
* refuses before taking any input (expectedTurnId is a precondition), so a non-`steered`
|
|
962
|
+
* outcome always means "queue it for the next turn as before": `no-turn` (nothing running,
|
|
963
|
+
* or it ended while we waited), `unsupported` (this app-server has no `turn/steer`,
|
|
964
|
+
* remembered until it is respawned), `refused` (Codex declined this one), `failed`
|
|
965
|
+
* (transport — the turn itself is reported through its own events).
|
|
966
|
+
*/
|
|
967
|
+
async steerTurn(input, opts) {
|
|
968
|
+
if (this.steerUnsupported) return "unsupported";
|
|
969
|
+
if (this.pendingInterrupt) return "no-turn";
|
|
970
|
+
const opened = await this.waitForTurnOpen(opts?.waitForTurnMs ?? CodexAppServerClient.STEER_OPEN_WAIT_MS);
|
|
971
|
+
const threadId = this._threadId;
|
|
972
|
+
const turnId = this._turnId;
|
|
973
|
+
if (!opened || !threadId || !turnId || !this.connected || this.pendingInterrupt) return "no-turn";
|
|
974
|
+
const params = {
|
|
975
|
+
threadId,
|
|
976
|
+
expectedTurnId: turnId,
|
|
977
|
+
...input.clientId ? { clientUserMessageId: input.clientId } : {},
|
|
978
|
+
input: [
|
|
979
|
+
{ type: "text", text: input.text },
|
|
980
|
+
...(input.images ?? []).map((path) => ({ type: "localImage", path }))
|
|
981
|
+
]
|
|
982
|
+
};
|
|
983
|
+
try {
|
|
984
|
+
const result = await this.request("turn/steer", params);
|
|
985
|
+
const steeredTurnId = typeof result?.turnId === "string" && result.turnId.length > 0 ? result.turnId : turnId;
|
|
986
|
+
if (input.clientId) this.steeredAwaitingEcho.set(input.clientId, steeredTurnId);
|
|
987
|
+
logger.logger.debug(`[CodexAppServer] Steered a message into turn ${steeredTurnId}`);
|
|
988
|
+
return "steered";
|
|
989
|
+
} catch (error) {
|
|
990
|
+
const code = jsonRpcErrorCodeOf(error);
|
|
991
|
+
if (code === -32601) {
|
|
992
|
+
this.steerUnsupported = true;
|
|
993
|
+
logger.logger.debug("[CodexAppServer] turn/steer is not supported by this codex; queuing instead");
|
|
994
|
+
return "unsupported";
|
|
995
|
+
}
|
|
996
|
+
if (code !== null) {
|
|
997
|
+
logger.logger.debug("[CodexAppServer] turn/steer refused:", contentLogMetadata.errorLogMetadata(error));
|
|
998
|
+
return "refused";
|
|
999
|
+
}
|
|
1000
|
+
logger.logger.debug("[CodexAppServer] turn/steer failed:", contentLogMetadata.errorLogMetadata(error));
|
|
1001
|
+
return "failed";
|
|
1002
|
+
}
|
|
752
1003
|
}
|
|
753
1004
|
/** Default wait for Codex's `turn/completed` after its thread reported idle/systemError. */
|
|
754
1005
|
static THREAD_STOP_GRACE_MS = 1500;
|
|
@@ -911,6 +1162,7 @@ ${text}`.slice(-400);
|
|
|
911
1162
|
} catch (err) {
|
|
912
1163
|
this.clearTurnWatchdog();
|
|
913
1164
|
this.pendingTurnCompletion = null;
|
|
1165
|
+
this.releaseTurnOpenWaiters();
|
|
914
1166
|
throw err;
|
|
915
1167
|
}
|
|
916
1168
|
const aborted = await completion;
|
|
@@ -928,6 +1180,7 @@ ${text}`.slice(-400);
|
|
|
928
1180
|
}
|
|
929
1181
|
logger.logger.warn(`[CodexAppServer] No notification from Codex for ${timeoutMs}ms \u2014 giving the turn up as aborted`);
|
|
930
1182
|
const turnId = this.pendingTurnCompletion.turnId ?? this._turnId;
|
|
1183
|
+
this.dropUnechoedSteers(turnId, true);
|
|
931
1184
|
this.eventHandler?.({
|
|
932
1185
|
type: "turn_aborted",
|
|
933
1186
|
reason: "timeout",
|
|
@@ -978,6 +1231,7 @@ ${text}`.slice(-400);
|
|
|
978
1231
|
logger.logger.debug(
|
|
979
1232
|
`[CodexAppServer] Clearing thread state: thread=${this._threadId ?? "none"} turn=${this._turnId ?? "none"}`
|
|
980
1233
|
);
|
|
1234
|
+
this.dropUnechoedSteers(null, true);
|
|
981
1235
|
this.resolvePendingTurn(true);
|
|
982
1236
|
this._threadId = null;
|
|
983
1237
|
this._turnId = null;
|
|
@@ -986,6 +1240,7 @@ ${text}`.slice(-400);
|
|
|
986
1240
|
this.failedTurnIds.clear();
|
|
987
1241
|
this.lastTurnError = null;
|
|
988
1242
|
this.rawFileChangesByItemId.clear();
|
|
1243
|
+
this.childThreadLabels.clear();
|
|
989
1244
|
}
|
|
990
1245
|
// ─── JSON-RPC transport ─────────────────────────────────────
|
|
991
1246
|
/** Default timeout for RPC requests (ms). */
|
|
@@ -1066,7 +1321,9 @@ ${text}`.slice(-400);
|
|
|
1066
1321
|
}
|
|
1067
1322
|
this.pending.delete(msg.id);
|
|
1068
1323
|
if (msg.error) {
|
|
1069
|
-
|
|
1324
|
+
const error = new Error(`${pending.method}: ${msg.error.message} (code=${msg.error.code})`);
|
|
1325
|
+
if (typeof msg.error.code === "number") error.jsonRpcCode = msg.error.code;
|
|
1326
|
+
pending.reject(error);
|
|
1070
1327
|
} else {
|
|
1071
1328
|
pending.resolve(msg.result);
|
|
1072
1329
|
}
|