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/index.js CHANGED
@@ -529,27 +529,37 @@ function getRecentActivity(state, limit = 20) {
529
529
  })
530
530
  })).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
531
531
  }
532
- function getSessionSeenAt(state, sessionId) {
533
- return state.sessionReads?.[sessionId] || 0;
532
+ function buildSessionReadStateKey(sessionId, providerSessionId) {
533
+ const normalizedProviderSessionId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
534
+ if (normalizedProviderSessionId) return `provider:${normalizedProviderSessionId}`;
535
+ return sessionId;
534
536
  }
535
- function getSessionSeenMarker(state, sessionId) {
536
- return state.sessionReadMarkers?.[sessionId] || "";
537
+ function getSessionSeenAt(state, sessionId, providerSessionId) {
538
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
539
+ return state.sessionReads?.[providerKey] || state.sessionReads?.[sessionId] || 0;
537
540
  }
538
- function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
541
+ function getSessionSeenMarker(state, sessionId, providerSessionId) {
542
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
543
+ return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
544
+ }
545
+ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
539
546
  const prev = state.sessionReads || {};
540
- const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
541
547
  const prevMarkers = state.sessionReadMarkers || {};
542
548
  const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
549
+ const readKeys = Array.from(new Set([
550
+ sessionId,
551
+ buildSessionReadStateKey(sessionId, providerSessionId)
552
+ ].filter(Boolean)));
553
+ const nextSessionReads = { ...prev };
554
+ const nextSessionReadMarkers = { ...prevMarkers };
555
+ for (const key of readKeys) {
556
+ nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
557
+ if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
558
+ }
543
559
  return {
544
560
  ...state,
545
- sessionReads: {
546
- ...prev,
547
- [sessionId]: nextSeenAt
548
- },
549
- sessionReadMarkers: nextMarker ? {
550
- ...prevMarkers,
551
- [sessionId]: nextMarker
552
- } : prevMarkers
561
+ sessionReads: nextSessionReads,
562
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
553
563
  };
554
564
  }
555
565
  var path2, MAX_ACTIVITY;
@@ -3814,6 +3824,43 @@ var init_provider_patch_state = __esm({
3814
3824
  }
3815
3825
  });
3816
3826
 
3827
+ // ../../oss/packages/daemon-core/src/providers/open-panel-support.ts
3828
+ function providerHasOpenPanelSupport(provider) {
3829
+ if (typeof provider.scripts?.openPanel === "function") return true;
3830
+ if (provider.category === "ide" && typeof provider.scripts?.webviewOpenPanel === "function") return true;
3831
+ return false;
3832
+ }
3833
+ function getProviderSessionCapabilities(provider, baseCapabilities) {
3834
+ return providerHasOpenPanelSupport(provider) ? [...baseCapabilities, "open_panel"] : [...baseCapabilities];
3835
+ }
3836
+ var IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE;
3837
+ var init_open_panel_support = __esm({
3838
+ "../../oss/packages/daemon-core/src/providers/open-panel-support.ts"() {
3839
+ "use strict";
3840
+ IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
3841
+ "read_chat",
3842
+ "send_message",
3843
+ "new_session",
3844
+ "list_sessions",
3845
+ "switch_session",
3846
+ "resolve_action",
3847
+ "change_model",
3848
+ "set_mode",
3849
+ "set_thought_level"
3850
+ ];
3851
+ EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE = [
3852
+ "read_chat",
3853
+ "send_message",
3854
+ "new_session",
3855
+ "list_sessions",
3856
+ "switch_session",
3857
+ "resolve_action",
3858
+ "change_model",
3859
+ "set_mode"
3860
+ ];
3861
+ }
3862
+ });
3863
+
3817
3864
  // ../../oss/packages/daemon-core/src/providers/extension-provider-instance.ts
3818
3865
  var ExtensionProviderInstance;
3819
3866
  var init_extension_provider_instance = __esm({
@@ -3825,6 +3872,7 @@ var init_extension_provider_instance = __esm({
3825
3872
  init_chat_history();
3826
3873
  init_provider_patch_state();
3827
3874
  init_chat_message_normalization();
3875
+ init_open_panel_support();
3828
3876
  ExtensionProviderInstance = class {
3829
3877
  type;
3830
3878
  category = "extension";
@@ -3850,6 +3898,7 @@ var init_extension_provider_instance = __esm({
3850
3898
  instanceId;
3851
3899
  ideType = "";
3852
3900
  chatId = null;
3901
+ providerSessionId = null;
3853
3902
  chatTitle = null;
3854
3903
  agentName = "";
3855
3904
  extensionId = "";
@@ -3883,8 +3932,10 @@ var init_extension_provider_instance = __esm({
3883
3932
  name: this.provider.name,
3884
3933
  category: "extension",
3885
3934
  status: this.currentStatus,
3935
+ providerSessionId: this.providerSessionId || this.chatId || void 0,
3936
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE),
3886
3937
  activeChat: this.messages.length > 0 || this.runtimeMessages.length > 0 ? {
3887
- id: this.chatId || this.instanceId,
3938
+ id: this.providerSessionId || this.chatId || this.instanceId,
3888
3939
  title: this.chatTitle || this.agentName || this.provider.name,
3889
3940
  status: this.currentStatus,
3890
3941
  messages: this.mergeConversationMessages(this.messages),
@@ -3914,7 +3965,11 @@ var init_extension_provider_instance = __esm({
3914
3965
  });
3915
3966
  this.controlValues = patchedState.controlValues;
3916
3967
  this.summaryMetadata = patchedState.summaryMetadata;
3917
- if (typeof data?.sessionId === "string" && data.sessionId.trim()) this.chatId = data.sessionId;
3968
+ const nextProviderSessionId = typeof data?.providerSessionId === "string" && data.providerSessionId.trim() ? data.providerSessionId.trim() : typeof data?.sessionId === "string" && data.sessionId.trim() ? data.sessionId.trim() : "";
3969
+ if (nextProviderSessionId) {
3970
+ this.providerSessionId = nextProviderSessionId;
3971
+ this.chatId = nextProviderSessionId;
3972
+ }
3918
3973
  if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
3919
3974
  if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
3920
3975
  if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
@@ -4200,6 +4255,7 @@ ${effect.notification.body || ""}`.trim();
4200
4255
  this.controlValues = {};
4201
4256
  this.currentStatus = "idle";
4202
4257
  this.chatId = null;
4258
+ this.providerSessionId = null;
4203
4259
  this.chatTitle = null;
4204
4260
  this.agentName = "";
4205
4261
  this.extensionId = "";
@@ -4248,6 +4304,7 @@ function validateMessage(message, source, index) {
4248
4304
  if (isFiniteNumber(message.index)) normalized.index = message.index;
4249
4305
  if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
4250
4306
  if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
4307
+ if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
4251
4308
  if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
4252
4309
  if (isPlainObject3(message.meta)) normalized.meta = message.meta;
4253
4310
  if (typeof message.senderName === "string") normalized.senderName = message.senderName;
@@ -4402,6 +4459,7 @@ var init_ide_provider_instance = __esm({
4402
4459
  init_approval_utils();
4403
4460
  init_provider_patch_state();
4404
4461
  init_chat_message_normalization();
4462
+ init_open_panel_support();
4405
4463
  IdeProviderInstance = class {
4406
4464
  type;
4407
4465
  category = "ide";
@@ -4494,6 +4552,7 @@ var init_ide_provider_instance = __esm({
4494
4552
  workspace: this.workspace || null,
4495
4553
  extensions: extensionStates,
4496
4554
  cdpConnected: cdp?.isConnected || false,
4555
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, IDE_PROVIDER_SESSION_CAPABILITIES_BASE),
4497
4556
  controlValues: surface.controlValues,
4498
4557
  providerControls: this.provider.controls,
4499
4558
  summaryMetadata: surface.summaryMetadata,
@@ -5574,7 +5633,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
5574
5633
  ...includeSessionMetadata && { workspace: state.workspace || null },
5575
5634
  activeChat,
5576
5635
  ...summaryMetadata && { summaryMetadata },
5577
- ...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
5636
+ ...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
5578
5637
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
5579
5638
  ...includeSessionControls && {
5580
5639
  ...controlValues && { controlValues },
@@ -5597,6 +5656,7 @@ function buildExtensionAgentSession(parent, ext, options) {
5597
5656
  parentId: parent.instanceId || parent.type,
5598
5657
  providerType: ext.type,
5599
5658
  ...includeSessionMetadata && { providerName: ext.name },
5659
+ providerSessionId: ext.providerSessionId,
5600
5660
  kind: "agent",
5601
5661
  transport: "cdp-webview",
5602
5662
  status: normalizeManagedStatus(activeChat?.status || ext.status, {
@@ -5606,7 +5666,7 @@ function buildExtensionAgentSession(parent, ext, options) {
5606
5666
  ...includeSessionMetadata && { workspace: parent.workspace || null },
5607
5667
  activeChat,
5608
5668
  ...summaryMetadata && { summaryMetadata },
5609
- ...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
5669
+ ...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
5610
5670
  ...includeSessionControls && {
5611
5671
  ...controlValues && { controlValues },
5612
5672
  providerControls: ext.providerControls
@@ -5725,27 +5785,9 @@ var init_builders = __esm({
5725
5785
  init_normalize();
5726
5786
  init_provider_patch_state();
5727
5787
  init_summary_metadata();
5728
- IDE_SESSION_CAPABILITIES = [
5729
- "read_chat",
5730
- "send_message",
5731
- "new_session",
5732
- "list_sessions",
5733
- "switch_session",
5734
- "resolve_action",
5735
- "change_model",
5736
- "set_mode",
5737
- "set_thought_level"
5738
- ];
5739
- EXTENSION_SESSION_CAPABILITIES = [
5740
- "read_chat",
5741
- "send_message",
5742
- "new_session",
5743
- "list_sessions",
5744
- "switch_session",
5745
- "resolve_action",
5746
- "change_model",
5747
- "set_mode"
5748
- ];
5788
+ init_open_panel_support();
5789
+ IDE_SESSION_CAPABILITIES = [...IDE_PROVIDER_SESSION_CAPABILITIES_BASE];
5790
+ EXTENSION_SESSION_CAPABILITIES = [...EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE];
5749
5791
  PTY_SESSION_CAPABILITIES = [
5750
5792
  "read_chat",
5751
5793
  "send_message",
@@ -7613,13 +7655,75 @@ function getCliPresentationMode(h, targetSessionId) {
7613
7655
  const mode = instance.getPresentationMode?.();
7614
7656
  return mode === "chat" || mode === "terminal" ? mode : null;
7615
7657
  }
7616
- async function handleFocusSession(h, args) {
7658
+ function normalizeOpenPanelCommandResult(result) {
7659
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
7660
+ if (payload === true) return { opened: true, visible: true, focused: false };
7661
+ if (!payload) return { opened: false, visible: false, focused: false };
7662
+ if (typeof payload === "string") {
7663
+ const normalized = payload.trim().toLowerCase();
7664
+ if (normalized === "visible") return { opened: false, visible: true, focused: false };
7665
+ if (normalized === "focused") return { opened: false, visible: true, focused: true };
7666
+ if (normalized === "opened" || normalized === "open" || normalized === "true" || normalized === "ok" || normalized === "success") {
7667
+ return { opened: true, visible: true, focused: false };
7668
+ }
7669
+ return { opened: false, visible: false, focused: false };
7670
+ }
7671
+ if (typeof payload === "object") {
7672
+ const record2 = payload;
7673
+ return {
7674
+ opened: record2.opened === true,
7675
+ visible: record2.visible === true || record2.opened === true || record2.focused === true,
7676
+ focused: record2.focused === true
7677
+ };
7678
+ }
7679
+ return { opened: false, visible: false, focused: false };
7680
+ }
7681
+ function normalizeFocusEditorCommandResult(result) {
7682
+ const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
7683
+ if (payload === true) return { focused: true };
7684
+ if (!payload) return { focused: false };
7685
+ if (typeof payload === "string") {
7686
+ const normalized = payload.trim().toLowerCase();
7687
+ return { focused: normalized === "focused" || normalized === "visible" || normalized === "true" || normalized === "ok" || normalized === "success" };
7688
+ }
7689
+ if (typeof payload === "object") {
7690
+ const record2 = payload;
7691
+ return { focused: record2.focused === true || record2.visible === true || record2.success === true || record2.ok === true };
7692
+ }
7693
+ return { focused: false };
7694
+ }
7695
+ async function handleSelectSession(h, args) {
7617
7696
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
7618
7697
  const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
7619
7698
  if (!sessionId) return { success: false, error: "targetSessionId required" };
7620
- const ok = await h.agentStream.focusSession(h.getCdp(), sessionId);
7699
+ const ok = await h.agentStream.selectSession(h.getCdp(), sessionId);
7621
7700
  return { success: ok };
7622
7701
  }
7702
+ async function handleOpenPanel(h, args) {
7703
+ const cdp = h.getCdp();
7704
+ if (!cdp) return { success: false, error: "AgentStream or CDP not available" };
7705
+ const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
7706
+ if (!sessionId) return { success: false, error: "targetSessionId required" };
7707
+ const currentTransport = h.currentSession?.transport;
7708
+ const shouldUseAgentStream = !!h.agentStream && currentTransport !== "cdp-page" && currentTransport !== "pty" && currentTransport !== "acp";
7709
+ if (shouldUseAgentStream) {
7710
+ const ok = await h.agentStream.openSessionPanel(cdp, sessionId);
7711
+ return { success: ok };
7712
+ }
7713
+ const openResult = await executeProviderScript(h, args, "openPanel");
7714
+ if (!openResult.success) return openResult;
7715
+ const revealState = normalizeOpenPanelCommandResult(openResult);
7716
+ let focusState = { focused: false };
7717
+ const focusResult = await executeProviderScript(h, args, "focusEditor");
7718
+ if (focusResult.success) {
7719
+ focusState = normalizeFocusEditorCommandResult(focusResult);
7720
+ }
7721
+ return {
7722
+ ...openResult,
7723
+ ...focusState.focused ? { focused: true } : {},
7724
+ success: revealState.visible || focusState.focused
7725
+ };
7726
+ }
7623
7727
  function handlePtyInput(h, args) {
7624
7728
  const { cliType, data, targetSessionId } = args || {};
7625
7729
  if (!data) return { success: false, error: "data required" };
@@ -8338,7 +8442,8 @@ var init_handler = __esm({
8338
8442
  "change_model",
8339
8443
  "set_thought_level",
8340
8444
  "resolve_action",
8341
- "focus_session",
8445
+ "select_session",
8446
+ "open_panel",
8342
8447
  "pty_input",
8343
8448
  "pty_resize",
8344
8449
  "invoke_provider_script"
@@ -8436,8 +8541,10 @@ var init_handler = __esm({
8436
8541
  case "refresh_scripts":
8437
8542
  return this.handleRefreshScripts(args);
8438
8543
  // ─── Stream commands (stream-commands.ts) ───────────
8439
- case "focus_session":
8440
- return handleFocusSession(this, args);
8544
+ case "select_session":
8545
+ return handleSelectSession(this, args);
8546
+ case "open_panel":
8547
+ return handleOpenPanel(this, args);
8441
8548
  // ─── PTY Raw I/O (stream-commands.ts) ─────────
8442
8549
  case "pty_input":
8443
8550
  return handlePtyInput(this, args);
@@ -11366,7 +11473,9 @@ ${data.message || ""}`.trim();
11366
11473
  }
11367
11474
  }
11368
11475
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
11369
- if (this.isWaitingForResponse) return;
11476
+ if (this.isWaitingForResponse) {
11477
+ throw new Error(`${this.cliName} is still processing the previous prompt`);
11478
+ }
11370
11479
  const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
11371
11480
  if (blockingModal || this.currentStatus === "waiting_approval") {
11372
11481
  throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
@@ -30779,6 +30888,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
30779
30888
  if (!cliType) throw new Error("cliType required");
30780
30889
  const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
30781
30890
  if (found) {
30891
+ if (!args?.targetSessionId && !dir) {
30892
+ const matchCount = [...this.adapters.values()].filter((a) => a.cliType === cliType).length;
30893
+ if (matchCount > 1) {
30894
+ return {
30895
+ success: false,
30896
+ error: `Multiple ${cliType} sessions running \u2014 provide targetSessionId to stop a specific session`,
30897
+ code: "AMBIGUOUS_SESSION"
30898
+ };
30899
+ }
30900
+ }
30782
30901
  await this.stopSessionWithMode(found.key, mode);
30783
30902
  } else {
30784
30903
  console.log(colorize("yellow", ` \u26A0 No adapter found for ${cliType}`));
@@ -32643,6 +32762,7 @@ function validateProviderDefinition(raw) {
32643
32762
  warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
32644
32763
  }
32645
32764
  const category = provider.category;
32765
+ const typedProvider = provider;
32646
32766
  const controls = Array.isArray(provider.controls) ? provider.controls : [];
32647
32767
  if (category === "cli" || category === "acp") {
32648
32768
  const spawn6 = provider.spawn;
@@ -32665,6 +32785,9 @@ function validateProviderDefinition(raw) {
32665
32785
  for (const control of controls) {
32666
32786
  validateControl(control, errors);
32667
32787
  }
32788
+ if ((category === "ide" || category === "extension") && typeof typedProvider.scripts?.focusEditor === "function" && !providerHasOpenPanelSupport(typedProvider)) {
32789
+ warnings.push("scripts.focusEditor is present without scripts.openPanel/webviewOpenPanel; open_panel capability will remain disabled");
32790
+ }
32668
32791
  return { errors, warnings };
32669
32792
  }
32670
32793
  function validateCapabilities(provider, controls, errors) {
@@ -32751,6 +32874,7 @@ var VALID_CAPABILITY_MEDIA_TYPES, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES;
32751
32874
  var init_provider_schema = __esm({
32752
32875
  "../../oss/packages/daemon-core/src/providers/provider-schema.ts"() {
32753
32876
  "use strict";
32877
+ init_open_panel_support();
32754
32878
  VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
32755
32879
  KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
32756
32880
  "type",
@@ -34825,8 +34949,8 @@ function buildStatusSnapshot(options) {
34825
34949
  for (const sourceSession of unreadSourceSessions) {
34826
34950
  const session = sessionsById.get(sourceSession.id);
34827
34951
  if (!session) continue;
34828
- const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
34829
- const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
34952
+ const lastSeenAt = getSessionSeenAt(state, sourceSession.id, sourceSession.providerSessionId);
34953
+ const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id, sourceSession.providerSessionId);
34830
34954
  const lastUsedAt = getSessionLastUsedAt(sourceSession);
34831
34955
  const completionMarker = getSessionCompletionMarker(sourceSession);
34832
34956
  const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
@@ -35689,7 +35813,8 @@ var init_router = __esm({
35689
35813
  currentState,
35690
35814
  sessionId,
35691
35815
  typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
35692
- completionMarker
35816
+ completionMarker,
35817
+ targetSession?.providerSessionId
35693
35818
  );
35694
35819
  if (READ_DEBUG_ENABLED2) {
35695
35820
  LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
@@ -36141,6 +36266,77 @@ var init_provider_adapter = __esm({
36141
36266
  return raw;
36142
36267
  }
36143
36268
  }
36269
+ getOptionalError(raw) {
36270
+ return typeof raw === "string" && raw.trim() ? raw.trim() : void 0;
36271
+ }
36272
+ normalizeFocusEditorResult(raw) {
36273
+ const data = this.parseMaybeJson(raw);
36274
+ if (data === true) return { focused: true };
36275
+ if (data === false || data == null) return { focused: false };
36276
+ if (typeof data === "string") {
36277
+ const trimmed = data.trim();
36278
+ const normalized = trimmed.toLowerCase();
36279
+ if (normalized === "true" || normalized === "ok" || normalized === "success" || normalized === "focused" || normalized === "visible") {
36280
+ return { focused: true };
36281
+ }
36282
+ if (normalized === "false" || normalized === "not_found" || normalized === "not found" || normalized === "missing" || normalized === "panel_hidden" || normalized === "hidden") {
36283
+ return { focused: false };
36284
+ }
36285
+ return { focused: false, ...trimmed ? { error: trimmed } : {} };
36286
+ }
36287
+ if (data && typeof data === "object") {
36288
+ const error48 = this.getOptionalError(data.error);
36289
+ if (data.focused === true || data.success === true || data.ok === true || data.visible === true) {
36290
+ return { focused: true };
36291
+ }
36292
+ if (data.focused === false || data.success === false || data.ok === false || error48) {
36293
+ return { focused: false, ...error48 ? { error: error48 } : {} };
36294
+ }
36295
+ }
36296
+ return { focused: false };
36297
+ }
36298
+ normalizeOpenPanelResult(raw) {
36299
+ const data = this.parseMaybeJson(raw);
36300
+ if (data === true) return { opened: true, visible: true };
36301
+ if (data === false || data == null) return { opened: false, visible: false };
36302
+ if (typeof data === "string") {
36303
+ const trimmed = data.trim();
36304
+ const normalized = trimmed.toLowerCase();
36305
+ if (normalized === "true" || normalized === "ok" || normalized === "opened" || normalized === "open" || normalized === "success") {
36306
+ return { opened: true, visible: true };
36307
+ }
36308
+ if (normalized === "visible") {
36309
+ return { opened: false, visible: true };
36310
+ }
36311
+ if (normalized === "focused") {
36312
+ return { opened: false, visible: true, focused: true };
36313
+ }
36314
+ if (normalized === "false" || normalized === "panel_hidden" || normalized === "hidden" || normalized === "not_found" || normalized === "not found" || normalized === "missing") {
36315
+ return { opened: false, visible: false };
36316
+ }
36317
+ return { opened: false, visible: false, ...trimmed ? { error: trimmed } : {} };
36318
+ }
36319
+ if (data && typeof data === "object") {
36320
+ const error48 = this.getOptionalError(data.error);
36321
+ const focused = data.focused === true;
36322
+ const visible = data.visible === true || data.opened === true || focused || data.success === true || data.ok === true;
36323
+ if (visible) {
36324
+ return {
36325
+ opened: data.opened === true,
36326
+ visible: true,
36327
+ ...focused ? { focused: true } : {}
36328
+ };
36329
+ }
36330
+ if (data.opened === false || data.visible === false || data.success === false || data.ok === false || error48) {
36331
+ return {
36332
+ opened: false,
36333
+ visible: false,
36334
+ ...error48 ? { error: error48 } : {}
36335
+ };
36336
+ }
36337
+ }
36338
+ return { opened: false, visible: false };
36339
+ }
36144
36340
  summarizeRaw(raw) {
36145
36341
  try {
36146
36342
  if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
@@ -36227,6 +36423,11 @@ var init_provider_adapter = __esm({
36227
36423
  if (typeof validated.title === "string" && validated.title.trim()) {
36228
36424
  state.title = validated.title.trim();
36229
36425
  }
36426
+ const providerSessionId = typeof validated.providerSessionId === "string" && validated.providerSessionId.trim() ? validated.providerSessionId.trim() : "";
36427
+ if (providerSessionId) {
36428
+ state.sessionId = providerSessionId;
36429
+ state.providerSessionId = providerSessionId;
36430
+ }
36230
36431
  const controlValues = extractProviderControlValues(this.provider.controls, validated);
36231
36432
  const surface = resolveProviderStateSurface({
36232
36433
  controlValues,
@@ -36349,8 +36550,15 @@ var init_provider_adapter = __esm({
36349
36550
  }
36350
36551
  async focusEditor(evaluate) {
36351
36552
  const script = this.callScript("focusEditor");
36352
- if (!script) return;
36353
- await evaluate(script);
36553
+ if (!script) return { focused: false };
36554
+ const raw = await evaluate(script);
36555
+ return this.normalizeFocusEditorResult(raw);
36556
+ }
36557
+ async openPanel(evaluate) {
36558
+ const script = this.callScript("openPanel");
36559
+ if (!script) return { opened: false, visible: false };
36560
+ const raw = await evaluate(script);
36561
+ return this.normalizeOpenPanelResult(raw);
36354
36562
  }
36355
36563
  errorState(message) {
36356
36564
  return {
@@ -36627,19 +36835,33 @@ var init_manager2 = __esm({
36627
36835
  return false;
36628
36836
  }
36629
36837
  }
36630
- async focusSession(cdp, sessionId) {
36838
+ async selectSession(cdp, sessionId) {
36631
36839
  const target = this.getSessionTarget(sessionId);
36632
36840
  if (!target?.parentSessionId) return false;
36633
36841
  await this.setActiveSession(cdp, target.parentSessionId, sessionId);
36634
36842
  await this.syncActiveSession(cdp, target.parentSessionId);
36843
+ return this.managedBySessionId.has(sessionId);
36844
+ }
36845
+ async openSessionPanel(cdp, sessionId) {
36846
+ const selected = await this.selectSession(cdp, sessionId);
36847
+ if (!selected) return false;
36635
36848
  const agent = this.managedBySessionId.get(sessionId);
36636
- if (!agent || typeof agent.adapter.focusEditor !== "function") return false;
36849
+ if (!agent) return false;
36850
+ let panelVisible = false;
36851
+ let editorFocused = false;
36637
36852
  try {
36638
36853
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
36639
- await agent.adapter.focusEditor(evaluate);
36640
- return true;
36854
+ if (typeof agent.adapter.openPanel === "function") {
36855
+ const result = await agent.adapter.openPanel(evaluate);
36856
+ panelVisible = result.visible;
36857
+ }
36858
+ if (typeof agent.adapter.focusEditor === "function") {
36859
+ const result = await agent.adapter.focusEditor(evaluate);
36860
+ editorFocused = result.focused;
36861
+ }
36862
+ return panelVisible || editorFocused;
36641
36863
  } catch (e) {
36642
- this.logFn(`[AgentStream] focusEditor(${sessionId}) error: ${e.message}`);
36864
+ this.logFn(`[AgentStream] openPanel(${sessionId}) error: ${e.message}`);
36643
36865
  return false;
36644
36866
  }
36645
36867
  }
@@ -36894,6 +37116,7 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
36894
37116
  summaryMetadata: stream.summaryMetadata || void 0,
36895
37117
  effects: stream.effects || void 0,
36896
37118
  sessionId: stream.sessionId || stream.instanceId || void 0,
37119
+ providerSessionId: stream.providerSessionId || stream.sessionId || void 0,
36897
37120
  title: stream.title || stream.agentName || void 0,
36898
37121
  agentType: stream.agentType || void 0,
36899
37122
  agentName: stream.agentName || void 0,
@@ -37553,9 +37776,14 @@ module.exports.setMode = (params) => {
37553
37776
  (() => {
37554
37777
  try {
37555
37778
  const input = document.querySelector('${meta3.inputSelector || '[contenteditable="true"]'}');
37556
- if (input) { input.focus(); return 'focused'; }
37557
- return 'not_found';
37558
- } catch(e) { return 'error'; }
37779
+ if (input) {
37780
+ input.focus();
37781
+ return JSON.stringify({ focused: true });
37782
+ }
37783
+ return JSON.stringify({ focused: false, error: 'not_found' });
37784
+ } catch(e) {
37785
+ return JSON.stringify({ focused: false, error: e.message });
37786
+ }
37559
37787
  })()
37560
37788
  `;
37561
37789
  files[`${scriptDir}/open_panel.js`] = `/**
@@ -37566,8 +37794,10 @@ module.exports.setMode = (params) => {
37566
37794
  (() => {
37567
37795
  try {
37568
37796
  // TODO: Check if panel visible, if not find toggle button
37569
- return 'not_found';
37570
- } catch(e) { return 'error'; }
37797
+ return JSON.stringify({ opened: false, visible: false, error: 'not_found' });
37798
+ } catch(e) {
37799
+ return JSON.stringify({ opened: false, visible: false, error: e.message });
37800
+ }
37571
37801
  })()
37572
37802
  `;
37573
37803
  files[`${scriptDir}/resolve_action.js`] = `/**
@@ -40390,8 +40620,8 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
40390
40620
  lines.push("| setModel | `{ success: true/false }` |");
40391
40621
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
40392
40622
  lines.push("| setMode | `{ success: true/false }` |");
40393
- lines.push("| focusEditor | `{ focused: true/false }` |");
40394
- lines.push("| openPanel | `{ opened: true/false }` |");
40623
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
40624
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
40395
40625
  lines.push("");
40396
40626
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
40397
40627
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
@@ -42053,8 +42283,8 @@ var init_dev_server = __esm({
42053
42283
  lines.push("| setModel | `{ success: true/false }` |");
42054
42284
  lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
42055
42285
  lines.push("| setMode | `{ success: true/false }` |");
42056
- lines.push("| focusEditor | `{ focused: true/false }` |");
42057
- lines.push("| openPanel | `{ opened: true/false }` |");
42286
+ lines.push("| focusEditor | `{ focused: true/false, error? }` |");
42287
+ lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
42058
42288
  lines.push("");
42059
42289
  lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
42060
42290
  lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
@@ -44009,10 +44239,29 @@ var init_log = __esm({
44009
44239
 
44010
44240
  // src/daemon-p2p/data-channel-router.ts
44011
44241
  function sendToPeer(peer, data) {
44012
- if (!peer?.dataChannel) return;
44242
+ const messageType = typeof data?.type === "string" ? data.type : "unknown";
44243
+ const requestId = typeof data?.id === "string" ? data.id : "";
44244
+ const peerId = typeof peer?.peerId === "string" ? peer.peerId : "unknown";
44245
+ if (!peer?.dataChannel) {
44246
+ if (messageType === "command_result") {
44247
+ log(`command_result dropped: peer=${peerId} id=${requestId || "-"} reason=no_data_channel`);
44248
+ }
44249
+ return false;
44250
+ }
44251
+ if (typeof peer.dataChannel.isOpen === "function" && !peer.dataChannel.isOpen()) {
44252
+ if (messageType === "command_result") {
44253
+ log(`command_result dropped: peer=${peerId} id=${requestId || "-"} reason=channel_not_open state=${peer.state}`);
44254
+ }
44255
+ return false;
44256
+ }
44013
44257
  try {
44014
44258
  peer.dataChannel.sendMessage(JSON.stringify(data));
44015
- } catch {
44259
+ return true;
44260
+ } catch (error48) {
44261
+ if (messageType === "command_result") {
44262
+ log(`command_result send failed: peer=${peerId} id=${requestId || "-"} error=${error48?.message || error48}`);
44263
+ }
44264
+ return false;
44016
44265
  }
44017
44266
  }
44018
44267
  function routeDataChannelMessage(peerId, msg, peers, handlers) {
@@ -44207,7 +44456,14 @@ async function handleP2PCommand(peerId, msg, peers, handlers) {
44207
44456
  }
44208
44457
  try {
44209
44458
  const result = await handlers.commandHandler(commandType, data || {}, id);
44210
- sendToPeer(peer, { type: "command_result", id, ...result });
44459
+ const commandPayload = result && typeof result === "object" ? result : { success: false, error: "Invalid command result" };
44460
+ const { id: commandPayloadId, ...rest } = commandPayload;
44461
+ sendToPeer(peer, {
44462
+ type: "command_result",
44463
+ id,
44464
+ ...commandPayloadId !== void 0 ? { resultId: commandPayloadId } : {},
44465
+ ...rest
44466
+ });
44211
44467
  } catch (e) {
44212
44468
  sendToPeer(peer, { type: "command_result", id, success: false, error: e?.message });
44213
44469
  }
@@ -52959,7 +53215,7 @@ var init_adhdev_daemon = __esm({
52959
53215
  init_source2();
52960
53216
  init_version();
52961
53217
  init_src();
52962
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.69" });
53218
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.71" });
52963
53219
  AdhdevDaemon = class _AdhdevDaemon {
52964
53220
  localHttpServer = null;
52965
53221
  localWss = null;