@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
package/dist/index.mjs
CHANGED
|
@@ -951,6 +951,58 @@ var init_read_chat_contract = __esm({
|
|
|
951
951
|
}
|
|
952
952
|
});
|
|
953
953
|
|
|
954
|
+
// src/logging/debug-config.ts
|
|
955
|
+
function normalizeCategories(categories) {
|
|
956
|
+
if (!Array.isArray(categories)) return [];
|
|
957
|
+
return categories.map((category) => String(category || "").trim()).filter(Boolean);
|
|
958
|
+
}
|
|
959
|
+
function resolveDebugRuntimeConfig(options = {}) {
|
|
960
|
+
const dev = options.dev === true;
|
|
961
|
+
return {
|
|
962
|
+
logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
|
|
963
|
+
collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
|
|
964
|
+
traceContent: options.traceContent === true,
|
|
965
|
+
traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
|
|
966
|
+
traceCategories: normalizeCategories(options.traceCategories)
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
function setDebugRuntimeConfig(config) {
|
|
970
|
+
currentConfig = {
|
|
971
|
+
...config,
|
|
972
|
+
traceCategories: normalizeCategories(config.traceCategories),
|
|
973
|
+
traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
function getDebugRuntimeConfig() {
|
|
977
|
+
return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
|
|
978
|
+
}
|
|
979
|
+
function resetDebugRuntimeConfig() {
|
|
980
|
+
currentConfig = { ...DEFAULT_CONFIG2 };
|
|
981
|
+
}
|
|
982
|
+
function shouldCollectTraceCategory(category) {
|
|
983
|
+
const config = currentConfig;
|
|
984
|
+
if (!config.collectDebugTrace) return false;
|
|
985
|
+
if (!category) return true;
|
|
986
|
+
if (config.traceCategories.length === 0) return true;
|
|
987
|
+
return config.traceCategories.includes(category);
|
|
988
|
+
}
|
|
989
|
+
var NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig;
|
|
990
|
+
var init_debug_config = __esm({
|
|
991
|
+
"src/logging/debug-config.ts"() {
|
|
992
|
+
"use strict";
|
|
993
|
+
NORMAL_TRACE_BUFFER_SIZE = 200;
|
|
994
|
+
DEV_TRACE_BUFFER_SIZE = 1e3;
|
|
995
|
+
DEFAULT_CONFIG2 = {
|
|
996
|
+
logLevel: "info",
|
|
997
|
+
collectDebugTrace: false,
|
|
998
|
+
traceContent: false,
|
|
999
|
+
traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
|
|
1000
|
+
traceCategories: []
|
|
1001
|
+
};
|
|
1002
|
+
currentConfig = { ...DEFAULT_CONFIG2 };
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
|
|
954
1006
|
// src/cli-adapters/terminal-backends/ghostty-vt-backend.ts
|
|
955
1007
|
function isModuleNotFoundError(error, ref) {
|
|
956
1008
|
if (!(error instanceof Error)) return false;
|
|
@@ -1149,10 +1201,12 @@ function logTerminalBackendSelection(preference, ghosttyAvailable, backendKind)
|
|
|
1149
1201
|
if (loggedTerminalBackends.has(key)) return;
|
|
1150
1202
|
loggedTerminalBackends.add(key);
|
|
1151
1203
|
if (backendKind === "xterm" && preference !== "xterm" && !ghosttyAvailable) {
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1204
|
+
const message = `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`;
|
|
1205
|
+
if (preference === "auto") {
|
|
1206
|
+
LOG.info("Terminal", message);
|
|
1207
|
+
} else {
|
|
1208
|
+
LOG.warn("Terminal", message);
|
|
1209
|
+
}
|
|
1156
1210
|
return;
|
|
1157
1211
|
}
|
|
1158
1212
|
LOG.info(
|
|
@@ -1806,6 +1860,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1806
1860
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
1807
1861
|
"use strict";
|
|
1808
1862
|
init_logger();
|
|
1863
|
+
init_debug_config();
|
|
1809
1864
|
init_terminal_screen();
|
|
1810
1865
|
init_pty_transport();
|
|
1811
1866
|
init_provider_cli_shared();
|
|
@@ -1839,7 +1894,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
1839
1894
|
`[${this.cliType}] Provider resolution: providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"} source=${this.providerResolutionMeta.scriptsSource || "-"} version=${this.providerResolutionMeta.resolvedVersion || "-"}`
|
|
1840
1895
|
);
|
|
1841
1896
|
} else {
|
|
1842
|
-
|
|
1897
|
+
const resolutionSummary = `providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"} source=${this.providerResolutionMeta.scriptsSource || "-"} version=${this.providerResolutionMeta.resolvedVersion || "-"}`;
|
|
1898
|
+
const hasResolvedProviderScripts = Boolean(
|
|
1899
|
+
this.providerResolutionMeta.providerDir || this.providerResolutionMeta.scriptDir || this.providerResolutionMeta.scriptsPath || this.providerResolutionMeta.scriptsSource || this.providerResolutionMeta.resolvedVersion
|
|
1900
|
+
);
|
|
1901
|
+
if (hasResolvedProviderScripts) {
|
|
1902
|
+
LOG.warn("CLI", `[${this.cliType}] \u26A0 No CLI scripts loaded! Provider needs scripts/{version}/scripts.js (${resolutionSummary})`);
|
|
1903
|
+
} else {
|
|
1904
|
+
LOG.info("CLI", `[${this.cliType}] CLI scripts not yet resolved (${resolutionSummary})`);
|
|
1905
|
+
}
|
|
1843
1906
|
}
|
|
1844
1907
|
}
|
|
1845
1908
|
cliType;
|
|
@@ -1857,6 +1920,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
1857
1920
|
recentOutputBuffer = "";
|
|
1858
1921
|
isWaitingForResponse = false;
|
|
1859
1922
|
activeModal = null;
|
|
1923
|
+
parseErrorMessage = null;
|
|
1860
1924
|
responseTimeout = null;
|
|
1861
1925
|
idleTimeout = null;
|
|
1862
1926
|
ready = false;
|
|
@@ -1917,7 +1981,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
1917
1981
|
currentTurnScope = null;
|
|
1918
1982
|
traceEntries = [];
|
|
1919
1983
|
traceSeq = 0;
|
|
1920
|
-
traceSessionId =
|
|
1984
|
+
traceSessionId = "";
|
|
1985
|
+
parsedStatusCache = null;
|
|
1921
1986
|
static MAX_TRACE_ENTRIES = 250;
|
|
1922
1987
|
providerResolutionMeta;
|
|
1923
1988
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
@@ -2158,7 +2223,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2158
2223
|
this.terminalScreen.write(rawData);
|
|
2159
2224
|
const cleanData = sanitizeTerminalText(rawData);
|
|
2160
2225
|
const now = Date.now();
|
|
2161
|
-
const
|
|
2226
|
+
const screenText = this.terminalScreen.getText();
|
|
2227
|
+
const normalizedScreenSnapshot = normalizeScreenSnapshot(screenText);
|
|
2162
2228
|
this.lastOutputAt = now;
|
|
2163
2229
|
if (cleanData.trim()) this.lastNonEmptyOutputAt = now;
|
|
2164
2230
|
if (normalizedScreenSnapshot !== this.lastScreenSnapshot) {
|
|
@@ -2171,13 +2237,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
2171
2237
|
if (this.idleFinishCandidate && (rawData.length > 0 || cleanData.length > 0)) {
|
|
2172
2238
|
this.clearIdleFinishCandidate("new_output");
|
|
2173
2239
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2240
|
+
if (getDebugRuntimeConfig().collectDebugTrace) {
|
|
2241
|
+
this.recordTrace("output", {
|
|
2242
|
+
rawLength: rawData.length,
|
|
2243
|
+
cleanLength: cleanData.length,
|
|
2244
|
+
rawPreview: summarizeCliTraceText(rawData, 300),
|
|
2245
|
+
cleanPreview: summarizeCliTraceText(cleanData, 300)
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2181
2248
|
if (this.startupParseGate) {
|
|
2182
2249
|
this.scheduleStartupSettleCheck();
|
|
2183
2250
|
}
|
|
@@ -2851,10 +2918,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
2851
2918
|
// ─── Public API (CliAdapter) ───────────────────
|
|
2852
2919
|
getStatus() {
|
|
2853
2920
|
return {
|
|
2854
|
-
status: this.currentStatus,
|
|
2921
|
+
status: this.parseErrorMessage ? "error" : this.currentStatus,
|
|
2855
2922
|
messages: [...this.committedMessages],
|
|
2856
2923
|
workingDir: this.workingDir,
|
|
2857
|
-
activeModal: this.activeModal
|
|
2924
|
+
activeModal: this.activeModal,
|
|
2925
|
+
errorMessage: this.parseErrorMessage || void 0,
|
|
2926
|
+
errorReason: this.parseErrorMessage ? "parse_error" : void 0
|
|
2858
2927
|
};
|
|
2859
2928
|
}
|
|
2860
2929
|
seedCommittedMessages(messages) {
|
|
@@ -2877,12 +2946,19 @@ var init_provider_cli_adapter = __esm({
|
|
|
2877
2946
|
* Called by command handler / dashboard for rich content rendering.
|
|
2878
2947
|
*/
|
|
2879
2948
|
getScriptParsedStatus() {
|
|
2949
|
+
const screenText = this.terminalScreen.getText();
|
|
2950
|
+
const cached = this.parsedStatusCache;
|
|
2951
|
+
if (cached && cached.committedMessagesRef === this.committedMessages && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.accumulatedRawBuffer === this.accumulatedRawBuffer && cached.screenText === screenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName && cached.lastOutputAt === this.lastOutputAt) {
|
|
2952
|
+
return cached.result;
|
|
2953
|
+
}
|
|
2880
2954
|
const parsed = this.parseCurrentTranscript(
|
|
2881
2955
|
this.committedMessages,
|
|
2882
2956
|
this.responseBuffer,
|
|
2883
|
-
this.currentTurnScope
|
|
2957
|
+
this.currentTurnScope,
|
|
2958
|
+
screenText
|
|
2884
2959
|
);
|
|
2885
2960
|
const shouldPreferCommittedMessages = !this.currentTurnScope && this.currentStatus === "idle" && !this.activeModal;
|
|
2961
|
+
let result;
|
|
2886
2962
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
2887
2963
|
const hydratedMessages = shouldPreferCommittedMessages ? this.committedMessages.map((message, index) => buildChatMessage({
|
|
2888
2964
|
...message,
|
|
@@ -2894,7 +2970,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
2894
2970
|
scope: this.currentTurnScope,
|
|
2895
2971
|
lastOutputAt: this.lastOutputAt
|
|
2896
2972
|
});
|
|
2897
|
-
|
|
2973
|
+
result = {
|
|
2898
2974
|
id: parsed.id || "cli_session",
|
|
2899
2975
|
status: parsed.status || this.currentStatus,
|
|
2900
2976
|
title: parsed.title || this.cliName,
|
|
@@ -2902,20 +2978,36 @@ var init_provider_cli_adapter = __esm({
|
|
|
2902
2978
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
2903
2979
|
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0
|
|
2904
2980
|
};
|
|
2981
|
+
} else {
|
|
2982
|
+
const messages = [...this.committedMessages];
|
|
2983
|
+
result = {
|
|
2984
|
+
id: "cli_session",
|
|
2985
|
+
status: this.currentStatus,
|
|
2986
|
+
title: this.cliName,
|
|
2987
|
+
messages: messages.map((message, index) => buildChatMessage({
|
|
2988
|
+
...message,
|
|
2989
|
+
id: message.id || `msg_${index}`,
|
|
2990
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
2991
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
2992
|
+
})),
|
|
2993
|
+
activeModal: this.activeModal
|
|
2994
|
+
};
|
|
2905
2995
|
}
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2996
|
+
this.parsedStatusCache = {
|
|
2997
|
+
committedMessagesRef: this.committedMessages,
|
|
2998
|
+
responseBuffer: this.responseBuffer,
|
|
2999
|
+
currentTurnScope: this.currentTurnScope,
|
|
3000
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
3001
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
3002
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3003
|
+
screenText,
|
|
3004
|
+
currentStatus: this.currentStatus,
|
|
3005
|
+
activeModal: this.activeModal,
|
|
3006
|
+
cliName: this.cliName,
|
|
3007
|
+
lastOutputAt: this.lastOutputAt,
|
|
3008
|
+
result
|
|
2918
3009
|
};
|
|
3010
|
+
return result;
|
|
2919
3011
|
}
|
|
2920
3012
|
async invokeScript(scriptName, args) {
|
|
2921
3013
|
const fn = this.cliScripts?.[scriptName];
|
|
@@ -2938,14 +3030,18 @@ var init_provider_cli_adapter = __esm({
|
|
|
2938
3030
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
2939
3031
|
}));
|
|
2940
3032
|
}
|
|
2941
|
-
parseCurrentTranscript(baseMessages, partialResponse, scope) {
|
|
2942
|
-
if (!this.cliScripts?.parseOutput)
|
|
3033
|
+
parseCurrentTranscript(baseMessages, partialResponse, scope, screenTextOverride) {
|
|
3034
|
+
if (!this.cliScripts?.parseOutput) {
|
|
3035
|
+
this.parseErrorMessage = null;
|
|
3036
|
+
return null;
|
|
3037
|
+
}
|
|
2943
3038
|
try {
|
|
3039
|
+
const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
|
|
2944
3040
|
const input = buildCliParseInput({
|
|
2945
3041
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
2946
3042
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2947
3043
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
2948
|
-
terminalScreenText:
|
|
3044
|
+
terminalScreenText: screenText,
|
|
2949
3045
|
baseMessages,
|
|
2950
3046
|
partialResponse,
|
|
2951
3047
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -2967,10 +3063,13 @@ var init_provider_cli_adapter = __esm({
|
|
|
2967
3063
|
lastAssistant.content = trimPromptEchoPrefix(lastAssistant.content, promptForTrim);
|
|
2968
3064
|
}
|
|
2969
3065
|
}
|
|
3066
|
+
this.parseErrorMessage = null;
|
|
2970
3067
|
return parsed;
|
|
2971
3068
|
} catch (e) {
|
|
2972
|
-
|
|
2973
|
-
|
|
3069
|
+
const message = e?.message || String(e);
|
|
3070
|
+
this.parseErrorMessage = message;
|
|
3071
|
+
LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
|
|
3072
|
+
throw e;
|
|
2974
3073
|
}
|
|
2975
3074
|
}
|
|
2976
3075
|
/** Whether this adapter has CLI scripts loaded */
|
|
@@ -3834,6 +3933,96 @@ function getSessionSeenMarker(state, sessionId, providerSessionId) {
|
|
|
3834
3933
|
const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
|
|
3835
3934
|
return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
|
|
3836
3935
|
}
|
|
3936
|
+
function getSessionNotificationDismissal(state, sessionId, providerSessionId) {
|
|
3937
|
+
const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
|
|
3938
|
+
return state.sessionNotificationDismissals?.[providerKey] || state.sessionNotificationDismissals?.[sessionId] || "";
|
|
3939
|
+
}
|
|
3940
|
+
function getSessionNotificationUnreadOverride(state, sessionId, providerSessionId) {
|
|
3941
|
+
const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
|
|
3942
|
+
return state.sessionNotificationUnreadOverrides?.[providerKey] || state.sessionNotificationUnreadOverrides?.[sessionId] || "";
|
|
3943
|
+
}
|
|
3944
|
+
function dismissSessionNotification(state, sessionId, notificationId, providerSessionId) {
|
|
3945
|
+
const dismissalId = String(notificationId || "").trim();
|
|
3946
|
+
if (!dismissalId) return state;
|
|
3947
|
+
const dismissalKeys = Array.from(new Set([
|
|
3948
|
+
sessionId,
|
|
3949
|
+
buildSessionReadStateKey(sessionId, providerSessionId)
|
|
3950
|
+
].filter(Boolean)));
|
|
3951
|
+
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
3952
|
+
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
3953
|
+
for (const key of dismissalKeys) {
|
|
3954
|
+
nextSessionNotificationDismissals[key] = dismissalId;
|
|
3955
|
+
delete nextSessionNotificationUnreadOverrides[key];
|
|
3956
|
+
}
|
|
3957
|
+
return {
|
|
3958
|
+
...state,
|
|
3959
|
+
sessionNotificationDismissals: nextSessionNotificationDismissals,
|
|
3960
|
+
sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
|
|
3961
|
+
};
|
|
3962
|
+
}
|
|
3963
|
+
function markSessionNotificationUnread(state, sessionId, notificationId, providerSessionId) {
|
|
3964
|
+
const unreadId = String(notificationId || "").trim();
|
|
3965
|
+
if (!unreadId) return state;
|
|
3966
|
+
const unreadKeys = Array.from(new Set([
|
|
3967
|
+
sessionId,
|
|
3968
|
+
buildSessionReadStateKey(sessionId, providerSessionId)
|
|
3969
|
+
].filter(Boolean)));
|
|
3970
|
+
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
3971
|
+
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
3972
|
+
for (const key of unreadKeys) {
|
|
3973
|
+
nextSessionNotificationUnreadOverrides[key] = unreadId;
|
|
3974
|
+
delete nextSessionNotificationDismissals[key];
|
|
3975
|
+
}
|
|
3976
|
+
return {
|
|
3977
|
+
...state,
|
|
3978
|
+
sessionNotificationDismissals: nextSessionNotificationDismissals,
|
|
3979
|
+
sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
function getSessionNotificationTargetValue(session) {
|
|
3983
|
+
const providerSessionId = typeof session.providerSessionId === "string" ? session.providerSessionId.trim() : "";
|
|
3984
|
+
return providerSessionId || session.id;
|
|
3985
|
+
}
|
|
3986
|
+
function getSessionCurrentNotificationId(session) {
|
|
3987
|
+
const inboxBucket = session.inboxBucket || "idle";
|
|
3988
|
+
const isNeedsAttention = inboxBucket === "needs_attention" || session.status === "waiting_approval";
|
|
3989
|
+
const isTaskComplete = inboxBucket === "task_complete" && !!session.unread;
|
|
3990
|
+
const type = isNeedsAttention ? "needs_attention" : isTaskComplete ? "task_complete" : "";
|
|
3991
|
+
if (!type) return "";
|
|
3992
|
+
const target = getSessionNotificationTargetValue(session);
|
|
3993
|
+
const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
|
|
3994
|
+
const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
|
|
3995
|
+
return [type, target, lastMessageHash, String(timestamp)].join("|");
|
|
3996
|
+
}
|
|
3997
|
+
function applySessionNotificationOverlay(session, overlay) {
|
|
3998
|
+
const currentNotificationId = getSessionCurrentNotificationId(session);
|
|
3999
|
+
const taskCompleteNotificationId = (() => {
|
|
4000
|
+
const target = getSessionNotificationTargetValue(session);
|
|
4001
|
+
const lastMessageHash = typeof session.lastMessageHash === "string" ? session.lastMessageHash : "";
|
|
4002
|
+
const timestamp = Number(session.lastMessageAt || session.lastUpdated || 0);
|
|
4003
|
+
if (!target || !lastMessageHash || !timestamp) return "";
|
|
4004
|
+
return ["task_complete", target, lastMessageHash, String(timestamp)].join("|");
|
|
4005
|
+
})();
|
|
4006
|
+
const dismissedNotificationId = typeof overlay.dismissedNotificationId === "string" ? overlay.dismissedNotificationId.trim() : "";
|
|
4007
|
+
const unreadNotificationId = typeof overlay.unreadNotificationId === "string" ? overlay.unreadNotificationId.trim() : "";
|
|
4008
|
+
if (unreadNotificationId && (currentNotificationId === unreadNotificationId || taskCompleteNotificationId === unreadNotificationId)) {
|
|
4009
|
+
const forcedInboxBucket = session.inboxBucket === "needs_attention" || session.status === "waiting_approval" ? "needs_attention" : "task_complete";
|
|
4010
|
+
return {
|
|
4011
|
+
unread: true,
|
|
4012
|
+
inboxBucket: forcedInboxBucket
|
|
4013
|
+
};
|
|
4014
|
+
}
|
|
4015
|
+
if (!currentNotificationId || !dismissedNotificationId || currentNotificationId !== dismissedNotificationId) {
|
|
4016
|
+
return {
|
|
4017
|
+
unread: !!session.unread,
|
|
4018
|
+
inboxBucket: session.inboxBucket || "idle"
|
|
4019
|
+
};
|
|
4020
|
+
}
|
|
4021
|
+
return {
|
|
4022
|
+
unread: false,
|
|
4023
|
+
inboxBucket: "idle"
|
|
4024
|
+
};
|
|
4025
|
+
}
|
|
3837
4026
|
function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
|
|
3838
4027
|
const prev = state.sessionReads || {};
|
|
3839
4028
|
const prevMarkers = state.sessionReadMarkers || {};
|
|
@@ -3844,14 +4033,20 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
|
|
|
3844
4033
|
].filter(Boolean)));
|
|
3845
4034
|
const nextSessionReads = { ...prev };
|
|
3846
4035
|
const nextSessionReadMarkers = { ...prevMarkers };
|
|
4036
|
+
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
4037
|
+
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
3847
4038
|
for (const key of readKeys) {
|
|
3848
4039
|
nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
|
|
3849
4040
|
if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
|
|
4041
|
+
delete nextSessionNotificationDismissals[key];
|
|
4042
|
+
delete nextSessionNotificationUnreadOverrides[key];
|
|
3850
4043
|
}
|
|
3851
4044
|
return {
|
|
3852
4045
|
...state,
|
|
3853
4046
|
sessionReads: nextSessionReads,
|
|
3854
|
-
sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
|
|
4047
|
+
sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers,
|
|
4048
|
+
sessionNotificationDismissals: nextSessionNotificationDismissals,
|
|
4049
|
+
sessionNotificationUnreadOverrides: nextSessionNotificationUnreadOverrides
|
|
3855
4050
|
};
|
|
3856
4051
|
}
|
|
3857
4052
|
|
|
@@ -3936,7 +4131,9 @@ var DEFAULT_STATE = {
|
|
|
3936
4131
|
recentActivity: [],
|
|
3937
4132
|
savedProviderSessions: [],
|
|
3938
4133
|
sessionReads: {},
|
|
3939
|
-
sessionReadMarkers: {}
|
|
4134
|
+
sessionReadMarkers: {},
|
|
4135
|
+
sessionNotificationDismissals: {},
|
|
4136
|
+
sessionNotificationUnreadOverrides: {}
|
|
3940
4137
|
};
|
|
3941
4138
|
function isPlainObject2(value) {
|
|
3942
4139
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -3968,11 +4165,19 @@ function normalizeState(raw) {
|
|
|
3968
4165
|
const sessionReadMarkers = Object.fromEntries(
|
|
3969
4166
|
Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
|
|
3970
4167
|
);
|
|
4168
|
+
const sessionNotificationDismissals = Object.fromEntries(
|
|
4169
|
+
Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
|
|
4170
|
+
);
|
|
4171
|
+
const sessionNotificationUnreadOverrides = Object.fromEntries(
|
|
4172
|
+
Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
|
|
4173
|
+
);
|
|
3971
4174
|
return {
|
|
3972
4175
|
recentActivity,
|
|
3973
4176
|
savedProviderSessions,
|
|
3974
4177
|
sessionReads,
|
|
3975
|
-
sessionReadMarkers
|
|
4178
|
+
sessionReadMarkers,
|
|
4179
|
+
sessionNotificationDismissals,
|
|
4180
|
+
sessionNotificationUnreadOverrides
|
|
3976
4181
|
};
|
|
3977
4182
|
}
|
|
3978
4183
|
function loadState() {
|
|
@@ -4376,9 +4581,15 @@ function classifyHotChatSessionsForSubscriptionFlush(sessions, previousHotSessio
|
|
|
4376
4581
|
continue;
|
|
4377
4582
|
}
|
|
4378
4583
|
const status = String(session?.status || "").toLowerCase();
|
|
4584
|
+
const unread = session?.unread === true;
|
|
4585
|
+
const inboxBucket = String(session?.inboxBucket || "").toLowerCase();
|
|
4586
|
+
const runtimeSurfaceKind = String(session?.runtimeSurfaceKind || "").toLowerCase();
|
|
4587
|
+
const runtimeLifecycle = String(session?.runtimeLifecycle || "").toLowerCase();
|
|
4588
|
+
const isLiveRuntime = runtimeSurfaceKind === "live_runtime" || LIVE_RUNTIME_LIFECYCLES.has(runtimeLifecycle);
|
|
4379
4589
|
const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
|
|
4380
4590
|
const recentlyUpdated = lastMessageAt > 0 && now - lastMessageAt <= recentMessageGraceMs;
|
|
4381
|
-
|
|
4591
|
+
const shouldKeepRecentTailHot = recentlyUpdated && (unread || inboxBucket === "task_complete" || inboxBucket === "needs_attention" || isLiveRuntime || activeStatuses.has(status));
|
|
4592
|
+
if (activeStatuses.has(status) || shouldKeepRecentTailHot) {
|
|
4382
4593
|
active.add(sessionId);
|
|
4383
4594
|
}
|
|
4384
4595
|
}
|
|
@@ -7295,7 +7506,6 @@ var ExtensionProviderInstance = class {
|
|
|
7295
7506
|
}
|
|
7296
7507
|
pushEvent(event) {
|
|
7297
7508
|
this.events.push(event);
|
|
7298
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
7299
7509
|
}
|
|
7300
7510
|
applyProviderResponse(data, options) {
|
|
7301
7511
|
if (!data || typeof data !== "object") return;
|
|
@@ -7371,7 +7581,6 @@ var ExtensionProviderInstance = class {
|
|
|
7371
7581
|
key: dedupKey,
|
|
7372
7582
|
message: normalizedMessage
|
|
7373
7583
|
});
|
|
7374
|
-
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
7375
7584
|
if (normalizedContent) {
|
|
7376
7585
|
this.historyWriter.appendNewMessages(
|
|
7377
7586
|
this.type,
|
|
@@ -7906,7 +8115,6 @@ var IdeProviderInstance = class {
|
|
|
7906
8115
|
}
|
|
7907
8116
|
pushEvent(event) {
|
|
7908
8117
|
this.events.push(event);
|
|
7909
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
7910
8118
|
}
|
|
7911
8119
|
applyProviderResponse(data, options) {
|
|
7912
8120
|
if (!data || typeof data !== "object") return;
|
|
@@ -7996,7 +8204,6 @@ var IdeProviderInstance = class {
|
|
|
7996
8204
|
key: dedupKey,
|
|
7997
8205
|
message: normalizedMessage
|
|
7998
8206
|
});
|
|
7999
|
-
if (this.runtimeMessages.length > 50) this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
8000
8207
|
if (normalizedContent) {
|
|
8001
8208
|
this.historyWriter.appendNewMessages(
|
|
8002
8209
|
this.type,
|
|
@@ -9014,53 +9221,8 @@ function assertProviderSupportsDeclaredInput(provider, input) {
|
|
|
9014
9221
|
init_read_chat_contract();
|
|
9015
9222
|
init_logger();
|
|
9016
9223
|
|
|
9017
|
-
// src/logging/debug-config.ts
|
|
9018
|
-
var NORMAL_TRACE_BUFFER_SIZE = 200;
|
|
9019
|
-
var DEV_TRACE_BUFFER_SIZE = 1e3;
|
|
9020
|
-
var DEFAULT_CONFIG2 = {
|
|
9021
|
-
logLevel: "info",
|
|
9022
|
-
collectDebugTrace: false,
|
|
9023
|
-
traceContent: false,
|
|
9024
|
-
traceBufferSize: NORMAL_TRACE_BUFFER_SIZE,
|
|
9025
|
-
traceCategories: []
|
|
9026
|
-
};
|
|
9027
|
-
var currentConfig = { ...DEFAULT_CONFIG2 };
|
|
9028
|
-
function normalizeCategories(categories) {
|
|
9029
|
-
if (!Array.isArray(categories)) return [];
|
|
9030
|
-
return categories.map((category) => String(category || "").trim()).filter(Boolean);
|
|
9031
|
-
}
|
|
9032
|
-
function resolveDebugRuntimeConfig(options = {}) {
|
|
9033
|
-
const dev = options.dev === true;
|
|
9034
|
-
return {
|
|
9035
|
-
logLevel: options.logLevel || (dev ? "debug" : DEFAULT_CONFIG2.logLevel),
|
|
9036
|
-
collectDebugTrace: typeof options.trace === "boolean" ? options.trace : dev,
|
|
9037
|
-
traceContent: options.traceContent === true,
|
|
9038
|
-
traceBufferSize: Number.isFinite(options.traceBufferSize) ? Math.max(10, Math.floor(options.traceBufferSize)) : dev ? DEV_TRACE_BUFFER_SIZE : DEFAULT_CONFIG2.traceBufferSize,
|
|
9039
|
-
traceCategories: normalizeCategories(options.traceCategories)
|
|
9040
|
-
};
|
|
9041
|
-
}
|
|
9042
|
-
function setDebugRuntimeConfig(config) {
|
|
9043
|
-
currentConfig = {
|
|
9044
|
-
...config,
|
|
9045
|
-
traceCategories: normalizeCategories(config.traceCategories),
|
|
9046
|
-
traceBufferSize: Math.max(10, Math.floor(config.traceBufferSize || DEFAULT_CONFIG2.traceBufferSize))
|
|
9047
|
-
};
|
|
9048
|
-
}
|
|
9049
|
-
function getDebugRuntimeConfig() {
|
|
9050
|
-
return { ...currentConfig, traceCategories: [...currentConfig.traceCategories] };
|
|
9051
|
-
}
|
|
9052
|
-
function resetDebugRuntimeConfig() {
|
|
9053
|
-
currentConfig = { ...DEFAULT_CONFIG2 };
|
|
9054
|
-
}
|
|
9055
|
-
function shouldCollectTraceCategory(category) {
|
|
9056
|
-
const config = currentConfig;
|
|
9057
|
-
if (!config.collectDebugTrace) return false;
|
|
9058
|
-
if (!category) return true;
|
|
9059
|
-
if (config.traceCategories.length === 0) return true;
|
|
9060
|
-
return config.traceCategories.includes(category);
|
|
9061
|
-
}
|
|
9062
|
-
|
|
9063
9224
|
// src/logging/debug-trace.ts
|
|
9225
|
+
init_debug_config();
|
|
9064
9226
|
function summarizeString(value) {
|
|
9065
9227
|
return `[${value.length} chars]`;
|
|
9066
9228
|
}
|
|
@@ -9560,7 +9722,14 @@ async function handleReadChat(h, args) {
|
|
|
9560
9722
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
9561
9723
|
if (adapter) {
|
|
9562
9724
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
9563
|
-
|
|
9725
|
+
let parsedStatus = null;
|
|
9726
|
+
if (typeof adapter.getScriptParsedStatus === "function") {
|
|
9727
|
+
try {
|
|
9728
|
+
parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
9729
|
+
} catch (error) {
|
|
9730
|
+
return { success: false, error: error?.message || String(error) };
|
|
9731
|
+
}
|
|
9732
|
+
}
|
|
9564
9733
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
9565
9734
|
const status = parsedRecord || adapter.getStatus();
|
|
9566
9735
|
const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
|
|
@@ -11894,6 +12063,8 @@ var CliProviderInstance = class {
|
|
|
11894
12063
|
runtimeMessages = [];
|
|
11895
12064
|
instanceId;
|
|
11896
12065
|
suppressIdleHistoryReplay = false;
|
|
12066
|
+
errorMessage = void 0;
|
|
12067
|
+
errorReason = void 0;
|
|
11897
12068
|
presentationMode;
|
|
11898
12069
|
providerSessionId;
|
|
11899
12070
|
launchMode;
|
|
@@ -11960,6 +12131,7 @@ var CliProviderInstance = class {
|
|
|
11960
12131
|
}
|
|
11961
12132
|
async onTick() {
|
|
11962
12133
|
if (this.providerSessionId) return;
|
|
12134
|
+
if (this.type === "hermes-cli" && this.launchMode === "new") return;
|
|
11963
12135
|
let probedSessionId = null;
|
|
11964
12136
|
const probeConfig = this.provider.sessionProbe;
|
|
11965
12137
|
if (probeConfig) {
|
|
@@ -12017,9 +12189,24 @@ var CliProviderInstance = class {
|
|
|
12017
12189
|
}
|
|
12018
12190
|
getState() {
|
|
12019
12191
|
const adapterStatus = this.adapter.getStatus();
|
|
12020
|
-
|
|
12192
|
+
let parsedStatus = null;
|
|
12193
|
+
let parseErrorMessage;
|
|
12194
|
+
if (typeof this.adapter.getScriptParsedStatus === "function") {
|
|
12195
|
+
try {
|
|
12196
|
+
parsedStatus = this.adapter.getScriptParsedStatus() || null;
|
|
12197
|
+
this.errorMessage = void 0;
|
|
12198
|
+
this.errorReason = void 0;
|
|
12199
|
+
} catch (error) {
|
|
12200
|
+
parseErrorMessage = error?.message || String(error);
|
|
12201
|
+
this.errorMessage = parseErrorMessage;
|
|
12202
|
+
this.errorReason = "parse_error";
|
|
12203
|
+
}
|
|
12204
|
+
} else {
|
|
12205
|
+
this.errorMessage = void 0;
|
|
12206
|
+
this.errorReason = void 0;
|
|
12207
|
+
}
|
|
12021
12208
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
12022
|
-
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
12209
|
+
const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
|
|
12023
12210
|
const parsedProviderSessionId = normalizeProviderSessionId(
|
|
12024
12211
|
this.type,
|
|
12025
12212
|
typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
|
|
@@ -12029,7 +12216,7 @@ var CliProviderInstance = class {
|
|
|
12029
12216
|
}
|
|
12030
12217
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
12031
12218
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
12032
|
-
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
12219
|
+
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : parseErrorMessage ? normalizeChatMessages(Array.isArray(adapterStatus.messages) ? adapterStatus.messages : []) : [];
|
|
12033
12220
|
const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
|
|
12034
12221
|
if (historyMessageCount !== null) {
|
|
12035
12222
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
@@ -12069,7 +12256,7 @@ var CliProviderInstance = class {
|
|
|
12069
12256
|
activeChat: {
|
|
12070
12257
|
id: `${this.type}_${this.workingDir}`,
|
|
12071
12258
|
title: parsedStatus?.title || dirName,
|
|
12072
|
-
status: autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
|
|
12259
|
+
status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
|
|
12073
12260
|
messages: mergedMessages,
|
|
12074
12261
|
activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
12075
12262
|
inputContent: ""
|
|
@@ -12095,7 +12282,9 @@ var CliProviderInstance = class {
|
|
|
12095
12282
|
resume: this.provider.resume,
|
|
12096
12283
|
controlValues: surface.controlValues,
|
|
12097
12284
|
providerControls: this.provider.controls,
|
|
12098
|
-
summaryMetadata: surface.summaryMetadata
|
|
12285
|
+
summaryMetadata: surface.summaryMetadata,
|
|
12286
|
+
errorMessage: this.errorMessage,
|
|
12287
|
+
errorReason: this.errorReason
|
|
12099
12288
|
};
|
|
12100
12289
|
}
|
|
12101
12290
|
setPresentationMode(mode) {
|
|
@@ -12282,7 +12471,6 @@ var CliProviderInstance = class {
|
|
|
12282
12471
|
}
|
|
12283
12472
|
pushEvent(event) {
|
|
12284
12473
|
this.events.push(event);
|
|
12285
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
12286
12474
|
}
|
|
12287
12475
|
flushEvents() {
|
|
12288
12476
|
const events = [...this.events];
|
|
@@ -12464,9 +12652,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
12464
12652
|
key: dedupKey,
|
|
12465
12653
|
message: normalizedMessage
|
|
12466
12654
|
});
|
|
12467
|
-
if (this.runtimeMessages.length > 50) {
|
|
12468
|
-
this.runtimeMessages = this.runtimeMessages.slice(-50);
|
|
12469
|
-
}
|
|
12470
12655
|
if (normalizedContent) {
|
|
12471
12656
|
this.historyWriter.appendNewMessages(
|
|
12472
12657
|
this.type,
|
|
@@ -12720,8 +12905,8 @@ var AcpProviderInstance = class {
|
|
|
12720
12905
|
}
|
|
12721
12906
|
getState() {
|
|
12722
12907
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
12723
|
-
const recentMessages = normalizeChatMessages(this.messages.
|
|
12724
|
-
const content =
|
|
12908
|
+
const recentMessages = normalizeChatMessages(this.messages.map((m) => {
|
|
12909
|
+
const content = m.content;
|
|
12725
12910
|
return buildChatMessage({
|
|
12726
12911
|
...m,
|
|
12727
12912
|
content
|
|
@@ -13514,18 +13699,6 @@ var AcpProviderInstance = class {
|
|
|
13514
13699
|
}
|
|
13515
13700
|
}
|
|
13516
13701
|
// ─── Rich Content Helpers ────────────────────────────
|
|
13517
|
-
/** Truncate content for transport (text: 2000 chars, images preserved) */
|
|
13518
|
-
truncateContent(content) {
|
|
13519
|
-
if (typeof content === "string") {
|
|
13520
|
-
return content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
|
|
13521
|
-
}
|
|
13522
|
-
return content.map((b) => {
|
|
13523
|
-
if (b.type === "text" && b.text.length > 2e3) {
|
|
13524
|
-
return { ...b, text: b.text.slice(0, 2e3) + "\n... (truncated)" };
|
|
13525
|
-
}
|
|
13526
|
-
return b;
|
|
13527
|
-
});
|
|
13528
|
-
}
|
|
13529
13702
|
/** Build ContentBlock[] from current partial state */
|
|
13530
13703
|
buildPartialBlocks() {
|
|
13531
13704
|
const blocks = [];
|
|
@@ -13679,7 +13852,6 @@ ${rawInput}` : rawInput;
|
|
|
13679
13852
|
}
|
|
13680
13853
|
pushEvent(event) {
|
|
13681
13854
|
this.events.push(event);
|
|
13682
|
-
if (this.events.length > 50) this.events = this.events.slice(-50);
|
|
13683
13855
|
}
|
|
13684
13856
|
appendSystemMessage(content, timestamp = Date.now()) {
|
|
13685
13857
|
const normalizedContent = String(content || "").trim();
|
|
@@ -16350,7 +16522,9 @@ var SKIP_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
16350
16522
|
"heartbeat",
|
|
16351
16523
|
"status_report",
|
|
16352
16524
|
"read_chat",
|
|
16353
|
-
"mark_session_seen"
|
|
16525
|
+
"mark_session_seen",
|
|
16526
|
+
"delete_notification",
|
|
16527
|
+
"mark_notification_unread"
|
|
16354
16528
|
]);
|
|
16355
16529
|
function shouldLogCommand(cmd) {
|
|
16356
16530
|
return !SKIP_COMMANDS.has(cmd);
|
|
@@ -16627,9 +16801,24 @@ function buildStatusSnapshot(options) {
|
|
|
16627
16801
|
completionMarker,
|
|
16628
16802
|
seenCompletionMarker
|
|
16629
16803
|
);
|
|
16804
|
+
const { unread: overlayUnread, inboxBucket: overlayInboxBucket } = applySessionNotificationOverlay({
|
|
16805
|
+
id: sourceSession.id,
|
|
16806
|
+
providerSessionId: sourceSession.providerSessionId,
|
|
16807
|
+
status: sourceSession.status,
|
|
16808
|
+
unread,
|
|
16809
|
+
inboxBucket,
|
|
16810
|
+
lastMessageHash: sourceSession.lastMessageHash,
|
|
16811
|
+
lastMessageAt: sourceSession.lastMessageAt,
|
|
16812
|
+
lastUpdated: sourceSession.lastUpdated
|
|
16813
|
+
}, {
|
|
16814
|
+
dismissedNotificationId: getSessionNotificationDismissal(state, sourceSession.id, sourceSession.providerSessionId),
|
|
16815
|
+
unreadNotificationId: getSessionNotificationUnreadOverride(state, sourceSession.id, sourceSession.providerSessionId)
|
|
16816
|
+
});
|
|
16630
16817
|
session.lastSeenAt = lastSeenAt;
|
|
16631
|
-
session.unread =
|
|
16632
|
-
session.inboxBucket =
|
|
16818
|
+
session.unread = overlayUnread;
|
|
16819
|
+
session.inboxBucket = overlayInboxBucket;
|
|
16820
|
+
session.completionMarker = completionMarker;
|
|
16821
|
+
session.seenCompletionMarker = seenCompletionMarker;
|
|
16633
16822
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== "idle" || session.providerType.includes("codex"))) {
|
|
16634
16823
|
const recentReadSnapshot = {
|
|
16635
16824
|
sessionId: session.id,
|
|
@@ -17446,6 +17635,62 @@ var DaemonCommandRouter = class {
|
|
|
17446
17635
|
completionMarker
|
|
17447
17636
|
};
|
|
17448
17637
|
}
|
|
17638
|
+
case "delete_notification": {
|
|
17639
|
+
const sessionId = args?.sessionId;
|
|
17640
|
+
const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
|
|
17641
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
17642
|
+
return { success: false, error: "sessionId is required" };
|
|
17643
|
+
}
|
|
17644
|
+
if (!notificationId) {
|
|
17645
|
+
return { success: false, error: "notificationId is required" };
|
|
17646
|
+
}
|
|
17647
|
+
const sessionEntries = buildSessionEntries(
|
|
17648
|
+
this.deps.instanceManager.collectAllStates(),
|
|
17649
|
+
this.deps.cdpManagers
|
|
17650
|
+
);
|
|
17651
|
+
const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
|
|
17652
|
+
const next = dismissSessionNotification(
|
|
17653
|
+
loadState(),
|
|
17654
|
+
sessionId,
|
|
17655
|
+
notificationId,
|
|
17656
|
+
targetSession?.providerSessionId
|
|
17657
|
+
);
|
|
17658
|
+
saveState(next);
|
|
17659
|
+
this.deps.onStatusChange?.();
|
|
17660
|
+
return {
|
|
17661
|
+
success: true,
|
|
17662
|
+
sessionId,
|
|
17663
|
+
notificationId
|
|
17664
|
+
};
|
|
17665
|
+
}
|
|
17666
|
+
case "mark_notification_unread": {
|
|
17667
|
+
const sessionId = args?.sessionId;
|
|
17668
|
+
const notificationId = typeof args?.notificationId === "string" ? args.notificationId.trim() : "";
|
|
17669
|
+
if (!sessionId || typeof sessionId !== "string") {
|
|
17670
|
+
return { success: false, error: "sessionId is required" };
|
|
17671
|
+
}
|
|
17672
|
+
if (!notificationId) {
|
|
17673
|
+
return { success: false, error: "notificationId is required" };
|
|
17674
|
+
}
|
|
17675
|
+
const sessionEntries = buildSessionEntries(
|
|
17676
|
+
this.deps.instanceManager.collectAllStates(),
|
|
17677
|
+
this.deps.cdpManagers
|
|
17678
|
+
);
|
|
17679
|
+
const targetSession = sessionEntries.find((entry) => entry.id === sessionId);
|
|
17680
|
+
const next = markSessionNotificationUnread(
|
|
17681
|
+
loadState(),
|
|
17682
|
+
sessionId,
|
|
17683
|
+
notificationId,
|
|
17684
|
+
targetSession?.providerSessionId
|
|
17685
|
+
);
|
|
17686
|
+
saveState(next);
|
|
17687
|
+
this.deps.onStatusChange?.();
|
|
17688
|
+
return {
|
|
17689
|
+
success: true,
|
|
17690
|
+
sessionId,
|
|
17691
|
+
notificationId
|
|
17692
|
+
};
|
|
17693
|
+
}
|
|
17449
17694
|
// ─── Daemon Self-Upgrade ───
|
|
17450
17695
|
case "daemon_upgrade": {
|
|
17451
17696
|
LOG.info("Upgrade", "Remote upgrade requested from dashboard");
|
|
@@ -17824,6 +18069,7 @@ var DaemonStatusReporter = class {
|
|
|
17824
18069
|
|
|
17825
18070
|
// src/index.ts
|
|
17826
18071
|
init_logger();
|
|
18072
|
+
init_debug_config();
|
|
17827
18073
|
|
|
17828
18074
|
// src/ipc-protocol.ts
|
|
17829
18075
|
var DEFAULT_DAEMON_PORT = 19222;
|