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,206 @@
|
|
|
1
|
+
import { I as InvalidateSync } from './sync-CxD-w_40.mjs';
|
|
2
|
+
import { R as RawJSONLinesSchema } from './types-CkqAACXx.mjs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { l as logger } from './logger-fXoNzNuB.mjs';
|
|
6
|
+
import { s as startFileWatcher } from './startFileWatcher-CdegMbJj.mjs';
|
|
7
|
+
import { g as getProjectPath } from './path-D2wdaNSk.mjs';
|
|
8
|
+
|
|
9
|
+
class Future {
|
|
10
|
+
_resolve;
|
|
11
|
+
_reject;
|
|
12
|
+
_promise;
|
|
13
|
+
constructor() {
|
|
14
|
+
this._promise = new Promise((resolve, reject) => {
|
|
15
|
+
this._resolve = resolve;
|
|
16
|
+
this._reject = reject;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
resolve(value) {
|
|
20
|
+
this._resolve(value);
|
|
21
|
+
}
|
|
22
|
+
reject(reason) {
|
|
23
|
+
this._reject(reason);
|
|
24
|
+
}
|
|
25
|
+
get promise() {
|
|
26
|
+
return this._promise;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const INTERNAL_CLAUDE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
31
|
+
"file-history-snapshot",
|
|
32
|
+
"change",
|
|
33
|
+
"queue-operation"
|
|
34
|
+
]);
|
|
35
|
+
async function createSessionScanner(opts) {
|
|
36
|
+
const projectDir = getProjectPath(opts.workingDirectory);
|
|
37
|
+
let finishedSessions = /* @__PURE__ */ new Set();
|
|
38
|
+
let pendingSessions = /* @__PURE__ */ new Set();
|
|
39
|
+
let currentSessionId = null;
|
|
40
|
+
let watchers = /* @__PURE__ */ new Map();
|
|
41
|
+
let processedMessageKeys = /* @__PURE__ */ new Set();
|
|
42
|
+
let deadSessions = /* @__PURE__ */ new Set();
|
|
43
|
+
if (opts.sessionId) {
|
|
44
|
+
let messages = await readSessionLog(projectDir, opts.sessionId);
|
|
45
|
+
logger.debug(`[SESSION_SCANNER] Marking ${messages.length} existing messages as processed from session ${opts.sessionId}`);
|
|
46
|
+
for (let m of messages) {
|
|
47
|
+
processedMessageKeys.add(messageKey(m));
|
|
48
|
+
}
|
|
49
|
+
currentSessionId = opts.sessionId;
|
|
50
|
+
}
|
|
51
|
+
const sync = new InvalidateSync(async () => {
|
|
52
|
+
let sessions = [];
|
|
53
|
+
for (let p of pendingSessions) {
|
|
54
|
+
if (!deadSessions.has(p)) {
|
|
55
|
+
sessions.push(p);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (currentSessionId && !pendingSessions.has(currentSessionId) && !deadSessions.has(currentSessionId)) {
|
|
59
|
+
sessions.push(currentSessionId);
|
|
60
|
+
}
|
|
61
|
+
for (let [sessionId] of watchers) {
|
|
62
|
+
if (!sessions.includes(sessionId) && !deadSessions.has(sessionId)) {
|
|
63
|
+
sessions.push(sessionId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (let session of sessions) {
|
|
67
|
+
const sessionMessages = await readSessionLog(projectDir, session);
|
|
68
|
+
let skipped = 0;
|
|
69
|
+
let sent = 0;
|
|
70
|
+
for (let file of sessionMessages) {
|
|
71
|
+
let key = messageKey(file);
|
|
72
|
+
if (processedMessageKeys.has(key)) {
|
|
73
|
+
skipped++;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
processedMessageKeys.add(key);
|
|
77
|
+
logger.debug(`[SESSION_SCANNER] Sending new message: type=${file.type}, uuid=${file.type === "summary" ? file.leafUuid : file.uuid}`);
|
|
78
|
+
opts.onMessage(file);
|
|
79
|
+
sent++;
|
|
80
|
+
}
|
|
81
|
+
if (sessionMessages.length > 0) {
|
|
82
|
+
logger.debug(`[SESSION_SCANNER] Session ${session}: found=${sessionMessages.length}, skipped=${skipped}, sent=${sent}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (let p of sessions) {
|
|
86
|
+
if (pendingSessions.has(p)) {
|
|
87
|
+
pendingSessions.delete(p);
|
|
88
|
+
finishedSessions.add(p);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (let p of sessions) {
|
|
92
|
+
if (!watchers.has(p) && !deadSessions.has(p)) {
|
|
93
|
+
logger.debug(`[SESSION_SCANNER] Starting watcher for session: ${p}`);
|
|
94
|
+
watchers.set(p, startFileWatcher(
|
|
95
|
+
join(projectDir, `${p}.jsonl`),
|
|
96
|
+
() => {
|
|
97
|
+
sync.invalidate();
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
missingFileTimeoutMs: opts.missingFileTimeoutMs,
|
|
101
|
+
onGaveUp: () => {
|
|
102
|
+
logger.debug(`[SESSION_SCANNER] Session ${p} transcript never appeared \u2014 dropping it`);
|
|
103
|
+
watchers.get(p)?.();
|
|
104
|
+
watchers.delete(p);
|
|
105
|
+
deadSessions.add(p);
|
|
106
|
+
pendingSessions.delete(p);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
await sync.invalidateAndAwait();
|
|
114
|
+
const intervalId = setInterval(() => {
|
|
115
|
+
sync.invalidate();
|
|
116
|
+
}, 3e3);
|
|
117
|
+
return {
|
|
118
|
+
cleanup: async () => {
|
|
119
|
+
clearInterval(intervalId);
|
|
120
|
+
for (let w of watchers.values()) {
|
|
121
|
+
w();
|
|
122
|
+
}
|
|
123
|
+
watchers.clear();
|
|
124
|
+
await sync.invalidateAndAwait();
|
|
125
|
+
sync.stop();
|
|
126
|
+
},
|
|
127
|
+
onNewSession: async (sessionId, options) => {
|
|
128
|
+
if (currentSessionId === sessionId) {
|
|
129
|
+
logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (deadSessions.delete(sessionId)) {
|
|
133
|
+
logger.debug(`[SESSION_SCANNER] Reviving previously-dropped session: ${sessionId}`);
|
|
134
|
+
}
|
|
135
|
+
if (finishedSessions.has(sessionId)) {
|
|
136
|
+
logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already finished, skipping`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (pendingSessions.has(sessionId)) {
|
|
140
|
+
logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already pending, skipping`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (options?.treatExistingAsProcessed) {
|
|
144
|
+
const existing = await readSessionLog(projectDir, sessionId);
|
|
145
|
+
logger.debug(`[SESSION_SCANNER] Pre-marking ${existing.length} existing messages as processed for new session ${sessionId}`);
|
|
146
|
+
for (const m of existing) {
|
|
147
|
+
processedMessageKeys.add(messageKey(m));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (currentSessionId) {
|
|
151
|
+
pendingSessions.add(currentSessionId);
|
|
152
|
+
}
|
|
153
|
+
logger.debug(`[SESSION_SCANNER] New session: ${sessionId}`);
|
|
154
|
+
currentSessionId = sessionId;
|
|
155
|
+
sync.invalidate();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function messageKey(message) {
|
|
160
|
+
if (message.type === "user") {
|
|
161
|
+
return message.uuid;
|
|
162
|
+
} else if (message.type === "assistant") {
|
|
163
|
+
return message.uuid;
|
|
164
|
+
} else if (message.type === "summary") {
|
|
165
|
+
return "summary: " + message.leafUuid + ": " + message.summary;
|
|
166
|
+
} else if (message.type === "system") {
|
|
167
|
+
return message.uuid;
|
|
168
|
+
} else {
|
|
169
|
+
throw Error();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function readSessionLog(projectDir, sessionId) {
|
|
173
|
+
const expectedSessionFile = join(projectDir, `${sessionId}.jsonl`);
|
|
174
|
+
logger.debug(`[SESSION_SCANNER] Reading session file: ${expectedSessionFile}`);
|
|
175
|
+
let file;
|
|
176
|
+
try {
|
|
177
|
+
file = await readFile(expectedSessionFile, "utf-8");
|
|
178
|
+
} catch (error) {
|
|
179
|
+
logger.debug(`[SESSION_SCANNER] Session file not found: ${expectedSessionFile}`);
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
let lines = file.split("\n");
|
|
183
|
+
let messages = [];
|
|
184
|
+
for (let l of lines) {
|
|
185
|
+
try {
|
|
186
|
+
if (l.trim() === "") {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
let message = JSON.parse(l);
|
|
190
|
+
if (message.type && INTERNAL_CLAUDE_EVENT_TYPES.has(message.type)) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
let parsed = RawJSONLinesSchema.safeParse(message);
|
|
194
|
+
if (!parsed.success) {
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
messages.push(parsed.data);
|
|
198
|
+
} catch (e) {
|
|
199
|
+
logger.debug(`[SESSION_SCANNER] Error processing message: ${e}`);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return messages;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { Future as F, createSessionScanner as c };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sync = require('./sync-CVk4QERO.cjs');
|
|
4
|
+
var types = require('./types-CRS-srZK.cjs');
|
|
5
|
+
var path$1 = require('node:path');
|
|
6
|
+
var promises = require('node:fs/promises');
|
|
7
|
+
var logger = require('./logger-Bc8-u1w0.cjs');
|
|
8
|
+
var startFileWatcher = require('./startFileWatcher-CKKx-8ZO.cjs');
|
|
9
|
+
var path = require('./path-B7zW-WwE.cjs');
|
|
10
|
+
|
|
11
|
+
class Future {
|
|
12
|
+
_resolve;
|
|
13
|
+
_reject;
|
|
14
|
+
_promise;
|
|
15
|
+
constructor() {
|
|
16
|
+
this._promise = new Promise((resolve, reject) => {
|
|
17
|
+
this._resolve = resolve;
|
|
18
|
+
this._reject = reject;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
resolve(value) {
|
|
22
|
+
this._resolve(value);
|
|
23
|
+
}
|
|
24
|
+
reject(reason) {
|
|
25
|
+
this._reject(reason);
|
|
26
|
+
}
|
|
27
|
+
get promise() {
|
|
28
|
+
return this._promise;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const INTERNAL_CLAUDE_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
33
|
+
"file-history-snapshot",
|
|
34
|
+
"change",
|
|
35
|
+
"queue-operation"
|
|
36
|
+
]);
|
|
37
|
+
async function createSessionScanner(opts) {
|
|
38
|
+
const projectDir = path.getProjectPath(opts.workingDirectory);
|
|
39
|
+
let finishedSessions = /* @__PURE__ */ new Set();
|
|
40
|
+
let pendingSessions = /* @__PURE__ */ new Set();
|
|
41
|
+
let currentSessionId = null;
|
|
42
|
+
let watchers = /* @__PURE__ */ new Map();
|
|
43
|
+
let processedMessageKeys = /* @__PURE__ */ new Set();
|
|
44
|
+
let deadSessions = /* @__PURE__ */ new Set();
|
|
45
|
+
if (opts.sessionId) {
|
|
46
|
+
let messages = await readSessionLog(projectDir, opts.sessionId);
|
|
47
|
+
logger.logger.debug(`[SESSION_SCANNER] Marking ${messages.length} existing messages as processed from session ${opts.sessionId}`);
|
|
48
|
+
for (let m of messages) {
|
|
49
|
+
processedMessageKeys.add(messageKey(m));
|
|
50
|
+
}
|
|
51
|
+
currentSessionId = opts.sessionId;
|
|
52
|
+
}
|
|
53
|
+
const sync$1 = new sync.InvalidateSync(async () => {
|
|
54
|
+
let sessions = [];
|
|
55
|
+
for (let p of pendingSessions) {
|
|
56
|
+
if (!deadSessions.has(p)) {
|
|
57
|
+
sessions.push(p);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (currentSessionId && !pendingSessions.has(currentSessionId) && !deadSessions.has(currentSessionId)) {
|
|
61
|
+
sessions.push(currentSessionId);
|
|
62
|
+
}
|
|
63
|
+
for (let [sessionId] of watchers) {
|
|
64
|
+
if (!sessions.includes(sessionId) && !deadSessions.has(sessionId)) {
|
|
65
|
+
sessions.push(sessionId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (let session of sessions) {
|
|
69
|
+
const sessionMessages = await readSessionLog(projectDir, session);
|
|
70
|
+
let skipped = 0;
|
|
71
|
+
let sent = 0;
|
|
72
|
+
for (let file of sessionMessages) {
|
|
73
|
+
let key = messageKey(file);
|
|
74
|
+
if (processedMessageKeys.has(key)) {
|
|
75
|
+
skipped++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
processedMessageKeys.add(key);
|
|
79
|
+
logger.logger.debug(`[SESSION_SCANNER] Sending new message: type=${file.type}, uuid=${file.type === "summary" ? file.leafUuid : file.uuid}`);
|
|
80
|
+
opts.onMessage(file);
|
|
81
|
+
sent++;
|
|
82
|
+
}
|
|
83
|
+
if (sessionMessages.length > 0) {
|
|
84
|
+
logger.logger.debug(`[SESSION_SCANNER] Session ${session}: found=${sessionMessages.length}, skipped=${skipped}, sent=${sent}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (let p of sessions) {
|
|
88
|
+
if (pendingSessions.has(p)) {
|
|
89
|
+
pendingSessions.delete(p);
|
|
90
|
+
finishedSessions.add(p);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
for (let p of sessions) {
|
|
94
|
+
if (!watchers.has(p) && !deadSessions.has(p)) {
|
|
95
|
+
logger.logger.debug(`[SESSION_SCANNER] Starting watcher for session: ${p}`);
|
|
96
|
+
watchers.set(p, startFileWatcher.startFileWatcher(
|
|
97
|
+
path$1.join(projectDir, `${p}.jsonl`),
|
|
98
|
+
() => {
|
|
99
|
+
sync$1.invalidate();
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
missingFileTimeoutMs: opts.missingFileTimeoutMs,
|
|
103
|
+
onGaveUp: () => {
|
|
104
|
+
logger.logger.debug(`[SESSION_SCANNER] Session ${p} transcript never appeared \u2014 dropping it`);
|
|
105
|
+
watchers.get(p)?.();
|
|
106
|
+
watchers.delete(p);
|
|
107
|
+
deadSessions.add(p);
|
|
108
|
+
pendingSessions.delete(p);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
await sync$1.invalidateAndAwait();
|
|
116
|
+
const intervalId = setInterval(() => {
|
|
117
|
+
sync$1.invalidate();
|
|
118
|
+
}, 3e3);
|
|
119
|
+
return {
|
|
120
|
+
cleanup: async () => {
|
|
121
|
+
clearInterval(intervalId);
|
|
122
|
+
for (let w of watchers.values()) {
|
|
123
|
+
w();
|
|
124
|
+
}
|
|
125
|
+
watchers.clear();
|
|
126
|
+
await sync$1.invalidateAndAwait();
|
|
127
|
+
sync$1.stop();
|
|
128
|
+
},
|
|
129
|
+
onNewSession: async (sessionId, options) => {
|
|
130
|
+
if (currentSessionId === sessionId) {
|
|
131
|
+
logger.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is the same as the current session, skipping`);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (deadSessions.delete(sessionId)) {
|
|
135
|
+
logger.logger.debug(`[SESSION_SCANNER] Reviving previously-dropped session: ${sessionId}`);
|
|
136
|
+
}
|
|
137
|
+
if (finishedSessions.has(sessionId)) {
|
|
138
|
+
logger.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already finished, skipping`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (pendingSessions.has(sessionId)) {
|
|
142
|
+
logger.logger.debug(`[SESSION_SCANNER] New session: ${sessionId} is already pending, skipping`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (options?.treatExistingAsProcessed) {
|
|
146
|
+
const existing = await readSessionLog(projectDir, sessionId);
|
|
147
|
+
logger.logger.debug(`[SESSION_SCANNER] Pre-marking ${existing.length} existing messages as processed for new session ${sessionId}`);
|
|
148
|
+
for (const m of existing) {
|
|
149
|
+
processedMessageKeys.add(messageKey(m));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (currentSessionId) {
|
|
153
|
+
pendingSessions.add(currentSessionId);
|
|
154
|
+
}
|
|
155
|
+
logger.logger.debug(`[SESSION_SCANNER] New session: ${sessionId}`);
|
|
156
|
+
currentSessionId = sessionId;
|
|
157
|
+
sync$1.invalidate();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function messageKey(message) {
|
|
162
|
+
if (message.type === "user") {
|
|
163
|
+
return message.uuid;
|
|
164
|
+
} else if (message.type === "assistant") {
|
|
165
|
+
return message.uuid;
|
|
166
|
+
} else if (message.type === "summary") {
|
|
167
|
+
return "summary: " + message.leafUuid + ": " + message.summary;
|
|
168
|
+
} else if (message.type === "system") {
|
|
169
|
+
return message.uuid;
|
|
170
|
+
} else {
|
|
171
|
+
throw Error();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async function readSessionLog(projectDir, sessionId) {
|
|
175
|
+
const expectedSessionFile = path$1.join(projectDir, `${sessionId}.jsonl`);
|
|
176
|
+
logger.logger.debug(`[SESSION_SCANNER] Reading session file: ${expectedSessionFile}`);
|
|
177
|
+
let file;
|
|
178
|
+
try {
|
|
179
|
+
file = await promises.readFile(expectedSessionFile, "utf-8");
|
|
180
|
+
} catch (error) {
|
|
181
|
+
logger.logger.debug(`[SESSION_SCANNER] Session file not found: ${expectedSessionFile}`);
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
let lines = file.split("\n");
|
|
185
|
+
let messages = [];
|
|
186
|
+
for (let l of lines) {
|
|
187
|
+
try {
|
|
188
|
+
if (l.trim() === "") {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
let message = JSON.parse(l);
|
|
192
|
+
if (message.type && INTERNAL_CLAUDE_EVENT_TYPES.has(message.type)) {
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
let parsed = types.RawJSONLinesSchema.safeParse(message);
|
|
196
|
+
if (!parsed.success) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
messages.push(parsed.data);
|
|
200
|
+
} catch (e) {
|
|
201
|
+
logger.logger.debug(`[SESSION_SCANNER] Error processing message: ${e}`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return messages;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
exports.Future = Future;
|
|
209
|
+
exports.createSessionScanner = createSessionScanner;
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var sessionOps = require('./sessionOps-DJdExmBy.cjs');
|
|
5
|
+
var ids = require('./ids-B6ZC0HGt.cjs');
|
|
6
|
+
var peerTools = require('./peerTools-CIeiy9wn.cjs');
|
|
7
|
+
var persistence = require('./persistence-CBNMzSa8.cjs');
|
|
6
8
|
var path = require('node:path');
|
|
7
|
-
require('
|
|
8
|
-
require('
|
|
9
|
-
require('
|
|
9
|
+
var remoteSessionClient = require('./remoteSessionClient-BNx78NLb.cjs');
|
|
10
|
+
require('axios');
|
|
11
|
+
require('./configuration-v9f8LM9T.cjs');
|
|
10
12
|
require('node:fs');
|
|
11
13
|
require('node:os');
|
|
12
|
-
require('
|
|
13
|
-
require('
|
|
14
|
-
require('
|
|
14
|
+
require('./package-Cl5BEP5x.cjs');
|
|
15
|
+
require('node:fs/promises');
|
|
16
|
+
require('./authRelay-BdYkC1Po.cjs');
|
|
17
|
+
require('node:crypto');
|
|
15
18
|
require('tweetnacl');
|
|
19
|
+
require('./controlClient-fEHE85bH.cjs');
|
|
20
|
+
require('./logger-Bc8-u1w0.cjs');
|
|
16
21
|
require('node:util');
|
|
22
|
+
require('./time-CNRE4ChD.cjs');
|
|
23
|
+
require('socket.io-client');
|
|
24
|
+
require('./backgroundTaskActivity-CBvUdj39.cjs');
|
|
25
|
+
require('zod');
|
|
17
26
|
|
|
18
27
|
const MACHINE_ID_RE = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
19
28
|
const ACTIONS = ["list", "read", "stop", "archive", "approve", "deny", "peers", "message"];
|
|
@@ -58,7 +67,7 @@ function parseSessionsArgs(args) {
|
|
|
58
67
|
} else if (arg === "--scope") {
|
|
59
68
|
const value = args[++i];
|
|
60
69
|
if (value === void 0) throw new Error("--scope requires a value");
|
|
61
|
-
if (!
|
|
70
|
+
if (!peerTools.PEER_SCOPES.includes(value)) throw new Error(`--scope must be one of ${peerTools.PEER_SCOPES.join(", ")}`);
|
|
62
71
|
options.scope = value;
|
|
63
72
|
} else if (arg === "--cwd") {
|
|
64
73
|
const value = args[++i];
|
|
@@ -102,7 +111,7 @@ function parseSessionsArgs(args) {
|
|
|
102
111
|
if (ACTIONS_NEEDING_ID.has(options.action)) {
|
|
103
112
|
const id = positionals[0];
|
|
104
113
|
if (id === void 0) throw new Error(`${options.action} requires a session id`);
|
|
105
|
-
if (!
|
|
114
|
+
if (!ids.isValidSessionId(id)) throw new Error(`Invalid session id: ${id}`);
|
|
106
115
|
options.sessionId = id;
|
|
107
116
|
}
|
|
108
117
|
if (options.action === "message") {
|
|
@@ -206,8 +215,8 @@ ${chalk.bold("Options:")}
|
|
|
206
215
|
\`spawn --spawned-by\`). With --all only decryptable rows
|
|
207
216
|
can match.
|
|
208
217
|
--limit <n> list: how many NOT-running / not-attention sessions to
|
|
209
|
-
include (default ${
|
|
210
|
-
never cut). read: how many messages (default 20, max ${
|
|
218
|
+
include (default ${sessionOps.DEFAULT_RECENT_LIMIT}; running and attention rows are
|
|
219
|
+
never cut). read: how many messages (default 20, max ${sessionOps.MAX_READ_LIMIT}).
|
|
211
220
|
--full read only: do not truncate entries (default caps each
|
|
212
221
|
line at 500 chars).
|
|
213
222
|
--answer read only: print just the agent's reply to the latest
|
|
@@ -309,13 +318,13 @@ async function handleSessionsCommand(args) {
|
|
|
309
318
|
}
|
|
310
319
|
try {
|
|
311
320
|
if (options.action === "list" && options.all) {
|
|
312
|
-
const listed = await
|
|
313
|
-
const fill = await
|
|
321
|
+
const listed = await sessionOps.listAccountSessions({ recentLimit: options.tag ? 150 : options.limit, includeArchived: options.includeArchived });
|
|
322
|
+
const fill = await remoteSessionClient.fillForeignAccountRows(listed);
|
|
314
323
|
let sessions = fill.rows;
|
|
315
324
|
if (options.tag) {
|
|
316
325
|
const wanted = options.tag;
|
|
317
326
|
sessions = sessions.filter((summary) => summary.tags?.includes(wanted) === true);
|
|
318
|
-
const recentLimit = Math.max(0, options.limit ??
|
|
327
|
+
const recentLimit = Math.max(0, options.limit ?? sessionOps.DEFAULT_RECENT_LIMIT);
|
|
319
328
|
let idleKept = 0;
|
|
320
329
|
sessions = sessions.filter((summary) => summary.attention || summary.live || idleKept++ < recentLimit);
|
|
321
330
|
}
|
|
@@ -339,7 +348,7 @@ async function handleSessionsCommand(args) {
|
|
|
339
348
|
process.exit(0);
|
|
340
349
|
}
|
|
341
350
|
if (options.action === "list" && options.machine) {
|
|
342
|
-
const listing = await
|
|
351
|
+
const listing = await remoteSessionClient.listRemoteSessions(options.machine, { tag: options.tag, limit: options.limit });
|
|
343
352
|
const sessions = listing.sessions;
|
|
344
353
|
if (options.json) {
|
|
345
354
|
console.log(JSON.stringify({ sessions, machine: { id: listing.machineId, host: listing.host } }));
|
|
@@ -352,7 +361,7 @@ async function handleSessionsCommand(args) {
|
|
|
352
361
|
process.exit(0);
|
|
353
362
|
}
|
|
354
363
|
if (options.action === "list") {
|
|
355
|
-
const sessions = await
|
|
364
|
+
const sessions = await sessionOps.listSessions({ tag: options.tag, recentLimit: options.limit });
|
|
356
365
|
if (options.json) {
|
|
357
366
|
console.log(JSON.stringify({ sessions }));
|
|
358
367
|
} else if (sessions.length === 0) {
|
|
@@ -365,9 +374,9 @@ async function handleSessionsCommand(args) {
|
|
|
365
374
|
if (options.action === "peers" || options.action === "message") {
|
|
366
375
|
const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
|
|
367
376
|
const persisted = persistence.readPersistedSessions();
|
|
368
|
-
const context = { self: () =>
|
|
377
|
+
const context = { self: () => peerTools.cliPeerSelf(process.env, cwd, persisted), readPersisted: () => persisted };
|
|
369
378
|
if (options.action === "peers") {
|
|
370
|
-
const listing = options.machine ? await
|
|
379
|
+
const listing = options.machine ? await remoteSessionClient.listRemotePeers(options.machine, { ...options.scope ? { scope: options.scope } : {}, ...options.cwd ? { cwd: options.cwd } : {} }) : await peerTools.listPeerSessions(context, options.scope ?? "repo");
|
|
371
380
|
if (options.json) {
|
|
372
381
|
console.log(JSON.stringify(listing));
|
|
373
382
|
} else if (listing.peers.length === 0) {
|
|
@@ -388,7 +397,7 @@ async function handleSessionsCommand(args) {
|
|
|
388
397
|
}
|
|
389
398
|
const target = options.sessionId;
|
|
390
399
|
try {
|
|
391
|
-
const result = await
|
|
400
|
+
const result = await peerTools.sendPeerMessage(context, { to: target, body: options.text, replyTo: options.replyTo, ...options.machine ? { machineId: options.machine } : {} });
|
|
392
401
|
if (options.json) console.log(JSON.stringify(result));
|
|
393
402
|
else if (result.delivered) console.log(`Message ${result.messageId} delivered to ${target}${result.machine ? ` on ${result.machine.host}` : ""}
|
|
394
403
|
${result.url}`);
|
|
@@ -407,27 +416,27 @@ ${result.url}`);
|
|
|
407
416
|
if (local) {
|
|
408
417
|
if (options.wait) {
|
|
409
418
|
try {
|
|
410
|
-
await
|
|
419
|
+
await sessionOps.waitForTurnEnd(sessionId, { timeoutMs: (options.timeoutSec ?? 600) * 1e3 });
|
|
411
420
|
} catch (error) {
|
|
412
|
-
if (!(error instanceof
|
|
421
|
+
if (!(error instanceof sessionOps.TurnWaitTimeoutError)) throw error;
|
|
413
422
|
timedOut = true;
|
|
414
423
|
console.error(chalk.yellow("Timeout:"), error.message);
|
|
415
424
|
}
|
|
416
425
|
}
|
|
417
|
-
result = await
|
|
426
|
+
result = await sessionOps.readSessionTranscript(sessionId, options.limit ?? 20, { full: options.full });
|
|
418
427
|
} else {
|
|
419
428
|
const readOptions = { limit: options.limit ?? 20, full: options.full, ...options.machine ? { machineId: options.machine } : {} };
|
|
420
429
|
let remote;
|
|
421
430
|
if (options.wait) {
|
|
422
431
|
const timeoutMs = (options.timeoutSec ?? 600) * 1e3;
|
|
423
|
-
const waited = await
|
|
432
|
+
const waited = await remoteSessionClient.waitForRemoteTurnEnd(sessionId, { ...readOptions, timeoutMs });
|
|
424
433
|
remote = waited.read;
|
|
425
434
|
if (waited.timedOut) {
|
|
426
435
|
timedOut = true;
|
|
427
436
|
console.error(chalk.yellow("Timeout:"), `Session ${sessionId} on ${remote.host}: the latest turn did not end within ${Math.round(timeoutMs / 1e3)}s`);
|
|
428
437
|
}
|
|
429
438
|
} else {
|
|
430
|
-
remote = await
|
|
439
|
+
remote = await remoteSessionClient.readRemoteTranscript(sessionId, readOptions);
|
|
431
440
|
}
|
|
432
441
|
const { machineId, host, ...rest } = remote;
|
|
433
442
|
result = { ...rest, machine: { id: machineId, host } };
|
|
@@ -447,7 +456,7 @@ ${result.url}`);
|
|
|
447
456
|
process.exit(timedOut ? 2 : 0);
|
|
448
457
|
}
|
|
449
458
|
if (options.action === "stop") {
|
|
450
|
-
const stopped = await
|
|
459
|
+
const stopped = await sessionOps.stopSession(sessionId);
|
|
451
460
|
if (!stopped) {
|
|
452
461
|
if (options.json) console.log(JSON.stringify({ sessionId, stopped: false }));
|
|
453
462
|
console.error(chalk.red("Error:"), `Session ${sessionId} is not among the daemon's running sessions.`);
|
|
@@ -462,7 +471,7 @@ ${result.url}`);
|
|
|
462
471
|
const verdict = options.action === "approve" ? { kind: "approve", forSession: options.forSession } : { kind: "deny", reason: options.reason };
|
|
463
472
|
let result;
|
|
464
473
|
try {
|
|
465
|
-
result = await
|
|
474
|
+
result = await sessionOps.resolvePermissionRequest(sessionId, requestId, verdict, {
|
|
466
475
|
// T-014: a rate refusal waits (bounded) before re-sending;
|
|
467
476
|
// say so on stderr so the wait does not look like a hang.
|
|
468
477
|
onRateLimited: ({ attempt, waitMs, serverError }) => {
|
|
@@ -487,7 +496,7 @@ ${result.url}`);
|
|
|
487
496
|
}
|
|
488
497
|
process.exit(0);
|
|
489
498
|
}
|
|
490
|
-
await
|
|
499
|
+
await sessionOps.archiveSession(sessionId);
|
|
491
500
|
if (options.json) console.log(JSON.stringify({ sessionId, archived: true }));
|
|
492
501
|
else console.log(`Archived ${sessionId}`);
|
|
493
502
|
process.exit(0);
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions,
|
|
3
|
-
import {
|
|
2
|
+
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, a as listSessions, w as waitForTurnEnd, T as TurnWaitTimeoutError, r as readSessionTranscript, b as stopSession, c as resolvePermissionRequest, d as archiveSession } from './sessionOps-C_f1wKOr.mjs';
|
|
3
|
+
import { i as isValidSessionId } from './ids-DU6sLx4C.mjs';
|
|
4
|
+
import { c as cliPeerSelf, l as listPeerSessions, s as sendPeerMessage, P as PEER_SCOPES } from './peerTools-Dz3_7Bkk.mjs';
|
|
5
|
+
import { readPersistedSessions } from './persistence-oET5n61f.mjs';
|
|
4
6
|
import { resolve } from 'node:path';
|
|
5
|
-
import '
|
|
6
|
-
import '
|
|
7
|
-
import '
|
|
7
|
+
import { f as fillForeignAccountRows, l as listRemoteSessions, a as listRemotePeers, w as waitForRemoteTurnEnd, r as readRemoteTranscript } from './remoteSessionClient-CO7qOjR0.mjs';
|
|
8
|
+
import 'axios';
|
|
9
|
+
import './configuration-DoWFJUPm.mjs';
|
|
8
10
|
import 'node:fs';
|
|
9
11
|
import 'node:os';
|
|
10
|
-
import '
|
|
11
|
-
import '
|
|
12
|
-
import '
|
|
12
|
+
import './package-uOg9SCKi.mjs';
|
|
13
|
+
import 'node:fs/promises';
|
|
14
|
+
import './authRelay-DSAvg1uv.mjs';
|
|
15
|
+
import 'node:crypto';
|
|
13
16
|
import 'tweetnacl';
|
|
17
|
+
import './controlClient-DjoKTtgK.mjs';
|
|
18
|
+
import './logger-fXoNzNuB.mjs';
|
|
14
19
|
import 'node:util';
|
|
20
|
+
import './time-BZNdNiIV.mjs';
|
|
21
|
+
import 'socket.io-client';
|
|
22
|
+
import './backgroundTaskActivity-8PdPxrvy.mjs';
|
|
23
|
+
import 'zod';
|
|
15
24
|
|
|
16
25
|
const MACHINE_ID_RE = /^[a-zA-Z0-9_-]{1,128}$/;
|
|
17
26
|
const ACTIONS = ["list", "read", "stop", "archive", "approve", "deny", "peers", "message"];
|