@adhdev/daemon-core 0.8.80 → 0.8.82

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 (32) hide show
  1. package/dist/cli-adapters/provider-cli-adapter.d.ts +1 -0
  2. package/dist/cli-adapters/provider-cli-shared.d.ts +2 -0
  3. package/dist/config/recent-activity.d.ts +14 -0
  4. package/dist/config/state-store.d.ts +4 -0
  5. package/dist/index.js +232 -41
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +232 -41
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/providers/acp-provider-instance.d.ts +0 -2
  10. package/dist/providers/cli-provider-instance.d.ts +2 -0
  11. package/dist/providers/provider-instance.d.ts +1 -1
  12. package/dist/shared-types.d.ts +1 -1
  13. package/dist/status/snapshot.d.ts +1 -0
  14. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  15. package/package.json +1 -1
  16. package/src/cli-adapter-types.d.ts +2 -0
  17. package/src/cli-adapters/provider-cli-adapter.ts +14 -5
  18. package/src/cli-adapters/provider-cli-shared.d.ts +3 -4
  19. package/src/cli-adapters/provider-cli-shared.ts +2 -0
  20. package/src/commands/chat-commands.ts +8 -3
  21. package/src/commands/router.ts +59 -1
  22. package/src/config/recent-activity.ts +122 -0
  23. package/src/config/state-store.ts +16 -0
  24. package/src/logging/command-log.ts +2 -0
  25. package/src/providers/acp-provider-instance.ts +2 -17
  26. package/src/providers/cli-provider-instance.ts +32 -10
  27. package/src/providers/extension-provider-instance.ts +0 -2
  28. package/src/providers/ide-provider-instance.ts +0 -2
  29. package/src/providers/provider-instance.d.ts +1 -1
  30. package/src/providers/provider-instance.ts +1 -0
  31. package/src/shared-types.ts +3 -1
  32. package/src/status/snapshot.ts +18 -3
@@ -39,6 +39,7 @@ export declare class ProviderCliAdapter implements CliAdapter {
39
39
  private recentOutputBuffer;
40
40
  private isWaitingForResponse;
41
41
  private activeModal;
42
+ private parseErrorMessage;
42
43
  private responseTimeout;
43
44
  private idleTimeout;
44
45
  private ready;
@@ -20,6 +20,8 @@ export interface CliSessionStatus {
20
20
  message: string;
21
21
  buttons: string[];
22
22
  } | null;
23
+ errorMessage?: string;
24
+ errorReason?: string;
23
25
  }
24
26
  export interface CliScripts {
25
27
  parseOutput?: (input: CliScriptInput) => any;
@@ -7,6 +7,7 @@
7
7
  * - used only for quick-launch shortcuts
8
8
  */
9
9
  import type { ProviderSummaryMetadata } from '../shared-types.js';
10
+ import type { RecentSessionBucket, SessionEntry } from '../shared-types.js';
10
11
  import type { DaemonState } from './state-store.js';
11
12
  export interface RecentActivityEntry {
12
13
  id: string;
@@ -28,4 +29,17 @@ export declare function getRecentActivity(state: DaemonState, limit?: number): R
28
29
  export declare function buildSessionReadStateKey(sessionId: string, providerSessionId?: string | null): string;
29
30
  export declare function getSessionSeenAt(state: DaemonState, sessionId: string, providerSessionId?: string | null): number;
30
31
  export declare function getSessionSeenMarker(state: DaemonState, sessionId: string, providerSessionId?: string | null): string;
32
+ export declare function getSessionNotificationDismissal(state: DaemonState, sessionId: string, providerSessionId?: string | null): string;
33
+ export declare function getSessionNotificationUnreadOverride(state: DaemonState, sessionId: string, providerSessionId?: string | null): string;
34
+ export declare function dismissSessionNotification(state: DaemonState, sessionId: string, notificationId: string, providerSessionId?: string | null): DaemonState;
35
+ export declare function markSessionNotificationUnread(state: DaemonState, sessionId: string, notificationId: string, providerSessionId?: string | null): DaemonState;
36
+ export declare function getSessionNotificationTargetValue(session: Pick<SessionEntry, 'id' | 'providerSessionId'>): string;
37
+ export declare function getSessionCurrentNotificationId(session: Pick<SessionEntry, 'id' | 'providerSessionId' | 'inboxBucket' | 'unread' | 'lastMessageHash' | 'lastMessageAt' | 'lastUpdated' | 'status'>): string;
38
+ export declare function applySessionNotificationOverlay(session: Pick<SessionEntry, 'id' | 'providerSessionId' | 'inboxBucket' | 'unread' | 'lastMessageHash' | 'lastMessageAt' | 'lastUpdated' | 'status'>, overlay: {
39
+ dismissedNotificationId?: string | null;
40
+ unreadNotificationId?: string | null;
41
+ }): {
42
+ unread: boolean;
43
+ inboxBucket: RecentSessionBucket;
44
+ };
31
45
  export declare function markSessionSeen(state: DaemonState, sessionId: string, seenAt?: number, completionMarker?: string | null, providerSessionId?: string | null): DaemonState;
@@ -17,6 +17,10 @@ export interface DaemonState {
17
17
  sessionReads: Record<string, number>;
18
18
  /** Last seen completion marker for live sessions, keyed by sessionId */
19
19
  sessionReadMarkers: Record<string, string>;
20
+ /** Current notification dismissal ids keyed by stable session target */
21
+ sessionNotificationDismissals: Record<string, string>;
22
+ /** Current notification unread override ids keyed by stable session target */
23
+ sessionNotificationUnreadOverrides: Record<string, string>;
20
24
  }
21
25
  /**
22
26
  * Load runtime state from disk
package/dist/index.js CHANGED
@@ -1860,6 +1860,7 @@ var init_provider_cli_adapter = __esm({
1860
1860
  recentOutputBuffer = "";
1861
1861
  isWaitingForResponse = false;
1862
1862
  activeModal = null;
1863
+ parseErrorMessage = null;
1863
1864
  responseTimeout = null;
1864
1865
  idleTimeout = null;
1865
1866
  ready = false;
@@ -2854,10 +2855,12 @@ var init_provider_cli_adapter = __esm({
2854
2855
  // ─── Public API (CliAdapter) ───────────────────
2855
2856
  getStatus() {
2856
2857
  return {
2857
- status: this.currentStatus,
2858
+ status: this.parseErrorMessage ? "error" : this.currentStatus,
2858
2859
  messages: [...this.committedMessages],
2859
2860
  workingDir: this.workingDir,
2860
- activeModal: this.activeModal
2861
+ activeModal: this.activeModal,
2862
+ errorMessage: this.parseErrorMessage || void 0,
2863
+ errorReason: this.parseErrorMessage ? "parse_error" : void 0
2861
2864
  };
2862
2865
  }
2863
2866
  seedCommittedMessages(messages) {
@@ -2911,7 +2914,7 @@ var init_provider_cli_adapter = __esm({
2911
2914
  id: "cli_session",
2912
2915
  status: this.currentStatus,
2913
2916
  title: this.cliName,
2914
- messages: messages.slice(-50).map((message, index) => buildChatMessage({
2917
+ messages: messages.map((message, index) => buildChatMessage({
2915
2918
  ...message,
2916
2919
  id: message.id || `msg_${index}`,
2917
2920
  index: typeof message.index === "number" ? message.index : index,
@@ -2942,7 +2945,10 @@ var init_provider_cli_adapter = __esm({
2942
2945
  }));
2943
2946
  }
2944
2947
  parseCurrentTranscript(baseMessages, partialResponse, scope) {
2945
- if (!this.cliScripts?.parseOutput) return null;
2948
+ if (!this.cliScripts?.parseOutput) {
2949
+ this.parseErrorMessage = null;
2950
+ return null;
2951
+ }
2946
2952
  try {
2947
2953
  const input = buildCliParseInput({
2948
2954
  accumulatedBuffer: this.accumulatedBuffer,
@@ -2970,10 +2976,13 @@ var init_provider_cli_adapter = __esm({
2970
2976
  lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
2971
2977
  }
2972
2978
  }
2979
+ this.parseErrorMessage = null;
2973
2980
  return parsed;
2974
2981
  } catch (e) {
2975
- LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
2976
- return null;
2982
+ const message = e?.message || String(e);
2983
+ this.parseErrorMessage = message;
2984
+ LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
2985
+ throw e;
2977
2986
  }
2978
2987
  }
2979
2988
  /** Whether this adapter has CLI scripts loaded */
@@ -3973,6 +3982,96 @@ function getSessionSeenMarker(state, sessionId, providerSessionId) {
3973
3982
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
3974
3983
  return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
3975
3984
  }
3985
+ function getSessionNotificationDismissal(state, sessionId, providerSessionId) {
3986
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
3987
+ return state.sessionNotificationDismissals?.[providerKey] || state.sessionNotificationDismissals?.[sessionId] || "";
3988
+ }
3989
+ function getSessionNotificationUnreadOverride(state, sessionId, providerSessionId) {
3990
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
3991
+ return state.sessionNotificationUnreadOverrides?.[providerKey] || state.sessionNotificationUnreadOverrides?.[sessionId] || "";
3992
+ }
3993
+ function dismissSessionNotification(state, sessionId, notificationId, providerSessionId) {
3994
+ const dismissalId = String(notificationId || "").trim();
3995
+ if (!dismissalId) return state;
3996
+ const dismissalKeys = Array.from(new Set([
3997
+ sessionId,
3998
+ buildSessionReadStateKey(sessionId, providerSessionId)
3999
+ ].filter(Boolean)));
4000
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
4001
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
4002
+ for (const key of dismissalKeys) {
4003
+ nextSessionNotificationDismissals[key] = dismissalId;
4004
+ delete nextSessionNotificationUnreadOverrides[key];
4005
+ }
4006
+ return {
4007
+ ...state,
4008
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
4009
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
4010
+ };
4011
+ }
4012
+ function markSessionNotificationUnread(state, sessionId, notificationId, providerSessionId) {
4013
+ const unreadId = String(notificationId || "").trim();
4014
+ if (!unreadId) return state;
4015
+ const unreadKeys = Array.from(new Set([
4016
+ sessionId,
4017
+ buildSessionReadStateKey(sessionId, providerSessionId)
4018
+ ].filter(Boolean)));
4019
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
4020
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
4021
+ for (const key of unreadKeys) {
4022
+ nextSessionNotificationUnreadOverrides[key] = unreadId;
4023
+ delete nextSessionNotificationDismissals[key];
4024
+ }
4025
+ return {
4026
+ ...state,
4027
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
4028
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
4029
+ };
4030
+ }
4031
+ function getSessionNotificationTargetValue(session) {
4032
+ const providerSessionId = typeof session.providerSessionId === "string" ? session.providerSessionId.trim() : "";
4033
+ return providerSessionId || session.id;
4034
+ }
4035
+ function getSessionCurrentNotificationId(session) {
4036
+ const inboxBucket = session.inboxBucket || "idle";
4037
+ const isNeedsAttention = inboxBucket === "needs_attention" || session.status === "waiting_approval";
4038
+ const isTaskComplete = inboxBucket === "task_complete" && !!session.unread;
4039
+ const type = isNeedsAttention ? "needs_attention" : isTaskComplete ? "task_complete" : "";
4040
+ if (!type) return "";
4041
+ const target = getSessionNotificationTargetValue(session);
4042
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
4043
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
4044
+ return [type, target, lastMessageHash, String(timestamp)].join("|");
4045
+ }
4046
+ function applySessionNotificationOverlay(session, overlay) {
4047
+ const currentNotificationId = getSessionCurrentNotificationId(session);
4048
+ const taskCompleteNotificationId = (() => {
4049
+ const target = getSessionNotificationTargetValue(session);
4050
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
4051
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
4052
+ if (!target || !lastMessageHash || !timestamp) return "";
4053
+ return ["task_complete", target, lastMessageHash, String(timestamp)].join("|");
4054
+ })();
4055
+ const dismissedNotificationId = typeof overlay.dismissedNotificationId === "string" ? overlay.dismissedNotificationId.trim() : "";
4056
+ const unreadNotificationId = typeof overlay.unreadNotificationId === "string" ? overlay.unreadNotificationId.trim() : "";
4057
+ if (unreadNotificationId && (currentNotificationId === unreadNotificationId || taskCompleteNotificationId === unreadNotificationId)) {
4058
+ const forcedInboxBucket = session.inboxBucket === "needs_attention" || session.status === "waiting_approval" ? "needs_attention" : "task_complete";
4059
+ return {
4060
+ unread: true,
4061
+ inboxBucket: forcedInboxBucket
4062
+ };
4063
+ }
4064
+ if (!currentNotificationId || !dismissedNotificationId || currentNotificationId !== dismissedNotificationId) {
4065
+ return {
4066
+ unread: !!session.unread,
4067
+ inboxBucket: session.inboxBucket || "idle"
4068
+ };
4069
+ }
4070
+ return {
4071
+ unread: false,
4072
+ inboxBucket: "idle"
4073
+ };
4074
+ }
3976
4075
  function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
3977
4076
  const prev = state.sessionReads || {};
3978
4077
  const prevMarkers = state.sessionReadMarkers || {};
@@ -3983,14 +4082,20 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
3983
4082
  ].filter(Boolean)));
3984
4083
  const nextSessionReads = { ...prev };
3985
4084
  const nextSessionReadMarkers = { ...prevMarkers };
4085
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
4086
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
3986
4087
  for (const key of readKeys) {
3987
4088
  nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
3988
4089
  if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
4090
+ delete nextSessionNotificationDismissals[key];
4091
+ delete nextSessionNotificationUnreadOverrides[key];
3989
4092
  }
3990
4093
  return {
3991
4094
  ...state,
3992
4095
  sessionReads: nextSessionReads,
3993
- sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
4096
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers,
4097
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
4098
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
3994
4099
  };
3995
4100
  }
3996
4101
 
@@ -4075,7 +4180,9 @@ var DEFAULT_STATE = {
4075
4180
  recentActivity: [],
4076
4181
  savedProviderSessions: [],
4077
4182
  sessionReads: {},
4078
- sessionReadMarkers: {}
4183
+ sessionReadMarkers: {},
4184
+ sessionNotificationDismissals: {},
4185
+ sessionNotificationUnreadOverrides: {}
4079
4186
  };
4080
4187
  function isPlainObject2(value) {
4081
4188
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -4107,11 +4214,19 @@ function normalizeState(raw) {
4107
4214
  const sessionReadMarkers = Object.fromEntries(
4108
4215
  Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
4109
4216
  );
4217
+ const sessionNotificationDismissals = Object.fromEntries(
4218
+ Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
4219
+ );
4220
+ const sessionNotificationUnreadOverrides = Object.fromEntries(
4221
+ Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
4222
+ );
4110
4223
  return {
4111
4224
  recentActivity,
4112
4225
  savedProviderSessions,
4113
4226
  sessionReads,
4114
- sessionReadMarkers
4227
+ sessionReadMarkers,
4228
+ sessionNotificationDismissals,
4229
+ sessionNotificationUnreadOverrides
4115
4230
  };
4116
4231
  }
4117
4232
  function loadState() {
@@ -7434,7 +7549,6 @@ var ExtensionProviderInstance = class {
7434
7549
  }
7435
7550
  pushEvent(event) {
7436
7551
  this.events.push(event);
7437
- if (this.events.length > 50) this.events = this.events.slice(-50);
7438
7552
  }
7439
7553
  applyProviderResponse(data, options) {
7440
7554
  if (!data || typeof data !== "object") return;
@@ -7510,7 +7624,6 @@ var ExtensionProviderInstance = class {
7510
7624
  key: dedupKey,
7511
7625
  message: normalizedMessage
7512
7626
  });
7513
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
7514
7627
  if (normalizedContent) {
7515
7628
  this.historyWriter.appendNewMessages(
7516
7629
  this.type,
@@ -8045,7 +8158,6 @@ var IdeProviderInstance = class {
8045
8158
  }
8046
8159
  pushEvent(event) {
8047
8160
  this.events.push(event);
8048
- if (this.events.length > 50) this.events = this.events.slice(-50);
8049
8161
  }
8050
8162
  applyProviderResponse(data, options) {
8051
8163
  if (!data || typeof data !== "object") return;
@@ -8135,7 +8247,6 @@ var IdeProviderInstance = class {
8135
8247
  key: dedupKey,
8136
8248
  message: normalizedMessage
8137
8249
  });
8138
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
8139
8250
  if (normalizedContent) {
8140
8251
  this.historyWriter.appendNewMessages(
8141
8252
  this.type,
@@ -9699,7 +9810,14 @@ async function handleReadChat(h, args) {
9699
9810
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
9700
9811
  if (adapter) {
9701
9812
  _log(`${transport} adapter: ${adapter.cliType}`);
9702
- const parsedStatus = typeof adapter.getScriptParsedStatus === "function" ? parseMaybeJson(adapter.getScriptParsedStatus()) : null;
9813
+ let parsedStatus = null;
9814
+ if (typeof adapter.getScriptParsedStatus === "function") {
9815
+ try {
9816
+ parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
9817
+ } catch (error) {
9818
+ return { success: false, error: error?.message || String(error) };
9819
+ }
9820
+ }
9703
9821
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
9704
9822
  const status = parsedRecord || adapter.getStatus();
9705
9823
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
@@ -12033,6 +12151,8 @@ var CliProviderInstance = class {
12033
12151
  runtimeMessages = [];
12034
12152
  instanceId;
12035
12153
  suppressIdleHistoryReplay = false;
12154
+ errorMessage = void 0;
12155
+ errorReason = void 0;
12036
12156
  presentationMode;
12037
12157
  providerSessionId;
12038
12158
  launchMode;
@@ -12156,9 +12276,24 @@ var CliProviderInstance = class {
12156
12276
  }
12157
12277
  getState() {
12158
12278
  const adapterStatus = this.adapter.getStatus();
12159
- const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
12279
+ let parsedStatus = null;
12280
+ let parseErrorMessage;
12281
+ if (typeof this.adapter.getScriptParsedStatus === "function") {
12282
+ try {
12283
+ parsedStatus = this.adapter.getScriptParsedStatus() || null;
12284
+ this.errorMessage = void 0;
12285
+ this.errorReason = void 0;
12286
+ } catch (error) {
12287
+ parseErrorMessage = error?.message || String(error);
12288
+ this.errorMessage = parseErrorMessage;
12289
+ this.errorReason = "parse_error";
12290
+ }
12291
+ } else {
12292
+ this.errorMessage = void 0;
12293
+ this.errorReason = void 0;
12294
+ }
12160
12295
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
12161
- const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
12296
+ const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
12162
12297
  const parsedProviderSessionId = normalizeProviderSessionId(
12163
12298
  this.type,
12164
12299
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
@@ -12168,7 +12303,7 @@ var CliProviderInstance = class {
12168
12303
  }
12169
12304
  const runtime = this.adapter.getRuntimeMetadata();
12170
12305
  this.maybeAppendRuntimeRecoveryMessage(runtime);
12171
- let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
12306
+ let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : parseErrorMessage ? normalizeChatMessages(Array.isArray(adapterStatus.messages) ? adapterStatus.messages : []) : [];
12172
12307
  const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
12173
12308
  if (historyMessageCount !== null) {
12174
12309
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
@@ -12208,7 +12343,7 @@ var CliProviderInstance = class {
12208
12343
  activeChat: {
12209
12344
  id: `${this.type}_${this.workingDir}`,
12210
12345
  title: parsedStatus?.title || dirName,
12211
- status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
12346
+ status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
12212
12347
  messages: mergedMessages,
12213
12348
  activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
12214
12349
  inputContent: ""
@@ -12234,7 +12369,9 @@ var CliProviderInstance = class {
12234
12369
  resume: this.provider.resume,
12235
12370
  controlValues: surface.controlValues,
12236
12371
  providerControls: this.provider.controls,
12237
- summaryMetadata: surface.summaryMetadata
12372
+ summaryMetadata: surface.summaryMetadata,
12373
+ errorMessage: this.errorMessage,
12374
+ errorReason: this.errorReason
12238
12375
  };
12239
12376
  }
12240
12377
  setPresentationMode(mode) {
@@ -12421,7 +12558,6 @@ var CliProviderInstance = class {
12421
12558
  }
12422
12559
  pushEvent(event) {
12423
12560
  this.events.push(event);
12424
- if (this.events.length > 50) this.events = this.events.slice(-50);
12425
12561
  }
12426
12562
  flushEvents() {
12427
12563
  const events = [...this.events];
@@ -12603,9 +12739,6 @@ ${effect.notification.body || ""}`.trim();
12603
12739
  key: dedupKey,
12604
12740
  message: normalizedMessage
12605
12741
  });
12606
- if (this.runtimeMessages.length > 50) {
12607
- this.runtimeMessages = this.runtimeMessages.slice(-50);
12608
- }
12609
12742
  if (normalizedContent) {
12610
12743
  this.historyWriter.appendNewMessages(
12611
12744
  this.type,
@@ -12854,8 +12987,8 @@ var AcpProviderInstance = class {
12854
12987
  }
12855
12988
  getState() {
12856
12989
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
12857
- const recentMessages = normalizeChatMessages(this.messages.slice(-50).map((m) => {
12858
- const content = this.truncateContent(m.content);
12990
+ const recentMessages = normalizeChatMessages(this.messages.map((m) => {
12991
+ const content = m.content;
12859
12992
  return buildChatMessage({
12860
12993
  ...m,
12861
12994
  content
@@ -13648,18 +13781,6 @@ var AcpProviderInstance = class {
13648
13781
  }
13649
13782
  }
13650
13783
  // ─── Rich Content Helpers ────────────────────────────
13651
- /** Truncate content for transport (text: 2000 chars, images preserved) */
13652
- truncateContent(content) {
13653
- if (typeof content === "string") {
13654
- return content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
13655
- }
13656
- return content.map((b) => {
13657
- if (b.type === "text" && b.text.length > 2e3) {
13658
- return { ...b, text: b.text.slice(0, 2e3) + "\n... (truncated)" };
13659
- }
13660
- return b;
13661
- });
13662
- }
13663
13784
  /** Build ContentBlock[] from current partial state */
13664
13785
  buildPartialBlocks() {
13665
13786
  const blocks = [];
@@ -13813,7 +13934,6 @@ ${rawInput}` : rawInput;
13813
13934
  }
13814
13935
  pushEvent(event) {
13815
13936
  this.events.push(event);
13816
- if (this.events.length > 50) this.events = this.events.slice(-50);
13817
13937
  }
13818
13938
  appendSystemMessage(content, timestamp = Date.now()) {
13819
13939
  const normalizedContent = String(content || "").trim();
@@ -16484,7 +16604,9 @@ var SKIP_COMMANDS = /* @__PURE__ */ new Set([
16484
16604
  "heartbeat",
16485
16605
  "status_report",
16486
16606
  "read_chat",
16487
- "mark_session_seen"
16607
+ "mark_session_seen",
16608
+ "delete_notification",
16609
+ "mark_notification_unread"
16488
16610
  ]);
16489
16611
  function shouldLogCommand(cmd) {
16490
16612
  return !SKIP_COMMANDS.has(cmd);
@@ -16761,9 +16883,22 @@ function buildStatusSnapshot(options) {
16761
16883
  completionMarker,
16762
16884
  seenCompletionMarker
16763
16885
  );
16886
+ const { unread: overlayUnread, inboxBucket: overlayInboxBucket } = applySessionNotificationOverlay({
16887
+ id: sourceSession.id,
16888
+ providerSessionId: sourceSession.providerSessionId,
16889
+ status: sourceSession.status,
16890
+ unread,
16891
+ inboxBucket,
16892
+ lastMessageHash: sourceSession.lastMessageHash,
16893
+ lastMessageAt: sourceSession.lastMessageAt,
16894
+ lastUpdated: sourceSession.lastUpdated
16895
+ }, {
16896
+ dismissedNotificationId: getSessionNotificationDismissal(state, sourceSession.id, sourceSession.providerSessionId),
16897
+ unreadNotificationId: getSessionNotificationUnreadOverride(state, sourceSession.id, sourceSession.providerSessionId)
16898
+ });
16764
16899
  session.lastSeenAt = lastSeenAt;
16765
- session.unread = unread;
16766
- session.inboxBucket = inboxBucket;
16900
+ session.unread = overlayUnread;
16901
+ session.inboxBucket = overlayInboxBucket;
16767
16902
  if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
16768
16903
  const recentReadSnapshot = {
16769
16904
  sessionId: session.id,
@@ -17580,6 +17715,62 @@ var DaemonCommandRouter = class {
17580
17715
  completionMarker
17581
17716
  };
17582
17717
  }
17718
+ case "delete_notification": {
17719
+ const sessionId = args?.sessionId;
17720
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
17721
+ if (!sessionId || typeof sessionId !== "string") {
17722
+ return { success: false, error: "sessionId is required" };
17723
+ }
17724
+ if (!notificationId) {
17725
+ return { success: false, error: "notificationId is required" };
17726
+ }
17727
+ const sessionEntries = buildSessionEntries(
17728
+ this.deps.instanceManager.collectAllStates(),
17729
+ this.deps.cdpManagers
17730
+ );
17731
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
17732
+ const next = dismissSessionNotification(
17733
+ loadState(),
17734
+ sessionId,
17735
+ notificationId,
17736
+ targetSession?.providerSessionId
17737
+ );
17738
+ saveState(next);
17739
+ this.deps.onStatusChange?.();
17740
+ return {
17741
+ success: true,
17742
+ sessionId,
17743
+ notificationId
17744
+ };
17745
+ }
17746
+ case "mark_notification_unread": {
17747
+ const sessionId = args?.sessionId;
17748
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
17749
+ if (!sessionId || typeof sessionId !== "string") {
17750
+ return { success: false, error: "sessionId is required" };
17751
+ }
17752
+ if (!notificationId) {
17753
+ return { success: false, error: "notificationId is required" };
17754
+ }
17755
+ const sessionEntries = buildSessionEntries(
17756
+ this.deps.instanceManager.collectAllStates(),
17757
+ this.deps.cdpManagers
17758
+ );
17759
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
17760
+ const next = markSessionNotificationUnread(
17761
+ loadState(),
17762
+ sessionId,
17763
+ notificationId,
17764
+ targetSession?.providerSessionId
17765
+ );
17766
+ saveState(next);
17767
+ this.deps.onStatusChange?.();
17768
+ return {
17769
+ success: true,
17770
+ sessionId,
17771
+ notificationId
17772
+ };
17773
+ }
17583
17774
  // ─── Daemon Self-Upgrade ───
17584
17775
  case "daemon_upgrade": {
17585
17776
  LOG.info("Upgrade", "Remote upgrade requested from dashboard");