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