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
|
@@ -2,50 +2,17 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
|
-
import { l as logger } from './
|
|
6
|
-
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './
|
|
7
|
-
import 'zod';
|
|
8
|
-
import '@paralleldrive/cuid2';
|
|
9
|
-
import 'node:fs/promises';
|
|
10
|
-
import 'node:fs';
|
|
11
|
-
import 'node:crypto';
|
|
12
|
-
import 'tweetnacl';
|
|
5
|
+
import { l as logger } from './logger-fXoNzNuB.mjs';
|
|
6
|
+
import { D as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './constants-BC4St0xd.mjs';
|
|
13
7
|
import 'chalk';
|
|
14
8
|
import 'node:util';
|
|
9
|
+
import './configuration-DoWFJUPm.mjs';
|
|
10
|
+
import 'node:fs';
|
|
15
11
|
import 'node:os';
|
|
16
12
|
import 'node:path';
|
|
17
|
-
import './
|
|
18
|
-
import '
|
|
19
|
-
import '
|
|
20
|
-
import 'socket.io-client';
|
|
21
|
-
import 'util';
|
|
22
|
-
import 'fs/promises';
|
|
23
|
-
import 'crypto';
|
|
24
|
-
import 'cross-spawn';
|
|
25
|
-
import './terminalTitleSuggest-DKgX3osW.mjs';
|
|
26
|
-
import 'url';
|
|
27
|
-
import 'node:child_process';
|
|
28
|
-
import 'node-pty';
|
|
29
|
-
import 'node:readline';
|
|
30
|
-
import '@anthropic-ai/sandbox-runtime';
|
|
31
|
-
import 'expo-server-sdk';
|
|
32
|
-
import './agentGuidance-KgvYuF3R.mjs';
|
|
33
|
-
import 'ink';
|
|
34
|
-
import 'react';
|
|
35
|
-
import '@anthropic-ai/claude-agent-sdk';
|
|
36
|
-
import 'ps-list';
|
|
37
|
-
import 'tmp';
|
|
38
|
-
import 'open';
|
|
39
|
-
import 'fastify';
|
|
40
|
-
import 'fastify-type-provider-zod';
|
|
41
|
-
import 'node:module';
|
|
42
|
-
import '@modelcontextprotocol/sdk/server/mcp.js';
|
|
43
|
-
import 'node:http';
|
|
44
|
-
import '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
45
|
-
import 'http';
|
|
46
|
-
import 'inquirer';
|
|
47
|
-
import 'node:url';
|
|
48
|
-
import 'node:readline/promises';
|
|
13
|
+
import './package-uOg9SCKi.mjs';
|
|
14
|
+
import 'node:fs/promises';
|
|
15
|
+
import './trimIdent-BAjmv_TG.mjs';
|
|
49
16
|
|
|
50
17
|
function readGeminiLocalConfig() {
|
|
51
18
|
let token = null;
|
|
@@ -4,50 +4,17 @@ var fs = require('fs');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
6
|
var child_process = require('child_process');
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
require('zod');
|
|
10
|
-
require('@paralleldrive/cuid2');
|
|
11
|
-
require('node:fs/promises');
|
|
12
|
-
require('node:fs');
|
|
13
|
-
require('node:crypto');
|
|
14
|
-
require('tweetnacl');
|
|
7
|
+
var logger = require('./logger-Bc8-u1w0.cjs');
|
|
8
|
+
var constants = require('./constants-VJ0N6WuG.cjs');
|
|
15
9
|
require('chalk');
|
|
16
10
|
require('node:util');
|
|
11
|
+
require('./configuration-v9f8LM9T.cjs');
|
|
12
|
+
require('node:fs');
|
|
17
13
|
require('node:os');
|
|
18
14
|
require('node:path');
|
|
19
|
-
require('./
|
|
20
|
-
require('
|
|
21
|
-
require('
|
|
22
|
-
require('socket.io-client');
|
|
23
|
-
require('util');
|
|
24
|
-
require('fs/promises');
|
|
25
|
-
require('crypto');
|
|
26
|
-
require('cross-spawn');
|
|
27
|
-
require('./terminalTitleSuggest-Dji8I0Jy.cjs');
|
|
28
|
-
require('url');
|
|
29
|
-
require('node:child_process');
|
|
30
|
-
require('node-pty');
|
|
31
|
-
require('node:readline');
|
|
32
|
-
require('@anthropic-ai/sandbox-runtime');
|
|
33
|
-
require('expo-server-sdk');
|
|
34
|
-
require('./agentGuidance-BRDN1NoZ.cjs');
|
|
35
|
-
require('ink');
|
|
36
|
-
require('react');
|
|
37
|
-
require('@anthropic-ai/claude-agent-sdk');
|
|
38
|
-
require('ps-list');
|
|
39
|
-
require('tmp');
|
|
40
|
-
require('open');
|
|
41
|
-
require('fastify');
|
|
42
|
-
require('fastify-type-provider-zod');
|
|
43
|
-
require('node:module');
|
|
44
|
-
require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
45
|
-
require('node:http');
|
|
46
|
-
require('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
47
|
-
require('http');
|
|
48
|
-
require('inquirer');
|
|
49
|
-
require('node:url');
|
|
50
|
-
require('node:readline/promises');
|
|
15
|
+
require('./package-Cl5BEP5x.cjs');
|
|
16
|
+
require('node:fs/promises');
|
|
17
|
+
require('./trimIdent-4gvk9Wk6.cjs');
|
|
51
18
|
|
|
52
19
|
function readGeminiLocalConfig() {
|
|
53
20
|
let token = null;
|
|
@@ -70,14 +37,14 @@ function readGeminiLocalConfig() {
|
|
|
70
37
|
const foundToken = config.access_token || config.token || config.apiKey || config.GEMINI_API_KEY;
|
|
71
38
|
if (foundToken && typeof foundToken === "string") {
|
|
72
39
|
token = foundToken;
|
|
73
|
-
|
|
40
|
+
logger.logger.debug(`[Gemini] Found token in ${configPath}`);
|
|
74
41
|
}
|
|
75
42
|
}
|
|
76
43
|
if (!model) {
|
|
77
44
|
const foundModel = config.model || config.GEMINI_MODEL;
|
|
78
45
|
if (foundModel && typeof foundModel === "string") {
|
|
79
46
|
model = foundModel;
|
|
80
|
-
|
|
47
|
+
logger.logger.debug(`[Gemini] Found model in ${configPath}: ${model}`);
|
|
81
48
|
}
|
|
82
49
|
}
|
|
83
50
|
if (!googleCloudProject) {
|
|
@@ -87,11 +54,11 @@ function readGeminiLocalConfig() {
|
|
|
87
54
|
if (config.googleCloudProjectEmail && typeof config.googleCloudProjectEmail === "string") {
|
|
88
55
|
googleCloudProjectEmail = config.googleCloudProjectEmail;
|
|
89
56
|
}
|
|
90
|
-
|
|
57
|
+
logger.logger.debug(`[Gemini] Found Google Cloud Project in ${configPath}: ${googleCloudProject}${googleCloudProjectEmail ? ` (for ${googleCloudProjectEmail})` : ""}`);
|
|
91
58
|
}
|
|
92
59
|
}
|
|
93
60
|
} catch (error) {
|
|
94
|
-
|
|
61
|
+
logger.logger.debug(`[Gemini] Failed to read config from ${configPath}:`, error);
|
|
95
62
|
}
|
|
96
63
|
}
|
|
97
64
|
}
|
|
@@ -105,10 +72,10 @@ function readGeminiLocalConfig() {
|
|
|
105
72
|
}).trim();
|
|
106
73
|
if (gcloudToken && gcloudToken.length > 0) {
|
|
107
74
|
token = gcloudToken;
|
|
108
|
-
|
|
75
|
+
logger.logger.debug("[Gemini] Found token via gcloud Application Default Credentials");
|
|
109
76
|
}
|
|
110
77
|
} catch (error) {
|
|
111
|
-
|
|
78
|
+
logger.logger.debug("[Gemini] gcloud Application Default Credentials not available");
|
|
112
79
|
}
|
|
113
80
|
}
|
|
114
81
|
if (!googleCloudProject) {
|
|
@@ -116,7 +83,7 @@ function readGeminiLocalConfig() {
|
|
|
116
83
|
if (envProject) {
|
|
117
84
|
googleCloudProject = envProject;
|
|
118
85
|
googleCloudProjectEmail = null;
|
|
119
|
-
|
|
86
|
+
logger.logger.debug(`[Gemini] Found Google Cloud Project from env: ${googleCloudProject}`);
|
|
120
87
|
}
|
|
121
88
|
}
|
|
122
89
|
return { token, model, googleCloudProject, googleCloudProjectEmail };
|
|
@@ -124,15 +91,15 @@ function readGeminiLocalConfig() {
|
|
|
124
91
|
function determineGeminiModel(explicitModel, localConfig) {
|
|
125
92
|
if (explicitModel !== void 0) {
|
|
126
93
|
if (explicitModel === null) {
|
|
127
|
-
return process.env[
|
|
94
|
+
return process.env[constants.GEMINI_MODEL_ENV] || constants.DEFAULT_GEMINI_MODEL;
|
|
128
95
|
} else {
|
|
129
96
|
return explicitModel;
|
|
130
97
|
}
|
|
131
98
|
} else {
|
|
132
|
-
const envModel = process.env[
|
|
133
|
-
|
|
134
|
-
const model = envModel || localConfig.model ||
|
|
135
|
-
|
|
99
|
+
const envModel = process.env[constants.GEMINI_MODEL_ENV];
|
|
100
|
+
logger.logger.debug(`[Gemini] Model selection: env[GEMINI_MODEL_ENV]=${envModel}, localConfig.model=${localConfig.model}, DEFAULT=${constants.DEFAULT_GEMINI_MODEL}`);
|
|
101
|
+
const model = envModel || localConfig.model || constants.DEFAULT_GEMINI_MODEL;
|
|
102
|
+
logger.logger.debug(`[Gemini] Selected model: ${model}`);
|
|
136
103
|
return model;
|
|
137
104
|
}
|
|
138
105
|
}
|
|
@@ -148,15 +115,15 @@ function saveGeminiModelToConfig(model) {
|
|
|
148
115
|
try {
|
|
149
116
|
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
150
117
|
} catch (error) {
|
|
151
|
-
|
|
118
|
+
logger.logger.debug(`[Gemini] Failed to read existing config, creating new one`);
|
|
152
119
|
config = {};
|
|
153
120
|
}
|
|
154
121
|
}
|
|
155
122
|
config.model = model;
|
|
156
123
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
157
|
-
|
|
124
|
+
logger.logger.debug(`[Gemini] Saved model "${model}" to ${configPath}`);
|
|
158
125
|
} catch (error) {
|
|
159
|
-
|
|
126
|
+
logger.logger.debug(`[Gemini] Failed to save model to config:`, error);
|
|
160
127
|
}
|
|
161
128
|
}
|
|
162
129
|
function saveGoogleCloudProjectToConfig(projectId, email) {
|
|
@@ -179,20 +146,20 @@ function saveGoogleCloudProjectToConfig(projectId, email) {
|
|
|
179
146
|
config.googleCloudProjectEmail = email;
|
|
180
147
|
}
|
|
181
148
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
182
|
-
|
|
149
|
+
logger.logger.debug(`[Gemini] Saved Google Cloud Project "${projectId}"${email ? ` for ${email}` : ""} to ${configPath}`);
|
|
183
150
|
} catch (error) {
|
|
184
|
-
|
|
151
|
+
logger.logger.debug(`[Gemini] Failed to save Google Cloud Project to config:`, error);
|
|
185
152
|
throw error;
|
|
186
153
|
}
|
|
187
154
|
}
|
|
188
155
|
function getInitialGeminiModel() {
|
|
189
156
|
const localConfig = readGeminiLocalConfig();
|
|
190
|
-
return process.env[
|
|
157
|
+
return process.env[constants.GEMINI_MODEL_ENV] || localConfig.model || constants.DEFAULT_GEMINI_MODEL;
|
|
191
158
|
}
|
|
192
159
|
function getGeminiModelSource(explicitModel, localConfig) {
|
|
193
160
|
if (explicitModel !== void 0 && explicitModel !== null) {
|
|
194
161
|
return "explicit";
|
|
195
|
-
} else if (process.env[
|
|
162
|
+
} else if (process.env[constants.GEMINI_MODEL_ENV]) {
|
|
196
163
|
return "env-var";
|
|
197
164
|
} else if (localConfig.model) {
|
|
198
165
|
return "local-config";
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { mkdirSync, chmodSync, readdirSync, statSync, appendFileSync, writeFileSync, existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { p as packageJson } from './package-uOg9SCKi.mjs';
|
|
5
|
+
import { mkdir, chmod, writeFile } from 'node:fs/promises';
|
|
6
|
+
|
|
7
|
+
const PRIVATE_DIRECTORY_MODE = 448;
|
|
8
|
+
const PRIVATE_FILE_MODE = 384;
|
|
9
|
+
function ignoreUnsupportedPermissions(error) {
|
|
10
|
+
if (process.platform !== "win32") throw error;
|
|
11
|
+
}
|
|
12
|
+
function ensurePrivateDirectorySync(path) {
|
|
13
|
+
mkdirSync(path, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
|
|
14
|
+
try {
|
|
15
|
+
chmodSync(path, PRIVATE_DIRECTORY_MODE);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
ignoreUnsupportedPermissions(error);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function ensurePrivateDirectory(path) {
|
|
21
|
+
await mkdir(path, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
|
|
22
|
+
try {
|
|
23
|
+
await chmod(path, PRIVATE_DIRECTORY_MODE);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
ignoreUnsupportedPermissions(error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function hardenPrivateFileSync(path) {
|
|
29
|
+
try {
|
|
30
|
+
chmodSync(path, PRIVATE_FILE_MODE);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
ignoreUnsupportedPermissions(error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function hardenPrivateDirectoryFilesSync(path) {
|
|
36
|
+
for (const name of readdirSync(path)) {
|
|
37
|
+
const candidate = join(path, name);
|
|
38
|
+
try {
|
|
39
|
+
if (statSync(candidate).isFile()) hardenPrivateFileSync(candidate);
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function hardenPrivateFile(path) {
|
|
45
|
+
try {
|
|
46
|
+
await chmod(path, PRIVATE_FILE_MODE);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
ignoreUnsupportedPermissions(error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function writePrivateFileSync(path, data) {
|
|
52
|
+
writeFileSync(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
53
|
+
hardenPrivateFileSync(path);
|
|
54
|
+
}
|
|
55
|
+
async function writePrivateFile(path, data) {
|
|
56
|
+
await writeFile(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
57
|
+
await hardenPrivateFile(path);
|
|
58
|
+
}
|
|
59
|
+
function appendPrivateFileSync(path, data) {
|
|
60
|
+
appendFileSync(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
61
|
+
hardenPrivateFileSync(path);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const DEFAULT_RELAY_URL = "https://veryhappy.dev";
|
|
65
|
+
function normalizeHttpEndpoint(value, source) {
|
|
66
|
+
const trimmed = value.trim();
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = new URL(trimmed);
|
|
70
|
+
} catch {
|
|
71
|
+
throw new Error(`${source} must be an absolute http(s) origin`);
|
|
72
|
+
}
|
|
73
|
+
const onlyOriginPath = /^\/+$/u.test(parsed.pathname);
|
|
74
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username.length > 0 || parsed.password.length > 0 || !onlyOriginPath || parsed.search.length > 0 || parsed.hash.length > 0) {
|
|
75
|
+
throw new Error(`${source} must be an http(s) origin without credentials, path, query, or fragment`);
|
|
76
|
+
}
|
|
77
|
+
return parsed.origin;
|
|
78
|
+
}
|
|
79
|
+
function resolveHttpEndpoint(environmentValue, settingsValue, environmentName, settingsName) {
|
|
80
|
+
if (environmentValue !== void 0) {
|
|
81
|
+
return normalizeHttpEndpoint(environmentValue, environmentName);
|
|
82
|
+
}
|
|
83
|
+
if (settingsValue !== void 0) {
|
|
84
|
+
return normalizeHttpEndpoint(settingsValue, `settings.${settingsName}`);
|
|
85
|
+
}
|
|
86
|
+
return DEFAULT_RELAY_URL;
|
|
87
|
+
}
|
|
88
|
+
class Configuration {
|
|
89
|
+
serverUrl;
|
|
90
|
+
webappUrl;
|
|
91
|
+
isDaemonProcess;
|
|
92
|
+
// Directories and paths (from persistence)
|
|
93
|
+
happyHomeDir;
|
|
94
|
+
logsDir;
|
|
95
|
+
settingsFile;
|
|
96
|
+
privateKeyFile;
|
|
97
|
+
daemonStateFile;
|
|
98
|
+
daemonLockFile;
|
|
99
|
+
sessionsFile;
|
|
100
|
+
currentCliVersion;
|
|
101
|
+
isExperimentalEnabled;
|
|
102
|
+
disableCaffeinate;
|
|
103
|
+
constructor() {
|
|
104
|
+
const args = process.argv.slice(2);
|
|
105
|
+
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
106
|
+
if (process.env.HAPPY_HOME_DIR) {
|
|
107
|
+
const expandedPath = process.env.HAPPY_HOME_DIR.replace(/^~/, homedir());
|
|
108
|
+
this.happyHomeDir = expandedPath;
|
|
109
|
+
} else {
|
|
110
|
+
this.happyHomeDir = join(homedir(), ".happy");
|
|
111
|
+
}
|
|
112
|
+
this.logsDir = join(this.happyHomeDir, "logs");
|
|
113
|
+
this.settingsFile = join(this.happyHomeDir, "settings.json");
|
|
114
|
+
this.privateKeyFile = join(this.happyHomeDir, "access.key");
|
|
115
|
+
this.daemonStateFile = join(this.happyHomeDir, "daemon.state.json");
|
|
116
|
+
this.daemonLockFile = join(this.happyHomeDir, "daemon.state.json.lock");
|
|
117
|
+
this.sessionsFile = join(this.happyHomeDir, "sessions.json");
|
|
118
|
+
try {
|
|
119
|
+
this.serverUrl = resolveHttpEndpoint(
|
|
120
|
+
process.env.HAPPY_SERVER_URL,
|
|
121
|
+
readSettingsStringSync(this.settingsFile, "serverUrl"),
|
|
122
|
+
"HAPPY_SERVER_URL",
|
|
123
|
+
"serverUrl"
|
|
124
|
+
);
|
|
125
|
+
this.webappUrl = resolveHttpEndpoint(
|
|
126
|
+
process.env.HAPPY_WEBAPP_URL,
|
|
127
|
+
readSettingsStringSync(this.settingsFile, "webappUrl"),
|
|
128
|
+
"HAPPY_WEBAPP_URL",
|
|
129
|
+
"webappUrl"
|
|
130
|
+
);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
const message = error instanceof Error ? error.message : "invalid client endpoint";
|
|
133
|
+
process.stderr.write(`[very-happy] Configuration error: ${message}
|
|
134
|
+
`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
|
|
138
|
+
this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
|
|
139
|
+
this.currentCliVersion = packageJson.version;
|
|
140
|
+
const variant = process.env.HAPPY_VARIANT || "stable";
|
|
141
|
+
if (!this.isDaemonProcess && variant === "dev") {
|
|
142
|
+
console.log("\x1B[33m\u{1F527} DEV MODE\x1B[0m - Data: " + this.happyHomeDir);
|
|
143
|
+
}
|
|
144
|
+
ensurePrivateDirectorySync(this.happyHomeDir);
|
|
145
|
+
ensurePrivateDirectorySync(this.logsDir);
|
|
146
|
+
for (const privateFile of [
|
|
147
|
+
this.settingsFile,
|
|
148
|
+
this.privateKeyFile,
|
|
149
|
+
this.daemonStateFile,
|
|
150
|
+
this.daemonLockFile,
|
|
151
|
+
this.sessionsFile
|
|
152
|
+
]) {
|
|
153
|
+
if (existsSync(privateFile)) hardenPrivateFileSync(privateFile);
|
|
154
|
+
}
|
|
155
|
+
hardenPrivateDirectoryFilesSync(this.logsDir);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function readSettingsStringSync(settingsFile, key) {
|
|
159
|
+
try {
|
|
160
|
+
if (!existsSync(settingsFile)) return void 0;
|
|
161
|
+
const raw = JSON.parse(readFileSync(settingsFile, "utf8"));
|
|
162
|
+
const value = raw?.[key];
|
|
163
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
164
|
+
} catch {
|
|
165
|
+
return void 0;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const configuration = new Configuration();
|
|
169
|
+
|
|
170
|
+
export { PRIVATE_FILE_MODE as P, writePrivateFile as a, hardenPrivateFile as b, configuration as c, appendPrivateFileSync as d, ensurePrivateDirectory as e, ensurePrivateDirectorySync as f, hardenPrivateFileSync as h, normalizeHttpEndpoint as n, writePrivateFileSync as w };
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node_fs = require('node:fs');
|
|
4
|
+
var os = require('node:os');
|
|
5
|
+
var path = require('node:path');
|
|
6
|
+
var _package = require('./package-Cl5BEP5x.cjs');
|
|
7
|
+
var promises = require('node:fs/promises');
|
|
8
|
+
|
|
9
|
+
const PRIVATE_DIRECTORY_MODE = 448;
|
|
10
|
+
const PRIVATE_FILE_MODE = 384;
|
|
11
|
+
function ignoreUnsupportedPermissions(error) {
|
|
12
|
+
if (process.platform !== "win32") throw error;
|
|
13
|
+
}
|
|
14
|
+
function ensurePrivateDirectorySync(path) {
|
|
15
|
+
node_fs.mkdirSync(path, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
|
|
16
|
+
try {
|
|
17
|
+
node_fs.chmodSync(path, PRIVATE_DIRECTORY_MODE);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
ignoreUnsupportedPermissions(error);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function ensurePrivateDirectory(path) {
|
|
23
|
+
await promises.mkdir(path, { recursive: true, mode: PRIVATE_DIRECTORY_MODE });
|
|
24
|
+
try {
|
|
25
|
+
await promises.chmod(path, PRIVATE_DIRECTORY_MODE);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
ignoreUnsupportedPermissions(error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function hardenPrivateFileSync(path) {
|
|
31
|
+
try {
|
|
32
|
+
node_fs.chmodSync(path, PRIVATE_FILE_MODE);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
ignoreUnsupportedPermissions(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function hardenPrivateDirectoryFilesSync(path$1) {
|
|
38
|
+
for (const name of node_fs.readdirSync(path$1)) {
|
|
39
|
+
const candidate = path.join(path$1, name);
|
|
40
|
+
try {
|
|
41
|
+
if (node_fs.statSync(candidate).isFile()) hardenPrivateFileSync(candidate);
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async function hardenPrivateFile(path) {
|
|
47
|
+
try {
|
|
48
|
+
await promises.chmod(path, PRIVATE_FILE_MODE);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
ignoreUnsupportedPermissions(error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function writePrivateFileSync(path, data) {
|
|
54
|
+
node_fs.writeFileSync(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
55
|
+
hardenPrivateFileSync(path);
|
|
56
|
+
}
|
|
57
|
+
async function writePrivateFile(path, data) {
|
|
58
|
+
await promises.writeFile(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
59
|
+
await hardenPrivateFile(path);
|
|
60
|
+
}
|
|
61
|
+
function appendPrivateFileSync(path, data) {
|
|
62
|
+
node_fs.appendFileSync(path, data, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
63
|
+
hardenPrivateFileSync(path);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const DEFAULT_RELAY_URL = "https://veryhappy.dev";
|
|
67
|
+
function normalizeHttpEndpoint(value, source) {
|
|
68
|
+
const trimmed = value.trim();
|
|
69
|
+
let parsed;
|
|
70
|
+
try {
|
|
71
|
+
parsed = new URL(trimmed);
|
|
72
|
+
} catch {
|
|
73
|
+
throw new Error(`${source} must be an absolute http(s) origin`);
|
|
74
|
+
}
|
|
75
|
+
const onlyOriginPath = /^\/+$/u.test(parsed.pathname);
|
|
76
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username.length > 0 || parsed.password.length > 0 || !onlyOriginPath || parsed.search.length > 0 || parsed.hash.length > 0) {
|
|
77
|
+
throw new Error(`${source} must be an http(s) origin without credentials, path, query, or fragment`);
|
|
78
|
+
}
|
|
79
|
+
return parsed.origin;
|
|
80
|
+
}
|
|
81
|
+
function resolveHttpEndpoint(environmentValue, settingsValue, environmentName, settingsName) {
|
|
82
|
+
if (environmentValue !== void 0) {
|
|
83
|
+
return normalizeHttpEndpoint(environmentValue, environmentName);
|
|
84
|
+
}
|
|
85
|
+
if (settingsValue !== void 0) {
|
|
86
|
+
return normalizeHttpEndpoint(settingsValue, `settings.${settingsName}`);
|
|
87
|
+
}
|
|
88
|
+
return DEFAULT_RELAY_URL;
|
|
89
|
+
}
|
|
90
|
+
class Configuration {
|
|
91
|
+
serverUrl;
|
|
92
|
+
webappUrl;
|
|
93
|
+
isDaemonProcess;
|
|
94
|
+
// Directories and paths (from persistence)
|
|
95
|
+
happyHomeDir;
|
|
96
|
+
logsDir;
|
|
97
|
+
settingsFile;
|
|
98
|
+
privateKeyFile;
|
|
99
|
+
daemonStateFile;
|
|
100
|
+
daemonLockFile;
|
|
101
|
+
sessionsFile;
|
|
102
|
+
currentCliVersion;
|
|
103
|
+
isExperimentalEnabled;
|
|
104
|
+
disableCaffeinate;
|
|
105
|
+
constructor() {
|
|
106
|
+
const args = process.argv.slice(2);
|
|
107
|
+
this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
|
|
108
|
+
if (process.env.HAPPY_HOME_DIR) {
|
|
109
|
+
const expandedPath = process.env.HAPPY_HOME_DIR.replace(/^~/, os.homedir());
|
|
110
|
+
this.happyHomeDir = expandedPath;
|
|
111
|
+
} else {
|
|
112
|
+
this.happyHomeDir = path.join(os.homedir(), ".happy");
|
|
113
|
+
}
|
|
114
|
+
this.logsDir = path.join(this.happyHomeDir, "logs");
|
|
115
|
+
this.settingsFile = path.join(this.happyHomeDir, "settings.json");
|
|
116
|
+
this.privateKeyFile = path.join(this.happyHomeDir, "access.key");
|
|
117
|
+
this.daemonStateFile = path.join(this.happyHomeDir, "daemon.state.json");
|
|
118
|
+
this.daemonLockFile = path.join(this.happyHomeDir, "daemon.state.json.lock");
|
|
119
|
+
this.sessionsFile = path.join(this.happyHomeDir, "sessions.json");
|
|
120
|
+
try {
|
|
121
|
+
this.serverUrl = resolveHttpEndpoint(
|
|
122
|
+
process.env.HAPPY_SERVER_URL,
|
|
123
|
+
readSettingsStringSync(this.settingsFile, "serverUrl"),
|
|
124
|
+
"HAPPY_SERVER_URL",
|
|
125
|
+
"serverUrl"
|
|
126
|
+
);
|
|
127
|
+
this.webappUrl = resolveHttpEndpoint(
|
|
128
|
+
process.env.HAPPY_WEBAPP_URL,
|
|
129
|
+
readSettingsStringSync(this.settingsFile, "webappUrl"),
|
|
130
|
+
"HAPPY_WEBAPP_URL",
|
|
131
|
+
"webappUrl"
|
|
132
|
+
);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : "invalid client endpoint";
|
|
135
|
+
process.stderr.write(`[very-happy] Configuration error: ${message}
|
|
136
|
+
`);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
|
|
140
|
+
this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
|
|
141
|
+
this.currentCliVersion = _package.packageJson.version;
|
|
142
|
+
const variant = process.env.HAPPY_VARIANT || "stable";
|
|
143
|
+
if (!this.isDaemonProcess && variant === "dev") {
|
|
144
|
+
console.log("\x1B[33m\u{1F527} DEV MODE\x1B[0m - Data: " + this.happyHomeDir);
|
|
145
|
+
}
|
|
146
|
+
ensurePrivateDirectorySync(this.happyHomeDir);
|
|
147
|
+
ensurePrivateDirectorySync(this.logsDir);
|
|
148
|
+
for (const privateFile of [
|
|
149
|
+
this.settingsFile,
|
|
150
|
+
this.privateKeyFile,
|
|
151
|
+
this.daemonStateFile,
|
|
152
|
+
this.daemonLockFile,
|
|
153
|
+
this.sessionsFile
|
|
154
|
+
]) {
|
|
155
|
+
if (node_fs.existsSync(privateFile)) hardenPrivateFileSync(privateFile);
|
|
156
|
+
}
|
|
157
|
+
hardenPrivateDirectoryFilesSync(this.logsDir);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function readSettingsStringSync(settingsFile, key) {
|
|
161
|
+
try {
|
|
162
|
+
if (!node_fs.existsSync(settingsFile)) return void 0;
|
|
163
|
+
const raw = JSON.parse(node_fs.readFileSync(settingsFile, "utf8"));
|
|
164
|
+
const value = raw?.[key];
|
|
165
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
166
|
+
} catch {
|
|
167
|
+
return void 0;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const configuration = new Configuration();
|
|
171
|
+
|
|
172
|
+
exports.PRIVATE_FILE_MODE = PRIVATE_FILE_MODE;
|
|
173
|
+
exports.appendPrivateFileSync = appendPrivateFileSync;
|
|
174
|
+
exports.configuration = configuration;
|
|
175
|
+
exports.ensurePrivateDirectory = ensurePrivateDirectory;
|
|
176
|
+
exports.ensurePrivateDirectorySync = ensurePrivateDirectorySync;
|
|
177
|
+
exports.hardenPrivateFile = hardenPrivateFile;
|
|
178
|
+
exports.hardenPrivateFileSync = hardenPrivateFileSync;
|
|
179
|
+
exports.normalizeHttpEndpoint = normalizeHttpEndpoint;
|
|
180
|
+
exports.writePrivateFile = writePrivateFile;
|
|
181
|
+
exports.writePrivateFileSync = writePrivateFileSync;
|