@zonease/happy 0.6.37 → 0.6.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{types-DYCJXXdA.mjs → api-CIZKyfSn.mjs} +136 -1725
- package/dist/{types-BrTorNAy.cjs → api-CwOCQeLH.cjs} +317 -1961
- package/dist/auth-0VnlXT9f.mjs +181 -0
- package/dist/auth-BE8dD20T.mjs +270 -0
- package/dist/auth-BIleVCw0.cjs +274 -0
- package/dist/auth-Cas9DR3b.cjs +183 -0
- package/dist/browser-Cc08m7of.cjs +22 -0
- package/dist/browser-Dll5hxOV.mjs +20 -0
- package/dist/claudeLocal-CPT3zcIU.mjs +344 -0
- package/dist/claudeLocal-WkgLbl1a.cjs +352 -0
- package/dist/codex/happyMcpStdioBridge.cjs +4 -1
- package/dist/codex/happyMcpStdioBridge.mjs +4 -1
- package/dist/common-BdNgghUJ.mjs +75 -0
- package/dist/common-CZvSRU4p.cjs +83 -0
- package/dist/{config-D_g6ohaV.cjs → config-Draa-5XC.cjs} +21 -34
- package/dist/{config-DPn-cbpz.mjs → config-rTT4qTU5.mjs} +7 -20
- package/dist/connect-BfC1tYP_.mjs +679 -0
- package/dist/connect-CJZ73syK.cjs +681 -0
- package/dist/{constants-B4x1K7by.cjs → constants-E_UWYTo3.cjs} +2 -2
- package/dist/{constants-BO9OAFOT.mjs → constants-pmXZGibX.mjs} +1 -1
- package/dist/controlClient-CM_QcJnB.mjs +159 -0
- package/dist/controlClient-DZMIsKsT.cjs +168 -0
- package/dist/deviceExec-CU1R9CRb.cjs +84 -0
- package/dist/deviceExec-D93AOVV4.mjs +81 -0
- package/dist/diagnose-B3D1a_v0.cjs +60 -0
- package/dist/diagnose-CuRKXxt1.mjs +58 -0
- package/dist/doctor-C08m5Z9f.cjs +78 -0
- package/dist/doctor-Cya9YSA0.cjs +214 -0
- package/dist/doctor-DZYB6IVc.mjs +211 -0
- package/dist/doctor-ON7pN5G5.mjs +74 -0
- package/dist/downloadImage-DfSFLb-h.mjs +887 -0
- package/dist/downloadImage-MQMrUUxS.cjs +897 -0
- package/dist/enroll-BxlbVftP.cjs +115 -0
- package/dist/enroll-C52x8oly.mjs +113 -0
- package/dist/evidence-Ccd9iYcj.mjs +127 -0
- package/dist/evidence-CjWBG5rX.cjs +129 -0
- package/dist/formatImageMessage-B4lSxlk2.mjs +43 -0
- package/dist/formatImageMessage-DbyG8c2j.cjs +46 -0
- package/dist/github-DKcyF1zp.mjs +57 -0
- package/dist/github-h9GhJJ_C.cjs +59 -0
- package/dist/index-CDTNgfUf.cjs +578 -0
- package/dist/index-CPKdvi7J.mjs +554 -0
- package/dist/index.cjs +812 -40
- package/dist/index.mjs +813 -40
- package/dist/install-BokHRgFW.cjs +98 -0
- package/dist/install-C_cp8b2-.cjs +96 -0
- package/dist/install-DAeCn8ae.mjs +94 -0
- package/dist/install-oRAjVLjP.mjs +95 -0
- package/dist/lib.cjs +18 -12
- package/dist/lib.d.cts +16 -16
- package/dist/lib.d.mts +16 -16
- package/dist/lib.mjs +13 -7
- package/dist/{loadableToolOutput-lQH8Kb_w.mjs → loadableToolOutput-Cuygmd4K.mjs} +4 -2
- package/dist/{loadableToolOutput-CasonFIt.cjs → loadableToolOutput-DDCJjywt.cjs} +63 -61
- package/dist/mcpToolSchemas-CjeTfrAs.mjs +62 -0
- package/dist/mcpToolSchemas-DK42yoZ_.cjs +64 -0
- package/dist/persistence-BFjvtUad.mjs +944 -0
- package/dist/persistence-JLUn_Nou.cjs +996 -0
- package/dist/projectPath-BTBIMB57.mjs +10 -0
- package/dist/projectPath-ChLhdOyt.cjs +13 -0
- package/dist/prompt-BTWDZZO0.cjs +25 -0
- package/dist/prompt-BsAZsPbo.mjs +22 -0
- package/dist/release-BMEzNONE.mjs +168 -0
- package/dist/release-EhOJeAZe.cjs +171 -0
- package/dist/run-BDn2aE3Q.cjs +2152 -0
- package/dist/run-DBZqN6Kn.mjs +2128 -0
- package/dist/runClaude-DNHvERX0.mjs +3763 -0
- package/dist/runClaude-uaKxPZPm.cjs +3766 -0
- package/dist/{runCodex-BTt3fxG4.cjs → runCodex-82UrZLme.cjs} +169 -153
- package/dist/{runCodex-BXCB5trB.mjs → runCodex-C-RTM0wA.mjs} +36 -20
- package/dist/{runGemini-37HHbp9n.mjs → runGemini-Bm6-4Xm2.mjs} +34 -17
- package/dist/{runGemini-C-0nSFBv.cjs → runGemini-CXMr4Jwb.cjs} +212 -195
- package/dist/{runOneShot-CXhbFJ2j.cjs → runOneShot-1B6RMYT7.cjs} +31 -55
- package/dist/{runOneShot-USX8QPfE.mjs → runOneShot-ioARRHrx.mjs} +14 -38
- package/dist/{serve-DZAq-_1F.cjs → serve-BtdAhkIE.cjs} +35 -58
- package/dist/{serve-BRedJPzL.mjs → serve-CwibwU6N.mjs} +12 -35
- package/dist/session-2sU4Bu1R.mjs +108 -0
- package/dist/session-D--F87zL.cjs +110 -0
- package/dist/sessionKeyCache-4Tp8pJ3N.cjs +36 -0
- package/dist/sessionKeyCache-D2BwO91C.mjs +33 -0
- package/dist/sessionList-BCSw3qYt.mjs +51 -0
- package/dist/sessionList-ICJsjNtJ.cjs +54 -0
- package/dist/sessionSummary-Bkz52BPh.cjs +393 -0
- package/dist/sessionSummary-lHGBWQSb.mjs +387 -0
- package/dist/spawnHappyCLI-CoORX0YW.mjs +66 -0
- package/dist/spawnHappyCLI-D_V-AAoP.cjs +70 -0
- package/dist/ssh-BTOlhhxi.cjs +333 -0
- package/dist/ssh-DL_AkRAD.mjs +328 -0
- package/dist/systemdScope-BeOtAkhk.mjs +25 -0
- package/dist/systemdScope-DW3-UoKB.cjs +29 -0
- package/dist/task-CQzrHRZe.mjs +165 -0
- package/dist/task-CSpaC9HX.cjs +167 -0
- package/dist/time-Bj2HRkKH.cjs +33 -0
- package/dist/time-DgsBLJA_.mjs +29 -0
- package/dist/trimIdent-4gvk9Wk6.cjs +22 -0
- package/dist/trimIdent-BAjmv_TG.mjs +20 -0
- package/dist/types-BoJh4Qfv.mjs +57 -0
- package/dist/types-DWeB7aqh.cjs +59 -0
- package/dist/uninstall-BiKyRAb1.cjs +77 -0
- package/dist/uninstall-nFMFGUVM.mjs +75 -0
- package/dist/update-BcqRHXf2.mjs +109 -0
- package/dist/update-Dw8pgsAT.cjs +111 -0
- package/dist/workflowCommon-B0d01Y_a.mjs +56 -0
- package/dist/workflowCommon-Bl568-rt.cjs +62 -0
- package/dist/workflowReports-BEWuQesA.cjs +113 -0
- package/dist/workflowReports-Dd8-4-8f.mjs +108 -0
- package/package.json +1 -1
- package/dist/index-BlkHOkB3.cjs +0 -11312
- package/dist/index-DJ2VpGiR.mjs +0 -11272
- package/dist/mcpToolSchemas-CdPXJQmb.mjs +0 -175
- package/dist/mcpToolSchemas-f-kttjFw.cjs +0 -186
package/dist/lib.mjs
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient } from './api-CIZKyfSn.mjs';
|
|
2
|
+
export { c as configuration, l as logger } from './persistence-BFjvtUad.mjs';
|
|
3
|
+
export { R as RawJSONLinesSchema } from './types-BoJh4Qfv.mjs';
|
|
2
4
|
import 'axios';
|
|
3
|
-
import 'chalk';
|
|
4
|
-
import 'fs';
|
|
5
|
-
import 'node:fs';
|
|
6
|
-
import 'node:os';
|
|
7
|
-
import 'node:path';
|
|
8
5
|
import 'node:events';
|
|
9
6
|
import 'socket.io-client';
|
|
10
7
|
import 'zod';
|
|
8
|
+
import './index-CPKdvi7J.mjs';
|
|
11
9
|
import '@paralleldrive/cuid2';
|
|
10
|
+
import './time-DgsBLJA_.mjs';
|
|
12
11
|
import 'node:crypto';
|
|
13
|
-
import '
|
|
12
|
+
import 'node:fs';
|
|
13
|
+
import 'node:path';
|
|
14
14
|
import 'node:child_process';
|
|
15
15
|
import 'node:fs/promises';
|
|
16
|
+
import 'node:os';
|
|
16
17
|
import 'node:util';
|
|
17
18
|
import 'child_process';
|
|
18
19
|
import 'util';
|
|
19
20
|
import 'fs/promises';
|
|
20
21
|
import 'path';
|
|
22
|
+
import './projectPath-BTBIMB57.mjs';
|
|
21
23
|
import 'url';
|
|
22
24
|
import 'node:module';
|
|
23
25
|
import 'ws';
|
|
24
26
|
import 'crypto';
|
|
27
|
+
import 'tweetnacl';
|
|
25
28
|
import '@stablelib/base64';
|
|
26
29
|
import 'node:readline';
|
|
27
30
|
import 'expo-server-sdk';
|
|
31
|
+
import './sessionKeyCache-D2BwO91C.mjs';
|
|
32
|
+
import 'chalk';
|
|
33
|
+
import 'fs';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { l as logger,
|
|
1
|
+
import { l as logger, c as configuration, p as packageJson } from './persistence-BFjvtUad.mjs';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
|
4
4
|
import os, { homedir } from 'node:os';
|
|
5
5
|
import { join, basename, dirname } from 'node:path';
|
|
6
|
-
import {
|
|
6
|
+
import { p as projectPath } from './projectPath-BTBIMB57.mjs';
|
|
7
|
+
import { r as resolveToolsDir, s as startOfflineReconnection, b as saveToolOutputRecord } from './api-CIZKyfSn.mjs';
|
|
8
|
+
import { a as detectGitWorktree } from './downloadImage-DfSFLb-h.mjs';
|
|
7
9
|
|
|
8
10
|
class BasePermissionHandler {
|
|
9
11
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var logger = require('./persistence-JLUn_Nou.cjs');
|
|
4
4
|
var node_crypto = require('node:crypto');
|
|
5
5
|
var fs = require('node:fs');
|
|
6
6
|
var os = require('node:os');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var
|
|
8
|
+
var projectPath = require('./projectPath-ChLhdOyt.cjs');
|
|
9
|
+
var api = require('./api-CwOCQeLH.cjs');
|
|
10
|
+
var downloadImage = require('./downloadImage-MQMrUUxS.cjs');
|
|
9
11
|
|
|
10
12
|
class BasePermissionHandler {
|
|
11
13
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
@@ -25,7 +27,7 @@ class BasePermissionHandler {
|
|
|
25
27
|
* This is critical for avoiding stale session references after onSessionSwap.
|
|
26
28
|
*/
|
|
27
29
|
updateSession(newSession) {
|
|
28
|
-
|
|
30
|
+
logger.logger.debug(`${this.getLogPrefix()} Session reference updated`);
|
|
29
31
|
this.session = newSession;
|
|
30
32
|
this.setupRpcHandler();
|
|
31
33
|
}
|
|
@@ -38,7 +40,7 @@ class BasePermissionHandler {
|
|
|
38
40
|
async (response) => {
|
|
39
41
|
const pending = this.pendingRequests.get(response.id);
|
|
40
42
|
if (!pending) {
|
|
41
|
-
|
|
43
|
+
logger.logger.debug(`${this.getLogPrefix()} Permission request not found or already resolved`);
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
46
|
this.pendingRequests.delete(response.id);
|
|
@@ -68,7 +70,7 @@ class BasePermissionHandler {
|
|
|
68
70
|
};
|
|
69
71
|
return res;
|
|
70
72
|
});
|
|
71
|
-
|
|
73
|
+
logger.logger.debug(`${this.getLogPrefix()} Permission ${response.approved ? "approved" : "denied"} for ${pending.toolName}`);
|
|
72
74
|
}
|
|
73
75
|
);
|
|
74
76
|
}
|
|
@@ -150,7 +152,7 @@ class BasePermissionHandler {
|
|
|
150
152
|
*/
|
|
151
153
|
reset() {
|
|
152
154
|
if (this.isResetting) {
|
|
153
|
-
|
|
155
|
+
logger.logger.debug(`${this.getLogPrefix()} Reset already in progress, skipping`);
|
|
154
156
|
return;
|
|
155
157
|
}
|
|
156
158
|
this.isResetting = true;
|
|
@@ -161,7 +163,7 @@ class BasePermissionHandler {
|
|
|
161
163
|
try {
|
|
162
164
|
pending.reject(new Error("Session reset"));
|
|
163
165
|
} catch (err) {
|
|
164
|
-
|
|
166
|
+
logger.logger.debug(`${this.getLogPrefix()} Error rejecting pending request ${id}:`, err);
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
this.session.updateAgentState((currentState) => {
|
|
@@ -181,7 +183,7 @@ class BasePermissionHandler {
|
|
|
181
183
|
completedRequests
|
|
182
184
|
};
|
|
183
185
|
});
|
|
184
|
-
|
|
186
|
+
logger.logger.debug(`${this.getLogPrefix()} Permission handler reset`);
|
|
185
187
|
} finally {
|
|
186
188
|
this.isResetting = false;
|
|
187
189
|
}
|
|
@@ -214,7 +216,7 @@ class BaseReasoningProcessor {
|
|
|
214
216
|
handleSectionBreak() {
|
|
215
217
|
this.finishCurrentToolCall("canceled");
|
|
216
218
|
this.resetState();
|
|
217
|
-
|
|
219
|
+
logger.logger.debug(`${this.getLogPrefix()} Section break - reset state`);
|
|
218
220
|
}
|
|
219
221
|
/**
|
|
220
222
|
* Process a reasoning delta/chunk and accumulate content.
|
|
@@ -225,7 +227,7 @@ class BaseReasoningProcessor {
|
|
|
225
227
|
if (this.accumulator.startsWith("**")) {
|
|
226
228
|
this.inTitleCapture = true;
|
|
227
229
|
this.titleBuffer = this.accumulator.substring(2);
|
|
228
|
-
|
|
230
|
+
logger.logger.debug(`${this.getLogPrefix()} Started title capture`);
|
|
229
231
|
} else if (this.accumulator.length > 0) {
|
|
230
232
|
this.contentBuffer = this.accumulator;
|
|
231
233
|
}
|
|
@@ -240,7 +242,7 @@ class BaseReasoningProcessor {
|
|
|
240
242
|
this.currentTitle = title;
|
|
241
243
|
this.contentBuffer = afterTitle;
|
|
242
244
|
this.currentCallId = node_crypto.randomUUID();
|
|
243
|
-
|
|
245
|
+
logger.logger.debug(`${this.getLogPrefix()} Title captured: "${title}"`);
|
|
244
246
|
this.sendToolCallStart(title);
|
|
245
247
|
}
|
|
246
248
|
} else if (this.hasTitle) {
|
|
@@ -270,7 +272,7 @@ class BaseReasoningProcessor {
|
|
|
270
272
|
},
|
|
271
273
|
id: node_crypto.randomUUID()
|
|
272
274
|
};
|
|
273
|
-
|
|
275
|
+
logger.logger.debug(`${this.getLogPrefix()} Sending tool call start for: "${title}"`);
|
|
274
276
|
this.onMessage?.(toolCall);
|
|
275
277
|
this.toolCallStarted = true;
|
|
276
278
|
}
|
|
@@ -281,7 +283,7 @@ class BaseReasoningProcessor {
|
|
|
281
283
|
completeReasoning(fullText) {
|
|
282
284
|
const text = fullText ?? this.accumulator;
|
|
283
285
|
if (!text.trim() && !this.toolCallStarted) {
|
|
284
|
-
|
|
286
|
+
logger.logger.debug(`${this.getLogPrefix()} Complete called but no content accumulated, skipping`);
|
|
285
287
|
return false;
|
|
286
288
|
}
|
|
287
289
|
let title;
|
|
@@ -293,7 +295,7 @@ class BaseReasoningProcessor {
|
|
|
293
295
|
content = text.substring(titleEndIndex + 2).trim();
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
|
-
|
|
298
|
+
logger.logger.debug(`${this.getLogPrefix()} Complete reasoning - Title: "${title}", Has content: ${content.length > 0}`);
|
|
297
299
|
if (title && !this.toolCallStarted) {
|
|
298
300
|
this.currentCallId = this.currentCallId || node_crypto.randomUUID();
|
|
299
301
|
this.sendToolCallStart(title);
|
|
@@ -308,7 +310,7 @@ class BaseReasoningProcessor {
|
|
|
308
310
|
},
|
|
309
311
|
id: node_crypto.randomUUID()
|
|
310
312
|
};
|
|
311
|
-
|
|
313
|
+
logger.logger.debug(`${this.getLogPrefix()} Sending tool call result`);
|
|
312
314
|
this.onMessage?.(toolResult);
|
|
313
315
|
} else if (content.trim()) {
|
|
314
316
|
const reasoningMessage = {
|
|
@@ -316,7 +318,7 @@ class BaseReasoningProcessor {
|
|
|
316
318
|
message: content,
|
|
317
319
|
id: node_crypto.randomUUID()
|
|
318
320
|
};
|
|
319
|
-
|
|
321
|
+
logger.logger.debug(`${this.getLogPrefix()} Sending reasoning message`);
|
|
320
322
|
this.onMessage?.(reasoningMessage);
|
|
321
323
|
}
|
|
322
324
|
this.resetState();
|
|
@@ -326,7 +328,7 @@ class BaseReasoningProcessor {
|
|
|
326
328
|
* Abort the current reasoning section.
|
|
327
329
|
*/
|
|
328
330
|
abort() {
|
|
329
|
-
|
|
331
|
+
logger.logger.debug(`${this.getLogPrefix()} Abort called`);
|
|
330
332
|
this.finishCurrentToolCall("canceled");
|
|
331
333
|
this.resetState();
|
|
332
334
|
}
|
|
@@ -351,7 +353,7 @@ class BaseReasoningProcessor {
|
|
|
351
353
|
},
|
|
352
354
|
id: node_crypto.randomUUID()
|
|
353
355
|
};
|
|
354
|
-
|
|
356
|
+
logger.logger.debug(`${this.getLogPrefix()} Sending tool call result with status: ${status}`);
|
|
355
357
|
this.onMessage?.(toolResult);
|
|
356
358
|
}
|
|
357
359
|
}
|
|
@@ -504,7 +506,7 @@ function detectWorkspaceSubdirectories(cwd) {
|
|
|
504
506
|
for (const entry of entries) {
|
|
505
507
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
506
508
|
const subDir = path.join(cwd, entry.name);
|
|
507
|
-
const info =
|
|
509
|
+
const info = downloadImage.detectGitWorktree(subDir);
|
|
508
510
|
if (info.isWorktree && info.worktreeBasePath && info.worktreeBranchName) {
|
|
509
511
|
repos.push({
|
|
510
512
|
path: subDir,
|
|
@@ -544,7 +546,7 @@ function detectWorktreeMetadata() {
|
|
|
544
546
|
worktreeBranchName: process.env.HAPPY_WORKTREE_BRANCH_NAME
|
|
545
547
|
};
|
|
546
548
|
}
|
|
547
|
-
const info =
|
|
549
|
+
const info = downloadImage.detectGitWorktree(process.cwd());
|
|
548
550
|
if (info.isWorktree) {
|
|
549
551
|
return {
|
|
550
552
|
isWorktree: true,
|
|
@@ -565,13 +567,13 @@ function createSessionMetadata(opts) {
|
|
|
565
567
|
const metadata = {
|
|
566
568
|
path: process.cwd(),
|
|
567
569
|
host: os.hostname(),
|
|
568
|
-
version:
|
|
570
|
+
version: logger.packageJson.version,
|
|
569
571
|
os: os.platform(),
|
|
570
572
|
machineId: opts.machineId,
|
|
571
573
|
homeDir: os.homedir(),
|
|
572
|
-
happyHomeDir:
|
|
573
|
-
happyLibDir:
|
|
574
|
-
happyToolsDir:
|
|
574
|
+
happyHomeDir: logger.configuration.happyHomeDir,
|
|
575
|
+
happyLibDir: projectPath.projectPath(),
|
|
576
|
+
happyToolsDir: api.resolveToolsDir(),
|
|
575
577
|
startedFromDaemon: opts.startedBy === "daemon",
|
|
576
578
|
hostPid: process.pid,
|
|
577
579
|
startedBy: opts.startedBy || "terminal",
|
|
@@ -624,17 +626,17 @@ function createOfflineSessionStub(sessionTag) {
|
|
|
624
626
|
}
|
|
625
627
|
|
|
626
628
|
function setupOfflineReconnection(opts) {
|
|
627
|
-
const { api, sessionTag, metadata, state, response, onSessionSwap } = opts;
|
|
629
|
+
const { api: api$1, sessionTag, metadata, state, response, onSessionSwap } = opts;
|
|
628
630
|
let session;
|
|
629
631
|
let reconnectionHandle = null;
|
|
630
632
|
if (!response) {
|
|
631
633
|
session = createOfflineSessionStub(sessionTag);
|
|
632
|
-
reconnectionHandle =
|
|
633
|
-
serverUrl:
|
|
634
|
+
reconnectionHandle = api.startOfflineReconnection({
|
|
635
|
+
serverUrl: logger.configuration.serverUrl,
|
|
634
636
|
onReconnected: async () => {
|
|
635
|
-
const resp = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
637
|
+
const resp = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
|
|
636
638
|
if (!resp) throw new Error("Server unavailable");
|
|
637
|
-
const realSession = api.sessionSyncClient(resp);
|
|
639
|
+
const realSession = api$1.sessionSyncClient(resp);
|
|
638
640
|
onSessionSwap(realSession);
|
|
639
641
|
return realSession;
|
|
640
642
|
},
|
|
@@ -644,7 +646,7 @@ function setupOfflineReconnection(opts) {
|
|
|
644
646
|
});
|
|
645
647
|
return { session, reconnectionHandle, isOffline: true };
|
|
646
648
|
} else {
|
|
647
|
-
session = api.sessionSyncClient(response);
|
|
649
|
+
session = api$1.sessionSyncClient(response);
|
|
648
650
|
return { session, reconnectionHandle: null, isOffline: false };
|
|
649
651
|
}
|
|
650
652
|
}
|
|
@@ -877,7 +879,7 @@ function handleAgentMessageChunk(update, ctx) {
|
|
|
877
879
|
payload: { text }
|
|
878
880
|
});
|
|
879
881
|
} else {
|
|
880
|
-
|
|
882
|
+
logger.logger.debug(`[AcpBackend] Received message chunk (length: ${text.length}): ${text.substring(0, 50)}...`);
|
|
881
883
|
ctx.emit({
|
|
882
884
|
type: "model-output",
|
|
883
885
|
textDelta: text
|
|
@@ -886,10 +888,10 @@ function handleAgentMessageChunk(update, ctx) {
|
|
|
886
888
|
const idleTimeoutMs = ctx.transport.getIdleTimeout?.() ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
887
889
|
ctx.setIdleTimeout(() => {
|
|
888
890
|
if (ctx.activeToolCalls.size === 0) {
|
|
889
|
-
|
|
891
|
+
logger.logger.debug("[AcpBackend] No more chunks received, emitting idle status");
|
|
890
892
|
ctx.emitIdleStatus();
|
|
891
893
|
} else {
|
|
892
|
-
|
|
894
|
+
logger.logger.debug(`[AcpBackend] Delaying idle status - ${ctx.activeToolCalls.size} active tool calls`);
|
|
893
895
|
}
|
|
894
896
|
}, idleTimeoutMs);
|
|
895
897
|
}
|
|
@@ -906,7 +908,7 @@ function handleAgentThoughtChunk(update, ctx) {
|
|
|
906
908
|
}
|
|
907
909
|
if (ctx.activeToolCalls.size > 0) {
|
|
908
910
|
const activeToolCallsList = Array.from(ctx.activeToolCalls);
|
|
909
|
-
|
|
911
|
+
logger.logger.debug(`[AcpBackend] \u{1F4AD} Thinking chunk received (${text.length} chars) during active tool calls: ${activeToolCallsList.join(", ")}`);
|
|
910
912
|
}
|
|
911
913
|
ctx.emit({
|
|
912
914
|
type: "event",
|
|
@@ -924,28 +926,28 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
|
|
|
924
926
|
ctx.toolCallIdToNameMap.set(toolCallId, realToolName);
|
|
925
927
|
ctx.activeToolCalls.add(toolCallId);
|
|
926
928
|
ctx.toolCallStartTimes.set(toolCallId, startTime);
|
|
927
|
-
|
|
928
|
-
|
|
929
|
+
logger.logger.debug(`[AcpBackend] \u23F1\uFE0F Set startTime for ${toolCallId} at ${new Date(startTime).toISOString()} (from ${source})`);
|
|
930
|
+
logger.logger.debug(`[AcpBackend] \u{1F527} Tool call START: ${toolCallId} (${toolKind} -> ${realToolName})${isInvestigation ? " [INVESTIGATION TOOL]" : ""}`);
|
|
929
931
|
if (isInvestigation) {
|
|
930
|
-
|
|
932
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool detected - extended timeout (10min) will be used`);
|
|
931
933
|
}
|
|
932
934
|
const timeoutMs = ctx.transport.getToolCallTimeout?.(toolCallId, toolKindStr) ?? DEFAULT_TOOL_CALL_TIMEOUT_MS;
|
|
933
935
|
if (!ctx.toolCallTimeouts.has(toolCallId)) {
|
|
934
936
|
const timeout = setTimeout(() => {
|
|
935
937
|
const duration = formatDuration(ctx.toolCallStartTimes.get(toolCallId));
|
|
936
|
-
|
|
938
|
+
logger.logger.debug(`[AcpBackend] \u23F1\uFE0F Tool call TIMEOUT (from ${source}): ${toolCallId} (${toolKind}) after ${(timeoutMs / 1e3).toFixed(0)}s - Duration: ${duration}, removing from active set`);
|
|
937
939
|
ctx.activeToolCalls.delete(toolCallId);
|
|
938
940
|
ctx.toolCallStartTimes.delete(toolCallId);
|
|
939
941
|
ctx.toolCallTimeouts.delete(toolCallId);
|
|
940
942
|
if (ctx.activeToolCalls.size === 0) {
|
|
941
|
-
|
|
943
|
+
logger.logger.debug("[AcpBackend] No more active tool calls after timeout, emitting idle status");
|
|
942
944
|
ctx.emitIdleStatus();
|
|
943
945
|
}
|
|
944
946
|
}, timeoutMs);
|
|
945
947
|
ctx.toolCallTimeouts.set(toolCallId, timeout);
|
|
946
|
-
|
|
948
|
+
logger.logger.debug(`[AcpBackend] \u23F1\uFE0F Set timeout for ${toolCallId}: ${(timeoutMs / 1e3).toFixed(0)}s${isInvestigation ? " (investigation tool)" : ""}`);
|
|
947
949
|
} else {
|
|
948
|
-
|
|
950
|
+
logger.logger.debug(`[AcpBackend] Timeout already set for ${toolCallId}, skipping`);
|
|
949
951
|
}
|
|
950
952
|
ctx.clearIdleTimeout();
|
|
951
953
|
ctx.emit({ type: "status", status: "running" });
|
|
@@ -958,7 +960,7 @@ function startToolCall(toolCallId, toolKind, update, ctx, source) {
|
|
|
958
960
|
args.locations = update.locations;
|
|
959
961
|
}
|
|
960
962
|
if (isInvestigation && args.objective) {
|
|
961
|
-
|
|
963
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool objective: ${String(args.objective).substring(0, 100)}...`);
|
|
962
964
|
}
|
|
963
965
|
ctx.emit({
|
|
964
966
|
type: "tool-call",
|
|
@@ -978,7 +980,7 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
|
|
|
978
980
|
clearTimeout(timeout);
|
|
979
981
|
ctx.toolCallTimeouts.delete(toolCallId);
|
|
980
982
|
}
|
|
981
|
-
|
|
983
|
+
logger.logger.debug(`[AcpBackend] \u2705 Tool call COMPLETED: ${toolCallId} (${toolKindStr}) - Duration: ${duration}. Active tool calls: ${ctx.activeToolCalls.size}`);
|
|
982
984
|
ctx.emit({
|
|
983
985
|
type: "tool-result",
|
|
984
986
|
toolName: toolKindStr,
|
|
@@ -987,7 +989,7 @@ function completeToolCall(toolCallId, toolKind, content, ctx) {
|
|
|
987
989
|
});
|
|
988
990
|
if (ctx.activeToolCalls.size === 0) {
|
|
989
991
|
ctx.clearIdleTimeout();
|
|
990
|
-
|
|
992
|
+
logger.logger.debug("[AcpBackend] All tool calls completed, emitting idle status");
|
|
991
993
|
ctx.emitIdleStatus();
|
|
992
994
|
}
|
|
993
995
|
}
|
|
@@ -1000,17 +1002,17 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
|
|
|
1000
1002
|
if (isInvestigation) {
|
|
1001
1003
|
const durationStr2 = formatDuration(startTime);
|
|
1002
1004
|
const durationMinutes = formatDurationMinutes(startTime);
|
|
1003
|
-
|
|
1005
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool ${status.toUpperCase()} after ${durationMinutes} minutes (${durationStr2})`);
|
|
1004
1006
|
if (duration) {
|
|
1005
1007
|
const threeMinutes = 3 * 60 * 1e3;
|
|
1006
1008
|
const tolerance = 5e3;
|
|
1007
1009
|
if (Math.abs(duration - threeMinutes) < tolerance) {
|
|
1008
|
-
|
|
1010
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} \u26A0\uFE0F Investigation tool failed at ~3 minutes - likely Gemini CLI timeout, not our timeout`);
|
|
1009
1011
|
}
|
|
1010
1012
|
}
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1013
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool FAILED - full content:`, JSON.stringify(content, null, 2));
|
|
1014
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool timeout status BEFORE cleanup: ${hadTimeout ? "timeout was set" : "no timeout was set"}`);
|
|
1015
|
+
logger.logger.debug(`[AcpBackend] \u{1F50D} Investigation tool startTime status BEFORE cleanup: ${startTime ? `set at ${new Date(startTime).toISOString()}` : "not set"}`);
|
|
1014
1016
|
}
|
|
1015
1017
|
ctx.activeToolCalls.delete(toolCallId);
|
|
1016
1018
|
ctx.toolCallStartTimes.delete(toolCallId);
|
|
@@ -1018,17 +1020,17 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
|
|
|
1018
1020
|
if (timeout) {
|
|
1019
1021
|
clearTimeout(timeout);
|
|
1020
1022
|
ctx.toolCallTimeouts.delete(toolCallId);
|
|
1021
|
-
|
|
1023
|
+
logger.logger.debug(`[AcpBackend] Cleared timeout for ${toolCallId} (tool call ${status})`);
|
|
1022
1024
|
} else {
|
|
1023
|
-
|
|
1025
|
+
logger.logger.debug(`[AcpBackend] No timeout found for ${toolCallId} (tool call ${status}) - timeout may not have been set`);
|
|
1024
1026
|
}
|
|
1025
1027
|
const durationStr = formatDuration(startTime);
|
|
1026
|
-
|
|
1028
|
+
logger.logger.debug(`[AcpBackend] \u274C Tool call ${status.toUpperCase()}: ${toolCallId} (${toolKindStr}) - Duration: ${durationStr}. Active tool calls: ${ctx.activeToolCalls.size}`);
|
|
1027
1029
|
const errorDetail = extractErrorDetail(content);
|
|
1028
1030
|
if (errorDetail) {
|
|
1029
|
-
|
|
1031
|
+
logger.logger.debug(`[AcpBackend] \u274C Tool call error details: ${errorDetail.substring(0, 500)}`);
|
|
1030
1032
|
} else {
|
|
1031
|
-
|
|
1033
|
+
logger.logger.debug(`[AcpBackend] \u274C Tool call ${status} but no error details in content`);
|
|
1032
1034
|
}
|
|
1033
1035
|
ctx.emit({
|
|
1034
1036
|
type: "tool-result",
|
|
@@ -1038,7 +1040,7 @@ function failToolCall(toolCallId, status, toolKind, content, ctx) {
|
|
|
1038
1040
|
});
|
|
1039
1041
|
if (ctx.activeToolCalls.size === 0) {
|
|
1040
1042
|
ctx.clearIdleTimeout();
|
|
1041
|
-
|
|
1043
|
+
logger.logger.debug("[AcpBackend] All tool calls completed/failed, emitting idle status");
|
|
1042
1044
|
ctx.emitIdleStatus();
|
|
1043
1045
|
}
|
|
1044
1046
|
}
|
|
@@ -1046,7 +1048,7 @@ function handleToolCallUpdate(update, ctx) {
|
|
|
1046
1048
|
const status = update.status;
|
|
1047
1049
|
const toolCallId = update.toolCallId;
|
|
1048
1050
|
if (!toolCallId) {
|
|
1049
|
-
|
|
1051
|
+
logger.logger.debug("[AcpBackend] Tool call update without toolCallId:", update);
|
|
1050
1052
|
return { handled: false };
|
|
1051
1053
|
}
|
|
1052
1054
|
const toolKind = update.kind || "unknown";
|
|
@@ -1056,7 +1058,7 @@ function handleToolCallUpdate(update, ctx) {
|
|
|
1056
1058
|
toolCallCountSincePrompt++;
|
|
1057
1059
|
startToolCall(toolCallId, toolKind, update, ctx, "tool_call_update");
|
|
1058
1060
|
} else {
|
|
1059
|
-
|
|
1061
|
+
logger.logger.debug(`[AcpBackend] Tool call ${toolCallId} already tracked, status: ${status}`);
|
|
1060
1062
|
}
|
|
1061
1063
|
} else if (status === "completed") {
|
|
1062
1064
|
completeToolCall(toolCallId, toolKind, update.content, ctx);
|
|
@@ -1068,14 +1070,14 @@ function handleToolCallUpdate(update, ctx) {
|
|
|
1068
1070
|
function handleToolCall(update, ctx) {
|
|
1069
1071
|
const toolCallId = update.toolCallId;
|
|
1070
1072
|
const status = update.status;
|
|
1071
|
-
|
|
1073
|
+
logger.logger.debug(`[AcpBackend] Received tool_call: toolCallId=${toolCallId}, status=${status}, kind=${update.kind}`);
|
|
1072
1074
|
const isInProgress = !status || status === "in_progress" || status === "pending";
|
|
1073
1075
|
if (!toolCallId || !isInProgress) {
|
|
1074
|
-
|
|
1076
|
+
logger.logger.debug(`[AcpBackend] Tool call ${toolCallId} not in progress (status: ${status}), skipping`);
|
|
1075
1077
|
return { handled: false };
|
|
1076
1078
|
}
|
|
1077
1079
|
if (ctx.activeToolCalls.has(toolCallId)) {
|
|
1078
|
-
|
|
1080
|
+
logger.logger.debug(`[AcpBackend] Tool call ${toolCallId} already in active set, skipping`);
|
|
1079
1081
|
return { handled: true };
|
|
1080
1082
|
}
|
|
1081
1083
|
startToolCall(toolCallId, update.kind, update, ctx, "tool_call");
|
|
@@ -1158,7 +1160,7 @@ function handleConfigMetadataEvent(eventName, payload, updateMetadata) {
|
|
|
1158
1160
|
|
|
1159
1161
|
function createLoadableToolOutput(options) {
|
|
1160
1162
|
if (options.persist !== false) {
|
|
1161
|
-
|
|
1163
|
+
api.saveToolOutputRecord(options.sessionId, {
|
|
1162
1164
|
callId: options.callId,
|
|
1163
1165
|
toolName: options.toolName,
|
|
1164
1166
|
agent: options.agent,
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
const orchestratorTargetTypeSchema = z.preprocess(
|
|
4
|
+
(value) => value === "machine" ? "machine_id" : value,
|
|
5
|
+
z.enum(["current_machine", "machine_id"])
|
|
6
|
+
).describe('Dispatch target type. Use "current_machine" for this machine, or "machine_id" for explicit machine routing. Alias "machine" is accepted and normalized to "machine_id".');
|
|
7
|
+
const orchestratorTaskSchema = z.object({
|
|
8
|
+
taskKey: z.string().min(1).max(128).optional(),
|
|
9
|
+
title: z.string().min(1).max(256).optional(),
|
|
10
|
+
provider: z.enum(["claude", "codex", "gemini"]).describe("AI agent provider to execute the task."),
|
|
11
|
+
model: z.string().min(1).max(128).optional().describe('Optional model mode for the selected provider. Prefer values from orchestrator_get_context.data.modelModes[provider]. Use "default" to follow CLI defaults.'),
|
|
12
|
+
prompt: z.string().min(1).max(65536),
|
|
13
|
+
workingDirectory: z.string().max(512).optional().describe("Absolute path for task execution. Defaults to the controller session working directory from get_context."),
|
|
14
|
+
dependsOn: z.array(z.string().min(1).max(128)).max(31).optional().describe("Optional list of prerequisite taskKeys (use taskKey, not taskId). This controls execution order only: the task starts after all listed tasks complete, but receives NONE of their output or context."),
|
|
15
|
+
retry: z.object({
|
|
16
|
+
maxAttempts: z.number().int().min(1).max(10).optional().describe("Maximum attempts for this task (including first run)."),
|
|
17
|
+
backoffMs: z.number().int().min(0).max(24 * 60 * 60 * 1e3).optional().describe("Retry backoff delay in milliseconds before the next attempt.")
|
|
18
|
+
}).optional(),
|
|
19
|
+
target: z.object({
|
|
20
|
+
type: orchestratorTargetTypeSchema,
|
|
21
|
+
machineId: z.string().optional().describe('Required when target.type is "machine_id" (or alias "machine").')
|
|
22
|
+
}).optional().describe("Optional dispatch routing target."),
|
|
23
|
+
metadata: z.record(z.string(), z.string()).optional()
|
|
24
|
+
});
|
|
25
|
+
({
|
|
26
|
+
inputSchema: {
|
|
27
|
+
title: z.string().min(1).max(256).describe("Run title"),
|
|
28
|
+
tasks: z.array(orchestratorTaskSchema).min(1).max(32),
|
|
29
|
+
maxConcurrency: z.number().int().min(1).max(8).optional(),
|
|
30
|
+
idempotencyKey: z.string().min(1).max(128).optional(),
|
|
31
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
32
|
+
controllerSessionId: z.string().optional().describe("Optional controller session ID. Defaults to current MCP session when omitted.")
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
({
|
|
36
|
+
inputSchema: {
|
|
37
|
+
runId: z.string().describe("Run ID"),
|
|
38
|
+
cursor: z.string().optional(),
|
|
39
|
+
waitFor: z.enum(["change", "terminal"]).optional(),
|
|
40
|
+
timeoutMs: z.number().int().min(0).max(36e5).optional().describe("Total wait timeout in ms. Defaults to 10 minutes when omitted."),
|
|
41
|
+
include: z.enum(["summary", "all_tasks"]).optional().describe('"summary" returns run-level status only; "all_tasks" includes per-task details.')
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
({
|
|
45
|
+
inputSchema: {
|
|
46
|
+
status: z.enum(["active", "terminal", "queued", "running", "canceling", "completed", "failed", "cancelled"]).optional().describe('Filter by status. "active" = queued|running|canceling; "terminal" = completed|failed|cancelled.'),
|
|
47
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
48
|
+
cursor: z.string().optional()
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
({
|
|
52
|
+
inputSchema: {
|
|
53
|
+
runId: z.string().describe("Run ID"),
|
|
54
|
+
reason: z.string().max(512).optional()
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
({
|
|
58
|
+
inputSchema: {
|
|
59
|
+
taskId: z.string().describe("Task ID to resume"),
|
|
60
|
+
message: z.string().min(1).max(65536).describe("Message to send to the existing child session")
|
|
61
|
+
}
|
|
62
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var z = require('zod');
|
|
4
|
+
|
|
5
|
+
const orchestratorTargetTypeSchema = z.z.preprocess(
|
|
6
|
+
(value) => value === "machine" ? "machine_id" : value,
|
|
7
|
+
z.z.enum(["current_machine", "machine_id"])
|
|
8
|
+
).describe('Dispatch target type. Use "current_machine" for this machine, or "machine_id" for explicit machine routing. Alias "machine" is accepted and normalized to "machine_id".');
|
|
9
|
+
const orchestratorTaskSchema = z.z.object({
|
|
10
|
+
taskKey: z.z.string().min(1).max(128).optional(),
|
|
11
|
+
title: z.z.string().min(1).max(256).optional(),
|
|
12
|
+
provider: z.z.enum(["claude", "codex", "gemini"]).describe("AI agent provider to execute the task."),
|
|
13
|
+
model: z.z.string().min(1).max(128).optional().describe('Optional model mode for the selected provider. Prefer values from orchestrator_get_context.data.modelModes[provider]. Use "default" to follow CLI defaults.'),
|
|
14
|
+
prompt: z.z.string().min(1).max(65536),
|
|
15
|
+
workingDirectory: z.z.string().max(512).optional().describe("Absolute path for task execution. Defaults to the controller session working directory from get_context."),
|
|
16
|
+
dependsOn: z.z.array(z.z.string().min(1).max(128)).max(31).optional().describe("Optional list of prerequisite taskKeys (use taskKey, not taskId). This controls execution order only: the task starts after all listed tasks complete, but receives NONE of their output or context."),
|
|
17
|
+
retry: z.z.object({
|
|
18
|
+
maxAttempts: z.z.number().int().min(1).max(10).optional().describe("Maximum attempts for this task (including first run)."),
|
|
19
|
+
backoffMs: z.z.number().int().min(0).max(24 * 60 * 60 * 1e3).optional().describe("Retry backoff delay in milliseconds before the next attempt.")
|
|
20
|
+
}).optional(),
|
|
21
|
+
target: z.z.object({
|
|
22
|
+
type: orchestratorTargetTypeSchema,
|
|
23
|
+
machineId: z.z.string().optional().describe('Required when target.type is "machine_id" (or alias "machine").')
|
|
24
|
+
}).optional().describe("Optional dispatch routing target."),
|
|
25
|
+
metadata: z.z.record(z.z.string(), z.z.string()).optional()
|
|
26
|
+
});
|
|
27
|
+
({
|
|
28
|
+
inputSchema: {
|
|
29
|
+
title: z.z.string().min(1).max(256).describe("Run title"),
|
|
30
|
+
tasks: z.z.array(orchestratorTaskSchema).min(1).max(32),
|
|
31
|
+
maxConcurrency: z.z.number().int().min(1).max(8).optional(),
|
|
32
|
+
idempotencyKey: z.z.string().min(1).max(128).optional(),
|
|
33
|
+
metadata: z.z.record(z.z.string(), z.z.unknown()).optional(),
|
|
34
|
+
controllerSessionId: z.z.string().optional().describe("Optional controller session ID. Defaults to current MCP session when omitted.")
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
({
|
|
38
|
+
inputSchema: {
|
|
39
|
+
runId: z.z.string().describe("Run ID"),
|
|
40
|
+
cursor: z.z.string().optional(),
|
|
41
|
+
waitFor: z.z.enum(["change", "terminal"]).optional(),
|
|
42
|
+
timeoutMs: z.z.number().int().min(0).max(36e5).optional().describe("Total wait timeout in ms. Defaults to 10 minutes when omitted."),
|
|
43
|
+
include: z.z.enum(["summary", "all_tasks"]).optional().describe('"summary" returns run-level status only; "all_tasks" includes per-task details.')
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
({
|
|
47
|
+
inputSchema: {
|
|
48
|
+
status: z.z.enum(["active", "terminal", "queued", "running", "canceling", "completed", "failed", "cancelled"]).optional().describe('Filter by status. "active" = queued|running|canceling; "terminal" = completed|failed|cancelled.'),
|
|
49
|
+
limit: z.z.number().int().min(1).max(50).optional(),
|
|
50
|
+
cursor: z.z.string().optional()
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
({
|
|
54
|
+
inputSchema: {
|
|
55
|
+
runId: z.z.string().describe("Run ID"),
|
|
56
|
+
reason: z.z.string().max(512).optional()
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
({
|
|
60
|
+
inputSchema: {
|
|
61
|
+
taskId: z.z.string().describe("Task ID to resume"),
|
|
62
|
+
message: z.z.string().min(1).max(65536).describe("Message to send to the existing child session")
|
|
63
|
+
}
|
|
64
|
+
});
|