very-happy-cli 0.2.159 → 0.2.161
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-VsfkZiVF.mjs → AcpBackend-6U6pQgx1.mjs} +4 -2
- package/dist/{AcpBackend-DUYFlyfN.cjs → AcpBackend-Ba98QDif.cjs} +78 -76
- package/dist/{AcpSessionManager-Bdv8LWXh.cjs → AcpSessionManager-BAY1Pggx.cjs} +9 -9
- package/dist/{AcpSessionManager-rYtVb0kN.mjs → AcpSessionManager-CoMWFVw3.mjs} +1 -1
- package/dist/BasePermissionHandler-2R0uH2CI.cjs +157 -0
- package/dist/BasePermissionHandler-BvvhBTja.mjs +155 -0
- package/dist/BaseReasoningProcessor-DyhO1uoU.mjs +198 -0
- package/dist/BaseReasoningProcessor-fsVNmCEF.cjs +200 -0
- package/dist/RemoteModeDisplay-D-HewyXg.mjs +150 -0
- package/dist/RemoteModeDisplay-NC1gPHtj.cjs +153 -0
- package/dist/agentAttachments-Dbw8iMCZ.cjs +20 -0
- package/dist/agentAttachments-M_B5qEF2.mjs +18 -0
- package/dist/agentGuidance-B5NATuFa.cjs +28 -0
- package/dist/agentGuidance-CQuNlNx8.mjs +20 -0
- package/dist/{agentHome-CvsJyeQB.mjs → agentHome-Ck1i1TQB.mjs} +8 -22
- package/dist/{agentHome-CHh4lmjM.cjs → agentHome-DvNnGphb.cjs} +14 -28
- package/dist/api-B2vLMS-z.cjs +3346 -0
- package/dist/api-SffjRQ1b.mjs +3339 -0
- package/dist/{types-Dh-s4Lqs.mjs → apiMachine-BpW9t8MO.mjs} +9116 -16205
- package/dist/{types-BbvK1Tr_.cjs → apiMachine-gFA54X7y.cjs} +9104 -16247
- package/dist/assistantTools-BfA0R3_m.cjs +380 -0
- package/dist/assistantTools-CgiTbnWb.mjs +376 -0
- package/dist/attachmentContent-CSGxr71v.mjs +82 -0
- package/dist/attachmentContent-DMMZzevR.cjs +88 -0
- package/dist/attachmentLimits-CzVrqgLR.cjs +354 -0
- package/dist/attachmentLimits-yba1uHFO.mjs +348 -0
- package/dist/auth-Bt4ceBBy.cjs +227 -0
- package/dist/auth-CYHjQ8oQ.mjs +225 -0
- package/dist/auth-DdyVZSo6.mjs +218 -0
- package/dist/auth-x4CEoysH.cjs +220 -0
- package/dist/authRelay-BdYkC1Po.cjs +156 -0
- package/dist/authRelay-DSAvg1uv.mjs +143 -0
- package/dist/{auto-DKmEls8Z.cjs → auto-BDXDUnjB.cjs} +70 -79
- package/dist/{auto-nb8GhRRy.mjs → auto-CXLlRi3a.mjs} +27 -36
- package/dist/backgroundTaskActivity-8PdPxrvy.mjs +149 -0
- package/dist/backgroundTaskActivity-CBvUdj39.cjs +157 -0
- package/dist/bootstrap-BNQq05jR.mjs +112 -0
- package/dist/bootstrap-CkgIq8N3.cjs +116 -0
- package/dist/browser-9pyhQr1R.mjs +20 -0
- package/dist/browser-BDOlKWYe.cjs +22 -0
- package/dist/claudeCliPath-BqkaH2oR.mjs +8 -0
- package/dist/claudeCliPath-U4HHmV4r.cjs +10 -0
- package/dist/claudeLocal-BDuGFnjJ.cjs +343 -0
- package/dist/claudeLocal-CQa8qnwq.mjs +339 -0
- package/dist/claudeLocalLauncher-Bd5I2-j6.cjs +154 -0
- package/dist/claudeLocalLauncher-CDqQI9ak.mjs +152 -0
- package/dist/cliUpdate-DsKXPFYp.cjs +120 -0
- package/dist/cliUpdate-Y34VGe9Y.mjs +112 -0
- package/dist/client-Brn-UwVk.mjs +100 -0
- package/dist/client-CXb1VJui.mjs +112 -0
- package/dist/client-C_axwRry.cjs +104 -0
- package/dist/client-DOBWJL3u.cjs +119 -0
- package/dist/codex/happyMcpStdioBridge.cjs +33 -14
- package/dist/codex/happyMcpStdioBridge.mjs +26 -7
- package/dist/codexAppServerClient-ZzhUTWPo.cjs +1090 -0
- package/dist/codexAppServerClient-oeQKD6Qf.mjs +1088 -0
- package/dist/codexCommand-C7H0NpBe.cjs +2088 -0
- package/dist/codexCommand-CJ82bl3l.mjs +2086 -0
- package/dist/codexThreadFork-BCaEMBiM.mjs +338 -0
- package/dist/codexThreadFork-BZqF-9bX.cjs +350 -0
- package/dist/{config-ClLtM6F3.mjs → config-BglnktIo.mjs} +7 -40
- package/dist/{config-DLx-vW3I.cjs → config-CYpL1Ahd.cjs} +26 -59
- package/dist/configuration-DoWFJUPm.mjs +170 -0
- package/dist/configuration-v9f8LM9T.cjs +181 -0
- package/dist/connect-hgcNjyAB.mjs +682 -0
- package/dist/connect-yEvjdRvx.cjs +684 -0
- package/dist/constants-BC4St0xd.mjs +11 -0
- package/dist/constants-VJ0N6WuG.cjs +17 -0
- package/dist/contentLogMetadata-BlWI0egu.mjs +51 -0
- package/dist/contentLogMetadata-ZSFk_NjQ.cjs +54 -0
- package/dist/context-B45vMtSZ.cjs +69 -0
- package/dist/context-C9GHPLEm.mjs +65 -0
- package/dist/controlClient-DjoKTtgK.mjs +260 -0
- package/dist/controlClient-fEHE85bH.cjs +279 -0
- package/dist/createSessionMetadata-BRLB9CNO.cjs +58 -0
- package/dist/createSessionMetadata-mIeehclp.mjs +54 -0
- package/dist/defaultPermissionMode-BnxJPVHT.mjs +4 -0
- package/dist/defaultPermissionMode-CxmTXUQR.cjs +7 -0
- package/dist/detectCLI-CSGMlV51.mjs +58 -0
- package/dist/detectCLI-DR9ZaN6B.cjs +61 -0
- package/dist/deterministicJson-DKDP_mM-.cjs +507 -0
- package/dist/deterministicJson-p835AdAU.mjs +502 -0
- package/dist/doctor-BPkYWSuq.mjs +75 -0
- package/dist/doctor-BeUuQXFs.mjs +391 -0
- package/dist/doctor-hVNnSZJn.cjs +395 -0
- package/dist/doctor-u46qYYKX.cjs +79 -0
- package/dist/doctorReadiness-BCZGcN0a.cjs +151 -0
- package/dist/doctorReadiness-C208SMN9.mjs +142 -0
- package/dist/editPaths-BVfS_FFL.mjs +68 -0
- package/dist/editPaths-Bqp4OFPw.cjs +73 -0
- package/dist/ensureDaemonRunning-CO7d1gOC.mjs +61 -0
- package/dist/ensureDaemonRunning-Dg9aZfjs.cjs +64 -0
- package/dist/handleResumeCommand-BiTPK0qd.mjs +240 -0
- package/dist/handleResumeCommand-DnVmy7a3.cjs +245 -0
- package/dist/ids-B6ZC0HGt.cjs +13 -0
- package/dist/ids-DU6sLx4C.mjs +10 -0
- package/dist/index-B6UGRQ7h.mjs +102 -0
- package/dist/{index-2mCaeKyf.mjs → index-CAFwetLk.mjs} +68 -38
- package/dist/index-Cqx-Raq6.mjs +68 -0
- package/dist/index-D3kI0hDR.cjs +107 -0
- package/dist/index-DA7yINuk.cjs +994 -0
- package/dist/{index-BEOMECtE.cjs → index-LIn6nCcq.cjs} +121 -91
- package/dist/index-Pf2cV9cn.cjs +182 -0
- package/dist/index-SPGPenK5.mjs +158 -0
- package/dist/index-gNTWtSKN.cjs +71 -0
- package/dist/index-qdS1friN.mjs +949 -0
- package/dist/index.cjs +5 -46
- package/dist/index.mjs +5 -46
- package/dist/{install-BPhJppvd.mjs → install-BO_W7VhL.mjs} +37 -37
- package/dist/install-Bu85vlHD.cjs +88 -0
- package/dist/install-ClUUl3yp.mjs +86 -0
- package/dist/{install-BOHrUaFM.cjs → install-Cs5qAPrB.cjs} +38 -38
- package/dist/{installPiTools-DuZ6jZvX.cjs → installPiTools-BKnXjrVu.cjs} +2 -3
- package/dist/{installPiTools-Cj7yU9Fc.mjs → installPiTools-B_CdM5_2.mjs} +1 -2
- package/dist/{installTerminalHooks-Cou3WUf3.cjs → installTerminalHooks-BQZbvxsZ.cjs} +5 -40
- package/dist/{installTerminalHooks-WeznjkuC.mjs → installTerminalHooks-By7gBMEF.mjs} +3 -38
- package/dist/lib.cjs +28 -19
- package/dist/lib.d.cts +12 -2
- package/dist/lib.d.mts +12 -2
- package/dist/lib.mjs +23 -14
- package/dist/lidState-C2dI0FAN.mjs +297 -0
- package/dist/lidState-KHHu1015.cjs +305 -0
- package/dist/limits-C-a7gr04.cjs +43 -0
- package/dist/limits-DIo7rEBR.mjs +36 -0
- package/dist/localHappyAgentAuth-BXiHPXdC.cjs +86 -0
- package/dist/localHappyAgentAuth-DCsetiyG.mjs +82 -0
- package/dist/logger-Bc8-u1w0.cjs +275 -0
- package/dist/logger-fXoNzNuB.mjs +271 -0
- package/dist/loginShellEnv-BkuYtExZ.cjs +182 -0
- package/dist/loginShellEnv-Dw8M7tkI.mjs +167 -0
- package/dist/machineMetadata-BHjehxJY.mjs +38 -0
- package/dist/machineMetadata-BibDMFVx.cjs +41 -0
- package/dist/main-BktM4A1K.mjs +939 -0
- package/dist/main-CLaX-t-b.cjs +941 -0
- package/dist/manager-BQ4flvQZ.mjs +101 -0
- package/dist/manager-Cly8xVIR.cjs +105 -0
- package/dist/{mcp-Dy3f_K0h.mjs → mcp-CeUd9KDr.mjs} +27 -33
- package/dist/{mcp-CPYbtsYG.cjs → mcp-GBfE70nk.cjs} +42 -48
- package/dist/messageBuffer-BWlGgR3A.mjs +71 -0
- package/dist/messageBuffer-fJMH6uY8.cjs +73 -0
- package/dist/mirrorProtocol-BNLtoWjO.mjs +170 -0
- package/dist/mirrorProtocol-BUtmg1ws.cjs +186 -0
- package/dist/oneShotPrompts-CL0dip9C.cjs +16 -0
- package/dist/oneShotPrompts-DT4p6RNd.mjs +12 -0
- package/dist/package-Cl5BEP5x.cjs +173 -0
- package/dist/package-uOg9SCKi.mjs +171 -0
- package/dist/path-B7zW-WwE.cjs +18 -0
- package/dist/path-D2wdaNSk.mjs +15 -0
- package/dist/peerTools-CIeiy9wn.cjs +283 -0
- package/dist/peerTools-Dz3_7Bkk.mjs +272 -0
- package/dist/permissionMode-CH4FoZfU.mjs +80 -0
- package/dist/permissionMode-CrV-XuMs.cjs +87 -0
- package/dist/persistence-CBNMzSa8.cjs +414 -0
- package/dist/persistence-oET5n61f.mjs +372 -0
- package/dist/piExtension.mjs +2 -1
- package/dist/piRunnerArgs-Bf7RUF__.cjs +66 -0
- package/dist/piRunnerArgs-Dk1ncwHF.mjs +59 -0
- package/dist/{piRuntime-NtF0YqjH.cjs → piRuntime-B_6TE9Eb.cjs} +4 -4
- package/dist/{piRuntime-kLZNpAAl.mjs → piRuntime-BwRdhK_N.mjs} +2 -2
- package/dist/{piTerminal-B0fEOV_2.mjs → piTerminal-Bap3R8Re.mjs} +32 -35
- package/dist/{piTerminal-9J0GAKzb.cjs → piTerminal-CagmEoez.cjs} +32 -35
- package/dist/previewPath-B0rBdhy1.cjs +83 -0
- package/dist/previewPath-CXN4Vag0.mjs +81 -0
- package/dist/projectPath-BTBIMB57.mjs +10 -0
- package/dist/projectPath-ChLhdOyt.cjs +13 -0
- package/dist/registerCommonHandlers-BjSV2Skz.cjs +538 -0
- package/dist/registerCommonHandlers-CrgvJsOy.mjs +536 -0
- package/dist/registerKillSessionHandler-6TC2S3lf.cjs +366 -0
- package/dist/registerKillSessionHandler-Cbc8Rgtd.mjs +363 -0
- package/dist/remoteSessionClient-BNx78NLb.cjs +634 -0
- package/dist/remoteSessionClient-CO7qOjR0.mjs +612 -0
- package/dist/resources-BdFBQi8r.mjs +117 -0
- package/dist/resources-JDPugcDq.cjs +120 -0
- package/dist/run-2l5vSt2h.mjs +5743 -0
- package/dist/run-D5xAEWSB.cjs +5766 -0
- package/dist/runClaude-BX6ixjtW.cjs +894 -0
- package/dist/runClaude-BgN6xo05.mjs +892 -0
- package/dist/runClaudeDeps-Bp20MScE.cjs +4168 -0
- package/dist/runClaudeDeps-COBBhD9o.mjs +4129 -0
- package/dist/{runGemini-F-mqx3_K.cjs → runGemini-CSMPkt0p.cjs} +202 -175
- package/dist/{runGemini-DV6Ouadt.mjs → runGemini-Cc2jq-uh.mjs} +58 -31
- package/dist/{runOpenClaw-D7MlPS5n.mjs → runOpenClaw-CIlCwdW2.mjs} +31 -32
- package/dist/{runOpenClaw-Qqo9j63M.cjs → runOpenClaw-YBwua4Rf.cjs} +64 -65
- package/dist/sandbox-C4gXLP1p.cjs +187 -0
- package/dist/sandbox-CNkwOtHI.mjs +180 -0
- package/dist/selfCheck-CU8xSDsl.cjs +87 -0
- package/dist/selfCheck-hJ6PCh7v.mjs +84 -0
- package/dist/{send-CLhYXNgy.mjs → send-CGHcKZ-w.mjs} +12 -5
- package/dist/{send-4qJTCAYW.cjs → send-DY9Nr-x4.cjs} +16 -9
- package/dist/server-II51Mimf.cjs +407 -0
- package/dist/server-m2b5pamZ.mjs +404 -0
- package/dist/sessionLock-7ePAYDOg.cjs +205 -0
- package/dist/sessionLock-Cw6FmbMv.mjs +197 -0
- package/dist/sessionModeFile-BVCV5f7E.cjs +36 -0
- package/dist/sessionModeFile-CDmDyRkD.mjs +32 -0
- package/dist/sessionOps-C_f1wKOr.mjs +760 -0
- package/dist/sessionOps-DJdExmBy.cjs +783 -0
- package/dist/sessionScanner-CaAHLyNV.mjs +206 -0
- package/dist/sessionScanner-D1goKdd3.cjs +209 -0
- package/dist/{sessions-Bh1pyddi.cjs → sessions-DGs6ALNo.cjs} +37 -28
- package/dist/{sessions-CzIH2rGp.mjs → sessions-DnvmWUel.mjs} +17 -8
- package/dist/setupOfflineReconnection-CVViqZft.mjs +72 -0
- package/dist/setupOfflineReconnection-R7XuR_sj.cjs +74 -0
- package/dist/smallFastModel-BLNgMrwR.mjs +18 -0
- package/dist/smallFastModel-D_uxGMo3.cjs +21 -0
- package/dist/{spawn-CmFOSVdW.cjs → spawn-CXTH7qg1.cjs} +61 -65
- package/dist/{spawn-CPIWlPOM.mjs → spawn-DNYSvFtC.mjs} +35 -40
- package/dist/spawnAgents-BGQiEF-w.cjs +52 -0
- package/dist/spawnAgents-DZzZ9jMI.mjs +45 -0
- package/dist/spawnHappyCLI-BhYj84rv.cjs +66 -0
- package/dist/spawnHappyCLI-cqWQbwsb.mjs +64 -0
- package/dist/specialCommands-BSqhYg5X.mjs +52 -0
- package/dist/specialCommands-DSsTeRej.cjs +54 -0
- package/dist/startFileWatcher-CKKx-8ZO.cjs +71 -0
- package/dist/startFileWatcher-CdegMbJj.mjs +69 -0
- package/dist/startupPlan-BLMbfQIH.cjs +12 -0
- package/dist/startupPlan-DFMyNgAs.mjs +10 -0
- package/dist/streamRelay-BiKw59Cc.cjs +233 -0
- package/dist/streamRelay-FPVbHpbM.mjs +231 -0
- package/dist/sync-CVk4QERO.cjs +71 -0
- package/dist/sync-CxD-w_40.mjs +69 -0
- package/dist/systemPrompt-BygJcmbi.cjs +97 -0
- package/dist/systemPrompt-DmtypUc7.mjs +94 -0
- package/dist/{teams-CEahj4cm.mjs → teams-BOC6nIPL.mjs} +9 -40
- package/dist/{teams-CB1R9-Z9.cjs → teams-BsvpOBfn.cjs} +14 -45
- package/dist/template-BaHAmH2K.cjs +129 -0
- package/dist/template-CiOPa2rd.mjs +121 -0
- package/dist/{terminalTitleSuggest-DKgX3osW.mjs → terminalTitleSuggest-CeKsX_V6.mjs} +1 -9
- package/dist/{terminalTitleSuggest-Dji8I0Jy.cjs → terminalTitleSuggest-DhvRFX3H.cjs} +0 -10
- package/dist/terminals-B_bfC9c2.cjs +250 -0
- package/dist/terminals-Dlg0x3nY.mjs +235 -0
- package/dist/time-BZNdNiIV.mjs +38 -0
- package/dist/time-CNRE4ChD.cjs +42 -0
- package/dist/titleGenerator-CFRhU-xq.cjs +172 -0
- package/dist/titleGenerator-ox6ptCsp.mjs +166 -0
- package/dist/tmuxSocket-B8Yx20sT.mjs +19 -0
- package/dist/tmuxSocket-D-Xt6Vn-.cjs +24 -0
- package/dist/{todo-DqyRI4wP.cjs → todo-B-KB7oAB.cjs} +15 -12
- package/dist/{todo-Cknp5D4U.mjs → todo-C5KBVbUw.mjs} +11 -8
- package/dist/tools-BZabNIid.mjs +177 -0
- package/dist/tools-BmQQUATY.mjs +60 -0
- package/dist/tools-CsSovyNp.cjs +180 -0
- package/dist/tools-lMDra4Pv.cjs +63 -0
- package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
- package/dist/trimIdent-BAjmv_TG.mjs +20 -0
- package/dist/types-CRS-srZK.cjs +66 -0
- package/dist/types-CkqAACXx.mjs +64 -0
- package/dist/uninstall-B1WLtC1d.mjs +47 -0
- package/dist/uninstall-fvA5aWpU.cjs +49 -0
- package/package.json +7 -7
- package/scripts/session_hook_forwarder.cjs +9 -2
- package/dist/agentGuidance-BRDN1NoZ.cjs +0 -2217
- package/dist/agentGuidance-KgvYuF3R.mjs +0 -2145
- package/dist/index-BF6WfgV5.mjs +0 -19624
- package/dist/index-C-JazrMB.mjs +0 -52
- package/dist/index-blDSadUR.cjs +0 -58
- package/dist/index-rH3DrQ5B.cjs +0 -19688
- package/dist/limits-BH5CV5vR.cjs +0 -2683
- package/dist/limits-CjRj8IX5.mjs +0 -2558
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var logger = require('./logger-Bc8-u1w0.cjs');
|
|
4
|
+
var claudeLocal = require('./claudeLocal-BDuGFnjJ.cjs');
|
|
5
|
+
var sessionScanner = require('./sessionScanner-D1goKdd3.cjs');
|
|
6
|
+
require('chalk');
|
|
7
|
+
require('node:util');
|
|
8
|
+
require('./configuration-v9f8LM9T.cjs');
|
|
9
|
+
require('node:fs');
|
|
10
|
+
require('node:os');
|
|
11
|
+
require('node:path');
|
|
12
|
+
require('./package-Cl5BEP5x.cjs');
|
|
13
|
+
require('node:fs/promises');
|
|
14
|
+
require('cross-spawn');
|
|
15
|
+
require('node:readline');
|
|
16
|
+
require('node:crypto');
|
|
17
|
+
require('./smallFastModel-D_uxGMo3.cjs');
|
|
18
|
+
require('./path-B7zW-WwE.cjs');
|
|
19
|
+
require('./systemPrompt-BygJcmbi.cjs');
|
|
20
|
+
require('./index-DA7yINuk.cjs');
|
|
21
|
+
require('zod');
|
|
22
|
+
require('@paralleldrive/cuid2');
|
|
23
|
+
require('./trimIdent-4gvk9Wk6.cjs');
|
|
24
|
+
require('./agentGuidance-B5NATuFa.cjs');
|
|
25
|
+
require('./manager-Cly8xVIR.cjs');
|
|
26
|
+
require('@anthropic-ai/sandbox-runtime');
|
|
27
|
+
require('./contentLogMetadata-ZSFk_NjQ.cjs');
|
|
28
|
+
require('./claudeCliPath-U4HHmV4r.cjs');
|
|
29
|
+
require('./projectPath-ChLhdOyt.cjs');
|
|
30
|
+
require('path');
|
|
31
|
+
require('url');
|
|
32
|
+
require('./sync-CVk4QERO.cjs');
|
|
33
|
+
require('./time-CNRE4ChD.cjs');
|
|
34
|
+
require('./types-CRS-srZK.cjs');
|
|
35
|
+
require('./startFileWatcher-CKKx-8ZO.cjs');
|
|
36
|
+
require('fs/promises');
|
|
37
|
+
|
|
38
|
+
async function claudeLocalLauncher(session) {
|
|
39
|
+
const scanner = await sessionScanner.createSessionScanner({
|
|
40
|
+
sessionId: session.sessionId,
|
|
41
|
+
workingDirectory: session.path,
|
|
42
|
+
onMessage: (message) => {
|
|
43
|
+
if (message.type !== "summary") {
|
|
44
|
+
session.client.sendClaudeSessionMessage(message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const scannerSessionCallback = (sessionId) => {
|
|
49
|
+
scanner.onNewSession(sessionId);
|
|
50
|
+
};
|
|
51
|
+
session.addSessionFoundCallback(scannerSessionCallback);
|
|
52
|
+
let exitReason = null;
|
|
53
|
+
let switchRequested = false;
|
|
54
|
+
const processAbortController = new AbortController();
|
|
55
|
+
let exutFuture = new sessionScanner.Future();
|
|
56
|
+
try {
|
|
57
|
+
async function abort() {
|
|
58
|
+
if (!processAbortController.signal.aborted) {
|
|
59
|
+
processAbortController.abort();
|
|
60
|
+
}
|
|
61
|
+
await exutFuture.promise;
|
|
62
|
+
}
|
|
63
|
+
async function doAbort() {
|
|
64
|
+
logger.logger.debug("[local]: doAbort");
|
|
65
|
+
session.onAbort();
|
|
66
|
+
if (!exitReason) {
|
|
67
|
+
exitReason = { type: "switch" };
|
|
68
|
+
}
|
|
69
|
+
session.client.closeClaudeSessionTurn("cancelled");
|
|
70
|
+
session.queue.reset();
|
|
71
|
+
await abort();
|
|
72
|
+
}
|
|
73
|
+
async function doSwitch() {
|
|
74
|
+
logger.logger.debug("[local]: doSwitch");
|
|
75
|
+
switchRequested = true;
|
|
76
|
+
if (!processAbortController.signal.aborted) {
|
|
77
|
+
processAbortController.abort();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
session.client.rpcHandlerManager.registerHandler("abort", doAbort);
|
|
81
|
+
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
82
|
+
session.queue.setOnMessage((_message, _mode) => {
|
|
83
|
+
void doSwitch();
|
|
84
|
+
});
|
|
85
|
+
if (session.queue.size() > 0) {
|
|
86
|
+
return { type: "switch" };
|
|
87
|
+
}
|
|
88
|
+
const handleSessionStart = (sessionId) => {
|
|
89
|
+
session.onSessionFound(sessionId);
|
|
90
|
+
scanner.onNewSession(sessionId);
|
|
91
|
+
};
|
|
92
|
+
while (true) {
|
|
93
|
+
if (exitReason) {
|
|
94
|
+
return exitReason;
|
|
95
|
+
}
|
|
96
|
+
logger.logger.debug("[local]: launch");
|
|
97
|
+
try {
|
|
98
|
+
await claudeLocal.claudeLocal({
|
|
99
|
+
path: session.path,
|
|
100
|
+
sessionId: session.sessionId,
|
|
101
|
+
onSessionFound: handleSessionStart,
|
|
102
|
+
onThinkingChange: session.onThinkingChange,
|
|
103
|
+
abort: processAbortController.signal,
|
|
104
|
+
claudeEnvVars: session.claudeEnvVars,
|
|
105
|
+
claudeArgs: session.claudeArgs,
|
|
106
|
+
mcpServers: session.mcpServers,
|
|
107
|
+
allowedTools: session.allowedTools,
|
|
108
|
+
hookSettingsPath: session.hookSettingsPath,
|
|
109
|
+
sandboxConfig: session.sandboxConfig
|
|
110
|
+
});
|
|
111
|
+
session.consumeOneTimeFlags();
|
|
112
|
+
if (!exitReason) {
|
|
113
|
+
session.client.closeClaudeSessionTurn("completed");
|
|
114
|
+
exitReason = switchRequested || session.queue.size() > 0 ? { type: "switch" } : { type: "exit", code: 0 };
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
} catch (e) {
|
|
118
|
+
logger.logger.debug("[local]: launch error", e);
|
|
119
|
+
if (e instanceof claudeLocal.ExitCodeError) {
|
|
120
|
+
if (exitReason) {
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
if (switchRequested || session.queue.size() > 0) {
|
|
124
|
+
session.client.closeClaudeSessionTurn("failed");
|
|
125
|
+
exitReason = { type: "switch" };
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
session.client.closeClaudeSessionTurn("failed");
|
|
129
|
+
exitReason = { type: "exit", code: e.exitCode };
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (!exitReason) {
|
|
133
|
+
session.client.sendSessionEvent({ type: "message", message: "Process exited unexpectedly" });
|
|
134
|
+
continue;
|
|
135
|
+
} else {
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
logger.logger.debug("[local]: launch done");
|
|
140
|
+
}
|
|
141
|
+
} finally {
|
|
142
|
+
exutFuture.resolve(void 0);
|
|
143
|
+
session.client.rpcHandlerManager.registerHandler("abort", async () => {
|
|
144
|
+
});
|
|
145
|
+
session.client.rpcHandlerManager.registerHandler("switch", async () => {
|
|
146
|
+
});
|
|
147
|
+
session.queue.setOnMessage(null);
|
|
148
|
+
session.removeSessionFoundCallback(scannerSessionCallback);
|
|
149
|
+
await scanner.cleanup();
|
|
150
|
+
}
|
|
151
|
+
return exitReason || { type: "exit", code: 0 };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
exports.claudeLocalLauncher = claudeLocalLauncher;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { l as logger } from './logger-fXoNzNuB.mjs';
|
|
2
|
+
import { claudeLocal, ExitCodeError } from './claudeLocal-CQa8qnwq.mjs';
|
|
3
|
+
import { c as createSessionScanner, F as Future } from './sessionScanner-CaAHLyNV.mjs';
|
|
4
|
+
import 'chalk';
|
|
5
|
+
import 'node:util';
|
|
6
|
+
import './configuration-DoWFJUPm.mjs';
|
|
7
|
+
import 'node:fs';
|
|
8
|
+
import 'node:os';
|
|
9
|
+
import 'node:path';
|
|
10
|
+
import './package-uOg9SCKi.mjs';
|
|
11
|
+
import 'node:fs/promises';
|
|
12
|
+
import 'cross-spawn';
|
|
13
|
+
import 'node:readline';
|
|
14
|
+
import 'node:crypto';
|
|
15
|
+
import './smallFastModel-BLNgMrwR.mjs';
|
|
16
|
+
import './path-D2wdaNSk.mjs';
|
|
17
|
+
import './systemPrompt-DmtypUc7.mjs';
|
|
18
|
+
import './index-qdS1friN.mjs';
|
|
19
|
+
import 'zod';
|
|
20
|
+
import '@paralleldrive/cuid2';
|
|
21
|
+
import './trimIdent-BAjmv_TG.mjs';
|
|
22
|
+
import './agentGuidance-CQuNlNx8.mjs';
|
|
23
|
+
import './manager-BQ4flvQZ.mjs';
|
|
24
|
+
import '@anthropic-ai/sandbox-runtime';
|
|
25
|
+
import './contentLogMetadata-BlWI0egu.mjs';
|
|
26
|
+
import './claudeCliPath-BqkaH2oR.mjs';
|
|
27
|
+
import './projectPath-BTBIMB57.mjs';
|
|
28
|
+
import 'path';
|
|
29
|
+
import 'url';
|
|
30
|
+
import './sync-CxD-w_40.mjs';
|
|
31
|
+
import './time-BZNdNiIV.mjs';
|
|
32
|
+
import './types-CkqAACXx.mjs';
|
|
33
|
+
import './startFileWatcher-CdegMbJj.mjs';
|
|
34
|
+
import 'fs/promises';
|
|
35
|
+
|
|
36
|
+
async function claudeLocalLauncher(session) {
|
|
37
|
+
const scanner = await createSessionScanner({
|
|
38
|
+
sessionId: session.sessionId,
|
|
39
|
+
workingDirectory: session.path,
|
|
40
|
+
onMessage: (message) => {
|
|
41
|
+
if (message.type !== "summary") {
|
|
42
|
+
session.client.sendClaudeSessionMessage(message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const scannerSessionCallback = (sessionId) => {
|
|
47
|
+
scanner.onNewSession(sessionId);
|
|
48
|
+
};
|
|
49
|
+
session.addSessionFoundCallback(scannerSessionCallback);
|
|
50
|
+
let exitReason = null;
|
|
51
|
+
let switchRequested = false;
|
|
52
|
+
const processAbortController = new AbortController();
|
|
53
|
+
let exutFuture = new Future();
|
|
54
|
+
try {
|
|
55
|
+
async function abort() {
|
|
56
|
+
if (!processAbortController.signal.aborted) {
|
|
57
|
+
processAbortController.abort();
|
|
58
|
+
}
|
|
59
|
+
await exutFuture.promise;
|
|
60
|
+
}
|
|
61
|
+
async function doAbort() {
|
|
62
|
+
logger.debug("[local]: doAbort");
|
|
63
|
+
session.onAbort();
|
|
64
|
+
if (!exitReason) {
|
|
65
|
+
exitReason = { type: "switch" };
|
|
66
|
+
}
|
|
67
|
+
session.client.closeClaudeSessionTurn("cancelled");
|
|
68
|
+
session.queue.reset();
|
|
69
|
+
await abort();
|
|
70
|
+
}
|
|
71
|
+
async function doSwitch() {
|
|
72
|
+
logger.debug("[local]: doSwitch");
|
|
73
|
+
switchRequested = true;
|
|
74
|
+
if (!processAbortController.signal.aborted) {
|
|
75
|
+
processAbortController.abort();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
session.client.rpcHandlerManager.registerHandler("abort", doAbort);
|
|
79
|
+
session.client.rpcHandlerManager.registerHandler("switch", doSwitch);
|
|
80
|
+
session.queue.setOnMessage((_message, _mode) => {
|
|
81
|
+
void doSwitch();
|
|
82
|
+
});
|
|
83
|
+
if (session.queue.size() > 0) {
|
|
84
|
+
return { type: "switch" };
|
|
85
|
+
}
|
|
86
|
+
const handleSessionStart = (sessionId) => {
|
|
87
|
+
session.onSessionFound(sessionId);
|
|
88
|
+
scanner.onNewSession(sessionId);
|
|
89
|
+
};
|
|
90
|
+
while (true) {
|
|
91
|
+
if (exitReason) {
|
|
92
|
+
return exitReason;
|
|
93
|
+
}
|
|
94
|
+
logger.debug("[local]: launch");
|
|
95
|
+
try {
|
|
96
|
+
await claudeLocal({
|
|
97
|
+
path: session.path,
|
|
98
|
+
sessionId: session.sessionId,
|
|
99
|
+
onSessionFound: handleSessionStart,
|
|
100
|
+
onThinkingChange: session.onThinkingChange,
|
|
101
|
+
abort: processAbortController.signal,
|
|
102
|
+
claudeEnvVars: session.claudeEnvVars,
|
|
103
|
+
claudeArgs: session.claudeArgs,
|
|
104
|
+
mcpServers: session.mcpServers,
|
|
105
|
+
allowedTools: session.allowedTools,
|
|
106
|
+
hookSettingsPath: session.hookSettingsPath,
|
|
107
|
+
sandboxConfig: session.sandboxConfig
|
|
108
|
+
});
|
|
109
|
+
session.consumeOneTimeFlags();
|
|
110
|
+
if (!exitReason) {
|
|
111
|
+
session.client.closeClaudeSessionTurn("completed");
|
|
112
|
+
exitReason = switchRequested || session.queue.size() > 0 ? { type: "switch" } : { type: "exit", code: 0 };
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
} catch (e) {
|
|
116
|
+
logger.debug("[local]: launch error", e);
|
|
117
|
+
if (e instanceof ExitCodeError) {
|
|
118
|
+
if (exitReason) {
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
if (switchRequested || session.queue.size() > 0) {
|
|
122
|
+
session.client.closeClaudeSessionTurn("failed");
|
|
123
|
+
exitReason = { type: "switch" };
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
session.client.closeClaudeSessionTurn("failed");
|
|
127
|
+
exitReason = { type: "exit", code: e.exitCode };
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (!exitReason) {
|
|
131
|
+
session.client.sendSessionEvent({ type: "message", message: "Process exited unexpectedly" });
|
|
132
|
+
continue;
|
|
133
|
+
} else {
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
logger.debug("[local]: launch done");
|
|
138
|
+
}
|
|
139
|
+
} finally {
|
|
140
|
+
exutFuture.resolve(void 0);
|
|
141
|
+
session.client.rpcHandlerManager.registerHandler("abort", async () => {
|
|
142
|
+
});
|
|
143
|
+
session.client.rpcHandlerManager.registerHandler("switch", async () => {
|
|
144
|
+
});
|
|
145
|
+
session.queue.setOnMessage(null);
|
|
146
|
+
session.removeSessionFoundCallback(scannerSessionCallback);
|
|
147
|
+
await scanner.cleanup();
|
|
148
|
+
}
|
|
149
|
+
return exitReason || { type: "exit", code: 0 };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export { claudeLocalLauncher };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
4
|
+
const MIN_CLI_UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
5
|
+
function withCurrentCliUpdateState(current, state) {
|
|
6
|
+
const { cliUpdate: _staleCliUpdate, ...rest } = current ?? {};
|
|
7
|
+
return {
|
|
8
|
+
...rest,
|
|
9
|
+
status: current?.status ?? "running",
|
|
10
|
+
...state ? { cliUpdate: state } : {}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function resolveCliUpdateCheckInterval(raw) {
|
|
14
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
15
|
+
if (!/^\d+$/.test(raw.trim())) return DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
16
|
+
const value = Number(raw.trim());
|
|
17
|
+
return Number.isSafeInteger(value) && value >= MIN_CLI_UPDATE_CHECK_INTERVAL_MS ? value : DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
18
|
+
}
|
|
19
|
+
function parseExactVersion(value) {
|
|
20
|
+
const match = /^(?:v)?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/.exec(value.trim());
|
|
21
|
+
if (!match) return null;
|
|
22
|
+
const preParts = match[4]?.split(".") ?? null;
|
|
23
|
+
const buildParts = match[5]?.split(".") ?? null;
|
|
24
|
+
if (preParts?.some((part) => !part || /^\d+$/.test(part) && part.length > 1 && part.startsWith("0"))) return null;
|
|
25
|
+
if (buildParts?.some((part) => !part)) return null;
|
|
26
|
+
const pre = preParts?.map((part) => /^\d+$/.test(part) ? Number(part) : part) ?? null;
|
|
27
|
+
const suffix = `${match[4] ? `-${match[4]}` : ""}${match[5] ? `+${match[5]}` : ""}`;
|
|
28
|
+
return { exact: `${match[1]}.${match[2]}.${match[3]}${suffix}`, core: [Number(match[1]), Number(match[2]), Number(match[3])], pre };
|
|
29
|
+
}
|
|
30
|
+
function compareExactVersions(left, right) {
|
|
31
|
+
const a = parseExactVersion(left);
|
|
32
|
+
const b = parseExactVersion(right);
|
|
33
|
+
if (!a || !b) return null;
|
|
34
|
+
for (let index = 0; index < 3; index += 1) {
|
|
35
|
+
if (a.core[index] !== b.core[index]) return a.core[index] < b.core[index] ? -1 : 1;
|
|
36
|
+
}
|
|
37
|
+
if (a.pre === null || b.pre === null) return a.pre === b.pre ? 0 : a.pre === null ? 1 : -1;
|
|
38
|
+
const count = Math.max(a.pre.length, b.pre.length);
|
|
39
|
+
for (let index = 0; index < count; index += 1) {
|
|
40
|
+
const av = a.pre[index];
|
|
41
|
+
const bv = b.pre[index];
|
|
42
|
+
if (av === void 0 || bv === void 0) return av === bv ? 0 : av === void 0 ? -1 : 1;
|
|
43
|
+
if (av === bv) continue;
|
|
44
|
+
if (typeof av === "number" && typeof bv === "string") return -1;
|
|
45
|
+
if (typeof av === "string" && typeof bv === "number") return 1;
|
|
46
|
+
return av < bv ? -1 : 1;
|
|
47
|
+
}
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
function deriveCliUpdateState(currentVersion, policy) {
|
|
51
|
+
if (!parseExactVersion(currentVersion)) return null;
|
|
52
|
+
const recommended = policy.recommendedVersion && parseExactVersion(policy.recommendedVersion) ? policy.recommendedVersion.replace(/^v/, "") : null;
|
|
53
|
+
const minimum = policy.minimumVersion && parseExactVersion(policy.minimumVersion) ? policy.minimumVersion.replace(/^v/, "") : null;
|
|
54
|
+
const autoUpdate = policy.autoUpdateVersion && parseExactVersion(policy.autoUpdateVersion) ? policy.autoUpdateVersion.replace(/^v/, "") : null;
|
|
55
|
+
if (!recommended && !minimum) return null;
|
|
56
|
+
const belowMinimum = minimum ? compareExactVersions(currentVersion, minimum) === -1 : false;
|
|
57
|
+
const belowRecommended = recommended ? compareExactVersions(currentVersion, recommended) === -1 : false;
|
|
58
|
+
return {
|
|
59
|
+
currentVersion: currentVersion.replace(/^v/, ""),
|
|
60
|
+
recommendedVersion: recommended ? parseExactVersion(recommended).exact : null,
|
|
61
|
+
minimumVersion: minimum ? parseExactVersion(minimum).exact : null,
|
|
62
|
+
status: belowMinimum ? "required" : belowRecommended ? "available" : "current",
|
|
63
|
+
autoUpdateVersion: autoUpdate ? parseExactVersion(autoUpdate).exact : null,
|
|
64
|
+
checkedAt: policy.checkedAt
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function cliInstallCommand(version) {
|
|
68
|
+
const parsed = parseExactVersion(version);
|
|
69
|
+
if (!parsed) return null;
|
|
70
|
+
return `npm install -g --allow-scripts=very-happy-cli,node-pty very-happy-cli@${parsed.exact}`;
|
|
71
|
+
}
|
|
72
|
+
function deriveLocalCliUpdateSummary(installedVersion, runningDaemonVersion, policy) {
|
|
73
|
+
const daemonComparison = runningDaemonVersion ? compareExactVersions(runningDaemonVersion, installedVersion) : 0;
|
|
74
|
+
const minimumComparison = policy?.minimumVersion ? compareExactVersions(installedVersion, policy.minimumVersion) : 0;
|
|
75
|
+
const recommendedComparison = policy?.recommendedVersion ? compareExactVersions(installedVersion, policy.recommendedVersion) : 0;
|
|
76
|
+
const installedStatus = minimumComparison === -1 ? "required" : recommendedComparison === -1 ? "available" : minimumComparison === null || recommendedComparison === null ? "unknown" : "current";
|
|
77
|
+
const targetVersion = installedStatus === "required" ? policy?.recommendedVersion ?? policy?.minimumVersion ?? null : installedStatus === "available" ? policy?.recommendedVersion ?? null : null;
|
|
78
|
+
return {
|
|
79
|
+
daemonMismatch: daemonComparison !== 0,
|
|
80
|
+
installedStatus,
|
|
81
|
+
targetVersion,
|
|
82
|
+
installCommand: targetVersion ? cliInstallCommand(targetVersion) : null
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function fetchCliUpdateState(serverUrl, currentVersion, fetcher = fetch, timeoutMs = 2e3) {
|
|
86
|
+
const controller = new AbortController();
|
|
87
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
88
|
+
try {
|
|
89
|
+
const response = await fetcher(`${serverUrl}/v1/version/cli`, {
|
|
90
|
+
signal: controller.signal,
|
|
91
|
+
headers: { accept: "application/json" }
|
|
92
|
+
});
|
|
93
|
+
if (!response.ok) return null;
|
|
94
|
+
const raw = await response.json();
|
|
95
|
+
if (!Number.isFinite(raw.checkedAt)) return null;
|
|
96
|
+
if (!["configured", "registry", "unavailable"].includes(String(raw.source))) return null;
|
|
97
|
+
if (raw.recommendedVersion !== null && raw.recommendedVersion !== void 0 && typeof raw.recommendedVersion !== "string") return null;
|
|
98
|
+
if (raw.minimumVersion !== null && raw.minimumVersion !== void 0 && typeof raw.minimumVersion !== "string") return null;
|
|
99
|
+
if (raw.autoUpdateVersion !== null && raw.autoUpdateVersion !== void 0 && typeof raw.autoUpdateVersion !== "string") return null;
|
|
100
|
+
return deriveCliUpdateState(currentVersion, {
|
|
101
|
+
recommendedVersion: raw.recommendedVersion ?? null,
|
|
102
|
+
minimumVersion: raw.minimumVersion ?? null,
|
|
103
|
+
autoUpdateVersion: raw.autoUpdateVersion ?? null,
|
|
104
|
+
checkedAt: raw.checkedAt,
|
|
105
|
+
source: raw.source
|
|
106
|
+
});
|
|
107
|
+
} catch {
|
|
108
|
+
return null;
|
|
109
|
+
} finally {
|
|
110
|
+
clearTimeout(timeout);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
exports.DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS = DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
115
|
+
exports.compareExactVersions = compareExactVersions;
|
|
116
|
+
exports.deriveLocalCliUpdateSummary = deriveLocalCliUpdateSummary;
|
|
117
|
+
exports.fetchCliUpdateState = fetchCliUpdateState;
|
|
118
|
+
exports.parseExactVersion = parseExactVersion;
|
|
119
|
+
exports.resolveCliUpdateCheckInterval = resolveCliUpdateCheckInterval;
|
|
120
|
+
exports.withCurrentCliUpdateState = withCurrentCliUpdateState;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS = 60 * 60 * 1e3;
|
|
2
|
+
const MIN_CLI_UPDATE_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3
|
+
function withCurrentCliUpdateState(current, state) {
|
|
4
|
+
const { cliUpdate: _staleCliUpdate, ...rest } = current ?? {};
|
|
5
|
+
return {
|
|
6
|
+
...rest,
|
|
7
|
+
status: current?.status ?? "running",
|
|
8
|
+
...state ? { cliUpdate: state } : {}
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function resolveCliUpdateCheckInterval(raw) {
|
|
12
|
+
if (raw === void 0 || raw.trim() === "") return DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
13
|
+
if (!/^\d+$/.test(raw.trim())) return DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
14
|
+
const value = Number(raw.trim());
|
|
15
|
+
return Number.isSafeInteger(value) && value >= MIN_CLI_UPDATE_CHECK_INTERVAL_MS ? value : DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS;
|
|
16
|
+
}
|
|
17
|
+
function parseExactVersion(value) {
|
|
18
|
+
const match = /^(?:v)?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$/.exec(value.trim());
|
|
19
|
+
if (!match) return null;
|
|
20
|
+
const preParts = match[4]?.split(".") ?? null;
|
|
21
|
+
const buildParts = match[5]?.split(".") ?? null;
|
|
22
|
+
if (preParts?.some((part) => !part || /^\d+$/.test(part) && part.length > 1 && part.startsWith("0"))) return null;
|
|
23
|
+
if (buildParts?.some((part) => !part)) return null;
|
|
24
|
+
const pre = preParts?.map((part) => /^\d+$/.test(part) ? Number(part) : part) ?? null;
|
|
25
|
+
const suffix = `${match[4] ? `-${match[4]}` : ""}${match[5] ? `+${match[5]}` : ""}`;
|
|
26
|
+
return { exact: `${match[1]}.${match[2]}.${match[3]}${suffix}`, core: [Number(match[1]), Number(match[2]), Number(match[3])], pre };
|
|
27
|
+
}
|
|
28
|
+
function compareExactVersions(left, right) {
|
|
29
|
+
const a = parseExactVersion(left);
|
|
30
|
+
const b = parseExactVersion(right);
|
|
31
|
+
if (!a || !b) return null;
|
|
32
|
+
for (let index = 0; index < 3; index += 1) {
|
|
33
|
+
if (a.core[index] !== b.core[index]) return a.core[index] < b.core[index] ? -1 : 1;
|
|
34
|
+
}
|
|
35
|
+
if (a.pre === null || b.pre === null) return a.pre === b.pre ? 0 : a.pre === null ? 1 : -1;
|
|
36
|
+
const count = Math.max(a.pre.length, b.pre.length);
|
|
37
|
+
for (let index = 0; index < count; index += 1) {
|
|
38
|
+
const av = a.pre[index];
|
|
39
|
+
const bv = b.pre[index];
|
|
40
|
+
if (av === void 0 || bv === void 0) return av === bv ? 0 : av === void 0 ? -1 : 1;
|
|
41
|
+
if (av === bv) continue;
|
|
42
|
+
if (typeof av === "number" && typeof bv === "string") return -1;
|
|
43
|
+
if (typeof av === "string" && typeof bv === "number") return 1;
|
|
44
|
+
return av < bv ? -1 : 1;
|
|
45
|
+
}
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
function deriveCliUpdateState(currentVersion, policy) {
|
|
49
|
+
if (!parseExactVersion(currentVersion)) return null;
|
|
50
|
+
const recommended = policy.recommendedVersion && parseExactVersion(policy.recommendedVersion) ? policy.recommendedVersion.replace(/^v/, "") : null;
|
|
51
|
+
const minimum = policy.minimumVersion && parseExactVersion(policy.minimumVersion) ? policy.minimumVersion.replace(/^v/, "") : null;
|
|
52
|
+
const autoUpdate = policy.autoUpdateVersion && parseExactVersion(policy.autoUpdateVersion) ? policy.autoUpdateVersion.replace(/^v/, "") : null;
|
|
53
|
+
if (!recommended && !minimum) return null;
|
|
54
|
+
const belowMinimum = minimum ? compareExactVersions(currentVersion, minimum) === -1 : false;
|
|
55
|
+
const belowRecommended = recommended ? compareExactVersions(currentVersion, recommended) === -1 : false;
|
|
56
|
+
return {
|
|
57
|
+
currentVersion: currentVersion.replace(/^v/, ""),
|
|
58
|
+
recommendedVersion: recommended ? parseExactVersion(recommended).exact : null,
|
|
59
|
+
minimumVersion: minimum ? parseExactVersion(minimum).exact : null,
|
|
60
|
+
status: belowMinimum ? "required" : belowRecommended ? "available" : "current",
|
|
61
|
+
autoUpdateVersion: autoUpdate ? parseExactVersion(autoUpdate).exact : null,
|
|
62
|
+
checkedAt: policy.checkedAt
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function cliInstallCommand(version) {
|
|
66
|
+
const parsed = parseExactVersion(version);
|
|
67
|
+
if (!parsed) return null;
|
|
68
|
+
return `npm install -g --allow-scripts=very-happy-cli,node-pty very-happy-cli@${parsed.exact}`;
|
|
69
|
+
}
|
|
70
|
+
function deriveLocalCliUpdateSummary(installedVersion, runningDaemonVersion, policy) {
|
|
71
|
+
const daemonComparison = runningDaemonVersion ? compareExactVersions(runningDaemonVersion, installedVersion) : 0;
|
|
72
|
+
const minimumComparison = policy?.minimumVersion ? compareExactVersions(installedVersion, policy.minimumVersion) : 0;
|
|
73
|
+
const recommendedComparison = policy?.recommendedVersion ? compareExactVersions(installedVersion, policy.recommendedVersion) : 0;
|
|
74
|
+
const installedStatus = minimumComparison === -1 ? "required" : recommendedComparison === -1 ? "available" : minimumComparison === null || recommendedComparison === null ? "unknown" : "current";
|
|
75
|
+
const targetVersion = installedStatus === "required" ? policy?.recommendedVersion ?? policy?.minimumVersion ?? null : installedStatus === "available" ? policy?.recommendedVersion ?? null : null;
|
|
76
|
+
return {
|
|
77
|
+
daemonMismatch: daemonComparison !== 0,
|
|
78
|
+
installedStatus,
|
|
79
|
+
targetVersion,
|
|
80
|
+
installCommand: targetVersion ? cliInstallCommand(targetVersion) : null
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
async function fetchCliUpdateState(serverUrl, currentVersion, fetcher = fetch, timeoutMs = 2e3) {
|
|
84
|
+
const controller = new AbortController();
|
|
85
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
86
|
+
try {
|
|
87
|
+
const response = await fetcher(`${serverUrl}/v1/version/cli`, {
|
|
88
|
+
signal: controller.signal,
|
|
89
|
+
headers: { accept: "application/json" }
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) return null;
|
|
92
|
+
const raw = await response.json();
|
|
93
|
+
if (!Number.isFinite(raw.checkedAt)) return null;
|
|
94
|
+
if (!["configured", "registry", "unavailable"].includes(String(raw.source))) return null;
|
|
95
|
+
if (raw.recommendedVersion !== null && raw.recommendedVersion !== void 0 && typeof raw.recommendedVersion !== "string") return null;
|
|
96
|
+
if (raw.minimumVersion !== null && raw.minimumVersion !== void 0 && typeof raw.minimumVersion !== "string") return null;
|
|
97
|
+
if (raw.autoUpdateVersion !== null && raw.autoUpdateVersion !== void 0 && typeof raw.autoUpdateVersion !== "string") return null;
|
|
98
|
+
return deriveCliUpdateState(currentVersion, {
|
|
99
|
+
recommendedVersion: raw.recommendedVersion ?? null,
|
|
100
|
+
minimumVersion: raw.minimumVersion ?? null,
|
|
101
|
+
autoUpdateVersion: raw.autoUpdateVersion ?? null,
|
|
102
|
+
checkedAt: raw.checkedAt,
|
|
103
|
+
source: raw.source
|
|
104
|
+
});
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
} finally {
|
|
108
|
+
clearTimeout(timeout);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as D, compareExactVersions as c, deriveLocalCliUpdateSummary as d, fetchCliUpdateState as f, parseExactVersion as p, resolveCliUpdateCheckInterval as r, withCurrentCliUpdateState as w };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { c as configuration } from './configuration-DoWFJUPm.mjs';
|
|
3
|
+
import { readSettings, readPersistedSessions, readCredentialsForConfiguredRelay } from './persistence-oET5n61f.mjs';
|
|
4
|
+
import { r as readTeamScope, t as teamScopePath, w as writeTeamScope } from './context-C9GHPLEm.mjs';
|
|
5
|
+
|
|
6
|
+
async function teamRequest(path, method, token, scoped, body) {
|
|
7
|
+
const response = await fetch(`${configuration.serverUrl}${path}`, {
|
|
8
|
+
method,
|
|
9
|
+
redirect: "error",
|
|
10
|
+
headers: { "content-type": "application/json", ...scoped ? { "x-happy-team-token": token } : { authorization: `Bearer ${token}` } },
|
|
11
|
+
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
12
|
+
signal: AbortSignal.timeout(25e3)
|
|
13
|
+
}).catch(() => {
|
|
14
|
+
throw new Error("Teams connection failed; outcome may be unknown. Reuse the request ID when retrying.");
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok) throw new Error(`Teams request failed (HTTP ${response.status})`);
|
|
17
|
+
try {
|
|
18
|
+
return await response.json();
|
|
19
|
+
} catch {
|
|
20
|
+
throw new Error("Teams returned an invalid response");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class TeamConnectionPreflightError extends Error {
|
|
24
|
+
}
|
|
25
|
+
const initializationLocks = /* @__PURE__ */ new Map();
|
|
26
|
+
async function serializeInitialization(path, work) {
|
|
27
|
+
const previous = initializationLocks.get(path) ?? Promise.resolve();
|
|
28
|
+
const next = previous.catch(() => {
|
|
29
|
+
}).then(work);
|
|
30
|
+
initializationLocks.set(path, next);
|
|
31
|
+
try {
|
|
32
|
+
return await next;
|
|
33
|
+
} finally {
|
|
34
|
+
if (initializationLocks.get(path) === next) initializationLocks.delete(path);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function createTeamsClient(sessionId) {
|
|
38
|
+
const scopePath = () => teamScopePath(sessionId ?? process.env.HAPPY_SESSION_ID);
|
|
39
|
+
return {
|
|
40
|
+
async initialize(input, options) {
|
|
41
|
+
const path = scopePath();
|
|
42
|
+
return serializeInitialization(path, async () => {
|
|
43
|
+
const priorScope = await readTeamScope(path);
|
|
44
|
+
if (priorScope && !options?.resumeAdoption) throw new Error("This session already has a team scope; use scoped team tools");
|
|
45
|
+
if (process.env.VH_TEAM_SCOPE_FILE) throw new Error("Assigned team scope is missing or already managed; ask the owner to restore it");
|
|
46
|
+
const sid = sessionId ?? process.env.HAPPY_SESSION_ID;
|
|
47
|
+
if (!sid) throw new Error("A managed session identity is required");
|
|
48
|
+
const machineId = (await readSettings()).machineId;
|
|
49
|
+
if (!machineId) throw new TeamConnectionPreflightError("Connect this machine to Very Happy before joining a team");
|
|
50
|
+
if (input.machineId && input.machineId !== machineId) throw new TeamConnectionPreflightError("Teams must use this session\u2019s local machine");
|
|
51
|
+
const persisted = readPersistedSessions()[sid];
|
|
52
|
+
if (!persisted || persisted.metadata.machineId !== machineId) throw new TeamConnectionPreflightError("Team identity must be a persisted session on this machine");
|
|
53
|
+
const credentials = await readCredentialsForConfiguredRelay();
|
|
54
|
+
if (!credentials) throw new TeamConnectionPreflightError("Sign in to Very Happy before creating or joining a team");
|
|
55
|
+
if (priorScope && !options?.expectedTeamId) throw new Error("This session already belongs to another team scope");
|
|
56
|
+
let teamId = input.teamId ?? options?.expectedTeamId;
|
|
57
|
+
if (!teamId) {
|
|
58
|
+
const created = await teamRequest("/v1/teams", "POST", credentials.token, false, { name: input.name, machineId, requestId: input.requestId });
|
|
59
|
+
teamId = created.team.id;
|
|
60
|
+
} else {
|
|
61
|
+
const existing = await teamRequest(`/v1/teams/${encodeURIComponent(teamId)}`, "GET", credentials.token, false);
|
|
62
|
+
if (existing.team?.machineId !== machineId) throw new TeamConnectionPreflightError("Team belongs to another machine");
|
|
63
|
+
}
|
|
64
|
+
if (options?.onTeamResolved) await options.onTeamResolved(teamId);
|
|
65
|
+
if (priorScope) {
|
|
66
|
+
if (priorScope.teamId !== teamId || priorScope.taskId) throw new Error("This session already belongs to another team scope");
|
|
67
|
+
const inspected = await teamRequest(`/v1/teams/${encodeURIComponent(teamId)}/agent`, "GET", priorScope.scopeToken, true);
|
|
68
|
+
const bot = inspected.team?.bots?.find((candidate) => candidate.id === priorScope.botId);
|
|
69
|
+
if (!bot?.root || bot.managed || bot.sessionId !== sid) throw new Error("Existing scope is not this session\u2019s root identity");
|
|
70
|
+
return { team: inspected.team, botId: priorScope.botId };
|
|
71
|
+
}
|
|
72
|
+
const result = await teamRequest(
|
|
73
|
+
`/v1/teams/${encodeURIComponent(teamId)}/actions`,
|
|
74
|
+
"POST",
|
|
75
|
+
credentials.token,
|
|
76
|
+
false,
|
|
77
|
+
{ requestId: input.requestId, action: { type: "join", name: input.name, sessionId: sid, ...input.botId ? { botId: input.botId } : {} } }
|
|
78
|
+
);
|
|
79
|
+
if (!result.credential?.token || !result.credential?.botId) throw new Error("Team join did not issue a credential");
|
|
80
|
+
await writeTeamScope(path, { serverUrl: configuration.serverUrl, teamId, botId: result.credential.botId, scopeToken: result.credential.token });
|
|
81
|
+
return { team: result.team, botId: result.credential.botId };
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
async inspect() {
|
|
85
|
+
const scope = await readTeamScope(scopePath());
|
|
86
|
+
if (!scope) throw new Error("Join or create a team first");
|
|
87
|
+
const { credential: _credential, ...safe } = await teamRequest(`/v1/teams/${encodeURIComponent(scope.teamId)}/agent`, "GET", scope.scopeToken, true);
|
|
88
|
+
return safe;
|
|
89
|
+
},
|
|
90
|
+
async action(action, requestId = randomUUID()) {
|
|
91
|
+
const scope = await readTeamScope(scopePath());
|
|
92
|
+
if (!scope) throw new Error("Join or create a team first");
|
|
93
|
+
const result = await teamRequest(`/v1/teams/${encodeURIComponent(scope.teamId)}/agent`, "POST", scope.scopeToken, true, { requestId, action });
|
|
94
|
+
const { credential: _credential, ...safe } = result;
|
|
95
|
+
return safe;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { TeamConnectionPreflightError as T, createTeamsClient as c, teamRequest as t };
|