@adhdev/daemon-core 0.8.34 → 0.8.36

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 (109) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +4 -0
  2. package/dist/commands/router.d.ts +3 -0
  3. package/dist/config/config.d.ts +5 -0
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +585 -256
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +584 -256
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/shared-types.d.ts +286 -16
  10. package/dist/status/builders.d.ts +5 -1
  11. package/dist/status/normalize.d.ts +11 -1
  12. package/dist/status/normalize.js +36 -16
  13. package/dist/status/normalize.js.map +1 -1
  14. package/dist/status/normalize.mjs +35 -16
  15. package/dist/status/normalize.mjs.map +1 -1
  16. package/dist/status/reporter.d.ts +7 -0
  17. package/dist/status/snapshot.d.ts +5 -5
  18. package/dist/types.d.ts +1 -1
  19. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  20. package/package.json +1 -1
  21. package/src/agent-stream/forward.d.ts +8 -0
  22. package/src/agent-stream/index.d.ts +6 -0
  23. package/src/agent-stream/manager.d.ts +60 -0
  24. package/src/agent-stream/poller.d.ts +41 -0
  25. package/src/agent-stream/provider-adapter.d.ts +36 -0
  26. package/src/agent-stream/types.d.ts +68 -0
  27. package/src/boot/daemon-lifecycle.d.ts +100 -0
  28. package/src/boot/daemon-lifecycle.ts +7 -0
  29. package/src/cdp/devtools.d.ts +51 -0
  30. package/src/cdp/initializer.d.ts +50 -0
  31. package/src/cdp/manager.d.ts +147 -0
  32. package/src/cdp/scanner.d.ts +58 -0
  33. package/src/cdp/setup.d.ts +58 -0
  34. package/src/cli-adapter-types.d.ts +57 -0
  35. package/src/cli-adapters/provider-cli-adapter.d.ts +177 -0
  36. package/src/cli-adapters/provider-cli-adapter.ts +115 -91
  37. package/src/cli-adapters/provider-cli-config.d.ts +30 -0
  38. package/src/cli-adapters/provider-cli-parse.d.ts +42 -0
  39. package/src/cli-adapters/provider-cli-runtime.d.ts +29 -0
  40. package/src/cli-adapters/provider-cli-shared.d.ts +158 -0
  41. package/src/cli-adapters/pty-transport.d.ts +48 -0
  42. package/src/cli-adapters/session-host-transport.d.ts +20 -0
  43. package/src/cli-adapters/spawn-env.d.ts +8 -0
  44. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +16 -0
  45. package/src/cli-adapters/terminal-backends/types.d.ts +18 -0
  46. package/src/cli-adapters/terminal-backends/xterm-backend.d.ts +17 -0
  47. package/src/cli-adapters/terminal-screen.d.ts +33 -0
  48. package/src/commands/cdp-commands.d.ts +15 -0
  49. package/src/commands/chat-commands.d.ts +15 -0
  50. package/src/commands/chat-commands.ts +192 -17
  51. package/src/commands/cli-manager.d.ts +94 -0
  52. package/src/commands/handler.d.ts +103 -0
  53. package/src/commands/router.d.ts +98 -0
  54. package/src/commands/router.ts +25 -0
  55. package/src/commands/stream-commands.d.ts +14 -0
  56. package/src/commands/stream-commands.ts +14 -10
  57. package/src/commands/upgrade-helper.d.ts +10 -0
  58. package/src/commands/workspace-commands.d.ts +11 -0
  59. package/src/config/chat-history.d.ts +99 -0
  60. package/src/config/config.d.ts +14 -0
  61. package/src/config/config.ts +8 -0
  62. package/src/config/recent-activity.d.ts +29 -0
  63. package/src/config/saved-sessions.d.ts +22 -0
  64. package/src/config/state-store.d.ts +32 -0
  65. package/src/config/workspaces.d.ts +0 -1
  66. package/src/daemon/dev-auto-implement.d.ts +43 -0
  67. package/src/daemon/dev-cdp-handlers.d.ts +22 -0
  68. package/src/daemon/dev-cli-debug.d.ts +106 -0
  69. package/src/daemon/dev-server-types.d.ts +43 -0
  70. package/src/daemon/dev-server.d.ts +140 -0
  71. package/src/daemon/scaffold-template.d.ts +32 -0
  72. package/src/daemon-core.d.ts +36 -0
  73. package/src/detection/cli-detector.d.ts +31 -0
  74. package/src/detection/ide-detector.d.ts +35 -0
  75. package/src/index.d.ts +83 -0
  76. package/src/index.ts +34 -1
  77. package/src/installer.d.ts +50 -0
  78. package/src/ipc-protocol.d.ts +111 -0
  79. package/src/launch.d.ts +46 -0
  80. package/src/logging/command-log.d.ts +31 -0
  81. package/src/logging/logger.d.ts +89 -0
  82. package/src/providers/acp-provider-instance.d.ts +102 -0
  83. package/src/providers/approval-utils.d.ts +7 -0
  84. package/src/providers/cli-provider-instance.d.ts +86 -0
  85. package/src/providers/contracts.d.ts +193 -1
  86. package/src/providers/control-effects.d.ts +4 -0
  87. package/src/providers/extension-provider-instance.d.ts +61 -0
  88. package/src/providers/ide-provider-instance.d.ts +70 -0
  89. package/src/providers/provider-instance-manager.d.ts +84 -0
  90. package/src/providers/provider-instance.d.ts +7 -1
  91. package/src/providers/provider-loader.d.ts +299 -0
  92. package/src/providers/status-monitor.d.ts +48 -0
  93. package/src/providers/version-archive.d.ts +52 -0
  94. package/src/session-host/runtime-support.d.ts +8 -0
  95. package/src/sessions/reconcile.d.ts +22 -0
  96. package/src/sessions/registry.d.ts +24 -0
  97. package/src/shared-types-extra.d.ts +29 -0
  98. package/src/shared-types.d.ts +204 -38
  99. package/src/shared-types.ts +319 -16
  100. package/src/status/builders.d.ts +33 -0
  101. package/src/status/builders.ts +110 -54
  102. package/src/status/normalize.ts +54 -19
  103. package/src/status/reporter.d.ts +69 -0
  104. package/src/status/reporter.ts +104 -26
  105. package/src/status/snapshot.d.ts +58 -0
  106. package/src/status/snapshot.ts +79 -41
  107. package/src/system/host-memory.d.ts +19 -0
  108. package/src/types.d.ts +3 -7
  109. package/src/types.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/status/normalize.ts"],"sourcesContent":["import type { ActiveChatData } from '../providers/provider-instance.js';\n\nexport type ManagedStatus =\n | 'idle'\n | 'generating'\n | 'waiting_approval'\n | 'error'\n | 'stopped'\n | 'starting'\n | 'panel_hidden'\n | 'not_monitored'\n | 'disconnected';\n\nconst WORKING_STATUSES = new Set([\n 'generating',\n 'streaming',\n 'loading',\n 'loading_reference',\n 'thinking',\n 'active',\n]);\n\n// Status snapshots are sent over P2P every 5s, so keep only a recent live window here.\n// Older history is fetched on demand via `chat_history`, and CLI terminals stream via runtime events.\nconst STATUS_ACTIVE_CHAT_MESSAGE_LIMIT = 60;\nconst STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT = 96 * 1024;\nconst STATUS_ACTIVE_CHAT_STRING_LIMIT = 4 * 1024;\nconst STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT = 1024;\nconst STATUS_INPUT_CONTENT_LIMIT = 2 * 1024;\nconst STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;\nconst STATUS_MODAL_BUTTON_LIMIT = 120;\n\nfunction truncateString(value: string, maxChars: number): string {\n if (value.length <= maxChars) return value;\n if (maxChars <= 12) return value.slice(0, Math.max(0, maxChars));\n return `${value.slice(0, maxChars - 12)}...[truncated]`;\n}\n\nfunction truncateStringTail(value: string, maxChars: number): string {\n if (value.length <= maxChars) return value;\n if (maxChars <= 12) return value.slice(value.length - Math.max(0, maxChars));\n return `...[truncated]${value.slice(value.length - (maxChars - 12))}`;\n}\n\nfunction trimStructuredStrings(value: unknown, maxChars: number): unknown {\n if (typeof value === 'string') return truncateString(value, maxChars);\n if (Array.isArray(value)) return value.map((item) => trimStructuredStrings(item, maxChars));\n if (!value || typeof value !== 'object') return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, nested]) => [key, trimStructuredStrings(nested, maxChars)]),\n );\n}\n\nfunction estimateBytes(value: unknown): number {\n try {\n return JSON.stringify(value).length;\n } catch {\n return String(value ?? '').length;\n }\n}\n\nfunction trimMessageForStatus(message: unknown, stringLimit: number): unknown {\n if (!message || typeof message !== 'object') return message;\n return trimStructuredStrings(message, stringLimit);\n}\n\n/**\n * Collapse timestamp / createdAt into receivedAt so downstream consumers\n * only ever need to read a single canonical time field.\n */\nfunction normalizeMessageTime(message: unknown): unknown {\n if (!message || typeof message !== 'object') return message;\n const msg = message as Record<string, unknown>;\n if (msg.receivedAt == null) {\n const fallback = msg.timestamp ?? msg.createdAt;\n if (fallback != null) {\n const ts = typeof fallback === 'string' ? Date.parse(fallback as string) : Number(fallback);\n if (Number.isFinite(ts) && ts > 0) msg.receivedAt = ts;\n }\n }\n return msg;\n}\n\nfunction trimMessagesForStatus(messages: unknown[] | null | undefined): unknown[] {\n if (!Array.isArray(messages) || messages.length === 0) return [];\n\n const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);\n const kept: unknown[] = [];\n let totalBytes = 0;\n\n for (let i = recent.length - 1; i >= 0; i -= 1) {\n let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT));\n let size = estimateBytes(normalized);\n\n if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {\n normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT));\n size = estimateBytes(normalized);\n }\n\n if (kept.length > 0 && (totalBytes + size) > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {\n continue;\n }\n\n kept.push(normalized);\n totalBytes += size;\n }\n\n return kept.reverse();\n}\n\nfunction hasApprovalButtons(activeModal?: { buttons?: unknown[] | null } | null): boolean {\n return (activeModal?.buttons?.length ?? 0) > 0;\n}\n\nexport function normalizeManagedStatus(\n status?: string | null,\n opts?: { activeModal?: { buttons?: unknown[] | null } | null },\n): ManagedStatus {\n if (hasApprovalButtons(opts?.activeModal)) return 'waiting_approval';\n\n const normalized = String(status || 'idle').trim().toLowerCase();\n if (normalized === 'waiting_approval') return 'waiting_approval';\n if (WORKING_STATUSES.has(normalized)) return 'generating';\n if (normalized === 'error') return 'error';\n if (normalized === 'stopped') return 'stopped';\n if (normalized === 'starting') return 'starting';\n if (normalized === 'panel_hidden') return 'panel_hidden';\n if (normalized === 'not_monitored') return 'not_monitored';\n if (normalized === 'disconnected') return 'disconnected';\n return 'idle';\n}\n\nexport function isManagedStatusWorking(status?: string | null): boolean {\n return normalizeManagedStatus(status) === 'generating';\n}\n\nexport function isManagedStatusWaiting(\n status?: string | null,\n opts?: { activeModal?: { buttons?: unknown[] | null } | null },\n): boolean {\n return normalizeManagedStatus(status, opts) === 'waiting_approval';\n}\n\nexport function normalizeActiveChatData<T extends ActiveChatData | null | undefined>(\n activeChat: T,\n): T {\n if (!activeChat) return activeChat;\n return {\n ...activeChat,\n status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),\n messages: trimMessagesForStatus(activeChat.messages) as T extends { messages: infer M } ? M : never,\n activeModal: activeChat.activeModal ? {\n message: truncateString(activeChat.activeModal.message || '', STATUS_MODAL_MESSAGE_LIMIT),\n buttons: (activeChat.activeModal.buttons || []).map((button) =>\n truncateString(String(button || ''), STATUS_MODAL_BUTTON_LIMIT)\n ),\n } : activeChat.activeModal,\n inputContent: activeChat.inputContent\n ? truncateString(activeChat.inputContent, STATUS_INPUT_CONTENT_LIMIT)\n : activeChat.inputContent,\n } as T;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/status/normalize.ts"],"sourcesContent":["import type { ActiveChatData } from '../providers/provider-instance.js';\n\nexport type ManagedStatus =\n | 'idle'\n | 'generating'\n | 'waiting_approval'\n | 'error'\n | 'stopped'\n | 'starting'\n | 'panel_hidden'\n | 'not_monitored'\n | 'disconnected';\n\nconst WORKING_STATUSES = new Set([\n 'generating',\n 'streaming',\n 'loading',\n 'loading_reference',\n 'thinking',\n 'active',\n]);\n\nexport interface NormalizeActiveChatOptions {\n includeMessages?: boolean;\n includeInputContent?: boolean;\n includeActiveModal?: boolean;\n messageLimit?: number;\n totalBytesLimit?: number;\n stringLimit?: number;\n fallbackStringLimit?: number;\n}\n\n// Full snapshots are still capped, but can carry recent chat context for API/inspection use.\nconst FULL_STATUS_ACTIVE_CHAT_OPTIONS: Required<NormalizeActiveChatOptions> = {\n includeMessages: true,\n includeInputContent: true,\n includeActiveModal: true,\n messageLimit: 60,\n totalBytesLimit: 96 * 1024,\n stringLimit: 4 * 1024,\n fallbackStringLimit: 1024,\n};\n\n// Live/metadata snapshots only need routing + UI summary. Current chat text is loaded\n// on demand via `read_chat`, and older history via `chat_history`.\nexport const LIVE_STATUS_ACTIVE_CHAT_OPTIONS: Required<NormalizeActiveChatOptions> = {\n includeMessages: false,\n includeInputContent: false,\n includeActiveModal: false,\n messageLimit: 0,\n totalBytesLimit: 0,\n stringLimit: 512,\n fallbackStringLimit: 256,\n};\n\nconst STATUS_MODAL_MESSAGE_LIMIT = 2 * 1024;\nconst STATUS_MODAL_BUTTON_LIMIT = 120;\n\nfunction truncateString(value: string, maxChars: number): string {\n if (value.length <= maxChars) return value;\n if (maxChars <= 12) return value.slice(0, Math.max(0, maxChars));\n return `${value.slice(0, maxChars - 12)}...[truncated]`;\n}\n\nfunction truncateStringTail(value: string, maxChars: number): string {\n if (value.length <= maxChars) return value;\n if (maxChars <= 12) return value.slice(value.length - Math.max(0, maxChars));\n return `...[truncated]${value.slice(value.length - (maxChars - 12))}`;\n}\n\nfunction trimStructuredStrings(value: unknown, maxChars: number): unknown {\n if (typeof value === 'string') return truncateString(value, maxChars);\n if (Array.isArray(value)) return value.map((item) => trimStructuredStrings(item, maxChars));\n if (!value || typeof value !== 'object') return value;\n return Object.fromEntries(\n Object.entries(value).map(([key, nested]) => [key, trimStructuredStrings(nested, maxChars)]),\n );\n}\n\nfunction estimateBytes(value: unknown): number {\n try {\n return JSON.stringify(value).length;\n } catch {\n return String(value ?? '').length;\n }\n}\n\nfunction trimMessageForStatus(message: unknown, stringLimit: number): unknown {\n if (!message || typeof message !== 'object') return message;\n return trimStructuredStrings(message, stringLimit);\n}\n\n/**\n * Collapse timestamp / createdAt into receivedAt so downstream consumers\n * only ever need to read a single canonical time field.\n */\nfunction normalizeMessageTime(message: unknown): unknown {\n if (!message || typeof message !== 'object') return message;\n const msg = message as Record<string, unknown>;\n if (msg.receivedAt == null) {\n const fallback = msg.timestamp ?? msg.createdAt;\n if (fallback != null) {\n const ts = typeof fallback === 'string' ? Date.parse(fallback as string) : Number(fallback);\n if (Number.isFinite(ts) && ts > 0) msg.receivedAt = ts;\n }\n }\n return msg;\n}\n\nfunction trimMessagesForStatus(\n messages: unknown[] | null | undefined,\n options: Required<NormalizeActiveChatOptions>,\n): unknown[] {\n if (!options.includeMessages || options.messageLimit <= 0 || options.totalBytesLimit <= 0) return [];\n if (!Array.isArray(messages) || messages.length === 0) return [];\n\n const recent = messages.slice(-options.messageLimit);\n const kept: unknown[] = [];\n let totalBytes = 0;\n\n for (let i = recent.length - 1; i >= 0; i -= 1) {\n let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.stringLimit));\n let size = estimateBytes(normalized);\n\n if (size > options.totalBytesLimit) {\n normalized = normalizeMessageTime(trimMessageForStatus(recent[i], options.fallbackStringLimit));\n size = estimateBytes(normalized);\n }\n\n if (kept.length > 0 && (totalBytes + size) > options.totalBytesLimit) {\n continue;\n }\n\n kept.push(normalized);\n totalBytes += size;\n }\n\n return kept.reverse();\n}\n\nfunction hasApprovalButtons(activeModal?: { buttons?: unknown[] | null } | null): boolean {\n return (activeModal?.buttons?.length ?? 0) > 0;\n}\n\nexport function normalizeManagedStatus(\n status?: string | null,\n opts?: { activeModal?: { buttons?: unknown[] | null } | null },\n): ManagedStatus {\n if (hasApprovalButtons(opts?.activeModal)) return 'waiting_approval';\n\n const normalized = String(status || 'idle').trim().toLowerCase();\n if (normalized === 'waiting_approval') return 'waiting_approval';\n if (WORKING_STATUSES.has(normalized)) return 'generating';\n if (normalized === 'error') return 'error';\n if (normalized === 'stopped') return 'stopped';\n if (normalized === 'starting') return 'starting';\n if (normalized === 'panel_hidden') return 'panel_hidden';\n if (normalized === 'not_monitored') return 'not_monitored';\n if (normalized === 'disconnected') return 'disconnected';\n return 'idle';\n}\n\nexport function isManagedStatusWorking(status?: string | null): boolean {\n return normalizeManagedStatus(status) === 'generating';\n}\n\nexport function isManagedStatusWaiting(\n status?: string | null,\n opts?: { activeModal?: { buttons?: unknown[] | null } | null },\n): boolean {\n return normalizeManagedStatus(status, opts) === 'waiting_approval';\n}\n\nexport function normalizeActiveChatData<T extends ActiveChatData | null | undefined>(\n activeChat: T,\n options: NormalizeActiveChatOptions = FULL_STATUS_ACTIVE_CHAT_OPTIONS,\n): T {\n if (!activeChat) return activeChat;\n const resolvedOptions: Required<NormalizeActiveChatOptions> = {\n ...FULL_STATUS_ACTIVE_CHAT_OPTIONS,\n ...options,\n };\n return {\n ...activeChat,\n status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),\n messages: trimMessagesForStatus(activeChat.messages, resolvedOptions) as T extends { messages: infer M } ? M : never,\n activeModal: resolvedOptions.includeActiveModal && activeChat.activeModal ? {\n message: truncateString(activeChat.activeModal.message || '', STATUS_MODAL_MESSAGE_LIMIT),\n buttons: (activeChat.activeModal.buttons || []).map((button) =>\n truncateString(String(button || ''), STATUS_MODAL_BUTTON_LIMIT)\n ),\n } : null,\n inputContent: resolvedOptions.includeInputContent && activeChat.inputContent\n ? truncateString(activeChat.inputContent, 2 * 1024)\n : undefined,\n } as T;\n}\n"],"mappings":"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","names":[]}
@@ -5,6 +5,7 @@
5
5
  * Each Instance manages its own status/transition. This module only assembles + transmits.
6
6
  */
7
7
  import type { DaemonCdpManager } from '../cdp/manager.js';
8
+ import type { DaemonStatusEventPayload } from '../shared-types.js';
8
9
  import type { ProviderState } from '../providers/provider-instance.js';
9
10
  export interface StatusReporterDeps {
10
11
  serverConn: {
@@ -20,6 +21,7 @@ export interface StatusReporterDeps {
20
21
  connectedPeerCount: number;
21
22
  screenshotActive: boolean;
22
23
  sendStatus(data: any): void;
24
+ sendStatusEvent(event: DaemonStatusEventPayload): void;
23
25
  } | null;
24
26
  providerLoader: {
25
27
  resolve(type: string): any;
@@ -44,6 +46,7 @@ export declare class DaemonStatusReporter {
44
46
  private lastStatusSentAt;
45
47
  private statusPendingThrottle;
46
48
  private lastP2PStatusHash;
49
+ private lastServerStatusHash;
47
50
  private lastStatusSummary;
48
51
  private statusTimer;
49
52
  private p2pTimer;
@@ -54,6 +57,8 @@ export declare class DaemonStatusReporter {
54
57
  stopReporting(): void;
55
58
  onStatusChange(): void;
56
59
  throttledReport(): void;
60
+ private toDaemonStatusEventName;
61
+ private buildServerStatusEvent;
57
62
  emitStatusEvent(event: Record<string, unknown>): void;
58
63
  removeAgentTracking(_key: string): void;
59
64
  updateAgentStreams(_ideType: string, _streams: any[]): void;
@@ -63,6 +68,8 @@ export declare class DaemonStatusReporter {
63
68
  private summarizeLargePayloadSessions;
64
69
  sendUnifiedStatusReport(opts?: {
65
70
  p2pOnly?: boolean;
71
+ forceServer?: boolean;
72
+ reason?: string;
66
73
  }): Promise<void>;
67
74
  private sendP2PPayload;
68
75
  private simpleHash;
@@ -6,8 +6,9 @@
6
6
  * - daemon-standalone HTTP/WS status responses
7
7
  */
8
8
  import type { DaemonCdpManager } from '../cdp/manager.js';
9
+ import { type SessionEntryProfile } from './builders.js';
9
10
  import type { ProviderState } from '../providers/provider-instance.js';
10
- import type { AvailableProviderInfo, StatusReportPayload } from '../shared-types.js';
11
+ import type { MachineInfo, StatusReportPayload } from '../shared-types.js';
11
12
  export interface StatusSnapshotOptions {
12
13
  allStates: ProviderState[];
13
14
  cdpManagers: Map<string, DaemonCdpManager>;
@@ -36,14 +37,13 @@ export interface StatusSnapshotOptions {
36
37
  }>;
37
38
  instanceId: string;
38
39
  version: string;
39
- daemonMode: boolean;
40
40
  timestamp?: number;
41
41
  p2p?: StatusReportPayload['p2p'];
42
42
  machineNickname?: string | null;
43
+ profile?: SessionEntryProfile;
43
44
  }
44
- export interface StatusSnapshot extends StatusReportPayload {
45
- availableProviders: AvailableProviderInfo[];
46
- }
45
+ export type StatusSnapshot = StatusReportPayload;
46
+ export declare function buildMachineInfo(profile?: 'full' | 'live' | 'metadata'): MachineInfo;
47
47
  export declare function getSessionCompletionMarker(session: {
48
48
  activeChat?: {
49
49
  messages?: Array<{
package/dist/types.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface StatusResponse extends StatusReportPayload {
15
15
  /** User display name from config */
16
16
  userName?: string;
17
17
  /** Available providers */
18
- availableProviders: AvailableProviderInfo[];
18
+ availableProviders?: AvailableProviderInfo[];
19
19
  /** System info (legacy compat) */
20
20
  system?: SystemInfo;
21
21
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.8.34",
3
+ "version": "0.8.36",
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.34",
3
+ "version": "0.8.36",
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",
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared helper for forwarding agent stream snapshots into the IDE instance.
3
+ *
4
+ * Both cloud and standalone daemons use the same InstanceManager wiring.
5
+ */
6
+ export declare function forwardAgentStreamsToIdeInstance(instanceManager: {
7
+ getInstance: (key: string) => any;
8
+ }, ideType: string, streams: any[]): void;
@@ -0,0 +1,6 @@
1
+ export { DaemonAgentStreamManager } from './manager.js';
2
+ export type { ManagedAgent } from './manager.js';
3
+ export { ProviderStreamAdapter } from './provider-adapter.js';
4
+ export * from './types.js';
5
+ export { AgentStreamPoller } from './poller.js';
6
+ export type { AgentStreamPollerDeps } from './poller.js';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * DaemonAgentStreamManager — manage agent streams (ported for Daemon)
3
+ *
4
+ * Agent stream manager for extension data collection.
5
+ * All vscode dependencies removed — pure Node.js environment.
6
+ *
7
+ * Panel focus is delegated to Extension via IPC.
8
+ * CDP session management uses DaemonCdpManager directly.
9
+ */
10
+ import { DaemonCdpManager, AgentWebviewTarget } from '../cdp/manager.js';
11
+ import { ProviderLoader } from '../providers/provider-loader.js';
12
+ import { SessionRegistry } from '../sessions/registry.js';
13
+ import type { IAgentStreamAdapter, AgentStreamState, AgentChatListItem } from './types.js';
14
+ export interface ManagedAgent {
15
+ adapter: IAgentStreamAdapter;
16
+ runtimeSessionId: string;
17
+ parentSessionId: string;
18
+ cdpSessionId: string;
19
+ target: AgentWebviewTarget;
20
+ lastState: AgentStreamState | null;
21
+ lastError: string | null;
22
+ lastHiddenCheckTime: number;
23
+ }
24
+ export declare class DaemonAgentStreamManager {
25
+ private readonly sessionRegistry?;
26
+ private adaptersByType;
27
+ private managedBySessionId;
28
+ private enabled;
29
+ private logFn;
30
+ private lastDiscoveryTimeByParent;
31
+ private discoveryIntervalMsByParent;
32
+ private activeSessionIdByParent;
33
+ constructor(logFn?: (msg: string) => void, providerLoader?: ProviderLoader, sessionRegistry?: SessionRegistry);
34
+ setEnabled(enabled: boolean): void;
35
+ get isEnabled(): boolean;
36
+ getActiveSessionId(parentSessionId: string): string | null;
37
+ private isRecoverableSessionError;
38
+ private getSessionTarget;
39
+ resetParentSession(parentSessionId: string): void;
40
+ /** Panel focus based on provider.js focusPanel or extensionId (currently no-op) */
41
+ ensureSessionPanelOpen(_sessionId: string): Promise<void>;
42
+ setActiveSession(cdp: DaemonCdpManager, parentSessionId: string, sessionId: string | null): Promise<void>;
43
+ private resolveSessionIdForTarget;
44
+ private getStateError;
45
+ private connectManagedSession;
46
+ /** Agent webview discovery + session connection */
47
+ syncActiveSession(cdp: DaemonCdpManager, parentSessionId: string): Promise<void>;
48
+ /** Collect active extension session state */
49
+ collectActiveSession(cdp: DaemonCdpManager, parentSessionId: string): Promise<AgentStreamState | null>;
50
+ sendToSession(cdp: DaemonCdpManager, sessionId: string, text: string): Promise<boolean>;
51
+ resolveSessionAction(cdp: DaemonCdpManager, sessionId: string, action: 'approve' | 'reject', button?: string): Promise<boolean>;
52
+ newSession(cdp: DaemonCdpManager, sessionId: string): Promise<boolean>;
53
+ listSessionChats(cdp: DaemonCdpManager, sessionId: string): Promise<AgentChatListItem[]>;
54
+ switchConversation(cdp: DaemonCdpManager, sessionId: string, conversationId: string): Promise<boolean>;
55
+ focusSession(cdp: DaemonCdpManager, sessionId: string): Promise<boolean>;
56
+ getConnectedSessions(parentSessionId?: string): string[];
57
+ getManagedSession(sessionId: string): ManagedAgent | undefined;
58
+ dispose(cdpManagers: Map<string, DaemonCdpManager>): Promise<void>;
59
+ resolveSessionForAgent(parentSessionId: string, agentType: string): string | null;
60
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * AgentStreamPoller — Periodic agent stream polling + extension dynamic management
3
+ *
4
+ * Handles periodic agent stream polling and extension dynamic management.
5
+ *
6
+ * Responsibilities:
7
+ * 1. Refresh extension providers in CDP managers (config changes take effect immediately)
8
+ * 2. Dynamically add/remove IDE instance extensions based on enabled state
9
+ * 3. Sync agent sessions + collect agent streams
10
+ * 4. Auto-discover agents in connected IDEs
11
+ */
12
+ import type { DaemonCdpManager } from '../cdp/manager.js';
13
+ import type { DaemonAgentStreamManager } from './manager.js';
14
+ import type { ProviderLoader } from '../providers/provider-loader.js';
15
+ import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
16
+ import type { SessionRegistry } from '../sessions/registry.js';
17
+ import type { AgentStreamState } from './types.js';
18
+ export interface AgentStreamPollerDeps {
19
+ agentStreamManager: DaemonAgentStreamManager;
20
+ providerLoader: ProviderLoader;
21
+ instanceManager: ProviderInstanceManager;
22
+ cdpManagers: Map<string, DaemonCdpManager>;
23
+ sessionRegistry: SessionRegistry;
24
+ /** Callback when agent streams are updated */
25
+ onStreamsUpdated?: (ideType: string, streams: AgentStreamState[]) => void;
26
+ }
27
+ export declare class AgentStreamPoller {
28
+ private deps;
29
+ private timer;
30
+ constructor(deps: AgentStreamPollerDeps);
31
+ /** Currently active IDE type for agent streaming */
32
+ get activeIde(): string | null;
33
+ /** Reset active IDE tracking (e.g., when IDE is stopped) */
34
+ resetActiveIde(parentSessionId: string): void;
35
+ /** Start polling (idempotent — ignored if already started) */
36
+ start(intervalMs?: number): void;
37
+ /** Stop polling */
38
+ stop(): void;
39
+ /** Single poll tick — can also be called manually */
40
+ private tick;
41
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * ProviderStreamAdapter — generic Extension adapter based on provider.js
3
+ *
4
+ * Consolidates ClineAdapter, RooCodeAdapter, ContinueAdapter.
5
+ * Auto-configured using provider.js scripts + metadata.
6
+ */
7
+ import type { IAgentStreamAdapter, AgentStreamState, AgentChatListItem, AgentEvaluateFn } from './types.js';
8
+ import type { ProviderModule } from '../providers/contracts.js';
9
+ export declare class ProviderStreamAdapter implements IAgentStreamAdapter {
10
+ readonly agentType: string;
11
+ readonly agentName: string;
12
+ readonly extensionId: string;
13
+ readonly extensionIdPattern: RegExp;
14
+ private provider;
15
+ private lastSuccessState;
16
+ constructor(provider: ProviderModule);
17
+ private callScript;
18
+ private hasScript;
19
+ private getStateTitle;
20
+ private parseMaybeJson;
21
+ private summarizeRaw;
22
+ private isTransportError;
23
+ private titlesMatch;
24
+ private messageCount;
25
+ private lastMessageSignature;
26
+ private verifySendOutcome;
27
+ private readStableBaselineState;
28
+ readChat(evaluate: AgentEvaluateFn): Promise<AgentStreamState>;
29
+ sendMessage(evaluate: AgentEvaluateFn, text: string): Promise<void>;
30
+ resolveAction(evaluate: AgentEvaluateFn, action: string, button?: string): Promise<boolean>;
31
+ newSession(evaluate: AgentEvaluateFn): Promise<void>;
32
+ listChats(evaluate: AgentEvaluateFn): Promise<AgentChatListItem[]>;
33
+ switchSession(evaluate: AgentEvaluateFn, sessionId: string): Promise<boolean>;
34
+ focusEditor(evaluate: AgentEvaluateFn): Promise<void>;
35
+ private errorState;
36
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Agent Stream Types — ported for Daemon (identical to original)
3
+ *
4
+ * Agent stream types.
5
+ * No vscode dependency — can be used as-is.
6
+ */
7
+ import type { ProviderEffect } from '../providers/contracts.js';
8
+ /** Agent chat message */
9
+ export interface AgentChatMessage {
10
+ role: 'user' | 'assistant' | 'system';
11
+ content: string;
12
+ timestamp?: number;
13
+ }
14
+ /** Agent chat history item */
15
+ export interface AgentChatListItem {
16
+ title: string;
17
+ id: string;
18
+ status?: string;
19
+ time?: string;
20
+ cost?: string;
21
+ }
22
+ /** Agent stream status */
23
+ export interface AgentStreamState {
24
+ agentType: string;
25
+ agentName: string;
26
+ extensionId: string;
27
+ status: 'idle' | 'streaming' | 'waiting_approval' | 'error' | 'disconnected' | 'panel_hidden' | 'not_monitored';
28
+ messages: AgentChatMessage[];
29
+ inputContent: string;
30
+ title?: string;
31
+ /** @deprecated Use controlValues['model'] — kept for backward compatibility */
32
+ model?: string;
33
+ /** @deprecated Use controlValues['mode'] — kept for backward compatibility */
34
+ mode?: string;
35
+ activeModal?: {
36
+ message: string;
37
+ buttons: string[];
38
+ };
39
+ error?: string;
40
+ _error?: string;
41
+ /** Dynamic control current values (populated from readChat + provider controls schema) */
42
+ controlValues?: Record<string, string | number | boolean>;
43
+ /** Provider-driven UI effects from readChat */
44
+ effects?: ProviderEffect[];
45
+ }
46
+ /** Agent webview target info */
47
+ export interface AgentWebviewTarget {
48
+ targetId: string;
49
+ extensionId: string;
50
+ agentType: string;
51
+ url: string;
52
+ }
53
+ /** Agent stream adapter interface */
54
+ export interface IAgentStreamAdapter {
55
+ readonly agentType: string;
56
+ readonly agentName: string;
57
+ readonly extensionId: string;
58
+ readonly extensionIdPattern: RegExp;
59
+ readChat(evaluate: AgentEvaluateFn): Promise<AgentStreamState>;
60
+ sendMessage(evaluate: AgentEvaluateFn, text: string): Promise<void>;
61
+ resolveAction(evaluate: AgentEvaluateFn, action: string, button?: string): Promise<boolean>;
62
+ newSession(evaluate: AgentEvaluateFn): Promise<void>;
63
+ listChats?(evaluate: AgentEvaluateFn): Promise<AgentChatListItem[]>;
64
+ switchSession?(evaluate: AgentEvaluateFn, sessionId: string): Promise<boolean>;
65
+ focusEditor?(evaluate: AgentEvaluateFn): Promise<void>;
66
+ setProvider?(provider: any): void;
67
+ }
68
+ export type AgentEvaluateFn = (expression: string, timeoutMs?: number) => Promise<unknown>;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Daemon Lifecycle — Shared init + shutdown logic
3
+ *
4
+ * initDaemonComponents(): Creates all core daemon components in correct order.
5
+ * shutdownDaemonComponents(): Graceful shutdown of all components.
6
+ *
7
+ * Transport-specific setup (ServerConnection, P2P, HTTP/WS) remains in each daemon.
8
+ */
9
+ import { DaemonCdpManager } from '../cdp/manager.js';
10
+ import { DaemonCdpInitializer } from '../cdp/initializer.js';
11
+ import { DaemonCommandHandler } from '../commands/handler.js';
12
+ import { DaemonCommandRouter } from '../commands/router.js';
13
+ import type { SessionHostControlPlane } from '../commands/router.js';
14
+ import { DaemonCliManager, type CliTransportFactoryParams, type HostedCliRuntimeDescriptor } from '../commands/cli-manager.js';
15
+ import { DaemonAgentStreamManager } from '../agent-stream/manager.js';
16
+ import { AgentStreamPoller } from '../agent-stream/poller.js';
17
+ import { ProviderLoader } from '../providers/provider-loader.js';
18
+ import { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
19
+ import { DevServer } from '../daemon/dev-server.js';
20
+ import { type IDEInfo } from '../detection/ide-detector.js';
21
+ import { SessionRegistry } from '../sessions/registry.js';
22
+ import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
23
+ export interface DaemonInitConfig {
24
+ /** ProviderLoader log function */
25
+ providerLogFn?: (msg: string) => void;
26
+ /** CLI Manager deps (transport-specific) */
27
+ cliManagerDeps: {
28
+ getServerConn: () => any;
29
+ getP2p: () => any;
30
+ onStatusChange: () => void;
31
+ removeAgentTracking: (key: string) => void;
32
+ createPtyTransportFactory?: (params: CliTransportFactoryParams) => PtyTransportFactory | null;
33
+ listHostedCliRuntimes?: () => Promise<HostedCliRuntimeDescriptor[]>;
34
+ };
35
+ /** CDP config */
36
+ enabledIdes?: string[];
37
+ /** Router transport-specific callbacks */
38
+ onStatusChange?: () => void;
39
+ onPostChatCommand?: () => void;
40
+ sessionHostControl?: SessionHostControlPlane | null;
41
+ getCdpLogFn?: (ideType: string) => (msg: string) => void;
42
+ /** Additional callback after CDP manager created (transport-specific extras) */
43
+ onCdpManagerSetup?: (ideType: string, manager: DaemonCdpManager, managerKey: string) => void | Promise<void>;
44
+ /** Poller callback (transport-specific) */
45
+ onStreamsUpdated?: (ideType: string, streams: any[]) => void;
46
+ /** Instance ticking interval (ms), default 5000 */
47
+ tickIntervalMs?: number;
48
+ /** CDP scan interval (ms), default 30000 */
49
+ cdpScanIntervalMs?: number;
50
+ }
51
+ export interface DaemonComponents {
52
+ providerLoader: ProviderLoader;
53
+ instanceManager: ProviderInstanceManager;
54
+ cliManager: DaemonCliManager;
55
+ commandHandler: DaemonCommandHandler;
56
+ agentStreamManager: DaemonAgentStreamManager;
57
+ router: DaemonCommandRouter;
58
+ poller: AgentStreamPoller;
59
+ cdpInitializer: DaemonCdpInitializer;
60
+ cdpManagers: Map<string, DaemonCdpManager>;
61
+ sessionRegistry: SessionRegistry;
62
+ detectedIdes: {
63
+ value: IDEInfo[];
64
+ };
65
+ }
66
+ export interface DaemonDevSupportOptions {
67
+ components: DaemonComponents;
68
+ logFn?: (msg: string) => void;
69
+ }
70
+ /**
71
+ * Initialize all daemon core components.
72
+ *
73
+ * Order:
74
+ * 1. Global log interceptor
75
+ * 2. ProviderLoader
76
+ * 3. InstanceManager + CliManager
77
+ * 4. Detect IDEs
78
+ * 5. CdpInitializer → connectAll + periodic scan + discovery
79
+ * 6. CommandHandler + AgentStreamManager
80
+ * 7. Router + Poller
81
+ * 8. Start instance ticking
82
+ */
83
+ export declare function initDaemonComponents(config: DaemonInitConfig): Promise<DaemonComponents>;
84
+ /**
85
+ * Start shared dev-only helpers:
86
+ * - DevServer on port 19280
87
+ * - Provider hot-reload watcher
88
+ */
89
+ export declare function startDaemonDevSupport(options: DaemonDevSupportOptions): Promise<DevServer>;
90
+ /**
91
+ * Graceful shutdown of all daemon components.
92
+ *
93
+ * Order:
94
+ * 1. Stop timers (poller, cdpInitializer)
95
+ * 2. Dispose agent stream
96
+ * 3. Shutdown CLIs
97
+ * 4. Dispose instances
98
+ * 5. Disconnect CDPs
99
+ */
100
+ export declare function shutdownDaemonComponents(components: DaemonComponents): Promise<void>;
@@ -68,6 +68,11 @@ export interface DaemonInitConfig {
68
68
 
69
69
  /** CDP scan interval (ms), default 30000 */
70
70
  cdpScanIntervalMs?: number;
71
+
72
+ /** Canonical status identity used by on-demand snapshot commands */
73
+ statusInstanceId?: string;
74
+ statusVersion?: string;
75
+ statusDaemonMode?: boolean;
71
76
  }
72
77
 
73
78
  // ─── Result ───
@@ -276,6 +281,8 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
276
281
  onStatusChange: config.onStatusChange,
277
282
  onPostChatCommand: config.onPostChatCommand,
278
283
  sessionHostControl: config.sessionHostControl,
284
+ statusInstanceId: config.statusInstanceId,
285
+ statusVersion: config.statusVersion,
279
286
  getCdpLogFn: config.getCdpLogFn || ((ideType: string) => LOG.forComponent(`CDP:${ideType}`).asLogFn()),
280
287
  });
281
288
 
@@ -0,0 +1,51 @@
1
+ /**
2
+ * CDP DOM Analysis Tools — DOM dump, query, debug
3
+ *
4
+ * Separated from daemon-commands.ts.
5
+ * Tools for analyzing DOM structure when developing new IDE scripts.
6
+ */
7
+ import type { DaemonCdpManager } from './manager.js';
8
+ import type { CommandResult } from '../commands/handler.js';
9
+ type CdpGetter = (ideType?: string) => DaemonCdpManager | null;
10
+ /**
11
+ * CDP DOM analysis handler
12
+ *
13
+ * Uses getCdp from DaemonCommandHandler.
14
+ */
15
+ export declare class CdpDomHandlers {
16
+ private getCdp;
17
+ constructor(getCdp: CdpGetter);
18
+ /**
19
+ * CDP DOM Dump — IDE's DOM tree retrieve
20
+ *
21
+ * args:
22
+ * selector?: string — CSS selector to dump specific area only (default: All)
23
+ * depth?: number — Dump depth limit (default: 10)
24
+ * attrs?: boolean — Whether to include properties (default: true)
25
+ * maxLength?: number — Max character count (default: 200000)
26
+ * format?: 'html' | 'tree' | 'summary' — Output format (default: 'html')
27
+ * sessionId?: string — Agent webview session ID (if provided, match webview DOM)
28
+ */
29
+ handleDomDump(args: any): Promise<CommandResult>;
30
+ /**
31
+ * CDP DOM Query — CSS Test selector
32
+ * Check how many elements match selector and what elements they are
33
+ *
34
+ * args:
35
+ * selector: string — CSS selector
36
+ * limit?: number — Max element count to return (default: 20)
37
+ * content?: boolean — Whether to include text content (default: true)
38
+ * sessionId?: string — agent webview session ID
39
+ */
40
+ handleDomQuery(args: any): Promise<CommandResult>;
41
+ /**
42
+ * CDP DOM Debug — IDE AI panel specialized analysis
43
+ * Collect all essential info at once when supporting new IDE
44
+ *
45
+ * args:
46
+ * ideType?: string — IDE type hint
47
+ * sessionId?: string — agent webview session ID
48
+ */
49
+ handleDomDebug(args: any): Promise<CommandResult>;
50
+ }
51
+ export {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * DaemonCdpInitializer — Unified CDP initialization + periodic scanning
3
+ *
4
+ * Unified CDP initialization + periodic scanning.
5
+ *
6
+ * Features:
7
+ * 1. Initial connection: connectAll() — multi-window aware
8
+ * 2. Periodic scan: startPeriodicScan() — auto-detect newly opened IDEs
9
+ * 3. Discovery: startDiscovery() — periodic agent webview discovery
10
+ */
11
+ import { DaemonCdpManager } from './manager.js';
12
+ import type { ProviderLoader } from '../providers/provider-loader.js';
13
+ export interface CdpInitializerConfig {
14
+ providerLoader: ProviderLoader;
15
+ cdpManagers: Map<string, DaemonCdpManager>;
16
+ /** Filter: only connect these IDEs (empty/undefined = all) */
17
+ enabledIdes?: string[];
18
+ /** Callback when a new CDP manager is connected */
19
+ onConnected?: (ideType: string, manager: DaemonCdpManager, managerKey: string) => void | Promise<void>;
20
+ /** Callback when a stale/disconnected CDP manager is removed */
21
+ onDisconnected?: (ideType: string, manager: DaemonCdpManager, managerKey: string, reason: 'ide_closed' | 'target_closed' | 'target_rekeyed') => void | Promise<void>;
22
+ }
23
+ export declare class DaemonCdpInitializer {
24
+ private config;
25
+ private scanTimer;
26
+ private discoveryTimer;
27
+ constructor(config: CdpInitializerConfig);
28
+ /**
29
+ * Connect to all detected IDEs.
30
+ * Multi-window aware: creates separate CdpManager per workbench page.
31
+ */
32
+ connectAll(detectedIdes: any[]): Promise<void>;
33
+ /**
34
+ * Connect to a single IDE port.
35
+ * Tries multi-window first (listAllTargets), falls back to direct connect.
36
+ */
37
+ private connectIdePort;
38
+ private pruneStaleManagers;
39
+ /**
40
+ * Start periodic scanning for newly opened IDEs.
41
+ * Idempotent — ignored if already started.
42
+ */
43
+ startPeriodicScan(intervalMs?: number): void;
44
+ /**
45
+ * Start periodic agent webview discovery.
46
+ */
47
+ startDiscovery(intervalMs?: number): void;
48
+ /** Stop all timers */
49
+ stop(): void;
50
+ }