@adhdev/daemon-core 0.8.68 → 0.8.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/agent-stream/manager.d.ts +2 -1
  2. package/dist/agent-stream/provider-adapter.d.ts +6 -2
  3. package/dist/agent-stream/types.d.ts +5 -2
  4. package/dist/commands/stream-commands.d.ts +2 -1
  5. package/dist/config/recent-activity.d.ts +4 -3
  6. package/dist/index.js +286 -64
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +286 -64
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/providers/contracts.d.ts +10 -0
  11. package/dist/providers/extension-provider-instance.d.ts +1 -0
  12. package/dist/providers/open-panel-support.d.ts +6 -0
  13. package/dist/providers/provider-instance.d.ts +2 -1
  14. package/dist/shared-types.d.ts +1 -1
  15. package/dist/types.d.ts +1 -0
  16. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  17. package/package.json +1 -1
  18. package/src/agent-stream/forward.ts +1 -0
  19. package/src/agent-stream/manager.d.ts +2 -1
  20. package/src/agent-stream/manager.ts +20 -5
  21. package/src/agent-stream/provider-adapter.d.ts +3 -2
  22. package/src/agent-stream/provider-adapter.ts +123 -4
  23. package/src/agent-stream/types.d.ts +3 -2
  24. package/src/agent-stream/types.ts +5 -2
  25. package/src/cli-adapters/provider-cli-adapter.ts +3 -1
  26. package/src/commands/cli-manager.ts +12 -0
  27. package/src/commands/handler.ts +4 -2
  28. package/src/commands/router.ts +1 -0
  29. package/src/commands/stream-commands.d.ts +2 -1
  30. package/src/commands/stream-commands.ts +74 -2
  31. package/src/config/recent-activity.ts +25 -15
  32. package/src/daemon/dev-auto-implement.ts +2 -2
  33. package/src/daemon/dev-server.ts +2 -2
  34. package/src/daemon/scaffold-template.ts +12 -5
  35. package/src/providers/contracts.d.ts +10 -0
  36. package/src/providers/contracts.ts +14 -0
  37. package/src/providers/extension-provider-instance.ts +15 -2
  38. package/src/providers/ide-provider-instance.ts +2 -0
  39. package/src/providers/open-panel-support.ts +40 -0
  40. package/src/providers/provider-instance.d.ts +2 -1
  41. package/src/providers/provider-instance.ts +2 -1
  42. package/src/providers/provider-schema.ts +10 -0
  43. package/src/providers/read-chat-contract.ts +1 -0
  44. package/src/shared-types.d.ts +1 -1
  45. package/src/shared-types.ts +1 -0
  46. package/src/status/builders.ts +9 -23
  47. package/src/status/snapshot.ts +2 -2
  48. package/src/types.ts +1 -0
@@ -303,9 +303,14 @@ module.exports.setMode = (params) => {
303
303
  (() => {
304
304
  try {
305
305
  const input = document.querySelector('${meta.inputSelector || '[contenteditable="true"]'}');
306
- if (input) { input.focus(); return 'focused'; }
307
- return 'not_found';
308
- } catch(e) { return 'error'; }
306
+ if (input) {
307
+ input.focus();
308
+ return JSON.stringify({ focused: true });
309
+ }
310
+ return JSON.stringify({ focused: false, error: 'not_found' });
311
+ } catch(e) {
312
+ return JSON.stringify({ focused: false, error: e.message });
313
+ }
309
314
  })()
310
315
  `;
311
316
 
@@ -318,8 +323,10 @@ module.exports.setMode = (params) => {
318
323
  (() => {
319
324
  try {
320
325
  // TODO: Check if panel visible, if not find toggle button
321
- return 'not_found';
322
- } catch(e) { return 'error'; }
326
+ return JSON.stringify({ opened: false, visible: false, error: 'not_found' });
327
+ } catch(e) {
328
+ return JSON.stringify({ opened: false, visible: false, error: e.message });
329
+ }
323
330
  })()
324
331
  `;
325
332
 
@@ -191,6 +191,16 @@ export interface SwitchSessionResult {
191
191
  clickY?: number;
192
192
  error?: string;
193
193
  }
194
+ export interface FocusEditorResult {
195
+ focused: boolean;
196
+ error?: string;
197
+ }
198
+ export interface OpenPanelResult {
199
+ opened: boolean;
200
+ visible: boolean;
201
+ focused?: boolean;
202
+ error?: string;
203
+ }
194
204
  /**
195
205
  * Method 1: Script-Click — script calls el.click() directly
196
206
  * Cursor Suitable for IDEs using div.cursor-pointer elements.
@@ -267,6 +267,20 @@ export interface SwitchSessionResult {
267
267
  error?: string;
268
268
  }
269
269
 
270
+ // ─── focusEditor() / openPanel() return values ─────────
271
+
272
+ export interface FocusEditorResult {
273
+ focused: boolean;
274
+ error?: string;
275
+ }
276
+
277
+ export interface OpenPanelResult {
278
+ opened: boolean;
279
+ visible: boolean;
280
+ focused?: boolean;
281
+ error?: string;
282
+ }
283
+
270
284
  // ─── resolveAction() return value ──────────────────────
271
285
  // Two methods supported:
272
286
 
@@ -13,6 +13,7 @@ import { ChatHistoryWriter } from '../config/chat-history.js';
13
13
  import type { ChatMessage } from '../types.js';
14
14
  import { mergeProviderPatchState, resolveProviderStateSurface } from './provider-patch-state.js';
15
15
  import { buildChatMessage, buildRuntimeSystemChatMessage, normalizeChatMessages } from './chat-message-normalization.js';
16
+ import { getProviderSessionCapabilities, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE } from './open-panel-support.js';
16
17
 
17
18
  export class ExtensionProviderInstance implements ProviderInstance {
18
19
  readonly type: string;
@@ -42,6 +43,7 @@ export class ExtensionProviderInstance implements ProviderInstance {
42
43
  private instanceId: string;
43
44
  private ideType: string = '';
44
45
  private chatId: string | null = null;
46
+ private providerSessionId: string | null = null;
45
47
  private chatTitle: string | null = null;
46
48
  private agentName: string = '';
47
49
  private extensionId: string = '';
@@ -87,8 +89,10 @@ export class ExtensionProviderInstance implements ProviderInstance {
87
89
  name: this.provider.name,
88
90
  category: 'extension',
89
91
  status: this.currentStatus as ProviderState['status'],
92
+ providerSessionId: this.providerSessionId || this.chatId || undefined,
93
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE),
90
94
  activeChat: (this.messages.length > 0 || this.runtimeMessages.length > 0) ? {
91
- id: this.chatId || this.instanceId,
95
+ id: this.providerSessionId || this.chatId || this.instanceId,
92
96
  title: this.chatTitle || this.agentName || this.provider.name,
93
97
  status: this.currentStatus,
94
98
  messages: this.mergeConversationMessages(this.messages),
@@ -120,7 +124,15 @@ export class ExtensionProviderInstance implements ProviderInstance {
120
124
  });
121
125
  this.controlValues = patchedState.controlValues;
122
126
  this.summaryMetadata = patchedState.summaryMetadata;
123
- if (typeof data?.sessionId === 'string' && data.sessionId.trim()) this.chatId = data.sessionId;
127
+ const nextProviderSessionId = typeof data?.providerSessionId === 'string' && data.providerSessionId.trim()
128
+ ? data.providerSessionId.trim()
129
+ : typeof data?.sessionId === 'string' && data.sessionId.trim()
130
+ ? data.sessionId.trim()
131
+ : '';
132
+ if (nextProviderSessionId) {
133
+ this.providerSessionId = nextProviderSessionId;
134
+ this.chatId = nextProviderSessionId;
135
+ }
124
136
  if (typeof data?.title === 'string' && data.title.trim()) this.chatTitle = data.title;
125
137
  if (typeof data?.agentName === 'string' && data.agentName.trim()) this.agentName = data.agentName;
126
138
  if (typeof data?.extensionId === 'string' && data.extensionId.trim()) this.extensionId = data.extensionId;
@@ -464,6 +476,7 @@ export class ExtensionProviderInstance implements ProviderInstance {
464
476
  this.controlValues = {};
465
477
  this.currentStatus = 'idle';
466
478
  this.chatId = null;
479
+ this.providerSessionId = null;
467
480
  this.chatTitle = null;
468
481
  this.agentName = '';
469
482
  this.extensionId = '';
@@ -23,6 +23,7 @@ import type { ChatMessage } from '../types.js';
23
23
  import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.js';
24
24
  import { mergeProviderPatchState, resolveProviderStateSurface } from './provider-patch-state.js';
25
25
  import { buildChatMessage, buildRuntimeSystemChatMessage, normalizeChatMessages } from './chat-message-normalization.js';
26
+ import { getProviderSessionCapabilities, IDE_PROVIDER_SESSION_CAPABILITIES_BASE } from './open-panel-support.js';
26
27
 
27
28
  type ReadChatModal = {
28
29
  message?: string;
@@ -160,6 +161,7 @@ export class IdeProviderInstance implements ProviderInstance {
160
161
  workspace: this.workspace || null,
161
162
  extensions: extensionStates,
162
163
  cdpConnected: cdp?.isConnected || false,
164
+ sessionCapabilities: getProviderSessionCapabilities(this.provider, IDE_PROVIDER_SESSION_CAPABILITIES_BASE),
163
165
  controlValues: surface.controlValues,
164
166
  providerControls: this.provider.controls,
165
167
  summaryMetadata: surface.summaryMetadata as any,
@@ -0,0 +1,40 @@
1
+ import type { ProviderModule } from './contracts.js'
2
+ import type { SessionCapability } from '../shared-types.js'
3
+
4
+ export const IDE_PROVIDER_SESSION_CAPABILITIES_BASE: SessionCapability[] = [
5
+ 'read_chat',
6
+ 'send_message',
7
+ 'new_session',
8
+ 'list_sessions',
9
+ 'switch_session',
10
+ 'resolve_action',
11
+ 'change_model',
12
+ 'set_mode',
13
+ 'set_thought_level',
14
+ ]
15
+
16
+ export const EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE: SessionCapability[] = [
17
+ 'read_chat',
18
+ 'send_message',
19
+ 'new_session',
20
+ 'list_sessions',
21
+ 'switch_session',
22
+ 'resolve_action',
23
+ 'change_model',
24
+ 'set_mode',
25
+ ]
26
+
27
+ export function providerHasOpenPanelSupport(provider: Pick<ProviderModule, 'category' | 'scripts'>): boolean {
28
+ if (typeof provider.scripts?.openPanel === 'function') return true
29
+ if (provider.category === 'ide' && typeof provider.scripts?.webviewOpenPanel === 'function') return true
30
+ return false
31
+ }
32
+
33
+ export function getProviderSessionCapabilities(
34
+ provider: Pick<ProviderModule, 'category' | 'scripts'>,
35
+ baseCapabilities: SessionCapability[],
36
+ ): SessionCapability[] {
37
+ return providerHasOpenPanelSupport(provider)
38
+ ? [...baseCapabilities, 'open_panel']
39
+ : [...baseCapabilities]
40
+ }
@@ -8,7 +8,7 @@
8
8
  * Each Instance manages its own status.
9
9
  */
10
10
  import type { ProviderResumeCapability } from './contracts.js';
11
- import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata } from '../shared-types.js';
11
+ import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata, SessionCapability } from '../shared-types.js';
12
12
  import type { ChatMessage } from '../types.js';
13
13
  export type ProviderStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting';
14
14
  export interface ProviderRuntimeWriteOwner {
@@ -66,6 +66,7 @@ interface ProviderStateBase {
66
66
  pendingEvents: ProviderEvent[];
67
67
  runtime?: ProviderRuntimeInfo;
68
68
  resume?: ProviderResumeCapability;
69
+ sessionCapabilities?: SessionCapability[];
69
70
  /** Dynamic control current values */
70
71
  controlValues?: Record<string, string | number | boolean>;
71
72
  /** Provider-declared controls schema (from provider.controls) */
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { ProviderModule, ProviderSettingDef, ProviderResumeCapability } from './contracts.js';
12
- import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata } from '../shared-types.js';
12
+ import type { AcpConfigOption, AcpMode, ProviderControlSchema, ProviderSummaryMetadata, SessionCapability } from '../shared-types.js';
13
13
  import type { ChatMessage } from '../types.js';
14
14
 
15
15
  // ─── ProviderState — Discriminated union by category ─────────────
@@ -81,6 +81,7 @@ interface ProviderStateBase {
81
81
  pendingEvents: ProviderEvent[];
82
82
  runtime?: ProviderRuntimeInfo;
83
83
  resume?: ProviderResumeCapability;
84
+ sessionCapabilities?: SessionCapability[];
84
85
  /** Dynamic control current values */
85
86
  controlValues?: Record<string, string | number | boolean>;
86
87
  /** Provider-declared controls schema (from provider.controls) */
@@ -1,4 +1,5 @@
1
1
  import type { ProviderControlDef, ProviderControlType, ProviderModule } from './contracts.js'
2
+ import { providerHasOpenPanelSupport } from './open-panel-support.js'
2
3
 
3
4
  const VALID_CAPABILITY_MEDIA_TYPES = new Set(['text', 'image', 'audio', 'video', 'resource'])
4
5
 
@@ -91,6 +92,7 @@ export function validateProviderDefinition(raw: unknown): ProviderValidationResu
91
92
  }
92
93
 
93
94
  const category = provider.category
95
+ const typedProvider = provider as unknown as ProviderModule
94
96
  const controls = Array.isArray(provider.controls) ? provider.controls : []
95
97
  if ((category === 'cli' || category === 'acp')) {
96
98
  const spawn = provider.spawn
@@ -120,6 +122,14 @@ export function validateProviderDefinition(raw: unknown): ProviderValidationResu
120
122
  validateControl(control as ProviderControlDef, errors)
121
123
  }
122
124
 
125
+ if (
126
+ (category === 'ide' || category === 'extension')
127
+ && typeof typedProvider.scripts?.focusEditor === 'function'
128
+ && !providerHasOpenPanelSupport(typedProvider)
129
+ ) {
130
+ warnings.push('scripts.focusEditor is present without scripts.openPanel/webviewOpenPanel; open_panel capability will remain disabled')
131
+ }
132
+
123
133
  return { errors, warnings }
124
134
  }
125
135
 
@@ -51,6 +51,7 @@ function validateMessage(message: unknown, source: string, index: number): ChatM
51
51
  if (isFiniteNumber(message.index)) normalized.index = message.index
52
52
  if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp
53
53
  if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt
54
+ if (typeof (message as any)._turnKey === 'string') normalized._turnKey = (message as any)._turnKey
54
55
  if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls as any
55
56
  if (isPlainObject(message.meta)) normalized.meta = message.meta as any
56
57
  if (typeof message.senderName === 'string') normalized.senderName = message.senderName
@@ -157,7 +157,7 @@ export type UnsubscribeRequest = {
157
157
  export type StandaloneWsStatusPayload = StatusReportPayload;
158
158
  export type SessionTransport = 'cdp-page' | 'cdp-webview' | 'pty' | 'acp';
159
159
  export type SessionKind = 'workspace' | 'agent';
160
- export type SessionCapability = 'read_chat' | 'send_message' | 'new_session' | 'list_sessions' | 'switch_session' | 'resolve_action' | 'terminal_io' | 'resize_terminal' | 'change_model' | 'set_mode' | 'set_thought_level';
160
+ export type SessionCapability = 'read_chat' | 'send_message' | 'new_session' | 'list_sessions' | 'switch_session' | 'resolve_action' | 'open_panel' | 'terminal_io' | 'resize_terminal' | 'change_model' | 'set_mode' | 'set_thought_level';
161
161
  import type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
162
162
  export type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
163
163
  export interface SessionEntry {
@@ -285,6 +285,7 @@ export type SessionCapability =
285
285
  | 'list_sessions'
286
286
  | 'switch_session'
287
287
  | 'resolve_action'
288
+ | 'open_panel'
288
289
  | 'terminal_io'
289
290
  | 'resize_terminal'
290
291
  | 'change_model'
@@ -25,6 +25,10 @@ import {
25
25
  } from './normalize.js';
26
26
  import { normalizeProviderStateControlValues } from '../providers/provider-patch-state.js';
27
27
  import { normalizeProviderSummaryMetadata } from '../providers/summary-metadata.js';
28
+ import {
29
+ IDE_PROVIDER_SESSION_CAPABILITIES_BASE,
30
+ EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE,
31
+ } from '../providers/open-panel-support.js';
28
32
 
29
33
  export type SessionEntryProfile = 'full' | 'live' | 'metadata';
30
34
 
@@ -107,28 +111,9 @@ export function isCdpConnected(
107
111
  }
108
112
 
109
113
 
110
- const IDE_SESSION_CAPABILITIES: SessionCapability[] = [
111
- 'read_chat',
112
- 'send_message',
113
- 'new_session',
114
- 'list_sessions',
115
- 'switch_session',
116
- 'resolve_action',
117
- 'change_model',
118
- 'set_mode',
119
- 'set_thought_level',
120
- ];
114
+ const IDE_SESSION_CAPABILITIES: SessionCapability[] = [...IDE_PROVIDER_SESSION_CAPABILITIES_BASE];
121
115
 
122
- const EXTENSION_SESSION_CAPABILITIES: SessionCapability[] = [
123
- 'read_chat',
124
- 'send_message',
125
- 'new_session',
126
- 'list_sessions',
127
- 'switch_session',
128
- 'resolve_action',
129
- 'change_model',
130
- 'set_mode',
131
- ];
116
+ const EXTENSION_SESSION_CAPABILITIES: SessionCapability[] = [...EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE];
132
117
 
133
118
  const PTY_SESSION_CAPABILITIES: SessionCapability[] = [
134
119
  'read_chat',
@@ -180,7 +165,7 @@ function buildIdeWorkspaceSession(
180
165
  ...(includeSessionMetadata && { workspace: state.workspace || null }),
181
166
  activeChat,
182
167
  ...(summaryMetadata && { summaryMetadata }),
183
- ...(includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES }),
168
+ ...(includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES }),
184
169
  cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
185
170
  ...(includeSessionControls && {
186
171
  ...(controlValues && { controlValues }),
@@ -208,6 +193,7 @@ function buildExtensionAgentSession(
208
193
  parentId: parent.instanceId || parent.type,
209
194
  providerType: ext.type,
210
195
  ...(includeSessionMetadata && { providerName: ext.name }),
196
+ providerSessionId: ext.providerSessionId,
211
197
  kind: 'agent',
212
198
  transport: 'cdp-webview',
213
199
  status: normalizeManagedStatus(activeChat?.status || ext.status, {
@@ -217,7 +203,7 @@ function buildExtensionAgentSession(
217
203
  ...(includeSessionMetadata && { workspace: parent.workspace || null }),
218
204
  activeChat,
219
205
  ...(summaryMetadata && { summaryMetadata }),
220
- ...(includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES }),
206
+ ...(includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES }),
221
207
  ...(includeSessionControls && {
222
208
  ...(controlValues && { controlValues }),
223
209
  providerControls: ext.providerControls,
@@ -375,8 +375,8 @@ export function buildStatusSnapshot(options: StatusSnapshotOptions): StatusSnaps
375
375
  for (const sourceSession of unreadSourceSessions) {
376
376
  const session = sessionsById.get(sourceSession.id);
377
377
  if (!session) continue;
378
- const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
379
- const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
378
+ const lastSeenAt = getSessionSeenAt(state, sourceSession.id, sourceSession.providerSessionId);
379
+ const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id, sourceSession.providerSessionId);
380
380
  const lastUsedAt = getSessionLastUsedAt(sourceSession);
381
381
  const completionMarker = getSessionCompletionMarker(sourceSession);
382
382
  const { unread, inboxBucket } = sourceSession.surfaceHidden
package/src/types.ts CHANGED
@@ -35,6 +35,7 @@ export interface ChatMessage {
35
35
  index?: number;
36
36
  timestamp?: number;
37
37
  receivedAt?: number;
38
+ _turnKey?: string;
38
39
  /** Tool calls associated with this message */
39
40
  toolCalls?: ToolCallInfo[];
40
41
  /** Optional: fiber metadata */