@adhdev/daemon-standalone 0.8.81 → 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.
package/dist/index.js CHANGED
@@ -29705,6 +29705,7 @@ var require_dist2 = __commonJS({
29705
29705
  recentOutputBuffer = "";
29706
29706
  isWaitingForResponse = false;
29707
29707
  activeModal = null;
29708
+ parseErrorMessage = null;
29708
29709
  responseTimeout = null;
29709
29710
  idleTimeout = null;
29710
29711
  ready = false;
@@ -30699,10 +30700,12 @@ var require_dist2 = __commonJS({
30699
30700
  // ─── Public API (CliAdapter) ───────────────────
30700
30701
  getStatus() {
30701
30702
  return {
30702
- status: this.currentStatus,
30703
+ status: this.parseErrorMessage ? "error" : this.currentStatus,
30703
30704
  messages: [...this.committedMessages],
30704
30705
  workingDir: this.workingDir,
30705
- activeModal: this.activeModal
30706
+ activeModal: this.activeModal,
30707
+ errorMessage: this.parseErrorMessage || void 0,
30708
+ errorReason: this.parseErrorMessage ? "parse_error" : void 0
30706
30709
  };
30707
30710
  }
30708
30711
  seedCommittedMessages(messages) {
@@ -30756,7 +30759,7 @@ var require_dist2 = __commonJS({
30756
30759
  id: "cli_session",
30757
30760
  status: this.currentStatus,
30758
30761
  title: this.cliName,
30759
- messages: messages.slice(-50).map((message, index) => buildChatMessage({
30762
+ messages: messages.map((message, index) => buildChatMessage({
30760
30763
  ...message,
30761
30764
  id: message.id || `msg_${index}`,
30762
30765
  index: typeof message.index === "number" ? message.index : index,
@@ -30787,7 +30790,10 @@ var require_dist2 = __commonJS({
30787
30790
  }));
30788
30791
  }
30789
30792
  parseCurrentTranscript(baseMessages, partialResponse, scope) {
30790
- if (!this.cliScripts?.parseOutput) return null;
30793
+ if (!this.cliScripts?.parseOutput) {
30794
+ this.parseErrorMessage = null;
30795
+ return null;
30796
+ }
30791
30797
  try {
30792
30798
  const input = buildCliParseInput({
30793
30799
  accumulatedBuffer: this.accumulatedBuffer,
@@ -30815,10 +30821,13 @@ var require_dist2 = __commonJS({
30815
30821
  lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
30816
30822
  }
30817
30823
  }
30824
+ this.parseErrorMessage = null;
30818
30825
  return parsed;
30819
30826
  } catch (e) {
30820
- LOG2.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
30821
- return null;
30827
+ const message = e?.message || String(e);
30828
+ this.parseErrorMessage = message;
30829
+ LOG2.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
30830
+ throw e;
30822
30831
  }
30823
30832
  }
30824
30833
  /** Whether this adapter has CLI scripts loaded */
@@ -31808,6 +31817,96 @@ ${data.message || ""}`.trim();
31808
31817
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
31809
31818
  return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
31810
31819
  }
31820
+ function getSessionNotificationDismissal(state, sessionId, providerSessionId) {
31821
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
31822
+ return state.sessionNotificationDismissals?.[providerKey] || state.sessionNotificationDismissals?.[sessionId] || "";
31823
+ }
31824
+ function getSessionNotificationUnreadOverride(state, sessionId, providerSessionId) {
31825
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
31826
+ return state.sessionNotificationUnreadOverrides?.[providerKey] || state.sessionNotificationUnreadOverrides?.[sessionId] || "";
31827
+ }
31828
+ function dismissSessionNotification(state, sessionId, notificationId, providerSessionId) {
31829
+ const dismissalId = String(notificationId || "").trim();
31830
+ if (!dismissalId) return state;
31831
+ const dismissalKeys = Array.from(new Set([
31832
+ sessionId,
31833
+ buildSessionReadStateKey(sessionId, providerSessionId)
31834
+ ].filter(Boolean)));
31835
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
31836
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
31837
+ for (const key of dismissalKeys) {
31838
+ nextSessionNotificationDismissals[key] = dismissalId;
31839
+ delete nextSessionNotificationUnreadOverrides[key];
31840
+ }
31841
+ return {
31842
+ ...state,
31843
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
31844
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
31845
+ };
31846
+ }
31847
+ function markSessionNotificationUnread(state, sessionId, notificationId, providerSessionId) {
31848
+ const unreadId = String(notificationId || "").trim();
31849
+ if (!unreadId) return state;
31850
+ const unreadKeys = Array.from(new Set([
31851
+ sessionId,
31852
+ buildSessionReadStateKey(sessionId, providerSessionId)
31853
+ ].filter(Boolean)));
31854
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
31855
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
31856
+ for (const key of unreadKeys) {
31857
+ nextSessionNotificationUnreadOverrides[key] = unreadId;
31858
+ delete nextSessionNotificationDismissals[key];
31859
+ }
31860
+ return {
31861
+ ...state,
31862
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
31863
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
31864
+ };
31865
+ }
31866
+ function getSessionNotificationTargetValue(session) {
31867
+ const providerSessionId = typeof session.providerSessionId === "string" ? session.providerSessionId.trim() : "";
31868
+ return providerSessionId || session.id;
31869
+ }
31870
+ function getSessionCurrentNotificationId(session) {
31871
+ const inboxBucket = session.inboxBucket || "idle";
31872
+ const isNeedsAttention = inboxBucket === "needs_attention" || session.status === "waiting_approval";
31873
+ const isTaskComplete = inboxBucket === "task_complete" && !!session.unread;
31874
+ const type = isNeedsAttention ? "needs_attention" : isTaskComplete ? "task_complete" : "";
31875
+ if (!type) return "";
31876
+ const target = getSessionNotificationTargetValue(session);
31877
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
31878
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
31879
+ return [type, target, lastMessageHash, String(timestamp)].join("|");
31880
+ }
31881
+ function applySessionNotificationOverlay(session, overlay) {
31882
+ const currentNotificationId = getSessionCurrentNotificationId(session);
31883
+ const taskCompleteNotificationId = (() => {
31884
+ const target = getSessionNotificationTargetValue(session);
31885
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
31886
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
31887
+ if (!target || !lastMessageHash || !timestamp) return "";
31888
+ return ["task_complete", target, lastMessageHash, String(timestamp)].join("|");
31889
+ })();
31890
+ const dismissedNotificationId = typeof overlay.dismissedNotificationId === "string" ? overlay.dismissedNotificationId.trim() : "";
31891
+ const unreadNotificationId = typeof overlay.unreadNotificationId === "string" ? overlay.unreadNotificationId.trim() : "";
31892
+ if (unreadNotificationId && (currentNotificationId === unreadNotificationId || taskCompleteNotificationId === unreadNotificationId)) {
31893
+ const forcedInboxBucket = session.inboxBucket === "needs_attention" || session.status === "waiting_approval" ? "needs_attention" : "task_complete";
31894
+ return {
31895
+ unread: true,
31896
+ inboxBucket: forcedInboxBucket
31897
+ };
31898
+ }
31899
+ if (!currentNotificationId || !dismissedNotificationId || currentNotificationId !== dismissedNotificationId) {
31900
+ return {
31901
+ unread: !!session.unread,
31902
+ inboxBucket: session.inboxBucket || "idle"
31903
+ };
31904
+ }
31905
+ return {
31906
+ unread: false,
31907
+ inboxBucket: "idle"
31908
+ };
31909
+ }
31811
31910
  function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
31812
31911
  const prev = state.sessionReads || {};
31813
31912
  const prevMarkers = state.sessionReadMarkers || {};
@@ -31818,14 +31917,20 @@ ${data.message || ""}`.trim();
31818
31917
  ].filter(Boolean)));
31819
31918
  const nextSessionReads = { ...prev };
31820
31919
  const nextSessionReadMarkers = { ...prevMarkers };
31920
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
31921
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
31821
31922
  for (const key of readKeys) {
31822
31923
  nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
31823
31924
  if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
31925
+ delete nextSessionNotificationDismissals[key];
31926
+ delete nextSessionNotificationUnreadOverrides[key];
31824
31927
  }
31825
31928
  return {
31826
31929
  ...state,
31827
31930
  sessionReads: nextSessionReads,
31828
- sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
31931
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers,
31932
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
31933
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
31829
31934
  };
31830
31935
  }
31831
31936
  var path32 = __toESM2(require("path"));
@@ -31902,7 +32007,9 @@ ${data.message || ""}`.trim();
31902
32007
  recentActivity: [],
31903
32008
  savedProviderSessions: [],
31904
32009
  sessionReads: {},
31905
- sessionReadMarkers: {}
32010
+ sessionReadMarkers: {},
32011
+ sessionNotificationDismissals: {},
32012
+ sessionNotificationUnreadOverrides: {}
31906
32013
  };
31907
32014
  function isPlainObject22(value) {
31908
32015
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -31934,11 +32041,19 @@ ${data.message || ""}`.trim();
31934
32041
  const sessionReadMarkers = Object.fromEntries(
31935
32042
  Object.entries(isPlainObject22(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
31936
32043
  );
32044
+ const sessionNotificationDismissals = Object.fromEntries(
32045
+ Object.entries(isPlainObject22(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
32046
+ );
32047
+ const sessionNotificationUnreadOverrides = Object.fromEntries(
32048
+ Object.entries(isPlainObject22(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
32049
+ );
31937
32050
  return {
31938
32051
  recentActivity,
31939
32052
  savedProviderSessions,
31940
32053
  sessionReads,
31941
- sessionReadMarkers
32054
+ sessionReadMarkers,
32055
+ sessionNotificationDismissals,
32056
+ sessionNotificationUnreadOverrides
31942
32057
  };
31943
32058
  }
31944
32059
  function loadState() {
@@ -35229,7 +35344,6 @@ ${cleanBody}`;
35229
35344
  }
35230
35345
  pushEvent(event) {
35231
35346
  this.events.push(event);
35232
- if (this.events.length > 50) this.events = this.events.slice(-50);
35233
35347
  }
35234
35348
  applyProviderResponse(data, options) {
35235
35349
  if (!data || typeof data !== "object") return;
@@ -35305,7 +35419,6 @@ ${cleanBody}`;
35305
35419
  key: dedupKey,
35306
35420
  message: normalizedMessage
35307
35421
  });
35308
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
35309
35422
  if (normalizedContent) {
35310
35423
  this.historyWriter.appendNewMessages(
35311
35424
  this.type,
@@ -35834,7 +35947,6 @@ ${effect.notification.body || ""}`.trim();
35834
35947
  }
35835
35948
  pushEvent(event) {
35836
35949
  this.events.push(event);
35837
- if (this.events.length > 50) this.events = this.events.slice(-50);
35838
35950
  }
35839
35951
  applyProviderResponse(data, options) {
35840
35952
  if (!data || typeof data !== "object") return;
@@ -35924,7 +36036,6 @@ ${effect.notification.body || ""}`.trim();
35924
36036
  key: dedupKey,
35925
36037
  message: normalizedMessage
35926
36038
  });
35927
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
35928
36039
  if (normalizedContent) {
35929
36040
  this.historyWriter.appendNewMessages(
35930
36041
  this.type,
@@ -37458,7 +37569,14 @@ ${effect.notification.body || ""}`.trim();
37458
37569
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
37459
37570
  if (adapter) {
37460
37571
  _log(`${transport} adapter: ${adapter.cliType}`);
37461
- const parsedStatus = typeof adapter.getScriptParsedStatus === "function" ? parseMaybeJson(adapter.getScriptParsedStatus()) : null;
37572
+ let parsedStatus = null;
37573
+ if (typeof adapter.getScriptParsedStatus === "function") {
37574
+ try {
37575
+ parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
37576
+ } catch (error48) {
37577
+ return { success: false, error: error48?.message || String(error48) };
37578
+ }
37579
+ }
37462
37580
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
37463
37581
  const status = parsedRecord || adapter.getStatus();
37464
37582
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
@@ -39774,6 +39892,8 @@ ${effect.notification.body || ""}`.trim();
39774
39892
  runtimeMessages = [];
39775
39893
  instanceId;
39776
39894
  suppressIdleHistoryReplay = false;
39895
+ errorMessage = void 0;
39896
+ errorReason = void 0;
39777
39897
  presentationMode;
39778
39898
  providerSessionId;
39779
39899
  launchMode;
@@ -39897,9 +40017,24 @@ ${effect.notification.body || ""}`.trim();
39897
40017
  }
39898
40018
  getState() {
39899
40019
  const adapterStatus = this.adapter.getStatus();
39900
- const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
40020
+ let parsedStatus = null;
40021
+ let parseErrorMessage;
40022
+ if (typeof this.adapter.getScriptParsedStatus === "function") {
40023
+ try {
40024
+ parsedStatus = this.adapter.getScriptParsedStatus() || null;
40025
+ this.errorMessage = void 0;
40026
+ this.errorReason = void 0;
40027
+ } catch (error48) {
40028
+ parseErrorMessage = error48?.message || String(error48);
40029
+ this.errorMessage = parseErrorMessage;
40030
+ this.errorReason = "parse_error";
40031
+ }
40032
+ } else {
40033
+ this.errorMessage = void 0;
40034
+ this.errorReason = void 0;
40035
+ }
39901
40036
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
39902
- const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
40037
+ const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
39903
40038
  const parsedProviderSessionId = normalizeProviderSessionId(
39904
40039
  this.type,
39905
40040
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
@@ -39909,7 +40044,7 @@ ${effect.notification.body || ""}`.trim();
39909
40044
  }
39910
40045
  const runtime = this.adapter.getRuntimeMetadata();
39911
40046
  this.maybeAppendRuntimeRecoveryMessage(runtime);
39912
- let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
40047
+ let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : parseErrorMessage ? normalizeChatMessages(Array.isArray(adapterStatus.messages) ? adapterStatus.messages : []) : [];
39913
40048
  const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
39914
40049
  if (historyMessageCount !== null) {
39915
40050
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
@@ -39949,7 +40084,7 @@ ${effect.notification.body || ""}`.trim();
39949
40084
  activeChat: {
39950
40085
  id: `${this.type}_${this.workingDir}`,
39951
40086
  title: parsedStatus?.title || dirName,
39952
- status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
40087
+ status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
39953
40088
  messages: mergedMessages,
39954
40089
  activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
39955
40090
  inputContent: ""
@@ -39975,7 +40110,9 @@ ${effect.notification.body || ""}`.trim();
39975
40110
  resume: this.provider.resume,
39976
40111
  controlValues: surface.controlValues,
39977
40112
  providerControls: this.provider.controls,
39978
- summaryMetadata: surface.summaryMetadata
40113
+ summaryMetadata: surface.summaryMetadata,
40114
+ errorMessage: this.errorMessage,
40115
+ errorReason: this.errorReason
39979
40116
  };
39980
40117
  }
39981
40118
  setPresentationMode(mode) {
@@ -40162,7 +40299,6 @@ ${effect.notification.body || ""}`.trim();
40162
40299
  }
40163
40300
  pushEvent(event) {
40164
40301
  this.events.push(event);
40165
- if (this.events.length > 50) this.events = this.events.slice(-50);
40166
40302
  }
40167
40303
  flushEvents() {
40168
40304
  const events = [...this.events];
@@ -40344,9 +40480,6 @@ ${effect.notification.body || ""}`.trim();
40344
40480
  key: dedupKey,
40345
40481
  message: normalizedMessage
40346
40482
  });
40347
- if (this.runtimeMessages.length > 50) {
40348
- this.runtimeMessages = this.runtimeMessages.slice(-50);
40349
- }
40350
40483
  if (normalizedContent) {
40351
40484
  this.historyWriter.appendNewMessages(
40352
40485
  this.type,
@@ -40593,8 +40726,8 @@ ${effect.notification.body || ""}`.trim();
40593
40726
  }
40594
40727
  getState() {
40595
40728
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
40596
- const recentMessages = normalizeChatMessages(this.messages.slice(-50).map((m) => {
40597
- const content = this.truncateContent(m.content);
40729
+ const recentMessages = normalizeChatMessages(this.messages.map((m) => {
40730
+ const content = m.content;
40598
40731
  return buildChatMessage({
40599
40732
  ...m,
40600
40733
  content
@@ -41387,18 +41520,6 @@ ${effect.notification.body || ""}`.trim();
41387
41520
  }
41388
41521
  }
41389
41522
  // ─── Rich Content Helpers ────────────────────────────
41390
- /** Truncate content for transport (text: 2000 chars, images preserved) */
41391
- truncateContent(content) {
41392
- if (typeof content === "string") {
41393
- return content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
41394
- }
41395
- return content.map((b2) => {
41396
- if (b2.type === "text" && b2.text.length > 2e3) {
41397
- return { ...b2, text: b2.text.slice(0, 2e3) + "\n... (truncated)" };
41398
- }
41399
- return b2;
41400
- });
41401
- }
41402
41523
  /** Build ContentBlock[] from current partial state */
41403
41524
  buildPartialBlocks() {
41404
41525
  const blocks = [];
@@ -41552,7 +41673,6 @@ ${rawInput}` : rawInput;
41552
41673
  }
41553
41674
  pushEvent(event) {
41554
41675
  this.events.push(event);
41555
- if (this.events.length > 50) this.events = this.events.slice(-50);
41556
41676
  }
41557
41677
  appendSystemMessage(content, timestamp = Date.now()) {
41558
41678
  const normalizedContent = String(content || "").trim();
@@ -44203,7 +44323,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
44203
44323
  "heartbeat",
44204
44324
  "status_report",
44205
44325
  "read_chat",
44206
- "mark_session_seen"
44326
+ "mark_session_seen",
44327
+ "delete_notification",
44328
+ "mark_notification_unread"
44207
44329
  ]);
44208
44330
  function shouldLogCommand(cmd) {
44209
44331
  return !SKIP_COMMANDS.has(cmd);
@@ -44476,9 +44598,22 @@ Run 'adhdev doctor' for detailed diagnostics.`
44476
44598
  completionMarker,
44477
44599
  seenCompletionMarker
44478
44600
  );
44601
+ const { unread: overlayUnread, inboxBucket: overlayInboxBucket } = applySessionNotificationOverlay({
44602
+ id: sourceSession.id,
44603
+ providerSessionId: sourceSession.providerSessionId,
44604
+ status: sourceSession.status,
44605
+ unread,
44606
+ inboxBucket,
44607
+ lastMessageHash: sourceSession.lastMessageHash,
44608
+ lastMessageAt: sourceSession.lastMessageAt,
44609
+ lastUpdated: sourceSession.lastUpdated
44610
+ }, {
44611
+ dismissedNotificationId: getSessionNotificationDismissal(state, sourceSession.id, sourceSession.providerSessionId),
44612
+ unreadNotificationId: getSessionNotificationUnreadOverride(state, sourceSession.id, sourceSession.providerSessionId)
44613
+ });
44479
44614
  session.lastSeenAt = lastSeenAt;
44480
- session.unread = unread;
44481
- session.inboxBucket = inboxBucket;
44615
+ session.unread = overlayUnread;
44616
+ session.inboxBucket = overlayInboxBucket;
44482
44617
  if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
44483
44618
  const recentReadSnapshot = {
44484
44619
  sessionId: session.id,
@@ -45291,6 +45426,62 @@ Run 'adhdev doctor' for detailed diagnostics.`
45291
45426
  completionMarker
45292
45427
  };
45293
45428
  }
45429
+ case "delete_notification": {
45430
+ const sessionId = args?.sessionId;
45431
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
45432
+ if (!sessionId || typeof sessionId !== "string") {
45433
+ return { success: false, error: "sessionId is required" };
45434
+ }
45435
+ if (!notificationId) {
45436
+ return { success: false, error: "notificationId is required" };
45437
+ }
45438
+ const sessionEntries = buildSessionEntries(
45439
+ this.deps.instanceManager.collectAllStates(),
45440
+ this.deps.cdpManagers
45441
+ );
45442
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
45443
+ const next = dismissSessionNotification(
45444
+ loadState(),
45445
+ sessionId,
45446
+ notificationId,
45447
+ targetSession?.providerSessionId
45448
+ );
45449
+ saveState(next);
45450
+ this.deps.onStatusChange?.();
45451
+ return {
45452
+ success: true,
45453
+ sessionId,
45454
+ notificationId
45455
+ };
45456
+ }
45457
+ case "mark_notification_unread": {
45458
+ const sessionId = args?.sessionId;
45459
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
45460
+ if (!sessionId || typeof sessionId !== "string") {
45461
+ return { success: false, error: "sessionId is required" };
45462
+ }
45463
+ if (!notificationId) {
45464
+ return { success: false, error: "notificationId is required" };
45465
+ }
45466
+ const sessionEntries = buildSessionEntries(
45467
+ this.deps.instanceManager.collectAllStates(),
45468
+ this.deps.cdpManagers
45469
+ );
45470
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
45471
+ const next = markSessionNotificationUnread(
45472
+ loadState(),
45473
+ sessionId,
45474
+ notificationId,
45475
+ targetSession?.providerSessionId
45476
+ );
45477
+ saveState(next);
45478
+ this.deps.onStatusChange?.();
45479
+ return {
45480
+ success: true,
45481
+ sessionId,
45482
+ notificationId
45483
+ };
45484
+ }
45294
45485
  // ─── Daemon Self-Upgrade ───
45295
45486
  case "daemon_upgrade": {
45296
45487
  LOG2.info("Upgrade", "Remote upgrade requested from dashboard");