@adhdev/daemon-standalone 0.8.28 → 0.8.29
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 +394 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-CE_CO9Co.js +59 -0
- package/public/index.html +1 -1
- package/vendor/session-host-daemon/index.d.mts +3 -0
- package/vendor/session-host-daemon/index.d.ts +3 -0
- package/vendor/session-host-daemon/index.js +101 -0
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +101 -0
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/public/assets/index-B9NQFXHb.js +0 -57
package/dist/index.js
CHANGED
|
@@ -9495,6 +9495,9 @@ var require_dist = __commonJS({
|
|
|
9495
9495
|
state.record.lastActivityAt = Date.now();
|
|
9496
9496
|
return this.cloneRecord(state.record);
|
|
9497
9497
|
}
|
|
9498
|
+
deleteSession(sessionId) {
|
|
9499
|
+
return this.sessions.delete(sessionId);
|
|
9500
|
+
}
|
|
9498
9501
|
requireSession(sessionId) {
|
|
9499
9502
|
const state = this.sessions.get(sessionId);
|
|
9500
9503
|
if (!state) throw new Error(`Unknown session: ${sessionId}`);
|
|
@@ -9676,10 +9679,12 @@ var require_dist = __commonJS({
|
|
|
9676
9679
|
env[key] = value;
|
|
9677
9680
|
}
|
|
9678
9681
|
for (const key of Object.keys(env)) {
|
|
9679
|
-
if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_")) {
|
|
9682
|
+
if (key === "INIT_CWD" || key === "npm_command" || key === "npm_execpath" || key === "npm_node_execpath" || key.startsWith("npm_") || key.startsWith("npm_config_") || key.startsWith("npm_package_") || key.startsWith("npm_lifecycle_") || key.startsWith("PNPM_") || key.startsWith("YARN_") || key.startsWith("BUN_") || key.startsWith("VSCODE_") || key.startsWith("ELECTRON_")) {
|
|
9680
9683
|
delete env[key];
|
|
9681
9684
|
}
|
|
9682
9685
|
}
|
|
9686
|
+
delete env.CODEX_THREAD_ID;
|
|
9687
|
+
delete env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE;
|
|
9683
9688
|
applyTerminalColorEnv(env);
|
|
9684
9689
|
return env;
|
|
9685
9690
|
}
|
|
@@ -29440,6 +29445,9 @@ var require_dist2 = __commonJS({
|
|
|
29440
29445
|
looksLikeVisibleIdlePrompt(screenText) {
|
|
29441
29446
|
const text = String(screenText || "");
|
|
29442
29447
|
if (!text.trim()) return false;
|
|
29448
|
+
if (this.cliType === "codex-cli" && /(^|\n)\s*[❯›>]\s+(?:Find and fix a bug in @filename|Improve documentation in @filename|Use \/skills|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Run \/review on my current changes)(?:\n|$)/im.test(text)) {
|
|
29449
|
+
return true;
|
|
29450
|
+
}
|
|
29443
29451
|
return /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(text) || /⏎\s+send/i.test(text) || /\?\s*for\s*shortcuts/i.test(text) || /Type your message(?:\s+or\s+@path\/to\/file)?/i.test(text) || /workspace\s*\(\/directory\)/i.test(text) || /for\s*shortcuts/i.test(text);
|
|
29444
29452
|
}
|
|
29445
29453
|
findLastMatchingLineIndex(lines, predicate) {
|
|
@@ -32739,11 +32747,72 @@ ${data.message || ""}`.trim();
|
|
|
32739
32747
|
var os52 = __toESM2(require("os"));
|
|
32740
32748
|
var HISTORY_DIR = path7.join(os52.homedir(), ".adhdev", "history");
|
|
32741
32749
|
var RETAIN_DAYS = 30;
|
|
32750
|
+
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;
|
|
32751
|
+
function normalizeHistoryComparable(text) {
|
|
32752
|
+
return String(text || "").replace(/\s+/g, " ").trim();
|
|
32753
|
+
}
|
|
32754
|
+
function cleanupHistoryContent(agentType, role, content) {
|
|
32755
|
+
let value = String(content || "").replace(/\r\n/g, "\n").trim();
|
|
32756
|
+
if (!value) return "";
|
|
32757
|
+
if (agentType === "codex-cli" && role === "assistant") {
|
|
32758
|
+
const filtered = value.split("\n").filter((line) => !CODEX_STARTER_PROMPT_RE.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
32759
|
+
value = filtered;
|
|
32760
|
+
}
|
|
32761
|
+
return value;
|
|
32762
|
+
}
|
|
32763
|
+
function buildHistoryMessageHash(agentType, message) {
|
|
32764
|
+
if (message.historyDedupKey) return message.historyDedupKey;
|
|
32765
|
+
const cleaned = cleanupHistoryContent(agentType, message.role, message.content);
|
|
32766
|
+
return `${message.kind || "standard"}:${message.role}:${message.receivedAt || 0}:${normalizeHistoryComparable(cleaned)}`;
|
|
32767
|
+
}
|
|
32768
|
+
function buildHistoryMessageSignature(agentType, message) {
|
|
32769
|
+
const cleaned = cleanupHistoryContent(agentType, message.role, message.content);
|
|
32770
|
+
return `${message.kind || "standard"}:${message.role}:${normalizeHistoryComparable(cleaned)}`;
|
|
32771
|
+
}
|
|
32772
|
+
function isAdjacentHistoryDuplicate(agentType, previous, next) {
|
|
32773
|
+
if (!previous || !next) return false;
|
|
32774
|
+
return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
|
|
32775
|
+
}
|
|
32776
|
+
function collapseReplayAssistantTurns(agentType, messages) {
|
|
32777
|
+
if (agentType !== "codex-cli") return messages;
|
|
32778
|
+
const collapsed = [];
|
|
32779
|
+
let sawAssistantSinceLastUser = false;
|
|
32780
|
+
for (const message of messages) {
|
|
32781
|
+
if (message.role === "user") {
|
|
32782
|
+
sawAssistantSinceLastUser = false;
|
|
32783
|
+
collapsed.push(message);
|
|
32784
|
+
continue;
|
|
32785
|
+
}
|
|
32786
|
+
if (message.role === "assistant") {
|
|
32787
|
+
if (sawAssistantSinceLastUser) continue;
|
|
32788
|
+
sawAssistantSinceLastUser = true;
|
|
32789
|
+
collapsed.push(message);
|
|
32790
|
+
continue;
|
|
32791
|
+
}
|
|
32792
|
+
collapsed.push(message);
|
|
32793
|
+
}
|
|
32794
|
+
return collapsed;
|
|
32795
|
+
}
|
|
32796
|
+
function sanitizeHistoryMessage(agentType, message) {
|
|
32797
|
+
if (!message || message.role !== "user" && message.role !== "assistant" && message.role !== "system") {
|
|
32798
|
+
return null;
|
|
32799
|
+
}
|
|
32800
|
+
const content = cleanupHistoryContent(agentType, message.role, message.content);
|
|
32801
|
+
if (!content) return null;
|
|
32802
|
+
return {
|
|
32803
|
+
...message,
|
|
32804
|
+
content
|
|
32805
|
+
};
|
|
32806
|
+
}
|
|
32742
32807
|
var ChatHistoryWriter = class {
|
|
32743
32808
|
/** Last seen message count per agent (deduplication) */
|
|
32744
32809
|
lastSeenCounts = /* @__PURE__ */ new Map();
|
|
32745
32810
|
/** Last seen message hash per agent (deduplication) */
|
|
32746
32811
|
lastSeenHashes = /* @__PURE__ */ new Map();
|
|
32812
|
+
/** Last appended normalized message signature per agent/session */
|
|
32813
|
+
lastSeenSignatures = /* @__PURE__ */ new Map();
|
|
32814
|
+
/** Last appended normalized non-system turn signature per agent/session */
|
|
32815
|
+
lastSeenTurnSignatures = /* @__PURE__ */ new Map();
|
|
32747
32816
|
rotated = false;
|
|
32748
32817
|
/**
|
|
32749
32818
|
* Append new messages to history
|
|
@@ -32765,14 +32834,36 @@ ${data.message || ""}`.trim();
|
|
|
32765
32834
|
}
|
|
32766
32835
|
const newMessages = [];
|
|
32767
32836
|
for (const msg of messages) {
|
|
32768
|
-
const
|
|
32837
|
+
const role = msg.role;
|
|
32838
|
+
if (role !== "user" && role !== "assistant" && role !== "system") continue;
|
|
32839
|
+
const content = cleanupHistoryContent(agentType, role, msg.content || "");
|
|
32840
|
+
if (!content) continue;
|
|
32841
|
+
const receivedAt = msg.receivedAt || Date.now();
|
|
32842
|
+
const hash2 = buildHistoryMessageHash(agentType, {
|
|
32843
|
+
role,
|
|
32844
|
+
content,
|
|
32845
|
+
receivedAt,
|
|
32846
|
+
kind: typeof msg.kind === "string" ? msg.kind : void 0,
|
|
32847
|
+
historyDedupKey: msg.historyDedupKey
|
|
32848
|
+
});
|
|
32849
|
+
const signature = buildHistoryMessageSignature(agentType, {
|
|
32850
|
+
role,
|
|
32851
|
+
content,
|
|
32852
|
+
kind: typeof msg.kind === "string" ? msg.kind : void 0
|
|
32853
|
+
});
|
|
32769
32854
|
if (seenHashes.has(hash2)) continue;
|
|
32855
|
+
if (this.lastSeenSignatures.get(dedupKey) === signature) continue;
|
|
32856
|
+
if (role !== "system" && this.lastSeenTurnSignatures.get(dedupKey) === signature) continue;
|
|
32770
32857
|
seenHashes.add(hash2);
|
|
32858
|
+
this.lastSeenSignatures.set(dedupKey, signature);
|
|
32859
|
+
if (role !== "system") {
|
|
32860
|
+
this.lastSeenTurnSignatures.set(dedupKey, signature);
|
|
32861
|
+
}
|
|
32771
32862
|
newMessages.push({
|
|
32772
|
-
ts: new Date(
|
|
32773
|
-
receivedAt
|
|
32774
|
-
role
|
|
32775
|
-
content
|
|
32863
|
+
ts: new Date(receivedAt).toISOString(),
|
|
32864
|
+
receivedAt,
|
|
32865
|
+
role,
|
|
32866
|
+
content,
|
|
32776
32867
|
kind: typeof msg.kind === "string" ? msg.kind : void 0,
|
|
32777
32868
|
senderName: typeof msg.senderName === "string" ? msg.senderName : void 0,
|
|
32778
32869
|
agent: agentType,
|
|
@@ -32792,6 +32883,8 @@ ${data.message || ""}`.trim();
|
|
|
32792
32883
|
const prevCount = this.lastSeenCounts.get(dedupKey) || 0;
|
|
32793
32884
|
if (messages.length < prevCount * 0.5 && prevCount > 3) {
|
|
32794
32885
|
seenHashes.clear();
|
|
32886
|
+
this.lastSeenSignatures.delete(dedupKey);
|
|
32887
|
+
this.lastSeenTurnSignatures.delete(dedupKey);
|
|
32795
32888
|
for (const msg of messages) {
|
|
32796
32889
|
seenHashes.add(msg.historyDedupKey || `${msg.kind || "standard"}:${msg.role}:${(msg.content || "").slice(0, 50)}`);
|
|
32797
32890
|
}
|
|
@@ -32805,6 +32898,54 @@ ${data.message || ""}`.trim();
|
|
|
32805
32898
|
} catch {
|
|
32806
32899
|
}
|
|
32807
32900
|
}
|
|
32901
|
+
seedSessionHistory(agentType, messages = [], historySessionId, instanceId) {
|
|
32902
|
+
const effectiveHistoryKey = historySessionId || instanceId;
|
|
32903
|
+
const dedupKey = effectiveHistoryKey ? `${agentType}:${effectiveHistoryKey}` : agentType;
|
|
32904
|
+
const seenHashes = /* @__PURE__ */ new Set();
|
|
32905
|
+
for (const raw of messages) {
|
|
32906
|
+
const role = raw?.role;
|
|
32907
|
+
if (role !== "user" && role !== "assistant" && role !== "system") continue;
|
|
32908
|
+
const content = cleanupHistoryContent(agentType, role, raw?.content || "");
|
|
32909
|
+
if (!content) continue;
|
|
32910
|
+
seenHashes.add(buildHistoryMessageHash(agentType, {
|
|
32911
|
+
role,
|
|
32912
|
+
content,
|
|
32913
|
+
receivedAt: raw?.receivedAt || 0,
|
|
32914
|
+
kind: typeof raw?.kind === "string" ? raw.kind : void 0,
|
|
32915
|
+
historyDedupKey: raw?.historyDedupKey
|
|
32916
|
+
}));
|
|
32917
|
+
}
|
|
32918
|
+
this.lastSeenHashes.set(dedupKey, seenHashes);
|
|
32919
|
+
this.lastSeenCounts.set(dedupKey, messages.length);
|
|
32920
|
+
const lastMessage = [...messages].reverse().find((raw) => {
|
|
32921
|
+
const role = raw?.role;
|
|
32922
|
+
if (role !== "user" && role !== "assistant" && role !== "system") return false;
|
|
32923
|
+
return !!cleanupHistoryContent(agentType, role, raw?.content || "");
|
|
32924
|
+
});
|
|
32925
|
+
const lastTurnMessage = [...messages].reverse().find((raw) => {
|
|
32926
|
+
const role = raw?.role;
|
|
32927
|
+
if (role !== "user" && role !== "assistant") return false;
|
|
32928
|
+
return !!cleanupHistoryContent(agentType, role, raw?.content || "");
|
|
32929
|
+
});
|
|
32930
|
+
if (lastMessage) {
|
|
32931
|
+
this.lastSeenSignatures.set(dedupKey, buildHistoryMessageSignature(agentType, {
|
|
32932
|
+
role: lastMessage.role,
|
|
32933
|
+
content: lastMessage.content,
|
|
32934
|
+
kind: typeof lastMessage.kind === "string" ? lastMessage.kind : void 0
|
|
32935
|
+
}));
|
|
32936
|
+
} else {
|
|
32937
|
+
this.lastSeenSignatures.delete(dedupKey);
|
|
32938
|
+
}
|
|
32939
|
+
if (lastTurnMessage) {
|
|
32940
|
+
this.lastSeenTurnSignatures.set(dedupKey, buildHistoryMessageSignature(agentType, {
|
|
32941
|
+
role: lastTurnMessage.role,
|
|
32942
|
+
content: lastTurnMessage.content,
|
|
32943
|
+
kind: typeof lastTurnMessage.kind === "string" ? lastTurnMessage.kind : void 0
|
|
32944
|
+
}));
|
|
32945
|
+
} else {
|
|
32946
|
+
this.lastSeenTurnSignatures.delete(dedupKey);
|
|
32947
|
+
}
|
|
32948
|
+
}
|
|
32808
32949
|
appendSystemMarker(agentType, content, options = {}) {
|
|
32809
32950
|
this.appendNewMessages(
|
|
32810
32951
|
agentType,
|
|
@@ -32835,6 +32976,16 @@ ${data.message || ""}`.trim();
|
|
|
32835
32976
|
this.lastSeenHashes.set(toDedupKey, nextHashes);
|
|
32836
32977
|
this.lastSeenHashes.delete(fromDedupKey);
|
|
32837
32978
|
}
|
|
32979
|
+
const fromSignature = this.lastSeenSignatures.get(fromDedupKey);
|
|
32980
|
+
if (fromSignature) {
|
|
32981
|
+
this.lastSeenSignatures.set(toDedupKey, fromSignature);
|
|
32982
|
+
this.lastSeenSignatures.delete(fromDedupKey);
|
|
32983
|
+
}
|
|
32984
|
+
const fromTurnSignature = this.lastSeenTurnSignatures.get(fromDedupKey);
|
|
32985
|
+
if (fromTurnSignature) {
|
|
32986
|
+
this.lastSeenTurnSignatures.set(toDedupKey, fromTurnSignature);
|
|
32987
|
+
this.lastSeenTurnSignatures.delete(fromDedupKey);
|
|
32988
|
+
}
|
|
32838
32989
|
const fromCount = this.lastSeenCounts.get(fromDedupKey);
|
|
32839
32990
|
if (typeof fromCount === "number") {
|
|
32840
32991
|
this.lastSeenCounts.set(toDedupKey, Math.max(fromCount, this.lastSeenCounts.get(toDedupKey) || 0));
|
|
@@ -32876,10 +33027,61 @@ ${data.message || ""}`.trim();
|
|
|
32876
33027
|
} catch {
|
|
32877
33028
|
}
|
|
32878
33029
|
}
|
|
33030
|
+
compactHistorySession(agentType, historySessionId) {
|
|
33031
|
+
const sessionId = String(historySessionId || "").trim();
|
|
33032
|
+
if (!sessionId) return;
|
|
33033
|
+
try {
|
|
33034
|
+
const dir = path7.join(HISTORY_DIR, this.sanitize(agentType));
|
|
33035
|
+
if (!fs32.existsSync(dir)) return;
|
|
33036
|
+
const prefix = `${this.sanitize(sessionId)}_`;
|
|
33037
|
+
const files = fs32.readdirSync(dir).filter((file2) => file2.startsWith(prefix) && file2.endsWith(".jsonl")).sort();
|
|
33038
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33039
|
+
for (const file2 of files) {
|
|
33040
|
+
const filePath = path7.join(dir, file2);
|
|
33041
|
+
const lines = fs32.readFileSync(filePath, "utf-8").split("\n").filter(Boolean);
|
|
33042
|
+
const next = [];
|
|
33043
|
+
for (const line of lines) {
|
|
33044
|
+
let parsed = null;
|
|
33045
|
+
try {
|
|
33046
|
+
parsed = JSON.parse(line);
|
|
33047
|
+
} catch {
|
|
33048
|
+
parsed = null;
|
|
33049
|
+
}
|
|
33050
|
+
if (!parsed || parsed.historySessionId !== sessionId) continue;
|
|
33051
|
+
const sanitized = sanitizeHistoryMessage(agentType, parsed);
|
|
33052
|
+
if (!sanitized) continue;
|
|
33053
|
+
const hash2 = buildHistoryMessageHash(agentType, sanitized);
|
|
33054
|
+
if (seen.has(hash2)) continue;
|
|
33055
|
+
seen.add(hash2);
|
|
33056
|
+
next.push(sanitized);
|
|
33057
|
+
}
|
|
33058
|
+
next.sort((a, b2) => a.receivedAt - b2.receivedAt);
|
|
33059
|
+
const dedupedAdjacent = [];
|
|
33060
|
+
let lastTurn = null;
|
|
33061
|
+
for (const entry of next) {
|
|
33062
|
+
const previous = dedupedAdjacent[dedupedAdjacent.length - 1];
|
|
33063
|
+
if (isAdjacentHistoryDuplicate(agentType, previous, entry)) continue;
|
|
33064
|
+
if (entry.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, entry)) continue;
|
|
33065
|
+
dedupedAdjacent.push(entry);
|
|
33066
|
+
if (entry.role !== "system") lastTurn = entry;
|
|
33067
|
+
}
|
|
33068
|
+
const collapsed = collapseReplayAssistantTurns(agentType, dedupedAdjacent);
|
|
33069
|
+
if (collapsed.length === 0) {
|
|
33070
|
+
fs32.unlinkSync(filePath);
|
|
33071
|
+
continue;
|
|
33072
|
+
}
|
|
33073
|
+
fs32.writeFileSync(filePath, `${collapsed.map((entry) => JSON.stringify(entry)).join("\n")}
|
|
33074
|
+
`, "utf-8");
|
|
33075
|
+
}
|
|
33076
|
+
} catch {
|
|
33077
|
+
}
|
|
33078
|
+
}
|
|
32879
33079
|
/** Called when agent session is explicitly changed */
|
|
32880
33080
|
onSessionChange(agentType) {
|
|
32881
33081
|
this.lastSeenHashes.delete(agentType);
|
|
32882
33082
|
this.lastSeenCounts.delete(agentType);
|
|
33083
|
+
this.lastSeenSignatures.delete(agentType);
|
|
33084
|
+
this.lastSeenTurnSignatures.delete(agentType);
|
|
32883
33085
|
}
|
|
32884
33086
|
/** Delete history files older than 30 days */
|
|
32885
33087
|
async rotateOldFiles() {
|
|
@@ -32920,23 +33122,37 @@ ${data.message || ""}`.trim();
|
|
|
32920
33122
|
return true;
|
|
32921
33123
|
}).sort().reverse();
|
|
32922
33124
|
const allMessages = [];
|
|
32923
|
-
const
|
|
33125
|
+
const seen = /* @__PURE__ */ new Set();
|
|
32924
33126
|
for (const file2 of files) {
|
|
32925
|
-
if (allMessages.length >= needed) break;
|
|
32926
33127
|
const filePath = path7.join(dir, file2);
|
|
32927
33128
|
const content = fs32.readFileSync(filePath, "utf-8");
|
|
32928
33129
|
const lines = content.trim().split("\n").filter(Boolean);
|
|
32929
|
-
for (let i =
|
|
32930
|
-
if (allMessages.length >= needed) break;
|
|
33130
|
+
for (let i = 0; i < lines.length; i++) {
|
|
32931
33131
|
try {
|
|
32932
|
-
|
|
33132
|
+
const parsed = JSON.parse(lines[i]);
|
|
33133
|
+
const sanitizedMessage = sanitizeHistoryMessage(agentType, parsed);
|
|
33134
|
+
if (!sanitizedMessage) continue;
|
|
33135
|
+
const hash2 = buildHistoryMessageHash(agentType, sanitizedMessage);
|
|
33136
|
+
if (seen.has(hash2)) continue;
|
|
33137
|
+
seen.add(hash2);
|
|
33138
|
+
allMessages.push(sanitizedMessage);
|
|
32933
33139
|
} catch {
|
|
32934
33140
|
}
|
|
32935
33141
|
}
|
|
32936
33142
|
}
|
|
32937
|
-
|
|
32938
|
-
const
|
|
32939
|
-
|
|
33143
|
+
allMessages.sort((a, b2) => a.receivedAt - b2.receivedAt);
|
|
33144
|
+
const chronological = [];
|
|
33145
|
+
let lastTurn = null;
|
|
33146
|
+
for (const message of allMessages) {
|
|
33147
|
+
const previous = chronological[chronological.length - 1];
|
|
33148
|
+
if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
|
|
33149
|
+
if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
|
|
33150
|
+
chronological.push(message);
|
|
33151
|
+
if (message.role !== "system") lastTurn = message;
|
|
33152
|
+
}
|
|
33153
|
+
const collapsed = collapseReplayAssistantTurns(agentType, chronological);
|
|
33154
|
+
const sliced = collapsed.slice(offset, offset + limit);
|
|
33155
|
+
const hasMore = collapsed.length > offset + limit;
|
|
32940
33156
|
return { messages: sliced, hasMore };
|
|
32941
33157
|
} catch {
|
|
32942
33158
|
return { messages: [], hasMore: false };
|
|
@@ -34770,6 +34986,46 @@ ${effect.notification.body || ""}`.trim();
|
|
|
34770
34986
|
if (!parsed || typeof parsed !== "object") return false;
|
|
34771
34987
|
return parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true;
|
|
34772
34988
|
}
|
|
34989
|
+
async function readExtensionChatState(h) {
|
|
34990
|
+
try {
|
|
34991
|
+
const evalResult = await h.evaluateProviderScript("readChat", void 0, 5e4);
|
|
34992
|
+
if (!evalResult?.result) return null;
|
|
34993
|
+
const parsed = parseMaybeJson(evalResult.result);
|
|
34994
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
34995
|
+
} catch {
|
|
34996
|
+
return null;
|
|
34997
|
+
}
|
|
34998
|
+
}
|
|
34999
|
+
function getStateMessageCount(state) {
|
|
35000
|
+
return Array.isArray(state?.messages) ? state.messages.length : 0;
|
|
35001
|
+
}
|
|
35002
|
+
function getStateLastSignature(state) {
|
|
35003
|
+
const messages = Array.isArray(state?.messages) ? state.messages : [];
|
|
35004
|
+
const last = messages[messages.length - 1];
|
|
35005
|
+
if (!last) return "";
|
|
35006
|
+
return `${last.role || ""}:${String(last.content || "").replace(/\s+/g, " ").trim()}`;
|
|
35007
|
+
}
|
|
35008
|
+
async function getStableExtensionBaseline(h) {
|
|
35009
|
+
const first = await readExtensionChatState(h);
|
|
35010
|
+
if (getStateMessageCount(first) > 0 || getStateLastSignature(first)) return first;
|
|
35011
|
+
await new Promise((resolve12) => setTimeout(resolve12, 150));
|
|
35012
|
+
const second = await readExtensionChatState(h);
|
|
35013
|
+
return getStateMessageCount(second) >= getStateMessageCount(first) ? second : first;
|
|
35014
|
+
}
|
|
35015
|
+
async function verifyExtensionSendObserved(h, before) {
|
|
35016
|
+
const beforeCount = getStateMessageCount(before);
|
|
35017
|
+
const beforeSignature = getStateLastSignature(before);
|
|
35018
|
+
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
35019
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
35020
|
+
const state = await readExtensionChatState(h);
|
|
35021
|
+
if (state?.status === "waiting_approval") return true;
|
|
35022
|
+
const afterCount = getStateMessageCount(state);
|
|
35023
|
+
const afterSignature = getStateLastSignature(state);
|
|
35024
|
+
if (afterCount > beforeCount) return true;
|
|
35025
|
+
if (afterSignature && afterSignature !== beforeSignature) return true;
|
|
35026
|
+
}
|
|
35027
|
+
return false;
|
|
35028
|
+
}
|
|
34773
35029
|
async function handleChatHistory(h, args) {
|
|
34774
35030
|
const { agentType, offset, limit } = args;
|
|
34775
35031
|
const historySessionId = getHistorySessionId(h, args);
|
|
@@ -34950,12 +35206,17 @@ ${effect.notification.body || ""}`.trim();
|
|
|
34950
35206
|
if (isExtensionTransport(transport)) {
|
|
34951
35207
|
_log(`Extension: ${provider?.type || "unknown_extension"}`);
|
|
34952
35208
|
try {
|
|
35209
|
+
const beforeState = await getStableExtensionBaseline(h);
|
|
34953
35210
|
const evalResult = await h.evaluateProviderScript("sendMessage", { message: text }, 3e4);
|
|
34954
35211
|
if (evalResult?.result) {
|
|
34955
35212
|
const parsed = parseMaybeJson(evalResult.result);
|
|
34956
35213
|
if (didProviderConfirmSend(parsed)) {
|
|
34957
|
-
|
|
34958
|
-
|
|
35214
|
+
const observed = await verifyExtensionSendObserved(h, beforeState);
|
|
35215
|
+
if (observed) {
|
|
35216
|
+
_log(`Extension script sent OK`);
|
|
35217
|
+
return _logSendSuccess("extension-script");
|
|
35218
|
+
}
|
|
35219
|
+
_log(`Extension script reported send but no chat-state change was observed`);
|
|
34959
35220
|
}
|
|
34960
35221
|
if (parsed?.needsTypeAndSend) {
|
|
34961
35222
|
_log(`Extension needsTypeAndSend \u2192 AgentStreamManager`);
|
|
@@ -35460,7 +35721,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
35460
35721
|
return { success: true, buttonIndex, button: buttons[buttonIndex] ?? button };
|
|
35461
35722
|
}
|
|
35462
35723
|
if (isExtensionTransport(transport) && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
|
|
35463
|
-
const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action);
|
|
35724
|
+
const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action, button);
|
|
35464
35725
|
return { success: ok };
|
|
35465
35726
|
}
|
|
35466
35727
|
if (transport === "acp") {
|
|
@@ -36855,6 +37116,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36855
37116
|
historyWriter;
|
|
36856
37117
|
runtimeMessages = [];
|
|
36857
37118
|
instanceId;
|
|
37119
|
+
suppressIdleHistoryReplay = false;
|
|
36858
37120
|
presentationMode;
|
|
36859
37121
|
providerSessionId;
|
|
36860
37122
|
launchMode;
|
|
@@ -36882,7 +37144,15 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36882
37144
|
await this.adapter.spawn();
|
|
36883
37145
|
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
36884
37146
|
if (this.providerSessionId) {
|
|
37147
|
+
this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
|
|
36885
37148
|
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
37149
|
+
this.historyWriter.seedSessionHistory(
|
|
37150
|
+
this.type,
|
|
37151
|
+
restoredHistory.messages,
|
|
37152
|
+
this.providerSessionId,
|
|
37153
|
+
this.instanceId
|
|
37154
|
+
);
|
|
37155
|
+
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
36886
37156
|
if (restoredHistory.messages.length > 0) {
|
|
36887
37157
|
this.adapter.seedCommittedMessages(
|
|
36888
37158
|
restoredHistory.messages.map((message) => ({
|
|
@@ -36926,7 +37196,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36926
37196
|
} else if (this.type === "codex-cli") {
|
|
36927
37197
|
probedSessionId = this.probeSessionIdFromConfig({
|
|
36928
37198
|
dbPath: "~/.codex/state_5.sqlite",
|
|
36929
|
-
query: "select id from threads where cwd in ({dirs}) and
|
|
37199
|
+
query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
|
|
36930
37200
|
timestampFormat: "unix_s"
|
|
36931
37201
|
});
|
|
36932
37202
|
} else if (this.type === "goose-cli") {
|
|
@@ -36986,6 +37256,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36986
37256
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
36987
37257
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
36988
37258
|
if (parsedMessages.length > 0) {
|
|
37259
|
+
const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
|
|
36989
37260
|
let messagesToSave = parsedMessages;
|
|
36990
37261
|
if (parsedStatus?.status === "generating" || parsedStatus?.status === "long_generating") {
|
|
36991
37262
|
const lastIdx = messagesToSave.length - 1;
|
|
@@ -36993,7 +37264,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
36993
37264
|
messagesToSave = messagesToSave.slice(0, lastIdx);
|
|
36994
37265
|
}
|
|
36995
37266
|
}
|
|
36996
|
-
if (messagesToSave.length > 0) {
|
|
37267
|
+
if (!shouldSkipReplayPersist && messagesToSave.length > 0) {
|
|
36997
37268
|
this.historyWriter.appendNewMessages(
|
|
36998
37269
|
this.type,
|
|
36999
37270
|
messagesToSave,
|
|
@@ -37088,6 +37359,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37088
37359
|
if (newStatus !== this.lastStatus) {
|
|
37089
37360
|
LOG2.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
37090
37361
|
if (this.lastStatus === "idle" && newStatus === "generating") {
|
|
37362
|
+
this.suppressIdleHistoryReplay = false;
|
|
37091
37363
|
if (this.completedDebouncePending) {
|
|
37092
37364
|
LOG2.info("CLI", `[${this.type}] cancelled pending completed (resumed generating)`);
|
|
37093
37365
|
if (this.completedDebounceTimer) {
|
|
@@ -37107,6 +37379,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
37107
37379
|
this.generatingDebounceTimer = null;
|
|
37108
37380
|
}, 1e3);
|
|
37109
37381
|
} else if (newStatus === "waiting_approval") {
|
|
37382
|
+
this.suppressIdleHistoryReplay = false;
|
|
37110
37383
|
if (this.generatingDebouncePending) {
|
|
37111
37384
|
if (this.generatingDebounceTimer) {
|
|
37112
37385
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -38811,6 +39084,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38811
39084
|
if (!instanceManager) return 0;
|
|
38812
39085
|
const sessions = records || await this.deps.listHostedCliRuntimes?.() || [];
|
|
38813
39086
|
let restored = 0;
|
|
39087
|
+
const restoredBindings = /* @__PURE__ */ new Set();
|
|
38814
39088
|
for (const record2 of sessions) {
|
|
38815
39089
|
if (!record2?.runtimeId || !record2?.cliType || !record2?.workspace) continue;
|
|
38816
39090
|
if (this.adapters.has(record2.runtimeId) || instanceManager.getInstance(record2.runtimeId)) continue;
|
|
@@ -38824,6 +39098,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38824
39098
|
record2.cliArgs,
|
|
38825
39099
|
record2.providerSessionId
|
|
38826
39100
|
);
|
|
39101
|
+
const bindingKey = [
|
|
39102
|
+
normalizedType,
|
|
39103
|
+
record2.workspace,
|
|
39104
|
+
sessionBinding.providerSessionId || record2.runtimeId
|
|
39105
|
+
].join("::");
|
|
39106
|
+
if (restoredBindings.has(bindingKey)) {
|
|
39107
|
+
LOG2.info(
|
|
39108
|
+
"CLI",
|
|
39109
|
+
`\u21B7 Skipping duplicate hosted runtime restore: ${record2.runtimeKey || record2.runtimeId} (${normalizedType} @ ${record2.workspace}) binding=${sessionBinding.providerSessionId || "runtime"}`
|
|
39110
|
+
);
|
|
39111
|
+
continue;
|
|
39112
|
+
}
|
|
38827
39113
|
try {
|
|
38828
39114
|
await this.registerCliInstance(
|
|
38829
39115
|
record2.runtimeId,
|
|
@@ -38839,6 +39125,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
38839
39125
|
launchMode: "manual"
|
|
38840
39126
|
}
|
|
38841
39127
|
);
|
|
39128
|
+
restoredBindings.add(bindingKey);
|
|
38842
39129
|
restored += 1;
|
|
38843
39130
|
LOG2.info("CLI", `\u267B Restored hosted runtime: ${record2.runtimeKey || record2.runtimeId} (${record2.displayName || record2.workspace})`);
|
|
38844
39131
|
} catch (error48) {
|
|
@@ -41172,6 +41459,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41172
41459
|
const record2 = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
41173
41460
|
return { success: true, record: record2 };
|
|
41174
41461
|
}
|
|
41462
|
+
case "session_host_prune_duplicate_sessions": {
|
|
41463
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41464
|
+
const result = await this.deps.sessionHostControl.pruneDuplicateSessions({
|
|
41465
|
+
providerType: typeof args?.providerType === "string" ? args.providerType : void 0,
|
|
41466
|
+
workspace: typeof args?.workspace === "string" ? args.workspace : void 0,
|
|
41467
|
+
dryRun: args?.dryRun === true
|
|
41468
|
+
});
|
|
41469
|
+
return { success: true, result };
|
|
41470
|
+
}
|
|
41175
41471
|
case "session_host_acquire_write": {
|
|
41176
41472
|
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
41177
41473
|
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
@@ -41749,6 +42045,51 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41749
42045
|
isTransportError(reason) {
|
|
41750
42046
|
return /Session with given id not found/i.test(reason) || /CDP not connected/i.test(reason) || /Target closed/i.test(reason) || /WebSocket not open/i.test(reason) || /not connected/i.test(reason) || /execution context/i.test(reason) || /Cannot find context with specified id/i.test(reason);
|
|
41751
42047
|
}
|
|
42048
|
+
titlesMatch(actual, expected) {
|
|
42049
|
+
const lhs = actual.trim().toLowerCase();
|
|
42050
|
+
const rhs = expected.trim().toLowerCase();
|
|
42051
|
+
if (!lhs || !rhs) return false;
|
|
42052
|
+
return lhs === rhs || lhs.includes(rhs) || rhs.includes(lhs);
|
|
42053
|
+
}
|
|
42054
|
+
messageCount(state) {
|
|
42055
|
+
return Array.isArray(state?.messages) ? state.messages.length : 0;
|
|
42056
|
+
}
|
|
42057
|
+
lastMessageSignature(state) {
|
|
42058
|
+
const messages = Array.isArray(state?.messages) ? state.messages : [];
|
|
42059
|
+
const last = messages[messages.length - 1];
|
|
42060
|
+
if (!last) return "";
|
|
42061
|
+
return `${last.role || ""}:${String(last.content || "").replace(/\s+/g, " ").trim()}`;
|
|
42062
|
+
}
|
|
42063
|
+
async verifySendOutcome(evaluate, before) {
|
|
42064
|
+
const beforeCount = this.messageCount(before);
|
|
42065
|
+
const beforeSignature = this.lastMessageSignature(before);
|
|
42066
|
+
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
42067
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
42068
|
+
let state;
|
|
42069
|
+
try {
|
|
42070
|
+
state = await this.readChat(evaluate);
|
|
42071
|
+
} catch {
|
|
42072
|
+
continue;
|
|
42073
|
+
}
|
|
42074
|
+
if (state.status === "waiting_approval") {
|
|
42075
|
+
return true;
|
|
42076
|
+
}
|
|
42077
|
+
const afterCount = this.messageCount(state);
|
|
42078
|
+
const afterSignature = this.lastMessageSignature(state);
|
|
42079
|
+
if (afterCount > beforeCount) return true;
|
|
42080
|
+
if (afterSignature && afterSignature !== beforeSignature) return true;
|
|
42081
|
+
}
|
|
42082
|
+
return false;
|
|
42083
|
+
}
|
|
42084
|
+
async readStableBaselineState(evaluate) {
|
|
42085
|
+
const first = await this.readChat(evaluate);
|
|
42086
|
+
if (this.messageCount(first) > 0 || this.lastMessageSignature(first)) {
|
|
42087
|
+
return first;
|
|
42088
|
+
}
|
|
42089
|
+
await new Promise((resolve12) => setTimeout(resolve12, 150));
|
|
42090
|
+
const second = await this.readChat(evaluate);
|
|
42091
|
+
return this.messageCount(second) >= this.messageCount(first) ? second : first;
|
|
42092
|
+
}
|
|
41752
42093
|
async readChat(evaluate) {
|
|
41753
42094
|
const script = this.callScript("readChat");
|
|
41754
42095
|
if (!script) return this.errorState("readChat script not available");
|
|
@@ -41774,6 +42115,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41774
42115
|
mode: data.mode,
|
|
41775
42116
|
activeModal: data.activeModal
|
|
41776
42117
|
};
|
|
42118
|
+
if (typeof data.title === "string" && data.title.trim()) {
|
|
42119
|
+
state.title = data.title.trim();
|
|
42120
|
+
}
|
|
41777
42121
|
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
41778
42122
|
if (controlValues) state.controlValues = controlValues;
|
|
41779
42123
|
const effects = normalizeProviderEffects(data);
|
|
@@ -41797,6 +42141,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41797
42141
|
}
|
|
41798
42142
|
}
|
|
41799
42143
|
async sendMessage(evaluate, text) {
|
|
42144
|
+
let beforeState = null;
|
|
42145
|
+
try {
|
|
42146
|
+
beforeState = await this.readStableBaselineState(evaluate);
|
|
42147
|
+
} catch {
|
|
42148
|
+
beforeState = null;
|
|
42149
|
+
}
|
|
41800
42150
|
const params = { message: text };
|
|
41801
42151
|
const script = this.callScript("sendMessage", params) || this.callScript("sendMessage", text);
|
|
41802
42152
|
if (!script) throw new Error(`[${this.agentName}] sendMessage script not available`);
|
|
@@ -41814,7 +42164,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41814
42164
|
}
|
|
41815
42165
|
if (parsed && typeof parsed === "object") {
|
|
41816
42166
|
if (parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true) {
|
|
41817
|
-
|
|
42167
|
+
const verified = await this.verifySendOutcome(evaluate, beforeState);
|
|
42168
|
+
if (verified) return;
|
|
42169
|
+
throw new Error(`[${this.agentName}] sendMessage was not observed in chat state`);
|
|
41818
42170
|
}
|
|
41819
42171
|
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
41820
42172
|
throw new Error(`[${this.agentName}] sendMessage failed: ${parsed.error}`);
|
|
@@ -41825,7 +42177,15 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41825
42177
|
async resolveAction(evaluate, action, button) {
|
|
41826
42178
|
const script = this.callScript("resolveAction", { action, button });
|
|
41827
42179
|
if (!script) return false;
|
|
41828
|
-
|
|
42180
|
+
const result = await evaluate(script);
|
|
42181
|
+
const parsed = this.parseMaybeJson(result);
|
|
42182
|
+
if (parsed === true) return true;
|
|
42183
|
+
if (typeof parsed === "string") {
|
|
42184
|
+
const normalized = parsed.trim().toLowerCase();
|
|
42185
|
+
return normalized === "ok" || normalized === "success" || normalized === "true" || normalized === "resolved" || normalized === "approved" || normalized === "rejected";
|
|
42186
|
+
}
|
|
42187
|
+
if (!parsed || typeof parsed !== "object") return false;
|
|
42188
|
+
return parsed.resolved === true || parsed.success === true || parsed.ok === true || parsed.found === true;
|
|
41829
42189
|
}
|
|
41830
42190
|
async newSession(evaluate) {
|
|
41831
42191
|
const script = this.callScript("newSession");
|
|
@@ -41862,7 +42222,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
41862
42222
|
return normalized === "true" || normalized === "ok" || normalized === "switched" || normalized === "success";
|
|
41863
42223
|
}
|
|
41864
42224
|
if (data && typeof data === "object") {
|
|
41865
|
-
|
|
42225
|
+
if (data.switched === true || data.success === true || data.ok === true) return true;
|
|
42226
|
+
if (typeof data.error === "string" && data.error.trim()) return false;
|
|
42227
|
+
}
|
|
42228
|
+
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
42229
|
+
await new Promise((resolve12) => setTimeout(resolve12, 250));
|
|
42230
|
+
const state = await this.readChat(evaluate);
|
|
42231
|
+
const title = typeof state.title === "string" ? state.title : "";
|
|
42232
|
+
if (this.titlesMatch(title, sessionId)) return true;
|
|
41866
42233
|
}
|
|
41867
42234
|
return false;
|
|
41868
42235
|
}
|
|
@@ -42068,7 +42435,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42068
42435
|
return false;
|
|
42069
42436
|
}
|
|
42070
42437
|
}
|
|
42071
|
-
async resolveSessionAction(cdp, sessionId, action) {
|
|
42438
|
+
async resolveSessionAction(cdp, sessionId, action, button) {
|
|
42072
42439
|
await this.ensureSessionPanelOpen(sessionId);
|
|
42073
42440
|
const target = this.getSessionTarget(sessionId);
|
|
42074
42441
|
if (!target?.parentSessionId) return false;
|
|
@@ -42078,7 +42445,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
42078
42445
|
if (!agent) return false;
|
|
42079
42446
|
try {
|
|
42080
42447
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
42081
|
-
return await agent.adapter.resolveAction(evaluate, action);
|
|
42448
|
+
return await agent.adapter.resolveAction(evaluate, action, button);
|
|
42082
42449
|
} catch (e) {
|
|
42083
42450
|
this.logFn(`[AgentStream] resolveAction(${sessionId}) error: ${e.message}`);
|
|
42084
42451
|
return false;
|
|
@@ -48995,6 +49362,9 @@ var StandaloneSessionHostControlPlane = class {
|
|
|
48995
49362
|
async forceDetachClient(sessionId, clientId) {
|
|
48996
49363
|
return this.request("force_detach_client", { sessionId, clientId });
|
|
48997
49364
|
}
|
|
49365
|
+
async pruneDuplicateSessions(payload = {}) {
|
|
49366
|
+
return this.request("prune_duplicate_sessions", payload);
|
|
49367
|
+
}
|
|
48998
49368
|
async acquireWrite(payload) {
|
|
48999
49369
|
return this.request("acquire_write", payload);
|
|
49000
49370
|
}
|