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
|
@@ -1,12 +1,100 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import { spawn } from 'cross-spawn';
|
|
1
|
+
import { spawn, execSync } from 'node:child_process';
|
|
2
|
+
import { spawn as spawn$1 } from 'cross-spawn';
|
|
3
3
|
import { createInterface } from 'node:readline';
|
|
4
|
-
import { l as logger } from './logger-
|
|
4
|
+
import { l as logger } from './logger-CihCDWDw.mjs';
|
|
5
5
|
import { e as errorLogMetadata, c as contentLogMetadata } from './contentLogMetadata-BlWI0egu.mjs';
|
|
6
|
-
import { i as initializeSandbox,
|
|
7
|
-
import { p as packageJson } from './package-
|
|
8
|
-
import { s as shouldReadCodexRateLimits, i as isUnsupportedCodexMethodError } from './rateLimitWindows-
|
|
6
|
+
import { i as initializeSandbox, a as wrapForMcpTransport } from './manager-2Il8XJVq.mjs';
|
|
7
|
+
import { p as packageJson } from './package-ayqGDKSp.mjs';
|
|
8
|
+
import { s as shouldReadCodexRateLimits, i as isUnsupportedCodexMethodError } from './rateLimitWindows-E5DRjfE6.mjs';
|
|
9
9
|
|
|
10
|
+
const CODEX_HELPER_LABEL_MAX_CHARS = 80;
|
|
11
|
+
function codexHelperLabel(prompt) {
|
|
12
|
+
if (typeof prompt !== "string") return null;
|
|
13
|
+
const collapsed = prompt.replace(/\s+/g, " ").trim();
|
|
14
|
+
if (collapsed.length === 0) return null;
|
|
15
|
+
if (collapsed.length <= CODEX_HELPER_LABEL_MAX_CHARS) return collapsed;
|
|
16
|
+
const keep = CODEX_HELPER_LABEL_MAX_CHARS - 1;
|
|
17
|
+
const last = collapsed.charCodeAt(keep - 1);
|
|
18
|
+
const end = last >= 55296 && last <= 56319 ? keep - 1 : keep;
|
|
19
|
+
return `${collapsed.slice(0, end)}\u2026`;
|
|
20
|
+
}
|
|
21
|
+
function codexAgentPathSegments(agentPath) {
|
|
22
|
+
if (typeof agentPath !== "string") return [];
|
|
23
|
+
return agentPath.split("/").map((segment) => segment.trim()).filter((segment) => segment.length > 0);
|
|
24
|
+
}
|
|
25
|
+
function isRootAgentPath(segments) {
|
|
26
|
+
return segments.length === 1 && segments[0] === "root";
|
|
27
|
+
}
|
|
28
|
+
function codexChildAnnouncements(item) {
|
|
29
|
+
if (item.type === "subAgentActivity") {
|
|
30
|
+
const threadId = item.agentThreadId;
|
|
31
|
+
if (typeof threadId !== "string" || threadId.length === 0) return [];
|
|
32
|
+
const segments = codexAgentPathSegments(item.agentPath);
|
|
33
|
+
if (isRootAgentPath(segments)) return [];
|
|
34
|
+
const leaf = segments.at(-1);
|
|
35
|
+
return [{ threadId, label: leaf && leaf.length > 0 ? leaf : null }];
|
|
36
|
+
}
|
|
37
|
+
if (item.type === "collabAgentToolCall") {
|
|
38
|
+
const receivers = Array.isArray(item.receiverThreadIds) ? item.receiverThreadIds.filter((id) => typeof id === "string" && id.length > 0) : [];
|
|
39
|
+
const label = item.tool === "spawnAgent" ? codexHelperLabel(item.prompt) : null;
|
|
40
|
+
return [...new Set(receivers)].map((threadId) => ({ threadId, label }));
|
|
41
|
+
}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function stopCodexProcess(proc, deps = {}) {
|
|
46
|
+
const platform = deps.platform ?? process.platform;
|
|
47
|
+
try {
|
|
48
|
+
proc.stdin?.end();
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
if (platform === "win32") return;
|
|
52
|
+
try {
|
|
53
|
+
proc.kill("SIGTERM");
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function killCodexProcessTree(proc, deps = {}) {
|
|
58
|
+
if (proc.exitCode != null || proc.signalCode != null) return;
|
|
59
|
+
const killRoot = () => {
|
|
60
|
+
try {
|
|
61
|
+
proc.kill("SIGKILL");
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const pid = proc.pid;
|
|
66
|
+
if (!pid || !("exitCode" in proc)) {
|
|
67
|
+
killRoot();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const platform = deps.platform ?? process.platform;
|
|
71
|
+
const spawn$1 = deps.spawn ?? ((command, args, options) => spawn(command, args, options));
|
|
72
|
+
if (platform === "win32") {
|
|
73
|
+
try {
|
|
74
|
+
const killer = spawn$1("taskkill", ["/pid", String(pid), "/t", "/f"], { stdio: "ignore", windowsHide: true });
|
|
75
|
+
killer.on("error", killRoot);
|
|
76
|
+
killer.on("exit", (code) => {
|
|
77
|
+
if (code !== 0) killRoot();
|
|
78
|
+
});
|
|
79
|
+
killer.unref();
|
|
80
|
+
} catch {
|
|
81
|
+
killRoot();
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const reaper = spawn$1("pkill", ["-KILL", "-P", String(pid)], { stdio: "ignore", windowsHide: true });
|
|
87
|
+
reaper.on("error", () => void 0);
|
|
88
|
+
reaper.unref();
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
killRoot();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function jsonRpcErrorCodeOf(error) {
|
|
95
|
+
const code = error?.jsonRpcCode;
|
|
96
|
+
return typeof code === "number" ? code : null;
|
|
97
|
+
}
|
|
10
98
|
function isAppServerAvailable() {
|
|
11
99
|
try {
|
|
12
100
|
const version = execSync("codex --version", { encoding: "utf8", windowsHide: true }).trim();
|
|
@@ -121,6 +209,18 @@ class CodexAppServerClient {
|
|
|
121
209
|
// Approval / elicitation requests we are still answering: a human may take
|
|
122
210
|
// longer than the watchdog to decide, and that is not Codex going silent.
|
|
123
211
|
inflightServerRequests = 0;
|
|
212
|
+
// B-628: `turn/steer` — a message sent into the running turn (approach from Orca,
|
|
213
|
+
// src/main/codex/codex-structured-turn-start.ts). This app-server has no such
|
|
214
|
+
// method (-32601) until it is respawned; a refusal is per call (the turn it named
|
|
215
|
+
// ended or changed meanwhile, a review/compact turn).
|
|
216
|
+
steerUnsupported = false;
|
|
217
|
+
/** Steered inputs Codex has not echoed back as a `userMessage` item yet: clientId → turnId. */
|
|
218
|
+
steeredAwaitingEcho = /* @__PURE__ */ new Map();
|
|
219
|
+
/** Waiters for the pending turn to open (steerTurn); released when it opens or ends. */
|
|
220
|
+
turnOpenWaiters = [];
|
|
221
|
+
/** B-628: the names Codex gave the child threads it spawned (see codexChildThreads.ts). */
|
|
222
|
+
childThreadLabels = /* @__PURE__ */ new Map();
|
|
223
|
+
static MAX_CHILD_LABELS = 128;
|
|
124
224
|
// Handlers set by the consumer (runCodex.ts)
|
|
125
225
|
eventHandler = null;
|
|
126
226
|
approvalHandler = null;
|
|
@@ -191,6 +291,58 @@ class CodexAppServerClient {
|
|
|
191
291
|
const threadId = this.extractThreadId(params);
|
|
192
292
|
return threadId === null || this._threadId === null || threadId === this._threadId;
|
|
193
293
|
}
|
|
294
|
+
/** B-628: the child thread a frame belongs to, or null for the session's own. */
|
|
295
|
+
childThreadIdOf(params) {
|
|
296
|
+
return this.isOwnThreadFrame(params) ? null : this.extractThreadId(params);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* B-628: what a child thread's item carries so the mapper files it under the child's
|
|
300
|
+
* card (`subagent` → the session protocol's sub-agent envelope, as a Claude Task's
|
|
301
|
+
* children are) instead of in the main conversation as the session's own work.
|
|
302
|
+
*/
|
|
303
|
+
childItemFields(params) {
|
|
304
|
+
const child = this.childThreadIdOf(params);
|
|
305
|
+
if (!child) return {};
|
|
306
|
+
const label = this.childThreadLabels.get(child);
|
|
307
|
+
return { subagent: child, ...label ? { subagent_label: label } : {} };
|
|
308
|
+
}
|
|
309
|
+
rememberChildLabels(item) {
|
|
310
|
+
for (const { threadId, label } of codexChildAnnouncements(item)) {
|
|
311
|
+
if (!label || this.childThreadLabels.has(threadId)) continue;
|
|
312
|
+
if (this.childThreadLabels.size >= CodexAppServerClient.MAX_CHILD_LABELS) {
|
|
313
|
+
const oldest = this.childThreadLabels.keys().next().value;
|
|
314
|
+
if (oldest !== void 0) this.childThreadLabels.delete(oldest);
|
|
315
|
+
}
|
|
316
|
+
this.childThreadLabels.set(threadId, label);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* B-628: steered inputs the ended turn never echoed. `report` = the turn did not complete
|
|
321
|
+
* (interrupted, failed, app-server gone, given up): Codex never read them, tell the runner.
|
|
322
|
+
* A turn that *completed* drains its pending input before it ends (core/src/session/turn.rs),
|
|
323
|
+
* so an unechoed input there is a codex that accepted the steer but echoes no `clientId` —
|
|
324
|
+
* forgotten silently, because a false「not delivered」on a message the model did read would
|
|
325
|
+
* be worse than today's silence.
|
|
326
|
+
*/
|
|
327
|
+
dropUnechoedSteers(turnId, report) {
|
|
328
|
+
const dropped = [];
|
|
329
|
+
for (const [clientId, steeredTurn] of this.steeredAwaitingEcho) {
|
|
330
|
+
if (turnId === null || steeredTurn === turnId) {
|
|
331
|
+
dropped.push(clientId);
|
|
332
|
+
this.steeredAwaitingEcho.delete(clientId);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (dropped.length === 0) return;
|
|
336
|
+
if (!report) {
|
|
337
|
+
logger.debug(`[CodexAppServer] ${dropped.length} steered message(s) completed without an echo; not reported`);
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
this.eventHandler?.({
|
|
341
|
+
type: "steer_dropped",
|
|
342
|
+
client_ids: dropped,
|
|
343
|
+
...turnId ? { turn_id: turnId } : {}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
194
346
|
/** Codex's last stderr lines, one line, for a message a person reads. */
|
|
195
347
|
stderrTail() {
|
|
196
348
|
return this.stderrRing.replace(/\x1b\[[0-9;]*m/g, "").replace(/\s+/g, " ").trim();
|
|
@@ -225,6 +377,7 @@ class CodexAppServerClient {
|
|
|
225
377
|
this.completedTurnIds.add(turnId);
|
|
226
378
|
if (failed) this.failedTurnIds.add(turnId);
|
|
227
379
|
}
|
|
380
|
+
this.dropUnechoedSteers(turnId, aborted || failed);
|
|
228
381
|
if (aborted) {
|
|
229
382
|
this.eventHandler?.({
|
|
230
383
|
type: "turn_aborted",
|
|
@@ -264,6 +417,11 @@ class CodexAppServerClient {
|
|
|
264
417
|
if (method === "turn/completed") {
|
|
265
418
|
if (!this.isOwnThreadFrame(params)) {
|
|
266
419
|
logger.debug(`[CodexAppServer] Child thread ${this.extractThreadId(params)} ended a turn`);
|
|
420
|
+
this.eventHandler?.({
|
|
421
|
+
type: "subagent_turn_end",
|
|
422
|
+
...this.childItemFields(params),
|
|
423
|
+
status: this.extractTurnStatus(params)
|
|
424
|
+
});
|
|
267
425
|
return true;
|
|
268
426
|
}
|
|
269
427
|
this.emitRawTurnCompletion(
|
|
@@ -296,6 +454,7 @@ class CodexAppServerClient {
|
|
|
296
454
|
return true;
|
|
297
455
|
}
|
|
298
456
|
if (method === "thread/tokenUsage/updated") {
|
|
457
|
+
if (!this.isOwnThreadFrame(params)) return true;
|
|
299
458
|
const tokenUsage = params?.tokenUsage;
|
|
300
459
|
if (tokenUsage && typeof tokenUsage === "object") {
|
|
301
460
|
this.eventHandler?.({
|
|
@@ -309,8 +468,15 @@ class CodexAppServerClient {
|
|
|
309
468
|
if (!item || typeof item !== "object") {
|
|
310
469
|
return method.startsWith("item/");
|
|
311
470
|
}
|
|
471
|
+
const child = this.childItemFields(params);
|
|
312
472
|
if ((method === "item/started" || method === "item/completed") && (item.type === "collabAgentToolCall" || item.type === "subAgentActivity")) {
|
|
313
|
-
this.
|
|
473
|
+
this.rememberChildLabels(item);
|
|
474
|
+
this.eventHandler?.({ type: "collab_agent_item", item, ...child });
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
if (method === "item/completed" && item.type === "userMessage") {
|
|
478
|
+
const clientId = typeof item.clientId === "string" ? item.clientId : null;
|
|
479
|
+
if (clientId && !child.subagent) this.steeredAwaitingEcho.delete(clientId);
|
|
314
480
|
return true;
|
|
315
481
|
}
|
|
316
482
|
if (method === "item/started" && item.type === "commandExecution") {
|
|
@@ -321,7 +487,8 @@ class CodexAppServerClient {
|
|
|
321
487
|
callId,
|
|
322
488
|
command: item.command,
|
|
323
489
|
cwd: item.cwd,
|
|
324
|
-
description: item.command
|
|
490
|
+
description: item.command,
|
|
491
|
+
...child
|
|
325
492
|
});
|
|
326
493
|
return true;
|
|
327
494
|
}
|
|
@@ -336,7 +503,8 @@ class CodexAppServerClient {
|
|
|
336
503
|
duration_ms: item.durationMs ?? null,
|
|
337
504
|
status: item.status,
|
|
338
505
|
cwd: item.cwd,
|
|
339
|
-
command: item.command
|
|
506
|
+
command: item.command,
|
|
507
|
+
...child
|
|
340
508
|
});
|
|
341
509
|
return true;
|
|
342
510
|
}
|
|
@@ -351,7 +519,8 @@ class CodexAppServerClient {
|
|
|
351
519
|
type: "patch_apply_begin",
|
|
352
520
|
call_id: callId,
|
|
353
521
|
callId,
|
|
354
|
-
changes: changes ?? {}
|
|
522
|
+
changes: changes ?? {},
|
|
523
|
+
...child
|
|
355
524
|
});
|
|
356
525
|
return true;
|
|
357
526
|
}
|
|
@@ -360,7 +529,8 @@ class CodexAppServerClient {
|
|
|
360
529
|
type: "patch_apply_end",
|
|
361
530
|
call_id: callId,
|
|
362
531
|
callId,
|
|
363
|
-
status: item.status
|
|
532
|
+
status: item.status,
|
|
533
|
+
...child
|
|
364
534
|
});
|
|
365
535
|
if (callId && (item.status === "completed" || item.status === "failed" || item.status === "declined")) {
|
|
366
536
|
this.rawFileChangesByItemId.delete(callId);
|
|
@@ -375,7 +545,8 @@ class CodexAppServerClient {
|
|
|
375
545
|
type: "agent_message",
|
|
376
546
|
message: text,
|
|
377
547
|
item_id: item.id,
|
|
378
|
-
phase: item.phase
|
|
548
|
+
phase: item.phase,
|
|
549
|
+
...child
|
|
379
550
|
});
|
|
380
551
|
}
|
|
381
552
|
return true;
|
|
@@ -421,7 +592,7 @@ class CodexAppServerClient {
|
|
|
421
592
|
}
|
|
422
593
|
logger.debug(`[CodexAppServer] Spawning: ${command} ${args.join(" ")}`);
|
|
423
594
|
const epoch = ++this.processEpoch;
|
|
424
|
-
const proc = spawn(command, args, {
|
|
595
|
+
const proc = spawn$1(command, args, {
|
|
425
596
|
stdio: ["pipe", "pipe", "pipe"],
|
|
426
597
|
env,
|
|
427
598
|
windowsHide: true
|
|
@@ -448,6 +619,7 @@ class CodexAppServerClient {
|
|
|
448
619
|
}
|
|
449
620
|
if (this.pendingTurnCompletion) {
|
|
450
621
|
const turnId = this.pendingTurnCompletion.turnId ?? this._turnId;
|
|
622
|
+
this.dropUnechoedSteers(null, true);
|
|
451
623
|
this.eventHandler?.({
|
|
452
624
|
type: "turn_aborted",
|
|
453
625
|
reason: "process-exit",
|
|
@@ -458,6 +630,9 @@ class CodexAppServerClient {
|
|
|
458
630
|
this.resolvePendingTurn(true);
|
|
459
631
|
});
|
|
460
632
|
this.stderrRing = "";
|
|
633
|
+
this.steerUnsupported = false;
|
|
634
|
+
this.steeredAwaitingEcho.clear();
|
|
635
|
+
this.childThreadLabels.clear();
|
|
461
636
|
proc.stderr?.on("data", (chunk) => {
|
|
462
637
|
if (this.process !== proc || this.processEpoch !== epoch) return;
|
|
463
638
|
const text = chunk.toString().trim();
|
|
@@ -496,20 +671,12 @@ ${text}`.slice(-400);
|
|
|
496
671
|
logger.debug(`[CodexAppServer] Disconnecting; pid=${pid ?? "none"}`);
|
|
497
672
|
this.readline?.close();
|
|
498
673
|
this.readline = null;
|
|
499
|
-
|
|
500
|
-
proc
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const killTimer = setTimeout(() => {
|
|
506
|
-
try {
|
|
507
|
-
process.kill(pid, 0);
|
|
508
|
-
process.kill(pid, "SIGKILL");
|
|
509
|
-
} catch {
|
|
510
|
-
}
|
|
511
|
-
}, 2e3);
|
|
512
|
-
killTimer.unref();
|
|
674
|
+
if (proc) {
|
|
675
|
+
stopCodexProcess(proc);
|
|
676
|
+
if (pid) {
|
|
677
|
+
const killTimer = setTimeout(() => killCodexProcessTree(proc), CodexAppServerClient.FORCE_KILL_AFTER_MS);
|
|
678
|
+
killTimer.unref();
|
|
679
|
+
}
|
|
513
680
|
}
|
|
514
681
|
this.process = null;
|
|
515
682
|
this.connected = false;
|
|
@@ -528,6 +695,7 @@ ${text}`.slice(-400);
|
|
|
528
695
|
req.reject(new Error(`Codex process disconnected while waiting for ${req.method}`));
|
|
529
696
|
this.pending.delete(id);
|
|
530
697
|
}
|
|
698
|
+
this.dropUnechoedSteers(null, true);
|
|
531
699
|
this.resolvePendingTurn(true);
|
|
532
700
|
if (this.sandboxCleanup) {
|
|
533
701
|
try {
|
|
@@ -731,6 +899,8 @@ ${text}`.slice(-400);
|
|
|
731
899
|
// ─── Turn management ────────────────────────────────────────
|
|
732
900
|
/** Default grace period after interrupt before forcing a restart (ms). */
|
|
733
901
|
static ABORT_GRACE_MS = 3e3;
|
|
902
|
+
/** How long the graceful stop gets before the process tree is killed (disconnectInternal). */
|
|
903
|
+
static FORCE_KILL_AFTER_MS = 2e3;
|
|
734
904
|
hasPendingTurnCompletion() {
|
|
735
905
|
return this.pendingTurnCompletion !== null;
|
|
736
906
|
}
|
|
@@ -740,6 +910,7 @@ ${text}`.slice(-400);
|
|
|
740
910
|
this.clearThreadStopGrace();
|
|
741
911
|
this.pendingTurnCompletion.resolve(aborted);
|
|
742
912
|
this.pendingTurnCompletion = null;
|
|
913
|
+
this.releaseTurnOpenWaiters();
|
|
743
914
|
}
|
|
744
915
|
markPendingTurnStarted(turnId) {
|
|
745
916
|
if (!this.pendingTurnCompletion) return;
|
|
@@ -747,6 +918,86 @@ ${text}`.slice(-400);
|
|
|
747
918
|
if (turnId) {
|
|
748
919
|
this.pendingTurnCompletion.turnId = turnId;
|
|
749
920
|
}
|
|
921
|
+
this.releaseTurnOpenWaiters();
|
|
922
|
+
}
|
|
923
|
+
// ─── B-628: steering the running turn ───────────────────────
|
|
924
|
+
/** How long a steer waits for the pending turn to open before the message is queued instead. */
|
|
925
|
+
static STEER_OPEN_WAIT_MS = 5e3;
|
|
926
|
+
/** A turn Codex has reported running, under an id `turn/steer` can name. */
|
|
927
|
+
turnIsOpen() {
|
|
928
|
+
return this.pendingTurnCompletion?.opened === true && this._turnId !== null;
|
|
929
|
+
}
|
|
930
|
+
releaseTurnOpenWaiters() {
|
|
931
|
+
const waiters = this.turnOpenWaiters;
|
|
932
|
+
this.turnOpenWaiters = [];
|
|
933
|
+
for (const release of waiters) release();
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Waits for the pending turn to open — `turn/start` is in flight, or the runner is still
|
|
937
|
+
* bringing a released app-server back before sending it (B-461) — as Orca's send does
|
|
938
|
+
* (codex-structured-turn-open-wait.ts, 5 s). Resolves early when the turn ends instead.
|
|
939
|
+
*/
|
|
940
|
+
async waitForTurnOpen(timeoutMs) {
|
|
941
|
+
if (this.turnIsOpen()) return true;
|
|
942
|
+
if (timeoutMs <= 0) return false;
|
|
943
|
+
await new Promise((resolve) => {
|
|
944
|
+
const release = () => {
|
|
945
|
+
clearTimeout(timer);
|
|
946
|
+
resolve();
|
|
947
|
+
};
|
|
948
|
+
const timer = setTimeout(release, timeoutMs);
|
|
949
|
+
timer.unref();
|
|
950
|
+
this.turnOpenWaiters.push(release);
|
|
951
|
+
});
|
|
952
|
+
return this.turnIsOpen();
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* B-628: send a message into the turn running right now (`turn/steer`, codex ≥ 0.148 /
|
|
956
|
+
* app-server-protocol v2 `TurnSteerParams`). Codex appends it to that turn's pending input
|
|
957
|
+
* and the model reads it before its next call; the turn keeps its own model, approval
|
|
958
|
+
* policy and sandbox — the runner applies any change on the next `turn/start`. Codex
|
|
959
|
+
* refuses before taking any input (expectedTurnId is a precondition), so a non-`steered`
|
|
960
|
+
* outcome always means "queue it for the next turn as before": `no-turn` (nothing running,
|
|
961
|
+
* or it ended while we waited), `unsupported` (this app-server has no `turn/steer`,
|
|
962
|
+
* remembered until it is respawned), `refused` (Codex declined this one), `failed`
|
|
963
|
+
* (transport — the turn itself is reported through its own events).
|
|
964
|
+
*/
|
|
965
|
+
async steerTurn(input, opts) {
|
|
966
|
+
if (this.steerUnsupported) return "unsupported";
|
|
967
|
+
if (this.pendingInterrupt) return "no-turn";
|
|
968
|
+
const opened = await this.waitForTurnOpen(opts?.waitForTurnMs ?? CodexAppServerClient.STEER_OPEN_WAIT_MS);
|
|
969
|
+
const threadId = this._threadId;
|
|
970
|
+
const turnId = this._turnId;
|
|
971
|
+
if (!opened || !threadId || !turnId || !this.connected || this.pendingInterrupt) return "no-turn";
|
|
972
|
+
const params = {
|
|
973
|
+
threadId,
|
|
974
|
+
expectedTurnId: turnId,
|
|
975
|
+
...input.clientId ? { clientUserMessageId: input.clientId } : {},
|
|
976
|
+
input: [
|
|
977
|
+
{ type: "text", text: input.text },
|
|
978
|
+
...(input.images ?? []).map((path) => ({ type: "localImage", path }))
|
|
979
|
+
]
|
|
980
|
+
};
|
|
981
|
+
try {
|
|
982
|
+
const result = await this.request("turn/steer", params);
|
|
983
|
+
const steeredTurnId = typeof result?.turnId === "string" && result.turnId.length > 0 ? result.turnId : turnId;
|
|
984
|
+
if (input.clientId) this.steeredAwaitingEcho.set(input.clientId, steeredTurnId);
|
|
985
|
+
logger.debug(`[CodexAppServer] Steered a message into turn ${steeredTurnId}`);
|
|
986
|
+
return "steered";
|
|
987
|
+
} catch (error) {
|
|
988
|
+
const code = jsonRpcErrorCodeOf(error);
|
|
989
|
+
if (code === -32601) {
|
|
990
|
+
this.steerUnsupported = true;
|
|
991
|
+
logger.debug("[CodexAppServer] turn/steer is not supported by this codex; queuing instead");
|
|
992
|
+
return "unsupported";
|
|
993
|
+
}
|
|
994
|
+
if (code !== null) {
|
|
995
|
+
logger.debug("[CodexAppServer] turn/steer refused:", errorLogMetadata(error));
|
|
996
|
+
return "refused";
|
|
997
|
+
}
|
|
998
|
+
logger.debug("[CodexAppServer] turn/steer failed:", errorLogMetadata(error));
|
|
999
|
+
return "failed";
|
|
1000
|
+
}
|
|
750
1001
|
}
|
|
751
1002
|
/** Default wait for Codex's `turn/completed` after its thread reported idle/systemError. */
|
|
752
1003
|
static THREAD_STOP_GRACE_MS = 1500;
|
|
@@ -909,6 +1160,7 @@ ${text}`.slice(-400);
|
|
|
909
1160
|
} catch (err) {
|
|
910
1161
|
this.clearTurnWatchdog();
|
|
911
1162
|
this.pendingTurnCompletion = null;
|
|
1163
|
+
this.releaseTurnOpenWaiters();
|
|
912
1164
|
throw err;
|
|
913
1165
|
}
|
|
914
1166
|
const aborted = await completion;
|
|
@@ -926,6 +1178,7 @@ ${text}`.slice(-400);
|
|
|
926
1178
|
}
|
|
927
1179
|
logger.warn(`[CodexAppServer] No notification from Codex for ${timeoutMs}ms \u2014 giving the turn up as aborted`);
|
|
928
1180
|
const turnId = this.pendingTurnCompletion.turnId ?? this._turnId;
|
|
1181
|
+
this.dropUnechoedSteers(turnId, true);
|
|
929
1182
|
this.eventHandler?.({
|
|
930
1183
|
type: "turn_aborted",
|
|
931
1184
|
reason: "timeout",
|
|
@@ -976,6 +1229,7 @@ ${text}`.slice(-400);
|
|
|
976
1229
|
logger.debug(
|
|
977
1230
|
`[CodexAppServer] Clearing thread state: thread=${this._threadId ?? "none"} turn=${this._turnId ?? "none"}`
|
|
978
1231
|
);
|
|
1232
|
+
this.dropUnechoedSteers(null, true);
|
|
979
1233
|
this.resolvePendingTurn(true);
|
|
980
1234
|
this._threadId = null;
|
|
981
1235
|
this._turnId = null;
|
|
@@ -984,6 +1238,7 @@ ${text}`.slice(-400);
|
|
|
984
1238
|
this.failedTurnIds.clear();
|
|
985
1239
|
this.lastTurnError = null;
|
|
986
1240
|
this.rawFileChangesByItemId.clear();
|
|
1241
|
+
this.childThreadLabels.clear();
|
|
987
1242
|
}
|
|
988
1243
|
// ─── JSON-RPC transport ─────────────────────────────────────
|
|
989
1244
|
/** Default timeout for RPC requests (ms). */
|
|
@@ -1064,7 +1319,9 @@ ${text}`.slice(-400);
|
|
|
1064
1319
|
}
|
|
1065
1320
|
this.pending.delete(msg.id);
|
|
1066
1321
|
if (msg.error) {
|
|
1067
|
-
|
|
1322
|
+
const error = new Error(`${pending.method}: ${msg.error.message} (code=${msg.error.code})`);
|
|
1323
|
+
if (typeof msg.error.code === "number") error.jsonRpcCode = msg.error.code;
|
|
1324
|
+
pending.reject(error);
|
|
1068
1325
|
} else {
|
|
1069
1326
|
pending.resolve(msg.result);
|
|
1070
1327
|
}
|