chat-recall 0.7.16 → 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 +573 -331
- package/dist/mcp-relay.js +136 -40
- package/dist/mcp-relay.js.map +1 -1
- package/dist/mcp.js +381 -128
- 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 +447 -202
- 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
|
});
|
|
@@ -6963,18 +6965,20 @@ function updateShadow(sessionId, exp, prebuilt) {
|
|
|
6963
6965
|
const curHash = containerSrcHash(current);
|
|
6964
6966
|
if (!prior) {
|
|
6965
6967
|
current.srcHash = curHash;
|
|
6968
|
+
current.mergeVersion = SHADOW_MERGE_VERSION;
|
|
6966
6969
|
try {
|
|
6967
6970
|
writeShadowContainer(tool, rawId, current);
|
|
6968
6971
|
} catch {
|
|
6969
6972
|
}
|
|
6970
6973
|
return { status: "created", sessionId, tool, container: current, recovered: 0, path };
|
|
6971
6974
|
}
|
|
6972
|
-
if (prior.srcHash && prior.srcHash === curHash) {
|
|
6975
|
+
if (prior.srcHash && prior.srcHash === curHash && prior.mergeVersion === SHADOW_MERGE_VERSION) {
|
|
6973
6976
|
return { status: "unchanged", sessionId, tool, container: prior, recovered: 0, path };
|
|
6974
6977
|
}
|
|
6975
6978
|
const merged = mergeContainer(prior, current);
|
|
6976
|
-
if (merged.status !== "unchanged" || prior.srcHash !== curHash) {
|
|
6979
|
+
if (merged.status !== "unchanged" || prior.srcHash !== curHash || prior.mergeVersion !== SHADOW_MERGE_VERSION) {
|
|
6977
6980
|
merged.container.srcHash = curHash;
|
|
6981
|
+
merged.container.mergeVersion = SHADOW_MERGE_VERSION;
|
|
6978
6982
|
try {
|
|
6979
6983
|
writeShadowContainer(tool, rawId, merged.container);
|
|
6980
6984
|
} catch {
|
|
@@ -7067,7 +7071,7 @@ function shadowSizeOnDisk(tool, rawId) {
|
|
|
7067
7071
|
return 0;
|
|
7068
7072
|
}
|
|
7069
7073
|
}
|
|
7070
|
-
var WHOLE_FILE_TOOLS, STATE_META, lastLiveFingerprint;
|
|
7074
|
+
var WHOLE_FILE_TOOLS, STATE_META, SHADOW_MERGE_VERSION, lastLiveFingerprint;
|
|
7071
7075
|
var init_shadow = __esm({
|
|
7072
7076
|
"../engine/dist/transcript/shadow.js"() {
|
|
7073
7077
|
"use strict";
|
|
@@ -7075,6 +7079,7 @@ var init_shadow = __esm({
|
|
|
7075
7079
|
init_raw();
|
|
7076
7080
|
WHOLE_FILE_TOOLS = /* @__PURE__ */ new Set(["cursor"]);
|
|
7077
7081
|
STATE_META = /* @__PURE__ */ new Set(["mode", "permission-mode", "ai-title", "last-prompt", "pr-link", "summary"]);
|
|
7082
|
+
SHADOW_MERGE_VERSION = 2;
|
|
7078
7083
|
lastLiveFingerprint = /* @__PURE__ */ new Map();
|
|
7079
7084
|
}
|
|
7080
7085
|
});
|
|
@@ -13522,6 +13527,7 @@ var init_opencode2 = __esm({
|
|
|
13522
13527
|
// ../engine/dist/transcript/index.js
|
|
13523
13528
|
var transcript_exports = {};
|
|
13524
13529
|
__export(transcript_exports, {
|
|
13530
|
+
RAW_PARSE_MAX_BYTES: () => RAW_PARSE_MAX_BYTES,
|
|
13525
13531
|
TRANSCRIPT_VERSION: () => TRANSCRIPT_VERSION,
|
|
13526
13532
|
archiveRawSession: () => archiveRawSession,
|
|
13527
13533
|
buildRawContainer: () => buildRawContainer,
|
|
@@ -18101,12 +18107,15 @@ var init_extractor_version = __esm({
|
|
|
18101
18107
|
// src/sync-ledger.ts
|
|
18102
18108
|
var sync_ledger_exports = {};
|
|
18103
18109
|
__export(sync_ledger_exports, {
|
|
18110
|
+
SETTLE_QUIET_MS: () => SETTLE_QUIET_MS,
|
|
18104
18111
|
_resetLedgerCacheForTests: () => _resetLedgerCacheForTests,
|
|
18105
18112
|
_resetUnackedCursorCount: () => _resetUnackedCursorCount,
|
|
18106
18113
|
fieldNeedsFullPass: () => fieldNeedsFullPass,
|
|
18107
18114
|
fieldNeedsScan: () => fieldNeedsScan,
|
|
18108
18115
|
flushLedger: () => flushLedger,
|
|
18109
18116
|
forceFieldRescan: () => forceFieldRescan,
|
|
18117
|
+
forgetFullCoverage: () => forgetFullCoverage,
|
|
18118
|
+
fullCoveredOffset: () => fullCoveredOffset,
|
|
18110
18119
|
getLedgerData: () => getLedgerData,
|
|
18111
18120
|
getSyncedMtimes: () => getSyncedMtimes,
|
|
18112
18121
|
getSyncedRows: () => getSyncedRows,
|
|
@@ -18358,6 +18367,11 @@ function markSynced(server, rows) {
|
|
|
18358
18367
|
base3.s = s;
|
|
18359
18368
|
}
|
|
18360
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;
|
|
18361
18375
|
forServer[r.id] = base3;
|
|
18362
18376
|
}
|
|
18363
18377
|
persist(data);
|
|
@@ -18431,6 +18445,14 @@ function _resetLedgerCacheForTests() {
|
|
|
18431
18445
|
diskStamp = null;
|
|
18432
18446
|
reconcileCache = null;
|
|
18433
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
|
+
}
|
|
18434
18456
|
function markFullResync(server, sessionId) {
|
|
18435
18457
|
const data = load();
|
|
18436
18458
|
const forServer = data[server];
|
|
@@ -18439,7 +18461,11 @@ function markFullResync(server, sessionId) {
|
|
|
18439
18461
|
delete forServer[sessionId];
|
|
18440
18462
|
persist(data);
|
|
18441
18463
|
}
|
|
18442
|
-
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()) {
|
|
18443
18469
|
if (!row) return "full";
|
|
18444
18470
|
if (row.v < extractorVersion) return "full";
|
|
18445
18471
|
const offset = row.o ?? 0;
|
|
@@ -18447,10 +18473,13 @@ function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly) {
|
|
|
18447
18473
|
if (process.env.CHAT_RECALL_TAIL_APPEND !== "0" && isAppendOnly && fileSize > 0 && offset > 0 && fileSize > (row.s ?? 0)) {
|
|
18448
18474
|
return "append";
|
|
18449
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
|
+
}
|
|
18450
18479
|
if (row.m >= Math.floor(mtime)) return "skip";
|
|
18451
18480
|
return "full";
|
|
18452
18481
|
}
|
|
18453
|
-
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;
|
|
18454
18483
|
var init_sync_ledger = __esm({
|
|
18455
18484
|
"src/sync-ledger.ts"() {
|
|
18456
18485
|
"use strict";
|
|
@@ -18470,6 +18499,7 @@ var init_sync_ledger = __esm({
|
|
|
18470
18499
|
unackedCursorAttempts = 0;
|
|
18471
18500
|
reconcilePath = () => join39(getDataDir(), "sync-field-reconcile.json");
|
|
18472
18501
|
reconcileCache = null;
|
|
18502
|
+
SETTLE_QUIET_MS = 2 * 60 * 60 * 1e3;
|
|
18473
18503
|
}
|
|
18474
18504
|
});
|
|
18475
18505
|
|
|
@@ -18612,7 +18642,7 @@ var init_http = __esm({
|
|
|
18612
18642
|
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18613
18643
|
} catch {
|
|
18614
18644
|
try {
|
|
18615
|
-
if (true) CLI_VERSION = "0.7.
|
|
18645
|
+
if (true) CLI_VERSION = "0.7.18";
|
|
18616
18646
|
} catch {
|
|
18617
18647
|
}
|
|
18618
18648
|
}
|
|
@@ -19106,7 +19136,7 @@ var init_telemetry = __esm({
|
|
|
19106
19136
|
init_sync_client();
|
|
19107
19137
|
cliVersion = () => {
|
|
19108
19138
|
try {
|
|
19109
|
-
return true ? "0.7.
|
|
19139
|
+
return true ? "0.7.18" : "dev";
|
|
19110
19140
|
} catch {
|
|
19111
19141
|
return "dev";
|
|
19112
19142
|
}
|
|
@@ -19116,6 +19146,150 @@ var init_telemetry = __esm({
|
|
|
19116
19146
|
}
|
|
19117
19147
|
});
|
|
19118
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
|
+
|
|
19119
19293
|
// src/server-probe.ts
|
|
19120
19294
|
var server_probe_exports = {};
|
|
19121
19295
|
__export(server_probe_exports, {
|
|
@@ -19259,7 +19433,7 @@ __export(client_events_exports, {
|
|
|
19259
19433
|
isTelemetryEnabled: () => isTelemetryEnabled,
|
|
19260
19434
|
reportClientEvent: () => reportClientEvent
|
|
19261
19435
|
});
|
|
19262
|
-
import { readFileSync as
|
|
19436
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
19263
19437
|
function scrub(msg) {
|
|
19264
19438
|
if (!msg) return "";
|
|
19265
19439
|
const noHome = msg.replace(/\/(?:home|Users)\/[^/\s]+/g, "~");
|
|
@@ -19312,7 +19486,7 @@ var init_client_events = __esm({
|
|
|
19312
19486
|
init_secret_redactor();
|
|
19313
19487
|
CLI_VERSION2 = "0.0.0";
|
|
19314
19488
|
try {
|
|
19315
|
-
CLI_VERSION2 = JSON.parse(
|
|
19489
|
+
CLI_VERSION2 = JSON.parse(readFileSync34(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION2;
|
|
19316
19490
|
} catch {
|
|
19317
19491
|
}
|
|
19318
19492
|
}
|
|
@@ -19342,11 +19516,11 @@ __export(auto_update_exports, {
|
|
|
19342
19516
|
tarballUrl: () => tarballUrl
|
|
19343
19517
|
});
|
|
19344
19518
|
import { execSync as execSync2, execFileSync as execFileSync3 } from "node:child_process";
|
|
19345
|
-
import { readFileSync as
|
|
19519
|
+
import { readFileSync as readFileSync35, existsSync as existsSync41 } from "node:fs";
|
|
19346
19520
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19347
|
-
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as
|
|
19348
|
-
import { join as
|
|
19349
|
-
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";
|
|
19350
19524
|
import { createHash as createHash7 } from "node:crypto";
|
|
19351
19525
|
function compareVersions(a, b) {
|
|
19352
19526
|
const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -19370,7 +19544,7 @@ function newerOf(a, b) {
|
|
|
19370
19544
|
function installedVersion() {
|
|
19371
19545
|
try {
|
|
19372
19546
|
const here = dirname18(fileURLToPath2(import.meta.url));
|
|
19373
|
-
const raw =
|
|
19547
|
+
const raw = readFileSync35(join42(here, "..", "package.json"), "utf-8");
|
|
19374
19548
|
return JSON.parse(raw).version || null;
|
|
19375
19549
|
} catch {
|
|
19376
19550
|
return null;
|
|
@@ -19383,7 +19557,7 @@ function planAutoUpdate(base3, caps, ownVersion3, flag) {
|
|
|
19383
19557
|
if (compareVersions(rel.version, ownVersion3) <= 0) return { update: false, reason: `already current (own ${ownVersion3} >= server ${rel.version})` };
|
|
19384
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 };
|
|
19385
19559
|
}
|
|
19386
|
-
function sweepStaleStaging(root =
|
|
19560
|
+
function sweepStaleStaging(root = tmpdir3(), now = Date.now()) {
|
|
19387
19561
|
const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
|
|
19388
19562
|
const COLD_MS = 60 * 60 * 1e3;
|
|
19389
19563
|
let removed = 0;
|
|
@@ -19395,13 +19569,13 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
19395
19569
|
}
|
|
19396
19570
|
for (const name of entries) {
|
|
19397
19571
|
if (!MKDTEMP_SUFFIX.test(name)) continue;
|
|
19398
|
-
const dir =
|
|
19572
|
+
const dir = join42(root, name);
|
|
19399
19573
|
try {
|
|
19400
|
-
const st =
|
|
19574
|
+
const st = statSync38(dir);
|
|
19401
19575
|
if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
|
|
19402
19576
|
const inside = readdirSync30(dir);
|
|
19403
19577
|
if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
|
|
19404
|
-
|
|
19578
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19405
19579
|
removed++;
|
|
19406
19580
|
} catch {
|
|
19407
19581
|
}
|
|
@@ -19424,14 +19598,14 @@ async function executeAutoUpdate(plan, deps) {
|
|
|
19424
19598
|
}
|
|
19425
19599
|
const got = createHash7("sha256").update(buf).digest("hex");
|
|
19426
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` };
|
|
19427
|
-
const dir = mkdtempSync3(
|
|
19601
|
+
const dir = mkdtempSync3(join42(tmpdir3(), "cr-update-"));
|
|
19428
19602
|
const discardStaging = () => {
|
|
19429
19603
|
try {
|
|
19430
|
-
|
|
19604
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19431
19605
|
} catch {
|
|
19432
19606
|
}
|
|
19433
19607
|
};
|
|
19434
|
-
const tgz =
|
|
19608
|
+
const tgz = join42(dir, "chat-recall.tgz");
|
|
19435
19609
|
writeFileSync8(tgz, buf);
|
|
19436
19610
|
if (deps.stopping?.()) {
|
|
19437
19611
|
discardStaging();
|
|
@@ -19511,7 +19685,7 @@ function realInstall(tgz) {
|
|
|
19511
19685
|
try {
|
|
19512
19686
|
npmInstall(npm, ["install", "-g", tgz]);
|
|
19513
19687
|
} catch {
|
|
19514
|
-
npmInstall(npm, ["install", "-g", "--prefix",
|
|
19688
|
+
npmInstall(npm, ["install", "-g", "--prefix", join42(homedir15(), ".local"), tgz]);
|
|
19515
19689
|
}
|
|
19516
19690
|
}
|
|
19517
19691
|
function acquireUpdateLock() {
|
|
@@ -19528,12 +19702,12 @@ function realRestart(platform2) {
|
|
|
19528
19702
|
if (c) execSync2(c.cmd, { stdio: "ignore", ...c.shell ? { shell: c.shell } : {} });
|
|
19529
19703
|
}
|
|
19530
19704
|
function updateStatePath() {
|
|
19531
|
-
const dir = process.env.CHAT_RECALL_DATA_DIR ||
|
|
19532
|
-
return
|
|
19705
|
+
const dir = process.env.CHAT_RECALL_DATA_DIR || join42(homedir15(), ".chat-recall");
|
|
19706
|
+
return join42(dir, "auto-update-state.json");
|
|
19533
19707
|
}
|
|
19534
19708
|
function readUpdateState() {
|
|
19535
19709
|
try {
|
|
19536
|
-
return JSON.parse(
|
|
19710
|
+
return JSON.parse(readFileSync35(updateStatePath(), "utf8"));
|
|
19537
19711
|
} catch {
|
|
19538
19712
|
return {};
|
|
19539
19713
|
}
|
|
@@ -19640,9 +19814,9 @@ var init_auto_update = __esm({
|
|
|
19640
19814
|
});
|
|
19641
19815
|
|
|
19642
19816
|
// src/sync-client.ts
|
|
19643
|
-
import { join as
|
|
19644
|
-
import { readFileSync as
|
|
19645
|
-
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";
|
|
19646
19820
|
import { createHash as createHash8 } from "node:crypto";
|
|
19647
19821
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19648
19822
|
import { gzipSync as gzipSync3 } from "zlib";
|
|
@@ -19678,7 +19852,7 @@ function loadAllCredentials() {
|
|
|
19678
19852
|
const fromEnv = envCredentials();
|
|
19679
19853
|
if (fromEnv) return [{ serverUrl: fromEnv.serverUrl, token: fromEnv.token }];
|
|
19680
19854
|
try {
|
|
19681
|
-
const parsed = JSON.parse(
|
|
19855
|
+
const parsed = JSON.parse(readFileSync36(credPath(), "utf-8"));
|
|
19682
19856
|
if (Array.isArray(parsed?.targets)) return parsed.targets.filter((t) => t?.serverUrl).map((t) => ({ serverUrl: t.serverUrl, token: t.token || "" }));
|
|
19683
19857
|
if (parsed?.serverUrl) return [{ serverUrl: parsed.serverUrl, token: parsed.token || "" }];
|
|
19684
19858
|
} catch {
|
|
@@ -19737,11 +19911,11 @@ async function fetchTenantSecurityConfig(cred) {
|
|
|
19737
19911
|
}
|
|
19738
19912
|
}
|
|
19739
19913
|
function syncConfigCachePath() {
|
|
19740
|
-
return
|
|
19914
|
+
return join43(getDataDir(), "sync-config-cache.json");
|
|
19741
19915
|
}
|
|
19742
19916
|
function readPersistedSyncConfigs() {
|
|
19743
19917
|
try {
|
|
19744
|
-
return JSON.parse(
|
|
19918
|
+
return JSON.parse(readFileSync36(syncConfigCachePath(), "utf-8"));
|
|
19745
19919
|
} catch {
|
|
19746
19920
|
return {};
|
|
19747
19921
|
}
|
|
@@ -19984,7 +20158,7 @@ async function reconcileFieldsForTarget(cred, fullRefs, opts = {}) {
|
|
|
19984
20158
|
}
|
|
19985
20159
|
return { pushed, absent, scanned };
|
|
19986
20160
|
}
|
|
19987
|
-
function reapStaleScanDirs(dir =
|
|
20161
|
+
function reapStaleScanDirs(dir = tmpdir4(), maxAgeMs = 6 * 36e5, now = Date.now()) {
|
|
19988
20162
|
let reaped = 0;
|
|
19989
20163
|
let names;
|
|
19990
20164
|
try {
|
|
@@ -19994,10 +20168,10 @@ function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now(
|
|
|
19994
20168
|
}
|
|
19995
20169
|
for (const name of names) {
|
|
19996
20170
|
if (!name.startsWith("cr-batchscan-")) continue;
|
|
19997
|
-
const p =
|
|
20171
|
+
const p = join43(dir, name);
|
|
19998
20172
|
try {
|
|
19999
|
-
if (now -
|
|
20000
|
-
|
|
20173
|
+
if (now - statSync39(p).mtimeMs < maxAgeMs) continue;
|
|
20174
|
+
rmSync7(p, { recursive: true, force: true });
|
|
20001
20175
|
reaped++;
|
|
20002
20176
|
} catch {
|
|
20003
20177
|
}
|
|
@@ -20011,7 +20185,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20011
20185
|
let scanned = 0, slices = 0, scanMs = 0;
|
|
20012
20186
|
if (items.length === 0) return { findings, scanned, slices, scanMs };
|
|
20013
20187
|
reapStaleScanDirs();
|
|
20014
|
-
let scanDir = mkdtempSync4(
|
|
20188
|
+
let scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20015
20189
|
let safeToId = /* @__PURE__ */ new Map();
|
|
20016
20190
|
let bytesInDir = 0;
|
|
20017
20191
|
const flushSlice = () => {
|
|
@@ -20029,7 +20203,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20029
20203
|
slices++;
|
|
20030
20204
|
}
|
|
20031
20205
|
try {
|
|
20032
|
-
|
|
20206
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20033
20207
|
} catch {
|
|
20034
20208
|
}
|
|
20035
20209
|
safeToId = /* @__PURE__ */ new Map();
|
|
@@ -20042,19 +20216,19 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20042
20216
|
if (raw === null) continue;
|
|
20043
20217
|
const safe = item.id.replace(/[^A-Za-z0-9_-]/g, "");
|
|
20044
20218
|
safeToId.set(safe, item.id);
|
|
20045
|
-
writeFileSync9(
|
|
20219
|
+
writeFileSync9(join43(scanDir, `${safe}.txt`), raw);
|
|
20046
20220
|
bytesInDir += Buffer.byteLength(raw);
|
|
20047
20221
|
} catch {
|
|
20048
20222
|
}
|
|
20049
20223
|
if (bytesInDir >= maxBytes) {
|
|
20050
20224
|
flushSlice();
|
|
20051
|
-
scanDir = mkdtempSync4(
|
|
20225
|
+
scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20052
20226
|
}
|
|
20053
20227
|
}
|
|
20054
20228
|
flushSlice();
|
|
20055
20229
|
} finally {
|
|
20056
20230
|
try {
|
|
20057
|
-
|
|
20231
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20058
20232
|
} catch {
|
|
20059
20233
|
}
|
|
20060
20234
|
}
|
|
@@ -20293,12 +20467,13 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20293
20467
|
markSynced(base3, rows.map((r) => {
|
|
20294
20468
|
const off = typeof r.from_offset === "number" ? r.from_offset : 0;
|
|
20295
20469
|
const hash = shippedHash.get(r.session_id);
|
|
20296
|
-
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 };
|
|
20297
20471
|
}));
|
|
20298
20472
|
} catch {
|
|
20299
20473
|
}
|
|
20300
20474
|
});
|
|
20301
20475
|
const appendResults = { uploaded: 0, fullResyncNeeded: /* @__PURE__ */ new Set() };
|
|
20476
|
+
const pendingArchives = [];
|
|
20302
20477
|
const postAppend = async (convs) => {
|
|
20303
20478
|
const headers = { "content-type": "application/json" };
|
|
20304
20479
|
if (cred.token) headers.authorization = `Bearer ${cred.token}`;
|
|
@@ -20333,8 +20508,10 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20333
20508
|
offset: c.from_offset,
|
|
20334
20509
|
size: c.from_offset,
|
|
20335
20510
|
// size = new offset (file grew to here)
|
|
20336
|
-
acked: true
|
|
20511
|
+
acked: true,
|
|
20337
20512
|
// server merged this tail
|
|
20513
|
+
chunkFinal: c.final === true
|
|
20514
|
+
// completes a chunked full sync
|
|
20338
20515
|
})));
|
|
20339
20516
|
} catch {
|
|
20340
20517
|
}
|
|
@@ -20366,9 +20543,9 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20366
20543
|
const mtime = conv.mtime;
|
|
20367
20544
|
try {
|
|
20368
20545
|
if (staged || !guarded) {
|
|
20369
|
-
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 }]);
|
|
20370
20547
|
} else if (typeof guarded.o === "number" && guarded.o > 0 && guarded.o <= fileSize) {
|
|
20371
|
-
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 }]);
|
|
20372
20549
|
} else {
|
|
20373
20550
|
markSynced(base3, [{ id, mtime }]);
|
|
20374
20551
|
}
|
|
@@ -20577,6 +20754,14 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20577
20754
|
if (built.srcHash) shippedHash.set(ref.prefixedId, built.srcHash);
|
|
20578
20755
|
if (built.conv.chunked) await postChunkedHead(built.conv, sessionFileBytes(ref));
|
|
20579
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
|
+
}
|
|
20580
20765
|
if (built.findings.length > 0) await findingsBatch.add(built.findings);
|
|
20581
20766
|
if (upload.sessionMeta) {
|
|
20582
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);
|
|
@@ -20729,6 +20914,30 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20729
20914
|
await kgTripleBatch.drain();
|
|
20730
20915
|
await findingsBatch.drain();
|
|
20731
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
|
+
}
|
|
20732
20941
|
{
|
|
20733
20942
|
const sentHashes = loadInventoryHashes(base3);
|
|
20734
20943
|
const entries = [];
|
|
@@ -20834,6 +21043,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
20834
21043
|
let includeRaw = opts.includeRaw !== false;
|
|
20835
21044
|
let includeMeta = opts.includeMeta !== false;
|
|
20836
21045
|
let srcHash;
|
|
21046
|
+
const wantRaw = opts.includeRaw !== false;
|
|
20837
21047
|
const oversized = sessionBuildBytes(ref) > FULL_BUILD_MAX_BYTES;
|
|
20838
21048
|
let headOffsetEnd = 0;
|
|
20839
21049
|
let oversizedFindings = null;
|
|
@@ -21002,7 +21212,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21002
21212
|
} else if (opts.scanSecrets) {
|
|
21003
21213
|
let tmp = null;
|
|
21004
21214
|
try {
|
|
21005
|
-
tmp =
|
|
21215
|
+
tmp = join43(tmpdir4(), `cr-scan-${ref.prefixedId.replace(/[^A-Za-z0-9_-]/g, "")}-${mtime}.txt`);
|
|
21006
21216
|
writeFileSync9(tmp, rawText);
|
|
21007
21217
|
for (const f of scanFileForSecrets(tmp, { verifyOnly: opts.verifySecrets, tenantRules: opts.tenantRules })) {
|
|
21008
21218
|
const verifiedAt = f.verified ? (/* @__PURE__ */ new Date()).toISOString() : null;
|
|
@@ -21054,6 +21264,25 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21054
21264
|
}
|
|
21055
21265
|
const envTexts = envelope.messages.filter((m) => m.content?.trim());
|
|
21056
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
|
+
}
|
|
21057
21286
|
return {
|
|
21058
21287
|
conv: {
|
|
21059
21288
|
session_id: ref.prefixedId,
|
|
@@ -21085,7 +21314,17 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21085
21314
|
redactions: count.redactions,
|
|
21086
21315
|
findings,
|
|
21087
21316
|
scanMs,
|
|
21088
|
-
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] }))
|
|
21089
21328
|
};
|
|
21090
21329
|
}
|
|
21091
21330
|
function parseTailMessages(tool, text) {
|
|
@@ -21241,14 +21480,15 @@ var init_sync_client = __esm({
|
|
|
21241
21480
|
init_telemetry();
|
|
21242
21481
|
init_collector_health();
|
|
21243
21482
|
init_live_session_scan();
|
|
21483
|
+
init_raw_archive_parts();
|
|
21244
21484
|
init_backends();
|
|
21245
21485
|
ownVersion = "0.0.0";
|
|
21246
21486
|
try {
|
|
21247
21487
|
const dir = dirname19(fileURLToPath3(import.meta.url));
|
|
21248
|
-
ownVersion = JSON.parse(
|
|
21488
|
+
ownVersion = JSON.parse(readFileSync36(join43(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21249
21489
|
} catch {
|
|
21250
21490
|
try {
|
|
21251
|
-
if (true) ownVersion = "0.7.
|
|
21491
|
+
if (true) ownVersion = "0.7.18";
|
|
21252
21492
|
} catch {
|
|
21253
21493
|
}
|
|
21254
21494
|
}
|
|
@@ -21260,7 +21500,7 @@ var init_sync_client = __esm({
|
|
|
21260
21500
|
]);
|
|
21261
21501
|
walkProgressForUpload = null;
|
|
21262
21502
|
lastServerPackSpec = null;
|
|
21263
|
-
credPath = () =>
|
|
21503
|
+
credPath = () => join43(getDataDir(), "credentials.json");
|
|
21264
21504
|
_securityConfigCache = /* @__PURE__ */ new Map();
|
|
21265
21505
|
SECURITY_CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
21266
21506
|
_syncConfigCache = /* @__PURE__ */ new Map();
|
|
@@ -21283,8 +21523,8 @@ var init_sync_client = __esm({
|
|
|
21283
21523
|
});
|
|
21284
21524
|
|
|
21285
21525
|
// ../engine/dist/core/artifact-codec.js
|
|
21286
|
-
import { readFileSync as
|
|
21287
|
-
import { basename as basename21, join as
|
|
21526
|
+
import { readFileSync as readFileSync37 } from "fs";
|
|
21527
|
+
import { basename as basename21, join as join44 } from "path";
|
|
21288
21528
|
import { homedir as homedir16 } from "os";
|
|
21289
21529
|
function parseCommandText(content, format, fallbackName) {
|
|
21290
21530
|
if (format === "toml") {
|
|
@@ -21307,41 +21547,41 @@ function parseAgentText(content, format, fallbackName) {
|
|
|
21307
21547
|
return { name: fm.name || fallbackName, description: fm.description || "", tools: fm.tools, body: body.trim() };
|
|
21308
21548
|
}
|
|
21309
21549
|
function readCommand(filePath, format) {
|
|
21310
|
-
return parseCommandText(
|
|
21550
|
+
return parseCommandText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21311
21551
|
}
|
|
21312
21552
|
function readAgent(filePath, format) {
|
|
21313
|
-
return parseAgentText(
|
|
21553
|
+
return parseAgentText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21314
21554
|
}
|
|
21315
21555
|
function readInstructions(filePath, name) {
|
|
21316
|
-
const content =
|
|
21556
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
21317
21557
|
return { name, description: "", body: content };
|
|
21318
21558
|
}
|
|
21319
21559
|
function commandPath(tool, name) {
|
|
21320
21560
|
switch (tool) {
|
|
21321
21561
|
case "claude":
|
|
21322
|
-
return
|
|
21562
|
+
return join44(claudeBackend.commandsDir(), `${name}.md`);
|
|
21323
21563
|
case "agy":
|
|
21324
|
-
return
|
|
21564
|
+
return join44(join44(agyBackend.homeDir(), "commands"), `${name}.toml`);
|
|
21325
21565
|
case "opencode":
|
|
21326
|
-
return
|
|
21566
|
+
return join44(opencodeBackend.commandsDir(), `${name}.md`);
|
|
21327
21567
|
case "codex":
|
|
21328
|
-
return
|
|
21568
|
+
return join44(codexBackend.promptsDir(), `${name}.md`);
|
|
21329
21569
|
case "cursor":
|
|
21330
|
-
return
|
|
21570
|
+
return join44(cursorHomeDir(), "commands", `${name}.md`);
|
|
21331
21571
|
}
|
|
21332
21572
|
}
|
|
21333
21573
|
function agentPath(tool, name) {
|
|
21334
21574
|
switch (tool) {
|
|
21335
21575
|
case "claude":
|
|
21336
|
-
return
|
|
21576
|
+
return join44(claudeBackend.agentsDir(), `${name}.md`);
|
|
21337
21577
|
case "agy":
|
|
21338
|
-
return
|
|
21578
|
+
return join44(join44(agyBackend.homeDir(), "agents"), `${name}.md`);
|
|
21339
21579
|
case "opencode":
|
|
21340
|
-
return
|
|
21580
|
+
return join44(opencodeBackend.agentsDir(), `${name}.md`);
|
|
21341
21581
|
case "codex":
|
|
21342
|
-
return
|
|
21582
|
+
return join44(codexBackend.agentsDir(), `${name}.toml`);
|
|
21343
21583
|
case "cursor":
|
|
21344
|
-
return
|
|
21584
|
+
return join44(cursorHomeDir(), "agents", `${name}.md`);
|
|
21345
21585
|
}
|
|
21346
21586
|
}
|
|
21347
21587
|
function instructionsFilename(tool) {
|
|
@@ -21366,21 +21606,21 @@ function instructionsFilename(tool) {
|
|
|
21366
21606
|
function instructionsPath(tool, projectPath) {
|
|
21367
21607
|
const file = instructionsFilename(tool);
|
|
21368
21608
|
if (projectPath)
|
|
21369
|
-
return
|
|
21609
|
+
return join44(projectPath, file);
|
|
21370
21610
|
switch (tool) {
|
|
21371
21611
|
case "claude":
|
|
21372
|
-
return
|
|
21612
|
+
return join44(claudeBackend.homeDir(), file);
|
|
21373
21613
|
case "agy":
|
|
21374
|
-
return
|
|
21614
|
+
return join44(agyBackend.homeDir(), file);
|
|
21375
21615
|
case "codex":
|
|
21376
|
-
return
|
|
21616
|
+
return join44(codexBackend.homeDir(), file);
|
|
21377
21617
|
case "opencode":
|
|
21378
|
-
return
|
|
21618
|
+
return join44(homedir16(), ".config", "opencode", file);
|
|
21379
21619
|
// Cursor has no single user-scope instructions FILE — user-level guidance
|
|
21380
21620
|
// is User Rules plus ~/.cursor/rules/*.mdc. AGENTS.md at the home root is
|
|
21381
21621
|
// the closest equivalent and is what a mirror can actually write.
|
|
21382
21622
|
case "cursor":
|
|
21383
|
-
return
|
|
21623
|
+
return join44(cursorHomeDir(), file);
|
|
21384
21624
|
}
|
|
21385
21625
|
}
|
|
21386
21626
|
function emit(type, art, toTool, projectPath) {
|
|
@@ -21426,8 +21666,8 @@ var init_artifact_codec = __esm({
|
|
|
21426
21666
|
});
|
|
21427
21667
|
|
|
21428
21668
|
// ../engine/dist/core/toolkit-sync.js
|
|
21429
|
-
import { existsSync as existsSync42, mkdirSync as mkdirSync11, readFileSync as
|
|
21430
|
-
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";
|
|
21431
21671
|
import { homedir as homedir17 } from "os";
|
|
21432
21672
|
function rowFromMemoryItem(type, item) {
|
|
21433
21673
|
const extra = item.extra || {};
|
|
@@ -21448,14 +21688,14 @@ function skillsDirFor(tool) {
|
|
|
21448
21688
|
case "claude":
|
|
21449
21689
|
return claudeBackend.skillsDir();
|
|
21450
21690
|
case "agy":
|
|
21451
|
-
return
|
|
21691
|
+
return join45(agyBackend.homeDir(), "skills");
|
|
21452
21692
|
case "opencode":
|
|
21453
21693
|
return opencodeBackend.skillsDir();
|
|
21454
21694
|
case "codex":
|
|
21455
21695
|
return codexBackend.skillsDir();
|
|
21456
21696
|
// user skills, NOT .system
|
|
21457
21697
|
case "cursor":
|
|
21458
|
-
return
|
|
21698
|
+
return join45(cursorHomeDir(), "skills");
|
|
21459
21699
|
}
|
|
21460
21700
|
}
|
|
21461
21701
|
function copySkill(row, toTool) {
|
|
@@ -21463,7 +21703,7 @@ function copySkill(row, toTool) {
|
|
|
21463
21703
|
if (!existsSync42(skillDir))
|
|
21464
21704
|
return { ok: false, status: 404, error: `Source dir missing: ${skillDir}` };
|
|
21465
21705
|
const name = row.extra.skillName || basename22(skillDir);
|
|
21466
|
-
const targetDir =
|
|
21706
|
+
const targetDir = join45(skillsDirFor(toTool), name);
|
|
21467
21707
|
if (existsSync42(targetDir))
|
|
21468
21708
|
return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
|
|
21469
21709
|
try {
|
|
@@ -21478,20 +21718,20 @@ function readMcpEntry(tool, name) {
|
|
|
21478
21718
|
const home = homedir17();
|
|
21479
21719
|
const tries = [];
|
|
21480
21720
|
if (tool === "claude") {
|
|
21481
|
-
tries.push({ path:
|
|
21482
|
-
tries.push({ path:
|
|
21721
|
+
tries.push({ path: join45(home, ".mcp.json"), key: "mcpServers" });
|
|
21722
|
+
tries.push({ path: join45(home, ".claude.json"), key: "mcpServers" });
|
|
21483
21723
|
} else if (tool === "gemini") {
|
|
21484
|
-
tries.push({ path:
|
|
21724
|
+
tries.push({ path: join45(home, ".gemini", "settings.json"), key: "mcpServers" });
|
|
21485
21725
|
} else if (tool === "agy") {
|
|
21486
|
-
tries.push({ path:
|
|
21726
|
+
tries.push({ path: join45(home, ".gemini", "config", "mcp_config.json"), key: "mcpServers" });
|
|
21487
21727
|
} else if (tool === "cursor") {
|
|
21488
|
-
tries.push({ path:
|
|
21728
|
+
tries.push({ path: join45(cursorHomeDir(), "mcp.json"), key: "mcpServers" });
|
|
21489
21729
|
} else if (tool === "opencode") {
|
|
21490
|
-
tries.push({ path:
|
|
21491
|
-
tries.push({ path:
|
|
21492
|
-
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" });
|
|
21493
21733
|
} else if (tool === "codex") {
|
|
21494
|
-
const entry = readCodexMcpEntry(
|
|
21734
|
+
const entry = readCodexMcpEntry(join45(home, ".codex", "config.toml"), name);
|
|
21495
21735
|
if (entry)
|
|
21496
21736
|
return entry;
|
|
21497
21737
|
}
|
|
@@ -21499,7 +21739,7 @@ function readMcpEntry(tool, name) {
|
|
|
21499
21739
|
if (!existsSync42(t.path))
|
|
21500
21740
|
continue;
|
|
21501
21741
|
try {
|
|
21502
|
-
const cfg = JSON.parse(
|
|
21742
|
+
const cfg = JSON.parse(readFileSync38(t.path, "utf-8"));
|
|
21503
21743
|
const block = cfg[t.key] || {};
|
|
21504
21744
|
if (block[name])
|
|
21505
21745
|
return block[name];
|
|
@@ -21513,7 +21753,7 @@ function readCodexMcpEntry(path, target) {
|
|
|
21513
21753
|
return null;
|
|
21514
21754
|
let content;
|
|
21515
21755
|
try {
|
|
21516
|
-
content =
|
|
21756
|
+
content = readFileSync38(path, "utf-8");
|
|
21517
21757
|
} catch {
|
|
21518
21758
|
return null;
|
|
21519
21759
|
}
|
|
@@ -21564,7 +21804,7 @@ function readCodexMcpEntry(path, target) {
|
|
|
21564
21804
|
function writeCodexMcpEntry(path, name, entry) {
|
|
21565
21805
|
let content = "";
|
|
21566
21806
|
if (existsSync42(path))
|
|
21567
|
-
content =
|
|
21807
|
+
content = readFileSync38(path, "utf-8");
|
|
21568
21808
|
const header = `[mcp_servers.${name}]`;
|
|
21569
21809
|
if (content.includes(header))
|
|
21570
21810
|
return false;
|
|
@@ -21600,7 +21840,7 @@ function writeCodexMcpEntry(path, name, entry) {
|
|
|
21600
21840
|
function writeMcpEntry(toTool, name, entry) {
|
|
21601
21841
|
const home = homedir17();
|
|
21602
21842
|
if (toTool === "codex") {
|
|
21603
|
-
const path2 =
|
|
21843
|
+
const path2 = join45(home, ".codex", "config.toml");
|
|
21604
21844
|
if (!writeCodexMcpEntry(path2, name, entry))
|
|
21605
21845
|
return { ok: false, status: 409, error: `MCP "${name}" already exists in ${path2}.` };
|
|
21606
21846
|
return { ok: true, targetPath: path2 };
|
|
@@ -21608,22 +21848,22 @@ function writeMcpEntry(toTool, name, entry) {
|
|
|
21608
21848
|
let path;
|
|
21609
21849
|
let key2;
|
|
21610
21850
|
if (toTool === "claude") {
|
|
21611
|
-
path =
|
|
21851
|
+
path = join45(home, ".mcp.json");
|
|
21612
21852
|
key2 = "mcpServers";
|
|
21613
21853
|
} else if (toTool === "agy") {
|
|
21614
|
-
path =
|
|
21854
|
+
path = join45(home, ".gemini", "config", "mcp_config.json");
|
|
21615
21855
|
key2 = "mcpServers";
|
|
21616
21856
|
} else if (toTool === "cursor") {
|
|
21617
|
-
path =
|
|
21857
|
+
path = join45(cursorHomeDir(), "mcp.json");
|
|
21618
21858
|
key2 = "mcpServers";
|
|
21619
21859
|
} else {
|
|
21620
|
-
path =
|
|
21860
|
+
path = join45(home, ".config", "opencode", "opencode.json");
|
|
21621
21861
|
key2 = "mcp";
|
|
21622
21862
|
}
|
|
21623
21863
|
let cfg = {};
|
|
21624
21864
|
if (existsSync42(path)) {
|
|
21625
21865
|
try {
|
|
21626
|
-
cfg = JSON.parse(
|
|
21866
|
+
cfg = JSON.parse(readFileSync38(path, "utf-8"));
|
|
21627
21867
|
} catch {
|
|
21628
21868
|
return { ok: false, status: 500, error: `Target config is malformed: ${path}` };
|
|
21629
21869
|
}
|
|
@@ -21848,11 +22088,11 @@ var init_toolkit_sync = __esm({
|
|
|
21848
22088
|
});
|
|
21849
22089
|
|
|
21850
22090
|
// ../engine/dist/core/which.js
|
|
21851
|
-
import { existsSync as existsSync44, statSync as
|
|
21852
|
-
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";
|
|
21853
22093
|
function executable(p) {
|
|
21854
22094
|
try {
|
|
21855
|
-
if (!
|
|
22095
|
+
if (!statSync41(p).isFile())
|
|
21856
22096
|
return false;
|
|
21857
22097
|
} catch {
|
|
21858
22098
|
return false;
|
|
@@ -21888,7 +22128,7 @@ function resolveOnPath(name) {
|
|
|
21888
22128
|
if (!dir)
|
|
21889
22129
|
continue;
|
|
21890
22130
|
for (const c of candidates(name)) {
|
|
21891
|
-
const full =
|
|
22131
|
+
const full = join47(dir, c);
|
|
21892
22132
|
if (existsSync44(full) && executable(full))
|
|
21893
22133
|
return full;
|
|
21894
22134
|
}
|
|
@@ -21915,11 +22155,11 @@ __export(toolkit_pull_exports, {
|
|
|
21915
22155
|
platformRefusal: () => platformRefusal,
|
|
21916
22156
|
portableCommand: () => portableCommand
|
|
21917
22157
|
});
|
|
21918
|
-
import { existsSync as existsSync45, mkdirSync as mkdirSync13, statSync as
|
|
21919
|
-
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";
|
|
21920
22160
|
function isExecutableFile(p) {
|
|
21921
22161
|
try {
|
|
21922
|
-
return
|
|
22162
|
+
return statSync42(p).isFile();
|
|
21923
22163
|
} catch {
|
|
21924
22164
|
return false;
|
|
21925
22165
|
}
|
|
@@ -22086,8 +22326,8 @@ function executePull(rows, opts = {}) {
|
|
|
22086
22326
|
const outcomes = [];
|
|
22087
22327
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
22088
22328
|
for (const tool of tools) {
|
|
22089
|
-
const dir =
|
|
22090
|
-
const file =
|
|
22329
|
+
const dir = join48(skillsDirFor(tool), name);
|
|
22330
|
+
const file = join48(dir, "SKILL.md");
|
|
22091
22331
|
if (existsSync45(file)) {
|
|
22092
22332
|
outcomes.push({ type: "skill", name, tool, status: "present" });
|
|
22093
22333
|
continue;
|
|
@@ -22420,11 +22660,16 @@ async function repairAll(opts = {}) {
|
|
|
22420
22660
|
scanned++;
|
|
22421
22661
|
if (opts.verbose && scanned % 50 === 0) log6(`checked ${scanned}/${ids.length}\u2026`);
|
|
22422
22662
|
const arch = await fetchJson(`${primary.url}/api/conversations/${id}/raw-archive?count=1`, primary.token);
|
|
22423
|
-
const
|
|
22424
|
-
if (
|
|
22425
|
-
|
|
22426
|
-
|
|
22427
|
-
|
|
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
|
+
}
|
|
22428
22673
|
const r = await repairSession(id, { dryRun: !opts.apply, verbose: opts.verbose, server: opts.server });
|
|
22429
22674
|
if (r.status === "already-full") continue;
|
|
22430
22675
|
candidates2.push(r);
|
|
@@ -22452,8 +22697,8 @@ __export(shadow_prune_exports, {
|
|
|
22452
22697
|
DEFAULT_MAX_TOTAL_BYTES: () => DEFAULT_MAX_TOTAL_BYTES,
|
|
22453
22698
|
pruneShadow: () => pruneShadow
|
|
22454
22699
|
});
|
|
22455
|
-
import { readdirSync as readdirSync32, statSync as
|
|
22456
|
-
import { join as
|
|
22700
|
+
import { readdirSync as readdirSync32, statSync as statSync45, unlinkSync as unlinkSync3 } from "fs";
|
|
22701
|
+
import { join as join51 } from "path";
|
|
22457
22702
|
function listShadows(isFullyAcked) {
|
|
22458
22703
|
const out = [];
|
|
22459
22704
|
const root = shadowRoot();
|
|
@@ -22464,7 +22709,7 @@ function listShadows(isFullyAcked) {
|
|
|
22464
22709
|
return out;
|
|
22465
22710
|
}
|
|
22466
22711
|
for (const tool of tools) {
|
|
22467
|
-
const dir =
|
|
22712
|
+
const dir = join51(root, tool);
|
|
22468
22713
|
let names;
|
|
22469
22714
|
try {
|
|
22470
22715
|
names = readdirSync32(dir);
|
|
@@ -22474,10 +22719,10 @@ function listShadows(isFullyAcked) {
|
|
|
22474
22719
|
for (const name of names) {
|
|
22475
22720
|
if (!name.endsWith(".gz"))
|
|
22476
22721
|
continue;
|
|
22477
|
-
const path =
|
|
22722
|
+
const path = join51(dir, name);
|
|
22478
22723
|
let st;
|
|
22479
22724
|
try {
|
|
22480
|
-
st =
|
|
22725
|
+
st = statSync45(path);
|
|
22481
22726
|
} catch {
|
|
22482
22727
|
continue;
|
|
22483
22728
|
}
|
|
@@ -22592,9 +22837,9 @@ var init_code_intel = __esm({
|
|
|
22592
22837
|
});
|
|
22593
22838
|
|
|
22594
22839
|
// ../engine/dist/core/companions.js
|
|
22595
|
-
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";
|
|
22596
22841
|
import { homedir as homedir19 } from "node:os";
|
|
22597
|
-
import { join as
|
|
22842
|
+
import { join as join52 } from "node:path";
|
|
22598
22843
|
import { execSync as execSync3 } from "node:child_process";
|
|
22599
22844
|
import { createHash as createHash13 } from "node:crypto";
|
|
22600
22845
|
function expectedCodeindexSha256(artifact) {
|
|
@@ -22643,7 +22888,7 @@ function checkCodeindexStatus() {
|
|
|
22643
22888
|
status.installed = true;
|
|
22644
22889
|
status.path = foundPath;
|
|
22645
22890
|
try {
|
|
22646
|
-
status.size =
|
|
22891
|
+
status.size = statSync46(foundPath).size;
|
|
22647
22892
|
} catch {
|
|
22648
22893
|
}
|
|
22649
22894
|
try {
|
|
@@ -22669,7 +22914,7 @@ async function downloadArtifact(artifact, dest) {
|
|
|
22669
22914
|
throw new Error(`Download failed: ${res.status} ${res.statusText}`);
|
|
22670
22915
|
if (!res.body)
|
|
22671
22916
|
throw new Error("Download returned empty body");
|
|
22672
|
-
const file =
|
|
22917
|
+
const file = createWriteStream2(dest);
|
|
22673
22918
|
await new Promise((resolve3, reject) => {
|
|
22674
22919
|
const reader = res.body.getReader();
|
|
22675
22920
|
const pump = async () => {
|
|
@@ -22704,7 +22949,7 @@ async function installCodeindex(opts = {}) {
|
|
|
22704
22949
|
if (!expected) {
|
|
22705
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.`);
|
|
22706
22951
|
}
|
|
22707
|
-
const actual = createHash13("sha256").update(
|
|
22952
|
+
const actual = createHash13("sha256").update(readFileSync43(tmpPath)).digest("hex");
|
|
22708
22953
|
if (actual !== expected) {
|
|
22709
22954
|
throw new Error(`Checksum mismatch for ${status.artifactName}.
|
|
22710
22955
|
expected ${expected}
|
|
@@ -22738,9 +22983,9 @@ var init_companions = __esm({
|
|
|
22738
22983
|
"x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
|
|
22739
22984
|
"aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
|
|
22740
22985
|
};
|
|
22741
|
-
CODEINDEX_INSTALL_DIR =
|
|
22986
|
+
CODEINDEX_INSTALL_DIR = join52(homedir19(), ".local", "bin");
|
|
22742
22987
|
CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
|
|
22743
|
-
CODEINDEX_BIN_PATH =
|
|
22988
|
+
CODEINDEX_BIN_PATH = join52(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
|
|
22744
22989
|
}
|
|
22745
22990
|
});
|
|
22746
22991
|
|
|
@@ -22855,8 +23100,8 @@ __export(collector_exports, {
|
|
|
22855
23100
|
});
|
|
22856
23101
|
import { spawn as spawn2 } from "node:child_process";
|
|
22857
23102
|
import { execSync as execSync4 } from "node:child_process";
|
|
22858
|
-
import { readFileSync as
|
|
22859
|
-
import { join as
|
|
23103
|
+
import { readFileSync as readFileSync44 } from "node:fs";
|
|
23104
|
+
import { join as join53, basename as basename24 } from "node:path";
|
|
22860
23105
|
async function resolveCodeindexBin(autoInstall = true) {
|
|
22861
23106
|
let st = checkCodeindexStatus();
|
|
22862
23107
|
if (!st.installed && autoInstall)
|
|
@@ -23038,7 +23283,7 @@ async function collectCode(opts) {
|
|
|
23038
23283
|
}
|
|
23039
23284
|
const complexity = (r) => {
|
|
23040
23285
|
try {
|
|
23041
|
-
const txt =
|
|
23286
|
+
const txt = readFileSync44(join53(ws, r), "utf8");
|
|
23042
23287
|
if (txt.length > 2e6)
|
|
23043
23288
|
return 1;
|
|
23044
23289
|
const m = txt.match(CF_RE);
|
|
@@ -23802,15 +24047,15 @@ __export(service_installer_exports, {
|
|
|
23802
24047
|
uninstallService: () => uninstallService
|
|
23803
24048
|
});
|
|
23804
24049
|
import { execSync as execSync5 } from "child_process";
|
|
23805
|
-
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";
|
|
23806
24051
|
import { homedir as homedir20 } from "os";
|
|
23807
|
-
import { join as
|
|
24052
|
+
import { join as join54 } from "path";
|
|
23808
24053
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23809
24054
|
function resolveDaemonPaths() {
|
|
23810
24055
|
const watchJs = fileURLToPath5(new URL("./watch.js", import.meta.url));
|
|
23811
24056
|
const node = process.execPath;
|
|
23812
|
-
const dataDir =
|
|
23813
|
-
const logFile =
|
|
24057
|
+
const dataDir = join54(homedir20(), ".chat-recall");
|
|
24058
|
+
const logFile = join54(dataDir, "watch.log");
|
|
23814
24059
|
return { watchJs, node, logFile, dataDir };
|
|
23815
24060
|
}
|
|
23816
24061
|
function tryCmd(cmd) {
|
|
@@ -23837,12 +24082,12 @@ function refreshServiceDefinition() {
|
|
|
23837
24082
|
if (process.platform !== "linux") return false;
|
|
23838
24083
|
try {
|
|
23839
24084
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
23840
|
-
const unitPath =
|
|
24085
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
23841
24086
|
if (!existsSync49(unitPath)) return false;
|
|
23842
|
-
const current =
|
|
24087
|
+
const current = readFileSync45(unitPath, "utf8");
|
|
23843
24088
|
if (!current.includes(watchJs)) return false;
|
|
23844
24089
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
23845
|
-
if (
|
|
24090
|
+
if (readFileSync45(unitPath, "utf8") === wanted) return false;
|
|
23846
24091
|
writeFileSync16(unitPath, wanted);
|
|
23847
24092
|
execSync5("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
23848
24093
|
return true;
|
|
@@ -23868,8 +24113,8 @@ function installService() {
|
|
|
23868
24113
|
);
|
|
23869
24114
|
}
|
|
23870
24115
|
function installSystemd(watchJs, node, logFile) {
|
|
23871
|
-
const unitDir =
|
|
23872
|
-
const unitPath =
|
|
24116
|
+
const unitDir = join54(homedir20(), ".config", "systemd", "user");
|
|
24117
|
+
const unitPath = join54(unitDir, "chat-recall-watch.service");
|
|
23873
24118
|
const unit = renderSystemdUnit(watchJs, node, logFile);
|
|
23874
24119
|
mkdirSync17(unitDir, { recursive: true });
|
|
23875
24120
|
writeFileSync16(unitPath, unit);
|
|
@@ -23948,8 +24193,8 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23948
24193
|
}
|
|
23949
24194
|
function installLaunchd(watchJs, node, logFile) {
|
|
23950
24195
|
const label = "com.chat-recall.watch";
|
|
23951
|
-
const plistDir =
|
|
23952
|
-
const plistPath =
|
|
24196
|
+
const plistDir = join54(homedir20(), "Library", "LaunchAgents");
|
|
24197
|
+
const plistPath = join54(plistDir, `${label}.plist`);
|
|
23953
24198
|
const plist = renderLaunchdPlist(watchJs, node, logFile, label);
|
|
23954
24199
|
mkdirSync17(plistDir, { recursive: true });
|
|
23955
24200
|
writeFileSync16(plistPath, plist);
|
|
@@ -24005,9 +24250,9 @@ function uninstallService() {
|
|
|
24005
24250
|
removed = true;
|
|
24006
24251
|
} catch {
|
|
24007
24252
|
}
|
|
24008
|
-
const unitPath =
|
|
24253
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
24009
24254
|
if (existsSync49(unitPath)) {
|
|
24010
|
-
|
|
24255
|
+
rmSync8(unitPath, { force: true });
|
|
24011
24256
|
removed = true;
|
|
24012
24257
|
}
|
|
24013
24258
|
try {
|
|
@@ -24017,14 +24262,14 @@ function uninstallService() {
|
|
|
24017
24262
|
return removed;
|
|
24018
24263
|
}
|
|
24019
24264
|
if (process.platform === "darwin") {
|
|
24020
|
-
const plistPath =
|
|
24265
|
+
const plistPath = join54(homedir20(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
|
|
24021
24266
|
try {
|
|
24022
24267
|
execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
24023
24268
|
} catch {
|
|
24024
24269
|
}
|
|
24025
24270
|
let removed = false;
|
|
24026
24271
|
if (existsSync49(plistPath)) {
|
|
24027
|
-
|
|
24272
|
+
rmSync8(plistPath, { force: true });
|
|
24028
24273
|
removed = true;
|
|
24029
24274
|
}
|
|
24030
24275
|
return removed;
|
|
@@ -24068,7 +24313,7 @@ init_settings();
|
|
|
24068
24313
|
init_sync_client();
|
|
24069
24314
|
init_http();
|
|
24070
24315
|
import chokidar from "chokidar";
|
|
24071
|
-
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";
|
|
24072
24317
|
import { homedir as homedir21 } from "os";
|
|
24073
24318
|
|
|
24074
24319
|
// src/intent-drain.ts
|
|
@@ -24081,13 +24326,13 @@ init_codex2();
|
|
|
24081
24326
|
init_cursor();
|
|
24082
24327
|
init_opencode();
|
|
24083
24328
|
init_agy();
|
|
24084
|
-
import { existsSync as existsSync46, readFileSync as
|
|
24085
|
-
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";
|
|
24086
24331
|
|
|
24087
24332
|
// src/project-tasks.ts
|
|
24088
24333
|
init_http();
|
|
24089
|
-
import { existsSync as existsSync43, readFileSync as
|
|
24090
|
-
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";
|
|
24091
24336
|
import { homedir as homedir18 } from "node:os";
|
|
24092
24337
|
|
|
24093
24338
|
// ../engine/dist/core/secret-task-status.js
|
|
@@ -24156,11 +24401,11 @@ function parseTaskFile(content) {
|
|
|
24156
24401
|
return out;
|
|
24157
24402
|
}
|
|
24158
24403
|
function ledgerPath2() {
|
|
24159
|
-
return
|
|
24404
|
+
return join46(homedir18(), ".chat-recall", "project-tasks-ledger.json");
|
|
24160
24405
|
}
|
|
24161
24406
|
function readLedger() {
|
|
24162
24407
|
try {
|
|
24163
|
-
return JSON.parse(
|
|
24408
|
+
return JSON.parse(readFileSync39(ledgerPath2(), "utf8"));
|
|
24164
24409
|
} catch {
|
|
24165
24410
|
return {};
|
|
24166
24411
|
}
|
|
@@ -24193,18 +24438,18 @@ async function pushProjectTaskStatuses(base3, authHeaders, opts = {}) {
|
|
|
24193
24438
|
continue;
|
|
24194
24439
|
}
|
|
24195
24440
|
for (const project of projects) {
|
|
24196
|
-
const file =
|
|
24441
|
+
const file = join46(project, fk.filename);
|
|
24197
24442
|
if (!existsSync43(file)) continue;
|
|
24198
24443
|
let mtime;
|
|
24199
24444
|
try {
|
|
24200
|
-
mtime =
|
|
24445
|
+
mtime = statSync40(file).mtimeMs;
|
|
24201
24446
|
} catch {
|
|
24202
24447
|
continue;
|
|
24203
24448
|
}
|
|
24204
24449
|
if (ledger[file] === mtime) continue;
|
|
24205
24450
|
let changed;
|
|
24206
24451
|
try {
|
|
24207
|
-
changed = parseTaskFile(
|
|
24452
|
+
changed = parseTaskFile(readFileSync39(file, "utf8")).filter((t) => t.kind === fk.kind);
|
|
24208
24453
|
} catch {
|
|
24209
24454
|
continue;
|
|
24210
24455
|
}
|
|
@@ -24255,16 +24500,16 @@ function instructionTargets(rootPath, isGlobal) {
|
|
|
24255
24500
|
const tools = installed.length ? installed : [INSTRUCTION_TOOLS[0]];
|
|
24256
24501
|
if (isGlobal) return [...new Set(tools.map((t) => instructionsPath(t.id)))];
|
|
24257
24502
|
if (!rootPath) return [];
|
|
24258
|
-
const present = INSTRUCTION_FILENAMES.map((f) =>
|
|
24503
|
+
const present = INSTRUCTION_FILENAMES.map((f) => join49(rootPath, f)).filter((p) => existsSync46(p));
|
|
24259
24504
|
if (present.length) return present;
|
|
24260
|
-
return [...new Set(tools.map((t) =>
|
|
24505
|
+
return [...new Set(tools.map((t) => join49(rootPath, instructionsFilename(t.id))))];
|
|
24261
24506
|
}
|
|
24262
24507
|
function applyCodeRecommendation(intent) {
|
|
24263
24508
|
try {
|
|
24264
24509
|
const meta = JSON.parse(intent.name || "{}");
|
|
24265
24510
|
if (intent.artifact_type === "write_tasks_file") {
|
|
24266
24511
|
if (!meta.rootPath || !meta.content) return { status: "error", result: JSON.stringify({ error: "missing rootPath or content" }) };
|
|
24267
|
-
const file =
|
|
24512
|
+
const file = join49(meta.rootPath, meta.filename || "CODE_TASKS.md");
|
|
24268
24513
|
writeFileSync13(file, meta.content);
|
|
24269
24514
|
return { status: "done", result: JSON.stringify({ wrote: file }) };
|
|
24270
24515
|
}
|
|
@@ -24283,7 +24528,7 @@ function applyCodeRecommendation(intent) {
|
|
|
24283
24528
|
mkdirSync14(dir, { recursive: true });
|
|
24284
24529
|
} catch {
|
|
24285
24530
|
}
|
|
24286
|
-
const existing = existsSync46(file) ?
|
|
24531
|
+
const existing = existsSync46(file) ? readFileSync40(file, "utf8") : "";
|
|
24287
24532
|
if (existing.includes(text)) {
|
|
24288
24533
|
skipped.push(file);
|
|
24289
24534
|
continue;
|
|
@@ -24382,10 +24627,10 @@ async function runIntent(intent, ctx) {
|
|
|
24382
24627
|
var ownVersion2 = "0.0.0";
|
|
24383
24628
|
try {
|
|
24384
24629
|
const dir = dirname23(fileURLToPath4(import.meta.url));
|
|
24385
|
-
ownVersion2 = JSON.parse(
|
|
24630
|
+
ownVersion2 = JSON.parse(readFileSync40(join49(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
24386
24631
|
} catch {
|
|
24387
24632
|
try {
|
|
24388
|
-
if (true) ownVersion2 = "0.7.
|
|
24633
|
+
if (true) ownVersion2 = "0.7.18";
|
|
24389
24634
|
} catch {
|
|
24390
24635
|
}
|
|
24391
24636
|
}
|
|
@@ -24450,14 +24695,14 @@ init_auto_update();
|
|
|
24450
24695
|
|
|
24451
24696
|
// src/code-index-cursor.ts
|
|
24452
24697
|
init_paths();
|
|
24453
|
-
import { readFileSync as
|
|
24698
|
+
import { readFileSync as readFileSync41, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15, statSync as statSync43 } from "fs";
|
|
24454
24699
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
24455
24700
|
import { createHash as createHash10 } from "crypto";
|
|
24456
|
-
import { join as
|
|
24457
|
-
var cursorPath = () =>
|
|
24701
|
+
import { join as join50, dirname as dirname24 } from "path";
|
|
24702
|
+
var cursorPath = () => join50(getDataDir(), "code-index-cursor.json");
|
|
24458
24703
|
function readCursor() {
|
|
24459
24704
|
try {
|
|
24460
|
-
const raw = JSON.parse(
|
|
24705
|
+
const raw = JSON.parse(readFileSync41(cursorPath(), "utf-8"));
|
|
24461
24706
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
24462
24707
|
const out = {};
|
|
24463
24708
|
for (const [k, v] of Object.entries(raw)) {
|
|
@@ -24501,7 +24746,7 @@ function workspaceFingerprint(workspace, collectorVersion) {
|
|
|
24501
24746
|
const rel = entry.slice(3);
|
|
24502
24747
|
let stamp2 = "gone";
|
|
24503
24748
|
try {
|
|
24504
|
-
const s =
|
|
24749
|
+
const s = statSync43(join50(workspace, rel));
|
|
24505
24750
|
stamp2 = `${s.size}:${Math.floor(s.mtimeMs)}`;
|
|
24506
24751
|
} catch {
|
|
24507
24752
|
}
|
|
@@ -24637,13 +24882,13 @@ init_telemetry();
|
|
|
24637
24882
|
|
|
24638
24883
|
// src/self-restart.ts
|
|
24639
24884
|
import { spawn } from "child_process";
|
|
24640
|
-
import { readFileSync as
|
|
24885
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
24641
24886
|
import { createHash as createHash11 } from "crypto";
|
|
24642
24887
|
var EXIT_CODE_CODE_CHANGED = 75;
|
|
24643
24888
|
function codeFingerprint(entry = process.argv[1]) {
|
|
24644
24889
|
if (!entry) return null;
|
|
24645
24890
|
try {
|
|
24646
|
-
const buf =
|
|
24891
|
+
const buf = readFileSync42(entry);
|
|
24647
24892
|
return {
|
|
24648
24893
|
path: entry,
|
|
24649
24894
|
size: buf.byteLength,
|
|
@@ -24710,11 +24955,11 @@ function checkSelfRestart(opts) {
|
|
|
24710
24955
|
}
|
|
24711
24956
|
|
|
24712
24957
|
// src/log-rotate.ts
|
|
24713
|
-
import { statSync as
|
|
24958
|
+
import { statSync as statSync44, copyFileSync as copyFileSync3, truncateSync } from "fs";
|
|
24714
24959
|
var LOG_MAX_BYTES = 32 * 1024 * 1024;
|
|
24715
24960
|
function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
24716
24961
|
try {
|
|
24717
|
-
const size =
|
|
24962
|
+
const size = statSync44(logPath).size;
|
|
24718
24963
|
if (size < maxBytes) return { rotated: false, sizeBefore: 0 };
|
|
24719
24964
|
copyFileSync3(logPath, `${logPath}.1`);
|
|
24720
24965
|
truncateSync(logPath, 0);
|
|
@@ -24769,8 +25014,8 @@ async function runCollectorMigration(opts) {
|
|
|
24769
25014
|
// auto-indexer/indexer.ts
|
|
24770
25015
|
init_sync_ledger();
|
|
24771
25016
|
init_collector_health();
|
|
24772
|
-
import { existsSync as existsSync50, readFileSync as
|
|
24773
|
-
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";
|
|
24774
25019
|
var DEBOUNCE_MS = 5e3;
|
|
24775
25020
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
24776
25021
|
var TASKS_DIR = claudeBackend.tasksDir();
|
|
@@ -24779,8 +25024,8 @@ var DIARY_DIR = getDiaryDir();
|
|
|
24779
25024
|
var CODEX_SESSIONS_DIR = codexBackend.sessionsDir();
|
|
24780
25025
|
var OPENCODE_DB_PATH = opencodeBackend.dbPath();
|
|
24781
25026
|
var OPENCODE_DB_DIR = dirname25(OPENCODE_DB_PATH);
|
|
24782
|
-
var CURRENT_RESUME_PATH =
|
|
24783
|
-
var LAST_CLEANUP_PATH =
|
|
25027
|
+
var CURRENT_RESUME_PATH = join55(claudeBackend.homeDir(), "current-resume");
|
|
25028
|
+
var LAST_CLEANUP_PATH = join55(claudeBackend.homeDir(), ".last-cleanup");
|
|
24784
25029
|
var debounceTimer = null;
|
|
24785
25030
|
var ticks = new TickQueue({
|
|
24786
25031
|
onError: (kind, err) => daemonLog.error(`${kind} tick failed: ${err instanceof Error ? err.message : err}`)
|
|
@@ -24829,7 +25074,7 @@ var lastResumeAt = /* @__PURE__ */ new Map();
|
|
|
24829
25074
|
var RESUME_REARM_MS = 6e4;
|
|
24830
25075
|
async function onResumeSignal(path) {
|
|
24831
25076
|
try {
|
|
24832
|
-
const txt =
|
|
25077
|
+
const txt = readFileSync46(path, "utf-8");
|
|
24833
25078
|
const m = /--resume\s+([0-9a-fA-F-]{36})/.exec(txt);
|
|
24834
25079
|
if (!m) return;
|
|
24835
25080
|
const id = m[1];
|
|
@@ -24875,7 +25120,7 @@ var CLAUDE_SESSION_ROOTS = claudeProjectDirs();
|
|
|
24875
25120
|
var sessionWatcher = watchWithFallback("sessions", CLAUDE_SESSION_ROOTS.map((root) => `${root}/**/*.jsonl`), {
|
|
24876
25121
|
ignored: (p, stats) => {
|
|
24877
25122
|
if (/agent-/.test(p) || /^\./.test(basename25(p))) return true;
|
|
24878
|
-
const st = stats ??
|
|
25123
|
+
const st = stats ?? statSync47(p, { throwIfNoEntry: false });
|
|
24879
25124
|
if (!st || st.isDirectory()) return false;
|
|
24880
25125
|
return st.mtimeMs < Date.now() - WATCH_WINDOW_MS;
|
|
24881
25126
|
},
|
|
@@ -25017,7 +25262,7 @@ if (BOOT_CODE) {
|
|
|
25017
25262
|
daemonLog.info(`running bundle ${BOOT_CODE.path} (${BOOT_CODE.size} bytes)`);
|
|
25018
25263
|
}
|
|
25019
25264
|
{
|
|
25020
|
-
const r = rotateLogIfLarge(
|
|
25265
|
+
const r = rotateLogIfLarge(join55(getDataDir(), "watch.log"));
|
|
25021
25266
|
if (r.rotated) {
|
|
25022
25267
|
daemonLog.info(`rotated watch.log at ${(r.sizeBefore / 1048576).toFixed(0)}MB \u2192 watch.log.1 (copy+truncate; the path is preserved)`);
|
|
25023
25268
|
}
|
|
@@ -25203,7 +25448,7 @@ function isCodeWorkspace(p) {
|
|
|
25203
25448
|
}
|
|
25204
25449
|
return WORKSPACE_MARKERS.some((m) => {
|
|
25205
25450
|
try {
|
|
25206
|
-
return existsSync50(
|
|
25451
|
+
return existsSync50(join55(p, m));
|
|
25207
25452
|
} catch {
|
|
25208
25453
|
return false;
|
|
25209
25454
|
}
|