@adhdev/daemon-core 0.7.4 → 0.7.6
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/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +195 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +195 -28
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.ts +6 -0
- package/src/boot/daemon-lifecycle.ts +1 -1
- package/src/cdp/initializer.ts +5 -5
- package/src/cdp/scanner.ts +2 -2
- package/src/commands/handler.ts +126 -3
- package/src/commands/stream-commands.ts +0 -1
- package/src/providers/extension-provider-instance.ts +50 -10
- package/src/providers/provider-instance-manager.ts +27 -10
package/dist/index.mjs
CHANGED
|
@@ -3411,6 +3411,10 @@ var ExtensionProviderInstance = class {
|
|
|
3411
3411
|
// meta
|
|
3412
3412
|
instanceId;
|
|
3413
3413
|
ideType = "";
|
|
3414
|
+
chatId = null;
|
|
3415
|
+
chatTitle = null;
|
|
3416
|
+
agentName = "";
|
|
3417
|
+
extensionId = "";
|
|
3414
3418
|
constructor(provider) {
|
|
3415
3419
|
this.type = provider.type;
|
|
3416
3420
|
this.provider = provider;
|
|
@@ -3437,8 +3441,8 @@ var ExtensionProviderInstance = class {
|
|
|
3437
3441
|
category: "extension",
|
|
3438
3442
|
status: this.currentStatus,
|
|
3439
3443
|
activeChat: this.messages.length > 0 ? {
|
|
3440
|
-
id:
|
|
3441
|
-
title: this.provider.name,
|
|
3444
|
+
id: this.chatId || this.instanceId,
|
|
3445
|
+
title: this.chatTitle || this.agentName || this.provider.name,
|
|
3442
3446
|
status: this.currentStatus,
|
|
3443
3447
|
messages: this.messages,
|
|
3444
3448
|
activeModal: this.activeModal,
|
|
@@ -3460,6 +3464,10 @@ var ExtensionProviderInstance = class {
|
|
|
3460
3464
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
3461
3465
|
if (data?.model) this.currentModel = data.model;
|
|
3462
3466
|
if (data?.mode) this.currentMode = data.mode;
|
|
3467
|
+
if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
|
|
3468
|
+
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
3469
|
+
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
3470
|
+
if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
|
|
3463
3471
|
if (data?.status) {
|
|
3464
3472
|
const newStatus = data.status;
|
|
3465
3473
|
this.detectTransition(newStatus, data);
|
|
@@ -3479,11 +3487,6 @@ var ExtensionProviderInstance = class {
|
|
|
3479
3487
|
return this.instanceId;
|
|
3480
3488
|
}
|
|
3481
3489
|
// ─── status transition detect ──────────────────────────────
|
|
3482
|
-
// NOTE: Extension transitions are TRACKED but NOT emitted as events.
|
|
3483
|
-
// The parent IdeProviderInstance already emits identical events
|
|
3484
|
-
// (generating_started, generating_completed, waiting_approval)
|
|
3485
|
-
// via its own detectAgentTransitions(). Emitting here would cause
|
|
3486
|
-
// duplicate toasts with slightly different content.
|
|
3487
3490
|
detectTransition(newStatus, data) {
|
|
3488
3491
|
const now = Date.now();
|
|
3489
3492
|
const agentStatus = newStatus === "streaming" || newStatus === "generating" ? "generating" : newStatus === "waiting_approval" ? "waiting_approval" : "idle";
|
|
@@ -3492,7 +3495,40 @@ var ExtensionProviderInstance = class {
|
|
|
3492
3495
|
if (agentStatus !== this.lastAgentStatus) {
|
|
3493
3496
|
if (this.lastAgentStatus === "idle" && agentStatus === "generating") {
|
|
3494
3497
|
this.generatingStartedAt = now;
|
|
3498
|
+
this.pushEvent({
|
|
3499
|
+
event: "agent:generating_started",
|
|
3500
|
+
chatTitle: this.resolveChatTitle(data),
|
|
3501
|
+
timestamp: now,
|
|
3502
|
+
ideType: this.ideType || this.type,
|
|
3503
|
+
agentType: this.type,
|
|
3504
|
+
agentName: this.agentName || this.provider.name,
|
|
3505
|
+
extensionId: this.extensionId || this.type
|
|
3506
|
+
});
|
|
3507
|
+
} else if (agentStatus === "waiting_approval") {
|
|
3508
|
+
if (!this.generatingStartedAt) this.generatingStartedAt = now;
|
|
3509
|
+
this.pushEvent({
|
|
3510
|
+
event: "agent:waiting_approval",
|
|
3511
|
+
chatTitle: this.resolveChatTitle(data),
|
|
3512
|
+
timestamp: now,
|
|
3513
|
+
ideType: this.ideType || this.type,
|
|
3514
|
+
agentType: this.type,
|
|
3515
|
+
agentName: this.agentName || this.provider.name,
|
|
3516
|
+
extensionId: this.extensionId || this.type,
|
|
3517
|
+
modalMessage: data?.activeModal?.message,
|
|
3518
|
+
modalButtons: data?.activeModal?.buttons
|
|
3519
|
+
});
|
|
3495
3520
|
} else if (agentStatus === "idle" && (this.lastAgentStatus === "generating" || this.lastAgentStatus === "waiting_approval")) {
|
|
3521
|
+
const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1e3) : 0;
|
|
3522
|
+
this.pushEvent({
|
|
3523
|
+
event: "agent:generating_completed",
|
|
3524
|
+
chatTitle: this.resolveChatTitle(data),
|
|
3525
|
+
duration,
|
|
3526
|
+
timestamp: now,
|
|
3527
|
+
ideType: this.ideType || this.type,
|
|
3528
|
+
agentType: this.type,
|
|
3529
|
+
agentName: this.agentName || this.provider.name,
|
|
3530
|
+
extensionId: this.extensionId || this.type
|
|
3531
|
+
});
|
|
3496
3532
|
this.generatingStartedAt = 0;
|
|
3497
3533
|
}
|
|
3498
3534
|
this.lastAgentStatus = agentStatus;
|
|
@@ -3512,6 +3548,10 @@ var ExtensionProviderInstance = class {
|
|
|
3512
3548
|
this.events = [];
|
|
3513
3549
|
return events;
|
|
3514
3550
|
}
|
|
3551
|
+
resolveChatTitle(data) {
|
|
3552
|
+
const title = typeof data?.title === "string" && data.title.trim() ? data.title.trim() : this.chatTitle;
|
|
3553
|
+
return title || this.agentName || this.provider.name;
|
|
3554
|
+
}
|
|
3515
3555
|
};
|
|
3516
3556
|
|
|
3517
3557
|
// src/config/chat-history.ts
|
|
@@ -4239,7 +4279,7 @@ var DaemonCdpScanner = class {
|
|
|
4239
4279
|
if (!manager) return;
|
|
4240
4280
|
registerExtensionProviders(this.ctx.providerLoader, manager, ide);
|
|
4241
4281
|
this.ctx.cdpManagers.set(ide, manager);
|
|
4242
|
-
LOG.info("
|
|
4282
|
+
LOG.info("IDE", `Attached: ${ide} (port ${port})`);
|
|
4243
4283
|
await setupIdeInstance(this.ctx, { ideType: ide, manager });
|
|
4244
4284
|
this.opts.onConnected?.(ide, ide, manager);
|
|
4245
4285
|
}
|
|
@@ -4272,7 +4312,7 @@ var DaemonCdpScanner = class {
|
|
|
4272
4312
|
);
|
|
4273
4313
|
if (!manager) continue;
|
|
4274
4314
|
this.ctx.cdpManagers.set(managerKey, manager);
|
|
4275
|
-
LOG.info("
|
|
4315
|
+
LOG.info("IDE", `Attached window: ${managerKey} (port ${port}, page "${target.title}")`);
|
|
4276
4316
|
await setupIdeInstance(this.ctx, {
|
|
4277
4317
|
ideType: ide,
|
|
4278
4318
|
manager,
|
|
@@ -4317,9 +4357,9 @@ var DaemonCdpInitializer = class {
|
|
|
4317
4357
|
await this.connectIdePort(port, ide);
|
|
4318
4358
|
}
|
|
4319
4359
|
if (cdpManagers.size > 0) {
|
|
4320
|
-
LOG.info("
|
|
4360
|
+
LOG.info("IDE", `${cdpManagers.size} IDE window(s) attached: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(", ")}`);
|
|
4321
4361
|
} else {
|
|
4322
|
-
LOG.warn("
|
|
4362
|
+
LOG.warn("IDE", `No IDE windows attached \u2014 tried: ${filtered.map((p) => `${p.ide}:${p.port}`).join(", ")}`);
|
|
4323
4363
|
}
|
|
4324
4364
|
}
|
|
4325
4365
|
// ─── Per-port connection (multi-window aware) ───
|
|
@@ -4345,7 +4385,7 @@ var DaemonCdpInitializer = class {
|
|
|
4345
4385
|
if (connected) {
|
|
4346
4386
|
registerExtensionProviders(providerLoader, manager, ide);
|
|
4347
4387
|
cdpManagers.set(ide, manager);
|
|
4348
|
-
LOG.info("
|
|
4388
|
+
LOG.info("IDE", `Attached: ${ide} (port ${port})`);
|
|
4349
4389
|
await this.config.onConnected?.(ide, manager, ide);
|
|
4350
4390
|
}
|
|
4351
4391
|
return;
|
|
@@ -4378,7 +4418,7 @@ var DaemonCdpInitializer = class {
|
|
|
4378
4418
|
if (connected) {
|
|
4379
4419
|
registerExtensionProviders(providerLoader, manager, ide);
|
|
4380
4420
|
cdpManagers.set(managerKey, manager);
|
|
4381
|
-
LOG.info("
|
|
4421
|
+
LOG.info("IDE", `Attached window: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ""})`);
|
|
4382
4422
|
await this.config.onConnected?.(ide, manager, managerKey);
|
|
4383
4423
|
}
|
|
4384
4424
|
}
|
|
@@ -4407,7 +4447,7 @@ var DaemonCdpInitializer = class {
|
|
|
4407
4447
|
} catch {
|
|
4408
4448
|
}
|
|
4409
4449
|
this.config.cdpManagers.delete(key);
|
|
4410
|
-
LOG.info("
|
|
4450
|
+
LOG.info("IDE", `Detached window: ${key} (${reason})`);
|
|
4411
4451
|
await this.config.onDisconnected?.(ide, manager, key, reason);
|
|
4412
4452
|
}
|
|
4413
4453
|
}
|
|
@@ -5803,7 +5843,6 @@ function handleSetProviderSetting(h, args) {
|
|
|
5803
5843
|
}
|
|
5804
5844
|
async function handleExtensionScript(h, args, scriptName) {
|
|
5805
5845
|
const { agentType, ideType } = args || {};
|
|
5806
|
-
LOG.info("Command", `[ExtScript] ${scriptName} agentType=${agentType} ideType=${ideType} session=${h.currentSession?.sessionId || ""}`);
|
|
5807
5846
|
if (!agentType) return { success: false, error: "agentType is required" };
|
|
5808
5847
|
const loader = h.ctx.providerLoader;
|
|
5809
5848
|
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
@@ -6017,6 +6056,83 @@ function handleWorkspaceSetDefault(args) {
|
|
|
6017
6056
|
|
|
6018
6057
|
// src/commands/handler.ts
|
|
6019
6058
|
init_workspaces();
|
|
6059
|
+
var COMMAND_DEBUG_LEVELS = /* @__PURE__ */ new Set([
|
|
6060
|
+
"pty_input",
|
|
6061
|
+
"pty_resize",
|
|
6062
|
+
"cdp_eval",
|
|
6063
|
+
"cdp_batch",
|
|
6064
|
+
"cdp_dom_query",
|
|
6065
|
+
"cdp_dom_dump",
|
|
6066
|
+
"cdp_dom_debug"
|
|
6067
|
+
]);
|
|
6068
|
+
function logAtLevel(level, category, message) {
|
|
6069
|
+
switch (level) {
|
|
6070
|
+
case "debug":
|
|
6071
|
+
LOG.debug(category, message);
|
|
6072
|
+
return;
|
|
6073
|
+
case "warn":
|
|
6074
|
+
LOG.warn(category, message);
|
|
6075
|
+
return;
|
|
6076
|
+
case "error":
|
|
6077
|
+
LOG.error(category, message);
|
|
6078
|
+
return;
|
|
6079
|
+
default:
|
|
6080
|
+
LOG.info(category, message);
|
|
6081
|
+
}
|
|
6082
|
+
}
|
|
6083
|
+
function getCommandLogLevel(cmd) {
|
|
6084
|
+
return COMMAND_DEBUG_LEVELS.has(cmd) ? "debug" : "info";
|
|
6085
|
+
}
|
|
6086
|
+
function summarizeLogValue(value) {
|
|
6087
|
+
if (value === null) return "null";
|
|
6088
|
+
if (value === void 0) return "undefined";
|
|
6089
|
+
if (typeof value === "string") {
|
|
6090
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
6091
|
+
if (!normalized) return '""';
|
|
6092
|
+
if (normalized.length <= 80) return JSON.stringify(normalized);
|
|
6093
|
+
return `${JSON.stringify(normalized.slice(0, 80))}\u2026(${normalized.length} chars)`;
|
|
6094
|
+
}
|
|
6095
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
6096
|
+
if (Array.isArray(value)) return `[${value.length} items]`;
|
|
6097
|
+
if (typeof value === "object") return "{...}";
|
|
6098
|
+
return String(value);
|
|
6099
|
+
}
|
|
6100
|
+
function summarizeCommandArgs(args) {
|
|
6101
|
+
if (!args || typeof args !== "object") return "-";
|
|
6102
|
+
const preferredKeys = [
|
|
6103
|
+
"targetSessionId",
|
|
6104
|
+
"providerType",
|
|
6105
|
+
"agentType",
|
|
6106
|
+
"ideType",
|
|
6107
|
+
"model",
|
|
6108
|
+
"mode",
|
|
6109
|
+
"action",
|
|
6110
|
+
"button",
|
|
6111
|
+
"key",
|
|
6112
|
+
"force",
|
|
6113
|
+
"offset",
|
|
6114
|
+
"limit",
|
|
6115
|
+
"cols",
|
|
6116
|
+
"rows",
|
|
6117
|
+
"path",
|
|
6118
|
+
"command",
|
|
6119
|
+
"commandId",
|
|
6120
|
+
"workspace",
|
|
6121
|
+
"dir",
|
|
6122
|
+
"url",
|
|
6123
|
+
"text",
|
|
6124
|
+
"message",
|
|
6125
|
+
"data",
|
|
6126
|
+
"value"
|
|
6127
|
+
];
|
|
6128
|
+
const entries = [];
|
|
6129
|
+
for (const key of preferredKeys) {
|
|
6130
|
+
if (!(key in args) || args[key] === void 0) continue;
|
|
6131
|
+
const value = key === "text" || key === "message" ? `${String(args[key] || "").length} chars` : key === "data" ? `${String(args[key] || "").length} chars` : summarizeLogValue(args[key]);
|
|
6132
|
+
entries.push(`${key}=${value}`);
|
|
6133
|
+
}
|
|
6134
|
+
return entries.length ? entries.join(" ") : "{...}";
|
|
6135
|
+
}
|
|
6020
6136
|
var DaemonCommandHandler = class {
|
|
6021
6137
|
_ctx;
|
|
6022
6138
|
_agentStream = null;
|
|
@@ -6164,23 +6280,54 @@ var DaemonCommandHandler = class {
|
|
|
6164
6280
|
}
|
|
6165
6281
|
return void 0;
|
|
6166
6282
|
}
|
|
6283
|
+
logCommandStart(cmd, args) {
|
|
6284
|
+
const routeBits = [
|
|
6285
|
+
this._currentRoute.session?.sessionId ? `session=${this._currentRoute.session.sessionId}` : "",
|
|
6286
|
+
this._currentRoute.managerKey ? `manager=${this._currentRoute.managerKey}` : "",
|
|
6287
|
+
this._currentRoute.providerType ? `provider=${this._currentRoute.providerType}` : ""
|
|
6288
|
+
].filter(Boolean).join(" ");
|
|
6289
|
+
const summary = summarizeCommandArgs(args);
|
|
6290
|
+
logAtLevel(
|
|
6291
|
+
getCommandLogLevel(cmd),
|
|
6292
|
+
"Command",
|
|
6293
|
+
`[${cmd}] start${routeBits ? ` ${routeBits}` : ""} args=${summary}`
|
|
6294
|
+
);
|
|
6295
|
+
}
|
|
6296
|
+
logCommandEnd(cmd, result, startedAt) {
|
|
6297
|
+
const durationMs = Date.now() - startedAt;
|
|
6298
|
+
const parts = [`[${cmd}] end`, `success=${result.success}`, `duration=${durationMs}ms`];
|
|
6299
|
+
if (typeof result.error === "string" && result.error) {
|
|
6300
|
+
parts.push(`error=${JSON.stringify(result.error)}`);
|
|
6301
|
+
}
|
|
6302
|
+
const level = result.success ? getCommandLogLevel(cmd) : "warn";
|
|
6303
|
+
logAtLevel(level, "Command", parts.join(" "));
|
|
6304
|
+
}
|
|
6167
6305
|
setAgentStreamManager(manager) {
|
|
6168
6306
|
this._agentStream = manager;
|
|
6169
6307
|
}
|
|
6170
6308
|
// ─── Command Dispatcher ──────────────────────────
|
|
6171
6309
|
async handle(cmd, args) {
|
|
6172
6310
|
this._currentRoute = this.resolveRoute(args);
|
|
6311
|
+
const startedAt = Date.now();
|
|
6312
|
+
this.logCommandStart(cmd, args);
|
|
6313
|
+
let result;
|
|
6173
6314
|
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
6174
6315
|
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
6175
6316
|
if (cdpCommands.includes(cmd)) {
|
|
6176
|
-
|
|
6317
|
+
result = { success: false, error: "No targetSessionId specified \u2014 cannot route command" };
|
|
6318
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
6319
|
+
return result;
|
|
6177
6320
|
}
|
|
6178
6321
|
}
|
|
6179
6322
|
try {
|
|
6180
|
-
|
|
6323
|
+
result = await this.dispatch(cmd, args);
|
|
6324
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
6325
|
+
return result;
|
|
6181
6326
|
} catch (e) {
|
|
6182
6327
|
LOG.error("Command", `[${cmd}] Unhandled error: ${e?.message || e}`);
|
|
6183
|
-
|
|
6328
|
+
result = { success: false, error: `Internal error: ${e?.message || "unknown"}` };
|
|
6329
|
+
this.logCommandEnd(cmd, result, startedAt);
|
|
6330
|
+
return result;
|
|
6184
6331
|
}
|
|
6185
6332
|
}
|
|
6186
6333
|
async dispatch(cmd, args) {
|
|
@@ -10509,7 +10656,13 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
10509
10656
|
status: stream.status || "idle",
|
|
10510
10657
|
activeModal: stream.activeModal || null,
|
|
10511
10658
|
model: stream.model || void 0,
|
|
10512
|
-
mode: stream.mode || void 0
|
|
10659
|
+
mode: stream.mode || void 0,
|
|
10660
|
+
sessionId: stream.sessionId || stream.instanceId || void 0,
|
|
10661
|
+
title: stream.title || stream.agentName || void 0,
|
|
10662
|
+
agentType: stream.agentType || void 0,
|
|
10663
|
+
agentName: stream.agentName || void 0,
|
|
10664
|
+
extensionId: stream.extensionId || void 0,
|
|
10665
|
+
inputContent: stream.inputContent || ""
|
|
10513
10666
|
});
|
|
10514
10667
|
}
|
|
10515
10668
|
}
|
|
@@ -10573,14 +10726,13 @@ var ProviderInstanceManager = class {
|
|
|
10573
10726
|
try {
|
|
10574
10727
|
const state = instance.getState();
|
|
10575
10728
|
states.push(state);
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
providerCategory: state.category
|
|
10729
|
+
this.emitPendingEvents(instance.type, state);
|
|
10730
|
+
if (state.category === "ide") {
|
|
10731
|
+
for (const childState of state.extensions) {
|
|
10732
|
+
this.emitPendingEvents(childState.type, childState, {
|
|
10733
|
+
targetSessionId: childState.instanceId,
|
|
10734
|
+
workspaceName: state.workspace || void 0,
|
|
10735
|
+
parentSessionId: state.instanceId
|
|
10584
10736
|
});
|
|
10585
10737
|
}
|
|
10586
10738
|
}
|
|
@@ -10629,6 +10781,21 @@ var ProviderInstanceManager = class {
|
|
|
10629
10781
|
onEvent(listener) {
|
|
10630
10782
|
this.eventListeners.push(listener);
|
|
10631
10783
|
}
|
|
10784
|
+
emitPendingEvents(providerType, state, extra = {}) {
|
|
10785
|
+
for (const event of state.pendingEvents) {
|
|
10786
|
+
for (const listener of this.eventListeners) {
|
|
10787
|
+
listener({
|
|
10788
|
+
...event,
|
|
10789
|
+
providerType,
|
|
10790
|
+
instanceId: state.instanceId,
|
|
10791
|
+
targetSessionId: state.instanceId,
|
|
10792
|
+
providerCategory: state.category,
|
|
10793
|
+
workspaceName: state.workspace || void 0,
|
|
10794
|
+
...extra
|
|
10795
|
+
});
|
|
10796
|
+
}
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
10632
10799
|
/**
|
|
10633
10800
|
* Forward event to specific Instance
|
|
10634
10801
|
*/
|
|
@@ -14519,7 +14686,7 @@ async function initDaemonComponents(config) {
|
|
|
14519
14686
|
const ideInstance = instanceManager.getInstance(instanceKey);
|
|
14520
14687
|
if (ideInstance) {
|
|
14521
14688
|
instanceManager.removeInstance(instanceKey);
|
|
14522
|
-
LOG.info("
|
|
14689
|
+
LOG.info("IDE", `Instance removed after detach: ${instanceKey}`);
|
|
14523
14690
|
}
|
|
14524
14691
|
if (ideInstance?.getInstanceId) {
|
|
14525
14692
|
agentStreamManager?.resetParentSession(ideInstance.getInstanceId());
|