chat-recall 0.7.8 → 0.7.10
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.js +198 -42
- package/dist/cli.js.map +1 -1
- package/dist/derived.d.ts.map +1 -1
- package/dist/derived.js +2 -5
- package/dist/derived.js.map +1 -1
- package/dist/escalate.d.ts +2 -0
- package/dist/escalate.d.ts.map +1 -1
- package/dist/escalate.js +2 -1
- package/dist/escalate.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +6821 -6565
- package/dist/scan-worker.js +109 -8
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +9 -7
- package/dist/sync-client.js.map +1 -1
- package/dist/watch.js +177 -39
- package/package.json +1 -1
- package/skills/chat-recall/SKILL.md +1 -1
- package/skills/chat-recall-find/SKILL.md +4 -2
- package/skills/chat-recall-resume/SKILL.md +3 -1
package/dist/cli.js
CHANGED
|
@@ -4568,6 +4568,72 @@ var init_banners = __esm({
|
|
|
4568
4568
|
}
|
|
4569
4569
|
});
|
|
4570
4570
|
|
|
4571
|
+
// ../engine/dist/core/claude-prompt-origin.js
|
|
4572
|
+
function originFromText(text) {
|
|
4573
|
+
const head = text.trimStart();
|
|
4574
|
+
for (const [prefix, origin] of INJECTED_PREFIXES) {
|
|
4575
|
+
if (head.startsWith(prefix))
|
|
4576
|
+
return origin;
|
|
4577
|
+
}
|
|
4578
|
+
return "human";
|
|
4579
|
+
}
|
|
4580
|
+
function declaredOrigin(value) {
|
|
4581
|
+
if (!value || typeof value !== "object")
|
|
4582
|
+
return void 0;
|
|
4583
|
+
const kind = value.kind;
|
|
4584
|
+
return typeof kind === "string" && kind ? kind : void 0;
|
|
4585
|
+
}
|
|
4586
|
+
function userRecordOrigin(obj, text) {
|
|
4587
|
+
if (obj.isSidechain === true)
|
|
4588
|
+
return "subagent";
|
|
4589
|
+
const declared = declaredOrigin(obj.origin);
|
|
4590
|
+
if (declared && declared !== "human")
|
|
4591
|
+
return declared;
|
|
4592
|
+
if (obj.isMeta === true)
|
|
4593
|
+
return "meta";
|
|
4594
|
+
if (declared === "human")
|
|
4595
|
+
return "human";
|
|
4596
|
+
return originFromText(text);
|
|
4597
|
+
}
|
|
4598
|
+
function queuedCommandPrompt(obj) {
|
|
4599
|
+
if (obj.type !== "attachment")
|
|
4600
|
+
return null;
|
|
4601
|
+
const att = obj.attachment;
|
|
4602
|
+
if (!att || att.type !== "queued_command")
|
|
4603
|
+
return null;
|
|
4604
|
+
const text = promptText(att.prompt);
|
|
4605
|
+
if (!text)
|
|
4606
|
+
return null;
|
|
4607
|
+
if (obj.isSidechain === true)
|
|
4608
|
+
return { text, origin: "subagent" };
|
|
4609
|
+
const declared = declaredOrigin(att.origin);
|
|
4610
|
+
if (declared)
|
|
4611
|
+
return { text, origin: declared };
|
|
4612
|
+
return { text, origin: att.humanTurn === true ? "human" : originFromText(text) };
|
|
4613
|
+
}
|
|
4614
|
+
function promptText(prompt) {
|
|
4615
|
+
if (typeof prompt === "string")
|
|
4616
|
+
return prompt;
|
|
4617
|
+
if (!Array.isArray(prompt))
|
|
4618
|
+
return "";
|
|
4619
|
+
return prompt.filter((b) => !!b && typeof b === "object" && b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n");
|
|
4620
|
+
}
|
|
4621
|
+
function isPersonMessage(m) {
|
|
4622
|
+
return m.role === "user" && !m.origin;
|
|
4623
|
+
}
|
|
4624
|
+
var INJECTED_PREFIXES;
|
|
4625
|
+
var init_claude_prompt_origin = __esm({
|
|
4626
|
+
"../engine/dist/core/claude-prompt-origin.js"() {
|
|
4627
|
+
"use strict";
|
|
4628
|
+
INJECTED_PREFIXES = [
|
|
4629
|
+
["<task-notification", "task-notification"],
|
|
4630
|
+
["<agent-message", "peer"],
|
|
4631
|
+
["Another Claude session sent a message:", "peer"],
|
|
4632
|
+
["Stop hook feedback:", "hook"]
|
|
4633
|
+
];
|
|
4634
|
+
}
|
|
4635
|
+
});
|
|
4636
|
+
|
|
4571
4637
|
// ../engine/dist/core/project-path-match.js
|
|
4572
4638
|
function canonicalProjectPath(p) {
|
|
4573
4639
|
return (p || "").trim().replace(/\\/g, "/").replace(/[-_]/g, "/").replace(/\/{2,}/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
@@ -5809,7 +5875,8 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
|
|
|
5809
5875
|
const filesToParse = hasSubagentsDir(sessionPath) ? [sessionPath, ...getSubagentPaths(sessionPath)] : [sessionPath];
|
|
5810
5876
|
let userCount = 0;
|
|
5811
5877
|
const seenPrompts = /* @__PURE__ */ new Set();
|
|
5812
|
-
const
|
|
5878
|
+
const pendingQueued = /* @__PURE__ */ new Set();
|
|
5879
|
+
const recordPrompt = (raw, line, via = "record") => {
|
|
5813
5880
|
if (userCount >= maxMessages)
|
|
5814
5881
|
return;
|
|
5815
5882
|
const withoutReminders = raw.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "");
|
|
@@ -5818,8 +5885,14 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
|
|
|
5818
5885
|
const cleanedText = stripInjectedBanners(withoutReminders).trim();
|
|
5819
5886
|
if (cleanedText.length < 10)
|
|
5820
5887
|
return;
|
|
5821
|
-
if (
|
|
5888
|
+
if (via === "enqueue") {
|
|
5889
|
+
if (seenPrompts.has(cleanedText))
|
|
5890
|
+
return;
|
|
5891
|
+
pendingQueued.add(cleanedText);
|
|
5892
|
+
} else if (pendingQueued.has(cleanedText)) {
|
|
5893
|
+
pendingQueued.delete(cleanedText);
|
|
5822
5894
|
return;
|
|
5895
|
+
}
|
|
5823
5896
|
seenPrompts.add(cleanedText);
|
|
5824
5897
|
content.userMessages.push({ text: cleanedText, lineNumber: line, contentType: "user" });
|
|
5825
5898
|
userCount++;
|
|
@@ -5904,12 +5977,16 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
|
|
|
5904
5977
|
text = textParts.join("\n");
|
|
5905
5978
|
}
|
|
5906
5979
|
}
|
|
5907
|
-
if (text)
|
|
5980
|
+
if (text && userRecordOrigin(obj, text) === "human")
|
|
5908
5981
|
recordPrompt(text, lineNum);
|
|
5909
5982
|
} else if (msgType === "queue-operation") {
|
|
5910
|
-
if (obj.operation === "enqueue" && typeof obj.content === "string") {
|
|
5911
|
-
recordPrompt(obj.content, lineNum,
|
|
5983
|
+
if (obj.operation === "enqueue" && typeof obj.content === "string" && originFromText(obj.content) === "human") {
|
|
5984
|
+
recordPrompt(obj.content, lineNum, "enqueue");
|
|
5912
5985
|
}
|
|
5986
|
+
} else if (msgType === "attachment") {
|
|
5987
|
+
const queued = queuedCommandPrompt(obj);
|
|
5988
|
+
if (queued?.origin === "human")
|
|
5989
|
+
recordPrompt(queued.text, lineNum, "delivery");
|
|
5913
5990
|
} else if (msgType === "assistant") {
|
|
5914
5991
|
const msg = obj.message;
|
|
5915
5992
|
if (!msg || typeof msg !== "object")
|
|
@@ -6013,6 +6090,7 @@ var init_session = __esm({
|
|
|
6013
6090
|
"../engine/dist/parsers/session.js"() {
|
|
6014
6091
|
"use strict";
|
|
6015
6092
|
init_banners();
|
|
6093
|
+
init_claude_prompt_origin();
|
|
6016
6094
|
init_claude2();
|
|
6017
6095
|
init_tool_paths();
|
|
6018
6096
|
init_project_dir_name();
|
|
@@ -6177,7 +6255,16 @@ function messagesFromRawLines(raw) {
|
|
|
6177
6255
|
const cleaned = stripBanners(text);
|
|
6178
6256
|
if (!cleaned)
|
|
6179
6257
|
continue;
|
|
6180
|
-
|
|
6258
|
+
const origin = userRecordOrigin(obj, cleaned);
|
|
6259
|
+
messages.push({ line, role: "user", content: cleaned, timestamp, ...origin === "human" ? {} : { origin } });
|
|
6260
|
+
} else if (obj.type === "attachment") {
|
|
6261
|
+
const queued = queuedCommandPrompt(obj);
|
|
6262
|
+
if (!queued)
|
|
6263
|
+
continue;
|
|
6264
|
+
const cleaned = stripBanners(queued.text);
|
|
6265
|
+
if (!cleaned)
|
|
6266
|
+
continue;
|
|
6267
|
+
messages.push({ line, role: "user", content: cleaned, timestamp, ...queued.origin === "human" ? {} : { origin: queued.origin } });
|
|
6181
6268
|
} else if (obj.type === "assistant") {
|
|
6182
6269
|
const blocks = Array.isArray(obj.message?.content) ? obj.message.content : [];
|
|
6183
6270
|
const thinkingBlock = blocks.find((c) => c?.type === "thinking");
|
|
@@ -6273,6 +6360,7 @@ var init_claude = __esm({
|
|
|
6273
6360
|
"../engine/dist/transcript/claude.js"() {
|
|
6274
6361
|
"use strict";
|
|
6275
6362
|
init_logger();
|
|
6363
|
+
init_claude_prompt_origin();
|
|
6276
6364
|
log2 = createLogger("transcript-claude");
|
|
6277
6365
|
INJECTED_BANNERS2 = [
|
|
6278
6366
|
/MCP issues detected\. ?Run \/mcp list for status\.?/g,
|
|
@@ -6885,10 +6973,15 @@ function summarizeMarkers(marked) {
|
|
|
6885
6973
|
}
|
|
6886
6974
|
return counts;
|
|
6887
6975
|
}
|
|
6888
|
-
|
|
6976
|
+
function markersFromTurns(sessionId, turns) {
|
|
6977
|
+
const prompts = turns.filter((t) => t.kind === "user" && t.text).map((t) => ({ line: t.line, ts: t.ts, tsIso: t.tsIso, ...markPrompt(t.text) }));
|
|
6978
|
+
return { v: MARKERS_VERSION, sessionId, prompts, summary: summarizeMarkers(prompts) };
|
|
6979
|
+
}
|
|
6980
|
+
var PROFANITY, PROFANITY_LOOSE, APPROVAL_HEAD, NEG_HEAD, QUESTION_HEAD, DIRECTIVE_HEAD, CLARIFY_PHRASES, FRUSTRATED_PHRASES, MARKERS_VERSION;
|
|
6889
6981
|
var init_session_sentiment = __esm({
|
|
6890
6982
|
"../engine/dist/core/session-sentiment.js"() {
|
|
6891
6983
|
"use strict";
|
|
6984
|
+
init_claude_prompt_origin();
|
|
6892
6985
|
PROFANITY = /\b(fuck(?:ing|er|ed)?|shit|ffs|wtf|bullshit|crap|damn(?:it)?|hell)\b/i;
|
|
6893
6986
|
PROFANITY_LOOSE = /\b(fu[ckj]+(?:ing|er|ed|c?k)?|fukc|fucj|sht|fk|wt[ft])\b/i;
|
|
6894
6987
|
APPROVAL_HEAD = /^(?:yes|y|ok(?:ay)?|sure|alright|fine|i\s*approve|approved|go\s*(?:on|ahead)|do\s*it|continue|please\s*do|sounds?\s*good|let'?s\s*go|ship\s*it|👍|✓+)\b/i;
|
|
@@ -6897,6 +6990,7 @@ var init_session_sentiment = __esm({
|
|
|
6897
6990
|
DIRECTIVE_HEAD = /^(?:please\s+)?(?:use|implement|build|make|add|create|fix|remove|delete|update|refactor|run|deploy|push|merge|test|check|investigate|find|search|show|list|generate|set\s+up|ensure)\b/i;
|
|
6898
6991
|
CLARIFY_PHRASES = /\b(?:wdym|what do you mean|explain|clarify|what is|what's|huh\??|i don'?t understand)\b/i;
|
|
6899
6992
|
FRUSTRATED_PHRASES = /\b(?:why (?:the )?(?:fuck|hell)|wtf|are you (?:kidding|serious)|stop slacking|stop making|why did you|why didn'?t you|i (?:fucking )?(?:asked|told you)|are you (?:listening|even)|come\s*on|just\s+do)\b/i;
|
|
6993
|
+
MARKERS_VERSION = 2;
|
|
6900
6994
|
}
|
|
6901
6995
|
});
|
|
6902
6996
|
|
|
@@ -11365,6 +11459,7 @@ var init_claude2 = __esm({
|
|
|
11365
11459
|
init_first_prompt();
|
|
11366
11460
|
init_tail_read();
|
|
11367
11461
|
init_project_dir_name();
|
|
11462
|
+
init_claude_prompt_origin();
|
|
11368
11463
|
init_generic_engine();
|
|
11369
11464
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
11370
11465
|
ClaudeBackend = class {
|
|
@@ -11672,6 +11767,15 @@ var init_claude2 = __esm({
|
|
|
11672
11767
|
}
|
|
11673
11768
|
appendEventsFromText(events, raw, mtime, startLine) {
|
|
11674
11769
|
let lineNum = startLine;
|
|
11770
|
+
const queued = /* @__PURE__ */ new Map();
|
|
11771
|
+
const superseded = /* @__PURE__ */ new Set();
|
|
11772
|
+
const pushPrompt = (e) => {
|
|
11773
|
+
const pending = queued.get(e.text);
|
|
11774
|
+
const earlier = pending?.shift();
|
|
11775
|
+
if (earlier)
|
|
11776
|
+
superseded.add(earlier);
|
|
11777
|
+
events.push(e);
|
|
11778
|
+
};
|
|
11675
11779
|
{
|
|
11676
11780
|
for (const line of raw.split("\n")) {
|
|
11677
11781
|
lineNum++;
|
|
@@ -11687,13 +11791,26 @@ var init_claude2 = __esm({
|
|
|
11687
11791
|
const ts = tsIso ? Date.parse(tsIso) || mtime : mtime;
|
|
11688
11792
|
if (obj.type === "queue-operation") {
|
|
11689
11793
|
if (obj.operation === "enqueue" && typeof obj.content === "string") {
|
|
11690
|
-
const
|
|
11691
|
-
if (
|
|
11692
|
-
|
|
11794
|
+
const text = stripReminders(obj.content);
|
|
11795
|
+
if (text && originFromText(text) === "human") {
|
|
11796
|
+
const e = { kind: "user", ts, tsIso, line: lineNum, text };
|
|
11797
|
+
events.push(e);
|
|
11798
|
+
const list = queued.get(text);
|
|
11799
|
+
if (list)
|
|
11800
|
+
list.push(e);
|
|
11801
|
+
else
|
|
11802
|
+
queued.set(text, [e]);
|
|
11693
11803
|
}
|
|
11694
11804
|
}
|
|
11695
11805
|
continue;
|
|
11696
11806
|
}
|
|
11807
|
+
const delivered = queuedCommandPrompt(obj);
|
|
11808
|
+
if (delivered) {
|
|
11809
|
+
const text = stripReminders(delivered.text);
|
|
11810
|
+
if (text && delivered.origin === "human")
|
|
11811
|
+
pushPrompt({ kind: "user", ts, tsIso, line: lineNum, text });
|
|
11812
|
+
continue;
|
|
11813
|
+
}
|
|
11697
11814
|
if (obj.type === "user") {
|
|
11698
11815
|
const msg = obj.message;
|
|
11699
11816
|
const content = msg?.content;
|
|
@@ -11728,8 +11845,9 @@ var init_claude2 = __esm({
|
|
|
11728
11845
|
}
|
|
11729
11846
|
}
|
|
11730
11847
|
const spoken = stripReminders(text);
|
|
11731
|
-
if (spoken)
|
|
11732
|
-
|
|
11848
|
+
if (spoken && userRecordOrigin(obj, spoken) === "human") {
|
|
11849
|
+
pushPrompt({ kind: "user", ts, tsIso, line: lineNum, text: spoken });
|
|
11850
|
+
}
|
|
11733
11851
|
for (const tr of toolResults) {
|
|
11734
11852
|
events.push({
|
|
11735
11853
|
kind: "tool_result",
|
|
@@ -11778,6 +11896,13 @@ var init_claude2 = __esm({
|
|
|
11778
11896
|
}
|
|
11779
11897
|
}
|
|
11780
11898
|
}
|
|
11899
|
+
if (superseded.size > 0) {
|
|
11900
|
+
let w = 0;
|
|
11901
|
+
for (const e of events)
|
|
11902
|
+
if (!superseded.has(e))
|
|
11903
|
+
events[w++] = e;
|
|
11904
|
+
events.length = w;
|
|
11905
|
+
}
|
|
11781
11906
|
return lineNum;
|
|
11782
11907
|
}
|
|
11783
11908
|
// ── Per-session operations — all delegate to the generic engine ─
|
|
@@ -18640,7 +18765,7 @@ var init_http = __esm({
|
|
|
18640
18765
|
CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18641
18766
|
} catch {
|
|
18642
18767
|
try {
|
|
18643
|
-
if (true) CLI_VERSION = "0.7.
|
|
18768
|
+
if (true) CLI_VERSION = "0.7.10";
|
|
18644
18769
|
} catch {
|
|
18645
18770
|
}
|
|
18646
18771
|
}
|
|
@@ -18685,8 +18810,7 @@ function collectDerivedRows(ref, mtime, count, maxRowBytes) {
|
|
|
18685
18810
|
if (fullOutcome.found) data = fullOutcome.commits;
|
|
18686
18811
|
} else if (kind === "markers") {
|
|
18687
18812
|
const turns = extractTurnsAny(id, { maxTurns: 5e4 });
|
|
18688
|
-
|
|
18689
|
-
data = { sessionId: id, prompts, summary: summarizeMarkers(prompts) };
|
|
18813
|
+
data = markersFromTurns(id, turns.turns);
|
|
18690
18814
|
}
|
|
18691
18815
|
} catch {
|
|
18692
18816
|
data = null;
|
|
@@ -19139,7 +19263,7 @@ var init_telemetry = __esm({
|
|
|
19139
19263
|
init_sync_client();
|
|
19140
19264
|
cliVersion2 = () => {
|
|
19141
19265
|
try {
|
|
19142
|
-
return true ? "0.7.
|
|
19266
|
+
return true ? "0.7.10" : "dev";
|
|
19143
19267
|
} catch {
|
|
19144
19268
|
return "dev";
|
|
19145
19269
|
}
|
|
@@ -19156,9 +19280,13 @@ __export(collector_health_exports, {
|
|
|
19156
19280
|
STALE_AFTER_MS: () => STALE_AFTER_MS,
|
|
19157
19281
|
applySyncOutcome: () => applySyncOutcome,
|
|
19158
19282
|
collectorHealthPath: () => collectorHealthPath,
|
|
19283
|
+
crashesAtBoot: () => crashesAtBoot,
|
|
19284
|
+
firstSyncInProgress: () => firstSyncInProgress,
|
|
19159
19285
|
judgeHealth: () => judgeHealth,
|
|
19286
|
+
markCleanExit: () => markCleanExit,
|
|
19160
19287
|
progressLine: () => progressLine,
|
|
19161
19288
|
readCollectorHealth: () => readCollectorHealth,
|
|
19289
|
+
recentCrashes: () => recentCrashes,
|
|
19162
19290
|
reportWalkProgress: () => reportWalkProgress,
|
|
19163
19291
|
updateCollectorHealth: () => updateCollectorHealth,
|
|
19164
19292
|
writeCollectorHealth: () => writeCollectorHealth
|
|
@@ -19186,7 +19314,11 @@ function progressLine(h) {
|
|
|
19186
19314
|
if (!p || p.complete || p.total <= 0)
|
|
19187
19315
|
return null;
|
|
19188
19316
|
const pct = Math.min(99, Math.floor(100 * p.done / p.total));
|
|
19189
|
-
return
|
|
19317
|
+
return `${p.first ? "first sync" : "sync"} in progress \u2014 ${p.done.toLocaleString()} of ${p.total.toLocaleString()} sessions (${pct}%)`;
|
|
19318
|
+
}
|
|
19319
|
+
function firstSyncInProgress(h) {
|
|
19320
|
+
const p = h?.progress;
|
|
19321
|
+
return !!p && p.first === true && !p.complete && p.total > 0;
|
|
19190
19322
|
}
|
|
19191
19323
|
function collectorHealthPath() {
|
|
19192
19324
|
return healthPath();
|
|
@@ -19227,6 +19359,20 @@ function reportWalkProgress(p) {
|
|
|
19227
19359
|
lastProgressWrite = now;
|
|
19228
19360
|
updateCollectorHealth({ progress: p });
|
|
19229
19361
|
}
|
|
19362
|
+
function crashesAtBoot(prior, procStart) {
|
|
19363
|
+
const history = (prior?.crashes ?? []).filter((t) => typeof t === "number");
|
|
19364
|
+
if (!prior)
|
|
19365
|
+
return history;
|
|
19366
|
+
const leftOnPurpose = typeof prior.cleanExitAt === "number" && prior.cleanExitAt >= prior.startedAt;
|
|
19367
|
+
return leftOnPurpose ? history : [...history, procStart];
|
|
19368
|
+
}
|
|
19369
|
+
function recentCrashes(crashes, now = Date.now()) {
|
|
19370
|
+
const cutoff = now - 36e5;
|
|
19371
|
+
return [...new Set(crashes.filter((t) => t > cutoff))].sort((a, b) => a - b).slice(-20);
|
|
19372
|
+
}
|
|
19373
|
+
function markCleanExit(now = Date.now()) {
|
|
19374
|
+
updateCollectorHealth({ cleanExitAt: now });
|
|
19375
|
+
}
|
|
19230
19376
|
function judgeHealth(h, now = Date.now()) {
|
|
19231
19377
|
if (!h)
|
|
19232
19378
|
return { ok: true, summary: null, reasons: [] };
|
|
@@ -19236,7 +19382,7 @@ function judgeHealth(h, now = Date.now()) {
|
|
|
19236
19382
|
reasons.push(`the collector has not reported for ${ago(silent)} \u2014 it may not be running`);
|
|
19237
19383
|
}
|
|
19238
19384
|
if (h.restartsLastHour >= CRASHLOOP_RESTARTS) {
|
|
19239
|
-
reasons.push(`it
|
|
19385
|
+
reasons.push(`it crashed ${h.restartsLastHour} times in the last hour`);
|
|
19240
19386
|
}
|
|
19241
19387
|
const targets = Object.entries(h.targets ?? {});
|
|
19242
19388
|
const stale = targets.filter(([, t]) => t.lastOkAt === null || now - t.lastOkAt > STALE_AFTER_MS);
|
|
@@ -20709,7 +20855,8 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20709
20855
|
}
|
|
20710
20856
|
trace?.("conversation walk start");
|
|
20711
20857
|
const walkStartedAt = Date.now();
|
|
20712
|
-
|
|
20858
|
+
const firstWalk = (ledger ?? getSyncedRows(base3)).size === 0;
|
|
20859
|
+
reportWalkProgress({ done: 0, total: slice.length, startedAt: walkStartedAt, complete: false, first: firstWalk });
|
|
20713
20860
|
walkProgressForUpload = { done: 0, total: slice.length, complete: false };
|
|
20714
20861
|
let traceN = 0;
|
|
20715
20862
|
let considered = 0;
|
|
@@ -20717,7 +20864,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20717
20864
|
await new Promise((resolve3) => setImmediate(resolve3));
|
|
20718
20865
|
considered++;
|
|
20719
20866
|
const walkDone = considered >= slice.length;
|
|
20720
|
-
reportWalkProgress({ done: considered, total: slice.length, startedAt: walkStartedAt, complete: walkDone });
|
|
20867
|
+
reportWalkProgress({ done: considered, total: slice.length, startedAt: walkStartedAt, complete: walkDone, first: firstWalk });
|
|
20721
20868
|
walkProgressForUpload = { done: considered, total: slice.length, complete: walkDone };
|
|
20722
20869
|
if (trace && ++traceN % 500 === 0) trace(`walk ${traceN}/${slice.length} \xB7 at ${ref.prefixedId}`);
|
|
20723
20870
|
localSessionIds.add(ref.prefixedId);
|
|
@@ -20989,7 +21136,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20989
21136
|
}
|
|
20990
21137
|
}
|
|
20991
21138
|
if (opts.prune) await post({ prune_empty_sessions: true });
|
|
20992
|
-
reportWalkProgress({ done: slice.length, total: slice.length, startedAt: walkStartedAt, complete: true });
|
|
21139
|
+
reportWalkProgress({ done: slice.length, total: slice.length, startedAt: walkStartedAt, complete: true, first: firstWalk });
|
|
20993
21140
|
walkProgressForUpload = { done: slice.length, total: slice.length, complete: true };
|
|
20994
21141
|
return {
|
|
20995
21142
|
uploaded: convBatch.sent + appendResults.uploaded,
|
|
@@ -21120,7 +21267,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21120
21267
|
if (!transcript) return null;
|
|
21121
21268
|
const textMessages = transcript.messages.filter((m) => m.role !== "summary" && m.content?.trim());
|
|
21122
21269
|
if (textMessages.length === 0 && !transcript.messages.some((m) => m.toolCalls?.length)) return null;
|
|
21123
|
-
const firstUser = textMessages.find(
|
|
21270
|
+
const firstUser = textMessages.find(isPersonMessage);
|
|
21124
21271
|
if (isInternalToolPrompt(firstUser?.content)) return null;
|
|
21125
21272
|
const count = { redactions: 0 };
|
|
21126
21273
|
const envelope = redactDeep(
|
|
@@ -21129,7 +21276,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21129
21276
|
);
|
|
21130
21277
|
let projectPath = ref.projectPath;
|
|
21131
21278
|
const meta = { messageCount: textMessages.length };
|
|
21132
|
-
if (textMessages.filter(
|
|
21279
|
+
if (textMessages.filter(isPersonMessage).length <= 1) meta.oneShot = true;
|
|
21133
21280
|
try {
|
|
21134
21281
|
const cwd = ref.fullPath ? readCwdFromJsonl(ref.fullPath) : "";
|
|
21135
21282
|
if (cwd) projectPath = cwd;
|
|
@@ -21281,7 +21428,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21281
21428
|
envelope,
|
|
21282
21429
|
raw_b64,
|
|
21283
21430
|
raw_size,
|
|
21284
|
-
first_prompt: envTexts.find(
|
|
21431
|
+
first_prompt: envTexts.find(isPersonMessage)?.content?.slice(0, 200),
|
|
21285
21432
|
// Byte offset this FULL sync is synced THROUGH (file size at build time,
|
|
21286
21433
|
// or the end of the bounded tail for an oversized session). The server
|
|
21287
21434
|
// stores it as the envelope's `o`; the ledger records the SAME value
|
|
@@ -21337,7 +21484,7 @@ async function buildConversationTail(ref, fromOffset, opts = {}) {
|
|
|
21337
21484
|
bytes: 0
|
|
21338
21485
|
};
|
|
21339
21486
|
}
|
|
21340
|
-
const firstUser = textMessages.find(
|
|
21487
|
+
const firstUser = textMessages.find(isPersonMessage);
|
|
21341
21488
|
if (isInternalToolPrompt(firstUser?.content)) return null;
|
|
21342
21489
|
const count = { redactions: 0 };
|
|
21343
21490
|
const envelope = redactDeep(
|
|
@@ -21414,6 +21561,7 @@ var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServer
|
|
|
21414
21561
|
var init_sync_client = __esm({
|
|
21415
21562
|
"src/sync-client.ts"() {
|
|
21416
21563
|
"use strict";
|
|
21564
|
+
init_claude_prompt_origin();
|
|
21417
21565
|
init_credentials_env();
|
|
21418
21566
|
init_secret_redactor();
|
|
21419
21567
|
init_source_discovery();
|
|
@@ -21455,7 +21603,7 @@ var init_sync_client = __esm({
|
|
|
21455
21603
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21456
21604
|
} catch {
|
|
21457
21605
|
try {
|
|
21458
|
-
if (true) ownVersion = "0.7.
|
|
21606
|
+
if (true) ownVersion = "0.7.10";
|
|
21459
21607
|
} catch {
|
|
21460
21608
|
}
|
|
21461
21609
|
}
|
|
@@ -23659,7 +23807,7 @@ function extractCorrections(messages, cap = 5) {
|
|
|
23659
23807
|
const seen = /* @__PURE__ */ new Set();
|
|
23660
23808
|
let userTurns = 0;
|
|
23661
23809
|
for (const msg of messages) {
|
|
23662
|
-
if (msg
|
|
23810
|
+
if (!isPersonMessage(msg)) continue;
|
|
23663
23811
|
userTurns++;
|
|
23664
23812
|
if (userTurns === 1) continue;
|
|
23665
23813
|
if (isNoiseUserMessage(msg.content)) continue;
|
|
@@ -23765,6 +23913,7 @@ var CORRECTION_STARTS, CORRECTION_CONTAINS, TERMINAL_STATUSES;
|
|
|
23765
23913
|
var init_escalate = __esm({
|
|
23766
23914
|
"src/escalate.ts"() {
|
|
23767
23915
|
"use strict";
|
|
23916
|
+
init_claude_prompt_origin();
|
|
23768
23917
|
CORRECTION_STARTS = [
|
|
23769
23918
|
/^no+\b[,.! ]/i,
|
|
23770
23919
|
/^(nope|wrong|incorrect|not quite|not right)\b/i,
|
|
@@ -25616,7 +25765,7 @@ var init_intent_drain = __esm({
|
|
|
25616
25765
|
ownVersion2 = JSON.parse(readFileSync45(join56(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
25617
25766
|
} catch {
|
|
25618
25767
|
try {
|
|
25619
|
-
if (true) ownVersion2 = "0.7.
|
|
25768
|
+
if (true) ownVersion2 = "0.7.10";
|
|
25620
25769
|
} catch {
|
|
25621
25770
|
}
|
|
25622
25771
|
}
|
|
@@ -27633,17 +27782,18 @@ var init_bulk_delete = __esm({
|
|
|
27633
27782
|
});
|
|
27634
27783
|
|
|
27635
27784
|
// ../engine/dist/core/resume-command.js
|
|
27785
|
+
var SESSION_ID_PREFIXES = {
|
|
27786
|
+
codex: "codex_",
|
|
27787
|
+
opencode: "opencode_",
|
|
27788
|
+
agy: "agy_",
|
|
27789
|
+
cursor: "cursor_",
|
|
27790
|
+
gemini: "gemini_"
|
|
27791
|
+
};
|
|
27636
27792
|
function toolOfSessionId(sessionId) {
|
|
27637
|
-
|
|
27638
|
-
|
|
27639
|
-
|
|
27640
|
-
|
|
27641
|
-
if (sessionId.startsWith("agy_"))
|
|
27642
|
-
return "agy";
|
|
27643
|
-
if (sessionId.startsWith("cursor_"))
|
|
27644
|
-
return "cursor";
|
|
27645
|
-
if (sessionId.startsWith("gemini_"))
|
|
27646
|
-
return "gemini";
|
|
27793
|
+
for (const [tool, prefix] of Object.entries(SESSION_ID_PREFIXES)) {
|
|
27794
|
+
if (sessionId.startsWith(prefix))
|
|
27795
|
+
return tool;
|
|
27796
|
+
}
|
|
27647
27797
|
return "claude";
|
|
27648
27798
|
}
|
|
27649
27799
|
function resumeCommandFor(sessionId, tool) {
|
|
@@ -27754,7 +27904,7 @@ function renderShowMessages(messages, opts = {}) {
|
|
|
27754
27904
|
const calls = msg.toolCalls ?? [];
|
|
27755
27905
|
if (!text.trim() && !thinking.trim() && !calls.length && msg.thinking !== void 0)
|
|
27756
27906
|
continue;
|
|
27757
|
-
out.push(`**${msg.role}** (line ${msg.line})`);
|
|
27907
|
+
out.push(msg.origin ? `**${msg.role}** (line ${msg.line}, written by the harness: ${msg.origin})` : `**${msg.role}** (line ${msg.line})`);
|
|
27758
27908
|
if (thinking.trim())
|
|
27759
27909
|
out.push(`_(thinking)_
|
|
27760
27910
|
${thinking}`);
|
|
@@ -27768,6 +27918,13 @@ ${thinking}`);
|
|
|
27768
27918
|
}
|
|
27769
27919
|
return out;
|
|
27770
27920
|
}
|
|
27921
|
+
function nearestMessageLines(messages, line, count = 4) {
|
|
27922
|
+
return [...new Set(messages.map((m) => m.line))].sort((a, b) => Math.abs(a - line) - Math.abs(b - line) || a - b).slice(0, count).sort((a, b) => a - b);
|
|
27923
|
+
}
|
|
27924
|
+
function noMessageAtLine(messages, line, sessionId) {
|
|
27925
|
+
const near = nearestMessageLines(messages, line);
|
|
27926
|
+
return `No message at line ${line} in ${sessionId}. The nearest messages are at lines ${near.join(", ")}.`;
|
|
27927
|
+
}
|
|
27771
27928
|
|
|
27772
27929
|
// src/cli.ts
|
|
27773
27930
|
init_paths();
|
|
@@ -28524,7 +28681,7 @@ program.command("search <query>").description("Search your server for relevant s
|
|
|
28524
28681
|
(c) => c.chunkType !== "summary" && c.chunkType !== "first_prompt"
|
|
28525
28682
|
);
|
|
28526
28683
|
if (chunk) {
|
|
28527
|
-
const label = chunk.chunkType === "assistant" ? "Discussed" : chunk.chunkType === "user_context" ? "Asked about" : chunk.chunkType === "tool_result" ? "Tool result" : "Context";
|
|
28684
|
+
const label = chunk.chunkType === "assistant" ? "Discussed" : chunk.chunkType === "user_context" ? "Asked about" : chunk.chunkType === "tool_result" ? "Tool result" : chunk.chunkType === "harness" ? "Harness message" : "Context";
|
|
28528
28685
|
let text = chunk.text.replace(/\n/g, " ").trim();
|
|
28529
28686
|
if (text.length > 150) text = text.slice(0, 150) + "...";
|
|
28530
28687
|
console.log(` ${chalk2.magenta(label + ":")} ${text}`);
|
|
@@ -28590,8 +28747,7 @@ program.command("show <session_id>").description("Show conversation content from
|
|
|
28590
28747
|
const line = parseInt(options.line, 10);
|
|
28591
28748
|
const hit = messagesList.find((m) => m.line === line);
|
|
28592
28749
|
if (!hit) {
|
|
28593
|
-
|
|
28594
|
-
console.log(chalk2.yellow(`No message at line ${options.line}. Its lines run from ${Math.min(...lines)} to ${Math.max(...lines)}.`));
|
|
28750
|
+
console.log(chalk2.yellow(noMessageAtLine(messagesList, line, sessionId)));
|
|
28595
28751
|
process.exit(1);
|
|
28596
28752
|
}
|
|
28597
28753
|
console.log(renderShowMessages([hit], { full: true }).join("\n"));
|