chat-recall 0.7.9 → 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 +180 -41
- 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 +6820 -6564
- 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 +152 -26
- 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
|
}
|
|
@@ -19157,6 +19281,7 @@ __export(collector_health_exports, {
|
|
|
19157
19281
|
applySyncOutcome: () => applySyncOutcome,
|
|
19158
19282
|
collectorHealthPath: () => collectorHealthPath,
|
|
19159
19283
|
crashesAtBoot: () => crashesAtBoot,
|
|
19284
|
+
firstSyncInProgress: () => firstSyncInProgress,
|
|
19160
19285
|
judgeHealth: () => judgeHealth,
|
|
19161
19286
|
markCleanExit: () => markCleanExit,
|
|
19162
19287
|
progressLine: () => progressLine,
|
|
@@ -19189,7 +19314,11 @@ function progressLine(h) {
|
|
|
19189
19314
|
if (!p || p.complete || p.total <= 0)
|
|
19190
19315
|
return null;
|
|
19191
19316
|
const pct = Math.min(99, Math.floor(100 * p.done / p.total));
|
|
19192
|
-
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;
|
|
19193
19322
|
}
|
|
19194
19323
|
function collectorHealthPath() {
|
|
19195
19324
|
return healthPath();
|
|
@@ -20726,7 +20855,8 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20726
20855
|
}
|
|
20727
20856
|
trace?.("conversation walk start");
|
|
20728
20857
|
const walkStartedAt = Date.now();
|
|
20729
|
-
|
|
20858
|
+
const firstWalk = (ledger ?? getSyncedRows(base3)).size === 0;
|
|
20859
|
+
reportWalkProgress({ done: 0, total: slice.length, startedAt: walkStartedAt, complete: false, first: firstWalk });
|
|
20730
20860
|
walkProgressForUpload = { done: 0, total: slice.length, complete: false };
|
|
20731
20861
|
let traceN = 0;
|
|
20732
20862
|
let considered = 0;
|
|
@@ -20734,7 +20864,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20734
20864
|
await new Promise((resolve3) => setImmediate(resolve3));
|
|
20735
20865
|
considered++;
|
|
20736
20866
|
const walkDone = considered >= slice.length;
|
|
20737
|
-
reportWalkProgress({ done: considered, total: slice.length, startedAt: walkStartedAt, complete: walkDone });
|
|
20867
|
+
reportWalkProgress({ done: considered, total: slice.length, startedAt: walkStartedAt, complete: walkDone, first: firstWalk });
|
|
20738
20868
|
walkProgressForUpload = { done: considered, total: slice.length, complete: walkDone };
|
|
20739
20869
|
if (trace && ++traceN % 500 === 0) trace(`walk ${traceN}/${slice.length} \xB7 at ${ref.prefixedId}`);
|
|
20740
20870
|
localSessionIds.add(ref.prefixedId);
|
|
@@ -21006,7 +21136,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
21006
21136
|
}
|
|
21007
21137
|
}
|
|
21008
21138
|
if (opts.prune) await post({ prune_empty_sessions: true });
|
|
21009
|
-
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 });
|
|
21010
21140
|
walkProgressForUpload = { done: slice.length, total: slice.length, complete: true };
|
|
21011
21141
|
return {
|
|
21012
21142
|
uploaded: convBatch.sent + appendResults.uploaded,
|
|
@@ -21137,7 +21267,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21137
21267
|
if (!transcript) return null;
|
|
21138
21268
|
const textMessages = transcript.messages.filter((m) => m.role !== "summary" && m.content?.trim());
|
|
21139
21269
|
if (textMessages.length === 0 && !transcript.messages.some((m) => m.toolCalls?.length)) return null;
|
|
21140
|
-
const firstUser = textMessages.find(
|
|
21270
|
+
const firstUser = textMessages.find(isPersonMessage);
|
|
21141
21271
|
if (isInternalToolPrompt(firstUser?.content)) return null;
|
|
21142
21272
|
const count = { redactions: 0 };
|
|
21143
21273
|
const envelope = redactDeep(
|
|
@@ -21146,7 +21276,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21146
21276
|
);
|
|
21147
21277
|
let projectPath = ref.projectPath;
|
|
21148
21278
|
const meta = { messageCount: textMessages.length };
|
|
21149
|
-
if (textMessages.filter(
|
|
21279
|
+
if (textMessages.filter(isPersonMessage).length <= 1) meta.oneShot = true;
|
|
21150
21280
|
try {
|
|
21151
21281
|
const cwd = ref.fullPath ? readCwdFromJsonl(ref.fullPath) : "";
|
|
21152
21282
|
if (cwd) projectPath = cwd;
|
|
@@ -21298,7 +21428,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21298
21428
|
envelope,
|
|
21299
21429
|
raw_b64,
|
|
21300
21430
|
raw_size,
|
|
21301
|
-
first_prompt: envTexts.find(
|
|
21431
|
+
first_prompt: envTexts.find(isPersonMessage)?.content?.slice(0, 200),
|
|
21302
21432
|
// Byte offset this FULL sync is synced THROUGH (file size at build time,
|
|
21303
21433
|
// or the end of the bounded tail for an oversized session). The server
|
|
21304
21434
|
// stores it as the envelope's `o`; the ledger records the SAME value
|
|
@@ -21354,7 +21484,7 @@ async function buildConversationTail(ref, fromOffset, opts = {}) {
|
|
|
21354
21484
|
bytes: 0
|
|
21355
21485
|
};
|
|
21356
21486
|
}
|
|
21357
|
-
const firstUser = textMessages.find(
|
|
21487
|
+
const firstUser = textMessages.find(isPersonMessage);
|
|
21358
21488
|
if (isInternalToolPrompt(firstUser?.content)) return null;
|
|
21359
21489
|
const count = { redactions: 0 };
|
|
21360
21490
|
const envelope = redactDeep(
|
|
@@ -21431,6 +21561,7 @@ var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServer
|
|
|
21431
21561
|
var init_sync_client = __esm({
|
|
21432
21562
|
"src/sync-client.ts"() {
|
|
21433
21563
|
"use strict";
|
|
21564
|
+
init_claude_prompt_origin();
|
|
21434
21565
|
init_credentials_env();
|
|
21435
21566
|
init_secret_redactor();
|
|
21436
21567
|
init_source_discovery();
|
|
@@ -21472,7 +21603,7 @@ var init_sync_client = __esm({
|
|
|
21472
21603
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21473
21604
|
} catch {
|
|
21474
21605
|
try {
|
|
21475
|
-
if (true) ownVersion = "0.7.
|
|
21606
|
+
if (true) ownVersion = "0.7.10";
|
|
21476
21607
|
} catch {
|
|
21477
21608
|
}
|
|
21478
21609
|
}
|
|
@@ -23676,7 +23807,7 @@ function extractCorrections(messages, cap = 5) {
|
|
|
23676
23807
|
const seen = /* @__PURE__ */ new Set();
|
|
23677
23808
|
let userTurns = 0;
|
|
23678
23809
|
for (const msg of messages) {
|
|
23679
|
-
if (msg
|
|
23810
|
+
if (!isPersonMessage(msg)) continue;
|
|
23680
23811
|
userTurns++;
|
|
23681
23812
|
if (userTurns === 1) continue;
|
|
23682
23813
|
if (isNoiseUserMessage(msg.content)) continue;
|
|
@@ -23782,6 +23913,7 @@ var CORRECTION_STARTS, CORRECTION_CONTAINS, TERMINAL_STATUSES;
|
|
|
23782
23913
|
var init_escalate = __esm({
|
|
23783
23914
|
"src/escalate.ts"() {
|
|
23784
23915
|
"use strict";
|
|
23916
|
+
init_claude_prompt_origin();
|
|
23785
23917
|
CORRECTION_STARTS = [
|
|
23786
23918
|
/^no+\b[,.! ]/i,
|
|
23787
23919
|
/^(nope|wrong|incorrect|not quite|not right)\b/i,
|
|
@@ -25633,7 +25765,7 @@ var init_intent_drain = __esm({
|
|
|
25633
25765
|
ownVersion2 = JSON.parse(readFileSync45(join56(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
25634
25766
|
} catch {
|
|
25635
25767
|
try {
|
|
25636
|
-
if (true) ownVersion2 = "0.7.
|
|
25768
|
+
if (true) ownVersion2 = "0.7.10";
|
|
25637
25769
|
} catch {
|
|
25638
25770
|
}
|
|
25639
25771
|
}
|
|
@@ -27650,17 +27782,18 @@ var init_bulk_delete = __esm({
|
|
|
27650
27782
|
});
|
|
27651
27783
|
|
|
27652
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
|
+
};
|
|
27653
27792
|
function toolOfSessionId(sessionId) {
|
|
27654
|
-
|
|
27655
|
-
|
|
27656
|
-
|
|
27657
|
-
|
|
27658
|
-
if (sessionId.startsWith("agy_"))
|
|
27659
|
-
return "agy";
|
|
27660
|
-
if (sessionId.startsWith("cursor_"))
|
|
27661
|
-
return "cursor";
|
|
27662
|
-
if (sessionId.startsWith("gemini_"))
|
|
27663
|
-
return "gemini";
|
|
27793
|
+
for (const [tool, prefix] of Object.entries(SESSION_ID_PREFIXES)) {
|
|
27794
|
+
if (sessionId.startsWith(prefix))
|
|
27795
|
+
return tool;
|
|
27796
|
+
}
|
|
27664
27797
|
return "claude";
|
|
27665
27798
|
}
|
|
27666
27799
|
function resumeCommandFor(sessionId, tool) {
|
|
@@ -27771,7 +27904,7 @@ function renderShowMessages(messages, opts = {}) {
|
|
|
27771
27904
|
const calls = msg.toolCalls ?? [];
|
|
27772
27905
|
if (!text.trim() && !thinking.trim() && !calls.length && msg.thinking !== void 0)
|
|
27773
27906
|
continue;
|
|
27774
|
-
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})`);
|
|
27775
27908
|
if (thinking.trim())
|
|
27776
27909
|
out.push(`_(thinking)_
|
|
27777
27910
|
${thinking}`);
|
|
@@ -27785,6 +27918,13 @@ ${thinking}`);
|
|
|
27785
27918
|
}
|
|
27786
27919
|
return out;
|
|
27787
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
|
+
}
|
|
27788
27928
|
|
|
27789
27929
|
// src/cli.ts
|
|
27790
27930
|
init_paths();
|
|
@@ -28541,7 +28681,7 @@ program.command("search <query>").description("Search your server for relevant s
|
|
|
28541
28681
|
(c) => c.chunkType !== "summary" && c.chunkType !== "first_prompt"
|
|
28542
28682
|
);
|
|
28543
28683
|
if (chunk) {
|
|
28544
|
-
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";
|
|
28545
28685
|
let text = chunk.text.replace(/\n/g, " ").trim();
|
|
28546
28686
|
if (text.length > 150) text = text.slice(0, 150) + "...";
|
|
28547
28687
|
console.log(` ${chalk2.magenta(label + ":")} ${text}`);
|
|
@@ -28607,8 +28747,7 @@ program.command("show <session_id>").description("Show conversation content from
|
|
|
28607
28747
|
const line = parseInt(options.line, 10);
|
|
28608
28748
|
const hit = messagesList.find((m) => m.line === line);
|
|
28609
28749
|
if (!hit) {
|
|
28610
|
-
|
|
28611
|
-
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)));
|
|
28612
28751
|
process.exit(1);
|
|
28613
28752
|
}
|
|
28614
28753
|
console.log(renderShowMessages([hit], { full: true }).join("\n"));
|