@adhdev/daemon-core 0.8.76 → 0.8.78

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.
@@ -19,6 +19,7 @@ export interface CommandLogEntry {
19
19
  error?: string;
20
20
  durationMs?: number;
21
21
  }
22
+ export declare function shouldLogCommand(cmd: string): boolean;
22
23
  /**
23
24
  * Log a command received from the dashboard/WS/P2P/extension/API.
24
25
  * Call this at the entry point of command handling.
@@ -25,8 +25,12 @@ export interface ProviderRuntimeInfo {
25
25
  runtimeKey?: string;
26
26
  displayName?: string;
27
27
  workspaceLabel?: string;
28
+ lifecycle?: string | null;
29
+ surfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
28
30
  writeOwner?: ProviderRuntimeWriteOwner | null;
29
31
  attachedClients?: ProviderRuntimeClient[];
32
+ restoredFromStorage?: boolean;
33
+ recoveryState?: string | null;
30
34
  }
31
35
  export interface ActiveChatData {
32
36
  id: string;
@@ -242,10 +242,14 @@ export interface SessionEntry {
242
242
  runtimeKey?: string;
243
243
  runtimeDisplayName?: string;
244
244
  runtimeWorkspaceLabel?: string;
245
+ runtimeLifecycle?: string | null;
246
+ runtimeSurfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
245
247
  /** CLI only: active presentation mode */
246
248
  mode?: 'terminal' | 'chat';
247
249
  runtimeWriteOwner?: RuntimeWriteOwner | null;
248
250
  runtimeAttachedClients?: RuntimeAttachedClient[];
251
+ runtimeRestoredFromStorage?: boolean;
252
+ runtimeRecoveryState?: string | null;
249
253
  resume?: ProviderResumeCapability;
250
254
  activeChat: _ActiveChatData | null;
251
255
  capabilities?: SessionCapability[];
@@ -4,6 +4,10 @@ export interface HotChatSessionLike {
4
4
  id?: string | null;
5
5
  status?: unknown;
6
6
  lastMessageAt?: unknown;
7
+ runtimeLifecycle?: unknown;
8
+ runtimeSurfaceKind?: unknown;
9
+ runtimeRestoredFromStorage?: unknown;
10
+ runtimeRecoveryState?: unknown;
7
11
  }
8
12
  export declare function classifyHotChatSessionsForSubscriptionFlush(sessions: HotChatSessionLike[], previousHotSessionIds: ReadonlySet<string>, options?: {
9
13
  now?: number;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.8.76",
4
- "description": "ADHDev local session host core \u2014 session registry, protocol, buffers",
3
+ "version": "0.8.78",
4
+ "description": "ADHDev local session host core session registry, protocol, buffers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.8.76",
4
- "description": "ADHDev daemon core \u2014 CDP, IDE detection, providers, command execution",
3
+ "version": "0.8.78",
4
+ "description": "ADHDev daemon core CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -40,6 +40,8 @@ export interface PtyRuntimeMetadata {
40
40
  runtimeKey?: string;
41
41
  displayName?: string;
42
42
  workspaceLabel?: string;
43
+ lifecycle?: string | null;
44
+ surfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
43
45
  writeOwner?: PtyRuntimeWriteOwner | null;
44
46
  attachedClients?: PtyRuntimeClientInfo[];
45
47
  restoredFromStorage?: boolean;
@@ -375,6 +375,8 @@ class SessionHostRuntimeTransport implements PtyRuntimeTransport {
375
375
  runtimeKey: record.runtimeKey,
376
376
  displayName: record.displayName,
377
377
  workspaceLabel: record.workspaceLabel,
378
+ lifecycle: typeof record.lifecycle === 'string' ? record.lifecycle : null,
379
+ surfaceKind: record.surfaceKind,
378
380
  writeOwner: record.writeOwner ? {
379
381
  clientId: record.writeOwner.clientId,
380
382
  ownerType: record.writeOwner.ownerType,
@@ -116,8 +116,14 @@ function checkSize(): void {
116
116
  const SKIP_COMMANDS = new Set([
117
117
  'heartbeat',
118
118
  'status_report',
119
+ 'read_chat',
120
+ 'mark_session_seen',
119
121
  ]);
120
122
 
123
+ export function shouldLogCommand(cmd: string): boolean {
124
+ return !SKIP_COMMANDS.has(cmd);
125
+ }
126
+
121
127
  // ─── Public API ──────────────────────────────
122
128
 
123
129
  /**
@@ -125,7 +131,7 @@ const SKIP_COMMANDS = new Set([
125
131
  * Call this at the entry point of command handling.
126
132
  */
127
133
  export function logCommand(entry: CommandLogEntry): void {
128
- if (SKIP_COMMANDS.has(entry.cmd)) return;
134
+ if (!shouldLogCommand(entry.cmd)) return;
129
135
 
130
136
  try {
131
137
  if (++writeCount % 500 === 0) {
@@ -383,8 +383,12 @@ export class CliProviderInstance implements ProviderInstance {
383
383
  runtimeKey: runtime.runtimeKey,
384
384
  displayName: runtime.displayName,
385
385
  workspaceLabel: runtime.workspaceLabel,
386
+ lifecycle: runtime.lifecycle ?? null,
387
+ surfaceKind: runtime.surfaceKind,
386
388
  writeOwner: runtime.writeOwner || null,
387
389
  attachedClients: runtime.attachedClients || [],
390
+ restoredFromStorage: runtime.restoredFromStorage === true,
391
+ recoveryState: runtime.recoveryState ?? null,
388
392
  } : undefined,
389
393
  resume: this.provider.resume,
390
394
  controlValues: surface.controlValues,
@@ -32,8 +32,12 @@ export interface ProviderRuntimeInfo {
32
32
  runtimeKey?: string;
33
33
  displayName?: string;
34
34
  workspaceLabel?: string;
35
+ lifecycle?: string | null;
36
+ surfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
35
37
  writeOwner?: ProviderRuntimeWriteOwner | null;
36
38
  attachedClients?: ProviderRuntimeClient[];
39
+ restoredFromStorage?: boolean;
40
+ recoveryState?: string | null;
37
41
  }
38
42
 
39
43
  export interface ActiveChatData {
@@ -309,10 +309,14 @@ export interface SessionEntry {
309
309
  runtimeKey?: string;
310
310
  runtimeDisplayName?: string;
311
311
  runtimeWorkspaceLabel?: string;
312
+ runtimeLifecycle?: string | null;
313
+ runtimeSurfaceKind?: 'live_runtime' | 'recovery_snapshot' | 'inactive_record';
312
314
  /** CLI only: active presentation mode */
313
315
  mode?: 'terminal' | 'chat';
314
316
  runtimeWriteOwner?: RuntimeWriteOwner | null;
315
317
  runtimeAttachedClients?: RuntimeAttachedClient[];
318
+ runtimeRestoredFromStorage?: boolean;
319
+ runtimeRecoveryState?: string | null;
316
320
  resume?: ProviderResumeCapability;
317
321
  activeChat: _ActiveChatData | null;
318
322
  capabilities?: SessionCapability[];
@@ -50,7 +50,7 @@ function shouldIncludeSessionMetadata(profile: SessionEntryProfile): boolean {
50
50
  }
51
51
 
52
52
  function shouldIncludeRuntimeMetadata(profile: SessionEntryProfile): boolean {
53
- return profile !== 'live';
53
+ return true;
54
54
  }
55
55
 
56
56
  // ─── CDP Manager lookup helpers ──────────────────────
@@ -266,8 +266,12 @@ function buildCliSession(state: CliProviderState, options: SessionEntryBuildOpti
266
266
  runtimeKey: state.runtime?.runtimeKey,
267
267
  runtimeDisplayName: state.runtime?.displayName,
268
268
  runtimeWorkspaceLabel: state.runtime?.workspaceLabel,
269
+ runtimeLifecycle: state.runtime?.lifecycle ?? null,
270
+ runtimeSurfaceKind: state.runtime?.surfaceKind,
269
271
  runtimeWriteOwner: state.runtime?.writeOwner || null,
270
272
  runtimeAttachedClients: state.runtime?.attachedClients || [],
273
+ runtimeRestoredFromStorage: state.runtime?.restoredFromStorage === true,
274
+ runtimeRecoveryState: state.runtime?.recoveryState ?? null,
271
275
  }),
272
276
  mode: state.mode,
273
277
  resume: state.resume,
@@ -1,3 +1,5 @@
1
+ import { getSessionHostSurfaceKind } from '../session-host/runtime-surface.js';
2
+
1
3
  export const DEFAULT_ACTIVE_CHAT_POLL_STATUSES = new Set([
2
4
  'generating',
3
5
  'waiting_approval',
@@ -6,10 +8,16 @@ export const DEFAULT_ACTIVE_CHAT_POLL_STATUSES = new Set([
6
8
 
7
9
  export const DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS = 8_000;
8
10
 
11
+ const LIVE_RUNTIME_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'interrupted']);
12
+
9
13
  export interface HotChatSessionLike {
10
14
  id?: string | null;
11
15
  status?: unknown;
12
16
  lastMessageAt?: unknown;
17
+ runtimeLifecycle?: unknown;
18
+ runtimeSurfaceKind?: unknown;
19
+ runtimeRestoredFromStorage?: unknown;
20
+ runtimeRecoveryState?: unknown;
13
21
  }
14
22
 
15
23
  function parseMessageTimestamp(value: unknown): number {
@@ -21,6 +29,27 @@ function parseMessageTimestamp(value: unknown): number {
21
29
  return 0;
22
30
  }
23
31
 
32
+ function isDefinitelyNonLiveRuntimeSession(session: HotChatSessionLike): boolean {
33
+ const surfaceKind = String(session?.runtimeSurfaceKind || '').trim();
34
+ if (surfaceKind === 'live_runtime') return false;
35
+ if (surfaceKind === 'recovery_snapshot') return true;
36
+ if (surfaceKind === 'inactive_record') return false;
37
+
38
+ const lifecycle = String(session?.runtimeLifecycle || '').trim();
39
+ if (lifecycle && LIVE_RUNTIME_LIFECYCLES.has(lifecycle)) return false;
40
+
41
+ const inferredSurfaceKind = getSessionHostSurfaceKind({
42
+ lifecycle: lifecycle || null,
43
+ meta: {
44
+ restoredFromStorage: session?.runtimeRestoredFromStorage === true,
45
+ ...(session?.runtimeRecoveryState ? { runtimeRecoveryState: session.runtimeRecoveryState } : {}),
46
+ },
47
+ });
48
+ if (inferredSurfaceKind === 'recovery_snapshot') return true;
49
+
50
+ return false;
51
+ }
52
+
24
53
  export function classifyHotChatSessionsForSubscriptionFlush(
25
54
  sessions: HotChatSessionLike[],
26
55
  previousHotSessionIds: ReadonlySet<string>,
@@ -39,10 +68,15 @@ export function classifyHotChatSessionsForSubscriptionFlush(
39
68
  );
40
69
  const activeStatuses = options.activeStatuses ?? DEFAULT_ACTIVE_CHAT_POLL_STATUSES;
41
70
  const active = new Set<string>();
71
+ const excluded = new Set<string>();
42
72
 
43
73
  for (const session of sessions) {
44
74
  const sessionId = typeof session?.id === 'string' ? session.id : '';
45
75
  if (!sessionId) continue;
76
+ if (isDefinitelyNonLiveRuntimeSession(session)) {
77
+ excluded.add(sessionId);
78
+ continue;
79
+ }
46
80
 
47
81
  const status = String(session?.status || '').toLowerCase();
48
82
  const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
@@ -54,7 +88,7 @@ export function classifyHotChatSessionsForSubscriptionFlush(
54
88
  }
55
89
 
56
90
  const finalizing = new Set(
57
- Array.from(previousHotSessionIds).filter((sessionId) => !active.has(sessionId)),
91
+ Array.from(previousHotSessionIds).filter((sessionId) => !active.has(sessionId) && !excluded.has(sessionId)),
58
92
  );
59
93
 
60
94
  return { active, finalizing };