@zonease/happy 0.6.37 → 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 (111) hide show
  1. package/dist/{types-DYCJXXdA.mjs → api-CIZKyfSn.mjs} +136 -1725
  2. package/dist/{types-BrTorNAy.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-D_g6ohaV.cjs → config-Draa-5XC.cjs} +21 -34
  16. package/dist/{config-DPn-cbpz.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.d.cts +16 -16
  51. package/dist/lib.d.mts +16 -16
  52. package/dist/lib.mjs +13 -7
  53. package/dist/{loadableToolOutput-lQH8Kb_w.mjs → loadableToolOutput-Cuygmd4K.mjs} +4 -2
  54. package/dist/{loadableToolOutput-CasonFIt.cjs → loadableToolOutput-DDCJjywt.cjs} +63 -61
  55. package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
  56. package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
  57. package/dist/persistence-BFjvtUad.mjs +944 -0
  58. package/dist/persistence-JLUn_Nou.cjs +996 -0
  59. package/dist/projectPath-BTBIMB57.mjs +10 -0
  60. package/dist/projectPath-ChLhdOyt.cjs +13 -0
  61. package/dist/prompt-BTWDZZO0.cjs +25 -0
  62. package/dist/prompt-BsAZsPbo.mjs +22 -0
  63. package/dist/release-BMEzNONE.mjs +168 -0
  64. package/dist/release-EhOJeAZe.cjs +171 -0
  65. package/dist/run-BDn2aE3Q.cjs +2152 -0
  66. package/dist/run-DBZqN6Kn.mjs +2128 -0
  67. package/dist/runClaude-DNHvERX0.mjs +3763 -0
  68. package/dist/runClaude-uaKxPZPm.cjs +3766 -0
  69. package/dist/{runCodex-BTt3fxG4.cjs → runCodex-82UrZLme.cjs} +169 -153
  70. package/dist/{runCodex-BXCB5trB.mjs → runCodex-C-RTM0wA.mjs} +36 -20
  71. package/dist/{runGemini-37HHbp9n.mjs → runGemini-Bm6-4Xm2.mjs} +34 -17
  72. package/dist/{runGemini-C-0nSFBv.cjs → runGemini-CXMr4Jwb.cjs} +212 -195
  73. package/dist/{runOneShot-CXhbFJ2j.cjs → runOneShot-1B6RMYT7.cjs} +31 -55
  74. package/dist/{runOneShot-USX8QPfE.mjs → runOneShot-ioARRHrx.mjs} +14 -38
  75. package/dist/{serve-DZAq-_1F.cjs → serve-BtdAhkIE.cjs} +35 -58
  76. package/dist/{serve-BRedJPzL.mjs → serve-CwibwU6N.mjs} +12 -35
  77. package/dist/session-2sU4Bu1R.mjs +108 -0
  78. package/dist/session-D--F87zL.cjs +110 -0
  79. package/dist/sessionKeyCache-4Tp8pJ3N.cjs +36 -0
  80. package/dist/sessionKeyCache-D2BwO91C.mjs +33 -0
  81. package/dist/sessionList-BCSw3qYt.mjs +51 -0
  82. package/dist/sessionList-ICJsjNtJ.cjs +54 -0
  83. package/dist/sessionSummary-Bkz52BPh.cjs +393 -0
  84. package/dist/sessionSummary-lHGBWQSb.mjs +387 -0
  85. package/dist/spawnHappyCLI-CoORX0YW.mjs +66 -0
  86. package/dist/spawnHappyCLI-D_V-AAoP.cjs +70 -0
  87. package/dist/ssh-BTOlhhxi.cjs +333 -0
  88. package/dist/ssh-DL_AkRAD.mjs +328 -0
  89. package/dist/systemdScope-BeOtAkhk.mjs +25 -0
  90. package/dist/systemdScope-DW3-UoKB.cjs +29 -0
  91. package/dist/task-CQzrHRZe.mjs +165 -0
  92. package/dist/task-CSpaC9HX.cjs +167 -0
  93. package/dist/time-Bj2HRkKH.cjs +33 -0
  94. package/dist/time-DgsBLJA_.mjs +29 -0
  95. package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
  96. package/dist/trimIdent-BAjmv_TG.mjs +20 -0
  97. package/dist/types-BoJh4Qfv.mjs +57 -0
  98. package/dist/types-DWeB7aqh.cjs +59 -0
  99. package/dist/uninstall-BiKyRAb1.cjs +77 -0
  100. package/dist/uninstall-nFMFGUVM.mjs +75 -0
  101. package/dist/update-BcqRHXf2.mjs +109 -0
  102. package/dist/update-Dw8pgsAT.cjs +111 -0
  103. package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
  104. package/dist/workflowCommon-Bl568-rt.cjs +62 -0
  105. package/dist/workflowReports-BEWuQesA.cjs +113 -0
  106. package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
  107. package/package.json +1 -1
  108. package/dist/index-BlkHOkB3.cjs +0 -11312
  109. package/dist/index-DJ2VpGiR.mjs +0 -11272
  110. package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
  111. package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
@@ -1,1268 +1,136 @@
1
1
  import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import axios from 'axios';
2
- import chalk from 'chalk';
3
- import { appendFileSync } from 'fs';
4
- import fs, { existsSync, mkdirSync, readdirSync, statSync, readFileSync, writeFileSync, mkdtempSync, chmodSync, constants, unlinkSync, createReadStream, createWriteStream, unlink as unlink$2, rmdirSync } from 'node:fs';
5
- import os, { homedir, tmpdir } from 'node:os';
6
- import path, { join, basename, dirname as dirname$1, resolve as resolve$1 } from 'node:path';
2
+ import { l as logger, c as configuration, f as encodeBase64, g as encrypt, h as decrypt, e as decodeBase64, i as isDebug, B as encryptLegacy, a as readSettings, C as getRandomBytes, D as libsodiumEncryptForPublicKey } from './persistence-BFjvtUad.mjs';
7
3
  import { EventEmitter } from 'node:events';
8
4
  import { io } from 'socket.io-client';
9
- import * as z from 'zod';
10
- import { z as z$1 } from 'zod';
11
- import { isCuid } from '@paralleldrive/cuid2';
12
- import { randomBytes, createHash, createCipheriv, createDecipheriv, randomUUID } from 'node:crypto';
13
- import tweetnacl from 'tweetnacl';
5
+ import { z } from 'zod';
6
+ import './index-CPKdvi7J.mjs';
7
+ import { b as backoff, e as exponentialBackoffDelay } from './time-DgsBLJA_.mjs';
8
+ import { randomUUID, createHash } from 'node:crypto';
9
+ import fs, { existsSync, readFileSync, writeFileSync, mkdirSync, statSync, readdirSync, mkdtempSync, chmodSync, createReadStream, createWriteStream, unlink as unlink$2, rmdirSync } from 'node:fs';
10
+ import path, { join, dirname, resolve as resolve$1, basename } from 'node:path';
14
11
  import { spawn, execFile, execSync, execFileSync } from 'node:child_process';
15
- import { readFile, rm, open, stat as stat$1, unlink as unlink$1, mkdir as mkdir$1, writeFile as writeFile$1, rename as rename$1, readdir as readdir$1, copyFile, appendFile as appendFile$1 } from 'node:fs/promises';
12
+ import { readFile, rm, open, writeFile as writeFile$1, rename as rename$1, unlink as unlink$1, stat as stat$1, readdir as readdir$1, copyFile, mkdir as mkdir$1, appendFile as appendFile$1 } from 'node:fs/promises';
13
+ import os, { tmpdir, homedir } from 'node:os';
16
14
  import { promisify } from 'node:util';
17
15
  import { spawn as spawn$1, exec } from 'child_process';
18
16
  import { promisify as promisify$1 } from 'util';
19
17
  import { readFile as readFile$1, writeFile, mkdir, rm as rm$1, stat, appendFile, rename, lstat, unlink, readdir } from 'fs/promises';
20
- import { dirname, resolve, join as join$1, sep } from 'path';
21
- import { fileURLToPath } from 'url';
18
+ import { resolve, join as join$1, dirname as dirname$1, sep } from 'path';
19
+ import { p as projectPath } from './projectPath-BTBIMB57.mjs';
22
20
  import { createRequire } from 'node:module';
23
21
  import WebSocket from 'ws';
24
22
  import { randomUUID as randomUUID$1 } from 'crypto';
23
+ import tweetnacl from 'tweetnacl';
25
24
  import { encode, decode } from '@stablelib/base64';
26
25
  import { createInterface } from 'node:readline';
27
26
  import { Expo } from 'expo-server-sdk';
27
+ import { c as cacheSessionKey } from './sessionKeyCache-D2BwO91C.mjs';
28
+ import chalk from 'chalk';
28
29
 
29
- const DEBUG_TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true"]);
30
- function isDebug() {
31
- return DEBUG_TRUE_VALUES.has(process.env.DEBUG?.toLowerCase() ?? "");
32
- }
33
-
34
- var name = "@zonease/happy";
35
- var version = "0.6.37";
36
- var description = "Mobile and Web client for Claude Code, Codex, and Gemini";
37
- var author = "ZonEaseTech";
38
- var license = "MIT";
39
- var type = "module";
40
- var homepage = "https://github.com/ZonEaseTech/happy-wfs";
41
- var bugs = "https://github.com/ZonEaseTech/happy-wfs/issues";
42
- var repository = {
43
- type: "git",
44
- url: "git+https://github.com/ZonEaseTech/happy-wfs.git",
45
- directory: "packages/happy-cli"
46
- };
47
- var bin = {
48
- happy: "./bin/happy.mjs",
49
- "happy-mcp": "./bin/happy-mcp.mjs"
50
- };
51
- var main = "./dist/index.cjs";
52
- var module$1 = "./dist/index.mjs";
53
- var types = "./dist/index.d.cts";
54
- var exports$1 = {
55
- ".": {
56
- require: {
57
- types: "./dist/index.d.cts",
58
- "default": "./dist/index.cjs"
59
- },
60
- "import": {
61
- types: "./dist/index.d.mts",
62
- "default": "./dist/index.mjs"
63
- }
64
- },
65
- "./lib": {
66
- require: {
67
- types: "./dist/lib.d.cts",
68
- "default": "./dist/lib.cjs"
69
- },
70
- "import": {
71
- types: "./dist/lib.d.mts",
72
- "default": "./dist/lib.mjs"
73
- }
74
- },
75
- "./codex/happyMcpStdioBridge": {
76
- require: {
77
- types: "./dist/codex/happyMcpStdioBridge.d.cts",
78
- "default": "./dist/codex/happyMcpStdioBridge.cjs"
79
- },
80
- "import": {
81
- types: "./dist/codex/happyMcpStdioBridge.d.mts",
82
- "default": "./dist/codex/happyMcpStdioBridge.mjs"
83
- }
84
- }
85
- };
86
- var files = [
87
- "dist",
88
- "bin",
89
- "scripts",
90
- "package.json"
91
- ];
92
- var scripts = {
93
- "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",
94
- typecheck: "tsc --noEmit",
95
- build: "shx rm -rf dist && tsc --noEmit && pkgroll",
96
- test: "$npm_execpath run build && vitest run",
97
- "test:integration": "$npm_execpath run build && vitest run --config vitest.integration.config.ts",
98
- start: "$npm_execpath run build && node ./bin/happy.mjs",
99
- dev: "tsx src/index.ts",
100
- "dev:local-server": "$npm_execpath run build && tsx --env-file .env.dev-local-server src/index.ts",
101
- "dev:integration-test-env": "$npm_execpath run build && tsx --env-file .env.integration-test src/index.ts",
102
- prepublishOnly: "$npm_execpath run build && $npm_execpath test",
103
- release: "$npm_execpath install && release-it",
104
- postinstall: "node scripts/unpack-tools.cjs",
105
- "// ==== Dev/Stable Variant Management ====": "",
106
- stable: "node scripts/env-wrapper.cjs stable",
107
- "dev:variant": "node scripts/env-wrapper.cjs dev",
108
- "// ==== Stable Version Quick Commands ====": "",
109
- "stable:daemon:start": "node scripts/env-wrapper.cjs stable daemon start",
110
- "stable:daemon:stop": "node scripts/env-wrapper.cjs stable daemon stop",
111
- "stable:daemon:status": "node scripts/env-wrapper.cjs stable daemon status",
112
- "stable:auth": "node scripts/env-wrapper.cjs stable auth",
113
- "// ==== Development Version Quick Commands ====": "",
114
- "dev:daemon:start": "node scripts/env-wrapper.cjs dev daemon start",
115
- "dev:daemon:stop": "node scripts/env-wrapper.cjs dev daemon stop",
116
- "dev:daemon:status": "node scripts/env-wrapper.cjs dev daemon status",
117
- "dev:auth": "node scripts/env-wrapper.cjs dev auth",
118
- "// ==== Setup ====": "",
119
- "setup:dev": "node scripts/setup-dev.cjs",
120
- doctor: "node scripts/env-wrapper.cjs stable doctor",
121
- "// ==== Development Linking ====": "",
122
- "link:dev": "node scripts/link-dev.cjs",
123
- "unlink:dev": "node scripts/link-dev.cjs unlink"
124
- };
125
- var dependencies = {
126
- "@agentclientprotocol/sdk": "^0.14.1",
127
- "@paralleldrive/cuid2": "^2.2.2",
128
- "@modelcontextprotocol/sdk": "^1.25.3",
129
- "@stablelib/base64": "^2.0.1",
130
- "@stablelib/hex": "^2.0.1",
131
- "@types/cross-spawn": "^6.0.6",
132
- "@types/http-proxy": "^1.17.17",
133
- "@types/qrcode-terminal": "^0.12.2",
134
- "@types/react": "^19.2.7",
135
- "@types/tmp": "^0.2.6",
136
- "@types/ws": "^8.18.1",
137
- ai: "^5.0.107",
138
- axios: "^1.13.2",
139
- chalk: "^5.6.2",
140
- "cross-spawn": "^7.0.6",
141
- "expo-server-sdk": "^3.15.0",
142
- fastify: "^5.6.2",
143
- "fastify-type-provider-zod": "4.0.2",
144
- "http-proxy": "^1.18.1",
145
- "http-proxy-middleware": "^3.0.5",
146
- ink: "^6.5.1",
147
- open: "^10.2.0",
148
- "ps-list": "^8.1.1",
149
- "qrcode-terminal": "^0.12.0",
150
- react: "^19.2.0",
151
- "socket.io-client": "^4.8.1",
152
- tar: "^7.5.2",
153
- tmp: "^0.2.5",
154
- tweetnacl: "^1.0.3",
155
- ws: "^8.19.0",
156
- zod: "3.25.76"
157
- };
158
- var devDependencies = {
159
- "@eslint/compat": "^1",
160
- "@types/node": ">=20",
161
- "cross-env": "^10.1.0",
162
- dotenv: "^16.6.1",
163
- eslint: "^9",
164
- "eslint-config-prettier": "^10",
165
- pkgroll: "^2.14.2",
166
- "release-it": "^19.0.6",
167
- shx: "^0.3.3",
168
- "ts-node": "^10",
169
- tsx: "^4.20.6",
170
- typescript: "5.9.3",
171
- vitest: "^3.2.4",
172
- "happy-wire": "*"
173
- };
174
- var resolutions = {
175
- "whatwg-url": "14.2.0",
176
- "parse-path": "7.0.3",
177
- "@types/parse-path": "7.0.3"
178
- };
179
- var publishConfig = {
180
- registry: "https://registry.npmjs.org",
181
- access: "public"
182
- };
183
- var packageManager = "yarn@1.22.22";
184
- var optionalDependencies = {
185
- "node-pty": "^1.0.0",
186
- "@zonease/happy-tools-arm64-darwin": "1.0.0",
187
- "@zonease/happy-tools-x64-darwin": "1.0.0",
188
- "@zonease/happy-tools-arm64-linux": "1.0.0",
189
- "@zonease/happy-tools-x64-linux": "1.0.0",
190
- "@zonease/happy-tools-x64-win32": "1.0.0",
191
- "@zonease/happy-tools-arm64-win32": "1.0.0"
192
- };
193
- var packageJson = {
194
- name: name,
195
- version: version,
196
- description: description,
197
- author: author,
198
- license: license,
199
- type: type,
200
- homepage: homepage,
201
- bugs: bugs,
202
- repository: repository,
203
- bin: bin,
204
- main: main,
205
- module: module$1,
206
- types: types,
207
- exports: exports$1,
208
- files: files,
209
- scripts: scripts,
210
- dependencies: dependencies,
211
- devDependencies: devDependencies,
212
- resolutions: resolutions,
213
- publishConfig: publishConfig,
214
- packageManager: packageManager,
215
- optionalDependencies: optionalDependencies
216
- };
217
-
218
- class Configuration {
219
- serverUrl;
220
- webappUrl;
221
- isDaemonProcess;
222
- // Directories and paths (from persistence)
223
- happyHomeDir;
224
- logsDir;
225
- settingsFile;
226
- privateKeyFile;
227
- daemonStateFile;
228
- daemonLockFile;
229
- sessionKeysDir;
230
- currentCliVersion;
231
- isExperimentalEnabled;
232
- disableCaffeinate;
233
- constructor() {
234
- this.serverUrl = process.env.HAPPY_SERVER_URL || "https://api-happy.zonease.org";
235
- this.webappUrl = process.env.HAPPY_WEBAPP_URL || "https://happy.zonease.org";
236
- const args = process.argv.slice(2);
237
- this.isDaemonProcess = args.length >= 2 && args[0] === "daemon" && args[1] === "start-sync";
238
- if (process.env.HAPPY_HOME_DIR) {
239
- const expandedPath = process.env.HAPPY_HOME_DIR.replace(/^~/, homedir());
240
- this.happyHomeDir = expandedPath;
241
- } else {
242
- this.happyHomeDir = join(homedir(), ".happy");
243
- }
244
- this.logsDir = join(this.happyHomeDir, "logs");
245
- this.settingsFile = join(this.happyHomeDir, "settings.json");
246
- this.privateKeyFile = join(this.happyHomeDir, "access.key");
247
- this.daemonStateFile = join(this.happyHomeDir, "daemon.state.json");
248
- this.daemonLockFile = join(this.happyHomeDir, "daemon.state.json.lock");
249
- this.sessionKeysDir = join(this.happyHomeDir, "session-keys");
250
- this.isExperimentalEnabled = ["true", "1", "yes"].includes(process.env.HAPPY_EXPERIMENTAL?.toLowerCase() || "");
251
- this.disableCaffeinate = ["true", "1", "yes"].includes(process.env.HAPPY_DISABLE_CAFFEINATE?.toLowerCase() || "");
252
- this.currentCliVersion = packageJson.version;
253
- const variant = process.env.HAPPY_VARIANT || "stable";
254
- if (variant === "dev" && !this.happyHomeDir.includes("dev")) {
255
- console.warn('\u26A0\uFE0F WARNING: HAPPY_VARIANT=dev but HAPPY_HOME_DIR does not contain "dev"');
256
- console.warn(` Current: ${this.happyHomeDir}`);
257
- console.warn(` Expected: Should contain "dev" (e.g., ~/.happy-dev)`);
258
- }
259
- if (!this.isDaemonProcess && variant === "dev") {
260
- console.log("\x1B[33m\u{1F527} DEV MODE\x1B[0m - Data: " + this.happyHomeDir);
261
- }
262
- if (!existsSync(this.happyHomeDir)) {
263
- mkdirSync(this.happyHomeDir, { recursive: true });
264
- }
265
- if (!existsSync(this.logsDir)) {
266
- mkdirSync(this.logsDir, { recursive: true });
267
- }
268
- }
269
- }
270
- const configuration = new Configuration();
271
-
272
- function createTimestampForFilename(date = /* @__PURE__ */ new Date()) {
273
- return date.toLocaleString("sv-SE", {
274
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
275
- year: "numeric",
276
- month: "2-digit",
277
- day: "2-digit",
278
- hour: "2-digit",
279
- minute: "2-digit",
280
- second: "2-digit"
281
- }).replace(/[: ]/g, "-").replace(/,/g, "") + "-pid-" + process.pid;
282
- }
283
- function createTimestampForLogEntry(date = /* @__PURE__ */ new Date()) {
284
- return date.toLocaleTimeString("en-US", {
285
- timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
286
- hour12: false,
287
- hour: "2-digit",
288
- minute: "2-digit",
289
- second: "2-digit",
290
- fractionalSecondDigits: 3
291
- });
292
- }
293
- function getSessionLogPath() {
294
- const timestamp = createTimestampForFilename();
295
- const filename = configuration.isDaemonProcess ? `${timestamp}-daemon.log` : `${timestamp}.log`;
296
- return join(configuration.logsDir, filename);
297
- }
298
- class Logger {
299
- constructor(logFilePath = getSessionLogPath()) {
300
- this.logFilePath = logFilePath;
301
- if (process.env.DANGEROUSLY_LOG_TO_SERVER_FOR_AI_AUTO_DEBUGGING && process.env.HAPPY_SERVER_URL) {
302
- this.dangerouslyUnencryptedServerLoggingUrl = process.env.HAPPY_SERVER_URL;
303
- console.log(chalk.yellow("[REMOTE LOGGING] Sending logs to server for AI debugging"));
304
- }
305
- }
306
- dangerouslyUnencryptedServerLoggingUrl;
307
- // Use local timezone for simplicity of locating the logs,
308
- // in practice you will not need absolute timestamps
309
- localTimezoneTimestamp() {
310
- return createTimestampForLogEntry();
311
- }
312
- debug(message, ...args) {
313
- this.logToFile(`[${this.localTimezoneTimestamp()}]`, message, ...args);
314
- }
315
- debugLargeJson(message, object, maxStringLength = 100, maxArrayLength = 10) {
316
- if (!isDebug()) {
317
- this.debug(`In production, skipping message inspection`);
318
- }
319
- const truncateStrings = (obj) => {
320
- if (typeof obj === "string") {
321
- return obj.length > maxStringLength ? obj.substring(0, maxStringLength) + "... [truncated for logs]" : obj;
322
- }
323
- if (Array.isArray(obj)) {
324
- const truncatedArray = obj.map((item) => truncateStrings(item)).slice(0, maxArrayLength);
325
- if (obj.length > maxArrayLength) {
326
- truncatedArray.push(`... [truncated array for logs up to ${maxArrayLength} items]`);
327
- }
328
- return truncatedArray;
329
- }
330
- if (obj && typeof obj === "object") {
331
- const result = {};
332
- for (const [key, value] of Object.entries(obj)) {
333
- if (key === "usage") {
334
- continue;
335
- }
336
- result[key] = truncateStrings(value);
337
- }
338
- return result;
339
- }
340
- return obj;
341
- };
342
- const truncatedObject = truncateStrings(object);
343
- const json = JSON.stringify(truncatedObject, null, 2);
344
- this.logToFile(`[${this.localTimezoneTimestamp()}]`, message, "\n", json);
345
- }
346
- info(message, ...args) {
347
- this.logToConsole("info", "", message, ...args);
348
- this.debug(message, args);
349
- }
350
- infoDeveloper(message, ...args) {
351
- this.debug(message, ...args);
352
- if (isDebug()) {
353
- this.logToConsole("info", "[DEV]", message, ...args);
354
- }
355
- }
356
- warn(message, ...args) {
357
- this.logToConsole("warn", "", message, ...args);
358
- this.debug(`[WARN] ${message}`, ...args);
359
- }
360
- getLogPath() {
361
- return this.logFilePath;
362
- }
363
- logToConsole(level, prefix, message, ...args) {
364
- switch (level) {
365
- case "debug": {
366
- console.log(chalk.gray(prefix), message, ...args);
367
- break;
368
- }
369
- case "error": {
370
- console.error(chalk.red(prefix), message, ...args);
371
- break;
372
- }
373
- case "info": {
374
- console.log(chalk.blue(prefix), message, ...args);
375
- break;
376
- }
377
- case "warn": {
378
- console.log(chalk.yellow(prefix), message, ...args);
379
- break;
380
- }
381
- default: {
382
- this.debug("Unknown log level:", level);
383
- console.log(chalk.blue(prefix), message, ...args);
384
- break;
385
- }
386
- }
387
- }
388
- async sendToRemoteServer(level, message, ...args) {
389
- if (!this.dangerouslyUnencryptedServerLoggingUrl) return;
390
- try {
391
- await fetch(this.dangerouslyUnencryptedServerLoggingUrl + "/logs-combined-from-cli-and-mobile-for-simple-ai-debugging", {
392
- method: "POST",
393
- headers: { "Content-Type": "application/json" },
394
- body: JSON.stringify({
395
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
396
- level,
397
- message: `${message} ${args.map(
398
- (a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)
399
- ).join(" ")}`,
400
- source: "cli",
401
- platform: process.platform
402
- })
403
- });
404
- } catch (error) {
405
- }
406
- }
407
- logToFile(prefix, message, ...args) {
408
- const logLine = `${prefix} ${message} ${args.map((arg) => {
409
- if (typeof arg === "string") return arg;
410
- if (arg instanceof Error) return `${arg.message}
411
- ${arg.stack ?? ""}`;
412
- return JSON.stringify(arg);
413
- }).join(" ")}
414
- `;
415
- if (this.dangerouslyUnencryptedServerLoggingUrl) {
416
- let level = "info";
417
- if (prefix.includes(this.localTimezoneTimestamp())) {
418
- level = "debug";
419
- }
420
- this.sendToRemoteServer(level, message, ...args).catch(() => {
421
- });
422
- }
423
- try {
424
- appendFileSync(this.logFilePath, logLine);
425
- } catch (appendError) {
426
- if (isDebug()) {
427
- console.error("[DEV MODE ONLY THROWING] Failed to append to log file:", appendError);
428
- throw appendError;
429
- }
430
- }
431
- }
432
- }
433
- let logger = new Logger();
434
- async function listDaemonLogFiles(limit = 50) {
435
- try {
436
- const logsDir = configuration.logsDir;
437
- if (!existsSync(logsDir)) {
438
- return [];
439
- }
440
- const logs = readdirSync(logsDir).filter((file) => file.endsWith("-daemon.log")).map((file) => {
441
- const fullPath = join(logsDir, file);
442
- const stats = statSync(fullPath);
443
- return { file, path: fullPath, modified: stats.mtime };
444
- }).sort((a, b) => b.modified.getTime() - a.modified.getTime());
445
- try {
446
- const { readDaemonState } = await Promise.resolve().then(function () { return persistence; });
447
- const state = await readDaemonState();
448
- if (!state) {
449
- return logs;
450
- }
451
- if (state.daemonLogPath && existsSync(state.daemonLogPath)) {
452
- const stats = statSync(state.daemonLogPath);
453
- const persisted = {
454
- file: basename(state.daemonLogPath),
455
- path: state.daemonLogPath,
456
- modified: stats.mtime
457
- };
458
- const idx = logs.findIndex((l) => l.path === persisted.path);
459
- if (idx >= 0) {
460
- const [found] = logs.splice(idx, 1);
461
- logs.unshift(found);
462
- } else {
463
- logs.unshift(persisted);
464
- }
465
- }
466
- } catch {
467
- }
468
- return logs.slice(0, Math.max(0, limit));
469
- } catch {
470
- return [];
471
- }
472
- }
473
- async function getLatestDaemonLog() {
474
- const [latest] = await listDaemonLogFiles(1);
475
- return latest || null;
476
- }
477
-
478
- const sessionRoleSchema = z.enum(["user", "agent"]);
479
- const sessionTextEventSchema = z.object({
480
- t: z.literal("text"),
481
- text: z.string(),
482
- thinking: z.boolean().optional()
483
- });
484
- const sessionServiceMessageEventSchema = z.object({
485
- t: z.literal("service"),
486
- text: z.string()
487
- });
488
- const sessionToolCallStartEventSchema = z.object({
489
- t: z.literal("tool-call-start"),
490
- call: z.string(),
491
- name: z.string(),
492
- title: z.string(),
493
- description: z.string(),
494
- args: z.record(z.string(), z.unknown())
495
- });
496
- const sessionToolCallEndEventSchema = z.object({
497
- t: z.literal("tool-call-end"),
498
- call: z.string()
499
- });
500
- const sessionFileEventSchema = z.object({
501
- t: z.literal("file"),
502
- ref: z.string(),
503
- name: z.string(),
504
- size: z.number(),
505
- image: z.object({
506
- width: z.number(),
507
- height: z.number(),
508
- thumbhash: z.string()
509
- }).optional()
510
- });
511
- const sessionTurnStartEventSchema = z.object({
512
- t: z.literal("turn-start")
513
- });
514
- const sessionStartEventSchema = z.object({
515
- t: z.literal("start"),
516
- title: z.string().optional()
517
- });
518
- const sessionTurnEndStatusSchema = z.enum(["completed", "failed", "cancelled"]);
519
- const sessionTurnEndEventSchema = z.object({
520
- t: z.literal("turn-end"),
521
- status: sessionTurnEndStatusSchema
522
- });
523
- const sessionStopEventSchema = z.object({
524
- t: z.literal("stop")
525
- });
526
- const sessionEventSchema = z.discriminatedUnion("t", [
527
- sessionTextEventSchema,
528
- sessionServiceMessageEventSchema,
529
- sessionToolCallStartEventSchema,
530
- sessionToolCallEndEventSchema,
531
- sessionFileEventSchema,
532
- sessionTurnStartEventSchema,
533
- sessionStartEventSchema,
534
- sessionTurnEndEventSchema,
535
- sessionStopEventSchema
536
- ]);
537
- const sessionEnvelopeSchema = z.object({
538
- id: z.string(),
539
- time: z.number(),
540
- role: sessionRoleSchema,
541
- turn: z.string().optional(),
542
- subagent: z.string().refine((value) => isCuid(value), {
543
- message: "subagent must be a cuid2 value"
544
- }).optional(),
545
- ev: sessionEventSchema
546
- }).superRefine((envelope, ctx) => {
547
- if (envelope.ev.t === "service" && envelope.role !== "agent") {
548
- ctx.addIssue({
549
- code: z.ZodIssueCode.custom,
550
- message: 'service events must use role "agent"',
551
- path: ["role"]
552
- });
553
- }
554
- if ((envelope.ev.t === "start" || envelope.ev.t === "stop") && envelope.role !== "agent") {
555
- ctx.addIssue({
556
- code: z.ZodIssueCode.custom,
557
- message: `${envelope.ev.t} events must use role "agent"`,
558
- path: ["role"]
559
- });
560
- }
561
- });
562
- const MessageMetaSchema$1 = z.object({
563
- sentFrom: z.string().optional(),
564
- permissionMode: z.enum(["default", "acceptEdits", "bypassPermissions", "plan", "read-only", "safe-yolo", "yolo"]).optional(),
565
- model: z.string().nullable().optional(),
566
- fallbackModel: z.string().nullable().optional(),
567
- reasoningEffort: z.string().nullable().optional(),
568
- customSystemPrompt: z.string().nullable().optional(),
569
- appendSystemPrompt: z.string().nullable().optional(),
570
- allowedTools: z.array(z.string()).nullable().optional(),
571
- disallowedTools: z.array(z.string()).nullable().optional(),
572
- displayText: z.string().optional()
573
- });
574
- const UserMessageSchema$1 = z.object({
575
- role: z.literal("user"),
576
- content: z.object({
577
- type: z.literal("text"),
578
- text: z.string()
579
- }),
580
- localKey: z.string().optional(),
581
- meta: MessageMetaSchema$1.optional()
582
- });
583
- const AgentMessageSchema$1 = z.object({
584
- role: z.literal("agent"),
585
- content: z.object({
586
- type: z.string()
587
- }).passthrough(),
588
- meta: MessageMetaSchema$1.optional()
589
- });
590
- z.discriminatedUnion("role", [UserMessageSchema$1, AgentMessageSchema$1]);
591
- const SessionMessageContentSchema = z.object({
592
- c: z.string(),
593
- t: z.literal("encrypted")
594
- });
595
- const SessionMessageSchema = z.object({
596
- id: z.string(),
597
- seq: z.number(),
598
- localId: z.string().nullish(),
599
- content: SessionMessageContentSchema,
600
- createdAt: z.number(),
601
- updatedAt: z.number()
602
- });
603
- const SessionProtocolMessageSchema = z.object({
604
- role: z.literal("session"),
605
- content: sessionEnvelopeSchema,
606
- meta: MessageMetaSchema$1.optional()
607
- });
608
- z.discriminatedUnion("role", [
609
- UserMessageSchema$1,
610
- AgentMessageSchema$1,
611
- SessionProtocolMessageSchema
612
- ]);
613
- const VersionedEncryptedValueSchema = z.object({
614
- version: z.number(),
615
- value: z.string()
616
- });
617
- const VersionedNullableEncryptedValueSchema = z.object({
618
- version: z.number(),
619
- value: z.string().nullable()
620
- });
621
- const UpdateNewMessageBodySchema = z.object({
622
- t: z.literal("new-message"),
623
- sid: z.string(),
624
- message: SessionMessageSchema
625
- });
626
- const UpdateSessionBodySchema = z.object({
627
- t: z.literal("update-session"),
628
- id: z.string(),
629
- metadata: VersionedEncryptedValueSchema.nullish(),
630
- agentState: VersionedNullableEncryptedValueSchema.nullish()
631
- });
632
- const VersionedMachineEncryptedValueSchema = z.object({
633
- version: z.number(),
634
- value: z.string()
635
- });
636
- const UpdateMachineBodySchema = z.object({
637
- t: z.literal("update-machine"),
638
- machineId: z.string(),
639
- metadata: VersionedMachineEncryptedValueSchema.nullish(),
640
- daemonState: VersionedMachineEncryptedValueSchema.nullish(),
641
- active: z.boolean().optional(),
642
- activeAt: z.number().optional()
643
- });
644
- const CoreUpdateBodySchema = z.discriminatedUnion("t", [
645
- UpdateNewMessageBodySchema,
646
- UpdateSessionBodySchema,
647
- UpdateMachineBodySchema
648
- ]);
649
30
  z.object({
650
- id: z.string(),
651
- seq: z.number(),
652
- body: CoreUpdateBodySchema,
653
- createdAt: z.number()
654
- });
655
- const MODEL_MODE_DEFAULT = "default";
656
- const MODEL_MODES = [
657
- MODEL_MODE_DEFAULT,
658
- "claude-fable-5",
659
- "claude-fable-5[1m]",
660
- "claude-opus-5",
661
- "claude-opus-5[1m]",
662
- "claude-opus-4-8",
663
- "claude-opus-4-8[1m]",
664
- "claude-opus-4-6",
665
- "claude-opus-4-6[1m]",
666
- "claude-sonnet-4-6",
667
- "claude-sonnet-4-6[1m]",
668
- "claude-haiku-4-5",
669
- "claude-fable-5-low",
670
- "claude-fable-5-medium",
671
- "claude-fable-5-high",
672
- "claude-fable-5-xhigh",
673
- "claude-fable-5-max",
674
- "claude-fable-5[1m]-low",
675
- "claude-fable-5[1m]-medium",
676
- "claude-fable-5[1m]-high",
677
- "claude-fable-5[1m]-xhigh",
678
- "claude-fable-5[1m]-max",
679
- "claude-opus-5-low",
680
- "claude-opus-5-medium",
681
- "claude-opus-5-high",
682
- "claude-opus-5-xhigh",
683
- "claude-opus-5-max",
684
- "claude-opus-5[1m]-low",
685
- "claude-opus-5[1m]-medium",
686
- "claude-opus-5[1m]-high",
687
- "claude-opus-5[1m]-xhigh",
688
- "claude-opus-5[1m]-max",
689
- "claude-opus-4-8-low",
690
- "claude-opus-4-8-medium",
691
- "claude-opus-4-8-high",
692
- "claude-opus-4-8-xhigh",
693
- "claude-opus-4-8-max",
694
- "claude-opus-4-8[1m]-low",
695
- "claude-opus-4-8[1m]-medium",
696
- "claude-opus-4-8[1m]-high",
697
- "claude-opus-4-8[1m]-xhigh",
698
- "claude-opus-4-8[1m]-max",
699
- "claude-opus-4-6-low",
700
- "claude-opus-4-6-medium",
701
- "claude-opus-4-6-high",
702
- "claude-opus-4-6-max",
703
- "claude-opus-4-6[1m]-low",
704
- "claude-opus-4-6[1m]-medium",
705
- "claude-opus-4-6[1m]-high",
706
- "claude-opus-4-6[1m]-max",
707
- "claude-sonnet-4-6-low",
708
- "claude-sonnet-4-6-medium",
709
- "claude-sonnet-4-6-high",
710
- "claude-sonnet-4-6[1m]-low",
711
- "claude-sonnet-4-6[1m]-medium",
712
- "claude-sonnet-4-6[1m]-high",
713
- "claude-haiku-4-5-low",
714
- "claude-haiku-4-5-medium",
715
- "claude-haiku-4-5-high",
716
- "gpt-5.6-sol-low",
717
- "gpt-5.6-sol-medium",
718
- "gpt-5.6-sol-high",
719
- "gpt-5.6-sol-xhigh",
720
- "gpt-5.6-sol-max",
721
- "gpt-5.6-terra-low",
722
- "gpt-5.6-terra-medium",
723
- "gpt-5.6-terra-high",
724
- "gpt-5.6-terra-xhigh",
725
- "gpt-5.6-luna-low",
726
- "gpt-5.6-luna-medium",
727
- "gpt-5.6-luna-high",
728
- "gpt-5.6-luna-xhigh",
729
- "gpt-5.5-low",
730
- "gpt-5.5-medium",
731
- "gpt-5.5-high",
732
- "gpt-5.5-xhigh",
733
- "gpt-5.4-low",
734
- "gpt-5.4-medium",
735
- "gpt-5.4-high",
736
- "gpt-5.4-xhigh",
737
- "gpt-5.3-codex-low",
738
- "gpt-5.3-codex-medium",
739
- "gpt-5.3-codex-high",
740
- "gpt-5.3-codex-xhigh",
741
- "gpt-5.2-codex-low",
742
- "gpt-5.2-codex-medium",
743
- "gpt-5.2-codex-high",
744
- "gpt-5.2-codex-xhigh",
745
- "gpt-5.2-low",
746
- "gpt-5.2-medium",
747
- "gpt-5.2-high",
748
- "gpt-5.2-xhigh",
749
- "gpt-5.1-codex-max-low",
750
- "gpt-5.1-codex-max-medium",
751
- "gpt-5.1-codex-max-high",
752
- "gpt-5.1-codex-max-xhigh",
753
- "gpt-5.1-codex-mini-medium",
754
- "gpt-5.1-codex-mini-high",
755
- "gemini-3-pro-preview",
756
- "gemini-3-flash-preview",
757
- "gemini-2.5-pro"
758
- ];
759
- const CLAUDE_MODEL_MODES = [
760
- MODEL_MODE_DEFAULT,
761
- "claude-fable-5",
762
- "claude-fable-5[1m]",
763
- "claude-opus-5",
764
- "claude-opus-5[1m]",
765
- "claude-opus-4-8",
766
- "claude-opus-4-8[1m]",
767
- "claude-opus-4-6",
768
- "claude-opus-4-6[1m]",
769
- "claude-sonnet-4-6",
770
- "claude-sonnet-4-6[1m]",
771
- "claude-haiku-4-5",
772
- "claude-fable-5-low",
773
- "claude-fable-5-medium",
774
- "claude-fable-5-high",
775
- "claude-fable-5-xhigh",
776
- "claude-fable-5-max",
777
- "claude-fable-5[1m]-low",
778
- "claude-fable-5[1m]-medium",
779
- "claude-fable-5[1m]-high",
780
- "claude-fable-5[1m]-xhigh",
781
- "claude-fable-5[1m]-max",
782
- "claude-opus-5-low",
783
- "claude-opus-5-medium",
784
- "claude-opus-5-high",
785
- "claude-opus-5-xhigh",
786
- "claude-opus-5-max",
787
- "claude-opus-5[1m]-low",
788
- "claude-opus-5[1m]-medium",
789
- "claude-opus-5[1m]-high",
790
- "claude-opus-5[1m]-xhigh",
791
- "claude-opus-5[1m]-max",
792
- "claude-opus-4-8-low",
793
- "claude-opus-4-8-medium",
794
- "claude-opus-4-8-high",
795
- "claude-opus-4-8-xhigh",
796
- "claude-opus-4-8-max",
797
- "claude-opus-4-8[1m]-low",
798
- "claude-opus-4-8[1m]-medium",
799
- "claude-opus-4-8[1m]-high",
800
- "claude-opus-4-8[1m]-xhigh",
801
- "claude-opus-4-8[1m]-max",
802
- "claude-opus-4-6-low",
803
- "claude-opus-4-6-medium",
804
- "claude-opus-4-6-high",
805
- "claude-opus-4-6-max",
806
- "claude-opus-4-6[1m]-low",
807
- "claude-opus-4-6[1m]-medium",
808
- "claude-opus-4-6[1m]-high",
809
- "claude-opus-4-6[1m]-max",
810
- "claude-sonnet-4-6-low",
811
- "claude-sonnet-4-6-medium",
812
- "claude-sonnet-4-6-high",
813
- "claude-sonnet-4-6[1m]-low",
814
- "claude-sonnet-4-6[1m]-medium",
815
- "claude-sonnet-4-6[1m]-high",
816
- "claude-haiku-4-5-low",
817
- "claude-haiku-4-5-medium",
818
- "claude-haiku-4-5-high"
819
- ];
820
- const GEMINI_MODEL_MODES = [
821
- MODEL_MODE_DEFAULT,
822
- "gemini-3-pro-preview",
823
- "gemini-3-flash-preview",
824
- "gemini-2.5-pro"
825
- ];
826
- const CODEX_MODEL_MODES = [
827
- MODEL_MODE_DEFAULT,
828
- "gpt-5.6-sol-low",
829
- "gpt-5.6-sol-medium",
830
- "gpt-5.6-sol-high",
831
- "gpt-5.6-sol-xhigh",
832
- "gpt-5.6-sol-max",
833
- "gpt-5.6-terra-low",
834
- "gpt-5.6-terra-medium",
835
- "gpt-5.6-terra-high",
836
- "gpt-5.6-terra-xhigh",
837
- "gpt-5.6-luna-low",
838
- "gpt-5.6-luna-medium",
839
- "gpt-5.6-luna-high",
840
- "gpt-5.6-luna-xhigh",
841
- "gpt-5.5-low",
842
- "gpt-5.5-medium",
843
- "gpt-5.5-high",
844
- "gpt-5.5-xhigh",
845
- "gpt-5.4-low",
846
- "gpt-5.4-medium",
847
- "gpt-5.4-high",
848
- "gpt-5.4-xhigh",
849
- "gpt-5.3-codex-low",
850
- "gpt-5.3-codex-medium",
851
- "gpt-5.3-codex-high",
852
- "gpt-5.3-codex-xhigh",
853
- "gpt-5.2-codex-low",
854
- "gpt-5.2-codex-medium",
855
- "gpt-5.2-codex-high",
856
- "gpt-5.2-codex-xhigh",
857
- "gpt-5.2-low",
858
- "gpt-5.2-medium",
859
- "gpt-5.2-high",
860
- "gpt-5.2-xhigh",
861
- "gpt-5.1-codex-max-low",
862
- "gpt-5.1-codex-max-medium",
863
- "gpt-5.1-codex-max-high",
864
- "gpt-5.1-codex-max-xhigh",
865
- "gpt-5.1-codex-mini-medium",
866
- "gpt-5.1-codex-mini-high"
867
- ];
868
- const MODEL_MODE_SET = new Set(MODEL_MODES);
869
- const CLAUDE_MODEL_MODE_SET = new Set(CLAUDE_MODEL_MODES);
870
- const GEMINI_MODEL_MODE_SET = new Set(GEMINI_MODEL_MODES);
871
- const CODEX_MODEL_MODE_SET = new Set(CODEX_MODEL_MODES);
872
- function isModelMode(value) {
873
- return MODEL_MODE_SET.has(value);
874
- }
875
- function isModelModeForAgent(agent, mode) {
876
- if (!isModelMode(mode)) return false;
877
- if (agent === "claude") return CLAUDE_MODEL_MODE_SET.has(mode);
878
- if (agent === "gemini") return GEMINI_MODEL_MODE_SET.has(mode);
879
- return CODEX_MODEL_MODE_SET.has(mode);
880
- }
881
- const CLAUDE_MODE_TO_SELECTION = {
882
- "claude-fable-5-low": { family: "claude-fable-5", effort: "low" },
883
- "claude-fable-5-medium": { family: "claude-fable-5", effort: "medium" },
884
- "claude-fable-5-high": { family: "claude-fable-5", effort: "high" },
885
- "claude-fable-5-xhigh": { family: "claude-fable-5", effort: "xhigh" },
886
- "claude-fable-5-max": { family: "claude-fable-5", effort: "max" },
887
- "claude-fable-5[1m]-low": { family: "claude-fable-5[1m]", effort: "low" },
888
- "claude-fable-5[1m]-medium": { family: "claude-fable-5[1m]", effort: "medium" },
889
- "claude-fable-5[1m]-high": { family: "claude-fable-5[1m]", effort: "high" },
890
- "claude-fable-5[1m]-xhigh": { family: "claude-fable-5[1m]", effort: "xhigh" },
891
- "claude-fable-5[1m]-max": { family: "claude-fable-5[1m]", effort: "max" },
892
- "claude-opus-5-low": { family: "claude-opus-5", effort: "low" },
893
- "claude-opus-5-medium": { family: "claude-opus-5", effort: "medium" },
894
- "claude-opus-5-high": { family: "claude-opus-5", effort: "high" },
895
- "claude-opus-5-xhigh": { family: "claude-opus-5", effort: "xhigh" },
896
- "claude-opus-5-max": { family: "claude-opus-5", effort: "max" },
897
- "claude-opus-5[1m]-low": { family: "claude-opus-5[1m]", effort: "low" },
898
- "claude-opus-5[1m]-medium": { family: "claude-opus-5[1m]", effort: "medium" },
899
- "claude-opus-5[1m]-high": { family: "claude-opus-5[1m]", effort: "high" },
900
- "claude-opus-5[1m]-xhigh": { family: "claude-opus-5[1m]", effort: "xhigh" },
901
- "claude-opus-5[1m]-max": { family: "claude-opus-5[1m]", effort: "max" },
902
- "claude-opus-4-8-low": { family: "claude-opus-4-8", effort: "low" },
903
- "claude-opus-4-8-medium": { family: "claude-opus-4-8", effort: "medium" },
904
- "claude-opus-4-8-high": { family: "claude-opus-4-8", effort: "high" },
905
- "claude-opus-4-8-xhigh": { family: "claude-opus-4-8", effort: "xhigh" },
906
- "claude-opus-4-8-max": { family: "claude-opus-4-8", effort: "max" },
907
- "claude-opus-4-8[1m]-low": { family: "claude-opus-4-8[1m]", effort: "low" },
908
- "claude-opus-4-8[1m]-medium": { family: "claude-opus-4-8[1m]", effort: "medium" },
909
- "claude-opus-4-8[1m]-high": { family: "claude-opus-4-8[1m]", effort: "high" },
910
- "claude-opus-4-8[1m]-xhigh": { family: "claude-opus-4-8[1m]", effort: "xhigh" },
911
- "claude-opus-4-8[1m]-max": { family: "claude-opus-4-8[1m]", effort: "max" },
912
- "claude-opus-4-6-low": { family: "claude-opus-4-6", effort: "low" },
913
- "claude-opus-4-6-medium": { family: "claude-opus-4-6", effort: "medium" },
914
- "claude-opus-4-6-high": { family: "claude-opus-4-6", effort: "high" },
915
- "claude-opus-4-6-max": { family: "claude-opus-4-6", effort: "max" },
916
- "claude-opus-4-6[1m]-low": { family: "claude-opus-4-6[1m]", effort: "low" },
917
- "claude-opus-4-6[1m]-medium": { family: "claude-opus-4-6[1m]", effort: "medium" },
918
- "claude-opus-4-6[1m]-high": { family: "claude-opus-4-6[1m]", effort: "high" },
919
- "claude-opus-4-6[1m]-max": { family: "claude-opus-4-6[1m]", effort: "max" },
920
- "claude-sonnet-4-6-low": { family: "claude-sonnet-4-6", effort: "low" },
921
- "claude-sonnet-4-6-medium": { family: "claude-sonnet-4-6", effort: "medium" },
922
- "claude-sonnet-4-6-high": { family: "claude-sonnet-4-6", effort: "high" },
923
- "claude-sonnet-4-6[1m]-low": { family: "claude-sonnet-4-6[1m]", effort: "low" },
924
- "claude-sonnet-4-6[1m]-medium": { family: "claude-sonnet-4-6[1m]", effort: "medium" },
925
- "claude-sonnet-4-6[1m]-high": { family: "claude-sonnet-4-6[1m]", effort: "high" },
926
- "claude-haiku-4-5-low": { family: "claude-haiku-4-5", effort: "low" },
927
- "claude-haiku-4-5-medium": { family: "claude-haiku-4-5", effort: "medium" },
928
- "claude-haiku-4-5-high": { family: "claude-haiku-4-5", effort: "high" }
929
- };
930
- const CODEX_MODE_TO_SELECTION = {
931
- "gpt-5.6-sol-low": { family: "gpt-5.6-sol", effort: "low" },
932
- "gpt-5.6-sol-medium": { family: "gpt-5.6-sol", effort: "medium" },
933
- "gpt-5.6-sol-high": { family: "gpt-5.6-sol", effort: "high" },
934
- "gpt-5.6-sol-xhigh": { family: "gpt-5.6-sol", effort: "xhigh" },
935
- "gpt-5.6-sol-max": { family: "gpt-5.6-sol", effort: "max" },
936
- "gpt-5.6-terra-low": { family: "gpt-5.6-terra", effort: "low" },
937
- "gpt-5.6-terra-medium": { family: "gpt-5.6-terra", effort: "medium" },
938
- "gpt-5.6-terra-high": { family: "gpt-5.6-terra", effort: "high" },
939
- "gpt-5.6-terra-xhigh": { family: "gpt-5.6-terra", effort: "xhigh" },
940
- "gpt-5.6-luna-low": { family: "gpt-5.6-luna", effort: "low" },
941
- "gpt-5.6-luna-medium": { family: "gpt-5.6-luna", effort: "medium" },
942
- "gpt-5.6-luna-high": { family: "gpt-5.6-luna", effort: "high" },
943
- "gpt-5.6-luna-xhigh": { family: "gpt-5.6-luna", effort: "xhigh" },
944
- "gpt-5.5-low": { family: "gpt-5.5", effort: "low" },
945
- "gpt-5.5-medium": { family: "gpt-5.5", effort: "medium" },
946
- "gpt-5.5-high": { family: "gpt-5.5", effort: "high" },
947
- "gpt-5.5-xhigh": { family: "gpt-5.5", effort: "xhigh" },
948
- "gpt-5.4-low": { family: "gpt-5.4", effort: "low" },
949
- "gpt-5.4-medium": { family: "gpt-5.4", effort: "medium" },
950
- "gpt-5.4-high": { family: "gpt-5.4", effort: "high" },
951
- "gpt-5.4-xhigh": { family: "gpt-5.4", effort: "xhigh" },
952
- "gpt-5.3-codex-low": { family: "gpt-5.3-codex", effort: "low" },
953
- "gpt-5.3-codex-medium": { family: "gpt-5.3-codex", effort: "medium" },
954
- "gpt-5.3-codex-high": { family: "gpt-5.3-codex", effort: "high" },
955
- "gpt-5.3-codex-xhigh": { family: "gpt-5.3-codex", effort: "xhigh" },
956
- "gpt-5.2-codex-low": { family: "gpt-5.2-codex", effort: "low" },
957
- "gpt-5.2-codex-medium": { family: "gpt-5.2-codex", effort: "medium" },
958
- "gpt-5.2-codex-high": { family: "gpt-5.2-codex", effort: "high" },
959
- "gpt-5.2-codex-xhigh": { family: "gpt-5.2-codex", effort: "xhigh" },
960
- "gpt-5.2-low": { family: "gpt-5.2", effort: "low" },
961
- "gpt-5.2-medium": { family: "gpt-5.2", effort: "medium" },
962
- "gpt-5.2-high": { family: "gpt-5.2", effort: "high" },
963
- "gpt-5.2-xhigh": { family: "gpt-5.2", effort: "xhigh" },
964
- "gpt-5.1-codex-max-low": { family: "gpt-5.1-codex-max", effort: "low" },
965
- "gpt-5.1-codex-max-medium": { family: "gpt-5.1-codex-max", effort: "medium" },
966
- "gpt-5.1-codex-max-high": { family: "gpt-5.1-codex-max", effort: "high" },
967
- "gpt-5.1-codex-max-xhigh": { family: "gpt-5.1-codex-max", effort: "xhigh" },
968
- "gpt-5.1-codex-mini-medium": { family: "gpt-5.1-codex-mini", effort: "medium" },
969
- "gpt-5.1-codex-mini-high": { family: "gpt-5.1-codex-mini", effort: "high" }
970
- };
971
- function parseClaudeModelMode(mode) {
972
- const entry = CLAUDE_MODE_TO_SELECTION[mode];
973
- if (entry) return entry;
974
- if (mode === MODEL_MODE_DEFAULT) return { family: MODEL_MODE_DEFAULT, effort: null };
975
- return { family: mode, effort: null };
976
- }
977
- function parseCodexModelMode(mode) {
978
- return CODEX_MODE_TO_SELECTION[mode] ?? { family: MODEL_MODE_DEFAULT, effort: "medium" };
979
- }
980
- const FeishuWebhookConfigSchema = z$1.object({
981
- url: z$1.string().url(),
982
- secret: z$1.string().optional(),
983
- enabled: z$1.boolean()
984
- });
985
- z$1.object({
986
- url: z$1.string().nullable(),
987
- secret_set: z$1.boolean(),
988
- enabled: z$1.boolean(),
989
- lastTestedAt: z$1.number().nullable()
990
- });
991
- z$1.object({
992
- feishu: FeishuWebhookConfigSchema.extend({
993
- lastTestedAt: z$1.number().optional()
994
- }).optional(),
995
- feishuMention: FeishuWebhookConfigSchema.extend({
996
- lastTestedAt: z$1.number().optional()
997
- }).optional(),
998
- /**
999
- * The account owner's own Feishu identity (open_id `ou_…` or tenant
1000
- * user_id). When set, collaboration @ notifications sent to any owner's
1001
- * mention webhook render this user as a real `<at>` ping instead of
1002
- * plain text. The ping only fires if the user is in the bot's group.
1003
- */
1004
- feishuUserId: z$1.string().optional()
1005
- });
1006
- const MemorySourceSchema = z$1.enum(["manual", "message-pin"]);
1007
- z$1.object({
1008
- id: z$1.string(),
1009
- content: z$1.string().min(1).max(8e3),
1010
- source: MemorySourceSchema,
1011
- sourceSessionId: z$1.string().nullable(),
1012
- sourceMessageId: z$1.string().nullable(),
1013
- archivedAt: z$1.number().nullable(),
1014
- createdAt: z$1.number(),
1015
- updatedAt: z$1.number()
1016
- });
1017
- z$1.object({
1018
- content: z$1.string().min(1).max(8e3),
1019
- source: MemorySourceSchema.optional().default("manual"),
1020
- sourceSessionId: z$1.string().optional(),
1021
- sourceMessageId: z$1.string().optional()
1022
- });
1023
- z$1.object({
1024
- content: z$1.string().min(1).max(8e3)
1025
- });
1026
-
1027
- z$1.object({
1028
- host: z$1.string(),
1029
- platform: z$1.string(),
1030
- happyCliVersion: z$1.string(),
1031
- homeDir: z$1.string(),
1032
- happyHomeDir: z$1.string(),
1033
- happyLibDir: z$1.string(),
1034
- displayName: z$1.string().optional(),
31
+ host: z.string(),
32
+ platform: z.string(),
33
+ happyCliVersion: z.string(),
34
+ homeDir: z.string(),
35
+ happyHomeDir: z.string(),
36
+ happyLibDir: z.string(),
37
+ displayName: z.string().optional(),
1035
38
  // True when this machine was added with `happy device enroll`: it serves
1036
39
  // shell/files/terminal over machine RPC but refuses `spawn-happy-session`,
1037
40
  // so clients must keep it out of session pickers.
1038
- deviceMode: z$1.boolean().optional()
41
+ deviceMode: z.boolean().optional()
1039
42
  });
1040
- z$1.object({
1041
- status: z$1.union([
1042
- z$1.enum(["running", "shutting-down"]),
1043
- z$1.string()
43
+ z.object({
44
+ status: z.union([
45
+ z.enum(["running", "shutting-down"]),
46
+ z.string()
1044
47
  // Forward compatibility
1045
48
  ]),
1046
- pid: z$1.number().optional(),
1047
- httpPort: z$1.number().optional(),
1048
- startedAt: z$1.number().optional(),
1049
- shutdownRequestedAt: z$1.number().optional(),
1050
- shutdownSource: z$1.union([
1051
- z$1.enum(["mobile-app", "cli", "os-signal", "unknown"]),
1052
- z$1.string()
49
+ pid: z.number().optional(),
50
+ httpPort: z.number().optional(),
51
+ startedAt: z.number().optional(),
52
+ shutdownRequestedAt: z.number().optional(),
53
+ shutdownSource: z.union([
54
+ z.enum(["mobile-app", "cli", "os-signal", "unknown"]),
55
+ z.string()
1053
56
  // Forward compatibility
1054
57
  ]).optional()
1055
58
  });
1056
- const CollaborationMentionMetaSchema = z$1.object({
1057
- kind: z$1.literal("mention"),
1058
- targetUserIds: z$1.array(z$1.string()).default([]),
1059
- targetUsernames: z$1.array(z$1.string()).default([])
59
+ const CollaborationMentionMetaSchema = z.object({
60
+ kind: z.literal("mention"),
61
+ targetUserIds: z.array(z.string()).default([]),
62
+ targetUsernames: z.array(z.string()).default([])
1060
63
  });
1061
- const MessageMetaSchema = z$1.object({
1062
- sentFrom: z$1.string().optional(),
64
+ const MessageMetaSchema = z.object({
65
+ sentFrom: z.string().optional(),
1063
66
  // Source identifier
1064
- permissionMode: z$1.enum(["default", "acceptEdits", "bypassPermissions", "plan", "read-only", "safe-yolo", "yolo"]).optional(),
67
+ permissionMode: z.enum(["default", "acceptEdits", "bypassPermissions", "plan", "read-only", "safe-yolo", "yolo"]).optional(),
1065
68
  // Permission mode for this message
1066
- model: z$1.string().nullable().optional(),
69
+ model: z.string().nullable().optional(),
1067
70
  // Model name for this message (null = reset)
1068
- reasoningEffort: z$1.string().nullable().optional(),
71
+ reasoningEffort: z.string().nullable().optional(),
1069
72
  // Reasoning effort for this message (null = reset)
1070
- fallbackModel: z$1.string().nullable().optional(),
73
+ fallbackModel: z.string().nullable().optional(),
1071
74
  // Fallback model for this message (null = reset)
1072
- customSystemPrompt: z$1.string().nullable().optional(),
75
+ customSystemPrompt: z.string().nullable().optional(),
1073
76
  // Custom system prompt for this message (null = reset)
1074
- appendSystemPrompt: z$1.string().nullable().optional(),
77
+ appendSystemPrompt: z.string().nullable().optional(),
1075
78
  // Append to system prompt for this message (null = reset)
1076
- allowedTools: z$1.array(z$1.string()).nullable().optional(),
79
+ allowedTools: z.array(z.string()).nullable().optional(),
1077
80
  // Allowed tools for this message (null = reset)
1078
- disallowedTools: z$1.array(z$1.string()).nullable().optional(),
81
+ disallowedTools: z.array(z.string()).nullable().optional(),
1079
82
  // Disallowed tools for this message (null = reset)
1080
- displayText: z$1.string().optional(),
1081
- humanOnly: z$1.boolean().optional(),
1082
- skipAiContext: z$1.boolean().optional(),
83
+ displayText: z.string().optional(),
84
+ humanOnly: z.boolean().optional(),
85
+ skipAiContext: z.boolean().optional(),
1083
86
  collaboration: CollaborationMentionMetaSchema.optional()
1084
87
  });
1085
- z$1.object({
1086
- session: z$1.object({
1087
- id: z$1.string(),
1088
- tag: z$1.string(),
1089
- seq: z$1.number(),
1090
- createdAt: z$1.number(),
1091
- updatedAt: z$1.number(),
1092
- metadata: z$1.string(),
1093
- metadataVersion: z$1.number(),
1094
- agentState: z$1.string().nullable(),
1095
- agentStateVersion: z$1.number()
88
+ z.object({
89
+ session: z.object({
90
+ id: z.string(),
91
+ tag: z.string(),
92
+ seq: z.number(),
93
+ createdAt: z.number(),
94
+ updatedAt: z.number(),
95
+ metadata: z.string(),
96
+ metadataVersion: z.number(),
97
+ agentState: z.string().nullable(),
98
+ agentStateVersion: z.number()
1096
99
  })
1097
100
  });
1098
- const ImageContentSchema = z$1.object({
1099
- type: z$1.literal("image"),
1100
- url: z$1.string(),
1101
- width: z$1.number(),
1102
- height: z$1.number(),
1103
- mimeType: z$1.string(),
1104
- thumbhash: z$1.string().optional()
101
+ const ImageContentSchema = z.object({
102
+ type: z.literal("image"),
103
+ url: z.string(),
104
+ width: z.number(),
105
+ height: z.number(),
106
+ mimeType: z.string(),
107
+ thumbhash: z.string().optional()
1105
108
  });
1106
- const UserMessageSchema = z$1.object({
1107
- role: z$1.literal("user"),
1108
- content: z$1.union([
1109
- z$1.object({
1110
- type: z$1.literal("text"),
1111
- text: z$1.string()
109
+ const UserMessageSchema = z.object({
110
+ role: z.literal("user"),
111
+ content: z.union([
112
+ z.object({
113
+ type: z.literal("text"),
114
+ text: z.string()
1112
115
  }),
1113
- z$1.object({
1114
- type: z$1.literal("mixed"),
1115
- text: z$1.string(),
1116
- images: z$1.array(ImageContentSchema)
116
+ z.object({
117
+ type: z.literal("mixed"),
118
+ text: z.string(),
119
+ images: z.array(ImageContentSchema)
1117
120
  })
1118
121
  ]),
1119
- localKey: z$1.string().optional(),
122
+ localKey: z.string().optional(),
1120
123
  meta: MessageMetaSchema.optional()
1121
124
  });
1122
- const AgentMessageSchema = z$1.object({
1123
- role: z$1.literal("agent"),
1124
- content: z$1.object({
1125
- type: z$1.literal("output"),
1126
- data: z$1.any()
125
+ const AgentMessageSchema = z.object({
126
+ role: z.literal("agent"),
127
+ content: z.object({
128
+ type: z.literal("output"),
129
+ data: z.any()
1127
130
  }),
1128
131
  meta: MessageMetaSchema.optional()
1129
132
  });
1130
- z$1.union([UserMessageSchema, AgentMessageSchema]);
1131
-
1132
- function encodeBase64(buffer, variant = "base64") {
1133
- if (variant === "base64url") {
1134
- return encodeBase64Url(buffer);
1135
- }
1136
- return Buffer.from(buffer).toString("base64");
1137
- }
1138
- function encodeBase64Url(buffer) {
1139
- return Buffer.from(buffer).toString("base64").replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
1140
- }
1141
- function decodeBase64(base64, variant = "base64") {
1142
- if (variant === "base64url") {
1143
- const base64Standard = base64.replaceAll("-", "+").replaceAll("_", "/") + "=".repeat((4 - base64.length % 4) % 4);
1144
- return new Uint8Array(Buffer.from(base64Standard, "base64"));
1145
- }
1146
- return new Uint8Array(Buffer.from(base64, "base64"));
1147
- }
1148
- function getRandomBytes(size) {
1149
- return new Uint8Array(randomBytes(size));
1150
- }
1151
- function libsodiumPublicKeyFromSecretKey(seed) {
1152
- const hashedSeed = new Uint8Array(createHash("sha512").update(seed).digest());
1153
- const secretKey = hashedSeed.slice(0, 32);
1154
- return new Uint8Array(tweetnacl.box.keyPair.fromSecretKey(secretKey).publicKey);
1155
- }
1156
- function libsodiumEncryptForPublicKey(data, recipientPublicKey) {
1157
- const ephemeralKeyPair = tweetnacl.box.keyPair();
1158
- const nonce = getRandomBytes(tweetnacl.box.nonceLength);
1159
- const encrypted = tweetnacl.box(data, nonce, recipientPublicKey, ephemeralKeyPair.secretKey);
1160
- const result = new Uint8Array(ephemeralKeyPair.publicKey.length + nonce.length + encrypted.length);
1161
- result.set(ephemeralKeyPair.publicKey, 0);
1162
- result.set(nonce, ephemeralKeyPair.publicKey.length);
1163
- result.set(encrypted, ephemeralKeyPair.publicKey.length + nonce.length);
1164
- return result;
1165
- }
1166
- function encryptLegacy(data, secret) {
1167
- const nonce = getRandomBytes(tweetnacl.secretbox.nonceLength);
1168
- const encrypted = tweetnacl.secretbox(new TextEncoder().encode(JSON.stringify(data)), nonce, secret);
1169
- const result = new Uint8Array(nonce.length + encrypted.length);
1170
- result.set(nonce);
1171
- result.set(encrypted, nonce.length);
1172
- return result;
1173
- }
1174
- function decryptLegacy(data, secret) {
1175
- const nonce = data.slice(0, tweetnacl.secretbox.nonceLength);
1176
- const encrypted = data.slice(tweetnacl.secretbox.nonceLength);
1177
- const decrypted = tweetnacl.secretbox.open(encrypted, nonce, secret);
1178
- if (!decrypted) {
1179
- return null;
1180
- }
1181
- return JSON.parse(new TextDecoder().decode(decrypted));
1182
- }
1183
- function encryptWithDataKey(data, dataKey) {
1184
- const nonce = getRandomBytes(12);
1185
- const cipher = createCipheriv("aes-256-gcm", dataKey, nonce);
1186
- const plaintext = new TextEncoder().encode(JSON.stringify(data));
1187
- const encrypted = Buffer.concat([
1188
- cipher.update(plaintext),
1189
- cipher.final()
1190
- ]);
1191
- const authTag = cipher.getAuthTag();
1192
- const bundle = new Uint8Array(12 + encrypted.length + 16 + 1);
1193
- bundle.set([0], 0);
1194
- bundle.set(nonce, 1);
1195
- bundle.set(new Uint8Array(encrypted), 13);
1196
- bundle.set(new Uint8Array(authTag), 13 + encrypted.length);
1197
- return bundle;
1198
- }
1199
- function decryptWithDataKey(bundle, dataKey) {
1200
- if (bundle.length < 1) {
1201
- return null;
1202
- }
1203
- if (bundle[0] !== 0) {
1204
- return null;
1205
- }
1206
- if (bundle.length < 12 + 16 + 1) {
1207
- return null;
1208
- }
1209
- const nonce = bundle.slice(1, 13);
1210
- const authTag = bundle.slice(bundle.length - 16);
1211
- const ciphertext = bundle.slice(13, bundle.length - 16);
1212
- try {
1213
- const decipher = createDecipheriv("aes-256-gcm", dataKey, nonce);
1214
- decipher.setAuthTag(authTag);
1215
- const decrypted = Buffer.concat([
1216
- decipher.update(ciphertext),
1217
- decipher.final()
1218
- ]);
1219
- return JSON.parse(new TextDecoder().decode(decrypted));
1220
- } catch (error) {
1221
- return null;
1222
- }
1223
- }
1224
- function encrypt(key, variant, data) {
1225
- if (variant === "legacy") {
1226
- return encryptLegacy(data, key);
1227
- } else {
1228
- return encryptWithDataKey(data, key);
1229
- }
1230
- }
1231
- function decrypt(key, variant, data) {
1232
- if (variant === "legacy") {
1233
- return decryptLegacy(data, key);
1234
- } else {
1235
- return decryptWithDataKey(data, key);
1236
- }
1237
- }
1238
-
1239
- async function delay(ms) {
1240
- return new Promise((resolve) => setTimeout(resolve, ms));
1241
- }
1242
- function exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount) {
1243
- let maxDelayRet = minDelay + (maxDelay - minDelay) / maxFailureCount * Math.min(currentFailureCount, maxFailureCount);
1244
- return Math.round(Math.random() * maxDelayRet);
1245
- }
1246
- function createBackoff(opts) {
1247
- return async (callback) => {
1248
- let currentFailureCount = 0;
1249
- const minDelay = 250;
1250
- const maxDelay = 1e3;
1251
- const maxFailureCount = 50;
1252
- while (true) {
1253
- try {
1254
- return await callback();
1255
- } catch (e) {
1256
- if (currentFailureCount < maxFailureCount) {
1257
- currentFailureCount++;
1258
- }
1259
- let waitForRequest = exponentialBackoffDelay(currentFailureCount, minDelay, maxDelay, maxFailureCount);
1260
- await delay(waitForRequest);
1261
- }
1262
- }
1263
- };
1264
- }
1265
- let backoff = createBackoff();
133
+ z.union([UserMessageSchema, AgentMessageSchema]);
1266
134
 
1267
135
  class AsyncLock {
1268
136
  permits = 1;
@@ -1962,12 +830,12 @@ function hasCompletionSemantics(text, customPhrases) {
1962
830
  return hasEvidence || normalized.length <= 24;
1963
831
  }
1964
832
 
1965
- const ReviewResultSchema = z$1.object({
1966
- status: z$1.enum(["pass", "needs_follow_up", "uncertain"]),
1967
- summary: z$1.string(),
1968
- missing: z$1.array(z$1.string()),
1969
- evidence: z$1.array(z$1.string()),
1970
- confidence: z$1.enum(["high", "medium", "low"])
833
+ const ReviewResultSchema = z.object({
834
+ status: z.enum(["pass", "needs_follow_up", "uncertain"]),
835
+ summary: z.string(),
836
+ missing: z.array(z.string()),
837
+ evidence: z.array(z.string()),
838
+ confidence: z.enum(["high", "medium", "low"])
1971
839
  });
1972
840
  const DEFAULT_REVIEW_PROMPT = "\u4F60\u662F\u4EE3\u7801\u5B8C\u6210\u5EA6\u5BA1\u67E5 AI\u3002\u53EA\u5BA1\u67E5\u4EE3\u7801\u5B8C\u6210\u5EA6\uFF1A\u662F\u5426\u5BF9\u6807\u660E\u786E\u9700\u6C42\u3001GitHub Issue\u3001\u7528\u6237\u8865\u5145\u8981\u6C42\u3001brainstorming/pma/writing-plans \u8BA1\u5212\u3001git diff \u4E0E\u9A8C\u8BC1\u8BC1\u636E\u3002\u4E0D\u8981\u63D0\u51FA\u65E0\u5173\u91CD\u6784\u3001\u6CDB\u6CDB\u4F18\u5316\u3001\u6027\u80FD/\u5B89\u5168\u6DF1\u6316\uFF0C\u9664\u975E\u4EFB\u52A1\u660E\u786E\u8981\u6C42\u3002\u5982\u679C\u4E0A\u4E0B\u6587\u5305\u542B\u539F\u578B\u56FE\u3001\u539F\u578B\u4EE3\u7801\u3001prototype\u3001supervisor\u3001design\u3001Figma \u7B49\u5F15\u7528\uFF0C\u53EA\u5728\u4EE3\u7801\u5C42\u9762\u989D\u5916\u5BA1\u67E5 UI \u662F\u5426\u5BF9\u9F50\u539F\u578B\uFF1A\u7ED3\u6784\u3001\u5E03\u5C40\u3001\u6587\u6848\u3001\u72B6\u6001\u3001\u4EA4\u4E92\u548C\u6837\u5F0F token \u662F\u5426\u6709\u660E\u663E\u6F0F\u9879\uFF1B\u4E0D\u8981\u505A\u622A\u56FE/\u6D4F\u89C8\u5668/\u89C6\u89C9\u50CF\u7D20\u6BD4\u5BF9\u3002";
1973
841
  const REVIEW_OUTPUT_CONTRACT = '\u4F60\u5FC5\u987B\u4FDD\u6301\u53EA\u8BFB\uFF1A\u4E0D\u8981\u4FEE\u6539\u6587\u4EF6\uFF0C\u4E0D\u8981\u6267\u884C\u4F1A\u6539\u53D8\u5DE5\u4F5C\u533A/\u7CFB\u7EDF\u72B6\u6001\u7684\u547D\u4EE4\uFF0C\u4E0D\u8981\u63D0\u4EA4\u3001\u63A8\u9001\u6216\u5B89\u88C5\u4F9D\u8D56\u3002\u4F60\u8FD0\u884C\u5728\u9694\u79BB\u76EE\u5F55\u4E2D\uFF1B\u4E0D\u8981\u628A\u9694\u79BB\u76EE\u5F55\uFF08\u4F8B\u5982 /tmp\uFF09\u4E0D\u662F git \u4ED3\u5E93\u5F53\u4F5C\u6F0F\u9879\u3002\u4EE3\u7801\u8BC1\u636E\u5DF2\u7ECF\u5728\u4E0B\u65B9\u9884\u91C7\u96C6\uFF0C\u8BF7\u53EA\u57FA\u4E8E\u4E0B\u65B9 GitHub Issue\u3001\u7528\u6237\u8981\u6C42\u3001\u8BA1\u5212\u3001\u4F1A\u8BDD\u6458\u8981\u548C\u4EE3\u7801\u8BC1\u636E\u5BA1\u67E5\u3002\u4E0D\u8981\u8981\u6C42\u8BFB\u53D6 it-note MCP\u3001AGENTS.md\u3001CLAUDE.md \u6216\u5176\u4ED6\u5916\u90E8\u89C4\u5219\uFF1B\u8FD9\u4E9B\u4E0D\u5C5E\u4E8E\u672C\u6B21\u81EA\u52A8\u5B8C\u6210\u5EA6\u5BA1\u67E5\u8303\u56F4\u3002\u8BF7\u53EA\u8F93\u51FA JSON\uFF0C\u4E0D\u8981\u8F93\u51FA Markdown\u3002\u683C\u5F0F\uFF1A{"status":"pass|needs_follow_up|uncertain","summary":"...","missing":["..."],"evidence":["..."],"confidence":"high|medium|low"}';
@@ -2479,12 +1347,6 @@ No git repository was found from session cwd or workspace repo metadata. Session
2479
1347
  };
2480
1348
  }
2481
1349
 
2482
- const __dirname$1 = dirname(fileURLToPath(import.meta.url));
2483
- function projectPath() {
2484
- const path = resolve(__dirname$1, "..");
2485
- return path;
2486
- }
2487
-
2488
1350
  function run$1(args, options) {
2489
1351
  const RUNNER_PATH = resolve(join$1(projectPath(), "scripts", "ripgrep_launcher.cjs"));
2490
1352
  return new Promise((resolve2, reject) => {
@@ -2531,7 +1393,7 @@ function resolveToolsDir() {
2531
1393
  function findToolsDir() {
2532
1394
  try {
2533
1395
  const manifest = createRequire(import.meta.url).resolve(`${toolsPackageName()}/package.json`);
2534
- return dirname$1(manifest);
1396
+ return dirname(manifest);
2535
1397
  } catch {
2536
1398
  }
2537
1399
  return legacyToolsDir();
@@ -2596,7 +1458,7 @@ let loadError = null;
2596
1458
  function ensureSpawnHelperExecutable() {
2597
1459
  if (process.platform === "win32") return;
2598
1460
  try {
2599
- const root = dirname$1(dirname$1(require.resolve("node-pty")));
1461
+ const root = dirname(dirname(require.resolve("node-pty")));
2600
1462
  const candidates = [
2601
1463
  join(root, "prebuilds", `${process.platform}-${process.arch}`, "spawn-helper"),
2602
1464
  join(root, "build", "Release", "spawn-helper")
@@ -2841,7 +1703,7 @@ function resolveSessionUploadPaths(params) {
2841
1703
  tempRelativePath,
2842
1704
  absolutePath,
2843
1705
  tempAbsolutePath,
2844
- directory: dirname(absolutePath)
1706
+ directory: dirname$1(absolutePath)
2845
1707
  };
2846
1708
  }
2847
1709
 
@@ -4760,376 +3622,6 @@ class ApiSessionClient extends EventEmitter {
4760
3622
  }
4761
3623
  }
4762
3624
 
4763
- const AnthropicConfigSchema = z.object({
4764
- baseUrl: z.string().url().optional(),
4765
- authToken: z.string().optional(),
4766
- model: z.string().optional()
4767
- });
4768
- const OpenAIConfigSchema = z.object({
4769
- apiKey: z.string().optional(),
4770
- baseUrl: z.string().url().optional(),
4771
- model: z.string().optional()
4772
- });
4773
- const AzureOpenAIConfigSchema = z.object({
4774
- apiKey: z.string().optional(),
4775
- endpoint: z.string().url().optional(),
4776
- apiVersion: z.string().optional(),
4777
- deploymentName: z.string().optional()
4778
- });
4779
- const TogetherAIConfigSchema = z.object({
4780
- apiKey: z.string().optional(),
4781
- model: z.string().optional()
4782
- });
4783
- const TmuxConfigSchema = z.object({
4784
- sessionName: z.string().optional(),
4785
- tmpDir: z.string().optional(),
4786
- updateEnvironment: z.boolean().optional()
4787
- });
4788
- const EnvironmentVariableSchema = z.object({
4789
- name: z.string().regex(/^[A-Z_][A-Z0-9_]*$/, "Invalid environment variable name"),
4790
- value: z.string()
4791
- });
4792
- const ProfileCompatibilitySchema = z.object({
4793
- claude: z.boolean().default(true),
4794
- codex: z.boolean().default(true),
4795
- gemini: z.boolean().default(true)
4796
- });
4797
- const AIBackendProfileSchema = z.object({
4798
- id: z.string().uuid(),
4799
- name: z.string().min(1).max(100),
4800
- description: z.string().max(500).optional(),
4801
- // Agent-specific configurations
4802
- anthropicConfig: AnthropicConfigSchema.optional(),
4803
- openaiConfig: OpenAIConfigSchema.optional(),
4804
- azureOpenAIConfig: AzureOpenAIConfigSchema.optional(),
4805
- togetherAIConfig: TogetherAIConfigSchema.optional(),
4806
- // Tmux configuration
4807
- tmuxConfig: TmuxConfigSchema.optional(),
4808
- // Environment variables (validated)
4809
- environmentVariables: z.array(EnvironmentVariableSchema).default([]),
4810
- // Default session type for this profile
4811
- defaultSessionType: z.enum(["simple", "worktree"]).optional(),
4812
- // Default permission mode for this profile (supports both Claude and Codex modes)
4813
- defaultPermissionMode: z.enum([
4814
- "default",
4815
- "acceptEdits",
4816
- "bypassPermissions",
4817
- "plan",
4818
- // Claude modes
4819
- "read-only",
4820
- "safe-yolo",
4821
- "yolo"
4822
- // Codex modes
4823
- ]).optional(),
4824
- // Default model mode for this profile
4825
- defaultModelMode: z.string().optional(),
4826
- // Compatibility metadata
4827
- compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true }),
4828
- // Built-in profile indicator
4829
- isBuiltIn: z.boolean().default(false),
4830
- // Metadata
4831
- createdAt: z.number().default(() => Date.now()),
4832
- updatedAt: z.number().default(() => Date.now()),
4833
- version: z.string().default("1.0.0")
4834
- });
4835
- function validateProfileForAgent(profile, agent) {
4836
- return profile.compatibility[agent];
4837
- }
4838
- function getProfileEnvironmentVariables(profile) {
4839
- const envVars = {};
4840
- profile.environmentVariables.forEach((envVar) => {
4841
- envVars[envVar.name] = envVar.value;
4842
- });
4843
- if (profile.anthropicConfig) {
4844
- if (profile.anthropicConfig.baseUrl) envVars.ANTHROPIC_BASE_URL = profile.anthropicConfig.baseUrl;
4845
- if (profile.anthropicConfig.authToken) envVars.ANTHROPIC_AUTH_TOKEN = profile.anthropicConfig.authToken;
4846
- if (profile.anthropicConfig.model) envVars.ANTHROPIC_MODEL = profile.anthropicConfig.model;
4847
- }
4848
- if (profile.openaiConfig) {
4849
- if (profile.openaiConfig.apiKey) envVars.OPENAI_API_KEY = profile.openaiConfig.apiKey;
4850
- if (profile.openaiConfig.baseUrl) envVars.OPENAI_BASE_URL = profile.openaiConfig.baseUrl;
4851
- if (profile.openaiConfig.model) envVars.OPENAI_MODEL = profile.openaiConfig.model;
4852
- }
4853
- if (profile.azureOpenAIConfig) {
4854
- if (profile.azureOpenAIConfig.apiKey) envVars.AZURE_OPENAI_API_KEY = profile.azureOpenAIConfig.apiKey;
4855
- if (profile.azureOpenAIConfig.endpoint) envVars.AZURE_OPENAI_ENDPOINT = profile.azureOpenAIConfig.endpoint;
4856
- if (profile.azureOpenAIConfig.apiVersion) envVars.AZURE_OPENAI_API_VERSION = profile.azureOpenAIConfig.apiVersion;
4857
- if (profile.azureOpenAIConfig.deploymentName) envVars.AZURE_OPENAI_DEPLOYMENT_NAME = profile.azureOpenAIConfig.deploymentName;
4858
- }
4859
- if (profile.togetherAIConfig) {
4860
- if (profile.togetherAIConfig.apiKey) envVars.TOGETHER_API_KEY = profile.togetherAIConfig.apiKey;
4861
- if (profile.togetherAIConfig.model) envVars.TOGETHER_MODEL = profile.togetherAIConfig.model;
4862
- }
4863
- if (profile.tmuxConfig) {
4864
- if (profile.tmuxConfig.sessionName !== void 0) envVars.TMUX_SESSION_NAME = profile.tmuxConfig.sessionName;
4865
- if (profile.tmuxConfig.tmpDir) envVars.TMUX_TMPDIR = profile.tmuxConfig.tmpDir;
4866
- if (profile.tmuxConfig.updateEnvironment !== void 0) {
4867
- envVars.TMUX_UPDATE_ENVIRONMENT = profile.tmuxConfig.updateEnvironment.toString();
4868
- }
4869
- }
4870
- return envVars;
4871
- }
4872
- const SUPPORTED_SCHEMA_VERSION = 2;
4873
- const defaultSettings = {
4874
- schemaVersion: SUPPORTED_SCHEMA_VERSION,
4875
- onboardingCompleted: false,
4876
- profiles: [],
4877
- localEnvironmentVariables: {}
4878
- };
4879
- function migrateSettings(raw, fromVersion) {
4880
- let migrated = { ...raw };
4881
- if (fromVersion < 2) {
4882
- if (!migrated.profiles) {
4883
- migrated.profiles = [];
4884
- }
4885
- if (!migrated.localEnvironmentVariables) {
4886
- migrated.localEnvironmentVariables = {};
4887
- }
4888
- migrated.schemaVersion = 2;
4889
- }
4890
- return migrated;
4891
- }
4892
- async function readSettings() {
4893
- if (!existsSync(configuration.settingsFile)) {
4894
- return { ...defaultSettings };
4895
- }
4896
- try {
4897
- const content = await readFile(configuration.settingsFile, "utf8");
4898
- const raw = JSON.parse(content);
4899
- const schemaVersion = raw.schemaVersion ?? 1;
4900
- if (schemaVersion > SUPPORTED_SCHEMA_VERSION) {
4901
- logger.warn(
4902
- `\u26A0\uFE0F Settings schema v${schemaVersion} > supported v${SUPPORTED_SCHEMA_VERSION}. Update happy-cli for full functionality.`
4903
- );
4904
- }
4905
- const migrated = migrateSettings(raw, schemaVersion);
4906
- if (migrated.profiles && Array.isArray(migrated.profiles)) {
4907
- const validProfiles = [];
4908
- for (const profile of migrated.profiles) {
4909
- try {
4910
- const validated = AIBackendProfileSchema.parse(profile);
4911
- validProfiles.push(validated);
4912
- } catch (error) {
4913
- logger.warn(
4914
- `\u26A0\uFE0F Invalid profile "${profile?.name || profile?.id || "unknown"}" - skipping. Error: ${error.message}`
4915
- );
4916
- }
4917
- }
4918
- migrated.profiles = validProfiles;
4919
- }
4920
- return { ...defaultSettings, ...migrated };
4921
- } catch (error) {
4922
- logger.warn(`Failed to read settings: ${error.message}`);
4923
- return { ...defaultSettings };
4924
- }
4925
- }
4926
- async function updateSettings(updater) {
4927
- const LOCK_RETRY_INTERVAL_MS = 100;
4928
- const MAX_LOCK_ATTEMPTS = 50;
4929
- const STALE_LOCK_TIMEOUT_MS = 1e4;
4930
- const lockFile = configuration.settingsFile + ".lock";
4931
- const tmpFile = configuration.settingsFile + ".tmp";
4932
- let fileHandle;
4933
- let attempts = 0;
4934
- while (attempts < MAX_LOCK_ATTEMPTS) {
4935
- try {
4936
- fileHandle = await open(lockFile, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
4937
- break;
4938
- } catch (err) {
4939
- if (err.code === "EEXIST") {
4940
- attempts++;
4941
- await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_INTERVAL_MS));
4942
- try {
4943
- const stats = await stat$1(lockFile);
4944
- if (Date.now() - stats.mtimeMs > STALE_LOCK_TIMEOUT_MS) {
4945
- await unlink$1(lockFile).catch(() => {
4946
- });
4947
- }
4948
- } catch {
4949
- }
4950
- } else {
4951
- throw err;
4952
- }
4953
- }
4954
- }
4955
- if (!fileHandle) {
4956
- throw new Error(`Failed to acquire settings lock after ${MAX_LOCK_ATTEMPTS * LOCK_RETRY_INTERVAL_MS / 1e3} seconds`);
4957
- }
4958
- try {
4959
- const current = await readSettings() || { ...defaultSettings };
4960
- const updated = await updater(current);
4961
- if (!existsSync(configuration.happyHomeDir)) {
4962
- await mkdir$1(configuration.happyHomeDir, { recursive: true });
4963
- }
4964
- await writeFile$1(tmpFile, JSON.stringify(updated, null, 2));
4965
- await rename$1(tmpFile, configuration.settingsFile);
4966
- return updated;
4967
- } finally {
4968
- await fileHandle.close();
4969
- await unlink$1(lockFile).catch(() => {
4970
- });
4971
- }
4972
- }
4973
- const credentialsSchema = z.object({
4974
- token: z.string(),
4975
- secret: z.string().base64().nullish(),
4976
- // Legacy
4977
- encryption: z.object({
4978
- publicKey: z.string().base64(),
4979
- machineKey: z.string().base64()
4980
- }).nullish()
4981
- });
4982
- async function readCredentials() {
4983
- if (!existsSync(configuration.privateKeyFile)) {
4984
- return null;
4985
- }
4986
- try {
4987
- const keyBase64 = await readFile(configuration.privateKeyFile, "utf8");
4988
- const credentials = credentialsSchema.parse(JSON.parse(keyBase64));
4989
- if (credentials.secret) {
4990
- return {
4991
- token: credentials.token,
4992
- encryption: {
4993
- type: "legacy",
4994
- secret: new Uint8Array(Buffer.from(credentials.secret, "base64"))
4995
- }
4996
- };
4997
- } else if (credentials.encryption) {
4998
- return {
4999
- token: credentials.token,
5000
- encryption: {
5001
- type: "dataKey",
5002
- publicKey: new Uint8Array(Buffer.from(credentials.encryption.publicKey, "base64")),
5003
- machineKey: new Uint8Array(Buffer.from(credentials.encryption.machineKey, "base64"))
5004
- }
5005
- };
5006
- }
5007
- } catch {
5008
- return null;
5009
- }
5010
- return null;
5011
- }
5012
- async function writeCredentialsLegacy(credentials) {
5013
- if (!existsSync(configuration.happyHomeDir)) {
5014
- await mkdir$1(configuration.happyHomeDir, { recursive: true });
5015
- }
5016
- await writeFile$1(configuration.privateKeyFile, JSON.stringify({
5017
- secret: encodeBase64(credentials.secret),
5018
- token: credentials.token
5019
- }, null, 2));
5020
- }
5021
- async function writeCredentialsDataKey(credentials) {
5022
- if (!existsSync(configuration.happyHomeDir)) {
5023
- await mkdir$1(configuration.happyHomeDir, { recursive: true });
5024
- }
5025
- await writeFile$1(configuration.privateKeyFile, JSON.stringify({
5026
- encryption: { publicKey: encodeBase64(credentials.publicKey), machineKey: encodeBase64(credentials.machineKey) },
5027
- token: credentials.token
5028
- }, null, 2));
5029
- }
5030
- async function clearCredentials() {
5031
- if (existsSync(configuration.privateKeyFile)) {
5032
- await unlink$1(configuration.privateKeyFile);
5033
- }
5034
- }
5035
- async function clearMachineId() {
5036
- await updateSettings((settings) => ({
5037
- ...settings,
5038
- machineId: void 0
5039
- }));
5040
- }
5041
- async function readDaemonState() {
5042
- try {
5043
- if (!existsSync(configuration.daemonStateFile)) {
5044
- return null;
5045
- }
5046
- const content = await readFile(configuration.daemonStateFile, "utf-8");
5047
- return JSON.parse(content);
5048
- } catch (error) {
5049
- console.error(`[PERSISTENCE] Daemon state file corrupted: ${configuration.daemonStateFile}`, error);
5050
- return null;
5051
- }
5052
- }
5053
- function writeDaemonState(state) {
5054
- writeFileSync(configuration.daemonStateFile, JSON.stringify(state, null, 2), "utf-8");
5055
- }
5056
- async function clearDaemonState() {
5057
- if (existsSync(configuration.daemonStateFile)) {
5058
- await unlink$1(configuration.daemonStateFile);
5059
- }
5060
- if (existsSync(configuration.daemonLockFile)) {
5061
- try {
5062
- await unlink$1(configuration.daemonLockFile);
5063
- } catch {
5064
- }
5065
- }
5066
- }
5067
- async function acquireDaemonLock(maxAttempts = 5, delayIncrementMs = 200) {
5068
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
5069
- try {
5070
- const fileHandle = await open(
5071
- configuration.daemonLockFile,
5072
- constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY
5073
- );
5074
- await fileHandle.writeFile(String(process.pid));
5075
- return fileHandle;
5076
- } catch (error) {
5077
- if (error.code === "EEXIST") {
5078
- try {
5079
- const lockPid = readFileSync(configuration.daemonLockFile, "utf-8").trim();
5080
- if (lockPid && !isNaN(Number(lockPid))) {
5081
- try {
5082
- process.kill(Number(lockPid), 0);
5083
- } catch {
5084
- unlinkSync(configuration.daemonLockFile);
5085
- continue;
5086
- }
5087
- }
5088
- } catch {
5089
- }
5090
- }
5091
- if (attempt === maxAttempts) {
5092
- return null;
5093
- }
5094
- const delayMs = attempt * delayIncrementMs;
5095
- await new Promise((resolve) => setTimeout(resolve, delayMs));
5096
- }
5097
- }
5098
- return null;
5099
- }
5100
- async function releaseDaemonLock(lockHandle) {
5101
- try {
5102
- await lockHandle.close();
5103
- } catch {
5104
- }
5105
- try {
5106
- if (existsSync(configuration.daemonLockFile)) {
5107
- unlinkSync(configuration.daemonLockFile);
5108
- }
5109
- } catch {
5110
- }
5111
- }
5112
-
5113
- var persistence = /*#__PURE__*/Object.freeze({
5114
- __proto__: null,
5115
- AIBackendProfileSchema: AIBackendProfileSchema,
5116
- SUPPORTED_SCHEMA_VERSION: SUPPORTED_SCHEMA_VERSION,
5117
- acquireDaemonLock: acquireDaemonLock,
5118
- clearCredentials: clearCredentials,
5119
- clearDaemonState: clearDaemonState,
5120
- clearMachineId: clearMachineId,
5121
- getProfileEnvironmentVariables: getProfileEnvironmentVariables,
5122
- readCredentials: readCredentials,
5123
- readDaemonState: readDaemonState,
5124
- readSettings: readSettings,
5125
- releaseDaemonLock: releaseDaemonLock,
5126
- updateSettings: updateSettings,
5127
- validateProfileForAgent: validateProfileForAgent,
5128
- writeCredentialsDataKey: writeCredentialsDataKey,
5129
- writeCredentialsLegacy: writeCredentialsLegacy,
5130
- writeDaemonState: writeDaemonState
5131
- });
5132
-
5133
3625
  function buildRunningDaemonState(previousState, currentRuntimeState, opts = {}) {
5134
3626
  const currentHttpPort = currentRuntimeState?.httpPort;
5135
3627
  const currentStartedAt = currentRuntimeState?.startedAt;
@@ -6633,49 +5125,49 @@ async function truncateSessionFile$1(jsonlPath, truncateBeforeUuid) {
6633
5125
  }
6634
5126
  }
6635
5127
 
6636
- const GeminiSessionLineSchema = z$1.discriminatedUnion("type", [
6637
- z$1.object({
6638
- type: z$1.literal("user"),
6639
- message: z$1.string(),
6640
- timestamp: z$1.number(),
6641
- uuid: z$1.string()
5128
+ const GeminiSessionLineSchema = z.discriminatedUnion("type", [
5129
+ z.object({
5130
+ type: z.literal("user"),
5131
+ message: z.string(),
5132
+ timestamp: z.number(),
5133
+ uuid: z.string()
6642
5134
  }),
6643
- z$1.object({
6644
- type: z$1.literal("assistant"),
6645
- message: z$1.string(),
6646
- timestamp: z$1.number(),
6647
- uuid: z$1.string(),
6648
- model: z$1.string().optional()
5135
+ z.object({
5136
+ type: z.literal("assistant"),
5137
+ message: z.string(),
5138
+ timestamp: z.number(),
5139
+ uuid: z.string(),
5140
+ model: z.string().optional()
6649
5141
  }),
6650
- z$1.object({
6651
- type: z$1.literal("tool-call"),
6652
- name: z$1.string(),
6653
- callId: z$1.string(),
6654
- input: z$1.unknown(),
6655
- timestamp: z$1.number(),
6656
- uuid: z$1.string()
5142
+ z.object({
5143
+ type: z.literal("tool-call"),
5144
+ name: z.string(),
5145
+ callId: z.string(),
5146
+ input: z.unknown(),
5147
+ timestamp: z.number(),
5148
+ uuid: z.string()
6657
5149
  }),
6658
- z$1.object({
6659
- type: z$1.literal("tool-result"),
6660
- callId: z$1.string(),
6661
- output: z$1.unknown(),
6662
- isError: z$1.boolean().optional(),
6663
- timestamp: z$1.number(),
6664
- uuid: z$1.string()
5150
+ z.object({
5151
+ type: z.literal("tool-result"),
5152
+ callId: z.string(),
5153
+ output: z.unknown(),
5154
+ isError: z.boolean().optional(),
5155
+ timestamp: z.number(),
5156
+ uuid: z.string()
6665
5157
  }),
6666
- z$1.object({
6667
- type: z$1.literal("file-edit"),
6668
- filePath: z$1.string(),
6669
- description: z$1.string(),
6670
- diff: z$1.string().optional(),
6671
- timestamp: z$1.number(),
6672
- uuid: z$1.string()
5158
+ z.object({
5159
+ type: z.literal("file-edit"),
5160
+ filePath: z.string(),
5161
+ description: z.string(),
5162
+ diff: z.string().optional(),
5163
+ timestamp: z.number(),
5164
+ uuid: z.string()
6673
5165
  }),
6674
- z$1.object({
6675
- type: z$1.literal("meta"),
6676
- key: z$1.string(),
6677
- value: z$1.unknown(),
6678
- timestamp: z$1.number()
5166
+ z.object({
5167
+ type: z.literal("meta"),
5168
+ key: z.string(),
5169
+ value: z.unknown(),
5170
+ timestamp: z.number()
6679
5171
  })
6680
5172
  ]);
6681
5173
 
@@ -7413,7 +5905,7 @@ async function forkAndTruncateCodexSession(codexSessionId, truncateBeforeUuid) {
7413
5905
  if (!originalPath) {
7414
5906
  return { success: false, errorMessage: `Codex session file not found for: ${codexSessionId}` };
7415
5907
  }
7416
- const dir = dirname$1(originalPath);
5908
+ const dir = dirname(originalPath);
7417
5909
  const now = /* @__PURE__ */ new Date();
7418
5910
  const dateStr = now.toISOString().replace(/[:.]/g, "-").slice(0, 19);
7419
5911
  const newUUID = randomUUID();
@@ -8356,33 +6848,6 @@ class PushNotificationClient {
8356
6848
  }
8357
6849
  }
8358
6850
 
8359
- function keyPath(sessionId) {
8360
- return join(configuration.sessionKeysDir, `${sessionId}.key`);
8361
- }
8362
- async function cacheSessionKey(sessionId, sessionAESKey, machineKey) {
8363
- if (!existsSync(configuration.sessionKeysDir)) {
8364
- mkdirSync(configuration.sessionKeysDir, { recursive: true });
8365
- }
8366
- const encrypted = encryptWithDataKey(encodeBase64(sessionAESKey), machineKey);
8367
- await writeFile$1(keyPath(sessionId), encrypted);
8368
- }
8369
- function readCachedSessionKey(sessionId, machineKey) {
8370
- const p = keyPath(sessionId);
8371
- if (!existsSync(p)) {
8372
- return null;
8373
- }
8374
- try {
8375
- const blob = new Uint8Array(readFileSync(p));
8376
- const b64 = decryptWithDataKey(blob, machineKey);
8377
- if (typeof b64 !== "string") {
8378
- return null;
8379
- }
8380
- return decodeBase64(b64);
8381
- } catch {
8382
- return null;
8383
- }
8384
- }
8385
-
8386
6851
  function startOfflineReconnection(config) {
8387
6852
  let reconnected = false;
8388
6853
  let session = null;
@@ -8907,62 +7372,8 @@ class ApiClient {
8907
7372
  }
8908
7373
 
8909
7374
  var api = /*#__PURE__*/Object.freeze({
8910
- __proto__: null,
8911
- ApiClient: ApiClient
7375
+ __proto__: null,
7376
+ ApiClient: ApiClient
8912
7377
  });
8913
7378
 
8914
- const UsageSchema = z$1.object({
8915
- input_tokens: z$1.number().int().nonnegative(),
8916
- cache_creation_input_tokens: z$1.number().int().nonnegative().optional(),
8917
- cache_read_input_tokens: z$1.number().int().nonnegative().optional(),
8918
- output_tokens: z$1.number().int().nonnegative(),
8919
- service_tier: z$1.string().nullish()
8920
- }).passthrough();
8921
- const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
8922
- // User message - validates uuid and message.content
8923
- z$1.object({
8924
- type: z$1.literal("user"),
8925
- isSidechain: z$1.boolean().optional(),
8926
- isMeta: z$1.boolean().optional(),
8927
- uuid: z$1.string(),
8928
- // Used in getMessageKey()
8929
- message: z$1.object({
8930
- content: z$1.union([z$1.string(), z$1.any()])
8931
- // Used in sessionScanner.ts
8932
- }).passthrough()
8933
- }).passthrough(),
8934
- // Assistant message - only validates uuid and type
8935
- // message object is optional to handle synthetic error messages (isApiErrorMessage: true)
8936
- // which may have different structure than normal assistant messages
8937
- z$1.object({
8938
- uuid: z$1.string(),
8939
- type: z$1.literal("assistant"),
8940
- message: z$1.object({
8941
- usage: UsageSchema.optional(),
8942
- // Used in apiSession.ts
8943
- model: z$1.string().optional()
8944
- // Used for cost calculation
8945
- }).passthrough().optional()
8946
- }).passthrough(),
8947
- // Summary message - validates summary and leafUuid
8948
- z$1.object({
8949
- type: z$1.literal("summary"),
8950
- summary: z$1.string(),
8951
- // Used in apiSession.ts
8952
- leafUuid: z$1.string()
8953
- // Used in getMessageKey()
8954
- }).passthrough(),
8955
- // System message - validates uuid
8956
- z$1.object({
8957
- type: z$1.literal("system"),
8958
- uuid: z$1.string()
8959
- // Used in getMessageKey()
8960
- }).passthrough(),
8961
- // Progress message - hook progress events, not counted toward message limits
8962
- z$1.object({
8963
- type: z$1.literal("progress"),
8964
- uuid: z$1.string()
8965
- }).passthrough()
8966
- ]);
8967
-
8968
- export { persistence as $, ApiClient as A, GeminiSessionWriter as B, buildResumeContextFromSessionLog as C, AsyncLock as D, readDaemonState as E, clearDaemonState as F, GEMINI_MODEL_MODES as G, updateSettings as H, InvalidateSync as I, encodeBase64Url as J, writeCredentialsLegacy as K, writeCredentialsDataKey as L, MODEL_MODE_DEFAULT as M, acquireDaemonLock as N, writeDaemonState as O, releaseDaemonLock as P, validateProfileForAgent as Q, RawJSONLinesSchema as R, getProfileEnvironmentVariables as S, findClaudeProjectId as T, libsodiumPublicKeyFromSecretKey as U, clearCredentials as V, clearMachineId as W, decryptLegacy as X, decryptWithDataKey as Y, readCachedSessionKey as Z, getLatestDaemonLog as _, ApiSessionClient as a, api as a0, parseClaudeModelMode as b, configuration as c, encrypt as d, encodeBase64 as e, decodeBase64 as f, decrypt as g, resolveToolsDir as h, isModelModeForAgent as i, projectPath as j, packageJson as k, logger as l, saveToolOutputRecord as m, saveDiffRecords as n, isDebug as o, parseCodexModelMode as p, extractUserText as q, readCredentials as r, startOfflineReconnection as s, isSystemMessage as t, generateStableUuid as u, findCodexSessionFile as v, connectionState as w, readSettings as x, delay as y, readGeminiSessionLog as z };
7379
+ export { ApiClient as A, GeminiSessionWriter as G, InvalidateSync as I, ApiSessionClient as a, saveToolOutputRecord as b, saveDiffRecords as c, connectionState as d, extractUserText as e, findCodexSessionFile as f, generateStableUuid as g, readGeminiSessionLog as h, isSystemMessage as i, buildResumeContextFromSessionLog as j, AsyncLock as k, findClaudeProjectId as l, api as m, resolveToolsDir as r, startOfflineReconnection as s };