adhdev 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/index.js CHANGED
@@ -1062,6 +1062,96 @@ function getSessionSeenMarker(state, sessionId, providerSessionId) {
1062
1062
  const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
1063
1063
  return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
1064
1064
  }
1065
+ function getSessionNotificationDismissal(state, sessionId, providerSessionId) {
1066
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
1067
+ return state.sessionNotificationDismissals?.[providerKey] || state.sessionNotificationDismissals?.[sessionId] || "";
1068
+ }
1069
+ function getSessionNotificationUnreadOverride(state, sessionId, providerSessionId) {
1070
+ const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
1071
+ return state.sessionNotificationUnreadOverrides?.[providerKey] || state.sessionNotificationUnreadOverrides?.[sessionId] || "";
1072
+ }
1073
+ function dismissSessionNotification(state, sessionId, notificationId, providerSessionId) {
1074
+ const dismissalId = String(notificationId || "").trim();
1075
+ if (!dismissalId) return state;
1076
+ const dismissalKeys = Array.from(new Set([
1077
+ sessionId,
1078
+ buildSessionReadStateKey(sessionId, providerSessionId)
1079
+ ].filter(Boolean)));
1080
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
1081
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
1082
+ for (const key of dismissalKeys) {
1083
+ nextSessionNotificationDismissals[key] = dismissalId;
1084
+ delete nextSessionNotificationUnreadOverrides[key];
1085
+ }
1086
+ return {
1087
+ ...state,
1088
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
1089
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
1090
+ };
1091
+ }
1092
+ function markSessionNotificationUnread(state, sessionId, notificationId, providerSessionId) {
1093
+ const unreadId = String(notificationId || "").trim();
1094
+ if (!unreadId) return state;
1095
+ const unreadKeys = Array.from(new Set([
1096
+ sessionId,
1097
+ buildSessionReadStateKey(sessionId, providerSessionId)
1098
+ ].filter(Boolean)));
1099
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
1100
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
1101
+ for (const key of unreadKeys) {
1102
+ nextSessionNotificationUnreadOverrides[key] = unreadId;
1103
+ delete nextSessionNotificationDismissals[key];
1104
+ }
1105
+ return {
1106
+ ...state,
1107
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
1108
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
1109
+ };
1110
+ }
1111
+ function getSessionNotificationTargetValue(session) {
1112
+ const providerSessionId = typeof session.providerSessionId === "string" ? session.providerSessionId.trim() : "";
1113
+ return providerSessionId || session.id;
1114
+ }
1115
+ function getSessionCurrentNotificationId(session) {
1116
+ const inboxBucket = session.inboxBucket || "idle";
1117
+ const isNeedsAttention = inboxBucket === "needs_attention" || session.status === "waiting_approval";
1118
+ const isTaskComplete = inboxBucket === "task_complete" && !!session.unread;
1119
+ const type = isNeedsAttention ? "needs_attention" : isTaskComplete ? "task_complete" : "";
1120
+ if (!type) return "";
1121
+ const target = getSessionNotificationTargetValue(session);
1122
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
1123
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
1124
+ return [type, target, lastMessageHash, String(timestamp)].join("|");
1125
+ }
1126
+ function applySessionNotificationOverlay(session, overlay) {
1127
+ const currentNotificationId = getSessionCurrentNotificationId(session);
1128
+ const taskCompleteNotificationId = (() => {
1129
+ const target = getSessionNotificationTargetValue(session);
1130
+ const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
1131
+ const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
1132
+ if (!target || !lastMessageHash || !timestamp) return "";
1133
+ return ["task_complete", target, lastMessageHash, String(timestamp)].join("|");
1134
+ })();
1135
+ const dismissedNotificationId = typeof overlay.dismissedNotificationId === "string" ? overlay.dismissedNotificationId.trim() : "";
1136
+ const unreadNotificationId = typeof overlay.unreadNotificationId === "string" ? overlay.unreadNotificationId.trim() : "";
1137
+ if (unreadNotificationId && (currentNotificationId === unreadNotificationId || taskCompleteNotificationId === unreadNotificationId)) {
1138
+ const forcedInboxBucket = session.inboxBucket === "needs_attention" || session.status === "waiting_approval" ? "needs_attention" : "task_complete";
1139
+ return {
1140
+ unread: true,
1141
+ inboxBucket: forcedInboxBucket
1142
+ };
1143
+ }
1144
+ if (!currentNotificationId || !dismissedNotificationId || currentNotificationId !== dismissedNotificationId) {
1145
+ return {
1146
+ unread: !!session.unread,
1147
+ inboxBucket: session.inboxBucket || "idle"
1148
+ };
1149
+ }
1150
+ return {
1151
+ unread: false,
1152
+ inboxBucket: "idle"
1153
+ };
1154
+ }
1065
1155
  function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
1066
1156
  const prev = state.sessionReads || {};
1067
1157
  const prevMarkers = state.sessionReadMarkers || {};
@@ -1072,14 +1162,20 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
1072
1162
  ].filter(Boolean)));
1073
1163
  const nextSessionReads = { ...prev };
1074
1164
  const nextSessionReadMarkers = { ...prevMarkers };
1165
+ const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
1166
+ const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
1075
1167
  for (const key of readKeys) {
1076
1168
  nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
1077
1169
  if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
1170
+ delete nextSessionNotificationDismissals[key];
1171
+ delete nextSessionNotificationUnreadOverrides[key];
1078
1172
  }
1079
1173
  return {
1080
1174
  ...state,
1081
1175
  sessionReads: nextSessionReads,
1082
- sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
1176
+ sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers,
1177
+ sessionNotificationDismissals: nextSessionNotificationDismissals,
1178
+ sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
1083
1179
  };
1084
1180
  }
1085
1181
  var path2, MAX_ACTIVITY;
@@ -1209,11 +1305,19 @@ function normalizeState(raw) {
1209
1305
  const sessionReadMarkers = Object.fromEntries(
1210
1306
  Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
1211
1307
  );
1308
+ const sessionNotificationDismissals = Object.fromEntries(
1309
+ Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
1310
+ );
1311
+ const sessionNotificationUnreadOverrides = Object.fromEntries(
1312
+ Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
1313
+ );
1212
1314
  return {
1213
1315
  recentActivity,
1214
1316
  savedProviderSessions,
1215
1317
  sessionReads,
1216
- sessionReadMarkers
1318
+ sessionReadMarkers,
1319
+ sessionNotificationDismissals,
1320
+ sessionNotificationUnreadOverrides
1217
1321
  };
1218
1322
  }
1219
1323
  function loadState() {
@@ -1248,7 +1352,9 @@ var init_state_store = __esm({
1248
1352
  recentActivity: [],
1249
1353
  savedProviderSessions: [],
1250
1354
  sessionReads: {},
1251
- sessionReadMarkers: {}
1355
+ sessionReadMarkers: {},
1356
+ sessionNotificationDismissals: {},
1357
+ sessionNotificationUnreadOverrides: {}
1252
1358
  };
1253
1359
  }
1254
1360
  });
@@ -1650,9 +1756,15 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
1650
1756
  continue;
1651
1757
  }
1652
1758
  const status = String(session?.status || "").toLowerCase();
1759
+ const unread = session?.unread === true;
1760
+ const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
1761
+ const runtimeSurfaceKind = String(session?.runtimeSurfaceKind || "").toLowerCase();
1762
+ const runtimeLifecycle = String(session?.runtimeLifecycle || "").toLowerCase();
1763
+ const isLiveRuntime = runtimeSurfaceKind === "live_runtime" || LIVE_RUNTIME_LIFECYCLES.has(runtimeLifecycle);
1653
1764
  const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
1654
1765
  const recentlyUpdated = lastMessageAt > 0 && now - lastMessageAt <= recentMessageGraceMs;
1655
- if (activeStatuses.has(status) || recentlyUpdated) {
1766
+ const shouldKeepRecentTailHot = recentlyUpdated && (unread || inboxBucket === "task_complete" || inboxBucket === "needs_attention" || isLiveRuntime || activeStatuses.has(status));
1767
+ if (activeStatuses.has(status) || shouldKeepRecentTailHot) {
1656
1768
  active.add(sessionId);
1657
1769
  }
1658
1770
  }
@@ -5217,7 +5329,6 @@ var init_extension_provider_instance = __esm({
5217
5329
  }
5218
5330
  pushEvent(event) {
5219
5331
  this.events.push(event);
5220
- if (this.events.length > 50) this.events = this.events.slice(-50);
5221
5332
  }
5222
5333
  applyProviderResponse(data, options) {
5223
5334
  if (!data || typeof data !== "object") return;
@@ -5293,7 +5404,6 @@ var init_extension_provider_instance = __esm({
5293
5404
  key: dedupKey,
5294
5405
  message: normalizedMessage
5295
5406
  });
5296
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
5297
5407
  if (normalizedContent) {
5298
5408
  this.historyWriter.appendNewMessages(
5299
5409
  this.type,
@@ -5970,7 +6080,6 @@ var init_ide_provider_instance = __esm({
5970
6080
  }
5971
6081
  pushEvent(event) {
5972
6082
  this.events.push(event);
5973
- if (this.events.length > 50) this.events = this.events.slice(-50);
5974
6083
  }
5975
6084
  applyProviderResponse(data, options) {
5976
6085
  if (!data || typeof data !== "object") return;
@@ -6060,7 +6169,6 @@ var init_ide_provider_instance = __esm({
6060
6169
  key: dedupKey,
6061
6170
  message: normalizedMessage
6062
6171
  });
6063
- if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
6064
6172
  if (normalizedContent) {
6065
6173
  this.historyWriter.appendNewMessages(
6066
6174
  this.type,
@@ -7687,7 +7795,14 @@ async function handleReadChat(h, args) {
7687
7795
  const adapter = getTargetedCliAdapter(h, args, provider?.type);
7688
7796
  if (adapter) {
7689
7797
  _log(`${transport} adapter: ${adapter.cliType}`);
7690
- const parsedStatus = typeof adapter.getScriptParsedStatus === "function" ? parseMaybeJson(adapter.getScriptParsedStatus()) : null;
7798
+ let parsedStatus = null;
7799
+ if (typeof adapter.getScriptParsedStatus === "function") {
7800
+ try {
7801
+ parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
7802
+ } catch (error48) {
7803
+ return { success: false, error: error48?.message || String(error48) };
7804
+ }
7805
+ }
7691
7806
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
7692
7807
  const status = parsedRecord || adapter.getStatus();
7693
7808
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
@@ -10702,10 +10817,12 @@ function logTerminalBackendSelection(preference, ghosttyAvailable, backendKind)
10702
10817
  if (loggedTerminalBackends.has(key)) return;
10703
10818
  loggedTerminalBackends.add(key);
10704
10819
  if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
10705
- LOG.warn(
10706
- "Terminal",
10707
- `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`
10708
- );
10820
+ const message = `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`;
10821
+ if (preference === "auto") {
10822
+ LOG.info("Terminal", message);
10823
+ } else {
10824
+ LOG.warn("Terminal", message);
10825
+ }
10709
10826
  return;
10710
10827
  }
10711
10828
  LOG.info(
@@ -11979,6 +12096,7 @@ var init_provider_cli_adapter = __esm({
11979
12096
  "use strict";
11980
12097
  os13 = __toESM(require("os"));
11981
12098
  init_logger();
12099
+ init_debug_config();
11982
12100
  init_terminal_screen();
11983
12101
  init_pty_transport();
11984
12102
  init_provider_cli_shared();
@@ -12012,7 +12130,15 @@ var init_provider_cli_adapter = __esm({
12012
12130
  `[${this.cliType}] Provider resolution: providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"} source=${this.providerResolutionMeta.scriptsSource || "-"} version=${this.providerResolutionMeta.resolvedVersion || "-"}`
12013
12131
  );
12014
12132
  } else {
12015
- LOG.warn("CLI", `[${this.cliType}] \u26A0 No CLI scripts loaded! Provider needs scripts/{version}/scripts.js`);
12133
+ const resolutionSummary = `providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"} source=${this.providerResolutionMeta.scriptsSource || "-"} version=${this.providerResolutionMeta.resolvedVersion || "-"}`;
12134
+ const hasResolvedProviderScripts = Boolean(
12135
+ this.providerResolutionMeta.providerDir || this.providerResolutionMeta.scriptDir || this.providerResolutionMeta.scriptsPath || this.providerResolutionMeta.scriptsSource || this.providerResolutionMeta.resolvedVersion
12136
+ );
12137
+ if (hasResolvedProviderScripts) {
12138
+ LOG.warn("CLI", `[${this.cliType}] \u26A0 No CLI scripts loaded! Provider needs scripts/{version}/scripts.js (${resolutionSummary})`);
12139
+ } else {
12140
+ LOG.info("CLI", `[${this.cliType}] CLI scripts not yet resolved (${resolutionSummary})`);
12141
+ }
12016
12142
  }
12017
12143
  }
12018
12144
  cliType;
@@ -12030,6 +12156,7 @@ var init_provider_cli_adapter = __esm({
12030
12156
  recentOutputBuffer = "";
12031
12157
  isWaitingForResponse = false;
12032
12158
  activeModal = null;
12159
+ parseErrorMessage = null;
12033
12160
  responseTimeout = null;
12034
12161
  idleTimeout = null;
12035
12162
  ready = false;
@@ -12090,7 +12217,8 @@ var init_provider_cli_adapter = __esm({
12090
12217
  currentTurnScope = null;
12091
12218
  traceEntries = [];
12092
12219
  traceSeq = 0;
12093
- traceSessionId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
12220
+ traceSessionId = "";
12221
+ parsedStatusCache = null;
12094
12222
  static MAX_TRACE_ENTRIES = 250;
12095
12223
  providerResolutionMeta;
12096
12224
  static FINISH_RETRY_DELAY_MS = 300;
@@ -12331,7 +12459,8 @@ var init_provider_cli_adapter = __esm({
12331
12459
  this.terminalScreen.write(rawData);
12332
12460
  const cleanData = sanitizeTerminalText(rawData);
12333
12461
  const now = Date.now();
12334
- const normalizedScreenSnapshot = normalizeScreenSnapshot(this.terminalScreen.getText());
12462
+ const screenText = this.terminalScreen.getText();
12463
+ const normalizedScreenSnapshot = normalizeScreenSnapshot(screenText);
12335
12464
  this.lastOutputAt = now;
12336
12465
  if (cleanData.trim()) this.lastNonEmptyOutputAt = now;
12337
12466
  if (normalizedScreenSnapshot !== this.lastScreenSnapshot) {
@@ -12344,13 +12473,14 @@ var init_provider_cli_adapter = __esm({
12344
12473
  if (this.idleFinishCandidate && (rawData.length > 0 || cleanData.length > 0)) {
12345
12474
  this.clearIdleFinishCandidate("new_output");
12346
12475
  }
12347
- this.recordTrace("output", {
12348
- rawLength: rawData.length,
12349
- cleanLength: cleanData.length,
12350
- rawPreview: summarizeCliTraceText(rawData, 300),
12351
- cleanPreview: summarizeCliTraceText(cleanData, 300),
12352
- screenText: summarizeCliTraceText(this.terminalScreen.getText(), 1200)
12353
- });
12476
+ if (getDebugRuntimeConfig().collectDebugTrace) {
12477
+ this.recordTrace("output", {
12478
+ rawLength: rawData.length,
12479
+ cleanLength: cleanData.length,
12480
+ rawPreview: summarizeCliTraceText(rawData, 300),
12481
+ cleanPreview: summarizeCliTraceText(cleanData, 300)
12482
+ });
12483
+ }
12354
12484
  if (this.startupParseGate) {
12355
12485
  this.scheduleStartupSettleCheck();
12356
12486
  }
@@ -13024,10 +13154,12 @@ var init_provider_cli_adapter = __esm({
13024
13154
  // ─── Public API (CliAdapter) ───────────────────
13025
13155
  getStatus() {
13026
13156
  return {
13027
- status: this.currentStatus,
13157
+ status: this.parseErrorMessage ? "error" : this.currentStatus,
13028
13158
  messages: [...this.committedMessages],
13029
13159
  workingDir: this.workingDir,
13030
- activeModal: this.activeModal
13160
+ activeModal: this.activeModal,
13161
+ errorMessage: this.parseErrorMessage || void 0,
13162
+ errorReason: this.parseErrorMessage ? "parse_error" : void 0
13031
13163
  };
13032
13164
  }
13033
13165
  seedCommittedMessages(messages) {
@@ -13050,12 +13182,19 @@ var init_provider_cli_adapter = __esm({
13050
13182
  * Called by command handler / dashboard for rich content rendering.
13051
13183
  */
13052
13184
  getScriptParsedStatus() {
13185
+ const screenText = this.terminalScreen.getText();
13186
+ const cached2 = this.parsedStatusCache;
13187
+ if (cached2 && cached2.committedMessagesRef === this.committedMessages && cached2.responseBuffer === this.responseBuffer && cached2.currentTurnScope === this.currentTurnScope && cached2.recentOutputBuffer === this.recentOutputBuffer && cached2.accumulatedBuffer === this.accumulatedBuffer && cached2.accumulatedRawBuffer === this.accumulatedRawBuffer && cached2.screenText === screenText && cached2.currentStatus === this.currentStatus && cached2.activeModal === this.activeModal && cached2.cliName === this.cliName && cached2.lastOutputAt === this.lastOutputAt) {
13188
+ return cached2.result;
13189
+ }
13053
13190
  const parsed = this.parseCurrentTranscript(
13054
13191
  this.committedMessages,
13055
13192
  this.responseBuffer,
13056
- this.currentTurnScope
13193
+ this.currentTurnScope,
13194
+ screenText
13057
13195
  );
13058
13196
  const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
13197
+ let result;
13059
13198
  if (parsed && Array.isArray(parsed.messages)) {
13060
13199
  const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => buildChatMessage({
13061
13200
  ...message,
@@ -13067,7 +13206,7 @@ var init_provider_cli_adapter = __esm({
13067
13206
  scope: this.currentTurnScope,
13068
13207
  lastOutputAt: this.lastOutputAt
13069
13208
  });
13070
- return {
13209
+ result = {
13071
13210
  id: parsed.id || "cli_session",
13072
13211
  status: parsed.status || this.currentStatus,
13073
13212
  title: parsed.title || this.cliName,
@@ -13075,20 +13214,36 @@ var init_provider_cli_adapter = __esm({
13075
13214
  activeModal: parsed.activeModal ?? this.activeModal,
13076
13215
  providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0
13077
13216
  };
13217
+ } else {
13218
+ const messages = [...this.committedMessages];
13219
+ result = {
13220
+ id: "cli_session",
13221
+ status: this.currentStatus,
13222
+ title: this.cliName,
13223
+ messages: messages.map((message, index) => buildChatMessage({
13224
+ ...message,
13225
+ id: message.id || `msg_${index}`,
13226
+ index: typeof message.index === "number" ? message.index : index,
13227
+ receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
13228
+ })),
13229
+ activeModal: this.activeModal
13230
+ };
13078
13231
  }
13079
- const messages = [...this.committedMessages];
13080
- return {
13081
- id: "cli_session",
13082
- status: this.currentStatus,
13083
- title: this.cliName,
13084
- messages: messages.slice(-50).map((message, index) => buildChatMessage({
13085
- ...message,
13086
- id: message.id || `msg_${index}`,
13087
- index: typeof message.index === "number" ? message.index : index,
13088
- receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
13089
- })),
13090
- activeModal: this.activeModal
13232
+ this.parsedStatusCache = {
13233
+ committedMessagesRef: this.committedMessages,
13234
+ responseBuffer: this.responseBuffer,
13235
+ currentTurnScope: this.currentTurnScope,
13236
+ recentOutputBuffer: this.recentOutputBuffer,
13237
+ accumulatedBuffer: this.accumulatedBuffer,
13238
+ accumulatedRawBuffer: this.accumulatedRawBuffer,
13239
+ screenText,
13240
+ currentStatus: this.currentStatus,
13241
+ activeModal: this.activeModal,
13242
+ cliName: this.cliName,
13243
+ lastOutputAt: this.lastOutputAt,
13244
+ result
13091
13245
  };
13246
+ return result;
13092
13247
  }
13093
13248
  async invokeScript(scriptName, args) {
13094
13249
  const fn = this.cliScripts?.[scriptName];
@@ -13111,14 +13266,18 @@ var init_provider_cli_adapter = __esm({
13111
13266
  args: args && typeof args === "object" ? { ...args } : {}
13112
13267
  }));
13113
13268
  }
13114
- parseCurrentTranscript(baseMessages, partialResponse, scope) {
13115
- if (!this.cliScripts?.parseOutput) return null;
13269
+ parseCurrentTranscript(baseMessages, partialResponse, scope, screenTextOverride) {
13270
+ if (!this.cliScripts?.parseOutput) {
13271
+ this.parseErrorMessage = null;
13272
+ return null;
13273
+ }
13116
13274
  try {
13275
+ const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
13117
13276
  const input = buildCliParseInput({
13118
13277
  accumulatedBuffer: this.accumulatedBuffer,
13119
13278
  accumulatedRawBuffer: this.accumulatedRawBuffer,
13120
13279
  recentOutputBuffer: this.recentOutputBuffer,
13121
- terminalScreenText: this.terminalScreen.getText(),
13280
+ terminalScreenText: screenText,
13122
13281
  baseMessages,
13123
13282
  partialResponse,
13124
13283
  isWaitingForResponse: this.isWaitingForResponse,
@@ -13140,10 +13299,13 @@ var init_provider_cli_adapter = __esm({
13140
13299
  lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
13141
13300
  }
13142
13301
  }
13302
+ this.parseErrorMessage = null;
13143
13303
  return parsed;
13144
13304
  } catch (e) {
13145
- LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${e.message}`);
13146
- return null;
13305
+ const message = e?.message || String(e);
13306
+ this.parseErrorMessage = message;
13307
+ LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
13308
+ throw e;
13147
13309
  }
13148
13310
  }
13149
13311
  /** Whether this adapter has CLI scripts loaded */
@@ -13817,6 +13979,8 @@ var init_cli_provider_instance = __esm({
13817
13979
  runtimeMessages = [];
13818
13980
  instanceId;
13819
13981
  suppressIdleHistoryReplay = false;
13982
+ errorMessage = void 0;
13983
+ errorReason = void 0;
13820
13984
  presentationMode;
13821
13985
  providerSessionId;
13822
13986
  launchMode;
@@ -13883,6 +14047,7 @@ var init_cli_provider_instance = __esm({
13883
14047
  }
13884
14048
  async onTick() {
13885
14049
  if (this.providerSessionId) return;
14050
+ if (this.type === "hermes-cli" && this.launchMode === "new") return;
13886
14051
  let probedSessionId = null;
13887
14052
  const probeConfig = this.provider.sessionProbe;
13888
14053
  if (probeConfig) {
@@ -13940,9 +14105,24 @@ var init_cli_provider_instance = __esm({
13940
14105
  }
13941
14106
  getState() {
13942
14107
  const adapterStatus = this.adapter.getStatus();
13943
- const parsedStatus = this.adapter.getScriptParsedStatus?.() || null;
14108
+ let parsedStatus = null;
14109
+ let parseErrorMessage;
14110
+ if (typeof this.adapter.getScriptParsedStatus === "function") {
14111
+ try {
14112
+ parsedStatus = this.adapter.getScriptParsedStatus() || null;
14113
+ this.errorMessage = void 0;
14114
+ this.errorReason = void 0;
14115
+ } catch (error48) {
14116
+ parseErrorMessage = error48?.message || String(error48);
14117
+ this.errorMessage = parseErrorMessage;
14118
+ this.errorReason = "parse_error";
14119
+ }
14120
+ } else {
14121
+ this.errorMessage = void 0;
14122
+ this.errorReason = void 0;
14123
+ }
13944
14124
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
13945
- const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
14125
+ const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
13946
14126
  const parsedProviderSessionId = normalizeProviderSessionId(
13947
14127
  this.type,
13948
14128
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
@@ -13952,7 +14132,7 @@ var init_cli_provider_instance = __esm({
13952
14132
  }
13953
14133
  const runtime = this.adapter.getRuntimeMetadata();
13954
14134
  this.maybeAppendRuntimeRecoveryMessage(runtime);
13955
- let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
14135
+ let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : parseErrorMessage ? normalizeChatMessages(Array.isArray(adapterStatus.messages) ? adapterStatus.messages : []) : [];
13956
14136
  const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
13957
14137
  if (historyMessageCount !== null) {
13958
14138
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
@@ -13992,7 +14172,7 @@ var init_cli_provider_instance = __esm({
13992
14172
  activeChat: {
13993
14173
  id: `${this.type}_${this.workingDir}`,
13994
14174
  title: parsedStatus?.title || dirName,
13995
- status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
14175
+ status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
13996
14176
  messages: mergedMessages,
13997
14177
  activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
13998
14178
  inputContent: ""
@@ -14018,7 +14198,9 @@ var init_cli_provider_instance = __esm({
14018
14198
  resume: this.provider.resume,
14019
14199
  controlValues: surface.controlValues,
14020
14200
  providerControls: this.provider.controls,
14021
- summaryMetadata: surface.summaryMetadata
14201
+ summaryMetadata: surface.summaryMetadata,
14202
+ errorMessage: this.errorMessage,
14203
+ errorReason: this.errorReason
14022
14204
  };
14023
14205
  }
14024
14206
  setPresentationMode(mode) {
@@ -14205,7 +14387,6 @@ var init_cli_provider_instance = __esm({
14205
14387
  }
14206
14388
  pushEvent(event) {
14207
14389
  this.events.push(event);
14208
- if (this.events.length > 50) this.events = this.events.slice(-50);
14209
14390
  }
14210
14391
  flushEvents() {
14211
14392
  const events = [...this.events];
@@ -14387,9 +14568,6 @@ ${effect.notification.body || ""}`.trim();
14387
14568
  key: dedupKey,
14388
14569
  message: normalizedMessage
14389
14570
  });
14390
- if (this.runtimeMessages.length > 50) {
14391
- this.runtimeMessages = this.runtimeMessages.slice(-50);
14392
- }
14393
14571
  if (normalizedContent) {
14394
14572
  this.historyWriter.appendNewMessages(
14395
14573
  this.type,
@@ -30948,8 +31126,8 @@ var init_acp_provider_instance = __esm({
30948
31126
  }
30949
31127
  getState() {
30950
31128
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
30951
- const recentMessages = normalizeChatMessages(this.messages.slice(-50).map((m) => {
30952
- const content = this.truncateContent(m.content);
31129
+ const recentMessages = normalizeChatMessages(this.messages.map((m) => {
31130
+ const content = m.content;
30953
31131
  return buildChatMessage({
30954
31132
  ...m,
30955
31133
  content
@@ -31742,18 +31920,6 @@ var init_acp_provider_instance = __esm({
31742
31920
  }
31743
31921
  }
31744
31922
  // ─── Rich Content Helpers ────────────────────────────
31745
- /** Truncate content for transport (text: 2000 chars, images preserved) */
31746
- truncateContent(content) {
31747
- if (typeof content === "string") {
31748
- return content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
31749
- }
31750
- return content.map((b) => {
31751
- if (b.type === "text" && b.text.length > 2e3) {
31752
- return { ...b, text: b.text.slice(0, 2e3) + "\n... (truncated)" };
31753
- }
31754
- return b;
31755
- });
31756
- }
31757
31923
  /** Build ContentBlock[] from current partial state */
31758
31924
  buildPartialBlocks() {
31759
31925
  const blocks = [];
@@ -31907,7 +32073,6 @@ ${rawInput}` : rawInput;
31907
32073
  }
31908
32074
  pushEvent(event) {
31909
32075
  this.events.push(event);
31910
- if (this.events.length > 50) this.events = this.events.slice(-50);
31911
32076
  }
31912
32077
  appendSystemMessage(content, timestamp = Date.now()) {
31913
32078
  const normalizedContent = String(content || "").trim();
@@ -36423,7 +36588,9 @@ var init_command_log = __esm({
36423
36588
  "heartbeat",
36424
36589
  "status_report",
36425
36590
  "read_chat",
36426
- "mark_session_seen"
36591
+ "mark_session_seen",
36592
+ "delete_notification",
36593
+ "mark_notification_unread"
36427
36594
  ]);
36428
36595
  cleanOldFiles();
36429
36596
  }
@@ -36643,9 +36810,24 @@ function buildStatusSnapshot(options) {
36643
36810
  completionMarker,
36644
36811
  seenCompletionMarker
36645
36812
  );
36813
+ const { unread: overlayUnread, inboxBucket: overlayInboxBucket } = applySessionNotificationOverlay({
36814
+ id: sourceSession.id,
36815
+ providerSessionId: sourceSession.providerSessionId,
36816
+ status: sourceSession.status,
36817
+ unread,
36818
+ inboxBucket,
36819
+ lastMessageHash: sourceSession.lastMessageHash,
36820
+ lastMessageAt: sourceSession.lastMessageAt,
36821
+ lastUpdated: sourceSession.lastUpdated
36822
+ }, {
36823
+ dismissedNotificationId: getSessionNotificationDismissal(state, sourceSession.id, sourceSession.providerSessionId),
36824
+ unreadNotificationId: getSessionNotificationUnreadOverride(state, sourceSession.id, sourceSession.providerSessionId)
36825
+ });
36646
36826
  session.lastSeenAt = lastSeenAt;
36647
- session.unread = unread;
36648
- session.inboxBucket = inboxBucket;
36827
+ session.unread = overlayUnread;
36828
+ session.inboxBucket = overlayInboxBucket;
36829
+ session.completionMarker = completionMarker;
36830
+ session.seenCompletionMarker = seenCompletionMarker;
36649
36831
  if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
36650
36832
  const recentReadSnapshot = {
36651
36833
  sessionId: session.id,
@@ -36710,6 +36892,7 @@ var init_snapshot = __esm({
36710
36892
  init_terminal_screen();
36711
36893
  init_logger();
36712
36894
  init_builders();
36895
+ init_recent_activity();
36713
36896
  READ_DEBUG_ENABLED = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
36714
36897
  recentReadDebugSignatureBySession = /* @__PURE__ */ new Map();
36715
36898
  }
@@ -37509,6 +37692,62 @@ var init_router = __esm({
37509
37692
  completionMarker
37510
37693
  };
37511
37694
  }
37695
+ case "delete_notification": {
37696
+ const sessionId = args?.sessionId;
37697
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
37698
+ if (!sessionId || typeof sessionId !== "string") {
37699
+ return { success: false, error: "sessionId is required" };
37700
+ }
37701
+ if (!notificationId) {
37702
+ return { success: false, error: "notificationId is required" };
37703
+ }
37704
+ const sessionEntries = buildSessionEntries(
37705
+ this.deps.instanceManager.collectAllStates(),
37706
+ this.deps.cdpManagers
37707
+ );
37708
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
37709
+ const next = dismissSessionNotification(
37710
+ loadState(),
37711
+ sessionId,
37712
+ notificationId,
37713
+ targetSession?.providerSessionId
37714
+ );
37715
+ saveState(next);
37716
+ this.deps.onStatusChange?.();
37717
+ return {
37718
+ success: true,
37719
+ sessionId,
37720
+ notificationId
37721
+ };
37722
+ }
37723
+ case "mark_notification_unread": {
37724
+ const sessionId = args?.sessionId;
37725
+ const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
37726
+ if (!sessionId || typeof sessionId !== "string") {
37727
+ return { success: false, error: "sessionId is required" };
37728
+ }
37729
+ if (!notificationId) {
37730
+ return { success: false, error: "notificationId is required" };
37731
+ }
37732
+ const sessionEntries = buildSessionEntries(
37733
+ this.deps.instanceManager.collectAllStates(),
37734
+ this.deps.cdpManagers
37735
+ );
37736
+ const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
37737
+ const next = markSessionNotificationUnread(
37738
+ loadState(),
37739
+ sessionId,
37740
+ notificationId,
37741
+ targetSession?.providerSessionId
37742
+ );
37743
+ saveState(next);
37744
+ this.deps.onStatusChange?.();
37745
+ return {
37746
+ success: true,
37747
+ sessionId,
37748
+ notificationId
37749
+ };
37750
+ }
37512
37751
  // ─── Daemon Self-Upgrade ───
37513
37752
  case "daemon_upgrade": {
37514
37753
  LOG.info("Upgrade", "Remote upgrade requested from dashboard");
@@ -77312,6 +77551,8 @@ var init_server_connection = __esm({
77312
77551
  if (misses >= 3 && this.ws) {
77313
77552
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 closing stale WS`);
77314
77553
  this.ws.terminate();
77554
+ } else if (misses === 1) {
77555
+ LOG.info("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
77315
77556
  } else {
77316
77557
  LOG.warn("Server", `[ServerConn] Pong timeout (${misses}x) \u2014 keeping WS open and retrying`);
77317
77558
  }
@@ -85867,7 +86108,7 @@ var init_adhdev_daemon = __esm({
85867
86108
  init_source();
85868
86109
  init_version();
85869
86110
  init_src();
85870
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.81" });
86111
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.83" });
85871
86112
  AdhdevDaemon = class _AdhdevDaemon {
85872
86113
  localHttpServer = null;
85873
86114
  localWss = null;