very-happy-cli 0.2.165 → 0.2.167
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/README.md +1 -1
- package/dist/{AcpBackend-DCfNt9bD.cjs → AcpBackend-D1IKJGz_.cjs} +3 -3
- package/dist/{AcpBackend-C11FnVw5.mjs → AcpBackend-kFZlee5E.mjs} +3 -3
- package/dist/{AcpSessionManager-BQnDJvct.mjs → AcpSessionManager-B7FIrsys.mjs} +1 -1
- package/dist/{AcpSessionManager-9yN2iH4b.cjs → AcpSessionManager-Zf00QnlL.cjs} +1 -1
- package/dist/{BasePermissionHandler-BwQHxl6M.cjs → BasePermissionHandler-DHxYAK5L.cjs} +1 -1
- package/dist/{BasePermissionHandler-CwJ48yiB.mjs → BasePermissionHandler-DS0kRTNI.mjs} +1 -1
- package/dist/{BaseReasoningProcessor-ClF2g1qz.mjs → BaseReasoningProcessor-BRtCCt7q.mjs} +1 -1
- package/dist/{BaseReasoningProcessor-81lf_M8G.cjs → BaseReasoningProcessor-CsjVdt_H.cjs} +1 -1
- package/dist/{agentGuidance-CQuNlNx8.mjs → agentGuidance-BDYt2Qy2.mjs} +4 -2
- package/dist/{agentGuidance-B5NATuFa.cjs → agentGuidance-BtBx2xxE.cjs} +4 -1
- package/dist/{agentHome-DvR176E5.mjs → agentHome-Ct-VXFeG.mjs} +4 -4
- package/dist/{agentHome-D3Nn82kI.cjs → agentHome-DeAWzhSe.cjs} +4 -4
- package/dist/{api-AzdzTKFs.cjs → api-BZYLRDM9.cjs} +93 -13
- package/dist/{api-DTVPUE7g.mjs → api-CReZazeT.mjs} +93 -13
- package/dist/{apiMachine-B_cJldfa.cjs → apiMachine-BgMxGPsR.cjs} +2173 -66
- package/dist/{apiMachine-BQ-b4Lu3.mjs → apiMachine-CWndf1Vn.mjs} +2176 -69
- package/dist/{attachmentContent-muDCe4Gy.cjs → attachmentContent-HcJqFQW8.cjs} +2 -2
- package/dist/{attachmentContent-dzIs-wis.mjs → attachmentContent-j875mwU7.mjs} +2 -2
- package/dist/{attachmentLimits-eJZ4ZBjF.cjs → attachmentLimits-BEYEEBm8.cjs} +40 -2
- package/dist/{attachmentLimits-B8nzhw-i.mjs → attachmentLimits-CxG3T18E.mjs} +40 -2
- package/dist/{auth-Jtmvh1w4.mjs → auth-BIHuc7vY.mjs} +10 -10
- package/dist/{auth-BY5ujhGn.mjs → auth-CFS9Lfgv.mjs} +5 -5
- package/dist/{auth-DtP-B4gf.cjs → auth-Myr2Q42x.cjs} +10 -10
- package/dist/{auth-CfLd3phE.cjs → auth-VzWpbo5P.cjs} +5 -5
- package/dist/{auto-ClNnbSoF.cjs → auto-Bf6Dr7_o.cjs} +85 -21
- package/dist/{auto-DjWfR1UB.mjs → auto-Df9-zmuN.mjs} +84 -22
- package/dist/{bootstrap-D_ExGrY2.mjs → bootstrap-BSOxYpaP.mjs} +2 -2
- package/dist/{bootstrap-B1dMZA-u.cjs → bootstrap-Dj8WBiR2.cjs} +2 -2
- package/dist/{browser-mwzpOmcw.mjs → browser-BCFIHOvo.mjs} +1 -1
- package/dist/{browser-_gV7tcPs.cjs → browser-BoCV40yC.cjs} +1 -1
- package/dist/{claudeLocal-G5UmJ81F.cjs → claudeLocal-CGsq7Kul.cjs} +7 -7
- package/dist/{claudeLocal-BeHToEK5.mjs → claudeLocal-D5-eA9SC.mjs} +7 -7
- package/dist/{claudeLocalLauncher-Cq6bqAT4.mjs → claudeLocalLauncher-C9Cc438l.mjs} +15 -12
- package/dist/{claudeLocalLauncher-B4y2BsmO.cjs → claudeLocalLauncher-Cf9QeYDT.cjs} +15 -12
- package/dist/{claudeSessionFork-CDJq_b9r.cjs → claudeSessionFork-Byd8zD1U.cjs} +1 -1
- package/dist/{claudeSessionFork-CokUhS4r.mjs → claudeSessionFork-CMzAva8G.mjs} +1 -1
- package/dist/{client-Do7cGPEq.cjs → client-BKnKRLSt.cjs} +3 -3
- package/dist/{client-CJZKBZCE.mjs → client-C7FYMer0.mjs} +2 -2
- package/dist/{client-uN9d6Git.cjs → client-D0T5-6Ds.cjs} +2 -2
- package/dist/{client-BwaWdlCm.mjs → client-Dsfy_SAb.mjs} +3 -3
- package/dist/codex/happyMcpStdioBridge.cjs +23 -18
- package/dist/codex/happyMcpStdioBridge.mjs +22 -17
- package/dist/{codexAppServerClient-B0QaMQsC.mjs → codexAppServerClient-Dd_4TxHv.mjs} +48 -4
- package/dist/{codexAppServerClient-BuSdeUxT.cjs → codexAppServerClient-TiW9OBk4.cjs} +47 -3
- package/dist/{codexCommand-C3gdjMAw.mjs → codexCommand-BZSr4MKI.mjs} +170 -69
- package/dist/{codexCommand-YdYmykAR.cjs → codexCommand-Bxryqh90.cjs} +170 -69
- package/dist/{config-CGCIFRCN.mjs → config-C_Pj7yxV.mjs} +3 -3
- package/dist/{config-ChoHFnfO.cjs → config-DXPash-r.cjs} +3 -3
- package/dist/{configuration-BE61XNsg.cjs → configuration-C3piBtxY.cjs} +1 -1
- package/dist/{configuration-L1qcGTFM.mjs → configuration-WspKd2C2.mjs} +2 -2
- package/dist/{connect-D5IKfcfd.cjs → connect-BN-IBElA.cjs} +14 -14
- package/dist/{connect-CFD0Em6a.mjs → connect-DGPZs5px.mjs} +14 -14
- package/dist/{context-DaCCB4cm.mjs → context-Cr6a3NTg.mjs} +1 -1
- package/dist/{context-3WVw8qPz.cjs → context-Jrq4-eCZ.cjs} +1 -1
- package/dist/{controlClient-RWTlQA4_.cjs → controlClient-BI6Fw3fQ.cjs} +28 -5
- package/dist/{controlClient-Ci7HTMII.mjs → controlClient-DTheOlvC.mjs} +27 -6
- package/dist/{createSessionMetadata-CWR-AB2A.mjs → createSessionMetadata-BEZ4DIDA.mjs} +57 -5
- package/dist/{createSessionMetadata-CPGTztXP.cjs → createSessionMetadata-zQSz3hgk.cjs} +56 -3
- package/dist/defaultPermissionMode-Cif_RHGb.mjs +191 -0
- package/dist/defaultPermissionMode-DNKNzk7l.cjs +197 -0
- package/dist/{deterministicJson-BBwG-Ase.mjs → deterministicJson-BMMifViN.mjs} +36 -52
- package/dist/{deterministicJson-C4Jo2RWy.cjs → deterministicJson-C7O2ulKY.cjs} +41 -59
- package/dist/{doctor-ZOQLE5AH.cjs → doctor-BykBaMTr.cjs} +6 -6
- package/dist/{doctor-CAC6qY9Z.mjs → doctor-D1KKyPzB.mjs} +6 -6
- package/dist/{assistantTools-BsrG3PD-.cjs → downloadTarget-CWTb2-EM.cjs} +44 -6
- package/dist/{assistantTools-DPGga5lM.mjs → downloadTarget-Cp48jrIP.mjs} +45 -8
- package/dist/{ensureDaemonRunning-b1pvEFcS.mjs → ensureDaemonRunning-Ba5fYoxb.mjs} +5 -5
- package/dist/{ensureDaemonRunning-mIgX2vnc.cjs → ensureDaemonRunning-CCxX7MoP.cjs} +5 -5
- package/dist/{handleResumeCommand-CTGbZkCL.mjs → handleResumeCommand-BTUGlNjB.mjs} +5 -5
- package/dist/{handleResumeCommand-DGNhbv-3.cjs → handleResumeCommand-yPdDQHqz.cjs} +5 -5
- package/dist/{index-vVWpCoTr.mjs → index-B0HEEYGh.mjs} +22 -5
- package/dist/{index-BzIxE0Eu.cjs → index-BjhKqDa0.cjs} +3 -3
- package/dist/{index-BgzjPv07.mjs → index-C3_83bqS.mjs} +3 -3
- package/dist/{index-DqlyNgt4.cjs → index-C9hI8a10.cjs} +26 -4
- package/dist/{index-DjtBengz.mjs → index-CE2GgPbr.mjs} +40 -39
- package/dist/{index-Diu6HdWH.mjs → index-D8m8Ripb.mjs} +4 -4
- package/dist/{index-DrSPR59N.cjs → index-DifM62wX.cjs} +39 -38
- package/dist/{index-DIodyAqF.cjs → index-PNMQPKhz.cjs} +4 -4
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{install-BO_W7VhL.mjs → install-BdvKiOQw.mjs} +2 -0
- package/dist/{install-Cp_aB-NQ.mjs → install-C0-QFn9s.mjs} +3 -3
- package/dist/{install-Cs5qAPrB.cjs → install-Cf6AFSWC.cjs} +2 -0
- package/dist/{install-DrUQk2DJ.cjs → install-CqZVeze8.cjs} +3 -3
- package/dist/lib.cjs +12 -12
- package/dist/lib.d.cts +116 -2
- package/dist/lib.d.mts +116 -2
- package/dist/lib.mjs +12 -12
- package/dist/{lidState-BLHLmhwd.mjs → lidState-B2ZxdREe.mjs} +1 -1
- package/dist/{lidState-z9ekRpZu.cjs → lidState-Bc2K9H9l.cjs} +1 -1
- package/dist/{localHappyAgentAuth-BWvmc_Hg.mjs → localHappyAgentAuth-B5XPEMwk.mjs} +1 -1
- package/dist/{localHappyAgentAuth-BCx0y1qW.cjs → localHappyAgentAuth-T5GOvRha.cjs} +1 -1
- package/dist/{logger-D0hkk7Vo.cjs → logger-B_MWPbZz.cjs} +2 -2
- package/dist/{logger-CknSVkIe.mjs → logger-CbBv3q_b.mjs} +2 -2
- package/dist/{machineMetadata-BDCYOXQg.cjs → machineMetadata-BafS4JY8.cjs} +4 -3
- package/dist/{machineMetadata-Cj1DoFot.mjs → machineMetadata-DHg238U4.mjs} +4 -3
- package/dist/{main-COAPGIso.cjs → main-DNrA0qBy.cjs} +45 -45
- package/dist/{main-CKUfkVG_.mjs → main-DXAK0n7x.mjs} +45 -45
- package/dist/{manager-BQ4flvQZ.mjs → manager-BEsI4qt3.mjs} +9 -3
- package/dist/{manager-Cly8xVIR.cjs → manager-HrEj442o.cjs} +8 -2
- package/dist/{mcp-BILnw4si.cjs → mcp-AvPOhDXy.cjs} +24 -19
- package/dist/{mcp-DeYUfpo8.mjs → mcp-BotAjCdD.mjs} +23 -18
- package/dist/mirrorProtocol-BdcN6QlN.cjs +1270 -0
- package/dist/mirrorProtocol-BwHm8odn.mjs +1247 -0
- package/dist/{package-UkmvSFsg.cjs → package-C9ZP9bpX.cjs} +7 -7
- package/dist/{package-VIUXrYZ1.mjs → package-DU1DxhH9.mjs} +7 -7
- package/dist/{peerTools-CttfOxti.cjs → peerTools-Dkbu7gag.cjs} +4 -4
- package/dist/{peerTools-SWITnkqz.mjs → peerTools-os2DVjA0.mjs} +4 -4
- package/dist/{persistence-C6ztVW1W.cjs → persistence-BYGl0QYw.cjs} +147 -25
- package/dist/{persistence-DujtUH94.mjs → persistence-ON0zpHfb.mjs} +123 -12
- package/dist/{piRunnerArgs-BVJHIjlk.mjs → piRunnerArgs-CYsnT9sV.mjs} +1 -1
- package/dist/{piRunnerArgs-tBQg6xDw.cjs → piRunnerArgs-DpbvstUX.cjs} +1 -1
- package/dist/{piRuntime-DZzjF9It.cjs → piRuntime-CDnILlCd.cjs} +1 -1
- package/dist/{piRuntime-DKFA8u8t.mjs → piRuntime-CmEid-wu.mjs} +1 -1
- package/dist/{piTerminal-BTSaFlpV.mjs → piTerminal-0eNlXSlL.mjs} +17 -17
- package/dist/{piTerminal-t5pQHCPT.cjs → piTerminal-B57TgMON.cjs} +17 -17
- package/dist/precheckCompat-CWOi5c9L.cjs +29 -0
- package/dist/precheckCompat-DeEbilbr.mjs +26 -0
- package/dist/rateLimitWindows-CusGIqlq.cjs +258 -0
- package/dist/rateLimitWindows-vZ9Bo7aT.mjs +248 -0
- package/dist/{registerCommonHandlers-BR0J4g64.mjs → registerCommonHandlers-B0PVff2U.mjs} +2 -2
- package/dist/{registerCommonHandlers--8ds2auE.cjs → registerCommonHandlers-DVYB3iVn.cjs} +2 -2
- package/dist/{registerKillSessionHandler-Czz0tdki.mjs → registerKillSessionHandler-BJMHJHXe.mjs} +15 -10
- package/dist/{registerKillSessionHandler-CI23l8aJ.cjs → registerKillSessionHandler-BwXGKtg_.cjs} +15 -10
- package/dist/{remoteSessionClient-DCAUHgPz.mjs → remoteSessionClient-BzPXSC21.mjs} +5 -5
- package/dist/{remoteSessionClient-BAkIwM2S.cjs → remoteSessionClient-PyUAIhwK.cjs} +5 -5
- package/dist/{tools-BVRoGcQH.mjs → reportProgressTool-BvB13EwC.mjs} +67 -10
- package/dist/{tools-mWqsE6ji.cjs → reportProgressTool-D4KB_4cP.cjs} +73 -9
- package/dist/{run-CkKujjn8.cjs → run-BC8jzq_h.cjs} +558 -122
- package/dist/{run-B75qm2I6.mjs → run-O2M8LsWf.mjs} +556 -120
- package/dist/{runClaude-B1T9DLLi.cjs → runClaude-C7jPa8VP.cjs} +93 -26
- package/dist/{runClaude-aBfBweec.mjs → runClaude-DGkr5E7s.mjs} +93 -26
- package/dist/{runClaudeDeps-BGjNGfuZ.cjs → runClaudeDeps-5kzncqME.cjs} +113 -35
- package/dist/{runClaudeDeps-BOrPP4J1.mjs → runClaudeDeps-CX_TxS78.mjs} +116 -37
- package/dist/{runGemini-BuAA_OQb.cjs → runGemini-BfYA4Uqc.cjs} +43 -36
- package/dist/{runGemini-a-V7JE-J.mjs → runGemini-CwmGBH3L.mjs} +43 -36
- package/dist/{runOpenClaw-DUSwXg1A.mjs → runOpenClaw-BYAPYFyL.mjs} +18 -18
- package/dist/{runOpenClaw-BBVffIh9.cjs → runOpenClaw-C72jut7v.cjs} +18 -18
- package/dist/{sandbox-Fd2G5yaq.cjs → sandbox-Bqkp8IT7.cjs} +4 -4
- package/dist/{sandbox-Brb_5wzc.mjs → sandbox-DlVnK1Vi.mjs} +4 -4
- package/dist/{selfCheck-NuJKMInJ.cjs → selfCheck-B4lLZplk.cjs} +34 -34
- package/dist/selfCheck-DYTGBdIO.mjs +84 -0
- package/dist/{send-DEQJiq_x.mjs → send-B5bWW9Tl.mjs} +8 -8
- package/dist/{send-4dgHKC3u.cjs → send-BCwS6n_s.cjs} +8 -8
- package/dist/{server-C6AlUFkw.mjs → server-CEJfRQfj.mjs} +4 -4
- package/dist/{server-DWGcDmHG.cjs → server-CFWZehnC.cjs} +6 -6
- package/dist/{sessionLock-Dm8QyGo4.mjs → sessionLock-AwOYsKT7.mjs} +12 -4
- package/dist/{sessionLock-B1GgaO1q.cjs → sessionLock-LBWNjpHf.cjs} +12 -3
- package/dist/{sessionModeFile-BvOEJ4Fl.cjs → sessionModeFile-CyPuZRIU.cjs} +1 -1
- package/dist/{sessionModeFile-CuNAWCKL.mjs → sessionModeFile-fvFn1JVG.mjs} +1 -1
- package/dist/{sessionOps-DG5MMEp_.mjs → sessionOps-DZRH4-hV.mjs} +4 -4
- package/dist/{sessionOps-JP64uJmc.cjs → sessionOps-DzbZI3Eq.cjs} +4 -4
- package/dist/{sessionScanner-DqSk5Ol_.mjs → sessionScanner-Q_Ei2flB.mjs} +75 -19
- package/dist/{sessionScanner-BBPEgJ5S.cjs → sessionScanner-i-cgwFVw.cjs} +75 -19
- package/dist/{sessions-4isbBAWi.mjs → sessions-DAmjMAZN.mjs} +9 -9
- package/dist/{sessions-DgJuw_i0.cjs → sessions-DYK5hD4T.cjs} +9 -9
- package/dist/{setupOfflineReconnection-_MoZtsro.mjs → setupOfflineReconnection-BfDBxNdo.mjs} +2 -2
- package/dist/{setupOfflineReconnection-CKJKVIUS.cjs → setupOfflineReconnection-C2LO3hSP.cjs} +2 -2
- package/dist/{spawn-BTOG4tTm.mjs → spawn-BmjG5j5Y.mjs} +15 -14
- package/dist/{spawn-CshERWbY.cjs → spawn-GK_sXE8h.cjs} +15 -14
- package/dist/{spawnAgents-Czi2VDzj.mjs → spawnAgents-HDaE3C0-.mjs} +1 -1
- package/dist/{spawnAgents-McixdtV1.cjs → spawnAgents-vglexX9N.cjs} +1 -1
- package/dist/{spawnHappyCLI-Dc4xYm8P.mjs → spawnHappyCLI-B2h0P4b5.mjs} +1 -1
- package/dist/{spawnHappyCLI-Dd5_8Vex.cjs → spawnHappyCLI-J4iEhfyZ.cjs} +1 -1
- package/dist/specialCommands-DisVxagO.mjs +93 -0
- package/dist/specialCommands-DmJMKspE.cjs +96 -0
- package/dist/{startFileWatcher-B0VlG-Fn.mjs → startFileWatcher-CeK1k5gt.mjs} +1 -1
- package/dist/{startFileWatcher-1LedLBY-.cjs → startFileWatcher-xKo8AoYl.cjs} +1 -1
- package/dist/{streamRelay-C0AffuX6.cjs → streamRelay-Ce9sgcOV.cjs} +1 -1
- package/dist/{streamRelay-BzMEEvJU.mjs → streamRelay-Iogsh51a.mjs} +1 -1
- package/dist/{sync-DwUUGGFz.cjs → sync-Bvc-vh6C.cjs} +1 -1
- package/dist/{sync-Dfm6K2te.mjs → sync-CCwYpJMS.mjs} +1 -1
- package/dist/{systemPrompt-D41Zw1a3.mjs → systemPrompt-BNIkP3tR.mjs} +3 -3
- package/dist/{systemPrompt-CB1Ls0AE.cjs → systemPrompt-DwOddbuG.cjs} +3 -3
- package/dist/{teams-D8Ly3i6u.mjs → teams-DRrLBcys.mjs} +7 -7
- package/dist/{teams-NWv2ji16.cjs → teams-GHMCRZOw.cjs} +7 -7
- package/dist/{time-BbzJ7PJQ.cjs → time-BXvtjhe9.cjs} +1 -1
- package/dist/{time-v1Y_qEJp.mjs → time-PG5Dfwdv.mjs} +1 -1
- package/dist/{titleGenerator-cH6IkPRi.cjs → titleGenerator-B07bZA0V.cjs} +2 -2
- package/dist/{titleGenerator-BhoblAQY.mjs → titleGenerator-CIzfpfZW.mjs} +1 -1
- package/dist/{todo-D1hgWV6d.cjs → todo-B0aeoNu3.cjs} +6 -6
- package/dist/{todo-CuNct-fw.mjs → todo-CfL7SBFc.mjs} +6 -6
- package/dist/{tools-jof0Bu54.mjs → tools-D91mq5Ib.mjs} +1 -1
- package/dist/{tools-c2fb0CF5.cjs → tools-DJIANHSh.cjs} +1 -1
- package/dist/transcriptCursor-B7T_gkQ0.mjs +102 -0
- package/dist/transcriptCursor-DcXGLeSc.cjs +106 -0
- package/dist/{uninstall-BB7WYYAk.mjs → uninstall-5xz3Xvhf.mjs} +3 -3
- package/dist/{uninstall-VPH5GfrA.cjs → uninstall-AtzOfdrj.cjs} +3 -3
- package/package.json +7 -7
- package/scripts/terminal_status_forwarder.cjs +89 -0
- package/dist/defaultPermissionMode-BnxJPVHT.mjs +0 -4
- package/dist/defaultPermissionMode-CxmTXUQR.cjs +0 -7
- package/dist/mirrorProtocol-BNLtoWjO.mjs +0 -170
- package/dist/mirrorProtocol-BUtmg1ws.cjs +0 -186
- package/dist/selfCheck-BgwJ3NGS.mjs +0 -84
- package/dist/specialCommands-BSqhYg5X.mjs +0 -52
- package/dist/specialCommands-DSsTeRej.cjs +0 -54
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ The web client URL follows the same precedence (`HAPPY_WEBAPP_URL`, then
|
|
|
161
161
|
|
|
162
162
|
Base managed Claude sessions receive `change_title`, `copy_to_clipboard`,
|
|
163
163
|
`open_preview`, and `report_progress`. The managed Codex, Gemini, and ACP bridge
|
|
164
|
-
exposes the
|
|
164
|
+
exposes the same four. For a plain `claude`, the standalone
|
|
165
165
|
command is intentionally clipboard-only:
|
|
166
166
|
|
|
167
167
|
```bash
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var sdk = require('@agentclientprotocol/sdk');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var logger = require('./logger-
|
|
7
|
-
var time = require('./time-
|
|
6
|
+
var logger = require('./logger-B_MWPbZz.cjs');
|
|
7
|
+
var time = require('./time-BXvtjhe9.cjs');
|
|
8
8
|
var contentLogMetadata = require('./contentLogMetadata-ZSFk_NjQ.cjs');
|
|
9
|
-
var _package = require('./package-
|
|
9
|
+
var _package = require('./package-C9ZP9bpX.cjs');
|
|
10
10
|
|
|
11
11
|
function acpImageBlocks(attachments, supportsImages) {
|
|
12
12
|
return attachments.filter((file) => ["image/jpeg", "image/png", "image/gif", "image/webp"].includes(file.mimeType)).map((file) => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger } from './logger-
|
|
5
|
-
import { d as delay } from './time-
|
|
4
|
+
import { l as logger } from './logger-CbBv3q_b.mjs';
|
|
5
|
+
import { d as delay } from './time-PG5Dfwdv.mjs';
|
|
6
6
|
import { c as contentLogMetadata, e as errorLogMetadata } from './contentLogMetadata-BlWI0egu.mjs';
|
|
7
|
-
import { p as packageJson } from './package-
|
|
7
|
+
import { p as packageJson } from './package-DU1DxhH9.mjs';
|
|
8
8
|
|
|
9
9
|
function acpImageBlocks(attachments, supportsImages) {
|
|
10
10
|
return attachments.filter((file) => ["image/jpeg", "image/png", "image/gif", "image/webp"].includes(file.mimeType)).map((file) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createId } from '@paralleldrive/cuid2';
|
|
2
|
-
import { s as streamKeyOf,
|
|
2
|
+
import { s as streamKeyOf, c as createEnvelope } from './index-B0HEEYGh.mjs';
|
|
3
3
|
|
|
4
4
|
function turnOptions(turnId, time) {
|
|
5
5
|
return turnId ? { turn: turnId, time } : { time };
|
|
@@ -5,6 +5,7 @@ const AGENT_GUIDANCE = (() => trimIdent(`
|
|
|
5
5
|
|
|
6
6
|
- Terminal output is not a good delivery channel. When the user asks for a piece of text ("copy that", "give me X", "\u590D\u5236\u7ED9\u6211", "\u53D1\u6211"), hand it over with mcp__happy__copy_to_clipboard instead of printing it for them to select by hand.
|
|
7
7
|
- When you produce or want to show a FILE (a document you wrote, a report, an image, a PDF, a diff), call mcp__happy__open_preview with its path instead of cat-ing it. Their client opens the rendered file.
|
|
8
|
+
- If the user wants to GET a file (any type: zip, docx, binary), pass download: true to mcp__happy__open_preview. Zip a directory first.
|
|
8
9
|
|
|
9
10
|
Judgement, not reflex: use these when the user's goal is to RECEIVE something. If they are asking a question you can just answer, answer it. Do not preview a file you only read for your own reasoning, and do not preview the same file repeatedly within a turn.
|
|
10
11
|
|
|
@@ -12,9 +13,10 @@ const AGENT_GUIDANCE = (() => trimIdent(`
|
|
|
12
13
|
`))();
|
|
13
14
|
const PREVIEW_TOOL_NAME = "open_preview";
|
|
14
15
|
const PREVIEW_TOOL_TITLE = "Open File Preview for the User";
|
|
15
|
-
const PREVIEW_TOOL_DESCRIPTION = 'Open a file in the preview panel of every web client the user currently has open. Use this whenever you produce or want to show the user a file: a document or report you just wrote, a generated image or diagram, a PDF, a data file, or a source file you want them to look at. Trigger phrases include: "write me a doc", "show me that file", "let me see it", "\u5199\u4E2A\u6587\u6863", "\u7ED9\u6211\u770B\u770B\u8FD9\u4E2A\u6587\u4EF6", "\u6253\u5F00\u770B\u4E0B". Pass an absolute path (or one starting with ~). The file is read on this machine and rendered in their browser \u2014 markdown is rendered, images and PDFs are displayed, other text is syntax-highlighted. Prefer this over printing file contents to the terminal, which the user is probably not looking at. NOTE: this only requests that their client open the file; it cannot confirm the user actually looked at it, so do not assume they have
|
|
16
|
+
const PREVIEW_TOOL_DESCRIPTION = 'Open a file in the preview panel of every web client the user currently has open. Use this whenever you produce or want to show the user a file: a document or report you just wrote, a generated image or diagram, a PDF, a data file, or a source file you want them to look at. Trigger phrases include: "write me a doc", "show me that file", "let me see it", "\u5199\u4E2A\u6587\u6863", "\u7ED9\u6211\u770B\u770B\u8FD9\u4E2A\u6587\u4EF6", "\u6253\u5F00\u770B\u4E0B". Pass an absolute path (or one starting with ~). The file is read on this machine and rendered in their browser \u2014 markdown is rendered, images and PDFs are displayed, other text is syntax-highlighted. Prefer this over printing file contents to the terminal, which the user is probably not looking at. Set download: true when the user wants to GET the file rather than read it \u2014 any type, including zip archives, Word/Excel/PowerPoint documents, binaries and installers ("send me the file", "let me download it", "\u7ED9\u6211\u4E0B\u8F7D", "\u53D1\u6211\u8FD9\u4E2A\u6587\u4EF6"). Their client then shows a prominent download button (and may start the download on desktop). Only single regular files can be downloaded: zip a directory first and pass the archive. The web download limit is 50 MiB; compress or split anything larger. NOTE: this only requests that their client open the file; it cannot confirm the user actually looked at it or downloaded it, so do not assume they have.';
|
|
17
|
+
const PREVIEW_DOWNLOAD_PARAM_DESCRIPTION = "true when the user wants to download/receive the file itself (any type) rather than just read it";
|
|
16
18
|
const REPORT_PROGRESS_TOOL_NAME = "report_progress";
|
|
17
19
|
const REPORT_PROGRESS_TOOL_TITLE = "Report Progress to the Task Board";
|
|
18
20
|
const REPORT_PROGRESS_TOOL_DESCRIPTION = `Report what you are doing to the user's task board, so they can see the state of this session at a glance without reading the transcript. Call it at meaningful milestones only: when you start substantive work, when you get blocked and need the user, when something is ready for their review, and when you are done. Do NOT call it after every tool call or every file edit \u2014 it is a status line, not a log. Set attention to "blocked" when you cannot proceed without the user, "review" when you want them to look at something, and "none" for ordinary progress. Keep progress to one short line describing the current state (the user reads it on a card).`;
|
|
19
21
|
|
|
20
|
-
export { AGENT_GUIDANCE as A, PREVIEW_TOOL_NAME as P, REPORT_PROGRESS_TOOL_NAME as R, PREVIEW_TOOL_TITLE as a, PREVIEW_TOOL_DESCRIPTION as b,
|
|
22
|
+
export { AGENT_GUIDANCE as A, PREVIEW_TOOL_NAME as P, REPORT_PROGRESS_TOOL_NAME as R, PREVIEW_TOOL_TITLE as a, PREVIEW_TOOL_DESCRIPTION as b, PREVIEW_DOWNLOAD_PARAM_DESCRIPTION as c, REPORT_PROGRESS_TOOL_TITLE as d, REPORT_PROGRESS_TOOL_DESCRIPTION as e };
|
|
@@ -7,6 +7,7 @@ const AGENT_GUIDANCE = (() => trimIdent.trimIdent(`
|
|
|
7
7
|
|
|
8
8
|
- Terminal output is not a good delivery channel. When the user asks for a piece of text ("copy that", "give me X", "\u590D\u5236\u7ED9\u6211", "\u53D1\u6211"), hand it over with mcp__happy__copy_to_clipboard instead of printing it for them to select by hand.
|
|
9
9
|
- When you produce or want to show a FILE (a document you wrote, a report, an image, a PDF, a diff), call mcp__happy__open_preview with its path instead of cat-ing it. Their client opens the rendered file.
|
|
10
|
+
- If the user wants to GET a file (any type: zip, docx, binary), pass download: true to mcp__happy__open_preview. Zip a directory first.
|
|
10
11
|
|
|
11
12
|
Judgement, not reflex: use these when the user's goal is to RECEIVE something. If they are asking a question you can just answer, answer it. Do not preview a file you only read for your own reasoning, and do not preview the same file repeatedly within a turn.
|
|
12
13
|
|
|
@@ -14,12 +15,14 @@ const AGENT_GUIDANCE = (() => trimIdent.trimIdent(`
|
|
|
14
15
|
`))();
|
|
15
16
|
const PREVIEW_TOOL_NAME = "open_preview";
|
|
16
17
|
const PREVIEW_TOOL_TITLE = "Open File Preview for the User";
|
|
17
|
-
const PREVIEW_TOOL_DESCRIPTION = 'Open a file in the preview panel of every web client the user currently has open. Use this whenever you produce or want to show the user a file: a document or report you just wrote, a generated image or diagram, a PDF, a data file, or a source file you want them to look at. Trigger phrases include: "write me a doc", "show me that file", "let me see it", "\u5199\u4E2A\u6587\u6863", "\u7ED9\u6211\u770B\u770B\u8FD9\u4E2A\u6587\u4EF6", "\u6253\u5F00\u770B\u4E0B". Pass an absolute path (or one starting with ~). The file is read on this machine and rendered in their browser \u2014 markdown is rendered, images and PDFs are displayed, other text is syntax-highlighted. Prefer this over printing file contents to the terminal, which the user is probably not looking at. NOTE: this only requests that their client open the file; it cannot confirm the user actually looked at it, so do not assume they have
|
|
18
|
+
const PREVIEW_TOOL_DESCRIPTION = 'Open a file in the preview panel of every web client the user currently has open. Use this whenever you produce or want to show the user a file: a document or report you just wrote, a generated image or diagram, a PDF, a data file, or a source file you want them to look at. Trigger phrases include: "write me a doc", "show me that file", "let me see it", "\u5199\u4E2A\u6587\u6863", "\u7ED9\u6211\u770B\u770B\u8FD9\u4E2A\u6587\u4EF6", "\u6253\u5F00\u770B\u4E0B". Pass an absolute path (or one starting with ~). The file is read on this machine and rendered in their browser \u2014 markdown is rendered, images and PDFs are displayed, other text is syntax-highlighted. Prefer this over printing file contents to the terminal, which the user is probably not looking at. Set download: true when the user wants to GET the file rather than read it \u2014 any type, including zip archives, Word/Excel/PowerPoint documents, binaries and installers ("send me the file", "let me download it", "\u7ED9\u6211\u4E0B\u8F7D", "\u53D1\u6211\u8FD9\u4E2A\u6587\u4EF6"). Their client then shows a prominent download button (and may start the download on desktop). Only single regular files can be downloaded: zip a directory first and pass the archive. The web download limit is 50 MiB; compress or split anything larger. NOTE: this only requests that their client open the file; it cannot confirm the user actually looked at it or downloaded it, so do not assume they have.';
|
|
19
|
+
const PREVIEW_DOWNLOAD_PARAM_DESCRIPTION = "true when the user wants to download/receive the file itself (any type) rather than just read it";
|
|
18
20
|
const REPORT_PROGRESS_TOOL_NAME = "report_progress";
|
|
19
21
|
const REPORT_PROGRESS_TOOL_TITLE = "Report Progress to the Task Board";
|
|
20
22
|
const REPORT_PROGRESS_TOOL_DESCRIPTION = `Report what you are doing to the user's task board, so they can see the state of this session at a glance without reading the transcript. Call it at meaningful milestones only: when you start substantive work, when you get blocked and need the user, when something is ready for their review, and when you are done. Do NOT call it after every tool call or every file edit \u2014 it is a status line, not a log. Set attention to "blocked" when you cannot proceed without the user, "review" when you want them to look at something, and "none" for ordinary progress. Keep progress to one short line describing the current state (the user reads it on a card).`;
|
|
21
23
|
|
|
22
24
|
exports.AGENT_GUIDANCE = AGENT_GUIDANCE;
|
|
25
|
+
exports.PREVIEW_DOWNLOAD_PARAM_DESCRIPTION = PREVIEW_DOWNLOAD_PARAM_DESCRIPTION;
|
|
23
26
|
exports.PREVIEW_TOOL_DESCRIPTION = PREVIEW_TOOL_DESCRIPTION;
|
|
24
27
|
exports.PREVIEW_TOOL_NAME = PREVIEW_TOOL_NAME;
|
|
25
28
|
exports.PREVIEW_TOOL_TITLE = PREVIEW_TOOL_TITLE;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
|
-
import { readSettings, updateSettings } from './persistence-
|
|
3
|
+
import { r as readSettings, u as updateSettings } from './persistence-ON0zpHfb.mjs';
|
|
4
4
|
import 'node:fs';
|
|
5
|
-
import './logger-
|
|
5
|
+
import './logger-CbBv3q_b.mjs';
|
|
6
6
|
import { d as describeAgentHome, p as probeLoginShellEnv, r as resolveAgentHomes, e as expandHomePath, A as AGENT_HOME_ENV_NAMES } from './loginShellEnv-Dw8M7tkI.mjs';
|
|
7
7
|
import 'node:fs/promises';
|
|
8
|
-
import './configuration-
|
|
8
|
+
import './configuration-WspKd2C2.mjs';
|
|
9
9
|
import 'node:path';
|
|
10
|
-
import './package-
|
|
10
|
+
import './package-DU1DxhH9.mjs';
|
|
11
11
|
import 'zod';
|
|
12
12
|
import './authRelay-DSAvg1uv.mjs';
|
|
13
13
|
import 'node:crypto';
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
|
-
var persistence = require('./persistence-
|
|
5
|
+
var persistence = require('./persistence-BYGl0QYw.cjs');
|
|
6
6
|
require('node:fs');
|
|
7
|
-
require('./logger-
|
|
7
|
+
require('./logger-B_MWPbZz.cjs');
|
|
8
8
|
var loginShellEnv = require('./loginShellEnv-BkuYtExZ.cjs');
|
|
9
9
|
require('node:fs/promises');
|
|
10
|
-
require('./configuration-
|
|
10
|
+
require('./configuration-C3piBtxY.cjs');
|
|
11
11
|
require('node:path');
|
|
12
|
-
require('./package-
|
|
12
|
+
require('./package-C9ZP9bpX.cjs');
|
|
13
13
|
require('zod');
|
|
14
14
|
require('./authRelay-BdYkC1Po.cjs');
|
|
15
15
|
require('node:crypto');
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var axios = require('axios');
|
|
4
|
-
var logger = require('./logger-
|
|
5
|
-
var lidState = require('./lidState-
|
|
4
|
+
var logger = require('./logger-B_MWPbZz.cjs');
|
|
5
|
+
var lidState = require('./lidState-Bc2K9H9l.cjs');
|
|
6
6
|
var node_events = require('node:events');
|
|
7
7
|
var socket_ioClient = require('socket.io-client');
|
|
8
|
-
var attachmentLimits = require('./attachmentLimits-
|
|
8
|
+
var attachmentLimits = require('./attachmentLimits-BEYEEBm8.cjs');
|
|
9
9
|
var authRelay = require('./authRelay-BdYkC1Po.cjs');
|
|
10
10
|
var limits = require('./limits-C-a7gr04.cjs');
|
|
11
|
-
var time = require('./time-
|
|
12
|
-
var configuration = require('./configuration-
|
|
11
|
+
var time = require('./time-BXvtjhe9.cjs');
|
|
12
|
+
var configuration = require('./configuration-C3piBtxY.cjs');
|
|
13
13
|
var node_crypto = require('node:crypto');
|
|
14
|
-
var index = require('./index-
|
|
15
|
-
var registerCommonHandlers = require('./registerCommonHandlers
|
|
14
|
+
var index = require('./index-C9hI8a10.cjs');
|
|
15
|
+
var registerCommonHandlers = require('./registerCommonHandlers-DVYB3iVn.cjs');
|
|
16
16
|
var cuid2 = require('@paralleldrive/cuid2');
|
|
17
|
-
var sync = require('./sync-
|
|
17
|
+
var sync = require('./sync-Bvc-vh6C.cjs');
|
|
18
18
|
var backgroundTaskActivity = require('./backgroundTaskActivity-CBvUdj39.cjs');
|
|
19
|
-
var controlClient = require('./controlClient-
|
|
19
|
+
var controlClient = require('./controlClient-BI6Fw3fQ.cjs');
|
|
20
20
|
var contentLogMetadata = require('./contentLogMetadata-ZSFk_NjQ.cjs');
|
|
21
21
|
var chalk = require('chalk');
|
|
22
22
|
|
|
@@ -1590,6 +1590,14 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1590
1590
|
}
|
|
1591
1591
|
}
|
|
1592
1592
|
routeIncomingMessage(message, sourceLocalId) {
|
|
1593
|
+
if (this.inboundFrozen) {
|
|
1594
|
+
logger.logger.debug(`[API] Hibernating: holding inbound ${sourceLocalId ?? "(no localId)"}`);
|
|
1595
|
+
this.frozenInbound.push({ message, sourceLocalId });
|
|
1596
|
+
this.inboundRoutedDuringCommit = true;
|
|
1597
|
+
return;
|
|
1598
|
+
}
|
|
1599
|
+
this.inboundRoutedDuringCommit = true;
|
|
1600
|
+
this.noteActivity();
|
|
1593
1601
|
if (sourceLocalId) this.promptQueueDrain?.onInbound(sourceLocalId);
|
|
1594
1602
|
const messageWithSource = sourceLocalId && typeof message === "object" && message !== null ? { ...message, localKey: message.localKey ?? sourceLocalId } : message;
|
|
1595
1603
|
const userResult = attachmentLimits.UserMessageSchema.safeParse(messageWithSource);
|
|
@@ -1835,6 +1843,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
1835
1843
|
}
|
|
1836
1844
|
}
|
|
1837
1845
|
enqueueMessage(content, invalidate = true, localId) {
|
|
1846
|
+
this.noteActivity();
|
|
1838
1847
|
const encrypted = authRelay.encodeBase64(authRelay.encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1839
1848
|
this.pendingOutbox.push({
|
|
1840
1849
|
content: encrypted,
|
|
@@ -2011,6 +2020,52 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2011
2020
|
};
|
|
2012
2021
|
this.enqueueMessage(content);
|
|
2013
2022
|
}
|
|
2023
|
+
// ── B-587 hibernation support ──────────────────────────────────────────
|
|
2024
|
+
/** Last user/agent activity this wrapper saw (spec §2.1). */
|
|
2025
|
+
lastActivity = Date.now();
|
|
2026
|
+
inboundFrozen = false;
|
|
2027
|
+
frozenInbound = [];
|
|
2028
|
+
heartbeatsMuted = false;
|
|
2029
|
+
lastHeartbeat = 0;
|
|
2030
|
+
get lastHeartbeatAt() {
|
|
2031
|
+
return this.lastHeartbeat;
|
|
2032
|
+
}
|
|
2033
|
+
muteHeartbeats() {
|
|
2034
|
+
this.heartbeatsMuted = true;
|
|
2035
|
+
}
|
|
2036
|
+
unmuteHeartbeats() {
|
|
2037
|
+
this.heartbeatsMuted = false;
|
|
2038
|
+
}
|
|
2039
|
+
inboundRoutedDuringCommit = false;
|
|
2040
|
+
noteActivity(now = Date.now()) {
|
|
2041
|
+
if (now > this.lastActivity) this.lastActivity = now;
|
|
2042
|
+
}
|
|
2043
|
+
get lastActivityAt() {
|
|
2044
|
+
return this.lastActivity;
|
|
2045
|
+
}
|
|
2046
|
+
/** The message cursor (highest seq this wrapper has seen). */
|
|
2047
|
+
get messageCursor() {
|
|
2048
|
+
return this.lastSeq;
|
|
2049
|
+
}
|
|
2050
|
+
/** Start watching for inbound routed during the hibernation commit window. */
|
|
2051
|
+
beginHibernationCommit() {
|
|
2052
|
+
this.inboundRoutedDuringCommit = false;
|
|
2053
|
+
}
|
|
2054
|
+
/** Was any inbound message routed since beginHibernationCommit()? */
|
|
2055
|
+
inboundRoutedSinceCommit() {
|
|
2056
|
+
return this.inboundRoutedDuringCommit;
|
|
2057
|
+
}
|
|
2058
|
+
/** Stop routing inbound messages; the next wrapper replays them (spec §3/§4). */
|
|
2059
|
+
freezeInbound() {
|
|
2060
|
+
this.inboundFrozen = true;
|
|
2061
|
+
}
|
|
2062
|
+
/** An aborted hibernation: route whatever arrived while frozen, in order. */
|
|
2063
|
+
unfreezeInbound() {
|
|
2064
|
+
this.inboundFrozen = false;
|
|
2065
|
+
const held = this.frozenInbound;
|
|
2066
|
+
this.frozenInbound = [];
|
|
2067
|
+
for (const item of held) this.routeIncomingMessage(item.message, item.sourceLocalId);
|
|
2068
|
+
}
|
|
2014
2069
|
/**
|
|
2015
2070
|
* Send a ping message to keep the connection alive
|
|
2016
2071
|
*/
|
|
@@ -2029,11 +2084,14 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2029
2084
|
}));
|
|
2030
2085
|
});
|
|
2031
2086
|
keepAlive(thinking, mode, backgroundTasks) {
|
|
2087
|
+
if (this.heartbeatsMuted) return;
|
|
2088
|
+
this.lastHeartbeat = Date.now();
|
|
2032
2089
|
if (process.env.DEBUG) {
|
|
2033
2090
|
logger.logger.debug(`[API] Sending keep alive message: ${thinking}`);
|
|
2034
2091
|
}
|
|
2035
2092
|
this.turnReporter.observe(thinking);
|
|
2036
2093
|
if (backgroundTasks) this.backgroundTaskReporter.observe(backgroundTasks);
|
|
2094
|
+
if (thinking || (backgroundTasks?.length ?? 0) > 0) this.noteActivity();
|
|
2037
2095
|
this.socket.volatile.emit("session-alive", {
|
|
2038
2096
|
sid: this.sessionId,
|
|
2039
2097
|
time: Date.now(),
|
|
@@ -2112,14 +2170,16 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2112
2170
|
* payload on this channel is (clipboard, fs RPC) — and a path leaks
|
|
2113
2171
|
* project/client names and directory structure.
|
|
2114
2172
|
*/
|
|
2115
|
-
pushFilePreview(path, mode = "file") {
|
|
2173
|
+
pushFilePreview(path, mode = "file", intent) {
|
|
2116
2174
|
if (!this.socket.connected) {
|
|
2117
2175
|
return { delivered: false, error: "not connected to the server" };
|
|
2118
2176
|
}
|
|
2119
2177
|
this.socket.emit("file-preview-push", {
|
|
2120
2178
|
payload: authRelay.encodeBase64(authRelay.encrypt(this.encryptionKey, this.encryptionVariant, path)),
|
|
2121
2179
|
enc: true,
|
|
2122
|
-
mode
|
|
2180
|
+
mode,
|
|
2181
|
+
// B-562: only present for downloads, so a plain preview keeps the old wire shape.
|
|
2182
|
+
...intent ? { intent } : {}
|
|
2123
2183
|
});
|
|
2124
2184
|
return { delivered: true };
|
|
2125
2185
|
}
|
|
@@ -2224,7 +2284,26 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2224
2284
|
});
|
|
2225
2285
|
}
|
|
2226
2286
|
updateMetadata(handler) {
|
|
2227
|
-
this.
|
|
2287
|
+
void this.writeMetadata(handler);
|
|
2288
|
+
}
|
|
2289
|
+
/**
|
|
2290
|
+
* B-587: the same write, awaitable with a ceiling — the hibernation stamp
|
|
2291
|
+
* must land before `session-end`. Resolves false on timeout (the write
|
|
2292
|
+
* itself keeps retrying in the background, exactly like updateMetadata).
|
|
2293
|
+
*/
|
|
2294
|
+
async updateMetadataAndWait(handler, timeoutMs = 1e4) {
|
|
2295
|
+
let timer;
|
|
2296
|
+
const timeout = new Promise((resolve) => {
|
|
2297
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
2298
|
+
});
|
|
2299
|
+
try {
|
|
2300
|
+
return await Promise.race([this.writeMetadata(handler).then(() => true), timeout]);
|
|
2301
|
+
} finally {
|
|
2302
|
+
if (timer) clearTimeout(timer);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
writeMetadata(handler) {
|
|
2306
|
+
return this.metadataLock.inLock(async () => {
|
|
2228
2307
|
let rateRefusals = 0;
|
|
2229
2308
|
await time.backoff(async () => {
|
|
2230
2309
|
let updated = handler(this.metadata);
|
|
@@ -2270,6 +2349,7 @@ class ApiSessionClient extends node_events.EventEmitter {
|
|
|
2270
2349
|
this.agentState = answer.agentState ? authRelay.decrypt(this.encryptionKey, this.encryptionVariant, authRelay.decodeBase64(answer.agentState)) : null;
|
|
2271
2350
|
this.agentStateVersion = answer.version;
|
|
2272
2351
|
rateRefusals = 0;
|
|
2352
|
+
if (Object.keys(this.agentState?.requests ?? {}).length > 0) this.noteActivity();
|
|
2273
2353
|
logger.logger.debug("Agent state updated", this.agentState);
|
|
2274
2354
|
} else if (answer.result === "version-mismatch") {
|
|
2275
2355
|
if (answer.version > this.agentStateVersion) {
|
|
@@ -3086,7 +3166,7 @@ class ApiClient {
|
|
|
3086
3166
|
return new ApiSessionClient(this.credential.token, session, opts);
|
|
3087
3167
|
}
|
|
3088
3168
|
async machineSyncClient(machine) {
|
|
3089
|
-
const { ApiMachineClient } = await Promise.resolve().then(function () { return require('./apiMachine-
|
|
3169
|
+
const { ApiMachineClient } = await Promise.resolve().then(function () { return require('./apiMachine-BgMxGPsR.cjs'); });
|
|
3090
3170
|
return new ApiMachineClient(this.credential.token, machine);
|
|
3091
3171
|
}
|
|
3092
3172
|
push() {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import { l as logger, r as redactLogValue } from './logger-
|
|
3
|
-
import { R as RpcHandlerManager, a as answerSocketRequest, c as connectGuarded, s as socketConnectGuard, d as describeSocketAckDrop, b as safeAck, i as isRateQuotaCode, p as pauseForRateQuota, e as shouldReconnect } from './lidState-
|
|
2
|
+
import { l as logger, r as redactLogValue } from './logger-CbBv3q_b.mjs';
|
|
3
|
+
import { R as RpcHandlerManager, a as answerSocketRequest, c as connectGuarded, s as socketConnectGuard, d as describeSocketAckDrop, b as safeAck, i as isRateQuotaCode, p as pauseForRateQuota, e as shouldReconnect } from './lidState-B2ZxdREe.mjs';
|
|
4
4
|
import { EventEmitter } from 'node:events';
|
|
5
5
|
import { io } from 'socket.io-client';
|
|
6
|
-
import { A as AsyncLock, a as MAX_CHAT_ATTACHMENT_ENCRYPTED_BYTES, U as UserMessageSchema, F as FileEventMessageSchema } from './attachmentLimits-
|
|
6
|
+
import { A as AsyncLock, a as MAX_CHAT_ATTACHMENT_ENCRYPTED_BYTES, U as UserMessageSchema, F as FileEventMessageSchema } from './attachmentLimits-CxG3T18E.mjs';
|
|
7
7
|
import { h as decrypt, d as decodeBase64, i as decryptBlob, e as encodeBase64, g as encrypt, l as libsodiumEncryptForPublicKey, j as libsodiumPublicKeyFromSecretKey, k as getRandomBytes } from './authRelay-DSAvg1uv.mjs';
|
|
8
8
|
import { p as prepareClipboardText, d as prepareClipboardHistoryText } from './limits-DIo7rEBR.mjs';
|
|
9
|
-
import { b as backoff, d as delay, e as exponentialBackoffDelay } from './time-
|
|
10
|
-
import { c as configuration } from './configuration-
|
|
9
|
+
import { b as backoff, d as delay, e as exponentialBackoffDelay } from './time-PG5Dfwdv.mjs';
|
|
10
|
+
import { c as configuration } from './configuration-WspKd2C2.mjs';
|
|
11
11
|
import { createHmac, randomUUID } from 'node:crypto';
|
|
12
|
-
import {
|
|
13
|
-
import { r as registerCommonHandlers } from './registerCommonHandlers-
|
|
12
|
+
import { c as createEnvelope, s as streamKeyOf, R as ReleaseDrainNoticeSchema, q as RelayAssignmentResponseSchema } from './index-B0HEEYGh.mjs';
|
|
13
|
+
import { r as registerCommonHandlers } from './registerCommonHandlers-B0PVff2U.mjs';
|
|
14
14
|
import { createId } from '@paralleldrive/cuid2';
|
|
15
|
-
import { I as InvalidateSync } from './sync-
|
|
15
|
+
import { I as InvalidateSync } from './sync-CCwYpJMS.mjs';
|
|
16
16
|
import { B as BackgroundTaskReporter } from './backgroundTaskActivity-8PdPxrvy.mjs';
|
|
17
|
-
import {
|
|
17
|
+
import { k as notifyDaemonTurnEvent, m as notifyDaemonBackgroundTasks } from './controlClient-DTheOlvC.mjs';
|
|
18
18
|
import { c as contentLogMetadata } from './contentLogMetadata-BlWI0egu.mjs';
|
|
19
19
|
import chalk from 'chalk';
|
|
20
20
|
|
|
@@ -1588,6 +1588,14 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1588
1588
|
}
|
|
1589
1589
|
}
|
|
1590
1590
|
routeIncomingMessage(message, sourceLocalId) {
|
|
1591
|
+
if (this.inboundFrozen) {
|
|
1592
|
+
logger.debug(`[API] Hibernating: holding inbound ${sourceLocalId ?? "(no localId)"}`);
|
|
1593
|
+
this.frozenInbound.push({ message, sourceLocalId });
|
|
1594
|
+
this.inboundRoutedDuringCommit = true;
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
this.inboundRoutedDuringCommit = true;
|
|
1598
|
+
this.noteActivity();
|
|
1591
1599
|
if (sourceLocalId) this.promptQueueDrain?.onInbound(sourceLocalId);
|
|
1592
1600
|
const messageWithSource = sourceLocalId && typeof message === "object" && message !== null ? { ...message, localKey: message.localKey ?? sourceLocalId } : message;
|
|
1593
1601
|
const userResult = UserMessageSchema.safeParse(messageWithSource);
|
|
@@ -1833,6 +1841,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
1833
1841
|
}
|
|
1834
1842
|
}
|
|
1835
1843
|
enqueueMessage(content, invalidate = true, localId) {
|
|
1844
|
+
this.noteActivity();
|
|
1836
1845
|
const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
|
|
1837
1846
|
this.pendingOutbox.push({
|
|
1838
1847
|
content: encrypted,
|
|
@@ -2009,6 +2018,52 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2009
2018
|
};
|
|
2010
2019
|
this.enqueueMessage(content);
|
|
2011
2020
|
}
|
|
2021
|
+
// ── B-587 hibernation support ──────────────────────────────────────────
|
|
2022
|
+
/** Last user/agent activity this wrapper saw (spec §2.1). */
|
|
2023
|
+
lastActivity = Date.now();
|
|
2024
|
+
inboundFrozen = false;
|
|
2025
|
+
frozenInbound = [];
|
|
2026
|
+
heartbeatsMuted = false;
|
|
2027
|
+
lastHeartbeat = 0;
|
|
2028
|
+
get lastHeartbeatAt() {
|
|
2029
|
+
return this.lastHeartbeat;
|
|
2030
|
+
}
|
|
2031
|
+
muteHeartbeats() {
|
|
2032
|
+
this.heartbeatsMuted = true;
|
|
2033
|
+
}
|
|
2034
|
+
unmuteHeartbeats() {
|
|
2035
|
+
this.heartbeatsMuted = false;
|
|
2036
|
+
}
|
|
2037
|
+
inboundRoutedDuringCommit = false;
|
|
2038
|
+
noteActivity(now = Date.now()) {
|
|
2039
|
+
if (now > this.lastActivity) this.lastActivity = now;
|
|
2040
|
+
}
|
|
2041
|
+
get lastActivityAt() {
|
|
2042
|
+
return this.lastActivity;
|
|
2043
|
+
}
|
|
2044
|
+
/** The message cursor (highest seq this wrapper has seen). */
|
|
2045
|
+
get messageCursor() {
|
|
2046
|
+
return this.lastSeq;
|
|
2047
|
+
}
|
|
2048
|
+
/** Start watching for inbound routed during the hibernation commit window. */
|
|
2049
|
+
beginHibernationCommit() {
|
|
2050
|
+
this.inboundRoutedDuringCommit = false;
|
|
2051
|
+
}
|
|
2052
|
+
/** Was any inbound message routed since beginHibernationCommit()? */
|
|
2053
|
+
inboundRoutedSinceCommit() {
|
|
2054
|
+
return this.inboundRoutedDuringCommit;
|
|
2055
|
+
}
|
|
2056
|
+
/** Stop routing inbound messages; the next wrapper replays them (spec §3/§4). */
|
|
2057
|
+
freezeInbound() {
|
|
2058
|
+
this.inboundFrozen = true;
|
|
2059
|
+
}
|
|
2060
|
+
/** An aborted hibernation: route whatever arrived while frozen, in order. */
|
|
2061
|
+
unfreezeInbound() {
|
|
2062
|
+
this.inboundFrozen = false;
|
|
2063
|
+
const held = this.frozenInbound;
|
|
2064
|
+
this.frozenInbound = [];
|
|
2065
|
+
for (const item of held) this.routeIncomingMessage(item.message, item.sourceLocalId);
|
|
2066
|
+
}
|
|
2012
2067
|
/**
|
|
2013
2068
|
* Send a ping message to keep the connection alive
|
|
2014
2069
|
*/
|
|
@@ -2027,11 +2082,14 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2027
2082
|
}));
|
|
2028
2083
|
});
|
|
2029
2084
|
keepAlive(thinking, mode, backgroundTasks) {
|
|
2085
|
+
if (this.heartbeatsMuted) return;
|
|
2086
|
+
this.lastHeartbeat = Date.now();
|
|
2030
2087
|
if (process.env.DEBUG) {
|
|
2031
2088
|
logger.debug(`[API] Sending keep alive message: ${thinking}`);
|
|
2032
2089
|
}
|
|
2033
2090
|
this.turnReporter.observe(thinking);
|
|
2034
2091
|
if (backgroundTasks) this.backgroundTaskReporter.observe(backgroundTasks);
|
|
2092
|
+
if (thinking || (backgroundTasks?.length ?? 0) > 0) this.noteActivity();
|
|
2035
2093
|
this.socket.volatile.emit("session-alive", {
|
|
2036
2094
|
sid: this.sessionId,
|
|
2037
2095
|
time: Date.now(),
|
|
@@ -2110,14 +2168,16 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2110
2168
|
* payload on this channel is (clipboard, fs RPC) — and a path leaks
|
|
2111
2169
|
* project/client names and directory structure.
|
|
2112
2170
|
*/
|
|
2113
|
-
pushFilePreview(path, mode = "file") {
|
|
2171
|
+
pushFilePreview(path, mode = "file", intent) {
|
|
2114
2172
|
if (!this.socket.connected) {
|
|
2115
2173
|
return { delivered: false, error: "not connected to the server" };
|
|
2116
2174
|
}
|
|
2117
2175
|
this.socket.emit("file-preview-push", {
|
|
2118
2176
|
payload: encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, path)),
|
|
2119
2177
|
enc: true,
|
|
2120
|
-
mode
|
|
2178
|
+
mode,
|
|
2179
|
+
// B-562: only present for downloads, so a plain preview keeps the old wire shape.
|
|
2180
|
+
...intent ? { intent } : {}
|
|
2121
2181
|
});
|
|
2122
2182
|
return { delivered: true };
|
|
2123
2183
|
}
|
|
@@ -2222,7 +2282,26 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2222
2282
|
});
|
|
2223
2283
|
}
|
|
2224
2284
|
updateMetadata(handler) {
|
|
2225
|
-
this.
|
|
2285
|
+
void this.writeMetadata(handler);
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* B-587: the same write, awaitable with a ceiling — the hibernation stamp
|
|
2289
|
+
* must land before `session-end`. Resolves false on timeout (the write
|
|
2290
|
+
* itself keeps retrying in the background, exactly like updateMetadata).
|
|
2291
|
+
*/
|
|
2292
|
+
async updateMetadataAndWait(handler, timeoutMs = 1e4) {
|
|
2293
|
+
let timer;
|
|
2294
|
+
const timeout = new Promise((resolve) => {
|
|
2295
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
2296
|
+
});
|
|
2297
|
+
try {
|
|
2298
|
+
return await Promise.race([this.writeMetadata(handler).then(() => true), timeout]);
|
|
2299
|
+
} finally {
|
|
2300
|
+
if (timer) clearTimeout(timer);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
writeMetadata(handler) {
|
|
2304
|
+
return this.metadataLock.inLock(async () => {
|
|
2226
2305
|
let rateRefusals = 0;
|
|
2227
2306
|
await backoff(async () => {
|
|
2228
2307
|
let updated = handler(this.metadata);
|
|
@@ -2268,6 +2347,7 @@ class ApiSessionClient extends EventEmitter {
|
|
|
2268
2347
|
this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
|
|
2269
2348
|
this.agentStateVersion = answer.version;
|
|
2270
2349
|
rateRefusals = 0;
|
|
2350
|
+
if (Object.keys(this.agentState?.requests ?? {}).length > 0) this.noteActivity();
|
|
2271
2351
|
logger.debug("Agent state updated", this.agentState);
|
|
2272
2352
|
} else if (answer.result === "version-mismatch") {
|
|
2273
2353
|
if (answer.version > this.agentStateVersion) {
|
|
@@ -3084,7 +3164,7 @@ class ApiClient {
|
|
|
3084
3164
|
return new ApiSessionClient(this.credential.token, session, opts);
|
|
3085
3165
|
}
|
|
3086
3166
|
async machineSyncClient(machine) {
|
|
3087
|
-
const { ApiMachineClient } = await import('./apiMachine-
|
|
3167
|
+
const { ApiMachineClient } = await import('./apiMachine-CWndf1Vn.mjs');
|
|
3088
3168
|
return new ApiMachineClient(this.credential.token, machine);
|
|
3089
3169
|
}
|
|
3090
3170
|
push() {
|