@adhdev/daemon-standalone 0.8.74 → 0.8.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +630 -92
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{index-WF9fZ0Od.js → index-99DIPRiD.js} +19 -19
- package/public/assets/index-Bya1aCQ_.css +1 -0
- package/public/assets/{terminal-fZXg9GuG.js → terminal-2SYILvaH.js} +39 -17
- package/public/index.html +2 -2
- package/public/assets/index-B57vauO6.css +0 -1
package/dist/index.js
CHANGED
|
@@ -31510,6 +31510,7 @@ ${data.message || ""}`.trim();
|
|
|
31510
31510
|
resolveChatMessageKind: () => resolveChatMessageKind,
|
|
31511
31511
|
resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
|
|
31512
31512
|
resolveSessionHostAppName: () => resolveSessionHostAppName2,
|
|
31513
|
+
runAsyncBatch: () => runAsyncBatch2,
|
|
31513
31514
|
saveConfig: () => saveConfig,
|
|
31514
31515
|
saveState: () => saveState,
|
|
31515
31516
|
setDebugRuntimeConfig: () => setDebugRuntimeConfig,
|
|
@@ -32268,6 +32269,32 @@ ${data.message || ""}`.trim();
|
|
|
32268
32269
|
var import_ws2 = __toESM2(require("ws"));
|
|
32269
32270
|
var http = __toESM2(require("http"));
|
|
32270
32271
|
init_logger();
|
|
32272
|
+
function normalizeTitle(value) {
|
|
32273
|
+
return String(value || "").trim().replace(/\s+/g, " ").toLowerCase();
|
|
32274
|
+
}
|
|
32275
|
+
function titlesMatch(lhs, rhs) {
|
|
32276
|
+
const a = normalizeTitle(lhs);
|
|
32277
|
+
const b2 = normalizeTitle(rhs);
|
|
32278
|
+
if (!a || !b2) return false;
|
|
32279
|
+
return a === b2 || a.includes(b2) || b2.includes(a);
|
|
32280
|
+
}
|
|
32281
|
+
function resolveCdpPageTarget(params) {
|
|
32282
|
+
const { pages, pinnedTargetId, previousPageTitle } = params;
|
|
32283
|
+
if (pages.length === 0) return { target: null, retargeted: false };
|
|
32284
|
+
if (!pinnedTargetId) {
|
|
32285
|
+
return { target: pages[0] || null, retargeted: false };
|
|
32286
|
+
}
|
|
32287
|
+
const exact = pages.find((page) => page.id === pinnedTargetId);
|
|
32288
|
+
if (exact) return { target: exact, retargeted: false };
|
|
32289
|
+
const titleMatchesList = pages.filter((page) => titlesMatch(page.title, previousPageTitle));
|
|
32290
|
+
if (titleMatchesList.length === 1) {
|
|
32291
|
+
return { target: titleMatchesList[0], retargeted: true };
|
|
32292
|
+
}
|
|
32293
|
+
if (pages.length === 1) {
|
|
32294
|
+
return { target: pages[0], retargeted: true };
|
|
32295
|
+
}
|
|
32296
|
+
return { target: null, retargeted: false };
|
|
32297
|
+
}
|
|
32271
32298
|
var DaemonCdpManager = class {
|
|
32272
32299
|
ws = null;
|
|
32273
32300
|
browserWs = null;
|
|
@@ -32428,18 +32455,28 @@ ${data.message || ""}`.trim();
|
|
|
32428
32455
|
resolve11(targets.find((t) => t.webSocketDebuggerUrl) || null);
|
|
32429
32456
|
return;
|
|
32430
32457
|
}
|
|
32431
|
-
const
|
|
32432
|
-
const
|
|
32458
|
+
const titleFilteredPages = pages.filter((t) => !this.isNonMainTitle(t.title || ""));
|
|
32459
|
+
const mainPages = titleFilteredPages.filter((t) => this.isMainPageUrl(t.url));
|
|
32460
|
+
const list = mainPages.length > 0 ? mainPages : titleFilteredPages.length > 0 ? titleFilteredPages : pages;
|
|
32433
32461
|
this.log(`[CDP] pages(${list.length}): ${list.map((t) => `"${t.title}"`).join(", ")}`);
|
|
32434
|
-
|
|
32435
|
-
|
|
32436
|
-
|
|
32437
|
-
|
|
32438
|
-
|
|
32439
|
-
|
|
32440
|
-
|
|
32441
|
-
|
|
32462
|
+
const previousTargetId = this._targetId;
|
|
32463
|
+
const selected = resolveCdpPageTarget({
|
|
32464
|
+
pages: list,
|
|
32465
|
+
pinnedTargetId: previousTargetId,
|
|
32466
|
+
previousPageTitle: this._pageTitle
|
|
32467
|
+
});
|
|
32468
|
+
if (selected.target) {
|
|
32469
|
+
if (selected.retargeted && previousTargetId && previousTargetId !== selected.target.id) {
|
|
32470
|
+
this.log(`[CDP] Target ${previousTargetId} rekeyed to ${selected.target.id}`);
|
|
32471
|
+
this._targetId = selected.target.id;
|
|
32442
32472
|
}
|
|
32473
|
+
this._pageTitle = selected.target.title || "";
|
|
32474
|
+
resolve11(selected.target);
|
|
32475
|
+
return;
|
|
32476
|
+
}
|
|
32477
|
+
if (previousTargetId) {
|
|
32478
|
+
this.log(`[CDP] Target ${previousTargetId} not found in page list`);
|
|
32479
|
+
resolve11(null);
|
|
32443
32480
|
return;
|
|
32444
32481
|
}
|
|
32445
32482
|
this._pageTitle = list[0]?.title || "";
|
|
@@ -33867,7 +33904,17 @@ ${cleanBody}`;
|
|
|
33867
33904
|
init_chat_message_normalization();
|
|
33868
33905
|
var HISTORY_DIR = path7.join(os52.homedir(), ".adhdev", "history");
|
|
33869
33906
|
var RETAIN_DAYS = 30;
|
|
33907
|
+
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
33908
|
+
var SAVED_HISTORY_INDEX_FILE = ".saved-history-index.json";
|
|
33909
|
+
var SAVED_HISTORY_INDEX_LOCK_SUFFIX = ".lock";
|
|
33910
|
+
var SAVED_HISTORY_INDEX_LOCK_WAIT_MS = 1500;
|
|
33911
|
+
var SAVED_HISTORY_INDEX_LOCK_STALE_MS = 15e3;
|
|
33912
|
+
var SAVED_HISTORY_INDEX_LOCK_POLL_MS = 25;
|
|
33913
|
+
var SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES = 16 * 1024 * 1024;
|
|
33870
33914
|
var savedHistorySessionCache = /* @__PURE__ */ new Map();
|
|
33915
|
+
var savedHistoryFileSummaryCache = /* @__PURE__ */ new Map();
|
|
33916
|
+
var savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
|
|
33917
|
+
var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
33871
33918
|
var CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
|
|
33872
33919
|
function normalizeHistoryComparable(text) {
|
|
33873
33920
|
return String(text || "").replace(/\s+/g, " ").trim();
|
|
@@ -33925,6 +33972,68 @@ ${cleanBody}`;
|
|
|
33925
33972
|
content
|
|
33926
33973
|
};
|
|
33927
33974
|
}
|
|
33975
|
+
function sortSavedHistorySessionSummaries(summaries) {
|
|
33976
|
+
return summaries.slice().sort((a, b2) => b2.lastMessageAt - a.lastMessageAt);
|
|
33977
|
+
}
|
|
33978
|
+
function buildSavedHistorySessionSummaryMapFromEntries(entries) {
|
|
33979
|
+
const summaries = /* @__PURE__ */ new Map();
|
|
33980
|
+
for (const entry of Array.from(entries.values())) {
|
|
33981
|
+
const fileSummary = entry.summary;
|
|
33982
|
+
if (!fileSummary || fileSummary.messageCount <= 0 || !fileSummary.lastMessageAt) continue;
|
|
33983
|
+
const existing = summaries.get(fileSummary.historySessionId);
|
|
33984
|
+
if (!existing) {
|
|
33985
|
+
summaries.set(fileSummary.historySessionId, {
|
|
33986
|
+
historySessionId: fileSummary.historySessionId,
|
|
33987
|
+
sessionTitle: fileSummary.sessionTitle,
|
|
33988
|
+
messageCount: fileSummary.messageCount,
|
|
33989
|
+
firstMessageAt: fileSummary.firstMessageAt,
|
|
33990
|
+
lastMessageAt: fileSummary.lastMessageAt,
|
|
33991
|
+
preview: fileSummary.preview,
|
|
33992
|
+
workspace: fileSummary.workspace
|
|
33993
|
+
});
|
|
33994
|
+
continue;
|
|
33995
|
+
}
|
|
33996
|
+
existing.messageCount += fileSummary.messageCount;
|
|
33997
|
+
if (!existing.firstMessageAt || fileSummary.firstMessageAt < existing.firstMessageAt) {
|
|
33998
|
+
existing.firstMessageAt = fileSummary.firstMessageAt;
|
|
33999
|
+
}
|
|
34000
|
+
if (fileSummary.lastMessageAt >= existing.lastMessageAt) {
|
|
34001
|
+
existing.lastMessageAt = fileSummary.lastMessageAt;
|
|
34002
|
+
if (fileSummary.sessionTitle) existing.sessionTitle = fileSummary.sessionTitle;
|
|
34003
|
+
if (fileSummary.preview) existing.preview = fileSummary.preview;
|
|
34004
|
+
}
|
|
34005
|
+
if (!existing.workspace && fileSummary.workspace) {
|
|
34006
|
+
existing.workspace = fileSummary.workspace;
|
|
34007
|
+
}
|
|
34008
|
+
}
|
|
34009
|
+
return Object.fromEntries(sortSavedHistorySessionSummaries(Array.from(summaries.values())).map((summary) => [summary.historySessionId, summary]));
|
|
34010
|
+
}
|
|
34011
|
+
function readPersistedSavedHistorySessionSummaries(dir) {
|
|
34012
|
+
try {
|
|
34013
|
+
const filePath = getSavedHistoryIndexFilePath(dir);
|
|
34014
|
+
if (!fs32.existsSync(filePath)) return null;
|
|
34015
|
+
const raw = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
|
|
34016
|
+
if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.sessions || typeof raw.sessions !== "object") {
|
|
34017
|
+
return null;
|
|
34018
|
+
}
|
|
34019
|
+
return sortSavedHistorySessionSummaries(
|
|
34020
|
+
Object.values(raw.sessions).filter((summary) => !!summary && typeof summary.historySessionId === "string" && summary.messageCount > 0 && summary.lastMessageAt > 0).map((summary) => ({
|
|
34021
|
+
historySessionId: summary.historySessionId,
|
|
34022
|
+
sessionTitle: summary.sessionTitle,
|
|
34023
|
+
messageCount: summary.messageCount,
|
|
34024
|
+
firstMessageAt: summary.firstMessageAt,
|
|
34025
|
+
lastMessageAt: summary.lastMessageAt,
|
|
34026
|
+
preview: summary.preview,
|
|
34027
|
+
workspace: summary.workspace
|
|
34028
|
+
}))
|
|
34029
|
+
);
|
|
34030
|
+
} catch {
|
|
34031
|
+
return null;
|
|
34032
|
+
}
|
|
34033
|
+
}
|
|
34034
|
+
function shouldScheduleSavedHistoryRollup(totalBytes) {
|
|
34035
|
+
return Number.isFinite(totalBytes) && totalBytes >= SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES;
|
|
34036
|
+
}
|
|
33928
34037
|
function sanitizeHistoryFileSegment(value) {
|
|
33929
34038
|
return String(value || "").replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
33930
34039
|
}
|
|
@@ -33938,71 +34047,386 @@ ${cleanBody}`;
|
|
|
33938
34047
|
return true;
|
|
33939
34048
|
}).sort().reverse();
|
|
33940
34049
|
}
|
|
33941
|
-
function
|
|
33942
|
-
|
|
34050
|
+
function normalizeSavedHistorySessionId(agentType, historySessionId) {
|
|
34051
|
+
const normalizedId = String(historySessionId || "").trim();
|
|
34052
|
+
if (!normalizedId) return "";
|
|
34053
|
+
const strictProviderId = normalizeProviderSessionId(agentType, normalizedId);
|
|
34054
|
+
if (strictProviderId) return strictProviderId;
|
|
34055
|
+
return agentType === "hermes-cli" ? "" : normalizedId;
|
|
34056
|
+
}
|
|
34057
|
+
function extractSavedHistorySessionIdFromFile(agentType, file2) {
|
|
34058
|
+
const match = file2.match(/^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/);
|
|
34059
|
+
return normalizeSavedHistorySessionId(agentType, match?.[1] || "");
|
|
34060
|
+
}
|
|
34061
|
+
function buildSavedHistoryFileSignatureMap(dir, files) {
|
|
34062
|
+
return new Map(files.map((file2) => {
|
|
33943
34063
|
try {
|
|
33944
34064
|
const stat4 = fs32.statSync(path7.join(dir, file2));
|
|
33945
|
-
return `${file2}:${stat4.size}:${Math.trunc(stat4.mtimeMs)}
|
|
34065
|
+
return [file2, `${file2}:${stat4.size}:${Math.trunc(stat4.mtimeMs)}`];
|
|
33946
34066
|
} catch {
|
|
33947
|
-
return `${file2}:missing
|
|
33948
|
-
}
|
|
33949
|
-
})
|
|
33950
|
-
}
|
|
33951
|
-
function
|
|
33952
|
-
|
|
33953
|
-
|
|
33954
|
-
|
|
33955
|
-
|
|
33956
|
-
|
|
33957
|
-
|
|
33958
|
-
|
|
33959
|
-
|
|
33960
|
-
|
|
33961
|
-
|
|
33962
|
-
|
|
33963
|
-
|
|
33964
|
-
|
|
33965
|
-
|
|
33966
|
-
|
|
33967
|
-
|
|
33968
|
-
|
|
33969
|
-
|
|
33970
|
-
|
|
33971
|
-
|
|
33972
|
-
|
|
33973
|
-
|
|
33974
|
-
|
|
33975
|
-
|
|
34067
|
+
return [file2, `${file2}:missing`];
|
|
34068
|
+
}
|
|
34069
|
+
}));
|
|
34070
|
+
}
|
|
34071
|
+
function buildSavedHistoryCacheSignature(files, fileSignatures) {
|
|
34072
|
+
return files.map((file2) => fileSignatures.get(file2) || `${file2}:missing`).join("|");
|
|
34073
|
+
}
|
|
34074
|
+
function getSavedHistoryIndexFilePath(dir) {
|
|
34075
|
+
return path7.join(dir, SAVED_HISTORY_INDEX_FILE);
|
|
34076
|
+
}
|
|
34077
|
+
function getSavedHistoryIndexLockPath(dir) {
|
|
34078
|
+
return `${getSavedHistoryIndexFilePath(dir)}${SAVED_HISTORY_INDEX_LOCK_SUFFIX}`;
|
|
34079
|
+
}
|
|
34080
|
+
function sleepBlocking(ms2) {
|
|
34081
|
+
if (ms2 <= 0) return;
|
|
34082
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms2);
|
|
34083
|
+
}
|
|
34084
|
+
function loadPersistedSavedHistoryIndexFromFile(dir) {
|
|
34085
|
+
try {
|
|
34086
|
+
const filePath = getSavedHistoryIndexFilePath(dir);
|
|
34087
|
+
if (!fs32.existsSync(filePath)) return /* @__PURE__ */ new Map();
|
|
34088
|
+
const raw = JSON.parse(fs32.readFileSync(filePath, "utf-8"));
|
|
34089
|
+
if (!raw || raw.version !== SAVED_HISTORY_INDEX_VERSION || !raw.files || typeof raw.files !== "object") {
|
|
34090
|
+
return /* @__PURE__ */ new Map();
|
|
34091
|
+
}
|
|
34092
|
+
return new Map(
|
|
34093
|
+
Object.entries(raw.files).filter(([file2, entry]) => !!file2 && !!entry && typeof entry.signature === "string").map(([file2, entry]) => [file2, {
|
|
34094
|
+
signature: entry.signature,
|
|
34095
|
+
summary: entry.summary || null
|
|
34096
|
+
}])
|
|
34097
|
+
);
|
|
34098
|
+
} catch {
|
|
34099
|
+
return /* @__PURE__ */ new Map();
|
|
34100
|
+
}
|
|
34101
|
+
}
|
|
34102
|
+
function writePersistedSavedHistoryIndexFile(dir, entries) {
|
|
34103
|
+
const filePath = getSavedHistoryIndexFilePath(dir);
|
|
34104
|
+
const tempPath = `${filePath}.tmp`;
|
|
34105
|
+
const payload = {
|
|
34106
|
+
version: SAVED_HISTORY_INDEX_VERSION,
|
|
34107
|
+
files: Object.fromEntries(entries.entries()),
|
|
34108
|
+
sessions: buildSavedHistorySessionSummaryMapFromEntries(entries)
|
|
34109
|
+
};
|
|
34110
|
+
fs32.writeFileSync(tempPath, JSON.stringify(payload), "utf-8");
|
|
34111
|
+
fs32.renameSync(tempPath, filePath);
|
|
34112
|
+
}
|
|
34113
|
+
function acquireSavedHistoryIndexLock(dir) {
|
|
34114
|
+
const lockPath = getSavedHistoryIndexLockPath(dir);
|
|
34115
|
+
const deadline = Date.now() + SAVED_HISTORY_INDEX_LOCK_WAIT_MS;
|
|
34116
|
+
while (Date.now() <= deadline) {
|
|
34117
|
+
try {
|
|
34118
|
+
fs32.mkdirSync(lockPath);
|
|
34119
|
+
return () => {
|
|
33976
34120
|
try {
|
|
33977
|
-
|
|
34121
|
+
fs32.rmSync(lockPath, { recursive: true, force: true });
|
|
33978
34122
|
} catch {
|
|
33979
|
-
parsed = null;
|
|
33980
34123
|
}
|
|
33981
|
-
|
|
33982
|
-
|
|
33983
|
-
|
|
34124
|
+
};
|
|
34125
|
+
} catch (error48) {
|
|
34126
|
+
if (error48?.code !== "EEXIST") return null;
|
|
34127
|
+
try {
|
|
34128
|
+
const stat4 = fs32.statSync(lockPath);
|
|
34129
|
+
if (Date.now() - stat4.mtimeMs > SAVED_HISTORY_INDEX_LOCK_STALE_MS) {
|
|
34130
|
+
fs32.rmSync(lockPath, { recursive: true, force: true });
|
|
33984
34131
|
continue;
|
|
33985
34132
|
}
|
|
33986
|
-
|
|
33987
|
-
|
|
33988
|
-
|
|
33989
|
-
|
|
33990
|
-
|
|
33991
|
-
}
|
|
33992
|
-
}
|
|
33993
|
-
if (messageCount === 0 || !lastMessageAt) continue;
|
|
33994
|
-
summaries.push({
|
|
33995
|
-
historySessionId,
|
|
33996
|
-
sessionTitle: sessionTitle || void 0,
|
|
33997
|
-
messageCount,
|
|
33998
|
-
firstMessageAt,
|
|
33999
|
-
lastMessageAt,
|
|
34000
|
-
preview: preview || void 0,
|
|
34001
|
-
workspace: workspace || void 0
|
|
34002
|
-
});
|
|
34133
|
+
} catch {
|
|
34134
|
+
continue;
|
|
34135
|
+
}
|
|
34136
|
+
sleepBlocking(SAVED_HISTORY_INDEX_LOCK_POLL_MS);
|
|
34137
|
+
}
|
|
34003
34138
|
}
|
|
34004
|
-
|
|
34005
|
-
|
|
34139
|
+
return null;
|
|
34140
|
+
}
|
|
34141
|
+
function withLockedPersistedSavedHistoryIndex(dir, callback) {
|
|
34142
|
+
const release2 = acquireSavedHistoryIndexLock(dir);
|
|
34143
|
+
if (!release2) return null;
|
|
34144
|
+
try {
|
|
34145
|
+
const entries = loadPersistedSavedHistoryIndexFromFile(dir);
|
|
34146
|
+
const result = callback(entries);
|
|
34147
|
+
writePersistedSavedHistoryIndexFile(dir, entries);
|
|
34148
|
+
return result;
|
|
34149
|
+
} catch {
|
|
34150
|
+
return null;
|
|
34151
|
+
} finally {
|
|
34152
|
+
release2();
|
|
34153
|
+
}
|
|
34154
|
+
}
|
|
34155
|
+
function loadPersistedSavedHistoryIndex(dir) {
|
|
34156
|
+
return loadPersistedSavedHistoryIndexFromFile(dir);
|
|
34157
|
+
}
|
|
34158
|
+
function savePersistedSavedHistoryIndex(dir, entries) {
|
|
34159
|
+
withLockedPersistedSavedHistoryIndex(dir, (currentEntries) => {
|
|
34160
|
+
const incomingFiles = new Set(Array.from(entries.keys()));
|
|
34161
|
+
for (const [file2, entry] of Array.from(entries.entries())) {
|
|
34162
|
+
const liveSignature = buildSavedHistoryFileSignature(dir, file2);
|
|
34163
|
+
const existingEntry = currentEntries.get(file2);
|
|
34164
|
+
if (existingEntry && existingEntry.signature !== liveSignature && entry.signature !== liveSignature) {
|
|
34165
|
+
continue;
|
|
34166
|
+
}
|
|
34167
|
+
if (entry.signature !== liveSignature && (!existingEntry || existingEntry.signature !== liveSignature)) {
|
|
34168
|
+
continue;
|
|
34169
|
+
}
|
|
34170
|
+
currentEntries.set(file2, entry.signature === liveSignature ? entry : {
|
|
34171
|
+
signature: liveSignature,
|
|
34172
|
+
summary: existingEntry?.summary || entry.summary
|
|
34173
|
+
});
|
|
34174
|
+
}
|
|
34175
|
+
for (const file2 of Array.from(currentEntries.keys())) {
|
|
34176
|
+
if (incomingFiles.has(file2)) continue;
|
|
34177
|
+
if (!fs32.existsSync(path7.join(dir, file2))) {
|
|
34178
|
+
currentEntries.delete(file2);
|
|
34179
|
+
}
|
|
34180
|
+
}
|
|
34181
|
+
});
|
|
34182
|
+
}
|
|
34183
|
+
function invalidatePersistedSavedHistoryIndex(agentType, dir) {
|
|
34184
|
+
try {
|
|
34185
|
+
fs32.rmSync(getSavedHistoryIndexFilePath(dir), { force: true });
|
|
34186
|
+
} catch {
|
|
34187
|
+
}
|
|
34188
|
+
savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
|
|
34189
|
+
}
|
|
34190
|
+
function buildSavedHistoryIndexFileSignature(dir) {
|
|
34191
|
+
try {
|
|
34192
|
+
const stat4 = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
34193
|
+
return `index:${stat4.size}:${Math.trunc(stat4.mtimeMs)}`;
|
|
34194
|
+
} catch {
|
|
34195
|
+
return "index:missing";
|
|
34196
|
+
}
|
|
34197
|
+
}
|
|
34198
|
+
function historyDirectoryHasFilesNewerThanIndex(dir) {
|
|
34199
|
+
try {
|
|
34200
|
+
const indexStat = fs32.statSync(getSavedHistoryIndexFilePath(dir));
|
|
34201
|
+
const files = listHistoryFiles(dir);
|
|
34202
|
+
for (const file2 of files) {
|
|
34203
|
+
const stat4 = fs32.statSync(path7.join(dir, file2));
|
|
34204
|
+
if (stat4.mtimeMs > indexStat.mtimeMs) return true;
|
|
34205
|
+
}
|
|
34206
|
+
return false;
|
|
34207
|
+
} catch {
|
|
34208
|
+
return true;
|
|
34209
|
+
}
|
|
34210
|
+
}
|
|
34211
|
+
function buildSavedHistoryFileSignature(dir, file2) {
|
|
34212
|
+
try {
|
|
34213
|
+
const stat4 = fs32.statSync(path7.join(dir, file2));
|
|
34214
|
+
return `${file2}:${stat4.size}:${Math.trunc(stat4.mtimeMs)}`;
|
|
34215
|
+
} catch {
|
|
34216
|
+
return `${file2}:missing`;
|
|
34217
|
+
}
|
|
34218
|
+
}
|
|
34219
|
+
function persistSavedHistoryFileSummaryEntry(agentType, dir, file2, updater) {
|
|
34220
|
+
const filePath = path7.join(dir, file2);
|
|
34221
|
+
const result = withLockedPersistedSavedHistoryIndex(dir, (entries) => {
|
|
34222
|
+
const currentEntry = entries.get(file2) || null;
|
|
34223
|
+
const nextSummary = updater(currentEntry?.summary || null);
|
|
34224
|
+
const nextEntry = {
|
|
34225
|
+
signature: buildSavedHistoryFileSignature(dir, file2),
|
|
34226
|
+
summary: nextSummary
|
|
34227
|
+
};
|
|
34228
|
+
entries.set(file2, nextEntry);
|
|
34229
|
+
savedHistoryFileSummaryCache.set(filePath, nextEntry);
|
|
34230
|
+
return nextEntry;
|
|
34231
|
+
});
|
|
34232
|
+
if (!result) return;
|
|
34233
|
+
if (result.summary?.historySessionId && shouldScheduleSavedHistoryRollupForSignature(result.signature)) {
|
|
34234
|
+
scheduleSavedHistoryRollup(agentType, result.summary.historySessionId);
|
|
34235
|
+
}
|
|
34236
|
+
}
|
|
34237
|
+
function updateSavedHistoryIndexForSessionStart(agentType, dir, file2, historySessionId, workspace) {
|
|
34238
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId);
|
|
34239
|
+
const normalizedWorkspace = String(workspace || "").trim();
|
|
34240
|
+
if (!normalizedSessionId || !normalizedWorkspace) return;
|
|
34241
|
+
persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => ({
|
|
34242
|
+
file: file2,
|
|
34243
|
+
historySessionId: normalizedSessionId,
|
|
34244
|
+
messageCount: currentSummary?.messageCount || 0,
|
|
34245
|
+
firstMessageAt: currentSummary?.firstMessageAt || 0,
|
|
34246
|
+
lastMessageAt: currentSummary?.lastMessageAt || 0,
|
|
34247
|
+
sessionTitle: currentSummary?.sessionTitle,
|
|
34248
|
+
preview: currentSummary?.preview,
|
|
34249
|
+
workspace: normalizedWorkspace
|
|
34250
|
+
}));
|
|
34251
|
+
}
|
|
34252
|
+
function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file2, historySessionId, messages) {
|
|
34253
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId || "");
|
|
34254
|
+
if (!normalizedSessionId || messages.length === 0) return;
|
|
34255
|
+
persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => {
|
|
34256
|
+
const nextSummary = {
|
|
34257
|
+
file: file2,
|
|
34258
|
+
historySessionId: normalizedSessionId,
|
|
34259
|
+
messageCount: currentSummary?.messageCount || 0,
|
|
34260
|
+
firstMessageAt: currentSummary?.firstMessageAt || 0,
|
|
34261
|
+
lastMessageAt: currentSummary?.lastMessageAt || 0,
|
|
34262
|
+
sessionTitle: currentSummary?.sessionTitle,
|
|
34263
|
+
preview: currentSummary?.preview,
|
|
34264
|
+
workspace: currentSummary?.workspace
|
|
34265
|
+
};
|
|
34266
|
+
for (const message of messages) {
|
|
34267
|
+
if (!message || message.historySessionId !== historySessionId) continue;
|
|
34268
|
+
if (message.kind === "session_start") {
|
|
34269
|
+
if (message.workspace) nextSummary.workspace = message.workspace;
|
|
34270
|
+
continue;
|
|
34271
|
+
}
|
|
34272
|
+
nextSummary.messageCount += 1;
|
|
34273
|
+
if (!nextSummary.firstMessageAt || message.receivedAt < nextSummary.firstMessageAt) {
|
|
34274
|
+
nextSummary.firstMessageAt = message.receivedAt;
|
|
34275
|
+
}
|
|
34276
|
+
if (!nextSummary.lastMessageAt || message.receivedAt >= nextSummary.lastMessageAt) {
|
|
34277
|
+
nextSummary.lastMessageAt = message.receivedAt;
|
|
34278
|
+
if (message.sessionTitle) nextSummary.sessionTitle = message.sessionTitle;
|
|
34279
|
+
if (message.role !== "system" && message.content.trim()) nextSummary.preview = message.content.trim();
|
|
34280
|
+
} else if (message.sessionTitle) {
|
|
34281
|
+
nextSummary.sessionTitle = message.sessionTitle;
|
|
34282
|
+
}
|
|
34283
|
+
if (!nextSummary.preview && message.role !== "system" && message.content.trim()) {
|
|
34284
|
+
nextSummary.preview = message.content.trim();
|
|
34285
|
+
}
|
|
34286
|
+
}
|
|
34287
|
+
return nextSummary;
|
|
34288
|
+
});
|
|
34289
|
+
}
|
|
34290
|
+
function computeSavedHistoryFileSummary(agentType, dir, file2) {
|
|
34291
|
+
const historySessionId = extractSavedHistorySessionIdFromFile(agentType, file2);
|
|
34292
|
+
if (!historySessionId) return null;
|
|
34293
|
+
const filePath = path7.join(dir, file2);
|
|
34294
|
+
const content = fs32.readFileSync(filePath, "utf-8");
|
|
34295
|
+
const lines = content.split("\n").filter(Boolean);
|
|
34296
|
+
let messageCount = 0;
|
|
34297
|
+
let firstMessageAt = 0;
|
|
34298
|
+
let lastMessageAt = 0;
|
|
34299
|
+
let sessionTitle = "";
|
|
34300
|
+
let preview = "";
|
|
34301
|
+
let workspace = "";
|
|
34302
|
+
for (const line of lines) {
|
|
34303
|
+
let parsed = null;
|
|
34304
|
+
try {
|
|
34305
|
+
parsed = JSON.parse(line);
|
|
34306
|
+
} catch {
|
|
34307
|
+
parsed = null;
|
|
34308
|
+
}
|
|
34309
|
+
if (!parsed || parsed.historySessionId !== historySessionId) continue;
|
|
34310
|
+
if (parsed.kind === "session_start") {
|
|
34311
|
+
if (!workspace && parsed.workspace) workspace = parsed.workspace;
|
|
34312
|
+
continue;
|
|
34313
|
+
}
|
|
34314
|
+
messageCount += 1;
|
|
34315
|
+
if (!firstMessageAt || parsed.receivedAt < firstMessageAt) firstMessageAt = parsed.receivedAt;
|
|
34316
|
+
if (!lastMessageAt || parsed.receivedAt > lastMessageAt) lastMessageAt = parsed.receivedAt;
|
|
34317
|
+
if (parsed.sessionTitle) sessionTitle = parsed.sessionTitle;
|
|
34318
|
+
if (parsed.role !== "system" && parsed.content.trim()) preview = parsed.content.trim();
|
|
34319
|
+
}
|
|
34320
|
+
if (messageCount === 0 || !lastMessageAt) return null;
|
|
34321
|
+
return {
|
|
34322
|
+
file: file2,
|
|
34323
|
+
historySessionId,
|
|
34324
|
+
messageCount,
|
|
34325
|
+
firstMessageAt,
|
|
34326
|
+
lastMessageAt,
|
|
34327
|
+
sessionTitle: sessionTitle || void 0,
|
|
34328
|
+
preview: preview || void 0,
|
|
34329
|
+
workspace: workspace || void 0
|
|
34330
|
+
};
|
|
34331
|
+
}
|
|
34332
|
+
function shouldScheduleSavedHistoryRollupForSignature(signature) {
|
|
34333
|
+
const parts = String(signature || "").split(":");
|
|
34334
|
+
const size = Number(parts[1] || 0);
|
|
34335
|
+
return shouldScheduleSavedHistoryRollup(size);
|
|
34336
|
+
}
|
|
34337
|
+
function scheduleSavedHistoryRollup(agentType, historySessionId) {
|
|
34338
|
+
const key = `${agentType}:${historySessionId}`;
|
|
34339
|
+
if (!historySessionId || savedHistoryRollupInFlight.has(key)) return;
|
|
34340
|
+
savedHistoryRollupInFlight.add(key);
|
|
34341
|
+
setTimeout(() => {
|
|
34342
|
+
try {
|
|
34343
|
+
new ChatHistoryWriter().compactHistorySession(agentType, historySessionId);
|
|
34344
|
+
} finally {
|
|
34345
|
+
savedHistoryRollupInFlight.delete(key);
|
|
34346
|
+
}
|
|
34347
|
+
}, 0);
|
|
34348
|
+
}
|
|
34349
|
+
function scheduleSavedHistoryBackgroundRefresh(agentType, dir) {
|
|
34350
|
+
const key = `${agentType}:${dir}`;
|
|
34351
|
+
if (savedHistoryBackgroundRefresh.has(key)) return;
|
|
34352
|
+
savedHistoryBackgroundRefresh.add(key);
|
|
34353
|
+
setTimeout(() => {
|
|
34354
|
+
try {
|
|
34355
|
+
if (!fs32.existsSync(dir)) return;
|
|
34356
|
+
const files = listHistoryFiles(dir);
|
|
34357
|
+
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
34358
|
+
const persistedEntries = loadPersistedSavedHistoryIndex(dir);
|
|
34359
|
+
const computed = computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatures, persistedEntries);
|
|
34360
|
+
savePersistedSavedHistoryIndex(dir, computed.persistedEntries || /* @__PURE__ */ new Map());
|
|
34361
|
+
const refreshedIndexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
34362
|
+
savedHistorySessionCache.set(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"), {
|
|
34363
|
+
signature: refreshedIndexSignature,
|
|
34364
|
+
summaries: computed.summaries || []
|
|
34365
|
+
});
|
|
34366
|
+
for (const [file2, entry] of Array.from(computed.persistedEntries.entries())) {
|
|
34367
|
+
if (!entry?.summary || !shouldScheduleSavedHistoryRollupForSignature(entry.signature)) continue;
|
|
34368
|
+
scheduleSavedHistoryRollup(agentType, entry.summary.historySessionId);
|
|
34369
|
+
}
|
|
34370
|
+
} catch {
|
|
34371
|
+
} finally {
|
|
34372
|
+
savedHistoryBackgroundRefresh.delete(key);
|
|
34373
|
+
}
|
|
34374
|
+
}, 0);
|
|
34375
|
+
}
|
|
34376
|
+
function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatures, persistedEntries) {
|
|
34377
|
+
const summaryBySessionId = /* @__PURE__ */ new Map();
|
|
34378
|
+
const nextPersistedEntries = /* @__PURE__ */ new Map();
|
|
34379
|
+
for (const file2 of files.slice().sort()) {
|
|
34380
|
+
const filePath = path7.join(dir, file2);
|
|
34381
|
+
const signature = fileSignatures.get(file2) || `${file2}:missing`;
|
|
34382
|
+
const cached2 = savedHistoryFileSummaryCache.get(filePath);
|
|
34383
|
+
const persisted = persistedEntries.get(file2);
|
|
34384
|
+
const reusableEntry = cached2?.signature === signature ? cached2 : persisted?.signature === signature ? persisted : null;
|
|
34385
|
+
const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(agentType, dir, file2);
|
|
34386
|
+
const nextEntry = reusableEntry || {
|
|
34387
|
+
signature,
|
|
34388
|
+
summary: fileSummary
|
|
34389
|
+
};
|
|
34390
|
+
if (!reusableEntry) {
|
|
34391
|
+
nextEntry.signature = signature;
|
|
34392
|
+
nextEntry.summary = fileSummary;
|
|
34393
|
+
}
|
|
34394
|
+
savedHistoryFileSummaryCache.set(filePath, nextEntry);
|
|
34395
|
+
nextPersistedEntries.set(file2, nextEntry);
|
|
34396
|
+
if (!fileSummary) continue;
|
|
34397
|
+
const existing = summaryBySessionId.get(fileSummary.historySessionId);
|
|
34398
|
+
if (fileSummary.messageCount <= 0 || !fileSummary.lastMessageAt) {
|
|
34399
|
+
continue;
|
|
34400
|
+
}
|
|
34401
|
+
if (!existing) {
|
|
34402
|
+
summaryBySessionId.set(fileSummary.historySessionId, {
|
|
34403
|
+
historySessionId: fileSummary.historySessionId,
|
|
34404
|
+
sessionTitle: fileSummary.sessionTitle,
|
|
34405
|
+
messageCount: fileSummary.messageCount,
|
|
34406
|
+
firstMessageAt: fileSummary.firstMessageAt,
|
|
34407
|
+
lastMessageAt: fileSummary.lastMessageAt,
|
|
34408
|
+
preview: fileSummary.preview,
|
|
34409
|
+
workspace: fileSummary.workspace
|
|
34410
|
+
});
|
|
34411
|
+
continue;
|
|
34412
|
+
}
|
|
34413
|
+
existing.messageCount += fileSummary.messageCount;
|
|
34414
|
+
if (!existing.firstMessageAt || fileSummary.firstMessageAt < existing.firstMessageAt) {
|
|
34415
|
+
existing.firstMessageAt = fileSummary.firstMessageAt;
|
|
34416
|
+
}
|
|
34417
|
+
if (fileSummary.lastMessageAt >= existing.lastMessageAt) {
|
|
34418
|
+
existing.lastMessageAt = fileSummary.lastMessageAt;
|
|
34419
|
+
if (fileSummary.sessionTitle) existing.sessionTitle = fileSummary.sessionTitle;
|
|
34420
|
+
if (fileSummary.preview) existing.preview = fileSummary.preview;
|
|
34421
|
+
}
|
|
34422
|
+
if (!existing.workspace && fileSummary.workspace) {
|
|
34423
|
+
existing.workspace = fileSummary.workspace;
|
|
34424
|
+
}
|
|
34425
|
+
}
|
|
34426
|
+
return {
|
|
34427
|
+
summaries: Array.from(summaryBySessionId.values()).sort((a, b2) => b2.lastMessageAt - a.lastMessageAt),
|
|
34428
|
+
persistedEntries: nextPersistedEntries
|
|
34429
|
+
};
|
|
34006
34430
|
}
|
|
34007
34431
|
var ChatHistoryWriter = class {
|
|
34008
34432
|
/** Last seen message count per agent (deduplication) */
|
|
@@ -34077,9 +34501,11 @@ ${cleanBody}`;
|
|
|
34077
34501
|
fs32.mkdirSync(dir, { recursive: true });
|
|
34078
34502
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
34079
34503
|
const filePrefix = effectiveHistoryKey ? `${this.sanitize(effectiveHistoryKey)}_` : "";
|
|
34080
|
-
const
|
|
34504
|
+
const fileName = `${filePrefix}${date5}.jsonl`;
|
|
34505
|
+
const filePath = path7.join(dir, fileName);
|
|
34081
34506
|
const lines = newMessages.map((m) => JSON.stringify(m)).join("\n") + "\n";
|
|
34082
34507
|
fs32.appendFileSync(filePath, lines, "utf-8");
|
|
34508
|
+
updateSavedHistoryIndexForAppendedMessages(agentType, dir, fileName, effectiveHistoryKey, newMessages);
|
|
34083
34509
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
34084
34510
|
if (!historySessionId && messages.length < prevCount * 0.5 && prevCount > 3) {
|
|
34085
34511
|
seenHashes.clear();
|
|
@@ -34170,7 +34596,8 @@ ${cleanBody}`;
|
|
|
34170
34596
|
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
34171
34597
|
fs32.mkdirSync(dir, { recursive: true });
|
|
34172
34598
|
const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
34173
|
-
const
|
|
34599
|
+
const fileName = `${this.sanitize(id)}_${date5}.jsonl`;
|
|
34600
|
+
const filePath = path7.join(dir, fileName);
|
|
34174
34601
|
const record2 = {
|
|
34175
34602
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34176
34603
|
receivedAt: Date.now(),
|
|
@@ -34183,6 +34610,7 @@ ${cleanBody}`;
|
|
|
34183
34610
|
workspace: ws2
|
|
34184
34611
|
};
|
|
34185
34612
|
fs32.appendFileSync(filePath, JSON.stringify(record2) + "\n", "utf-8");
|
|
34613
|
+
updateSavedHistoryIndexForSessionStart(agentType, dir, fileName, id, ws2);
|
|
34186
34614
|
} catch {
|
|
34187
34615
|
}
|
|
34188
34616
|
}
|
|
@@ -34248,6 +34676,7 @@ ${cleanBody}`;
|
|
|
34248
34676
|
}
|
|
34249
34677
|
fs32.unlinkSync(sourcePath);
|
|
34250
34678
|
}
|
|
34679
|
+
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
34251
34680
|
} catch {
|
|
34252
34681
|
}
|
|
34253
34682
|
}
|
|
@@ -34297,6 +34726,7 @@ ${cleanBody}`;
|
|
|
34297
34726
|
fs32.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
|
|
34298
34727
|
`, "utf-8");
|
|
34299
34728
|
}
|
|
34729
|
+
invalidatePersistedSavedHistoryIndex(agentType, dir);
|
|
34300
34730
|
} catch {
|
|
34301
34731
|
}
|
|
34302
34732
|
}
|
|
@@ -34316,13 +34746,18 @@ ${cleanBody}`;
|
|
|
34316
34746
|
for (const dir of agentDirs) {
|
|
34317
34747
|
const dirPath = path7.join(HISTORY_DIR, dir.name);
|
|
34318
34748
|
const files = fs32.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl") || f.endsWith(".terminal.log"));
|
|
34749
|
+
let removedAny = false;
|
|
34319
34750
|
for (const file2 of files) {
|
|
34320
34751
|
const filePath = path7.join(dirPath, file2);
|
|
34321
34752
|
const stat4 = fs32.statSync(filePath);
|
|
34322
34753
|
if (stat4.mtimeMs < cutoff) {
|
|
34323
34754
|
fs32.unlinkSync(filePath);
|
|
34755
|
+
removedAny = true;
|
|
34324
34756
|
}
|
|
34325
34757
|
}
|
|
34758
|
+
if (removedAny) {
|
|
34759
|
+
invalidatePersistedSavedHistoryIndex(dir.name, dirPath);
|
|
34760
|
+
}
|
|
34326
34761
|
}
|
|
34327
34762
|
} catch {
|
|
34328
34763
|
}
|
|
@@ -34388,18 +34823,51 @@ ${cleanBody}`;
|
|
|
34388
34823
|
savedHistorySessionCache.delete(sanitized);
|
|
34389
34824
|
return { sessions: [], hasMore: false };
|
|
34390
34825
|
}
|
|
34391
|
-
const files = listHistoryFiles(dir);
|
|
34392
|
-
const signature = buildSavedHistoryCacheSignature(dir, files);
|
|
34393
34826
|
const cached2 = savedHistorySessionCache.get(sanitized);
|
|
34394
|
-
const
|
|
34395
|
-
|
|
34827
|
+
const offset = Math.max(0, options.offset || 0);
|
|
34828
|
+
const limit = Math.max(1, options.limit || 30);
|
|
34829
|
+
const indexSignature = buildSavedHistoryIndexFileSignature(dir);
|
|
34830
|
+
let cacheWasInvalidated = false;
|
|
34831
|
+
if (cached2) {
|
|
34832
|
+
const cacheLooksPersisted = cached2.signature.startsWith("index:");
|
|
34833
|
+
const cacheStillValid = cacheLooksPersisted ? cached2.signature === indexSignature : (() => {
|
|
34834
|
+
const files2 = listHistoryFiles(dir);
|
|
34835
|
+
const fileSignatures2 = buildSavedHistoryFileSignatureMap(dir, files2);
|
|
34836
|
+
return cached2.signature === buildSavedHistoryCacheSignature(files2, fileSignatures2);
|
|
34837
|
+
})();
|
|
34838
|
+
if (cacheStillValid) {
|
|
34839
|
+
const sliced2 = cached2.summaries.slice(offset, offset + limit);
|
|
34840
|
+
return {
|
|
34841
|
+
sessions: sliced2,
|
|
34842
|
+
hasMore: cached2.summaries.length > offset + limit
|
|
34843
|
+
};
|
|
34844
|
+
}
|
|
34845
|
+
cacheWasInvalidated = true;
|
|
34846
|
+
}
|
|
34847
|
+
const persistedSessions = readPersistedSavedHistorySessionSummaries(dir);
|
|
34848
|
+
if (!cacheWasInvalidated && persistedSessions?.length && !historyDirectoryHasFilesNewerThanIndex(dir)) {
|
|
34396
34849
|
savedHistorySessionCache.set(sanitized, {
|
|
34397
|
-
signature,
|
|
34398
|
-
summaries
|
|
34850
|
+
signature: indexSignature,
|
|
34851
|
+
summaries: persistedSessions
|
|
34399
34852
|
});
|
|
34853
|
+
scheduleSavedHistoryBackgroundRefresh(agentType, dir);
|
|
34854
|
+
const sliced2 = persistedSessions.slice(offset, offset + limit);
|
|
34855
|
+
return {
|
|
34856
|
+
sessions: sliced2,
|
|
34857
|
+
hasMore: persistedSessions.length > offset + limit
|
|
34858
|
+
};
|
|
34400
34859
|
}
|
|
34401
|
-
const
|
|
34402
|
-
const
|
|
34860
|
+
const files = listHistoryFiles(dir);
|
|
34861
|
+
const fileSignatures = buildSavedHistoryFileSignatureMap(dir, files);
|
|
34862
|
+
const signature = buildSavedHistoryCacheSignature(files, fileSignatures);
|
|
34863
|
+
const persistedEntries = loadPersistedSavedHistoryIndex(dir);
|
|
34864
|
+
const computed = computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatures, persistedEntries);
|
|
34865
|
+
const summaries = computed.summaries || [];
|
|
34866
|
+
savePersistedSavedHistoryIndex(dir, computed.persistedEntries || /* @__PURE__ */ new Map());
|
|
34867
|
+
savedHistorySessionCache.set(sanitized, {
|
|
34868
|
+
signature,
|
|
34869
|
+
summaries
|
|
34870
|
+
});
|
|
34403
34871
|
const sliced = summaries.slice(offset, offset + limit);
|
|
34404
34872
|
return {
|
|
34405
34873
|
sessions: sliced,
|
|
@@ -36128,6 +36596,21 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36128
36596
|
lastUpdated: ext.lastUpdated
|
|
36129
36597
|
};
|
|
36130
36598
|
}
|
|
36599
|
+
function shouldIncludeExtensionSession(ext) {
|
|
36600
|
+
const status = String(ext.status || "").trim().toLowerCase();
|
|
36601
|
+
const hasActiveChat = !!ext.activeChat;
|
|
36602
|
+
const hasMessages = Array.isArray(ext.activeChat?.messages) && ext.activeChat.messages.length > 0;
|
|
36603
|
+
const hasModal = !!ext.activeChat?.activeModal;
|
|
36604
|
+
const hasStreams = Array.isArray(ext.agentStreams) && ext.agentStreams.length > 0;
|
|
36605
|
+
const hasProviderSessionId = typeof ext.providerSessionId === "string" && ext.providerSessionId.trim().length > 0;
|
|
36606
|
+
const hasControlValues = !!(ext.controlValues && Object.keys(ext.controlValues).length > 0);
|
|
36607
|
+
const hasProviderControls = Array.isArray(ext.providerControls) && ext.providerControls.length > 0;
|
|
36608
|
+
const hasOpenPanelCapability = Array.isArray(ext.sessionCapabilities) && ext.sessionCapabilities.includes("open_panel");
|
|
36609
|
+
const hasSummaryMetadata = !!ext.summaryMetadata;
|
|
36610
|
+
const hasError = typeof ext.errorMessage === "string" && ext.errorMessage.trim().length > 0;
|
|
36611
|
+
const hasInterestingStatus = !!status && !["idle", "panel_hidden", "disconnected", "not_monitored"].includes(status);
|
|
36612
|
+
return hasActiveChat || hasMessages || hasModal || hasStreams || hasProviderSessionId || hasControlValues || hasProviderControls || hasOpenPanelCapability || hasSummaryMetadata || hasError || hasInterestingStatus;
|
|
36613
|
+
}
|
|
36131
36614
|
function buildCliSession(state, options) {
|
|
36132
36615
|
const profile = options.profile || "full";
|
|
36133
36616
|
const activeChat = normalizeActiveChatData(state.activeChat, getActiveChatOptions(profile));
|
|
@@ -36211,6 +36694,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36211
36694
|
for (const state of ideStates) {
|
|
36212
36695
|
sessions.push(buildIdeWorkspaceSession(state, cdpManagers, options));
|
|
36213
36696
|
for (const ext of state.extensions) {
|
|
36697
|
+
if (!shouldIncludeExtensionSession(ext)) continue;
|
|
36214
36698
|
sessions.push(buildExtensionAgentSession(state, ext, options));
|
|
36215
36699
|
}
|
|
36216
36700
|
}
|
|
@@ -38351,7 +38835,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38351
38835
|
});
|
|
38352
38836
|
}
|
|
38353
38837
|
async function executeProviderScript(h, args, scriptName) {
|
|
38354
|
-
const
|
|
38838
|
+
const explicitTargetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
38839
|
+
const targetSession = explicitTargetSessionId ? h.ctx.sessionRegistry?.get(explicitTargetSessionId) : void 0;
|
|
38840
|
+
const resolvedProviderType = targetSession?.providerType || h.currentSession?.providerType || h.currentProviderType || args?.agentType || args?.providerType;
|
|
38355
38841
|
if (!resolvedProviderType) return { success: false, error: "targetSessionId or providerType is required" };
|
|
38356
38842
|
const loader = h.ctx.providerLoader;
|
|
38357
38843
|
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
@@ -38394,16 +38880,16 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38394
38880
|
const scriptFn = provider.scripts[actualScriptName];
|
|
38395
38881
|
const scriptCode = scriptFn(normalizedArgs);
|
|
38396
38882
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
38397
|
-
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType : h.currentSession?.cdpManagerKey || h.currentManagerKey;
|
|
38883
|
+
const cdpKey = provider.category === "ide" ? targetSession?.cdpManagerKey || h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType : targetSession?.cdpManagerKey || h.currentSession?.cdpManagerKey || h.currentManagerKey;
|
|
38398
38884
|
LOG2.info("Command", `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
|
|
38399
38885
|
const cdp = h.getCdp(cdpKey);
|
|
38400
38886
|
if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
38401
38887
|
try {
|
|
38402
38888
|
let result;
|
|
38403
38889
|
if (provider.category === "extension") {
|
|
38404
|
-
const runtimeSessionId = h.currentSession?.sessionId
|
|
38890
|
+
const runtimeSessionId = explicitTargetSessionId || h.currentSession?.sessionId;
|
|
38405
38891
|
if (!runtimeSessionId) return { success: false, error: `No target session found for ${resolvedProviderType}` };
|
|
38406
|
-
const parentSessionId = h.currentSession?.parentSessionId;
|
|
38892
|
+
const parentSessionId = targetSession?.parentSessionId || h.currentSession?.parentSessionId;
|
|
38407
38893
|
if (parentSessionId) {
|
|
38408
38894
|
await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
|
|
38409
38895
|
await h.agentStream?.syncActiveSession(cdp, parentSessionId);
|
|
@@ -45277,6 +45763,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45277
45763
|
}
|
|
45278
45764
|
};
|
|
45279
45765
|
}
|
|
45766
|
+
async function runAsyncBatch2(items, worker, options = {}) {
|
|
45767
|
+
const list = Array.from(items);
|
|
45768
|
+
if (list.length === 0) return;
|
|
45769
|
+
const concurrency = Math.max(1, Math.min(list.length, Math.floor(options.concurrency || 1)));
|
|
45770
|
+
let nextIndex = 0;
|
|
45771
|
+
const runners = Array.from({ length: concurrency }, async () => {
|
|
45772
|
+
while (true) {
|
|
45773
|
+
const currentIndex = nextIndex;
|
|
45774
|
+
nextIndex += 1;
|
|
45775
|
+
if (currentIndex >= list.length) return;
|
|
45776
|
+
await worker(list[currentIndex], currentIndex);
|
|
45777
|
+
}
|
|
45778
|
+
});
|
|
45779
|
+
await Promise.all(runners);
|
|
45780
|
+
}
|
|
45280
45781
|
init_read_chat_contract();
|
|
45281
45782
|
init_chat_message_normalization();
|
|
45282
45783
|
var ProviderStreamAdapter = class {
|
|
@@ -45742,10 +46243,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45742
46243
|
}
|
|
45743
46244
|
}
|
|
45744
46245
|
/** Collect active extension session state */
|
|
45745
|
-
async collectActiveSession(cdp, parentSessionId) {
|
|
46246
|
+
async collectActiveSession(cdp, parentSessionId, attemptedSessionIds = /* @__PURE__ */ new Set(), originSessionId) {
|
|
45746
46247
|
if (!this.enabled) return null;
|
|
45747
46248
|
const activeSessionId = this.getActiveSessionId(parentSessionId);
|
|
45748
46249
|
if (!activeSessionId) return null;
|
|
46250
|
+
const resolvedOriginSessionId = originSessionId || activeSessionId;
|
|
46251
|
+
attemptedSessionIds.add(activeSessionId);
|
|
45749
46252
|
let agent = this.managedBySessionId.get(activeSessionId);
|
|
45750
46253
|
if (!agent) {
|
|
45751
46254
|
agent = await this.connectManagedSession(cdp, parentSessionId, activeSessionId) || void 0;
|
|
@@ -45758,18 +46261,44 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45758
46261
|
try {
|
|
45759
46262
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
45760
46263
|
const state = await agent.adapter.readChat(evaluate);
|
|
45761
|
-
const
|
|
45762
|
-
const
|
|
45763
|
-
|
|
45764
|
-
|
|
46264
|
+
const resolvedProviderSessionId = typeof state.providerSessionId === "string" && state.providerSessionId.trim() ? state.providerSessionId.trim() : typeof state.sessionId === "string" && state.sessionId.trim() && state.sessionId !== agent.runtimeSessionId ? state.sessionId.trim() : void 0;
|
|
46265
|
+
const normalizedState = {
|
|
46266
|
+
...state,
|
|
46267
|
+
sessionId: agent.runtimeSessionId,
|
|
46268
|
+
...resolvedProviderSessionId ? { providerSessionId: resolvedProviderSessionId } : {}
|
|
46269
|
+
};
|
|
46270
|
+
const stateError = this.getStateError(normalizedState);
|
|
46271
|
+
const selectedModelValue = typeof normalizedState.controlValues?.model === "string" ? normalizedState.controlValues.model : "";
|
|
46272
|
+
LOG2.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${normalizedState.status} msgs=${normalizedState.messages?.length || 0} model=${selectedModelValue}${normalizedState.status === "error" ? " error=" + JSON.stringify(stateError) : ""}`);
|
|
46273
|
+
if (normalizedState.status === "error" && this.isRecoverableSessionError(stateError)) {
|
|
45765
46274
|
throw new Error(stateError);
|
|
45766
46275
|
}
|
|
45767
|
-
agent.lastState =
|
|
46276
|
+
agent.lastState = normalizedState;
|
|
45768
46277
|
agent.lastError = null;
|
|
45769
|
-
if (
|
|
46278
|
+
if (normalizedState.status === "panel_hidden") {
|
|
46279
|
+
const discovered = await cdp.discoverAgentWebviews().catch(() => []);
|
|
46280
|
+
const fallbackTarget = discovered.find((entry) => {
|
|
46281
|
+
if (entry.agentType === type) return false;
|
|
46282
|
+
const fallbackSessionId = this.resolveSessionIdForTarget(parentSessionId, entry.agentType);
|
|
46283
|
+
return !!fallbackSessionId && fallbackSessionId !== activeSessionId && !attemptedSessionIds.has(fallbackSessionId);
|
|
46284
|
+
});
|
|
46285
|
+
if (fallbackTarget) {
|
|
46286
|
+
const fallbackSessionId = this.resolveSessionIdForTarget(parentSessionId, fallbackTarget.agentType);
|
|
46287
|
+
if (fallbackSessionId && fallbackSessionId !== activeSessionId && !attemptedSessionIds.has(fallbackSessionId)) {
|
|
46288
|
+
this.logFn(`[AgentStream] Active session ${type} is hidden; switching to visible agent ${fallbackTarget.agentType} (${parentSessionId})`);
|
|
46289
|
+
await this.setActiveSession(cdp, parentSessionId, fallbackSessionId);
|
|
46290
|
+
await this.syncActiveSession(cdp, parentSessionId);
|
|
46291
|
+
const fallbackState = await this.collectActiveSession(cdp, parentSessionId, attemptedSessionIds, resolvedOriginSessionId);
|
|
46292
|
+
if (fallbackState?.status === "panel_hidden" && resolvedOriginSessionId !== fallbackSessionId) {
|
|
46293
|
+
await this.setActiveSession(cdp, parentSessionId, resolvedOriginSessionId);
|
|
46294
|
+
await this.syncActiveSession(cdp, parentSessionId);
|
|
46295
|
+
}
|
|
46296
|
+
return fallbackState;
|
|
46297
|
+
}
|
|
46298
|
+
}
|
|
45770
46299
|
agent.lastHiddenCheckTime = Date.now();
|
|
45771
46300
|
}
|
|
45772
|
-
return
|
|
46301
|
+
return normalizedState;
|
|
45773
46302
|
} catch (e) {
|
|
45774
46303
|
const errorMsg = e?.message || String(e);
|
|
45775
46304
|
this.logFn(`[AgentStream] readChat(${type}) error: ${errorMsg.slice(0, 200)}`);
|
|
@@ -46063,6 +46592,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
46063
46592
|
try {
|
|
46064
46593
|
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
46065
46594
|
let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
46595
|
+
resolvedActiveSessionId = stream?.sessionId || agentStreamManager.getActiveSessionId(parentSessionId) || resolvedActiveSessionId;
|
|
46066
46596
|
if (stream?.status === "waiting_approval") {
|
|
46067
46597
|
const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
|
|
46068
46598
|
if (autoApprove && resolvedActiveSessionId) {
|
|
@@ -53256,7 +53786,7 @@ var StandaloneServer = class {
|
|
|
53256
53786
|
}),
|
|
53257
53787
|
onStatusChange: () => {
|
|
53258
53788
|
this.scheduleBroadcastStatus();
|
|
53259
|
-
void this.flushWsChatSubscriptions(void 0, { onlyActive:
|
|
53789
|
+
void this.flushWsChatSubscriptions(void 0, { onlyActive: true });
|
|
53260
53790
|
},
|
|
53261
53791
|
removeAgentTracking: () => {
|
|
53262
53792
|
},
|
|
@@ -53285,7 +53815,7 @@ var StandaloneServer = class {
|
|
|
53285
53815
|
statusDaemonMode: false,
|
|
53286
53816
|
onStatusChange: () => {
|
|
53287
53817
|
this.scheduleBroadcastStatus();
|
|
53288
|
-
void this.flushWsChatSubscriptions(void 0, { onlyActive:
|
|
53818
|
+
void this.flushWsChatSubscriptions(void 0, { onlyActive: true });
|
|
53289
53819
|
},
|
|
53290
53820
|
sessionHostControl,
|
|
53291
53821
|
onStreamsUpdated: (ideType, streams) => {
|
|
@@ -53885,6 +54415,7 @@ var StandaloneServer = class {
|
|
|
53885
54415
|
try {
|
|
53886
54416
|
const targets = targetWs ? [targetWs] : Array.from(this.clients);
|
|
53887
54417
|
const hotSessionIds = options.onlyActive ? this.getHotChatSessionIdsForWsFlush() : null;
|
|
54418
|
+
const tasks = [];
|
|
53888
54419
|
for (const ws2 of targets) {
|
|
53889
54420
|
if (ws2.readyState !== import_ws.WebSocket.OPEN) continue;
|
|
53890
54421
|
const subs = this.wsSubscriptions.get(ws2);
|
|
@@ -53894,11 +54425,18 @@ var StandaloneServer = class {
|
|
|
53894
54425
|
if (hotSessionIds && !hotSessionIds.active.has(targetSessionId) && !hotSessionIds.finalizing.has(targetSessionId)) {
|
|
53895
54426
|
continue;
|
|
53896
54427
|
}
|
|
54428
|
+
tasks.push({ ws: ws2, key, sub });
|
|
54429
|
+
}
|
|
54430
|
+
}
|
|
54431
|
+
await (0, import_daemon_core2.runAsyncBatch)(tasks, async ({ ws: ws2, key, sub }) => {
|
|
54432
|
+
try {
|
|
53897
54433
|
const update = await this.buildChatTailUpdate(sub.request.params, sub, key);
|
|
53898
|
-
if (!update || ws2.readyState !== import_ws.WebSocket.OPEN)
|
|
54434
|
+
if (!update || ws2.readyState !== import_ws.WebSocket.OPEN) return;
|
|
53899
54435
|
ws2.send(JSON.stringify({ type: "topic_update", update }));
|
|
54436
|
+
} catch (error48) {
|
|
54437
|
+
import_daemon_core2.LOG.warn("Standalone", `[chat_tail] skipped session=${sub.request.params.targetSessionId} key=${key} error=${error48?.message || error48}`);
|
|
53900
54438
|
}
|
|
53901
|
-
}
|
|
54439
|
+
}, { concurrency: 4 });
|
|
53902
54440
|
} finally {
|
|
53903
54441
|
this.wsChatFlushInFlight = false;
|
|
53904
54442
|
if (this.pendingWsChatFlush) {
|