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,82 @@
|
|
|
1
|
+
import { createHash, createHmac } from 'node:crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import tweetnacl from 'tweetnacl';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { c as credentialRelayProblem, d as decodeBase64 } from './authRelay-DSAvg1uv.mjs';
|
|
7
|
+
import { c as configuration } from './configuration-RfeNjFmd.mjs';
|
|
8
|
+
|
|
9
|
+
const AgentCredentialsSchema = z.object({
|
|
10
|
+
token: z.string().min(1),
|
|
11
|
+
secret: z.string().min(1),
|
|
12
|
+
authServerUrl: z.string().optional()
|
|
13
|
+
});
|
|
14
|
+
function hmacSha512(key, data) {
|
|
15
|
+
const hmac = createHmac("sha512", key);
|
|
16
|
+
hmac.update(data);
|
|
17
|
+
return new Uint8Array(hmac.digest());
|
|
18
|
+
}
|
|
19
|
+
function deriveKey(master, usage, path) {
|
|
20
|
+
const root = hmacSha512(new TextEncoder().encode(`${usage} Master Seed`), master);
|
|
21
|
+
let state = {
|
|
22
|
+
key: root.slice(0, 32),
|
|
23
|
+
chainCode: root.slice(32)
|
|
24
|
+
};
|
|
25
|
+
for (const index of path) {
|
|
26
|
+
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
27
|
+
const derived = hmacSha512(state.chainCode, data);
|
|
28
|
+
state = {
|
|
29
|
+
key: derived.slice(0, 32),
|
|
30
|
+
chainCode: derived.slice(32)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return state.key;
|
|
34
|
+
}
|
|
35
|
+
function deriveContentKeyPair(secret) {
|
|
36
|
+
const seed = deriveKey(secret, "Happy EnCoder", ["content"]);
|
|
37
|
+
const hashedSeed = new Uint8Array(createHash("sha512").update(seed).digest());
|
|
38
|
+
const secretKey = hashedSeed.slice(0, 32);
|
|
39
|
+
const keyPair = tweetnacl.box.keyPair.fromSecretKey(secretKey);
|
|
40
|
+
return {
|
|
41
|
+
publicKey: keyPair.publicKey,
|
|
42
|
+
secretKey: keyPair.secretKey
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function getLocalHappyAgentCredentialPath(happyHomeDir = configuration.happyHomeDir) {
|
|
46
|
+
return join(happyHomeDir, "agent.key");
|
|
47
|
+
}
|
|
48
|
+
function readLocalHappyAgentCredentials(happyHomeDir = configuration.happyHomeDir, serverUrl = configuration.serverUrl) {
|
|
49
|
+
const credentialPath = getLocalHappyAgentCredentialPath(happyHomeDir);
|
|
50
|
+
if (!existsSync(credentialPath)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const parsed = AgentCredentialsSchema.parse(JSON.parse(readFileSync(credentialPath, "utf8")));
|
|
55
|
+
if (!parsed.authServerUrl) return null;
|
|
56
|
+
if (credentialRelayProblem(parsed.authServerUrl, serverUrl)) return null;
|
|
57
|
+
const secret = decodeBase64(parsed.secret);
|
|
58
|
+
return {
|
|
59
|
+
token: parsed.token,
|
|
60
|
+
authServerUrl: parsed.authServerUrl,
|
|
61
|
+
secret,
|
|
62
|
+
contentKeyPair: deriveContentKeyPair(secret)
|
|
63
|
+
};
|
|
64
|
+
} catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function hasLocalHappyAgentAuth(happyHomeDir = configuration.happyHomeDir) {
|
|
69
|
+
return readLocalHappyAgentCredentials(happyHomeDir) !== null;
|
|
70
|
+
}
|
|
71
|
+
function detectResumeSupport(happyHomeDir = configuration.happyHomeDir) {
|
|
72
|
+
const happyAgentAuthenticated = hasLocalHappyAgentAuth(happyHomeDir);
|
|
73
|
+
return {
|
|
74
|
+
rpcAvailable: happyAgentAuthenticated,
|
|
75
|
+
requiresSameMachine: true,
|
|
76
|
+
requiresHappyAgentAuth: true,
|
|
77
|
+
happyAgentAuthenticated,
|
|
78
|
+
detectedAt: Date.now()
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { detectResumeSupport as d, getLocalHappyAgentCredentialPath as g, readLocalHappyAgentCredentials as r };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node_crypto = require('node:crypto');
|
|
4
|
+
var node_fs = require('node:fs');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var tweetnacl = require('tweetnacl');
|
|
7
|
+
var z = require('zod');
|
|
8
|
+
var authRelay = require('./authRelay-BdYkC1Po.cjs');
|
|
9
|
+
var configuration = require('./configuration-BSYpcPwE.cjs');
|
|
10
|
+
|
|
11
|
+
const AgentCredentialsSchema = z.z.object({
|
|
12
|
+
token: z.z.string().min(1),
|
|
13
|
+
secret: z.z.string().min(1),
|
|
14
|
+
authServerUrl: z.z.string().optional()
|
|
15
|
+
});
|
|
16
|
+
function hmacSha512(key, data) {
|
|
17
|
+
const hmac = node_crypto.createHmac("sha512", key);
|
|
18
|
+
hmac.update(data);
|
|
19
|
+
return new Uint8Array(hmac.digest());
|
|
20
|
+
}
|
|
21
|
+
function deriveKey(master, usage, path) {
|
|
22
|
+
const root = hmacSha512(new TextEncoder().encode(`${usage} Master Seed`), master);
|
|
23
|
+
let state = {
|
|
24
|
+
key: root.slice(0, 32),
|
|
25
|
+
chainCode: root.slice(32)
|
|
26
|
+
};
|
|
27
|
+
for (const index of path) {
|
|
28
|
+
const data = new Uint8Array([0, ...new TextEncoder().encode(index)]);
|
|
29
|
+
const derived = hmacSha512(state.chainCode, data);
|
|
30
|
+
state = {
|
|
31
|
+
key: derived.slice(0, 32),
|
|
32
|
+
chainCode: derived.slice(32)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return state.key;
|
|
36
|
+
}
|
|
37
|
+
function deriveContentKeyPair(secret) {
|
|
38
|
+
const seed = deriveKey(secret, "Happy EnCoder", ["content"]);
|
|
39
|
+
const hashedSeed = new Uint8Array(node_crypto.createHash("sha512").update(seed).digest());
|
|
40
|
+
const secretKey = hashedSeed.slice(0, 32);
|
|
41
|
+
const keyPair = tweetnacl.box.keyPair.fromSecretKey(secretKey);
|
|
42
|
+
return {
|
|
43
|
+
publicKey: keyPair.publicKey,
|
|
44
|
+
secretKey: keyPair.secretKey
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function getLocalHappyAgentCredentialPath(happyHomeDir = configuration.configuration.happyHomeDir) {
|
|
48
|
+
return path.join(happyHomeDir, "agent.key");
|
|
49
|
+
}
|
|
50
|
+
function readLocalHappyAgentCredentials(happyHomeDir = configuration.configuration.happyHomeDir, serverUrl = configuration.configuration.serverUrl) {
|
|
51
|
+
const credentialPath = getLocalHappyAgentCredentialPath(happyHomeDir);
|
|
52
|
+
if (!node_fs.existsSync(credentialPath)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const parsed = AgentCredentialsSchema.parse(JSON.parse(node_fs.readFileSync(credentialPath, "utf8")));
|
|
57
|
+
if (!parsed.authServerUrl) return null;
|
|
58
|
+
if (authRelay.credentialRelayProblem(parsed.authServerUrl, serverUrl)) return null;
|
|
59
|
+
const secret = authRelay.decodeBase64(parsed.secret);
|
|
60
|
+
return {
|
|
61
|
+
token: parsed.token,
|
|
62
|
+
authServerUrl: parsed.authServerUrl,
|
|
63
|
+
secret,
|
|
64
|
+
contentKeyPair: deriveContentKeyPair(secret)
|
|
65
|
+
};
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function hasLocalHappyAgentAuth(happyHomeDir = configuration.configuration.happyHomeDir) {
|
|
71
|
+
return readLocalHappyAgentCredentials(happyHomeDir) !== null;
|
|
72
|
+
}
|
|
73
|
+
function detectResumeSupport(happyHomeDir = configuration.configuration.happyHomeDir) {
|
|
74
|
+
const happyAgentAuthenticated = hasLocalHappyAgentAuth(happyHomeDir);
|
|
75
|
+
return {
|
|
76
|
+
rpcAvailable: happyAgentAuthenticated,
|
|
77
|
+
requiresSameMachine: true,
|
|
78
|
+
requiresHappyAgentAuth: true,
|
|
79
|
+
happyAgentAuthenticated,
|
|
80
|
+
detectedAt: Date.now()
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
exports.detectResumeSupport = detectResumeSupport;
|
|
85
|
+
exports.getLocalHappyAgentCredentialPath = getLocalHappyAgentCredentialPath;
|
|
86
|
+
exports.readLocalHappyAgentCredentials = readLocalHappyAgentCredentials;
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { inspect } from 'node:util';
|
|
3
|
+
import { d as appendPrivateFileSync, c as configuration } from './configuration-RfeNjFmd.mjs';
|
|
4
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
5
|
+
import { join, basename } from 'node:path';
|
|
6
|
+
|
|
7
|
+
function sensitiveKey(key) {
|
|
8
|
+
const normalized = key.toLowerCase().replace(/[_\-\s]/g, "");
|
|
9
|
+
return /(token|secret|password|authorization|cookie|credential|apikey|privatekey|encryptionkey|accesskey|claimsecret)/.test(normalized);
|
|
10
|
+
}
|
|
11
|
+
function redactLogString(value) {
|
|
12
|
+
return value.replace(/(Bearer\s+)[A-Za-z0-9._~+/=-]+/gi, "$1[REDACTED]").replace(/([?&](?:token|secret|password|api[_-]?key)=)[^&#\s]+/gi, "$1[REDACTED]").replace(/((?:token|secret|password|api[_-]?key)\s*[=:]\s*)[^\s,;]+/gi, "$1[REDACTED]");
|
|
13
|
+
}
|
|
14
|
+
function redactLogValue(value, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
|
|
15
|
+
if (typeof value === "string") return redactLogString(value);
|
|
16
|
+
if (value === null || typeof value !== "object") return value;
|
|
17
|
+
if (depth >= 6) return "[TRUNCATED]";
|
|
18
|
+
if (seen.has(value)) return "[CIRCULAR]";
|
|
19
|
+
seen.add(value);
|
|
20
|
+
if (value instanceof Error) {
|
|
21
|
+
const error = value;
|
|
22
|
+
return {
|
|
23
|
+
name: error.name,
|
|
24
|
+
message: redactLogString(error.message),
|
|
25
|
+
...typeof error.code === "string" || typeof error.code === "number" ? { code: error.code } : {},
|
|
26
|
+
...typeof (error.status ?? error.response?.status) === "number" ? { status: error.status ?? error.response?.status } : {}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(value)) return value.map((item) => redactLogValue(item, depth + 1, seen));
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [key, child] of Object.entries(value)) {
|
|
32
|
+
if (sensitiveKey(key)) {
|
|
33
|
+
result[key] = "[REDACTED]";
|
|
34
|
+
} else if (key === "environmentVariables" && child && typeof child === "object") {
|
|
35
|
+
result[key] = { names: Object.keys(child).sort() };
|
|
36
|
+
} else {
|
|
37
|
+
result[key] = redactLogValue(child, depth + 1, seen);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function createTimestampForFilename(date = /* @__PURE__ */ new Date()) {
|
|
44
|
+
return date.toLocaleString("sv-SE", {
|
|
45
|
+
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
46
|
+
year: "numeric",
|
|
47
|
+
month: "2-digit",
|
|
48
|
+
day: "2-digit",
|
|
49
|
+
hour: "2-digit",
|
|
50
|
+
minute: "2-digit",
|
|
51
|
+
second: "2-digit"
|
|
52
|
+
}).replace(/[: ]/g, "-").replace(/,/g, "") + "-pid-" + process.pid;
|
|
53
|
+
}
|
|
54
|
+
function createTimestampForLogEntry(date = /* @__PURE__ */ new Date()) {
|
|
55
|
+
return date.toLocaleTimeString("en-US", {
|
|
56
|
+
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
57
|
+
hour12: false,
|
|
58
|
+
hour: "2-digit",
|
|
59
|
+
minute: "2-digit",
|
|
60
|
+
second: "2-digit",
|
|
61
|
+
fractionalSecondDigits: 3
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function getSessionLogPath() {
|
|
65
|
+
const timestamp = createTimestampForFilename();
|
|
66
|
+
const filename = configuration.isDaemonProcess ? `${timestamp}-daemon.log` : `${timestamp}.log`;
|
|
67
|
+
return join(configuration.logsDir, filename);
|
|
68
|
+
}
|
|
69
|
+
function safeRemoteLogUrl(raw) {
|
|
70
|
+
if (!raw) return void 0;
|
|
71
|
+
try {
|
|
72
|
+
const url = new URL(raw);
|
|
73
|
+
const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
|
|
74
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && loopback)) return void 0;
|
|
75
|
+
if (url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") return void 0;
|
|
76
|
+
return url.origin;
|
|
77
|
+
} catch {
|
|
78
|
+
return void 0;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
class Logger {
|
|
82
|
+
constructor(logFilePath = getSessionLogPath()) {
|
|
83
|
+
this.logFilePath = logFilePath;
|
|
84
|
+
const remoteUrl = safeRemoteLogUrl(process.env.HAPPY_SERVER_URL);
|
|
85
|
+
const remoteToken = process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING_TOKEN;
|
|
86
|
+
if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && remoteUrl && remoteToken && Buffer.byteLength(remoteToken) >= 32) {
|
|
87
|
+
this.dangerouslyUnencryptedServerLoggingUrl = remoteUrl;
|
|
88
|
+
this.dangerouslyUnencryptedServerLoggingToken = remoteToken;
|
|
89
|
+
console.log(chalk.yellow("[REMOTE LOGGING] Sending logs to server for AI debugging"));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
dangerouslyUnencryptedServerLoggingUrl;
|
|
93
|
+
dangerouslyUnencryptedServerLoggingToken;
|
|
94
|
+
// Use local timezone for simplicity of locating the logs,
|
|
95
|
+
// in practice you will not need absolute timestamps
|
|
96
|
+
localTimezoneTimestamp() {
|
|
97
|
+
return createTimestampForLogEntry();
|
|
98
|
+
}
|
|
99
|
+
debug(message, ...args) {
|
|
100
|
+
this.logToFile(`[${this.localTimezoneTimestamp()}]`, message, ...args);
|
|
101
|
+
}
|
|
102
|
+
debugLargeJson(message, object, maxStringLength = 100, maxArrayLength = 10) {
|
|
103
|
+
if (!process.env.DEBUG) {
|
|
104
|
+
this.debug(`In production, skipping message inspection`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const truncateStrings = (obj) => {
|
|
108
|
+
if (typeof obj === "string") {
|
|
109
|
+
return obj.length > maxStringLength ? obj.substring(0, maxStringLength) + "... [truncated for logs]" : obj;
|
|
110
|
+
}
|
|
111
|
+
if (Array.isArray(obj)) {
|
|
112
|
+
const truncatedArray = obj.map((item) => truncateStrings(item)).slice(0, maxArrayLength);
|
|
113
|
+
if (obj.length > maxArrayLength) {
|
|
114
|
+
truncatedArray.push(`... [truncated array for logs up to ${maxArrayLength} items]`);
|
|
115
|
+
}
|
|
116
|
+
return truncatedArray;
|
|
117
|
+
}
|
|
118
|
+
if (obj && typeof obj === "object") {
|
|
119
|
+
const result = {};
|
|
120
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
121
|
+
if (key === "usage") {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
result[key] = truncateStrings(value);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
return obj;
|
|
129
|
+
};
|
|
130
|
+
const truncatedObject = truncateStrings(redactLogValue(object));
|
|
131
|
+
const json = JSON.stringify(truncatedObject, null, 2);
|
|
132
|
+
this.logToFile(`[${this.localTimezoneTimestamp()}]`, redactLogString(message), "\n", json);
|
|
133
|
+
}
|
|
134
|
+
info(message, ...args) {
|
|
135
|
+
this.logToConsole("info", "", message, ...args);
|
|
136
|
+
this.debug(message, args);
|
|
137
|
+
}
|
|
138
|
+
infoDeveloper(message, ...args) {
|
|
139
|
+
this.debug(message, ...args);
|
|
140
|
+
if (process.env.DEBUG) {
|
|
141
|
+
this.logToConsole("info", "[DEV]", message, ...args);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
warn(message, ...args) {
|
|
145
|
+
this.logToConsole("warn", "", message, ...args);
|
|
146
|
+
this.debug(`[WARN] ${message}`, ...args);
|
|
147
|
+
}
|
|
148
|
+
getLogPath() {
|
|
149
|
+
return this.logFilePath;
|
|
150
|
+
}
|
|
151
|
+
logToConsole(level, prefix, message, ...args) {
|
|
152
|
+
message = redactLogString(message);
|
|
153
|
+
args = args.map((arg) => redactLogValue(arg));
|
|
154
|
+
switch (level) {
|
|
155
|
+
case "debug": {
|
|
156
|
+
console.log(chalk.gray(prefix), message, ...args);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case "error": {
|
|
160
|
+
console.error(chalk.red(prefix), message, ...args);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case "info": {
|
|
164
|
+
console.log(chalk.blue(prefix), message, ...args);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case "warn": {
|
|
168
|
+
console.log(chalk.yellow(prefix), message, ...args);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
default: {
|
|
172
|
+
this.debug("Unknown log level:", level);
|
|
173
|
+
console.log(chalk.blue(prefix), message, ...args);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async sendToRemoteServer(level, message, ...args) {
|
|
179
|
+
if (!this.dangerouslyUnencryptedServerLoggingUrl) return;
|
|
180
|
+
try {
|
|
181
|
+
await fetch(this.dangerouslyUnencryptedServerLoggingUrl + "/logs-combined-from-cli-and-mobile-for-simple-ai-debugging", {
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: {
|
|
184
|
+
"Content-Type": "application/json",
|
|
185
|
+
"Authorization": `Bearer ${this.dangerouslyUnencryptedServerLoggingToken}`
|
|
186
|
+
},
|
|
187
|
+
body: JSON.stringify({
|
|
188
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
189
|
+
level,
|
|
190
|
+
message: `${redactLogString(message)} ${args.map((raw) => {
|
|
191
|
+
const safe = redactLogValue(raw);
|
|
192
|
+
return typeof safe === "object" ? JSON.stringify(safe, null, 2) : String(safe);
|
|
193
|
+
}).join(" ")}`,
|
|
194
|
+
source: "cli",
|
|
195
|
+
platform: process.platform
|
|
196
|
+
})
|
|
197
|
+
});
|
|
198
|
+
} catch (error) {
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
logToFile(prefix, message, ...args) {
|
|
202
|
+
const safeMessage = redactLogString(message);
|
|
203
|
+
const safeArgs = args.map((arg) => redactLogValue(arg));
|
|
204
|
+
const logLine = `${prefix} ${safeMessage} ${safeArgs.map(
|
|
205
|
+
(arg) => typeof arg === "string" ? arg : inspect(arg, { depth: 5, breakLength: 120 })
|
|
206
|
+
).join(" ")}
|
|
207
|
+
`;
|
|
208
|
+
if (this.dangerouslyUnencryptedServerLoggingUrl) {
|
|
209
|
+
let level = "info";
|
|
210
|
+
if (prefix.includes(this.localTimezoneTimestamp())) {
|
|
211
|
+
level = "debug";
|
|
212
|
+
}
|
|
213
|
+
this.sendToRemoteServer(level, safeMessage, ...safeArgs).catch(() => {
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
appendPrivateFileSync(this.logFilePath, logLine);
|
|
218
|
+
} catch (appendError) {
|
|
219
|
+
if (process.env.DEBUG) {
|
|
220
|
+
console.error("[DEV MODE ONLY THROWING] Failed to append to log file:", appendError);
|
|
221
|
+
throw appendError;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
let logger = new Logger();
|
|
227
|
+
async function listDaemonLogFiles(limit = 50) {
|
|
228
|
+
try {
|
|
229
|
+
const logsDir = configuration.logsDir;
|
|
230
|
+
if (!existsSync(logsDir)) {
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
const logs = readdirSync(logsDir).filter((file) => file.endsWith("-daemon.log")).map((file) => {
|
|
234
|
+
const fullPath = join(logsDir, file);
|
|
235
|
+
const stats = statSync(fullPath);
|
|
236
|
+
return { file, path: fullPath, modified: stats.mtime };
|
|
237
|
+
}).sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
238
|
+
try {
|
|
239
|
+
const { readDaemonState } = await import('./persistence-HGW_ZVs9.mjs');
|
|
240
|
+
const state = await readDaemonState();
|
|
241
|
+
if (!state) {
|
|
242
|
+
return logs;
|
|
243
|
+
}
|
|
244
|
+
if (state.daemonLogPath && existsSync(state.daemonLogPath)) {
|
|
245
|
+
const stats = statSync(state.daemonLogPath);
|
|
246
|
+
const persisted = {
|
|
247
|
+
file: basename(state.daemonLogPath),
|
|
248
|
+
path: state.daemonLogPath,
|
|
249
|
+
modified: stats.mtime
|
|
250
|
+
};
|
|
251
|
+
const idx = logs.findIndex((l) => l.path === persisted.path);
|
|
252
|
+
if (idx >= 0) {
|
|
253
|
+
const [found] = logs.splice(idx, 1);
|
|
254
|
+
logs.unshift(found);
|
|
255
|
+
} else {
|
|
256
|
+
logs.unshift(persisted);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
}
|
|
261
|
+
return logs.slice(0, Math.max(0, limit));
|
|
262
|
+
} catch {
|
|
263
|
+
return [];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function getLatestDaemonLog() {
|
|
267
|
+
const [latest] = await listDaemonLogFiles(1);
|
|
268
|
+
return latest || null;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export { getLatestDaemonLog as g, logger as l, redactLogValue as r };
|