@zonease/happy 0.6.38 → 0.6.39

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.
Files changed (109) hide show
  1. package/dist/{types-BWpRU1VN.mjs → api-CIZKyfSn.mjs} +136 -1725
  2. package/dist/{types-DvTsFaqR.cjs → api-CwOCQeLH.cjs} +317 -1961
  3. package/dist/auth-0VnlXT9f.mjs +181 -0
  4. package/dist/auth-BE8dD20T.mjs +270 -0
  5. package/dist/auth-BIleVCw0.cjs +274 -0
  6. package/dist/auth-Cas9DR3b.cjs +183 -0
  7. package/dist/browser-Cc08m7of.cjs +22 -0
  8. package/dist/browser-Dll5hxOV.mjs +20 -0
  9. package/dist/claudeLocal-CPT3zcIU.mjs +344 -0
  10. package/dist/claudeLocal-WkgLbl1a.cjs +352 -0
  11. package/dist/codex/happyMcpStdioBridge.cjs +4 -1
  12. package/dist/codex/happyMcpStdioBridge.mjs +4 -1
  13. package/dist/common-BdNgghUJ.mjs +75 -0
  14. package/dist/common-CZvSRU4p.cjs +83 -0
  15. package/dist/{config-0Xnc8ARM.cjs → config-Draa-5XC.cjs} +21 -34
  16. package/dist/{config-_GW4YBCP.mjs → config-rTT4qTU5.mjs} +7 -20
  17. package/dist/connect-BfC1tYP_.mjs +679 -0
  18. package/dist/connect-CJZ73syK.cjs +681 -0
  19. package/dist/{constants-B4x1K7by.cjs → constants-E_UWYTo3.cjs} +2 -2
  20. package/dist/{constants-BO9OAFOT.mjs → constants-pmXZGibX.mjs} +1 -1
  21. package/dist/controlClient-CM_QcJnB.mjs +159 -0
  22. package/dist/controlClient-DZMIsKsT.cjs +168 -0
  23. package/dist/deviceExec-CU1R9CRb.cjs +84 -0
  24. package/dist/deviceExec-D93AOVV4.mjs +81 -0
  25. package/dist/diagnose-B3D1a_v0.cjs +60 -0
  26. package/dist/diagnose-CuRKXxt1.mjs +58 -0
  27. package/dist/doctor-C08m5Z9f.cjs +78 -0
  28. package/dist/doctor-Cya9YSA0.cjs +214 -0
  29. package/dist/doctor-DZYB6IVc.mjs +211 -0
  30. package/dist/doctor-ON7pN5G5.mjs +74 -0
  31. package/dist/downloadImage-DfSFLb-h.mjs +887 -0
  32. package/dist/downloadImage-MQMrUUxS.cjs +897 -0
  33. package/dist/enroll-BxlbVftP.cjs +115 -0
  34. package/dist/enroll-C52x8oly.mjs +113 -0
  35. package/dist/evidence-Ccd9iYcj.mjs +127 -0
  36. package/dist/evidence-CjWBG5rX.cjs +129 -0
  37. package/dist/formatImageMessage-B4lSxlk2.mjs +43 -0
  38. package/dist/formatImageMessage-DbyG8c2j.cjs +46 -0
  39. package/dist/github-DKcyF1zp.mjs +57 -0
  40. package/dist/github-h9GhJJ_C.cjs +59 -0
  41. package/dist/index-CDTNgfUf.cjs +578 -0
  42. package/dist/index-CPKdvi7J.mjs +554 -0
  43. package/dist/index.cjs +812 -40
  44. package/dist/index.mjs +813 -40
  45. package/dist/install-BokHRgFW.cjs +98 -0
  46. package/dist/install-C_cp8b2-.cjs +96 -0
  47. package/dist/install-DAeCn8ae.mjs +94 -0
  48. package/dist/install-oRAjVLjP.mjs +95 -0
  49. package/dist/lib.cjs +18 -12
  50. package/dist/lib.mjs +13 -7
  51. package/dist/{loadableToolOutput-va3RLplh.mjs → loadableToolOutput-Cuygmd4K.mjs} +4 -2
  52. package/dist/{loadableToolOutput-5vdQB98M.cjs → loadableToolOutput-DDCJjywt.cjs} +63 -61
  53. package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
  54. package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
  55. package/dist/persistence-BFjvtUad.mjs +944 -0
  56. package/dist/persistence-JLUn_Nou.cjs +996 -0
  57. package/dist/projectPath-BTBIMB57.mjs +10 -0
  58. package/dist/projectPath-ChLhdOyt.cjs +13 -0
  59. package/dist/prompt-BTWDZZO0.cjs +25 -0
  60. package/dist/prompt-BsAZsPbo.mjs +22 -0
  61. package/dist/release-BMEzNONE.mjs +168 -0
  62. package/dist/release-EhOJeAZe.cjs +171 -0
  63. package/dist/run-BDn2aE3Q.cjs +2152 -0
  64. package/dist/run-DBZqN6Kn.mjs +2128 -0
  65. package/dist/runClaude-DNHvERX0.mjs +3763 -0
  66. package/dist/runClaude-uaKxPZPm.cjs +3766 -0
  67. package/dist/{runCodex-skq0j05d.cjs → runCodex-82UrZLme.cjs} +169 -153
  68. package/dist/{runCodex-DiKzBf9q.mjs → runCodex-C-RTM0wA.mjs} +36 -20
  69. package/dist/{runGemini-BeqrVq8R.mjs → runGemini-Bm6-4Xm2.mjs} +34 -17
  70. package/dist/{runGemini-CVp-CEIh.cjs → runGemini-CXMr4Jwb.cjs} +212 -195
  71. package/dist/{runOneShot-BQNkNW61.cjs → runOneShot-1B6RMYT7.cjs} +31 -55
  72. package/dist/{runOneShot-ltCpHbBB.mjs → runOneShot-ioARRHrx.mjs} +14 -38
  73. package/dist/{serve-BECdtivY.cjs → serve-BtdAhkIE.cjs} +35 -58
  74. package/dist/{serve-BNdoEDVx.mjs → serve-CwibwU6N.mjs} +12 -35
  75. package/dist/session-2sU4Bu1R.mjs +108 -0
  76. package/dist/session-D--F87zL.cjs +110 -0
  77. package/dist/sessionKeyCache-4Tp8pJ3N.cjs +36 -0
  78. package/dist/sessionKeyCache-D2BwO91C.mjs +33 -0
  79. package/dist/sessionList-BCSw3qYt.mjs +51 -0
  80. package/dist/sessionList-ICJsjNtJ.cjs +54 -0
  81. package/dist/sessionSummary-Bkz52BPh.cjs +393 -0
  82. package/dist/sessionSummary-lHGBWQSb.mjs +387 -0
  83. package/dist/spawnHappyCLI-CoORX0YW.mjs +66 -0
  84. package/dist/spawnHappyCLI-D_V-AAoP.cjs +70 -0
  85. package/dist/ssh-BTOlhhxi.cjs +333 -0
  86. package/dist/ssh-DL_AkRAD.mjs +328 -0
  87. package/dist/systemdScope-BeOtAkhk.mjs +25 -0
  88. package/dist/systemdScope-DW3-UoKB.cjs +29 -0
  89. package/dist/task-CQzrHRZe.mjs +165 -0
  90. package/dist/task-CSpaC9HX.cjs +167 -0
  91. package/dist/time-Bj2HRkKH.cjs +33 -0
  92. package/dist/time-DgsBLJA_.mjs +29 -0
  93. package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
  94. package/dist/trimIdent-BAjmv_TG.mjs +20 -0
  95. package/dist/types-BoJh4Qfv.mjs +57 -0
  96. package/dist/types-DWeB7aqh.cjs +59 -0
  97. package/dist/uninstall-BiKyRAb1.cjs +77 -0
  98. package/dist/uninstall-nFMFGUVM.mjs +75 -0
  99. package/dist/update-BcqRHXf2.mjs +109 -0
  100. package/dist/update-Dw8pgsAT.cjs +111 -0
  101. package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
  102. package/dist/workflowCommon-Bl568-rt.cjs +62 -0
  103. package/dist/workflowReports-BEWuQesA.cjs +113 -0
  104. package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
  105. package/package.json +1 -1
  106. package/dist/index-BbCDDvoB.cjs +0 -11376
  107. package/dist/index-vvZXdswy.mjs +0 -11336
  108. package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
  109. package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
@@ -1,1050 +1,35 @@
1
1
  'use strict';
2
2
 
3
3
  var axios = require('axios');
4
- var chalk = require('chalk');
5
- var fs$1 = require('fs');
6
- var fs = require('node:fs');
7
- var os = require('node:os');
8
- var path = require('node:path');
4
+ var logger = require('./persistence-JLUn_Nou.cjs');
9
5
  var node_events = require('node:events');
10
6
  var socket_ioClient = require('socket.io-client');
11
7
  var z = require('zod');
12
- var cuid2 = require('@paralleldrive/cuid2');
8
+ require('./index-CDTNgfUf.cjs');
9
+ var time = require('./time-Bj2HRkKH.cjs');
13
10
  var node_crypto = require('node:crypto');
14
- var tweetnacl = require('tweetnacl');
11
+ var fs = require('node:fs');
12
+ var path = require('node:path');
15
13
  var node_child_process = require('node:child_process');
16
14
  var promises = require('node:fs/promises');
15
+ var os = require('node:os');
17
16
  var node_util = require('node:util');
18
17
  var child_process = require('child_process');
19
18
  var util = require('util');
20
- var fs$2 = require('fs/promises');
19
+ var fs$1 = require('fs/promises');
21
20
  var path$1 = require('path');
22
- var url = require('url');
21
+ var projectPath = require('./projectPath-ChLhdOyt.cjs');
23
22
  var node_module = require('node:module');
24
23
  var WebSocket = require('ws');
25
24
  var crypto = require('crypto');
25
+ var tweetnacl = require('tweetnacl');
26
26
  var base64 = require('@stablelib/base64');
27
27
  var node_readline = require('node:readline');
28
28
  var expoServerSdk = require('expo-server-sdk');
29
+ var sessionKeyCache = require('./sessionKeyCache-4Tp8pJ3N.cjs');
30
+ var chalk = require('chalk');
29
31
 
30
32
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
31
- function _interopNamespaceDefault(e) {
32
- var n = Object.create(null);
33
- if (e) {
34
- Object.keys(e).forEach(function (k) {
35
- if (k !== 'default') {
36
- var d = Object.getOwnPropertyDescriptor(e, k);
37
- Object.defineProperty(n, k, d.get ? d : {
38
- enumerable: true,
39
- get: function () { return e[k]; }
40
- });
41
- }
42
- });
43
- }
44
- n.default = e;
45
- return Object.freeze(n);
46
- }
47
-
48
- var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
49
-
50
- const DEBUG_TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true"]);
51
- function isDebug() {
52
- return DEBUG_TRUE_VALUES.has(process.env.DEBUG?.toLowerCase() ?? "");
53
- }
54
-
55
- var name = "@zonease/happy";
56
- var version = "0.6.38";
57
- var description = "Mobile and Web client for Claude Code, Codex, and Gemini";
58
- var author = "ZonEaseTech";
59
- var license = "MIT";
60
- var type = "module";
61
- var homepage = "https://github.com/ZonEaseTech/happy-wfs";
62
- var bugs = "https://github.com/ZonEaseTech/happy-wfs/issues";
63
- var repository = {
64
- type: "git",
65
- url: "git+https://github.com/ZonEaseTech/happy-wfs.git",
66
- directory: "packages/happy-cli"
67
- };
68
- var bin = {
69
- happy: "./bin/happy.mjs",
70
- "happy-mcp": "./bin/happy-mcp.mjs"
71
- };
72
- var main = "./dist/index.cjs";
73
- var module$1 = "./dist/index.mjs";
74
- var types = "./dist/index.d.cts";
75
- var exports$1 = {
76
- ".": {
77
- require: {
78
- types: "./dist/index.d.cts",
79
- "default": "./dist/index.cjs"
80
- },
81
- "import": {
82
- types: "./dist/index.d.mts",
83
- "default": "./dist/index.mjs"
84
- }
85
- },
86
- "./lib": {
87
- require: {
88
- types: "./dist/lib.d.cts",
89
- "default": "./dist/lib.cjs"
90
- },
91
- "import": {
92
- types: "./dist/lib.d.mts",
93
- "default": "./dist/lib.mjs"
94
- }
95
- },
96
- "./codex/happyMcpStdioBridge": {
97
- require: {
98
- types: "./dist/codex/happyMcpStdioBridge.d.cts",
99
- "default": "./dist/codex/happyMcpStdioBridge.cjs"
100
- },
101
- "import": {
102
- types: "./dist/codex/happyMcpStdioBridge.d.mts",
103
- "default": "./dist/codex/happyMcpStdioBridge.mjs"
104
- }
105
- }
106
- };
107
- var files = [
108
- "dist",
109
- "bin",
110
- "scripts",
111
- "package.json"
112
- ];
113
- var scripts = {
114
- "why do we need to build before running tests / dev?": "We need the binary to be built so we run daemon commands which directly run the binary - we don't want them to go out of sync or have custom spawn logic depending how we started happy",
115
- typecheck: "tsc --noEmit",
116
- build: "shx rm -rf dist && tsc --noEmit && pkgroll",
117
- test: "$npm_execpath run build && vitest run",
118
- "test:integration": "$npm_execpath run build && vitest run --config vitest.integration.config.ts",
119
- start: "$npm_execpath run build && node ./bin/happy.mjs",
120
- dev: "tsx src/index.ts",
121
- "dev:local-server": "$npm_execpath run build && tsx --env-file .env.dev-local-server src/index.ts",
122
- "dev:integration-test-env": "$npm_execpath run build && tsx --env-file .env.integration-test src/index.ts",
123
- prepublishOnly: "$npm_execpath run build && $npm_execpath test",
124
- release: "$npm_execpath install && release-it",
125
- postinstall: "node scripts/unpack-tools.cjs",
126
- "// ==== Dev/Stable Variant Management ====": "",
127
- stable: "node scripts/env-wrapper.cjs stable",
128
- "dev:variant": "node scripts/env-wrapper.cjs dev",
129
- "// ==== Stable Version Quick Commands ====": "",
130
- "stable:daemon:start": "node scripts/env-wrapper.cjs stable daemon start",
131
- "stable:daemon:stop": "node scripts/env-wrapper.cjs stable daemon stop",
132
- "stable:daemon:status": "node scripts/env-wrapper.cjs stable daemon status",
133
- "stable:auth": "node scripts/env-wrapper.cjs stable auth",
134
- "// ==== Development Version Quick Commands ====": "",
135
- "dev:daemon:start": "node scripts/env-wrapper.cjs dev daemon start",
136
- "dev:daemon:stop": "node scripts/env-wrapper.cjs dev daemon stop",
137
- "dev:daemon:status": "node scripts/env-wrapper.cjs dev daemon status",
138
- "dev:auth": "node scripts/env-wrapper.cjs dev auth",
139
- "// ==== Setup ====": "",
140
- "setup:dev": "node scripts/setup-dev.cjs",
141
- doctor: "node scripts/env-wrapper.cjs stable doctor",
142
- "// ==== Development Linking ====": "",
143
- "link:dev": "node scripts/link-dev.cjs",
144
- "unlink:dev": "node scripts/link-dev.cjs unlink"
145
- };
146
- var dependencies = {
147
- "@agentclientprotocol/sdk": "^0.14.1",
148
- "@paralleldrive/cuid2": "^2.2.2",
149
- "@modelcontextprotocol/sdk": "^1.25.3",
150
- "@stablelib/base64": "^2.0.1",
151
- "@stablelib/hex": "^2.0.1",
152
- "@types/cross-spawn": "^6.0.6",
153
- "@types/http-proxy": "^1.17.17",
154
- "@types/qrcode-terminal": "^0.12.2",
155
- "@types/react": "^19.2.7",
156
- "@types/tmp": "^0.2.6",
157
- "@types/ws": "^8.18.1",
158
- ai: "^5.0.107",
159
- axios: "^1.13.2",
160
- chalk: "^5.6.2",
161
- "cross-spawn": "^7.0.6",
162
- "expo-server-sdk": "^3.15.0",
163
- fastify: "^5.6.2",
164
- "fastify-type-provider-zod": "4.0.2",
165
- "http-proxy": "^1.18.1",
166
- "http-proxy-middleware": "^3.0.5",
167
- ink: "^6.5.1",
168
- open: "^10.2.0",
169
- "ps-list": "^8.1.1",
170
- "qrcode-terminal": "^0.12.0",
171
- react: "^19.2.0",
172
- "socket.io-client": "^4.8.1",
173
- tar: "^7.5.2",
174
- tmp: "^0.2.5",
175
- tweetnacl: "^1.0.3",
176
- ws: "^8.19.0",
177
- zod: "3.25.76"
178
- };
179
- var devDependencies = {
180
- "@eslint/compat": "^1",
181
- "@types/node": ">=20",
182
- "cross-env": "^10.1.0",
183
- dotenv: "^16.6.1",
184
- eslint: "^9",
185
- "eslint-config-prettier": "^10",
186
- pkgroll: "^2.14.2",
187
- "release-it": "^19.0.6",
188
- shx: "^0.3.3",
189
- "ts-node": "^10",
190
- tsx: "^4.20.6",
191
- typescript: "5.9.3",
192
- vitest: "^3.2.4",
193
- "happy-wire": "*"
194
- };
195
- var resolutions = {
196
- "whatwg-url": "14.2.0",
197
- "parse-path": "7.0.3",
198
- "@types/parse-path": "7.0.3"
199
- };
200
- var publishConfig = {
201
- registry: "https://registry.npmjs.org",
202
- access: "public"
203
- };
204
- var packageManager = "yarn@1.22.22";
205
- var optionalDependencies = {
206
- "node-pty": "^1.0.0",
207
- "@zonease/happy-tools-arm64-darwin": "1.0.0",
208
- "@zonease/happy-tools-x64-darwin": "1.0.0",
209
- "@zonease/happy-tools-arm64-linux": "1.0.0",
210
- "@zonease/happy-tools-x64-linux": "1.0.0",
211
- "@zonease/happy-tools-x64-win32": "1.0.0",
212
- "@zonease/happy-tools-arm64-win32": "1.0.0"
213
- };
214
- var packageJson = {
215
- name: name,
216
- version: version,
217
- description: description,
218
- author: author,
219
- license: license,
220
- type: type,
221
- homepage: homepage,
222
- bugs: bugs,
223
- repository: repository,
224
- bin: bin,
225
- main: main,
226
- module: module$1,
227
- types: types,
228
- exports: exports$1,
229
- files: files,
230
- scripts: scripts,
231
- dependencies: dependencies,
232
- devDependencies: devDependencies,
233
- resolutions: resolutions,
234
- publishConfig: publishConfig,
235
- packageManager: packageManager,
236
- optionalDependencies: optionalDependencies
237
- };
238
-
239
- class Configuration {
240
- serverUrl;
241
- webappUrl;
242
- isDaemonProcess;
243
- // Directories and paths (from persistence)
244
- happyHomeDir;
245
- logsDir;
246
- settingsFile;
247
- privateKeyFile;
248
- daemonStateFile;
249
- daemonLockFile;
250
- sessionKeysDir;
251
- currentCliVersion;
252
- isExperimentalEnabled;
253
- disableCaffeinate;
254
- constructor() {
255
- this.serverUrl = process.env.HAPPY_SERVER_URL || "https://api-happy.zonease.org";
256
- this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.zonease.org";
257
- const args = process.argv.slice(2);
258
- this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
259
- if (process.env.HAPPY_HOME_DIR) {
260
- const expandedPath = process.env.HAPPY_HOME_DIR.replace(/^~/, os.homedir());
261
- this.happyHomeDir = expandedPath;
262
- } else {
263
- this.happyHomeDir = path.join(os.homedir(), ".happy");
264
- }
265
- this.logsDir = path.join(this.happyHomeDir, "logs");
266
- this.settingsFile = path.join(this.happyHomeDir, "settings.json");
267
- this.privateKeyFile = path.join(this.happyHomeDir, "access.key");
268
- this.daemonStateFile = path.join(this.happyHomeDir, "daemon.state.json");
269
- this.daemonLockFile = path.join(this.happyHomeDir, "daemon.state.json.lock");
270
- this.sessionKeysDir = path.join(this.happyHomeDir, "session-keys");
271
- this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
272
- this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
273
- this.currentCliVersion = packageJson.version;
274
- const variant = process.env.HAPPY_VARIANT || "stable";
275
- if (variant === "dev" && !this.happyHomeDir.includes("dev")) {
276
- console.warn('\u26A0\uFE0F WARNING: HAPPY_VARIANT=dev but HAPPY_HOME_DIR does not contain "dev"');
277
- console.warn(` Current: ${this.happyHomeDir}`);
278
- console.warn(` Expected: Should contain "dev" (e.g., ~/.happy-dev)`);
279
- }
280
- if (!this.isDaemonProcess && variant === "dev") {
281
- console.log("\x1B[33m\u{1F527} DEV MODE\x1B[0m - Data: " + this.happyHomeDir);
282
- }
283
- if (!fs.existsSync(this.happyHomeDir)) {
284
- fs.mkdirSync(this.happyHomeDir, { recursive: true });
285
- }
286
- if (!fs.existsSync(this.logsDir)) {
287
- fs.mkdirSync(this.logsDir, { recursive: true });
288
- }
289
- }
290
- }
291
- const configuration = new Configuration();
292
-
293
- function createTimestampForFilename(date = /* @__PURE__ */ new Date()) {
294
- return date.toLocaleString("sv-SE", {
295
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
296
- year: "numeric",
297
- month: "2-digit",
298
- day: "2-digit",
299
- hour: "2-digit",
300
- minute: "2-digit",
301
- second: "2-digit"
302
- }).replace(/[: ]/g, "-").replace(/,/g, "") + "-pid-" + process.pid;
303
- }
304
- function createTimestampForLogEntry(date = /* @__PURE__ */ new Date()) {
305
- return date.toLocaleTimeString("en-US", {
306
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
307
- hour12: false,
308
- hour: "2-digit",
309
- minute: "2-digit",
310
- second: "2-digit",
311
- fractionalSecondDigits: 3
312
- });
313
- }
314
- function getSessionLogPath() {
315
- const timestamp = createTimestampForFilename();
316
- const filename = configuration.isDaemonProcess ? `${timestamp}-daemon.log` : `${timestamp}.log`;
317
- return path.join(configuration.logsDir, filename);
318
- }
319
- class Logger {
320
- constructor(logFilePath = getSessionLogPath()) {
321
- this.logFilePath = logFilePath;
322
- if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && process.env.HAPPY_SERVER_URL) {
323
- this.dangerouslyUnencryptedServerLoggingUrl = process.env.HAPPY_SERVER_URL;
324
- console.log(chalk.yellow("[REMOTE LOGGING] Sending logs to server for AI debugging"));
325
- }
326
- }
327
- dangerouslyUnencryptedServerLoggingUrl;
328
- // Use local timezone for simplicity of locating the logs,
329
- // in practice you will not need absolute timestamps
330
- localTimezoneTimestamp() {
331
- return createTimestampForLogEntry();
332
- }
333
- debug(message, ...args) {
334
- this.logToFile(`[${this.localTimezoneTimestamp()}]`, message, ...args);
335
- }
336
- debugLargeJson(message, object, maxStringLength = 100, maxArrayLength = 10) {
337
- if (!isDebug()) {
338
- this.debug(`In production, skipping message inspection`);
339
- }
340
- const truncateStrings = (obj) => {
341
- if (typeof obj === "string") {
342
- return obj.length > maxStringLength ? obj.substring(0, maxStringLength) + "... [truncated for logs]" : obj;
343
- }
344
- if (Array.isArray(obj)) {
345
- const truncatedArray = obj.map((item) => truncateStrings(item)).slice(0, maxArrayLength);
346
- if (obj.length > maxArrayLength) {
347
- truncatedArray.push(`... [truncated array for logs up to ${maxArrayLength} items]`);
348
- }
349
- return truncatedArray;
350
- }
351
- if (obj && typeof obj === "object") {
352
- const result = {};
353
- for (const [key, value] of Object.entries(obj)) {
354
- if (key === "usage") {
355
- continue;
356
- }
357
- result[key] = truncateStrings(value);
358
- }
359
- return result;
360
- }
361
- return obj;
362
- };
363
- const truncatedObject = truncateStrings(object);
364
- const json = JSON.stringify(truncatedObject, null, 2);
365
- this.logToFile(`[${this.localTimezoneTimestamp()}]`, message, "\n", json);
366
- }
367
- info(message, ...args) {
368
- this.logToConsole("info", "", message, ...args);
369
- this.debug(message, args);
370
- }
371
- infoDeveloper(message, ...args) {
372
- this.debug(message, ...args);
373
- if (isDebug()) {
374
- this.logToConsole("info", "[DEV]", message, ...args);
375
- }
376
- }
377
- warn(message, ...args) {
378
- this.logToConsole("warn", "", message, ...args);
379
- this.debug(`[WARN] ${message}`, ...args);
380
- }
381
- getLogPath() {
382
- return this.logFilePath;
383
- }
384
- logToConsole(level, prefix, message, ...args) {
385
- switch (level) {
386
- case "debug": {
387
- console.log(chalk.gray(prefix), message, ...args);
388
- break;
389
- }
390
- case "error": {
391
- console.error(chalk.red(prefix), message, ...args);
392
- break;
393
- }
394
- case "info": {
395
- console.log(chalk.blue(prefix), message, ...args);
396
- break;
397
- }
398
- case "warn": {
399
- console.log(chalk.yellow(prefix), message, ...args);
400
- break;
401
- }
402
- default: {
403
- this.debug("Unknown log level:", level);
404
- console.log(chalk.blue(prefix), message, ...args);
405
- break;
406
- }
407
- }
408
- }
409
- async sendToRemoteServer(level, message, ...args) {
410
- if (!this.dangerouslyUnencryptedServerLoggingUrl) return;
411
- try {
412
- await fetch(this.dangerouslyUnencryptedServerLoggingUrl + "/logs-combined-from-cli-and-mobile-for-simple-ai-debugging", {
413
- method: "POST",
414
- headers: { "Content-Type": "application/json" },
415
- body: JSON.stringify({
416
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
417
- level,
418
- message: `${message} ${args.map(
419
- (a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)
420
- ).join(" ")}`,
421
- source: "cli",
422
- platform: process.platform
423
- })
424
- });
425
- } catch (error) {
426
- }
427
- }
428
- logToFile(prefix, message, ...args) {
429
- const logLine = `${prefix} ${message} ${args.map((arg) => {
430
- if (typeof arg === "string") return arg;
431
- if (arg instanceof Error) return `${arg.message}
432
- ${arg.stack ?? ""}`;
433
- return JSON.stringify(arg);
434
- }).join(" ")}
435
- `;
436
- if (this.dangerouslyUnencryptedServerLoggingUrl) {
437
- let level = "info";
438
- if (prefix.includes(this.localTimezoneTimestamp())) {
439
- level = "debug";
440
- }
441
- this.sendToRemoteServer(level, message, ...args).catch(() => {
442
- });
443
- }
444
- try {
445
- fs$1.appendFileSync(this.logFilePath, logLine);
446
- } catch (appendError) {
447
- if (isDebug()) {
448
- console.error("[DEV MODE ONLY THROWING] Failed to append to log file:", appendError);
449
- throw appendError;
450
- }
451
- }
452
- }
453
- }
454
- let logger = new Logger();
455
- async function listDaemonLogFiles(limit = 50) {
456
- try {
457
- const logsDir = configuration.logsDir;
458
- if (!fs.existsSync(logsDir)) {
459
- return [];
460
- }
461
- const logs = fs.readdirSync(logsDir).filter((file) => file.endsWith("-daemon.log")).map((file) => {
462
- const fullPath = path.join(logsDir, file);
463
- const stats = fs.statSync(fullPath);
464
- return { file, path: fullPath, modified: stats.mtime };
465
- }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
466
- try {
467
- const { readDaemonState } = await Promise.resolve().then(function () { return persistence; });
468
- const state = await readDaemonState();
469
- if (!state) {
470
- return logs;
471
- }
472
- if (state.daemonLogPath && fs.existsSync(state.daemonLogPath)) {
473
- const stats = fs.statSync(state.daemonLogPath);
474
- const persisted = {
475
- file: path.basename(state.daemonLogPath),
476
- path: state.daemonLogPath,
477
- modified: stats.mtime
478
- };
479
- const idx = logs.findIndex((l) => l.path === persisted.path);
480
- if (idx >= 0) {
481
- const [found] = logs.splice(idx, 1);
482
- logs.unshift(found);
483
- } else {
484
- logs.unshift(persisted);
485
- }
486
- }
487
- } catch {
488
- }
489
- return logs.slice(0, Math.max(0, limit));
490
- } catch {
491
- return [];
492
- }
493
- }
494
- async function getLatestDaemonLog() {
495
- const [latest] = await listDaemonLogFiles(1);
496
- return latest || null;
497
- }
498
-
499
- const sessionRoleSchema = z__namespace.enum(["user", "agent"]);
500
- const sessionTextEventSchema = z__namespace.object({
501
- t: z__namespace.literal("text"),
502
- text: z__namespace.string(),
503
- thinking: z__namespace.boolean().optional()
504
- });
505
- const sessionServiceMessageEventSchema = z__namespace.object({
506
- t: z__namespace.literal("service"),
507
- text: z__namespace.string()
508
- });
509
- const sessionToolCallStartEventSchema = z__namespace.object({
510
- t: z__namespace.literal("tool-call-start"),
511
- call: z__namespace.string(),
512
- name: z__namespace.string(),
513
- title: z__namespace.string(),
514
- description: z__namespace.string(),
515
- args: z__namespace.record(z__namespace.string(), z__namespace.unknown())
516
- });
517
- const sessionToolCallEndEventSchema = z__namespace.object({
518
- t: z__namespace.literal("tool-call-end"),
519
- call: z__namespace.string()
520
- });
521
- const sessionFileEventSchema = z__namespace.object({
522
- t: z__namespace.literal("file"),
523
- ref: z__namespace.string(),
524
- name: z__namespace.string(),
525
- size: z__namespace.number(),
526
- image: z__namespace.object({
527
- width: z__namespace.number(),
528
- height: z__namespace.number(),
529
- thumbhash: z__namespace.string()
530
- }).optional()
531
- });
532
- const sessionTurnStartEventSchema = z__namespace.object({
533
- t: z__namespace.literal("turn-start")
534
- });
535
- const sessionStartEventSchema = z__namespace.object({
536
- t: z__namespace.literal("start"),
537
- title: z__namespace.string().optional()
538
- });
539
- const sessionTurnEndStatusSchema = z__namespace.enum(["completed", "failed", "cancelled"]);
540
- const sessionTurnEndEventSchema = z__namespace.object({
541
- t: z__namespace.literal("turn-end"),
542
- status: sessionTurnEndStatusSchema
543
- });
544
- const sessionStopEventSchema = z__namespace.object({
545
- t: z__namespace.literal("stop")
546
- });
547
- const sessionEventSchema = z__namespace.discriminatedUnion("t", [
548
- sessionTextEventSchema,
549
- sessionServiceMessageEventSchema,
550
- sessionToolCallStartEventSchema,
551
- sessionToolCallEndEventSchema,
552
- sessionFileEventSchema,
553
- sessionTurnStartEventSchema,
554
- sessionStartEventSchema,
555
- sessionTurnEndEventSchema,
556
- sessionStopEventSchema
557
- ]);
558
- const sessionEnvelopeSchema = z__namespace.object({
559
- id: z__namespace.string(),
560
- time: z__namespace.number(),
561
- role: sessionRoleSchema,
562
- turn: z__namespace.string().optional(),
563
- subagent: z__namespace.string().refine((value) => cuid2.isCuid(value), {
564
- message: "subagent must be a cuid2 value"
565
- }).optional(),
566
- ev: sessionEventSchema
567
- }).superRefine((envelope, ctx) => {
568
- if (envelope.ev.t === "service" && envelope.role !== "agent") {
569
- ctx.addIssue({
570
- code: z__namespace.ZodIssueCode.custom,
571
- message: 'service events must use role "agent"',
572
- path: ["role"]
573
- });
574
- }
575
- if ((envelope.ev.t === "start" || envelope.ev.t === "stop") && envelope.role !== "agent") {
576
- ctx.addIssue({
577
- code: z__namespace.ZodIssueCode.custom,
578
- message: `${envelope.ev.t} events must use role "agent"`,
579
- path: ["role"]
580
- });
581
- }
582
- });
583
- const MessageMetaSchema$1 = z__namespace.object({
584
- sentFrom: z__namespace.string().optional(),
585
- permissionMode: z__namespace.enum(["default", "acceptEdits", "bypassPermissions", "plan", "read-only", "safe-yolo", "yolo"]).optional(),
586
- model: z__namespace.string().nullable().optional(),
587
- fallbackModel: z__namespace.string().nullable().optional(),
588
- reasoningEffort: z__namespace.string().nullable().optional(),
589
- customSystemPrompt: z__namespace.string().nullable().optional(),
590
- appendSystemPrompt: z__namespace.string().nullable().optional(),
591
- allowedTools: z__namespace.array(z__namespace.string()).nullable().optional(),
592
- disallowedTools: z__namespace.array(z__namespace.string()).nullable().optional(),
593
- displayText: z__namespace.string().optional()
594
- });
595
- const UserMessageSchema$1 = z__namespace.object({
596
- role: z__namespace.literal("user"),
597
- content: z__namespace.object({
598
- type: z__namespace.literal("text"),
599
- text: z__namespace.string()
600
- }),
601
- localKey: z__namespace.string().optional(),
602
- meta: MessageMetaSchema$1.optional()
603
- });
604
- const AgentMessageSchema$1 = z__namespace.object({
605
- role: z__namespace.literal("agent"),
606
- content: z__namespace.object({
607
- type: z__namespace.string()
608
- }).passthrough(),
609
- meta: MessageMetaSchema$1.optional()
610
- });
611
- z__namespace.discriminatedUnion("role", [UserMessageSchema$1, AgentMessageSchema$1]);
612
- const SessionMessageContentSchema = z__namespace.object({
613
- c: z__namespace.string(),
614
- t: z__namespace.literal("encrypted")
615
- });
616
- const SessionMessageSchema = z__namespace.object({
617
- id: z__namespace.string(),
618
- seq: z__namespace.number(),
619
- localId: z__namespace.string().nullish(),
620
- content: SessionMessageContentSchema,
621
- createdAt: z__namespace.number(),
622
- updatedAt: z__namespace.number()
623
- });
624
- const SessionProtocolMessageSchema = z__namespace.object({
625
- role: z__namespace.literal("session"),
626
- content: sessionEnvelopeSchema,
627
- meta: MessageMetaSchema$1.optional()
628
- });
629
- z__namespace.discriminatedUnion("role", [
630
- UserMessageSchema$1,
631
- AgentMessageSchema$1,
632
- SessionProtocolMessageSchema
633
- ]);
634
- const VersionedEncryptedValueSchema = z__namespace.object({
635
- version: z__namespace.number(),
636
- value: z__namespace.string()
637
- });
638
- const VersionedNullableEncryptedValueSchema = z__namespace.object({
639
- version: z__namespace.number(),
640
- value: z__namespace.string().nullable()
641
- });
642
- const UpdateNewMessageBodySchema = z__namespace.object({
643
- t: z__namespace.literal("new-message"),
644
- sid: z__namespace.string(),
645
- message: SessionMessageSchema
646
- });
647
- const UpdateSessionBodySchema = z__namespace.object({
648
- t: z__namespace.literal("update-session"),
649
- id: z__namespace.string(),
650
- metadata: VersionedEncryptedValueSchema.nullish(),
651
- agentState: VersionedNullableEncryptedValueSchema.nullish()
652
- });
653
- const VersionedMachineEncryptedValueSchema = z__namespace.object({
654
- version: z__namespace.number(),
655
- value: z__namespace.string()
656
- });
657
- const UpdateMachineBodySchema = z__namespace.object({
658
- t: z__namespace.literal("update-machine"),
659
- machineId: z__namespace.string(),
660
- metadata: VersionedMachineEncryptedValueSchema.nullish(),
661
- daemonState: VersionedMachineEncryptedValueSchema.nullish(),
662
- active: z__namespace.boolean().optional(),
663
- activeAt: z__namespace.number().optional()
664
- });
665
- const CoreUpdateBodySchema = z__namespace.discriminatedUnion("t", [
666
- UpdateNewMessageBodySchema,
667
- UpdateSessionBodySchema,
668
- UpdateMachineBodySchema
669
- ]);
670
- z__namespace.object({
671
- id: z__namespace.string(),
672
- seq: z__namespace.number(),
673
- body: CoreUpdateBodySchema,
674
- createdAt: z__namespace.number()
675
- });
676
- const MODEL_MODE_DEFAULT = "default";
677
- const MODEL_MODES = [
678
- MODEL_MODE_DEFAULT,
679
- "claude-fable-5",
680
- "claude-fable-5[1m]",
681
- "claude-opus-5",
682
- "claude-opus-5[1m]",
683
- "claude-opus-4-8",
684
- "claude-opus-4-8[1m]",
685
- "claude-opus-4-6",
686
- "claude-opus-4-6[1m]",
687
- "claude-sonnet-4-6",
688
- "claude-sonnet-4-6[1m]",
689
- "claude-haiku-4-5",
690
- "claude-fable-5-low",
691
- "claude-fable-5-medium",
692
- "claude-fable-5-high",
693
- "claude-fable-5-xhigh",
694
- "claude-fable-5-max",
695
- "claude-fable-5[1m]-low",
696
- "claude-fable-5[1m]-medium",
697
- "claude-fable-5[1m]-high",
698
- "claude-fable-5[1m]-xhigh",
699
- "claude-fable-5[1m]-max",
700
- "claude-opus-5-low",
701
- "claude-opus-5-medium",
702
- "claude-opus-5-high",
703
- "claude-opus-5-xhigh",
704
- "claude-opus-5-max",
705
- "claude-opus-5[1m]-low",
706
- "claude-opus-5[1m]-medium",
707
- "claude-opus-5[1m]-high",
708
- "claude-opus-5[1m]-xhigh",
709
- "claude-opus-5[1m]-max",
710
- "claude-opus-4-8-low",
711
- "claude-opus-4-8-medium",
712
- "claude-opus-4-8-high",
713
- "claude-opus-4-8-xhigh",
714
- "claude-opus-4-8-max",
715
- "claude-opus-4-8[1m]-low",
716
- "claude-opus-4-8[1m]-medium",
717
- "claude-opus-4-8[1m]-high",
718
- "claude-opus-4-8[1m]-xhigh",
719
- "claude-opus-4-8[1m]-max",
720
- "claude-opus-4-6-low",
721
- "claude-opus-4-6-medium",
722
- "claude-opus-4-6-high",
723
- "claude-opus-4-6-max",
724
- "claude-opus-4-6[1m]-low",
725
- "claude-opus-4-6[1m]-medium",
726
- "claude-opus-4-6[1m]-high",
727
- "claude-opus-4-6[1m]-max",
728
- "claude-sonnet-4-6-low",
729
- "claude-sonnet-4-6-medium",
730
- "claude-sonnet-4-6-high",
731
- "claude-sonnet-4-6[1m]-low",
732
- "claude-sonnet-4-6[1m]-medium",
733
- "claude-sonnet-4-6[1m]-high",
734
- "claude-haiku-4-5-low",
735
- "claude-haiku-4-5-medium",
736
- "claude-haiku-4-5-high",
737
- "gpt-5.6-sol-low",
738
- "gpt-5.6-sol-medium",
739
- "gpt-5.6-sol-high",
740
- "gpt-5.6-sol-xhigh",
741
- "gpt-5.6-sol-max",
742
- "gpt-5.6-terra-low",
743
- "gpt-5.6-terra-medium",
744
- "gpt-5.6-terra-high",
745
- "gpt-5.6-terra-xhigh",
746
- "gpt-5.6-luna-low",
747
- "gpt-5.6-luna-medium",
748
- "gpt-5.6-luna-high",
749
- "gpt-5.6-luna-xhigh",
750
- "gpt-5.5-low",
751
- "gpt-5.5-medium",
752
- "gpt-5.5-high",
753
- "gpt-5.5-xhigh",
754
- "gpt-5.4-low",
755
- "gpt-5.4-medium",
756
- "gpt-5.4-high",
757
- "gpt-5.4-xhigh",
758
- "gpt-5.3-codex-low",
759
- "gpt-5.3-codex-medium",
760
- "gpt-5.3-codex-high",
761
- "gpt-5.3-codex-xhigh",
762
- "gpt-5.2-codex-low",
763
- "gpt-5.2-codex-medium",
764
- "gpt-5.2-codex-high",
765
- "gpt-5.2-codex-xhigh",
766
- "gpt-5.2-low",
767
- "gpt-5.2-medium",
768
- "gpt-5.2-high",
769
- "gpt-5.2-xhigh",
770
- "gpt-5.1-codex-max-low",
771
- "gpt-5.1-codex-max-medium",
772
- "gpt-5.1-codex-max-high",
773
- "gpt-5.1-codex-max-xhigh",
774
- "gpt-5.1-codex-mini-medium",
775
- "gpt-5.1-codex-mini-high",
776
- "gemini-3-pro-preview",
777
- "gemini-3-flash-preview",
778
- "gemini-2.5-pro"
779
- ];
780
- const CLAUDE_MODEL_MODES = [
781
- MODEL_MODE_DEFAULT,
782
- "claude-fable-5",
783
- "claude-fable-5[1m]",
784
- "claude-opus-5",
785
- "claude-opus-5[1m]",
786
- "claude-opus-4-8",
787
- "claude-opus-4-8[1m]",
788
- "claude-opus-4-6",
789
- "claude-opus-4-6[1m]",
790
- "claude-sonnet-4-6",
791
- "claude-sonnet-4-6[1m]",
792
- "claude-haiku-4-5",
793
- "claude-fable-5-low",
794
- "claude-fable-5-medium",
795
- "claude-fable-5-high",
796
- "claude-fable-5-xhigh",
797
- "claude-fable-5-max",
798
- "claude-fable-5[1m]-low",
799
- "claude-fable-5[1m]-medium",
800
- "claude-fable-5[1m]-high",
801
- "claude-fable-5[1m]-xhigh",
802
- "claude-fable-5[1m]-max",
803
- "claude-opus-5-low",
804
- "claude-opus-5-medium",
805
- "claude-opus-5-high",
806
- "claude-opus-5-xhigh",
807
- "claude-opus-5-max",
808
- "claude-opus-5[1m]-low",
809
- "claude-opus-5[1m]-medium",
810
- "claude-opus-5[1m]-high",
811
- "claude-opus-5[1m]-xhigh",
812
- "claude-opus-5[1m]-max",
813
- "claude-opus-4-8-low",
814
- "claude-opus-4-8-medium",
815
- "claude-opus-4-8-high",
816
- "claude-opus-4-8-xhigh",
817
- "claude-opus-4-8-max",
818
- "claude-opus-4-8[1m]-low",
819
- "claude-opus-4-8[1m]-medium",
820
- "claude-opus-4-8[1m]-high",
821
- "claude-opus-4-8[1m]-xhigh",
822
- "claude-opus-4-8[1m]-max",
823
- "claude-opus-4-6-low",
824
- "claude-opus-4-6-medium",
825
- "claude-opus-4-6-high",
826
- "claude-opus-4-6-max",
827
- "claude-opus-4-6[1m]-low",
828
- "claude-opus-4-6[1m]-medium",
829
- "claude-opus-4-6[1m]-high",
830
- "claude-opus-4-6[1m]-max",
831
- "claude-sonnet-4-6-low",
832
- "claude-sonnet-4-6-medium",
833
- "claude-sonnet-4-6-high",
834
- "claude-sonnet-4-6[1m]-low",
835
- "claude-sonnet-4-6[1m]-medium",
836
- "claude-sonnet-4-6[1m]-high",
837
- "claude-haiku-4-5-low",
838
- "claude-haiku-4-5-medium",
839
- "claude-haiku-4-5-high"
840
- ];
841
- const GEMINI_MODEL_MODES = [
842
- MODEL_MODE_DEFAULT,
843
- "gemini-3-pro-preview",
844
- "gemini-3-flash-preview",
845
- "gemini-2.5-pro"
846
- ];
847
- const CODEX_MODEL_MODES = [
848
- MODEL_MODE_DEFAULT,
849
- "gpt-5.6-sol-low",
850
- "gpt-5.6-sol-medium",
851
- "gpt-5.6-sol-high",
852
- "gpt-5.6-sol-xhigh",
853
- "gpt-5.6-sol-max",
854
- "gpt-5.6-terra-low",
855
- "gpt-5.6-terra-medium",
856
- "gpt-5.6-terra-high",
857
- "gpt-5.6-terra-xhigh",
858
- "gpt-5.6-luna-low",
859
- "gpt-5.6-luna-medium",
860
- "gpt-5.6-luna-high",
861
- "gpt-5.6-luna-xhigh",
862
- "gpt-5.5-low",
863
- "gpt-5.5-medium",
864
- "gpt-5.5-high",
865
- "gpt-5.5-xhigh",
866
- "gpt-5.4-low",
867
- "gpt-5.4-medium",
868
- "gpt-5.4-high",
869
- "gpt-5.4-xhigh",
870
- "gpt-5.3-codex-low",
871
- "gpt-5.3-codex-medium",
872
- "gpt-5.3-codex-high",
873
- "gpt-5.3-codex-xhigh",
874
- "gpt-5.2-codex-low",
875
- "gpt-5.2-codex-medium",
876
- "gpt-5.2-codex-high",
877
- "gpt-5.2-codex-xhigh",
878
- "gpt-5.2-low",
879
- "gpt-5.2-medium",
880
- "gpt-5.2-high",
881
- "gpt-5.2-xhigh",
882
- "gpt-5.1-codex-max-low",
883
- "gpt-5.1-codex-max-medium",
884
- "gpt-5.1-codex-max-high",
885
- "gpt-5.1-codex-max-xhigh",
886
- "gpt-5.1-codex-mini-medium",
887
- "gpt-5.1-codex-mini-high"
888
- ];
889
- const MODEL_MODE_SET = new Set(MODEL_MODES);
890
- const CLAUDE_MODEL_MODE_SET = new Set(CLAUDE_MODEL_MODES);
891
- const GEMINI_MODEL_MODE_SET = new Set(GEMINI_MODEL_MODES);
892
- const CODEX_MODEL_MODE_SET = new Set(CODEX_MODEL_MODES);
893
- function isModelMode(value) {
894
- return MODEL_MODE_SET.has(value);
895
- }
896
- function isModelModeForAgent(agent, mode) {
897
- if (!isModelMode(mode)) return false;
898
- if (agent === "claude") return CLAUDE_MODEL_MODE_SET.has(mode);
899
- if (agent === "gemini") return GEMINI_MODEL_MODE_SET.has(mode);
900
- return CODEX_MODEL_MODE_SET.has(mode);
901
- }
902
- const CLAUDE_MODE_TO_SELECTION = {
903
- "claude-fable-5-low": { family: "claude-fable-5", effort: "low" },
904
- "claude-fable-5-medium": { family: "claude-fable-5", effort: "medium" },
905
- "claude-fable-5-high": { family: "claude-fable-5", effort: "high" },
906
- "claude-fable-5-xhigh": { family: "claude-fable-5", effort: "xhigh" },
907
- "claude-fable-5-max": { family: "claude-fable-5", effort: "max" },
908
- "claude-fable-5[1m]-low": { family: "claude-fable-5[1m]", effort: "low" },
909
- "claude-fable-5[1m]-medium": { family: "claude-fable-5[1m]", effort: "medium" },
910
- "claude-fable-5[1m]-high": { family: "claude-fable-5[1m]", effort: "high" },
911
- "claude-fable-5[1m]-xhigh": { family: "claude-fable-5[1m]", effort: "xhigh" },
912
- "claude-fable-5[1m]-max": { family: "claude-fable-5[1m]", effort: "max" },
913
- "claude-opus-5-low": { family: "claude-opus-5", effort: "low" },
914
- "claude-opus-5-medium": { family: "claude-opus-5", effort: "medium" },
915
- "claude-opus-5-high": { family: "claude-opus-5", effort: "high" },
916
- "claude-opus-5-xhigh": { family: "claude-opus-5", effort: "xhigh" },
917
- "claude-opus-5-max": { family: "claude-opus-5", effort: "max" },
918
- "claude-opus-5[1m]-low": { family: "claude-opus-5[1m]", effort: "low" },
919
- "claude-opus-5[1m]-medium": { family: "claude-opus-5[1m]", effort: "medium" },
920
- "claude-opus-5[1m]-high": { family: "claude-opus-5[1m]", effort: "high" },
921
- "claude-opus-5[1m]-xhigh": { family: "claude-opus-5[1m]", effort: "xhigh" },
922
- "claude-opus-5[1m]-max": { family: "claude-opus-5[1m]", effort: "max" },
923
- "claude-opus-4-8-low": { family: "claude-opus-4-8", effort: "low" },
924
- "claude-opus-4-8-medium": { family: "claude-opus-4-8", effort: "medium" },
925
- "claude-opus-4-8-high": { family: "claude-opus-4-8", effort: "high" },
926
- "claude-opus-4-8-xhigh": { family: "claude-opus-4-8", effort: "xhigh" },
927
- "claude-opus-4-8-max": { family: "claude-opus-4-8", effort: "max" },
928
- "claude-opus-4-8[1m]-low": { family: "claude-opus-4-8[1m]", effort: "low" },
929
- "claude-opus-4-8[1m]-medium": { family: "claude-opus-4-8[1m]", effort: "medium" },
930
- "claude-opus-4-8[1m]-high": { family: "claude-opus-4-8[1m]", effort: "high" },
931
- "claude-opus-4-8[1m]-xhigh": { family: "claude-opus-4-8[1m]", effort: "xhigh" },
932
- "claude-opus-4-8[1m]-max": { family: "claude-opus-4-8[1m]", effort: "max" },
933
- "claude-opus-4-6-low": { family: "claude-opus-4-6", effort: "low" },
934
- "claude-opus-4-6-medium": { family: "claude-opus-4-6", effort: "medium" },
935
- "claude-opus-4-6-high": { family: "claude-opus-4-6", effort: "high" },
936
- "claude-opus-4-6-max": { family: "claude-opus-4-6", effort: "max" },
937
- "claude-opus-4-6[1m]-low": { family: "claude-opus-4-6[1m]", effort: "low" },
938
- "claude-opus-4-6[1m]-medium": { family: "claude-opus-4-6[1m]", effort: "medium" },
939
- "claude-opus-4-6[1m]-high": { family: "claude-opus-4-6[1m]", effort: "high" },
940
- "claude-opus-4-6[1m]-max": { family: "claude-opus-4-6[1m]", effort: "max" },
941
- "claude-sonnet-4-6-low": { family: "claude-sonnet-4-6", effort: "low" },
942
- "claude-sonnet-4-6-medium": { family: "claude-sonnet-4-6", effort: "medium" },
943
- "claude-sonnet-4-6-high": { family: "claude-sonnet-4-6", effort: "high" },
944
- "claude-sonnet-4-6[1m]-low": { family: "claude-sonnet-4-6[1m]", effort: "low" },
945
- "claude-sonnet-4-6[1m]-medium": { family: "claude-sonnet-4-6[1m]", effort: "medium" },
946
- "claude-sonnet-4-6[1m]-high": { family: "claude-sonnet-4-6[1m]", effort: "high" },
947
- "claude-haiku-4-5-low": { family: "claude-haiku-4-5", effort: "low" },
948
- "claude-haiku-4-5-medium": { family: "claude-haiku-4-5", effort: "medium" },
949
- "claude-haiku-4-5-high": { family: "claude-haiku-4-5", effort: "high" }
950
- };
951
- const CODEX_MODE_TO_SELECTION = {
952
- "gpt-5.6-sol-low": { family: "gpt-5.6-sol", effort: "low" },
953
- "gpt-5.6-sol-medium": { family: "gpt-5.6-sol", effort: "medium" },
954
- "gpt-5.6-sol-high": { family: "gpt-5.6-sol", effort: "high" },
955
- "gpt-5.6-sol-xhigh": { family: "gpt-5.6-sol", effort: "xhigh" },
956
- "gpt-5.6-sol-max": { family: "gpt-5.6-sol", effort: "max" },
957
- "gpt-5.6-terra-low": { family: "gpt-5.6-terra", effort: "low" },
958
- "gpt-5.6-terra-medium": { family: "gpt-5.6-terra", effort: "medium" },
959
- "gpt-5.6-terra-high": { family: "gpt-5.6-terra", effort: "high" },
960
- "gpt-5.6-terra-xhigh": { family: "gpt-5.6-terra", effort: "xhigh" },
961
- "gpt-5.6-luna-low": { family: "gpt-5.6-luna", effort: "low" },
962
- "gpt-5.6-luna-medium": { family: "gpt-5.6-luna", effort: "medium" },
963
- "gpt-5.6-luna-high": { family: "gpt-5.6-luna", effort: "high" },
964
- "gpt-5.6-luna-xhigh": { family: "gpt-5.6-luna", effort: "xhigh" },
965
- "gpt-5.5-low": { family: "gpt-5.5", effort: "low" },
966
- "gpt-5.5-medium": { family: "gpt-5.5", effort: "medium" },
967
- "gpt-5.5-high": { family: "gpt-5.5", effort: "high" },
968
- "gpt-5.5-xhigh": { family: "gpt-5.5", effort: "xhigh" },
969
- "gpt-5.4-low": { family: "gpt-5.4", effort: "low" },
970
- "gpt-5.4-medium": { family: "gpt-5.4", effort: "medium" },
971
- "gpt-5.4-high": { family: "gpt-5.4", effort: "high" },
972
- "gpt-5.4-xhigh": { family: "gpt-5.4", effort: "xhigh" },
973
- "gpt-5.3-codex-low": { family: "gpt-5.3-codex", effort: "low" },
974
- "gpt-5.3-codex-medium": { family: "gpt-5.3-codex", effort: "medium" },
975
- "gpt-5.3-codex-high": { family: "gpt-5.3-codex", effort: "high" },
976
- "gpt-5.3-codex-xhigh": { family: "gpt-5.3-codex", effort: "xhigh" },
977
- "gpt-5.2-codex-low": { family: "gpt-5.2-codex", effort: "low" },
978
- "gpt-5.2-codex-medium": { family: "gpt-5.2-codex", effort: "medium" },
979
- "gpt-5.2-codex-high": { family: "gpt-5.2-codex", effort: "high" },
980
- "gpt-5.2-codex-xhigh": { family: "gpt-5.2-codex", effort: "xhigh" },
981
- "gpt-5.2-low": { family: "gpt-5.2", effort: "low" },
982
- "gpt-5.2-medium": { family: "gpt-5.2", effort: "medium" },
983
- "gpt-5.2-high": { family: "gpt-5.2", effort: "high" },
984
- "gpt-5.2-xhigh": { family: "gpt-5.2", effort: "xhigh" },
985
- "gpt-5.1-codex-max-low": { family: "gpt-5.1-codex-max", effort: "low" },
986
- "gpt-5.1-codex-max-medium": { family: "gpt-5.1-codex-max", effort: "medium" },
987
- "gpt-5.1-codex-max-high": { family: "gpt-5.1-codex-max", effort: "high" },
988
- "gpt-5.1-codex-max-xhigh": { family: "gpt-5.1-codex-max", effort: "xhigh" },
989
- "gpt-5.1-codex-mini-medium": { family: "gpt-5.1-codex-mini", effort: "medium" },
990
- "gpt-5.1-codex-mini-high": { family: "gpt-5.1-codex-mini", effort: "high" }
991
- };
992
- function parseClaudeModelMode(mode) {
993
- const entry = CLAUDE_MODE_TO_SELECTION[mode];
994
- if (entry) return entry;
995
- if (mode === MODEL_MODE_DEFAULT) return { family: MODEL_MODE_DEFAULT, effort: null };
996
- return { family: mode, effort: null };
997
- }
998
- function parseCodexModelMode(mode) {
999
- return CODEX_MODE_TO_SELECTION[mode] ?? { family: MODEL_MODE_DEFAULT, effort: "medium" };
1000
- }
1001
- const FeishuWebhookConfigSchema = z.z.object({
1002
- url: z.z.string().url(),
1003
- secret: z.z.string().optional(),
1004
- enabled: z.z.boolean()
1005
- });
1006
- z.z.object({
1007
- url: z.z.string().nullable(),
1008
- secret_set: z.z.boolean(),
1009
- enabled: z.z.boolean(),
1010
- lastTestedAt: z.z.number().nullable()
1011
- });
1012
- z.z.object({
1013
- feishu: FeishuWebhookConfigSchema.extend({
1014
- lastTestedAt: z.z.number().optional()
1015
- }).optional(),
1016
- feishuMention: FeishuWebhookConfigSchema.extend({
1017
- lastTestedAt: z.z.number().optional()
1018
- }).optional(),
1019
- /**
1020
- * The account owner's own Feishu identity (open_id `ou_…` or tenant
1021
- * user_id). When set, collaboration @ notifications sent to any owner's
1022
- * mention webhook render this user as a real `<at>` ping instead of
1023
- * plain text. The ping only fires if the user is in the bot's group.
1024
- */
1025
- feishuUserId: z.z.string().optional()
1026
- });
1027
- const MemorySourceSchema = z.z.enum(["manual", "message-pin"]);
1028
- z.z.object({
1029
- id: z.z.string(),
1030
- content: z.z.string().min(1).max(8e3),
1031
- source: MemorySourceSchema,
1032
- sourceSessionId: z.z.string().nullable(),
1033
- sourceMessageId: z.z.string().nullable(),
1034
- archivedAt: z.z.number().nullable(),
1035
- createdAt: z.z.number(),
1036
- updatedAt: z.z.number()
1037
- });
1038
- z.z.object({
1039
- content: z.z.string().min(1).max(8e3),
1040
- source: MemorySourceSchema.optional().default("manual"),
1041
- sourceSessionId: z.z.string().optional(),
1042
- sourceMessageId: z.z.string().optional()
1043
- });
1044
- z.z.object({
1045
- content: z.z.string().min(1).max(8e3)
1046
- });
1047
-
1048
33
  z.z.object({
1049
34
  host: z.z.string(),
1050
35
  platform: z.z.string(),
@@ -1150,141 +135,6 @@ const AgentMessageSchema = z.z.object({
1150
135
  });
1151
136
  z.z.union([UserMessageSchema, AgentMessageSchema]);
1152
137
 
1153
- function encodeBase64(buffer, variant = "base64") {
1154
- if (variant === "base64url") {
1155
- return encodeBase64Url(buffer);
1156
- }
1157
- return Buffer.from(buffer).toString("base64");
1158
- }
1159
- function encodeBase64Url(buffer) {
1160
- return Buffer.from(buffer).toString("base64").replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
1161
- }
1162
- function decodeBase64(base64, variant = "base64") {
1163
- if (variant === "base64url") {
1164
- const base64Standard = base64.replaceAll("-", "+").replaceAll("_", "/") + "=".repeat((4 - base64.length % 4) % 4);
1165
- return new Uint8Array(Buffer.from(base64Standard, "base64"));
1166
- }
1167
- return new Uint8Array(Buffer.from(base64, "base64"));
1168
- }
1169
- function getRandomBytes(size) {
1170
- return new Uint8Array(node_crypto.randomBytes(size));
1171
- }
1172
- function libsodiumPublicKeyFromSecretKey(seed) {
1173
- const hashedSeed = new Uint8Array(node_crypto.createHash("sha512").update(seed).digest());
1174
- const secretKey = hashedSeed.slice(0, 32);
1175
- return new Uint8Array(tweetnacl.box.keyPair.fromSecretKey(secretKey).publicKey);
1176
- }
1177
- function libsodiumEncryptForPublicKey(data, recipientPublicKey) {
1178
- const ephemeralKeyPair = tweetnacl.box.keyPair();
1179
- const nonce = getRandomBytes(tweetnacl.box.nonceLength);
1180
- const encrypted = tweetnacl.box(data, nonce, recipientPublicKey, ephemeralKeyPair.secretKey);
1181
- const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
1182
- result.set(ephemeralKeyPair.publicKey, 0);
1183
- result.set(nonce, ephemeralKeyPair.publicKey.length);
1184
- result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
1185
- return result;
1186
- }
1187
- function encryptLegacy(data, secret) {
1188
- const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
1189
- const encrypted = tweetnacl.secretbox(new TextEncoder().encode(JSON.stringify(data)), nonce, secret);
1190
- const result = new Uint8Array(nonce.length + encrypted.length);
1191
- result.set(nonce);
1192
- result.set(encrypted, nonce.length);
1193
- return result;
1194
- }
1195
- function decryptLegacy(data, secret) {
1196
- const nonce = data.slice(0, tweetnacl.secretbox.nonceLength);
1197
- const encrypted = data.slice(tweetnacl.secretbox.nonceLength);
1198
- const decrypted = tweetnacl.secretbox.open(encrypted, nonce, secret);
1199
- if (!decrypted) {
1200
- return null;
1201
- }
1202
- return JSON.parse(new TextDecoder().decode(decrypted));
1203
- }
1204
- function encryptWithDataKey(data, dataKey) {
1205
- const nonce = getRandomBytes(12);
1206
- const cipher = node_crypto.createCipheriv("aes-256-gcm", dataKey, nonce);
1207
- const plaintext = new TextEncoder().encode(JSON.stringify(data));
1208
- const encrypted = Buffer.concat([
1209
- cipher.update(plaintext),
1210
- cipher.final()
1211
- ]);
1212
- const authTag = cipher.getAuthTag();
1213
- const bundle = new Uint8Array(12 + encrypted.length + 16 + 1);
1214
- bundle.set([0], 0);
1215
- bundle.set(nonce, 1);
1216
- bundle.set(new Uint8Array(encrypted), 13);
1217
- bundle.set(new Uint8Array(authTag), 13 + encrypted.length);
1218
- return bundle;
1219
- }
1220
- function decryptWithDataKey(bundle, dataKey) {
1221
- if (bundle.length < 1) {
1222
- return null;
1223
- }
1224
- if (bundle[0] !== 0) {
1225
- return null;
1226
- }
1227
- if (bundle.length < 12 + 16 + 1) {
1228
- return null;
1229
- }
1230
- const nonce = bundle.slice(1, 13);
1231
- const authTag = bundle.slice(bundle.length - 16);
1232
- const ciphertext = bundle.slice(13, bundle.length - 16);
1233
- try {
1234
- const decipher = node_crypto.createDecipheriv("aes-256-gcm", dataKey, nonce);
1235
- decipher.setAuthTag(authTag);
1236
- const decrypted = Buffer.concat([
1237
- decipher.update(ciphertext),
1238
- decipher.final()
1239
- ]);
1240
- return JSON.parse(new TextDecoder().decode(decrypted));
1241
- } catch (error) {
1242
- return null;
1243
- }
1244
- }
1245
- function encrypt(key, variant, data) {
1246
- if (variant === "legacy") {
1247
- return encryptLegacy(data, key);
1248
- } else {
1249
- return encryptWithDataKey(data, key);
1250
- }
1251
- }
1252
- function decrypt(key, variant, data) {
1253
- if (variant === "legacy") {
1254
- return decryptLegacy(data, key);
1255
- } else {
1256
- return decryptWithDataKey(data, key);
1257
- }
1258
- }
1259
-
1260
- async function delay(ms) {
1261
- return new Promise((resolve) => setTimeout(resolve, ms));
1262
- }
1263
- function exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount) {
1264
- let maxDelayRet = minDelay + (maxDelay - minDelay) / maxFailureCount * Math.min(currentFailureCount, maxFailureCount);
1265
- return Math.round(Math.random() * maxDelayRet);
1266
- }
1267
- function createBackoff(opts) {
1268
- return async (callback) => {
1269
- let currentFailureCount = 0;
1270
- const minDelay = 250;
1271
- const maxDelay = 1e3;
1272
- const maxFailureCount = 50;
1273
- while (true) {
1274
- try {
1275
- return await callback();
1276
- } catch (e) {
1277
- if (currentFailureCount < maxFailureCount) {
1278
- currentFailureCount++;
1279
- }
1280
- let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
1281
- await delay(waitForRequest);
1282
- }
1283
- }
1284
- };
1285
- }
1286
- let backoff = createBackoff();
1287
-
1288
138
  class AsyncLock {
1289
139
  permits = 1;
1290
140
  promiseResolverQueue = [];
@@ -1365,7 +215,7 @@ class InvalidateSync {
1365
215
  this._pendings = [];
1366
216
  };
1367
217
  _doSync = async () => {
1368
- await backoff(async () => {
218
+ await time.backoff(async () => {
1369
219
  if (this._stopped) {
1370
220
  return;
1371
221
  }
@@ -1385,7 +235,7 @@ class InvalidateSync {
1385
235
  };
1386
236
  }
1387
237
 
1388
- const diffsDir = path.join(configuration.happyHomeDir, "diffs");
238
+ const diffsDir = path.join(logger.configuration.happyHomeDir, "diffs");
1389
239
  function ensureDiffsDir() {
1390
240
  if (!fs.existsSync(diffsDir)) {
1391
241
  fs.mkdirSync(diffsDir, { recursive: true });
@@ -1409,9 +259,9 @@ function saveDiffRecords(sessionId, records) {
1409
259
  }
1410
260
  existing.push(...records);
1411
261
  fs.writeFileSync(filePath, JSON.stringify(existing), "utf-8");
1412
- logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`);
262
+ logger.logger.debug(`[DiffStore] Saved ${records.length} record(s) for session ${sessionId}`);
1413
263
  } catch (error) {
1414
- logger.warn(`[DiffStore] Failed to save diff records:`, error);
264
+ logger.logger.warn(`[DiffStore] Failed to save diff records:`, error);
1415
265
  }
1416
266
  }
1417
267
  function getDiffDetail(sessionId, callId, filePath) {
@@ -1423,12 +273,12 @@ function getDiffDetail(sessionId, callId, filePath) {
1423
273
  if (!record) return null;
1424
274
  return { diff: record.diff, additions: record.additions, deletions: record.deletions };
1425
275
  } catch (error) {
1426
- logger.warn(`[DiffStore] Failed to get diff detail:`, error);
276
+ logger.logger.warn(`[DiffStore] Failed to get diff detail:`, error);
1427
277
  return null;
1428
278
  }
1429
279
  }
1430
280
 
1431
- const toolOutputsDir = path.join(configuration.happyHomeDir, "tool-outputs");
281
+ const toolOutputsDir = path.join(logger.configuration.happyHomeDir, "tool-outputs");
1432
282
  function ensureToolOutputsDir() {
1433
283
  if (!fs.existsSync(toolOutputsDir)) {
1434
284
  fs.mkdirSync(toolOutputsDir, { recursive: true });
@@ -1451,9 +301,9 @@ function saveToolOutputRecord(sessionId, record) {
1451
301
  }
1452
302
  existing.push(record);
1453
303
  fs.writeFileSync(filePath, JSON.stringify(existing), "utf-8");
1454
- logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`);
304
+ logger.logger.debug(`[ToolOutputStore] Saved output for ${record.toolName} (${record.callId}) in session ${sessionId}`);
1455
305
  } catch (error) {
1456
- logger.warn("[ToolOutputStore] Failed to save tool output record:", error);
306
+ logger.logger.warn("[ToolOutputStore] Failed to save tool output record:", error);
1457
307
  }
1458
308
  }
1459
309
  function getToolOutputRecord(sessionId, callId) {
@@ -1463,7 +313,7 @@ function getToolOutputRecord(sessionId, callId) {
1463
313
  const records = JSON.parse(fs.readFileSync(filePath, "utf-8"));
1464
314
  return records.find((record) => record.callId === callId) || null;
1465
315
  } catch (error) {
1466
- logger.warn("[ToolOutputStore] Failed to get tool output record:", error);
316
+ logger.logger.warn("[ToolOutputStore] Failed to get tool output record:", error);
1467
317
  return null;
1468
318
  }
1469
319
  }
@@ -1769,7 +619,7 @@ class RpcHandlerManager {
1769
619
  this.scopePrefix = config.scopePrefix;
1770
620
  this.encryptionKey = config.encryptionKey;
1771
621
  this.encryptionVariant = config.encryptionVariant;
1772
- this.logger = config.logger || ((msg, data) => logger.debug(msg, data));
622
+ this.logger = config.logger || ((msg, data) => logger.logger.debug(msg, data));
1773
623
  }
1774
624
  /** Encryption key — exposed so feature modules can encrypt outbound non-RPC frames. */
1775
625
  getEncryptionKey() {
@@ -1824,11 +674,11 @@ class RpcHandlerManager {
1824
674
  if (!handler) {
1825
675
  this.logger("[RPC] [ERROR] Method not found", { method: request.method });
1826
676
  const errorResponse = { error: "Method not found" };
1827
- const encryptedError = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
677
+ const encryptedError = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
1828
678
  return encryptedError;
1829
679
  }
1830
680
  const isPlaintext = typeof request.params !== "string";
1831
- const decryptedParams = isPlaintext ? request.params : decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(request.params));
681
+ const decryptedParams = isPlaintext ? request.params : logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(request.params));
1832
682
  this.logger("[RPC] Calling handler", { method: request.method });
1833
683
  const result = await handler(decryptedParams);
1834
684
  this.logger("[RPC] Handler returned", { method: request.method, hasResult: result !== void 0 });
@@ -1839,7 +689,7 @@ class RpcHandlerManager {
1839
689
  this.logger("[RPC] Handler returned pre-encrypted response", { method: request.method });
1840
690
  return result.data;
1841
691
  }
1842
- const encryptedResponse = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, result));
692
+ const encryptedResponse = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, result));
1843
693
  this.logger("[RPC] Sending encrypted response", { method: request.method, responseLength: encryptedResponse.length });
1844
694
  return encryptedResponse;
1845
695
  } catch (error) {
@@ -1850,7 +700,7 @@ class RpcHandlerManager {
1850
700
  if (typeof request.params !== "string") {
1851
701
  return errorResponse;
1852
702
  }
1853
- return encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
703
+ return logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, errorResponse));
1854
704
  }
1855
705
  }
1856
706
  onSocketConnect(socket) {
@@ -2500,14 +1350,8 @@ No git repository was found from session cwd or workspace repo metadata. Session
2500
1350
  };
2501
1351
  }
2502
1352
 
2503
- const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-DvTsFaqR.cjs', document.baseURI).href))));
2504
- function projectPath() {
2505
- const path = path$1.resolve(__dirname$1, "..");
2506
- return path;
2507
- }
2508
-
2509
1353
  function run$1(args, options) {
2510
- const RUNNER_PATH = path$1.resolve(path$1.join(projectPath(), "scripts", "ripgrep_launcher.cjs"));
1354
+ const RUNNER_PATH = path$1.resolve(path$1.join(projectPath.projectPath(), "scripts", "ripgrep_launcher.cjs"));
2511
1355
  return new Promise((resolve2, reject) => {
2512
1356
  const child = child_process.spawn("node", [RUNNER_PATH, JSON.stringify(args)], {
2513
1357
  stdio: ["pipe", "pipe", "pipe"],
@@ -2541,7 +1385,7 @@ function toolsPackageName() {
2541
1385
  return `@zonease/happy-tools-${toolsPlatform()}`;
2542
1386
  }
2543
1387
  function legacyToolsDir() {
2544
- return path.resolve(projectPath(), "tools", "unpacked");
1388
+ return path.resolve(projectPath.projectPath(), "tools", "unpacked");
2545
1389
  }
2546
1390
  let cached$1;
2547
1391
  function resolveToolsDir() {
@@ -2551,7 +1395,7 @@ function resolveToolsDir() {
2551
1395
  }
2552
1396
  function findToolsDir() {
2553
1397
  try {
2554
- const manifest = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-DvTsFaqR.cjs', document.baseURI).href))).resolve(`${toolsPackageName()}/package.json`);
1398
+ const manifest = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('api-CwOCQeLH.cjs', document.baseURI).href))).resolve(`${toolsPackageName()}/package.json`);
2555
1399
  return path.dirname(manifest);
2556
1400
  } catch {
2557
1401
  }
@@ -2625,10 +1469,10 @@ function ensureSpawnHelperExecutable() {
2625
1469
  for (const candidate of candidates) {
2626
1470
  if (!fs.existsSync(candidate) || (fs.statSync(candidate).mode & 73) !== 0) continue;
2627
1471
  fs.chmodSync(candidate, 493);
2628
- logger.debug(`[pty] restored exec bit on ${candidate}`);
1472
+ logger.logger.debug(`[pty] restored exec bit on ${candidate}`);
2629
1473
  }
2630
1474
  } catch (err) {
2631
- logger.debug("[pty] could not check spawn-helper permissions:", err);
1475
+ logger.logger.debug("[pty] could not check spawn-helper permissions:", err);
2632
1476
  }
2633
1477
  }
2634
1478
  function loadNodePty() {
@@ -2643,7 +1487,7 @@ function loadNodePty() {
2643
1487
  return mod;
2644
1488
  } catch (err) {
2645
1489
  loadError = err instanceof Error ? err : new Error(String(err));
2646
- logger.debug("[pty] node-pty unavailable:", loadError.message);
1490
+ logger.logger.debug("[pty] node-pty unavailable:", loadError.message);
2647
1491
  return null;
2648
1492
  }
2649
1493
  }
@@ -2701,7 +1545,7 @@ function spawnShell(opts) {
2701
1545
  if (!mod) {
2702
1546
  const err = new Error(PTY_UNAVAILABLE);
2703
1547
  if (loadError) {
2704
- logger.debug("[pty] underlying load error:", loadError.stack ?? loadError.message);
1548
+ logger.logger.debug("[pty] underlying load error:", loadError.stack ?? loadError.message);
2705
1549
  }
2706
1550
  throw err;
2707
1551
  }
@@ -2736,7 +1580,7 @@ function spawnShell(opts) {
2736
1580
  });
2737
1581
  const ptyId = node_crypto.randomUUID();
2738
1582
  ptys.set(ptyId, term);
2739
- logger.debug(`[pty] spawned ${ptyId} pid=${term.pid} shell=${shell} cols=${opts.cols} rows=${opts.rows} cwd=${cwd}`);
1583
+ logger.logger.debug(`[pty] spawned ${ptyId} pid=${term.pid} shell=${shell} cols=${opts.cols} rows=${opts.rows} cwd=${cwd}`);
2740
1584
  return { ptyId, term };
2741
1585
  }
2742
1586
  function resizePty(ptyId, cols, rows) {
@@ -2746,7 +1590,7 @@ function resizePty(ptyId, cols, rows) {
2746
1590
  term.resize(cols, rows);
2747
1591
  return true;
2748
1592
  } catch (err) {
2749
- logger.debug(`[pty] resize ${ptyId} failed:`, err);
1593
+ logger.logger.debug(`[pty] resize ${ptyId} failed:`, err);
2750
1594
  return false;
2751
1595
  }
2752
1596
  }
@@ -2757,7 +1601,7 @@ function writeToPty(ptyId, data) {
2757
1601
  term.write(data);
2758
1602
  return true;
2759
1603
  } catch (err) {
2760
- logger.debug(`[pty] write ${ptyId} failed:`, err);
1604
+ logger.logger.debug(`[pty] write ${ptyId} failed:`, err);
2761
1605
  return false;
2762
1606
  }
2763
1607
  }
@@ -2768,7 +1612,7 @@ function closePty(ptyId) {
2768
1612
  try {
2769
1613
  term.kill();
2770
1614
  } catch (err) {
2771
- logger.debug(`[pty] kill ${ptyId} failed (likely already exited):`, err);
1615
+ logger.logger.debug(`[pty] kill ${ptyId} failed (likely already exited):`, err);
2772
1616
  }
2773
1617
  return true;
2774
1618
  }
@@ -2801,7 +1645,7 @@ function runLoginShell(shell) {
2801
1645
  (error, stdout) => {
2802
1646
  const parsed = parseEnvDump(stdout ?? "");
2803
1647
  if (!parsed && error) {
2804
- logger.debug("[shellEnv] login shell did not return an environment:", error.message);
1648
+ logger.logger.debug("[shellEnv] login shell did not return an environment:", error.message);
2805
1649
  }
2806
1650
  resolve(parsed);
2807
1651
  }
@@ -2822,7 +1666,7 @@ function resolveLoginShellEnv() {
2822
1666
  if (!shell) return process.env;
2823
1667
  const resolved = await runLoginShell(shell);
2824
1668
  if (!resolved) return process.env;
2825
- logger.debug(`[shellEnv] resolved ${Object.keys(resolved).length} variables from ${shell}`);
1669
+ logger.logger.debug(`[shellEnv] resolved ${Object.keys(resolved).length} variables from ${shell}`);
2826
1670
  return { ...resolved, ...daemonOwnedEnv() };
2827
1671
  })();
2828
1672
  return cached;
@@ -2871,7 +1715,7 @@ const PTY_OUTPUT_FLUSH_MS = 16;
2871
1715
  const PTY_OUTPUT_FLUSH_BYTES = 32 * 1024;
2872
1716
  function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId) {
2873
1717
  rpcHandlerManager.registerHandler("bash", async (data) => {
2874
- logger.debug("Shell command request:", data.command);
1718
+ logger.logger.debug("Shell command request:", data.command);
2875
1719
  if (data.cwd && data.cwd !== "/") {
2876
1720
  const validation = validatePath(data.cwd, workingDirectory);
2877
1721
  if (!validation.valid) {
@@ -2888,16 +1732,16 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2888
1732
  // fails here with "command not found".
2889
1733
  env: await resolveLoginShellEnv()
2890
1734
  };
2891
- logger.debug("Shell command executing...", { cwd: options.cwd, timeout: options.timeout });
1735
+ logger.logger.debug("Shell command executing...", { cwd: options.cwd, timeout: options.timeout });
2892
1736
  const { stdout, stderr } = await execAsync(data.command, options);
2893
- logger.debug("Shell command executed, processing result...");
1737
+ logger.logger.debug("Shell command executed, processing result...");
2894
1738
  const result = {
2895
1739
  success: true,
2896
1740
  stdout: stdout ? stdout.toString() : "",
2897
1741
  stderr: stderr ? stderr.toString() : "",
2898
1742
  exitCode: 0
2899
1743
  };
2900
- logger.debug("Shell command result:", {
1744
+ logger.logger.debug("Shell command result:", {
2901
1745
  success: true,
2902
1746
  exitCode: 0,
2903
1747
  stdoutLen: result.stdout.length,
@@ -2914,7 +1758,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2914
1758
  exitCode: typeof execError.code === "number" ? execError.code : -1,
2915
1759
  error: "Command timed out"
2916
1760
  };
2917
- logger.debug("Shell command timed out:", {
1761
+ logger.logger.debug("Shell command timed out:", {
2918
1762
  success: false,
2919
1763
  exitCode: result2.exitCode,
2920
1764
  error: "Command timed out"
@@ -2928,7 +1772,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2928
1772
  exitCode: typeof execError.code === "number" ? execError.code : 1,
2929
1773
  error: execError.message || "Command failed"
2930
1774
  };
2931
- logger.debug("Shell command failed:", {
1775
+ logger.logger.debug("Shell command failed:", {
2932
1776
  success: false,
2933
1777
  exitCode: result.exitCode,
2934
1778
  error: result.error,
@@ -2939,40 +1783,40 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
2939
1783
  }
2940
1784
  });
2941
1785
  rpcHandlerManager.registerHandler("readFile", async (data) => {
2942
- logger.debug("Read file request:", data.path);
1786
+ logger.logger.debug("Read file request:", data.path);
2943
1787
  const validation = validatePath(data.path, workingDirectory);
2944
1788
  if (!validation.valid) {
2945
1789
  return { success: false, error: validation.error };
2946
1790
  }
2947
1791
  try {
2948
- const buffer = await fs$2.readFile(data.path);
1792
+ const buffer = await fs$1.readFile(data.path);
2949
1793
  const content = buffer.toString("base64");
2950
1794
  return { success: true, content };
2951
1795
  } catch (error) {
2952
- logger.debug("Failed to read file:", error);
1796
+ logger.logger.debug("Failed to read file:", error);
2953
1797
  return { success: false, error: error instanceof Error ? error.message : "Failed to read file" };
2954
1798
  }
2955
1799
  });
2956
1800
  rpcHandlerManager.registerHandler("writeFile", async (data) => {
2957
- logger.debug("Write file request:", data.path);
1801
+ logger.logger.debug("Write file request:", data.path);
2958
1802
  const absPath = path$1.resolve(workingDirectory, data.path);
2959
1803
  const validation = validatePath(data.path, workingDirectory);
2960
1804
  if (!validation.valid) {
2961
- logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, validation.error);
1805
+ logger.logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, validation.error);
2962
1806
  return { success: false, error: validation.error };
2963
1807
  }
2964
1808
  if (!isWritableForSession(absPath)) {
2965
- logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
1809
+ logger.logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
2966
1810
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
2967
1811
  }
2968
1812
  try {
2969
1813
  const buf = Buffer.from(data.content, "base64");
2970
- await fs$2.writeFile(absPath, buf);
2971
- logger.debug("[writeFile] path=%s bytes=%d ok=%s", absPath, buf.length, true);
1814
+ await fs$1.writeFile(absPath, buf);
1815
+ logger.logger.debug("[writeFile] path=%s bytes=%d ok=%s", absPath, buf.length, true);
2972
1816
  return { success: true, bytesWritten: buf.length };
2973
1817
  } catch (error) {
2974
1818
  const message = error instanceof Error ? error.message : "Failed to write file";
2975
- logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, message);
1819
+ logger.logger.debug("[writeFile] path=%s ok=%s reason=%s", absPath, false, message);
2976
1820
  return { success: false, error: message };
2977
1821
  }
2978
1822
  });
@@ -3001,10 +1845,10 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3001
1845
  return { success: false, error: `Path '${paths.absolutePath}' is on the system write deny-list` };
3002
1846
  }
3003
1847
  try {
3004
- await fs$2.mkdir(paths.directory, { recursive: true });
3005
- await fs$2.rm(paths.tempAbsolutePath, { force: true });
3006
- await fs$2.rm(paths.absolutePath, { force: true });
3007
- await fs$2.writeFile(paths.tempAbsolutePath, Buffer.alloc(0));
1848
+ await fs$1.mkdir(paths.directory, { recursive: true });
1849
+ await fs$1.rm(paths.tempAbsolutePath, { force: true });
1850
+ await fs$1.rm(paths.absolutePath, { force: true });
1851
+ await fs$1.writeFile(paths.tempAbsolutePath, Buffer.alloc(0));
3008
1852
  return {
3009
1853
  success: true,
3010
1854
  relativePath: paths.relativePath,
@@ -3033,12 +1877,12 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3033
1877
  }
3034
1878
  try {
3035
1879
  const chunk = Buffer.from(data.chunkBase64, "base64");
3036
- const current = await fs$2.stat(paths.tempAbsolutePath).catch(() => null);
1880
+ const current = await fs$1.stat(paths.tempAbsolutePath).catch(() => null);
3037
1881
  const currentSize = current?.size ?? 0;
3038
1882
  if (currentSize + chunk.length > MAX_SESSION_UPLOAD_FILE_BYTES) {
3039
1883
  return { success: false, error: "File exceeds 100MB limit" };
3040
1884
  }
3041
- await fs$2.appendFile(paths.tempAbsolutePath, chunk);
1885
+ await fs$1.appendFile(paths.tempAbsolutePath, chunk);
3042
1886
  return {
3043
1887
  success: true,
3044
1888
  relativePath: paths.relativePath,
@@ -3074,11 +1918,11 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3074
1918
  return { success: false, error: `Path '${paths.absolutePath}' is on the system write deny-list` };
3075
1919
  }
3076
1920
  try {
3077
- const info = await fs$2.stat(paths.tempAbsolutePath);
1921
+ const info = await fs$1.stat(paths.tempAbsolutePath);
3078
1922
  if (info.size !== data.fileSize) {
3079
1923
  return { success: false, error: `Upload size mismatch: expected ${data.fileSize}, got ${info.size}` };
3080
1924
  }
3081
- await fs$2.rename(paths.tempAbsolutePath, paths.absolutePath);
1925
+ await fs$1.rename(paths.tempAbsolutePath, paths.absolutePath);
3082
1926
  return {
3083
1927
  success: true,
3084
1928
  relativePath: paths.relativePath,
@@ -3096,14 +1940,14 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3096
1940
  uploadId: data.uploadId,
3097
1941
  fileName: data.fileName
3098
1942
  });
3099
- await fs$2.rm(paths.tempAbsolutePath, { force: true });
1943
+ await fs$1.rm(paths.tempAbsolutePath, { force: true });
3100
1944
  return { success: true };
3101
1945
  } catch (error) {
3102
1946
  return { success: false, error: error instanceof Error ? error.message : "Failed to abort upload" };
3103
1947
  }
3104
1948
  });
3105
1949
  rpcHandlerManager.registerHandler("rename", async (data) => {
3106
- logger.debug("Rename request:", data.from, "->", data.to);
1950
+ logger.logger.debug("Rename request:", data.from, "->", data.to);
3107
1951
  const absFrom = path$1.resolve(workingDirectory, data.from);
3108
1952
  const absTo = path$1.resolve(workingDirectory, data.to);
3109
1953
  const fromValidation = validatePath(data.from, workingDirectory);
@@ -3115,68 +1959,68 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3115
1959
  return { success: false, error: toValidation.error };
3116
1960
  }
3117
1961
  if (!isWritableForSession(absFrom)) {
3118
- logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
1962
+ logger.logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
3119
1963
  return { success: false, error: `Path '${absFrom}' is on the system write deny-list` };
3120
1964
  }
3121
1965
  if (!isWritableForSession(absTo)) {
3122
- logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
1966
+ logger.logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
3123
1967
  return { success: false, error: `Path '${absTo}' is on the system write deny-list` };
3124
1968
  }
3125
1969
  try {
3126
- await fs$2.rename(absFrom, absTo);
3127
- logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, true);
1970
+ await fs$1.rename(absFrom, absTo);
1971
+ logger.logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, true);
3128
1972
  return { success: true };
3129
1973
  } catch (error) {
3130
1974
  const message = error instanceof Error ? error.message : "Failed to rename";
3131
- logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
1975
+ logger.logger.info("[rename] %s -> %s ok=%s", absFrom, absTo, false);
3132
1976
  return { success: false, error: message };
3133
1977
  }
3134
1978
  });
3135
1979
  rpcHandlerManager.registerHandler("deleteFile", async (data) => {
3136
- logger.debug("Delete file request:", data.path);
1980
+ logger.logger.debug("Delete file request:", data.path);
3137
1981
  const absPath = path$1.resolve(workingDirectory, data.path);
3138
1982
  const validation = validatePath(data.path, workingDirectory);
3139
1983
  if (!validation.valid) {
3140
1984
  return { success: false, error: validation.error };
3141
1985
  }
3142
1986
  if (!isWritableForSession(absPath)) {
3143
- logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
1987
+ logger.logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
3144
1988
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
3145
1989
  }
3146
1990
  try {
3147
- const st = await fs$2.lstat(absPath);
1991
+ const st = await fs$1.lstat(absPath);
3148
1992
  if (st.isDirectory()) {
3149
- logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, "is directory");
1993
+ logger.logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, "is directory");
3150
1994
  return { success: false, error: "Not a file, use deleteDirectory" };
3151
1995
  }
3152
- await fs$2.unlink(absPath);
3153
- logger.info("[deleteFile] path=%s ok=%s", absPath, true);
1996
+ await fs$1.unlink(absPath);
1997
+ logger.logger.info("[deleteFile] path=%s ok=%s", absPath, true);
3154
1998
  return { success: true };
3155
1999
  } catch (error) {
3156
2000
  const message = error instanceof Error ? error.message : "Failed to delete file";
3157
- logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, message);
2001
+ logger.logger.info("[deleteFile] path=%s ok=%s reason=%s", absPath, false, message);
3158
2002
  return { success: false, error: message };
3159
2003
  }
3160
2004
  });
3161
2005
  rpcHandlerManager.registerHandler("deleteDirectory", async (data) => {
3162
- logger.debug("Delete directory request:", data.path);
2006
+ logger.logger.debug("Delete directory request:", data.path);
3163
2007
  const absPath = path$1.resolve(workingDirectory, data.path);
3164
2008
  const validation = validatePath(data.path, workingDirectory);
3165
2009
  if (!validation.valid) {
3166
2010
  return { success: false, error: validation.error };
3167
2011
  }
3168
2012
  if (!isWritableForSession(absPath)) {
3169
- logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
2013
+ logger.logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
3170
2014
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
3171
2015
  }
3172
2016
  try {
3173
- const top = await fs$2.lstat(absPath);
2017
+ const top = await fs$1.lstat(absPath);
3174
2018
  if (!top.isDirectory()) {
3175
- logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, "not a directory");
2019
+ logger.logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, "not a directory");
3176
2020
  return { success: false, error: "Not a directory" };
3177
2021
  }
3178
2022
  async function countEntries(dir) {
3179
- const entries = await fs$2.readdir(dir, { withFileTypes: true });
2023
+ const entries = await fs$1.readdir(dir, { withFileTypes: true });
3180
2024
  let n = 0;
3181
2025
  for (const entry of entries) {
3182
2026
  n += 1;
@@ -3187,70 +2031,70 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3187
2031
  return n;
3188
2032
  }
3189
2033
  const deletedCount = await countEntries(absPath);
3190
- await fs$2.rm(absPath, { recursive: true, force: false });
3191
- logger.info("[deleteDirectory] path=%s deletedCount=%d ok=%s", absPath, deletedCount, true);
2034
+ await fs$1.rm(absPath, { recursive: true, force: false });
2035
+ logger.logger.info("[deleteDirectory] path=%s deletedCount=%d ok=%s", absPath, deletedCount, true);
3192
2036
  return { success: true, deletedCount };
3193
2037
  } catch (error) {
3194
2038
  const message = error instanceof Error ? error.message : "Failed to delete directory";
3195
- logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, message);
2039
+ logger.logger.info("[deleteDirectory] path=%s ok=%s reason=%s", absPath, false, message);
3196
2040
  return { success: false, error: message };
3197
2041
  }
3198
2042
  });
3199
2043
  rpcHandlerManager.registerHandler("createFile", async (data) => {
3200
- logger.debug("Create file request:", data.path);
2044
+ logger.logger.debug("Create file request:", data.path);
3201
2045
  const absPath = path$1.resolve(workingDirectory, data.path);
3202
2046
  const validation = validatePath(data.path, workingDirectory);
3203
2047
  if (!validation.valid) {
3204
2048
  return { success: false, error: validation.error };
3205
2049
  }
3206
2050
  if (!isWritableForSession(absPath)) {
3207
- logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
2051
+ logger.logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
3208
2052
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
3209
2053
  }
3210
2054
  try {
3211
2055
  const buf = data.content ? Buffer.from(data.content, "base64") : Buffer.alloc(0);
3212
- await fs$2.writeFile(absPath, buf, { flag: "wx" });
3213
- logger.info("[createFile] path=%s bytes=%d ok=%s", absPath, buf.length, true);
2056
+ await fs$1.writeFile(absPath, buf, { flag: "wx" });
2057
+ logger.logger.info("[createFile] path=%s bytes=%d ok=%s", absPath, buf.length, true);
3214
2058
  return { success: true };
3215
2059
  } catch (error) {
3216
2060
  const errno = error.code;
3217
2061
  if (errno === "EEXIST") {
3218
- logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, "file exists");
2062
+ logger.logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, "file exists");
3219
2063
  return { success: false, error: "File exists" };
3220
2064
  }
3221
2065
  const message = error instanceof Error ? error.message : "Failed to create file";
3222
- logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, message);
2066
+ logger.logger.info("[createFile] path=%s ok=%s reason=%s", absPath, false, message);
3223
2067
  return { success: false, error: message };
3224
2068
  }
3225
2069
  });
3226
2070
  rpcHandlerManager.registerHandler("createDirectory", async (data) => {
3227
- logger.debug("Create directory request:", data.path);
2071
+ logger.logger.debug("Create directory request:", data.path);
3228
2072
  const absPath = path$1.resolve(workingDirectory, data.path);
3229
2073
  const validation = validatePath(data.path, workingDirectory);
3230
2074
  if (!validation.valid) {
3231
2075
  return { success: false, error: validation.error };
3232
2076
  }
3233
2077
  if (!isWritableForSession(absPath)) {
3234
- logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
2078
+ logger.logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, "system path is read-only");
3235
2079
  return { success: false, error: `Path '${absPath}' is on the system write deny-list` };
3236
2080
  }
3237
2081
  try {
3238
- await fs$2.mkdir(absPath);
3239
- logger.info("[createDirectory] path=%s ok=%s", absPath, true);
2082
+ await fs$1.mkdir(absPath);
2083
+ logger.logger.info("[createDirectory] path=%s ok=%s", absPath, true);
3240
2084
  return { success: true };
3241
2085
  } catch (error) {
3242
2086
  const errno = error.code;
3243
2087
  if (errno === "EEXIST") {
3244
- logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, "directory exists");
2088
+ logger.logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, "directory exists");
3245
2089
  return { success: false, error: "Directory exists" };
3246
2090
  }
3247
2091
  const message = error instanceof Error ? error.message : "Failed to create directory";
3248
- logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, message);
2092
+ logger.logger.info("[createDirectory] path=%s ok=%s reason=%s", absPath, false, message);
3249
2093
  return { success: false, error: message };
3250
2094
  }
3251
2095
  });
3252
2096
  rpcHandlerManager.registerHandler("listDirectory", async (data) => {
3253
- logger.debug("List directory request:", data.path);
2097
+ logger.logger.debug("List directory request:", data.path);
3254
2098
  const absPath = path$1.resolve(workingDirectory, data.path);
3255
2099
  const validation = validatePath(data.path, workingDirectory);
3256
2100
  if (!validation.valid) {
@@ -3258,7 +2102,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3258
2102
  }
3259
2103
  const hideSystem = data.hideSystem !== false;
3260
2104
  try {
3261
- const rawEntries = await fs$2.readdir(absPath, { withFileTypes: true });
2105
+ const rawEntries = await fs$1.readdir(absPath, { withFileTypes: true });
3262
2106
  const noSymlinks = rawEntries.filter((e) => !e.isSymbolicLink());
3263
2107
  const visible = hideSystem ? noSymlinks.filter((e) => !isSystemNoise(e.name)) : noSymlinks;
3264
2108
  const entries = await Promise.all(
@@ -3268,11 +2112,11 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3268
2112
  let size;
3269
2113
  let mtime;
3270
2114
  try {
3271
- const stats = await fs$2.stat(fullPath);
2115
+ const stats = await fs$1.stat(fullPath);
3272
2116
  size = stats.size;
3273
2117
  mtime = stats.mtime.getTime();
3274
2118
  } catch (error) {
3275
- logger.debug(`Failed to stat ${fullPath}:`, error);
2119
+ logger.logger.debug(`Failed to stat ${fullPath}:`, error);
3276
2120
  }
3277
2121
  return { name: entry.name, path: fullPath, type, size, mtime };
3278
2122
  })
@@ -3284,19 +2128,19 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3284
2128
  });
3285
2129
  return { success: true, entries };
3286
2130
  } catch (error) {
3287
- logger.debug("Failed to list directory:", error);
2131
+ logger.logger.debug("Failed to list directory:", error);
3288
2132
  return { success: false, error: error instanceof Error ? error.message : "Failed to list directory" };
3289
2133
  }
3290
2134
  });
3291
2135
  rpcHandlerManager.registerHandler("getDirectoryTree", async (data) => {
3292
- logger.debug("Get directory tree request:", data.path, "maxDepth:", data.maxDepth);
2136
+ logger.logger.debug("Get directory tree request:", data.path, "maxDepth:", data.maxDepth);
3293
2137
  const validation = validatePath(data.path, workingDirectory);
3294
2138
  if (!validation.valid) {
3295
2139
  return { success: false, error: validation.error };
3296
2140
  }
3297
2141
  async function buildTree(path, name, currentDepth) {
3298
2142
  try {
3299
- const stats = await fs$2.stat(path);
2143
+ const stats = await fs$1.stat(path);
3300
2144
  const node = {
3301
2145
  name,
3302
2146
  path,
@@ -3305,12 +2149,12 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3305
2149
  modified: stats.mtime.getTime()
3306
2150
  };
3307
2151
  if (stats.isDirectory() && currentDepth < data.maxDepth) {
3308
- const entries = await fs$2.readdir(path, { withFileTypes: true });
2152
+ const entries = await fs$1.readdir(path, { withFileTypes: true });
3309
2153
  const children = [];
3310
2154
  await Promise.all(
3311
2155
  entries.map(async (entry) => {
3312
2156
  if (entry.isSymbolicLink()) {
3313
- logger.debug(`Skipping symlink: ${path$1.join(path, entry.name)}`);
2157
+ logger.logger.debug(`Skipping symlink: ${path$1.join(path, entry.name)}`);
3314
2158
  return;
3315
2159
  }
3316
2160
  const childPath = path$1.join(path, entry.name);
@@ -3329,7 +2173,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3329
2173
  }
3330
2174
  return node;
3331
2175
  } catch (error) {
3332
- logger.debug(`Failed to process ${path}:`, error instanceof Error ? error.message : String(error));
2176
+ logger.logger.debug(`Failed to process ${path}:`, error instanceof Error ? error.message : String(error));
3333
2177
  return null;
3334
2178
  }
3335
2179
  }
@@ -3344,12 +2188,12 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3344
2188
  }
3345
2189
  return { success: true, tree };
3346
2190
  } catch (error) {
3347
- logger.debug("Failed to get directory tree:", error);
2191
+ logger.logger.debug("Failed to get directory tree:", error);
3348
2192
  return { success: false, error: error instanceof Error ? error.message : "Failed to get directory tree" };
3349
2193
  }
3350
2194
  });
3351
2195
  rpcHandlerManager.registerHandler("ripgrep", async (data) => {
3352
- logger.debug("Ripgrep request with args:", data.args, "cwd:", data.cwd);
2196
+ logger.logger.debug("Ripgrep request with args:", data.args, "cwd:", data.cwd);
3353
2197
  if (data.cwd) {
3354
2198
  const validation = validatePath(data.cwd, workingDirectory);
3355
2199
  if (!validation.valid) {
@@ -3365,7 +2209,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3365
2209
  stderr: result.stderr.toString()
3366
2210
  };
3367
2211
  } catch (error) {
3368
- logger.debug("Failed to run ripgrep:", error);
2212
+ logger.logger.debug("Failed to run ripgrep:", error);
3369
2213
  return {
3370
2214
  success: false,
3371
2215
  error: error instanceof Error ? error.message : "Failed to run ripgrep"
@@ -3373,7 +2217,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3373
2217
  }
3374
2218
  });
3375
2219
  rpcHandlerManager.registerHandler("difftastic", async (data) => {
3376
- logger.debug("Difftastic request with args:", data.args, "cwd:", data.cwd);
2220
+ logger.logger.debug("Difftastic request with args:", data.args, "cwd:", data.cwd);
3377
2221
  if (data.cwd) {
3378
2222
  const validation = validatePath(data.cwd, workingDirectory);
3379
2223
  if (!validation.valid) {
@@ -3389,7 +2233,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3389
2233
  stderr: result.stderr.toString()
3390
2234
  };
3391
2235
  } catch (error) {
3392
- logger.debug("Failed to run difftastic:", error);
2236
+ logger.logger.debug("Failed to run difftastic:", error);
3393
2237
  return {
3394
2238
  success: false,
3395
2239
  error: error instanceof Error ? error.message : "Failed to run difftastic"
@@ -3398,7 +2242,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3398
2242
  });
3399
2243
  if (sessionId) {
3400
2244
  rpcHandlerManager.registerHandler("getDiffDetail", async (data) => {
3401
- logger.debug("getDiffDetail request:", data.callId, data.filePath);
2245
+ logger.logger.debug("getDiffDetail request:", data.callId, data.filePath);
3402
2246
  const result = getDiffDetail(sessionId, data.callId, data.filePath);
3403
2247
  if (!result) {
3404
2248
  return { success: false, error: "not_found" };
@@ -3411,7 +2255,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3411
2255
  };
3412
2256
  });
3413
2257
  rpcHandlerManager.registerHandler("getToolOutput", async (data) => {
3414
- logger.debug("getToolOutput request:", data.callId);
2258
+ logger.logger.debug("getToolOutput request:", data.callId);
3415
2259
  const record = getToolOutputRecord(sessionId, data.callId);
3416
2260
  if (!record) {
3417
2261
  return { success: false, error: "not_found" };
@@ -3433,7 +2277,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3433
2277
  if (event === "pty-output" && typeof payload.data === "string") {
3434
2278
  const key = rpcHandlerManager.getEncryptionKey();
3435
2279
  const variant = rpcHandlerManager.getEncryptionVariant();
3436
- envelope.data = encodeBase64(encrypt(key, variant, payload.data));
2280
+ envelope.data = logger.encodeBase64(logger.encrypt(key, variant, payload.data));
3437
2281
  } else if (event === "pty-exit" && typeof payload.exitCode === "number") {
3438
2282
  envelope.exitCode = payload.exitCode;
3439
2283
  }
@@ -3493,7 +2337,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3493
2337
  outboundStates.delete(ptyId);
3494
2338
  };
3495
2339
  rpcHandlerManager.registerHandler("pty-start", async (data) => {
3496
- logger.debug("[pty-start] request", { cols: data.cols, rows: data.rows, cwd: data.cwd });
2340
+ logger.logger.debug("[pty-start] request", { cols: data.cols, rows: data.rows, cwd: data.cwd });
3497
2341
  try {
3498
2342
  const { ptyId, term } = spawnShell({
3499
2343
  cols: data.cols,
@@ -3515,7 +2359,7 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3515
2359
  }
3516
2360
  });
3517
2361
  const exitDispose = term.onExit(({ exitCode }) => {
3518
- logger.debug(`[pty-exit] ${ptyId} exitCode=${exitCode}`);
2362
+ logger.logger.debug(`[pty-exit] ${ptyId} exitCode=${exitCode}`);
3519
2363
  flushPtyOutput(ptyId);
3520
2364
  emitEncrypted("pty-exit", { sessionId, ptyId, exitCode });
3521
2365
  cleanupPtyState(ptyId);
@@ -3532,27 +2376,27 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3532
2376
  } catch (err) {
3533
2377
  const message = err instanceof Error ? err.message : String(err);
3534
2378
  if (message === PTY_UNAVAILABLE) {
3535
- logger.debug("[pty-start] node-pty unavailable on this host");
2379
+ logger.logger.debug("[pty-start] node-pty unavailable on this host");
3536
2380
  return { ok: false, error: PTY_UNAVAILABLE };
3537
2381
  }
3538
- logger.debug("[pty-start] spawn failed:", message);
2382
+ logger.logger.debug("[pty-start] spawn failed:", message);
3539
2383
  return { ok: false, error: message };
3540
2384
  }
3541
2385
  });
3542
2386
  rpcHandlerManager.registerHandler("pty-resize", async (data) => {
3543
- logger.debug(`[pty-resize] ${data.ptyId} ${data.cols}x${data.rows}`);
2387
+ logger.logger.debug(`[pty-resize] ${data.ptyId} ${data.cols}x${data.rows}`);
3544
2388
  const ok = resizePty(data.ptyId, data.cols, data.rows);
3545
2389
  return { ok };
3546
2390
  });
3547
2391
  rpcHandlerManager.registerHandler("pty-close", async (data) => {
3548
- logger.debug(`[pty-close] ${data.ptyId}`);
2392
+ logger.logger.debug(`[pty-close] ${data.ptyId}`);
3549
2393
  cleanupPtyState(data.ptyId);
3550
2394
  const ok = closePty(data.ptyId);
3551
2395
  return { ok };
3552
2396
  });
3553
2397
  rpcHandlerManager.registerSocketEvent("pty-input", (envelope) => {
3554
2398
  if (!envelope || typeof envelope !== "object") {
3555
- logger.debug("[pty-input] unexpected envelope shape, dropping");
2399
+ logger.logger.debug("[pty-input] unexpected envelope shape, dropping");
3556
2400
  return;
3557
2401
  }
3558
2402
  if (envelope.sessionId !== sessionId) return;
@@ -3561,14 +2405,14 @@ function registerCommonHandlers(rpcHandlerManager, workingDirectory, sessionId)
3561
2405
  try {
3562
2406
  const key = rpcHandlerManager.getEncryptionKey();
3563
2407
  const variant = rpcHandlerManager.getEncryptionVariant();
3564
- const decoded = decrypt(key, variant, decodeBase64(envelope.data));
2408
+ const decoded = logger.decrypt(key, variant, logger.decodeBase64(envelope.data));
3565
2409
  if (typeof decoded !== "string") {
3566
- logger.debug("[pty-input] decrypted payload not a string, dropping");
2410
+ logger.logger.debug("[pty-input] decrypted payload not a string, dropping");
3567
2411
  return;
3568
2412
  }
3569
2413
  writeToPty(envelope.ptyId, decoded);
3570
2414
  } catch (err) {
3571
- logger.debug("[pty-input] decrypt/dispatch failed:", err);
2415
+ logger.logger.debug("[pty-input] decrypt/dispatch failed:", err);
3572
2416
  }
3573
2417
  });
3574
2418
  }
@@ -3836,7 +2680,7 @@ class ApiSessionClient extends node_events.EventEmitter {
3836
2680
  initialTitleSet = false;
3837
2681
  queueOrDeliverUserMessage(message, source) {
3838
2682
  if (isHumanOnlyMessageRecord(message)) {
3839
- logger.debug(`[API] Ignoring human-only collaboration message from ${source}`);
2683
+ logger.logger.debug(`[API] Ignoring human-only collaboration message from ${source}`);
3840
2684
  return false;
3841
2685
  }
3842
2686
  if (this.pendingMessageCallback) {
@@ -3861,7 +2705,7 @@ class ApiSessionClient extends node_events.EventEmitter {
3861
2705
  scopePrefix: this.sessionId,
3862
2706
  encryptionKey: this.encryptionKey,
3863
2707
  encryptionVariant: this.encryptionVariant,
3864
- logger: (msg, data) => logger.debug(msg, data)
2708
+ logger: (msg, data) => logger.logger.debug(msg, data)
3865
2709
  });
3866
2710
  registerCommonHandlers(this.rpcHandlerManager, this.metadata.path, this.sessionId);
3867
2711
  this.autoReviewGuard = this.createAutoReviewGuard();
@@ -3878,7 +2722,7 @@ class ApiSessionClient extends node_events.EventEmitter {
3878
2722
  }
3879
2723
  });
3880
2724
  this.sendSync = new InvalidateSync(() => this.flushOutbox());
3881
- this.socket = socket_ioClient.io(configuration.serverUrl, {
2725
+ this.socket = socket_ioClient.io(logger.configuration.serverUrl, {
3882
2726
  auth: {
3883
2727
  token: this.token,
3884
2728
  clientType: "session-scoped",
@@ -3895,18 +2739,18 @@ class ApiSessionClient extends node_events.EventEmitter {
3895
2739
  autoConnect: false
3896
2740
  });
3897
2741
  this.socket.on("connect", () => {
3898
- logger.debug("Socket connected successfully");
2742
+ logger.logger.debug("Socket connected successfully");
3899
2743
  this.rpcHandlerManager.onSocketConnect(this.socket);
3900
2744
  });
3901
2745
  this.socket.on("rpc-request", async (data, callback) => {
3902
2746
  callback(await this.rpcHandlerManager.handleRequest(data));
3903
2747
  });
3904
2748
  this.socket.on("disconnect", (reason) => {
3905
- logger.debug("[API] Socket disconnected:", reason);
2749
+ logger.logger.debug("[API] Socket disconnected:", reason);
3906
2750
  this.rpcHandlerManager.onSocketDisconnect();
3907
2751
  });
3908
2752
  this.socket.on("connect_error", (error) => {
3909
- logger.debug("[API] Socket connection error:", error);
2753
+ logger.logger.debug("[API] Socket connection error:", error);
3910
2754
  this.rpcHandlerManager.onSocketDisconnect();
3911
2755
  });
3912
2756
  this.socket.on("ephemeral", (payload) => {
@@ -3939,20 +2783,20 @@ class ApiSessionClient extends node_events.EventEmitter {
3939
2783
  });
3940
2784
  };
3941
2785
  try {
3942
- logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", data);
2786
+ logger.logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", data);
3943
2787
  if (!data.body) {
3944
- logger.debug("[SOCKET] [UPDATE] [ERROR] No body in update!");
2788
+ logger.logger.debug("[SOCKET] [UPDATE] [ERROR] No body in update!");
3945
2789
  return;
3946
2790
  }
3947
2791
  if (data.body.t === "new-message" && data.body.message.content.t === "encrypted") {
3948
- const body = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.message.content.c));
3949
- logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
2792
+ const body = logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(data.body.message.content.c));
2793
+ logger.logger.debugLargeJson("[SOCKET] [UPDATE] Received update:", body);
3950
2794
  const userResult = UserMessageSchema.safeParse(body);
3951
2795
  if (userResult.success) {
3952
2796
  if (isHumanOnlyMessageRecord(body)) {
3953
- logger.debug("[SOCKET] [UPDATE] Ignoring human-only collaboration message");
2797
+ logger.logger.debug("[SOCKET] [UPDATE] Ignoring human-only collaboration message");
3954
2798
  } else if (userResult.data.meta?.sentFrom === "cli") {
3955
- logger.debug("[SOCKET] [UPDATE] Ignoring echo of CLI-originated user message");
2799
+ logger.logger.debug("[SOCKET] [UPDATE] Ignoring echo of CLI-originated user message");
3956
2800
  } else {
3957
2801
  this.maybeSetInitialTitleFromUserText(userResult.data.content.text);
3958
2802
  if (this.queueOrDeliverUserMessage(userResult.data, "socket-update")) {
@@ -3971,22 +2815,22 @@ class ApiSessionClient extends node_events.EventEmitter {
3971
2815
  if (data.body.metadata && data.body.metadata.version > this.metadataVersion) {
3972
2816
  this.metadata = adoptServerSessionMetadata(
3973
2817
  this.metadata,
3974
- decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.metadata.value))
2818
+ logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(data.body.metadata.value))
3975
2819
  );
3976
2820
  this.metadataVersion = data.body.metadata.version;
3977
2821
  this.syncedModel = this.metadata?.model?.trim() || null;
3978
2822
  }
3979
2823
  if (data.body.agentState && data.body.agentState.version > this.agentStateVersion) {
3980
- this.agentState = data.body.agentState.value ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(data.body.agentState.value)) : null;
2824
+ this.agentState = data.body.agentState.value ? logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(data.body.agentState.value)) : null;
3981
2825
  this.agentStateVersion = data.body.agentState.version;
3982
2826
  }
3983
2827
  } else if (data.body.t === "update-machine") {
3984
- logger.debug(`[SOCKET] WARNING: Session client received unexpected machine update - ignoring`);
2828
+ logger.logger.debug(`[SOCKET] WARNING: Session client received unexpected machine update - ignoring`);
3985
2829
  } else {
3986
2830
  this.emit("message", data.body);
3987
2831
  }
3988
2832
  } catch (error) {
3989
- logger.debug("[SOCKET] [UPDATE] [ERROR] Error handling update", { error });
2833
+ logger.logger.debug("[SOCKET] [UPDATE] [ERROR] Error handling update", { error });
3990
2834
  if (data?.body?.t === "new-message") {
3991
2835
  const errorMessage = error instanceof Error ? error.message : String(error);
3992
2836
  emitMessageReceipt({
@@ -4000,7 +2844,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4000
2844
  }
4001
2845
  });
4002
2846
  this.socket.on("error", (error) => {
4003
- logger.debug("[API] Socket error:", error);
2847
+ logger.logger.debug("[API] Socket error:", error);
4004
2848
  });
4005
2849
  this.socket.connect();
4006
2850
  }
@@ -4015,7 +2859,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4015
2859
  }
4016
2860
  async orchestratorSubmit(body) {
4017
2861
  const response = await axios.post(
4018
- `${configuration.serverUrl}/v1/orchestrator/submit`,
2862
+ `${logger.configuration.serverUrl}/v1/orchestrator/submit`,
4019
2863
  body,
4020
2864
  {
4021
2865
  headers: this.orchestratorHeaders(),
@@ -4026,7 +2870,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4026
2870
  }
4027
2871
  async orchestratorGetContext() {
4028
2872
  const response = await axios.get(
4029
- `${configuration.serverUrl}/v1/orchestrator/context`,
2873
+ `${logger.configuration.serverUrl}/v1/orchestrator/context`,
4030
2874
  {
4031
2875
  headers: this.orchestratorHeaders(),
4032
2876
  timeout: 3e4
@@ -4036,7 +2880,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4036
2880
  }
4037
2881
  async orchestratorGetRun(runId, includeTasks = true) {
4038
2882
  const response = await axios.get(
4039
- `${configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}`,
2883
+ `${logger.configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}`,
4040
2884
  {
4041
2885
  headers: this.orchestratorHeaders(),
4042
2886
  params: { includeTasks },
@@ -4047,7 +2891,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4047
2891
  }
4048
2892
  async orchestratorListRuns(query = {}) {
4049
2893
  const response = await axios.get(
4050
- `${configuration.serverUrl}/v1/orchestrator/runs`,
2894
+ `${logger.configuration.serverUrl}/v1/orchestrator/runs`,
4051
2895
  {
4052
2896
  headers: this.orchestratorHeaders(),
4053
2897
  params: query,
@@ -4058,7 +2902,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4058
2902
  }
4059
2903
  async orchestratorPend(runId, query = {}) {
4060
2904
  const response = await axios.get(
4061
- `${configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}/pend`,
2905
+ `${logger.configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}/pend`,
4062
2906
  {
4063
2907
  headers: this.orchestratorHeaders(),
4064
2908
  params: query,
@@ -4069,7 +2913,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4069
2913
  }
4070
2914
  async orchestratorSendMessage(body) {
4071
2915
  const response = await axios.post(
4072
- `${configuration.serverUrl}/v1/orchestrator/tasks/${encodeURIComponent(body.taskId)}/send-message`,
2916
+ `${logger.configuration.serverUrl}/v1/orchestrator/tasks/${encodeURIComponent(body.taskId)}/send-message`,
4073
2917
  {
4074
2918
  message: body.message
4075
2919
  },
@@ -4082,7 +2926,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4082
2926
  }
4083
2927
  async orchestratorCancel(runId, body) {
4084
2928
  const response = await axios.post(
4085
- `${configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}/cancel`,
2929
+ `${logger.configuration.serverUrl}/v1/orchestrator/runs/${encodeURIComponent(runId)}/cancel`,
4086
2930
  body ?? {},
4087
2931
  {
4088
2932
  headers: this.orchestratorHeaders(),
@@ -4321,7 +3165,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4321
3165
  for (let offset = 0; offset < batch.length; offset += OUTBOX_FLUSH_BATCH_SIZE) {
4322
3166
  const chunk = batch.slice(offset, offset + OUTBOX_FLUSH_BATCH_SIZE);
4323
3167
  await axios.post(
4324
- `${configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/messages`,
3168
+ `${logger.configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/messages`,
4325
3169
  {
4326
3170
  messages: chunk
4327
3171
  },
@@ -4341,7 +3185,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4341
3185
  * This is the parallel reliable path alongside the fast-path socket emit.
4342
3186
  */
4343
3187
  enqueueMessage(content) {
4344
- const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
3188
+ const encrypted = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, content));
4345
3189
  this.pendingOutbox.push({
4346
3190
  content: encrypted,
4347
3191
  localId: node_crypto.randomUUID()
@@ -4358,7 +3202,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4358
3202
  const messages = await this.fetchRecentReviewMessages(80);
4359
3203
  return messages.some((message) => message.role === "user" && normalizeAutoReviewTextForDedupe(message.text) === normalized);
4360
3204
  } catch (error) {
4361
- logger.debug("[AUTO_REVIEW] Failed to check duplicate follow-up messages:", error);
3205
+ logger.logger.debug("[AUTO_REVIEW] Failed to check duplicate follow-up messages:", error);
4362
3206
  return false;
4363
3207
  }
4364
3208
  }
@@ -4380,9 +3224,9 @@ class ApiSessionClient extends node_events.EventEmitter {
4380
3224
  displayText: trimmed
4381
3225
  }
4382
3226
  };
4383
- const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
3227
+ const encrypted = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, content));
4384
3228
  await axios.post(
4385
- `${configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/send`,
3229
+ `${logger.configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/send`,
4386
3230
  {
4387
3231
  content: encrypted,
4388
3232
  localId,
@@ -4399,7 +3243,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4399
3243
  }
4400
3244
  async fetchRecentReviewMessages(limit = 200) {
4401
3245
  const response = await axios.get(
4402
- `${configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/messages`,
3246
+ `${logger.configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/messages`,
4403
3247
  {
4404
3248
  params: { limit },
4405
3249
  headers: { "Authorization": `Bearer ${this.token}` },
@@ -4412,7 +3256,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4412
3256
  const encrypted = row?.content?.t === "encrypted" ? row.content.c : null;
4413
3257
  if (!encrypted) continue;
4414
3258
  try {
4415
- const decrypted = decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(encrypted));
3259
+ const decrypted = logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(encrypted));
4416
3260
  if (isHumanOnlyMessageRecord(decrypted)) {
4417
3261
  continue;
4418
3262
  }
@@ -4420,7 +3264,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4420
3264
  const text = extractPlainTextForAutoReview(decrypted);
4421
3265
  if (text) result.push({ role, text });
4422
3266
  } catch (error) {
4423
- logger.debug("[AUTO_REVIEW] Failed to decrypt review history message:", error);
3267
+ logger.logger.debug("[AUTO_REVIEW] Failed to decrypt review history message:", error);
4424
3268
  }
4425
3269
  }
4426
3270
  return result;
@@ -4431,13 +3275,13 @@ class ApiSessionClient extends node_events.EventEmitter {
4431
3275
  const isSidechain = body.isSidechain === true;
4432
3276
  this.sendUsageData(body.message.usage, isSidechain ? void 0 : body.message.model);
4433
3277
  } catch (error) {
4434
- logger.debug("[SOCKET] Failed to send usage data:", error);
3278
+ logger.logger.debug("[SOCKET] Failed to send usage data:", error);
4435
3279
  }
4436
3280
  }
4437
3281
  if (body.type === "summary" && "summary" in body && "leafUuid" in body) {
4438
3282
  this.updateMetadata((metadata) => {
4439
3283
  if (metadata.summaryPinned) {
4440
- logger.debug("[SOCKET] Skipping summary update: title is pinned by user");
3284
+ logger.logger.debug("[SOCKET] Skipping summary update: title is pinned by user");
4441
3285
  return metadata;
4442
3286
  }
4443
3287
  const newSummary = body.summary;
@@ -4445,7 +3289,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4445
3289
  const dirName = metadata.path?.split(/[\\/]/).filter(Boolean).pop();
4446
3290
  const isNewSummaryDirName = dirName && newSummary === dirName;
4447
3291
  if (isNewSummaryDirName && currentSummary && currentSummary !== dirName) {
4448
- logger.debug("[SOCKET] Skipping summary update: new summary is directory name but current title is better", {
3292
+ logger.logger.debug("[SOCKET] Skipping summary update: new summary is directory name but current title is better", {
4449
3293
  newSummary,
4450
3294
  currentSummary,
4451
3295
  dirName
@@ -4471,18 +3315,18 @@ class ApiSessionClient extends node_events.EventEmitter {
4471
3315
  if (content.role === "agent") {
4472
3316
  this.autoReviewGuard.onAgentText(extractPlainTextForAutoReview(content), String(body.uuid || node_crypto.randomUUID()));
4473
3317
  }
4474
- logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
3318
+ logger.logger.debugLargeJson("[SOCKET] Sending message through socket:", content);
4475
3319
  this.enqueueMessage(content);
4476
3320
  this.postSendProcessing(body);
4477
3321
  }
4478
3322
  async sendClaudeSessionMessageBatch(messages, mode = "append") {
4479
3323
  if (!this.socket.connected) {
4480
- logger.debug("[API] Socket not connected, cannot send Claude session message batch. Messages will be lost:", { count: messages.length });
3324
+ logger.logger.debug("[API] Socket not connected, cannot send Claude session message batch. Messages will be lost:", { count: messages.length });
4481
3325
  return { result: "error" };
4482
3326
  }
4483
3327
  const payload = messages.map((item) => {
4484
3328
  const content = this.buildMessageContent(item.message);
4485
- const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
3329
+ const encrypted = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, content));
4486
3330
  return {
4487
3331
  message: encrypted,
4488
3332
  localId: item.localId ?? null
@@ -4537,7 +3381,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4537
3381
  sentFrom: "cli"
4538
3382
  }
4539
3383
  };
4540
- logger.debug(`[SOCKET] Sending ACP message from ${provider}:`, { type: body.type, hasMessage: "message" in body });
3384
+ logger.logger.debug(`[SOCKET] Sending ACP message from ${provider}:`, { type: body.type, hasMessage: "message" in body });
4541
3385
  this.autoReviewGuard.onAgentText(normalizeReviewableAgentText(body), `${provider}-${Date.now()}`);
4542
3386
  this.enqueueMessage(content);
4543
3387
  }
@@ -4548,17 +3392,17 @@ class ApiSessionClient extends node_events.EventEmitter {
4548
3392
  */
4549
3393
  async sendBackfillBatch(messages, mode = "append") {
4550
3394
  if (!this.socket.connected) {
4551
- logger.debug(`[API] Socket not connected, cannot send backfill batch (${messages.length} messages)`);
3395
+ logger.logger.debug(`[API] Socket not connected, cannot send backfill batch (${messages.length} messages)`);
4552
3396
  return { result: "error" };
4553
3397
  }
4554
3398
  const payload = messages.map((item) => {
4555
- const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, item.content));
3399
+ const encrypted = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, item.content));
4556
3400
  return {
4557
3401
  message: encrypted,
4558
3402
  localId: item.localId
4559
3403
  };
4560
3404
  });
4561
- logger.debug(`[SOCKET] Sending backfill batch: ${messages.length} messages, mode=${mode}`);
3405
+ logger.logger.debug(`[SOCKET] Sending backfill batch: ${messages.length} messages, mode=${mode}`);
4562
3406
  const response = await this.socket.emitWithAck("message-batch", {
4563
3407
  sid: this.sessionId,
4564
3408
  messages: payload,
@@ -4575,7 +3419,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4575
3419
  data: event
4576
3420
  }
4577
3421
  };
4578
- const encrypted = encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, content));
3422
+ const encrypted = logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, content));
4579
3423
  this.socket.emit("message", {
4580
3424
  sid: this.sessionId,
4581
3425
  message: encrypted
@@ -4585,8 +3429,8 @@ class ApiSessionClient extends node_events.EventEmitter {
4585
3429
  * Send a ping message to keep the connection alive
4586
3430
  */
4587
3431
  keepAlive(thinking, mode) {
4588
- if (isDebug()) {
4589
- logger.debug(`[API] Sending keep alive message: ${thinking}`);
3432
+ if (logger.isDebug()) {
3433
+ logger.logger.debug(`[API] Sending keep alive message: ${thinking}`);
4590
3434
  }
4591
3435
  this.socket.volatile.emit("session-alive", {
4592
3436
  sid: this.sessionId,
@@ -4605,7 +3449,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4605
3449
  * Send a generic usage report to the server for any provider
4606
3450
  */
4607
3451
  sendUsageReport(report) {
4608
- logger.debugLargeJson("[SOCKET] Sending usage report:", report);
3452
+ logger.logger.debugLargeJson("[SOCKET] Sending usage report:", report);
4609
3453
  this.socket.emit("usage-report", {
4610
3454
  key: report.key,
4611
3455
  sessionId: this.sessionId,
@@ -4613,7 +3457,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4613
3457
  cost: report.cost
4614
3458
  }, (response) => {
4615
3459
  if (!response?.success) {
4616
- logger.debug("[SOCKET] Usage report rejected by server", {
3460
+ logger.logger.debug("[SOCKET] Usage report rejected by server", {
4617
3461
  key: report.key,
4618
3462
  sessionId: this.sessionId,
4619
3463
  error: response?.error || "unknown error"
@@ -4700,22 +3544,22 @@ class ApiSessionClient extends node_events.EventEmitter {
4700
3544
  }
4701
3545
  async updateMetadataAsync(handler) {
4702
3546
  await this.metadataLock.inLock(async () => {
4703
- await backoff(async () => {
3547
+ await time.backoff(async () => {
4704
3548
  const base = this.metadata;
4705
3549
  if (!base) {
4706
- logger.debug("[API] skipping metadata update: no local metadata to build on");
3550
+ logger.logger.debug("[API] skipping metadata update: no local metadata to build on");
4707
3551
  return;
4708
3552
  }
4709
3553
  const updated = adoptServerSessionMetadata(base, handler(base));
4710
- const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) });
3554
+ const answer = await this.socket.emitWithAck("update-metadata", { sid: this.sessionId, expectedVersion: this.metadataVersion, metadata: logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, updated)) });
4711
3555
  if (answer.result === "success") {
4712
- this.metadata = adoptServerSessionMetadata(this.metadata, decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata)));
3556
+ this.metadata = adoptServerSessionMetadata(this.metadata, logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(answer.metadata)));
4713
3557
  this.metadataVersion = answer.version;
4714
3558
  this.syncedModel = this.metadata?.model?.trim() || null;
4715
3559
  } else if (answer.result === "version-mismatch") {
4716
3560
  if (answer.version > this.metadataVersion) {
4717
3561
  this.metadataVersion = answer.version;
4718
- this.metadata = adoptServerSessionMetadata(this.metadata, decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.metadata)));
3562
+ this.metadata = adoptServerSessionMetadata(this.metadata, logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(answer.metadata)));
4719
3563
  this.syncedModel = this.metadata?.model?.trim() || null;
4720
3564
  }
4721
3565
  throw new Error("Metadata version mismatch");
@@ -4728,19 +3572,19 @@ class ApiSessionClient extends node_events.EventEmitter {
4728
3572
  * @param handler - Handler function that returns the updated agent state
4729
3573
  */
4730
3574
  updateAgentState(handler) {
4731
- logger.debugLargeJson("Updating agent state", this.agentState);
3575
+ logger.logger.debugLargeJson("Updating agent state", this.agentState);
4732
3576
  this.agentStateLock.inLock(async () => {
4733
- await backoff(async () => {
3577
+ await time.backoff(async () => {
4734
3578
  let updated = handler(this.agentState || {});
4735
- const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
3579
+ const answer = await this.socket.emitWithAck("update-state", { sid: this.sessionId, expectedVersion: this.agentStateVersion, agentState: updated ? logger.encodeBase64(logger.encrypt(this.encryptionKey, this.encryptionVariant, updated)) : null });
4736
3580
  if (answer.result === "success") {
4737
- this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
3581
+ this.agentState = answer.agentState ? logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(answer.agentState)) : null;
4738
3582
  this.agentStateVersion = answer.version;
4739
- logger.debug("Agent state updated", this.agentState);
3583
+ logger.logger.debug("Agent state updated", this.agentState);
4740
3584
  } else if (answer.result === "version-mismatch") {
4741
3585
  if (answer.version > this.agentStateVersion) {
4742
3586
  this.agentStateVersion = answer.version;
4743
- this.agentState = answer.agentState ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(answer.agentState)) : null;
3587
+ this.agentState = answer.agentState ? logger.decrypt(this.encryptionKey, this.encryptionVariant, logger.decodeBase64(answer.agentState)) : null;
4744
3588
  }
4745
3589
  throw new Error("Agent state version mismatch");
4746
3590
  } else if (answer.result === "error") ;
@@ -4755,7 +3599,7 @@ class ApiSessionClient extends node_events.EventEmitter {
4755
3599
  try {
4756
3600
  await this.sendSync.invalidateAndAwait();
4757
3601
  } catch (error) {
4758
- logger.debug("[API] flush: outbox flush failed, some messages may be lost:", error);
3602
+ logger.logger.debug("[API] flush: outbox flush failed, some messages may be lost:", error);
4759
3603
  }
4760
3604
  if (!this.socket.connected) {
4761
3605
  return;
@@ -4770,387 +3614,17 @@ class ApiSessionClient extends node_events.EventEmitter {
4770
3614
  });
4771
3615
  }
4772
3616
  async close() {
4773
- logger.debug("[API] socket.close() called");
3617
+ logger.logger.debug("[API] socket.close() called");
4774
3618
  try {
4775
3619
  await this.sendSync.invalidateAndAwait();
4776
3620
  } catch (error) {
4777
- logger.debug("[API] close: final outbox flush failed:", error);
3621
+ logger.logger.debug("[API] close: final outbox flush failed:", error);
4778
3622
  }
4779
3623
  this.sendSync.stop();
4780
3624
  this.socket.close();
4781
3625
  }
4782
3626
  }
4783
3627
 
4784
- const AnthropicConfigSchema = z__namespace.object({
4785
- baseUrl: z__namespace.string().url().optional(),
4786
- authToken: z__namespace.string().optional(),
4787
- model: z__namespace.string().optional()
4788
- });
4789
- const OpenAIConfigSchema = z__namespace.object({
4790
- apiKey: z__namespace.string().optional(),
4791
- baseUrl: z__namespace.string().url().optional(),
4792
- model: z__namespace.string().optional()
4793
- });
4794
- const AzureOpenAIConfigSchema = z__namespace.object({
4795
- apiKey: z__namespace.string().optional(),
4796
- endpoint: z__namespace.string().url().optional(),
4797
- apiVersion: z__namespace.string().optional(),
4798
- deploymentName: z__namespace.string().optional()
4799
- });
4800
- const TogetherAIConfigSchema = z__namespace.object({
4801
- apiKey: z__namespace.string().optional(),
4802
- model: z__namespace.string().optional()
4803
- });
4804
- const TmuxConfigSchema = z__namespace.object({
4805
- sessionName: z__namespace.string().optional(),
4806
- tmpDir: z__namespace.string().optional(),
4807
- updateEnvironment: z__namespace.boolean().optional()
4808
- });
4809
- const EnvironmentVariableSchema = z__namespace.object({
4810
- name: z__namespace.string().regex(/^[A-Z_][A-Z0-9_]*$/, "Invalid environment variable name"),
4811
- value: z__namespace.string()
4812
- });
4813
- const ProfileCompatibilitySchema = z__namespace.object({
4814
- claude: z__namespace.boolean().default(true),
4815
- codex: z__namespace.boolean().default(true),
4816
- gemini: z__namespace.boolean().default(true)
4817
- });
4818
- const AIBackendProfileSchema = z__namespace.object({
4819
- id: z__namespace.string().uuid(),
4820
- name: z__namespace.string().min(1).max(100),
4821
- description: z__namespace.string().max(500).optional(),
4822
- // Agent-specific configurations
4823
- anthropicConfig: AnthropicConfigSchema.optional(),
4824
- openaiConfig: OpenAIConfigSchema.optional(),
4825
- azureOpenAIConfig: AzureOpenAIConfigSchema.optional(),
4826
- togetherAIConfig: TogetherAIConfigSchema.optional(),
4827
- // Tmux configuration
4828
- tmuxConfig: TmuxConfigSchema.optional(),
4829
- // Environment variables (validated)
4830
- environmentVariables: z__namespace.array(EnvironmentVariableSchema).default([]),
4831
- // Default session type for this profile
4832
- defaultSessionType: z__namespace.enum(["simple", "worktree"]).optional(),
4833
- // Default permission mode for this profile (supports both Claude and Codex modes)
4834
- defaultPermissionMode: z__namespace.enum([
4835
- "default",
4836
- "acceptEdits",
4837
- "bypassPermissions",
4838
- "plan",
4839
- // Claude modes
4840
- "read-only",
4841
- "safe-yolo",
4842
- "yolo"
4843
- // Codex modes
4844
- ]).optional(),
4845
- // Default model mode for this profile
4846
- defaultModelMode: z__namespace.string().optional(),
4847
- // Compatibility metadata
4848
- compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true }),
4849
- // Built-in profile indicator
4850
- isBuiltIn: z__namespace.boolean().default(false),
4851
- // Metadata
4852
- createdAt: z__namespace.number().default(() => Date.now()),
4853
- updatedAt: z__namespace.number().default(() => Date.now()),
4854
- version: z__namespace.string().default("1.0.0")
4855
- });
4856
- function validateProfileForAgent(profile, agent) {
4857
- return profile.compatibility[agent];
4858
- }
4859
- function getProfileEnvironmentVariables(profile) {
4860
- const envVars = {};
4861
- profile.environmentVariables.forEach((envVar) => {
4862
- envVars[envVar.name] = envVar.value;
4863
- });
4864
- if (profile.anthropicConfig) {
4865
- if (profile.anthropicConfig.baseUrl) envVars.ANTHROPIC_BASE_URL = profile.anthropicConfig.baseUrl;
4866
- if (profile.anthropicConfig.authToken) envVars.ANTHROPIC_AUTH_TOKEN = profile.anthropicConfig.authToken;
4867
- if (profile.anthropicConfig.model) envVars.ANTHROPIC_MODEL = profile.anthropicConfig.model;
4868
- }
4869
- if (profile.openaiConfig) {
4870
- if (profile.openaiConfig.apiKey) envVars.OPENAI_API_KEY = profile.openaiConfig.apiKey;
4871
- if (profile.openaiConfig.baseUrl) envVars.OPENAI_BASE_URL = profile.openaiConfig.baseUrl;
4872
- if (profile.openaiConfig.model) envVars.OPENAI_MODEL = profile.openaiConfig.model;
4873
- }
4874
- if (profile.azureOpenAIConfig) {
4875
- if (profile.azureOpenAIConfig.apiKey) envVars.AZURE_OPENAI_API_KEY = profile.azureOpenAIConfig.apiKey;
4876
- if (profile.azureOpenAIConfig.endpoint) envVars.AZURE_OPENAI_ENDPOINT = profile.azureOpenAIConfig.endpoint;
4877
- if (profile.azureOpenAIConfig.apiVersion) envVars.AZURE_OPENAI_API_VERSION = profile.azureOpenAIConfig.apiVersion;
4878
- if (profile.azureOpenAIConfig.deploymentName) envVars.AZURE_OPENAI_DEPLOYMENT_NAME = profile.azureOpenAIConfig.deploymentName;
4879
- }
4880
- if (profile.togetherAIConfig) {
4881
- if (profile.togetherAIConfig.apiKey) envVars.TOGETHER_API_KEY = profile.togetherAIConfig.apiKey;
4882
- if (profile.togetherAIConfig.model) envVars.TOGETHER_MODEL = profile.togetherAIConfig.model;
4883
- }
4884
- if (profile.tmuxConfig) {
4885
- if (profile.tmuxConfig.sessionName !== void 0) envVars.TMUX_SESSION_NAME = profile.tmuxConfig.sessionName;
4886
- if (profile.tmuxConfig.tmpDir) envVars.TMUX_TMPDIR = profile.tmuxConfig.tmpDir;
4887
- if (profile.tmuxConfig.updateEnvironment !== void 0) {
4888
- envVars.TMUX_UPDATE_ENVIRONMENT = profile.tmuxConfig.updateEnvironment.toString();
4889
- }
4890
- }
4891
- return envVars;
4892
- }
4893
- const SUPPORTED_SCHEMA_VERSION = 2;
4894
- const defaultSettings = {
4895
- schemaVersion: SUPPORTED_SCHEMA_VERSION,
4896
- onboardingCompleted: false,
4897
- profiles: [],
4898
- localEnvironmentVariables: {}
4899
- };
4900
- function migrateSettings(raw, fromVersion) {
4901
- let migrated = { ...raw };
4902
- if (fromVersion < 2) {
4903
- if (!migrated.profiles) {
4904
- migrated.profiles = [];
4905
- }
4906
- if (!migrated.localEnvironmentVariables) {
4907
- migrated.localEnvironmentVariables = {};
4908
- }
4909
- migrated.schemaVersion = 2;
4910
- }
4911
- return migrated;
4912
- }
4913
- async function readSettings() {
4914
- if (!fs.existsSync(configuration.settingsFile)) {
4915
- return { ...defaultSettings };
4916
- }
4917
- try {
4918
- const content = await promises.readFile(configuration.settingsFile, "utf8");
4919
- const raw = JSON.parse(content);
4920
- const schemaVersion = raw.schemaVersion ?? 1;
4921
- if (schemaVersion > SUPPORTED_SCHEMA_VERSION) {
4922
- logger.warn(
4923
- `\u26A0\uFE0F Settings schema v${schemaVersion} > supported v${SUPPORTED_SCHEMA_VERSION}. Update happy-cli for full functionality.`
4924
- );
4925
- }
4926
- const migrated = migrateSettings(raw, schemaVersion);
4927
- if (migrated.profiles && Array.isArray(migrated.profiles)) {
4928
- const validProfiles = [];
4929
- for (const profile of migrated.profiles) {
4930
- try {
4931
- const validated = AIBackendProfileSchema.parse(profile);
4932
- validProfiles.push(validated);
4933
- } catch (error) {
4934
- logger.warn(
4935
- `\u26A0\uFE0F Invalid profile "${profile?.name || profile?.id || "unknown"}" - skipping. Error: ${error.message}`
4936
- );
4937
- }
4938
- }
4939
- migrated.profiles = validProfiles;
4940
- }
4941
- return { ...defaultSettings, ...migrated };
4942
- } catch (error) {
4943
- logger.warn(`Failed to read settings: ${error.message}`);
4944
- return { ...defaultSettings };
4945
- }
4946
- }
4947
- async function updateSettings(updater) {
4948
- const LOCK_RETRY_INTERVAL_MS = 100;
4949
- const MAX_LOCK_ATTEMPTS = 50;
4950
- const STALE_LOCK_TIMEOUT_MS = 1e4;
4951
- const lockFile = configuration.settingsFile + ".lock";
4952
- const tmpFile = configuration.settingsFile + ".tmp";
4953
- let fileHandle;
4954
- let attempts = 0;
4955
- while (attempts < MAX_LOCK_ATTEMPTS) {
4956
- try {
4957
- fileHandle = await promises.open(lockFile, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY);
4958
- break;
4959
- } catch (err) {
4960
- if (err.code === "EEXIST") {
4961
- attempts++;
4962
- await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_INTERVAL_MS));
4963
- try {
4964
- const stats = await promises.stat(lockFile);
4965
- if (Date.now() - stats.mtimeMs > STALE_LOCK_TIMEOUT_MS) {
4966
- await promises.unlink(lockFile).catch(() => {
4967
- });
4968
- }
4969
- } catch {
4970
- }
4971
- } else {
4972
- throw err;
4973
- }
4974
- }
4975
- }
4976
- if (!fileHandle) {
4977
- throw new Error(`Failed to acquire settings lock after ${MAX_LOCK_ATTEMPTS * LOCK_RETRY_INTERVAL_MS / 1e3} seconds`);
4978
- }
4979
- try {
4980
- const current = await readSettings() || { ...defaultSettings };
4981
- const updated = await updater(current);
4982
- if (!fs.existsSync(configuration.happyHomeDir)) {
4983
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
4984
- }
4985
- await promises.writeFile(tmpFile, JSON.stringify(updated, null, 2));
4986
- await promises.rename(tmpFile, configuration.settingsFile);
4987
- return updated;
4988
- } finally {
4989
- await fileHandle.close();
4990
- await promises.unlink(lockFile).catch(() => {
4991
- });
4992
- }
4993
- }
4994
- const credentialsSchema = z__namespace.object({
4995
- token: z__namespace.string(),
4996
- secret: z__namespace.string().base64().nullish(),
4997
- // Legacy
4998
- encryption: z__namespace.object({
4999
- publicKey: z__namespace.string().base64(),
5000
- machineKey: z__namespace.string().base64()
5001
- }).nullish()
5002
- });
5003
- async function readCredentials() {
5004
- if (!fs.existsSync(configuration.privateKeyFile)) {
5005
- return null;
5006
- }
5007
- try {
5008
- const keyBase64 = await promises.readFile(configuration.privateKeyFile, "utf8");
5009
- const credentials = credentialsSchema.parse(JSON.parse(keyBase64));
5010
- if (credentials.secret) {
5011
- return {
5012
- token: credentials.token,
5013
- encryption: {
5014
- type: "legacy",
5015
- secret: new Uint8Array(Buffer.from(credentials.secret, "base64"))
5016
- }
5017
- };
5018
- } else if (credentials.encryption) {
5019
- return {
5020
- token: credentials.token,
5021
- encryption: {
5022
- type: "dataKey",
5023
- publicKey: new Uint8Array(Buffer.from(credentials.encryption.publicKey, "base64")),
5024
- machineKey: new Uint8Array(Buffer.from(credentials.encryption.machineKey, "base64"))
5025
- }
5026
- };
5027
- }
5028
- } catch {
5029
- return null;
5030
- }
5031
- return null;
5032
- }
5033
- async function writeCredentialsLegacy(credentials) {
5034
- if (!fs.existsSync(configuration.happyHomeDir)) {
5035
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
5036
- }
5037
- await promises.writeFile(configuration.privateKeyFile, JSON.stringify({
5038
- secret: encodeBase64(credentials.secret),
5039
- token: credentials.token
5040
- }, null, 2));
5041
- }
5042
- async function writeCredentialsDataKey(credentials) {
5043
- if (!fs.existsSync(configuration.happyHomeDir)) {
5044
- await promises.mkdir(configuration.happyHomeDir, { recursive: true });
5045
- }
5046
- await promises.writeFile(configuration.privateKeyFile, JSON.stringify({
5047
- encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
5048
- token: credentials.token
5049
- }, null, 2));
5050
- }
5051
- async function clearCredentials() {
5052
- if (fs.existsSync(configuration.privateKeyFile)) {
5053
- await promises.unlink(configuration.privateKeyFile);
5054
- }
5055
- }
5056
- async function clearMachineId() {
5057
- await updateSettings((settings) => ({
5058
- ...settings,
5059
- machineId: void 0
5060
- }));
5061
- }
5062
- async function readDaemonState() {
5063
- try {
5064
- if (!fs.existsSync(configuration.daemonStateFile)) {
5065
- return null;
5066
- }
5067
- const content = await promises.readFile(configuration.daemonStateFile, "utf-8");
5068
- return JSON.parse(content);
5069
- } catch (error) {
5070
- console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
5071
- return null;
5072
- }
5073
- }
5074
- function writeDaemonState(state) {
5075
- fs.writeFileSync(configuration.daemonStateFile, JSON.stringify(state, null, 2), "utf-8");
5076
- }
5077
- async function clearDaemonState() {
5078
- if (fs.existsSync(configuration.daemonStateFile)) {
5079
- await promises.unlink(configuration.daemonStateFile);
5080
- }
5081
- if (fs.existsSync(configuration.daemonLockFile)) {
5082
- try {
5083
- await promises.unlink(configuration.daemonLockFile);
5084
- } catch {
5085
- }
5086
- }
5087
- }
5088
- async function acquireDaemonLock(maxAttempts = 5, delayIncrementMs = 200) {
5089
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
5090
- try {
5091
- const fileHandle = await promises.open(
5092
- configuration.daemonLockFile,
5093
- fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY
5094
- );
5095
- await fileHandle.writeFile(String(process.pid));
5096
- return fileHandle;
5097
- } catch (error) {
5098
- if (error.code === "EEXIST") {
5099
- try {
5100
- const lockPid = fs.readFileSync(configuration.daemonLockFile, "utf-8").trim();
5101
- if (lockPid && !isNaN(Number(lockPid))) {
5102
- try {
5103
- process.kill(Number(lockPid), 0);
5104
- } catch {
5105
- fs.unlinkSync(configuration.daemonLockFile);
5106
- continue;
5107
- }
5108
- }
5109
- } catch {
5110
- }
5111
- }
5112
- if (attempt === maxAttempts) {
5113
- return null;
5114
- }
5115
- const delayMs = attempt * delayIncrementMs;
5116
- await new Promise((resolve) => setTimeout(resolve, delayMs));
5117
- }
5118
- }
5119
- return null;
5120
- }
5121
- async function releaseDaemonLock(lockHandle) {
5122
- try {
5123
- await lockHandle.close();
5124
- } catch {
5125
- }
5126
- try {
5127
- if (fs.existsSync(configuration.daemonLockFile)) {
5128
- fs.unlinkSync(configuration.daemonLockFile);
5129
- }
5130
- } catch {
5131
- }
5132
- }
5133
-
5134
- var persistence = /*#__PURE__*/Object.freeze({
5135
- __proto__: null,
5136
- AIBackendProfileSchema: AIBackendProfileSchema,
5137
- SUPPORTED_SCHEMA_VERSION: SUPPORTED_SCHEMA_VERSION,
5138
- acquireDaemonLock: acquireDaemonLock,
5139
- clearCredentials: clearCredentials,
5140
- clearDaemonState: clearDaemonState,
5141
- clearMachineId: clearMachineId,
5142
- getProfileEnvironmentVariables: getProfileEnvironmentVariables,
5143
- readCredentials: readCredentials,
5144
- readDaemonState: readDaemonState,
5145
- readSettings: readSettings,
5146
- releaseDaemonLock: releaseDaemonLock,
5147
- updateSettings: updateSettings,
5148
- validateProfileForAgent: validateProfileForAgent,
5149
- writeCredentialsDataKey: writeCredentialsDataKey,
5150
- writeCredentialsLegacy: writeCredentialsLegacy,
5151
- writeDaemonState: writeDaemonState
5152
- });
5153
-
5154
3628
  function buildRunningDaemonState(previousState, currentRuntimeState, opts = {}) {
5155
3629
  const currentHttpPort = currentRuntimeState?.httpPort;
5156
3630
  const currentStartedAt = currentRuntimeState?.startedAt;
@@ -5216,11 +3690,11 @@ class OpenClawTunnelManager {
5216
3690
  this.tunnels.set(tunnelId, tunnel);
5217
3691
  return new Promise((resolve) => {
5218
3692
  try {
5219
- logger.debug(`[OpenClawTunnel] Connecting to ${config.url}`);
3693
+ logger.logger.debug(`[OpenClawTunnel] Connecting to ${config.url}`);
5220
3694
  const ws = new WebSocket(config.url);
5221
3695
  tunnel.ws = ws;
5222
3696
  ws.on("open", () => {
5223
- logger.debug(`[OpenClawTunnel] WebSocket opened for tunnel ${tunnelId}`);
3697
+ logger.logger.debug(`[OpenClawTunnel] WebSocket opened for tunnel ${tunnelId}`);
5224
3698
  });
5225
3699
  ws.on("message", async (data) => {
5226
3700
  const result = await this.handleMessage(tunnelId, tunnel, data.toString());
@@ -5229,7 +3703,7 @@ class OpenClawTunnelManager {
5229
3703
  }
5230
3704
  });
5231
3705
  ws.on("error", (error) => {
5232
- logger.debug(`[OpenClawTunnel] WebSocket error for tunnel ${tunnelId}:`, error);
3706
+ logger.logger.debug(`[OpenClawTunnel] WebSocket error for tunnel ${tunnelId}:`, error);
5233
3707
  tunnel.status = "error";
5234
3708
  this.failAllPending(tunnel, new Error("WebSocket error"));
5235
3709
  resolve({
@@ -5240,7 +3714,7 @@ class OpenClawTunnelManager {
5240
3714
  });
5241
3715
  ws.on("close", (code, reason) => {
5242
3716
  const reasonStr = reason?.toString() || "";
5243
- logger.debug(`[OpenClawTunnel] WebSocket closed for tunnel ${tunnelId}: ${code} ${reasonStr}`);
3717
+ logger.logger.debug(`[OpenClawTunnel] WebSocket closed for tunnel ${tunnelId}: ${code} ${reasonStr}`);
5244
3718
  const isPairingRequired = reasonStr.includes("unauthorized") || reasonStr.includes("NOT_PAIRED");
5245
3719
  this.failAllPending(tunnel, new Error(reasonStr || "Connection closed"));
5246
3720
  if (tunnel.status === "connecting") {
@@ -5372,7 +3846,7 @@ class OpenClawTunnelManager {
5372
3846
  tunnel.ws = null;
5373
3847
  }
5374
3848
  this.tunnels.delete(tunnelId);
5375
- logger.debug(`[OpenClawTunnel] Closed tunnel ${tunnelId}`);
3849
+ logger.logger.debug(`[OpenClawTunnel] Closed tunnel ${tunnelId}`);
5376
3850
  return true;
5377
3851
  }
5378
3852
  async handleMessage(tunnelId, tunnel, data) {
@@ -5380,7 +3854,7 @@ class OpenClawTunnelManager {
5380
3854
  try {
5381
3855
  frame = JSON.parse(data);
5382
3856
  } catch {
5383
- logger.debug(`[OpenClawTunnel] Invalid JSON: ${data.slice(0, 100)}`);
3857
+ logger.logger.debug(`[OpenClawTunnel] Invalid JSON: ${data.slice(0, 100)}`);
5384
3858
  return null;
5385
3859
  }
5386
3860
  if (frame.type === "res") {
@@ -5405,7 +3879,7 @@ class OpenClawTunnelManager {
5405
3879
  if (frame.event === "connect.challenge" && !tunnel.connectSent) {
5406
3880
  const nonce = payload?.nonce;
5407
3881
  if (nonce) {
5408
- logger.debug(`[OpenClawTunnel] Received challenge nonce for tunnel ${tunnelId}`);
3882
+ logger.logger.debug(`[OpenClawTunnel] Received challenge nonce for tunnel ${tunnelId}`);
5409
3883
  tunnel.connectNonce = nonce;
5410
3884
  }
5411
3885
  return this.sendConnect(tunnelId, tunnel);
@@ -5485,7 +3959,7 @@ class OpenClawTunnelManager {
5485
3959
  tunnel.mainSessionKey = result.snapshot?.sessionDefaults?.mainSessionKey ?? null;
5486
3960
  tunnel.serverHost = result.server?.host ?? null;
5487
3961
  tunnel.deviceToken = result.auth?.deviceToken ?? null;
5488
- logger.debug(`[OpenClawTunnel] Connected tunnel ${tunnelId}, server: ${tunnel.serverHost}`);
3962
+ logger.logger.debug(`[OpenClawTunnel] Connected tunnel ${tunnelId}, server: ${tunnel.serverHost}`);
5489
3963
  resolve({
5490
3964
  ok: true,
5491
3965
  status: "connected",
@@ -5603,7 +4077,7 @@ function registerOpenClawHandlers(rpcManager, encryptionContext) {
5603
4077
  if (Array.isArray(payload.messages) && payload.messages.length > 0) {
5604
4078
  return {
5605
4079
  __preEncrypted: true,
5606
- data: encodeBase64(encryptLegacy(result, encryptionContext.key))
4080
+ data: logger.encodeBase64(logger.encryptLegacy(result, encryptionContext.key))
5607
4081
  };
5608
4082
  }
5609
4083
  }
@@ -5655,7 +4129,7 @@ const SESSION_CACHE_REFRESH_MODES = /* @__PURE__ */ new Set([
5655
4129
  "background"
5656
4130
  ]);
5657
4131
  function getSessionMetadataCachePath(cacheFileName) {
5658
- return path.join(configuration.happyHomeDir, cacheFileName);
4132
+ return path.join(logger.configuration.happyHomeDir, cacheFileName);
5659
4133
  }
5660
4134
  function getCacheLockPath(cachePath) {
5661
4135
  return `${cachePath}.lock`;
@@ -6702,7 +5176,7 @@ const GeminiSessionLineSchema = z.z.discriminatedUnion("type", [
6702
5176
 
6703
5177
  const SESSIONS_DIR_NAME = "gemini_sessions";
6704
5178
  function getGeminiSessionsDir() {
6705
- return path.join(configuration.happyHomeDir, SESSIONS_DIR_NAME);
5179
+ return path.join(logger.configuration.happyHomeDir, SESSIONS_DIR_NAME);
6706
5180
  }
6707
5181
  function getGeminiSessionFilePath(sessionId) {
6708
5182
  return path.join(getGeminiSessionsDir(), `${sessionId}.jsonl`);
@@ -6722,9 +5196,9 @@ class GeminiSessionWriter {
6722
5196
  value: meta ?? {},
6723
5197
  timestamp: Date.now()
6724
5198
  });
6725
- logger.debug(`[GeminiSessionWriter] Initialized: ${this.filePath}`);
5199
+ logger.logger.debug(`[GeminiSessionWriter] Initialized: ${this.filePath}`);
6726
5200
  } catch (error) {
6727
- logger.debug(`[GeminiSessionWriter] Failed to init:`, error);
5201
+ logger.logger.debug(`[GeminiSessionWriter] Failed to init:`, error);
6728
5202
  }
6729
5203
  }
6730
5204
  getFilePath() {
@@ -6783,7 +5257,7 @@ class GeminiSessionWriter {
6783
5257
  */
6784
5258
  appendLine(line) {
6785
5259
  this.writePromise = this.writePromise.then(() => promises.appendFile(this.filePath, JSON.stringify(line) + "\n", "utf-8")).catch((error) => {
6786
- logger.debug(`[GeminiSessionWriter] Write failed:`, error);
5260
+ logger.logger.debug(`[GeminiSessionWriter] Write failed:`, error);
6787
5261
  });
6788
5262
  }
6789
5263
  }
@@ -6794,7 +5268,7 @@ async function readGeminiSessionLog(sessionId) {
6794
5268
  try {
6795
5269
  content = await promises.readFile(filePath, "utf-8");
6796
5270
  } catch (error) {
6797
- logger.debug(`[GeminiSessionReader] Session file not found: ${filePath}`);
5271
+ logger.logger.debug(`[GeminiSessionReader] Session file not found: ${filePath}`);
6798
5272
  return [];
6799
5273
  }
6800
5274
  const lines = content.split("\n");
@@ -6807,10 +5281,10 @@ async function readGeminiSessionLog(sessionId) {
6807
5281
  if (result.success) {
6808
5282
  entries.push(result.data);
6809
5283
  } else {
6810
- logger.debug(`[GeminiSessionReader] Skipping invalid line: ${line.substring(0, 100)}`);
5284
+ logger.logger.debug(`[GeminiSessionReader] Skipping invalid line: ${line.substring(0, 100)}`);
6811
5285
  }
6812
5286
  } catch {
6813
- logger.debug(`[GeminiSessionReader] Skipping non-JSON line: ${line.substring(0, 100)}`);
5287
+ logger.logger.debug(`[GeminiSessionReader] Skipping non-JSON line: ${line.substring(0, 100)}`);
6814
5288
  }
6815
5289
  }
6816
5290
  return entries;
@@ -7032,7 +5506,7 @@ async function forkAndTruncateGeminiSession(sessionId, truncateBeforeUuid) {
7032
5506
  return { success: false, errorMessage: truncateResult.errorMessage };
7033
5507
  }
7034
5508
  }
7035
- logger.debug(`[GeminiSessionFork] Forked ${sessionId} -> ${newSessionId}`);
5509
+ logger.logger.debug(`[GeminiSessionFork] Forked ${sessionId} -> ${newSessionId}`);
7036
5510
  return { success: true, newSessionId };
7037
5511
  } catch (error) {
7038
5512
  try {
@@ -7169,14 +5643,14 @@ function isSystemMessage(text) {
7169
5643
  async function readCodexSessionUserMessages(codexSessionId, limit = 50) {
7170
5644
  const filePath = findCodexSessionFile(codexSessionId);
7171
5645
  if (!filePath) {
7172
- logger.debug(`[CodexSessionReader] Session file not found for: ${codexSessionId}`);
5646
+ logger.logger.debug(`[CodexSessionReader] Session file not found for: ${codexSessionId}`);
7173
5647
  return [];
7174
5648
  }
7175
5649
  let content;
7176
5650
  try {
7177
5651
  content = await promises.readFile(filePath, "utf-8");
7178
5652
  } catch (error) {
7179
- logger.debug(`[CodexSessionReader] Failed to read file: ${filePath}`, error);
5653
+ logger.logger.debug(`[CodexSessionReader] Failed to read file: ${filePath}`, error);
7180
5654
  return [];
7181
5655
  }
7182
5656
  const lines = content.split("\n");
@@ -7473,7 +5947,7 @@ async function forkAndTruncateCodexSession(codexSessionId, truncateBeforeUuid) {
7473
5947
  }
7474
5948
  await promises.writeFile(newPath, outputLines.join("\n") + "\n", "utf-8");
7475
5949
  }
7476
- logger.debug(`[CodexSessionFork] Forked ${path.basename(originalPath)} -> ${path.basename(newPath)}`);
5950
+ logger.logger.debug(`[CodexSessionFork] Forked ${path.basename(originalPath)} -> ${path.basename(newPath)}`);
7477
5951
  return { success: true, newFilePath: newPath };
7478
5952
  } catch (error) {
7479
5953
  try {
@@ -7660,7 +6134,7 @@ function createSessionCacheStatsReporter(saveStats, label) {
7660
6134
  const stats = pendingStats;
7661
6135
  pendingStats = null;
7662
6136
  flushPromise = saveStats(stats).catch((error) => {
7663
- logger.debug(`[API MACHINE] Failed to persist ${label} session cache stats`, error);
6137
+ logger.logger.debug(`[API MACHINE] Failed to persist ${label} session cache stats`, error);
7664
6138
  }).then(() => {
7665
6139
  flushPromise = null;
7666
6140
  });
@@ -7692,7 +6166,7 @@ class ApiMachineClient {
7692
6166
  scopePrefix: this.machine.id,
7693
6167
  encryptionKey: this.machine.encryptionKey,
7694
6168
  encryptionVariant: this.machine.encryptionVariant,
7695
- logger: (msg, data) => logger.debug(msg, data)
6169
+ logger: (msg, data) => logger.logger.debug(msg, data)
7696
6170
  });
7697
6171
  registerCommonHandlers(this.rpcHandlerManager, process.env.HAPPY_DAEMON_ROOT || "/", this.machine.id);
7698
6172
  registerOpenClawHandlers(this.rpcHandlerManager, {
@@ -7741,7 +6215,7 @@ class ApiMachineClient {
7741
6215
  event,
7742
6216
  payload
7743
6217
  };
7744
- const encryptedData = encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, eventData));
6218
+ const encryptedData = logger.encodeBase64(logger.encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, eventData));
7745
6219
  const rpcMethod = `${this.machine.id}:openclaw-tunnel-event`;
7746
6220
  this.socket.emit("rpc-call", {
7747
6221
  method: rpcMethod,
@@ -7757,12 +6231,12 @@ class ApiMachineClient {
7757
6231
  orchestratorCancel
7758
6232
  }) {
7759
6233
  this.rpcHandlerManager.registerHandler("spawn-happy-session", async (params) => {
7760
- const settings = await readSettings();
6234
+ const settings = await logger.readSettings();
7761
6235
  if (settings.deviceMode) {
7762
6236
  throw new Error("This machine is enrolled as a device and does not host sessions");
7763
6237
  }
7764
6238
  const { directory, sessionId, resumeSessionId, intent, sessionTitle, skipForkSession, machineId, approvedNewDirectoryCreation, agent, token, environmentVariables, worktreeBasePath, worktreeBranchName, workspaceRepos, workspacePath, repoScripts, mcpServers } = params || {};
7765
- logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
6239
+ logger.logger.debug(`[API MACHINE] Spawning session with params: ${JSON.stringify(params)}`);
7766
6240
  if (!directory) {
7767
6241
  throw new Error("Directory is required");
7768
6242
  }
@@ -7772,10 +6246,10 @@ class ApiMachineClient {
7772
6246
  this.claudeCache.invalidate();
7773
6247
  this.geminiCache.invalidate();
7774
6248
  this.codexCache.invalidate();
7775
- logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
6249
+ logger.logger.debug(`[API MACHINE] Spawned session ${result.sessionId}`);
7776
6250
  return { type: "success", sessionId: result.sessionId };
7777
6251
  case "requestToApproveDirectoryCreation":
7778
- logger.debug(`[API MACHINE] Requesting directory creation approval for: ${result.directory}`);
6252
+ logger.logger.debug(`[API MACHINE] Requesting directory creation approval for: ${result.directory}`);
7779
6253
  return { type: "requestToApproveDirectoryCreation", directory: result.directory };
7780
6254
  case "error":
7781
6255
  throw new Error(result.errorMessage);
@@ -7791,9 +6265,9 @@ class ApiMachineClient {
7791
6265
  const { worktreePath, basePath, branchName, archiveScript, deleteBranch } = repo;
7792
6266
  try {
7793
6267
  if (archiveScript) {
7794
- logger.info(`[DAEMON] Running archive script in ${worktreePath}...`);
6268
+ logger.logger.info(`[DAEMON] Running archive script in ${worktreePath}...`);
7795
6269
  node_child_process.execSync(archiveScript, { cwd: worktreePath, stdio: "pipe", timeout: 3e5 });
7796
- logger.info(`[DAEMON] Archive script completed for ${worktreePath}`);
6270
+ logger.logger.info(`[DAEMON] Archive script completed for ${worktreePath}`);
7797
6271
  }
7798
6272
  if (worktreePath !== basePath) {
7799
6273
  try {
@@ -7803,7 +6277,7 @@ class ApiMachineClient {
7803
6277
  timeout: 3e4
7804
6278
  });
7805
6279
  } catch (err) {
7806
- logger.warn(`[DAEMON] git worktree remove failed: ${err.message}`);
6280
+ logger.logger.warn(`[DAEMON] git worktree remove failed: ${err.message}`);
7807
6281
  }
7808
6282
  if (deleteBranch && branchName) {
7809
6283
  try {
@@ -7813,13 +6287,13 @@ class ApiMachineClient {
7813
6287
  timeout: 1e4
7814
6288
  });
7815
6289
  } catch (err) {
7816
- logger.warn(`[DAEMON] git branch -D failed: ${err.message}`);
6290
+ logger.logger.warn(`[DAEMON] git branch -D failed: ${err.message}`);
7817
6291
  }
7818
6292
  }
7819
6293
  }
7820
6294
  results.push({ repo: worktreePath, success: true });
7821
6295
  } catch (err) {
7822
- logger.warn(`[DAEMON] Archive failed for ${worktreePath}: ${err.message}`);
6296
+ logger.logger.warn(`[DAEMON] Archive failed for ${worktreePath}: ${err.message}`);
7823
6297
  results.push({ repo: worktreePath, success: false, error: err.message });
7824
6298
  }
7825
6299
  }
@@ -7828,7 +6302,7 @@ class ApiMachineClient {
7828
6302
  const entries = fs.readdirSync(workspacePath);
7829
6303
  if (entries.length === 0) {
7830
6304
  fs.rmdirSync(workspacePath);
7831
- logger.info(`[DAEMON] Removed empty workspace directory: ${workspacePath}`);
6305
+ logger.logger.info(`[DAEMON] Removed empty workspace directory: ${workspacePath}`);
7832
6306
  }
7833
6307
  } catch {
7834
6308
  }
@@ -7847,13 +6321,13 @@ class ApiMachineClient {
7847
6321
  this.claudeCache.invalidate();
7848
6322
  this.geminiCache.invalidate();
7849
6323
  this.codexCache.invalidate();
7850
- logger.debug(`[API MACHINE] Stopped session ${sessionId}`);
6324
+ logger.logger.debug(`[API MACHINE] Stopped session ${sessionId}`);
7851
6325
  return { message: "Session stopped" };
7852
6326
  });
7853
6327
  this.rpcHandlerManager.registerHandler("stop-daemon", () => {
7854
- logger.debug("[API MACHINE] Received stop-daemon RPC request");
6328
+ logger.logger.debug("[API MACHINE] Received stop-daemon RPC request");
7855
6329
  setTimeout(() => {
7856
- logger.debug("[API MACHINE] Initiating daemon shutdown from RPC");
6330
+ logger.logger.debug("[API MACHINE] Initiating daemon shutdown from RPC");
7857
6331
  requestShutdown();
7858
6332
  }, 100);
7859
6333
  return { message: "Daemon stop request acknowledged, starting shutdown sequence..." };
@@ -8091,21 +6565,21 @@ class ApiMachineClient {
8091
6565
  * for example to set a custom name.
8092
6566
  */
8093
6567
  async updateMachineMetadata(handler) {
8094
- await backoff(async () => {
6568
+ await time.backoff(async () => {
8095
6569
  const updated = handler(this.machine.metadata);
8096
6570
  const answer = await this.socket.emitWithAck("machine-update-metadata", {
8097
6571
  machineId: this.machine.id,
8098
- metadata: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
6572
+ metadata: logger.encodeBase64(logger.encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
8099
6573
  expectedVersion: this.machine.metadataVersion
8100
6574
  });
8101
6575
  if (answer.result === "success") {
8102
- this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
6576
+ this.machine.metadata = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(answer.metadata));
8103
6577
  this.machine.metadataVersion = answer.version;
8104
- logger.debug("[API MACHINE] Metadata updated successfully");
6578
+ logger.logger.debug("[API MACHINE] Metadata updated successfully");
8105
6579
  } else if (answer.result === "version-mismatch") {
8106
6580
  if (answer.version > this.machine.metadataVersion) {
8107
6581
  this.machine.metadataVersion = answer.version;
8108
- this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.metadata));
6582
+ this.machine.metadata = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(answer.metadata));
8109
6583
  }
8110
6584
  throw new Error("Metadata version mismatch");
8111
6585
  }
@@ -8116,29 +6590,29 @@ class ApiMachineClient {
8116
6590
  * Simplified without lock - relies on backoff for retry
8117
6591
  */
8118
6592
  async updateDaemonState(handler) {
8119
- await backoff(async () => {
6593
+ await time.backoff(async () => {
8120
6594
  const updated = handler(this.machine.daemonState);
8121
6595
  const answer = await this.socket.emitWithAck("machine-update-state", {
8122
6596
  machineId: this.machine.id,
8123
- daemonState: encodeBase64(encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
6597
+ daemonState: logger.encodeBase64(logger.encrypt(this.machine.encryptionKey, this.machine.encryptionVariant, updated)),
8124
6598
  expectedVersion: this.machine.daemonStateVersion
8125
6599
  });
8126
6600
  if (answer.result === "success") {
8127
- this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
6601
+ this.machine.daemonState = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(answer.daemonState));
8128
6602
  this.machine.daemonStateVersion = answer.version;
8129
- logger.debug("[API MACHINE] Daemon state updated successfully");
6603
+ logger.logger.debug("[API MACHINE] Daemon state updated successfully");
8130
6604
  } else if (answer.result === "version-mismatch") {
8131
6605
  if (answer.version > this.machine.daemonStateVersion) {
8132
6606
  this.machine.daemonStateVersion = answer.version;
8133
- this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(answer.daemonState));
6607
+ this.machine.daemonState = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(answer.daemonState));
8134
6608
  }
8135
6609
  throw new Error("Daemon state version mismatch");
8136
6610
  }
8137
6611
  });
8138
6612
  }
8139
6613
  connect() {
8140
- const serverUrl = configuration.serverUrl.replace(/^http/, "ws");
8141
- logger.debug(`[API MACHINE] Connecting to ${serverUrl}`);
6614
+ const serverUrl = logger.configuration.serverUrl.replace(/^http/, "ws");
6615
+ logger.logger.debug(`[API MACHINE] Connecting to ${serverUrl}`);
8142
6616
  this.socket = socket_ioClient.io(serverUrl, {
8143
6617
  transports: ["websocket"],
8144
6618
  auth: {
@@ -8152,7 +6626,7 @@ class ApiMachineClient {
8152
6626
  reconnectionDelayMax: 5e3
8153
6627
  });
8154
6628
  this.socket.on("connect", () => {
8155
- logger.debug("[API MACHINE] Connected to server");
6629
+ logger.logger.debug("[API MACHINE] Connected to server");
8156
6630
  this.updateDaemonState((state) => buildRunningDaemonState(
8157
6631
  state,
8158
6632
  this.currentRuntimeDaemonState ?? this.machine.daemonState
@@ -8161,36 +6635,36 @@ class ApiMachineClient {
8161
6635
  this.startKeepAlive();
8162
6636
  });
8163
6637
  this.socket.on("disconnect", () => {
8164
- logger.debug("[API MACHINE] Disconnected from server");
6638
+ logger.logger.debug("[API MACHINE] Disconnected from server");
8165
6639
  this.rpcHandlerManager.onSocketDisconnect();
8166
6640
  this.stopKeepAlive();
8167
6641
  });
8168
6642
  this.socket.on("rpc-request", async (data, callback) => {
8169
- logger.debugLargeJson(`[API MACHINE] Received RPC request:`, data);
6643
+ logger.logger.debugLargeJson(`[API MACHINE] Received RPC request:`, data);
8170
6644
  callback(await this.rpcHandlerManager.handleRequest(data));
8171
6645
  });
8172
6646
  this.socket.on("update", (data) => {
8173
6647
  if (data.body.t === "update-machine" && data.body.machineId === this.machine.id) {
8174
6648
  const update = data.body;
8175
6649
  if (update.metadata) {
8176
- logger.debug("[API MACHINE] Received external metadata update");
8177
- this.machine.metadata = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.metadata.value));
6650
+ logger.logger.debug("[API MACHINE] Received external metadata update");
6651
+ this.machine.metadata = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(update.metadata.value));
8178
6652
  this.machine.metadataVersion = update.metadata.version;
8179
6653
  }
8180
6654
  if (update.daemonState) {
8181
- logger.debug("[API MACHINE] Received external daemon state update");
8182
- this.machine.daemonState = decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, decodeBase64(update.daemonState.value));
6655
+ logger.logger.debug("[API MACHINE] Received external daemon state update");
6656
+ this.machine.daemonState = logger.decrypt(this.machine.encryptionKey, this.machine.encryptionVariant, logger.decodeBase64(update.daemonState.value));
8183
6657
  this.machine.daemonStateVersion = update.daemonState.version;
8184
6658
  }
8185
6659
  } else {
8186
- logger.debug(`[API MACHINE] Received unknown update type: ${data.body.t}`);
6660
+ logger.logger.debug(`[API MACHINE] Received unknown update type: ${data.body.t}`);
8187
6661
  }
8188
6662
  });
8189
6663
  this.socket.on("connect_error", (error) => {
8190
- logger.debug(`[API MACHINE] Connection error: ${error.message}`);
6664
+ logger.logger.debug(`[API MACHINE] Connection error: ${error.message}`);
8191
6665
  });
8192
6666
  this.socket.io.on("error", (error) => {
8193
- logger.debug("[API MACHINE] Socket error:", error);
6667
+ logger.logger.debug("[API MACHINE] Socket error:", error);
8194
6668
  });
8195
6669
  }
8196
6670
  startKeepAlive() {
@@ -8200,27 +6674,27 @@ class ApiMachineClient {
8200
6674
  machineId: this.machine.id,
8201
6675
  time: Date.now()
8202
6676
  };
8203
- if (isDebug()) {
8204
- logger.debugLargeJson(`[API MACHINE] Emitting machine-alive`, payload);
6677
+ if (logger.isDebug()) {
6678
+ logger.logger.debugLargeJson(`[API MACHINE] Emitting machine-alive`, payload);
8205
6679
  }
8206
6680
  this.socket.emit("machine-alive", payload);
8207
6681
  }, 2e4);
8208
- logger.debug("[API MACHINE] Keep-alive started (20s interval)");
6682
+ logger.logger.debug("[API MACHINE] Keep-alive started (20s interval)");
8209
6683
  }
8210
6684
  stopKeepAlive() {
8211
6685
  if (this.keepAliveInterval) {
8212
6686
  clearInterval(this.keepAliveInterval);
8213
6687
  this.keepAliveInterval = null;
8214
- logger.debug("[API MACHINE] Keep-alive stopped");
6688
+ logger.logger.debug("[API MACHINE] Keep-alive stopped");
8215
6689
  }
8216
6690
  }
8217
6691
  shutdown() {
8218
- logger.debug("[API MACHINE] Shutting down");
6692
+ logger.logger.debug("[API MACHINE] Shutting down");
8219
6693
  openClawTunnelManager.closeAll();
8220
6694
  this.stopKeepAlive();
8221
6695
  if (this.socket) {
8222
6696
  this.socket.close();
8223
- logger.debug("[API MACHINE] Socket closed");
6697
+ logger.logger.debug("[API MACHINE] Socket closed");
8224
6698
  }
8225
6699
  }
8226
6700
  }
@@ -8248,13 +6722,13 @@ class PushNotificationClient {
8248
6722
  }
8249
6723
  }
8250
6724
  );
8251
- logger.debug(`Fetched ${response.data.tokens.length} push tokens`);
6725
+ logger.logger.debug(`Fetched ${response.data.tokens.length} push tokens`);
8252
6726
  response.data.tokens.forEach((token, index) => {
8253
- logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
6727
+ logger.logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
8254
6728
  });
8255
6729
  return response.data.tokens;
8256
6730
  } catch (error) {
8257
- logger.debug("[PUSH] [ERROR] Failed to fetch push tokens:", error);
6731
+ logger.logger.debug("[PUSH] [ERROR] Failed to fetch push tokens:", error);
8258
6732
  throw new Error(`Failed to fetch push tokens: ${error instanceof Error ? error.message : "Unknown error"}`);
8259
6733
  }
8260
6734
  }
@@ -8263,7 +6737,7 @@ class PushNotificationClient {
8263
6737
  * @param messages - Array of push messages to send
8264
6738
  */
8265
6739
  async sendPushNotifications(messages) {
8266
- logger.debug(`Sending ${messages.length} push notifications`);
6740
+ logger.logger.debug(`Sending ${messages.length} push notifications`);
8267
6741
  const validMessages = messages.filter((message) => {
8268
6742
  if (Array.isArray(message.to)) {
8269
6743
  return message.to.every((token) => expoServerSdk.Expo.isExpoPushToken(token));
@@ -8271,7 +6745,7 @@ class PushNotificationClient {
8271
6745
  return expoServerSdk.Expo.isExpoPushToken(message.to);
8272
6746
  });
8273
6747
  if (validMessages.length === 0) {
8274
- logger.debug("No valid Expo push tokens found");
6748
+ logger.logger.debug("No valid Expo push tokens found");
8275
6749
  return;
8276
6750
  }
8277
6751
  const chunks = this.expo.chunkPushNotifications(validMessages);
@@ -8285,7 +6759,7 @@ class PushNotificationClient {
8285
6759
  const errors = ticketChunk.filter((ticket) => ticket.status === "error");
8286
6760
  if (errors.length > 0) {
8287
6761
  const errorDetails = errors.map((e) => ({ message: e.message, details: e.details }));
8288
- logger.debug("[PUSH] Some notifications failed:", errorDetails);
6762
+ logger.logger.debug("[PUSH] Some notifications failed:", errorDetails);
8289
6763
  }
8290
6764
  if (errors.length === ticketChunk.length) {
8291
6765
  throw new Error("All push notifications in chunk failed");
@@ -8294,7 +6768,7 @@ class PushNotificationClient {
8294
6768
  } catch (error) {
8295
6769
  const elapsed = Date.now() - startTime;
8296
6770
  if (elapsed >= timeout) {
8297
- logger.debug("[PUSH] Timeout reached after 5 minutes, giving up on chunk");
6771
+ logger.logger.debug("[PUSH] Timeout reached after 5 minutes, giving up on chunk");
8298
6772
  break;
8299
6773
  }
8300
6774
  attempt++;
@@ -8302,13 +6776,13 @@ class PushNotificationClient {
8302
6776
  const remainingTime = timeout - elapsed;
8303
6777
  const waitTime = Math.min(delay, remainingTime);
8304
6778
  if (waitTime > 0) {
8305
- logger.debug(`[PUSH] Retrying in ${waitTime}ms (attempt ${attempt})`);
6779
+ logger.logger.debug(`[PUSH] Retrying in ${waitTime}ms (attempt ${attempt})`);
8306
6780
  await new Promise((resolve) => setTimeout(resolve, waitTime));
8307
6781
  }
8308
6782
  }
8309
6783
  }
8310
6784
  }
8311
- logger.debug(`Push notifications sent successfully`);
6785
+ logger.logger.debug(`Push notifications sent successfully`);
8312
6786
  }
8313
6787
  /**
8314
6788
  * Increment the badge count on the server and return the new value
@@ -8327,7 +6801,7 @@ class PushNotificationClient {
8327
6801
  );
8328
6802
  return response.data.badgeCount;
8329
6803
  } catch (error) {
8330
- logger.debug("[PUSH] Failed to increment badge count:", error);
6804
+ logger.logger.debug("[PUSH] Failed to increment badge count:", error);
8331
6805
  return 1;
8332
6806
  }
8333
6807
  }
@@ -8338,24 +6812,24 @@ class PushNotificationClient {
8338
6812
  * @param data - Additional data to send with the notification
8339
6813
  */
8340
6814
  sendToAllDevices(title, body, data) {
8341
- logger.debug(`[PUSH] sendToAllDevices called with title: "${title}", body: "${body}"`);
6815
+ logger.logger.debug(`[PUSH] sendToAllDevices called with title: "${title}", body: "${body}"`);
8342
6816
  (async () => {
8343
6817
  try {
8344
- logger.debug("[PUSH] Fetching push tokens and incrementing badge...");
6818
+ logger.logger.debug("[PUSH] Fetching push tokens and incrementing badge...");
8345
6819
  const [tokens, badgeCount] = await Promise.all([
8346
6820
  this.fetchPushTokens(),
8347
6821
  this.incrementBadgeCount()
8348
6822
  ]);
8349
- logger.debug(`[PUSH] Fetched ${tokens.length} push tokens, badge: ${badgeCount}`);
6823
+ logger.logger.debug(`[PUSH] Fetched ${tokens.length} push tokens, badge: ${badgeCount}`);
8350
6824
  tokens.forEach((token, index) => {
8351
- logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}`);
6825
+ logger.logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}`);
8352
6826
  });
8353
6827
  if (tokens.length === 0) {
8354
- logger.debug("No push tokens found for user");
6828
+ logger.logger.debug("No push tokens found for user");
8355
6829
  return;
8356
6830
  }
8357
6831
  const messages = tokens.map((token, index) => {
8358
- logger.debug(`[PUSH] Creating message ${index + 1} for token`);
6832
+ logger.logger.debug(`[PUSH] Creating message ${index + 1} for token`);
8359
6833
  return {
8360
6834
  to: token.token,
8361
6835
  title,
@@ -8367,43 +6841,16 @@ class PushNotificationClient {
8367
6841
  badge: badgeCount
8368
6842
  };
8369
6843
  });
8370
- logger.debug(`[PUSH] Sending ${messages.length} push notifications...`);
6844
+ logger.logger.debug(`[PUSH] Sending ${messages.length} push notifications...`);
8371
6845
  await this.sendPushNotifications(messages);
8372
- logger.debug("[PUSH] Push notifications sent successfully");
6846
+ logger.logger.debug("[PUSH] Push notifications sent successfully");
8373
6847
  } catch (error) {
8374
- logger.debug("[PUSH] Error sending to all devices:", error);
6848
+ logger.logger.debug("[PUSH] Error sending to all devices:", error);
8375
6849
  }
8376
6850
  })();
8377
6851
  }
8378
6852
  }
8379
6853
 
8380
- function keyPath(sessionId) {
8381
- return path.join(configuration.sessionKeysDir, `${sessionId}.key`);
8382
- }
8383
- async function cacheSessionKey(sessionId, sessionAESKey, machineKey) {
8384
- if (!fs.existsSync(configuration.sessionKeysDir)) {
8385
- fs.mkdirSync(configuration.sessionKeysDir, { recursive: true });
8386
- }
8387
- const encrypted = encryptWithDataKey(encodeBase64(sessionAESKey), machineKey);
8388
- await promises.writeFile(keyPath(sessionId), encrypted);
8389
- }
8390
- function readCachedSessionKey(sessionId, machineKey) {
8391
- const p = keyPath(sessionId);
8392
- if (!fs.existsSync(p)) {
8393
- return null;
8394
- }
8395
- try {
8396
- const blob = new Uint8Array(fs.readFileSync(p));
8397
- const b64 = decryptWithDataKey(blob, machineKey);
8398
- if (typeof b64 !== "string") {
8399
- return null;
8400
- }
8401
- return decodeBase64(b64);
8402
- } catch {
8403
- return null;
8404
- }
8405
- }
8406
-
8407
6854
  function startOfflineReconnection(config) {
8408
6855
  let reconnected = false;
8409
6856
  let session = null;
@@ -8428,16 +6875,16 @@ function startOfflineReconnection(config) {
8428
6875
  if (cancelled) return;
8429
6876
  reconnected = true;
8430
6877
  config.onNotify("\u2705 Reconnected! Session syncing in background.");
8431
- logger.debug("[OfflineReconnection] Successfully reconnected");
6878
+ logger.logger.debug("[OfflineReconnection] Successfully reconnected");
8432
6879
  } catch (e) {
8433
6880
  if (axios.isAxiosError(e) && e.response?.status === 401) {
8434
- logger.debug("[OfflineReconnection] Authentication error, stopping retries");
6881
+ logger.logger.debug("[OfflineReconnection] Authentication error, stopping retries");
8435
6882
  config.onNotify("\u274C Authentication failed. Please re-authenticate with `happy auth`.");
8436
6883
  return;
8437
6884
  }
8438
6885
  failureCount++;
8439
- const delay = exponentialBackoffDelay(failureCount, 5e3, 6e4, 10);
8440
- logger.debug(`[OfflineReconnection] Attempt ${failureCount} failed, retrying in ${delay}ms`);
6886
+ const delay = time.exponentialBackoffDelay(failureCount, 5e3, 6e4, 10);
6887
+ logger.logger.debug(`[OfflineReconnection] Attempt ${failureCount} failed, retrying in ${delay}ms`);
8441
6888
  if (!cancelled) {
8442
6889
  timeoutId = setTimeout(attemptReconnect, delay);
8443
6890
  }
@@ -8537,7 +6984,7 @@ class ApiClient {
8537
6984
  pushClient;
8538
6985
  constructor(credential) {
8539
6986
  this.credential = credential;
8540
- this.pushClient = new PushNotificationClient(credential.token, configuration.serverUrl);
6987
+ this.pushClient = new PushNotificationClient(credential.token, logger.configuration.serverUrl);
8541
6988
  }
8542
6989
  /**
8543
6990
  * Create a new session or load existing one with the given tag
@@ -8547,9 +6994,9 @@ class ApiClient {
8547
6994
  let encryptionKey;
8548
6995
  let encryptionVariant;
8549
6996
  if (this.credential.encryption.type === "dataKey") {
8550
- encryptionKey = getRandomBytes(32);
6997
+ encryptionKey = logger.getRandomBytes(32);
8551
6998
  encryptionVariant = "dataKey";
8552
- let encryptedDataKey = libsodiumEncryptForPublicKey(encryptionKey, this.credential.encryption.publicKey);
6999
+ let encryptedDataKey = logger.libsodiumEncryptForPublicKey(encryptionKey, this.credential.encryption.publicKey);
8553
7000
  dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
8554
7001
  dataEncryptionKey.set([0], 0);
8555
7002
  dataEncryptionKey.set(encryptedDataKey, 1);
@@ -8559,12 +7006,12 @@ class ApiClient {
8559
7006
  }
8560
7007
  try {
8561
7008
  const response = await axios.post(
8562
- `${configuration.serverUrl}/v1/sessions`,
7009
+ `${logger.configuration.serverUrl}/v1/sessions`,
8563
7010
  {
8564
7011
  tag: opts.tag,
8565
- metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
8566
- agentState: opts.state ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.state)) : null,
8567
- dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : null
7012
+ metadata: logger.encodeBase64(logger.encrypt(encryptionKey, encryptionVariant, opts.metadata)),
7013
+ agentState: opts.state ? logger.encodeBase64(logger.encrypt(encryptionKey, encryptionVariant, opts.state)) : null,
7014
+ dataEncryptionKey: dataEncryptionKey ? logger.encodeBase64(dataEncryptionKey) : null
8568
7015
  },
8569
7016
  {
8570
7017
  headers: {
@@ -8575,25 +7022,25 @@ class ApiClient {
8575
7022
  // 1 minute timeout for very bad network connections
8576
7023
  }
8577
7024
  );
8578
- logger.debug(`Session created/loaded: ${response.data.session.id} (tag: ${opts.tag})`);
7025
+ logger.logger.debug(`Session created/loaded: ${response.data.session.id} (tag: ${opts.tag})`);
8579
7026
  let raw = response.data.session;
8580
7027
  let session = {
8581
7028
  id: raw.id,
8582
7029
  seq: raw.seq,
8583
- metadata: decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)),
7030
+ metadata: logger.decrypt(encryptionKey, encryptionVariant, logger.decodeBase64(raw.metadata)),
8584
7031
  metadataVersion: raw.metadataVersion,
8585
- agentState: raw.agentState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.agentState)) : null,
7032
+ agentState: raw.agentState ? logger.decrypt(encryptionKey, encryptionVariant, logger.decodeBase64(raw.agentState)) : null,
8586
7033
  agentStateVersion: raw.agentStateVersion,
8587
7034
  encryptionKey,
8588
7035
  encryptionVariant
8589
7036
  };
8590
7037
  if (this.credential.encryption.type === "dataKey") {
8591
- cacheSessionKey(raw.id, encryptionKey, this.credential.encryption.machineKey).catch(() => {
7038
+ sessionKeyCache.cacheSessionKey(raw.id, encryptionKey, this.credential.encryption.machineKey).catch(() => {
8592
7039
  });
8593
7040
  }
8594
7041
  return session;
8595
7042
  } catch (error) {
8596
- logger.debug("[API] [ERROR] Failed to get or create session:", error);
7043
+ logger.logger.debug("[API] [ERROR] Failed to get or create session:", error);
8597
7044
  if (error && typeof error === "object" && "code" in error) {
8598
7045
  const errorCode = error.code;
8599
7046
  if (isNetworkError(errorCode)) {
@@ -8601,7 +7048,7 @@ class ApiClient {
8601
7048
  operation: "Session creation",
8602
7049
  caller: "api.getOrCreateSession",
8603
7050
  errorCode,
8604
- url: `${configuration.serverUrl}/v1/sessions`
7051
+ url: `${logger.configuration.serverUrl}/v1/sessions`
8605
7052
  });
8606
7053
  return null;
8607
7054
  }
@@ -8611,7 +7058,7 @@ class ApiClient {
8611
7058
  connectionState.fail({
8612
7059
  operation: "Session creation",
8613
7060
  errorCode: "404",
8614
- url: `${configuration.serverUrl}/v1/sessions`
7061
+ url: `${logger.configuration.serverUrl}/v1/sessions`
8615
7062
  });
8616
7063
  return null;
8617
7064
  }
@@ -8621,7 +7068,7 @@ class ApiClient {
8621
7068
  connectionState.fail({
8622
7069
  operation: "Session creation",
8623
7070
  errorCode: String(status),
8624
- url: `${configuration.serverUrl}/v1/sessions`,
7071
+ url: `${logger.configuration.serverUrl}/v1/sessions`,
8625
7072
  details: ["Server encountered an error, will retry automatically"]
8626
7073
  });
8627
7074
  return null;
@@ -8641,7 +7088,7 @@ class ApiClient {
8641
7088
  if (this.credential.encryption.type === "dataKey") {
8642
7089
  encryptionVariant = "dataKey";
8643
7090
  encryptionKey = this.credential.encryption.machineKey;
8644
- let encryptedDataKey = libsodiumEncryptForPublicKey(this.credential.encryption.machineKey, this.credential.encryption.publicKey);
7091
+ let encryptedDataKey = logger.libsodiumEncryptForPublicKey(this.credential.encryption.machineKey, this.credential.encryption.publicKey);
8645
7092
  dataEncryptionKey = new Uint8Array(encryptedDataKey.length + 1);
8646
7093
  dataEncryptionKey.set([0], 0);
8647
7094
  dataEncryptionKey.set(encryptedDataKey, 1);
@@ -8660,12 +7107,12 @@ class ApiClient {
8660
7107
  });
8661
7108
  try {
8662
7109
  const response = await axios.post(
8663
- `${configuration.serverUrl}/v1/machines`,
7110
+ `${logger.configuration.serverUrl}/v1/machines`,
8664
7111
  {
8665
7112
  id: opts.machineId,
8666
- metadata: encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.metadata)),
8667
- daemonState: opts.daemonState ? encodeBase64(encrypt(encryptionKey, encryptionVariant, opts.daemonState)) : void 0,
8668
- dataEncryptionKey: dataEncryptionKey ? encodeBase64(dataEncryptionKey) : void 0,
7113
+ metadata: logger.encodeBase64(logger.encrypt(encryptionKey, encryptionVariant, opts.metadata)),
7114
+ daemonState: opts.daemonState ? logger.encodeBase64(logger.encrypt(encryptionKey, encryptionVariant, opts.daemonState)) : void 0,
7115
+ dataEncryptionKey: dataEncryptionKey ? logger.encodeBase64(dataEncryptionKey) : void 0,
8669
7116
  // Plaintext label so other clients can render a device list without
8670
7117
  // holding this machine's key. Everything else stays encrypted.
8671
7118
  displayName: opts.metadata.displayName || opts.metadata.host || void 0,
@@ -8683,14 +7130,14 @@ class ApiClient {
8683
7130
  }
8684
7131
  );
8685
7132
  const raw = response.data.machine;
8686
- logger.debug(`[API] Machine ${opts.machineId} registered/updated with server`);
7133
+ logger.logger.debug(`[API] Machine ${opts.machineId} registered/updated with server`);
8687
7134
  const machine = {
8688
7135
  id: raw.id,
8689
7136
  encryptionKey,
8690
7137
  encryptionVariant,
8691
- metadata: raw.metadata ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.metadata)) : null,
7138
+ metadata: raw.metadata ? logger.decrypt(encryptionKey, encryptionVariant, logger.decodeBase64(raw.metadata)) : null,
8692
7139
  metadataVersion: raw.metadataVersion || 0,
8693
- daemonState: raw.daemonState ? decrypt(encryptionKey, encryptionVariant, decodeBase64(raw.daemonState)) : null,
7140
+ daemonState: raw.daemonState ? logger.decrypt(encryptionKey, encryptionVariant, logger.decodeBase64(raw.daemonState)) : null,
8694
7141
  daemonStateVersion: raw.daemonStateVersion || 0
8695
7142
  };
8696
7143
  return machine;
@@ -8700,7 +7147,7 @@ class ApiClient {
8700
7147
  operation: "Machine registration",
8701
7148
  caller: "api.getOrCreateMachine",
8702
7149
  errorCode: error.code,
8703
- url: `${configuration.serverUrl}/v1/machines`
7150
+ url: `${logger.configuration.serverUrl}/v1/machines`
8704
7151
  });
8705
7152
  return createMinimalMachine();
8706
7153
  }
@@ -8728,7 +7175,7 @@ class ApiClient {
8728
7175
  connectionState.fail({
8729
7176
  operation: "Machine registration",
8730
7177
  errorCode: String(status),
8731
- url: `${configuration.serverUrl}/v1/machines`,
7178
+ url: `${logger.configuration.serverUrl}/v1/machines`,
8732
7179
  details: ["Server encountered an error, will retry automatically"]
8733
7180
  });
8734
7181
  return createMinimalMachine();
@@ -8737,7 +7184,7 @@ class ApiClient {
8737
7184
  connectionState.fail({
8738
7185
  operation: "Machine registration",
8739
7186
  errorCode: "404",
8740
- url: `${configuration.serverUrl}/v1/machines`
7187
+ url: `${logger.configuration.serverUrl}/v1/machines`
8741
7188
  });
8742
7189
  return createMinimalMachine();
8743
7190
  }
@@ -8759,7 +7206,7 @@ class ApiClient {
8759
7206
  */
8760
7207
  async reportOrchestratorExecutionStart(opts) {
8761
7208
  await axios.post(
8762
- `${configuration.serverUrl}/v1/orchestrator/executions/${opts.executionId}/start`,
7209
+ `${logger.configuration.serverUrl}/v1/orchestrator/executions/${opts.executionId}/start`,
8763
7210
  {
8764
7211
  dispatchToken: opts.dispatchToken,
8765
7212
  startedAt: opts.startedAt,
@@ -8779,7 +7226,7 @@ class ApiClient {
8779
7226
  */
8780
7227
  async reportOrchestratorExecutionFinish(opts) {
8781
7228
  await axios.post(
8782
- `${configuration.serverUrl}/v1/orchestrator/executions/${opts.executionId}/finish`,
7229
+ `${logger.configuration.serverUrl}/v1/orchestrator/executions/${opts.executionId}/finish`,
8783
7230
  {
8784
7231
  dispatchToken: opts.dispatchToken,
8785
7232
  status: opts.status,
@@ -8808,7 +7255,7 @@ class ApiClient {
8808
7255
  async registerVendorToken(vendor, apiKey) {
8809
7256
  try {
8810
7257
  const response = await axios.post(
8811
- `${configuration.serverUrl}/v1/connect/${vendor}/register`,
7258
+ `${logger.configuration.serverUrl}/v1/connect/${vendor}/register`,
8812
7259
  {
8813
7260
  token: JSON.stringify(apiKey)
8814
7261
  },
@@ -8823,9 +7270,9 @@ class ApiClient {
8823
7270
  if (response.status !== 200 && response.status !== 201) {
8824
7271
  throw new Error(`Server returned status ${response.status}`);
8825
7272
  }
8826
- logger.debug(`[API] Vendor token for ${vendor} registered successfully`);
7273
+ logger.logger.debug(`[API] Vendor token for ${vendor} registered successfully`);
8827
7274
  } catch (error) {
8828
- logger.debug(`[API] [ERROR] Failed to register vendor token:`, error);
7275
+ logger.logger.debug(`[API] [ERROR] Failed to register vendor token:`, error);
8829
7276
  throw new Error(`Failed to register vendor token: ${error instanceof Error ? error.message : "Unknown error"}`);
8830
7277
  }
8831
7278
  }
@@ -8838,7 +7285,7 @@ class ApiClient {
8838
7285
  async listMemories() {
8839
7286
  try {
8840
7287
  const response = await axios.get(
8841
- `${configuration.serverUrl}/v1/memory`,
7288
+ `${logger.configuration.serverUrl}/v1/memory`,
8842
7289
  {
8843
7290
  headers: {
8844
7291
  "Authorization": `Bearer ${this.credential.token}`,
@@ -8852,7 +7299,7 @@ class ApiClient {
8852
7299
  }
8853
7300
  return response.data.memories;
8854
7301
  } catch (err) {
8855
- logger.debug("[API] listMemories failed (continuing without memory injection):", err);
7302
+ logger.logger.debug("[API] listMemories failed (continuing without memory injection):", err);
8856
7303
  return [];
8857
7304
  }
8858
7305
  }
@@ -8863,7 +7310,7 @@ class ApiClient {
8863
7310
  async getVendorToken(vendor) {
8864
7311
  try {
8865
7312
  const response = await axios.get(
8866
- `${configuration.serverUrl}/v1/connect/${vendor}/token`,
7313
+ `${logger.configuration.serverUrl}/v1/connect/${vendor}/token`,
8867
7314
  {
8868
7315
  headers: {
8869
7316
  "Authorization": `Bearer ${this.credential.token}`,
@@ -8873,13 +7320,13 @@ class ApiClient {
8873
7320
  }
8874
7321
  );
8875
7322
  if (response.status === 404) {
8876
- logger.debug(`[API] No vendor token found for ${vendor}`);
7323
+ logger.logger.debug(`[API] No vendor token found for ${vendor}`);
8877
7324
  return null;
8878
7325
  }
8879
7326
  if (response.status !== 200) {
8880
7327
  throw new Error(`Server returned status ${response.status}`);
8881
7328
  }
8882
- logger.debug(`[API] Raw vendor token response:`, {
7329
+ logger.logger.debug(`[API] Raw vendor token response:`, {
8883
7330
  status: response.status,
8884
7331
  dataKeys: Object.keys(response.data || {}),
8885
7332
  hasToken: "token" in (response.data || {}),
@@ -8891,153 +7338,62 @@ class ApiClient {
8891
7338
  try {
8892
7339
  tokenData = JSON.parse(response.data.token);
8893
7340
  } catch (parseError) {
8894
- logger.debug(`[API] Failed to parse token as JSON, using as string:`, parseError);
7341
+ logger.logger.debug(`[API] Failed to parse token as JSON, using as string:`, parseError);
8895
7342
  tokenData = response.data.token;
8896
7343
  }
8897
7344
  } else if (response.data.token !== null) {
8898
7345
  tokenData = response.data.token;
8899
7346
  } else {
8900
- logger.debug(`[API] Token is null for ${vendor}, treating as not found`);
7347
+ logger.logger.debug(`[API] Token is null for ${vendor}, treating as not found`);
8901
7348
  return null;
8902
7349
  }
8903
7350
  } else if (response.data && typeof response.data === "object") {
8904
7351
  if (response.data.token === null && Object.keys(response.data).length === 1) {
8905
- logger.debug(`[API] Response contains only null token for ${vendor}, treating as not found`);
7352
+ logger.logger.debug(`[API] Response contains only null token for ${vendor}, treating as not found`);
8906
7353
  return null;
8907
7354
  }
8908
7355
  tokenData = response.data;
8909
7356
  }
8910
7357
  if (tokenData === null || tokenData && typeof tokenData === "object" && tokenData.token === null && Object.keys(tokenData).length === 1) {
8911
- logger.debug(`[API] Token data is null for ${vendor}`);
7358
+ logger.logger.debug(`[API] Token data is null for ${vendor}`);
8912
7359
  return null;
8913
7360
  }
8914
- logger.debug(`[API] Vendor token for ${vendor} retrieved successfully`, {
7361
+ logger.logger.debug(`[API] Vendor token for ${vendor} retrieved successfully`, {
8915
7362
  tokenDataType: typeof tokenData,
8916
7363
  tokenDataKeys: tokenData && typeof tokenData === "object" ? Object.keys(tokenData) : "not an object"
8917
7364
  });
8918
7365
  return tokenData;
8919
7366
  } catch (error) {
8920
7367
  if (error.response?.status === 404) {
8921
- logger.debug(`[API] No vendor token found for ${vendor}`);
7368
+ logger.logger.debug(`[API] No vendor token found for ${vendor}`);
8922
7369
  return null;
8923
7370
  }
8924
- logger.debug(`[API] [ERROR] Failed to get vendor token:`, error);
7371
+ logger.logger.debug(`[API] [ERROR] Failed to get vendor token:`, error);
8925
7372
  return null;
8926
7373
  }
8927
7374
  }
8928
7375
  }
8929
7376
 
8930
7377
  var api = /*#__PURE__*/Object.freeze({
8931
- __proto__: null,
8932
- ApiClient: ApiClient
7378
+ __proto__: null,
7379
+ ApiClient: ApiClient
8933
7380
  });
8934
7381
 
8935
- const UsageSchema = z.z.object({
8936
- input_tokens: z.z.number().int().nonnegative(),
8937
- cache_creation_input_tokens: z.z.number().int().nonnegative().optional(),
8938
- cache_read_input_tokens: z.z.number().int().nonnegative().optional(),
8939
- output_tokens: z.z.number().int().nonnegative(),
8940
- service_tier: z.z.string().nullish()
8941
- }).passthrough();
8942
- const RawJSONLinesSchema = z.z.discriminatedUnion("type", [
8943
- // User message - validates uuid and message.content
8944
- z.z.object({
8945
- type: z.z.literal("user"),
8946
- isSidechain: z.z.boolean().optional(),
8947
- isMeta: z.z.boolean().optional(),
8948
- uuid: z.z.string(),
8949
- // Used in getMessageKey()
8950
- message: z.z.object({
8951
- content: z.z.union([z.z.string(), z.z.any()])
8952
- // Used in sessionScanner.ts
8953
- }).passthrough()
8954
- }).passthrough(),
8955
- // Assistant message - only validates uuid and type
8956
- // message object is optional to handle synthetic error messages (isApiErrorMessage: true)
8957
- // which may have different structure than normal assistant messages
8958
- z.z.object({
8959
- uuid: z.z.string(),
8960
- type: z.z.literal("assistant"),
8961
- message: z.z.object({
8962
- usage: UsageSchema.optional(),
8963
- // Used in apiSession.ts
8964
- model: z.z.string().optional()
8965
- // Used for cost calculation
8966
- }).passthrough().optional()
8967
- }).passthrough(),
8968
- // Summary message - validates summary and leafUuid
8969
- z.z.object({
8970
- type: z.z.literal("summary"),
8971
- summary: z.z.string(),
8972
- // Used in apiSession.ts
8973
- leafUuid: z.z.string()
8974
- // Used in getMessageKey()
8975
- }).passthrough(),
8976
- // System message - validates uuid
8977
- z.z.object({
8978
- type: z.z.literal("system"),
8979
- uuid: z.z.string()
8980
- // Used in getMessageKey()
8981
- }).passthrough(),
8982
- // Progress message - hook progress events, not counted toward message limits
8983
- z.z.object({
8984
- type: z.z.literal("progress"),
8985
- uuid: z.z.string()
8986
- }).passthrough()
8987
- ]);
8988
-
8989
7382
  exports.ApiClient = ApiClient;
8990
7383
  exports.ApiSessionClient = ApiSessionClient;
8991
7384
  exports.AsyncLock = AsyncLock;
8992
- exports.GEMINI_MODEL_MODES = GEMINI_MODEL_MODES;
8993
7385
  exports.GeminiSessionWriter = GeminiSessionWriter;
8994
7386
  exports.InvalidateSync = InvalidateSync;
8995
- exports.MODEL_MODE_DEFAULT = MODEL_MODE_DEFAULT;
8996
- exports.RawJSONLinesSchema = RawJSONLinesSchema;
8997
- exports.acquireDaemonLock = acquireDaemonLock;
8998
7387
  exports.api = api;
8999
7388
  exports.buildResumeContextFromSessionLog = buildResumeContextFromSessionLog;
9000
- exports.clearCredentials = clearCredentials;
9001
- exports.clearDaemonState = clearDaemonState;
9002
- exports.clearMachineId = clearMachineId;
9003
- exports.configuration = configuration;
9004
7389
  exports.connectionState = connectionState;
9005
- exports.decodeBase64 = decodeBase64;
9006
- exports.decrypt = decrypt;
9007
- exports.decryptLegacy = decryptLegacy;
9008
- exports.decryptWithDataKey = decryptWithDataKey;
9009
- exports.delay = delay;
9010
- exports.encodeBase64 = encodeBase64;
9011
- exports.encodeBase64Url = encodeBase64Url;
9012
- exports.encrypt = encrypt;
9013
7390
  exports.extractUserText = extractUserText;
9014
7391
  exports.findClaudeProjectId = findClaudeProjectId;
9015
7392
  exports.findCodexSessionFile = findCodexSessionFile;
9016
7393
  exports.generateStableUuid = generateStableUuid;
9017
- exports.getLatestDaemonLog = getLatestDaemonLog;
9018
- exports.getProfileEnvironmentVariables = getProfileEnvironmentVariables;
9019
- exports.isDebug = isDebug;
9020
- exports.isModelModeForAgent = isModelModeForAgent;
9021
7394
  exports.isSystemMessage = isSystemMessage;
9022
- exports.libsodiumPublicKeyFromSecretKey = libsodiumPublicKeyFromSecretKey;
9023
- exports.logger = logger;
9024
- exports.packageJson = packageJson;
9025
- exports.parseClaudeModelMode = parseClaudeModelMode;
9026
- exports.parseCodexModelMode = parseCodexModelMode;
9027
- exports.persistence = persistence;
9028
- exports.projectPath = projectPath;
9029
- exports.readCachedSessionKey = readCachedSessionKey;
9030
- exports.readCredentials = readCredentials;
9031
- exports.readDaemonState = readDaemonState;
9032
7395
  exports.readGeminiSessionLog = readGeminiSessionLog;
9033
- exports.readSettings = readSettings;
9034
- exports.releaseDaemonLock = releaseDaemonLock;
9035
7396
  exports.resolveToolsDir = resolveToolsDir;
9036
7397
  exports.saveDiffRecords = saveDiffRecords;
9037
7398
  exports.saveToolOutputRecord = saveToolOutputRecord;
9038
7399
  exports.startOfflineReconnection = startOfflineReconnection;
9039
- exports.updateSettings = updateSettings;
9040
- exports.validateProfileForAgent = validateProfileForAgent;
9041
- exports.writeCredentialsDataKey = writeCredentialsDataKey;
9042
- exports.writeCredentialsLegacy = writeCredentialsLegacy;
9043
- exports.writeDaemonState = writeDaemonState;