@zonease/happy 0.6.41 → 0.6.43

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 (87) hide show
  1. package/dist/{api-XeHlmApX.cjs → api-B-PlVQY6.cjs} +50 -4
  2. package/dist/{api-K2-jr9ar.mjs → api-BUCtd3cB.mjs} +51 -5
  3. package/dist/{auth-BQvEuSs5.cjs → auth-BqGkUXvq.cjs} +2 -2
  4. package/dist/{auth-CjLkoM3m.mjs → auth-DQH6q_q-.mjs} +4 -4
  5. package/dist/{auth-BbvPcnkY.cjs → auth-OL3nNcDX.cjs} +4 -4
  6. package/dist/{auth-DS8fzlin.mjs → auth-qM2eojWx.mjs} +2 -2
  7. package/dist/{browser-C05SP_Tt.cjs → browser-CY7VNU0C.cjs} +1 -1
  8. package/dist/{browser-C05Ak6RL.mjs → browser-D5RN_Axa.mjs} +1 -1
  9. package/dist/{claudeLocal-DJNRlHIC.mjs → claudeLocal-BXK_vQXS.mjs} +1 -1
  10. package/dist/{claudeLocal-CpDhLCcZ.cjs → claudeLocal-HAXk0deK.cjs} +1 -1
  11. package/dist/{config-DWWtjKQx.mjs → config-2wMjzcHl.mjs} +1 -1
  12. package/dist/{config-B0mns9fF.cjs → config-CaKxWGVe.cjs} +1 -1
  13. package/dist/{connect-DXQC1CJe.mjs → connect-BAunPyp_.mjs} +5 -5
  14. package/dist/{connect-BxCScVNX.cjs → connect-Dt1vY1BC.cjs} +5 -5
  15. package/dist/{controlClient-DgjVRN8D.mjs → controlClient-BzzTNSfl.mjs} +1 -1
  16. package/dist/{controlClient-DgELDZgM.cjs → controlClient-yTkpwcOq.cjs} +1 -1
  17. package/dist/cursorApprovalHook-B2chnVni.cjs +115 -0
  18. package/dist/cursorApprovalHook-BDLPzI5l.mjs +113 -0
  19. package/dist/cursorApprovalServer-Ba1yOUCA.mjs +263 -0
  20. package/dist/cursorApprovalServer-xwxVGL3u.cjs +268 -0
  21. package/dist/{deviceKeys-CejCdWpw.mjs → deviceKeys-CQyFFPtt.mjs} +2 -2
  22. package/dist/{deviceKeys-BpIAWz13.cjs → deviceKeys-CdW-HPnz.cjs} +2 -2
  23. package/dist/{doctor-DznasgP3.cjs → doctor-D4xWXiE7.cjs} +2 -2
  24. package/dist/{doctor-B-LCMVN9.mjs → doctor-DDT2TXHH.mjs} +2 -2
  25. package/dist/downloadImage-3A6zY5AX.cjs +492 -0
  26. package/dist/downloadImage-BqNp0l7y.mjs +485 -0
  27. package/dist/{enroll-HjUqyGnD.mjs → enroll-BlZ0giJI.mjs} +3 -3
  28. package/dist/{enroll-BvfpRUGJ.cjs → enroll-DeYs89Ic.cjs} +3 -3
  29. package/dist/{evidence-CVgTjBrq.cjs → evidence-Bn1JXtdz.cjs} +1 -1
  30. package/dist/{evidence-BEQd1dCh.mjs → evidence-PUnN9yPK.mjs} +1 -1
  31. package/dist/{formatImageMessage-DVs57t3x.mjs → formatImageMessage-BRHeLf0-.mjs} +1 -1
  32. package/dist/{formatImageMessage-CmJTP_hU.cjs → formatImageMessage-bVFGFDJl.cjs} +1 -1
  33. package/dist/{index-CDTNgfUf.cjs → index-BeKrqPYR.cjs} +25 -1
  34. package/dist/{index-CPKdvi7J.mjs → index-DTV7drqs.mjs} +25 -1
  35. package/dist/index.cjs +95 -41
  36. package/dist/index.mjs +95 -41
  37. package/dist/{install-UTz_vYvB.mjs → install-BLPNuSeM.mjs} +2 -2
  38. package/dist/{install-B3mMGISS.mjs → install-BOIcR_Wr.mjs} +1 -1
  39. package/dist/{install-Ck22tYHP.cjs → install-Jrs6YUu8.cjs} +1 -1
  40. package/dist/{install-2Yl_L582.cjs → install-Q-YMwwwg.cjs} +2 -2
  41. package/dist/lib.cjs +4 -4
  42. package/dist/lib.d.cts +4 -2
  43. package/dist/lib.d.mts +4 -2
  44. package/dist/lib.mjs +4 -4
  45. package/dist/{loadableToolOutput-BZYlaqHn.cjs → loadableToolOutput-B3qpMqXT.cjs} +2 -458
  46. package/dist/{loadableToolOutput-4EvraaNY.mjs → loadableToolOutput-DzReWITb.mjs} +3 -456
  47. package/dist/{persistence-DrfN7TzY.cjs → persistence-D7zNFI-d.cjs} +7 -4
  48. package/dist/{persistence-CIUFyOwz.mjs → persistence-DbLMvLvk.mjs} +7 -4
  49. package/dist/{push-CCOXCcM_.cjs → push-RT6Y0Hr3.cjs} +6 -6
  50. package/dist/{push-USXj_pv0.mjs → push-z5wQ4Ki_.mjs} +6 -6
  51. package/dist/{downloadImage-ia5SzlCV.mjs → registerKillSessionHandler-DmfnJ0zq.mjs} +7 -487
  52. package/dist/{downloadImage-B_ygLAXY.cjs → registerKillSessionHandler-MoLdSQxM.cjs} +6 -492
  53. package/dist/{run-Dy6KX6m-.mjs → run-BFnSUK1o.mjs} +14 -9
  54. package/dist/{run-D3CopmEb.cjs → run-C5StYRIB.cjs} +14 -9
  55. package/dist/{runClaude-aHzvx6Ha.cjs → runClaude-ChRp6f5G.cjs} +27 -26
  56. package/dist/{runClaude-CWux2RDq.mjs → runClaude-CjENBdrX.mjs} +22 -21
  57. package/dist/{runCodex-D0ZxSj3O.mjs → runCodex-BzQWlRoj.mjs} +27 -25
  58. package/dist/{runCodex-G-Aq531U.cjs → runCodex-DcQGyotH.cjs} +32 -30
  59. package/dist/runCursor-B73z6MCN.mjs +752 -0
  60. package/dist/runCursor-BlPAxaTy.cjs +754 -0
  61. package/dist/{runGemini-DZC2i6vA.mjs → runGemini-BPv4UzuF.mjs} +18 -16
  62. package/dist/{runGemini-DxGgDAIM.cjs → runGemini-JFqaIC3u.cjs} +23 -21
  63. package/dist/{runOneShot-BgT-JNMA.cjs → runOneShot-2iV11e9L.cjs} +3 -3
  64. package/dist/{runOneShot-cxlk7VKA.mjs → runOneShot-DTukim2A.mjs} +3 -3
  65. package/dist/{serve-Dr3wPrtK.cjs → serve-BDwuAIK4.cjs} +7 -7
  66. package/dist/{serve-CKyvJNs0.mjs → serve-BnlYj5ek.mjs} +7 -7
  67. package/dist/{session-dYzbOo_W.cjs → session-Cp9LEESM.cjs} +5 -5
  68. package/dist/{session-vf2ZjFto.mjs → session-gfeFU8CA.mjs} +5 -5
  69. package/dist/{sessionKeyCache-dDquDzn0.cjs → sessionKeyCache-3Pme04yL.cjs} +1 -1
  70. package/dist/{sessionKeyCache-D2u3JUys.mjs → sessionKeyCache-DtBS_Sb3.mjs} +1 -1
  71. package/dist/{sessionList-C1k2PNg_.mjs → sessionList-B1w4BUdv.mjs} +2 -2
  72. package/dist/{sessionList-DmmtC7uR.cjs → sessionList-BR_5UDZJ.cjs} +2 -2
  73. package/dist/{sessionSummary-DGLoVOxd.cjs → sessionSummary-DLweYgHO.cjs} +3 -3
  74. package/dist/{sessionSummary-5a1QtFVS.mjs → sessionSummary-E-a2bg8W.mjs} +3 -3
  75. package/dist/setupOfflineReconnection-DHwthFtd.mjs +459 -0
  76. package/dist/setupOfflineReconnection-Dkp00dC9.cjs +463 -0
  77. package/dist/{spawnHappyCLI-CarRI4GM.cjs → spawnHappyCLI-C2uY9WV-.cjs} +1 -1
  78. package/dist/{spawnHappyCLI-D3EkTFIn.mjs → spawnHappyCLI-Dt7fbmbk.mjs} +1 -1
  79. package/dist/{ssh-B0hvEYIl.mjs → ssh-C-nEZiGP.mjs} +5 -5
  80. package/dist/{ssh-CBgVwKsB.cjs → ssh-CsnS89Lr.cjs} +5 -5
  81. package/dist/{task-CRo6W-3_.mjs → task-B-8_QGGX.mjs} +6 -6
  82. package/dist/{task-CMunPKCV.cjs → task-lrLb4FCL.cjs} +6 -6
  83. package/dist/{uninstall-BALE2up0.mjs → uninstall-CirMt_WC.mjs} +2 -2
  84. package/dist/{uninstall-BJ3eEGM4.cjs → uninstall-DMjUlEXT.cjs} +2 -2
  85. package/dist/{update-BfjtLrhO.mjs → update-CfXbYshs.mjs} +3 -3
  86. package/dist/{update-Bb3iijy8.cjs → update-mx2p28IP.cjs} +3 -3
  87. package/package.json +1 -1
@@ -1,192 +1,6 @@
1
- import { l as logger, c as configuration, p as packageJson } from './persistence-CIUFyOwz.mjs';
2
1
  import { randomUUID } from 'node:crypto';
3
- import { readFileSync, existsSync, readdirSync } from 'node:fs';
4
- import os, { homedir } from 'node:os';
5
- import { join, basename, dirname } from 'node:path';
6
- import { p as projectPath } from './projectPath-BTBIMB57.mjs';
7
- import { r as resolveToolsDir, s as startOfflineReconnection, b as saveToolOutputRecord } from './api-K2-jr9ar.mjs';
8
- import { a as detectGitWorktree } from './downloadImage-ia5SzlCV.mjs';
9
-
10
- class BasePermissionHandler {
11
- pendingRequests = /* @__PURE__ */ new Map();
12
- session;
13
- pushClient;
14
- isResetting = false;
15
- isUserInteractionTool(toolName) {
16
- return ["AskUserQuestion", "ExitPlanMode", "exit_plan_mode"].includes(toolName);
17
- }
18
- constructor(session, pushClient) {
19
- this.session = session;
20
- this.pushClient = pushClient;
21
- this.setupRpcHandler();
22
- }
23
- /**
24
- * Update the session reference (used after offline reconnection swaps sessions).
25
- * This is critical for avoiding stale session references after onSessionSwap.
26
- */
27
- updateSession(newSession) {
28
- logger.debug(`${this.getLogPrefix()} Session reference updated`);
29
- this.session = newSession;
30
- this.setupRpcHandler();
31
- }
32
- /**
33
- * Setup RPC handler for permission responses.
34
- */
35
- setupRpcHandler() {
36
- this.session.rpcHandlerManager.registerHandler(
37
- "permission",
38
- async (response) => {
39
- const pending = this.pendingRequests.get(response.id);
40
- if (!pending) {
41
- logger.debug(`${this.getLogPrefix()} Permission request not found or already resolved`);
42
- return;
43
- }
44
- this.pendingRequests.delete(response.id);
45
- const result = response.approved ? { decision: response.decision === "approved_for_session" ? "approved_for_session" : "approved" } : { decision: response.decision === "denied" ? "denied" : "abort" };
46
- pending.resolve(result);
47
- if (response.approved && (response.mode === "bypassPermissions" || response.decision === "approved_for_session")) {
48
- this.approvePendingRequestsForSession(response);
49
- }
50
- this.session.updateAgentState((currentState) => {
51
- const request = currentState.requests?.[response.id];
52
- if (!request) return currentState;
53
- const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
54
- let res = {
55
- ...currentState,
56
- requests: remainingRequests,
57
- completedRequests: {
58
- ...currentState.completedRequests,
59
- [response.id]: {
60
- ...request,
61
- completedAt: Date.now(),
62
- status: response.approved ? "approved" : "denied",
63
- decision: result.decision,
64
- mode: response.mode,
65
- allowedTools: response.allowTools
66
- }
67
- }
68
- };
69
- return res;
70
- });
71
- logger.debug(`${this.getLogPrefix()} Permission ${response.approved ? "approved" : "denied"} for ${pending.toolName}`);
72
- }
73
- );
74
- }
75
- approvePendingRequestsForSession(response) {
76
- const pendingSnapshot = Array.from(this.pendingRequests.entries());
77
- const completedAt = Date.now();
78
- for (const [id, pending] of pendingSnapshot) {
79
- if (this.isUserInteractionTool(pending.toolName)) {
80
- continue;
81
- }
82
- this.pendingRequests.delete(id);
83
- pending.resolve({ decision: "approved_for_session" });
84
- }
85
- if (pendingSnapshot.length === 0) {
86
- return;
87
- }
88
- this.session.updateAgentState((currentState) => {
89
- const requests = { ...currentState.requests || {} };
90
- const completedRequests = { ...currentState.completedRequests };
91
- let changed = false;
92
- for (const [id, pending] of pendingSnapshot) {
93
- if (this.isUserInteractionTool(pending.toolName)) {
94
- continue;
95
- }
96
- const request = requests[id];
97
- if (!request) {
98
- continue;
99
- }
100
- delete requests[id];
101
- completedRequests[id] = {
102
- ...request,
103
- completedAt,
104
- status: "approved",
105
- decision: "approved_for_session",
106
- mode: response.mode,
107
- allowedTools: response.allowTools
108
- };
109
- changed = true;
110
- }
111
- if (!changed) {
112
- return currentState;
113
- }
114
- return {
115
- ...currentState,
116
- requests,
117
- completedRequests
118
- };
119
- });
120
- }
121
- /**
122
- * Add a pending request to the agent state and send a push notification.
123
- */
124
- addPendingRequestToState(toolCallId, toolName, input) {
125
- this.pushClient.sendToAllDevices(
126
- "Permission Request",
127
- `${this.getAgentName()} wants to ${toolName}`,
128
- {
129
- sessionId: this.session.sessionId,
130
- requestId: toolCallId,
131
- tool: toolName,
132
- type: "permission_request"
133
- }
134
- );
135
- this.session.updateAgentState((currentState) => ({
136
- ...currentState,
137
- requests: {
138
- ...currentState.requests,
139
- [toolCallId]: {
140
- tool: toolName,
141
- arguments: input,
142
- createdAt: Date.now()
143
- }
144
- }
145
- }));
146
- }
147
- /**
148
- * Reset state for new sessions.
149
- * This method is idempotent - safe to call multiple times.
150
- */
151
- reset() {
152
- if (this.isResetting) {
153
- logger.debug(`${this.getLogPrefix()} Reset already in progress, skipping`);
154
- return;
155
- }
156
- this.isResetting = true;
157
- try {
158
- const pendingSnapshot = Array.from(this.pendingRequests.entries());
159
- this.pendingRequests.clear();
160
- for (const [id, pending] of pendingSnapshot) {
161
- try {
162
- pending.reject(new Error("Session reset"));
163
- } catch (err) {
164
- logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
165
- }
166
- }
167
- this.session.updateAgentState((currentState) => {
168
- const pendingRequests = currentState.requests || {};
169
- const completedRequests = { ...currentState.completedRequests };
170
- for (const [id, request] of Object.entries(pendingRequests)) {
171
- completedRequests[id] = {
172
- ...request,
173
- completedAt: Date.now(),
174
- status: "canceled",
175
- reason: "Session reset"
176
- };
177
- }
178
- return {
179
- ...currentState,
180
- requests: {},
181
- completedRequests
182
- };
183
- });
184
- logger.debug(`${this.getLogPrefix()} Permission handler reset`);
185
- } finally {
186
- this.isResetting = false;
187
- }
188
- }
189
- }
2
+ import { l as logger } from './persistence-DbLMvLvk.mjs';
3
+ import { s as saveToolOutputRecord } from './api-BUCtd3cB.mjs';
190
4
 
191
5
  class BaseReasoningProcessor {
192
6
  accumulator = "";
@@ -382,273 +196,6 @@ class BaseReasoningProcessor {
382
196
  }
383
197
  }
384
198
 
385
- const DEFAULT_MAX_SKILLS = 400;
386
- const DEFAULT_MAX_DEPTH = 10;
387
- const SKILL_FILE = "SKILL.md";
388
- const IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
389
- ".git",
390
- "node_modules",
391
- "dist",
392
- "build",
393
- "references",
394
- "assets",
395
- "templates"
396
- ]);
397
- function parseFrontMatter(content) {
398
- if (!content.startsWith("---")) return {};
399
- const end = content.indexOf("\n---", 3);
400
- if (end < 0) return {};
401
- const block = content.slice(3, end).split(/\r?\n/);
402
- const result = {};
403
- for (let i = 0; i < block.length; i++) {
404
- const line = block[i];
405
- const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line.trim());
406
- if (!match) continue;
407
- const [, key, rawValue] = match;
408
- let value = rawValue.trim().replace(/^['"]|['"]$/g, "");
409
- if ((rawValue.trim() === ">-" || rawValue.trim() === ">" || rawValue.trim() === "|-" || rawValue.trim() === "|") && key === "description") {
410
- const continuation = [];
411
- while (i + 1 < block.length && /^\s+/.test(block[i + 1])) {
412
- i++;
413
- continuation.push(block[i].trim());
414
- }
415
- value = continuation.join(rawValue.trim().startsWith("|") ? "\n" : " ").trim();
416
- }
417
- if (key === "name" && value) result.name = value;
418
- if (key === "description" && value) result.description = value;
419
- }
420
- return result;
421
- }
422
- function deriveSkillName(skillFilePath) {
423
- return basename(dirname(skillFilePath));
424
- }
425
- function collectSkillFiles(root, maxDepth, maxFiles) {
426
- const files = [];
427
- function walk(dir, depth) {
428
- if (files.length >= maxFiles || depth > maxDepth) return;
429
- let entries;
430
- try {
431
- entries = readdirSync(dir, { withFileTypes: true });
432
- } catch {
433
- return;
434
- }
435
- for (const entry of entries) {
436
- if (files.length >= maxFiles) return;
437
- const fullPath = join(dir, entry.name);
438
- if (entry.isFile() && entry.name === SKILL_FILE) {
439
- files.push(fullPath);
440
- continue;
441
- }
442
- if (!entry.isDirectory()) continue;
443
- if (IGNORED_DIRECTORIES.has(entry.name)) continue;
444
- walk(fullPath, depth + 1);
445
- }
446
- }
447
- if (existsSync(root)) {
448
- walk(root, 0);
449
- }
450
- return files;
451
- }
452
- function skillRoots(homeDir, includePluginCache) {
453
- const roots = [
454
- { path: join(homeDir, ".agents", "skills"), source: "agents" },
455
- { path: join(homeDir, ".codex", "skills"), source: "codex" },
456
- { path: join(homeDir, ".claude", "skills"), source: "claude" }
457
- ];
458
- if (includePluginCache) {
459
- roots.push(
460
- { path: join(homeDir, ".codex", "plugins", "cache"), source: "codex-plugin-cache" },
461
- { path: join(homeDir, ".codex", ".tmp", "plugins", "plugins"), source: "codex-plugin-marketplace" }
462
- );
463
- }
464
- return roots;
465
- }
466
- function discoverCodexSkills(options = {}) {
467
- const homeDir = options.homeDir ?? homedir();
468
- const maxSkills = options.maxSkills ?? DEFAULT_MAX_SKILLS;
469
- const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
470
- const includePluginCache = options.includePluginCache ?? true;
471
- const result = [];
472
- const seen = /* @__PURE__ */ new Set();
473
- for (const root of skillRoots(homeDir, includePluginCache)) {
474
- if (result.length >= maxSkills) break;
475
- const skillFiles = collectSkillFiles(root.path, maxDepth, maxSkills - result.length);
476
- for (const skillFile of skillFiles) {
477
- if (result.length >= maxSkills) break;
478
- let content = "";
479
- try {
480
- content = readFileSync(skillFile, "utf8");
481
- } catch {
482
- continue;
483
- }
484
- const frontMatter = parseFrontMatter(content);
485
- const name = (frontMatter.name || deriveSkillName(skillFile)).trim();
486
- if (!name) continue;
487
- const key = name.toLowerCase();
488
- if (seen.has(key)) continue;
489
- seen.add(key);
490
- result.push({
491
- name,
492
- description: frontMatter.description,
493
- source: root.source
494
- });
495
- }
496
- }
497
- return result;
498
- }
499
-
500
- function detectWorkspaceSubdirectories(cwd) {
501
- try {
502
- const entries = readdirSync(cwd, { withFileTypes: true });
503
- const repos = [];
504
- for (const entry of entries) {
505
- if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
506
- const subDir = join(cwd, entry.name);
507
- const info = detectGitWorktree(subDir);
508
- if (info.isWorktree && info.worktreeBasePath && info.worktreeBranchName) {
509
- repos.push({
510
- path: subDir,
511
- basePath: info.worktreeBasePath,
512
- branchName: info.worktreeBranchName,
513
- displayName: entry.name
514
- });
515
- }
516
- }
517
- if (repos.length > 0) {
518
- return {
519
- isWorktree: true,
520
- workspaceRepos: repos,
521
- workspacePath: cwd
522
- };
523
- }
524
- } catch {
525
- }
526
- return {};
527
- }
528
- function detectWorktreeMetadata() {
529
- if (process.env.HAPPY_WORKSPACE_REPOS) {
530
- try {
531
- const repos = JSON.parse(process.env.HAPPY_WORKSPACE_REPOS);
532
- return {
533
- isWorktree: true,
534
- workspaceRepos: repos,
535
- workspacePath: process.env.HAPPY_WORKSPACE_PATH
536
- };
537
- } catch {
538
- }
539
- }
540
- if (process.env.HAPPY_WORKTREE_BASE_PATH) {
541
- return {
542
- isWorktree: true,
543
- worktreeBasePath: process.env.HAPPY_WORKTREE_BASE_PATH,
544
- worktreeBranchName: process.env.HAPPY_WORKTREE_BRANCH_NAME
545
- };
546
- }
547
- const info = detectGitWorktree(process.cwd());
548
- if (info.isWorktree) {
549
- return {
550
- isWorktree: true,
551
- worktreeBasePath: info.worktreeBasePath,
552
- worktreeBranchName: info.worktreeBranchName
553
- };
554
- }
555
- const workspaceResult = detectWorkspaceSubdirectories(process.cwd());
556
- if (workspaceResult.isWorktree) {
557
- return workspaceResult;
558
- }
559
- return {};
560
- }
561
- function createSessionMetadata(opts) {
562
- const state = {
563
- controlledByUser: false
564
- };
565
- const metadata = {
566
- path: process.cwd(),
567
- host: os.hostname(),
568
- version: packageJson.version,
569
- os: os.platform(),
570
- machineId: opts.machineId,
571
- homeDir: os.homedir(),
572
- happyHomeDir: configuration.happyHomeDir,
573
- happyLibDir: projectPath(),
574
- happyToolsDir: resolveToolsDir(),
575
- startedFromDaemon: opts.startedBy === "daemon",
576
- hostPid: process.pid,
577
- startedBy: opts.startedBy || "terminal",
578
- lifecycleState: "running",
579
- lifecycleStateSince: Date.now(),
580
- flavor: opts.flavor,
581
- // Worktree metadata: env vars from daemon take priority, otherwise detect via git
582
- ...detectWorktreeMetadata()
583
- };
584
- if (opts.flavor === "codex") {
585
- metadata.skills = discoverCodexSkills();
586
- }
587
- return { state, metadata };
588
- }
589
-
590
- function createOfflineSessionStub(sessionTag) {
591
- return {
592
- sessionId: `offline-${sessionTag}`,
593
- sendCodexMessage: () => {
594
- },
595
- sendAgentMessage: () => {
596
- },
597
- sendClaudeSessionMessage: () => {
598
- },
599
- keepAlive: () => {
600
- },
601
- sendSessionEvent: () => {
602
- },
603
- sendSessionDeath: () => {
604
- },
605
- updateLifecycleState: () => {
606
- },
607
- requestControlTransfer: async () => {
608
- },
609
- flush: async () => {
610
- },
611
- close: async () => {
612
- },
613
- updateMetadata: () => {
614
- },
615
- updateAgentState: () => {
616
- },
617
- onUserMessage: () => {
618
- },
619
- rpcHandlerManager: {
620
- registerHandler: () => {
621
- }
622
- }
623
- };
624
- }
625
-
626
- function setupOfflineReconnection(opts) {
627
- const { api, sessionTag, metadata, state, response, onSessionSwap } = opts;
628
- let session;
629
- let reconnectionHandle = null;
630
- if (!response) {
631
- session = createOfflineSessionStub(sessionTag);
632
- reconnectionHandle = startOfflineReconnection({
633
- serverUrl: configuration.serverUrl,
634
- onReconnected: async () => {
635
- const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
636
- if (!resp) throw new Error("Server unavailable");
637
- const realSession = api.sessionSyncClient(resp);
638
- onSessionSwap(realSession);
639
- return realSession;
640
- },
641
- onNotify: (msg) => {
642
- console.log(msg);
643
- }
644
- });
645
- return { session, reconnectionHandle, isOffline: true };
646
- } else {
647
- session = api.sessionSyncClient(response);
648
- return { session, reconnectionHandle: null, isOffline: false };
649
- }
650
- }
651
-
652
199
  const SUPPORTED_CATEGORIES = /* @__PURE__ */ new Set(["mode", "model", "thought_level"]);
653
200
  function isRecord(value) {
654
201
  return !!value && typeof value === "object";
@@ -1189,4 +736,4 @@ function summarizeBashToolOutput(options) {
1189
736
  });
1190
737
  }
1191
738
 
1192
- export { BasePermissionHandler as B, BaseReasoningProcessor as a, summarizeBashToolOutput as b, createSessionMetadata as c, handleAgentMessageChunk as d, handleToolCallUpdate as e, handleAgentThoughtChunk as f, handleToolCall as g, handleConfigMetadataEvent as h, handleLegacyMessageChunk as i, handlePlanUpdate as j, handleThinkingUpdate as k, setupOfflineReconnection as s };
739
+ export { BaseReasoningProcessor as B, handleAgentMessageChunk as a, handleToolCallUpdate as b, handleAgentThoughtChunk as c, handleToolCall as d, handleLegacyMessageChunk as e, handlePlanUpdate as f, handleThinkingUpdate as g, handleConfigMetadataEvent as h, summarizeBashToolOutput as s };
@@ -35,7 +35,7 @@ function isDebug() {
35
35
  }
36
36
 
37
37
  var name = "@zonease/happy";
38
- var version = "0.6.41";
38
+ var version = "0.6.43";
39
39
  var description = "Mobile and Web client for Claude Code, Codex, and Gemini";
40
40
  var author = "ZonEaseTech";
41
41
  var license = "MIT";
@@ -624,7 +624,10 @@ const EnvironmentVariableSchema = z__namespace.object({
624
624
  const ProfileCompatibilitySchema = z__namespace.object({
625
625
  claude: z__namespace.boolean().default(true),
626
626
  codex: z__namespace.boolean().default(true),
627
- gemini: z__namespace.boolean().default(true)
627
+ gemini: z__namespace.boolean().default(true),
628
+ // Defaults to false: profiles written before Cursor existed describe
629
+ // Anthropic-style endpoints and must not silently claim to support it.
630
+ cursor: z__namespace.boolean().default(false)
628
631
  });
629
632
  const AIBackendProfileSchema = z__namespace.object({
630
633
  id: z__namespace.string().uuid(),
@@ -656,7 +659,7 @@ const AIBackendProfileSchema = z__namespace.object({
656
659
  // Default model mode for this profile
657
660
  defaultModelMode: z__namespace.string().optional(),
658
661
  // Compatibility metadata
659
- compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true }),
662
+ compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true, cursor: false }),
660
663
  // Built-in profile indicator
661
664
  isBuiltIn: z__namespace.boolean().default(false),
662
665
  // Metadata
@@ -665,7 +668,7 @@ const AIBackendProfileSchema = z__namespace.object({
665
668
  version: z__namespace.string().default("1.0.0")
666
669
  });
667
670
  function validateProfileForAgent(profile, agent) {
668
- return profile.compatibility[agent];
671
+ return profile.compatibility[agent] ?? false;
669
672
  }
670
673
  function getProfileEnvironmentVariables(profile) {
671
674
  const envVars = {};
@@ -14,7 +14,7 @@ function isDebug() {
14
14
  }
15
15
 
16
16
  var name = "@zonease/happy";
17
- var version = "0.6.41";
17
+ var version = "0.6.43";
18
18
  var description = "Mobile and Web client for Claude Code, Codex, and Gemini";
19
19
  var author = "ZonEaseTech";
20
20
  var license = "MIT";
@@ -603,7 +603,10 @@ const EnvironmentVariableSchema = z.object({
603
603
  const ProfileCompatibilitySchema = z.object({
604
604
  claude: z.boolean().default(true),
605
605
  codex: z.boolean().default(true),
606
- gemini: z.boolean().default(true)
606
+ gemini: z.boolean().default(true),
607
+ // Defaults to false: profiles written before Cursor existed describe
608
+ // Anthropic-style endpoints and must not silently claim to support it.
609
+ cursor: z.boolean().default(false)
607
610
  });
608
611
  const AIBackendProfileSchema = z.object({
609
612
  id: z.string().uuid(),
@@ -635,7 +638,7 @@ const AIBackendProfileSchema = z.object({
635
638
  // Default model mode for this profile
636
639
  defaultModelMode: z.string().optional(),
637
640
  // Compatibility metadata
638
- compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true }),
641
+ compatibility: ProfileCompatibilitySchema.default({ claude: true, codex: true, gemini: true, cursor: false }),
639
642
  // Built-in profile indicator
640
643
  isBuiltIn: z.boolean().default(false),
641
644
  // Metadata
@@ -644,7 +647,7 @@ const AIBackendProfileSchema = z.object({
644
647
  version: z.string().default("1.0.0")
645
648
  });
646
649
  function validateProfileForAgent(profile, agent) {
647
- return profile.compatibility[agent];
650
+ return profile.compatibility[agent] ?? false;
648
651
  }
649
652
  function getProfileEnvironmentVariables(profile) {
650
653
  const envVars = {};
@@ -2,8 +2,8 @@
2
2
 
3
3
  var promises = require('node:fs/promises');
4
4
  var socket_ioClient = require('socket.io-client');
5
- var logger = require('./persistence-DrfN7TzY.cjs');
6
- var ssh = require('./ssh-CBgVwKsB.cjs');
5
+ var logger = require('./persistence-D7zNFI-d.cjs');
6
+ var ssh = require('./ssh-CsnS89Lr.cjs');
7
7
  require('node:fs');
8
8
  require('node:os');
9
9
  require('node:path');
@@ -12,16 +12,16 @@ require('node:crypto');
12
12
  require('tweetnacl');
13
13
  require('chalk');
14
14
  require('fs');
15
- require('./deviceKeys-BpIAWz13.cjs');
15
+ require('./deviceKeys-CdW-HPnz.cjs');
16
16
  require('axios');
17
- require('./auth-BQvEuSs5.cjs');
17
+ require('./auth-BqGkUXvq.cjs');
18
18
  require('qrcode-terminal');
19
19
  require('./time-Bj2HRkKH.cjs');
20
- require('./browser-C05SP_Tt.cjs');
20
+ require('./browser-CY7VNU0C.cjs');
21
21
  require('open');
22
22
  require('react');
23
23
  require('ink');
24
- require('./controlClient-DgELDZgM.cjs');
24
+ require('./controlClient-yTkpwcOq.cjs');
25
25
  require('./projectPath-ChLhdOyt.cjs');
26
26
  require('path');
27
27
  require('url');
@@ -1,7 +1,7 @@
1
1
  import { stat, readFile } from 'node:fs/promises';
2
2
  import { io } from 'socket.io-client';
3
- import { c as configuration, e as encodeBase64, f as encrypt, g as decrypt, h as decodeBase64 } from './persistence-CIUFyOwz.mjs';
4
- import { resolveDeviceForCommand } from './ssh-B0hvEYIl.mjs';
3
+ import { c as configuration, e as encodeBase64, f as encrypt, g as decrypt, h as decodeBase64 } from './persistence-DbLMvLvk.mjs';
4
+ import { resolveDeviceForCommand } from './ssh-C-nEZiGP.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:os';
7
7
  import 'node:path';
@@ -10,16 +10,16 @@ import 'node:crypto';
10
10
  import 'tweetnacl';
11
11
  import 'chalk';
12
12
  import 'fs';
13
- import './deviceKeys-CejCdWpw.mjs';
13
+ import './deviceKeys-CQyFFPtt.mjs';
14
14
  import 'axios';
15
- import './auth-DS8fzlin.mjs';
15
+ import './auth-qM2eojWx.mjs';
16
16
  import 'qrcode-terminal';
17
17
  import './time-DgsBLJA_.mjs';
18
- import './browser-C05Ak6RL.mjs';
18
+ import './browser-D5RN_Axa.mjs';
19
19
  import 'open';
20
20
  import 'react';
21
21
  import 'ink';
22
- import './controlClient-DgjVRN8D.mjs';
22
+ import './controlClient-BzzTNSfl.mjs';
23
23
  import './projectPath-BTBIMB57.mjs';
24
24
  import 'path';
25
25
  import 'url';