chat-recall 0.7.17 → 0.7.18
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 +567 -328
- package/dist/mcp-relay.js +136 -40
- package/dist/mcp-relay.js.map +1 -1
- package/dist/mcp.js +375 -125
- package/dist/mcp.js.map +1 -1
- package/dist/raw-archive-parts.d.ts +46 -0
- package/dist/raw-archive-parts.d.ts.map +1 -0
- package/dist/raw-archive-parts.js +175 -0
- package/dist/raw-archive-parts.js.map +1 -0
- package/dist/relay-lifecycle.d.ts +23 -0
- package/dist/relay-lifecycle.d.ts.map +1 -1
- package/dist/relay-lifecycle.js +173 -0
- package/dist/relay-lifecycle.js.map +1 -1
- package/dist/repair.d.ts.map +1 -1
- package/dist/repair.js +15 -7
- package/dist/repair.js.map +1 -1
- package/dist/scan-worker.js +2 -0
- package/dist/sync-client.d.ts +8 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +86 -5
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-ledger.d.ts +31 -1
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +47 -1
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +441 -199
- package/package.json +1 -1
package/dist/watch.js
CHANGED
|
@@ -2233,7 +2233,7 @@ var require_thread_stream = __commonJS({
|
|
|
2233
2233
|
var { version } = require_package();
|
|
2234
2234
|
var { EventEmitter } = __require("events");
|
|
2235
2235
|
var { Worker: Worker2 } = __require("worker_threads");
|
|
2236
|
-
var { join:
|
|
2236
|
+
var { join: join56 } = __require("path");
|
|
2237
2237
|
var { pathToFileURL } = __require("url");
|
|
2238
2238
|
var { wait } = require_wait();
|
|
2239
2239
|
var {
|
|
@@ -2276,7 +2276,7 @@ var require_thread_stream = __commonJS({
|
|
|
2276
2276
|
function createWorker(stream, opts) {
|
|
2277
2277
|
const { filename, workerData } = opts;
|
|
2278
2278
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
2279
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
2279
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join56(__dirname, "lib", "worker.js");
|
|
2280
2280
|
const worker = new Worker2(toExecute, {
|
|
2281
2281
|
...opts.workerOpts,
|
|
2282
2282
|
trackUnmanagedFds: false,
|
|
@@ -2679,7 +2679,7 @@ var require_transport = __commonJS({
|
|
|
2679
2679
|
"use strict";
|
|
2680
2680
|
var { createRequire: createRequire3 } = __require("module");
|
|
2681
2681
|
var getCallers = require_caller();
|
|
2682
|
-
var { join:
|
|
2682
|
+
var { join: join56, isAbsolute: isAbsolute4, sep: sep5 } = __require("node:path");
|
|
2683
2683
|
var sleep = require_atomic_sleep();
|
|
2684
2684
|
var onExit = require_on_exit_leak_free();
|
|
2685
2685
|
var ThreadStream = require_thread_stream();
|
|
@@ -2742,7 +2742,7 @@ var require_transport = __commonJS({
|
|
|
2742
2742
|
throw new Error("only one of target or targets can be specified");
|
|
2743
2743
|
}
|
|
2744
2744
|
if (targets) {
|
|
2745
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2745
|
+
target = bundlerOverrides["pino-worker"] || join56(__dirname, "worker.js");
|
|
2746
2746
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
2747
2747
|
return {
|
|
2748
2748
|
...dest,
|
|
@@ -2760,7 +2760,7 @@ var require_transport = __commonJS({
|
|
|
2760
2760
|
});
|
|
2761
2761
|
});
|
|
2762
2762
|
} else if (pipeline) {
|
|
2763
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2763
|
+
target = bundlerOverrides["pino-worker"] || join56(__dirname, "worker.js");
|
|
2764
2764
|
options.pipelines = [pipeline.map((dest) => {
|
|
2765
2765
|
return {
|
|
2766
2766
|
...dest,
|
|
@@ -2782,7 +2782,7 @@ var require_transport = __commonJS({
|
|
|
2782
2782
|
return origin;
|
|
2783
2783
|
}
|
|
2784
2784
|
if (origin === "pino/file") {
|
|
2785
|
-
return
|
|
2785
|
+
return join56(__dirname, "..", "file.js");
|
|
2786
2786
|
}
|
|
2787
2787
|
let fixTarget2;
|
|
2788
2788
|
for (const filePath of callers) {
|
|
@@ -3771,7 +3771,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3771
3771
|
return circularValue;
|
|
3772
3772
|
}
|
|
3773
3773
|
let res = "";
|
|
3774
|
-
let
|
|
3774
|
+
let join56 = ",";
|
|
3775
3775
|
const originalIndentation = indentation;
|
|
3776
3776
|
if (Array.isArray(value)) {
|
|
3777
3777
|
if (value.length === 0) {
|
|
@@ -3785,7 +3785,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3785
3785
|
indentation += spacer;
|
|
3786
3786
|
res += `
|
|
3787
3787
|
${indentation}`;
|
|
3788
|
-
|
|
3788
|
+
join56 = `,
|
|
3789
3789
|
${indentation}`;
|
|
3790
3790
|
}
|
|
3791
3791
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3793,13 +3793,13 @@ ${indentation}`;
|
|
|
3793
3793
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3794
3794
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3795
3795
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3796
|
-
res +=
|
|
3796
|
+
res += join56;
|
|
3797
3797
|
}
|
|
3798
3798
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3799
3799
|
res += tmp !== void 0 ? tmp : "null";
|
|
3800
3800
|
if (value.length - 1 > maximumBreadth) {
|
|
3801
3801
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3802
|
-
res += `${
|
|
3802
|
+
res += `${join56}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3803
3803
|
}
|
|
3804
3804
|
if (spacer !== "") {
|
|
3805
3805
|
res += `
|
|
@@ -3820,7 +3820,7 @@ ${originalIndentation}`;
|
|
|
3820
3820
|
let separator = "";
|
|
3821
3821
|
if (spacer !== "") {
|
|
3822
3822
|
indentation += spacer;
|
|
3823
|
-
|
|
3823
|
+
join56 = `,
|
|
3824
3824
|
${indentation}`;
|
|
3825
3825
|
whitespace = " ";
|
|
3826
3826
|
}
|
|
@@ -3834,13 +3834,13 @@ ${indentation}`;
|
|
|
3834
3834
|
const tmp = stringifyFnReplacer(key3, value, stack, replacer, spacer, indentation);
|
|
3835
3835
|
if (tmp !== void 0) {
|
|
3836
3836
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3837
|
-
separator =
|
|
3837
|
+
separator = join56;
|
|
3838
3838
|
}
|
|
3839
3839
|
}
|
|
3840
3840
|
if (keyLength > maximumBreadth) {
|
|
3841
3841
|
const removedKeys = keyLength - maximumBreadth;
|
|
3842
3842
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
3843
|
-
separator =
|
|
3843
|
+
separator = join56;
|
|
3844
3844
|
}
|
|
3845
3845
|
if (spacer !== "" && separator.length > 1) {
|
|
3846
3846
|
res = `
|
|
@@ -3881,7 +3881,7 @@ ${originalIndentation}`;
|
|
|
3881
3881
|
}
|
|
3882
3882
|
const originalIndentation = indentation;
|
|
3883
3883
|
let res = "";
|
|
3884
|
-
let
|
|
3884
|
+
let join56 = ",";
|
|
3885
3885
|
if (Array.isArray(value)) {
|
|
3886
3886
|
if (value.length === 0) {
|
|
3887
3887
|
return "[]";
|
|
@@ -3894,7 +3894,7 @@ ${originalIndentation}`;
|
|
|
3894
3894
|
indentation += spacer;
|
|
3895
3895
|
res += `
|
|
3896
3896
|
${indentation}`;
|
|
3897
|
-
|
|
3897
|
+
join56 = `,
|
|
3898
3898
|
${indentation}`;
|
|
3899
3899
|
}
|
|
3900
3900
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3902,13 +3902,13 @@ ${indentation}`;
|
|
|
3902
3902
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3903
3903
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3904
3904
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3905
|
-
res +=
|
|
3905
|
+
res += join56;
|
|
3906
3906
|
}
|
|
3907
3907
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3908
3908
|
res += tmp !== void 0 ? tmp : "null";
|
|
3909
3909
|
if (value.length - 1 > maximumBreadth) {
|
|
3910
3910
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3911
|
-
res += `${
|
|
3911
|
+
res += `${join56}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3912
3912
|
}
|
|
3913
3913
|
if (spacer !== "") {
|
|
3914
3914
|
res += `
|
|
@@ -3921,7 +3921,7 @@ ${originalIndentation}`;
|
|
|
3921
3921
|
let whitespace = "";
|
|
3922
3922
|
if (spacer !== "") {
|
|
3923
3923
|
indentation += spacer;
|
|
3924
|
-
|
|
3924
|
+
join56 = `,
|
|
3925
3925
|
${indentation}`;
|
|
3926
3926
|
whitespace = " ";
|
|
3927
3927
|
}
|
|
@@ -3930,7 +3930,7 @@ ${indentation}`;
|
|
|
3930
3930
|
const tmp = stringifyArrayReplacer(key3, value[key3], stack, replacer, spacer, indentation);
|
|
3931
3931
|
if (tmp !== void 0) {
|
|
3932
3932
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3933
|
-
separator =
|
|
3933
|
+
separator = join56;
|
|
3934
3934
|
}
|
|
3935
3935
|
}
|
|
3936
3936
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -3988,20 +3988,20 @@ ${originalIndentation}`;
|
|
|
3988
3988
|
indentation += spacer;
|
|
3989
3989
|
let res2 = `
|
|
3990
3990
|
${indentation}`;
|
|
3991
|
-
const
|
|
3991
|
+
const join57 = `,
|
|
3992
3992
|
${indentation}`;
|
|
3993
3993
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
3994
3994
|
let i = 0;
|
|
3995
3995
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3996
3996
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
3997
3997
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
3998
|
-
res2 +=
|
|
3998
|
+
res2 += join57;
|
|
3999
3999
|
}
|
|
4000
4000
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
4001
4001
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
4002
4002
|
if (value.length - 1 > maximumBreadth) {
|
|
4003
4003
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
4004
|
-
res2 += `${
|
|
4004
|
+
res2 += `${join57}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
4005
4005
|
}
|
|
4006
4006
|
res2 += `
|
|
4007
4007
|
${originalIndentation}`;
|
|
@@ -4017,16 +4017,16 @@ ${originalIndentation}`;
|
|
|
4017
4017
|
return '"[Object]"';
|
|
4018
4018
|
}
|
|
4019
4019
|
indentation += spacer;
|
|
4020
|
-
const
|
|
4020
|
+
const join56 = `,
|
|
4021
4021
|
${indentation}`;
|
|
4022
4022
|
let res = "";
|
|
4023
4023
|
let separator = "";
|
|
4024
4024
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
4025
4025
|
if (isTypedArrayWithEntries(value)) {
|
|
4026
|
-
res += stringifyTypedArray(value,
|
|
4026
|
+
res += stringifyTypedArray(value, join56, maximumBreadth);
|
|
4027
4027
|
keys = keys.slice(value.length);
|
|
4028
4028
|
maximumPropertiesToStringify -= value.length;
|
|
4029
|
-
separator =
|
|
4029
|
+
separator = join56;
|
|
4030
4030
|
}
|
|
4031
4031
|
if (deterministic) {
|
|
4032
4032
|
keys = sort(keys, comparator);
|
|
@@ -4037,13 +4037,13 @@ ${indentation}`;
|
|
|
4037
4037
|
const tmp = stringifyIndent(key3, value[key3], stack, spacer, indentation);
|
|
4038
4038
|
if (tmp !== void 0) {
|
|
4039
4039
|
res += `${separator}${strEscape(key3)}: ${tmp}`;
|
|
4040
|
-
separator =
|
|
4040
|
+
separator = join56;
|
|
4041
4041
|
}
|
|
4042
4042
|
}
|
|
4043
4043
|
if (keyLength > maximumBreadth) {
|
|
4044
4044
|
const removedKeys = keyLength - maximumBreadth;
|
|
4045
4045
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
4046
|
-
separator =
|
|
4046
|
+
separator = join56;
|
|
4047
4047
|
}
|
|
4048
4048
|
if (separator !== "") {
|
|
4049
4049
|
res = `
|
|
@@ -6448,6 +6448,7 @@ var init_from_events = __esm({
|
|
|
6448
6448
|
// ../engine/dist/transcript/raw.js
|
|
6449
6449
|
var raw_exports = {};
|
|
6450
6450
|
__export(raw_exports, {
|
|
6451
|
+
RAW_PARSE_MAX_BYTES: () => RAW_PARSE_MAX_BYTES,
|
|
6451
6452
|
archiveRawSession: () => archiveRawSession,
|
|
6452
6453
|
buildRawContainer: () => buildRawContainer,
|
|
6453
6454
|
containerSrcHash: () => containerSrcHash,
|
|
@@ -6747,11 +6748,11 @@ async function archiveRawSession(store, sessionId) {
|
|
|
6747
6748
|
return await store.putRawSession(sessionId, exp.tool, Math.floor(exp.mtime), gz, size);
|
|
6748
6749
|
}
|
|
6749
6750
|
function detectForkPredecessor(sessionPath) {
|
|
6750
|
-
const { readFileSync:
|
|
6751
|
-
const { dirname: dirname26, join:
|
|
6751
|
+
const { readFileSync: readFileSync47, readdirSync: readdirSync33 } = requireFs();
|
|
6752
|
+
const { dirname: dirname26, join: join56, basename: basename26 } = requirePath();
|
|
6752
6753
|
let text;
|
|
6753
6754
|
try {
|
|
6754
|
-
text =
|
|
6755
|
+
text = readFileSync47(sessionPath, "utf-8");
|
|
6755
6756
|
} catch {
|
|
6756
6757
|
return null;
|
|
6757
6758
|
}
|
|
@@ -6785,7 +6786,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
6785
6786
|
if (!f.endsWith(".jsonl") || f === self || f === "sessions-index.json")
|
|
6786
6787
|
continue;
|
|
6787
6788
|
try {
|
|
6788
|
-
if (
|
|
6789
|
+
if (readFileSync47(join56(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
|
|
6789
6790
|
return basename26(f, ".jsonl");
|
|
6790
6791
|
}
|
|
6791
6792
|
} catch {
|
|
@@ -6799,7 +6800,7 @@ function requireFs() {
|
|
|
6799
6800
|
function requirePath() {
|
|
6800
6801
|
return pathMod;
|
|
6801
6802
|
}
|
|
6802
|
-
var MARKER_QUOTE;
|
|
6803
|
+
var RAW_PARSE_MAX_BYTES, MARKER_QUOTE;
|
|
6803
6804
|
var init_raw = __esm({
|
|
6804
6805
|
"../engine/dist/transcript/raw.js"() {
|
|
6805
6806
|
"use strict";
|
|
@@ -6807,6 +6808,7 @@ var init_raw = __esm({
|
|
|
6807
6808
|
init_claude();
|
|
6808
6809
|
init_codex();
|
|
6809
6810
|
init_from_events();
|
|
6811
|
+
RAW_PARSE_MAX_BYTES = 40 * 1024 * 1024;
|
|
6810
6812
|
MARKER_QUOTE = /\[REDACTED:[A-Za-z0-9_-]+\]"/g;
|
|
6811
6813
|
}
|
|
6812
6814
|
});
|
|
@@ -13525,6 +13527,7 @@ var init_opencode2 = __esm({
|
|
|
13525
13527
|
// ../engine/dist/transcript/index.js
|
|
13526
13528
|
var transcript_exports = {};
|
|
13527
13529
|
__export(transcript_exports, {
|
|
13530
|
+
RAW_PARSE_MAX_BYTES: () => RAW_PARSE_MAX_BYTES,
|
|
13528
13531
|
TRANSCRIPT_VERSION: () => TRANSCRIPT_VERSION,
|
|
13529
13532
|
archiveRawSession: () => archiveRawSession,
|
|
13530
13533
|
buildRawContainer: () => buildRawContainer,
|
|
@@ -18104,12 +18107,15 @@ var init_extractor_version = __esm({
|
|
|
18104
18107
|
// src/sync-ledger.ts
|
|
18105
18108
|
var sync_ledger_exports = {};
|
|
18106
18109
|
__export(sync_ledger_exports, {
|
|
18110
|
+
SETTLE_QUIET_MS: () => SETTLE_QUIET_MS,
|
|
18107
18111
|
_resetLedgerCacheForTests: () => _resetLedgerCacheForTests,
|
|
18108
18112
|
_resetUnackedCursorCount: () => _resetUnackedCursorCount,
|
|
18109
18113
|
fieldNeedsFullPass: () => fieldNeedsFullPass,
|
|
18110
18114
|
fieldNeedsScan: () => fieldNeedsScan,
|
|
18111
18115
|
flushLedger: () => flushLedger,
|
|
18112
18116
|
forceFieldRescan: () => forceFieldRescan,
|
|
18117
|
+
forgetFullCoverage: () => forgetFullCoverage,
|
|
18118
|
+
fullCoveredOffset: () => fullCoveredOffset,
|
|
18113
18119
|
getLedgerData: () => getLedgerData,
|
|
18114
18120
|
getSyncedMtimes: () => getSyncedMtimes,
|
|
18115
18121
|
getSyncedRows: () => getSyncedRows,
|
|
@@ -18361,6 +18367,11 @@ function markSynced(server, rows) {
|
|
|
18361
18367
|
base3.s = s;
|
|
18362
18368
|
}
|
|
18363
18369
|
if (r.hash !== void 0) base3.h = r.hash;
|
|
18370
|
+
const completesChunked = cursorFromCaller && r.chunkFinal === true && prev?.k === 1;
|
|
18371
|
+
if (cursorFromCaller && (r.full || completesChunked) && o > 0) base3.F = o;
|
|
18372
|
+
else if (prev?.F !== void 0) base3.F = prev.F;
|
|
18373
|
+
if (cursorFromCaller && r.chunkedHead) base3.k = 1;
|
|
18374
|
+
else if (prev?.k && !completesChunked && !(cursorFromCaller && r.full)) base3.k = 1;
|
|
18364
18375
|
forServer[r.id] = base3;
|
|
18365
18376
|
}
|
|
18366
18377
|
persist(data);
|
|
@@ -18434,6 +18445,14 @@ function _resetLedgerCacheForTests() {
|
|
|
18434
18445
|
diskStamp = null;
|
|
18435
18446
|
reconcileCache = null;
|
|
18436
18447
|
}
|
|
18448
|
+
function forgetFullCoverage(server, sessionId) {
|
|
18449
|
+
const data = load();
|
|
18450
|
+
const row = data[server]?.[sessionId];
|
|
18451
|
+
if (!row || typeof row !== "object") return;
|
|
18452
|
+
delete row.F;
|
|
18453
|
+
delete row.h;
|
|
18454
|
+
persist(data);
|
|
18455
|
+
}
|
|
18437
18456
|
function markFullResync(server, sessionId) {
|
|
18438
18457
|
const data = load();
|
|
18439
18458
|
const forServer = data[server];
|
|
@@ -18442,7 +18461,11 @@ function markFullResync(server, sessionId) {
|
|
|
18442
18461
|
delete forServer[sessionId];
|
|
18443
18462
|
persist(data);
|
|
18444
18463
|
}
|
|
18445
|
-
function
|
|
18464
|
+
function fullCoveredOffset(row) {
|
|
18465
|
+
if (row.F !== void 0) return row.F;
|
|
18466
|
+
return row.h ? row.s ?? 0 : 0;
|
|
18467
|
+
}
|
|
18468
|
+
function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly, nowMs = Date.now()) {
|
|
18446
18469
|
if (!row) return "full";
|
|
18447
18470
|
if (row.v < extractorVersion) return "full";
|
|
18448
18471
|
const offset = row.o ?? 0;
|
|
@@ -18450,10 +18473,13 @@ function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly) {
|
|
|
18450
18473
|
if (process.env.CHAT_RECALL_TAIL_APPEND !== "0" && isAppendOnly && fileSize > 0 && offset > 0 && fileSize > (row.s ?? 0)) {
|
|
18451
18474
|
return "append";
|
|
18452
18475
|
}
|
|
18476
|
+
if (isAppendOnly && offset > 0 && fileSize > 0 && fileSize === (row.s ?? 0) && !row.k && fullCoveredOffset(row) < offset && nowMs - Math.floor(mtime) >= SETTLE_QUIET_MS) {
|
|
18477
|
+
return "full";
|
|
18478
|
+
}
|
|
18453
18479
|
if (row.m >= Math.floor(mtime)) return "skip";
|
|
18454
18480
|
return "full";
|
|
18455
18481
|
}
|
|
18456
|
-
var ledgerPath, cache3, base, diskStamp, rowKey, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
18482
|
+
var ledgerPath, cache3, base, diskStamp, rowKey, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache, SETTLE_QUIET_MS;
|
|
18457
18483
|
var init_sync_ledger = __esm({
|
|
18458
18484
|
"src/sync-ledger.ts"() {
|
|
18459
18485
|
"use strict";
|
|
@@ -18473,6 +18499,7 @@ var init_sync_ledger = __esm({
|
|
|
18473
18499
|
unackedCursorAttempts = 0;
|
|
18474
18500
|
reconcilePath = () => join39(getDataDir(), "sync-field-reconcile.json");
|
|
18475
18501
|
reconcileCache = null;
|
|
18502
|
+
SETTLE_QUIET_MS = 2 * 60 * 60 * 1e3;
|
|
18476
18503
|
}
|
|
18477
18504
|
});
|
|
18478
18505
|
|
|
@@ -18615,7 +18642,7 @@ var init_http = __esm({
|
|
|
18615
18642
|
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18616
18643
|
} catch {
|
|
18617
18644
|
try {
|
|
18618
|
-
if (true) CLI_VERSION = "0.7.
|
|
18645
|
+
if (true) CLI_VERSION = "0.7.18";
|
|
18619
18646
|
} catch {
|
|
18620
18647
|
}
|
|
18621
18648
|
}
|
|
@@ -19109,7 +19136,7 @@ var init_telemetry = __esm({
|
|
|
19109
19136
|
init_sync_client();
|
|
19110
19137
|
cliVersion = () => {
|
|
19111
19138
|
try {
|
|
19112
|
-
return true ? "0.7.
|
|
19139
|
+
return true ? "0.7.18" : "dev";
|
|
19113
19140
|
} catch {
|
|
19114
19141
|
return "dev";
|
|
19115
19142
|
}
|
|
@@ -19119,6 +19146,150 @@ var init_telemetry = __esm({
|
|
|
19119
19146
|
}
|
|
19120
19147
|
});
|
|
19121
19148
|
|
|
19149
|
+
// src/raw-archive-parts.ts
|
|
19150
|
+
import { createReadStream as createReadStream4, createWriteStream, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, rmSync as rmSync5, statSync as statSync37 } from "node:fs";
|
|
19151
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
19152
|
+
import { join as join41 } from "node:path";
|
|
19153
|
+
import { randomBytes } from "node:crypto";
|
|
19154
|
+
import { createGzip } from "node:zlib";
|
|
19155
|
+
import { once } from "node:events";
|
|
19156
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
19157
|
+
async function* fileLines(path) {
|
|
19158
|
+
let rest = "";
|
|
19159
|
+
const decoder = new TextDecoder("utf-8");
|
|
19160
|
+
for await (const chunk of createReadStream4(path, { highWaterMark: 1024 * 1024 })) {
|
|
19161
|
+
rest += decoder.decode(chunk, { stream: true });
|
|
19162
|
+
let nl = rest.indexOf("\n");
|
|
19163
|
+
while (nl >= 0) {
|
|
19164
|
+
yield rest.slice(0, nl + 1);
|
|
19165
|
+
rest = rest.slice(nl + 1);
|
|
19166
|
+
nl = rest.indexOf("\n");
|
|
19167
|
+
}
|
|
19168
|
+
}
|
|
19169
|
+
rest += decoder.decode();
|
|
19170
|
+
if (rest) yield rest;
|
|
19171
|
+
}
|
|
19172
|
+
function* textLines(text) {
|
|
19173
|
+
let at = 0;
|
|
19174
|
+
while (at < text.length) {
|
|
19175
|
+
const nl = text.indexOf("\n", at);
|
|
19176
|
+
const end = nl < 0 ? text.length : nl + 1;
|
|
19177
|
+
yield text.slice(at, end);
|
|
19178
|
+
at = end;
|
|
19179
|
+
}
|
|
19180
|
+
}
|
|
19181
|
+
async function writeArchiveFile(source, meta, redact, dir = tmpdir2()) {
|
|
19182
|
+
const path = join41(dir, `cr-archive-${randomBytes(8).toString("hex")}.json.gz`);
|
|
19183
|
+
const gzip = createGzip({ level: 6 });
|
|
19184
|
+
const out = createWriteStream(path, { mode: 384 });
|
|
19185
|
+
const done = once(out, "finish");
|
|
19186
|
+
gzip.pipe(out);
|
|
19187
|
+
let size = 0;
|
|
19188
|
+
const write = async (s) => {
|
|
19189
|
+
size += Buffer.byteLength(s);
|
|
19190
|
+
if (!gzip.write(s)) await once(gzip, "drain");
|
|
19191
|
+
};
|
|
19192
|
+
try {
|
|
19193
|
+
await write(`{"v":1,"tool":${JSON.stringify(meta.tool)},"mtime":${Math.floor(meta.mtime)},"files":[`);
|
|
19194
|
+
for (const [i, f] of source.files.entries()) {
|
|
19195
|
+
await write(`${i ? "," : ""}{"name":${JSON.stringify(f.name)},"text":"`);
|
|
19196
|
+
const whole = () => source.kind === "memory" ? f.text : readFileSync33(f.path, "utf-8");
|
|
19197
|
+
if (!f.name.endsWith(".jsonl")) {
|
|
19198
|
+
await write(escapeJson(redact(whole())));
|
|
19199
|
+
} else {
|
|
19200
|
+
const lines = source.kind === "memory" ? textLines(f.text) : fileLines(f.path);
|
|
19201
|
+
for await (const line of lines) {
|
|
19202
|
+
const nl = line.endsWith("\n");
|
|
19203
|
+
const body = nl ? line.slice(0, -1) : line;
|
|
19204
|
+
await write(escapeJson((body ? redactJsonLine(body, redact) : body) + (nl ? "\n" : "")));
|
|
19205
|
+
}
|
|
19206
|
+
}
|
|
19207
|
+
await write('"}');
|
|
19208
|
+
}
|
|
19209
|
+
await write("]}");
|
|
19210
|
+
gzip.end();
|
|
19211
|
+
await done;
|
|
19212
|
+
} catch (err) {
|
|
19213
|
+
gzip.destroy();
|
|
19214
|
+
out.destroy();
|
|
19215
|
+
rmSync5(path, { force: true });
|
|
19216
|
+
throw err;
|
|
19217
|
+
}
|
|
19218
|
+
return { path, gzSize: statSync37(path).size, size };
|
|
19219
|
+
}
|
|
19220
|
+
async function putPart(url, body) {
|
|
19221
|
+
let last;
|
|
19222
|
+
for (let attempt = 1; attempt <= PART_ATTEMPTS; attempt++) {
|
|
19223
|
+
const ac = new AbortController();
|
|
19224
|
+
const timer = setTimeout(() => ac.abort(), PART_TIMEOUT_MS);
|
|
19225
|
+
try {
|
|
19226
|
+
const r = await fetch(url, { method: "PUT", body, signal: ac.signal });
|
|
19227
|
+
const etag = r.headers.get("etag");
|
|
19228
|
+
if (r.ok && etag) return etag;
|
|
19229
|
+
last = new Error(`part PUT answered ${r.status}`);
|
|
19230
|
+
if (r.status === 403 || r.status === 404) break;
|
|
19231
|
+
} catch (err) {
|
|
19232
|
+
last = err;
|
|
19233
|
+
} finally {
|
|
19234
|
+
clearTimeout(timer);
|
|
19235
|
+
}
|
|
19236
|
+
}
|
|
19237
|
+
throw last instanceof Error ? last : new Error(String(last));
|
|
19238
|
+
}
|
|
19239
|
+
async function uploadArchiveFile(base3, token, args) {
|
|
19240
|
+
const headers = { "content-type": "application/json" };
|
|
19241
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
19242
|
+
const post = async (path, body) => {
|
|
19243
|
+
const r = await fetch(`${base3}/api/sync/raw-upload/${path}`, { method: "POST", headers, body: JSON.stringify(body) });
|
|
19244
|
+
const json = await r.json().catch(() => ({}));
|
|
19245
|
+
return { status: r.status, json };
|
|
19246
|
+
};
|
|
19247
|
+
const start = await post("start", {
|
|
19248
|
+
session_id: args.sessionId,
|
|
19249
|
+
tool: args.tool,
|
|
19250
|
+
mtime: Math.floor(args.mtime),
|
|
19251
|
+
size: args.file.size,
|
|
19252
|
+
gz_size: args.file.gzSize,
|
|
19253
|
+
project_id: args.projectId,
|
|
19254
|
+
project_path: args.projectPath
|
|
19255
|
+
});
|
|
19256
|
+
if (start.status === 501 || start.status === 404) return "unsupported";
|
|
19257
|
+
if (start.status !== 200) throw new Error(`raw upload start answered ${start.status}: ${start.json.error ?? ""}`);
|
|
19258
|
+
if (start.json.result === "unchanged" || start.json.result === "shrink-protected") return start.json.result;
|
|
19259
|
+
const urls = start.json.urls;
|
|
19260
|
+
const partBytes = Number(start.json.part_bytes);
|
|
19261
|
+
const parts = [];
|
|
19262
|
+
const fd = openSync9(args.file.path, "r");
|
|
19263
|
+
try {
|
|
19264
|
+
for (const [i, url] of urls.entries()) {
|
|
19265
|
+
const len = Math.min(partBytes, args.file.gzSize - i * partBytes);
|
|
19266
|
+
const buf = Buffer.allocUnsafe(len);
|
|
19267
|
+
let got = 0;
|
|
19268
|
+
while (got < len) {
|
|
19269
|
+
const n = readSync8(fd, buf, got, len - got, i * partBytes + got);
|
|
19270
|
+
if (n <= 0) break;
|
|
19271
|
+
got += n;
|
|
19272
|
+
}
|
|
19273
|
+
parts.push({ part_number: i + 1, etag: await putPart(url, buf.subarray(0, got)) });
|
|
19274
|
+
}
|
|
19275
|
+
} finally {
|
|
19276
|
+
closeSync9(fd);
|
|
19277
|
+
}
|
|
19278
|
+
const done = await post("complete", { session_id: args.sessionId, upload_id: start.json.upload_id, parts });
|
|
19279
|
+
if (done.status !== 200) throw new Error(`raw upload complete answered ${done.status}: ${done.json.error ?? ""}`);
|
|
19280
|
+
return done.json.result;
|
|
19281
|
+
}
|
|
19282
|
+
var escapeJson, PART_TIMEOUT_MS, PART_ATTEMPTS;
|
|
19283
|
+
var init_raw_archive_parts = __esm({
|
|
19284
|
+
"src/raw-archive-parts.ts"() {
|
|
19285
|
+
"use strict";
|
|
19286
|
+
init_transcript();
|
|
19287
|
+
escapeJson = (s) => JSON.stringify(s).slice(1, -1);
|
|
19288
|
+
PART_TIMEOUT_MS = 12e4;
|
|
19289
|
+
PART_ATTEMPTS = 3;
|
|
19290
|
+
}
|
|
19291
|
+
});
|
|
19292
|
+
|
|
19122
19293
|
// src/server-probe.ts
|
|
19123
19294
|
var server_probe_exports = {};
|
|
19124
19295
|
__export(server_probe_exports, {
|
|
@@ -19262,7 +19433,7 @@ __export(client_events_exports, {
|
|
|
19262
19433
|
isTelemetryEnabled: () => isTelemetryEnabled,
|
|
19263
19434
|
reportClientEvent: () => reportClientEvent
|
|
19264
19435
|
});
|
|
19265
|
-
import { readFileSync as
|
|
19436
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
19266
19437
|
function scrub(msg) {
|
|
19267
19438
|
if (!msg) return "";
|
|
19268
19439
|
const noHome = msg.replace(/\/(?:home|Users)\/[^/\s]+/g, "~");
|
|
@@ -19315,7 +19486,7 @@ var init_client_events = __esm({
|
|
|
19315
19486
|
init_secret_redactor();
|
|
19316
19487
|
CLI_VERSION2 = "0.0.0";
|
|
19317
19488
|
try {
|
|
19318
|
-
CLI_VERSION2 = JSON.parse(
|
|
19489
|
+
CLI_VERSION2 = JSON.parse(readFileSync34(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION2;
|
|
19319
19490
|
} catch {
|
|
19320
19491
|
}
|
|
19321
19492
|
}
|
|
@@ -19345,11 +19516,11 @@ __export(auto_update_exports, {
|
|
|
19345
19516
|
tarballUrl: () => tarballUrl
|
|
19346
19517
|
});
|
|
19347
19518
|
import { execSync as execSync2, execFileSync as execFileSync3 } from "node:child_process";
|
|
19348
|
-
import { readFileSync as
|
|
19519
|
+
import { readFileSync as readFileSync35, existsSync as existsSync41 } from "node:fs";
|
|
19349
19520
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19350
|
-
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as
|
|
19351
|
-
import { join as
|
|
19352
|
-
import { tmpdir as
|
|
19521
|
+
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync6, readdirSync as readdirSync30, statSync as statSync38, mkdirSync as mkdirSync9 } from "node:fs";
|
|
19522
|
+
import { join as join42, dirname as dirname18, sep as sep2, posix as pathPosix, win32 as pathWin32 } from "node:path";
|
|
19523
|
+
import { tmpdir as tmpdir3, homedir as homedir15 } from "node:os";
|
|
19353
19524
|
import { createHash as createHash7 } from "node:crypto";
|
|
19354
19525
|
function compareVersions(a, b) {
|
|
19355
19526
|
const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -19373,7 +19544,7 @@ function newerOf(a, b) {
|
|
|
19373
19544
|
function installedVersion() {
|
|
19374
19545
|
try {
|
|
19375
19546
|
const here = dirname18(fileURLToPath2(import.meta.url));
|
|
19376
|
-
const raw =
|
|
19547
|
+
const raw = readFileSync35(join42(here, "..", "package.json"), "utf-8");
|
|
19377
19548
|
return JSON.parse(raw).version || null;
|
|
19378
19549
|
} catch {
|
|
19379
19550
|
return null;
|
|
@@ -19386,7 +19557,7 @@ function planAutoUpdate(base3, caps, ownVersion3, flag) {
|
|
|
19386
19557
|
if (compareVersions(rel.version, ownVersion3) <= 0) return { update: false, reason: `already current (own ${ownVersion3} >= server ${rel.version})` };
|
|
19387
19558
|
return { update: true, reason: `server ${rel.version} > own ${ownVersion3}`, url: tarballUrl(base3, rel.version), fallbackUrl: tarballUrl(base3), sha256: rel.sha256, from: ownVersion3, to: rel.version };
|
|
19388
19559
|
}
|
|
19389
|
-
function sweepStaleStaging(root =
|
|
19560
|
+
function sweepStaleStaging(root = tmpdir3(), now = Date.now()) {
|
|
19390
19561
|
const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
|
|
19391
19562
|
const COLD_MS = 60 * 60 * 1e3;
|
|
19392
19563
|
let removed = 0;
|
|
@@ -19398,13 +19569,13 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
19398
19569
|
}
|
|
19399
19570
|
for (const name of entries) {
|
|
19400
19571
|
if (!MKDTEMP_SUFFIX.test(name)) continue;
|
|
19401
|
-
const dir =
|
|
19572
|
+
const dir = join42(root, name);
|
|
19402
19573
|
try {
|
|
19403
|
-
const st =
|
|
19574
|
+
const st = statSync38(dir);
|
|
19404
19575
|
if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
|
|
19405
19576
|
const inside = readdirSync30(dir);
|
|
19406
19577
|
if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
|
|
19407
|
-
|
|
19578
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19408
19579
|
removed++;
|
|
19409
19580
|
} catch {
|
|
19410
19581
|
}
|
|
@@ -19427,14 +19598,14 @@ async function executeAutoUpdate(plan, deps) {
|
|
|
19427
19598
|
}
|
|
19428
19599
|
const got = createHash7("sha256").update(buf).digest("hex");
|
|
19429
19600
|
if (got !== plan.sha256) return { updated: false, reason: `checksum mismatch (expected ${plan.sha256.slice(0, 12)}\u2026, got ${got.slice(0, 12)}\u2026) \u2014 NOT installing` };
|
|
19430
|
-
const dir = mkdtempSync3(
|
|
19601
|
+
const dir = mkdtempSync3(join42(tmpdir3(), "cr-update-"));
|
|
19431
19602
|
const discardStaging = () => {
|
|
19432
19603
|
try {
|
|
19433
|
-
|
|
19604
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19434
19605
|
} catch {
|
|
19435
19606
|
}
|
|
19436
19607
|
};
|
|
19437
|
-
const tgz =
|
|
19608
|
+
const tgz = join42(dir, "chat-recall.tgz");
|
|
19438
19609
|
writeFileSync8(tgz, buf);
|
|
19439
19610
|
if (deps.stopping?.()) {
|
|
19440
19611
|
discardStaging();
|
|
@@ -19514,7 +19685,7 @@ function realInstall(tgz) {
|
|
|
19514
19685
|
try {
|
|
19515
19686
|
npmInstall(npm, ["install", "-g", tgz]);
|
|
19516
19687
|
} catch {
|
|
19517
|
-
npmInstall(npm, ["install", "-g", "--prefix",
|
|
19688
|
+
npmInstall(npm, ["install", "-g", "--prefix", join42(homedir15(), ".local"), tgz]);
|
|
19518
19689
|
}
|
|
19519
19690
|
}
|
|
19520
19691
|
function acquireUpdateLock() {
|
|
@@ -19531,12 +19702,12 @@ function realRestart(platform2) {
|
|
|
19531
19702
|
if (c) execSync2(c.cmd, { stdio: "ignore", ...c.shell ? { shell: c.shell } : {} });
|
|
19532
19703
|
}
|
|
19533
19704
|
function updateStatePath() {
|
|
19534
|
-
const dir = process.env.CHAT_RECALL_DATA_DIR ||
|
|
19535
|
-
return
|
|
19705
|
+
const dir = process.env.CHAT_RECALL_DATA_DIR || join42(homedir15(), ".chat-recall");
|
|
19706
|
+
return join42(dir, "auto-update-state.json");
|
|
19536
19707
|
}
|
|
19537
19708
|
function readUpdateState() {
|
|
19538
19709
|
try {
|
|
19539
|
-
return JSON.parse(
|
|
19710
|
+
return JSON.parse(readFileSync35(updateStatePath(), "utf8"));
|
|
19540
19711
|
} catch {
|
|
19541
19712
|
return {};
|
|
19542
19713
|
}
|
|
@@ -19643,9 +19814,9 @@ var init_auto_update = __esm({
|
|
|
19643
19814
|
});
|
|
19644
19815
|
|
|
19645
19816
|
// src/sync-client.ts
|
|
19646
|
-
import { join as
|
|
19647
|
-
import { readFileSync as
|
|
19648
|
-
import { tmpdir as
|
|
19817
|
+
import { join as join43, dirname as dirname19, basename as basename20 } from "node:path";
|
|
19818
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync4, rmSync as rmSync7, chmodSync as chmodSync3, unlinkSync as unlinkSync2, readdirSync as readdirSync31, statSync as statSync39 } from "node:fs";
|
|
19819
|
+
import { tmpdir as tmpdir4, hostname as hostname2 } from "node:os";
|
|
19649
19820
|
import { createHash as createHash8 } from "node:crypto";
|
|
19650
19821
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19651
19822
|
import { gzipSync as gzipSync3 } from "zlib";
|
|
@@ -19681,7 +19852,7 @@ function loadAllCredentials() {
|
|
|
19681
19852
|
const fromEnv = envCredentials();
|
|
19682
19853
|
if (fromEnv) return [{ serverUrl: fromEnv.serverUrl, token: fromEnv.token }];
|
|
19683
19854
|
try {
|
|
19684
|
-
const parsed = JSON.parse(
|
|
19855
|
+
const parsed = JSON.parse(readFileSync36(credPath(), "utf-8"));
|
|
19685
19856
|
if (Array.isArray(parsed?.targets)) return parsed.targets.filter((t) => t?.serverUrl).map((t) => ({ serverUrl: t.serverUrl, token: t.token || "" }));
|
|
19686
19857
|
if (parsed?.serverUrl) return [{ serverUrl: parsed.serverUrl, token: parsed.token || "" }];
|
|
19687
19858
|
} catch {
|
|
@@ -19740,11 +19911,11 @@ async function fetchTenantSecurityConfig(cred) {
|
|
|
19740
19911
|
}
|
|
19741
19912
|
}
|
|
19742
19913
|
function syncConfigCachePath() {
|
|
19743
|
-
return
|
|
19914
|
+
return join43(getDataDir(), "sync-config-cache.json");
|
|
19744
19915
|
}
|
|
19745
19916
|
function readPersistedSyncConfigs() {
|
|
19746
19917
|
try {
|
|
19747
|
-
return JSON.parse(
|
|
19918
|
+
return JSON.parse(readFileSync36(syncConfigCachePath(), "utf-8"));
|
|
19748
19919
|
} catch {
|
|
19749
19920
|
return {};
|
|
19750
19921
|
}
|
|
@@ -19987,7 +20158,7 @@ async function reconcileFieldsForTarget(cred, fullRefs, opts = {}) {
|
|
|
19987
20158
|
}
|
|
19988
20159
|
return { pushed, absent, scanned };
|
|
19989
20160
|
}
|
|
19990
|
-
function reapStaleScanDirs(dir =
|
|
20161
|
+
function reapStaleScanDirs(dir = tmpdir4(), maxAgeMs = 6 * 36e5, now = Date.now()) {
|
|
19991
20162
|
let reaped = 0;
|
|
19992
20163
|
let names;
|
|
19993
20164
|
try {
|
|
@@ -19997,10 +20168,10 @@ function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now(
|
|
|
19997
20168
|
}
|
|
19998
20169
|
for (const name of names) {
|
|
19999
20170
|
if (!name.startsWith("cr-batchscan-")) continue;
|
|
20000
|
-
const p =
|
|
20171
|
+
const p = join43(dir, name);
|
|
20001
20172
|
try {
|
|
20002
|
-
if (now -
|
|
20003
|
-
|
|
20173
|
+
if (now - statSync39(p).mtimeMs < maxAgeMs) continue;
|
|
20174
|
+
rmSync7(p, { recursive: true, force: true });
|
|
20004
20175
|
reaped++;
|
|
20005
20176
|
} catch {
|
|
20006
20177
|
}
|
|
@@ -20014,7 +20185,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20014
20185
|
let scanned = 0, slices = 0, scanMs = 0;
|
|
20015
20186
|
if (items.length === 0) return { findings, scanned, slices, scanMs };
|
|
20016
20187
|
reapStaleScanDirs();
|
|
20017
|
-
let scanDir = mkdtempSync4(
|
|
20188
|
+
let scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20018
20189
|
let safeToId = /* @__PURE__ */ new Map();
|
|
20019
20190
|
let bytesInDir = 0;
|
|
20020
20191
|
const flushSlice = () => {
|
|
@@ -20032,7 +20203,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20032
20203
|
slices++;
|
|
20033
20204
|
}
|
|
20034
20205
|
try {
|
|
20035
|
-
|
|
20206
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20036
20207
|
} catch {
|
|
20037
20208
|
}
|
|
20038
20209
|
safeToId = /* @__PURE__ */ new Map();
|
|
@@ -20045,19 +20216,19 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20045
20216
|
if (raw === null) continue;
|
|
20046
20217
|
const safe = item.id.replace(/[^A-Za-z0-9_-]/g, "");
|
|
20047
20218
|
safeToId.set(safe, item.id);
|
|
20048
|
-
writeFileSync9(
|
|
20219
|
+
writeFileSync9(join43(scanDir, `${safe}.txt`), raw);
|
|
20049
20220
|
bytesInDir += Buffer.byteLength(raw);
|
|
20050
20221
|
} catch {
|
|
20051
20222
|
}
|
|
20052
20223
|
if (bytesInDir >= maxBytes) {
|
|
20053
20224
|
flushSlice();
|
|
20054
|
-
scanDir = mkdtempSync4(
|
|
20225
|
+
scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20055
20226
|
}
|
|
20056
20227
|
}
|
|
20057
20228
|
flushSlice();
|
|
20058
20229
|
} finally {
|
|
20059
20230
|
try {
|
|
20060
|
-
|
|
20231
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20061
20232
|
} catch {
|
|
20062
20233
|
}
|
|
20063
20234
|
}
|
|
@@ -20296,12 +20467,13 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20296
20467
|
markSynced(base3, rows.map((r) => {
|
|
20297
20468
|
const off = typeof r.from_offset === "number" ? r.from_offset : 0;
|
|
20298
20469
|
const hash = shippedHash.get(r.session_id);
|
|
20299
|
-
return off > 0 ? { id: r.session_id, mtime: r.mtime, offset: off, size: off, hash, acked: true } : { id: r.session_id, mtime: r.mtime, hash };
|
|
20470
|
+
return off > 0 ? { id: r.session_id, mtime: r.mtime, offset: off, size: off, hash, acked: true, full: true } : { id: r.session_id, mtime: r.mtime, hash };
|
|
20300
20471
|
}));
|
|
20301
20472
|
} catch {
|
|
20302
20473
|
}
|
|
20303
20474
|
});
|
|
20304
20475
|
const appendResults = { uploaded: 0, fullResyncNeeded: /* @__PURE__ */ new Set() };
|
|
20476
|
+
const pendingArchives = [];
|
|
20305
20477
|
const postAppend = async (convs) => {
|
|
20306
20478
|
const headers = { "content-type": "application/json" };
|
|
20307
20479
|
if (cred.token) headers.authorization = `Bearer ${cred.token}`;
|
|
@@ -20336,8 +20508,10 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20336
20508
|
offset: c.from_offset,
|
|
20337
20509
|
size: c.from_offset,
|
|
20338
20510
|
// size = new offset (file grew to here)
|
|
20339
|
-
acked: true
|
|
20511
|
+
acked: true,
|
|
20340
20512
|
// server merged this tail
|
|
20513
|
+
chunkFinal: c.final === true
|
|
20514
|
+
// completes a chunked full sync
|
|
20341
20515
|
})));
|
|
20342
20516
|
} catch {
|
|
20343
20517
|
}
|
|
@@ -20369,9 +20543,9 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20369
20543
|
const mtime = conv.mtime;
|
|
20370
20544
|
try {
|
|
20371
20545
|
if (staged || !guarded) {
|
|
20372
|
-
markSynced(base3, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true }]);
|
|
20546
|
+
markSynced(base3, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true, chunkedHead: true }]);
|
|
20373
20547
|
} else if (typeof guarded.o === "number" && guarded.o > 0 && guarded.o <= fileSize) {
|
|
20374
|
-
markSynced(base3, [{ id, mtime, offset: guarded.o, size: guarded.o, acked: true }]);
|
|
20548
|
+
markSynced(base3, [{ id, mtime, offset: guarded.o, size: guarded.o, acked: true, chunkedHead: true }]);
|
|
20375
20549
|
} else {
|
|
20376
20550
|
markSynced(base3, [{ id, mtime }]);
|
|
20377
20551
|
}
|
|
@@ -20580,6 +20754,14 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20580
20754
|
if (built.srcHash) shippedHash.set(ref.prefixedId, built.srcHash);
|
|
20581
20755
|
if (built.conv.chunked) await postChunkedHead(built.conv, sessionFileBytes(ref));
|
|
20582
20756
|
else await convBatch.add(built.conv);
|
|
20757
|
+
if (built.archive) {
|
|
20758
|
+
pendingArchives.push({
|
|
20759
|
+
id: ref.prefixedId,
|
|
20760
|
+
...built.archive,
|
|
20761
|
+
projectId: built.conv.project_id,
|
|
20762
|
+
projectPath: built.conv.project_path
|
|
20763
|
+
});
|
|
20764
|
+
}
|
|
20583
20765
|
if (built.findings.length > 0) await findingsBatch.add(built.findings);
|
|
20584
20766
|
if (upload.sessionMeta) {
|
|
20585
20767
|
await accumulateKg(extractEntities(built.kgText, { projectPath: built.projectPath, sourceType: "session", sessionId: ref.prefixedId, validFrom: ref.mtime ? new Date(ref.mtime).toISOString().slice(0, 10) : void 0 }), ref.prefixedId);
|
|
@@ -20732,6 +20914,30 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20732
20914
|
await kgTripleBatch.drain();
|
|
20733
20915
|
await findingsBatch.drain();
|
|
20734
20916
|
await drainInflight();
|
|
20917
|
+
let archivesUnsupported = false;
|
|
20918
|
+
for (const a of pendingArchives) {
|
|
20919
|
+
try {
|
|
20920
|
+
if (!archivesUnsupported) {
|
|
20921
|
+
const r = await uploadArchiveFile(base3, cred.token, {
|
|
20922
|
+
sessionId: a.id,
|
|
20923
|
+
tool: a.tool,
|
|
20924
|
+
mtime: a.mtime,
|
|
20925
|
+
projectId: a.projectId,
|
|
20926
|
+
projectPath: a.projectPath,
|
|
20927
|
+
file: a.file
|
|
20928
|
+
});
|
|
20929
|
+
if (r === "unsupported") archivesUnsupported = true;
|
|
20930
|
+
}
|
|
20931
|
+
} catch (err) {
|
|
20932
|
+
console.error(`[sync] raw archive for ${a.id} not uploaded (tried again when the session is next quiet): ${err instanceof Error ? err.message : err}`);
|
|
20933
|
+
try {
|
|
20934
|
+
forgetFullCoverage(base3, a.id);
|
|
20935
|
+
} catch {
|
|
20936
|
+
}
|
|
20937
|
+
} finally {
|
|
20938
|
+
rmSync7(a.file.path, { force: true });
|
|
20939
|
+
}
|
|
20940
|
+
}
|
|
20735
20941
|
{
|
|
20736
20942
|
const sentHashes = loadInventoryHashes(base3);
|
|
20737
20943
|
const entries = [];
|
|
@@ -20837,6 +21043,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
20837
21043
|
let includeRaw = opts.includeRaw !== false;
|
|
20838
21044
|
let includeMeta = opts.includeMeta !== false;
|
|
20839
21045
|
let srcHash;
|
|
21046
|
+
const wantRaw = opts.includeRaw !== false;
|
|
20840
21047
|
const oversized = sessionBuildBytes(ref) > FULL_BUILD_MAX_BYTES;
|
|
20841
21048
|
let headOffsetEnd = 0;
|
|
20842
21049
|
let oversizedFindings = null;
|
|
@@ -21005,7 +21212,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21005
21212
|
} else if (opts.scanSecrets) {
|
|
21006
21213
|
let tmp = null;
|
|
21007
21214
|
try {
|
|
21008
|
-
tmp =
|
|
21215
|
+
tmp = join43(tmpdir4(), `cr-scan-${ref.prefixedId.replace(/[^A-Za-z0-9_-]/g, "")}-${mtime}.txt`);
|
|
21009
21216
|
writeFileSync9(tmp, rawText);
|
|
21010
21217
|
for (const f of scanFileForSecrets(tmp, { verifyOnly: opts.verifySecrets, tenantRules: opts.tenantRules })) {
|
|
21011
21218
|
const verifiedAt = f.verified ? (/* @__PURE__ */ new Date()).toISOString() : null;
|
|
@@ -21057,6 +21264,25 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21057
21264
|
}
|
|
21058
21265
|
const envTexts = envelope.messages.filter((m) => m.content?.trim());
|
|
21059
21266
|
const redactedText = envTexts.map((m) => m.content).join("\n");
|
|
21267
|
+
let archive;
|
|
21268
|
+
if (wantRaw && !raw_b64) {
|
|
21269
|
+
try {
|
|
21270
|
+
const redact = (t) => redactSecrets(t, { force: true, count });
|
|
21271
|
+
let source = null;
|
|
21272
|
+
let archiveMtime = Math.floor(ref.mtime) || 0;
|
|
21273
|
+
let archiveTool = ref.toolId;
|
|
21274
|
+
if (container) {
|
|
21275
|
+
source = { kind: "memory", files: container.files };
|
|
21276
|
+
archiveMtime = container.mtime;
|
|
21277
|
+
archiveTool = container.tool;
|
|
21278
|
+
} else if (oversized) {
|
|
21279
|
+
source = diskArchiveSource(ref);
|
|
21280
|
+
}
|
|
21281
|
+
if (source) archive = { file: await writeArchiveFile(source, { tool: archiveTool, mtime: archiveMtime }, redact), tool: archiveTool, mtime: archiveMtime };
|
|
21282
|
+
} catch (err) {
|
|
21283
|
+
console.error(`[sync] raw archive for ${ref.prefixedId} not written: ${err instanceof Error ? err.message : err}`);
|
|
21284
|
+
}
|
|
21285
|
+
}
|
|
21060
21286
|
return {
|
|
21061
21287
|
conv: {
|
|
21062
21288
|
session_id: ref.prefixedId,
|
|
@@ -21088,7 +21314,17 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21088
21314
|
redactions: count.redactions,
|
|
21089
21315
|
findings,
|
|
21090
21316
|
scanMs,
|
|
21091
|
-
srcHash
|
|
21317
|
+
srcHash,
|
|
21318
|
+
archive
|
|
21319
|
+
};
|
|
21320
|
+
}
|
|
21321
|
+
function diskArchiveSource(ref) {
|
|
21322
|
+
if (ref.toolId !== "claude") return null;
|
|
21323
|
+
const groups = resolveSessionContentGroups(ref.rawId);
|
|
21324
|
+
if (groups.length === 0 || groups.some((g) => g.paths.length !== 1)) return null;
|
|
21325
|
+
return {
|
|
21326
|
+
kind: "disk",
|
|
21327
|
+
files: groups.map((g) => ({ name: g.name === "main" ? `${ref.rawId}.jsonl` : g.name, path: g.paths[0] }))
|
|
21092
21328
|
};
|
|
21093
21329
|
}
|
|
21094
21330
|
function parseTailMessages(tool, text) {
|
|
@@ -21244,14 +21480,15 @@ var init_sync_client = __esm({
|
|
|
21244
21480
|
init_telemetry();
|
|
21245
21481
|
init_collector_health();
|
|
21246
21482
|
init_live_session_scan();
|
|
21483
|
+
init_raw_archive_parts();
|
|
21247
21484
|
init_backends();
|
|
21248
21485
|
ownVersion = "0.0.0";
|
|
21249
21486
|
try {
|
|
21250
21487
|
const dir = dirname19(fileURLToPath3(import.meta.url));
|
|
21251
|
-
ownVersion = JSON.parse(
|
|
21488
|
+
ownVersion = JSON.parse(readFileSync36(join43(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21252
21489
|
} catch {
|
|
21253
21490
|
try {
|
|
21254
|
-
if (true) ownVersion = "0.7.
|
|
21491
|
+
if (true) ownVersion = "0.7.18";
|
|
21255
21492
|
} catch {
|
|
21256
21493
|
}
|
|
21257
21494
|
}
|
|
@@ -21263,7 +21500,7 @@ var init_sync_client = __esm({
|
|
|
21263
21500
|
]);
|
|
21264
21501
|
walkProgressForUpload = null;
|
|
21265
21502
|
lastServerPackSpec = null;
|
|
21266
|
-
credPath = () =>
|
|
21503
|
+
credPath = () => join43(getDataDir(), "credentials.json");
|
|
21267
21504
|
_securityConfigCache = /* @__PURE__ */ new Map();
|
|
21268
21505
|
SECURITY_CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
21269
21506
|
_syncConfigCache = /* @__PURE__ */ new Map();
|
|
@@ -21286,8 +21523,8 @@ var init_sync_client = __esm({
|
|
|
21286
21523
|
});
|
|
21287
21524
|
|
|
21288
21525
|
// ../engine/dist/core/artifact-codec.js
|
|
21289
|
-
import { readFileSync as
|
|
21290
|
-
import { basename as basename21, join as
|
|
21526
|
+
import { readFileSync as readFileSync37 } from "fs";
|
|
21527
|
+
import { basename as basename21, join as join44 } from "path";
|
|
21291
21528
|
import { homedir as homedir16 } from "os";
|
|
21292
21529
|
function parseCommandText(content, format, fallbackName) {
|
|
21293
21530
|
if (format === "toml") {
|
|
@@ -21310,41 +21547,41 @@ function parseAgentText(content, format, fallbackName) {
|
|
|
21310
21547
|
return { name: fm.name || fallbackName, description: fm.description || "", tools: fm.tools, body: body.trim() };
|
|
21311
21548
|
}
|
|
21312
21549
|
function readCommand(filePath, format) {
|
|
21313
|
-
return parseCommandText(
|
|
21550
|
+
return parseCommandText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21314
21551
|
}
|
|
21315
21552
|
function readAgent(filePath, format) {
|
|
21316
|
-
return parseAgentText(
|
|
21553
|
+
return parseAgentText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21317
21554
|
}
|
|
21318
21555
|
function readInstructions(filePath, name) {
|
|
21319
|
-
const content =
|
|
21556
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
21320
21557
|
return { name, description: "", body: content };
|
|
21321
21558
|
}
|
|
21322
21559
|
function commandPath(tool, name) {
|
|
21323
21560
|
switch (tool) {
|
|
21324
21561
|
case "claude":
|
|
21325
|
-
return
|
|
21562
|
+
return join44(claudeBackend.commandsDir(), `${name}.md`);
|
|
21326
21563
|
case "agy":
|
|
21327
|
-
return
|
|
21564
|
+
return join44(join44(agyBackend.homeDir(), "commands"), `${name}.toml`);
|
|
21328
21565
|
case "opencode":
|
|
21329
|
-
return
|
|
21566
|
+
return join44(opencodeBackend.commandsDir(), `${name}.md`);
|
|
21330
21567
|
case "codex":
|
|
21331
|
-
return
|
|
21568
|
+
return join44(codexBackend.promptsDir(), `${name}.md`);
|
|
21332
21569
|
case "cursor":
|
|
21333
|
-
return
|
|
21570
|
+
return join44(cursorHomeDir(), "commands", `${name}.md`);
|
|
21334
21571
|
}
|
|
21335
21572
|
}
|
|
21336
21573
|
function agentPath(tool, name) {
|
|
21337
21574
|
switch (tool) {
|
|
21338
21575
|
case "claude":
|
|
21339
|
-
return
|
|
21576
|
+
return join44(claudeBackend.agentsDir(), `${name}.md`);
|
|
21340
21577
|
case "agy":
|
|
21341
|
-
return
|
|
21578
|
+
return join44(join44(agyBackend.homeDir(), "agents"), `${name}.md`);
|
|
21342
21579
|
case "opencode":
|
|
21343
|
-
return
|
|
21580
|
+
return join44(opencodeBackend.agentsDir(), `${name}.md`);
|
|
21344
21581
|
case "codex":
|
|
21345
|
-
return
|
|
21582
|
+
return join44(codexBackend.agentsDir(), `${name}.toml`);
|
|
21346
21583
|
case "cursor":
|
|
21347
|
-
return
|
|
21584
|
+
return join44(cursorHomeDir(), "agents", `${name}.md`);
|
|
21348
21585
|
}
|
|
21349
21586
|
}
|
|
21350
21587
|
function instructionsFilename(tool) {
|
|
@@ -21369,21 +21606,21 @@ function instructionsFilename(tool) {
|
|
|
21369
21606
|
function instructionsPath(tool, projectPath) {
|
|
21370
21607
|
const file = instructionsFilename(tool);
|
|
21371
21608
|
if (projectPath)
|
|
21372
|
-
return
|
|
21609
|
+
return join44(projectPath, file);
|
|
21373
21610
|
switch (tool) {
|
|
21374
21611
|
case "claude":
|
|
21375
|
-
return
|
|
21612
|
+
return join44(claudeBackend.homeDir(), file);
|
|
21376
21613
|
case "agy":
|
|
21377
|
-
return
|
|
21614
|
+
return join44(agyBackend.homeDir(), file);
|
|
21378
21615
|
case "codex":
|
|
21379
|
-
return
|
|
21616
|
+
return join44(codexBackend.homeDir(), file);
|
|
21380
21617
|
case "opencode":
|
|
21381
|
-
return
|
|
21618
|
+
return join44(homedir16(), ".config", "opencode", file);
|
|
21382
21619
|
// Cursor has no single user-scope instructions FILE — user-level guidance
|
|
21383
21620
|
// is User Rules plus ~/.cursor/rules/*.mdc. AGENTS.md at the home root is
|
|
21384
21621
|
// the closest equivalent and is what a mirror can actually write.
|
|
21385
21622
|
case "cursor":
|
|
21386
|
-
return
|
|
21623
|
+
return join44(cursorHomeDir(), file);
|
|
21387
21624
|
}
|
|
21388
21625
|
}
|
|
21389
21626
|
function emit(type, art, toTool, projectPath) {
|
|
@@ -21429,8 +21666,8 @@ var init_artifact_codec = __esm({
|
|
|
21429
21666
|
});
|
|
21430
21667
|
|
|
21431
21668
|
// ../engine/dist/core/toolkit-sync.js
|
|
21432
|
-
import { existsSync as existsSync42, mkdirSync as mkdirSync11, readFileSync as
|
|
21433
|
-
import { dirname as dirname20, join as
|
|
21669
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync11, readFileSync as readFileSync38, writeFileSync as writeFileSync10, cpSync } from "fs";
|
|
21670
|
+
import { dirname as dirname20, join as join45, basename as basename22 } from "path";
|
|
21434
21671
|
import { homedir as homedir17 } from "os";
|
|
21435
21672
|
function rowFromMemoryItem(type, item) {
|
|
21436
21673
|
const extra = item.extra || {};
|
|
@@ -21451,14 +21688,14 @@ function skillsDirFor(tool) {
|
|
|
21451
21688
|
case "claude":
|
|
21452
21689
|
return claudeBackend.skillsDir();
|
|
21453
21690
|
case "agy":
|
|
21454
|
-
return
|
|
21691
|
+
return join45(agyBackend.homeDir(), "skills");
|
|
21455
21692
|
case "opencode":
|
|
21456
21693
|
return opencodeBackend.skillsDir();
|
|
21457
21694
|
case "codex":
|
|
21458
21695
|
return codexBackend.skillsDir();
|
|
21459
21696
|
// user skills, NOT .system
|
|
21460
21697
|
case "cursor":
|
|
21461
|
-
return
|
|
21698
|
+
return join45(cursorHomeDir(), "skills");
|
|
21462
21699
|
}
|
|
21463
21700
|
}
|
|
21464
21701
|
function copySkill(row, toTool) {
|
|
@@ -21466,7 +21703,7 @@ function copySkill(row, toTool) {
|
|
|
21466
21703
|
if (!existsSync42(skillDir))
|
|
21467
21704
|
return { ok: false, status: 404, error: `Source dir missing: ${skillDir}` };
|
|
21468
21705
|
const name = row.extra.skillName || basename22(skillDir);
|
|
21469
|
-
const targetDir =
|
|
21706
|
+
const targetDir = join45(skillsDirFor(toTool), name);
|
|
21470
21707
|
if (existsSync42(targetDir))
|
|
21471
21708
|
return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
|
|
21472
21709
|
try {
|
|
@@ -21481,20 +21718,20 @@ function readMcpEntry(tool, name) {
|
|
|
21481
21718
|
const home = homedir17();
|
|
21482
21719
|
const tries = [];
|
|
21483
21720
|
if (tool === "claude") {
|
|
21484
|
-
tries.push({ path:
|
|
21485
|
-
tries.push({ path:
|
|
21721
|
+
tries.push({ path: join45(home, ".mcp.json"), key: "mcpServers" });
|
|
21722
|
+
tries.push({ path: join45(home, ".claude.json"), key: "mcpServers" });
|
|
21486
21723
|
} else if (tool === "gemini") {
|
|
21487
|
-
tries.push({ path:
|
|
21724
|
+
tries.push({ path: join45(home, ".gemini", "settings.json"), key: "mcpServers" });
|
|
21488
21725
|
} else if (tool === "agy") {
|
|
21489
|
-
tries.push({ path:
|
|
21726
|
+
tries.push({ path: join45(home, ".gemini", "config", "mcp_config.json"), key: "mcpServers" });
|
|
21490
21727
|
} else if (tool === "cursor") {
|
|
21491
|
-
tries.push({ path:
|
|
21728
|
+
tries.push({ path: join45(cursorHomeDir(), "mcp.json"), key: "mcpServers" });
|
|
21492
21729
|
} else if (tool === "opencode") {
|
|
21493
|
-
tries.push({ path:
|
|
21494
|
-
tries.push({ path:
|
|
21495
|
-
tries.push({ path:
|
|
21730
|
+
tries.push({ path: join45(home, ".config", "opencode", "opencode.json"), key: "mcp" });
|
|
21731
|
+
tries.push({ path: join45(home, ".config", "opencode", "config.json"), key: "mcp" });
|
|
21732
|
+
tries.push({ path: join45(home, ".opencode", "config.json"), key: "mcp" });
|
|
21496
21733
|
} else if (tool === "codex") {
|
|
21497
|
-
const entry = readCodexMcpEntry(
|
|
21734
|
+
const entry = readCodexMcpEntry(join45(home, ".codex", "config.toml"), name);
|
|
21498
21735
|
if (entry)
|
|
21499
21736
|
return entry;
|
|
21500
21737
|
}
|
|
@@ -21502,7 +21739,7 @@ function readMcpEntry(tool, name) {
|
|
|
21502
21739
|
if (!existsSync42(t.path))
|
|
21503
21740
|
continue;
|
|
21504
21741
|
try {
|
|
21505
|
-
const cfg = JSON.parse(
|
|
21742
|
+
const cfg = JSON.parse(readFileSync38(t.path, "utf-8"));
|
|
21506
21743
|
const block = cfg[t.key] || {};
|
|
21507
21744
|
if (block[name])
|
|
21508
21745
|
return block[name];
|
|
@@ -21516,7 +21753,7 @@ function readCodexMcpEntry(path, target) {
|
|
|
21516
21753
|
return null;
|
|
21517
21754
|
let content;
|
|
21518
21755
|
try {
|
|
21519
|
-
content =
|
|
21756
|
+
content = readFileSync38(path, "utf-8");
|
|
21520
21757
|
} catch {
|
|
21521
21758
|
return null;
|
|
21522
21759
|
}
|
|
@@ -21567,7 +21804,7 @@ function readCodexMcpEntry(path, target) {
|
|
|
21567
21804
|
function writeCodexMcpEntry(path, name, entry) {
|
|
21568
21805
|
let content = "";
|
|
21569
21806
|
if (existsSync42(path))
|
|
21570
|
-
content =
|
|
21807
|
+
content = readFileSync38(path, "utf-8");
|
|
21571
21808
|
const header = `[mcp_servers.${name}]`;
|
|
21572
21809
|
if (content.includes(header))
|
|
21573
21810
|
return false;
|
|
@@ -21603,7 +21840,7 @@ function writeCodexMcpEntry(path, name, entry) {
|
|
|
21603
21840
|
function writeMcpEntry(toTool, name, entry) {
|
|
21604
21841
|
const home = homedir17();
|
|
21605
21842
|
if (toTool === "codex") {
|
|
21606
|
-
const path2 =
|
|
21843
|
+
const path2 = join45(home, ".codex", "config.toml");
|
|
21607
21844
|
if (!writeCodexMcpEntry(path2, name, entry))
|
|
21608
21845
|
return { ok: false, status: 409, error: `MCP "${name}" already exists in ${path2}.` };
|
|
21609
21846
|
return { ok: true, targetPath: path2 };
|
|
@@ -21611,22 +21848,22 @@ function writeMcpEntry(toTool, name, entry) {
|
|
|
21611
21848
|
let path;
|
|
21612
21849
|
let key2;
|
|
21613
21850
|
if (toTool === "claude") {
|
|
21614
|
-
path =
|
|
21851
|
+
path = join45(home, ".mcp.json");
|
|
21615
21852
|
key2 = "mcpServers";
|
|
21616
21853
|
} else if (toTool === "agy") {
|
|
21617
|
-
path =
|
|
21854
|
+
path = join45(home, ".gemini", "config", "mcp_config.json");
|
|
21618
21855
|
key2 = "mcpServers";
|
|
21619
21856
|
} else if (toTool === "cursor") {
|
|
21620
|
-
path =
|
|
21857
|
+
path = join45(cursorHomeDir(), "mcp.json");
|
|
21621
21858
|
key2 = "mcpServers";
|
|
21622
21859
|
} else {
|
|
21623
|
-
path =
|
|
21860
|
+
path = join45(home, ".config", "opencode", "opencode.json");
|
|
21624
21861
|
key2 = "mcp";
|
|
21625
21862
|
}
|
|
21626
21863
|
let cfg = {};
|
|
21627
21864
|
if (existsSync42(path)) {
|
|
21628
21865
|
try {
|
|
21629
|
-
cfg = JSON.parse(
|
|
21866
|
+
cfg = JSON.parse(readFileSync38(path, "utf-8"));
|
|
21630
21867
|
} catch {
|
|
21631
21868
|
return { ok: false, status: 500, error: `Target config is malformed: ${path}` };
|
|
21632
21869
|
}
|
|
@@ -21851,11 +22088,11 @@ var init_toolkit_sync = __esm({
|
|
|
21851
22088
|
});
|
|
21852
22089
|
|
|
21853
22090
|
// ../engine/dist/core/which.js
|
|
21854
|
-
import { existsSync as existsSync44, statSync as
|
|
21855
|
-
import { join as
|
|
22091
|
+
import { existsSync as existsSync44, statSync as statSync41, accessSync, constants } from "node:fs";
|
|
22092
|
+
import { join as join47, isAbsolute as isAbsolute2, delimiter as delimiter2, sep as sep3 } from "node:path";
|
|
21856
22093
|
function executable(p) {
|
|
21857
22094
|
try {
|
|
21858
|
-
if (!
|
|
22095
|
+
if (!statSync41(p).isFile())
|
|
21859
22096
|
return false;
|
|
21860
22097
|
} catch {
|
|
21861
22098
|
return false;
|
|
@@ -21891,7 +22128,7 @@ function resolveOnPath(name) {
|
|
|
21891
22128
|
if (!dir)
|
|
21892
22129
|
continue;
|
|
21893
22130
|
for (const c of candidates(name)) {
|
|
21894
|
-
const full =
|
|
22131
|
+
const full = join47(dir, c);
|
|
21895
22132
|
if (existsSync44(full) && executable(full))
|
|
21896
22133
|
return full;
|
|
21897
22134
|
}
|
|
@@ -21918,11 +22155,11 @@ __export(toolkit_pull_exports, {
|
|
|
21918
22155
|
platformRefusal: () => platformRefusal,
|
|
21919
22156
|
portableCommand: () => portableCommand
|
|
21920
22157
|
});
|
|
21921
|
-
import { existsSync as existsSync45, mkdirSync as mkdirSync13, statSync as
|
|
21922
|
-
import { dirname as dirname22, join as
|
|
22158
|
+
import { existsSync as existsSync45, mkdirSync as mkdirSync13, statSync as statSync42, writeFileSync as writeFileSync12 } from "node:fs";
|
|
22159
|
+
import { dirname as dirname22, join as join48, basename as basename23, isAbsolute as isAbsolute3 } from "node:path";
|
|
21923
22160
|
function isExecutableFile(p) {
|
|
21924
22161
|
try {
|
|
21925
|
-
return
|
|
22162
|
+
return statSync42(p).isFile();
|
|
21926
22163
|
} catch {
|
|
21927
22164
|
return false;
|
|
21928
22165
|
}
|
|
@@ -22089,8 +22326,8 @@ function executePull(rows, opts = {}) {
|
|
|
22089
22326
|
const outcomes = [];
|
|
22090
22327
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
22091
22328
|
for (const tool of tools) {
|
|
22092
|
-
const dir =
|
|
22093
|
-
const file =
|
|
22329
|
+
const dir = join48(skillsDirFor(tool), name);
|
|
22330
|
+
const file = join48(dir, "SKILL.md");
|
|
22094
22331
|
if (existsSync45(file)) {
|
|
22095
22332
|
outcomes.push({ type: "skill", name, tool, status: "present" });
|
|
22096
22333
|
continue;
|
|
@@ -22423,11 +22660,16 @@ async function repairAll(opts = {}) {
|
|
|
22423
22660
|
scanned++;
|
|
22424
22661
|
if (opts.verbose && scanned % 50 === 0) log6(`checked ${scanned}/${ids.length}\u2026`);
|
|
22425
22662
|
const arch = await fetchJson(`${primary.url}/api/conversations/${id}/raw-archive?count=1`, primary.token);
|
|
22426
|
-
const
|
|
22427
|
-
if (
|
|
22428
|
-
|
|
22429
|
-
|
|
22430
|
-
|
|
22663
|
+
const counted = arch && arch.messages !== null;
|
|
22664
|
+
if (counted) {
|
|
22665
|
+
const archiveMsgs = typeof arch?.messages === "number" ? arch.messages : 0;
|
|
22666
|
+
if (archiveMsgs < minMessages) continue;
|
|
22667
|
+
const meta = await fetchJson(`${primary.url}/api/conversations/${id}/metadata`, primary.token);
|
|
22668
|
+
const current = typeof meta?.messageCount === "number" ? meta.messageCount : 0;
|
|
22669
|
+
if (archiveMsgs <= current) continue;
|
|
22670
|
+
} else if (!arch) {
|
|
22671
|
+
continue;
|
|
22672
|
+
}
|
|
22431
22673
|
const r = await repairSession(id, { dryRun: !opts.apply, verbose: opts.verbose, server: opts.server });
|
|
22432
22674
|
if (r.status === "already-full") continue;
|
|
22433
22675
|
candidates2.push(r);
|
|
@@ -22455,8 +22697,8 @@ __export(shadow_prune_exports, {
|
|
|
22455
22697
|
DEFAULT_MAX_TOTAL_BYTES: () => DEFAULT_MAX_TOTAL_BYTES,
|
|
22456
22698
|
pruneShadow: () => pruneShadow
|
|
22457
22699
|
});
|
|
22458
|
-
import { readdirSync as readdirSync32, statSync as
|
|
22459
|
-
import { join as
|
|
22700
|
+
import { readdirSync as readdirSync32, statSync as statSync45, unlinkSync as unlinkSync3 } from "fs";
|
|
22701
|
+
import { join as join51 } from "path";
|
|
22460
22702
|
function listShadows(isFullyAcked) {
|
|
22461
22703
|
const out = [];
|
|
22462
22704
|
const root = shadowRoot();
|
|
@@ -22467,7 +22709,7 @@ function listShadows(isFullyAcked) {
|
|
|
22467
22709
|
return out;
|
|
22468
22710
|
}
|
|
22469
22711
|
for (const tool of tools) {
|
|
22470
|
-
const dir =
|
|
22712
|
+
const dir = join51(root, tool);
|
|
22471
22713
|
let names;
|
|
22472
22714
|
try {
|
|
22473
22715
|
names = readdirSync32(dir);
|
|
@@ -22477,10 +22719,10 @@ function listShadows(isFullyAcked) {
|
|
|
22477
22719
|
for (const name of names) {
|
|
22478
22720
|
if (!name.endsWith(".gz"))
|
|
22479
22721
|
continue;
|
|
22480
|
-
const path =
|
|
22722
|
+
const path = join51(dir, name);
|
|
22481
22723
|
let st;
|
|
22482
22724
|
try {
|
|
22483
|
-
st =
|
|
22725
|
+
st = statSync45(path);
|
|
22484
22726
|
} catch {
|
|
22485
22727
|
continue;
|
|
22486
22728
|
}
|
|
@@ -22595,9 +22837,9 @@ var init_code_intel = __esm({
|
|
|
22595
22837
|
});
|
|
22596
22838
|
|
|
22597
22839
|
// ../engine/dist/core/companions.js
|
|
22598
|
-
import { existsSync as existsSync48, mkdirSync as mkdirSync16, statSync as
|
|
22840
|
+
import { existsSync as existsSync48, mkdirSync as mkdirSync16, statSync as statSync46, chmodSync as chmodSync4, unlinkSync as unlinkSync4, renameSync as renameSync5, createWriteStream as createWriteStream2, readFileSync as readFileSync43, writeFileSync as writeFileSync15 } from "node:fs";
|
|
22599
22841
|
import { homedir as homedir19 } from "node:os";
|
|
22600
|
-
import { join as
|
|
22842
|
+
import { join as join52 } from "node:path";
|
|
22601
22843
|
import { execSync as execSync3 } from "node:child_process";
|
|
22602
22844
|
import { createHash as createHash13 } from "node:crypto";
|
|
22603
22845
|
function expectedCodeindexSha256(artifact) {
|
|
@@ -22646,7 +22888,7 @@ function checkCodeindexStatus() {
|
|
|
22646
22888
|
status.installed = true;
|
|
22647
22889
|
status.path = foundPath;
|
|
22648
22890
|
try {
|
|
22649
|
-
status.size =
|
|
22891
|
+
status.size = statSync46(foundPath).size;
|
|
22650
22892
|
} catch {
|
|
22651
22893
|
}
|
|
22652
22894
|
try {
|
|
@@ -22672,7 +22914,7 @@ async function downloadArtifact(artifact, dest) {
|
|
|
22672
22914
|
throw new Error(`Download failed: ${res.status} ${res.statusText}`);
|
|
22673
22915
|
if (!res.body)
|
|
22674
22916
|
throw new Error("Download returned empty body");
|
|
22675
|
-
const file =
|
|
22917
|
+
const file = createWriteStream2(dest);
|
|
22676
22918
|
await new Promise((resolve3, reject) => {
|
|
22677
22919
|
const reader = res.body.getReader();
|
|
22678
22920
|
const pump = async () => {
|
|
@@ -22707,7 +22949,7 @@ async function installCodeindex(opts = {}) {
|
|
|
22707
22949
|
if (!expected) {
|
|
22708
22950
|
throw new Error(`No pinned checksum for ${status.artifactName} \u2014 refusing to install an unverified binary. Add its sha256 to CODEINDEX_SHA256 in companions.ts.`);
|
|
22709
22951
|
}
|
|
22710
|
-
const actual = createHash13("sha256").update(
|
|
22952
|
+
const actual = createHash13("sha256").update(readFileSync43(tmpPath)).digest("hex");
|
|
22711
22953
|
if (actual !== expected) {
|
|
22712
22954
|
throw new Error(`Checksum mismatch for ${status.artifactName}.
|
|
22713
22955
|
expected ${expected}
|
|
@@ -22741,9 +22983,9 @@ var init_companions = __esm({
|
|
|
22741
22983
|
"x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
|
|
22742
22984
|
"aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
|
|
22743
22985
|
};
|
|
22744
|
-
CODEINDEX_INSTALL_DIR =
|
|
22986
|
+
CODEINDEX_INSTALL_DIR = join52(homedir19(), ".local", "bin");
|
|
22745
22987
|
CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
|
|
22746
|
-
CODEINDEX_BIN_PATH =
|
|
22988
|
+
CODEINDEX_BIN_PATH = join52(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
|
|
22747
22989
|
}
|
|
22748
22990
|
});
|
|
22749
22991
|
|
|
@@ -22858,8 +23100,8 @@ __export(collector_exports, {
|
|
|
22858
23100
|
});
|
|
22859
23101
|
import { spawn as spawn2 } from "node:child_process";
|
|
22860
23102
|
import { execSync as execSync4 } from "node:child_process";
|
|
22861
|
-
import { readFileSync as
|
|
22862
|
-
import { join as
|
|
23103
|
+
import { readFileSync as readFileSync44 } from "node:fs";
|
|
23104
|
+
import { join as join53, basename as basename24 } from "node:path";
|
|
22863
23105
|
async function resolveCodeindexBin(autoInstall = true) {
|
|
22864
23106
|
let st = checkCodeindexStatus();
|
|
22865
23107
|
if (!st.installed && autoInstall)
|
|
@@ -23041,7 +23283,7 @@ async function collectCode(opts) {
|
|
|
23041
23283
|
}
|
|
23042
23284
|
const complexity = (r) => {
|
|
23043
23285
|
try {
|
|
23044
|
-
const txt =
|
|
23286
|
+
const txt = readFileSync44(join53(ws, r), "utf8");
|
|
23045
23287
|
if (txt.length > 2e6)
|
|
23046
23288
|
return 1;
|
|
23047
23289
|
const m = txt.match(CF_RE);
|
|
@@ -23805,15 +24047,15 @@ __export(service_installer_exports, {
|
|
|
23805
24047
|
uninstallService: () => uninstallService
|
|
23806
24048
|
});
|
|
23807
24049
|
import { execSync as execSync5 } from "child_process";
|
|
23808
|
-
import { existsSync as existsSync49, mkdirSync as mkdirSync17, readFileSync as
|
|
24050
|
+
import { existsSync as existsSync49, mkdirSync as mkdirSync17, readFileSync as readFileSync45, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
23809
24051
|
import { homedir as homedir20 } from "os";
|
|
23810
|
-
import { join as
|
|
24052
|
+
import { join as join54 } from "path";
|
|
23811
24053
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23812
24054
|
function resolveDaemonPaths() {
|
|
23813
24055
|
const watchJs = fileURLToPath5(new URL("./watch.js", import.meta.url));
|
|
23814
24056
|
const node = process.execPath;
|
|
23815
|
-
const dataDir =
|
|
23816
|
-
const logFile =
|
|
24057
|
+
const dataDir = join54(homedir20(), ".chat-recall");
|
|
24058
|
+
const logFile = join54(dataDir, "watch.log");
|
|
23817
24059
|
return { watchJs, node, logFile, dataDir };
|
|
23818
24060
|
}
|
|
23819
24061
|
function tryCmd(cmd) {
|
|
@@ -23840,12 +24082,12 @@ function refreshServiceDefinition() {
|
|
|
23840
24082
|
if (process.platform !== "linux") return false;
|
|
23841
24083
|
try {
|
|
23842
24084
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
23843
|
-
const unitPath =
|
|
24085
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
23844
24086
|
if (!existsSync49(unitPath)) return false;
|
|
23845
|
-
const current =
|
|
24087
|
+
const current = readFileSync45(unitPath, "utf8");
|
|
23846
24088
|
if (!current.includes(watchJs)) return false;
|
|
23847
24089
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
23848
|
-
if (
|
|
24090
|
+
if (readFileSync45(unitPath, "utf8") === wanted) return false;
|
|
23849
24091
|
writeFileSync16(unitPath, wanted);
|
|
23850
24092
|
execSync5("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
23851
24093
|
return true;
|
|
@@ -23871,8 +24113,8 @@ function installService() {
|
|
|
23871
24113
|
);
|
|
23872
24114
|
}
|
|
23873
24115
|
function installSystemd(watchJs, node, logFile) {
|
|
23874
|
-
const unitDir =
|
|
23875
|
-
const unitPath =
|
|
24116
|
+
const unitDir = join54(homedir20(), ".config", "systemd", "user");
|
|
24117
|
+
const unitPath = join54(unitDir, "chat-recall-watch.service");
|
|
23876
24118
|
const unit = renderSystemdUnit(watchJs, node, logFile);
|
|
23877
24119
|
mkdirSync17(unitDir, { recursive: true });
|
|
23878
24120
|
writeFileSync16(unitPath, unit);
|
|
@@ -23951,8 +24193,8 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23951
24193
|
}
|
|
23952
24194
|
function installLaunchd(watchJs, node, logFile) {
|
|
23953
24195
|
const label = "com.chat-recall.watch";
|
|
23954
|
-
const plistDir =
|
|
23955
|
-
const plistPath =
|
|
24196
|
+
const plistDir = join54(homedir20(), "Library", "LaunchAgents");
|
|
24197
|
+
const plistPath = join54(plistDir, `${label}.plist`);
|
|
23956
24198
|
const plist = renderLaunchdPlist(watchJs, node, logFile, label);
|
|
23957
24199
|
mkdirSync17(plistDir, { recursive: true });
|
|
23958
24200
|
writeFileSync16(plistPath, plist);
|
|
@@ -24008,9 +24250,9 @@ function uninstallService() {
|
|
|
24008
24250
|
removed = true;
|
|
24009
24251
|
} catch {
|
|
24010
24252
|
}
|
|
24011
|
-
const unitPath =
|
|
24253
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
24012
24254
|
if (existsSync49(unitPath)) {
|
|
24013
|
-
|
|
24255
|
+
rmSync8(unitPath, { force: true });
|
|
24014
24256
|
removed = true;
|
|
24015
24257
|
}
|
|
24016
24258
|
try {
|
|
@@ -24020,14 +24262,14 @@ function uninstallService() {
|
|
|
24020
24262
|
return removed;
|
|
24021
24263
|
}
|
|
24022
24264
|
if (process.platform === "darwin") {
|
|
24023
|
-
const plistPath =
|
|
24265
|
+
const plistPath = join54(homedir20(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
|
|
24024
24266
|
try {
|
|
24025
24267
|
execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
24026
24268
|
} catch {
|
|
24027
24269
|
}
|
|
24028
24270
|
let removed = false;
|
|
24029
24271
|
if (existsSync49(plistPath)) {
|
|
24030
|
-
|
|
24272
|
+
rmSync8(plistPath, { force: true });
|
|
24031
24273
|
removed = true;
|
|
24032
24274
|
}
|
|
24033
24275
|
return removed;
|
|
@@ -24071,7 +24313,7 @@ init_settings();
|
|
|
24071
24313
|
init_sync_client();
|
|
24072
24314
|
init_http();
|
|
24073
24315
|
import chokidar from "chokidar";
|
|
24074
|
-
import { dirname as dirname25, basename as basename25, join as
|
|
24316
|
+
import { dirname as dirname25, basename as basename25, join as join55, resolve as resolve2, sep as sep4 } from "path";
|
|
24075
24317
|
import { homedir as homedir21 } from "os";
|
|
24076
24318
|
|
|
24077
24319
|
// src/intent-drain.ts
|
|
@@ -24084,13 +24326,13 @@ init_codex2();
|
|
|
24084
24326
|
init_cursor();
|
|
24085
24327
|
init_opencode();
|
|
24086
24328
|
init_agy();
|
|
24087
|
-
import { existsSync as existsSync46, readFileSync as
|
|
24088
|
-
import { join as
|
|
24329
|
+
import { existsSync as existsSync46, readFileSync as readFileSync40, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync14 } from "node:fs";
|
|
24330
|
+
import { join as join49 } from "node:path";
|
|
24089
24331
|
|
|
24090
24332
|
// src/project-tasks.ts
|
|
24091
24333
|
init_http();
|
|
24092
|
-
import { existsSync as existsSync43, readFileSync as
|
|
24093
|
-
import { join as
|
|
24334
|
+
import { existsSync as existsSync43, readFileSync as readFileSync39, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12, statSync as statSync40 } from "node:fs";
|
|
24335
|
+
import { join as join46, dirname as dirname21 } from "node:path";
|
|
24094
24336
|
import { homedir as homedir18 } from "node:os";
|
|
24095
24337
|
|
|
24096
24338
|
// ../engine/dist/core/secret-task-status.js
|
|
@@ -24159,11 +24401,11 @@ function parseTaskFile(content) {
|
|
|
24159
24401
|
return out;
|
|
24160
24402
|
}
|
|
24161
24403
|
function ledgerPath2() {
|
|
24162
|
-
return
|
|
24404
|
+
return join46(homedir18(), ".chat-recall", "project-tasks-ledger.json");
|
|
24163
24405
|
}
|
|
24164
24406
|
function readLedger() {
|
|
24165
24407
|
try {
|
|
24166
|
-
return JSON.parse(
|
|
24408
|
+
return JSON.parse(readFileSync39(ledgerPath2(), "utf8"));
|
|
24167
24409
|
} catch {
|
|
24168
24410
|
return {};
|
|
24169
24411
|
}
|
|
@@ -24196,18 +24438,18 @@ async function pushProjectTaskStatuses(base3, authHeaders, opts = {}) {
|
|
|
24196
24438
|
continue;
|
|
24197
24439
|
}
|
|
24198
24440
|
for (const project of projects) {
|
|
24199
|
-
const file =
|
|
24441
|
+
const file = join46(project, fk.filename);
|
|
24200
24442
|
if (!existsSync43(file)) continue;
|
|
24201
24443
|
let mtime;
|
|
24202
24444
|
try {
|
|
24203
|
-
mtime =
|
|
24445
|
+
mtime = statSync40(file).mtimeMs;
|
|
24204
24446
|
} catch {
|
|
24205
24447
|
continue;
|
|
24206
24448
|
}
|
|
24207
24449
|
if (ledger[file] === mtime) continue;
|
|
24208
24450
|
let changed;
|
|
24209
24451
|
try {
|
|
24210
|
-
changed = parseTaskFile(
|
|
24452
|
+
changed = parseTaskFile(readFileSync39(file, "utf8")).filter((t) => t.kind === fk.kind);
|
|
24211
24453
|
} catch {
|
|
24212
24454
|
continue;
|
|
24213
24455
|
}
|
|
@@ -24258,16 +24500,16 @@ function instructionTargets(rootPath, isGlobal) {
|
|
|
24258
24500
|
const tools = installed.length ? installed : [INSTRUCTION_TOOLS[0]];
|
|
24259
24501
|
if (isGlobal) return [...new Set(tools.map((t) => instructionsPath(t.id)))];
|
|
24260
24502
|
if (!rootPath) return [];
|
|
24261
|
-
const present = INSTRUCTION_FILENAMES.map((f) =>
|
|
24503
|
+
const present = INSTRUCTION_FILENAMES.map((f) => join49(rootPath, f)).filter((p) => existsSync46(p));
|
|
24262
24504
|
if (present.length) return present;
|
|
24263
|
-
return [...new Set(tools.map((t) =>
|
|
24505
|
+
return [...new Set(tools.map((t) => join49(rootPath, instructionsFilename(t.id))))];
|
|
24264
24506
|
}
|
|
24265
24507
|
function applyCodeRecommendation(intent) {
|
|
24266
24508
|
try {
|
|
24267
24509
|
const meta = JSON.parse(intent.name || "{}");
|
|
24268
24510
|
if (intent.artifact_type === "write_tasks_file") {
|
|
24269
24511
|
if (!meta.rootPath || !meta.content) return { status: "error", result: JSON.stringify({ error: "missing rootPath or content" }) };
|
|
24270
|
-
const file =
|
|
24512
|
+
const file = join49(meta.rootPath, meta.filename || "CODE_TASKS.md");
|
|
24271
24513
|
writeFileSync13(file, meta.content);
|
|
24272
24514
|
return { status: "done", result: JSON.stringify({ wrote: file }) };
|
|
24273
24515
|
}
|
|
@@ -24286,7 +24528,7 @@ function applyCodeRecommendation(intent) {
|
|
|
24286
24528
|
mkdirSync14(dir, { recursive: true });
|
|
24287
24529
|
} catch {
|
|
24288
24530
|
}
|
|
24289
|
-
const existing = existsSync46(file) ?
|
|
24531
|
+
const existing = existsSync46(file) ? readFileSync40(file, "utf8") : "";
|
|
24290
24532
|
if (existing.includes(text)) {
|
|
24291
24533
|
skipped.push(file);
|
|
24292
24534
|
continue;
|
|
@@ -24385,10 +24627,10 @@ async function runIntent(intent, ctx) {
|
|
|
24385
24627
|
var ownVersion2 = "0.0.0";
|
|
24386
24628
|
try {
|
|
24387
24629
|
const dir = dirname23(fileURLToPath4(import.meta.url));
|
|
24388
|
-
ownVersion2 = JSON.parse(
|
|
24630
|
+
ownVersion2 = JSON.parse(readFileSync40(join49(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
24389
24631
|
} catch {
|
|
24390
24632
|
try {
|
|
24391
|
-
if (true) ownVersion2 = "0.7.
|
|
24633
|
+
if (true) ownVersion2 = "0.7.18";
|
|
24392
24634
|
} catch {
|
|
24393
24635
|
}
|
|
24394
24636
|
}
|
|
@@ -24453,14 +24695,14 @@ init_auto_update();
|
|
|
24453
24695
|
|
|
24454
24696
|
// src/code-index-cursor.ts
|
|
24455
24697
|
init_paths();
|
|
24456
|
-
import { readFileSync as
|
|
24698
|
+
import { readFileSync as readFileSync41, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15, statSync as statSync43 } from "fs";
|
|
24457
24699
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
24458
24700
|
import { createHash as createHash10 } from "crypto";
|
|
24459
|
-
import { join as
|
|
24460
|
-
var cursorPath = () =>
|
|
24701
|
+
import { join as join50, dirname as dirname24 } from "path";
|
|
24702
|
+
var cursorPath = () => join50(getDataDir(), "code-index-cursor.json");
|
|
24461
24703
|
function readCursor() {
|
|
24462
24704
|
try {
|
|
24463
|
-
const raw = JSON.parse(
|
|
24705
|
+
const raw = JSON.parse(readFileSync41(cursorPath(), "utf-8"));
|
|
24464
24706
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
24465
24707
|
const out = {};
|
|
24466
24708
|
for (const [k, v] of Object.entries(raw)) {
|
|
@@ -24504,7 +24746,7 @@ function workspaceFingerprint(workspace, collectorVersion) {
|
|
|
24504
24746
|
const rel = entry.slice(3);
|
|
24505
24747
|
let stamp2 = "gone";
|
|
24506
24748
|
try {
|
|
24507
|
-
const s =
|
|
24749
|
+
const s = statSync43(join50(workspace, rel));
|
|
24508
24750
|
stamp2 = `${s.size}:${Math.floor(s.mtimeMs)}`;
|
|
24509
24751
|
} catch {
|
|
24510
24752
|
}
|
|
@@ -24640,13 +24882,13 @@ init_telemetry();
|
|
|
24640
24882
|
|
|
24641
24883
|
// src/self-restart.ts
|
|
24642
24884
|
import { spawn } from "child_process";
|
|
24643
|
-
import { readFileSync as
|
|
24885
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
24644
24886
|
import { createHash as createHash11 } from "crypto";
|
|
24645
24887
|
var EXIT_CODE_CODE_CHANGED = 75;
|
|
24646
24888
|
function codeFingerprint(entry = process.argv[1]) {
|
|
24647
24889
|
if (!entry) return null;
|
|
24648
24890
|
try {
|
|
24649
|
-
const buf =
|
|
24891
|
+
const buf = readFileSync42(entry);
|
|
24650
24892
|
return {
|
|
24651
24893
|
path: entry,
|
|
24652
24894
|
size: buf.byteLength,
|
|
@@ -24713,11 +24955,11 @@ function checkSelfRestart(opts) {
|
|
|
24713
24955
|
}
|
|
24714
24956
|
|
|
24715
24957
|
// src/log-rotate.ts
|
|
24716
|
-
import { statSync as
|
|
24958
|
+
import { statSync as statSync44, copyFileSync as copyFileSync3, truncateSync } from "fs";
|
|
24717
24959
|
var LOG_MAX_BYTES = 32 * 1024 * 1024;
|
|
24718
24960
|
function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
24719
24961
|
try {
|
|
24720
|
-
const size =
|
|
24962
|
+
const size = statSync44(logPath).size;
|
|
24721
24963
|
if (size < maxBytes) return { rotated: false, sizeBefore: 0 };
|
|
24722
24964
|
copyFileSync3(logPath, `${logPath}.1`);
|
|
24723
24965
|
truncateSync(logPath, 0);
|
|
@@ -24772,8 +25014,8 @@ async function runCollectorMigration(opts) {
|
|
|
24772
25014
|
// auto-indexer/indexer.ts
|
|
24773
25015
|
init_sync_ledger();
|
|
24774
25016
|
init_collector_health();
|
|
24775
|
-
import { existsSync as existsSync50, readFileSync as
|
|
24776
|
-
var CLI_VERSION3 = true ? "0.7.
|
|
25017
|
+
import { existsSync as existsSync50, readFileSync as readFileSync46, statSync as statSync47 } from "fs";
|
|
25018
|
+
var CLI_VERSION3 = true ? "0.7.18" : "0.0.0";
|
|
24777
25019
|
var DEBOUNCE_MS = 5e3;
|
|
24778
25020
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
24779
25021
|
var TASKS_DIR = claudeBackend.tasksDir();
|
|
@@ -24782,8 +25024,8 @@ var DIARY_DIR = getDiaryDir();
|
|
|
24782
25024
|
var CODEX_SESSIONS_DIR = codexBackend.sessionsDir();
|
|
24783
25025
|
var OPENCODE_DB_PATH = opencodeBackend.dbPath();
|
|
24784
25026
|
var OPENCODE_DB_DIR = dirname25(OPENCODE_DB_PATH);
|
|
24785
|
-
var CURRENT_RESUME_PATH =
|
|
24786
|
-
var LAST_CLEANUP_PATH =
|
|
25027
|
+
var CURRENT_RESUME_PATH = join55(claudeBackend.homeDir(), "current-resume");
|
|
25028
|
+
var LAST_CLEANUP_PATH = join55(claudeBackend.homeDir(), ".last-cleanup");
|
|
24787
25029
|
var debounceTimer = null;
|
|
24788
25030
|
var ticks = new TickQueue({
|
|
24789
25031
|
onError: (kind, err) => daemonLog.error(`${kind} tick failed: ${err instanceof Error ? err.message : err}`)
|
|
@@ -24832,7 +25074,7 @@ var lastResumeAt = /* @__PURE__ */ new Map();
|
|
|
24832
25074
|
var RESUME_REARM_MS = 6e4;
|
|
24833
25075
|
async function onResumeSignal(path) {
|
|
24834
25076
|
try {
|
|
24835
|
-
const txt =
|
|
25077
|
+
const txt = readFileSync46(path, "utf-8");
|
|
24836
25078
|
const m = /--resume\s+([0-9a-fA-F-]{36})/.exec(txt);
|
|
24837
25079
|
if (!m) return;
|
|
24838
25080
|
const id = m[1];
|
|
@@ -24878,7 +25120,7 @@ var CLAUDE_SESSION_ROOTS = claudeProjectDirs();
|
|
|
24878
25120
|
var sessionWatcher = watchWithFallback("sessions", CLAUDE_SESSION_ROOTS.map((root) => `${root}/**/*.jsonl`), {
|
|
24879
25121
|
ignored: (p, stats) => {
|
|
24880
25122
|
if (/agent-/.test(p) || /^\./.test(basename25(p))) return true;
|
|
24881
|
-
const st = stats ??
|
|
25123
|
+
const st = stats ?? statSync47(p, { throwIfNoEntry: false });
|
|
24882
25124
|
if (!st || st.isDirectory()) return false;
|
|
24883
25125
|
return st.mtimeMs < Date.now() - WATCH_WINDOW_MS;
|
|
24884
25126
|
},
|
|
@@ -25020,7 +25262,7 @@ if (BOOT_CODE) {
|
|
|
25020
25262
|
daemonLog.info(`running bundle ${BOOT_CODE.path} (${BOOT_CODE.size} bytes)`);
|
|
25021
25263
|
}
|
|
25022
25264
|
{
|
|
25023
|
-
const r = rotateLogIfLarge(
|
|
25265
|
+
const r = rotateLogIfLarge(join55(getDataDir(), "watch.log"));
|
|
25024
25266
|
if (r.rotated) {
|
|
25025
25267
|
daemonLog.info(`rotated watch.log at ${(r.sizeBefore / 1048576).toFixed(0)}MB \u2192 watch.log.1 (copy+truncate; the path is preserved)`);
|
|
25026
25268
|
}
|
|
@@ -25206,7 +25448,7 @@ function isCodeWorkspace(p) {
|
|
|
25206
25448
|
}
|
|
25207
25449
|
return WORKSPACE_MARKERS.some((m) => {
|
|
25208
25450
|
try {
|
|
25209
|
-
return existsSync50(
|
|
25451
|
+
return existsSync50(join55(p, m));
|
|
25210
25452
|
} catch {
|
|
25211
25453
|
return false;
|
|
25212
25454
|
}
|