very-happy-cli 0.2.162 → 0.2.164
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--TmFHgRH.mjs → AcpBackend-B8l1ZePt.mjs} +3 -3
- package/dist/{AcpBackend-9asD_DL7.cjs → AcpBackend-CHDqSii9.cjs} +3 -3
- package/dist/{AcpSessionManager-BvIuBzoO.cjs → AcpSessionManager-9yN2iH4b.cjs} +1 -1
- package/dist/{AcpSessionManager-BSIBnWUb.mjs → AcpSessionManager-BQnDJvct.mjs} +1 -1
- package/dist/{BasePermissionHandler-D4B-NNu2.cjs → BasePermissionHandler-DGQYvBPg.cjs} +1 -1
- package/dist/{BasePermissionHandler-DUBySe0f.mjs → BasePermissionHandler-DgtAtJTV.mjs} +1 -1
- package/dist/{BaseReasoningProcessor-CqLl-ikP.cjs → BaseReasoningProcessor-BqalZhQO.cjs} +1 -1
- package/dist/{BaseReasoningProcessor-9TybUGTq.mjs → BaseReasoningProcessor-Dfacnfhj.mjs} +1 -1
- package/dist/{agentHome-DQrq_FG1.mjs → agentHome-DM0urHEI.mjs} +4 -4
- package/dist/{agentHome-BohNUYnE.cjs → agentHome-DtsPKfTS.cjs} +4 -4
- package/dist/{api-CQnLOqRS.cjs → api-EKlS0r1w.cjs} +57 -15
- package/dist/{api-D57dsd6_.mjs → api-Yoh_zKdR.mjs} +57 -15
- package/dist/{apiMachine-fFFaWxYy.cjs → apiMachine-q71suojS.cjs} +20 -17
- package/dist/{apiMachine-78Aqzg--.mjs → apiMachine-s3HiV-SL.mjs} +20 -17
- package/dist/{assistantTools-mEz6uNqL.mjs → assistantTools-BWfAV349.mjs} +6 -6
- package/dist/{assistantTools-CwESq24n.cjs → assistantTools-D3cZvgUX.cjs} +6 -6
- package/dist/{attachmentContent-s1xPha4Q.mjs → attachmentContent-BLyyo1al.mjs} +2 -2
- package/dist/{attachmentContent-GHOk6Muq.cjs → attachmentContent-Bakb0XV3.cjs} +2 -2
- package/dist/{attachmentLimits-D5pgmASK.mjs → attachmentLimits-B8nzhw-i.mjs} +1 -1
- package/dist/{attachmentLimits-DzlBPyJP.cjs → attachmentLimits-eJZ4ZBjF.cjs} +1 -1
- package/dist/{auth-BOaHWquu.mjs → auth-BTfv8yW0.mjs} +8 -8
- package/dist/{auth-BbSdXMQ_.cjs → auth-Cn3dQInF.cjs} +5 -5
- package/dist/{auth-C8V7-oUT.mjs → auth-Cxhx5evk.mjs} +5 -5
- package/dist/{auth-B8EagV6G.cjs → auth-Hpg4Yxfa.cjs} +8 -8
- package/dist/{auto-CWDOX35m.mjs → auto-BAAEVGZa.mjs} +15 -14
- package/dist/{auto-Bw_h0yVc.cjs → auto-CK8irHum.cjs} +15 -14
- package/dist/{bootstrap-BKmsYSwh.mjs → bootstrap-CTNjn_aj.mjs} +2 -2
- package/dist/{bootstrap-DvZjEa9_.cjs → bootstrap-D9SUykG_.cjs} +2 -2
- package/dist/{browser-CBZj-1Wx.cjs → browser-C8ztaIkm.cjs} +1 -1
- package/dist/{browser-CrMAr5fI.mjs → browser-DydXWySF.mjs} +1 -1
- package/dist/{claudeLocal-dhdlcQ6F.mjs → claudeLocal-CdJJovWq.mjs} +5 -5
- package/dist/{claudeLocal-Bpw-u9et.cjs → claudeLocal-CsLFMvFU.cjs} +5 -5
- package/dist/{claudeLocalLauncher-BFfGT4eY.mjs → claudeLocalLauncher-CKazNnl0.mjs} +10 -10
- package/dist/{claudeLocalLauncher-DWFWuLhY.cjs → claudeLocalLauncher-DRc-tET5.cjs} +10 -10
- package/dist/{claudeSessionFork-D9-mANmu.cjs → claudeSessionFork-BWdhyy9B.cjs} +1 -1
- package/dist/{claudeSessionFork-_DUrXaqd.mjs → claudeSessionFork-BfPW9D2S.mjs} +1 -1
- package/dist/{client-CVQJWqjx.cjs → client-BZtKFCJr.cjs} +2 -2
- package/dist/{client-DiBTHWNU.cjs → client-C1GAIJ04.cjs} +3 -3
- package/dist/{client-DwqHDsLb.mjs → client-DkoV3VWl.mjs} +2 -2
- package/dist/{client-Dk7x-s-O.mjs → client-Do5CHQnZ.mjs} +3 -3
- package/dist/codex/happyMcpStdioBridge.cjs +15 -15
- package/dist/codex/happyMcpStdioBridge.mjs +15 -15
- package/dist/{codexAppServerClient-C2ybs2mZ.mjs → codexAppServerClient-CfF33X-8.mjs} +2 -2
- package/dist/{codexAppServerClient-DlKv5TjG.cjs → codexAppServerClient-JddkV_aP.cjs} +2 -2
- package/dist/{codexCommand-4vLE31fj.cjs → codexCommand-Bdj3XZbi.cjs} +43 -40
- package/dist/{codexCommand-DnmFr9Qx.mjs → codexCommand-btJso8yC.mjs} +43 -40
- package/dist/{config-Btd4B05_.cjs → config-DpCNivmg.cjs} +3 -3
- package/dist/{config-CSOG_ZcP.mjs → config-nziuMb7g.mjs} +3 -3
- package/dist/{configuration-A5gW_0GE.mjs → configuration-CiBUH72C.mjs} +1 -1
- package/dist/{configuration-UsI0sxEv.cjs → configuration-PXAE4-FP.cjs} +1 -1
- package/dist/{connect-C9yxp8Om.cjs → connect-D7ehaW2C.cjs} +13 -13
- package/dist/{connect-DWYj8LP_.mjs → connect-XHdi6Vtc.mjs} +13 -13
- package/dist/{context-BXnxalWW.mjs → context-BpEYcuLv.mjs} +1 -1
- package/dist/{context-0FjjA4vJ.cjs → context-DhvXl1oC.cjs} +1 -1
- package/dist/{controlClient-BXktrQ4z.cjs → controlClient-DI-Er-Ww.cjs} +3 -3
- package/dist/{controlClient-CYzHrh3e.mjs → controlClient-DzmCQrY_.mjs} +3 -3
- package/dist/{createSessionMetadata-Dyg33ZlU.mjs → createSessionMetadata-B47GrTX6.mjs} +2 -2
- package/dist/{createSessionMetadata-EX1eAlHx.cjs → createSessionMetadata-D04x6OMW.cjs} +2 -2
- package/dist/{deterministicJson-eha_oMZ2.cjs → deterministicJson-BM8e8QwP.cjs} +9 -9
- package/dist/{deterministicJson-DiR7EOMO.mjs → deterministicJson-CKqT3awl.mjs} +9 -9
- package/dist/{doctor-FuCvKdRa.mjs → doctor-CSgzbG5L.mjs} +6 -6
- package/dist/{doctor-DunLBgVi.cjs → doctor-Cl6cqvok.cjs} +6 -6
- package/dist/{ensureDaemonRunning-B4dZFmUy.cjs → ensureDaemonRunning-CJ4-U32n.cjs} +5 -5
- package/dist/{ensureDaemonRunning-EZkb-CAF.mjs → ensureDaemonRunning-fPVSsjIm.mjs} +5 -5
- package/dist/forkBackfill-8eLDeS73.cjs +66 -0
- package/dist/forkBackfill-DYIjlN1Z.mjs +62 -0
- package/dist/{handleResumeCommand-CsXendKb.mjs → handleResumeCommand-B84dt2aH.mjs} +5 -5
- package/dist/{handleResumeCommand-CKMIw4pE.cjs → handleResumeCommand-bX-aNF_z.cjs} +5 -5
- package/dist/{index-DRhWHEuW.cjs → index-B2UvSWo_.cjs} +3 -3
- package/dist/{index-BOhgL3rh.cjs → index-CP2fh7JX.cjs} +38 -38
- package/dist/{index-9L39wqYR.mjs → index-CRJtZCK-.mjs} +39 -39
- package/dist/{index-CvXcVQ06.mjs → index-CbF87SeZ.mjs} +3 -3
- package/dist/{index-CZWAiydF.cjs → index-DaTxsAC3.cjs} +4 -4
- package/dist/{index-DJ-oV52i.cjs → index-DqlyNgt4.cjs} +6 -1
- package/dist/{index-DK2JpTJf.mjs → index-OEGj3BxE.mjs} +4 -4
- package/dist/{index-BBg9j0XK.mjs → index-vVWpCoTr.mjs} +6 -1
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{install-B2duVo9a.mjs → install-CurvoW2u.mjs} +3 -3
- package/dist/{install-C8WyZI9K.cjs → install-__Mni4NU.cjs} +3 -3
- package/dist/lib.cjs +17 -17
- package/dist/lib.d.cts +47 -0
- package/dist/lib.d.mts +47 -0
- package/dist/lib.mjs +17 -17
- package/dist/{lidState-CigXWxhe.mjs → lidState-BbR6y9rq.mjs} +66 -2
- package/dist/{lidState-Ds-6ytZV.cjs → lidState-De2HP6nu.cjs} +67 -1
- package/dist/{localHappyAgentAuth-CaCyKzYp.mjs → localHappyAgentAuth-C7rDePjF.mjs} +1 -1
- package/dist/{localHappyAgentAuth-l0Na-5Ys.cjs → localHappyAgentAuth-CboZb3_a.cjs} +1 -1
- package/dist/{logger-CGE4C8ho.mjs → logger-8dtZPn3n.mjs} +2 -2
- package/dist/{logger-7ucWm9wp.cjs → logger-B1k7eZnq.cjs} +2 -2
- package/dist/{machineMetadata-ue1nkowa.mjs → machineMetadata-Bhp_w3-_.mjs} +3 -3
- package/dist/{machineMetadata-lMPtpF16.cjs → machineMetadata-C4OfKn6I.cjs} +3 -3
- package/dist/{main-3fIFXD-t.mjs → main-BQTaUrz0.mjs} +44 -44
- package/dist/{main-CFI0datL.cjs → main-eAiLspBM.cjs} +44 -44
- package/dist/{mcp-DARQBZ7l.mjs → mcp-DXCdbQHM.mjs} +14 -14
- package/dist/{mcp-DfxLAc1G.cjs → mcp-fapbM7Q4.cjs} +14 -14
- package/dist/{package-D1A-8ZJy.cjs → package-CC_txQ31.cjs} +8 -8
- package/dist/{package-DQsvY1XN.mjs → package-tVYgFJoK.mjs} +8 -8
- package/dist/{peerTools-D19hhSQF.mjs → peerTools-C1cduHh1.mjs} +4 -4
- package/dist/{peerTools-DLwNaEEV.cjs → peerTools-CqIcCEIg.cjs} +4 -4
- package/dist/{persistence-Cw8aLoyL.mjs → persistence-C_xFQLsD.mjs} +3 -3
- package/dist/{persistence-i0nQMLlk.cjs → persistence-d3ZyER6o.cjs} +3 -3
- package/dist/{piRunnerArgs-BUyxPxjZ.cjs → piRunnerArgs-DSxolPlV.cjs} +1 -1
- package/dist/{piRunnerArgs-58t454gw.mjs → piRunnerArgs-aq0zJX1Q.mjs} +1 -1
- package/dist/{piRuntime-DVPixFjl.mjs → piRuntime-BnNl5Lmb.mjs} +1 -1
- package/dist/{piRuntime-Dff73XCb.cjs → piRuntime-Dne1LPu-.cjs} +1 -1
- package/dist/{piTerminal-gHWFAyzq.mjs → piTerminal-CKWxWtW-.mjs} +16 -16
- package/dist/{piTerminal-Dz1RrO70.cjs → piTerminal-fjado4cR.cjs} +16 -16
- package/dist/{registerCommonHandlers-CMROPdJz.cjs → registerCommonHandlers-Dausbdsb.cjs} +2 -2
- package/dist/{registerCommonHandlers-Ckv5boQI.mjs → registerCommonHandlers-bSskMveZ.mjs} +2 -2
- package/dist/{registerKillSessionHandler-Cll4-o8Y.mjs → registerKillSessionHandler-Ben5lAsN.mjs} +6 -6
- package/dist/{registerKillSessionHandler-CA9-oelM.cjs → registerKillSessionHandler-CgKyzwqw.cjs} +6 -6
- package/dist/{remoteSessionClient-DX9jHLeW.cjs → remoteSessionClient-BkJt8SHa.cjs} +5 -5
- package/dist/{remoteSessionClient-BMjsbuBh.mjs → remoteSessionClient-DnCIuZpQ.mjs} +5 -5
- package/dist/{run-CjbGo2wb.cjs → run-B8dxbDsg.cjs} +33 -33
- package/dist/{run-CrunzDlt.mjs → run-BEYMVE4J.mjs} +32 -32
- package/dist/{runClaude-KN-4Y4LH.cjs → runClaude-Cy_HzLyO.cjs} +26 -23
- package/dist/{runClaude-WDBWRtnF.mjs → runClaude-Dd_P1c0f.mjs} +26 -23
- package/dist/{runClaudeDeps-QaEx8y5r.mjs → runClaudeDeps-JG7EUH7B.mjs} +441 -49
- package/dist/{runClaudeDeps-DW-8lnHv.cjs → runClaudeDeps-dxv910DR.cjs} +436 -44
- package/dist/{runGemini-Nf6SKBpw.mjs → runGemini-CpaBuvoW.mjs} +34 -34
- package/dist/{runGemini-Djmwjdv1.cjs → runGemini-DY1IDW_f.cjs} +34 -34
- package/dist/{runOpenClaw-CAqP5KFH.cjs → runOpenClaw-C0VARcYj.cjs} +20 -20
- package/dist/{runOpenClaw-9nHtmYbN.mjs → runOpenClaw-C7vrDQbq.mjs} +20 -20
- package/dist/{sandbox-C8Dd8GPM.cjs → sandbox-Bx9-M9rN.cjs} +4 -4
- package/dist/{sandbox-SP0THMt0.mjs → sandbox-DRUJZuaM.mjs} +4 -4
- package/dist/{selfCheck-D9ZXrK7h.cjs → selfCheck-Ba1sECTO.cjs} +34 -34
- package/dist/selfCheck-DdT8r263.mjs +84 -0
- package/dist/{send-DOx9aQsx.mjs → send-BrzkbMy2.mjs} +8 -8
- package/dist/{send-LPk6Q5HI.cjs → send-Dqdpx-w5.cjs} +8 -8
- package/dist/{server-BZNi8Hq_.mjs → server-CPMPoEAA.mjs} +4 -4
- package/dist/{server-CxT8jNyn.cjs → server-CfB8EWCg.cjs} +6 -6
- package/dist/{sessionLock-y9rnA4LK.cjs → sessionLock-BsP3Y_nG.cjs} +2 -2
- package/dist/{sessionLock-CfLqJfeI.mjs → sessionLock-DukLVzAQ.mjs} +2 -2
- package/dist/{sessionModeFile-BKxgNH3P.mjs → sessionModeFile-CSvi4H_t.mjs} +1 -1
- package/dist/{sessionModeFile-B5YeoQJh.cjs → sessionModeFile-JWWF6Nn7.cjs} +1 -1
- package/dist/{sessionOps-CdwVPSZz.mjs → sessionOps-BlMg1uAa.mjs} +5 -5
- package/dist/{sessionOps-GsELm2PZ.cjs → sessionOps-HuoMXcIZ.cjs} +4 -4
- package/dist/{sessionScanner-aLEv7mD3.cjs → sessionScanner-BWU6KvZw.cjs} +3 -3
- package/dist/{sessionScanner-Cdukzo70.mjs → sessionScanner-Ct-JoNHP.mjs} +3 -3
- package/dist/{sessions-Dne-OiRL.mjs → sessions-3Hw1xXMV.mjs} +9 -9
- package/dist/{sessions-CfG4WGN0.cjs → sessions-AjflCj5y.cjs} +9 -9
- package/dist/{setupOfflineReconnection-DiQma2Cc.mjs → setupOfflineReconnection-B_9xp36H.mjs} +2 -2
- package/dist/{setupOfflineReconnection-CFwltTcP.cjs → setupOfflineReconnection-Cxh9Sz9M.cjs} +2 -2
- package/dist/{spawn-DkgP2BGF.mjs → spawn-BXEVKCQK.mjs} +38 -18
- package/dist/{spawn-BI_sdgWs.cjs → spawn-CN8PH11G.cjs} +38 -17
- package/dist/{spawnAgents-Y1LjnCt9.mjs → spawnAgents-Czi2VDzj.mjs} +1 -1
- package/dist/{spawnAgents-iSu1Xzs5.cjs → spawnAgents-McixdtV1.cjs} +1 -1
- package/dist/{spawnHappyCLI-9mx4lPxh.mjs → spawnHappyCLI-BFN0h2fK.mjs} +1 -1
- package/dist/{spawnHappyCLI-BRdx0sAX.cjs → spawnHappyCLI-Cj-9-d_7.cjs} +1 -1
- package/dist/{startFileWatcher-C2HC2_Dg.cjs → startFileWatcher-BfMu444W.cjs} +1 -1
- package/dist/{startFileWatcher-COD5UKNs.mjs → startFileWatcher-Csql7gdv.mjs} +1 -1
- package/dist/{streamRelay-BLgU9X3R.mjs → streamRelay-BzMEEvJU.mjs} +1 -1
- package/dist/{streamRelay-DnObXZZj.cjs → streamRelay-C0AffuX6.cjs} +1 -1
- package/dist/{sync-Dj92ZJ8Y.cjs → sync--uxtLWbo.cjs} +5 -1
- package/dist/{sync-BpLasLu2.mjs → sync-SCvDzRy6.mjs} +5 -1
- package/dist/{systemPrompt-CyEz_IfR.cjs → systemPrompt-C1tRiZ-u.cjs} +2 -2
- package/dist/{systemPrompt-DsQoUgQw.mjs → systemPrompt-D0KMySrK.mjs} +2 -2
- package/dist/{teams-BETNMjpZ.mjs → teams-By-hcvMF.mjs} +6 -6
- package/dist/{teams-Ctx9zXn4.cjs → teams-CYDIFXEC.cjs} +6 -6
- package/dist/{time-CLwVAz6s.cjs → time-C7BplxuS.cjs} +1 -1
- package/dist/{time-CVvxdEDh.mjs → time-CRvAaC5H.mjs} +1 -1
- package/dist/{titleGenerator-B4AW3dLr.mjs → titleGenerator-CUG-n2r3.mjs} +1 -1
- package/dist/{titleGenerator-FDpdizn7.cjs → titleGenerator-Kw3sTnNQ.cjs} +2 -2
- package/dist/{todo-C3tyFeq1.cjs → todo-B7a7J5Ng.cjs} +6 -6
- package/dist/{todo-Jk4Vs7hP.mjs → todo-yuIsUvU8.mjs} +6 -6
- package/dist/{tools-CGxq3I52.cjs → tools-BTBgpiRc.cjs} +2 -2
- package/dist/{tools-O5beDK-s.cjs → tools-D7UeLMZ7.cjs} +1 -1
- package/dist/{tools-_kFe4m_l.mjs → tools-RvMKw7yx.mjs} +1 -1
- package/dist/{tools-BA1qkiV1.mjs → tools-gUjkPpCw.mjs} +2 -2
- package/dist/{uninstall-DHKF90lo.cjs → uninstall-D5D16-KM.cjs} +3 -3
- package/dist/{uninstall-C_mdAZlm.mjs → uninstall-Dx9FmLXs.mjs} +3 -3
- package/package.json +8 -8
- package/dist/selfCheck-7FaZtVu2.mjs +0 -84
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var logger = require('./logger-
|
|
4
|
-
var controlClient = require('./controlClient-
|
|
3
|
+
var logger = require('./logger-B1k7eZnq.cjs');
|
|
4
|
+
var controlClient = require('./controlClient-DI-Er-Ww.cjs');
|
|
5
5
|
var backgroundTaskActivity = require('./backgroundTaskActivity-CBvUdj39.cjs');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
var messageBuffer = require('./messageBuffer-fJMH6uY8.cjs');
|
|
8
8
|
var index = require('./index-D3kI0hDR.cjs');
|
|
9
9
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
10
10
|
var permissionMode = require('./permissionMode-CrV-XuMs.cjs');
|
|
11
|
-
var systemPrompt = require('./systemPrompt-
|
|
11
|
+
var systemPrompt = require('./systemPrompt-C1tRiZ-u.cjs');
|
|
12
12
|
var path$1 = require('node:path');
|
|
13
13
|
var specialCommands = require('./specialCommands-DSsTeRej.cjs');
|
|
14
14
|
require('axios');
|
|
15
15
|
require('node:events');
|
|
16
16
|
require('socket.io-client');
|
|
17
|
-
var attachmentLimits = require('./attachmentLimits-
|
|
17
|
+
var attachmentLimits = require('./attachmentLimits-eJZ4ZBjF.cjs');
|
|
18
18
|
require('tweetnacl');
|
|
19
|
-
var configuration = require('./configuration-
|
|
20
|
-
require('./index-
|
|
21
|
-
require('./registerCommonHandlers-
|
|
19
|
+
var configuration = require('./configuration-PXAE4-FP.cjs');
|
|
20
|
+
require('./index-DqlyNgt4.cjs');
|
|
21
|
+
require('./registerCommonHandlers-Dausbdsb.cjs');
|
|
22
22
|
require('os');
|
|
23
23
|
require('child_process');
|
|
24
24
|
require('@paralleldrive/cuid2');
|
|
25
|
-
require('./persistence-
|
|
25
|
+
require('./persistence-d3ZyER6o.cjs');
|
|
26
26
|
var contentLogMetadata = require('./contentLogMetadata-ZSFk_NjQ.cjs');
|
|
27
27
|
require('chalk');
|
|
28
28
|
var types = require('./types-CRS-srZK.cjs');
|
|
29
29
|
var path = require('./path-B7zW-WwE.cjs');
|
|
30
30
|
var fs = require('fs/promises');
|
|
31
|
-
var time = require('./time-
|
|
31
|
+
var time = require('./time-C7BplxuS.cjs');
|
|
32
32
|
var node_fs = require('node:fs');
|
|
33
|
-
var deterministicJson = require('./deterministicJson-
|
|
34
|
-
var sessionScanner = require('./sessionScanner-
|
|
33
|
+
var deterministicJson = require('./deterministicJson-BM8e8QwP.cjs');
|
|
34
|
+
var sessionScanner = require('./sessionScanner-BWU6KvZw.cjs');
|
|
35
35
|
var node_child_process = require('node:child_process');
|
|
36
|
-
var streamRelay = require('./streamRelay-
|
|
37
|
-
var attachmentContent = require('./attachmentContent-
|
|
36
|
+
var streamRelay = require('./streamRelay-C0AffuX6.cjs');
|
|
37
|
+
var attachmentContent = require('./attachmentContent-Bakb0XV3.cjs');
|
|
38
38
|
var promises = require('node:fs/promises');
|
|
39
|
-
var claudeSessionFork = require('./claudeSessionFork-
|
|
40
|
-
var registerKillSessionHandler = require('./registerKillSessionHandler-
|
|
41
|
-
var doctor = require('./doctor-
|
|
39
|
+
var claudeSessionFork = require('./claudeSessionFork-BWdhyy9B.cjs');
|
|
40
|
+
var registerKillSessionHandler = require('./registerKillSessionHandler-CgKyzwqw.cjs');
|
|
41
|
+
var doctor = require('./doctor-Cl6cqvok.cjs');
|
|
42
42
|
var node_http = require('node:http');
|
|
43
43
|
var editPaths = require('./editPaths-Bqp4OFPw.cjs');
|
|
44
44
|
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
45
|
-
var titleGenerator = require('./titleGenerator-
|
|
45
|
+
var titleGenerator = require('./titleGenerator-Kw3sTnNQ.cjs');
|
|
46
46
|
var oneShotPrompts = require('./oneShotPrompts-CL0dip9C.cjs');
|
|
47
47
|
require('node:util');
|
|
48
48
|
require('./smallFastModel-D_uxGMo3.cjs');
|
|
@@ -50,33 +50,33 @@ require('./trimIdent-4gvk9Wk6.cjs');
|
|
|
50
50
|
require('node:os');
|
|
51
51
|
require('./agentGuidance-B5NATuFa.cjs');
|
|
52
52
|
require('zod');
|
|
53
|
-
require('./package-
|
|
53
|
+
require('./package-CC_txQ31.cjs');
|
|
54
54
|
require('util');
|
|
55
55
|
require('crypto');
|
|
56
56
|
require('path');
|
|
57
57
|
require('cross-spawn');
|
|
58
58
|
require('./authRelay-BdYkC1Po.cjs');
|
|
59
|
-
require('./client-
|
|
60
|
-
require('./context-
|
|
61
|
-
require('./sessionOps-
|
|
59
|
+
require('./client-C1GAIJ04.cjs');
|
|
60
|
+
require('./context-DhvXl1oC.cjs');
|
|
61
|
+
require('./sessionOps-HuoMXcIZ.cjs');
|
|
62
62
|
require('./resources-JDPugcDq.cjs');
|
|
63
|
-
require('./tools-
|
|
64
|
-
require('./tools-
|
|
65
|
-
require('./client-
|
|
66
|
-
require('./peerTools-
|
|
63
|
+
require('./tools-D7UeLMZ7.cjs');
|
|
64
|
+
require('./tools-BTBgpiRc.cjs');
|
|
65
|
+
require('./client-BZtKFCJr.cjs');
|
|
66
|
+
require('./peerTools-CqIcCEIg.cjs');
|
|
67
67
|
require('./ids-B6ZC0HGt.cjs');
|
|
68
|
-
require('./remoteSessionClient-
|
|
68
|
+
require('./remoteSessionClient-BkJt8SHa.cjs');
|
|
69
69
|
require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
70
70
|
require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
71
71
|
require('./limits-C-a7gr04.cjs');
|
|
72
|
-
require('./assistantTools-
|
|
72
|
+
require('./assistantTools-D3cZvgUX.cjs');
|
|
73
73
|
require('./terminals-B_bfC9c2.cjs');
|
|
74
74
|
require('./terminalTitleSuggest-DhvRFX3H.cjs');
|
|
75
75
|
require('./tmuxSocket-D-Xt6Vn-.cjs');
|
|
76
|
-
require('./bootstrap-
|
|
76
|
+
require('./bootstrap-D9SUykG_.cjs');
|
|
77
77
|
require('./previewPath-B0rBdhy1.cjs');
|
|
78
|
-
require('./sync
|
|
79
|
-
require('./startFileWatcher-
|
|
78
|
+
require('./sync--uxtLWbo.cjs');
|
|
79
|
+
require('./startFileWatcher-BfMu444W.cjs');
|
|
80
80
|
require('node:readline');
|
|
81
81
|
require('./doctor-u46qYYKX.cjs');
|
|
82
82
|
require('ps-list');
|
|
@@ -2891,16 +2891,55 @@ function rewindTranscriptLines(lines, action, target) {
|
|
|
2891
2891
|
});
|
|
2892
2892
|
return [...before.map((entry) => entry.line), ...relinked];
|
|
2893
2893
|
}
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2894
|
+
function transcriptSourceId(lines, claudeSessionId) {
|
|
2895
|
+
let source = null;
|
|
2896
|
+
for (const line of lines) {
|
|
2897
|
+
if (!line || !line.includes('"sessionId"')) continue;
|
|
2898
|
+
let parsed;
|
|
2899
|
+
try {
|
|
2900
|
+
parsed = JSON.parse(line);
|
|
2901
|
+
} catch {
|
|
2902
|
+
continue;
|
|
2903
|
+
}
|
|
2904
|
+
if (typeof parsed?.sessionId === "string" && parsed.sessionId && parsed.sessionId !== claudeSessionId) source = parsed.sessionId;
|
|
2905
|
+
}
|
|
2906
|
+
return source;
|
|
2907
|
+
}
|
|
2908
|
+
const MAX_LINEAGE_DEPTH = 4;
|
|
2909
|
+
async function readTranscriptLines(projectDir, claudeSessionId) {
|
|
2910
|
+
const path = path$1.join(projectDir, `${claudeSessionId}.jsonl`);
|
|
2897
2911
|
try {
|
|
2898
|
-
|
|
2912
|
+
return (await promises.readFile(path, "utf-8")).split("\n");
|
|
2899
2913
|
} catch (error) {
|
|
2900
|
-
if (error.code === "ENOENT") throw new claudeSessionFork.ForkSourceMissingError(
|
|
2914
|
+
if (error.code === "ENOENT") throw new claudeSessionFork.ForkSourceMissingError(path);
|
|
2901
2915
|
throw error;
|
|
2902
2916
|
}
|
|
2903
|
-
|
|
2917
|
+
}
|
|
2918
|
+
async function rewindAcrossLineage(load, claudeSessionId, action, target) {
|
|
2919
|
+
let id = claudeSessionId;
|
|
2920
|
+
let lines = await load(id);
|
|
2921
|
+
if (!lines) throw new claudeSessionFork.ForkSourceMissingError(id);
|
|
2922
|
+
for (let depth = 0; ; depth++) {
|
|
2923
|
+
try {
|
|
2924
|
+
return { kept: rewindTranscriptLines(lines, action, target), from: id };
|
|
2925
|
+
} catch (error) {
|
|
2926
|
+
if (!(error instanceof ConversationRewindError) || error.code !== "not-found" || depth >= MAX_LINEAGE_DEPTH) throw error;
|
|
2927
|
+
const source = transcriptSourceId(lines, id);
|
|
2928
|
+
const sourceLines = source ? await load(source) : null;
|
|
2929
|
+
if (!source || !sourceLines) throw error;
|
|
2930
|
+
id = source;
|
|
2931
|
+
lines = sourceLines;
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
async function rewindClaudeTranscript(projectDir, claudeSessionId, action, target) {
|
|
2936
|
+
const { kept } = await rewindAcrossLineage(async (id) => {
|
|
2937
|
+
if (id === claudeSessionId) return readTranscriptLines(projectDir, id);
|
|
2938
|
+
return readTranscriptLines(projectDir, id).catch((error) => {
|
|
2939
|
+
if (error instanceof claudeSessionFork.ForkSourceMissingError) return null;
|
|
2940
|
+
throw error;
|
|
2941
|
+
});
|
|
2942
|
+
}, claudeSessionId, action, target);
|
|
2904
2943
|
if (kept === null) return null;
|
|
2905
2944
|
const newId = node_crypto.randomUUID();
|
|
2906
2945
|
const destination = path$1.join(projectDir, `${newId}.jsonl`);
|
|
@@ -2915,6 +2954,7 @@ async function rewindClaudeTranscript(projectDir, claudeSessionId, action, targe
|
|
|
2915
2954
|
return newId;
|
|
2916
2955
|
}
|
|
2917
2956
|
|
|
2957
|
+
const REQUEST_ID = /^[A-Za-z0-9_-]{1,100}$/;
|
|
2918
2958
|
const STOP_WAIT_MS = 8e3;
|
|
2919
2959
|
function createConversationRewind(deps) {
|
|
2920
2960
|
let inFlight = false;
|
|
@@ -2924,6 +2964,7 @@ function createConversationRewind(deps) {
|
|
|
2924
2964
|
const action = request.action;
|
|
2925
2965
|
const sourceId = typeof request.sourceId === "string" && request.sourceId.length > 0 && request.sourceId.length <= 200 ? request.sourceId : void 0;
|
|
2926
2966
|
const text = typeof request.text === "string" && request.text.length <= 2e5 ? request.text : void 0;
|
|
2967
|
+
const requestId = typeof request.requestId === "string" && REQUEST_ID.test(request.requestId) ? request.requestId : void 0;
|
|
2927
2968
|
if (action !== "edit" && action !== "delete" || !sourceId && !text?.trim()) {
|
|
2928
2969
|
return { ok: false, code: "invalid", error: "Invalid rewind request" };
|
|
2929
2970
|
}
|
|
@@ -2940,7 +2981,9 @@ function createConversationRewind(deps) {
|
|
|
2940
2981
|
if (!current) return { ok: false, code: "no-conversation", error: "The agent has no conversation to change yet" };
|
|
2941
2982
|
const uuids = sourceId ? [sourceId, ...deps.aliases(sourceId)] : [];
|
|
2942
2983
|
const next = await rewrite(deps.projectDir(), current, action, { uuids, text });
|
|
2984
|
+
const recorded = requestId && deps.beginPending ? deps.beginPending({ requestId, action, sourceClaudeSessionId: current, claudeSessionId: next, at: (deps.now ?? Date.now)() }) : null;
|
|
2943
2985
|
await deps.switchConversation(next);
|
|
2986
|
+
if (recorded) await recorded;
|
|
2944
2987
|
return { ok: true, action, freshConversation: next === null };
|
|
2945
2988
|
} catch (error) {
|
|
2946
2989
|
if (error instanceof ConversationRewindError) return { ok: false, code: error.code, error: error.message };
|
|
@@ -2952,7 +2995,326 @@ function createConversationRewind(deps) {
|
|
|
2952
2995
|
};
|
|
2953
2996
|
}
|
|
2954
2997
|
|
|
2998
|
+
const REWIND_CONFIRM_MS = 12e4;
|
|
2999
|
+
function parseRewindRecord(raw) {
|
|
3000
|
+
if (!raw || typeof raw !== "object") return null;
|
|
3001
|
+
const r = raw;
|
|
3002
|
+
if (typeof r.requestId !== "string" || !r.requestId) return null;
|
|
3003
|
+
if (r.action !== "edit" && r.action !== "delete") return null;
|
|
3004
|
+
if (typeof r.sourceClaudeSessionId !== "string" || !r.sourceClaudeSessionId) return null;
|
|
3005
|
+
if (r.claudeSessionId !== null && typeof r.claudeSessionId !== "string") return null;
|
|
3006
|
+
if (typeof r.at !== "number" || !Number.isFinite(r.at)) return null;
|
|
3007
|
+
if (typeof r.state !== "string") return null;
|
|
3008
|
+
return {
|
|
3009
|
+
requestId: r.requestId,
|
|
3010
|
+
action: r.action,
|
|
3011
|
+
sourceClaudeSessionId: r.sourceClaudeSessionId,
|
|
3012
|
+
claudeSessionId: r.claudeSessionId,
|
|
3013
|
+
at: r.at,
|
|
3014
|
+
state: r.state
|
|
3015
|
+
};
|
|
3016
|
+
}
|
|
3017
|
+
function pendingResumeId(claudeArgs) {
|
|
3018
|
+
if (!claudeArgs) return null;
|
|
3019
|
+
const index = claudeArgs.indexOf("--resume");
|
|
3020
|
+
const next = index >= 0 ? claudeArgs[index + 1] : void 0;
|
|
3021
|
+
return next && !next.startsWith("-") && next.includes("-") ? next : null;
|
|
3022
|
+
}
|
|
3023
|
+
function decideRewind(record, confirmedRequestIds, now, currentClaudeSessionId) {
|
|
3024
|
+
if (!record || record.state !== "pending") return { kind: "none" };
|
|
3025
|
+
if (confirmedRequestIds.has(record.requestId)) return { kind: "confirm" };
|
|
3026
|
+
const deadline = record.at + REWIND_CONFIRM_MS;
|
|
3027
|
+
if (now < deadline) return { kind: "wait", ms: deadline - now };
|
|
3028
|
+
if (currentClaudeSessionId !== record.claudeSessionId) return { kind: "supersede" };
|
|
3029
|
+
return { kind: "revert", to: record.sourceClaudeSessionId };
|
|
3030
|
+
}
|
|
3031
|
+
function chainRewindRecord(next, pending) {
|
|
3032
|
+
if (!pending || pending.state !== "pending") return next;
|
|
3033
|
+
return { ...next, sourceClaudeSessionId: pending.sourceClaudeSessionId };
|
|
3034
|
+
}
|
|
3035
|
+
function transcriptDropOf(body) {
|
|
3036
|
+
const b = body;
|
|
3037
|
+
if (b?.role !== "session" || b.content?.type !== "session") return null;
|
|
3038
|
+
const ev = b.content.data?.ev;
|
|
3039
|
+
if (ev?.t !== "transcript-drop" || typeof ev.fromSeq !== "number") return null;
|
|
3040
|
+
return {
|
|
3041
|
+
fromSeq: ev.fromSeq,
|
|
3042
|
+
...typeof ev.toSeq === "number" ? { toSeq: ev.toSeq } : {},
|
|
3043
|
+
...typeof ev.requestId === "string" && ev.requestId ? { requestId: ev.requestId } : {}
|
|
3044
|
+
};
|
|
3045
|
+
}
|
|
3046
|
+
function tombstoneRequestIds(records) {
|
|
3047
|
+
const ids = /* @__PURE__ */ new Set();
|
|
3048
|
+
for (const record of records) {
|
|
3049
|
+
const drop = transcriptDropOf(record.body);
|
|
3050
|
+
if (drop?.requestId) ids.add(drop.requestId);
|
|
3051
|
+
}
|
|
3052
|
+
return ids;
|
|
3053
|
+
}
|
|
3054
|
+
function visibleUserLocalIds(records) {
|
|
3055
|
+
const drops = [];
|
|
3056
|
+
for (const record of records) {
|
|
3057
|
+
const drop = transcriptDropOf(record.body);
|
|
3058
|
+
if (drop) drops.push({ seq: record.seq, ...drop });
|
|
3059
|
+
}
|
|
3060
|
+
const hidden = (seq) => drops.some((drop) => seq >= drop.fromSeq && seq < (drop.toSeq ?? drop.seq));
|
|
3061
|
+
return records.filter((record) => record.body?.role === "user" && typeof record.localId === "string" && record.localId).filter((record) => !hidden(record.seq)).map((record) => record.localId);
|
|
3062
|
+
}
|
|
3063
|
+
function transcriptLineage(lines, claudeSessionId) {
|
|
3064
|
+
const promptUuids = /* @__PURE__ */ new Set();
|
|
3065
|
+
for (const line of lines) {
|
|
3066
|
+
if (!line) continue;
|
|
3067
|
+
let parsed;
|
|
3068
|
+
try {
|
|
3069
|
+
parsed = JSON.parse(line);
|
|
3070
|
+
} catch {
|
|
3071
|
+
continue;
|
|
3072
|
+
}
|
|
3073
|
+
if (typeof parsed?.uuid === "string" && transcriptPromptText(parsed) !== null) promptUuids.add(parsed.uuid);
|
|
3074
|
+
}
|
|
3075
|
+
return { promptUuids, sourceClaudeSessionId: transcriptSourceId(lines, claudeSessionId) };
|
|
3076
|
+
}
|
|
3077
|
+
function decideLineageRepair(input) {
|
|
3078
|
+
if (!input.source) return { kind: "none" };
|
|
3079
|
+
const missing = input.visibleLocalIds.filter((id) => !input.current.promptUuids.has(id) && input.source.promptUuids.has(id));
|
|
3080
|
+
if (missing.length === 0) return { kind: "none" };
|
|
3081
|
+
const onlyInCurrent = input.visibleLocalIds.filter((id) => input.current.promptUuids.has(id) && !input.source.promptUuids.has(id));
|
|
3082
|
+
return { kind: "revert", to: input.source.claudeSessionId, missing, onlyInCurrent };
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
const REWIND_POLL_MS = 15e3;
|
|
3086
|
+
class RewindReconciler {
|
|
3087
|
+
constructor(deps) {
|
|
3088
|
+
this.deps = deps;
|
|
3089
|
+
}
|
|
3090
|
+
pending = null;
|
|
3091
|
+
/** The last rewind this process rolled back — a late tombstone re-applies it. */
|
|
3092
|
+
lastReverted = null;
|
|
3093
|
+
confirmedIds = /* @__PURE__ */ new Set();
|
|
3094
|
+
waiters = [];
|
|
3095
|
+
timer = null;
|
|
3096
|
+
checking = null;
|
|
3097
|
+
disposed = false;
|
|
3098
|
+
get pendingRecord() {
|
|
3099
|
+
return this.pending;
|
|
3100
|
+
}
|
|
3101
|
+
/** Synchronously marks the rewind pending; the returned promise is the metadata write. */
|
|
3102
|
+
begin(record) {
|
|
3103
|
+
const next = chainRewindRecord({ ...record, state: "pending" }, this.pending);
|
|
3104
|
+
this.pending = next;
|
|
3105
|
+
this.arm(next);
|
|
3106
|
+
this.deps.log(`[rewind] pending ${next.requestId}: ${next.sourceClaudeSessionId} -> ${next.claudeSessionId ?? "(fresh)"}`);
|
|
3107
|
+
const written = this.deps.writeRecord(next);
|
|
3108
|
+
if (this.confirmedIds.has(next.requestId)) void this.apply(next, { kind: "confirm" });
|
|
3109
|
+
return written;
|
|
3110
|
+
}
|
|
3111
|
+
/** Every inbound session record. */
|
|
3112
|
+
observe(body) {
|
|
3113
|
+
const requestId = transcriptDropOf(body)?.requestId;
|
|
3114
|
+
if (!requestId) return;
|
|
3115
|
+
this.confirmedIds.add(requestId);
|
|
3116
|
+
const record = this.pending;
|
|
3117
|
+
if (record && record.requestId === requestId) {
|
|
3118
|
+
void this.apply(record, { kind: "confirm" });
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
void this.reapplyIfReverted(requestId);
|
|
3122
|
+
}
|
|
3123
|
+
/**
|
|
3124
|
+
* The web hides the turns only AFTER it saw our record, but its tombstone
|
|
3125
|
+
* may still land after the deadline (slow outbox). The log then says
|
|
3126
|
+
* "rewound": follow it, or screen and agent disagree again. Synchronous up
|
|
3127
|
+
* to the abort, so the edited prompt that follows the tombstone is not
|
|
3128
|
+
* dequeued by the old query.
|
|
3129
|
+
*/
|
|
3130
|
+
reapplyIfReverted(requestId) {
|
|
3131
|
+
const reverted = this.lastReverted;
|
|
3132
|
+
if (this.pending || reverted?.requestId !== requestId || this.deps.currentClaudeSessionId() !== reverted.sourceClaudeSessionId) {
|
|
3133
|
+
return Promise.resolve();
|
|
3134
|
+
}
|
|
3135
|
+
this.lastReverted = null;
|
|
3136
|
+
this.deps.log(`[rewind] late tombstone for reverted ${requestId}; re-applying the rewind`);
|
|
3137
|
+
return this.deps.switchConversation(reverted.claudeSessionId).then(() => this.deps.writeRecord({ ...reverted, state: "confirmed" })).catch((error) => this.deps.log("[rewind] re-applying failed", error));
|
|
3138
|
+
}
|
|
3139
|
+
/** Resolves when no rewind is pending (or `signal` aborts). */
|
|
3140
|
+
settled(signal) {
|
|
3141
|
+
if (!this.pending || signal?.aborted) return Promise.resolve();
|
|
3142
|
+
return new Promise((resolve) => {
|
|
3143
|
+
const done = () => {
|
|
3144
|
+
signal?.removeEventListener("abort", done);
|
|
3145
|
+
resolve();
|
|
3146
|
+
};
|
|
3147
|
+
this.waiters.push(done);
|
|
3148
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
check() {
|
|
3152
|
+
if (!this.checking) {
|
|
3153
|
+
this.checking = this.runCheck().finally(() => {
|
|
3154
|
+
this.checking = null;
|
|
3155
|
+
});
|
|
3156
|
+
}
|
|
3157
|
+
return this.checking;
|
|
3158
|
+
}
|
|
3159
|
+
/** Wrapper start / resume: decide a leftover pending record, else repair a legacy split. */
|
|
3160
|
+
async startup() {
|
|
3161
|
+
const record = parseRewindRecord(this.deps.readRecord());
|
|
3162
|
+
if (record?.state === "pending") {
|
|
3163
|
+
this.pending = chainRewindRecord(record, this.pending);
|
|
3164
|
+
this.deps.log(`[rewind] startup: pending record ${record.requestId} from ${new Date(record.at).toISOString()}`);
|
|
3165
|
+
await this.check();
|
|
3166
|
+
return;
|
|
3167
|
+
}
|
|
3168
|
+
if (record?.state === "reverted") {
|
|
3169
|
+
this.lastReverted = record;
|
|
3170
|
+
if (tombstoneRequestIds(await this.deps.readLog()).has(record.requestId)) {
|
|
3171
|
+
await this.reapplyIfReverted(record.requestId);
|
|
3172
|
+
return;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
await this.repairLineage();
|
|
3176
|
+
}
|
|
3177
|
+
dispose() {
|
|
3178
|
+
this.disposed = true;
|
|
3179
|
+
this.clearTimer();
|
|
3180
|
+
this.release();
|
|
3181
|
+
}
|
|
3182
|
+
arm(record, ms) {
|
|
3183
|
+
if (this.disposed) return;
|
|
3184
|
+
if (this.timer) clearTimeout(this.timer);
|
|
3185
|
+
const wait = ms ?? Math.min(REWIND_POLL_MS, Math.max(0, decideWaitMs(record, this.deps.now())));
|
|
3186
|
+
this.timer = setTimeout(() => {
|
|
3187
|
+
this.timer = null;
|
|
3188
|
+
void this.check().catch((error) => this.deps.log("[rewind] check failed", error));
|
|
3189
|
+
}, wait);
|
|
3190
|
+
this.timer.unref?.();
|
|
3191
|
+
}
|
|
3192
|
+
async runCheck() {
|
|
3193
|
+
const record = this.pending;
|
|
3194
|
+
if (!record) return;
|
|
3195
|
+
let decision = this.decide(record);
|
|
3196
|
+
if (decision.kind !== "confirm" && decision.kind !== "none") {
|
|
3197
|
+
try {
|
|
3198
|
+
for (const id of tombstoneRequestIds(await this.deps.readLog())) this.confirmedIds.add(id);
|
|
3199
|
+
} catch (error) {
|
|
3200
|
+
this.deps.log("[rewind] reading the session log failed; retrying", error);
|
|
3201
|
+
if (this.pending === record) this.arm(record, REWIND_POLL_MS);
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
if (this.pending !== record) return;
|
|
3205
|
+
decision = this.decide(record);
|
|
3206
|
+
}
|
|
3207
|
+
await this.apply(record, decision);
|
|
3208
|
+
}
|
|
3209
|
+
decide(record) {
|
|
3210
|
+
return decideRewind(record, this.confirmedIds, this.deps.now(), this.deps.currentClaudeSessionId());
|
|
3211
|
+
}
|
|
3212
|
+
async apply(record, decision) {
|
|
3213
|
+
if (this.pending !== record) return;
|
|
3214
|
+
switch (decision.kind) {
|
|
3215
|
+
case "none":
|
|
3216
|
+
this.pending = null;
|
|
3217
|
+
this.release();
|
|
3218
|
+
return;
|
|
3219
|
+
case "wait":
|
|
3220
|
+
this.arm(record);
|
|
3221
|
+
return;
|
|
3222
|
+
case "confirm":
|
|
3223
|
+
this.finish(record, "confirmed");
|
|
3224
|
+
return;
|
|
3225
|
+
case "supersede":
|
|
3226
|
+
this.deps.log(`[rewind] ${record.requestId} unconfirmed but the agent already moved on; closing it`);
|
|
3227
|
+
this.finish(record, "superseded");
|
|
3228
|
+
return;
|
|
3229
|
+
case "revert": {
|
|
3230
|
+
this.deps.log(`[rewind] ${record.requestId} never confirmed by the log; switching back to ${decision.to}`);
|
|
3231
|
+
this.pending = null;
|
|
3232
|
+
this.clearTimer();
|
|
3233
|
+
this.lastReverted = record;
|
|
3234
|
+
try {
|
|
3235
|
+
await this.deps.switchConversation(decision.to);
|
|
3236
|
+
} catch (error) {
|
|
3237
|
+
this.deps.log("[rewind] switching back failed; retrying", error);
|
|
3238
|
+
if (!this.pending && this.lastReverted === record) {
|
|
3239
|
+
this.lastReverted = null;
|
|
3240
|
+
this.pending = record;
|
|
3241
|
+
this.arm(record, REWIND_POLL_MS);
|
|
3242
|
+
}
|
|
3243
|
+
return;
|
|
3244
|
+
}
|
|
3245
|
+
if (this.lastReverted === record) this.record(record, "reverted");
|
|
3246
|
+
if (!this.pending) this.release();
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
finish(record, state) {
|
|
3252
|
+
if (this.pending !== record) return;
|
|
3253
|
+
this.pending = null;
|
|
3254
|
+
this.clearTimer();
|
|
3255
|
+
this.lastReverted = null;
|
|
3256
|
+
this.record(record, state);
|
|
3257
|
+
this.release();
|
|
3258
|
+
}
|
|
3259
|
+
record(record, state) {
|
|
3260
|
+
this.deps.log(`[rewind] ${record.requestId} ${state}`);
|
|
3261
|
+
void this.deps.writeRecord({ ...record, state }).catch((error) => this.deps.log("[rewind] recording state failed", error));
|
|
3262
|
+
}
|
|
3263
|
+
clearTimer() {
|
|
3264
|
+
if (this.timer) clearTimeout(this.timer);
|
|
3265
|
+
this.timer = null;
|
|
3266
|
+
}
|
|
3267
|
+
release() {
|
|
3268
|
+
const waiters = this.waiters;
|
|
3269
|
+
this.waiters = [];
|
|
3270
|
+
for (const resolve of waiters) resolve();
|
|
3271
|
+
}
|
|
3272
|
+
async repairLineage() {
|
|
3273
|
+
const current = this.deps.currentClaudeSessionId();
|
|
3274
|
+
if (!current) return;
|
|
3275
|
+
const lines = await this.deps.readTranscript(current);
|
|
3276
|
+
if (!lines) return;
|
|
3277
|
+
const lineage = transcriptLineage(lines, current);
|
|
3278
|
+
if (!lineage.sourceClaudeSessionId) return;
|
|
3279
|
+
const sourceLines = await this.deps.readTranscript(lineage.sourceClaudeSessionId);
|
|
3280
|
+
if (!sourceLines) return;
|
|
3281
|
+
const source = transcriptLineage(sourceLines, lineage.sourceClaudeSessionId);
|
|
3282
|
+
const repair = decideLineageRepair({
|
|
3283
|
+
visibleLocalIds: visibleUserLocalIds(await this.deps.readLog()),
|
|
3284
|
+
current: lineage,
|
|
3285
|
+
source: { claudeSessionId: lineage.sourceClaudeSessionId, promptUuids: source.promptUuids }
|
|
3286
|
+
});
|
|
3287
|
+
if (repair.kind === "none") return;
|
|
3288
|
+
if (this.pending || this.deps.currentClaudeSessionId() !== current) return;
|
|
3289
|
+
this.deps.log(`[rewind] startup: ${current} is an unconfirmed rewound copy (${repair.missing.length} visible prompt(s) only in ${repair.to}); switching back`, {
|
|
3290
|
+
missing: repair.missing,
|
|
3291
|
+
forgottenAfterSplit: repair.onlyInCurrent
|
|
3292
|
+
});
|
|
3293
|
+
await this.deps.switchConversation(repair.to);
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3296
|
+
function decideWaitMs(record, now) {
|
|
3297
|
+
const decision = decideRewind(record, /* @__PURE__ */ new Set(), now, record.claudeSessionId);
|
|
3298
|
+
return decision.kind === "wait" ? decision.ms : 0;
|
|
3299
|
+
}
|
|
3300
|
+
async function persistRewindRecord(client, record, opts = {}) {
|
|
3301
|
+
const owns = (raw) => {
|
|
3302
|
+
const existing = parseRewindRecord(raw);
|
|
3303
|
+
return record.state === "pending" || !existing || existing.requestId === record.requestId;
|
|
3304
|
+
};
|
|
3305
|
+
if (!owns(client.getMetadata()?.rewind)) return;
|
|
3306
|
+
client.updateMetadata((metadata) => owns(metadata?.rewind) ? { ...metadata, rewind: record } : metadata);
|
|
3307
|
+
const deadline = Date.now() + (opts.timeoutMs ?? 8e3);
|
|
3308
|
+
while (Date.now() < deadline) {
|
|
3309
|
+
const current = parseRewindRecord(client.getMetadata()?.rewind);
|
|
3310
|
+
if (current?.requestId === record.requestId && current.state === record.state) return;
|
|
3311
|
+
await new Promise((resolve) => setTimeout(resolve, opts.pollMs ?? 100));
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
|
|
2955
3315
|
const ABORT_INTERRUPT_GRACE_MS = 4e3;
|
|
3316
|
+
const REWIND_LOG_WINDOW = 500;
|
|
3317
|
+
const REWIND_STARTUP_BUDGET_MS = 15e3;
|
|
2956
3318
|
async function claudeRemoteLauncher(session, onPermissionModeChange, onEffectivePermissionMode, onPromptFinalized) {
|
|
2957
3319
|
logger.logger.debug("[claudeRemoteLauncher] Starting remote launcher");
|
|
2958
3320
|
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
@@ -3054,8 +3416,35 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3054
3416
|
return first;
|
|
3055
3417
|
};
|
|
3056
3418
|
let silentRelaunch = false;
|
|
3419
|
+
const agentConversationId = () => session.sessionId ?? pendingResumeId(session.claudeArgs);
|
|
3420
|
+
const switchConversation = async (claudeSessionId) => {
|
|
3421
|
+
if (claudeSessionId) session.onSessionFound(claudeSessionId);
|
|
3422
|
+
else session.clearSessionId();
|
|
3423
|
+
if (!abortController || abortController.signal.aborted) return;
|
|
3424
|
+
silentRelaunch = true;
|
|
3425
|
+
await abort();
|
|
3426
|
+
};
|
|
3427
|
+
const rewindReconciler = new RewindReconciler({
|
|
3428
|
+
now: Date.now,
|
|
3429
|
+
readRecord: () => session.client.getMetadata()?.rewind,
|
|
3430
|
+
writeRecord: (record) => persistRewindRecord(session.client, record),
|
|
3431
|
+
readLog: () => session.client.readLogTail(REWIND_LOG_WINDOW),
|
|
3432
|
+
currentClaudeSessionId: () => agentConversationId(),
|
|
3433
|
+
readTranscript: async (claudeSessionId) => {
|
|
3434
|
+
try {
|
|
3435
|
+
return (await promises.readFile(path$1.join(path.getProjectPath(session.path), `${claudeSessionId}.jsonl`), "utf-8")).split("\n");
|
|
3436
|
+
} catch (error) {
|
|
3437
|
+
if (error.code === "ENOENT") return null;
|
|
3438
|
+
throw error;
|
|
3439
|
+
}
|
|
3440
|
+
},
|
|
3441
|
+
switchConversation,
|
|
3442
|
+
log: (message, data) => logger.logger.debug(message, data)
|
|
3443
|
+
});
|
|
3444
|
+
const observeSessionRecord = (body) => rewindReconciler.observe(body);
|
|
3445
|
+
session.client.on("message", observeSessionRecord);
|
|
3057
3446
|
session.client.rpcHandlerManager.registerHandler("conversation-rewind", createConversationRewind({
|
|
3058
|
-
claudeSessionId: () =>
|
|
3447
|
+
claudeSessionId: () => agentConversationId(),
|
|
3059
3448
|
projectDir: () => path.getProjectPath(session.path),
|
|
3060
3449
|
isThinking: () => session.thinking,
|
|
3061
3450
|
stopTurn: doAbort,
|
|
@@ -3064,12 +3453,8 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3064
3453
|
const alias = promptAliases.get(sourceId);
|
|
3065
3454
|
return alias ? [alias] : [];
|
|
3066
3455
|
},
|
|
3067
|
-
switchConversation
|
|
3068
|
-
|
|
3069
|
-
else session.clearSessionId();
|
|
3070
|
-
silentRelaunch = true;
|
|
3071
|
-
await abort();
|
|
3072
|
-
}
|
|
3456
|
+
switchConversation,
|
|
3457
|
+
beginPending: (record) => rewindReconciler.begin(record)
|
|
3073
3458
|
}));
|
|
3074
3459
|
let livePermissionModeHandler = null;
|
|
3075
3460
|
let idlePermissionModeHandler = null;
|
|
@@ -3227,6 +3612,10 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3227
3612
|
try {
|
|
3228
3613
|
const modeGate = new LaunchModeGate(session.queue.modeHasher);
|
|
3229
3614
|
let previousSessionId = null;
|
|
3615
|
+
await Promise.race([
|
|
3616
|
+
rewindReconciler.startup().catch((error) => logger.logger.debug("[rewind] startup reconcile failed", error)),
|
|
3617
|
+
new Promise((resolve) => setTimeout(resolve, REWIND_STARTUP_BUDGET_MS).unref?.())
|
|
3618
|
+
]);
|
|
3230
3619
|
while (!exitReason) {
|
|
3231
3620
|
logger.logger.debug("[remote]: launch");
|
|
3232
3621
|
messageBuffer$1.addMessage("\u2550".repeat(40), "status");
|
|
@@ -3283,6 +3672,7 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3283
3672
|
if (typeof parked.message === "string") onPromptFinalized?.(parked.message);
|
|
3284
3673
|
return parked;
|
|
3285
3674
|
}
|
|
3675
|
+
await rewindReconciler.settled(controller.signal);
|
|
3286
3676
|
let msg = await session.queue.waitForMessagesAndGetAsString(controller.signal);
|
|
3287
3677
|
if (msg) {
|
|
3288
3678
|
if (modeGate.requiresRelaunch(msg.hash, msg.isolate)) {
|
|
@@ -3475,6 +3865,8 @@ async function claudeRemoteLauncher(session, onPermissionModeChange, onEffective
|
|
|
3475
3865
|
}
|
|
3476
3866
|
}
|
|
3477
3867
|
} finally {
|
|
3868
|
+
session.client.off("message", observeSessionRecord);
|
|
3869
|
+
rewindReconciler.dispose();
|
|
3478
3870
|
permissionHandler.reset();
|
|
3479
3871
|
const t0 = Date.now();
|
|
3480
3872
|
logger.logger.debug(`[remote]: cleanup begin exitReason=${exitReason} hasInk=${!!inkInstance} rawMode=${process.stdin.isRaw}`);
|
|
@@ -3524,7 +3916,7 @@ async function loop(opts) {
|
|
|
3524
3916
|
logger.logger.debug(`[loop] Iteration with mode: ${mode}`);
|
|
3525
3917
|
switch (mode) {
|
|
3526
3918
|
case "local": {
|
|
3527
|
-
const { claudeLocalLauncher } = await Promise.resolve().then(function () { return require('./claudeLocalLauncher-
|
|
3919
|
+
const { claudeLocalLauncher } = await Promise.resolve().then(function () { return require('./claudeLocalLauncher-DRc-tET5.cjs'); });
|
|
3528
3920
|
const result = await claudeLocalLauncher(session);
|
|
3529
3921
|
switch (result.type) {
|
|
3530
3922
|
case "switch":
|