chat-recall 0.7.7 → 0.7.8
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 +362 -210
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +305 -167
- package/dist/scan-worker.js +70 -16
- package/dist/watch.js +80 -26
- package/package.json +1 -1
- package/skills/chat-recall-find/SKILL.md +3 -1
- package/skills/chat-recall-resume/SKILL.md +3 -1
package/dist/scan-worker.js
CHANGED
|
@@ -9754,15 +9754,36 @@ var init_claude = __esm({
|
|
|
9754
9754
|
listSessions(opts = {}) {
|
|
9755
9755
|
const cutoff = opts.sinceMs ?? 0;
|
|
9756
9756
|
const filter = opts.projectFilter?.toLowerCase();
|
|
9757
|
-
const
|
|
9758
|
-
const out = [];
|
|
9757
|
+
const byId = /* @__PURE__ */ new Map();
|
|
9759
9758
|
for (const root of claudeProjectDirs()) {
|
|
9760
|
-
this.collectSessionsFromRoot(root,
|
|
9759
|
+
this.collectSessionsFromRoot(root, filter, byId, opts.previews !== false);
|
|
9761
9760
|
}
|
|
9761
|
+
const out = [...byId.values()].filter((r) => r.mtime >= cutoff);
|
|
9762
9762
|
out.sort((a, b) => b.mtime - a.mtime);
|
|
9763
9763
|
return opts.limit ? out.slice(0, opts.limit) : out;
|
|
9764
9764
|
}
|
|
9765
|
-
|
|
9765
|
+
/**
|
|
9766
|
+
* Add this root's sessions to `byId`. A session resumed under a second
|
|
9767
|
+
* profile has one file in each home under the same id. It is ONE session: the
|
|
9768
|
+
* first home keeps its path, and its mtime is the newest of all copies.
|
|
9769
|
+
*
|
|
9770
|
+
* Each copy was listed as its own ref before. Session 8da8d72b had a primary
|
|
9771
|
+
* copy frozen at 05:55 and a second-home copy growing until 12:00; the walk
|
|
9772
|
+
* handled both refs under one ledger row with two different mtimes, and the
|
|
9773
|
+
* row that shipped nothing stamped the other copy's mtime.
|
|
9774
|
+
*/
|
|
9775
|
+
collectSessionsFromRoot(root, filter, byId, previews) {
|
|
9776
|
+
const add = (ref) => {
|
|
9777
|
+
const prior = byId.get(ref.rawId);
|
|
9778
|
+
if (!prior) {
|
|
9779
|
+
byId.set(ref.rawId, ref);
|
|
9780
|
+
return;
|
|
9781
|
+
}
|
|
9782
|
+
if (ref.mtime > prior.mtime) {
|
|
9783
|
+
prior.mtime = ref.mtime;
|
|
9784
|
+
prior.modified = ref.modified;
|
|
9785
|
+
}
|
|
9786
|
+
};
|
|
9766
9787
|
if (!existsSync11(root))
|
|
9767
9788
|
return;
|
|
9768
9789
|
for (const proj of readdirSync8(root, { withFileTypes: true })) {
|
|
@@ -9773,6 +9794,7 @@ var init_claude = __esm({
|
|
|
9773
9794
|
const projPath = join11(root, proj.name);
|
|
9774
9795
|
const projectPath = resolveProjectDirName(proj.name);
|
|
9775
9796
|
const indexPath = join11(projPath, "sessions-index.json");
|
|
9797
|
+
const indexed = /* @__PURE__ */ new Set();
|
|
9776
9798
|
if (existsSync11(indexPath)) {
|
|
9777
9799
|
try {
|
|
9778
9800
|
const indexData = JSON.parse(readFileSync7(indexPath, "utf-8"));
|
|
@@ -9780,10 +9802,8 @@ var init_claude = __esm({
|
|
|
9780
9802
|
for (const entry of entries) {
|
|
9781
9803
|
if (!entry.fullPath || !existsSync11(entry.fullPath))
|
|
9782
9804
|
continue;
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
seen.add(entry.sessionId);
|
|
9786
|
-
out.push({
|
|
9805
|
+
indexed.add(entry.sessionId);
|
|
9806
|
+
add({
|
|
9787
9807
|
toolId: "claude",
|
|
9788
9808
|
rawId: entry.sessionId,
|
|
9789
9809
|
prefixedId: entry.sessionId,
|
|
@@ -9810,7 +9830,7 @@ var init_claude = __esm({
|
|
|
9810
9830
|
if (!f.endsWith(".jsonl") || f === "sessions-index.json")
|
|
9811
9831
|
continue;
|
|
9812
9832
|
const sessionId = basename6(f, ".jsonl");
|
|
9813
|
-
if (
|
|
9833
|
+
if (indexed.has(sessionId))
|
|
9814
9834
|
continue;
|
|
9815
9835
|
const fullPath = join11(projPath, f);
|
|
9816
9836
|
let stat;
|
|
@@ -9819,10 +9839,13 @@ var init_claude = __esm({
|
|
|
9819
9839
|
} catch {
|
|
9820
9840
|
continue;
|
|
9821
9841
|
}
|
|
9822
|
-
|
|
9842
|
+
const prior = byId.get(sessionId);
|
|
9843
|
+
if (prior) {
|
|
9844
|
+
add({ ...prior, mtime: stat.mtimeMs, modified: stat.mtime.toISOString() });
|
|
9823
9845
|
continue;
|
|
9846
|
+
}
|
|
9824
9847
|
const firstPrompt = previews ? extractFirstUserPromptSync(fullPath, { maxLength: 200 }) : "";
|
|
9825
|
-
|
|
9848
|
+
add({
|
|
9826
9849
|
toolId: "claude",
|
|
9827
9850
|
rawId: sessionId,
|
|
9828
9851
|
prefixedId: sessionId,
|
|
@@ -10326,6 +10349,7 @@ var init_shadow = __esm({
|
|
|
10326
10349
|
// ../engine/dist/core/live-session-scan.js
|
|
10327
10350
|
var live_session_scan_exports = {};
|
|
10328
10351
|
__export(live_session_scan_exports, {
|
|
10352
|
+
INDEX_RECHECK_MS: () => INDEX_RECHECK_MS,
|
|
10329
10353
|
MAX_EVENT_LINE_BYTES: () => MAX_EVENT_LINE_BYTES,
|
|
10330
10354
|
detectTool: () => detectTool,
|
|
10331
10355
|
findCodexSessionFile: () => findCodexSessionFile,
|
|
@@ -10372,9 +10396,29 @@ function findSessionFile(sessionId) {
|
|
|
10372
10396
|
function invalidateSessionFileIndex() {
|
|
10373
10397
|
indexCache = null;
|
|
10374
10398
|
}
|
|
10399
|
+
function indexStillValid(cache2) {
|
|
10400
|
+
const roots = claudeProjectDirs();
|
|
10401
|
+
if (roots.length !== cache2.roots.length || roots.some((r, i) => r !== cache2.roots[i]))
|
|
10402
|
+
return false;
|
|
10403
|
+
for (const [dir, mtime] of cache2.dirs) {
|
|
10404
|
+
if (dirMtime(dir) !== mtime)
|
|
10405
|
+
return false;
|
|
10406
|
+
}
|
|
10407
|
+
return true;
|
|
10408
|
+
}
|
|
10375
10409
|
function sessionFileIndex() {
|
|
10376
|
-
if (indexCache)
|
|
10377
|
-
|
|
10410
|
+
if (indexCache) {
|
|
10411
|
+
const now = Date.now();
|
|
10412
|
+
if (now - indexCache.checkedAt < INDEX_RECHECK_MS)
|
|
10413
|
+
return indexCache.byId;
|
|
10414
|
+
if (indexStillValid(indexCache)) {
|
|
10415
|
+
indexCache.checkedAt = now;
|
|
10416
|
+
return indexCache.byId;
|
|
10417
|
+
}
|
|
10418
|
+
indexCache = null;
|
|
10419
|
+
}
|
|
10420
|
+
const dirs = /* @__PURE__ */ new Map();
|
|
10421
|
+
const roots = claudeProjectDirs();
|
|
10378
10422
|
const byId = /* @__PURE__ */ new Map();
|
|
10379
10423
|
const seenRoots = /* @__PURE__ */ new Set();
|
|
10380
10424
|
const projectPaths = /* @__PURE__ */ new Map();
|
|
@@ -10386,10 +10430,11 @@ function sessionFileIndex() {
|
|
|
10386
10430
|
}
|
|
10387
10431
|
return p;
|
|
10388
10432
|
};
|
|
10389
|
-
for (const root of
|
|
10433
|
+
for (const root of roots) {
|
|
10390
10434
|
if (seenRoots.has(root) || !existsSync13(root))
|
|
10391
10435
|
continue;
|
|
10392
10436
|
seenRoots.add(root);
|
|
10437
|
+
dirs.set(root, dirMtime(root));
|
|
10393
10438
|
let entries;
|
|
10394
10439
|
try {
|
|
10395
10440
|
entries = readdirSync10(root, { withFileTypes: true });
|
|
@@ -10400,6 +10445,7 @@ function sessionFileIndex() {
|
|
|
10400
10445
|
if (!entry.isDirectory())
|
|
10401
10446
|
continue;
|
|
10402
10447
|
const dir = join13(root, entry.name);
|
|
10448
|
+
dirs.set(dir, dirMtime(dir));
|
|
10403
10449
|
let names;
|
|
10404
10450
|
try {
|
|
10405
10451
|
names = readdirSync10(dir);
|
|
@@ -10424,7 +10470,7 @@ function sessionFileIndex() {
|
|
|
10424
10470
|
}
|
|
10425
10471
|
}
|
|
10426
10472
|
if (scanScopeDepth > 0)
|
|
10427
|
-
indexCache = byId;
|
|
10473
|
+
indexCache = { byId, dirs, roots, checkedAt: Date.now() };
|
|
10428
10474
|
return byId;
|
|
10429
10475
|
}
|
|
10430
10476
|
function findSessionFiles(sessionId) {
|
|
@@ -10797,7 +10843,7 @@ function liveScanRecentEdits(opts) {
|
|
|
10797
10843
|
allEdits.sort((a, b) => b.ts - a.ts);
|
|
10798
10844
|
return allEdits;
|
|
10799
10845
|
}
|
|
10800
|
-
var scanScopeDepth, indexCache, readScope, readScopeDepth, derivedScope, geminiProjectMapCache, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
10846
|
+
var scanScopeDepth, indexCache, INDEX_RECHECK_MS, dirMtime, readScope, readScopeDepth, derivedScope, geminiProjectMapCache, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
10801
10847
|
var init_live_session_scan = __esm({
|
|
10802
10848
|
"../engine/dist/core/live-session-scan.js"() {
|
|
10803
10849
|
"use strict";
|
|
@@ -10809,6 +10855,14 @@ var init_live_session_scan = __esm({
|
|
|
10809
10855
|
init_project_dir_name();
|
|
10810
10856
|
scanScopeDepth = 0;
|
|
10811
10857
|
indexCache = null;
|
|
10858
|
+
INDEX_RECHECK_MS = 1e3;
|
|
10859
|
+
dirMtime = (p) => {
|
|
10860
|
+
try {
|
|
10861
|
+
return statSync11(p).mtimeMs;
|
|
10862
|
+
} catch {
|
|
10863
|
+
return -1;
|
|
10864
|
+
}
|
|
10865
|
+
};
|
|
10812
10866
|
readScope = null;
|
|
10813
10867
|
readScopeDepth = 0;
|
|
10814
10868
|
derivedScope = null;
|
package/dist/watch.js
CHANGED
|
@@ -6874,9 +6874,29 @@ function findSessionFile(sessionId) {
|
|
|
6874
6874
|
function invalidateSessionFileIndex() {
|
|
6875
6875
|
indexCache = null;
|
|
6876
6876
|
}
|
|
6877
|
+
function indexStillValid(cache4) {
|
|
6878
|
+
const roots = claudeProjectDirs();
|
|
6879
|
+
if (roots.length !== cache4.roots.length || roots.some((r, i) => r !== cache4.roots[i]))
|
|
6880
|
+
return false;
|
|
6881
|
+
for (const [dir, mtime] of cache4.dirs) {
|
|
6882
|
+
if (dirMtime(dir) !== mtime)
|
|
6883
|
+
return false;
|
|
6884
|
+
}
|
|
6885
|
+
return true;
|
|
6886
|
+
}
|
|
6877
6887
|
function sessionFileIndex() {
|
|
6878
|
-
if (indexCache)
|
|
6879
|
-
|
|
6888
|
+
if (indexCache) {
|
|
6889
|
+
const now = Date.now();
|
|
6890
|
+
if (now - indexCache.checkedAt < INDEX_RECHECK_MS)
|
|
6891
|
+
return indexCache.byId;
|
|
6892
|
+
if (indexStillValid(indexCache)) {
|
|
6893
|
+
indexCache.checkedAt = now;
|
|
6894
|
+
return indexCache.byId;
|
|
6895
|
+
}
|
|
6896
|
+
indexCache = null;
|
|
6897
|
+
}
|
|
6898
|
+
const dirs = /* @__PURE__ */ new Map();
|
|
6899
|
+
const roots = claudeProjectDirs();
|
|
6880
6900
|
const byId = /* @__PURE__ */ new Map();
|
|
6881
6901
|
const seenRoots = /* @__PURE__ */ new Set();
|
|
6882
6902
|
const projectPaths = /* @__PURE__ */ new Map();
|
|
@@ -6888,10 +6908,11 @@ function sessionFileIndex() {
|
|
|
6888
6908
|
}
|
|
6889
6909
|
return p;
|
|
6890
6910
|
};
|
|
6891
|
-
for (const root of
|
|
6911
|
+
for (const root of roots) {
|
|
6892
6912
|
if (seenRoots.has(root) || !existsSync7(root))
|
|
6893
6913
|
continue;
|
|
6894
6914
|
seenRoots.add(root);
|
|
6915
|
+
dirs.set(root, dirMtime(root));
|
|
6895
6916
|
let entries;
|
|
6896
6917
|
try {
|
|
6897
6918
|
entries = readdirSync6(root, { withFileTypes: true });
|
|
@@ -6902,6 +6923,7 @@ function sessionFileIndex() {
|
|
|
6902
6923
|
if (!entry.isDirectory())
|
|
6903
6924
|
continue;
|
|
6904
6925
|
const dir = join9(root, entry.name);
|
|
6926
|
+
dirs.set(dir, dirMtime(dir));
|
|
6905
6927
|
let names;
|
|
6906
6928
|
try {
|
|
6907
6929
|
names = readdirSync6(dir);
|
|
@@ -6926,7 +6948,7 @@ function sessionFileIndex() {
|
|
|
6926
6948
|
}
|
|
6927
6949
|
}
|
|
6928
6950
|
if (scanScopeDepth > 0)
|
|
6929
|
-
indexCache = byId;
|
|
6951
|
+
indexCache = { byId, dirs, roots, checkedAt: Date.now() };
|
|
6930
6952
|
return byId;
|
|
6931
6953
|
}
|
|
6932
6954
|
function findSessionFiles(sessionId) {
|
|
@@ -7084,7 +7106,7 @@ function findCodexSessionFileIn(root, sessionId) {
|
|
|
7084
7106
|
}
|
|
7085
7107
|
return scanDir(root);
|
|
7086
7108
|
}
|
|
7087
|
-
var scanScopeDepth, indexCache, readScope, readScopeDepth, derivedScope, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
7109
|
+
var scanScopeDepth, indexCache, INDEX_RECHECK_MS, dirMtime, readScope, readScopeDepth, derivedScope, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
7088
7110
|
var init_live_session_scan = __esm({
|
|
7089
7111
|
"../engine/dist/core/live-session-scan.js"() {
|
|
7090
7112
|
"use strict";
|
|
@@ -7096,6 +7118,14 @@ var init_live_session_scan = __esm({
|
|
|
7096
7118
|
init_project_dir_name();
|
|
7097
7119
|
scanScopeDepth = 0;
|
|
7098
7120
|
indexCache = null;
|
|
7121
|
+
INDEX_RECHECK_MS = 1e3;
|
|
7122
|
+
dirMtime = (p) => {
|
|
7123
|
+
try {
|
|
7124
|
+
return statSync5(p).mtimeMs;
|
|
7125
|
+
} catch {
|
|
7126
|
+
return -1;
|
|
7127
|
+
}
|
|
7128
|
+
};
|
|
7099
7129
|
readScope = null;
|
|
7100
7130
|
readScopeDepth = 0;
|
|
7101
7131
|
derivedScope = null;
|
|
@@ -8196,15 +8226,36 @@ var init_claude2 = __esm({
|
|
|
8196
8226
|
listSessions(opts = {}) {
|
|
8197
8227
|
const cutoff = opts.sinceMs ?? 0;
|
|
8198
8228
|
const filter = opts.projectFilter?.toLowerCase();
|
|
8199
|
-
const
|
|
8200
|
-
const out = [];
|
|
8229
|
+
const byId = /* @__PURE__ */ new Map();
|
|
8201
8230
|
for (const root of claudeProjectDirs()) {
|
|
8202
|
-
this.collectSessionsFromRoot(root,
|
|
8231
|
+
this.collectSessionsFromRoot(root, filter, byId, opts.previews !== false);
|
|
8203
8232
|
}
|
|
8233
|
+
const out = [...byId.values()].filter((r) => r.mtime >= cutoff);
|
|
8204
8234
|
out.sort((a, b) => b.mtime - a.mtime);
|
|
8205
8235
|
return opts.limit ? out.slice(0, opts.limit) : out;
|
|
8206
8236
|
}
|
|
8207
|
-
|
|
8237
|
+
/**
|
|
8238
|
+
* Add this root's sessions to `byId`. A session resumed under a second
|
|
8239
|
+
* profile has one file in each home under the same id. It is ONE session: the
|
|
8240
|
+
* first home keeps its path, and its mtime is the newest of all copies.
|
|
8241
|
+
*
|
|
8242
|
+
* Each copy was listed as its own ref before. Session 8da8d72b had a primary
|
|
8243
|
+
* copy frozen at 05:55 and a second-home copy growing until 12:00; the walk
|
|
8244
|
+
* handled both refs under one ledger row with two different mtimes, and the
|
|
8245
|
+
* row that shipped nothing stamped the other copy's mtime.
|
|
8246
|
+
*/
|
|
8247
|
+
collectSessionsFromRoot(root, filter, byId, previews) {
|
|
8248
|
+
const add = (ref) => {
|
|
8249
|
+
const prior = byId.get(ref.rawId);
|
|
8250
|
+
if (!prior) {
|
|
8251
|
+
byId.set(ref.rawId, ref);
|
|
8252
|
+
return;
|
|
8253
|
+
}
|
|
8254
|
+
if (ref.mtime > prior.mtime) {
|
|
8255
|
+
prior.mtime = ref.mtime;
|
|
8256
|
+
prior.modified = ref.modified;
|
|
8257
|
+
}
|
|
8258
|
+
};
|
|
8208
8259
|
if (!existsSync10(root))
|
|
8209
8260
|
return;
|
|
8210
8261
|
for (const proj of readdirSync7(root, { withFileTypes: true })) {
|
|
@@ -8215,6 +8266,7 @@ var init_claude2 = __esm({
|
|
|
8215
8266
|
const projPath = join10(root, proj.name);
|
|
8216
8267
|
const projectPath = resolveProjectDirName(proj.name);
|
|
8217
8268
|
const indexPath = join10(projPath, "sessions-index.json");
|
|
8269
|
+
const indexed = /* @__PURE__ */ new Set();
|
|
8218
8270
|
if (existsSync10(indexPath)) {
|
|
8219
8271
|
try {
|
|
8220
8272
|
const indexData = JSON.parse(readFileSync5(indexPath, "utf-8"));
|
|
@@ -8222,10 +8274,8 @@ var init_claude2 = __esm({
|
|
|
8222
8274
|
for (const entry of entries) {
|
|
8223
8275
|
if (!entry.fullPath || !existsSync10(entry.fullPath))
|
|
8224
8276
|
continue;
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
seen.add(entry.sessionId);
|
|
8228
|
-
out.push({
|
|
8277
|
+
indexed.add(entry.sessionId);
|
|
8278
|
+
add({
|
|
8229
8279
|
toolId: "claude",
|
|
8230
8280
|
rawId: entry.sessionId,
|
|
8231
8281
|
prefixedId: entry.sessionId,
|
|
@@ -8252,7 +8302,7 @@ var init_claude2 = __esm({
|
|
|
8252
8302
|
if (!f.endsWith(".jsonl") || f === "sessions-index.json")
|
|
8253
8303
|
continue;
|
|
8254
8304
|
const sessionId = basename8(f, ".jsonl");
|
|
8255
|
-
if (
|
|
8305
|
+
if (indexed.has(sessionId))
|
|
8256
8306
|
continue;
|
|
8257
8307
|
const fullPath = join10(projPath, f);
|
|
8258
8308
|
let stat3;
|
|
@@ -8261,10 +8311,13 @@ var init_claude2 = __esm({
|
|
|
8261
8311
|
} catch {
|
|
8262
8312
|
continue;
|
|
8263
8313
|
}
|
|
8264
|
-
|
|
8314
|
+
const prior = byId.get(sessionId);
|
|
8315
|
+
if (prior) {
|
|
8316
|
+
add({ ...prior, mtime: stat3.mtimeMs, modified: stat3.mtime.toISOString() });
|
|
8265
8317
|
continue;
|
|
8318
|
+
}
|
|
8266
8319
|
const firstPrompt = previews ? extractFirstUserPromptSync(fullPath, { maxLength: 200 }) : "";
|
|
8267
|
-
|
|
8320
|
+
add({
|
|
8268
8321
|
toolId: "claude",
|
|
8269
8322
|
rawId: sessionId,
|
|
8270
8323
|
prefixedId: sessionId,
|
|
@@ -18119,7 +18172,7 @@ var init_http = __esm({
|
|
|
18119
18172
|
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18120
18173
|
} catch {
|
|
18121
18174
|
try {
|
|
18122
|
-
if (true) CLI_VERSION = "0.7.
|
|
18175
|
+
if (true) CLI_VERSION = "0.7.8";
|
|
18123
18176
|
} catch {
|
|
18124
18177
|
}
|
|
18125
18178
|
}
|
|
@@ -18614,7 +18667,7 @@ var init_telemetry = __esm({
|
|
|
18614
18667
|
init_sync_client();
|
|
18615
18668
|
cliVersion = () => {
|
|
18616
18669
|
try {
|
|
18617
|
-
return true ? "0.7.
|
|
18670
|
+
return true ? "0.7.8" : "dev";
|
|
18618
18671
|
} catch {
|
|
18619
18672
|
return "dev";
|
|
18620
18673
|
}
|
|
@@ -20704,7 +20757,7 @@ var init_sync_client = __esm({
|
|
|
20704
20757
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
20705
20758
|
} catch {
|
|
20706
20759
|
try {
|
|
20707
|
-
if (true) ownVersion = "0.7.
|
|
20760
|
+
if (true) ownVersion = "0.7.8";
|
|
20708
20761
|
} catch {
|
|
20709
20762
|
}
|
|
20710
20763
|
}
|
|
@@ -23518,6 +23571,7 @@ var init_service_installer = __esm({
|
|
|
23518
23571
|
// auto-indexer/indexer.ts
|
|
23519
23572
|
init_backends();
|
|
23520
23573
|
init_paths();
|
|
23574
|
+
init_tool_paths();
|
|
23521
23575
|
init_collector_health();
|
|
23522
23576
|
init_settings();
|
|
23523
23577
|
init_sync_client();
|
|
@@ -23840,7 +23894,7 @@ try {
|
|
|
23840
23894
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23841
23895
|
} catch {
|
|
23842
23896
|
try {
|
|
23843
|
-
if (true) ownVersion2 = "0.7.
|
|
23897
|
+
if (true) ownVersion2 = "0.7.8";
|
|
23844
23898
|
} catch {
|
|
23845
23899
|
}
|
|
23846
23900
|
}
|
|
@@ -24225,9 +24279,8 @@ async function runCollectorMigration(opts) {
|
|
|
24225
24279
|
init_sync_ledger();
|
|
24226
24280
|
init_collector_health();
|
|
24227
24281
|
import { existsSync as existsSync50, readFileSync as readFileSync45, statSync as statSync45 } from "fs";
|
|
24228
|
-
var CLI_VERSION3 = true ? "0.7.
|
|
24282
|
+
var CLI_VERSION3 = true ? "0.7.8" : "0.0.0";
|
|
24229
24283
|
var DEBOUNCE_MS = 5e3;
|
|
24230
|
-
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24231
24284
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
24232
24285
|
var TASKS_DIR = claudeBackend.tasksDir();
|
|
24233
24286
|
var HISTORY_PATH = claudeBackend.historyFile();
|
|
@@ -24327,7 +24380,8 @@ function watchWithFallback(name, pattern, t) {
|
|
|
24327
24380
|
return w;
|
|
24328
24381
|
}
|
|
24329
24382
|
var WATCH_WINDOW_MS = Math.max(1, Number(process.env.CHAT_RECALL_WATCH_WINDOW_DAYS) || 14) * 24 * 60 * 60 * 1e3;
|
|
24330
|
-
var
|
|
24383
|
+
var CLAUDE_SESSION_ROOTS = claudeProjectDirs();
|
|
24384
|
+
var sessionWatcher = watchWithFallback("sessions", CLAUDE_SESSION_ROOTS.map((root) => `${root}/**/*.jsonl`), {
|
|
24331
24385
|
ignored: (p, stats) => {
|
|
24332
24386
|
if (/agent-/.test(p) || /^\./.test(basename25(p))) return true;
|
|
24333
24387
|
const st = stats ?? statSync45(p, { throwIfNoEntry: false });
|
|
@@ -24377,7 +24431,7 @@ var opencodeWatcher = chokidar.watch(
|
|
|
24377
24431
|
...POLL(1e4)
|
|
24378
24432
|
}
|
|
24379
24433
|
);
|
|
24380
|
-
var agentMemoryWatcher = chokidar.watch(`${
|
|
24434
|
+
var agentMemoryWatcher = chokidar.watch(CLAUDE_SESSION_ROOTS.map((root) => `${root}/*/memory/*.md`), {
|
|
24381
24435
|
persistent: true,
|
|
24382
24436
|
ignoreInitial: true,
|
|
24383
24437
|
awaitWriteFinish: { stabilityThreshold: 1e3, pollInterval: 100 },
|
|
@@ -24425,14 +24479,14 @@ for (const [name, watcher] of Object.entries(watchers)) {
|
|
|
24425
24479
|
});
|
|
24426
24480
|
}
|
|
24427
24481
|
daemonLog.info(`chat-recall ship daemon started (thin collector \u2014 no local index)`);
|
|
24428
|
-
daemonLog.info(` Watching sessions: ${
|
|
24482
|
+
daemonLog.info(` Watching sessions: ${CLAUDE_SESSION_ROOTS.join(", ")}`);
|
|
24429
24483
|
daemonLog.info(` Watching plans: ${PLANS_DIR}`);
|
|
24430
24484
|
daemonLog.info(` Watching tasks: ${TASKS_DIR}`);
|
|
24431
24485
|
daemonLog.info(` Watching history: ${HISTORY_PATH}`);
|
|
24432
24486
|
daemonLog.info(` Watching diary: ${DIARY_DIR}`);
|
|
24433
24487
|
daemonLog.info(` Watching codex: ${CODEX_SESSIONS_DIR}`);
|
|
24434
24488
|
daemonLog.info(` Watching opencode: ${OPENCODE_DB_DIR}`);
|
|
24435
|
-
daemonLog.info(` Watching agent memory: ${
|
|
24489
|
+
daemonLog.info(` Watching agent memory: ${CLAUDE_SESSION_ROOTS.map((root) => `${root}/*/memory/`).join(", ")}`);
|
|
24436
24490
|
daemonLog.info(` Resume-guard: ${CURRENT_RESUME_PATH}`);
|
|
24437
24491
|
daemonLog.info(` Debounce: ${DEBOUNCE_MS}ms \xB7 ships via syncIncremental() to the configured server`);
|
|
24438
24492
|
daemonLog.info(` Ready for changes...`);
|
package/package.json
CHANGED
|
@@ -40,7 +40,9 @@ description: >-
|
|
|
40
40
|
Every tool here takes a NAMED `session_id` (not a positional argument).
|
|
41
41
|
|
|
42
42
|
- `mcp__chat-recall__recall_show` — read the session slice (`around_line`,
|
|
43
|
-
`from_end`). Each message comes back in full
|
|
43
|
+
`from_end`). Each message comes back in full, with its tool calls and
|
|
44
|
+
results. A body over 2000 characters shows its ends and the `expand_line`
|
|
45
|
+
that returns it whole. It returns **10 messages
|
|
44
46
|
by default**: raise `max_messages` before telling the user what a session
|
|
45
47
|
contains, or you will describe a tenth of it as the whole.
|
|
46
48
|
- `mcp__chat-recall__recall_summary` — AI summary + outcome.
|
|
@@ -47,7 +47,9 @@ Once you have a session id:
|
|
|
47
47
|
- `mcp__chat-recall__recall_context` — structured context (requests, decisions,
|
|
48
48
|
files, tools).
|
|
49
49
|
- `mcp__chat-recall__recall_show` — raw slice; `from_end: N` for the last N
|
|
50
|
-
messages. Each message comes back in full, code and commands included
|
|
50
|
+
messages. Each message comes back in full, code and commands included, with
|
|
51
|
+
its tool results. A body over 2000 characters shows its ends; pass
|
|
52
|
+
`expand_line` to get it whole. It
|
|
51
53
|
returns 10 messages unless you raise `max_messages`, so don't read a partial
|
|
52
54
|
slice as the whole session.
|
|
53
55
|
- `mcp__chat-recall__recall_summary` — AI summary + outcome (did the work land?).
|