@adhdev/daemon-core 0.8.46 → 0.8.48

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.
@@ -591,6 +591,12 @@ export interface ProviderControlDef {
591
591
  invokeScript?: string;
592
592
  /** How to display action result: 'toast' = notification, 'inline' = show in bar, 'none' = silent */
593
593
  resultDisplay?: 'toast' | 'inline' | 'none';
594
+ /** Optional confirmation title shown before invoking a destructive or disruptive action */
595
+ confirmTitle?: string;
596
+ /** Optional confirmation message shown before invoking a destructive or disruptive action */
597
+ confirmMessage?: string;
598
+ /** Optional confirmation button label */
599
+ confirmLabel?: string;
594
600
  min?: number;
595
601
  max?: number;
596
602
  step?: number;
@@ -330,6 +330,12 @@ export interface ProviderControlSchema {
330
330
  invokeScript?: string;
331
331
  /** How to display action result */
332
332
  resultDisplay?: 'toast' | 'inline' | 'none';
333
+ /** Optional confirmation title shown before invoking the action */
334
+ confirmTitle?: string;
335
+ /** Optional confirmation message shown before invoking the action */
336
+ confirmMessage?: string;
337
+ /** Optional confirmation button label */
338
+ confirmLabel?: string;
333
339
  /** Slider range */
334
340
  min?: number;
335
341
  max?: number;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.8.46",
3
+ "version": "0.8.48",
4
4
  "description": "ADHDev local session host core — session registry, protocol, buffers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.8.46",
3
+ "version": "0.8.48",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -775,6 +775,8 @@ export class DaemonCdpManager {
775
775
  }
776
776
 
777
777
  const pageWebviewUrls = await this.getCurrentPageWebviewUrls();
778
+ const pageWebviewOrder = new Map<string, number>();
779
+ Array.from(pageWebviewUrls).forEach((url, index) => pageWebviewOrder.set(url, index));
778
780
 
779
781
  const iframes = allTargets.filter((t: any) => t.type === 'iframe');
780
782
  const typeMap = new Map<string, number>();
@@ -821,7 +823,16 @@ export class DaemonCdpManager {
821
823
  }
822
824
  }
823
825
  }
824
-
826
+
827
+ agents.sort((lhs, rhs) => {
828
+ const leftOrder = pageWebviewOrder.get(lhs.url);
829
+ const rightOrder = pageWebviewOrder.get(rhs.url);
830
+ if (leftOrder != null && rightOrder != null) return leftOrder - rightOrder;
831
+ if (leftOrder != null) return -1;
832
+ if (rightOrder != null) return 1;
833
+ return lhs.url.localeCompare(rhs.url);
834
+ });
835
+
825
836
  this._lastDiscoveredTargets = new Set(agents.map(a => a.targetId));
826
837
  return agents;
827
838
  } catch (e) {
@@ -980,6 +991,26 @@ export class DaemonCdpManager {
980
991
  private async getCurrentPageWebviewUrls(): Promise<Set<string>> {
981
992
  if (!this.isConnected) return new Set();
982
993
 
994
+ try {
995
+ const raw = await this.evaluate(
996
+ `JSON.stringify(Array.from(document.querySelectorAll('iframe,webview'))
997
+ .filter((el) => {
998
+ const rect = el.getBoundingClientRect();
999
+ if (rect.width <= 8 || rect.height <= 8) return false;
1000
+ const style = window.getComputedStyle(el);
1001
+ return style.display !== 'none' && style.visibility !== 'hidden';
1002
+ })
1003
+ .map((el) => el.src || el.getAttribute('src') || '')
1004
+ .filter((src) => typeof src === 'string' && src.includes('vscode-webview')))`,
1005
+ 5000,
1006
+ );
1007
+ const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
1008
+ if (Array.isArray(parsed)) {
1009
+ const urls = parsed.filter((src: unknown): src is string => typeof src === 'string' && src.length > 0);
1010
+ if (urls.length > 0) return new Set(urls);
1011
+ }
1012
+ } catch { /* fall through to frame tree */ }
1013
+
983
1014
  try {
984
1015
  const urls = new Set<string>();
985
1016
  const { frameTree } = await this.sendInternal('Page.getFrameTree', {}, 5000);
@@ -991,19 +1022,7 @@ export class DaemonCdpManager {
991
1022
  for (const child of node?.childFrames || []) visit(child);
992
1023
  };
993
1024
  if (frameTree) visit(frameTree);
994
- if (urls.size > 0) return urls;
995
- } catch { /* fall through to DOM scan */ }
996
-
997
- try {
998
- const raw = await this.evaluate(
999
- `JSON.stringify(Array.from(document.querySelectorAll('iframe,webview'))
1000
- .map((el) => el.src || el.getAttribute('src') || '')
1001
- .filter((src) => typeof src === 'string' && src.includes('vscode-webview')))`,
1002
- 5000,
1003
- );
1004
- const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;
1005
- if (!Array.isArray(parsed)) return new Set();
1006
- return new Set(parsed.filter((src: unknown): src is string => typeof src === 'string' && src.length > 0));
1025
+ return urls;
1007
1026
  } catch {
1008
1027
  return new Set();
1009
1028
  }
@@ -238,7 +238,9 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
238
238
  const targetSessionId = managed?.cdpSessionId || null;
239
239
 
240
240
  // IDE-level scripts (model/mode) — try session frame first, fallback to main page
241
- const IDE_LEVEL_SCRIPTS = ['listModes', 'setMode', 'listModels', 'setModel'];
241
+ const IDE_LEVEL_SCRIPTS = provider.type === 'claude-code-vscode'
242
+ ? ['listModes', 'setMode']
243
+ : ['listModes', 'setMode', 'listModels', 'setModel'];
242
244
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
243
245
  // Try session frame first (some extensions embed mode selector in their webview)
244
246
  if (targetSessionId) {
@@ -260,14 +260,30 @@ export class CliProviderInstance implements ProviderInstance {
260
260
  }
261
261
  const runtime = this.adapter.getRuntimeMetadata();
262
262
  this.maybeAppendRuntimeRecoveryMessage(runtime);
263
- const parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
263
+ let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
264
+ const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount)
265
+ ? Math.max(0, Number(parsedStatus.historyMessageCount))
266
+ : null;
267
+ if (historyMessageCount !== null) {
268
+ parsedMessages = historyMessageCount > 0
269
+ ? parsedMessages.slice(-historyMessageCount)
270
+ : [];
271
+ }
264
272
  const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
265
273
  if (controlValues) {
266
- this.controlValues = controlValues;
267
- } else if (Object.keys(this.controlValues).length > 0) {
268
- this.controlValues = {};
274
+ this.controlValues = { ...this.controlValues, ...controlValues };
269
275
  }
270
276
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
277
+ const currentModel = typeof parsedStatus?.model === 'string' && parsedStatus.model.trim()
278
+ ? parsedStatus.model.trim()
279
+ : (typeof this.controlValues.model === 'string' && this.controlValues.model.trim()
280
+ ? this.controlValues.model.trim()
281
+ : undefined);
282
+ const currentPlan = typeof parsedStatus?.mode === 'string' && parsedStatus.mode.trim()
283
+ ? parsedStatus.mode.trim()
284
+ : (typeof this.controlValues.mode === 'string' && this.controlValues.mode.trim()
285
+ ? this.controlValues.mode.trim()
286
+ : undefined);
271
287
 
272
288
  const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
273
289
 
@@ -313,6 +329,8 @@ export class CliProviderInstance implements ProviderInstance {
313
329
  inputContent: '',
314
330
  },
315
331
  workspace: this.workingDir,
332
+ currentModel,
333
+ currentPlan,
316
334
  instanceId: this.instanceId,
317
335
  providerSessionId: this.providerSessionId,
318
336
  lastUpdated: Date.now(),
@@ -513,6 +531,19 @@ export class CliProviderInstance implements ProviderInstance {
513
531
  private applyProviderResponse(data: any, options: { phase: 'immediate' | 'turn_completed' }): void {
514
532
  if (!data || typeof data !== 'object') return;
515
533
 
534
+ const patchedProviderSessionId = typeof data.providerSessionId === 'string'
535
+ ? data.providerSessionId.trim()
536
+ : '';
537
+ if (patchedProviderSessionId) {
538
+ this.promoteProviderSessionId(patchedProviderSessionId);
539
+ }
540
+
541
+ if (data.sessionEvent === 'new_session') {
542
+ this.runtimeMessages = [];
543
+ this.suppressIdleHistoryReplay = false;
544
+ this.adapter.clearHistory();
545
+ }
546
+
516
547
  const controlValues = extractProviderControlValues(this.provider.controls, data);
517
548
  if (controlValues) {
518
549
  this.controlValues = { ...this.controlValues, ...controlValues };
@@ -722,6 +722,12 @@ export interface ProviderControlDef {
722
722
  invokeScript?: string;
723
723
  /** How to display action result: 'toast' = notification, 'inline' = show in bar, 'none' = silent */
724
724
  resultDisplay?: 'toast' | 'inline' | 'none';
725
+ /** Optional confirmation title shown before invoking a destructive or disruptive action */
726
+ confirmTitle?: string;
727
+ /** Optional confirmation message shown before invoking a destructive or disruptive action */
728
+ confirmMessage?: string;
729
+ /** Optional confirmation button label */
730
+ confirmLabel?: string;
725
731
 
726
732
  // ─── Slider-specific ───
727
733
  min?: number;
@@ -397,6 +397,12 @@ export interface ProviderControlSchema {
397
397
  invokeScript?: string;
398
398
  /** How to display action result */
399
399
  resultDisplay?: 'toast' | 'inline' | 'none';
400
+ /** Optional confirmation title shown before invoking the action */
401
+ confirmTitle?: string;
402
+ /** Optional confirmation message shown before invoking the action */
403
+ confirmMessage?: string;
404
+ /** Optional confirmation button label */
405
+ confirmLabel?: string;
400
406
  /** Slider range */
401
407
  min?: number;
402
408
  max?: number;