very-happy-cli 0.2.179 → 0.2.181
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-DFipFF7-.cjs → AcpBackend-CgHb_ya5.cjs} +3 -3
- package/dist/{AcpBackend-CHp3y7cb.mjs → AcpBackend-DZGCSuXF.mjs} +3 -3
- package/dist/{AcpSessionManager-0zpvRJXc.cjs → AcpSessionManager-CacC2EVn.cjs} +1 -1
- package/dist/{AcpSessionManager-d2-rKWWa.mjs → AcpSessionManager-DwuPzWBh.mjs} +1 -1
- package/dist/{BasePermissionHandler-CH3zuEkA.cjs → BasePermissionHandler-DCP8ZEB4.cjs} +1 -1
- package/dist/{BasePermissionHandler-DdZBYIR4.mjs → BasePermissionHandler-Uo-GUjbb.mjs} +1 -1
- package/dist/{acpSessionResume-DTGmAPLt.mjs → acpSessionResume-9OLTD6kT.mjs} +1 -1
- package/dist/{acpSessionResume-oiCBnAVA.cjs → acpSessionResume-BaVMD80f.cjs} +1 -1
- package/dist/{agentHome-CghLvL_1.mjs → agentHome-B1BsKeqD.mjs} +4 -4
- package/dist/{agentHome-BWcz8mz0.cjs → agentHome-BtUmGcPX.cjs} +4 -4
- package/dist/{api-Cmjfr8Z7.cjs → api-COHFAkb_.cjs} +20 -12
- package/dist/{api-CzwFpJQc.mjs → api-Dr3wXL_7.mjs} +21 -13
- package/dist/{apiMachine-DJkTEiqy.mjs → apiMachine-CHEzPQdS.mjs} +73 -32
- package/dist/{apiMachine-G6OogT08.cjs → apiMachine-D8H7CXaz.cjs} +75 -34
- package/dist/{attachmentContent-B2os4HbA.mjs → attachmentContent-1YwtKgWl.mjs} +2 -2
- package/dist/{attachmentContent-Bo0UAsSu.cjs → attachmentContent-mIhbtRKl.cjs} +2 -2
- package/dist/{auth-DMX0xPNK.mjs → auth-CbZkcMAb.mjs} +8 -8
- package/dist/{auth-D6bBUwZa.cjs → auth-CgQP7d0q.cjs} +5 -5
- package/dist/{auth-BS6PaOOG.mjs → auth-DZsthtSk.mjs} +5 -5
- package/dist/{auth-HEhRaNgL.cjs → auth-Fg8fLadK.cjs} +8 -8
- package/dist/{auto-C6I55iOh.cjs → auto-BB7kqSh5.cjs} +19 -19
- package/dist/{auto-Cl1SEDcD.mjs → auto-_T-Ud-z5.mjs} +19 -19
- package/dist/{backgroundTaskActivity-BVwJBl02.mjs → backgroundTaskActivity-8PdPxrvy.mjs} +1 -1
- package/dist/{bootstrap-iuyufnp3.mjs → bootstrap-B6EkZh4u.mjs} +2 -2
- package/dist/{bootstrap-exVucYav.cjs → bootstrap-CYtOtbi7.cjs} +2 -2
- package/dist/{browser-CSYum7xH.mjs → browser-C2qhUHSE.mjs} +1 -1
- package/dist/{browser-BohJK12g.cjs → browser-DjNNQQk2.cjs} +1 -1
- package/dist/{claudeCliPath-U4HHmV4r.cjs → claudeCliPath-GaP3UUz1.cjs} +1 -1
- package/dist/{claudeLocal-Dq_R3Ax_.mjs → claudeLocal-BAFjWhZ8.mjs} +6 -6
- package/dist/{claudeLocal-re4yjSTx.cjs → claudeLocal-O_w7-fBh.cjs} +8 -8
- package/dist/{claudeLocalLauncher-CN67lN7-.mjs → claudeLocalLauncher-CWn30LZR.mjs} +11 -11
- package/dist/{claudeLocalLauncher-B4hJHpCA.cjs → claudeLocalLauncher-Df3zg1q0.cjs} +13 -13
- package/dist/{claudeSessionFork-BihfD0Ik.mjs → claudeSessionFork-2ZkSTOGn.mjs} +1 -1
- package/dist/{claudeSessionFork-DiSMYerV.cjs → claudeSessionFork-pwcKqB-e.cjs} +1 -1
- package/dist/{client-BhoEBnuN.mjs → client-BKyU66lg.mjs} +2 -2
- package/dist/{client-BKcK1Bi-.cjs → client-CUO3ItoB.cjs} +34 -8
- package/dist/{client-wo9nbxuf.mjs → client-CXOnzuOy.mjs} +2 -2
- package/dist/{client-ZjOsn6nZ.cjs → client-DWs6k041.cjs} +2 -2
- package/dist/{client-CuVdN6PP.cjs → client-D_U2VjO3.cjs} +2 -2
- package/dist/{client-DuTDwWSQ.mjs → client-DsQcxVUV.mjs} +34 -9
- package/dist/codex/happyMcpStdioBridge.cjs +17 -17
- package/dist/codex/happyMcpStdioBridge.mjs +18 -18
- package/dist/{codexAppServerClient-Dt5zxrun.cjs → codexAppServerClient-BRX3JZ_5.cjs} +3 -3
- package/dist/{codexAppServerClient-BK3zra_1.mjs → codexAppServerClient-C3JO3pwM.mjs} +3 -3
- package/dist/{codexCommand-B6pY7CMh.mjs → codexCommand-BZIAAqKS.mjs} +59 -51
- package/dist/{codexCommand-CAZ1SLjg.cjs → codexCommand-dKOc5iQl.cjs} +85 -77
- package/dist/{codexTermination-DmGbHxcD.cjs → codexTermination-BVR9HeVI.cjs} +7 -2
- package/dist/{codexTermination-Cd1Eon_4.mjs → codexTermination-ztFkwHrG.mjs} +7 -2
- package/dist/{config-2oMG_fEI.mjs → config-NbHjx8ge.mjs} +3 -3
- package/dist/{config-B0uK6K7n.cjs → config-cftYxLC7.cjs} +26 -26
- package/dist/{configuration-WMi4idBB.mjs → configuration-BPrfb17M.mjs} +1 -1
- package/dist/{configuration-CMHZnp6G.cjs → configuration-C8JgseHy.cjs} +1 -1
- package/dist/{connect-uaglGrde.cjs → connect-Br8VMrK1.cjs} +27 -27
- package/dist/{connect-BLVHhHzA.mjs → connect-CLD1ai0k.mjs} +14 -14
- package/dist/{context-DXzU5bFM.cjs → context-D1lgQTJC.cjs} +1 -1
- package/dist/{context-DploEcoN.mjs → context-_YGq8xdH.mjs} +1 -1
- package/dist/{controlClient-BWUJrj3t.mjs → controlClient-CkNpT5zS.mjs} +4 -4
- package/dist/{controlClient-C-5qCt8W.cjs → controlClient-D68Zj7Q-.cjs} +3 -3
- package/dist/{createSessionMetadata-3uXrJgOW.mjs → createSessionMetadata-3WAj3_xl.mjs} +2 -2
- package/dist/{createSessionMetadata-BkIzHALd.cjs → createSessionMetadata-DNIbKLHg.cjs} +3 -3
- package/dist/{defaultPermissionMode-pS3vmiSg.cjs → defaultPermissionMode-BmvjP32v.cjs} +2 -2
- package/dist/{defaultPermissionMode-BzxLh20a.mjs → defaultPermissionMode-DXMznl8v.mjs} +2 -2
- package/dist/{detectCLI-DR9ZaN6B.cjs → detectCLI-BuYR_Qxe.cjs} +4 -4
- package/dist/{deterministicJson-B8z2GPi9.cjs → deterministicJson-BS7D7URE.cjs} +89 -24
- package/dist/{deterministicJson-D_whDMFd.mjs → deterministicJson-BcBIKKf1.mjs} +87 -24
- package/dist/{doctor-Br1Kcy2J.cjs → doctor-Be7zC0AF.cjs} +10 -9
- package/dist/{doctor-CmtSsR2-.mjs → doctor-CoOaPq6w.mjs} +8 -8
- package/dist/{doctorReadiness-BCZGcN0a.cjs → doctorReadiness-Dl6yRQCy.cjs} +1 -1
- package/dist/{downloadTarget-BoNwTIH_.mjs → downloadTarget-CeaAXdJj.mjs} +6 -6
- package/dist/{downloadTarget-BQJK_6oH.cjs → downloadTarget-LyOiucn_.cjs} +6 -6
- package/dist/{ensureDaemonRunning-Czo9IHJQ.mjs → ensureDaemonRunning--98j7-17.mjs} +5 -5
- package/dist/{ensureDaemonRunning-BRUmsq6J.cjs → ensureDaemonRunning-B8z37VKD.cjs} +6 -6
- package/dist/fileStore-5qpetZS0.mjs +146 -0
- package/dist/fileStore-7qhnbs6N.cjs +152 -0
- package/dist/{handleResumeCommand-tKD_Hpxc.cjs → handleResumeCommand-BFZlrFVH.cjs} +7 -7
- package/dist/{handleResumeCommand-C8thKjqf.mjs → handleResumeCommand-gO8I4keP.mjs} +6 -6
- package/dist/{index-DMqDMT1Q.cjs → index-B5PXbZjW.cjs} +80 -62
- package/dist/{index-D09T1m8Y.cjs → index-BRMq9gOe.cjs} +3 -3
- package/dist/{index-B0UjHlAe.cjs → index-BkluinoS.cjs} +4 -4
- package/dist/{index-CdQI0C9p.mjs → index-CO0n9ue6.mjs} +4 -4
- package/dist/{index-DPOa4NhL.mjs → index-CeRXrGnH.mjs} +41 -6
- package/dist/{index-C6O2vVjm.cjs → index-Df2eHm3O.cjs} +42 -6
- package/dist/{index-BTxHphpV.mjs → index-DneHoQXf.mjs} +80 -62
- package/dist/{index-BiyC7cZ3.mjs → index-WUj3954m.mjs} +4 -4
- package/dist/{index-D3bidoG8.mjs → index-hQ8LP1C2.mjs} +3 -3
- package/dist/{index-CUuc6iCn.cjs → index-jF2t3ACW.cjs} +4 -4
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{install-BX3lv3NO.mjs → install-D0inLCv-.mjs} +1 -1
- package/dist/{install-BXvf2E3o.cjs → install-D2NCbeJ-.cjs} +1 -1
- package/dist/{install-hnve_9vq.mjs → install-DkYFiVK4.mjs} +3 -3
- package/dist/{install-CYRZxS87.cjs → install-FqkSUjPC.cjs} +7 -7
- package/dist/{installPiTools-BKnXjrVu.cjs → installPiTools-CL_axh_6.cjs} +1 -1
- package/dist/{installTerminalHooks-BQZbvxsZ.cjs → installTerminalHooks-BETLKAtd.cjs} +3 -3
- package/dist/lib.cjs +13 -13
- package/dist/lib.d.cts +216 -2
- package/dist/lib.d.mts +216 -2
- package/dist/lib.mjs +13 -13
- package/dist/{lidState-Bb8fgXg3.mjs → lidState-DghbfRbr.mjs} +1 -1
- package/dist/{lidState-Dv2wwFTj.cjs → lidState-x8cJ8J_9.cjs} +1 -1
- package/dist/{localHappyAgentAuth-DjYvkXvV.cjs → localHappyAgentAuth-DZ2kb9uq.cjs} +1 -1
- package/dist/{localHappyAgentAuth-NEU7fax7.mjs → localHappyAgentAuth-IKmeRpuQ.mjs} +1 -1
- package/dist/{logger-C1GWx3gi.cjs → logger-DgBwUSgS.cjs} +2 -2
- package/dist/{logger-BtVhHnD8.mjs → logger-LFr8iPgl.mjs} +2 -2
- package/dist/machineMetadata-BglCsfvf.mjs +75 -0
- package/dist/machineMetadata-DB03ez4K.cjs +87 -0
- package/dist/{main-CWhSsbtU.cjs → main-YQ-Vkakw.cjs} +99 -132
- package/dist/{main-B2LWV8DI.mjs → main-_1LSzlLv.mjs} +93 -126
- package/dist/{mcp-CARUsXHV.cjs → mcp-BIY80jSc.cjs} +15 -15
- package/dist/{mcp-ext92q3Y.mjs → mcp-Csj-mT5Y.mjs} +15 -15
- package/dist/{mirrorProtocol-DEy2g1CB.cjs → mirrorProtocol-BphKIAK9.cjs} +15 -6
- package/dist/{mirrorProtocol-BwYibqry.mjs → mirrorProtocol-CAxOMBkb.mjs} +15 -6
- package/dist/{package-BPPebGQF.mjs → package-DYGwlmXl.mjs} +9 -8
- package/dist/{package-SgqTYsjn.cjs → package-NoD8QOOM.cjs} +9 -8
- package/dist/{panels-BZ0_Tt7B.mjs → panels-B8zRm7_d.mjs} +5 -5
- package/dist/{panels-D1c7q2dD.cjs → panels-DYEc1NyQ.cjs} +5 -5
- package/dist/{peerTools-CWKzcQ7u.mjs → peerTools-CK3JYu1k.mjs} +5 -5
- package/dist/{peerTools-DRQETXaz.cjs → peerTools-CP-x-Peu.cjs} +5 -5
- package/dist/{persistence-BegE7NPa.cjs → persistence-BY-D00wT.cjs} +2 -2
- package/dist/{persistence-Cr-wutZ4.mjs → persistence-D2Djrf7t.mjs} +2 -2
- package/dist/pi-CqyoZMjI.mjs +380 -0
- package/dist/pi-DlsrPCTa.cjs +400 -0
- package/dist/{piRunnerArgs-DwvM_yWA.mjs → piRunnerArgs-IZLoL7TG.mjs} +1 -1
- package/dist/{piRunnerArgs-Cs-378Vz.cjs → piRunnerArgs-gxLYIZH4.cjs} +1 -1
- package/dist/{piRuntime-Bue5mnlc.mjs → piRuntime-D7Y4oHVL.mjs} +2 -2
- package/dist/{piRuntime-BG-1td_n.cjs → piRuntime-o5L8uX-W.cjs} +2 -2
- package/dist/{piTerminal-G4z-xVyy.cjs → piTerminal-C_-JDkLN.cjs} +18 -18
- package/dist/{piTerminal-B5x9X5yV.mjs → piTerminal-Kphx8Uhw.mjs} +18 -18
- package/dist/projectPath-C3ioB4Bu.cjs +13 -0
- package/dist/{prompt-lgF9IE82.cjs → prompt-Bof2aQkI.cjs} +7 -2
- package/dist/{prompt-BOouDaTM.mjs → prompt-QHuFx9j6.mjs} +7 -2
- package/dist/{pushNotifications-DaLQUyi0.cjs → pushNotifications-BXoOSq_G.cjs} +14 -4
- package/dist/{pushNotifications-BdFjDjQe.mjs → pushNotifications-DXGIhE-A.mjs} +14 -4
- package/dist/{query-DYP_W1wp.mjs → query-CcA6DVZK.mjs} +1 -1
- package/dist/{query-Ctfg-5gy.cjs → query-CdCxzuaB.cjs} +1 -1
- package/dist/{rateLimitWindows-Dj_8voBK.cjs → rateLimitWindows-OpAmdOtC.cjs} +1 -1
- package/dist/{rateLimitWindows-CuEqk_0g.mjs → rateLimitWindows-ZtHZHe-l.mjs} +1 -1
- package/dist/{registerCommonHandlers-Cj084Sg7.cjs → registerCommonHandlers-CRjBoJLK.cjs} +30 -30
- package/dist/{registerCommonHandlers-BAlP7SGc.mjs → registerCommonHandlers-DF6bdDtd.mjs} +2 -2
- package/dist/{registerKillSessionHandler-qMju0ZfF.cjs → registerKillSessionHandler-7fOm6ooh.cjs} +6 -6
- package/dist/{registerKillSessionHandler-PD0jWtQo.mjs → registerKillSessionHandler-DDCKL3wf.mjs} +6 -6
- package/dist/{remoteSessionClient-Bn2qu5C5.mjs → remoteSessionClient-B2POSKFT.mjs} +5 -5
- package/dist/{remoteSessionClient-B7i7MkYV.cjs → remoteSessionClient-CFCn42bs.cjs} +5 -5
- package/dist/{reportProgressTool-gHItlSzz.mjs → reportProgressTool-tPxEvh6x.mjs} +4 -4
- package/dist/{reportProgressTool-CM1JFAHg.cjs → reportProgressTool-th4trcET.cjs} +4 -4
- package/dist/{resources-CvIlkzpP.cjs → resources-BPyN59Iv.cjs} +23 -2
- package/dist/{resources-y9jfyO-_.mjs → resources-CH1iP6Cv.mjs} +22 -3
- package/dist/{run-CNXwIe0A.cjs → run-C_FumCQk.cjs} +2767 -183
- package/dist/{run-BM4TxiyN.mjs → run-cKQBbVi4.mjs} +2762 -178
- package/dist/{runClaude-C_3I8hvR.mjs → runClaude-CYnM6krL.mjs} +34 -28
- package/dist/{runClaude-CWhj2V4Q.cjs → runClaude-z_2YC_aa.cjs} +35 -29
- package/dist/{runClaudeDeps-B81cOKnH.cjs → runClaudeDeps-CLubzWnA.cjs} +59 -122
- package/dist/{runClaudeDeps-QGrOeDe2.mjs → runClaudeDeps-duS06Pb4.mjs} +52 -114
- package/dist/{runGemini-BEdWEZLR.mjs → runGemini-C_Pc2EhH.mjs} +39 -37
- package/dist/{runGemini-CgRLYbt5.cjs → runGemini-vEoXV6qT.cjs} +67 -65
- package/dist/{runOpenClaw-C1NVmzOL.cjs → runOpenClaw-CXJCtMgB.cjs} +20 -20
- package/dist/{runOpenClaw-DdQZAYj1.mjs → runOpenClaw-Cxun1qLC.mjs} +19 -19
- package/dist/{sandbox-nocIjliq.cjs → sandbox-CO46H2tK.cjs} +4 -4
- package/dist/{sandbox-DjQUdCMG.mjs → sandbox-CsvPnTmz.mjs} +4 -4
- package/dist/{selfCheck-DCt4Uzbq.cjs → selfCheck-DIr7Gc0i.cjs} +39 -39
- package/dist/selfCheck-NamtBHVB.mjs +85 -0
- package/dist/{send-Ct7X4pPU.mjs → send-DMoFg6F1.mjs} +9 -9
- package/dist/{send-Dydf_hwZ.cjs → send-X2mfVEyr.cjs} +8 -8
- package/dist/{server-CosABFbd.cjs → server-BwTEdbkr.cjs} +6 -6
- package/dist/{server-DTQGZMxh.mjs → server-CkqQ0sRH.mjs} +4 -4
- package/dist/sessionExitLifecycle-CzkLIgNZ.mjs +142 -0
- package/dist/sessionExitLifecycle-DFltxXU8.cjs +148 -0
- package/dist/{sessionLock-DokGab2R.cjs → sessionLock-CdIRJlHH.cjs} +25 -5
- package/dist/{sessionLock-WYIyaVO4.mjs → sessionLock-JIfwCqMk.mjs} +24 -5
- package/dist/{sessionOps-S-qPBLFf.cjs → sessionOps-DVA-00nR.cjs} +4 -4
- package/dist/{sessionOps-BIGgRube.mjs → sessionOps-DqlftXxe.mjs} +5 -5
- package/dist/{sessionScanner-o5hnMi5e.mjs → sessionScanner-BI0Vo1xT.mjs} +3 -3
- package/dist/{sessionScanner-CIMM2hvZ.cjs → sessionScanner-BMwgGAhY.cjs} +3 -3
- package/dist/{sessions-BJHEZpi2.mjs → sessions-D6IimX7b.mjs} +11 -11
- package/dist/{sessions-JchI1w3z.cjs → sessions-DjgEcHaT.cjs} +10 -10
- package/dist/{setupOfflineReconnection-CNiAt5ZP.cjs → setupOfflineReconnection-CjuCiKY3.cjs} +2 -2
- package/dist/{setupOfflineReconnection-DMiBO2y9.mjs → setupOfflineReconnection-DgJK_4m1.mjs} +2 -2
- package/dist/{spawn-DgvUNYEo.mjs → spawn-Dvzy-tzc.mjs} +15 -15
- package/dist/{spawn-6PD7nnoC.cjs → spawn-rhF28shY.cjs} +15 -15
- package/dist/{spawnAgents-P006Hqio.mjs → spawnAgents-CCnlq-FI.mjs} +1 -1
- package/dist/{spawnAgents-DsXgegHM.cjs → spawnAgents-iwuqrgR9.cjs} +1 -1
- package/dist/{spawnHappyCLI-Dywezwk6.cjs → spawnHappyCLI-DnKmIsEt.cjs} +2 -2
- package/dist/{spawnHappyCLI-CCOrEtf9.mjs → spawnHappyCLI-Dq3LLXLb.mjs} +1 -1
- package/dist/{specialCommands-DPcd9edP.mjs → specialCommands-CcyZ1hGA.mjs} +3 -3
- package/dist/{specialCommands-QxPpkGKf.cjs → specialCommands-Zwr2C6A2.cjs} +3 -3
- package/dist/{startFileWatcher-DghDOCO4.mjs → startFileWatcher-4thXDK9d.mjs} +1 -1
- package/dist/{startFileWatcher-RECH5qY8.cjs → startFileWatcher-K6hJSyiR.cjs} +1 -1
- package/dist/startupSessionCreate-BfByJ16A.mjs +24 -0
- package/dist/startupSessionCreate-CKEbq0tL.cjs +26 -0
- package/dist/{streamRelay-DlUWKUpo.cjs → streamRelay-Gy8Xfnon.cjs} +1 -1
- package/dist/{streamRelay-DMV_TXfS.mjs → streamRelay-LcDvyEjK.mjs} +1 -1
- package/dist/{sync-D23jbqVa.cjs → sync-1hQ5KHpL.cjs} +1 -1
- package/dist/{sync-CSe0Rf45.mjs → sync-DO-2PU45.mjs} +1 -1
- package/dist/{systemPrompt-CFNKnh65.mjs → systemPrompt-BctLfMZs.mjs} +3 -3
- package/dist/{systemPrompt-BOy4kU4P.cjs → systemPrompt-Dj7pgkMK.cjs} +3 -3
- package/dist/{teams-DyY669f0.mjs → teams-Bu8YeOoF.mjs} +8 -8
- package/dist/{teams-Ov2BDT-A.cjs → teams-uQxUlyyz.cjs} +8 -8
- package/dist/{time-65DcU6Jx.mjs → time-BcoJaG8E.mjs} +1 -1
- package/dist/{time-CrwIMHta.cjs → time-nqa9shu8.cjs} +1 -1
- package/dist/{titleGenerator-CS_rh2_J.cjs → titleGenerator-D09XyYYG.cjs} +3 -3
- package/dist/{titleGenerator-CiAMxf7s.mjs → titleGenerator-D5r06bhf.mjs} +1 -1
- package/dist/{todo-KY-okGii.cjs → todo-CCOnL7pT.cjs} +6 -6
- package/dist/{todo-BDONw0sK.mjs → todo-D1q8146q.mjs} +6 -6
- package/dist/{tools-D8-PnZEG.mjs → tools-D2E--n1x.mjs} +3 -3
- package/dist/{tools-_w52DZG6.cjs → tools-DiCXnAC5.cjs} +3 -3
- package/dist/{uninstall-8vnLN-IE.cjs → uninstall-BrNwwwSD.cjs} +6 -6
- package/dist/{uninstall-_fjGRP9b.mjs → uninstall-CtwXi1Rt.mjs} +3 -3
- package/package.json +9 -8
- package/dist/machineMetadata-CLHS9sv_.cjs +0 -42
- package/dist/machineMetadata-D-g--oU_.mjs +0 -39
- package/dist/messageBuffer-BWlGgR3A.mjs +0 -71
- package/dist/messageBuffer-fJMH6uY8.cjs +0 -73
- package/dist/projectPath-ChLhdOyt.cjs +0 -13
- package/dist/selfCheck-CjCF4C3v.mjs +0 -85
|
@@ -3,10 +3,18 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
3
3
|
import { constants, writeFileSync, chmodSync, openSync, fstatSync, closeSync, existsSync, readFileSync, renameSync, readdirSync, rmSync, lstatSync, realpathSync, statSync, mkdirSync, readSync, unlinkSync, rmdirSync } from 'node:fs';
|
|
4
4
|
import { relative, isAbsolute, sep, join, dirname, basename, resolve } from 'node:path';
|
|
5
5
|
import { realpath, lstat, stat, mkdir, copyFile, symlink, readdir } from 'node:fs/promises';
|
|
6
|
-
import { f as ensurePrivateDirectorySync, w as writePrivateFileSync } from './configuration-
|
|
7
|
-
import { r as AGENT_VERSION_SOURCES } from './index-
|
|
8
|
-
import { p as packageJson } from './package-
|
|
6
|
+
import { f as ensurePrivateDirectorySync, w as writePrivateFileSync } from './configuration-BPrfb17M.mjs';
|
|
7
|
+
import { r as AGENT_VERSION_SOURCES } from './index-CeRXrGnH.mjs';
|
|
8
|
+
import { p as packageJson } from './package-DYGwlmXl.mjs';
|
|
9
9
|
|
|
10
|
+
function spawnOriginForLog(value) {
|
|
11
|
+
if (!value || typeof value !== "object") return void 0;
|
|
12
|
+
const input = value;
|
|
13
|
+
const source = typeof input.source === "string" && /^[a-z][a-z-]{0,23}$/.test(input.source) ? input.source : "invalid";
|
|
14
|
+
const route = typeof input.route === "string" && /^[A-Za-z0-9/:._-]{1,64}$/.test(input.route) ? input.route : "invalid";
|
|
15
|
+
const flag = (v) => typeof v === "boolean" ? v : null;
|
|
16
|
+
return { source, route, visible: flag(input.visible), gesture: flag(input.gesture) };
|
|
17
|
+
}
|
|
10
18
|
function summarizeSpawnSessionForLog(value) {
|
|
11
19
|
const input = value && typeof value === "object" ? value : {};
|
|
12
20
|
const environmentVariables = input.environmentVariables && typeof input.environmentVariables === "object" ? input.environmentVariables : {};
|
|
@@ -21,7 +29,8 @@ function summarizeSpawnSessionForLog(value) {
|
|
|
21
29
|
resumesCodex: typeof input.resumeCodexThreadId === "string" && input.resumeCodexThreadId.length > 0,
|
|
22
30
|
importsClaude: typeof input.importedFromClaudeSessionId === "string" && input.importedFromClaudeSessionId.length > 0,
|
|
23
31
|
forceNew: input.forceNew === true,
|
|
24
|
-
...typeof input.permissionMode === "string" ? { permissionMode: input.permissionMode } : {}
|
|
32
|
+
...typeof input.permissionMode === "string" ? { permissionMode: input.permissionMode } : {},
|
|
33
|
+
...input.origin !== void 0 ? { origin: spawnOriginForLog(input.origin) } : {}
|
|
25
34
|
};
|
|
26
35
|
}
|
|
27
36
|
|
|
@@ -1168,10 +1177,10 @@ function startAgentVersionChecks(publish, onError, detect = detectAgentVersions)
|
|
|
1168
1177
|
void refresh();
|
|
1169
1178
|
const timer = setInterval(() => void refresh(), AGENT_CHECK_INTERVAL);
|
|
1170
1179
|
timer.unref();
|
|
1171
|
-
return () => {
|
|
1180
|
+
return Object.assign(() => {
|
|
1172
1181
|
stopped = true;
|
|
1173
1182
|
clearInterval(timer);
|
|
1174
|
-
};
|
|
1183
|
+
}, { refresh });
|
|
1175
1184
|
}
|
|
1176
1185
|
|
|
1177
1186
|
function parseTerminalHookPayload(body) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "very-happy-cli";
|
|
2
|
-
var version = "0.2.
|
|
2
|
+
var version = "0.2.181";
|
|
3
3
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
4
4
|
var author = "Kirill Dubovitskiy";
|
|
5
5
|
var contributors = [
|
|
@@ -82,7 +82,7 @@ var scripts = {
|
|
|
82
82
|
};
|
|
83
83
|
var dependencies = {
|
|
84
84
|
"@agentclientprotocol/sdk": "^0.14.1",
|
|
85
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
85
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.306",
|
|
86
86
|
"@anthropic-ai/sandbox-runtime": "^0.0.37",
|
|
87
87
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
88
88
|
"@noble/ed25519": "^3.0.0",
|
|
@@ -116,12 +116,12 @@ var dependencies = {
|
|
|
116
116
|
zod: "^4.0.0"
|
|
117
117
|
};
|
|
118
118
|
var optionalDependencies = {
|
|
119
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
120
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
121
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
122
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
123
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
124
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
119
|
+
"very-happy-tools-arm64-darwin": "0.2.181",
|
|
120
|
+
"very-happy-tools-x64-darwin": "0.2.181",
|
|
121
|
+
"very-happy-tools-arm64-linux": "0.2.181",
|
|
122
|
+
"very-happy-tools-x64-linux": "0.2.181",
|
|
123
|
+
"very-happy-tools-arm64-win32": "0.2.181",
|
|
124
|
+
"very-happy-tools-x64-win32": "0.2.181"
|
|
125
125
|
};
|
|
126
126
|
var devDependencies = {
|
|
127
127
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -133,6 +133,7 @@ var devDependencies = {
|
|
|
133
133
|
"cross-env": "^10.1.0",
|
|
134
134
|
dotenv: "^16.6.1",
|
|
135
135
|
pkgroll: "^2.14.2",
|
|
136
|
+
"smol-toml": "1.9.0",
|
|
136
137
|
"ts-node": "^10",
|
|
137
138
|
tsx: "^4.20.6",
|
|
138
139
|
typescript: "5.9.3",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var name = "very-happy-cli";
|
|
4
|
-
var version = "0.2.
|
|
4
|
+
var version = "0.2.181";
|
|
5
5
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
6
6
|
var author = "Kirill Dubovitskiy";
|
|
7
7
|
var contributors = [
|
|
@@ -84,7 +84,7 @@ var scripts = {
|
|
|
84
84
|
};
|
|
85
85
|
var dependencies = {
|
|
86
86
|
"@agentclientprotocol/sdk": "^0.14.1",
|
|
87
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
87
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.306",
|
|
88
88
|
"@anthropic-ai/sandbox-runtime": "^0.0.37",
|
|
89
89
|
"@modelcontextprotocol/sdk": "1.30.0",
|
|
90
90
|
"@noble/ed25519": "^3.0.0",
|
|
@@ -118,12 +118,12 @@ var dependencies = {
|
|
|
118
118
|
zod: "^4.0.0"
|
|
119
119
|
};
|
|
120
120
|
var optionalDependencies = {
|
|
121
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
122
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
123
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
124
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
125
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
126
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
121
|
+
"very-happy-tools-arm64-darwin": "0.2.181",
|
|
122
|
+
"very-happy-tools-x64-darwin": "0.2.181",
|
|
123
|
+
"very-happy-tools-arm64-linux": "0.2.181",
|
|
124
|
+
"very-happy-tools-x64-linux": "0.2.181",
|
|
125
|
+
"very-happy-tools-arm64-win32": "0.2.181",
|
|
126
|
+
"very-happy-tools-x64-win32": "0.2.181"
|
|
127
127
|
};
|
|
128
128
|
var devDependencies = {
|
|
129
129
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -135,6 +135,7 @@ var devDependencies = {
|
|
|
135
135
|
"cross-env": "^10.1.0",
|
|
136
136
|
dotenv: "^16.6.1",
|
|
137
137
|
pkgroll: "^2.14.2",
|
|
138
|
+
"smol-toml": "1.9.0",
|
|
138
139
|
"ts-node": "^10",
|
|
139
140
|
tsx: "^4.20.6",
|
|
140
141
|
typescript: "5.9.3",
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { c as configuration } from './configuration-
|
|
4
|
-
import { b as readCredentialsForConfiguredRelay, r as readSettings } from './persistence-
|
|
3
|
+
import { c as configuration } from './configuration-BPrfb17M.mjs';
|
|
4
|
+
import { b as readCredentialsForConfiguredRelay, r as readSettings } from './persistence-D2Djrf7t.mjs';
|
|
5
5
|
import { n as normalizeWebPanels, w as webPanelPath } from './webPanels-B2_C2-3g.mjs';
|
|
6
6
|
import 'node:fs';
|
|
7
7
|
import 'node:os';
|
|
8
8
|
import 'node:path';
|
|
9
|
-
import './package-
|
|
9
|
+
import './package-DYGwlmXl.mjs';
|
|
10
10
|
import 'node:fs/promises';
|
|
11
11
|
import 'zod';
|
|
12
12
|
import './authRelay-DhQhkBvX.mjs';
|
|
13
13
|
import 'node:crypto';
|
|
14
14
|
import 'tweetnacl';
|
|
15
|
-
import './logger-
|
|
15
|
+
import './logger-LFr8iPgl.mjs';
|
|
16
16
|
import 'node:util';
|
|
17
17
|
|
|
18
18
|
function frameVerdict(headers) {
|
|
@@ -106,7 +106,7 @@ async function handleAttentionCommand(args) {
|
|
|
106
106
|
else console.error(chalk.yellow(`panel "${parsed.panel}" is not declared in ${configuration.settingsFile}; the notification will not deep-link`));
|
|
107
107
|
}
|
|
108
108
|
if (parsed.session) {
|
|
109
|
-
const { ApiClient } = await import('./api-
|
|
109
|
+
const { ApiClient } = await import('./api-Dr3wXL_7.mjs').then(function (n) { return n.b; });
|
|
110
110
|
const api = await ApiClient.create(credentials);
|
|
111
111
|
const r = await api.push().sendAttention({ sessionId: parsed.session, reason: parsed.reason, url: link ?? `/session/${encodeURIComponent(parsed.session)}` });
|
|
112
112
|
if (!r.sent) {
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
var axios = require('axios');
|
|
4
4
|
var chalk = require('chalk');
|
|
5
|
-
var configuration = require('./configuration-
|
|
6
|
-
var persistence = require('./persistence-
|
|
5
|
+
var configuration = require('./configuration-C8JgseHy.cjs');
|
|
6
|
+
var persistence = require('./persistence-BY-D00wT.cjs');
|
|
7
7
|
var webPanels = require('./webPanels-FCgFKvVe.cjs');
|
|
8
8
|
require('node:fs');
|
|
9
9
|
require('node:os');
|
|
10
10
|
require('node:path');
|
|
11
|
-
require('./package-
|
|
11
|
+
require('./package-NoD8QOOM.cjs');
|
|
12
12
|
require('node:fs/promises');
|
|
13
13
|
require('zod');
|
|
14
14
|
require('./authRelay-Dy1qU9td.cjs');
|
|
15
15
|
require('node:crypto');
|
|
16
16
|
require('tweetnacl');
|
|
17
|
-
require('./logger-
|
|
17
|
+
require('./logger-DgBwUSgS.cjs');
|
|
18
18
|
require('node:util');
|
|
19
19
|
|
|
20
20
|
function frameVerdict(headers) {
|
|
@@ -108,7 +108,7 @@ async function handleAttentionCommand(args) {
|
|
|
108
108
|
else console.error(chalk.yellow(`panel "${parsed.panel}" is not declared in ${configuration.configuration.settingsFile}; the notification will not deep-link`));
|
|
109
109
|
}
|
|
110
110
|
if (parsed.session) {
|
|
111
|
-
const { ApiClient } = await Promise.resolve().then(function () { return require('./api-
|
|
111
|
+
const { ApiClient } = await Promise.resolve().then(function () { return require('./api-COHFAkb_.cjs'); }).then(function (n) { return n.api; });
|
|
112
112
|
const api = await ApiClient.create(credentials);
|
|
113
113
|
const r = await api.push().sendAttention({ sessionId: parsed.session, reason: parsed.reason, url: link ?? `/session/${encodeURIComponent(parsed.session)}` });
|
|
114
114
|
if (!r.sent) {
|
|
@@ -2,13 +2,13 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import { userInfo, hostname } from 'node:os';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { i as isValidSessionId } from './ids-DU6sLx4C.mjs';
|
|
5
|
-
import { g as listDaemonPeers } from './controlClient-
|
|
6
|
-
import { c as readPersistedSessions } from './persistence-
|
|
7
|
-
import { s as sessionWebUrl, e as sendUserMessage } from './sessionOps-
|
|
8
|
-
import { a as listRemotePeers, b as sendRemotePeerMessage, d as deliverToSession } from './remoteSessionClient-
|
|
5
|
+
import { g as listDaemonPeers } from './controlClient-CkNpT5zS.mjs';
|
|
6
|
+
import { c as readPersistedSessions } from './persistence-D2Djrf7t.mjs';
|
|
7
|
+
import { s as sessionWebUrl, e as sendUserMessage } from './sessionOps-DqlftXxe.mjs';
|
|
8
|
+
import { a as listRemotePeers, b as sendRemotePeerMessage, d as deliverToSession } from './remoteSessionClient-B2POSKFT.mjs';
|
|
9
9
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
10
10
|
import { resolve, isAbsolute, dirname } from 'node:path';
|
|
11
|
-
import { P as ProjectsUnsupportedError, s as sharedProjectsClient } from './client-
|
|
11
|
+
import { P as ProjectsUnsupportedError, s as sharedProjectsClient } from './client-BKyU66lg.mjs';
|
|
12
12
|
|
|
13
13
|
const SESSION_PEER_SENT_FROM = "session-peer";
|
|
14
14
|
const CLI_PEER_SENDER_ID = "cli";
|
|
@@ -4,13 +4,13 @@ var node_crypto = require('node:crypto');
|
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var z = require('zod');
|
|
6
6
|
var ids = require('./ids-B6ZC0HGt.cjs');
|
|
7
|
-
var controlClient = require('./controlClient-
|
|
8
|
-
var persistence = require('./persistence-
|
|
9
|
-
var sessionOps = require('./sessionOps-
|
|
10
|
-
var remoteSessionClient = require('./remoteSessionClient-
|
|
7
|
+
var controlClient = require('./controlClient-D68Zj7Q-.cjs');
|
|
8
|
+
var persistence = require('./persistence-BY-D00wT.cjs');
|
|
9
|
+
var sessionOps = require('./sessionOps-DVA-00nR.cjs');
|
|
10
|
+
var remoteSessionClient = require('./remoteSessionClient-CFCn42bs.cjs');
|
|
11
11
|
var node_fs = require('node:fs');
|
|
12
12
|
var path = require('node:path');
|
|
13
|
-
var client = require('./client-
|
|
13
|
+
var client = require('./client-DWs6k041.cjs');
|
|
14
14
|
|
|
15
15
|
const SESSION_PEER_SENT_FROM = "session-peer";
|
|
16
16
|
const CLI_PEER_SENDER_ID = "cli";
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
var promises = require('node:fs/promises');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
|
-
var configuration = require('./configuration-
|
|
5
|
+
var configuration = require('./configuration-C8JgseHy.cjs');
|
|
6
6
|
var z = require('zod');
|
|
7
7
|
var authRelay = require('./authRelay-Dy1qU9td.cjs');
|
|
8
|
-
var logger = require('./logger-
|
|
8
|
+
var logger = require('./logger-DgBwUSgS.cjs');
|
|
9
9
|
|
|
10
10
|
function _interopNamespaceDefault(e) {
|
|
11
11
|
var n = Object.create(null);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readFile, open, unlink, stat, rename } from 'node:fs/promises';
|
|
2
2
|
import { existsSync, constants, readFileSync, unlinkSync, renameSync } from 'node:fs';
|
|
3
|
-
import { c as configuration, P as PRIVATE_FILE_MODE, w as writePrivateFileSync, a as hardenPrivateFileSync, e as ensurePrivateDirectory, b as writePrivateFile, h as hardenPrivateFile } from './configuration-
|
|
3
|
+
import { c as configuration, P as PRIVATE_FILE_MODE, w as writePrivateFileSync, a as hardenPrivateFileSync, e as ensurePrivateDirectory, b as writePrivateFile, h as hardenPrivateFile } from './configuration-BPrfb17M.mjs';
|
|
4
4
|
import * as z from 'zod';
|
|
5
5
|
import { c as credentialRelayProblem, e as encodeBase64 } from './authRelay-DhQhkBvX.mjs';
|
|
6
|
-
import { l as logger } from './logger-
|
|
6
|
+
import { l as logger } from './logger-LFr8iPgl.mjs';
|
|
7
7
|
|
|
8
8
|
const HIBERNATION_CAPABILITY = "agent-hibernation-v1";
|
|
9
9
|
const HOUR_MS = 60 * 60 * 1e3;
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { M as ModelConfigError } from './fileStore-5qpetZS0.mjs';
|
|
3
|
+
|
|
4
|
+
function parseJsonObject(text, label) {
|
|
5
|
+
if (text.trim() === "") return {};
|
|
6
|
+
let value;
|
|
7
|
+
try {
|
|
8
|
+
value = JSON.parse(text);
|
|
9
|
+
} catch (error) {
|
|
10
|
+
const hasComments = /^\s*\/\/|\/\*/m.test(text);
|
|
11
|
+
throw new ModelConfigError(
|
|
12
|
+
hasComments ? "json-has-comments" : "invalid-json",
|
|
13
|
+
hasComments ? `${label} contains comments; Very Happy only edits strict JSON so it never drops them. Edit it by hand or remove the comments.` : `${label} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
17
|
+
throw new ModelConfigError("invalid-json", `${label} must contain a JSON object`);
|
|
18
|
+
}
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
function detectIndent(text) {
|
|
22
|
+
const m = /^([ \t]+)"/m.exec(text);
|
|
23
|
+
return m ? m[1] : 2;
|
|
24
|
+
}
|
|
25
|
+
function stringifyLike(original, value) {
|
|
26
|
+
const compact = original.trim() !== "" && !original.trim().includes("\n");
|
|
27
|
+
const body = compact ? JSON.stringify(value) : JSON.stringify(value, null, detectIndent(original));
|
|
28
|
+
const eol = original.includes("\r\n") ? "\r\n" : "\n";
|
|
29
|
+
const withEol = eol === "\r\n" ? body.replace(/\n/g, "\r\n") : body;
|
|
30
|
+
return original === "" || /\r?\n$/.test(original) ? withEol + eol : withEol;
|
|
31
|
+
}
|
|
32
|
+
function setOrDelete(obj, key, value) {
|
|
33
|
+
if (value === void 0 || value === null || value === "") delete obj[key];
|
|
34
|
+
else obj[key] = value;
|
|
35
|
+
}
|
|
36
|
+
function childObject(obj, key, label) {
|
|
37
|
+
const current = obj[key];
|
|
38
|
+
if (current === void 0) {
|
|
39
|
+
const created = {};
|
|
40
|
+
obj[key] = created;
|
|
41
|
+
return created;
|
|
42
|
+
}
|
|
43
|
+
if (!current || typeof current !== "object" || Array.isArray(current)) {
|
|
44
|
+
throw new ModelConfigError("unexpected-shape", `${label}.${key} is not an object; refusing to overwrite it`);
|
|
45
|
+
}
|
|
46
|
+
return current;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const SECRET_KEY_PATTERN = /(api[_-]?key|apikey|token|secret|password|passwd|authorization|bearer|credential|cookie|private[_-]?key)/i;
|
|
50
|
+
const EXTRA_SECRET_KEYS = /* @__PURE__ */ new Set(["ANTHROPIC_CUSTOM_HEADERS"]);
|
|
51
|
+
function isSecretKey(key) {
|
|
52
|
+
return SECRET_KEY_PATTERN.test(key) || EXTRA_SECRET_KEYS.has(key);
|
|
53
|
+
}
|
|
54
|
+
function maskSecret(value) {
|
|
55
|
+
const v = value.trim();
|
|
56
|
+
if (!v) return "";
|
|
57
|
+
if (v.length < 16) return "\u2022\u2022\u2022\u2022";
|
|
58
|
+
return `${v.slice(0, 4)}\u2026${v.slice(-4)}`;
|
|
59
|
+
}
|
|
60
|
+
function collectSecretValues(value, out = /* @__PURE__ */ new Set(), parentKey = "") {
|
|
61
|
+
if (typeof value === "string") {
|
|
62
|
+
if (parentKey && isSecretKey(parentKey) && value.length >= 4) out.add(value);
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
for (const item of value) collectSecretValues(item, out, parentKey);
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
if (value && typeof value === "object") {
|
|
70
|
+
for (const [key, child] of Object.entries(value)) {
|
|
71
|
+
collectSecretValues(child, out, key);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
function redactText(text, secrets) {
|
|
77
|
+
const list = [...new Set(secrets)].filter((s) => s.length >= 4).sort((a, b) => b.length - a.length);
|
|
78
|
+
let out = text;
|
|
79
|
+
for (const secret of list) {
|
|
80
|
+
out = out.split(secret).join(maskSecret(secret));
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
const ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
85
|
+
function isValidEnvName(name) {
|
|
86
|
+
return typeof name === "string" && ENV_NAME_PATTERN.test(name);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const MODEL_ID = /^[A-Za-z0-9._:/@+\-[\]]{1,200}$/;
|
|
90
|
+
const PROVIDER_ID = /^[A-Za-z0-9_-]{1,64}$/;
|
|
91
|
+
function fail(code, message) {
|
|
92
|
+
throw new ModelConfigError(code, message);
|
|
93
|
+
}
|
|
94
|
+
function normalizeBaseUrl(value, field = "baseUrl") {
|
|
95
|
+
if (value === void 0) return void 0;
|
|
96
|
+
if (value === null) return null;
|
|
97
|
+
if (typeof value !== "string") fail("invalid-input", `${field} must be a string`);
|
|
98
|
+
const v = value.trim();
|
|
99
|
+
if (v === "") return null;
|
|
100
|
+
if (v.length > 2048 || /\s/.test(v)) fail("invalid-input", `${field} is not a valid URL`);
|
|
101
|
+
let url;
|
|
102
|
+
try {
|
|
103
|
+
url = new URL(v);
|
|
104
|
+
} catch {
|
|
105
|
+
fail("invalid-input", `${field} is not a valid URL`);
|
|
106
|
+
}
|
|
107
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") fail("invalid-input", `${field} must be http(s)`);
|
|
108
|
+
if (url.username || url.password) fail("invalid-input", `${field} must not embed credentials; use the API key field`);
|
|
109
|
+
return v;
|
|
110
|
+
}
|
|
111
|
+
function normalizeModelId(value, field = "model") {
|
|
112
|
+
if (value === void 0) return void 0;
|
|
113
|
+
if (value === null) return null;
|
|
114
|
+
if (typeof value !== "string") fail("invalid-input", `${field} must be a string`);
|
|
115
|
+
const v = value.trim();
|
|
116
|
+
if (v === "") return null;
|
|
117
|
+
if (!MODEL_ID.test(v)) fail("invalid-input", `${field} contains unsupported characters`);
|
|
118
|
+
return v;
|
|
119
|
+
}
|
|
120
|
+
function normalizeModelList(value, field = "models") {
|
|
121
|
+
if (value === void 0) return void 0;
|
|
122
|
+
if (!Array.isArray(value)) fail("invalid-input", `${field} must be an array`);
|
|
123
|
+
if (value.length > 64) fail("invalid-input", `${field} has too many entries`);
|
|
124
|
+
const out = [];
|
|
125
|
+
for (const item of value) {
|
|
126
|
+
const id = normalizeModelId(item, field);
|
|
127
|
+
if (id && !out.includes(id)) out.push(id);
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
function normalizeProviderId(value, reserved = []) {
|
|
132
|
+
if (typeof value !== "string" || !PROVIDER_ID.test(value.trim())) fail("invalid-input", "providerId must be 1-64 letters, digits, - or _");
|
|
133
|
+
const v = value.trim();
|
|
134
|
+
if (reserved.includes(v)) fail("invalid-input", `providerId "${v}" is reserved by the harness`);
|
|
135
|
+
return v;
|
|
136
|
+
}
|
|
137
|
+
function normalizeSecret(value, allowed = ["keep", "clear", "literal", "env"]) {
|
|
138
|
+
if (value === void 0) return { mode: "keep" };
|
|
139
|
+
if (!value || typeof value !== "object") fail("invalid-input", "apiKey must be an object");
|
|
140
|
+
const v = value;
|
|
141
|
+
const mode = v.mode;
|
|
142
|
+
if (typeof mode !== "string" || !allowed.includes(mode)) fail("invalid-input", `apiKey.mode must be one of ${allowed.join(", ")}`);
|
|
143
|
+
if (mode === "literal") {
|
|
144
|
+
if (typeof v.value !== "string") fail("invalid-input", "apiKey.value must be a string");
|
|
145
|
+
const key = v.value.trim();
|
|
146
|
+
if (!key || key.length > 4096 || /[\s\u0000-\u001f\u007f]/.test(key)) fail("invalid-input", "apiKey.value must be a single line without spaces");
|
|
147
|
+
return { mode: "literal", value: key };
|
|
148
|
+
}
|
|
149
|
+
if (mode === "env") {
|
|
150
|
+
if (!isValidEnvName(v.name)) fail("invalid-input", "apiKey.name must be an environment variable name");
|
|
151
|
+
return { mode: "env", name: v.name };
|
|
152
|
+
}
|
|
153
|
+
return { mode };
|
|
154
|
+
}
|
|
155
|
+
function baseUrlWarnings(url, kind) {
|
|
156
|
+
if (!url) return [];
|
|
157
|
+
const path = (() => {
|
|
158
|
+
try {
|
|
159
|
+
return new URL(url).pathname.replace(/\/+$/, "");
|
|
160
|
+
} catch {
|
|
161
|
+
return "";
|
|
162
|
+
}
|
|
163
|
+
})();
|
|
164
|
+
const out = [];
|
|
165
|
+
if (/\/(chat\/completions|responses|messages|completions)$/.test(path)) {
|
|
166
|
+
out.push({ code: "base-url-has-endpoint", message: "The base URL ends with an API endpoint path; harnesses append that themselves." });
|
|
167
|
+
}
|
|
168
|
+
if (kind === "anthropic" && /\/v1$/.test(path)) {
|
|
169
|
+
out.push({ code: "base-url-v1", message: "Claude Code appends /v1/messages; a base URL ending in /v1 usually produces /v1/v1/messages." });
|
|
170
|
+
}
|
|
171
|
+
if (kind === "openai" && !/\/v\d/.test(path)) {
|
|
172
|
+
out.push({ code: "base-url-no-version", message: "OpenAI-compatible base URLs usually end in /v1." });
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
const MIN_CONTEXT_WINDOW = 1024;
|
|
177
|
+
const MAX_CONTEXT_WINDOW = 1e8;
|
|
178
|
+
function normalizeContextWindows(value) {
|
|
179
|
+
if (value === void 0) return void 0;
|
|
180
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) fail("invalid-input", "contextWindows must be an object");
|
|
181
|
+
const entries = Object.entries(value);
|
|
182
|
+
if (entries.length > 64) fail("invalid-input", "contextWindows has too many entries");
|
|
183
|
+
const out = {};
|
|
184
|
+
for (const [rawId, window] of entries) {
|
|
185
|
+
const id = normalizeModelId(rawId, "contextWindows");
|
|
186
|
+
if (!id) fail("invalid-input", "contextWindows keys must be model ids");
|
|
187
|
+
if (window === null) {
|
|
188
|
+
out[id] = null;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (typeof window !== "number" || !Number.isInteger(window) || window < MIN_CONTEXT_WINDOW || window > MAX_CONTEXT_WINDOW) {
|
|
192
|
+
fail("invalid-input", `contextWindows.${id} must be a whole number of tokens between ${MIN_CONTEXT_WINDOW} and ${MAX_CONTEXT_WINDOW}`);
|
|
193
|
+
}
|
|
194
|
+
out[id] = window;
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function getPath(obj, path) {
|
|
200
|
+
let cur = obj;
|
|
201
|
+
for (const p of path) {
|
|
202
|
+
if (!cur || typeof cur !== "object" || Array.isArray(cur)) return void 0;
|
|
203
|
+
cur = cur[p];
|
|
204
|
+
}
|
|
205
|
+
return cur;
|
|
206
|
+
}
|
|
207
|
+
function changedPaths(before, after, paths) {
|
|
208
|
+
return paths.filter((path) => JSON.stringify(getPath(before, path)) !== JSON.stringify(getPath(after, path))).map((path) => path.join("."));
|
|
209
|
+
}
|
|
210
|
+
function uniq(values) {
|
|
211
|
+
const out = [];
|
|
212
|
+
for (const v of values) if (v && !out.includes(v)) out.push(v);
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const MODELS = "models";
|
|
217
|
+
const SETTINGS = "settings";
|
|
218
|
+
const PI_APIS = ["openai-completions", "openai-responses", "anthropic-messages", "google-generative-ai", "mistral-conversations"];
|
|
219
|
+
const ENV_REF = /^\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?$/;
|
|
220
|
+
function piAgentDir(ctx) {
|
|
221
|
+
return ctx.env.PI_CODING_AGENT_DIR?.trim() || join(ctx.home, ".pi", "agent");
|
|
222
|
+
}
|
|
223
|
+
const str = (v) => typeof v === "string" && v.trim() ? v : null;
|
|
224
|
+
function providersOf(models) {
|
|
225
|
+
const p = models.providers;
|
|
226
|
+
if (!p || typeof p !== "object" || Array.isArray(p)) return {};
|
|
227
|
+
return Object.fromEntries(Object.entries(p).filter(([, v]) => v && typeof v === "object" && !Array.isArray(v)));
|
|
228
|
+
}
|
|
229
|
+
function modelIds(provider) {
|
|
230
|
+
const list = provider?.models;
|
|
231
|
+
return Array.isArray(list) ? list.flatMap((m) => m && typeof m === "object" && typeof m.id === "string" ? [m.id] : []) : [];
|
|
232
|
+
}
|
|
233
|
+
function contextWindowsOf(provider) {
|
|
234
|
+
const list = provider?.models;
|
|
235
|
+
if (!Array.isArray(list)) return {};
|
|
236
|
+
const out = {};
|
|
237
|
+
for (const m of list) {
|
|
238
|
+
const entry = m && typeof m === "object" ? m : null;
|
|
239
|
+
if (typeof entry?.id === "string" && typeof entry.contextWindow === "number" && entry.contextWindow > 0) out[entry.id] = entry.contextWindow;
|
|
240
|
+
}
|
|
241
|
+
return out;
|
|
242
|
+
}
|
|
243
|
+
function secretView(provider, ctx) {
|
|
244
|
+
const key = str(provider?.apiKey);
|
|
245
|
+
if (!key) return { mode: "none" };
|
|
246
|
+
const ref = ENV_REF.exec(key.trim());
|
|
247
|
+
if (ref) return { mode: "env", envName: ref[1], envPresent: !!ctx.env[ref[1]] };
|
|
248
|
+
if (key.trim().startsWith("!")) return { mode: "command" };
|
|
249
|
+
return { mode: "literal", masked: maskSecret(key) };
|
|
250
|
+
}
|
|
251
|
+
function currentOf(models, settings, providerId, ctx) {
|
|
252
|
+
const provider = providerId ? providersOf(models)[providerId] : void 0;
|
|
253
|
+
const activeProvider = str(settings.defaultProvider);
|
|
254
|
+
return {
|
|
255
|
+
providerId,
|
|
256
|
+
baseUrl: str(provider?.baseUrl),
|
|
257
|
+
api: str(provider?.api),
|
|
258
|
+
apiKey: secretView(provider, ctx),
|
|
259
|
+
models: modelIds(provider),
|
|
260
|
+
contextWindows: contextWindowsOf(provider),
|
|
261
|
+
activeProvider,
|
|
262
|
+
defaultModel: str(settings.defaultModel),
|
|
263
|
+
active: !!providerId && activeProvider === providerId
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function pickerModelsOf(models) {
|
|
267
|
+
return uniq(Object.entries(providersOf(models)).flatMap(([id, p]) => modelIds(p).map((m) => `${id}/${m}`)));
|
|
268
|
+
}
|
|
269
|
+
function warningsOf(settings, current) {
|
|
270
|
+
const out = [...baseUrlWarnings(current.baseUrl, current.api === "anthropic-messages" ? "anthropic" : "openai")].filter((w) => w.code !== "base-url-v1");
|
|
271
|
+
if (current.apiKey?.mode === "env" && !current.apiKey.envPresent) {
|
|
272
|
+
out.push({ code: "env-missing", message: `${current.apiKey.envName} is not set in the daemon's environment; pi hides models whose key cannot be resolved.` });
|
|
273
|
+
}
|
|
274
|
+
if (current.providerId && current.apiKey?.mode === "none") {
|
|
275
|
+
out.push({ code: "no-key", message: "pi hides models whose provider has no resolvable API key." });
|
|
276
|
+
}
|
|
277
|
+
if (Array.isArray(settings.enabledModels) && current.providerId) {
|
|
278
|
+
const enabled = settings.enabledModels;
|
|
279
|
+
const hidden = (current.models ?? []).filter((m) => !enabled.includes(`${current.providerId}/${m}`) && !enabled.includes(m));
|
|
280
|
+
if (hidden.length) out.push({ code: "enabled-models-filter", message: `settings.json enabledModels does not include ${hidden.join(", ")}.` });
|
|
281
|
+
}
|
|
282
|
+
return out;
|
|
283
|
+
}
|
|
284
|
+
const piAdapter = {
|
|
285
|
+
id: "pi",
|
|
286
|
+
binary: "pi",
|
|
287
|
+
files: (ctx) => [{ role: MODELS, path: join(piAgentDir(ctx), "models.json") }, { role: SETTINGS, path: join(piAgentDir(ctx), "settings.json") }],
|
|
288
|
+
view(files, ctx, opts) {
|
|
289
|
+
const models = parseJsonObject(files[MODELS].content, "models.json");
|
|
290
|
+
const settings = parseJsonObject(files[SETTINGS].content, "settings.json");
|
|
291
|
+
const providers = providersOf(models);
|
|
292
|
+
const active = str(settings.defaultProvider);
|
|
293
|
+
const selected = opts.providerId ?? (active && providers[active] ? active : Object.keys(providers)[0] ?? null);
|
|
294
|
+
const current = currentOf(models, settings, selected, ctx);
|
|
295
|
+
return { current, providers: Object.keys(providers), pickerModels: pickerModelsOf(models), warnings: warningsOf(settings, current) };
|
|
296
|
+
},
|
|
297
|
+
plan(files, raw, ctx) {
|
|
298
|
+
const p = raw;
|
|
299
|
+
const providerId = normalizeProviderId(p.providerId);
|
|
300
|
+
const baseUrl = normalizeBaseUrl(p.baseUrl);
|
|
301
|
+
if (p.api !== void 0 && !PI_APIS.includes(p.api)) fail("invalid-input", `api must be one of ${PI_APIS.join(", ")}`);
|
|
302
|
+
const apiKey = normalizeSecret(p.apiKey);
|
|
303
|
+
if (apiKey.mode === "literal" && /^[$!]/.test(apiKey.value)) fail("invalid-input", "pi treats a key starting with $ or ! as an env reference / command; use the environment-variable mode");
|
|
304
|
+
const ids = normalizeModelList(p.models);
|
|
305
|
+
const windows = normalizeContextWindows(p.contextWindows);
|
|
306
|
+
const defaultModel = normalizeModelId(p.defaultModel, "defaultModel");
|
|
307
|
+
if (p.activate !== void 0 && typeof p.activate !== "boolean") fail("invalid-input", "activate must be a boolean");
|
|
308
|
+
const modelsText = files[MODELS].content;
|
|
309
|
+
const settingsText = files[SETTINGS].content;
|
|
310
|
+
const modelsBefore = parseJsonObject(modelsText, "models.json");
|
|
311
|
+
const settingsBefore = parseJsonObject(settingsText, "settings.json");
|
|
312
|
+
const models = structuredClone(modelsBefore);
|
|
313
|
+
const settings = structuredClone(settingsBefore);
|
|
314
|
+
const providers = childObject(models, "providers", "models.json");
|
|
315
|
+
const isNew = providers[providerId] === void 0;
|
|
316
|
+
if (isNew && !baseUrl) fail("invalid-input", "A new provider needs a base URL");
|
|
317
|
+
const provider = childObject(providers, providerId, "models.json.providers");
|
|
318
|
+
if (baseUrl !== void 0) {
|
|
319
|
+
if (baseUrl === null) fail("invalid-input", "A provider needs a base URL");
|
|
320
|
+
provider.baseUrl = baseUrl;
|
|
321
|
+
}
|
|
322
|
+
if (p.api !== void 0) provider.api = p.api;
|
|
323
|
+
else if (isNew) provider.api = "openai-completions";
|
|
324
|
+
const secrets = [];
|
|
325
|
+
if (apiKey.mode === "literal") {
|
|
326
|
+
provider.apiKey = apiKey.value;
|
|
327
|
+
secrets.push(apiKey.value);
|
|
328
|
+
}
|
|
329
|
+
if (apiKey.mode === "env") provider.apiKey = `\${${apiKey.name}}`;
|
|
330
|
+
if (apiKey.mode === "clear") delete provider.apiKey;
|
|
331
|
+
if (ids !== void 0) {
|
|
332
|
+
const existing = Array.isArray(provider.models) ? provider.models : [];
|
|
333
|
+
const next = ids.map((id) => existing.find((m) => m && typeof m === "object" && m.id === id) ?? { id });
|
|
334
|
+
if (next.length) provider.models = next;
|
|
335
|
+
else delete provider.models;
|
|
336
|
+
}
|
|
337
|
+
const finalIds = modelIds(provider);
|
|
338
|
+
if (windows) {
|
|
339
|
+
const entries = Array.isArray(provider.models) ? provider.models : [];
|
|
340
|
+
for (const [id, window] of Object.entries(windows)) {
|
|
341
|
+
const entry = entries.find((m) => m && typeof m === "object" && m.id === id);
|
|
342
|
+
if (!entry) fail("invalid-input", `contextWindows names ${id}, which is not one of the provider models`);
|
|
343
|
+
if (window === null) delete entry.contextWindow;
|
|
344
|
+
else entry.contextWindow = window;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (p.activate === true) {
|
|
348
|
+
settings.defaultProvider = providerId;
|
|
349
|
+
const chosen = defaultModel ?? (finalIds.includes(str(settings.defaultModel) ?? "") ? str(settings.defaultModel) : finalIds[0]);
|
|
350
|
+
setOrDelete(settings, "defaultModel", chosen);
|
|
351
|
+
} else if (p.activate === false && str(settings.defaultProvider) === providerId) {
|
|
352
|
+
delete settings.defaultProvider;
|
|
353
|
+
delete settings.defaultModel;
|
|
354
|
+
} else if (defaultModel !== void 0 && str(settings.defaultProvider) === providerId) {
|
|
355
|
+
setOrDelete(settings, "defaultModel", defaultModel);
|
|
356
|
+
}
|
|
357
|
+
if (defaultModel && !finalIds.includes(defaultModel)) fail("invalid-input", "defaultModel must be one of the provider models");
|
|
358
|
+
const modelKeys = changedPaths(modelsBefore, models, [["providers", providerId, "baseUrl"], ["providers", providerId, "api"], ["providers", providerId, "apiKey"], ["providers", providerId, "models"]]);
|
|
359
|
+
const settingsKeys = changedPaths(settingsBefore, settings, [["defaultProvider"], ["defaultModel"]]);
|
|
360
|
+
const current = currentOf(models, settings, providerId, ctx);
|
|
361
|
+
return {
|
|
362
|
+
contents: {
|
|
363
|
+
[MODELS]: modelKeys.length ? stringifyLike(modelsText, models) : void 0,
|
|
364
|
+
[SETTINGS]: settingsKeys.length ? stringifyLike(settingsText, settings) : void 0
|
|
365
|
+
},
|
|
366
|
+
warnings: warningsOf(settings, current),
|
|
367
|
+
changedKeys: [...modelKeys.map((k) => `models.json.${k}`), ...settingsKeys.map((k) => `settings.json.${k}`)],
|
|
368
|
+
secrets
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
secretsIn(_role, content) {
|
|
372
|
+
try {
|
|
373
|
+
return collectSecretValues(parseJsonObject(content, "pi config"));
|
|
374
|
+
} catch {
|
|
375
|
+
return /* @__PURE__ */ new Set();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
export { parseJsonObject as a, childObject as b, collectSecretValues as c, changedPaths as d, stringifyLike as e, fail as f, normalizeModelId as g, normalizeSecret as h, normalizeBaseUrl as i, baseUrlWarnings as j, getPath as k, normalizeProviderId as l, maskSecret as m, normalizeModelList as n, piAdapter as o, piAgentDir as p, redactText as r, setOrDelete as s, uniq as u };
|