@zonease/happy 0.6.41 → 0.6.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{api-XeHlmApX.cjs → api-CIE4_cWd.cjs} +4 -4
- package/dist/{api-K2-jr9ar.mjs → api-Ew6xr81i.mjs} +4 -4
- package/dist/{auth-CjLkoM3m.mjs → auth-BzYevJo2.mjs} +4 -4
- package/dist/{auth-BbvPcnkY.cjs → auth-Dor79zTL.cjs} +4 -4
- package/dist/{auth-BQvEuSs5.cjs → auth-G9fZpVJ2.cjs} +2 -2
- package/dist/{auth-DS8fzlin.mjs → auth-Q2STUNI-.mjs} +2 -2
- package/dist/{browser-C05Ak6RL.mjs → browser-BI7s-V8E.mjs} +1 -1
- package/dist/{browser-C05SP_Tt.cjs → browser-qDIIAL7S.cjs} +1 -1
- package/dist/{claudeLocal-DJNRlHIC.mjs → claudeLocal-Db2tDC4X.mjs} +1 -1
- package/dist/{claudeLocal-CpDhLCcZ.cjs → claudeLocal-f4uBLJaM.cjs} +1 -1
- package/dist/{config-DWWtjKQx.mjs → config-CHjDs8AS.mjs} +1 -1
- package/dist/{config-B0mns9fF.cjs → config-CSBlEik9.cjs} +1 -1
- package/dist/{connect-BxCScVNX.cjs → connect-CJoTliii.cjs} +5 -5
- package/dist/{connect-DXQC1CJe.mjs → connect-O_nA5BOC.mjs} +5 -5
- package/dist/{controlClient-DgELDZgM.cjs → controlClient-CEz_p1zc.cjs} +1 -1
- package/dist/{controlClient-DgjVRN8D.mjs → controlClient-DoS9JqQC.mjs} +1 -1
- package/dist/cursorApprovalHook-B0v1kGa7.mjs +95 -0
- package/dist/cursorApprovalHook-DRAHfTXU.cjs +97 -0
- package/dist/cursorApprovalServer-DzY8yJlI.cjs +167 -0
- package/dist/cursorApprovalServer-JjPkdjGR.mjs +164 -0
- package/dist/{deviceKeys-CejCdWpw.mjs → deviceKeys-B4aqjnE6.mjs} +2 -2
- package/dist/{deviceKeys-BpIAWz13.cjs → deviceKeys-DyUn0bEx.cjs} +2 -2
- package/dist/{doctor-DznasgP3.cjs → doctor-BJSuVRUZ.cjs} +2 -2
- package/dist/{doctor-B-LCMVN9.mjs → doctor-DRnft_5-.mjs} +2 -2
- package/dist/{downloadImage-ia5SzlCV.mjs → downloadImage-BpVF7A79.mjs} +7 -40
- package/dist/{downloadImage-B_ygLAXY.cjs → downloadImage-Cijmufpr.cjs} +5 -39
- package/dist/{enroll-BvfpRUGJ.cjs → enroll-C2gunHdt.cjs} +3 -3
- package/dist/{enroll-HjUqyGnD.mjs → enroll-CysDL6ee.mjs} +3 -3
- package/dist/{evidence-BEQd1dCh.mjs → evidence-DPutCuUr.mjs} +1 -1
- package/dist/{evidence-CVgTjBrq.cjs → evidence-DsQ-h-_W.cjs} +1 -1
- package/dist/{formatImageMessage-DVs57t3x.mjs → formatImageMessage-6aV9YFWr.mjs} +1 -1
- package/dist/{formatImageMessage-CmJTP_hU.cjs → formatImageMessage-BPK_Ivfe.cjs} +1 -1
- package/dist/gitWorktree-C6jLoaMw.cjs +39 -0
- package/dist/gitWorktree-CzJDU2BV.mjs +37 -0
- package/dist/{index-CDTNgfUf.cjs → index-BeKrqPYR.cjs} +25 -1
- package/dist/{index-CPKdvi7J.mjs → index-DTV7drqs.mjs} +25 -1
- package/dist/index.cjs +91 -41
- package/dist/index.mjs +91 -41
- package/dist/{install-UTz_vYvB.mjs → install-BsTA2tZn.mjs} +2 -2
- package/dist/{install-B3mMGISS.mjs → install-DBg0xQ3g.mjs} +1 -1
- package/dist/{install-2Yl_L582.cjs → install-DlOppA-e.cjs} +2 -2
- package/dist/{install-Ck22tYHP.cjs → install-Tyhs6rUp.cjs} +1 -1
- package/dist/lib.cjs +4 -4
- package/dist/lib.d.cts +3 -2
- package/dist/lib.d.mts +3 -2
- package/dist/lib.mjs +4 -4
- package/dist/{loadableToolOutput-4EvraaNY.mjs → loadableToolOutput-2dMPAp4N.mjs} +3 -456
- package/dist/{loadableToolOutput-BZYlaqHn.cjs → loadableToolOutput-DPGTtKJM.cjs} +2 -458
- package/dist/{persistence-DrfN7TzY.cjs → persistence-BcQmjobZ.cjs} +7 -4
- package/dist/{persistence-CIUFyOwz.mjs → persistence-D9tMm6bj.mjs} +7 -4
- package/dist/{push-CCOXCcM_.cjs → push-Cnm6JQMD.cjs} +6 -6
- package/dist/{push-USXj_pv0.mjs → push-Dxsugkes.mjs} +6 -6
- package/dist/{run-Dy6KX6m-.mjs → run-BEflQaQ2.mjs} +12 -9
- package/dist/{run-D3CopmEb.cjs → run-CiPWWhXt.cjs} +12 -9
- package/dist/{runClaude-aHzvx6Ha.cjs → runClaude-BVXsyCHb.cjs} +19 -18
- package/dist/{runClaude-CWux2RDq.mjs → runClaude-sPkSqHWY.mjs} +16 -15
- package/dist/{runCodex-G-Aq531U.cjs → runCodex-BAwhdmSA.cjs} +19 -17
- package/dist/{runCodex-D0ZxSj3O.mjs → runCodex-C4rHkIyw.mjs} +16 -14
- package/dist/runCursor-CD5wC3gA.cjs +578 -0
- package/dist/runCursor-DiHLWMs8.mjs +576 -0
- package/dist/{runGemini-DZC2i6vA.mjs → runGemini-B-93gOqB.mjs} +18 -16
- package/dist/{runGemini-DxGgDAIM.cjs → runGemini-Cto-adir.cjs} +21 -19
- package/dist/{runOneShot-BgT-JNMA.cjs → runOneShot-BfIzE9W4.cjs} +3 -3
- package/dist/{runOneShot-cxlk7VKA.mjs → runOneShot-DGjlYVhR.mjs} +3 -3
- package/dist/{serve-Dr3wPrtK.cjs → serve-CqL6NWDr.cjs} +7 -7
- package/dist/{serve-CKyvJNs0.mjs → serve-ttlqF5jn.mjs} +7 -7
- package/dist/{session-dYzbOo_W.cjs → session-BZhGpQUJ.cjs} +5 -5
- package/dist/{session-vf2ZjFto.mjs → session-Co0REU9e.mjs} +5 -5
- package/dist/{sessionKeyCache-dDquDzn0.cjs → sessionKeyCache-BwFUGgMs.cjs} +1 -1
- package/dist/{sessionKeyCache-D2u3JUys.mjs → sessionKeyCache-pXTjpETo.mjs} +1 -1
- package/dist/{sessionList-C1k2PNg_.mjs → sessionList-DaufR-sA.mjs} +2 -2
- package/dist/{sessionList-DmmtC7uR.cjs → sessionList-fG5uAPzU.cjs} +2 -2
- package/dist/{sessionSummary-DGLoVOxd.cjs → sessionSummary-CjZPt6nr.cjs} +3 -3
- package/dist/{sessionSummary-5a1QtFVS.mjs → sessionSummary-Dv6dPABg.mjs} +3 -3
- package/dist/setupOfflineReconnection-B6coH9QN.cjs +461 -0
- package/dist/setupOfflineReconnection-DW5il97B.mjs +457 -0
- package/dist/{spawnHappyCLI-CarRI4GM.cjs → spawnHappyCLI-Cfu7C1uM.cjs} +1 -1
- package/dist/{spawnHappyCLI-D3EkTFIn.mjs → spawnHappyCLI-DhUeycct.mjs} +1 -1
- package/dist/{ssh-B0hvEYIl.mjs → ssh-8tPIKk-i.mjs} +5 -5
- package/dist/{ssh-CBgVwKsB.cjs → ssh-C4YTSHXL.cjs} +5 -5
- package/dist/{task-CRo6W-3_.mjs → task-CH-oidFy.mjs} +6 -6
- package/dist/{task-CMunPKCV.cjs → task-DFW-PecP.cjs} +6 -6
- package/dist/{uninstall-BALE2up0.mjs → uninstall-CeioRZNI.mjs} +2 -2
- package/dist/{uninstall-BJ3eEGM4.cjs → uninstall-yTSL3X6Y.cjs} +2 -2
- package/dist/{update-Bb3iijy8.cjs → update-Bju28vNP.cjs} +3 -3
- package/dist/{update-BfjtLrhO.mjs → update-Derd2hoX.mjs} +3 -3
- package/package.json +1 -1
|
@@ -1,194 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var logger = require('./persistence-DrfN7TzY.cjs');
|
|
4
3
|
var node_crypto = require('node:crypto');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var path = require('node:path');
|
|
8
|
-
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
9
|
-
var api = require('./api-XeHlmApX.cjs');
|
|
10
|
-
var downloadImage = require('./downloadImage-B_ygLAXY.cjs');
|
|
11
|
-
|
|
12
|
-
class BasePermissionHandler {
|
|
13
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
14
|
-
session;
|
|
15
|
-
pushClient;
|
|
16
|
-
isResetting = false;
|
|
17
|
-
isUserInteractionTool(toolName) {
|
|
18
|
-
return ["AskUserQuestion", "ExitPlanMode", "exit_plan_mode"].includes(toolName);
|
|
19
|
-
}
|
|
20
|
-
constructor(session, pushClient) {
|
|
21
|
-
this.session = session;
|
|
22
|
-
this.pushClient = pushClient;
|
|
23
|
-
this.setupRpcHandler();
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Update the session reference (used after offline reconnection swaps sessions).
|
|
27
|
-
* This is critical for avoiding stale session references after onSessionSwap.
|
|
28
|
-
*/
|
|
29
|
-
updateSession(newSession) {
|
|
30
|
-
logger.logger.debug(`${this.getLogPrefix()} Session reference updated`);
|
|
31
|
-
this.session = newSession;
|
|
32
|
-
this.setupRpcHandler();
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Setup RPC handler for permission responses.
|
|
36
|
-
*/
|
|
37
|
-
setupRpcHandler() {
|
|
38
|
-
this.session.rpcHandlerManager.registerHandler(
|
|
39
|
-
"permission",
|
|
40
|
-
async (response) => {
|
|
41
|
-
const pending = this.pendingRequests.get(response.id);
|
|
42
|
-
if (!pending) {
|
|
43
|
-
logger.logger.debug(`${this.getLogPrefix()} Permission request not found or already resolved`);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
this.pendingRequests.delete(response.id);
|
|
47
|
-
const result = response.approved ? { decision: response.decision === "approved_for_session" ? "approved_for_session" : "approved" } : { decision: response.decision === "denied" ? "denied" : "abort" };
|
|
48
|
-
pending.resolve(result);
|
|
49
|
-
if (response.approved && (response.mode === "bypassPermissions" || response.decision === "approved_for_session")) {
|
|
50
|
-
this.approvePendingRequestsForSession(response);
|
|
51
|
-
}
|
|
52
|
-
this.session.updateAgentState((currentState) => {
|
|
53
|
-
const request = currentState.requests?.[response.id];
|
|
54
|
-
if (!request) return currentState;
|
|
55
|
-
const { [response.id]: _, ...remainingRequests } = currentState.requests || {};
|
|
56
|
-
let res = {
|
|
57
|
-
...currentState,
|
|
58
|
-
requests: remainingRequests,
|
|
59
|
-
completedRequests: {
|
|
60
|
-
...currentState.completedRequests,
|
|
61
|
-
[response.id]: {
|
|
62
|
-
...request,
|
|
63
|
-
completedAt: Date.now(),
|
|
64
|
-
status: response.approved ? "approved" : "denied",
|
|
65
|
-
decision: result.decision,
|
|
66
|
-
mode: response.mode,
|
|
67
|
-
allowedTools: response.allowTools
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
return res;
|
|
72
|
-
});
|
|
73
|
-
logger.logger.debug(`${this.getLogPrefix()} Permission ${response.approved ? "approved" : "denied"} for ${pending.toolName}`);
|
|
74
|
-
}
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
approvePendingRequestsForSession(response) {
|
|
78
|
-
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
79
|
-
const completedAt = Date.now();
|
|
80
|
-
for (const [id, pending] of pendingSnapshot) {
|
|
81
|
-
if (this.isUserInteractionTool(pending.toolName)) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
this.pendingRequests.delete(id);
|
|
85
|
-
pending.resolve({ decision: "approved_for_session" });
|
|
86
|
-
}
|
|
87
|
-
if (pendingSnapshot.length === 0) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
this.session.updateAgentState((currentState) => {
|
|
91
|
-
const requests = { ...currentState.requests || {} };
|
|
92
|
-
const completedRequests = { ...currentState.completedRequests };
|
|
93
|
-
let changed = false;
|
|
94
|
-
for (const [id, pending] of pendingSnapshot) {
|
|
95
|
-
if (this.isUserInteractionTool(pending.toolName)) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
const request = requests[id];
|
|
99
|
-
if (!request) {
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
delete requests[id];
|
|
103
|
-
completedRequests[id] = {
|
|
104
|
-
...request,
|
|
105
|
-
completedAt,
|
|
106
|
-
status: "approved",
|
|
107
|
-
decision: "approved_for_session",
|
|
108
|
-
mode: response.mode,
|
|
109
|
-
allowedTools: response.allowTools
|
|
110
|
-
};
|
|
111
|
-
changed = true;
|
|
112
|
-
}
|
|
113
|
-
if (!changed) {
|
|
114
|
-
return currentState;
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
...currentState,
|
|
118
|
-
requests,
|
|
119
|
-
completedRequests
|
|
120
|
-
};
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Add a pending request to the agent state and send a push notification.
|
|
125
|
-
*/
|
|
126
|
-
addPendingRequestToState(toolCallId, toolName, input) {
|
|
127
|
-
this.pushClient.sendToAllDevices(
|
|
128
|
-
"Permission Request",
|
|
129
|
-
`${this.getAgentName()} wants to ${toolName}`,
|
|
130
|
-
{
|
|
131
|
-
sessionId: this.session.sessionId,
|
|
132
|
-
requestId: toolCallId,
|
|
133
|
-
tool: toolName,
|
|
134
|
-
type: "permission_request"
|
|
135
|
-
}
|
|
136
|
-
);
|
|
137
|
-
this.session.updateAgentState((currentState) => ({
|
|
138
|
-
...currentState,
|
|
139
|
-
requests: {
|
|
140
|
-
...currentState.requests,
|
|
141
|
-
[toolCallId]: {
|
|
142
|
-
tool: toolName,
|
|
143
|
-
arguments: input,
|
|
144
|
-
createdAt: Date.now()
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}));
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Reset state for new sessions.
|
|
151
|
-
* This method is idempotent - safe to call multiple times.
|
|
152
|
-
*/
|
|
153
|
-
reset() {
|
|
154
|
-
if (this.isResetting) {
|
|
155
|
-
logger.logger.debug(`${this.getLogPrefix()} Reset already in progress, skipping`);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
this.isResetting = true;
|
|
159
|
-
try {
|
|
160
|
-
const pendingSnapshot = Array.from(this.pendingRequests.entries());
|
|
161
|
-
this.pendingRequests.clear();
|
|
162
|
-
for (const [id, pending] of pendingSnapshot) {
|
|
163
|
-
try {
|
|
164
|
-
pending.reject(new Error("Session reset"));
|
|
165
|
-
} catch (err) {
|
|
166
|
-
logger.logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
this.session.updateAgentState((currentState) => {
|
|
170
|
-
const pendingRequests = currentState.requests || {};
|
|
171
|
-
const completedRequests = { ...currentState.completedRequests };
|
|
172
|
-
for (const [id, request] of Object.entries(pendingRequests)) {
|
|
173
|
-
completedRequests[id] = {
|
|
174
|
-
...request,
|
|
175
|
-
completedAt: Date.now(),
|
|
176
|
-
status: "canceled",
|
|
177
|
-
reason: "Session reset"
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
return {
|
|
181
|
-
...currentState,
|
|
182
|
-
requests: {},
|
|
183
|
-
completedRequests
|
|
184
|
-
};
|
|
185
|
-
});
|
|
186
|
-
logger.logger.debug(`${this.getLogPrefix()} Permission handler reset`);
|
|
187
|
-
} finally {
|
|
188
|
-
this.isResetting = false;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
4
|
+
var logger = require('./persistence-BcQmjobZ.cjs');
|
|
5
|
+
var api = require('./api-CIE4_cWd.cjs');
|
|
192
6
|
|
|
193
7
|
class BaseReasoningProcessor {
|
|
194
8
|
accumulator = "";
|
|
@@ -384,273 +198,6 @@ class BaseReasoningProcessor {
|
|
|
384
198
|
}
|
|
385
199
|
}
|
|
386
200
|
|
|
387
|
-
const DEFAULT_MAX_SKILLS = 400;
|
|
388
|
-
const DEFAULT_MAX_DEPTH = 10;
|
|
389
|
-
const SKILL_FILE = "SKILL.md";
|
|
390
|
-
const IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
391
|
-
".git",
|
|
392
|
-
"node_modules",
|
|
393
|
-
"dist",
|
|
394
|
-
"build",
|
|
395
|
-
"references",
|
|
396
|
-
"assets",
|
|
397
|
-
"templates"
|
|
398
|
-
]);
|
|
399
|
-
function parseFrontMatter(content) {
|
|
400
|
-
if (!content.startsWith("---")) return {};
|
|
401
|
-
const end = content.indexOf("\n---", 3);
|
|
402
|
-
if (end < 0) return {};
|
|
403
|
-
const block = content.slice(3, end).split(/\r?\n/);
|
|
404
|
-
const result = {};
|
|
405
|
-
for (let i = 0; i < block.length; i++) {
|
|
406
|
-
const line = block[i];
|
|
407
|
-
const match = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line.trim());
|
|
408
|
-
if (!match) continue;
|
|
409
|
-
const [, key, rawValue] = match;
|
|
410
|
-
let value = rawValue.trim().replace(/^['"]|['"]$/g, "");
|
|
411
|
-
if ((rawValue.trim() === ">-" || rawValue.trim() === ">" || rawValue.trim() === "|-" || rawValue.trim() === "|") && key === "description") {
|
|
412
|
-
const continuation = [];
|
|
413
|
-
while (i + 1 < block.length && /^\s+/.test(block[i + 1])) {
|
|
414
|
-
i++;
|
|
415
|
-
continuation.push(block[i].trim());
|
|
416
|
-
}
|
|
417
|
-
value = continuation.join(rawValue.trim().startsWith("|") ? "\n" : " ").trim();
|
|
418
|
-
}
|
|
419
|
-
if (key === "name" && value) result.name = value;
|
|
420
|
-
if (key === "description" && value) result.description = value;
|
|
421
|
-
}
|
|
422
|
-
return result;
|
|
423
|
-
}
|
|
424
|
-
function deriveSkillName(skillFilePath) {
|
|
425
|
-
return path.basename(path.dirname(skillFilePath));
|
|
426
|
-
}
|
|
427
|
-
function collectSkillFiles(root, maxDepth, maxFiles) {
|
|
428
|
-
const files = [];
|
|
429
|
-
function walk(dir, depth) {
|
|
430
|
-
if (files.length >= maxFiles || depth > maxDepth) return;
|
|
431
|
-
let entries;
|
|
432
|
-
try {
|
|
433
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
434
|
-
} catch {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
for (const entry of entries) {
|
|
438
|
-
if (files.length >= maxFiles) return;
|
|
439
|
-
const fullPath = path.join(dir, entry.name);
|
|
440
|
-
if (entry.isFile() && entry.name === SKILL_FILE) {
|
|
441
|
-
files.push(fullPath);
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
if (!entry.isDirectory()) continue;
|
|
445
|
-
if (IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
446
|
-
walk(fullPath, depth + 1);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
if (fs.existsSync(root)) {
|
|
450
|
-
walk(root, 0);
|
|
451
|
-
}
|
|
452
|
-
return files;
|
|
453
|
-
}
|
|
454
|
-
function skillRoots(homeDir, includePluginCache) {
|
|
455
|
-
const roots = [
|
|
456
|
-
{ path: path.join(homeDir, ".agents", "skills"), source: "agents" },
|
|
457
|
-
{ path: path.join(homeDir, ".codex", "skills"), source: "codex" },
|
|
458
|
-
{ path: path.join(homeDir, ".claude", "skills"), source: "claude" }
|
|
459
|
-
];
|
|
460
|
-
if (includePluginCache) {
|
|
461
|
-
roots.push(
|
|
462
|
-
{ path: path.join(homeDir, ".codex", "plugins", "cache"), source: "codex-plugin-cache" },
|
|
463
|
-
{ path: path.join(homeDir, ".codex", ".tmp", "plugins", "plugins"), source: "codex-plugin-marketplace" }
|
|
464
|
-
);
|
|
465
|
-
}
|
|
466
|
-
return roots;
|
|
467
|
-
}
|
|
468
|
-
function discoverCodexSkills(options = {}) {
|
|
469
|
-
const homeDir = options.homeDir ?? os.homedir();
|
|
470
|
-
const maxSkills = options.maxSkills ?? DEFAULT_MAX_SKILLS;
|
|
471
|
-
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
472
|
-
const includePluginCache = options.includePluginCache ?? true;
|
|
473
|
-
const result = [];
|
|
474
|
-
const seen = /* @__PURE__ */ new Set();
|
|
475
|
-
for (const root of skillRoots(homeDir, includePluginCache)) {
|
|
476
|
-
if (result.length >= maxSkills) break;
|
|
477
|
-
const skillFiles = collectSkillFiles(root.path, maxDepth, maxSkills - result.length);
|
|
478
|
-
for (const skillFile of skillFiles) {
|
|
479
|
-
if (result.length >= maxSkills) break;
|
|
480
|
-
let content = "";
|
|
481
|
-
try {
|
|
482
|
-
content = fs.readFileSync(skillFile, "utf8");
|
|
483
|
-
} catch {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
const frontMatter = parseFrontMatter(content);
|
|
487
|
-
const name = (frontMatter.name || deriveSkillName(skillFile)).trim();
|
|
488
|
-
if (!name) continue;
|
|
489
|
-
const key = name.toLowerCase();
|
|
490
|
-
if (seen.has(key)) continue;
|
|
491
|
-
seen.add(key);
|
|
492
|
-
result.push({
|
|
493
|
-
name,
|
|
494
|
-
description: frontMatter.description,
|
|
495
|
-
source: root.source
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
return result;
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
function detectWorkspaceSubdirectories(cwd) {
|
|
503
|
-
try {
|
|
504
|
-
const entries = fs.readdirSync(cwd, { withFileTypes: true });
|
|
505
|
-
const repos = [];
|
|
506
|
-
for (const entry of entries) {
|
|
507
|
-
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
508
|
-
const subDir = path.join(cwd, entry.name);
|
|
509
|
-
const info = downloadImage.detectGitWorktree(subDir);
|
|
510
|
-
if (info.isWorktree && info.worktreeBasePath && info.worktreeBranchName) {
|
|
511
|
-
repos.push({
|
|
512
|
-
path: subDir,
|
|
513
|
-
basePath: info.worktreeBasePath,
|
|
514
|
-
branchName: info.worktreeBranchName,
|
|
515
|
-
displayName: entry.name
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
if (repos.length > 0) {
|
|
520
|
-
return {
|
|
521
|
-
isWorktree: true,
|
|
522
|
-
workspaceRepos: repos,
|
|
523
|
-
workspacePath: cwd
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
} catch {
|
|
527
|
-
}
|
|
528
|
-
return {};
|
|
529
|
-
}
|
|
530
|
-
function detectWorktreeMetadata() {
|
|
531
|
-
if (process.env.HAPPY_WORKSPACE_REPOS) {
|
|
532
|
-
try {
|
|
533
|
-
const repos = JSON.parse(process.env.HAPPY_WORKSPACE_REPOS);
|
|
534
|
-
return {
|
|
535
|
-
isWorktree: true,
|
|
536
|
-
workspaceRepos: repos,
|
|
537
|
-
workspacePath: process.env.HAPPY_WORKSPACE_PATH
|
|
538
|
-
};
|
|
539
|
-
} catch {
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
if (process.env.HAPPY_WORKTREE_BASE_PATH) {
|
|
543
|
-
return {
|
|
544
|
-
isWorktree: true,
|
|
545
|
-
worktreeBasePath: process.env.HAPPY_WORKTREE_BASE_PATH,
|
|
546
|
-
worktreeBranchName: process.env.HAPPY_WORKTREE_BRANCH_NAME
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
const info = downloadImage.detectGitWorktree(process.cwd());
|
|
550
|
-
if (info.isWorktree) {
|
|
551
|
-
return {
|
|
552
|
-
isWorktree: true,
|
|
553
|
-
worktreeBasePath: info.worktreeBasePath,
|
|
554
|
-
worktreeBranchName: info.worktreeBranchName
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
const workspaceResult = detectWorkspaceSubdirectories(process.cwd());
|
|
558
|
-
if (workspaceResult.isWorktree) {
|
|
559
|
-
return workspaceResult;
|
|
560
|
-
}
|
|
561
|
-
return {};
|
|
562
|
-
}
|
|
563
|
-
function createSessionMetadata(opts) {
|
|
564
|
-
const state = {
|
|
565
|
-
controlledByUser: false
|
|
566
|
-
};
|
|
567
|
-
const metadata = {
|
|
568
|
-
path: process.cwd(),
|
|
569
|
-
host: os.hostname(),
|
|
570
|
-
version: logger.packageJson.version,
|
|
571
|
-
os: os.platform(),
|
|
572
|
-
machineId: opts.machineId,
|
|
573
|
-
homeDir: os.homedir(),
|
|
574
|
-
happyHomeDir: logger.configuration.happyHomeDir,
|
|
575
|
-
happyLibDir: projectPath.projectPath(),
|
|
576
|
-
happyToolsDir: api.resolveToolsDir(),
|
|
577
|
-
startedFromDaemon: opts.startedBy === "daemon",
|
|
578
|
-
hostPid: process.pid,
|
|
579
|
-
startedBy: opts.startedBy || "terminal",
|
|
580
|
-
lifecycleState: "running",
|
|
581
|
-
lifecycleStateSince: Date.now(),
|
|
582
|
-
flavor: opts.flavor,
|
|
583
|
-
// Worktree metadata: env vars from daemon take priority, otherwise detect via git
|
|
584
|
-
...detectWorktreeMetadata()
|
|
585
|
-
};
|
|
586
|
-
if (opts.flavor === "codex") {
|
|
587
|
-
metadata.skills = discoverCodexSkills();
|
|
588
|
-
}
|
|
589
|
-
return { state, metadata };
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
function createOfflineSessionStub(sessionTag) {
|
|
593
|
-
return {
|
|
594
|
-
sessionId: `offline-${sessionTag}`,
|
|
595
|
-
sendCodexMessage: () => {
|
|
596
|
-
},
|
|
597
|
-
sendAgentMessage: () => {
|
|
598
|
-
},
|
|
599
|
-
sendClaudeSessionMessage: () => {
|
|
600
|
-
},
|
|
601
|
-
keepAlive: () => {
|
|
602
|
-
},
|
|
603
|
-
sendSessionEvent: () => {
|
|
604
|
-
},
|
|
605
|
-
sendSessionDeath: () => {
|
|
606
|
-
},
|
|
607
|
-
updateLifecycleState: () => {
|
|
608
|
-
},
|
|
609
|
-
requestControlTransfer: async () => {
|
|
610
|
-
},
|
|
611
|
-
flush: async () => {
|
|
612
|
-
},
|
|
613
|
-
close: async () => {
|
|
614
|
-
},
|
|
615
|
-
updateMetadata: () => {
|
|
616
|
-
},
|
|
617
|
-
updateAgentState: () => {
|
|
618
|
-
},
|
|
619
|
-
onUserMessage: () => {
|
|
620
|
-
},
|
|
621
|
-
rpcHandlerManager: {
|
|
622
|
-
registerHandler: () => {
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
function setupOfflineReconnection(opts) {
|
|
629
|
-
const { api: api$1, sessionTag, metadata, state, response, onSessionSwap } = opts;
|
|
630
|
-
let session;
|
|
631
|
-
let reconnectionHandle = null;
|
|
632
|
-
if (!response) {
|
|
633
|
-
session = createOfflineSessionStub(sessionTag);
|
|
634
|
-
reconnectionHandle = api.startOfflineReconnection({
|
|
635
|
-
serverUrl: logger.configuration.serverUrl,
|
|
636
|
-
onReconnected: async () => {
|
|
637
|
-
const resp = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
638
|
-
if (!resp) throw new Error("Server unavailable");
|
|
639
|
-
const realSession = api$1.sessionSyncClient(resp);
|
|
640
|
-
onSessionSwap(realSession);
|
|
641
|
-
return realSession;
|
|
642
|
-
},
|
|
643
|
-
onNotify: (msg) => {
|
|
644
|
-
console.log(msg);
|
|
645
|
-
}
|
|
646
|
-
});
|
|
647
|
-
return { session, reconnectionHandle, isOffline: true };
|
|
648
|
-
} else {
|
|
649
|
-
session = api$1.sessionSyncClient(response);
|
|
650
|
-
return { session, reconnectionHandle: null, isOffline: false };
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
|
|
654
201
|
const SUPPORTED_CATEGORIES = /* @__PURE__ */ new Set(["mode", "model", "thought_level"]);
|
|
655
202
|
function isRecord(value) {
|
|
656
203
|
return !!value && typeof value === "object";
|
|
@@ -1191,9 +738,7 @@ function summarizeBashToolOutput(options) {
|
|
|
1191
738
|
});
|
|
1192
739
|
}
|
|
1193
740
|
|
|
1194
|
-
exports.BasePermissionHandler = BasePermissionHandler;
|
|
1195
741
|
exports.BaseReasoningProcessor = BaseReasoningProcessor;
|
|
1196
|
-
exports.createSessionMetadata = createSessionMetadata;
|
|
1197
742
|
exports.handleAgentMessageChunk = handleAgentMessageChunk;
|
|
1198
743
|
exports.handleAgentThoughtChunk = handleAgentThoughtChunk;
|
|
1199
744
|
exports.handleConfigMetadataEvent = handleConfigMetadataEvent;
|
|
@@ -1202,5 +747,4 @@ exports.handlePlanUpdate = handlePlanUpdate;
|
|
|
1202
747
|
exports.handleThinkingUpdate = handleThinkingUpdate;
|
|
1203
748
|
exports.handleToolCall = handleToolCall;
|
|
1204
749
|
exports.handleToolCallUpdate = handleToolCallUpdate;
|
|
1205
|
-
exports.setupOfflineReconnection = setupOfflineReconnection;
|
|
1206
750
|
exports.summarizeBashToolOutput = summarizeBashToolOutput;
|
|
@@ -35,7 +35,7 @@ function isDebug() {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
var name = "@zonease/happy";
|
|
38
|
-
var version = "0.6.
|
|
38
|
+
var version = "0.6.42";
|
|
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.
|
|
17
|
+
var version = "0.6.42";
|
|
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-
|
|
6
|
-
var ssh = require('./ssh-
|
|
5
|
+
var logger = require('./persistence-BcQmjobZ.cjs');
|
|
6
|
+
var ssh = require('./ssh-C4YTSHXL.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-
|
|
15
|
+
require('./deviceKeys-DyUn0bEx.cjs');
|
|
16
16
|
require('axios');
|
|
17
|
-
require('./auth-
|
|
17
|
+
require('./auth-G9fZpVJ2.cjs');
|
|
18
18
|
require('qrcode-terminal');
|
|
19
19
|
require('./time-Bj2HRkKH.cjs');
|
|
20
|
-
require('./browser-
|
|
20
|
+
require('./browser-qDIIAL7S.cjs');
|
|
21
21
|
require('open');
|
|
22
22
|
require('react');
|
|
23
23
|
require('ink');
|
|
24
|
-
require('./controlClient-
|
|
24
|
+
require('./controlClient-CEz_p1zc.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-
|
|
4
|
-
import { resolveDeviceForCommand } from './ssh-
|
|
3
|
+
import { c as configuration, e as encodeBase64, f as encrypt, g as decrypt, h as decodeBase64 } from './persistence-D9tMm6bj.mjs';
|
|
4
|
+
import { resolveDeviceForCommand } from './ssh-8tPIKk-i.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-
|
|
13
|
+
import './deviceKeys-B4aqjnE6.mjs';
|
|
14
14
|
import 'axios';
|
|
15
|
-
import './auth-
|
|
15
|
+
import './auth-Q2STUNI-.mjs';
|
|
16
16
|
import 'qrcode-terminal';
|
|
17
17
|
import './time-DgsBLJA_.mjs';
|
|
18
|
-
import './browser-
|
|
18
|
+
import './browser-BI7s-V8E.mjs';
|
|
19
19
|
import 'open';
|
|
20
20
|
import 'react';
|
|
21
21
|
import 'ink';
|
|
22
|
-
import './controlClient-
|
|
22
|
+
import './controlClient-DoS9JqQC.mjs';
|
|
23
23
|
import './projectPath-BTBIMB57.mjs';
|
|
24
24
|
import 'path';
|
|
25
25
|
import 'url';
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import fs from 'fs/promises';
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import * as tmp from 'tmp';
|
|
4
|
-
import { A as ApiClient } from './api-
|
|
5
|
-
import { c as configuration, l as logger, p as packageJson, v as acquireDaemonLock, a as readSettings, i as isDebug, e as encodeBase64, x as writeDaemonState, m as readDaemonState, y as releaseDaemonLock, z as validateProfileForAgent, A as getProfileEnvironmentVariables } from './persistence-
|
|
6
|
-
import { authAndSetupMachineIfNeeded } from './auth-
|
|
4
|
+
import { A as ApiClient } from './api-Ew6xr81i.mjs';
|
|
5
|
+
import { c as configuration, l as logger, p as packageJson, v as acquireDaemonLock, a as readSettings, i as isDebug, e as encodeBase64, x as writeDaemonState, m as readDaemonState, y as releaseDaemonLock, z as validateProfileForAgent, A as getProfileEnvironmentVariables } from './persistence-D9tMm6bj.mjs';
|
|
6
|
+
import { authAndSetupMachineIfNeeded } from './auth-Q2STUNI-.mjs';
|
|
7
7
|
import { spawn, execSync, exec } from 'child_process';
|
|
8
|
-
import { getEnvironmentInfo } from './doctor-
|
|
9
|
-
import { s as spawnHappyCLI } from './spawnHappyCLI-
|
|
10
|
-
import { isDaemonRunningCurrentlyInstalledHappyVersion, stopDaemon, cleanupDaemonState } from './controlClient-
|
|
11
|
-
import { a as readCachedDeviceKey, d as deviceExec } from './deviceKeys-
|
|
12
|
-
import { P as PLIST_LABEL } from './install-
|
|
8
|
+
import { getEnvironmentInfo } from './doctor-DRnft_5-.mjs';
|
|
9
|
+
import { s as spawnHappyCLI } from './spawnHappyCLI-DhUeycct.mjs';
|
|
10
|
+
import { isDaemonRunningCurrentlyInstalledHappyVersion, stopDaemon, cleanupDaemonState } from './controlClient-DoS9JqQC.mjs';
|
|
11
|
+
import { a as readCachedDeviceKey, d as deviceExec } from './deviceKeys-B4aqjnE6.mjs';
|
|
12
|
+
import { P as PLIST_LABEL } from './install-DBg0xQ3g.mjs';
|
|
13
13
|
import fastify from 'fastify';
|
|
14
14
|
import { createReadStream } from 'node:fs';
|
|
15
15
|
import { stat } from 'node:fs/promises';
|
|
@@ -1759,7 +1759,7 @@ ${error.message}
|
|
|
1759
1759
|
logger.debug(`[DAEMON RUN] Attempting to spawn session in tmux: ${sessionDesc}`);
|
|
1760
1760
|
const tmux = getTmuxUtilities(tmuxSessionName);
|
|
1761
1761
|
const cliPath = join(projectPath(), "dist", "index.mjs");
|
|
1762
|
-
const agent = options.agent === "gemini" ? "gemini" : options.agent === "codex" ? "codex" : "claude";
|
|
1762
|
+
const agent = options.agent === "gemini" ? "gemini" : options.agent === "codex" ? "codex" : options.agent === "cursor" ? "cursor" : "claude";
|
|
1763
1763
|
const forkFlag = skipForkSession ? "" : " --fork-session";
|
|
1764
1764
|
const resumeArgs = resumeSessionId && isClaudeAgent ? ` --resume ${resumeSessionId}${forkFlag}` : "";
|
|
1765
1765
|
const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${agent} --happy-starting-mode remote --started-by daemon${resumeArgs}`;
|
|
@@ -1830,6 +1830,9 @@ ${error.message}
|
|
|
1830
1830
|
case "gemini":
|
|
1831
1831
|
agentCommand = "gemini";
|
|
1832
1832
|
break;
|
|
1833
|
+
case "cursor":
|
|
1834
|
+
agentCommand = "cursor";
|
|
1835
|
+
break;
|
|
1833
1836
|
default:
|
|
1834
1837
|
return {
|
|
1835
1838
|
type: "error",
|