very-happy-cli 0.2.158 → 0.2.160
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-DIDRig5G.cjs → AcpBackend-Bm2rdke8.cjs} +78 -76
- package/dist/{AcpBackend-vDVLHuYJ.mjs → AcpBackend-mzv8Dhba.mjs} +4 -2
- package/dist/{AcpSessionManager-C44U99CC.cjs → AcpSessionManager-BAY1Pggx.cjs} +9 -9
- package/dist/{AcpSessionManager-CmRjfhn3.mjs → AcpSessionManager-CoMWFVw3.mjs} +1 -1
- package/dist/BasePermissionHandler-CFHAxumV.cjs +157 -0
- package/dist/BasePermissionHandler-m3WVholL.mjs +155 -0
- package/dist/BaseReasoningProcessor-BFa9_rZA.cjs +200 -0
- package/dist/BaseReasoningProcessor-CYrKBXGm.mjs +198 -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-Dw8Jx_CJ.cjs → agentHome-CboCeKWq.cjs} +14 -28
- package/dist/{agentHome-CyLmGH5L.mjs → agentHome-Dj1C43aJ.mjs} +8 -22
- package/dist/api-CLMUr-SX.mjs +3339 -0
- package/dist/api-CgundNNX.cjs +3346 -0
- package/dist/{types-DIBF4U0Y.mjs → apiMachine-B9dLW_p5.mjs} +9116 -16015
- package/dist/{types-DnrPeN80.cjs → apiMachine-Bn8482VM.cjs} +9104 -16057
- package/dist/assistantTools-BTqPnlFl.cjs +380 -0
- package/dist/assistantTools-D6tuc6o4.mjs +376 -0
- package/dist/attachmentContent-DpiTJZb4.cjs +88 -0
- package/dist/attachmentContent-_kxRznNf.mjs +82 -0
- package/dist/attachmentLimits-CzVrqgLR.cjs +354 -0
- package/dist/attachmentLimits-yba1uHFO.mjs +348 -0
- package/dist/auth-BDOVh5h5.cjs +220 -0
- package/dist/auth-Cwutmdsa.mjs +225 -0
- package/dist/auth-PYHZQNPp.mjs +218 -0
- package/dist/auth-ba4WMYrN.cjs +227 -0
- package/dist/authRelay-BdYkC1Po.cjs +156 -0
- package/dist/authRelay-DSAvg1uv.mjs +143 -0
- package/dist/{auto-DZbNcTXx.cjs → auto-BOX_fgmR.cjs} +70 -79
- package/dist/{auto-BlMZPwOk.mjs → auto-BXu14yP_.mjs} +27 -36
- package/dist/backgroundTaskActivity-8PdPxrvy.mjs +149 -0
- package/dist/backgroundTaskActivity-CBvUdj39.cjs +157 -0
- package/dist/bootstrap-B5G1TijC.cjs +116 -0
- package/dist/bootstrap-hxXPCFMx.mjs +112 -0
- package/dist/browser-Y6Bl8L_O.cjs +22 -0
- package/dist/browser-jh2P0UVZ.mjs +20 -0
- package/dist/claudeCliPath-BqkaH2oR.mjs +8 -0
- package/dist/claudeCliPath-U4HHmV4r.cjs +10 -0
- package/dist/claudeLocal-BaY4fZKi.mjs +339 -0
- package/dist/claudeLocal-CRGG4Pea.cjs +343 -0
- package/dist/claudeLocalLauncher-D4T7MTqd.mjs +152 -0
- package/dist/claudeLocalLauncher-DyEbVzUN.cjs +154 -0
- package/dist/cliUpdate-DsKXPFYp.cjs +120 -0
- package/dist/cliUpdate-Y34VGe9Y.mjs +112 -0
- package/dist/client-3Ac-O4pw.cjs +104 -0
- package/dist/client-BPNbmtvO.cjs +119 -0
- package/dist/client-CeGKqqcJ.mjs +100 -0
- package/dist/client-ClR0K8zX.mjs +112 -0
- package/dist/codex/happyMcpStdioBridge.cjs +33 -14
- package/dist/codex/happyMcpStdioBridge.mjs +26 -7
- package/dist/codexAppServerClient-I3teiV-N.mjs +1088 -0
- package/dist/codexAppServerClient-q2FjnRcK.cjs +1090 -0
- package/dist/codexCommand-4zcccIoq.cjs +2088 -0
- package/dist/codexCommand-Cc9gcbdX.mjs +2086 -0
- package/dist/codexThreadFork-BH9IZPqD.cjs +350 -0
- package/dist/codexThreadFork-slzAseLx.mjs +338 -0
- package/dist/{config-BtPArqRH.mjs → config-CTx_jb-C.mjs} +7 -40
- package/dist/{config-DG84bjwF.cjs → config-Ci9Kpgwa.cjs} +26 -59
- package/dist/configuration-BSYpcPwE.cjs +181 -0
- package/dist/configuration-RfeNjFmd.mjs +170 -0
- package/dist/connect-BpOdzNbE.mjs +682 -0
- package/dist/connect-C2CiOUFs.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-DsDr6E2t.cjs +69 -0
- package/dist/context-H0Bcb9S_.mjs +65 -0
- package/dist/controlClient-BGbDcgWS.mjs +260 -0
- package/dist/controlClient-Bcwv3D21.cjs +279 -0
- package/dist/createSessionMetadata-BJxEnM-o.cjs +58 -0
- package/dist/createSessionMetadata-CVVkGjxV.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-C5CYTVpm.cjs +507 -0
- package/dist/deterministicJson-CzkFJWw1.mjs +502 -0
- package/dist/doctor-BPkYWSuq.mjs +75 -0
- package/dist/doctor-D2YJ-Yn2.cjs +395 -0
- package/dist/doctor-DOvByjbk.mjs +391 -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-BCwNrMyv.cjs +64 -0
- package/dist/ensureDaemonRunning-Dqa2pOjY.mjs +61 -0
- package/dist/handleResumeCommand-BvXYf5El.mjs +240 -0
- package/dist/handleResumeCommand-C2cKchpX.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-DPCsWlWK.cjs → index-B6pAdvJx.cjs} +131 -91
- package/dist/index-Bu5Zi_a9.cjs +182 -0
- package/dist/index-D3kI0hDR.cjs +107 -0
- package/dist/index-DA7yINuk.cjs +994 -0
- package/dist/index-DDeHXrIX.cjs +71 -0
- package/dist/index-DKLU_fD0.mjs +158 -0
- package/dist/{index-ZChGsuB7.mjs → index-DMZqWwsP.mjs} +79 -39
- package/dist/index-DVkMGPyS.mjs +68 -0
- package/dist/index-qdS1friN.mjs +949 -0
- package/dist/index.cjs +5 -46
- package/dist/index.mjs +5 -46
- package/dist/{install-DarS_Wco.mjs → install-BO_W7VhL.mjs} +37 -37
- package/dist/install-BgoC2e_2.cjs +88 -0
- package/dist/install-CFY3tYtJ.mjs +86 -0
- package/dist/{install-wKQGgXvN.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-DcQfee_O.cjs → installTerminalHooks-BQZbvxsZ.cjs} +5 -40
- package/dist/{installTerminalHooks-CpNbRFPz.mjs → installTerminalHooks-By7gBMEF.mjs} +3 -38
- package/dist/lib.cjs +28 -19
- package/dist/lib.d.cts +126 -2
- package/dist/lib.d.mts +126 -2
- package/dist/lib.mjs +23 -14
- package/dist/lidState-BeDfxxEX.cjs +305 -0
- package/dist/lidState-CeEt442o.mjs +297 -0
- package/dist/limits-C-a7gr04.cjs +43 -0
- package/dist/limits-DIo7rEBR.mjs +36 -0
- package/dist/localHappyAgentAuth-C-HQyiv6.mjs +82 -0
- package/dist/localHappyAgentAuth-D6rFhaoc.cjs +86 -0
- package/dist/logger-6HYUEXNk.mjs +271 -0
- package/dist/logger-CS0mw3fa.cjs +275 -0
- package/dist/loginShellEnv-BkuYtExZ.cjs +182 -0
- package/dist/loginShellEnv-Dw8M7tkI.mjs +167 -0
- package/dist/machineMetadata-DyDbODYd.cjs +41 -0
- package/dist/machineMetadata-oOzBfDfs.mjs +38 -0
- package/dist/main-BkxJP6JQ.cjs +941 -0
- package/dist/main-BwNIAI1A.mjs +939 -0
- package/dist/manager-BQ4flvQZ.mjs +101 -0
- package/dist/manager-Cly8xVIR.cjs +105 -0
- package/dist/{mcp-BN6bKIGb.mjs → mcp-B1A4I3TK.mjs} +27 -33
- package/dist/{mcp-DGdeUUDJ.cjs → mcp-Hszd7qpS.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-BhaKlnxz.mjs +171 -0
- package/dist/package-BwMrPwqH.cjs +173 -0
- package/dist/path-B7zW-WwE.cjs +18 -0
- package/dist/path-D2wdaNSk.mjs +15 -0
- package/dist/peerTools-BTqw97Gb.mjs +272 -0
- package/dist/peerTools-BvKtHXj8.cjs +283 -0
- package/dist/permissionMode-Cr5JCbB7.mjs +80 -0
- package/dist/permissionMode-CrV-XuMs.cjs +87 -0
- package/dist/persistence-HGW_ZVs9.mjs +372 -0
- package/dist/persistence-yKTH3-5X.cjs +414 -0
- package/dist/piExtension.mjs +2 -1
- package/dist/piRunnerArgs-BNloJCCg.cjs +66 -0
- package/dist/piRunnerArgs-BuX1UFWy.mjs +59 -0
- package/dist/{piRuntime-bkw2NAZU.mjs → piRuntime-CSGkwCKQ.mjs} +2 -2
- package/dist/{piRuntime-3qtbKujX.cjs → piRuntime-C_H7MJCM.cjs} +4 -4
- package/dist/{piTerminal-DilKwM7B.mjs → piTerminal-C8a1OrNQ.mjs} +32 -35
- package/dist/{piTerminal-BYxp3LMr.cjs → piTerminal-DNCZ6yTM.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-Ccvsz7Ou.mjs +536 -0
- package/dist/registerCommonHandlers-DskirN-_.cjs +538 -0
- package/dist/registerKillSessionHandler-DZeLXWcB.cjs +361 -0
- package/dist/registerKillSessionHandler-GYvHdipX.mjs +358 -0
- package/dist/remoteSessionClient-B0LraSB9.cjs +634 -0
- package/dist/remoteSessionClient-CYnXRynE.mjs +612 -0
- package/dist/resources-BdFBQi8r.mjs +117 -0
- package/dist/resources-JDPugcDq.cjs +120 -0
- package/dist/run-CJzxoHVh.cjs +5762 -0
- package/dist/run-D3ifupU3.mjs +5739 -0
- package/dist/runClaude-Ba01qT-u.mjs +848 -0
- package/dist/runClaude-Da3RirzE.cjs +850 -0
- package/dist/runClaudeDeps-DOt79DjU.mjs +3624 -0
- package/dist/runClaudeDeps-DOzEBMls.cjs +3649 -0
- package/dist/{runGemini-Cjii069p.mjs → runGemini-BGeTz57m.mjs} +58 -31
- package/dist/{runGemini-28O2sqyI.cjs → runGemini-DSr9LIxL.cjs} +202 -175
- package/dist/{runOpenClaw-CiMZad-H.cjs → runOpenClaw-B1mTxN35.cjs} +64 -65
- package/dist/{runOpenClaw-jaLr7KF1.mjs → runOpenClaw-CogSedIc.mjs} +31 -32
- package/dist/sandbox-CG7IyDTU.cjs +187 -0
- package/dist/sandbox-DTe6d54R.mjs +180 -0
- package/dist/selfCheck-C9mVrQwf.mjs +84 -0
- package/dist/selfCheck-Dc-mNSLb.cjs +87 -0
- package/dist/{send-D5ejHPXG.cjs → send-B7J_eaG3.cjs} +16 -9
- package/dist/{send-C9mOtChi.mjs → send-CBXJKc6O.mjs} +12 -5
- package/dist/server-CZTP_iOn.cjs +407 -0
- package/dist/server-DcVBv04l.mjs +404 -0
- package/dist/sessionLock-Bys1PNSo.cjs +205 -0
- package/dist/sessionLock-D-EG2CfG.mjs +197 -0
- package/dist/sessionModeFile-DMl3dw3r.mjs +32 -0
- package/dist/sessionModeFile-RSm0NQkH.cjs +36 -0
- package/dist/sessionOps-Dn8z85h_.cjs +783 -0
- package/dist/sessionOps-SuHW8Dfe.mjs +760 -0
- package/dist/sessionScanner-BOrGjMXL.cjs +209 -0
- package/dist/sessionScanner-CX3onqXh.mjs +206 -0
- package/dist/{sessions-W6771g3X.mjs → sessions-BEG_HTSi.mjs} +17 -8
- package/dist/{sessions-BNMPQoLE.cjs → sessions-D74aJbhL.cjs} +37 -28
- package/dist/setupOfflineReconnection-ByElY60m.cjs +74 -0
- package/dist/setupOfflineReconnection-DpvWTt69.mjs +72 -0
- package/dist/smallFastModel-BLNgMrwR.mjs +18 -0
- package/dist/smallFastModel-D_uxGMo3.cjs +21 -0
- package/dist/{spawn-D0QVhzRb.mjs → spawn-B7yro0b2.mjs} +26 -38
- package/dist/{spawn-Ddtom1cb.cjs → spawn-DgR0RKRs.cjs} +52 -64
- package/dist/spawnAgents-BGQiEF-w.cjs +52 -0
- package/dist/spawnAgents-DZzZ9jMI.mjs +45 -0
- package/dist/spawnHappyCLI-B2H5s4B_.mjs +64 -0
- package/dist/spawnHappyCLI-DBhwZT7O.cjs +66 -0
- package/dist/specialCommands-BSqhYg5X.mjs +52 -0
- package/dist/specialCommands-DSsTeRej.cjs +54 -0
- package/dist/startFileWatcher-B4VsLgjD.cjs +71 -0
- package/dist/startFileWatcher-DErVWZE4.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-C8gyQFMc.mjs +69 -0
- package/dist/sync-DccIKZ5_.cjs +71 -0
- package/dist/systemPrompt-BwTPWfMu.cjs +97 -0
- package/dist/systemPrompt-DX521JJz.mjs +94 -0
- package/dist/{teams-CqSwtw2O.mjs → teams-C32F1hqd.mjs} +9 -40
- package/dist/{teams-BZ1tayg_.cjs → teams-Dl8g8kTI.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-D0XyHOid.mjs +38 -0
- package/dist/time-DCuTyook.cjs +42 -0
- package/dist/titleGenerator-CQ8CoGhg.mjs +166 -0
- package/dist/titleGenerator-ChzMJsyg.cjs +172 -0
- package/dist/tmuxSocket-B8Yx20sT.mjs +19 -0
- package/dist/tmuxSocket-D-Xt6Vn-.cjs +24 -0
- package/dist/{todo-BYMg0fR0.cjs → todo-BvUOTa8G.cjs} +15 -12
- package/dist/{todo-BbusB1zM.mjs → todo-CZ6cFrrn.mjs} +11 -8
- package/dist/tools-BZtHF_qQ.mjs +177 -0
- package/dist/tools-Be3AoAwu.cjs +63 -0
- package/dist/tools-DQj0AeLk.cjs +180 -0
- package/dist/tools-DkluDcG4.mjs +60 -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-BkLzaJ6I.mjs +47 -0
- package/dist/uninstall-x-TUtf5H.cjs +49 -0
- package/package.json +7 -7
- package/dist/agentGuidance-CrR9l62U.mjs +0 -2145
- package/dist/agentGuidance-DwOWbX55.cjs +0 -2217
- package/dist/index-BG932eCh.cjs +0 -19655
- package/dist/index-CVCt3kSt.mjs +0 -19591
- package/dist/index-D5ScEErM.cjs +0 -58
- package/dist/index-DgO0FHOx.mjs +0 -52
- package/dist/limits-D2uN090G.mjs +0 -2528
- package/dist/limits-kqFqhfsh.cjs +0 -2652
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var name = "very-happy-cli";
|
|
4
|
+
var version = "0.2.160";
|
|
5
|
+
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
6
|
+
var author = "Kirill Dubovitskiy";
|
|
7
|
+
var contributors = [
|
|
8
|
+
"Mereith (very-happy-cli fork)"
|
|
9
|
+
];
|
|
10
|
+
var license = "MIT";
|
|
11
|
+
var engines = {
|
|
12
|
+
node: "^20.19.0 || ^22.13.0 || >=24.0.0"
|
|
13
|
+
};
|
|
14
|
+
var type = "module";
|
|
15
|
+
var homepage = "https://github.com/Mereithhh/very-happy";
|
|
16
|
+
var bugs = "https://github.com/Mereithhh/very-happy/issues";
|
|
17
|
+
var repository = {
|
|
18
|
+
type: "git",
|
|
19
|
+
url: "git+https://github.com/Mereithhh/very-happy.git"
|
|
20
|
+
};
|
|
21
|
+
var bin = {
|
|
22
|
+
"very-happy": "./bin/very-happy.mjs",
|
|
23
|
+
"very-happy-mcp": "./bin/very-happy-mcp.mjs"
|
|
24
|
+
};
|
|
25
|
+
var main = "./dist/index.cjs";
|
|
26
|
+
var module$1 = "./dist/index.mjs";
|
|
27
|
+
var types = "./dist/index.d.cts";
|
|
28
|
+
var exports$1 = {
|
|
29
|
+
"./pi-extension": {
|
|
30
|
+
types: "./dist/piExtension.d.mts",
|
|
31
|
+
"default": "./dist/piExtension.mjs"
|
|
32
|
+
},
|
|
33
|
+
".": {
|
|
34
|
+
require: {
|
|
35
|
+
types: "./dist/index.d.cts",
|
|
36
|
+
"default": "./dist/index.cjs"
|
|
37
|
+
},
|
|
38
|
+
"import": {
|
|
39
|
+
types: "./dist/index.d.mts",
|
|
40
|
+
"default": "./dist/index.mjs"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"./lib": {
|
|
44
|
+
require: {
|
|
45
|
+
types: "./dist/lib.d.cts",
|
|
46
|
+
"default": "./dist/lib.cjs"
|
|
47
|
+
},
|
|
48
|
+
"import": {
|
|
49
|
+
types: "./dist/lib.d.mts",
|
|
50
|
+
"default": "./dist/lib.mjs"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"./codex/happyMcpStdioBridge": {
|
|
54
|
+
require: {
|
|
55
|
+
types: "./dist/codex/happyMcpStdioBridge.d.cts",
|
|
56
|
+
"default": "./dist/codex/happyMcpStdioBridge.cjs"
|
|
57
|
+
},
|
|
58
|
+
"import": {
|
|
59
|
+
types: "./dist/codex/happyMcpStdioBridge.d.mts",
|
|
60
|
+
"default": "./dist/codex/happyMcpStdioBridge.mjs"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var files = [
|
|
65
|
+
"dist",
|
|
66
|
+
"bin",
|
|
67
|
+
"scripts",
|
|
68
|
+
"tools/licenses",
|
|
69
|
+
"package.json",
|
|
70
|
+
"README.md",
|
|
71
|
+
"LICENSE"
|
|
72
|
+
];
|
|
73
|
+
var scripts = {
|
|
74
|
+
typecheck: "tsc --noEmit",
|
|
75
|
+
"bundle:server": "node scripts/bundle-server.cjs",
|
|
76
|
+
"bundle:server:all": "node scripts/bundle-server.cjs --all-platforms",
|
|
77
|
+
"bundle:webapp": "node scripts/bundle-webapp.cjs",
|
|
78
|
+
build: "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc --noEmit && pkgroll",
|
|
79
|
+
test: "pnpm run build && vitest run --project unit",
|
|
80
|
+
"test:integration": "pnpm run build && vitest run --project integration-empty --project integration-plan-mode --project integration-authenticated",
|
|
81
|
+
"cli:install": "node scripts/install-local.cjs",
|
|
82
|
+
prepublishOnly: "pnpm test",
|
|
83
|
+
postinstall: "node scripts/unpack-tools.cjs && node scripts/fix-pty-perms.cjs"
|
|
84
|
+
};
|
|
85
|
+
var dependencies = {
|
|
86
|
+
"@agentclientprotocol/sdk": "^0.14.1",
|
|
87
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.281",
|
|
88
|
+
"@anthropic-ai/sandbox-runtime": "^0.0.37",
|
|
89
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
90
|
+
"@noble/ed25519": "^3.0.0",
|
|
91
|
+
"@noble/hashes": "^2.0.1",
|
|
92
|
+
"@paralleldrive/cuid2": "^2.2.2",
|
|
93
|
+
"@stablelib/base64": "^2.0.1",
|
|
94
|
+
"@stablelib/hex": "^2.0.1",
|
|
95
|
+
"@types/cross-spawn": "^6.0.6",
|
|
96
|
+
"@types/http-proxy": "^1.17.17",
|
|
97
|
+
"@types/react": "^19.2.7",
|
|
98
|
+
"@types/tmp": "^0.2.6",
|
|
99
|
+
axios: "^1.13.2",
|
|
100
|
+
chalk: "^5.6.2",
|
|
101
|
+
"cross-spawn": "^7.0.6",
|
|
102
|
+
"expo-server-sdk": "^3.15.0",
|
|
103
|
+
fastify: "5.8.5",
|
|
104
|
+
"fastify-type-provider-zod": "^6.1.0",
|
|
105
|
+
"http-proxy": "^1.18.1",
|
|
106
|
+
"http-proxy-middleware": "^3.0.7",
|
|
107
|
+
ink: "^6.5.1",
|
|
108
|
+
inquirer: "^13.2.2",
|
|
109
|
+
"node-pty": "^1.0.0",
|
|
110
|
+
open: "^10.2.0",
|
|
111
|
+
"ps-list": "^8.1.1",
|
|
112
|
+
react: "^19.2.0",
|
|
113
|
+
"socket.io-client": "^4.8.1",
|
|
114
|
+
tar: "^7.5.22",
|
|
115
|
+
tmp: "^0.2.7",
|
|
116
|
+
tweetnacl: "^1.0.3",
|
|
117
|
+
ws: "^8.21.3",
|
|
118
|
+
zod: "^4.0.0"
|
|
119
|
+
};
|
|
120
|
+
var optionalDependencies = {
|
|
121
|
+
"very-happy-tools-arm64-darwin": "0.2.160",
|
|
122
|
+
"very-happy-tools-x64-darwin": "0.2.160",
|
|
123
|
+
"very-happy-tools-arm64-linux": "0.2.160",
|
|
124
|
+
"very-happy-tools-x64-linux": "0.2.160",
|
|
125
|
+
"very-happy-tools-arm64-win32": "0.2.160",
|
|
126
|
+
"very-happy-tools-x64-win32": "0.2.160"
|
|
127
|
+
};
|
|
128
|
+
var devDependencies = {
|
|
129
|
+
"@slopus/happy-wire": "workspace:*",
|
|
130
|
+
"@xterm/addon-serialize": "0.13.0",
|
|
131
|
+
"@xterm/headless": "5.5.0",
|
|
132
|
+
"@types/inquirer": "^9.0.9",
|
|
133
|
+
"@types/node": ">=20",
|
|
134
|
+
"@types/ws": "^8.18.1",
|
|
135
|
+
"cross-env": "^10.1.0",
|
|
136
|
+
dotenv: "^16.6.1",
|
|
137
|
+
pkgroll: "^2.14.2",
|
|
138
|
+
"ts-node": "^10",
|
|
139
|
+
tsx: "^4.20.6",
|
|
140
|
+
typescript: "5.9.3",
|
|
141
|
+
vitest: "3.2.6"
|
|
142
|
+
};
|
|
143
|
+
var publishConfig = {
|
|
144
|
+
registry: "https://registry.npmjs.org"
|
|
145
|
+
};
|
|
146
|
+
var packageManager = "pnpm@10.11.0";
|
|
147
|
+
var packageJson = {
|
|
148
|
+
name: name,
|
|
149
|
+
version: version,
|
|
150
|
+
description: description,
|
|
151
|
+
author: author,
|
|
152
|
+
contributors: contributors,
|
|
153
|
+
license: license,
|
|
154
|
+
engines: engines,
|
|
155
|
+
type: type,
|
|
156
|
+
homepage: homepage,
|
|
157
|
+
bugs: bugs,
|
|
158
|
+
repository: repository,
|
|
159
|
+
bin: bin,
|
|
160
|
+
main: main,
|
|
161
|
+
module: module$1,
|
|
162
|
+
types: types,
|
|
163
|
+
exports: exports$1,
|
|
164
|
+
files: files,
|
|
165
|
+
scripts: scripts,
|
|
166
|
+
dependencies: dependencies,
|
|
167
|
+
optionalDependencies: optionalDependencies,
|
|
168
|
+
devDependencies: devDependencies,
|
|
169
|
+
publishConfig: publishConfig,
|
|
170
|
+
packageManager: packageManager
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
exports.packageJson = packageJson;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var os = require('node:os');
|
|
4
|
+
var path = require('node:path');
|
|
5
|
+
|
|
6
|
+
function getClaudeConfigDir() {
|
|
7
|
+
return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
|
|
8
|
+
}
|
|
9
|
+
function getClaudeProjectsRoot() {
|
|
10
|
+
return path.join(getClaudeConfigDir(), "projects");
|
|
11
|
+
}
|
|
12
|
+
function getProjectPath(workingDirectory) {
|
|
13
|
+
const projectId = path.resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
|
|
14
|
+
return path.join(getClaudeProjectsRoot(), projectId);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.getClaudeProjectsRoot = getClaudeProjectsRoot;
|
|
18
|
+
exports.getProjectPath = getProjectPath;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { resolve, join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
function getClaudeConfigDir() {
|
|
5
|
+
return process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
|
|
6
|
+
}
|
|
7
|
+
function getClaudeProjectsRoot() {
|
|
8
|
+
return join(getClaudeConfigDir(), "projects");
|
|
9
|
+
}
|
|
10
|
+
function getProjectPath(workingDirectory) {
|
|
11
|
+
const projectId = resolve(workingDirectory).replace(/[^a-zA-Z0-9-]/g, "-");
|
|
12
|
+
return join(getClaudeProjectsRoot(), projectId);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { getClaudeProjectsRoot as a, getProjectPath as g };
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { userInfo, hostname } from 'node:os';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { i as isValidSessionId } from './ids-DU6sLx4C.mjs';
|
|
5
|
+
import { f as listDaemonPeers } from './controlClient-BGbDcgWS.mjs';
|
|
6
|
+
import { readPersistedSessions } from './persistence-HGW_ZVs9.mjs';
|
|
7
|
+
import { s as sessionWebUrl, g as sendUserMessage } from './sessionOps-SuHW8Dfe.mjs';
|
|
8
|
+
import { b as sendRemotePeerMessage, d as deliverToSession, a as listRemotePeers } from './remoteSessionClient-CYnXRynE.mjs';
|
|
9
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
10
|
+
import { resolve, isAbsolute, dirname } from 'node:path';
|
|
11
|
+
|
|
12
|
+
const SESSION_PEER_SENT_FROM = "session-peer";
|
|
13
|
+
const CLI_PEER_SENDER_ID = "cli";
|
|
14
|
+
const MESSAGE_FOOTER = "This message comes from another agent session on this machine, not from the user.";
|
|
15
|
+
const MESSAGE_FOOTER_PREFIX = "This message comes from another agent session";
|
|
16
|
+
function messageFooterFor(sender) {
|
|
17
|
+
return sender.machine ? `${MESSAGE_FOOTER_PREFIX} on machine ${sanitizeHeaderValue(sender.machine, 128)}, not from the user.` : MESSAGE_FOOTER;
|
|
18
|
+
}
|
|
19
|
+
function sanitizeHeaderValue(value, max = 200) {
|
|
20
|
+
if (!value) return "";
|
|
21
|
+
const collapsed = value.replace(/\s+/g, " ").trim().slice(0, max);
|
|
22
|
+
return collapsed.replace(/[%"\];]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
|
|
23
|
+
}
|
|
24
|
+
function senderFields(sender) {
|
|
25
|
+
const parts = [];
|
|
26
|
+
if (sender.flavor) parts.push(`agent ${sanitizeHeaderValue(sender.flavor, 32)}`);
|
|
27
|
+
if (sender.cwd) parts.push(`cwd ${sanitizeHeaderValue(sender.cwd, 400)}`);
|
|
28
|
+
if (sender.machine) parts.push(`machine ${sanitizeHeaderValue(sender.machine, 128)}`);
|
|
29
|
+
return parts.map((part) => `; ${part}`).join("");
|
|
30
|
+
}
|
|
31
|
+
function quotedTitle(sender) {
|
|
32
|
+
return `"${sanitizeHeaderValue(sender.title, 120)}"`;
|
|
33
|
+
}
|
|
34
|
+
function formatSessionPeerMessage(input) {
|
|
35
|
+
const header = `[Very Happy session message ${input.id} from ${quotedTitle(input.from)} ${input.from.sessionId}${senderFields(input.from)}${input.replyTo ? `; re ${sanitizeHeaderValue(input.replyTo, 64)}` : ""}]`;
|
|
36
|
+
const base = messageFooterFor(input.from);
|
|
37
|
+
const routed = input.from.machine ? " (it is routed to that machine for you)" : "";
|
|
38
|
+
const footer = input.from.sessionId === CLI_PEER_SENDER_ID ? `${base} It was sent from the command line (\`very-happy sessions message\`), so there is no session to reply to; act on it here.` : `${base} Reply with session_message(to: "${input.from.sessionId}")${routed} \u2014 or \`very-happy sessions message ${input.from.sessionId} "<text>"\` \u2014 only when you have something to add (a question, a decision, a heads-up). Do not reply just to acknowledge or thank; the exchange ends when nothing is left to coordinate.`;
|
|
39
|
+
return `${header}
|
|
40
|
+
${input.body.trim()}
|
|
41
|
+
|
|
42
|
+
${footer}`;
|
|
43
|
+
}
|
|
44
|
+
function formatDuration(ms) {
|
|
45
|
+
const seconds = Math.max(0, Math.round(ms / 1e3));
|
|
46
|
+
if (seconds < 90) return `${seconds}s`;
|
|
47
|
+
const minutes = Math.round(seconds / 60);
|
|
48
|
+
if (minutes < 90) return `${minutes}m`;
|
|
49
|
+
return `${Math.round(minutes / 60)}h`;
|
|
50
|
+
}
|
|
51
|
+
function formatEditConflictNotice(input) {
|
|
52
|
+
const paths = input.paths && input.paths.length > 0 ? input.paths : [input.path];
|
|
53
|
+
const more = paths.length - 1;
|
|
54
|
+
const header = `[Very Happy edit conflict ${input.id}; file ${sanitizeHeaderValue(paths[0], 600)}${more > 0 ? `; more ${more}` : ""}; peer ${quotedTitle(input.peer)} ${input.peer.sessionId}${senderFields(input.peer)}; peer edited ${formatDuration(input.peerEditedAgoMs)} ago]`;
|
|
55
|
+
const window = formatDuration(input.windowMs);
|
|
56
|
+
const mirror = input.peer.flavor === "terminal-mirror";
|
|
57
|
+
const what = more > 0 ? `the same ${paths.length} files` : "the same file";
|
|
58
|
+
const advice = mirror ? `The peer is a terminal session (agent terminal-mirror): it cannot be messaged, and the person at that terminal owns those edits \u2014 re-read the file before changing it further and keep your change minimal.` : `No lock is held \u2014 coordinate before continuing: session_message(to: "${input.peer.sessionId}", body: "\u2026") saying what you are changing in ${more > 0 ? "these files" : "that file"} and asking what they are changing. One message that covers everything; do not send one per file.`;
|
|
59
|
+
const list = more > 0 ? `
|
|
60
|
+
Files:
|
|
61
|
+
${paths.map((p) => `- ${p}`).join("\n")}` : "";
|
|
62
|
+
return `${header}
|
|
63
|
+
Another session on this machine edited ${what} within the last ${window}. Both sessions received this notice. ${advice}${list}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const realFs = {
|
|
67
|
+
existsSync,
|
|
68
|
+
isDirectory: (path) => {
|
|
69
|
+
try {
|
|
70
|
+
return statSync(path).isDirectory();
|
|
71
|
+
} catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
readFileSync: (path) => readFileSync(path, "utf8")
|
|
76
|
+
};
|
|
77
|
+
function resolveRepoIdentity(cwd, fs = realFs) {
|
|
78
|
+
let dir = resolve(cwd);
|
|
79
|
+
for (let depth = 0; depth < 64; depth++) {
|
|
80
|
+
const dotGit = resolve(dir, ".git");
|
|
81
|
+
try {
|
|
82
|
+
if (fs.existsSync(dotGit)) {
|
|
83
|
+
if (fs.isDirectory(dotGit)) return { root: dir, common: dotGit };
|
|
84
|
+
const gitdir = fs.readFileSync(dotGit).match(/^gitdir:\s*(.+?)\s*$/m)?.[1];
|
|
85
|
+
if (gitdir) {
|
|
86
|
+
const absolute = isAbsolute(gitdir) ? gitdir : resolve(dir, gitdir);
|
|
87
|
+
const worktree = absolute.match(/^(.*[\\/]\.git)[\\/]worktrees[\\/][^\\/]+[\\/]?$/);
|
|
88
|
+
return { root: dir, common: worktree ? worktree[1] : absolute };
|
|
89
|
+
}
|
|
90
|
+
return { root: dir, common: dotGit };
|
|
91
|
+
}
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
const parent = dirname(dir);
|
|
95
|
+
if (parent === dir) break;
|
|
96
|
+
dir = parent;
|
|
97
|
+
}
|
|
98
|
+
return { root: null, common: null };
|
|
99
|
+
}
|
|
100
|
+
const PEER_SCOPES = ["repo", "cwd", "machine"];
|
|
101
|
+
function isPeerInScope(scope, self, other) {
|
|
102
|
+
if (scope === "machine") return true;
|
|
103
|
+
if (scope === "cwd") return resolve(self.cwd) === resolve(other.cwd);
|
|
104
|
+
if (self.repo.common && other.repo.common) return self.repo.common === other.repo.common;
|
|
105
|
+
return resolve(self.cwd) === resolve(other.cwd);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const SESSION_PEER_TOOL_NAMES = ["session_message", "session_peers"];
|
|
109
|
+
const SESSION_PEER_TOOL_SCHEMAS = {
|
|
110
|
+
session_message: {
|
|
111
|
+
title: "Message Another Session",
|
|
112
|
+
readOnly: false,
|
|
113
|
+
description: "Send a message to another agent session (find ids with session_peers). It lands in that session's chat with your title, session id and cwd, and tells the peer how to reply to you. Use it to coordinate when you both edit the same files: say what you are changing and ask what they are changing. Returns as soon as the message is queued; the reply arrives later as a message from that session. Sessions on this machine are reached directly; a session spawned by another machine of this account is routed to that machine's daemon (it must be online). Terminal-mirror sessions cannot receive messages.",
|
|
114
|
+
inputSchema: {
|
|
115
|
+
to: z.string().min(1).max(128).describe("Target session id (from session_peers, or a peer's message header)"),
|
|
116
|
+
body: z.string().min(1).max(16e3).describe("The message text"),
|
|
117
|
+
replyTo: z.string().min(1).max(64).optional().describe("Id of the peer message you are answering (from its header), if any"),
|
|
118
|
+
machineId: z.string().min(1).max(128).optional().describe("Machine id the target session runs on, when known (skips the lookup across the account's machines)")
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
session_peers: {
|
|
122
|
+
title: "List Peer Sessions",
|
|
123
|
+
readOnly: true,
|
|
124
|
+
description: 'List the other agent sessions running on this machine and the files each edited in the last 30 minutes. Default scope "repo": sessions in the same git repository, including its other worktrees (sameWorktree says whether they share your checkout). "cwd": the same directory only. "machine": every live session here. With machineId, list the live sessions on that other machine of this account instead (scope "machine" unless you pass a cwd that exists there).',
|
|
125
|
+
inputSchema: {
|
|
126
|
+
scope: z.enum(["repo", "cwd", "machine"]).optional().describe("repo (default) | cwd | machine"),
|
|
127
|
+
machineId: z.string().min(1).max(128).optional().describe("Another machine of this account (from the web's machine list) to list instead of this one"),
|
|
128
|
+
cwd: z.string().min(1).max(4096).optional().describe("With machineId: a directory on that machine to compute repo/cwd scope from")
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const PEER_MESSAGE_RATE_LIMIT = 8;
|
|
133
|
+
const PEER_MESSAGE_RATE_WINDOW_MS = 10 * 6e4;
|
|
134
|
+
async function listPeerSessions(context, scope = "repo") {
|
|
135
|
+
const self = context.self();
|
|
136
|
+
const repoOf = context.repoOf ?? resolveRepoIdentity;
|
|
137
|
+
const selfRepo = repoOf(self.cwd);
|
|
138
|
+
const sessions = await (context.listPeers ?? listDaemonPeers)();
|
|
139
|
+
const peers = sessions.filter((session) => session.sessionId !== self.sessionId).filter((session) => {
|
|
140
|
+
const cwd = session.cwd ?? "";
|
|
141
|
+
if (!cwd) return scope === "machine";
|
|
142
|
+
return isPeerInScope(scope, { cwd: self.cwd, repo: selfRepo }, { cwd, repo: repoOf(cwd) });
|
|
143
|
+
}).map((session) => ({
|
|
144
|
+
...session,
|
|
145
|
+
url: sessionWebUrl(session.sessionId),
|
|
146
|
+
sameWorktree: !!session.cwd && !!selfRepo.root && repoOf(session.cwd).root === selfRepo.root
|
|
147
|
+
}));
|
|
148
|
+
return { self: { sessionId: self.sessionId, cwd: self.cwd, repoRoot: selfRepo.root, scope }, scope, peers };
|
|
149
|
+
}
|
|
150
|
+
function defaultDeliver(to, persisted, text, localId) {
|
|
151
|
+
return deliverToSession(to, persisted, text, "session-message", {
|
|
152
|
+
sentFrom: SESSION_PEER_SENT_FROM,
|
|
153
|
+
resumeHint: "It has to be running to read a peer message; spawn a new session or ask the person."
|
|
154
|
+
}, {
|
|
155
|
+
send: (sessionId, key, body, client, options) => sendUserMessage(sessionId, key, body, client, { ...options, localId })
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function checkPeerSendBudget(sentTo, to, now, limit = PEER_MESSAGE_RATE_LIMIT, windowMs = PEER_MESSAGE_RATE_WINDOW_MS) {
|
|
159
|
+
const recent = (sentTo.get(to) ?? []).filter((t) => now - t <= windowMs);
|
|
160
|
+
sentTo.set(to, recent);
|
|
161
|
+
return { ok: recent.length < limit, count: recent.length };
|
|
162
|
+
}
|
|
163
|
+
async function sendPeerMessage(context, args) {
|
|
164
|
+
const self = context.self();
|
|
165
|
+
if (!isValidSessionId(args.to)) throw new Error("Invalid session id");
|
|
166
|
+
if (args.to === self.sessionId) throw new Error("That is this session; message a peer instead");
|
|
167
|
+
const body = typeof args.body === "string" ? args.body.trim() : "";
|
|
168
|
+
if (!body) throw new Error("body must be non-empty");
|
|
169
|
+
const now = (context.now ?? Date.now)();
|
|
170
|
+
const persisted = (context.readPersisted ?? readPersistedSessions)()[args.to];
|
|
171
|
+
if (!persisted || args.machineId) {
|
|
172
|
+
const remote = context.remoteMessage === void 0 ? sendRemotePeerMessage : context.remoteMessage;
|
|
173
|
+
if (remote === null) {
|
|
174
|
+
throw new Error(`Session ${args.to} is not on this machine (no local key)`);
|
|
175
|
+
}
|
|
176
|
+
if (context.sentTo) {
|
|
177
|
+
const budget = checkPeerSendBudget(context.sentTo, args.to, now);
|
|
178
|
+
if (!budget.ok) throw new Error(replyLoopRefusal(budget.count, args.to));
|
|
179
|
+
}
|
|
180
|
+
const result2 = await remote({ to: args.to, body, replyTo: args.replyTo, from: self, machineId: args.machineId });
|
|
181
|
+
context.sentTo?.get(args.to)?.push(now);
|
|
182
|
+
return result2;
|
|
183
|
+
}
|
|
184
|
+
const live = (await (context.listPeers ?? listDaemonPeers)()).find((session) => session.sessionId === args.to);
|
|
185
|
+
if (!live) throw new Error(`Session ${args.to} is not running on this machine; nothing would read the message`);
|
|
186
|
+
if (live.kind === "mirror") throw new Error(`Session ${args.to} is a terminal mirror (a person typing claude in a terminal); it cannot receive messages`);
|
|
187
|
+
if (context.sentTo) {
|
|
188
|
+
const budget = checkPeerSendBudget(context.sentTo, args.to, now);
|
|
189
|
+
if (!budget.ok) throw new Error(replyLoopRefusal(budget.count, args.to));
|
|
190
|
+
}
|
|
191
|
+
const messageId = randomUUID().slice(0, 8);
|
|
192
|
+
const text = formatSessionPeerMessage({ id: messageId, from: self, body, replyTo: args.replyTo });
|
|
193
|
+
const result = await (context.deliver ?? defaultDeliver)(args.to, persisted, text, `session-message-${messageId}`);
|
|
194
|
+
context.sentTo?.get(args.to)?.push(now);
|
|
195
|
+
return {
|
|
196
|
+
delivered: result.delivered,
|
|
197
|
+
stored: result.stored,
|
|
198
|
+
status: result.status,
|
|
199
|
+
messageId,
|
|
200
|
+
to: args.to,
|
|
201
|
+
url: sessionWebUrl(args.to),
|
|
202
|
+
...result.error ? { error: result.error } : {}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function replyLoopRefusal(count, to) {
|
|
206
|
+
return `Refused: this session already sent ${count} messages to ${to} in the last ${Math.round(PEER_MESSAGE_RATE_WINDOW_MS / 6e4)} minutes. That is a reply loop, not coordination \u2014 STOP replying to that session now; do not send acknowledgements or thanks. Continue your own work.`;
|
|
207
|
+
}
|
|
208
|
+
async function executeSessionPeerTool(name, args, context) {
|
|
209
|
+
switch (name) {
|
|
210
|
+
case "session_message":
|
|
211
|
+
return sendPeerMessage(context, {
|
|
212
|
+
to: String(args?.to ?? ""),
|
|
213
|
+
body: String(args?.body ?? ""),
|
|
214
|
+
...args?.replyTo ? { replyTo: String(args.replyTo) } : {},
|
|
215
|
+
...args?.machineId ? { machineId: String(args.machineId) } : {}
|
|
216
|
+
});
|
|
217
|
+
case "session_peers": {
|
|
218
|
+
const scope = args?.scope;
|
|
219
|
+
if (scope !== void 0 && !PEER_SCOPES.includes(scope)) throw new Error(`scope must be one of ${PEER_SCOPES.join(", ")}`);
|
|
220
|
+
if (args?.machineId) {
|
|
221
|
+
return (context.remotePeers ?? listRemotePeers)(String(args.machineId), {
|
|
222
|
+
...scope !== void 0 ? { scope } : {},
|
|
223
|
+
...typeof args.cwd === "string" && args.cwd ? { cwd: args.cwd } : {}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return listPeerSessions(context, scope ?? "repo");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function cliPeerSelf(env, cwd, persisted) {
|
|
231
|
+
const sessionId = env.VH_PEER_SESSION_ID;
|
|
232
|
+
if (sessionId && isValidSessionId(sessionId)) {
|
|
233
|
+
const meta = persisted[sessionId]?.metadata;
|
|
234
|
+
return { sessionId, title: meta?.summary?.text, flavor: meta?.flavor, cwd: meta?.path ?? cwd };
|
|
235
|
+
}
|
|
236
|
+
let user = "user";
|
|
237
|
+
try {
|
|
238
|
+
user = userInfo().username;
|
|
239
|
+
} catch {
|
|
240
|
+
}
|
|
241
|
+
return { sessionId: CLI_PEER_SENDER_ID, title: `cli ${user}@${hostname()}`, flavor: "cli", cwd };
|
|
242
|
+
}
|
|
243
|
+
function createSessionPeerToolExecutor(client) {
|
|
244
|
+
const context = {
|
|
245
|
+
self: () => {
|
|
246
|
+
const meta = client.getMetadata();
|
|
247
|
+
return { sessionId: client.sessionId, title: meta?.summary?.text, flavor: meta?.flavor, cwd: meta?.path ?? process.cwd() };
|
|
248
|
+
},
|
|
249
|
+
// One budget per session process: the reply-loop guard.
|
|
250
|
+
sentTo: /* @__PURE__ */ new Map()
|
|
251
|
+
};
|
|
252
|
+
return (name, args) => executeSessionPeerTool(name, args, context);
|
|
253
|
+
}
|
|
254
|
+
function registerSessionPeerTools(server, execute) {
|
|
255
|
+
for (const name of SESSION_PEER_TOOL_NAMES) {
|
|
256
|
+
const spec = SESSION_PEER_TOOL_SCHEMAS[name];
|
|
257
|
+
server.registerTool(name, {
|
|
258
|
+
description: spec.description,
|
|
259
|
+
title: spec.title,
|
|
260
|
+
inputSchema: spec.inputSchema,
|
|
261
|
+
annotations: { readOnlyHint: spec.readOnly, idempotentHint: spec.readOnly, openWorldHint: false, destructiveHint: false }
|
|
262
|
+
}, async (args) => {
|
|
263
|
+
try {
|
|
264
|
+
return { content: [{ type: "text", text: JSON.stringify(await execute(name, args ?? {})) }], isError: false };
|
|
265
|
+
} catch (error) {
|
|
266
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : "Session peer operation failed" }], isError: true };
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export { CLI_PEER_SENDER_ID as C, PEER_SCOPES as P, SESSION_PEER_TOOL_NAMES as S, createSessionPeerToolExecutor as a, SESSION_PEER_SENT_FROM as b, cliPeerSelf as c, formatEditConflictNotice as f, listPeerSessions as l, registerSessionPeerTools as r, sendPeerMessage as s };
|