chat-recall 0.5.3 → 0.5.5
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 +121 -40
- package/dist/cli.js.map +1 -1
- package/dist/mcp-diagnostics.d.ts +45 -0
- package/dist/mcp-diagnostics.d.ts.map +1 -0
- package/dist/mcp-diagnostics.js +96 -0
- package/dist/mcp-diagnostics.js.map +1 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +946 -677
- package/dist/mcp.js.map +1 -1
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +18 -0
- package/dist/sync-client.js.map +1 -1
- package/dist/watch.js +120 -41
- package/package.json +1 -1
- package/skills/chat-recall/SKILL.md +3 -2
package/dist/cli.js
CHANGED
|
@@ -6278,6 +6278,24 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
|
|
|
6278
6278
|
}
|
|
6279
6279
|
const filesToParse = hasSubagentsDir(sessionPath) ? [sessionPath, ...getSubagentPaths(sessionPath)] : [sessionPath];
|
|
6280
6280
|
let userCount = 0;
|
|
6281
|
+
const seenPrompts = /* @__PURE__ */ new Set();
|
|
6282
|
+
const recordPrompt = (raw, line, dedupe = false) => {
|
|
6283
|
+
if (userCount >= maxMessages)
|
|
6284
|
+
return;
|
|
6285
|
+
const withoutReminders = raw.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "");
|
|
6286
|
+
if (!withoutReminders.trim() || withoutReminders.trim().length <= 10)
|
|
6287
|
+
return;
|
|
6288
|
+
const cleanedText = stripInjectedBanners(withoutReminders).trim();
|
|
6289
|
+
if (cleanedText.length < 10)
|
|
6290
|
+
return;
|
|
6291
|
+
if (dedupe && seenPrompts.has(cleanedText))
|
|
6292
|
+
return;
|
|
6293
|
+
seenPrompts.add(cleanedText);
|
|
6294
|
+
content.userMessages.push({ text: cleanedText, lineNumber: line, contentType: "user" });
|
|
6295
|
+
userCount++;
|
|
6296
|
+
if (!content.firstPrompt)
|
|
6297
|
+
content.firstPrompt = cleanedText.slice(0, 1e3);
|
|
6298
|
+
};
|
|
6281
6299
|
let assistantCount = 0;
|
|
6282
6300
|
let toolCount = 0;
|
|
6283
6301
|
let lineNum = 0;
|
|
@@ -6356,19 +6374,11 @@ async function parseSessionFile(sessionPath, maxMessages = 50) {
|
|
|
6356
6374
|
text = textParts.join("\n");
|
|
6357
6375
|
}
|
|
6358
6376
|
}
|
|
6359
|
-
if (text
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
content
|
|
6364
|
-
text: cleanedText,
|
|
6365
|
-
lineNumber: lineNum,
|
|
6366
|
-
contentType: "user"
|
|
6367
|
-
});
|
|
6368
|
-
userCount++;
|
|
6369
|
-
if (!content.firstPrompt) {
|
|
6370
|
-
content.firstPrompt = cleanedText.slice(0, 1e3);
|
|
6371
|
-
}
|
|
6377
|
+
if (text)
|
|
6378
|
+
recordPrompt(text, lineNum);
|
|
6379
|
+
} else if (msgType === "queue-operation") {
|
|
6380
|
+
if (obj.operation === "enqueue" && typeof obj.content === "string") {
|
|
6381
|
+
recordPrompt(obj.content, lineNum, true);
|
|
6372
6382
|
}
|
|
6373
6383
|
} else if (msgType === "assistant") {
|
|
6374
6384
|
const msg = obj.message;
|
|
@@ -9539,23 +9549,24 @@ var init_codex2 = __esm({
|
|
|
9539
9549
|
return null;
|
|
9540
9550
|
}
|
|
9541
9551
|
/**
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9552
|
+
* Stream a Codex JSONL rollout into canonical events. Codex separates:
|
|
9553
|
+
* - event_msg + payload.type='user_message' → user
|
|
9554
|
+
* - response_item + payload.type='message' → user OR assistant_text,
|
|
9555
|
+
* by payload.role
|
|
9556
|
+
* - response_item + payload.type='function_call' → tool_use
|
|
9557
|
+
* - response_item + payload.type='function_call_output' → tool_result
|
|
9558
|
+
*
|
|
9559
|
+
* Filters Codex's wrapper-bearing user messages (environment_context etc.).
|
|
9560
|
+
*
|
|
9561
|
+
* **Subagent fan-out:** Codex orchestrates work via `spawn_agent` calls
|
|
9562
|
+
* that produce sibling rollout files in the same YYYY/MM/DD directory.
|
|
9563
|
+
* Sub-agent rollouts carry `payload.source.subagent.thread_spawn` linking
|
|
9564
|
+
* back to the parent. The actual file edits often happen inside those
|
|
9565
|
+
* subagent rollouts — without folding their events into the parent's
|
|
9566
|
+
* stream, replay/scan would see the parent as edit-free. We append every
|
|
9567
|
+
* subagent rollout's events here so the generic engine sees one unified
|
|
9568
|
+
* stream per user-facing session.
|
|
9569
|
+
*/
|
|
9559
9570
|
readEvents(rawId) {
|
|
9560
9571
|
const located = findCodexSessionFile(this.toRawId(rawId));
|
|
9561
9572
|
if (!located)
|
|
@@ -9625,6 +9636,11 @@ var init_codex2 = __esm({
|
|
|
9625
9636
|
if (text && !isCodexInjectedWrapper2(text)) {
|
|
9626
9637
|
events.push({ kind: "user", ts, tsIso, line: lineNum, text });
|
|
9627
9638
|
}
|
|
9639
|
+
} else if (obj.type === "response_item" && payload.type === "message" && payload.role === "user") {
|
|
9640
|
+
const text = flattenContent(payload.content).trim();
|
|
9641
|
+
if (text && !isCodexInjectedWrapper2(text)) {
|
|
9642
|
+
events.push({ kind: "user", ts, tsIso, line: lineNum, text });
|
|
9643
|
+
}
|
|
9628
9644
|
} else if (obj.type === "response_item" && payload.type === "message" && payload.role === "assistant") {
|
|
9629
9645
|
const text = flattenContent(payload.content).trim();
|
|
9630
9646
|
if (text)
|
|
@@ -11087,6 +11103,9 @@ var init_first_prompt = __esm({
|
|
|
11087
11103
|
// ../engine/dist/core/backends/claude.js
|
|
11088
11104
|
import { existsSync as existsSync13, readdirSync as readdirSync9, readFileSync as readFileSync9, statSync as statSync11, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "fs";
|
|
11089
11105
|
import { join as join14, basename as basename11 } from "path";
|
|
11106
|
+
function stripReminders(text) {
|
|
11107
|
+
return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
|
|
11108
|
+
}
|
|
11090
11109
|
function parseExitCode(text) {
|
|
11091
11110
|
const m = text.match(/(?:^|\n)\s*(?:exit\s+code|returncode|exit\s+status|exit)\s*[:=]\s*(\d+)\b/i);
|
|
11092
11111
|
return m ? Number(m[1]) : void 0;
|
|
@@ -11395,6 +11414,15 @@ var init_claude2 = __esm({
|
|
|
11395
11414
|
}
|
|
11396
11415
|
const tsIso = typeof obj.timestamp === "string" ? obj.timestamp : void 0;
|
|
11397
11416
|
const ts = tsIso ? Date.parse(tsIso) || mtime : mtime;
|
|
11417
|
+
if (obj.type === "queue-operation") {
|
|
11418
|
+
if (obj.operation === "enqueue" && typeof obj.content === "string") {
|
|
11419
|
+
const queued = stripReminders(obj.content);
|
|
11420
|
+
if (queued && !queued.startsWith("<task-notification")) {
|
|
11421
|
+
events.push({ kind: "user", ts, tsIso, line: lineNum, text: queued });
|
|
11422
|
+
}
|
|
11423
|
+
}
|
|
11424
|
+
continue;
|
|
11425
|
+
}
|
|
11398
11426
|
if (obj.type === "user") {
|
|
11399
11427
|
const msg = obj.message;
|
|
11400
11428
|
const content = msg?.content;
|
|
@@ -11428,9 +11456,9 @@ var init_claude2 = __esm({
|
|
|
11428
11456
|
}
|
|
11429
11457
|
}
|
|
11430
11458
|
}
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11459
|
+
const spoken = stripReminders(text);
|
|
11460
|
+
if (spoken)
|
|
11461
|
+
events.push({ kind: "user", ts, tsIso, line: lineNum, text: spoken });
|
|
11434
11462
|
for (const tr of toolResults) {
|
|
11435
11463
|
events.push({
|
|
11436
11464
|
kind: "tool_result",
|
|
@@ -17641,7 +17669,9 @@ var init_extractor_version = __esm({
|
|
|
17641
17669
|
"use strict";
|
|
17642
17670
|
BASE_EXTRACTOR_VERSION = 2;
|
|
17643
17671
|
TOOL_EXTRACTOR_BUMP = {
|
|
17644
|
-
agy: 2
|
|
17672
|
+
agy: 2,
|
|
17673
|
+
claude: 1,
|
|
17674
|
+
codex: 1
|
|
17645
17675
|
};
|
|
17646
17676
|
EXTRACTOR_VERSION = BASE_EXTRACTOR_VERSION;
|
|
17647
17677
|
}
|
|
@@ -17971,7 +18001,7 @@ var init_http = __esm({
|
|
|
17971
18001
|
CLI_VERSION = JSON.parse(readFileSync31(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
17972
18002
|
} catch {
|
|
17973
18003
|
try {
|
|
17974
|
-
if (true) CLI_VERSION = "0.5.
|
|
18004
|
+
if (true) CLI_VERSION = "0.5.5";
|
|
17975
18005
|
} catch {
|
|
17976
18006
|
}
|
|
17977
18007
|
}
|
|
@@ -18610,6 +18640,17 @@ async function syncToTarget(cred, opts = {}) {
|
|
|
18610
18640
|
if (res.status === 401 || res.status === 403) {
|
|
18611
18641
|
throw new Error(`server rejected this machine's device token (HTTP ${res.status} \u2014 revoked?). Reconnect with: chat-recall login ${base2}`);
|
|
18612
18642
|
}
|
|
18643
|
+
if (res.status === 402) {
|
|
18644
|
+
let detail = text;
|
|
18645
|
+
try {
|
|
18646
|
+
const body2 = JSON.parse(text);
|
|
18647
|
+
detail = body2.error ?? text;
|
|
18648
|
+
if (body2.resetsAt) detail += ` (resets ${new Date(body2.resetsAt).toISOString().slice(0, 10)})`;
|
|
18649
|
+
if (body2.upgradeUrl) detail += ` \u2014 ${body2.upgradeUrl}`;
|
|
18650
|
+
} catch {
|
|
18651
|
+
}
|
|
18652
|
+
throw new Error(`sync paused by the server: ${detail}`);
|
|
18653
|
+
}
|
|
18613
18654
|
if (!retryable) throw new Error(`sync failed: HTTP ${res.status} ${text}`);
|
|
18614
18655
|
if (attempt >= RETRY_DELAYS_MS.length) throw new Error(`sync failed after ${attempt + 1} attempts: HTTP ${res.status} ${text}`);
|
|
18615
18656
|
const retryAfterS = Number(res.headers.get("retry-after"));
|
|
@@ -19494,7 +19535,7 @@ var init_sync_client = __esm({
|
|
|
19494
19535
|
ownVersion = JSON.parse(readFileSync33(join40(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
19495
19536
|
} catch {
|
|
19496
19537
|
try {
|
|
19497
|
-
if (true) ownVersion = "0.5.
|
|
19538
|
+
if (true) ownVersion = "0.5.5";
|
|
19498
19539
|
} catch {
|
|
19499
19540
|
}
|
|
19500
19541
|
}
|
|
@@ -21073,6 +21114,14 @@ async function collectCode(opts) {
|
|
|
21073
21114
|
agentPrompt: manifestPrompt(v.violation_type ?? "", file, v.line ?? null, v.description ?? "")
|
|
21074
21115
|
});
|
|
21075
21116
|
}
|
|
21117
|
+
{
|
|
21118
|
+
const before = findings.length;
|
|
21119
|
+
const own = findings.filter((f) => !f.file || !isGenerated(f.file));
|
|
21120
|
+
if (own.length !== before) {
|
|
21121
|
+
findings.splice(0, before, ...own);
|
|
21122
|
+
log6(`dropped ${before - own.length} finding(s) in vendored/generated files`);
|
|
21123
|
+
}
|
|
21124
|
+
}
|
|
21076
21125
|
const godSet = new Set((coup?.god_modules ?? []).map((m) => rel(m.file)));
|
|
21077
21126
|
const cloneSet = /* @__PURE__ */ new Set();
|
|
21078
21127
|
for (const g of clones?.groups ?? [])
|
|
@@ -21158,7 +21207,9 @@ async function collectCode(opts) {
|
|
|
21158
21207
|
}
|
|
21159
21208
|
for (const g of clones?.groups ?? []) {
|
|
21160
21209
|
if ((g.count ?? 0) >= 3 || (g.lines ?? 0) >= 12) {
|
|
21161
|
-
const fns = (g.functions ?? []).filter((x) => x && typeof x === "object");
|
|
21210
|
+
const fns = (g.functions ?? []).filter((x) => x && typeof x === "object").filter((x) => !isGenerated(rel(x.file)));
|
|
21211
|
+
if (fns.length < 2)
|
|
21212
|
+
continue;
|
|
21162
21213
|
const names = [...new Set(fns.map((x) => x.name))];
|
|
21163
21214
|
const locs = fns.map((x) => rel(x.file)).slice(0, 5);
|
|
21164
21215
|
pushAction((g.lines ?? 0) * (g.count ?? 0) >= 150 ? 1 : 2, "duplication", `${names.join(", ")} copy-pasted ${g.count}\xD7 (${g.lines} lines each)`, "Extract one shared implementation and replace the copies.", locs.map((f) => ({ file: f })), clonePrompt(names, g.lines ?? 0, g.count ?? 0, locs));
|
|
@@ -21177,10 +21228,14 @@ async function collectCode(opts) {
|
|
|
21177
21228
|
}
|
|
21178
21229
|
for (const m of (coup?.god_modules ?? []).slice(0, 5)) {
|
|
21179
21230
|
const file = rel(m.file);
|
|
21231
|
+
if (isGenerated(file))
|
|
21232
|
+
continue;
|
|
21180
21233
|
pushAction(2, "modularity", `God module ${file} (fan-in ${m.fan_in}, fan-out ${m.fan_out})`, "Split into cohesive sub-modules; introduce interfaces to cut fan-out.", [{ file }], couplingPrompt(file, m.fan_in ?? 0, m.fan_out ?? 0, Math.round((m.instability ?? 0) * 100) / 100));
|
|
21181
21234
|
}
|
|
21182
21235
|
for (const c of (cyc?.cycles ?? []).slice(0, 5)) {
|
|
21183
|
-
const chain = (c.files ?? []).map(rel);
|
|
21236
|
+
const chain = (c.files ?? []).map(rel).filter((f) => !isGenerated(f));
|
|
21237
|
+
if (chain.length < 2)
|
|
21238
|
+
continue;
|
|
21184
21239
|
pushAction(2, "architecture", `Circular dependency (${chain.length} files)`, "Break the cycle: extract the shared type/interface into a separate module.", chain.slice(0, 4).map((f) => ({ file: f })), cyclePrompt(chain.slice(0, 6)));
|
|
21185
21240
|
}
|
|
21186
21241
|
for (const h of hotspotsAll.slice(0, 5)) {
|
|
@@ -21319,7 +21374,31 @@ var init_collector = __esm({
|
|
|
21319
21374
|
"migration_parity",
|
|
21320
21375
|
"manifest_compliance"
|
|
21321
21376
|
];
|
|
21322
|
-
GENERATED = [
|
|
21377
|
+
GENERATED = [
|
|
21378
|
+
"generated/",
|
|
21379
|
+
"__generated__/",
|
|
21380
|
+
".pb.go",
|
|
21381
|
+
".gen.",
|
|
21382
|
+
"_pb2.py",
|
|
21383
|
+
"/gen/",
|
|
21384
|
+
".g.dart",
|
|
21385
|
+
"/node_modules/",
|
|
21386
|
+
"/vendor/",
|
|
21387
|
+
"/third_party/",
|
|
21388
|
+
"/site-packages/",
|
|
21389
|
+
".lock",
|
|
21390
|
+
"/dist/",
|
|
21391
|
+
"/build/",
|
|
21392
|
+
"/out/",
|
|
21393
|
+
"/target/",
|
|
21394
|
+
"/.next/",
|
|
21395
|
+
"/coverage/",
|
|
21396
|
+
".min.js",
|
|
21397
|
+
".min.css",
|
|
21398
|
+
".bundle.js",
|
|
21399
|
+
"-bundle.js",
|
|
21400
|
+
".map"
|
|
21401
|
+
];
|
|
21323
21402
|
CF_RE = /\b(if|for|while|switch|case|catch|elif|when|loop|&&|\|\||\?)\b|\?/g;
|
|
21324
21403
|
DEPTH = 2;
|
|
21325
21404
|
MCP_OUT_MAX_BYTES = 64 * 1024 * 1024;
|
|
@@ -22313,7 +22392,7 @@ var init_intent_drain = __esm({
|
|
|
22313
22392
|
ownVersion2 = JSON.parse(readFileSync41(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
22314
22393
|
} catch {
|
|
22315
22394
|
try {
|
|
22316
|
-
if (true) ownVersion2 = "0.5.
|
|
22395
|
+
if (true) ownVersion2 = "0.5.5";
|
|
22317
22396
|
} catch {
|
|
22318
22397
|
}
|
|
22319
22398
|
}
|
|
@@ -23826,6 +23905,8 @@ var DEFAULT_ALLOW = [
|
|
|
23826
23905
|
"recall_tasks",
|
|
23827
23906
|
"recall_task_create",
|
|
23828
23907
|
"recall_task_update",
|
|
23908
|
+
"recall_task_comment",
|
|
23909
|
+
"recall_help",
|
|
23829
23910
|
"recall_smart_resume",
|
|
23830
23911
|
"recall_project_context",
|
|
23831
23912
|
"recall_weekly_digest",
|