@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,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- var logger = require('./persistence-DrfN7TzY.cjs');
4
- var crypto = require('crypto');
5
3
  var path = require('node:path');
6
4
  var projectPath = require('./projectPath-ChLhdOyt.cjs');
7
5
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
@@ -9,18 +7,20 @@ var node_http = require('node:http');
9
7
  var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
10
8
  var types_js = require('@modelcontextprotocol/sdk/types.js');
11
9
  var z = require('zod');
12
- var deviceKeys = require('./deviceKeys-BpIAWz13.cjs');
10
+ var logger = require('./persistence-D7zNFI-d.cjs');
11
+ var deviceKeys = require('./deviceKeys-CdW-HPnz.cjs');
13
12
  var node_crypto = require('node:crypto');
14
13
  var prompt = require('./prompt-BTWDZZO0.cjs');
15
14
  require('./mcpToolSchemas-DK42yoZ_.cjs');
16
- require('./index-CDTNgfUf.cjs');
15
+ require('./index-BeKrqPYR.cjs');
17
16
  var node_child_process = require('node:child_process');
18
- var axios = require('axios');
17
+ require('axios');
19
18
  require('node:events');
20
19
  require('socket.io-client');
21
- require('./api-XeHlmApX.cjs');
20
+ require('./api-B-PlVQY6.cjs');
22
21
  require('tweetnacl');
23
22
  require('ws');
23
+ require('crypto');
24
24
  require('@stablelib/base64');
25
25
  require('node:os');
26
26
  require('node:fs/promises');
@@ -30,403 +30,6 @@ require('expo-server-sdk');
30
30
  require('chalk');
31
31
  require('./types-DWeB7aqh.cjs');
32
32
 
33
- function parseCompact(message) {
34
- const trimmed = message.trim();
35
- if (trimmed === "/compact") {
36
- return {
37
- isCompact: true,
38
- originalMessage: trimmed
39
- };
40
- }
41
- if (trimmed.startsWith("/compact ")) {
42
- return {
43
- isCompact: true,
44
- originalMessage: trimmed
45
- };
46
- }
47
- return {
48
- isCompact: false,
49
- originalMessage: message
50
- };
51
- }
52
- function parseClear(message) {
53
- const trimmed = message.trim();
54
- return {
55
- isClear: trimmed === "/clear"
56
- };
57
- }
58
- function parseSpecialCommand(message) {
59
- const compactResult = parseCompact(message);
60
- if (compactResult.isCompact) {
61
- return {
62
- type: "compact",
63
- originalMessage: compactResult.originalMessage
64
- };
65
- }
66
- const clearResult = parseClear(message);
67
- if (clearResult.isClear) {
68
- return {
69
- type: "clear"
70
- };
71
- }
72
- return {
73
- type: null
74
- };
75
- }
76
-
77
- class MessageQueue2 {
78
- queue = [];
79
- // Made public for testing
80
- waiter = null;
81
- closed = false;
82
- onMessageHandler = null;
83
- modeHasher;
84
- constructor(modeHasher, onMessageHandler = null) {
85
- this.modeHasher = modeHasher;
86
- this.onMessageHandler = onMessageHandler;
87
- logger.logger.debug(`[MessageQueue2] Initialized`);
88
- }
89
- /**
90
- * Set a handler that will be called when a message arrives
91
- */
92
- setOnMessage(handler) {
93
- this.onMessageHandler = handler;
94
- }
95
- /**
96
- * Push a message to the queue with a mode.
97
- */
98
- push(message, mode) {
99
- if (this.closed) {
100
- throw new Error("Cannot push to closed queue");
101
- }
102
- const modeHash = this.modeHasher(mode);
103
- logger.logger.debug(`[MessageQueue2] push() called with mode hash: ${modeHash}`);
104
- this.queue.push({
105
- message,
106
- mode,
107
- modeHash,
108
- isolate: false
109
- });
110
- if (this.onMessageHandler) {
111
- this.onMessageHandler(message, mode);
112
- }
113
- if (this.waiter) {
114
- logger.logger.debug(`[MessageQueue2] Notifying waiter`);
115
- const waiter = this.waiter;
116
- this.waiter = null;
117
- waiter(true);
118
- }
119
- logger.logger.debug(`[MessageQueue2] push() completed. Queue size: ${this.queue.length}`);
120
- }
121
- /**
122
- * Push a message immediately without batching delay.
123
- * Does not clear the queue or enforce isolation.
124
- */
125
- pushImmediate(message, mode) {
126
- if (this.closed) {
127
- throw new Error("Cannot push to closed queue");
128
- }
129
- const modeHash = this.modeHasher(mode);
130
- logger.logger.debug(`[MessageQueue2] pushImmediate() called with mode hash: ${modeHash}`);
131
- this.queue.push({
132
- message,
133
- mode,
134
- modeHash,
135
- isolate: false
136
- });
137
- if (this.onMessageHandler) {
138
- this.onMessageHandler(message, mode);
139
- }
140
- if (this.waiter) {
141
- logger.logger.debug(`[MessageQueue2] Notifying waiter for immediate message`);
142
- const waiter = this.waiter;
143
- this.waiter = null;
144
- waiter(true);
145
- }
146
- logger.logger.debug(`[MessageQueue2] pushImmediate() completed. Queue size: ${this.queue.length}`);
147
- }
148
- /**
149
- * Push a message that must be processed in complete isolation.
150
- * Clears any pending messages and ensures this message is never batched with others.
151
- * Used for special commands that require dedicated processing.
152
- */
153
- pushIsolateAndClear(message, mode) {
154
- if (this.closed) {
155
- throw new Error("Cannot push to closed queue");
156
- }
157
- const modeHash = this.modeHasher(mode);
158
- logger.logger.debug(`[MessageQueue2] pushIsolateAndClear() called with mode hash: ${modeHash} - clearing ${this.queue.length} pending messages`);
159
- this.queue = [];
160
- this.queue.push({
161
- message,
162
- mode,
163
- modeHash,
164
- isolate: true
165
- });
166
- if (this.onMessageHandler) {
167
- this.onMessageHandler(message, mode);
168
- }
169
- if (this.waiter) {
170
- logger.logger.debug(`[MessageQueue2] Notifying waiter for isolated message`);
171
- const waiter = this.waiter;
172
- this.waiter = null;
173
- waiter(true);
174
- }
175
- logger.logger.debug(`[MessageQueue2] pushIsolateAndClear() completed. Queue size: ${this.queue.length}`);
176
- }
177
- /**
178
- * Push a message to the beginning of the queue with a mode.
179
- */
180
- unshift(message, mode) {
181
- if (this.closed) {
182
- throw new Error("Cannot unshift to closed queue");
183
- }
184
- const modeHash = this.modeHasher(mode);
185
- logger.logger.debug(`[MessageQueue2] unshift() called with mode hash: ${modeHash}`);
186
- this.queue.unshift({
187
- message,
188
- mode,
189
- modeHash,
190
- isolate: false
191
- });
192
- if (this.onMessageHandler) {
193
- this.onMessageHandler(message, mode);
194
- }
195
- if (this.waiter) {
196
- logger.logger.debug(`[MessageQueue2] Notifying waiter`);
197
- const waiter = this.waiter;
198
- this.waiter = null;
199
- waiter(true);
200
- }
201
- logger.logger.debug(`[MessageQueue2] unshift() completed. Queue size: ${this.queue.length}`);
202
- }
203
- /**
204
- * Reset the queue - clears all messages and resets to empty state
205
- */
206
- reset() {
207
- logger.logger.debug(`[MessageQueue2] reset() called. Clearing ${this.queue.length} messages`);
208
- this.queue = [];
209
- this.closed = false;
210
- this.waiter = null;
211
- }
212
- /**
213
- * Close the queue - no more messages can be pushed
214
- */
215
- close() {
216
- logger.logger.debug(`[MessageQueue2] close() called`);
217
- this.closed = true;
218
- if (this.waiter) {
219
- const waiter = this.waiter;
220
- this.waiter = null;
221
- waiter(false);
222
- }
223
- }
224
- /**
225
- * Check if the queue is closed
226
- */
227
- isClosed() {
228
- return this.closed;
229
- }
230
- /**
231
- * Get the current queue size
232
- */
233
- size() {
234
- return this.queue.length;
235
- }
236
- /**
237
- * Wait for messages and return all messages with the same mode.
238
- * For string messages, multiple messages are joined with newlines.
239
- * For object messages (e.g., mixed content with images), returns them one at a time.
240
- * Returns { message: M, mode: T } or null if aborted/closed
241
- */
242
- async waitForMessagesAndGetAsString(abortSignal) {
243
- if (this.queue.length > 0) {
244
- return this.collectBatch();
245
- }
246
- if (this.closed || abortSignal?.aborted) {
247
- return null;
248
- }
249
- const hasMessages = await this.waitForMessages(abortSignal);
250
- if (!hasMessages) {
251
- return null;
252
- }
253
- return this.collectBatch();
254
- }
255
- /**
256
- * Collect a batch of messages with the same mode, respecting isolation requirements.
257
- * For string messages, joins them with newlines.
258
- * For object messages (like mixed content with images), returns one at a time.
259
- */
260
- collectBatch() {
261
- if (this.queue.length === 0) {
262
- return null;
263
- }
264
- const firstItem = this.queue[0];
265
- let mode = firstItem.mode;
266
- let isolate = firstItem.isolate ?? false;
267
- const targetModeHash = firstItem.modeHash;
268
- if (firstItem.isolate) {
269
- const item = this.queue.shift();
270
- logger.logger.debug(`[MessageQueue2] Collected isolated message with mode hash: ${targetModeHash}`);
271
- return {
272
- message: item.message,
273
- mode,
274
- hash: targetModeHash,
275
- isolate
276
- };
277
- }
278
- if (typeof firstItem.message !== "string") {
279
- const item = this.queue.shift();
280
- logger.logger.debug(`[MessageQueue2] Collected single object message with mode hash: ${targetModeHash}`);
281
- return {
282
- message: item.message,
283
- mode,
284
- hash: targetModeHash,
285
- isolate
286
- };
287
- }
288
- const sameModeMessages = [];
289
- while (this.queue.length > 0 && this.queue[0].modeHash === targetModeHash && !this.queue[0].isolate && typeof this.queue[0].message === "string") {
290
- const item = this.queue.shift();
291
- sameModeMessages.push(item.message);
292
- }
293
- logger.logger.debug(`[MessageQueue2] Collected batch of ${sameModeMessages.length} messages with mode hash: ${targetModeHash}`);
294
- const combinedMessage = sameModeMessages.join("\n");
295
- return {
296
- message: combinedMessage,
297
- mode,
298
- hash: targetModeHash,
299
- isolate
300
- };
301
- }
302
- /**
303
- * Wait for messages to arrive
304
- */
305
- waitForMessages(abortSignal) {
306
- return new Promise((resolve) => {
307
- let abortHandler = null;
308
- if (abortSignal) {
309
- abortHandler = () => {
310
- logger.logger.debug("[MessageQueue2] Wait aborted");
311
- if (this.waiter === waiterFunc) {
312
- this.waiter = null;
313
- }
314
- resolve(false);
315
- };
316
- abortSignal.addEventListener("abort", abortHandler);
317
- }
318
- const waiterFunc = (hasMessages) => {
319
- if (abortHandler && abortSignal) {
320
- abortSignal.removeEventListener("abort", abortHandler);
321
- }
322
- resolve(hasMessages);
323
- };
324
- if (this.queue.length > 0) {
325
- if (abortHandler && abortSignal) {
326
- abortSignal.removeEventListener("abort", abortHandler);
327
- }
328
- resolve(true);
329
- return;
330
- }
331
- if (this.closed || abortSignal?.aborted) {
332
- if (abortHandler && abortSignal) {
333
- abortSignal.removeEventListener("abort", abortHandler);
334
- }
335
- resolve(false);
336
- return;
337
- }
338
- this.waiter = waiterFunc;
339
- logger.logger.debug("[MessageQueue2] Waiting for messages...");
340
- });
341
- }
342
- }
343
-
344
- function deterministicStringify(obj, options = {}) {
345
- const {
346
- undefinedBehavior = "omit",
347
- sortArrays = false,
348
- replacer,
349
- includeSymbols = false
350
- } = options;
351
- const seen = /* @__PURE__ */ new WeakSet();
352
- function processValue(value, key) {
353
- if (replacer && key !== void 0) {
354
- value = replacer(key, value);
355
- }
356
- if (value === null) return null;
357
- if (value === void 0) {
358
- switch (undefinedBehavior) {
359
- case "omit":
360
- return void 0;
361
- case "null":
362
- return null;
363
- case "throw":
364
- throw new Error(`Undefined value at key: ${key}`);
365
- }
366
- }
367
- if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
368
- return value;
369
- }
370
- if (value instanceof Date) {
371
- return value.toISOString();
372
- }
373
- if (value instanceof RegExp) {
374
- return value.toString();
375
- }
376
- if (typeof value === "function") {
377
- return void 0;
378
- }
379
- if (typeof value === "symbol") {
380
- return includeSymbols ? value.toString() : void 0;
381
- }
382
- if (typeof value === "bigint") {
383
- return value.toString() + "n";
384
- }
385
- if (seen.has(value)) {
386
- throw new Error("Circular reference detected");
387
- }
388
- seen.add(value);
389
- if (Array.isArray(value)) {
390
- const processed2 = value.map((item, index) => processValue(item, String(index))).filter((item) => item !== void 0);
391
- if (sortArrays) {
392
- processed2.sort((a, b) => {
393
- const aStr = JSON.stringify(processValue(a));
394
- const bStr = JSON.stringify(processValue(b));
395
- return aStr.localeCompare(bStr);
396
- });
397
- }
398
- seen.delete(value);
399
- return processed2;
400
- }
401
- if (value.constructor === Object || value.constructor === void 0) {
402
- const processed2 = {};
403
- const keys = Object.keys(value).sort();
404
- for (const k of keys) {
405
- const processedValue = processValue(value[k], k);
406
- if (processedValue !== void 0) {
407
- processed2[k] = processedValue;
408
- }
409
- }
410
- seen.delete(value);
411
- return processed2;
412
- }
413
- try {
414
- const plain = { ...value };
415
- seen.delete(value);
416
- return processValue(plain, key);
417
- } catch {
418
- seen.delete(value);
419
- return String(value);
420
- }
421
- }
422
- const processed = processValue(obj);
423
- return JSON.stringify(processed);
424
- }
425
- function hashObject(obj, options, encoding = "hex") {
426
- const jsonString = deterministicStringify(obj, options);
427
- return crypto.createHash("sha256").update(jsonString).digest(encoding);
428
- }
429
-
430
33
  function createMcpServer(client, options) {
431
34
  const mcp = new mcp_js.McpServer({
432
35
  name: "Happy MCP",
@@ -792,76 +395,6 @@ function detectGitWorktree(cwd) {
792
395
  }
793
396
  }
794
397
 
795
- class MessageBuffer {
796
- messages = [];
797
- listeners = [];
798
- nextId = 1;
799
- addMessage(content, type = "assistant") {
800
- const message = {
801
- id: `msg-${this.nextId++}`,
802
- timestamp: /* @__PURE__ */ new Date(),
803
- content,
804
- type
805
- };
806
- this.messages.push(message);
807
- this.notifyListeners();
808
- }
809
- /**
810
- * Update the last message of a specific type by appending content to it
811
- * Useful for streaming responses where deltas should accumulate in one message
812
- */
813
- updateLastMessage(contentDelta, type = "assistant") {
814
- for (let i = this.messages.length - 1; i >= 0; i--) {
815
- if (this.messages[i].type === type) {
816
- const oldMessage = this.messages[i];
817
- const updatedMessage = {
818
- ...oldMessage,
819
- content: oldMessage.content + contentDelta
820
- };
821
- this.messages[i] = updatedMessage;
822
- this.notifyListeners();
823
- return;
824
- }
825
- }
826
- this.addMessage(contentDelta, type);
827
- }
828
- /**
829
- * Remove the last message of a specific type
830
- * Useful for removing placeholder messages like "Thinking..." when actual response starts
831
- */
832
- removeLastMessage(type) {
833
- for (let i = this.messages.length - 1; i >= 0; i--) {
834
- if (this.messages[i].type === type) {
835
- this.messages.splice(i, 1);
836
- this.notifyListeners();
837
- return true;
838
- }
839
- }
840
- return false;
841
- }
842
- getMessages() {
843
- return [...this.messages];
844
- }
845
- clear() {
846
- this.messages = [];
847
- this.nextId = 1;
848
- this.notifyListeners();
849
- }
850
- onUpdate(listener) {
851
- this.listeners.push(listener);
852
- return () => {
853
- const index = this.listeners.indexOf(listener);
854
- if (index > -1) {
855
- this.listeners.splice(index, 1);
856
- }
857
- };
858
- }
859
- notifyListeners() {
860
- const messages = this.getMessages();
861
- this.listeners.forEach((listener) => listener(messages));
862
- }
863
- }
864
-
865
398
  function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
866
399
  rpcHandlerManager.registerHandler("killSession", async () => {
867
400
  logger.logger.debug("Kill session request received");
@@ -873,25 +406,6 @@ function registerKillSessionHandler(rpcHandlerManager, killThisHappy) {
873
406
  });
874
407
  }
875
408
 
876
- async function downloadImage(url) {
877
- const response = await axios.get(url, {
878
- responseType: "arraybuffer"
879
- });
880
- const buffer = Buffer.from(response.data);
881
- const base64 = buffer.toString("base64");
882
- let mimeType = response.headers["content-type"] || "image/jpeg";
883
- if (mimeType.includes(";")) {
884
- mimeType = mimeType.split(";")[0].trim();
885
- }
886
- return { base64, mimeType };
887
- }
888
-
889
- exports.MessageBuffer = MessageBuffer;
890
- exports.MessageQueue2 = MessageQueue2;
891
409
  exports.createMcpContext = createMcpContext;
892
410
  exports.detectGitWorktree = detectGitWorktree;
893
- exports.downloadImage = downloadImage;
894
- exports.hashObject = hashObject;
895
- exports.parseClear = parseClear;
896
- exports.parseSpecialCommand = parseSpecialCommand;
897
411
  exports.registerKillSessionHandler = registerKillSessionHandler;
@@ -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-K2-jr9ar.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-CIUFyOwz.mjs';
6
- import { authAndSetupMachineIfNeeded } from './auth-DS8fzlin.mjs';
4
+ import { A as ApiClient } from './api-BUCtd3cB.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-DbLMvLvk.mjs';
6
+ import { authAndSetupMachineIfNeeded } from './auth-qM2eojWx.mjs';
7
7
  import { spawn, execSync, exec } from 'child_process';
8
- import { getEnvironmentInfo } from './doctor-B-LCMVN9.mjs';
9
- import { s as spawnHappyCLI } from './spawnHappyCLI-D3EkTFIn.mjs';
10
- import { isDaemonRunningCurrentlyInstalledHappyVersion, stopDaemon, cleanupDaemonState } from './controlClient-DgjVRN8D.mjs';
11
- import { a as readCachedDeviceKey, d as deviceExec } from './deviceKeys-CejCdWpw.mjs';
12
- import { P as PLIST_LABEL } from './install-B3mMGISS.mjs';
8
+ import { getEnvironmentInfo } from './doctor-DDT2TXHH.mjs';
9
+ import { s as spawnHappyCLI } from './spawnHappyCLI-Dt7fbmbk.mjs';
10
+ import { isDaemonRunningCurrentlyInstalledHappyVersion, stopDaemon, cleanupDaemonState } from './controlClient-BzzTNSfl.mjs';
11
+ import { a as readCachedDeviceKey, d as deviceExec } from './deviceKeys-CQyFFPtt.mjs';
12
+ import { P as PLIST_LABEL } from './install-BOIcR_Wr.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",
@@ -1848,6 +1851,8 @@ ${error.message}
1848
1851
  if (!skipForkSession) {
1849
1852
  args.push("--fork-session");
1850
1853
  }
1854
+ } else if (resumeSessionId && options.agent === "cursor") {
1855
+ args.push("--resume", resumeSessionId);
1851
1856
  }
1852
1857
  const happyProcess = spawnHappyCLI(args, {
1853
1858
  cwd: directory,
@@ -3,15 +3,15 @@
3
3
  var fs$1 = require('fs/promises');
4
4
  var os = require('os');
5
5
  var tmp = require('tmp');
6
- var api = require('./api-XeHlmApX.cjs');
7
- var logger = require('./persistence-DrfN7TzY.cjs');
8
- var auth = require('./auth-BQvEuSs5.cjs');
6
+ var api = require('./api-B-PlVQY6.cjs');
7
+ var logger = require('./persistence-D7zNFI-d.cjs');
8
+ var auth = require('./auth-BqGkUXvq.cjs');
9
9
  var child_process = require('child_process');
10
- var doctor = require('./doctor-DznasgP3.cjs');
11
- var spawnHappyCLI = require('./spawnHappyCLI-CarRI4GM.cjs');
12
- var controlClient = require('./controlClient-DgELDZgM.cjs');
13
- var deviceKeys = require('./deviceKeys-BpIAWz13.cjs');
14
- var install = require('./install-Ck22tYHP.cjs');
10
+ var doctor = require('./doctor-D4xWXiE7.cjs');
11
+ var spawnHappyCLI = require('./spawnHappyCLI-C2uY9WV-.cjs');
12
+ var controlClient = require('./controlClient-yTkpwcOq.cjs');
13
+ var deviceKeys = require('./deviceKeys-CdW-HPnz.cjs');
14
+ var install = require('./install-Jrs6YUu8.cjs');
15
15
  var fastify = require('fastify');
16
16
  var fs = require('node:fs');
17
17
  var promises = require('node:fs/promises');
@@ -1780,7 +1780,7 @@ ${error.message}
1780
1780
  logger.logger.debug(`[DAEMON RUN] Attempting to spawn session in tmux: ${sessionDesc}`);
1781
1781
  const tmux = getTmuxUtilities(tmuxSessionName);
1782
1782
  const cliPath = path$1.join(projectPath.projectPath(), "dist", "index.mjs");
1783
- const agent = options.agent === "gemini" ? "gemini" : options.agent === "codex" ? "codex" : "claude";
1783
+ const agent = options.agent === "gemini" ? "gemini" : options.agent === "codex" ? "codex" : options.agent === "cursor" ? "cursor" : "claude";
1784
1784
  const forkFlag = skipForkSession ? "" : " --fork-session";
1785
1785
  const resumeArgs = resumeSessionId && isClaudeAgent ? ` --resume ${resumeSessionId}${forkFlag}` : "";
1786
1786
  const fullCommand = `node --no-warnings --no-deprecation ${cliPath} ${agent} --happy-starting-mode remote --started-by daemon${resumeArgs}`;
@@ -1851,6 +1851,9 @@ ${error.message}
1851
1851
  case "gemini":
1852
1852
  agentCommand = "gemini";
1853
1853
  break;
1854
+ case "cursor":
1855
+ agentCommand = "cursor";
1856
+ break;
1854
1857
  default:
1855
1858
  return {
1856
1859
  type: "error",
@@ -1869,6 +1872,8 @@ ${error.message}
1869
1872
  if (!skipForkSession) {
1870
1873
  args.push("--fork-session");
1871
1874
  }
1875
+ } else if (resumeSessionId && options.agent === "cursor") {
1876
+ args.push("--resume", resumeSessionId);
1872
1877
  }
1873
1878
  const happyProcess = spawnHappyCLI.spawnHappyCLI(args, {
1874
1879
  cwd: directory,