@openacp/cli 2026.328.2 → 2026.330.3
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/{adapter-HGJENQCN.js → adapter-AWSI4GML.js} +4 -4
- package/dist/api-server-5VNYFWJE.js +7 -0
- package/dist/{api-server-WFB5K6FP.js → api-server-JLBDKCU4.js} +2 -2
- package/dist/{chunk-5TCXYDLR.js → chunk-237WYH6H.js} +26 -3
- package/dist/chunk-237WYH6H.js.map +1 -0
- package/dist/{chunk-E2SLHZAC.js → chunk-2HEFALTZ.js} +6 -6
- package/dist/{chunk-I53NEV3S.js → chunk-5WGVYX3C.js} +13 -3
- package/dist/chunk-5WGVYX3C.js.map +1 -0
- package/dist/{chunk-IXMIC4GQ.js → chunk-BTJHGSLM.js} +2 -2
- package/dist/{chunk-43JVXFYP.js → chunk-GEOXPGCO.js} +2 -2
- package/dist/{chunk-JUFN4XMB.js → chunk-KDU3ZEWT.js} +2 -2
- package/dist/{chunk-QWP76EBW.js → chunk-MITTQMGZ.js} +16 -9
- package/dist/chunk-MITTQMGZ.js.map +1 -0
- package/dist/{chunk-QBEQJFGL.js → chunk-MPGEHTGE.js} +3 -3
- package/dist/{chunk-4B6PCWQP.js → chunk-PA6MNBG4.js} +6 -2
- package/dist/chunk-PA6MNBG4.js.map +1 -0
- package/dist/{chunk-VD3QSMVY.js → chunk-QWVHCTCA.js} +2 -2
- package/dist/{chunk-NT6FYV27.js → chunk-TMVTSWVH.js} +2 -2
- package/dist/{chunk-6VR4GWOO.js → chunk-UCIZM5SW.js} +247 -70
- package/dist/chunk-UCIZM5SW.js.map +1 -0
- package/dist/chunk-UWH7KIAA.js +701 -0
- package/dist/chunk-UWH7KIAA.js.map +1 -0
- package/dist/{chunk-JOMDPFQ2.js → chunk-W4LK6WJP.js} +29 -4
- package/dist/chunk-W4LK6WJP.js.map +1 -0
- package/dist/{chunk-RXMWJHWH.js → chunk-XBZIHNKV.js} +733 -221
- package/dist/chunk-XBZIHNKV.js.map +1 -0
- package/dist/cli.js +63 -68
- package/dist/cli.js.map +1 -1
- package/dist/config-KN6NKKPF.js +20 -0
- package/dist/{config-editor-OU6PUY66.js → config-editor-76RVZS4B.js} +3 -3
- package/dist/context-NXXW62NJ.js +9 -0
- package/dist/{core-plugins-R2EVZAJV.js → core-plugins-BPZY7SEB.js} +9 -9
- package/dist/{daemon-DTA6KYYY.js → daemon-XFEMMJSZ.js} +3 -3
- package/dist/doctor-AV6AUO22.js +9 -0
- package/dist/index.d.ts +110 -44
- package/dist/index.js +8 -8
- package/dist/{main-RRSX5SRL.js → main-VEJCG5PY.js} +38 -30
- package/dist/main-VEJCG5PY.js.map +1 -0
- package/dist/{plugin-installer-5XHORMLS.js → plugin-installer-VSTYZSXC.js} +2 -2
- package/dist/{setup-OI6A3OXW.js → setup-DISPNDEK.js} +4 -5
- package/dist/setup-DISPNDEK.js.map +1 -0
- package/dist/speech-SG62JYIF.js +9 -0
- package/dist/telegram-L3YM6SQJ.js +7 -0
- package/dist/tunnel-HWJ27WDH.js +7 -0
- package/dist/{tunnel-service-I2NFUX3V.js → tunnel-service-ZMO4THKE.js} +88 -8
- package/dist/tunnel-service-ZMO4THKE.js.map +1 -0
- package/package.json +1 -1
- package/dist/api-server-DSUW637I.js +0 -7
- package/dist/chunk-4B6PCWQP.js.map +0 -1
- package/dist/chunk-5TCXYDLR.js.map +0 -1
- package/dist/chunk-6VR4GWOO.js.map +0 -1
- package/dist/chunk-I53NEV3S.js.map +0 -1
- package/dist/chunk-JOMDPFQ2.js.map +0 -1
- package/dist/chunk-QWP76EBW.js.map +0 -1
- package/dist/chunk-RXMWJHWH.js.map +0 -1
- package/dist/chunk-ZHGPZBS4.js +0 -49
- package/dist/chunk-ZHGPZBS4.js.map +0 -1
- package/dist/config-UCAFCS5W.js +0 -14
- package/dist/context-7MPU7RL5.js +0 -9
- package/dist/doctor-D723IB2I.js +0 -9
- package/dist/main-RRSX5SRL.js.map +0 -1
- package/dist/setup-OI6A3OXW.js.map +0 -1
- package/dist/speech-GB7PHVQZ.js +0 -9
- package/dist/telegram-UVIAXADE.js +0 -7
- package/dist/tunnel-4WNFC7GO.js +0 -7
- package/dist/tunnel-service-I2NFUX3V.js.map +0 -1
- /package/dist/{adapter-HGJENQCN.js.map → adapter-AWSI4GML.js.map} +0 -0
- /package/dist/{api-server-DSUW637I.js.map → api-server-5VNYFWJE.js.map} +0 -0
- /package/dist/{api-server-WFB5K6FP.js.map → api-server-JLBDKCU4.js.map} +0 -0
- /package/dist/{chunk-E2SLHZAC.js.map → chunk-2HEFALTZ.js.map} +0 -0
- /package/dist/{chunk-IXMIC4GQ.js.map → chunk-BTJHGSLM.js.map} +0 -0
- /package/dist/{chunk-43JVXFYP.js.map → chunk-GEOXPGCO.js.map} +0 -0
- /package/dist/{chunk-JUFN4XMB.js.map → chunk-KDU3ZEWT.js.map} +0 -0
- /package/dist/{chunk-QBEQJFGL.js.map → chunk-MPGEHTGE.js.map} +0 -0
- /package/dist/{chunk-VD3QSMVY.js.map → chunk-QWVHCTCA.js.map} +0 -0
- /package/dist/{chunk-NT6FYV27.js.map → chunk-TMVTSWVH.js.map} +0 -0
- /package/dist/{config-UCAFCS5W.js.map → config-KN6NKKPF.js.map} +0 -0
- /package/dist/{config-editor-OU6PUY66.js.map → config-editor-76RVZS4B.js.map} +0 -0
- /package/dist/{context-7MPU7RL5.js.map → context-NXXW62NJ.js.map} +0 -0
- /package/dist/{core-plugins-R2EVZAJV.js.map → core-plugins-BPZY7SEB.js.map} +0 -0
- /package/dist/{daemon-DTA6KYYY.js.map → daemon-XFEMMJSZ.js.map} +0 -0
- /package/dist/{doctor-D723IB2I.js.map → doctor-AV6AUO22.js.map} +0 -0
- /package/dist/{plugin-installer-5XHORMLS.js.map → plugin-installer-VSTYZSXC.js.map} +0 -0
- /package/dist/{speech-GB7PHVQZ.js.map → speech-SG62JYIF.js.map} +0 -0
- /package/dist/{telegram-UVIAXADE.js.map → telegram-L3YM6SQJ.js.map} +0 -0
- /package/dist/{tunnel-4WNFC7GO.js.map → tunnel-HWJ27WDH.js.map} +0 -0
|
@@ -142,8 +142,8 @@ var TypedEmitter = class {
|
|
|
142
142
|
// src/core/agents/agent-instance.ts
|
|
143
143
|
import { spawn as spawn2, execFileSync } from "child_process";
|
|
144
144
|
import { Transform } from "stream";
|
|
145
|
-
import
|
|
146
|
-
import
|
|
145
|
+
import fs2 from "fs";
|
|
146
|
+
import path2 from "path";
|
|
147
147
|
import { ClientSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
|
|
148
148
|
import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
149
149
|
|
|
@@ -297,15 +297,48 @@ var McpManager = class {
|
|
|
297
297
|
}
|
|
298
298
|
};
|
|
299
299
|
|
|
300
|
+
// src/core/utils/debug-tracer.ts
|
|
301
|
+
import fs from "fs";
|
|
302
|
+
import path from "path";
|
|
303
|
+
var DEBUG_ENABLED = process.env.OPENACP_DEBUG === "true" || process.env.OPENACP_DEBUG === "1";
|
|
304
|
+
var DebugTracer = class {
|
|
305
|
+
constructor(sessionId, workingDirectory) {
|
|
306
|
+
this.sessionId = sessionId;
|
|
307
|
+
this.workingDirectory = workingDirectory;
|
|
308
|
+
this.logDir = path.join(workingDirectory, ".log");
|
|
309
|
+
}
|
|
310
|
+
dirCreated = false;
|
|
311
|
+
logDir;
|
|
312
|
+
log(layer, data) {
|
|
313
|
+
try {
|
|
314
|
+
if (!this.dirCreated) {
|
|
315
|
+
fs.mkdirSync(this.logDir, { recursive: true });
|
|
316
|
+
this.dirCreated = true;
|
|
317
|
+
}
|
|
318
|
+
const filePath = path.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
|
|
319
|
+
const line = JSON.stringify({ ts: Date.now(), ...data }) + "\n";
|
|
320
|
+
fs.appendFileSync(filePath, line);
|
|
321
|
+
} catch {
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/** No-op cleanup — establishes the pattern for future async implementations */
|
|
325
|
+
destroy() {
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
function createDebugTracer(sessionId, workingDirectory) {
|
|
329
|
+
if (!DEBUG_ENABLED) return null;
|
|
330
|
+
return new DebugTracer(sessionId, workingDirectory);
|
|
331
|
+
}
|
|
332
|
+
|
|
300
333
|
// src/core/agents/agent-instance.ts
|
|
301
334
|
var log = createChildLogger({ module: "agent-instance" });
|
|
302
335
|
function findPackageRoot(startDir) {
|
|
303
336
|
let dir = startDir;
|
|
304
|
-
while (dir !==
|
|
305
|
-
if (
|
|
337
|
+
while (dir !== path2.dirname(dir)) {
|
|
338
|
+
if (fs2.existsSync(path2.join(dir, "package.json"))) {
|
|
306
339
|
return dir;
|
|
307
340
|
}
|
|
308
|
-
dir =
|
|
341
|
+
dir = path2.dirname(dir);
|
|
309
342
|
}
|
|
310
343
|
return startDir;
|
|
311
344
|
}
|
|
@@ -317,26 +350,26 @@ function resolveAgentCommand(cmd) {
|
|
|
317
350
|
}
|
|
318
351
|
for (const root of searchRoots) {
|
|
319
352
|
const packageDirs = [
|
|
320
|
-
|
|
321
|
-
|
|
353
|
+
path2.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
|
|
354
|
+
path2.resolve(root, "node_modules", cmd, "dist", "index.js")
|
|
322
355
|
];
|
|
323
356
|
for (const jsPath of packageDirs) {
|
|
324
|
-
if (
|
|
357
|
+
if (fs2.existsSync(jsPath)) {
|
|
325
358
|
return { command: process.execPath, args: [jsPath] };
|
|
326
359
|
}
|
|
327
360
|
}
|
|
328
361
|
}
|
|
329
362
|
for (const root of searchRoots) {
|
|
330
|
-
const localBin =
|
|
331
|
-
if (
|
|
332
|
-
const content =
|
|
363
|
+
const localBin = path2.resolve(root, "node_modules", ".bin", cmd);
|
|
364
|
+
if (fs2.existsSync(localBin)) {
|
|
365
|
+
const content = fs2.readFileSync(localBin, "utf-8");
|
|
333
366
|
if (content.startsWith("#!/usr/bin/env node")) {
|
|
334
367
|
return { command: process.execPath, args: [localBin] };
|
|
335
368
|
}
|
|
336
369
|
const match = content.match(/"([^"]+\.js)"/);
|
|
337
370
|
if (match) {
|
|
338
|
-
const target =
|
|
339
|
-
if (
|
|
371
|
+
const target = path2.resolve(path2.dirname(localBin), match[1]);
|
|
372
|
+
if (fs2.existsSync(target)) {
|
|
340
373
|
return { command: process.execPath, args: [target] };
|
|
341
374
|
}
|
|
342
375
|
}
|
|
@@ -345,7 +378,7 @@ function resolveAgentCommand(cmd) {
|
|
|
345
378
|
try {
|
|
346
379
|
const fullPath = execFileSync("which", [cmd], { encoding: "utf-8" }).trim();
|
|
347
380
|
if (fullPath) {
|
|
348
|
-
const content =
|
|
381
|
+
const content = fs2.readFileSync(fullPath, "utf-8");
|
|
349
382
|
if (content.startsWith("#!/usr/bin/env node")) {
|
|
350
383
|
return { command: process.execPath, args: [fullPath] };
|
|
351
384
|
}
|
|
@@ -365,6 +398,7 @@ var AgentInstance = class _AgentInstance extends TypedEmitter {
|
|
|
365
398
|
agentName;
|
|
366
399
|
promptCapabilities;
|
|
367
400
|
middlewareChain;
|
|
401
|
+
debugTracer = null;
|
|
368
402
|
// Callback — set by core when wiring events
|
|
369
403
|
onPermissionRequest = async () => "";
|
|
370
404
|
constructor(agentName) {
|
|
@@ -407,20 +441,28 @@ var AgentInstance = class _AgentInstance extends TypedEmitter {
|
|
|
407
441
|
});
|
|
408
442
|
const stdinLogger = new Transform({
|
|
409
443
|
transform(chunk, _enc, cb) {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
444
|
+
if (instance.debugTracer) {
|
|
445
|
+
const raw = chunk.toString().trimEnd();
|
|
446
|
+
try {
|
|
447
|
+
instance.debugTracer.log("acp", { dir: "send", data: JSON.parse(raw) });
|
|
448
|
+
} catch {
|
|
449
|
+
instance.debugTracer.log("acp", { dir: "send", data: raw });
|
|
450
|
+
}
|
|
451
|
+
}
|
|
414
452
|
cb(null, chunk);
|
|
415
453
|
}
|
|
416
454
|
});
|
|
417
455
|
stdinLogger.pipe(instance.child.stdin);
|
|
418
456
|
const stdoutLogger = new Transform({
|
|
419
457
|
transform(chunk, _enc, cb) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
458
|
+
if (instance.debugTracer) {
|
|
459
|
+
const raw = chunk.toString().trimEnd();
|
|
460
|
+
try {
|
|
461
|
+
instance.debugTracer.log("acp", { dir: "recv", data: JSON.parse(raw) });
|
|
462
|
+
} catch {
|
|
463
|
+
instance.debugTracer.log("acp", { dir: "recv", data: raw });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
424
466
|
cb(null, chunk);
|
|
425
467
|
}
|
|
426
468
|
});
|
|
@@ -489,6 +531,7 @@ ${stderr}`
|
|
|
489
531
|
mcpServers: resolvedMcp
|
|
490
532
|
});
|
|
491
533
|
instance.sessionId = response.sessionId;
|
|
534
|
+
instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);
|
|
492
535
|
instance.setupCrashDetection();
|
|
493
536
|
log.info(
|
|
494
537
|
{ sessionId: response.sessionId, durationMs: Date.now() - spawnStart },
|
|
@@ -509,6 +552,7 @@ ${stderr}`
|
|
|
509
552
|
cwd: workingDirectory
|
|
510
553
|
});
|
|
511
554
|
instance.sessionId = response.sessionId;
|
|
555
|
+
instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);
|
|
512
556
|
log.info(
|
|
513
557
|
{ sessionId: response.sessionId, durationMs: Date.now() - spawnStart },
|
|
514
558
|
"Agent resume complete"
|
|
@@ -524,6 +568,7 @@ ${stderr}`
|
|
|
524
568
|
mcpServers: resolvedMcp
|
|
525
569
|
});
|
|
526
570
|
instance.sessionId = response.sessionId;
|
|
571
|
+
instance.debugTracer = createDebugTracer(response.sessionId, workingDirectory);
|
|
527
572
|
log.info(
|
|
528
573
|
{ sessionId: response.sessionId, durationMs: Date.now() - spawnStart },
|
|
529
574
|
"Agent fallback spawn complete"
|
|
@@ -712,8 +757,8 @@ ${stderr}`
|
|
|
712
757
|
writePath = result.path;
|
|
713
758
|
writeContent = result.content;
|
|
714
759
|
}
|
|
715
|
-
await
|
|
716
|
-
await
|
|
760
|
+
await fs2.promises.mkdir(path2.dirname(writePath), { recursive: true });
|
|
761
|
+
await fs2.promises.writeFile(writePath, writeContent, "utf-8");
|
|
717
762
|
return {};
|
|
718
763
|
},
|
|
719
764
|
// ── Terminal operations (delegated to TerminalManager) ─────────────
|
|
@@ -797,10 +842,10 @@ ${stderr}`
|
|
|
797
842
|
for (const att of attachments ?? []) {
|
|
798
843
|
const tooLarge = att.size > 10 * 1024 * 1024;
|
|
799
844
|
if (att.type === "image" && this.promptCapabilities?.image && !tooLarge && SUPPORTED_IMAGE_MIMES.has(att.mimeType)) {
|
|
800
|
-
const data = await
|
|
845
|
+
const data = await fs2.promises.readFile(att.filePath);
|
|
801
846
|
contentBlocks.push({ type: "image", data: data.toString("base64"), mimeType: att.mimeType });
|
|
802
847
|
} else if (att.type === "audio" && this.promptCapabilities?.audio && !tooLarge) {
|
|
803
|
-
const data = await
|
|
848
|
+
const data = await fs2.promises.readFile(att.filePath);
|
|
804
849
|
contentBlocks.push({ type: "audio", data: data.toString("base64"), mimeType: att.mimeType });
|
|
805
850
|
} else {
|
|
806
851
|
if ((att.type === "image" || att.type === "audio") && !tooLarge) {
|
|
@@ -1003,7 +1048,7 @@ var PermissionGate = class {
|
|
|
1003
1048
|
|
|
1004
1049
|
// src/core/sessions/session.ts
|
|
1005
1050
|
import { nanoid } from "nanoid";
|
|
1006
|
-
import * as
|
|
1051
|
+
import * as fs3 from "fs";
|
|
1007
1052
|
var moduleLog = createChildLogger({ module: "session" });
|
|
1008
1053
|
var TTS_PROMPT_INSTRUCTION = `
|
|
1009
1054
|
|
|
@@ -1220,7 +1265,7 @@ ${text}`;
|
|
|
1220
1265
|
try {
|
|
1221
1266
|
const audioPath = att.originalFilePath || att.filePath;
|
|
1222
1267
|
const audioMime = att.originalFilePath ? "audio/ogg" : att.mimeType;
|
|
1223
|
-
const audioBuffer = await
|
|
1268
|
+
const audioBuffer = await fs3.promises.readFile(audioPath);
|
|
1224
1269
|
const result = await this.speechService.transcribe(audioBuffer, audioMime);
|
|
1225
1270
|
this.log.info({ provider: "stt", duration: result.duration }, "Voice transcribed");
|
|
1226
1271
|
this.emit("agent_event", {
|
|
@@ -1564,17 +1609,23 @@ var SessionBridge = class {
|
|
|
1564
1609
|
sessionEventHandler;
|
|
1565
1610
|
statusChangeHandler;
|
|
1566
1611
|
namedHandler;
|
|
1612
|
+
get tracer() {
|
|
1613
|
+
return this.session.agentInstance.debugTracer ?? null;
|
|
1614
|
+
}
|
|
1567
1615
|
/** Send message to adapter, optionally running through message:outgoing middleware */
|
|
1568
1616
|
async sendMessage(sessionId, message) {
|
|
1569
1617
|
try {
|
|
1570
1618
|
const mw = this.deps.middlewareChain;
|
|
1571
1619
|
if (mw) {
|
|
1572
1620
|
const result = await mw.execute("message:outgoing", { sessionId, message }, async (m) => m);
|
|
1621
|
+
this.tracer?.log("core", { step: "middleware:outgoing", sessionId, hook: "message:outgoing", blocked: !result });
|
|
1573
1622
|
if (!result) return;
|
|
1623
|
+
this.tracer?.log("core", { step: "dispatch", sessionId, message: result.message });
|
|
1574
1624
|
this.adapter.sendMessage(sessionId, result.message).catch((err) => {
|
|
1575
1625
|
log2.error({ err, sessionId }, "Failed to send message to adapter");
|
|
1576
1626
|
});
|
|
1577
1627
|
} else {
|
|
1628
|
+
this.tracer?.log("core", { step: "dispatch", sessionId, message });
|
|
1578
1629
|
this.adapter.sendMessage(sessionId, message).catch((err) => {
|
|
1579
1630
|
log2.error({ err, sessionId }, "Failed to send message to adapter");
|
|
1580
1631
|
});
|
|
@@ -1616,9 +1667,11 @@ var SessionBridge = class {
|
|
|
1616
1667
|
}
|
|
1617
1668
|
wireSessionToAdapter() {
|
|
1618
1669
|
this.sessionEventHandler = (event) => {
|
|
1670
|
+
this.tracer?.log("core", { step: "agent_event", sessionId: this.session.id, event });
|
|
1619
1671
|
const mw = this.deps.middlewareChain;
|
|
1620
1672
|
if (mw) {
|
|
1621
1673
|
mw.execute("agent:beforeEvent", { sessionId: this.session.id, event }, async (e) => e).then((result) => {
|
|
1674
|
+
this.tracer?.log("core", { step: "middleware:before", sessionId: this.session.id, hook: "agent:beforeEvent", blocked: !result });
|
|
1622
1675
|
if (!result) return;
|
|
1623
1676
|
try {
|
|
1624
1677
|
const transformedEvent = result.event;
|
|
@@ -1668,6 +1721,7 @@ var SessionBridge = class {
|
|
|
1668
1721
|
case "plan":
|
|
1669
1722
|
case "usage":
|
|
1670
1723
|
outgoing = this.deps.messageTransformer.transform(event, ctx);
|
|
1724
|
+
this.tracer?.log("core", { step: "transform", sessionId: this.session.id, input: event, output: outgoing });
|
|
1671
1725
|
this.sendMessage(this.session.id, outgoing);
|
|
1672
1726
|
break;
|
|
1673
1727
|
case "session_end":
|
|
@@ -1697,12 +1751,12 @@ var SessionBridge = class {
|
|
|
1697
1751
|
break;
|
|
1698
1752
|
case "image_content": {
|
|
1699
1753
|
if (this.deps.fileService) {
|
|
1700
|
-
const
|
|
1754
|
+
const fs6 = this.deps.fileService;
|
|
1701
1755
|
const sid = this.session.id;
|
|
1702
1756
|
const { data, mimeType } = event;
|
|
1703
1757
|
const buffer = Buffer.from(data, "base64");
|
|
1704
|
-
const ext =
|
|
1705
|
-
|
|
1758
|
+
const ext = fs6.extensionFromMime(mimeType);
|
|
1759
|
+
fs6.saveFile(sid, `agent-image${ext}`, buffer, mimeType).then((att) => {
|
|
1706
1760
|
this.sendMessage(sid, {
|
|
1707
1761
|
type: "attachment",
|
|
1708
1762
|
text: "",
|
|
@@ -1714,12 +1768,12 @@ var SessionBridge = class {
|
|
|
1714
1768
|
}
|
|
1715
1769
|
case "audio_content": {
|
|
1716
1770
|
if (this.deps.fileService) {
|
|
1717
|
-
const
|
|
1771
|
+
const fs6 = this.deps.fileService;
|
|
1718
1772
|
const sid = this.session.id;
|
|
1719
1773
|
const { data, mimeType } = event;
|
|
1720
1774
|
const buffer = Buffer.from(data, "base64");
|
|
1721
|
-
const ext =
|
|
1722
|
-
|
|
1775
|
+
const ext = fs6.extensionFromMime(mimeType);
|
|
1776
|
+
fs6.saveFile(sid, `agent-audio${ext}`, buffer, mimeType).then((att) => {
|
|
1723
1777
|
this.sendMessage(sid, {
|
|
1724
1778
|
type: "attachment",
|
|
1725
1779
|
text: "",
|
|
@@ -1896,14 +1950,22 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
1896
1950
|
let info = null;
|
|
1897
1951
|
if (meta) {
|
|
1898
1952
|
const m = meta;
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1953
|
+
const toolResponse = resolveToolResponse(m);
|
|
1954
|
+
if (toolResponse) {
|
|
1955
|
+
const file = toolResponse.file;
|
|
1956
|
+
if (typeof file?.filePath === "string" && typeof file?.content === "string") {
|
|
1957
|
+
info = { filePath: file.filePath, content: file.content };
|
|
1958
|
+
}
|
|
1959
|
+
if (!info && typeof toolResponse.filePath === "string" && typeof toolResponse.originalFile === "string") {
|
|
1960
|
+
const originalFile = toolResponse.originalFile;
|
|
1961
|
+
const oldString = typeof toolResponse.oldString === "string" ? toolResponse.oldString : void 0;
|
|
1962
|
+
const newString = typeof toolResponse.newString === "string" ? toolResponse.newString : void 0;
|
|
1963
|
+
const newContent = oldString && newString ? originalFile.replace(oldString, newString) : originalFile;
|
|
1964
|
+
info = { filePath: toolResponse.filePath, content: newContent, oldContent: originalFile };
|
|
1965
|
+
}
|
|
1966
|
+
if (!info && typeof toolResponse.filePath === "string" && typeof toolResponse.content === "string") {
|
|
1967
|
+
info = { filePath: toolResponse.filePath, content: toolResponse.content };
|
|
1968
|
+
}
|
|
1907
1969
|
}
|
|
1908
1970
|
}
|
|
1909
1971
|
if (!info && rawInput && typeof rawInput === "object") {
|
|
@@ -1912,7 +1974,19 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
1912
1974
|
if (typeof filePath === "string") {
|
|
1913
1975
|
const parsed = content ? parseContent(content) : null;
|
|
1914
1976
|
const riContent = typeof ri?.content === "string" ? ri.content : void 0;
|
|
1915
|
-
|
|
1977
|
+
if (kind === "edit") {
|
|
1978
|
+
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : void 0;
|
|
1979
|
+
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : void 0;
|
|
1980
|
+
if (newStr) {
|
|
1981
|
+
info = { filePath, content: newStr, oldContent: oldStr };
|
|
1982
|
+
} else {
|
|
1983
|
+
info = { filePath, content: riContent || parsed?.content, oldContent: parsed?.oldContent };
|
|
1984
|
+
}
|
|
1985
|
+
} else if (kind === "write") {
|
|
1986
|
+
info = { filePath, content: riContent || parsed?.content, oldContent: parsed?.oldContent };
|
|
1987
|
+
} else {
|
|
1988
|
+
info = { filePath, content: parsed?.content || riContent, oldContent: parsed?.oldContent };
|
|
1989
|
+
}
|
|
1916
1990
|
}
|
|
1917
1991
|
}
|
|
1918
1992
|
if (!info && content) {
|
|
@@ -1926,6 +2000,16 @@ function extractFileInfo(name, kind, content, rawInput, meta) {
|
|
|
1926
2000
|
if (!info.filePath || !info.content) return null;
|
|
1927
2001
|
return info;
|
|
1928
2002
|
}
|
|
2003
|
+
function resolveToolResponse(meta) {
|
|
2004
|
+
const claudeCode = meta.claudeCode;
|
|
2005
|
+
if (claudeCode?.toolResponse && typeof claudeCode.toolResponse === "object") {
|
|
2006
|
+
return claudeCode.toolResponse;
|
|
2007
|
+
}
|
|
2008
|
+
if (meta.toolResponse && typeof meta.toolResponse === "object") {
|
|
2009
|
+
return meta.toolResponse;
|
|
2010
|
+
}
|
|
2011
|
+
return void 0;
|
|
2012
|
+
}
|
|
1929
2013
|
function parseContent(content) {
|
|
1930
2014
|
if (typeof content === "string") {
|
|
1931
2015
|
return { content };
|
|
@@ -1984,7 +2068,30 @@ function parseContent(content) {
|
|
|
1984
2068
|
|
|
1985
2069
|
// src/core/message-transformer.ts
|
|
1986
2070
|
var log3 = createChildLogger({ module: "message-transformer" });
|
|
2071
|
+
function computeLineDiff(oldStr, newStr) {
|
|
2072
|
+
const oldLines = oldStr ? oldStr.split("\n") : [];
|
|
2073
|
+
const newLines = newStr ? newStr.split("\n") : [];
|
|
2074
|
+
let prefixLen = 0;
|
|
2075
|
+
const minLen = Math.min(oldLines.length, newLines.length);
|
|
2076
|
+
while (prefixLen < minLen && oldLines[prefixLen] === newLines[prefixLen]) {
|
|
2077
|
+
prefixLen++;
|
|
2078
|
+
}
|
|
2079
|
+
let suffixLen = 0;
|
|
2080
|
+
const maxSuffix = minLen - prefixLen;
|
|
2081
|
+
while (suffixLen < maxSuffix && oldLines[oldLines.length - 1 - suffixLen] === newLines[newLines.length - 1 - suffixLen]) {
|
|
2082
|
+
suffixLen++;
|
|
2083
|
+
}
|
|
2084
|
+
return {
|
|
2085
|
+
added: Math.max(0, newLines.length - prefixLen - suffixLen),
|
|
2086
|
+
removed: Math.max(0, oldLines.length - prefixLen - suffixLen)
|
|
2087
|
+
};
|
|
2088
|
+
}
|
|
1987
2089
|
var MessageTransformer = class {
|
|
2090
|
+
tunnelService;
|
|
2091
|
+
/** Cache rawInput from tool_call so it's available in tool_update (which often lacks it) */
|
|
2092
|
+
toolRawInputCache = /* @__PURE__ */ new Map();
|
|
2093
|
+
/** Cache viewer links generated from intermediate updates so completion events carry them */
|
|
2094
|
+
toolViewerCache = /* @__PURE__ */ new Map();
|
|
1988
2095
|
constructor(tunnelService) {
|
|
1989
2096
|
this.tunnelService = tunnelService;
|
|
1990
2097
|
}
|
|
@@ -1995,6 +2102,9 @@ var MessageTransformer = class {
|
|
|
1995
2102
|
case "thought":
|
|
1996
2103
|
return { type: "thought", text: event.content };
|
|
1997
2104
|
case "tool_call": {
|
|
2105
|
+
if (event.id && this.isNonEmptyInput(event.rawInput)) {
|
|
2106
|
+
this.toolRawInputCache.set(event.id, event.rawInput);
|
|
2107
|
+
}
|
|
1998
2108
|
const meta = event.meta;
|
|
1999
2109
|
const metadata = {
|
|
2000
2110
|
id: event.id,
|
|
@@ -2012,6 +2122,14 @@ var MessageTransformer = class {
|
|
|
2012
2122
|
return { type: "tool_call", text: event.name, metadata };
|
|
2013
2123
|
}
|
|
2014
2124
|
case "tool_update": {
|
|
2125
|
+
if (event.id && this.isNonEmptyInput(event.rawInput)) {
|
|
2126
|
+
this.toolRawInputCache.set(event.id, event.rawInput);
|
|
2127
|
+
}
|
|
2128
|
+
const cachedRawInput = event.id ? this.toolRawInputCache.get(event.id) : void 0;
|
|
2129
|
+
const effectiveRawInput = this.isNonEmptyInput(event.rawInput) ? event.rawInput : cachedRawInput;
|
|
2130
|
+
if (event.id && (event.status === "completed" || event.status === "done" || event.status === "failed" || event.status === "error")) {
|
|
2131
|
+
this.toolRawInputCache.delete(event.id);
|
|
2132
|
+
}
|
|
2015
2133
|
const meta = event.meta;
|
|
2016
2134
|
const metadata = {
|
|
2017
2135
|
id: event.id,
|
|
@@ -2019,12 +2137,28 @@ var MessageTransformer = class {
|
|
|
2019
2137
|
kind: event.kind,
|
|
2020
2138
|
status: event.status,
|
|
2021
2139
|
content: event.content,
|
|
2022
|
-
rawInput:
|
|
2140
|
+
rawInput: effectiveRawInput,
|
|
2023
2141
|
displaySummary: meta?.displaySummary,
|
|
2024
2142
|
displayTitle: meta?.displayTitle,
|
|
2025
2143
|
displayKind: meta?.displayKind
|
|
2026
2144
|
};
|
|
2027
|
-
|
|
2145
|
+
const enrichEvent = { ...event, rawInput: effectiveRawInput };
|
|
2146
|
+
this.enrichWithViewerLinks(enrichEvent, metadata, sessionContext);
|
|
2147
|
+
if (event.id) {
|
|
2148
|
+
const cached = this.toolViewerCache.get(event.id);
|
|
2149
|
+
if (cached) {
|
|
2150
|
+
metadata.viewerLinks = cached.viewerLinks;
|
|
2151
|
+
metadata.viewerFilePath = cached.viewerFilePath;
|
|
2152
|
+
} else if (metadata.viewerLinks) {
|
|
2153
|
+
this.toolViewerCache.set(event.id, {
|
|
2154
|
+
viewerLinks: metadata.viewerLinks,
|
|
2155
|
+
viewerFilePath: metadata.viewerFilePath
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
if (event.status === "completed" || event.status === "done" || event.status === "failed" || event.status === "error") {
|
|
2159
|
+
this.toolViewerCache.delete(event.id);
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2028
2162
|
return { type: "tool_update", text: "", metadata };
|
|
2029
2163
|
}
|
|
2030
2164
|
case "plan":
|
|
@@ -2094,12 +2228,38 @@ var MessageTransformer = class {
|
|
|
2094
2228
|
return { type: "text", text: "" };
|
|
2095
2229
|
}
|
|
2096
2230
|
}
|
|
2231
|
+
/** Check if rawInput is a non-empty object (not null, not {}) */
|
|
2232
|
+
isNonEmptyInput(input) {
|
|
2233
|
+
return input !== null && input !== void 0 && typeof input === "object" && !Array.isArray(input) && Object.keys(input).length > 0;
|
|
2234
|
+
}
|
|
2097
2235
|
enrichWithViewerLinks(event, metadata, sessionContext) {
|
|
2098
|
-
if (!this.tunnelService || !sessionContext) return;
|
|
2099
|
-
const name = "name" in event ? event.name || "" : "";
|
|
2100
2236
|
const kind = "kind" in event ? event.kind : void 0;
|
|
2237
|
+
if (!metadata.diffStats && (kind === "edit" || kind === "write")) {
|
|
2238
|
+
const ri = event.rawInput;
|
|
2239
|
+
if (ri) {
|
|
2240
|
+
const oldStr = typeof ri.old_string === "string" ? ri.old_string : typeof ri.oldText === "string" ? ri.oldText : null;
|
|
2241
|
+
const newStr = typeof ri.new_string === "string" ? ri.new_string : typeof ri.newText === "string" ? ri.newText : typeof ri.content === "string" ? ri.content : null;
|
|
2242
|
+
if (oldStr !== null && newStr !== null) {
|
|
2243
|
+
const stats = computeLineDiff(oldStr, newStr);
|
|
2244
|
+
if (stats.added > 0 || stats.removed > 0) {
|
|
2245
|
+
metadata.diffStats = stats;
|
|
2246
|
+
}
|
|
2247
|
+
} else if (oldStr === null && newStr !== null && kind === "write") {
|
|
2248
|
+
const added = newStr.split("\n").length;
|
|
2249
|
+
if (added > 0) metadata.diffStats = { added, removed: 0 };
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
if (!this.tunnelService || !sessionContext) {
|
|
2254
|
+
log3.debug(
|
|
2255
|
+
{ hasTunnel: !!this.tunnelService, hasCtx: !!sessionContext, kind },
|
|
2256
|
+
"enrichWithViewerLinks: skipping (no tunnel or session context)"
|
|
2257
|
+
);
|
|
2258
|
+
return;
|
|
2259
|
+
}
|
|
2260
|
+
const name = "name" in event ? event.name || "" : "";
|
|
2101
2261
|
log3.debug(
|
|
2102
|
-
{ name, kind, status: event.status, hasContent: !!event.content },
|
|
2262
|
+
{ name, kind, status: event.status, hasContent: !!event.content, hasRawInput: !!event.rawInput },
|
|
2103
2263
|
"enrichWithViewerLinks: inspecting event"
|
|
2104
2264
|
);
|
|
2105
2265
|
const fileInfo = extractFileInfo(
|
|
@@ -2109,7 +2269,18 @@ var MessageTransformer = class {
|
|
|
2109
2269
|
event.rawInput,
|
|
2110
2270
|
event.meta
|
|
2111
2271
|
);
|
|
2112
|
-
if (!fileInfo)
|
|
2272
|
+
if (!fileInfo) {
|
|
2273
|
+
log3.debug(
|
|
2274
|
+
{ name, kind, hasContent: !!event.content, hasRawInput: !!event.rawInput, hasMeta: !!event.meta },
|
|
2275
|
+
"enrichWithViewerLinks: extractFileInfo returned null"
|
|
2276
|
+
);
|
|
2277
|
+
return;
|
|
2278
|
+
}
|
|
2279
|
+
const publicUrl = this.tunnelService.getPublicUrl();
|
|
2280
|
+
if (publicUrl.startsWith("http://localhost") || publicUrl.startsWith("http://127.0.0.1")) {
|
|
2281
|
+
log3.debug({ kind, filePath: fileInfo.filePath }, "enrichWithViewerLinks: skipping (no public tunnel URL)");
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2113
2284
|
log3.info(
|
|
2114
2285
|
{
|
|
2115
2286
|
name,
|
|
@@ -2130,6 +2301,12 @@ var MessageTransformer = class {
|
|
|
2130
2301
|
sessionContext.workingDirectory
|
|
2131
2302
|
);
|
|
2132
2303
|
if (id2) viewerLinks.diff = this.tunnelService.diffUrl(id2);
|
|
2304
|
+
if (!metadata.diffStats) {
|
|
2305
|
+
const stats = computeLineDiff(fileInfo.oldContent, fileInfo.content);
|
|
2306
|
+
if (stats.added > 0 || stats.removed > 0) {
|
|
2307
|
+
metadata.diffStats = stats;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2133
2310
|
}
|
|
2134
2311
|
const id = store.storeFile(
|
|
2135
2312
|
sessionContext.id,
|
|
@@ -2245,12 +2422,12 @@ var EventBus = class extends TypedEmitter {
|
|
|
2245
2422
|
};
|
|
2246
2423
|
|
|
2247
2424
|
// src/core/core.ts
|
|
2248
|
-
import
|
|
2425
|
+
import path5 from "path";
|
|
2249
2426
|
import os from "os";
|
|
2250
2427
|
|
|
2251
2428
|
// src/core/sessions/session-store.ts
|
|
2252
|
-
import
|
|
2253
|
-
import
|
|
2429
|
+
import fs4 from "fs";
|
|
2430
|
+
import path3 from "path";
|
|
2254
2431
|
var log5 = createChildLogger({ module: "session-store" });
|
|
2255
2432
|
var DEBOUNCE_MS = 2e3;
|
|
2256
2433
|
var JsonFileSessionStore = class {
|
|
@@ -2312,9 +2489,9 @@ var JsonFileSessionStore = class {
|
|
|
2312
2489
|
version: 1,
|
|
2313
2490
|
sessions: Object.fromEntries(this.records)
|
|
2314
2491
|
};
|
|
2315
|
-
const dir =
|
|
2316
|
-
if (!
|
|
2317
|
-
|
|
2492
|
+
const dir = path3.dirname(this.filePath);
|
|
2493
|
+
if (!fs4.existsSync(dir)) fs4.mkdirSync(dir, { recursive: true });
|
|
2494
|
+
fs4.writeFileSync(this.filePath, JSON.stringify(data, null, 2));
|
|
2318
2495
|
}
|
|
2319
2496
|
destroy() {
|
|
2320
2497
|
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
@@ -2327,10 +2504,10 @@ var JsonFileSessionStore = class {
|
|
|
2327
2504
|
}
|
|
2328
2505
|
}
|
|
2329
2506
|
load() {
|
|
2330
|
-
if (!
|
|
2507
|
+
if (!fs4.existsSync(this.filePath)) return;
|
|
2331
2508
|
try {
|
|
2332
2509
|
const raw = JSON.parse(
|
|
2333
|
-
|
|
2510
|
+
fs4.readFileSync(this.filePath, "utf-8")
|
|
2334
2511
|
);
|
|
2335
2512
|
if (raw.version !== 1) {
|
|
2336
2513
|
log5.warn(
|
|
@@ -2346,7 +2523,7 @@ var JsonFileSessionStore = class {
|
|
|
2346
2523
|
} catch (err) {
|
|
2347
2524
|
log5.error({ err }, "Failed to load session store, backing up corrupt file");
|
|
2348
2525
|
try {
|
|
2349
|
-
|
|
2526
|
+
fs4.renameSync(this.filePath, `${this.filePath}.bak`);
|
|
2350
2527
|
} catch {
|
|
2351
2528
|
}
|
|
2352
2529
|
}
|
|
@@ -2620,27 +2797,27 @@ var ErrorTracker = class {
|
|
|
2620
2797
|
};
|
|
2621
2798
|
|
|
2622
2799
|
// src/core/plugin/plugin-storage.ts
|
|
2623
|
-
import
|
|
2624
|
-
import
|
|
2800
|
+
import fs5 from "fs";
|
|
2801
|
+
import path4 from "path";
|
|
2625
2802
|
var PluginStorageImpl = class {
|
|
2626
2803
|
kvPath;
|
|
2627
2804
|
dataDir;
|
|
2628
2805
|
writeChain = Promise.resolve();
|
|
2629
2806
|
constructor(baseDir) {
|
|
2630
|
-
this.dataDir =
|
|
2631
|
-
this.kvPath =
|
|
2632
|
-
|
|
2807
|
+
this.dataDir = path4.join(baseDir, "data");
|
|
2808
|
+
this.kvPath = path4.join(baseDir, "kv.json");
|
|
2809
|
+
fs5.mkdirSync(baseDir, { recursive: true });
|
|
2633
2810
|
}
|
|
2634
2811
|
readKv() {
|
|
2635
2812
|
try {
|
|
2636
|
-
const raw =
|
|
2813
|
+
const raw = fs5.readFileSync(this.kvPath, "utf-8");
|
|
2637
2814
|
return JSON.parse(raw);
|
|
2638
2815
|
} catch {
|
|
2639
2816
|
return {};
|
|
2640
2817
|
}
|
|
2641
2818
|
}
|
|
2642
2819
|
writeKv(data) {
|
|
2643
|
-
|
|
2820
|
+
fs5.writeFileSync(this.kvPath, JSON.stringify(data), "utf-8");
|
|
2644
2821
|
}
|
|
2645
2822
|
async get(key) {
|
|
2646
2823
|
const data = this.readKv();
|
|
@@ -2666,7 +2843,7 @@ var PluginStorageImpl = class {
|
|
|
2666
2843
|
return Object.keys(this.readKv());
|
|
2667
2844
|
}
|
|
2668
2845
|
getDataDir() {
|
|
2669
|
-
|
|
2846
|
+
fs5.mkdirSync(this.dataDir, { recursive: true });
|
|
2670
2847
|
return this.dataDir;
|
|
2671
2848
|
}
|
|
2672
2849
|
};
|
|
@@ -3113,7 +3290,7 @@ var OpenACPCore = class {
|
|
|
3113
3290
|
this.agentCatalog = new AgentCatalog();
|
|
3114
3291
|
this.agentCatalog.load();
|
|
3115
3292
|
this.agentManager = new AgentManager(this.agentCatalog);
|
|
3116
|
-
const storePath =
|
|
3293
|
+
const storePath = path5.join(os.homedir(), ".openacp", "sessions.json");
|
|
3117
3294
|
this.sessionStore = new JsonFileSessionStore(
|
|
3118
3295
|
storePath,
|
|
3119
3296
|
config.sessionStore.ttlDays
|
|
@@ -3136,7 +3313,7 @@ var OpenACPCore = class {
|
|
|
3136
3313
|
sessions: this.sessionManager,
|
|
3137
3314
|
config: this.configManager,
|
|
3138
3315
|
core: this,
|
|
3139
|
-
storagePath:
|
|
3316
|
+
storagePath: path5.join(os.homedir(), ".openacp", "plugins", "data"),
|
|
3140
3317
|
log: createChildLogger({ module: "plugin" })
|
|
3141
3318
|
});
|
|
3142
3319
|
this.sessionFactory.middlewareChain = this.lifecycleManager.middlewareChain;
|
|
@@ -3169,7 +3346,7 @@ var OpenACPCore = class {
|
|
|
3169
3346
|
}
|
|
3170
3347
|
set tunnelService(service) {
|
|
3171
3348
|
this._tunnelService = service;
|
|
3172
|
-
this.messageTransformer =
|
|
3349
|
+
this.messageTransformer.tunnelService = service;
|
|
3173
3350
|
}
|
|
3174
3351
|
registerAdapter(name, adapter) {
|
|
3175
3352
|
this.adapters.set(name, adapter);
|
|
@@ -3737,4 +3914,4 @@ export {
|
|
|
3737
3914
|
OpenACPCore,
|
|
3738
3915
|
CommandRegistry
|
|
3739
3916
|
};
|
|
3740
|
-
//# sourceMappingURL=chunk-
|
|
3917
|
+
//# sourceMappingURL=chunk-UCIZM5SW.js.map
|