@adhdev/daemon-core 0.8.69 → 0.8.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/agent-stream/manager.d.ts +2 -1
  2. package/dist/agent-stream/provider-adapter.d.ts +6 -2
  3. package/dist/agent-stream/types.d.ts +5 -2
  4. package/dist/commands/stream-commands.d.ts +2 -1
  5. package/dist/config/recent-activity.d.ts +4 -3
  6. package/dist/index.js +286 -64
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +286 -64
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/providers/contracts.d.ts +10 -0
  11. package/dist/providers/extension-provider-instance.d.ts +1 -0
  12. package/dist/providers/open-panel-support.d.ts +6 -0
  13. package/dist/providers/provider-instance.d.ts +2 -1
  14. package/dist/shared-types.d.ts +1 -1
  15. package/dist/types.d.ts +1 -0
  16. package/node_modules/@adhdev/session-host-core/package.json +2 -2
  17. package/package.json +2 -2
  18. package/src/agent-stream/forward.ts +1 -0
  19. package/src/agent-stream/manager.d.ts +2 -1
  20. package/src/agent-stream/manager.ts +20 -5
  21. package/src/agent-stream/provider-adapter.d.ts +3 -2
  22. package/src/agent-stream/provider-adapter.ts +123 -4
  23. package/src/agent-stream/types.d.ts +3 -2
  24. package/src/agent-stream/types.ts +5 -2
  25. package/src/cli-adapters/provider-cli-adapter.ts +3 -1
  26. package/src/commands/cli-manager.ts +12 -0
  27. package/src/commands/handler.ts +4 -2
  28. package/src/commands/router.ts +1 -0
  29. package/src/commands/stream-commands.d.ts +2 -1
  30. package/src/commands/stream-commands.ts +74 -2
  31. package/src/config/recent-activity.ts +25 -15
  32. package/src/daemon/dev-auto-implement.ts +2 -2
  33. package/src/daemon/dev-server.ts +2 -2
  34. package/src/daemon/scaffold-template.ts +12 -5
  35. package/src/providers/contracts.d.ts +10 -0
  36. package/src/providers/contracts.ts +14 -0
  37. package/src/providers/extension-provider-instance.ts +15 -2
  38. package/src/providers/ide-provider-instance.ts +2 -0
  39. package/src/providers/open-panel-support.ts +40 -0
  40. package/src/providers/provider-instance.d.ts +2 -1
  41. package/src/providers/provider-instance.ts +2 -1
  42. package/src/providers/provider-schema.ts +10 -0
  43. package/src/providers/read-chat-contract.ts +1 -0
  44. package/src/shared-types.d.ts +1 -1
  45. package/src/shared-types.ts +1 -0
  46. package/src/status/builders.ts +9 -23
  47. package/src/status/snapshot.ts +2 -2
  48. package/src/types.ts +1 -0
package/dist/index.mjs CHANGED
@@ -865,6 +865,7 @@ function validateMessage(message, source, index) {
865
865
  if (isFiniteNumber(message.index)) normalized.index = message.index;
866
866
  if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
867
867
  if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
868
+ if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
868
869
  if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
869
870
  if (isPlainObject3(message.meta)) normalized.meta = message.meta;
870
871
  if (typeof message.senderName === "string") normalized.senderName = message.senderName;
@@ -3021,7 +3022,9 @@ ${data.message || ""}`.trim();
3021
3022
  }
3022
3023
  }
3023
3024
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
3024
- if (this.isWaitingForResponse) return;
3025
+ if (this.isWaitingForResponse) {
3026
+ throw new Error(`${this.cliName} is still processing the previous prompt`);
3027
+ }
3025
3028
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
3026
3029
  if (blockingModal || this.currentStatus === "waiting_approval") {
3027
3030
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
@@ -3814,27 +3817,37 @@ function getRecentActivity(state, limit = 20) {
3814
3817
  })
3815
3818
  })).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
3816
3819
  }
3817
- function getSessionSeenAt(state, sessionId) {
3818
- return state.sessionReads?.[sessionId] || 0;
3820
+ function buildSessionReadStateKey(sessionId, providerSessionId) {
3821
+ const normalizedProviderSessionId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
3822
+ if (normalizedProviderSessionId) return `provider:${normalizedProviderSessionId}`;
3823
+ return sessionId;
3824
+ }
3825
+ function getSessionSeenAt(state, sessionId, providerSessionId) {
3826
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
3827
+ return state.sessionReads?.[providerKey] || state.sessionReads?.[sessionId] || 0;
3819
3828
  }
3820
- function getSessionSeenMarker(state, sessionId) {
3821
- return state.sessionReadMarkers?.[sessionId] || "";
3829
+ function getSessionSeenMarker(state, sessionId, providerSessionId) {
3830
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
3831
+ return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
3822
3832
  }
3823
- function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
3833
+ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
3824
3834
  const prev = state.sessionReads || {};
3825
- const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
3826
3835
  const prevMarkers = state.sessionReadMarkers || {};
3827
3836
  const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
3837
+ const readKeys = Array.from(new Set([
3838
+ sessionId,
3839
+ buildSessionReadStateKey(sessionId, providerSessionId)
3840
+ ].filter(Boolean)));
3841
+ const nextSessionReads = { ...prev };
3842
+ const nextSessionReadMarkers = { ...prevMarkers };
3843
+ for (const key of readKeys) {
3844
+ nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
3845
+ if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
3846
+ }
3828
3847
  return {
3829
3848
  ...state,
3830
- sessionReads: {
3831
- ...prev,
3832
- [sessionId]: nextSeenAt
3833
- },
3834
- sessionReadMarkers: nextMarker ? {
3835
- ...prevMarkers,
3836
- [sessionId]: nextMarker
3837
- } : prevMarkers
3849
+ sessionReads: nextSessionReads,
3850
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
3838
3851
  };
3839
3852
  }
3840
3853
 
@@ -6434,6 +6447,39 @@ function resolveProviderStateSurface(params) {
6434
6447
 
6435
6448
  // src/providers/extension-provider-instance.ts
6436
6449
  init_chat_message_normalization();
6450
+
6451
+ // src/providers/open-panel-support.ts
6452
+ var IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
6453
+ "read_chat",
6454
+ "send_message",
6455
+ "new_session",
6456
+ "list_sessions",
6457
+ "switch_session",
6458
+ "resolve_action",
6459
+ "change_model",
6460
+ "set_mode",
6461
+ "set_thought_level"
6462
+ ];
6463
+ var EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE = [
6464
+ "read_chat",
6465
+ "send_message",
6466
+ "new_session",
6467
+ "list_sessions",
6468
+ "switch_session",
6469
+ "resolve_action",
6470
+ "change_model",
6471
+ "set_mode"
6472
+ ];
6473
+ function providerHasOpenPanelSupport(provider) {
6474
+ if (typeof provider.scripts?.openPanel === "function") return true;
6475
+ if (provider.category === "ide" && typeof provider.scripts?.webviewOpenPanel === "function") return true;
6476
+ return false;
6477
+ }
6478
+ function getProviderSessionCapabilities(provider, baseCapabilities) {
6479
+ return providerHasOpenPanelSupport(provider) ? [...baseCapabilities, "open_panel"] : [...baseCapabilities];
6480
+ }
6481
+
6482
+ // src/providers/extension-provider-instance.ts
6437
6483
  var ExtensionProviderInstance = class {
6438
6484
  type;
6439
6485
  category = "extension";
@@ -6459,6 +6505,7 @@ var ExtensionProviderInstance = class {
6459
6505
  instanceId;
6460
6506
  ideType = "";
6461
6507
  chatId = null;
6508
+ providerSessionId = null;
6462
6509
  chatTitle = null;
6463
6510
  agentName = "";
6464
6511
  extensionId = "";
@@ -6492,8 +6539,10 @@ var ExtensionProviderInstance = class {
6492
6539
  name: this.provider.name,
6493
6540
  category: "extension",
6494
6541
  status: this.currentStatus,
6542
+ providerSessionId: this.providerSessionId || this.chatId || void 0,
6543
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE),
6495
6544
  activeChat: this.messages.length > 0 || this.runtimeMessages.length > 0 ? {
6496
- id: this.chatId || this.instanceId,
6545
+ id: this.providerSessionId || this.chatId || this.instanceId,
6497
6546
  title: this.chatTitle || this.agentName || this.provider.name,
6498
6547
  status: this.currentStatus,
6499
6548
  messages: this.mergeConversationMessages(this.messages),
@@ -6523,7 +6572,11 @@ var ExtensionProviderInstance = class {
6523
6572
  });
6524
6573
  this.controlValues = patchedState.controlValues;
6525
6574
  this.summaryMetadata = patchedState.summaryMetadata;
6526
- if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
6575
+ const nextProviderSessionId = typeof data?.providerSessionId === "string" && data.providerSessionId.trim() ? data.providerSessionId.trim() : typeof data?.sessionId === "string" && data.sessionId.trim() ? data.sessionId.trim() : "";
6576
+ if (nextProviderSessionId) {
6577
+ this.providerSessionId = nextProviderSessionId;
6578
+ this.chatId = nextProviderSessionId;
6579
+ }
6527
6580
  if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
6528
6581
  if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
6529
6582
  if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
@@ -6809,6 +6862,7 @@ ${effect.notification.body || ""}`.trim();
6809
6862
  this.controlValues = {};
6810
6863
  this.currentStatus = "idle";
6811
6864
  this.chatId = null;
6865
+ this.providerSessionId = null;
6812
6866
  this.chatTitle = null;
6813
6867
  this.agentName = "";
6814
6868
  this.extensionId = "";
@@ -6963,6 +7017,7 @@ var IdeProviderInstance = class {
6963
7017
  workspace: this.workspace || null,
6964
7018
  extensions: extensionStates,
6965
7019
  cdpConnected: cdp?.isConnected || false,
7020
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, IDE_PROVIDER_SESSION_CAPABILITIES_BASE),
6966
7021
  controlValues: surface.controlValues,
6967
7022
  providerControls: this.provider.controls,
6968
7023
  summaryMetadata: surface.summaryMetadata,
@@ -7989,27 +8044,8 @@ function isCdpConnected(cdpManagers, key) {
7989
8044
  }
7990
8045
  return false;
7991
8046
  }
7992
- var IDE_SESSION_CAPABILITIES = [
7993
- "read_chat",
7994
- "send_message",
7995
- "new_session",
7996
- "list_sessions",
7997
- "switch_session",
7998
- "resolve_action",
7999
- "change_model",
8000
- "set_mode",
8001
- "set_thought_level"
8002
- ];
8003
- var EXTENSION_SESSION_CAPABILITIES = [
8004
- "read_chat",
8005
- "send_message",
8006
- "new_session",
8007
- "list_sessions",
8008
- "switch_session",
8009
- "resolve_action",
8010
- "change_model",
8011
- "set_mode"
8012
- ];
8047
+ var IDE_SESSION_CAPABILITIES = [...IDE_PROVIDER_SESSION_CAPABILITIES_BASE];
8048
+ var EXTENSION_SESSION_CAPABILITIES = [...EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE];
8013
8049
  var PTY_SESSION_CAPABILITIES = [
8014
8050
  "read_chat",
8015
8051
  "send_message",
@@ -8053,7 +8089,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
8053
8089
  ...includeSessionMetadata && { workspace: state.workspace || null },
8054
8090
  activeChat,
8055
8091
  ...summaryMetadata && { summaryMetadata },
8056
- ...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
8092
+ ...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
8057
8093
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
8058
8094
  ...includeSessionControls && {
8059
8095
  ...controlValues && { controlValues },
@@ -8076,6 +8112,7 @@ function buildExtensionAgentSession(parent, ext, options) {
8076
8112
  parentId: parent.instanceId || parent.type,
8077
8113
  providerType: ext.type,
8078
8114
  ...includeSessionMetadata && { providerName: ext.name },
8115
+ providerSessionId: ext.providerSessionId,
8079
8116
  kind: "agent",
8080
8117
  transport: "cdp-webview",
8081
8118
  status: normalizeManagedStatus(activeChat?.status || ext.status, {
@@ -8085,7 +8122,7 @@ function buildExtensionAgentSession(parent, ext, options) {
8085
8122
  ...includeSessionMetadata && { workspace: parent.workspace || null },
8086
8123
  activeChat,
8087
8124
  ...summaryMetadata && { summaryMetadata },
8088
- ...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
8125
+ ...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
8089
8126
  ...includeSessionControls && {
8090
8127
  ...controlValues && { controlValues },
8091
8128
  providerControls: ext.providerControls
@@ -10003,13 +10040,75 @@ function getCliPresentationMode(h, targetSessionId) {
10003
10040
  const mode = instance.getPresentationMode?.();
10004
10041
  return mode === "chat" || mode === "terminal" ? mode : null;
10005
10042
  }
10006
- async function handleFocusSession(h, args) {
10043
+ function normalizeOpenPanelCommandResult(result) {
10044
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
10045
+ if (payload === true) return { opened: true, visible: true, focused: false };
10046
+ if (!payload) return { opened: false, visible: false, focused: false };
10047
+ if (typeof payload === "string") {
10048
+ const normalized = payload.trim().toLowerCase();
10049
+ if (normalized === "visible") return { opened: false, visible: true, focused: false };
10050
+ if (normalized === "focused") return { opened: false, visible: true, focused: true };
10051
+ if (normalized === "opened" || normalized === "open" || normalized === "true" || normalized === "ok" || normalized === "success") {
10052
+ return { opened: true, visible: true, focused: false };
10053
+ }
10054
+ return { opened: false, visible: false, focused: false };
10055
+ }
10056
+ if (typeof payload === "object") {
10057
+ const record = payload;
10058
+ return {
10059
+ opened: record.opened === true,
10060
+ visible: record.visible === true || record.opened === true || record.focused === true,
10061
+ focused: record.focused === true
10062
+ };
10063
+ }
10064
+ return { opened: false, visible: false, focused: false };
10065
+ }
10066
+ function normalizeFocusEditorCommandResult(result) {
10067
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
10068
+ if (payload === true) return { focused: true };
10069
+ if (!payload) return { focused: false };
10070
+ if (typeof payload === "string") {
10071
+ const normalized = payload.trim().toLowerCase();
10072
+ return { focused: normalized === "focused" || normalized === "visible" || normalized === "true" || normalized === "ok" || normalized === "success" };
10073
+ }
10074
+ if (typeof payload === "object") {
10075
+ const record = payload;
10076
+ return { focused: record.focused === true || record.visible === true || record.success === true || record.ok === true };
10077
+ }
10078
+ return { focused: false };
10079
+ }
10080
+ async function handleSelectSession(h, args) {
10007
10081
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
10008
10082
  const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
10009
10083
  if (!sessionId) return { success: false, error: "targetSessionId required" };
10010
- const ok = await h.agentStream.focusSession(h.getCdp(), sessionId);
10084
+ const ok = await h.agentStream.selectSession(h.getCdp(), sessionId);
10011
10085
  return { success: ok };
10012
10086
  }
10087
+ async function handleOpenPanel(h, args) {
10088
+ const cdp = h.getCdp();
10089
+ if (!cdp) return { success: false, error: "AgentStream or CDP not available" };
10090
+ const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
10091
+ if (!sessionId) return { success: false, error: "targetSessionId required" };
10092
+ const currentTransport = h.currentSession?.transport;
10093
+ const shouldUseAgentStream = !!h.agentStream && currentTransport !== "cdp-page" && currentTransport !== "pty" && currentTransport !== "acp";
10094
+ if (shouldUseAgentStream) {
10095
+ const ok = await h.agentStream.openSessionPanel(cdp, sessionId);
10096
+ return { success: ok };
10097
+ }
10098
+ const openResult = await executeProviderScript(h, args, "openPanel");
10099
+ if (!openResult.success) return openResult;
10100
+ const revealState = normalizeOpenPanelCommandResult(openResult);
10101
+ let focusState = { focused: false };
10102
+ const focusResult = await executeProviderScript(h, args, "focusEditor");
10103
+ if (focusResult.success) {
10104
+ focusState = normalizeFocusEditorCommandResult(focusResult);
10105
+ }
10106
+ return {
10107
+ ...openResult,
10108
+ ...focusState.focused ? { focused: true } : {},
10109
+ success: revealState.visible || focusState.focused
10110
+ };
10111
+ }
10013
10112
  function handlePtyInput(h, args) {
10014
10113
  const { cliType, data, targetSessionId } = args || {};
10015
10114
  if (!data) return { success: false, error: "data required" };
@@ -10699,7 +10798,8 @@ var DaemonCommandHandler = class {
10699
10798
  "change_model",
10700
10799
  "set_thought_level",
10701
10800
  "resolve_action",
10702
- "focus_session",
10801
+ "select_session",
10802
+ "open_panel",
10703
10803
  "pty_input",
10704
10804
  "pty_resize",
10705
10805
  "invoke_provider_script"
@@ -10797,8 +10897,10 @@ var DaemonCommandHandler = class {
10797
10897
  case "refresh_scripts":
10798
10898
  return this.handleRefreshScripts(args);
10799
10899
  // ─── Stream commands (stream-commands.ts) ───────────
10800
- case "focus_session":
10801
- return handleFocusSession(this, args);
10900
+ case "select_session":
10901
+ return handleSelectSession(this, args);
10902
+ case "open_panel":
10903
+ return handleOpenPanel(this, args);
10802
10904
  // ─── PTY Raw I/O (stream-commands.ts) ─────────
10803
10905
  case "pty_input":
10804
10906
  return handlePtyInput(this, args);
@@ -13500,6 +13602,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
13500
13602
  if (!cliType) throw new Error("cliType required");
13501
13603
  const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
13502
13604
  if (found) {
13605
+ if (!args?.targetSessionId && !dir) {
13606
+ const matchCount = [...this.adapters.values()].filter((a) => a.cliType === cliType).length;
13607
+ if (matchCount > 1) {
13608
+ return {
13609
+ success: false,
13610
+ error: `Multiple ${cliType} sessions running \u2014 provide targetSessionId to stop a specific session`,
13611
+ code: "AMBIGUOUS_SESSION"
13612
+ };
13613
+ }
13614
+ }
13503
13615
  await this.stopSessionWithMode(found.key, mode);
13504
13616
  } else {
13505
13617
  console.log(colorize("yellow", ` \u26A0 No adapter found for ${cliType}`));
@@ -13681,6 +13793,7 @@ function validateProviderDefinition(raw) {
13681
13793
  warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
13682
13794
  }
13683
13795
  const category = provider.category;
13796
+ const typedProvider = provider;
13684
13797
  const controls = Array.isArray(provider.controls) ? provider.controls : [];
13685
13798
  if (category === "cli" || category === "acp") {
13686
13799
  const spawn4 = provider.spawn;
@@ -13703,6 +13816,9 @@ function validateProviderDefinition(raw) {
13703
13816
  for (const control of controls) {
13704
13817
  validateControl(control, errors);
13705
13818
  }
13819
+ if ((category === "ide" || category === "extension") && typeof typedProvider.scripts?.focusEditor === "function" && !providerHasOpenPanelSupport(typedProvider)) {
13820
+ warnings.push("scripts.focusEditor is present without scripts.openPanel/webviewOpenPanel; open_panel capability will remain disabled");
13821
+ }
13706
13822
  return { errors, warnings };
13707
13823
  }
13708
13824
  function validateCapabilities(provider, controls, errors) {
@@ -15778,8 +15894,8 @@ function buildStatusSnapshot(options) {
15778
15894
  for (const sourceSession of unreadSourceSessions) {
15779
15895
  const session = sessionsById.get(sourceSession.id);
15780
15896
  if (!session) continue;
15781
- const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
15782
- const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
15897
+ const lastSeenAt = getSessionSeenAt(state, sourceSession.id, sourceSession.providerSessionId);
15898
+ const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id, sourceSession.providerSessionId);
15783
15899
  const lastUsedAt = getSessionLastUsedAt(sourceSession);
15784
15900
  const completionMarker = getSessionCompletionMarker(sourceSession);
15785
15901
  const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
@@ -16595,7 +16711,8 @@ var DaemonCommandRouter = class {
16595
16711
  currentState,
16596
16712
  sessionId,
16597
16713
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
16598
- completionMarker
16714
+ completionMarker,
16715
+ targetSession?.providerSessionId
16599
16716
  );
16600
16717
  if (READ_DEBUG_ENABLED2) {
16601
16718
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
@@ -17028,6 +17145,77 @@ var ProviderStreamAdapter = class {
17028
17145
  return raw;
17029
17146
  }
17030
17147
  }
17148
+ getOptionalError(raw) {
17149
+ return typeof raw === "string" && raw.trim() ? raw.trim() : void 0;
17150
+ }
17151
+ normalizeFocusEditorResult(raw) {
17152
+ const data = this.parseMaybeJson(raw);
17153
+ if (data === true) return { focused: true };
17154
+ if (data === false || data == null) return { focused: false };
17155
+ if (typeof data === "string") {
17156
+ const trimmed = data.trim();
17157
+ const normalized = trimmed.toLowerCase();
17158
+ if (normalized === "true" || normalized === "ok" || normalized === "success" || normalized === "focused" || normalized === "visible") {
17159
+ return { focused: true };
17160
+ }
17161
+ if (normalized === "false" || normalized === "not_found" || normalized === "not found" || normalized === "missing" || normalized === "panel_hidden" || normalized === "hidden") {
17162
+ return { focused: false };
17163
+ }
17164
+ return { focused: false, ...trimmed ? { error: trimmed } : {} };
17165
+ }
17166
+ if (data && typeof data === "object") {
17167
+ const error = this.getOptionalError(data.error);
17168
+ if (data.focused === true || data.success === true || data.ok === true || data.visible === true) {
17169
+ return { focused: true };
17170
+ }
17171
+ if (data.focused === false || data.success === false || data.ok === false || error) {
17172
+ return { focused: false, ...error ? { error } : {} };
17173
+ }
17174
+ }
17175
+ return { focused: false };
17176
+ }
17177
+ normalizeOpenPanelResult(raw) {
17178
+ const data = this.parseMaybeJson(raw);
17179
+ if (data === true) return { opened: true, visible: true };
17180
+ if (data === false || data == null) return { opened: false, visible: false };
17181
+ if (typeof data === "string") {
17182
+ const trimmed = data.trim();
17183
+ const normalized = trimmed.toLowerCase();
17184
+ if (normalized === "true" || normalized === "ok" || normalized === "opened" || normalized === "open" || normalized === "success") {
17185
+ return { opened: true, visible: true };
17186
+ }
17187
+ if (normalized === "visible") {
17188
+ return { opened: false, visible: true };
17189
+ }
17190
+ if (normalized === "focused") {
17191
+ return { opened: false, visible: true, focused: true };
17192
+ }
17193
+ if (normalized === "false" || normalized === "panel_hidden" || normalized === "hidden" || normalized === "not_found" || normalized === "not found" || normalized === "missing") {
17194
+ return { opened: false, visible: false };
17195
+ }
17196
+ return { opened: false, visible: false, ...trimmed ? { error: trimmed } : {} };
17197
+ }
17198
+ if (data && typeof data === "object") {
17199
+ const error = this.getOptionalError(data.error);
17200
+ const focused = data.focused === true;
17201
+ const visible = data.visible === true || data.opened === true || focused || data.success === true || data.ok === true;
17202
+ if (visible) {
17203
+ return {
17204
+ opened: data.opened === true,
17205
+ visible: true,
17206
+ ...focused ? { focused: true } : {}
17207
+ };
17208
+ }
17209
+ if (data.opened === false || data.visible === false || data.success === false || data.ok === false || error) {
17210
+ return {
17211
+ opened: false,
17212
+ visible: false,
17213
+ ...error ? { error } : {}
17214
+ };
17215
+ }
17216
+ }
17217
+ return { opened: false, visible: false };
17218
+ }
17031
17219
  summarizeRaw(raw) {
17032
17220
  try {
17033
17221
  if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
@@ -17114,6 +17302,11 @@ var ProviderStreamAdapter = class {
17114
17302
  if (typeof validated.title === "string" && validated.title.trim()) {
17115
17303
  state.title = validated.title.trim();
17116
17304
  }
17305
+ const providerSessionId = typeof validated.providerSessionId === "string" && validated.providerSessionId.trim() ? validated.providerSessionId.trim() : "";
17306
+ if (providerSessionId) {
17307
+ state.sessionId = providerSessionId;
17308
+ state.providerSessionId = providerSessionId;
17309
+ }
17117
17310
  const controlValues = extractProviderControlValues(this.provider.controls, validated);
17118
17311
  const surface = resolveProviderStateSurface({
17119
17312
  controlValues,
@@ -17236,8 +17429,15 @@ var ProviderStreamAdapter = class {
17236
17429
  }
17237
17430
  async focusEditor(evaluate) {
17238
17431
  const script = this.callScript("focusEditor");
17239
- if (!script) return;
17240
- await evaluate(script);
17432
+ if (!script) return { focused: false };
17433
+ const raw = await evaluate(script);
17434
+ return this.normalizeFocusEditorResult(raw);
17435
+ }
17436
+ async openPanel(evaluate) {
17437
+ const script = this.callScript("openPanel");
17438
+ if (!script) return { opened: false, visible: false };
17439
+ const raw = await evaluate(script);
17440
+ return this.normalizeOpenPanelResult(raw);
17241
17441
  }
17242
17442
  errorState(message) {
17243
17443
  return {
@@ -17507,19 +17707,33 @@ var DaemonAgentStreamManager = class {
17507
17707
  return false;
17508
17708
  }
17509
17709
  }
17510
- async focusSession(cdp, sessionId) {
17710
+ async selectSession(cdp, sessionId) {
17511
17711
  const target = this.getSessionTarget(sessionId);
17512
17712
  if (!target?.parentSessionId) return false;
17513
17713
  await this.setActiveSession(cdp, target.parentSessionId, sessionId);
17514
17714
  await this.syncActiveSession(cdp, target.parentSessionId);
17715
+ return this.managedBySessionId.has(sessionId);
17716
+ }
17717
+ async openSessionPanel(cdp, sessionId) {
17718
+ const selected = await this.selectSession(cdp, sessionId);
17719
+ if (!selected) return false;
17515
17720
  const agent = this.managedBySessionId.get(sessionId);
17516
- if (!agent || typeof agent.adapter.focusEditor !== "function") return false;
17721
+ if (!agent) return false;
17722
+ let panelVisible = false;
17723
+ let editorFocused = false;
17517
17724
  try {
17518
17725
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
17519
- await agent.adapter.focusEditor(evaluate);
17520
- return true;
17726
+ if (typeof agent.adapter.openPanel === "function") {
17727
+ const result = await agent.adapter.openPanel(evaluate);
17728
+ panelVisible = result.visible;
17729
+ }
17730
+ if (typeof agent.adapter.focusEditor === "function") {
17731
+ const result = await agent.adapter.focusEditor(evaluate);
17732
+ editorFocused = result.focused;
17733
+ }
17734
+ return panelVisible || editorFocused;
17521
17735
  } catch (e) {
17522
- this.logFn(`[AgentStream] focusEditor(${sessionId}) error: ${e.message}`);
17736
+ this.logFn(`[AgentStream] openPanel(${sessionId}) error: ${e.message}`);
17523
17737
  return false;
17524
17738
  }
17525
17739
  }
@@ -17745,6 +17959,7 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
17745
17959
  summaryMetadata: stream.summaryMetadata || void 0,
17746
17960
  effects: stream.effects || void 0,
17747
17961
  sessionId: stream.sessionId || stream.instanceId || void 0,
17962
+ providerSessionId: stream.providerSessionId || stream.sessionId || void 0,
17748
17963
  title: stream.title || stream.agentName || void 0,
17749
17964
  agentType: stream.agentType || void 0,
17750
17965
  agentName: stream.agentName || void 0,
@@ -18397,9 +18612,14 @@ module.exports.setMode = (params) => {
18397
18612
  (() => {
18398
18613
  try {
18399
18614
  const input = document.querySelector('${meta.inputSelector || '[contenteditable="true"]'}');
18400
- if (input) { input.focus(); return 'focused'; }
18401
- return 'not_found';
18402
- } catch(e) { return 'error'; }
18615
+ if (input) {
18616
+ input.focus();
18617
+ return JSON.stringify({ focused: true });
18618
+ }
18619
+ return JSON.stringify({ focused: false, error: 'not_found' });
18620
+ } catch(e) {
18621
+ return JSON.stringify({ focused: false, error: e.message });
18622
+ }
18403
18623
  })()
18404
18624
  `;
18405
18625
  files[`${scriptDir}/open_panel.js`] = `/**
@@ -18410,8 +18630,10 @@ module.exports.setMode = (params) => {
18410
18630
  (() => {
18411
18631
  try {
18412
18632
  // TODO: Check if panel visible, if not find toggle button
18413
- return 'not_found';
18414
- } catch(e) { return 'error'; }
18633
+ return JSON.stringify({ opened: false, visible: false, error: 'not_found' });
18634
+ } catch(e) {
18635
+ return JSON.stringify({ opened: false, visible: false, error: e.message });
18636
+ }
18415
18637
  })()
18416
18638
  `;
18417
18639
  files[`${scriptDir}/resolve_action.js`] = `/**
@@ -21223,8 +21445,8 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
21223
21445
  lines.push("| setModel | `{ success: true/false }` |");
21224
21446
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
21225
21447
  lines.push("| setMode | `{ success: true/false }` |");
21226
- lines.push("| focusEditor | `{ focused: true/false }` |");
21227
- lines.push("| openPanel | `{ opened: true/false }` |");
21448
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
21449
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
21228
21450
  lines.push("");
21229
21451
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
21230
21452
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
@@ -22858,8 +23080,8 @@ var DevServer = class _DevServer {
22858
23080
  lines.push("| setModel | `{ success: true/false }` |");
22859
23081
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
22860
23082
  lines.push("| setMode | `{ success: true/false }` |");
22861
- lines.push("| focusEditor | `{ focused: true/false }` |");
22862
- lines.push("| openPanel | `{ opened: true/false }` |");
23083
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
23084
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
22863
23085
  lines.push("");
22864
23086
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
22865
23087
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");