adhdev 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.
package/dist/cli/index.js CHANGED
@@ -1049,27 +1049,37 @@ function getRecentActivity(state, limit = 20) {
1049
1049
  })
1050
1050
  })).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
1051
1051
  }
1052
- function getSessionSeenAt(state, sessionId) {
1053
- return state.sessionReads?.[sessionId] || 0;
1052
+ function buildSessionReadStateKey(sessionId, providerSessionId) {
1053
+ const normalizedProviderSessionId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
1054
+ if (normalizedProviderSessionId) return `provider:${normalizedProviderSessionId}`;
1055
+ return sessionId;
1054
1056
  }
1055
- function getSessionSeenMarker(state, sessionId) {
1056
- return state.sessionReadMarkers?.[sessionId] || "";
1057
+ function getSessionSeenAt(state, sessionId, providerSessionId) {
1058
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
1059
+ return state.sessionReads?.[providerKey] || state.sessionReads?.[sessionId] || 0;
1057
1060
  }
1058
- function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
1061
+ function getSessionSeenMarker(state, sessionId, providerSessionId) {
1062
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
1063
+ return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
1064
+ }
1065
+ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
1059
1066
  const prev = state.sessionReads || {};
1060
- const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
1061
1067
  const prevMarkers = state.sessionReadMarkers || {};
1062
1068
  const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
1069
+ const readKeys = Array.from(new Set([
1070
+ sessionId,
1071
+ buildSessionReadStateKey(sessionId, providerSessionId)
1072
+ ].filter(Boolean)));
1073
+ const nextSessionReads = { ...prev };
1074
+ const nextSessionReadMarkers = { ...prevMarkers };
1075
+ for (const key of readKeys) {
1076
+ nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
1077
+ if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
1078
+ }
1063
1079
  return {
1064
1080
  ...state,
1065
- sessionReads: {
1066
- ...prev,
1067
- [sessionId]: nextSeenAt
1068
- },
1069
- sessionReadMarkers: nextMarker ? {
1070
- ...prevMarkers,
1071
- [sessionId]: nextMarker
1072
- } : prevMarkers
1081
+ sessionReads: nextSessionReads,
1082
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
1073
1083
  };
1074
1084
  }
1075
1085
  var path2, MAX_ACTIVITY;
@@ -4334,6 +4344,43 @@ var init_provider_patch_state = __esm({
4334
4344
  }
4335
4345
  });
4336
4346
 
4347
+ // ../../oss/packages/daemon-core/src/providers/open-panel-support.ts
4348
+ function providerHasOpenPanelSupport(provider) {
4349
+ if (typeof provider.scripts?.openPanel === "function") return true;
4350
+ if (provider.category === "ide" && typeof provider.scripts?.webviewOpenPanel === "function") return true;
4351
+ return false;
4352
+ }
4353
+ function getProviderSessionCapabilities(provider, baseCapabilities) {
4354
+ return providerHasOpenPanelSupport(provider) ? [...baseCapabilities, "open_panel"] : [...baseCapabilities];
4355
+ }
4356
+ var IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE;
4357
+ var init_open_panel_support = __esm({
4358
+ "../../oss/packages/daemon-core/src/providers/open-panel-support.ts"() {
4359
+ "use strict";
4360
+ IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
4361
+ "read_chat",
4362
+ "send_message",
4363
+ "new_session",
4364
+ "list_sessions",
4365
+ "switch_session",
4366
+ "resolve_action",
4367
+ "change_model",
4368
+ "set_mode",
4369
+ "set_thought_level"
4370
+ ];
4371
+ EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE = [
4372
+ "read_chat",
4373
+ "send_message",
4374
+ "new_session",
4375
+ "list_sessions",
4376
+ "switch_session",
4377
+ "resolve_action",
4378
+ "change_model",
4379
+ "set_mode"
4380
+ ];
4381
+ }
4382
+ });
4383
+
4337
4384
  // ../../oss/packages/daemon-core/src/providers/extension-provider-instance.ts
4338
4385
  var ExtensionProviderInstance;
4339
4386
  var init_extension_provider_instance = __esm({
@@ -4345,6 +4392,7 @@ var init_extension_provider_instance = __esm({
4345
4392
  init_chat_history();
4346
4393
  init_provider_patch_state();
4347
4394
  init_chat_message_normalization();
4395
+ init_open_panel_support();
4348
4396
  ExtensionProviderInstance = class {
4349
4397
  type;
4350
4398
  category = "extension";
@@ -4370,6 +4418,7 @@ var init_extension_provider_instance = __esm({
4370
4418
  instanceId;
4371
4419
  ideType = "";
4372
4420
  chatId = null;
4421
+ providerSessionId = null;
4373
4422
  chatTitle = null;
4374
4423
  agentName = "";
4375
4424
  extensionId = "";
@@ -4403,8 +4452,10 @@ var init_extension_provider_instance = __esm({
4403
4452
  name: this.provider.name,
4404
4453
  category: "extension",
4405
4454
  status: this.currentStatus,
4455
+ providerSessionId: this.providerSessionId || this.chatId || void 0,
4456
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE),
4406
4457
  activeChat: this.messages.length > 0 || this.runtimeMessages.length > 0 ? {
4407
- id: this.chatId || this.instanceId,
4458
+ id: this.providerSessionId || this.chatId || this.instanceId,
4408
4459
  title: this.chatTitle || this.agentName || this.provider.name,
4409
4460
  status: this.currentStatus,
4410
4461
  messages: this.mergeConversationMessages(this.messages),
@@ -4434,7 +4485,11 @@ var init_extension_provider_instance = __esm({
4434
4485
  });
4435
4486
  this.controlValues = patchedState.controlValues;
4436
4487
  this.summaryMetadata = patchedState.summaryMetadata;
4437
- if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
4488
+ const nextProviderSessionId = typeof data?.providerSessionId === "string" && data.providerSessionId.trim() ? data.providerSessionId.trim() : typeof data?.sessionId === "string" && data.sessionId.trim() ? data.sessionId.trim() : "";
4489
+ if (nextProviderSessionId) {
4490
+ this.providerSessionId = nextProviderSessionId;
4491
+ this.chatId = nextProviderSessionId;
4492
+ }
4438
4493
  if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
4439
4494
  if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
4440
4495
  if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
@@ -4720,6 +4775,7 @@ ${effect.notification.body || ""}`.trim();
4720
4775
  this.controlValues = {};
4721
4776
  this.currentStatus = "idle";
4722
4777
  this.chatId = null;
4778
+ this.providerSessionId = null;
4723
4779
  this.chatTitle = null;
4724
4780
  this.agentName = "";
4725
4781
  this.extensionId = "";
@@ -4768,6 +4824,7 @@ function validateMessage(message, source, index) {
4768
4824
  if (isFiniteNumber(message.index)) normalized.index = message.index;
4769
4825
  if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
4770
4826
  if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
4827
+ if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
4771
4828
  if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
4772
4829
  if (isPlainObject3(message.meta)) normalized.meta = message.meta;
4773
4830
  if (typeof message.senderName === "string") normalized.senderName = message.senderName;
@@ -4922,6 +4979,7 @@ var init_ide_provider_instance = __esm({
4922
4979
  init_approval_utils();
4923
4980
  init_provider_patch_state();
4924
4981
  init_chat_message_normalization();
4982
+ init_open_panel_support();
4925
4983
  IdeProviderInstance = class {
4926
4984
  type;
4927
4985
  category = "ide";
@@ -5014,6 +5072,7 @@ var init_ide_provider_instance = __esm({
5014
5072
  workspace: this.workspace || null,
5015
5073
  extensions: extensionStates,
5016
5074
  cdpConnected: cdp?.isConnected || false,
5075
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, IDE_PROVIDER_SESSION_CAPABILITIES_BASE),
5017
5076
  controlValues: surface.controlValues,
5018
5077
  providerControls: this.provider.controls,
5019
5078
  summaryMetadata: surface.summaryMetadata,
@@ -6094,7 +6153,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
6094
6153
  ...includeSessionMetadata && { workspace: state.workspace || null },
6095
6154
  activeChat,
6096
6155
  ...summaryMetadata && { summaryMetadata },
6097
- ...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
6156
+ ...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
6098
6157
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
6099
6158
  ...includeSessionControls && {
6100
6159
  ...controlValues && { controlValues },
@@ -6117,6 +6176,7 @@ function buildExtensionAgentSession(parent, ext, options) {
6117
6176
  parentId: parent.instanceId || parent.type,
6118
6177
  providerType: ext.type,
6119
6178
  ...includeSessionMetadata && { providerName: ext.name },
6179
+ providerSessionId: ext.providerSessionId,
6120
6180
  kind: "agent",
6121
6181
  transport: "cdp-webview",
6122
6182
  status: normalizeManagedStatus(activeChat?.status || ext.status, {
@@ -6126,7 +6186,7 @@ function buildExtensionAgentSession(parent, ext, options) {
6126
6186
  ...includeSessionMetadata && { workspace: parent.workspace || null },
6127
6187
  activeChat,
6128
6188
  ...summaryMetadata && { summaryMetadata },
6129
- ...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
6189
+ ...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
6130
6190
  ...includeSessionControls && {
6131
6191
  ...controlValues && { controlValues },
6132
6192
  providerControls: ext.providerControls
@@ -6245,27 +6305,9 @@ var init_builders = __esm({
6245
6305
  init_normalize();
6246
6306
  init_provider_patch_state();
6247
6307
  init_summary_metadata();
6248
- IDE_SESSION_CAPABILITIES = [
6249
- "read_chat",
6250
- "send_message",
6251
- "new_session",
6252
- "list_sessions",
6253
- "switch_session",
6254
- "resolve_action",
6255
- "change_model",
6256
- "set_mode",
6257
- "set_thought_level"
6258
- ];
6259
- EXTENSION_SESSION_CAPABILITIES = [
6260
- "read_chat",
6261
- "send_message",
6262
- "new_session",
6263
- "list_sessions",
6264
- "switch_session",
6265
- "resolve_action",
6266
- "change_model",
6267
- "set_mode"
6268
- ];
6308
+ init_open_panel_support();
6309
+ IDE_SESSION_CAPABILITIES = [...IDE_PROVIDER_SESSION_CAPABILITIES_BASE];
6310
+ EXTENSION_SESSION_CAPABILITIES = [...EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE];
6269
6311
  PTY_SESSION_CAPABILITIES = [
6270
6312
  "read_chat",
6271
6313
  "send_message",
@@ -8133,13 +8175,75 @@ function getCliPresentationMode(h, targetSessionId) {
8133
8175
  const mode = instance.getPresentationMode?.();
8134
8176
  return mode === "chat" || mode === "terminal" ? mode : null;
8135
8177
  }
8136
- async function handleFocusSession(h, args) {
8178
+ function normalizeOpenPanelCommandResult(result) {
8179
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
8180
+ if (payload === true) return { opened: true, visible: true, focused: false };
8181
+ if (!payload) return { opened: false, visible: false, focused: false };
8182
+ if (typeof payload === "string") {
8183
+ const normalized = payload.trim().toLowerCase();
8184
+ if (normalized === "visible") return { opened: false, visible: true, focused: false };
8185
+ if (normalized === "focused") return { opened: false, visible: true, focused: true };
8186
+ if (normalized === "opened" || normalized === "open" || normalized === "true" || normalized === "ok" || normalized === "success") {
8187
+ return { opened: true, visible: true, focused: false };
8188
+ }
8189
+ return { opened: false, visible: false, focused: false };
8190
+ }
8191
+ if (typeof payload === "object") {
8192
+ const record2 = payload;
8193
+ return {
8194
+ opened: record2.opened === true,
8195
+ visible: record2.visible === true || record2.opened === true || record2.focused === true,
8196
+ focused: record2.focused === true
8197
+ };
8198
+ }
8199
+ return { opened: false, visible: false, focused: false };
8200
+ }
8201
+ function normalizeFocusEditorCommandResult(result) {
8202
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
8203
+ if (payload === true) return { focused: true };
8204
+ if (!payload) return { focused: false };
8205
+ if (typeof payload === "string") {
8206
+ const normalized = payload.trim().toLowerCase();
8207
+ return { focused: normalized === "focused" || normalized === "visible" || normalized === "true" || normalized === "ok" || normalized === "success" };
8208
+ }
8209
+ if (typeof payload === "object") {
8210
+ const record2 = payload;
8211
+ return { focused: record2.focused === true || record2.visible === true || record2.success === true || record2.ok === true };
8212
+ }
8213
+ return { focused: false };
8214
+ }
8215
+ async function handleSelectSession(h, args) {
8137
8216
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
8138
8217
  const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
8139
8218
  if (!sessionId) return { success: false, error: "targetSessionId required" };
8140
- const ok = await h.agentStream.focusSession(h.getCdp(), sessionId);
8219
+ const ok = await h.agentStream.selectSession(h.getCdp(), sessionId);
8141
8220
  return { success: ok };
8142
8221
  }
8222
+ async function handleOpenPanel(h, args) {
8223
+ const cdp = h.getCdp();
8224
+ if (!cdp) return { success: false, error: "AgentStream or CDP not available" };
8225
+ const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
8226
+ if (!sessionId) return { success: false, error: "targetSessionId required" };
8227
+ const currentTransport = h.currentSession?.transport;
8228
+ const shouldUseAgentStream = !!h.agentStream && currentTransport !== "cdp-page" && currentTransport !== "pty" && currentTransport !== "acp";
8229
+ if (shouldUseAgentStream) {
8230
+ const ok = await h.agentStream.openSessionPanel(cdp, sessionId);
8231
+ return { success: ok };
8232
+ }
8233
+ const openResult = await executeProviderScript(h, args, "openPanel");
8234
+ if (!openResult.success) return openResult;
8235
+ const revealState = normalizeOpenPanelCommandResult(openResult);
8236
+ let focusState = { focused: false };
8237
+ const focusResult = await executeProviderScript(h, args, "focusEditor");
8238
+ if (focusResult.success) {
8239
+ focusState = normalizeFocusEditorCommandResult(focusResult);
8240
+ }
8241
+ return {
8242
+ ...openResult,
8243
+ ...focusState.focused ? { focused: true } : {},
8244
+ success: revealState.visible || focusState.focused
8245
+ };
8246
+ }
8143
8247
  function handlePtyInput(h, args) {
8144
8248
  const { cliType, data, targetSessionId } = args || {};
8145
8249
  if (!data) return { success: false, error: "data required" };
@@ -8858,7 +8962,8 @@ var init_handler = __esm({
8858
8962
  "change_model",
8859
8963
  "set_thought_level",
8860
8964
  "resolve_action",
8861
- "focus_session",
8965
+ "select_session",
8966
+ "open_panel",
8862
8967
  "pty_input",
8863
8968
  "pty_resize",
8864
8969
  "invoke_provider_script"
@@ -8956,8 +9061,10 @@ var init_handler = __esm({
8956
9061
  case "refresh_scripts":
8957
9062
  return this.handleRefreshScripts(args);
8958
9063
  // ─── Stream commands (stream-commands.ts) ───────────
8959
- case "focus_session":
8960
- return handleFocusSession(this, args);
9064
+ case "select_session":
9065
+ return handleSelectSession(this, args);
9066
+ case "open_panel":
9067
+ return handleOpenPanel(this, args);
8961
9068
  // ─── PTY Raw I/O (stream-commands.ts) ─────────
8962
9069
  case "pty_input":
8963
9070
  return handlePtyInput(this, args);
@@ -12307,7 +12414,9 @@ ${data.message || ""}`.trim();
12307
12414
  }
12308
12415
  }
12309
12416
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
12310
- if (this.isWaitingForResponse) return;
12417
+ if (this.isWaitingForResponse) {
12418
+ throw new Error(`${this.cliName} is still processing the previous prompt`);
12419
+ }
12311
12420
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
12312
12421
  if (blockingModal || this.currentStatus === "waiting_approval") {
12313
12422
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
@@ -31720,6 +31829,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
31720
31829
  if (!cliType) throw new Error("cliType required");
31721
31830
  const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
31722
31831
  if (found) {
31832
+ if (!args?.targetSessionId && !dir) {
31833
+ const matchCount = [...this.adapters.values()].filter((a) => a.cliType === cliType).length;
31834
+ if (matchCount > 1) {
31835
+ return {
31836
+ success: false,
31837
+ error: `Multiple ${cliType} sessions running \u2014 provide targetSessionId to stop a specific session`,
31838
+ code: "AMBIGUOUS_SESSION"
31839
+ };
31840
+ }
31841
+ }
31723
31842
  await this.stopSessionWithMode(found.key, mode);
31724
31843
  } else {
31725
31844
  console.log(colorize("yellow", ` \u26A0 No adapter found for ${cliType}`));
@@ -33584,6 +33703,7 @@ function validateProviderDefinition(raw) {
33584
33703
  warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
33585
33704
  }
33586
33705
  const category = provider.category;
33706
+ const typedProvider = provider;
33587
33707
  const controls = Array.isArray(provider.controls) ? provider.controls : [];
33588
33708
  if (category === "cli" || category === "acp") {
33589
33709
  const spawn6 = provider.spawn;
@@ -33606,6 +33726,9 @@ function validateProviderDefinition(raw) {
33606
33726
  for (const control of controls) {
33607
33727
  validateControl(control, errors);
33608
33728
  }
33729
+ if ((category === "ide" || category === "extension") && typeof typedProvider.scripts?.focusEditor === "function" && !providerHasOpenPanelSupport(typedProvider)) {
33730
+ warnings.push("scripts.focusEditor is present without scripts.openPanel/webviewOpenPanel; open_panel capability will remain disabled");
33731
+ }
33609
33732
  return { errors, warnings };
33610
33733
  }
33611
33734
  function validateCapabilities(provider, controls, errors) {
@@ -33692,6 +33815,7 @@ var VALID_CAPABILITY_MEDIA_TYPES, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES;
33692
33815
  var init_provider_schema = __esm({
33693
33816
  "../../oss/packages/daemon-core/src/providers/provider-schema.ts"() {
33694
33817
  "use strict";
33818
+ init_open_panel_support();
33695
33819
  VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
33696
33820
  KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
33697
33821
  "type",
@@ -35766,8 +35890,8 @@ function buildStatusSnapshot(options) {
35766
35890
  for (const sourceSession of unreadSourceSessions) {
35767
35891
  const session = sessionsById.get(sourceSession.id);
35768
35892
  if (!session) continue;
35769
- const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
35770
- const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
35893
+ const lastSeenAt = getSessionSeenAt(state, sourceSession.id, sourceSession.providerSessionId);
35894
+ const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id, sourceSession.providerSessionId);
35771
35895
  const lastUsedAt = getSessionLastUsedAt(sourceSession);
35772
35896
  const completionMarker = getSessionCompletionMarker(sourceSession);
35773
35897
  const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
@@ -36630,7 +36754,8 @@ var init_router = __esm({
36630
36754
  currentState,
36631
36755
  sessionId,
36632
36756
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
36633
- completionMarker
36757
+ completionMarker,
36758
+ targetSession?.providerSessionId
36634
36759
  );
36635
36760
  if (READ_DEBUG_ENABLED2) {
36636
36761
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
@@ -37082,6 +37207,77 @@ var init_provider_adapter = __esm({
37082
37207
  return raw;
37083
37208
  }
37084
37209
  }
37210
+ getOptionalError(raw) {
37211
+ return typeof raw === "string" && raw.trim() ? raw.trim() : void 0;
37212
+ }
37213
+ normalizeFocusEditorResult(raw) {
37214
+ const data = this.parseMaybeJson(raw);
37215
+ if (data === true) return { focused: true };
37216
+ if (data === false || data == null) return { focused: false };
37217
+ if (typeof data === "string") {
37218
+ const trimmed = data.trim();
37219
+ const normalized = trimmed.toLowerCase();
37220
+ if (normalized === "true" || normalized === "ok" || normalized === "success" || normalized === "focused" || normalized === "visible") {
37221
+ return { focused: true };
37222
+ }
37223
+ if (normalized === "false" || normalized === "not_found" || normalized === "not found" || normalized === "missing" || normalized === "panel_hidden" || normalized === "hidden") {
37224
+ return { focused: false };
37225
+ }
37226
+ return { focused: false, ...trimmed ? { error: trimmed } : {} };
37227
+ }
37228
+ if (data && typeof data === "object") {
37229
+ const error48 = this.getOptionalError(data.error);
37230
+ if (data.focused === true || data.success === true || data.ok === true || data.visible === true) {
37231
+ return { focused: true };
37232
+ }
37233
+ if (data.focused === false || data.success === false || data.ok === false || error48) {
37234
+ return { focused: false, ...error48 ? { error: error48 } : {} };
37235
+ }
37236
+ }
37237
+ return { focused: false };
37238
+ }
37239
+ normalizeOpenPanelResult(raw) {
37240
+ const data = this.parseMaybeJson(raw);
37241
+ if (data === true) return { opened: true, visible: true };
37242
+ if (data === false || data == null) return { opened: false, visible: false };
37243
+ if (typeof data === "string") {
37244
+ const trimmed = data.trim();
37245
+ const normalized = trimmed.toLowerCase();
37246
+ if (normalized === "true" || normalized === "ok" || normalized === "opened" || normalized === "open" || normalized === "success") {
37247
+ return { opened: true, visible: true };
37248
+ }
37249
+ if (normalized === "visible") {
37250
+ return { opened: false, visible: true };
37251
+ }
37252
+ if (normalized === "focused") {
37253
+ return { opened: false, visible: true, focused: true };
37254
+ }
37255
+ if (normalized === "false" || normalized === "panel_hidden" || normalized === "hidden" || normalized === "not_found" || normalized === "not found" || normalized === "missing") {
37256
+ return { opened: false, visible: false };
37257
+ }
37258
+ return { opened: false, visible: false, ...trimmed ? { error: trimmed } : {} };
37259
+ }
37260
+ if (data && typeof data === "object") {
37261
+ const error48 = this.getOptionalError(data.error);
37262
+ const focused = data.focused === true;
37263
+ const visible = data.visible === true || data.opened === true || focused || data.success === true || data.ok === true;
37264
+ if (visible) {
37265
+ return {
37266
+ opened: data.opened === true,
37267
+ visible: true,
37268
+ ...focused ? { focused: true } : {}
37269
+ };
37270
+ }
37271
+ if (data.opened === false || data.visible === false || data.success === false || data.ok === false || error48) {
37272
+ return {
37273
+ opened: false,
37274
+ visible: false,
37275
+ ...error48 ? { error: error48 } : {}
37276
+ };
37277
+ }
37278
+ }
37279
+ return { opened: false, visible: false };
37280
+ }
37085
37281
  summarizeRaw(raw) {
37086
37282
  try {
37087
37283
  if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
@@ -37168,6 +37364,11 @@ var init_provider_adapter = __esm({
37168
37364
  if (typeof validated.title === "string" && validated.title.trim()) {
37169
37365
  state.title = validated.title.trim();
37170
37366
  }
37367
+ const providerSessionId = typeof validated.providerSessionId === "string" && validated.providerSessionId.trim() ? validated.providerSessionId.trim() : "";
37368
+ if (providerSessionId) {
37369
+ state.sessionId = providerSessionId;
37370
+ state.providerSessionId = providerSessionId;
37371
+ }
37171
37372
  const controlValues = extractProviderControlValues(this.provider.controls, validated);
37172
37373
  const surface = resolveProviderStateSurface({
37173
37374
  controlValues,
@@ -37290,8 +37491,15 @@ var init_provider_adapter = __esm({
37290
37491
  }
37291
37492
  async focusEditor(evaluate) {
37292
37493
  const script = this.callScript("focusEditor");
37293
- if (!script) return;
37294
- await evaluate(script);
37494
+ if (!script) return { focused: false };
37495
+ const raw = await evaluate(script);
37496
+ return this.normalizeFocusEditorResult(raw);
37497
+ }
37498
+ async openPanel(evaluate) {
37499
+ const script = this.callScript("openPanel");
37500
+ if (!script) return { opened: false, visible: false };
37501
+ const raw = await evaluate(script);
37502
+ return this.normalizeOpenPanelResult(raw);
37295
37503
  }
37296
37504
  errorState(message) {
37297
37505
  return {
@@ -37568,19 +37776,33 @@ var init_manager2 = __esm({
37568
37776
  return false;
37569
37777
  }
37570
37778
  }
37571
- async focusSession(cdp, sessionId) {
37779
+ async selectSession(cdp, sessionId) {
37572
37780
  const target = this.getSessionTarget(sessionId);
37573
37781
  if (!target?.parentSessionId) return false;
37574
37782
  await this.setActiveSession(cdp, target.parentSessionId, sessionId);
37575
37783
  await this.syncActiveSession(cdp, target.parentSessionId);
37784
+ return this.managedBySessionId.has(sessionId);
37785
+ }
37786
+ async openSessionPanel(cdp, sessionId) {
37787
+ const selected = await this.selectSession(cdp, sessionId);
37788
+ if (!selected) return false;
37576
37789
  const agent = this.managedBySessionId.get(sessionId);
37577
- if (!agent || typeof agent.adapter.focusEditor !== "function") return false;
37790
+ if (!agent) return false;
37791
+ let panelVisible = false;
37792
+ let editorFocused = false;
37578
37793
  try {
37579
37794
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
37580
- await agent.adapter.focusEditor(evaluate);
37581
- return true;
37795
+ if (typeof agent.adapter.openPanel === "function") {
37796
+ const result = await agent.adapter.openPanel(evaluate);
37797
+ panelVisible = result.visible;
37798
+ }
37799
+ if (typeof agent.adapter.focusEditor === "function") {
37800
+ const result = await agent.adapter.focusEditor(evaluate);
37801
+ editorFocused = result.focused;
37802
+ }
37803
+ return panelVisible || editorFocused;
37582
37804
  } catch (e) {
37583
- this.logFn(`[AgentStream] focusEditor(${sessionId}) error: ${e.message}`);
37805
+ this.logFn(`[AgentStream] openPanel(${sessionId}) error: ${e.message}`);
37584
37806
  return false;
37585
37807
  }
37586
37808
  }
@@ -37835,6 +38057,7 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
37835
38057
  summaryMetadata: stream.summaryMetadata || void 0,
37836
38058
  effects: stream.effects || void 0,
37837
38059
  sessionId: stream.sessionId || stream.instanceId || void 0,
38060
+ providerSessionId: stream.providerSessionId || stream.sessionId || void 0,
37838
38061
  title: stream.title || stream.agentName || void 0,
37839
38062
  agentType: stream.agentType || void 0,
37840
38063
  agentName: stream.agentName || void 0,
@@ -38494,9 +38717,14 @@ module.exports.setMode = (params) => {
38494
38717
  (() => {
38495
38718
  try {
38496
38719
  const input = document.querySelector('${meta3.inputSelector || '[contenteditable="true"]'}');
38497
- if (input) { input.focus(); return 'focused'; }
38498
- return 'not_found';
38499
- } catch(e) { return 'error'; }
38720
+ if (input) {
38721
+ input.focus();
38722
+ return JSON.stringify({ focused: true });
38723
+ }
38724
+ return JSON.stringify({ focused: false, error: 'not_found' });
38725
+ } catch(e) {
38726
+ return JSON.stringify({ focused: false, error: e.message });
38727
+ }
38500
38728
  })()
38501
38729
  `;
38502
38730
  files[`${scriptDir}/open_panel.js`] = `/**
@@ -38507,8 +38735,10 @@ module.exports.setMode = (params) => {
38507
38735
  (() => {
38508
38736
  try {
38509
38737
  // TODO: Check if panel visible, if not find toggle button
38510
- return 'not_found';
38511
- } catch(e) { return 'error'; }
38738
+ return JSON.stringify({ opened: false, visible: false, error: 'not_found' });
38739
+ } catch(e) {
38740
+ return JSON.stringify({ opened: false, visible: false, error: e.message });
38741
+ }
38512
38742
  })()
38513
38743
  `;
38514
38744
  files[`${scriptDir}/resolve_action.js`] = `/**
@@ -41331,8 +41561,8 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
41331
41561
  lines.push("| setModel | `{ success: true/false }` |");
41332
41562
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
41333
41563
  lines.push("| setMode | `{ success: true/false }` |");
41334
- lines.push("| focusEditor | `{ focused: true/false }` |");
41335
- lines.push("| openPanel | `{ opened: true/false }` |");
41564
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
41565
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
41336
41566
  lines.push("");
41337
41567
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
41338
41568
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
@@ -42994,8 +43224,8 @@ var init_dev_server = __esm({
42994
43224
  lines.push("| setModel | `{ success: true/false }` |");
42995
43225
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
42996
43226
  lines.push("| setMode | `{ success: true/false }` |");
42997
- lines.push("| focusEditor | `{ focused: true/false }` |");
42998
- lines.push("| openPanel | `{ opened: true/false }` |");
43227
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
43228
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
42999
43229
  lines.push("");
43000
43230
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
43001
43231
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
@@ -76180,10 +76410,29 @@ var init_log = __esm({
76180
76410
 
76181
76411
  // src/daemon-p2p/data-channel-router.ts
76182
76412
  function sendToPeer(peer, data) {
76183
- if (!peer?.dataChannel) return;
76413
+ const messageType = typeof data?.type === "string" ? data.type : "unknown";
76414
+ const requestId = typeof data?.id === "string" ? data.id : "";
76415
+ const peerId = typeof peer?.peerId === "string" ? peer.peerId : "unknown";
76416
+ if (!peer?.dataChannel) {
76417
+ if (messageType === "command_result") {
76418
+ log(`command_result dropped: peer=${peerId} id=${requestId || "-"} reason=no_data_channel`);
76419
+ }
76420
+ return false;
76421
+ }
76422
+ if (typeof peer.dataChannel.isOpen === "function" && !peer.dataChannel.isOpen()) {
76423
+ if (messageType === "command_result") {
76424
+ log(`command_result dropped: peer=${peerId} id=${requestId || "-"} reason=channel_not_open state=${peer.state}`);
76425
+ }
76426
+ return false;
76427
+ }
76184
76428
  try {
76185
76429
  peer.dataChannel.sendMessage(JSON.stringify(data));
76186
- } catch {
76430
+ return true;
76431
+ } catch (error48) {
76432
+ if (messageType === "command_result") {
76433
+ log(`command_result send failed: peer=${peerId} id=${requestId || "-"} error=${error48?.message || error48}`);
76434
+ }
76435
+ return false;
76187
76436
  }
76188
76437
  }
76189
76438
  function routeDataChannelMessage(peerId, msg, peers, handlers) {
@@ -76378,7 +76627,14 @@ async function handleP2PCommand(peerId, msg, peers, handlers) {
76378
76627
  }
76379
76628
  try {
76380
76629
  const result = await handlers.commandHandler(commandType, data || {}, id);
76381
- sendToPeer(peer, { type: "command_result", id, ...result });
76630
+ const commandPayload = result && typeof result === "object" ? result : { success: false, error: "Invalid command result" };
76631
+ const { id: commandPayloadId, ...rest } = commandPayload;
76632
+ sendToPeer(peer, {
76633
+ type: "command_result",
76634
+ id,
76635
+ ...commandPayloadId !== void 0 ? { resultId: commandPayloadId } : {},
76636
+ ...rest
76637
+ });
76382
76638
  } catch (e) {
76383
76639
  sendToPeer(peer, { type: "command_result", id, success: false, error: e?.message });
76384
76640
  }
@@ -84663,7 +84919,7 @@ var init_adhdev_daemon = __esm({
84663
84919
  init_source();
84664
84920
  init_version();
84665
84921
  init_src();
84666
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.69" });
84922
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.71" });
84667
84923
  AdhdevDaemon = class _AdhdevDaemon {
84668
84924
  localHttpServer = null;
84669
84925
  localWss = null;