@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.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: `${this.type}_session`,
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("CDP", `Connected: ${ide} (port ${port})`);
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("CDP", `Connected: ${managerKey} (port ${port}, page "${target.title}")`);
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("CDP", `${cdpManagers.size} IDE(s) connected: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(", ")}`);
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("CDP", `No IDEs connected \u2014 tried: ${filtered.map((p) => `${p.ide}:${p.port}`).join(", ")}`);
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("CDP", `Connected: ${ide} (port ${port})`);
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("CDP", `Connected: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ""})`);
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("CDP", `Removed stale manager: ${key} (${reason})`);
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
- return { success: false, error: "No targetSessionId specified \u2014 cannot route command" };
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
- return await this.dispatch(cmd, args);
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
- return { success: false, error: `Internal error: ${e?.message || "unknown"}` };
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
- for (const event of state.pendingEvents) {
10577
- for (const listener of this.eventListeners) {
10578
- listener({
10579
- ...event,
10580
- providerType: instance.type,
10581
- instanceId: state.instanceId,
10582
- targetSessionId: state.instanceId,
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("CDP", `Instance removed after disconnect: ${instanceKey}`);
14689
+ LOG.info("IDE", `Instance removed after detach: ${instanceKey}`);
14523
14690
  }
14524
14691
  if (ideInstance?.getInstanceId) {
14525
14692
  agentStreamManager?.resetParentSession(ideInstance.getInstanceId());