@adhdev/daemon-core 0.8.81 → 0.8.83
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/cli-adapters/provider-cli-adapter.d.ts +2 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +2 -0
- package/dist/config/recent-activity.d.ts +14 -0
- package/dist/config/state-store.d.ts +4 -0
- package/dist/index.js +363 -117
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +363 -117
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +0 -2
- package/dist/providers/cli-provider-instance.d.ts +2 -0
- package/dist/providers/provider-instance.d.ts +1 -1
- package/dist/shared-types.d.ts +3 -1
- package/dist/status/chat-tail-hot-sessions.d.ts +2 -0
- package/dist/status/snapshot.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapter-types.d.ts +2 -0
- package/src/cli-adapters/provider-cli-adapter.ts +107 -30
- package/src/cli-adapters/provider-cli-shared.d.ts +3 -4
- package/src/cli-adapters/provider-cli-shared.ts +2 -0
- package/src/cli-adapters/terminal-screen.ts +6 -4
- package/src/commands/chat-commands.ts +8 -3
- package/src/commands/router.ts +59 -1
- package/src/config/recent-activity.ts +122 -0
- package/src/config/state-store.ts +16 -0
- package/src/logging/command-log.ts +2 -0
- package/src/providers/acp-provider-instance.ts +2 -17
- package/src/providers/cli-provider-instance.ts +33 -10
- package/src/providers/extension-provider-instance.ts +0 -2
- package/src/providers/ide-provider-instance.ts +0 -2
- package/src/providers/provider-instance.d.ts +1 -1
- package/src/providers/provider-instance.ts +1 -0
- package/src/shared-types.d.ts +3 -0
- package/src/shared-types.ts +5 -1
- package/src/status/chat-tail-hot-sessions.ts +15 -1
- package/src/status/snapshot.ts +20 -3
|
@@ -23,6 +23,10 @@ export interface DaemonState {
|
|
|
23
23
|
sessionReads: Record<string, number>;
|
|
24
24
|
/** Last seen completion marker for live sessions, keyed by sessionId */
|
|
25
25
|
sessionReadMarkers: Record<string, string>;
|
|
26
|
+
/** Current notification dismissal ids keyed by stable session target */
|
|
27
|
+
sessionNotificationDismissals: Record<string, string>;
|
|
28
|
+
/** Current notification unread override ids keyed by stable session target */
|
|
29
|
+
sessionNotificationUnreadOverrides: Record<string, string>;
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
const DEFAULT_STATE: DaemonState = {
|
|
@@ -30,6 +34,8 @@ const DEFAULT_STATE: DaemonState = {
|
|
|
30
34
|
savedProviderSessions: [],
|
|
31
35
|
sessionReads: {},
|
|
32
36
|
sessionReadMarkers: {},
|
|
37
|
+
sessionNotificationDismissals: {},
|
|
38
|
+
sessionNotificationUnreadOverrides: {},
|
|
33
39
|
};
|
|
34
40
|
|
|
35
41
|
function isPlainObject(value: unknown): value is Record<string, any> {
|
|
@@ -71,12 +77,22 @@ function normalizeState(raw: unknown): DaemonState {
|
|
|
71
77
|
Object.entries(isPlainObject(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {})
|
|
72
78
|
.filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === 'string')
|
|
73
79
|
);
|
|
80
|
+
const sessionNotificationDismissals = Object.fromEntries(
|
|
81
|
+
Object.entries(isPlainObject(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {})
|
|
82
|
+
.filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === 'string' && value.length > 0)
|
|
83
|
+
);
|
|
84
|
+
const sessionNotificationUnreadOverrides = Object.fromEntries(
|
|
85
|
+
Object.entries(isPlainObject(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {})
|
|
86
|
+
.filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === 'string' && value.length > 0)
|
|
87
|
+
);
|
|
74
88
|
|
|
75
89
|
return {
|
|
76
90
|
recentActivity,
|
|
77
91
|
savedProviderSessions,
|
|
78
92
|
sessionReads,
|
|
79
93
|
sessionReadMarkers,
|
|
94
|
+
sessionNotificationDismissals,
|
|
95
|
+
sessionNotificationUnreadOverrides,
|
|
80
96
|
};
|
|
81
97
|
}
|
|
82
98
|
|
|
@@ -286,9 +286,8 @@ export class AcpProviderInstance implements ProviderInstance {
|
|
|
286
286
|
getState(): AcpProviderState {
|
|
287
287
|
const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const content = this.truncateContent(m.content);
|
|
289
|
+
const recentMessages = normalizeChatMessages(this.messages.map(m => {
|
|
290
|
+
const content = m.content;
|
|
292
291
|
return buildChatMessage({
|
|
293
292
|
...m,
|
|
294
293
|
content,
|
|
@@ -1239,19 +1238,6 @@ export class AcpProviderInstance implements ProviderInstance {
|
|
|
1239
1238
|
|
|
1240
1239
|
// ─── Rich Content Helpers ────────────────────────────
|
|
1241
1240
|
|
|
1242
|
-
/** Truncate content for transport (text: 2000 chars, images preserved) */
|
|
1243
|
-
private truncateContent(content: string | ContentBlock[]): string | ContentBlock[] {
|
|
1244
|
-
if (typeof content === 'string') {
|
|
1245
|
-
return content.length > 2000 ? content.slice(0, 2000) + '\n... (truncated)' : content;
|
|
1246
|
-
}
|
|
1247
|
-
return content.map(b => {
|
|
1248
|
-
if (b.type === 'text' && b.text.length > 2000) {
|
|
1249
|
-
return { ...b, text: b.text.slice(0, 2000) + '\n... (truncated)' };
|
|
1250
|
-
}
|
|
1251
|
-
return b;
|
|
1252
|
-
});
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
1241
|
/** Build ContentBlock[] from current partial state */
|
|
1256
1242
|
private buildPartialBlocks(): ContentBlock[] {
|
|
1257
1243
|
const blocks: ContentBlock[] = [];
|
|
@@ -1437,7 +1423,6 @@ export class AcpProviderInstance implements ProviderInstance {
|
|
|
1437
1423
|
|
|
1438
1424
|
private pushEvent(event: ProviderEvent): void {
|
|
1439
1425
|
this.events.push(event);
|
|
1440
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
1441
1426
|
}
|
|
1442
1427
|
|
|
1443
1428
|
private appendSystemMessage(content: string, timestamp = Date.now()): void {
|
|
@@ -12,7 +12,7 @@ import * as fs from 'fs';
|
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
13
|
import { normalizeInputEnvelope, type ProviderModule, flattenContent } from './contracts.js';
|
|
14
14
|
import { assertTextOnlyInput } from './provider-input-support.js';
|
|
15
|
-
import type { ProviderInstance, ProviderState, ProviderEvent, InstanceContext } from './provider-instance.js';
|
|
15
|
+
import type { ProviderInstance, ProviderState, ProviderEvent, InstanceContext, ProviderErrorReason } from './provider-instance.js';
|
|
16
16
|
import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
|
|
17
17
|
import type { CliProviderModule } from '../cli-adapters/provider-cli-adapter.js';
|
|
18
18
|
import type { PtyRuntimeMetadata, PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
@@ -114,6 +114,8 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
114
114
|
private runtimeMessages: Array<{ key: string; message: ChatMessage }> = [];
|
|
115
115
|
readonly instanceId: string;
|
|
116
116
|
private suppressIdleHistoryReplay = false;
|
|
117
|
+
private errorMessage: string | undefined = undefined;
|
|
118
|
+
private errorReason: ProviderErrorReason | undefined = undefined;
|
|
117
119
|
|
|
118
120
|
private presentationMode: 'terminal' | 'chat';
|
|
119
121
|
private providerSessionId?: string;
|
|
@@ -229,6 +231,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
229
231
|
|
|
230
232
|
async onTick(): Promise<void> {
|
|
231
233
|
if (this.providerSessionId) return;
|
|
234
|
+
if (this.type === 'hermes-cli' && this.launchMode === 'new') return;
|
|
232
235
|
|
|
233
236
|
let probedSessionId: string | null = null;
|
|
234
237
|
|
|
@@ -302,9 +305,26 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
302
305
|
|
|
303
306
|
getState(): ProviderState {
|
|
304
307
|
const adapterStatus = this.adapter.getStatus();
|
|
305
|
-
|
|
308
|
+
let parsedStatus: any = null;
|
|
309
|
+
let parseErrorMessage: string | undefined;
|
|
310
|
+
if (typeof this.adapter.getScriptParsedStatus === 'function') {
|
|
311
|
+
try {
|
|
312
|
+
parsedStatus = this.adapter.getScriptParsedStatus() || null;
|
|
313
|
+
this.errorMessage = undefined;
|
|
314
|
+
this.errorReason = undefined;
|
|
315
|
+
} catch (error: any) {
|
|
316
|
+
parseErrorMessage = error?.message || String(error);
|
|
317
|
+
this.errorMessage = parseErrorMessage;
|
|
318
|
+
this.errorReason = 'parse_error';
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
this.errorMessage = undefined;
|
|
322
|
+
this.errorReason = undefined;
|
|
323
|
+
}
|
|
306
324
|
const autoApproveActive = adapterStatus.status === 'waiting_approval' && this.shouldAutoApprove();
|
|
307
|
-
const visibleStatus =
|
|
325
|
+
const visibleStatus = parseErrorMessage
|
|
326
|
+
? 'error'
|
|
327
|
+
: (autoApproveActive ? 'generating' : adapterStatus.status);
|
|
308
328
|
const parsedProviderSessionId = normalizeProviderSessionId(
|
|
309
329
|
this.type,
|
|
310
330
|
typeof parsedStatus?.providerSessionId === 'string' ? parsedStatus.providerSessionId : '',
|
|
@@ -314,7 +334,11 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
314
334
|
}
|
|
315
335
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
316
336
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
317
|
-
let parsedMessages = Array.isArray(parsedStatus?.messages)
|
|
337
|
+
let parsedMessages = Array.isArray(parsedStatus?.messages)
|
|
338
|
+
? parsedStatus.messages
|
|
339
|
+
: (parseErrorMessage
|
|
340
|
+
? normalizeChatMessages(Array.isArray(adapterStatus.messages) ? adapterStatus.messages as any : [])
|
|
341
|
+
: []);
|
|
318
342
|
const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount)
|
|
319
343
|
? Math.max(0, Number(parsedStatus.historyMessageCount))
|
|
320
344
|
: null;
|
|
@@ -365,7 +389,9 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
365
389
|
activeChat: {
|
|
366
390
|
id: `${this.type}_${this.workingDir}`,
|
|
367
391
|
title: parsedStatus?.title || dirName,
|
|
368
|
-
status:
|
|
392
|
+
status: parseErrorMessage
|
|
393
|
+
? 'error'
|
|
394
|
+
: autoApproveActive && parsedStatus?.status === 'waiting_approval'
|
|
369
395
|
? 'generating'
|
|
370
396
|
: (parsedStatus?.status || visibleStatus),
|
|
371
397
|
messages: mergedMessages,
|
|
@@ -394,6 +420,8 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
394
420
|
controlValues: surface.controlValues,
|
|
395
421
|
providerControls: this.provider.controls,
|
|
396
422
|
summaryMetadata: surface.summaryMetadata as any,
|
|
423
|
+
errorMessage: this.errorMessage,
|
|
424
|
+
errorReason: this.errorReason,
|
|
397
425
|
};
|
|
398
426
|
}
|
|
399
427
|
|
|
@@ -591,8 +619,6 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
591
619
|
|
|
592
620
|
private pushEvent(event: ProviderEvent): void {
|
|
593
621
|
this.events.push(event);
|
|
594
|
-
// Max 50
|
|
595
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
596
622
|
}
|
|
597
623
|
|
|
598
624
|
private flushEvents(): ProviderEvent[] {
|
|
@@ -805,9 +831,6 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
805
831
|
key: dedupKey,
|
|
806
832
|
message: normalizedMessage,
|
|
807
833
|
});
|
|
808
|
-
if (this.runtimeMessages.length > 50) {
|
|
809
|
-
this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
810
|
-
}
|
|
811
834
|
|
|
812
835
|
if (normalizedContent) {
|
|
813
836
|
this.historyWriter.appendNewMessages(
|
|
@@ -246,7 +246,6 @@ export class ExtensionProviderInstance implements ProviderInstance {
|
|
|
246
246
|
|
|
247
247
|
private pushEvent(event: ProviderEvent): void {
|
|
248
248
|
this.events.push(event);
|
|
249
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
250
249
|
}
|
|
251
250
|
|
|
252
251
|
private applyProviderResponse(data: any, options: { phase: 'immediate' | 'turn_completed' }): void {
|
|
@@ -335,7 +334,6 @@ export class ExtensionProviderInstance implements ProviderInstance {
|
|
|
335
334
|
key: dedupKey,
|
|
336
335
|
message: normalizedMessage,
|
|
337
336
|
});
|
|
338
|
-
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
339
337
|
|
|
340
338
|
if (normalizedContent) {
|
|
341
339
|
this.historyWriter.appendNewMessages(
|
|
@@ -473,7 +473,6 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
473
473
|
|
|
474
474
|
private pushEvent(event: ProviderEvent): void {
|
|
475
475
|
this.events.push(event);
|
|
476
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
477
476
|
}
|
|
478
477
|
|
|
479
478
|
private applyProviderResponse(data: any, options: { phase: 'immediate' | 'turn_completed' }): void {
|
|
@@ -576,7 +575,6 @@ export class IdeProviderInstance implements ProviderInstance {
|
|
|
576
575
|
key: dedupKey,
|
|
577
576
|
message: normalizedMessage,
|
|
578
577
|
});
|
|
579
|
-
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
580
578
|
|
|
581
579
|
if (normalizedContent) {
|
|
582
580
|
this.historyWriter.appendNewMessages(
|
|
@@ -40,7 +40,7 @@ export interface ActiveChatData {
|
|
|
40
40
|
inputContent?: string;
|
|
41
41
|
}
|
|
42
42
|
/** Standardized error reasons across all provider categories */
|
|
43
|
-
export type ProviderErrorReason = 'not_installed' | 'auth_failed' | 'spawn_error' | 'init_failed' | 'crash' | 'timeout' | 'cdp_error' | 'disconnected';
|
|
43
|
+
export type ProviderErrorReason = 'not_installed' | 'auth_failed' | 'spawn_error' | 'init_failed' | 'parse_error' | 'crash' | 'timeout' | 'cdp_error' | 'disconnected';
|
|
44
44
|
/** Common fields shared by all provider categories */
|
|
45
45
|
interface ProviderStateBase {
|
|
46
46
|
/** Provider type (e.g. 'gemini-cli', 'cursor', 'cline') */
|
|
@@ -55,6 +55,7 @@ export type ProviderErrorReason =
|
|
|
55
55
|
| 'auth_failed' // Authentication/API key error
|
|
56
56
|
| 'spawn_error' // Process spawn failure
|
|
57
57
|
| 'init_failed' // Initialization/handshake failure
|
|
58
|
+
| 'parse_error' // Provider parser/adapter script failure
|
|
58
59
|
| 'crash' // Unexpected process crash
|
|
59
60
|
| 'timeout' // Operation timeout
|
|
60
61
|
| 'cdp_error' // CDP connection failure (IDE)
|
package/src/shared-types.d.ts
CHANGED
|
@@ -190,10 +190,13 @@ export interface SessionEntry {
|
|
|
190
190
|
summaryMetadata?: ProviderSummaryMetadata;
|
|
191
191
|
errorMessage?: string;
|
|
192
192
|
errorReason?: _ProviderErrorReason;
|
|
193
|
+
lastMessageHash?: string;
|
|
193
194
|
lastUpdated?: number;
|
|
194
195
|
unread?: boolean;
|
|
195
196
|
lastSeenAt?: number;
|
|
196
197
|
inboxBucket?: RecentSessionBucket;
|
|
198
|
+
completionMarker?: string;
|
|
199
|
+
seenCompletionMarker?: string;
|
|
197
200
|
surfaceHidden?: boolean;
|
|
198
201
|
}
|
|
199
202
|
/**
|
package/src/shared-types.ts
CHANGED
|
@@ -290,7 +290,9 @@ export type SessionCapability =
|
|
|
290
290
|
| 'resize_terminal'
|
|
291
291
|
| 'change_model'
|
|
292
292
|
| 'set_mode'
|
|
293
|
-
| 'set_thought_level'
|
|
293
|
+
| 'set_thought_level'
|
|
294
|
+
| 'delete_notification'
|
|
295
|
+
| 'mark_notification_unread';
|
|
294
296
|
|
|
295
297
|
import type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
296
298
|
export type { RuntimeWriteOwner, RuntimeAttachedClient, SessionStatus } from './shared-types-extra.js';
|
|
@@ -337,6 +339,8 @@ export interface SessionEntry {
|
|
|
337
339
|
unread?: boolean;
|
|
338
340
|
lastSeenAt?: number;
|
|
339
341
|
inboxBucket?: RecentSessionBucket;
|
|
342
|
+
completionMarker?: string;
|
|
343
|
+
seenCompletionMarker?: string;
|
|
340
344
|
surfaceHidden?: boolean;
|
|
341
345
|
}
|
|
342
346
|
|
|
@@ -13,6 +13,8 @@ const LIVE_RUNTIME_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'int
|
|
|
13
13
|
export interface HotChatSessionLike {
|
|
14
14
|
id?: string | null;
|
|
15
15
|
status?: unknown;
|
|
16
|
+
unread?: unknown;
|
|
17
|
+
inboxBucket?: unknown;
|
|
16
18
|
lastMessageAt?: unknown;
|
|
17
19
|
runtimeLifecycle?: unknown;
|
|
18
20
|
runtimeSurfaceKind?: unknown;
|
|
@@ -79,10 +81,22 @@ export function classifyHotChatSessionsForSubscriptionFlush(
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
const status = String(session?.status || '').toLowerCase();
|
|
84
|
+
const unread = session?.unread === true;
|
|
85
|
+
const inboxBucket = String(session?.inboxBucket || '').toLowerCase();
|
|
86
|
+
const runtimeSurfaceKind = String(session?.runtimeSurfaceKind || '').toLowerCase();
|
|
87
|
+
const runtimeLifecycle = String(session?.runtimeLifecycle || '').toLowerCase();
|
|
88
|
+
const isLiveRuntime = runtimeSurfaceKind === 'live_runtime' || LIVE_RUNTIME_LIFECYCLES.has(runtimeLifecycle);
|
|
82
89
|
const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
|
|
83
90
|
const recentlyUpdated = lastMessageAt > 0 && (now - lastMessageAt) <= recentMessageGraceMs;
|
|
91
|
+
const shouldKeepRecentTailHot = recentlyUpdated && (
|
|
92
|
+
unread
|
|
93
|
+
|| inboxBucket === 'task_complete'
|
|
94
|
+
|| inboxBucket === 'needs_attention'
|
|
95
|
+
|| isLiveRuntime
|
|
96
|
+
|| activeStatuses.has(status)
|
|
97
|
+
);
|
|
84
98
|
|
|
85
|
-
if (activeStatuses.has(status) ||
|
|
99
|
+
if (activeStatuses.has(status) || shouldKeepRecentTailHot) {
|
|
86
100
|
active.add(sessionId);
|
|
87
101
|
}
|
|
88
102
|
}
|
package/src/status/snapshot.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import * as os from 'os';
|
|
10
10
|
import { loadConfig } from '../config/config.js';
|
|
11
11
|
import { loadState } from '../config/state-store.js';
|
|
12
|
-
import { getRecentActivity, getSessionSeenAt, getSessionSeenMarker } from '../config/recent-activity.js';
|
|
12
|
+
import { getRecentActivity, getSessionSeenAt, getSessionSeenMarker, getSessionNotificationDismissal, getSessionNotificationUnreadOverride, applySessionNotificationOverlay, getSessionCurrentNotificationId } from '../config/recent-activity.js';
|
|
13
13
|
import { getWorkspaceState } from '../config/workspaces.js';
|
|
14
14
|
import { getHostMemorySnapshot } from '../system/host-memory.js';
|
|
15
15
|
import { getTerminalBackendRuntimeStatus } from '../cli-adapters/terminal-screen.js';
|
|
@@ -259,6 +259,8 @@ function getLastDisplayMessage(session: {
|
|
|
259
259
|
return null;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
export { getSessionCurrentNotificationId, applySessionNotificationOverlay } from '../config/recent-activity.js';
|
|
263
|
+
|
|
262
264
|
function getSessionMessageUpdatedAt(session: {
|
|
263
265
|
activeChat?: {
|
|
264
266
|
messages?: Array<{ receivedAt?: number | string; timestamp?: number | string }> | null
|
|
@@ -390,9 +392,24 @@ export function buildStatusSnapshot(options: StatusSnapshotOptions): StatusSnaps
|
|
|
390
392
|
completionMarker,
|
|
391
393
|
seenCompletionMarker,
|
|
392
394
|
);
|
|
395
|
+
const { unread: overlayUnread, inboxBucket: overlayInboxBucket } = applySessionNotificationOverlay({
|
|
396
|
+
id: sourceSession.id,
|
|
397
|
+
providerSessionId: sourceSession.providerSessionId,
|
|
398
|
+
status: sourceSession.status,
|
|
399
|
+
unread,
|
|
400
|
+
inboxBucket,
|
|
401
|
+
lastMessageHash: sourceSession.lastMessageHash,
|
|
402
|
+
lastMessageAt: sourceSession.lastMessageAt,
|
|
403
|
+
lastUpdated: sourceSession.lastUpdated,
|
|
404
|
+
}, {
|
|
405
|
+
dismissedNotificationId: getSessionNotificationDismissal(state, sourceSession.id, sourceSession.providerSessionId),
|
|
406
|
+
unreadNotificationId: getSessionNotificationUnreadOverride(state, sourceSession.id, sourceSession.providerSessionId),
|
|
407
|
+
});
|
|
393
408
|
session.lastSeenAt = lastSeenAt;
|
|
394
|
-
session.unread =
|
|
395
|
-
session.inboxBucket =
|
|
409
|
+
session.unread = overlayUnread;
|
|
410
|
+
session.inboxBucket = overlayInboxBucket;
|
|
411
|
+
session.completionMarker = completionMarker;
|
|
412
|
+
session.seenCompletionMarker = seenCompletionMarker;
|
|
396
413
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== 'idle' || session.providerType.includes('codex'))) {
|
|
397
414
|
const recentReadSnapshot: RecentReadDebugSnapshot = {
|
|
398
415
|
sessionId: session.id,
|