@adhdev/daemon-core 0.6.76 → 0.6.79

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
@@ -1814,6 +1814,8 @@ __export(index_exports, {
1814
1814
  isCdpConnected: () => isCdpConnected,
1815
1815
  isExtensionInstalled: () => isExtensionInstalled,
1816
1816
  isIdeRunning: () => isIdeRunning,
1817
+ isManagedStatusWaiting: () => isManagedStatusWaiting,
1818
+ isManagedStatusWorking: () => isManagedStatusWorking,
1817
1819
  isSetupComplete: () => isSetupComplete,
1818
1820
  killIdeProcess: () => killIdeProcess,
1819
1821
  launchIDE: () => launchIDE,
@@ -1821,6 +1823,8 @@ __export(index_exports, {
1821
1823
  loadConfig: () => loadConfig,
1822
1824
  logCommand: () => logCommand,
1823
1825
  markSetupComplete: () => markSetupComplete,
1826
+ normalizeActiveChatData: () => normalizeActiveChatData,
1827
+ normalizeManagedStatus: () => normalizeManagedStatus,
1824
1828
  probeCdpPort: () => probeCdpPort,
1825
1829
  readChatHistory: () => readChatHistory,
1826
1830
  registerExtensionProviders: () => registerExtensionProviders,
@@ -2711,9 +2715,12 @@ var DaemonCdpManager = class {
2711
2715
  };
2712
2716
  try {
2713
2717
  const { targetInfos } = await sendWs("Target.getTargets");
2714
- const webviewIframes = (targetInfos || []).filter(
2715
- (t) => t.type === "iframe" && (t.url || "").includes("vscode-webview")
2716
- );
2718
+ const pageWebviewUrls = await this.getCurrentPageWebviewUrls();
2719
+ const webviewIframes = (targetInfos || []).filter((t) => {
2720
+ if (t.type !== "iframe" || !(t.url || "").includes("vscode-webview")) return false;
2721
+ if (pageWebviewUrls.size === 0) return true;
2722
+ return pageWebviewUrls.has(t.url || "");
2723
+ });
2717
2724
  if (webviewIframes.length === 0) {
2718
2725
  this.log("[CDP] evaluateInWebviewFrame: no webview iframes found");
2719
2726
  return null;
@@ -2800,6 +2807,7 @@ var DaemonCdpManager = class {
2800
2807
  const result = await this.sendInternal("Target.getTargets");
2801
2808
  allTargets = result?.targetInfos || [];
2802
2809
  }
2810
+ const pageWebviewUrls = await this.getCurrentPageWebviewUrls();
2803
2811
  const iframes = allTargets.filter((t) => t.type === "iframe");
2804
2812
  const typeMap = /* @__PURE__ */ new Map();
2805
2813
  for (const t of allTargets) {
@@ -2825,6 +2833,7 @@ var DaemonCdpManager = class {
2825
2833
  const url = target.url || "";
2826
2834
  const hasWebview = url.includes("vscode-webview");
2827
2835
  if (!hasWebview) continue;
2836
+ if (pageWebviewUrls.size > 0 && !pageWebviewUrls.has(url)) continue;
2828
2837
  for (const known of this.extensionProviders) {
2829
2838
  if (known.extensionIdPattern.test(url)) {
2830
2839
  agents.push({
@@ -2972,6 +2981,22 @@ var DaemonCdpManager = class {
2972
2981
  getAgentSessions() {
2973
2982
  return this.agentSessions;
2974
2983
  }
2984
+ async getCurrentPageWebviewUrls() {
2985
+ if (!this.isConnected) return /* @__PURE__ */ new Set();
2986
+ try {
2987
+ const raw = await this.evaluate(
2988
+ `JSON.stringify(Array.from(document.querySelectorAll('iframe,webview'))
2989
+ .map((el) => el.src || el.getAttribute('src') || '')
2990
+ .filter((src) => typeof src === 'string' && src.includes('vscode-webview')))`,
2991
+ 5e3
2992
+ );
2993
+ const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
2994
+ if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
2995
+ return new Set(parsed.filter((src) => typeof src === "string" && src.length > 0));
2996
+ } catch {
2997
+ return /* @__PURE__ */ new Set();
2998
+ }
2999
+ }
2975
3000
  // ─── Screenshot ──────────────────────────────────────────
2976
3001
  async captureScreenshot(opts) {
2977
3002
  if (!this.isConnected) return null;
@@ -4443,6 +4468,45 @@ var DaemonCdpInitializer = class {
4443
4468
  }
4444
4469
  };
4445
4470
 
4471
+ // src/status/normalize.ts
4472
+ var WORKING_STATUSES = /* @__PURE__ */ new Set([
4473
+ "generating",
4474
+ "streaming",
4475
+ "loading",
4476
+ "loading_reference",
4477
+ "thinking",
4478
+ "active"
4479
+ ]);
4480
+ function hasApprovalButtons(activeModal) {
4481
+ return (activeModal?.buttons?.length ?? 0) > 0;
4482
+ }
4483
+ function normalizeManagedStatus(status, opts) {
4484
+ if (hasApprovalButtons(opts?.activeModal)) return "waiting_approval";
4485
+ const normalized = String(status || "idle").trim().toLowerCase();
4486
+ if (normalized === "waiting_approval") return "waiting_approval";
4487
+ if (WORKING_STATUSES.has(normalized)) return "generating";
4488
+ if (normalized === "error") return "error";
4489
+ if (normalized === "stopped") return "stopped";
4490
+ if (normalized === "starting") return "starting";
4491
+ if (normalized === "panel_hidden") return "panel_hidden";
4492
+ if (normalized === "not_monitored") return "not_monitored";
4493
+ if (normalized === "disconnected") return "disconnected";
4494
+ return "idle";
4495
+ }
4496
+ function isManagedStatusWorking(status) {
4497
+ return normalizeManagedStatus(status) === "generating";
4498
+ }
4499
+ function isManagedStatusWaiting(status, opts) {
4500
+ return normalizeManagedStatus(status, opts) === "waiting_approval";
4501
+ }
4502
+ function normalizeActiveChatData(activeChat) {
4503
+ if (!activeChat) return activeChat;
4504
+ return {
4505
+ ...activeChat,
4506
+ status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal })
4507
+ };
4508
+ }
4509
+
4446
4510
  // src/status/builders.ts
4447
4511
  function findCdpManager(cdpManagers, key) {
4448
4512
  const exact = cdpManagers.get(key);
@@ -4476,13 +4540,13 @@ function buildManagedIdes(ideStates, cdpManagers, opts) {
4476
4540
  workspace: state.workspace || null,
4477
4541
  terminals: 0,
4478
4542
  aiAgents: [],
4479
- activeChat: state.activeChat,
4543
+ activeChat: normalizeActiveChatData(state.activeChat),
4480
4544
  chats: [],
4481
4545
  agentStreams: state.extensions.map((ext) => ({
4482
4546
  agentType: ext.type,
4483
4547
  agentName: ext.name,
4484
4548
  extensionId: ext.type,
4485
- status: ext.status || "idle",
4549
+ status: normalizeManagedStatus(ext.status, { activeModal: ext.activeChat?.activeModal || null }),
4486
4550
  messages: ext.activeChat?.messages || [],
4487
4551
  inputContent: ext.activeChat?.inputContent || "",
4488
4552
  activeModal: ext.activeChat?.activeModal || null
@@ -4522,10 +4586,10 @@ function buildManagedClis(cliStates) {
4522
4586
  instanceId: s.instanceId,
4523
4587
  cliType: s.type,
4524
4588
  cliName: s.name,
4525
- status: s.status,
4589
+ status: normalizeManagedStatus(s.status, { activeModal: s.activeChat?.activeModal || null }),
4526
4590
  mode: "terminal",
4527
4591
  workspace: s.workspace || "",
4528
- activeChat: s.activeChat
4592
+ activeChat: normalizeActiveChatData(s.activeChat)
4529
4593
  }));
4530
4594
  }
4531
4595
  function buildManagedAcps(acpStates) {
@@ -4533,10 +4597,10 @@ function buildManagedAcps(acpStates) {
4533
4597
  id: s.instanceId,
4534
4598
  acpType: s.type,
4535
4599
  acpName: s.name,
4536
- status: s.status,
4600
+ status: normalizeManagedStatus(s.status, { activeModal: s.activeChat?.activeModal || null }),
4537
4601
  mode: "chat",
4538
4602
  workspace: s.workspace || "",
4539
- activeChat: s.activeChat,
4603
+ activeChat: normalizeActiveChatData(s.activeChat),
4540
4604
  currentModel: s.currentModel,
4541
4605
  currentPlan: s.currentPlan,
4542
4606
  acpConfigOptions: s.acpConfigOptions,
@@ -4623,8 +4687,8 @@ async function handleReadChat(h, args) {
4623
4687
  }
4624
4688
  if (h.agentStream) {
4625
4689
  const cdp2 = h.getCdp();
4626
- if (cdp2) {
4627
- const streams = await h.agentStream.collectAgentStreams(cdp2);
4690
+ if (cdp2 && h.currentIdeType) {
4691
+ const streams = await h.agentStream.collectAgentStreams(cdp2, h.currentIdeType);
4628
4692
  const stream = streams.find((s) => s.agentType === provider.type);
4629
4693
  if (stream) {
4630
4694
  h.historyWriter.appendNewMessages(
@@ -4748,8 +4812,8 @@ async function handleSendChat(h, args) {
4748
4812
  } catch (e) {
4749
4813
  _log(`Extension script error: ${e.message}`);
4750
4814
  }
4751
- if (h.agentStream && h.getCdp()) {
4752
- const ok = await h.agentStream.sendToAgent(h.getCdp(), provider.type, text, h.currentIdeType);
4815
+ if (h.agentStream && h.getCdp() && h.currentIdeType) {
4816
+ const ok = await h.agentStream.sendToAgent(h.getCdp(), h.currentIdeType, provider.type, text, h.currentIdeType);
4753
4817
  if (ok) {
4754
4818
  _log(`AgentStreamManager sent OK`);
4755
4819
  return _logSendSuccess("agent-stream");
@@ -4868,9 +4932,9 @@ async function handleSendChat(h, args) {
4868
4932
  }
4869
4933
  async function handleListChats(h, args) {
4870
4934
  const provider = h.getProvider(args?.agentType);
4871
- if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
4935
+ if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentIdeType) {
4872
4936
  try {
4873
- const chats = await h.agentStream.listAgentChats(h.getCdp(), provider.type);
4937
+ const chats = await h.agentStream.listAgentChats(h.getCdp(), h.currentIdeType, provider.type);
4874
4938
  LOG.info("Command", `[list_chats] Extension: ${chats.length} chats`);
4875
4939
  return { success: true, chats };
4876
4940
  } catch (e) {
@@ -4929,8 +4993,8 @@ async function handleNewChat(h, args) {
4929
4993
  }
4930
4994
  return { success: false, error: "new_chat not supported by this CLI provider" };
4931
4995
  }
4932
- if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
4933
- const ok = await h.agentStream.newAgentSession(h.getCdp(), provider.type, h.currentIdeType);
4996
+ if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentIdeType) {
4997
+ const ok = await h.agentStream.newAgentSession(h.getCdp(), h.currentIdeType, provider.type, h.currentIdeType);
4934
4998
  return { success: ok };
4935
4999
  }
4936
5000
  try {
@@ -4958,8 +5022,8 @@ async function handleSwitchChat(h, args) {
4958
5022
  const sessionId = args?.sessionId || args?.id || args?.chatId;
4959
5023
  if (!sessionId) return { success: false, error: "sessionId required" };
4960
5024
  LOG.info("Command", `[switch_chat] sessionId=${sessionId}, ideType=${ideType}`);
4961
- if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
4962
- const ok = await h.agentStream.switchAgentSession(h.getCdp(), provider.type, sessionId);
5025
+ if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentIdeType) {
5026
+ const ok = await h.agentStream.switchAgentSession(h.getCdp(), h.currentIdeType, provider.type, sessionId);
4963
5027
  return { success: ok, result: ok ? "switched" : "failed" };
4964
5028
  }
4965
5029
  const cdp = h.getCdp(ideType);
@@ -5225,9 +5289,10 @@ async function handleResolveAction(h, args) {
5225
5289
  LOG.info("Command", `[resolveAction] CLI PTY \u2192 buttonIndex=${buttonIndex} "${buttons[buttonIndex] ?? "?"}"`);
5226
5290
  return { success: true, buttonIndex, button: buttons[buttonIndex] ?? button };
5227
5291
  }
5228
- if (provider?.category === "extension" && h.agentStream && h.getCdp()) {
5292
+ if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentIdeType) {
5229
5293
  const ok = await h.agentStream.resolveAgentAction(
5230
5294
  h.getCdp(),
5295
+ h.currentIdeType,
5231
5296
  provider.type,
5232
5297
  action,
5233
5298
  h.currentIdeType
@@ -5592,14 +5657,14 @@ async function handleFileListBrowse(h, args) {
5592
5657
  init_config();
5593
5658
  init_logger();
5594
5659
  async function handleAgentStreamSwitch(h, args) {
5595
- if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5660
+ if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: "AgentStream or CDP not available" };
5596
5661
  const agentType = args?.agentType || args?.agent || null;
5597
- await h.agentStream.switchActiveAgent(h.getCdp(), agentType);
5662
+ await h.agentStream.switchActiveAgent(h.getCdp(), h.currentIdeType, agentType);
5598
5663
  return { success: true, activeAgent: agentType };
5599
5664
  }
5600
5665
  async function handleAgentStreamRead(h, args) {
5601
- if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5602
- const streams = await h.agentStream.collectAgentStreams(h.getCdp());
5666
+ if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: "AgentStream or CDP not available" };
5667
+ const streams = await h.agentStream.collectAgentStreams(h.getCdp(), h.currentIdeType);
5603
5668
  return { success: true, streams };
5604
5669
  }
5605
5670
  async function handleAgentStreamSend(h, args) {
@@ -5621,47 +5686,53 @@ async function handleAgentStreamSend(h, args) {
5621
5686
  }
5622
5687
  }
5623
5688
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5624
- const resolvedAgent = agentType || h.agentStream.activeAgentType;
5689
+ const resolvedAgent = agentType || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5625
5690
  if (!resolvedAgent) return { success: false, error: "agentType required" };
5626
- const ok = await h.agentStream.sendToAgent(h.getCdp(), resolvedAgent, text, h.currentIdeType);
5691
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5692
+ const ok = await h.agentStream.sendToAgent(h.getCdp(), h.currentIdeType, resolvedAgent, text, h.currentIdeType);
5627
5693
  return { success: ok };
5628
5694
  }
5629
5695
  async function handleAgentStreamResolve(h, args) {
5630
5696
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5631
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
5697
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5632
5698
  const action = args?.action || "approve";
5633
5699
  if (!agentType) return { success: false, error: "agentType required" };
5634
- const ok = await h.agentStream.resolveAgentAction(h.getCdp(), agentType, action, h.currentIdeType);
5700
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5701
+ const ok = await h.agentStream.resolveAgentAction(h.getCdp(), h.currentIdeType, agentType, action, h.currentIdeType);
5635
5702
  return { success: ok };
5636
5703
  }
5637
5704
  async function handleAgentStreamNew(h, args) {
5638
5705
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5639
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
5706
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5640
5707
  if (!agentType) return { success: false, error: "agentType required" };
5641
- const ok = await h.agentStream.newAgentSession(h.getCdp(), agentType, h.currentIdeType);
5708
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5709
+ const ok = await h.agentStream.newAgentSession(h.getCdp(), h.currentIdeType, agentType, h.currentIdeType);
5642
5710
  return { success: ok };
5643
5711
  }
5644
5712
  async function handleAgentStreamListChats(h, args) {
5645
5713
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5646
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
5714
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5647
5715
  if (!agentType) return { success: false, error: "agentType required" };
5648
- const chats = await h.agentStream.listAgentChats(h.getCdp(), agentType);
5716
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5717
+ const chats = await h.agentStream.listAgentChats(h.getCdp(), h.currentIdeType, agentType);
5649
5718
  return { success: true, chats };
5650
5719
  }
5651
5720
  async function handleAgentStreamSwitchSession(h, args) {
5652
5721
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5653
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
5722
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5654
5723
  const sessionId = args?.sessionId || args?.id;
5655
5724
  if (!agentType || !sessionId) return { success: false, error: "agentType and sessionId required" };
5656
- const ok = await h.agentStream.switchAgentSession(h.getCdp(), agentType, sessionId);
5725
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5726
+ const ok = await h.agentStream.switchAgentSession(h.getCdp(), h.currentIdeType, agentType, sessionId);
5657
5727
  return { success: ok };
5658
5728
  }
5659
5729
  async function handleAgentStreamFocus(h, args) {
5660
5730
  if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
5661
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
5731
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
5662
5732
  if (!agentType) return { success: false, error: "agentType required" };
5663
5733
  await h.agentStream.ensureAgentPanelOpen(agentType, h.currentIdeType);
5664
- const ok = await h.agentStream.focusAgentEditor(h.getCdp(), agentType);
5734
+ if (!h.currentIdeType) return { success: false, error: "ideType required" };
5735
+ const ok = await h.agentStream.focusAgentEditor(h.getCdp(), h.currentIdeType, agentType);
5665
5736
  return { success: ok };
5666
5737
  }
5667
5738
  function handlePtyInput(h, args) {
@@ -6021,7 +6092,7 @@ var DaemonCommandHandler = class {
6021
6092
  const key = ideType || this._currentIdeType;
6022
6093
  if (!key) return null;
6023
6094
  const resolved = this._ctx.instanceIdMap?.get(key) || key;
6024
- const m = findCdpManager(this._ctx.cdpManagers, resolved.toLowerCase());
6095
+ const m = findCdpManager(this._ctx.cdpManagers, resolved);
6025
6096
  if (m?.isConnected) return m;
6026
6097
  return null;
6027
6098
  }
@@ -6062,11 +6133,11 @@ var DaemonCommandHandler = class {
6062
6133
  const cdp = this.getCdp();
6063
6134
  if (!cdp?.isConnected) return null;
6064
6135
  if (provider?.category === "extension") {
6065
- let sessionId = this.getExtensionSessionId(provider);
6066
- if (!sessionId && this._agentStream) {
6067
- await this._agentStream.switchActiveAgent(cdp, provider.type);
6068
- await this._agentStream.syncAgentSessions(cdp);
6069
- sessionId = this.getExtensionSessionId(provider);
6136
+ let sessionId = this.getExtensionSessionId(provider, this._currentIdeType);
6137
+ if (!sessionId && this._agentStream && this._currentIdeType) {
6138
+ await this._agentStream.switchActiveAgent(cdp, this._currentIdeType, provider.type);
6139
+ await this._agentStream.syncAgentSessions(cdp, this._currentIdeType);
6140
+ sessionId = this.getExtensionSessionId(provider, this._currentIdeType);
6070
6141
  }
6071
6142
  if (!sessionId) return null;
6072
6143
  const result2 = await cdp.evaluateInSessionFrame(sessionId, script, timeout);
@@ -6092,15 +6163,39 @@ var DaemonCommandHandler = class {
6092
6163
  return null;
6093
6164
  }
6094
6165
  // ─── Private helpers ──────────────────────────────
6095
- getExtensionSessionId(provider) {
6096
- if (provider.category !== "extension" || !this._agentStream) return null;
6097
- const managed = this._agentStream.getManagedAgent(provider.type);
6166
+ getExtensionSessionId(provider, scopeKey) {
6167
+ if (provider.category !== "extension" || !this._agentStream || !scopeKey) return null;
6168
+ const managed = this._agentStream.getManagedAgent(provider.type, scopeKey);
6098
6169
  return managed?.sessionId || null;
6099
6170
  }
6171
+ resolveManagerKeyFromInstanceId(instanceId) {
6172
+ const mapped = this._ctx.instanceIdMap?.get(instanceId);
6173
+ if (mapped) return mapped;
6174
+ const entries = this._ctx.instanceManager?.instances?.entries?.();
6175
+ if (!entries) return void 0;
6176
+ for (const [instanceKey, instance] of entries) {
6177
+ if (typeof instanceKey !== "string" || !instanceKey.startsWith("ide:")) continue;
6178
+ if (typeof instance?.getInstanceId === "function" && instance.getInstanceId() === instanceId) {
6179
+ const managerKey = instanceKey.slice(4);
6180
+ this._ctx.instanceIdMap?.set(instanceId, managerKey);
6181
+ return managerKey;
6182
+ }
6183
+ if (typeof instance?.getExtensionInstances === "function") {
6184
+ for (const ext of instance.getExtensionInstances() || []) {
6185
+ if (typeof ext?.getInstanceId === "function" && ext.getInstanceId() === instanceId) {
6186
+ const managerKey = instanceKey.slice(4);
6187
+ this._ctx.instanceIdMap?.set(instanceId, managerKey);
6188
+ return managerKey;
6189
+ }
6190
+ }
6191
+ }
6192
+ }
6193
+ return void 0;
6194
+ }
6100
6195
  /** Extract ideType from _targetInstance or explicit ideType */
6101
6196
  extractIdeType(args) {
6102
6197
  if (args?.ideType) {
6103
- const mappedKey = this._ctx.instanceIdMap?.get(args.ideType);
6198
+ const mappedKey = this.resolveManagerKeyFromInstanceId(args.ideType);
6104
6199
  if (mappedKey) {
6105
6200
  return mappedKey;
6106
6201
  }
@@ -6122,8 +6217,9 @@ var DaemonCommandHandler = class {
6122
6217
  if (ideMatch) raw = ideMatch[1];
6123
6218
  else if (cliMatch) raw = cliMatch[1];
6124
6219
  else if (acpMatch) raw = acpMatch[1];
6125
- if (this._ctx.instanceIdMap?.has(raw)) {
6126
- return this._ctx.instanceIdMap.get(raw);
6220
+ const mappedKey = this.resolveManagerKeyFromInstanceId(raw);
6221
+ if (mappedKey) {
6222
+ return mappedKey;
6127
6223
  }
6128
6224
  if (this._ctx.cdpManagers.has(raw)) {
6129
6225
  return raw;
@@ -10078,12 +10174,12 @@ var ProviderStreamAdapter = class {
10078
10174
  init_logger();
10079
10175
  var DaemonAgentStreamManager = class {
10080
10176
  allAdapters = [];
10081
- managed = /* @__PURE__ */ new Map();
10177
+ managedByScope = /* @__PURE__ */ new Map();
10082
10178
  enabled = true;
10083
10179
  logFn;
10084
- lastDiscoveryTime = 0;
10085
- discoveryIntervalMs = 1e4;
10086
- _activeAgentType = null;
10180
+ lastDiscoveryTimeByScope = /* @__PURE__ */ new Map();
10181
+ discoveryIntervalMsByScope = /* @__PURE__ */ new Map();
10182
+ activeAgentTypeByScope = /* @__PURE__ */ new Map();
10087
10183
  constructor(logFn, providerLoader) {
10088
10184
  this.logFn = logFn || LOG.forComponent("AgentStream").asLogFn();
10089
10185
  if (providerLoader) {
@@ -10103,46 +10199,69 @@ var DaemonAgentStreamManager = class {
10103
10199
  get isEnabled() {
10104
10200
  return this.enabled;
10105
10201
  }
10106
- get activeAgentType() {
10107
- return this._activeAgentType;
10202
+ getActiveAgentType(scopeKey) {
10203
+ return this.activeAgentTypeByScope.get(scopeKey) || null;
10204
+ }
10205
+ getManagedScope(scopeKey) {
10206
+ let managed = this.managedByScope.get(scopeKey);
10207
+ if (!managed) {
10208
+ managed = /* @__PURE__ */ new Map();
10209
+ this.managedByScope.set(scopeKey, managed);
10210
+ }
10211
+ return managed;
10212
+ }
10213
+ resetScope(scopeKey) {
10214
+ this.managedByScope.delete(scopeKey);
10215
+ this.activeAgentTypeByScope.delete(scopeKey);
10216
+ this.lastDiscoveryTimeByScope.delete(scopeKey);
10217
+ this.discoveryIntervalMsByScope.delete(scopeKey);
10108
10218
  }
10109
10219
  /** Panel focus based on provider.js focusPanel or extensionId (currently no-op) */
10110
10220
  async ensureAgentPanelOpen(agentType, targetIdeType) {
10111
10221
  }
10112
- async switchActiveAgent(cdp, agentType) {
10113
- if (this._activeAgentType === agentType) return;
10114
- if (this._activeAgentType) {
10115
- const prev = this.managed.get(this._activeAgentType);
10222
+ async switchActiveAgent(cdp, scopeKey, agentType) {
10223
+ const managed = this.getManagedScope(scopeKey);
10224
+ const previousAgentType = this.getActiveAgentType(scopeKey);
10225
+ if (previousAgentType === agentType) return;
10226
+ if (previousAgentType) {
10227
+ const prev = managed.get(previousAgentType);
10116
10228
  if (prev) {
10117
10229
  try {
10118
10230
  await cdp.detachAgent(prev.sessionId);
10119
10231
  } catch {
10120
10232
  }
10121
- this.managed.delete(this._activeAgentType);
10122
- this.logFn(`[AgentStream] Deactivated: ${prev.adapter.agentName}`);
10233
+ managed.delete(previousAgentType);
10234
+ this.logFn(`[AgentStream] Deactivated: ${prev.adapter.agentName} (${scopeKey})`);
10123
10235
  }
10124
10236
  }
10125
- this._activeAgentType = agentType;
10126
- this.lastDiscoveryTime = 0;
10127
- this.logFn(`[AgentStream] Active agent: ${agentType || "none"}`);
10237
+ this.activeAgentTypeByScope.set(scopeKey, agentType);
10238
+ this.lastDiscoveryTimeByScope.set(scopeKey, 0);
10239
+ if (!agentType && managed.size === 0) {
10240
+ this.managedByScope.delete(scopeKey);
10241
+ }
10242
+ this.logFn(`[AgentStream] Active agent (${scopeKey}): ${agentType || "none"}`);
10128
10243
  }
10129
10244
  /** Agent webview discovery + session connection */
10130
- async syncAgentSessions(cdp) {
10131
- if (!this.enabled || !this._activeAgentType) return;
10245
+ async syncAgentSessions(cdp, scopeKey) {
10246
+ const activeAgentType = this.getActiveAgentType(scopeKey);
10247
+ if (!this.enabled || !activeAgentType) return;
10132
10248
  const now = Date.now();
10133
- if (this.managed.has(this._activeAgentType) && now - this.lastDiscoveryTime < this.discoveryIntervalMs) {
10249
+ const managed = this.getManagedScope(scopeKey);
10250
+ const lastDiscoveryTime = this.lastDiscoveryTimeByScope.get(scopeKey) || 0;
10251
+ const discoveryIntervalMs = this.discoveryIntervalMsByScope.get(scopeKey) || 1e4;
10252
+ if (managed.has(activeAgentType) && now - lastDiscoveryTime < discoveryIntervalMs) {
10134
10253
  return;
10135
10254
  }
10136
- this.lastDiscoveryTime = now;
10255
+ this.lastDiscoveryTimeByScope.set(scopeKey, now);
10137
10256
  try {
10138
10257
  const targets = await cdp.discoverAgentWebviews();
10139
- const activeTarget = targets.find((t) => t.agentType === this._activeAgentType);
10140
- if (activeTarget && !this.managed.has(this._activeAgentType)) {
10141
- const adapter = this.allAdapters.find((a) => a.agentType === this._activeAgentType);
10258
+ const activeTarget = targets.find((t) => t.agentType === activeAgentType);
10259
+ if (activeTarget && !managed.has(activeAgentType)) {
10260
+ const adapter = this.allAdapters.find((a) => a.agentType === activeAgentType);
10142
10261
  if (adapter) {
10143
10262
  const sessionId = await cdp.attachToAgent(activeTarget);
10144
10263
  if (sessionId) {
10145
- this.managed.set(this._activeAgentType, {
10264
+ managed.set(activeAgentType, {
10146
10265
  adapter,
10147
10266
  sessionId,
10148
10267
  target: activeTarget,
@@ -10150,28 +10269,30 @@ var DaemonAgentStreamManager = class {
10150
10269
  lastError: null,
10151
10270
  lastHiddenCheckTime: 0
10152
10271
  });
10153
- this.logFn(`[AgentStream] Connected: ${adapter.agentName}`);
10272
+ this.logFn(`[AgentStream] Connected: ${adapter.agentName} (${scopeKey})`);
10154
10273
  }
10155
10274
  }
10156
10275
  }
10157
- for (const [type, agent] of this.managed) {
10158
- if (type !== this._activeAgentType) {
10276
+ for (const [type, agent] of managed) {
10277
+ if (type !== activeAgentType) {
10159
10278
  await cdp.detachAgent(agent.sessionId);
10160
- this.managed.delete(type);
10279
+ managed.delete(type);
10161
10280
  }
10162
10281
  }
10163
- this.discoveryIntervalMs = this.managed.has(this._activeAgentType) ? 3e4 : 1e4;
10282
+ this.discoveryIntervalMsByScope.set(scopeKey, managed.has(activeAgentType) ? 3e4 : 1e4);
10164
10283
  } catch (e) {
10165
- this.logFn(`[AgentStream] sync error: ${e.message}`);
10284
+ this.logFn(`[AgentStream] sync error (${scopeKey}): ${e.message}`);
10166
10285
  }
10167
10286
  }
10168
10287
  /** Collect active agent status */
10169
- async collectAgentStreams(cdp) {
10288
+ async collectAgentStreams(cdp, scopeKey) {
10170
10289
  if (!this.enabled) return [];
10171
10290
  const results = [];
10172
- if (this._activeAgentType && this.managed.has(this._activeAgentType)) {
10173
- const agent = this.managed.get(this._activeAgentType);
10174
- const type = this._activeAgentType;
10291
+ const activeAgentType = this.getActiveAgentType(scopeKey);
10292
+ const managed = this.managedByScope.get(scopeKey);
10293
+ if (activeAgentType && managed?.has(activeAgentType)) {
10294
+ const agent = managed.get(activeAgentType);
10295
+ const type = activeAgentType;
10175
10296
  const isHidden = agent.lastState?.status === "panel_hidden";
10176
10297
  const hiddenCacheFresh = isHidden && Date.now() - agent.lastHiddenCheckTime < 3e4;
10177
10298
  if (hiddenCacheFresh) {
@@ -10204,17 +10325,17 @@ var DaemonAgentStreamManager = class {
10204
10325
  await cdp.detachAgent(agent.sessionId);
10205
10326
  } catch {
10206
10327
  }
10207
- this.managed.delete(type);
10208
- this.lastDiscoveryTime = 0;
10328
+ managed.delete(type);
10329
+ this.lastDiscoveryTimeByScope.set(scopeKey, 0);
10209
10330
  }
10210
10331
  }
10211
10332
  }
10212
10333
  }
10213
10334
  return results;
10214
10335
  }
10215
- async sendToAgent(cdp, agentType, text, targetIdeType) {
10336
+ async sendToAgent(cdp, scopeKey, agentType, text, targetIdeType) {
10216
10337
  await this.ensureAgentPanelOpen(agentType, targetIdeType);
10217
- const agent = this.managed.get(agentType);
10338
+ const agent = this.getManagedAgent(agentType, scopeKey);
10218
10339
  if (!agent) return false;
10219
10340
  try {
10220
10341
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.sessionId, expr, timeout);
@@ -10225,9 +10346,9 @@ var DaemonAgentStreamManager = class {
10225
10346
  return false;
10226
10347
  }
10227
10348
  }
10228
- async resolveAgentAction(cdp, agentType, action, targetIdeType) {
10349
+ async resolveAgentAction(cdp, scopeKey, agentType, action, targetIdeType) {
10229
10350
  await this.ensureAgentPanelOpen(agentType, targetIdeType);
10230
- const agent = this.managed.get(agentType);
10351
+ const agent = this.getManagedAgent(agentType, scopeKey);
10231
10352
  if (!agent) return false;
10232
10353
  try {
10233
10354
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.sessionId, expr, timeout);
@@ -10237,9 +10358,9 @@ var DaemonAgentStreamManager = class {
10237
10358
  return false;
10238
10359
  }
10239
10360
  }
10240
- async newAgentSession(cdp, agentType, targetIdeType) {
10361
+ async newAgentSession(cdp, scopeKey, agentType, targetIdeType) {
10241
10362
  await this.ensureAgentPanelOpen(agentType, targetIdeType);
10242
- const agent = this.managed.get(agentType);
10363
+ const agent = this.getManagedAgent(agentType, scopeKey);
10243
10364
  if (!agent) return false;
10244
10365
  try {
10245
10366
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.sessionId, expr, timeout);
@@ -10250,13 +10371,13 @@ var DaemonAgentStreamManager = class {
10250
10371
  return false;
10251
10372
  }
10252
10373
  }
10253
- async listAgentChats(cdp, agentType) {
10254
- let agent = this.managed.get(agentType);
10374
+ async listAgentChats(cdp, scopeKey, agentType) {
10375
+ let agent = this.getManagedAgent(agentType, scopeKey);
10255
10376
  if (!agent) {
10256
- this.logFn(`[AgentStream] listChats: ${agentType} not managed, trying on-demand activation`);
10257
- await this.switchActiveAgent(cdp, agentType);
10258
- await this.syncAgentSessions(cdp);
10259
- agent = this.managed.get(agentType);
10377
+ this.logFn(`[AgentStream] listChats: ${agentType} not managed in ${scopeKey}, trying on-demand activation`);
10378
+ await this.switchActiveAgent(cdp, scopeKey, agentType);
10379
+ await this.syncAgentSessions(cdp, scopeKey);
10380
+ agent = this.getManagedAgent(agentType, scopeKey);
10260
10381
  }
10261
10382
  if (!agent || typeof agent.adapter.listChats !== "function") return [];
10262
10383
  try {
@@ -10267,13 +10388,13 @@ var DaemonAgentStreamManager = class {
10267
10388
  return [];
10268
10389
  }
10269
10390
  }
10270
- async switchAgentSession(cdp, agentType, sessionId) {
10271
- let agent = this.managed.get(agentType);
10391
+ async switchAgentSession(cdp, scopeKey, agentType, sessionId) {
10392
+ let agent = this.getManagedAgent(agentType, scopeKey);
10272
10393
  if (!agent) {
10273
- this.logFn(`[AgentStream] switchSession: ${agentType} not managed, trying on-demand activation`);
10274
- await this.switchActiveAgent(cdp, agentType);
10275
- await this.syncAgentSessions(cdp);
10276
- agent = this.managed.get(agentType);
10394
+ this.logFn(`[AgentStream] switchSession: ${agentType} not managed in ${scopeKey}, trying on-demand activation`);
10395
+ await this.switchActiveAgent(cdp, scopeKey, agentType);
10396
+ await this.syncAgentSessions(cdp, scopeKey);
10397
+ agent = this.getManagedAgent(agentType, scopeKey);
10277
10398
  }
10278
10399
  if (!agent || typeof agent.adapter.switchSession !== "function") return false;
10279
10400
  try {
@@ -10284,8 +10405,8 @@ var DaemonAgentStreamManager = class {
10284
10405
  return false;
10285
10406
  }
10286
10407
  }
10287
- async focusAgentEditor(cdp, agentType) {
10288
- const agent = this.managed.get(agentType);
10408
+ async focusAgentEditor(cdp, scopeKey, agentType) {
10409
+ const agent = this.getManagedAgent(agentType, scopeKey);
10289
10410
  if (!agent || typeof agent.adapter.focusEditor !== "function") return false;
10290
10411
  try {
10291
10412
  const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.sessionId, expr, timeout);
@@ -10296,20 +10417,28 @@ var DaemonAgentStreamManager = class {
10296
10417
  return false;
10297
10418
  }
10298
10419
  }
10299
- getConnectedAgents() {
10300
- return Array.from(this.managed.keys());
10420
+ getConnectedAgents(scopeKey) {
10421
+ if (scopeKey) return Array.from((this.managedByScope.get(scopeKey) || /* @__PURE__ */ new Map()).keys());
10422
+ return Array.from(this.managedByScope.values()).flatMap((scope) => Array.from(scope.keys()));
10301
10423
  }
10302
- getManagedAgent(agentType) {
10303
- return this.managed.get(agentType);
10424
+ getManagedAgent(agentType, scopeKey) {
10425
+ return this.managedByScope.get(scopeKey)?.get(agentType);
10304
10426
  }
10305
- async dispose(cdp) {
10306
- for (const [, agent] of this.managed) {
10307
- try {
10308
- await cdp.detachAgent(agent.sessionId);
10309
- } catch {
10427
+ async dispose(cdpManagers) {
10428
+ for (const [scopeKey, managed] of this.managedByScope) {
10429
+ const cdp = cdpManagers.get(scopeKey);
10430
+ if (!cdp) continue;
10431
+ for (const [, agent] of managed) {
10432
+ try {
10433
+ await cdp.detachAgent(agent.sessionId);
10434
+ } catch {
10435
+ }
10310
10436
  }
10311
10437
  }
10312
- this.managed.clear();
10438
+ this.managedByScope.clear();
10439
+ this.activeAgentTypeByScope.clear();
10440
+ this.lastDiscoveryTimeByScope.clear();
10441
+ this.discoveryIntervalMsByScope.clear();
10313
10442
  }
10314
10443
  };
10315
10444
 
@@ -10317,20 +10446,17 @@ var DaemonAgentStreamManager = class {
10317
10446
  init_logger();
10318
10447
  var AgentStreamPoller = class {
10319
10448
  deps;
10320
- _activeIdeType = null;
10321
10449
  timer = null;
10322
10450
  constructor(deps) {
10323
10451
  this.deps = deps;
10324
10452
  }
10325
10453
  /** Currently active IDE type for agent streaming */
10326
10454
  get activeIde() {
10327
- return this._activeIdeType;
10455
+ return null;
10328
10456
  }
10329
10457
  /** Reset active IDE tracking (e.g., when IDE is stopped) */
10330
10458
  resetActiveIde(ideType) {
10331
- if (this._activeIdeType === ideType) {
10332
- this._activeIdeType = null;
10333
- }
10459
+ this.deps.agentStreamManager.resetScope(ideType);
10334
10460
  }
10335
10461
  /** Start polling (idempotent — ignored if already started) */
10336
10462
  start(intervalMs = 5e3) {
@@ -10380,49 +10506,43 @@ var AgentStreamPoller = class {
10380
10506
  }
10381
10507
  }
10382
10508
  }
10383
- if (this._activeIdeType === ideType && agentStreamManager.activeAgentType) {
10384
- const activeType = agentStreamManager.activeAgentType;
10509
+ const activeType = agentStreamManager.getActiveAgentType(ideType);
10510
+ if (activeType) {
10385
10511
  const enabledExtTypes = new Set(
10386
10512
  providerLoader.getEnabledExtensionProviders(ideType).map((p) => p.type)
10387
10513
  );
10388
10514
  if (!enabledExtTypes.has(activeType)) {
10389
10515
  LOG.info("AgentStream", `Active agent ${activeType} was disabled for ${ideType} \u2014 detaching`);
10390
- await agentStreamManager.switchActiveAgent(cdp, null);
10391
- this._activeIdeType = null;
10516
+ await agentStreamManager.switchActiveAgent(cdp, ideType, null);
10392
10517
  this.deps.onStreamsUpdated?.(ideType, []);
10393
10518
  }
10394
10519
  }
10395
- }
10396
- if (this._activeIdeType) {
10397
- const cdp = cdpManagers.get(this._activeIdeType);
10398
- if (cdp?.isConnected) {
10399
- try {
10400
- await agentStreamManager.syncAgentSessions(cdp);
10401
- const streams = await agentStreamManager.collectAgentStreams(cdp);
10402
- this.deps.onStreamsUpdated?.(this._activeIdeType, streams);
10403
- } catch {
10520
+ if (!cdp.isConnected) {
10521
+ if (activeType) {
10522
+ agentStreamManager.resetScope(ideType);
10523
+ this.deps.onStreamsUpdated?.(ideType, []);
10404
10524
  }
10405
- return;
10525
+ continue;
10406
10526
  }
10407
- this._activeIdeType = null;
10408
- }
10409
- if (!agentStreamManager.activeAgentType) {
10410
- for (const [ideType, cdp] of cdpManagers) {
10411
- if (!cdp.isConnected) continue;
10527
+ let resolvedActiveType = activeType;
10528
+ if (!resolvedActiveType) {
10412
10529
  try {
10413
10530
  const discovered = await cdp.discoverAgentWebviews();
10414
10531
  if (discovered.length > 0) {
10415
- this._activeIdeType = ideType;
10416
- await agentStreamManager.switchActiveAgent(cdp, discovered[0].agentType);
10417
- LOG.info("AgentStream", `Auto-activated: ${discovered[0].agentType} (${ideType})`);
10418
- await agentStreamManager.syncAgentSessions(cdp);
10419
- const streams = await agentStreamManager.collectAgentStreams(cdp);
10420
- this.deps.onStreamsUpdated?.(ideType, streams);
10421
- return;
10532
+ resolvedActiveType = discovered[0].agentType;
10533
+ await agentStreamManager.switchActiveAgent(cdp, ideType, resolvedActiveType);
10534
+ LOG.info("AgentStream", `Auto-activated: ${resolvedActiveType} (${ideType})`);
10422
10535
  }
10423
10536
  } catch {
10424
10537
  }
10425
10538
  }
10539
+ if (!resolvedActiveType) continue;
10540
+ try {
10541
+ await agentStreamManager.syncAgentSessions(cdp, ideType);
10542
+ const streams = await agentStreamManager.collectAgentStreams(cdp, ideType);
10543
+ this.deps.onStreamsUpdated?.(ideType, streams);
10544
+ } catch {
10545
+ }
10426
10546
  }
10427
10547
  }
10428
10548
  };
@@ -13525,14 +13645,16 @@ var DevServer = class _DevServer {
13525
13645
  lines.push("| Status | When to use | How to detect |");
13526
13646
  lines.push("|---|---|---|");
13527
13647
  lines.push("| `idle` | AI is NOT generating, no approval needed | Default state. No stop button, no spinners, no approval pills/buttons |");
13528
- lines.push("| `generating` | AI is actively streaming/thinking | ANY of: (1) Stop/Cancel button visible, (2) CSS animation (animate-spin/pulse/bounce), (3) floating state text like Thinking/Generating/Sailing, (4) streaming indicator class |");
13648
+ lines.push('| `generating` | AI is actively streaming/thinking | ANY of: (1) Submit button icon SVG changes (e.g. arrow\u2192stop square, fill="none"\u2192fill="currentColor"), (2) Stop/Cancel button visible, (3) CSS animation, (4) Structural markers (aria-labels that only appear during generation) |');
13529
13649
  lines.push("| `waiting_approval` | AI stopped and needs user action | Actionable buttons like Run/Skip/Accept/Reject are visible AND clickable |");
13530
13650
  lines.push("");
13531
13651
  lines.push("### \u26A0\uFE0F Status Detection Gotchas (MUST READ!)");
13532
- lines.push('1. **FALSE POSITIVES from old messages**: Chat history may contain text like "Command Awaiting Approval" from PAST turns. If you search the entire chat panel for this text, you will get false matches from parent divs whose innerText includes ALL child text. ONLY match small leaf elements (under 80 chars) or use explicit button/pill selectors.');
13533
- lines.push('2. **Awaiting Approval pill without actions**: Some IDEs show a floating pill/banner saying "Awaiting Approval" that is just a scroll-to indicator (not an actual approval dialog). If this pill exists but NO actionable buttons (Run/Skip/Accept/Reject) exist anywhere in the panel, the status should be `idle`, NOT `waiting_approval`.');
13534
- lines.push("3. **generating detection must be multi-signal**: Do NOT rely on just one indicator. Check ALL of: stop buttons, CSS animations, floating state labels, streaming classes. IDEs differ widely.");
13535
- lines.push("4. **activeModal must include actions**: When `status` is `waiting_approval`, the `activeModal` object MUST include a non-empty `actions` array listing the button labels. If you cannot find any action buttons, the status is NOT `waiting_approval`.");
13652
+ lines.push(`1. **DO NOT rely on button text/labels in the user's language.** OS locale may be Korean, Japanese, etc. Button text like "Cancel" or "Stop" will be localized. Instead, detect STRUCTURAL indicators: SVG icon changes, CSS classes, aria-labels from the extension's own React/Radix UI (which stay in English regardless of OS locale).`);
13653
+ lines.push('2. **Use sendMessage to CREATE a generating state, then CAPTURE the DOM.** Send a LONG prompt (e.g. "Write an extremely detailed 5000-word essay...") so the AI takes 10+ seconds. Then periodically capture the DOM during generation to find which elements appear/change. Compare idle vs generating DOM snapshots to find reliable structural markers.');
13654
+ lines.push("3. **Look for SVG icon changes in the submit button.** Many IDEs change the submit button icon from an arrow (send) to a square (stop) during generation. Check the SVG `fill` attribute or path data.");
13655
+ lines.push('4. **FALSE POSITIVES from old messages**: Chat history may contain text like "Command Awaiting Approval" from PAST turns. ONLY match small leaf elements (under 80 chars) or use explicit button/pill selectors.');
13656
+ lines.push("5. **Awaiting Approval pill without actions**: Some IDEs show a floating pill/banner that is just a scroll-to indicator. If NO actionable buttons exist, the status should be `idle`, NOT `waiting_approval`.");
13657
+ lines.push("6. **activeModal must include actions**: When `status` is `waiting_approval`, the `activeModal` object MUST include a non-empty `actions` array.");
13536
13658
  lines.push("");
13537
13659
  lines.push("## Action");
13538
13660
  lines.push("1. Edit the script files to implement working code");
@@ -13590,10 +13712,10 @@ var DevServer = class _DevServer {
13590
13712
  lines.push(`echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); r=d.get('result',d); r=json.loads(r) if isinstance(r,str) else r; assert r.get('status')=='idle', f'Expected idle, got {r.get(chr(34)+chr(115)+chr(116)+chr(97)+chr(116)+chr(117)+chr(115)+chr(34))}'; print('Step 1 PASS: status=idle')"`);
13591
13713
  lines.push("```");
13592
13714
  lines.push("");
13593
- lines.push("### Step 2: Send a message that triggers generation");
13715
+ lines.push("### Step 2: Send a LONG message that triggers extended generation (10+ seconds)");
13594
13716
  lines.push("```bash");
13595
- lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${type}", "args": {"message": "Say hello in one word"}}'`);
13596
- lines.push("sleep 2");
13717
+ lines.push(`curl -sS -X POST http://127.0.0.1:${DEV_SERVER_PORT}/api/scripts/run -H "Content-Type: application/json" -d '{"script": "sendMessage", "type": "${type}", "ideType": "${type}", "args": {"message": "Write an extremely detailed 5000-word essay about the history of artificial intelligence from Alan Turing to 2025. Be very thorough and verbose."}}'`);
13718
+ lines.push("sleep 3");
13597
13719
  lines.push("```");
13598
13720
  lines.push("");
13599
13721
  lines.push("### Step 3: Check generating OR completed");
@@ -14462,9 +14584,8 @@ async function shutdownDaemonComponents(components) {
14462
14584
  poller.stop();
14463
14585
  cdpInitializer.stop();
14464
14586
  try {
14465
- const anyCdp = [...cdpManagers.values()].find((m) => m.isConnected);
14466
- if (agentStreamManager && anyCdp) {
14467
- await agentStreamManager.dispose(anyCdp);
14587
+ if (agentStreamManager) {
14588
+ await agentStreamManager.dispose(cdpManagers);
14468
14589
  }
14469
14590
  } catch (e) {
14470
14591
  LOG.warn("Shutdown", `AgentStream dispose: ${e?.message}`);
@@ -14535,6 +14656,8 @@ async function shutdownDaemonComponents(components) {
14535
14656
  isCdpConnected,
14536
14657
  isExtensionInstalled,
14537
14658
  isIdeRunning,
14659
+ isManagedStatusWaiting,
14660
+ isManagedStatusWorking,
14538
14661
  isSetupComplete,
14539
14662
  killIdeProcess,
14540
14663
  launchIDE,
@@ -14542,6 +14665,8 @@ async function shutdownDaemonComponents(components) {
14542
14665
  loadConfig,
14543
14666
  logCommand,
14544
14667
  markSetupComplete,
14668
+ normalizeActiveChatData,
14669
+ normalizeManagedStatus,
14545
14670
  probeCdpPort,
14546
14671
  readChatHistory,
14547
14672
  registerExtensionProviders,