chat-recall 0.7.17 → 0.7.19
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/README.md +2 -2
- package/dist/cli.js +1402 -538
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +136 -40
- package/dist/mcp-relay.js.map +1 -1
- package/dist/mcp.js +1160 -290
- 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 +617 -31
- package/dist/sync-client.d.ts +8 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +107 -12
- package/dist/sync-client.js.map +1 -1
- package/dist/sync-ledger.d.ts +37 -1
- package/dist/sync-ledger.d.ts.map +1 -1
- package/dist/sync-ledger.js +50 -1
- package/dist/sync-ledger.js.map +1 -1
- package/dist/watch.js +1221 -348
- package/package.json +1 -1
package/dist/watch.js
CHANGED
|
@@ -152,6 +152,8 @@ function declaredOrigin(value) {
|
|
|
152
152
|
function userRecordOrigin(obj, text) {
|
|
153
153
|
if (obj.isSidechain === true)
|
|
154
154
|
return "subagent";
|
|
155
|
+
if (obj.isCompactSummary === true)
|
|
156
|
+
return "compact-summary";
|
|
155
157
|
const declared = declaredOrigin(obj.origin);
|
|
156
158
|
if (declared && declared !== "human")
|
|
157
159
|
return declared;
|
|
@@ -2233,7 +2235,7 @@ var require_thread_stream = __commonJS({
|
|
|
2233
2235
|
var { version } = require_package();
|
|
2234
2236
|
var { EventEmitter } = __require("events");
|
|
2235
2237
|
var { Worker: Worker2 } = __require("worker_threads");
|
|
2236
|
-
var { join:
|
|
2238
|
+
var { join: join56 } = __require("path");
|
|
2237
2239
|
var { pathToFileURL } = __require("url");
|
|
2238
2240
|
var { wait } = require_wait();
|
|
2239
2241
|
var {
|
|
@@ -2276,7 +2278,7 @@ var require_thread_stream = __commonJS({
|
|
|
2276
2278
|
function createWorker(stream, opts) {
|
|
2277
2279
|
const { filename, workerData } = opts;
|
|
2278
2280
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
2279
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
2281
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join56(__dirname, "lib", "worker.js");
|
|
2280
2282
|
const worker = new Worker2(toExecute, {
|
|
2281
2283
|
...opts.workerOpts,
|
|
2282
2284
|
trackUnmanagedFds: false,
|
|
@@ -2679,7 +2681,7 @@ var require_transport = __commonJS({
|
|
|
2679
2681
|
"use strict";
|
|
2680
2682
|
var { createRequire: createRequire3 } = __require("module");
|
|
2681
2683
|
var getCallers = require_caller();
|
|
2682
|
-
var { join:
|
|
2684
|
+
var { join: join56, isAbsolute: isAbsolute4, sep: sep5 } = __require("node:path");
|
|
2683
2685
|
var sleep = require_atomic_sleep();
|
|
2684
2686
|
var onExit = require_on_exit_leak_free();
|
|
2685
2687
|
var ThreadStream = require_thread_stream();
|
|
@@ -2742,7 +2744,7 @@ var require_transport = __commonJS({
|
|
|
2742
2744
|
throw new Error("only one of target or targets can be specified");
|
|
2743
2745
|
}
|
|
2744
2746
|
if (targets) {
|
|
2745
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2747
|
+
target = bundlerOverrides["pino-worker"] || join56(__dirname, "worker.js");
|
|
2746
2748
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
2747
2749
|
return {
|
|
2748
2750
|
...dest,
|
|
@@ -2760,7 +2762,7 @@ var require_transport = __commonJS({
|
|
|
2760
2762
|
});
|
|
2761
2763
|
});
|
|
2762
2764
|
} else if (pipeline) {
|
|
2763
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
2765
|
+
target = bundlerOverrides["pino-worker"] || join56(__dirname, "worker.js");
|
|
2764
2766
|
options.pipelines = [pipeline.map((dest) => {
|
|
2765
2767
|
return {
|
|
2766
2768
|
...dest,
|
|
@@ -2782,7 +2784,7 @@ var require_transport = __commonJS({
|
|
|
2782
2784
|
return origin;
|
|
2783
2785
|
}
|
|
2784
2786
|
if (origin === "pino/file") {
|
|
2785
|
-
return
|
|
2787
|
+
return join56(__dirname, "..", "file.js");
|
|
2786
2788
|
}
|
|
2787
2789
|
let fixTarget2;
|
|
2788
2790
|
for (const filePath of callers) {
|
|
@@ -3771,7 +3773,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3771
3773
|
return circularValue;
|
|
3772
3774
|
}
|
|
3773
3775
|
let res = "";
|
|
3774
|
-
let
|
|
3776
|
+
let join56 = ",";
|
|
3775
3777
|
const originalIndentation = indentation;
|
|
3776
3778
|
if (Array.isArray(value)) {
|
|
3777
3779
|
if (value.length === 0) {
|
|
@@ -3785,7 +3787,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
3785
3787
|
indentation += spacer;
|
|
3786
3788
|
res += `
|
|
3787
3789
|
${indentation}`;
|
|
3788
|
-
|
|
3790
|
+
join56 = `,
|
|
3789
3791
|
${indentation}`;
|
|
3790
3792
|
}
|
|
3791
3793
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3793,13 +3795,13 @@ ${indentation}`;
|
|
|
3793
3795
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3794
3796
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3795
3797
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3796
|
-
res +=
|
|
3798
|
+
res += join56;
|
|
3797
3799
|
}
|
|
3798
3800
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
3799
3801
|
res += tmp !== void 0 ? tmp : "null";
|
|
3800
3802
|
if (value.length - 1 > maximumBreadth) {
|
|
3801
3803
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3802
|
-
res += `${
|
|
3804
|
+
res += `${join56}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3803
3805
|
}
|
|
3804
3806
|
if (spacer !== "") {
|
|
3805
3807
|
res += `
|
|
@@ -3820,7 +3822,7 @@ ${originalIndentation}`;
|
|
|
3820
3822
|
let separator = "";
|
|
3821
3823
|
if (spacer !== "") {
|
|
3822
3824
|
indentation += spacer;
|
|
3823
|
-
|
|
3825
|
+
join56 = `,
|
|
3824
3826
|
${indentation}`;
|
|
3825
3827
|
whitespace = " ";
|
|
3826
3828
|
}
|
|
@@ -3834,13 +3836,13 @@ ${indentation}`;
|
|
|
3834
3836
|
const tmp = stringifyFnReplacer(key3, value, stack, replacer, spacer, indentation);
|
|
3835
3837
|
if (tmp !== void 0) {
|
|
3836
3838
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3837
|
-
separator =
|
|
3839
|
+
separator = join56;
|
|
3838
3840
|
}
|
|
3839
3841
|
}
|
|
3840
3842
|
if (keyLength > maximumBreadth) {
|
|
3841
3843
|
const removedKeys = keyLength - maximumBreadth;
|
|
3842
3844
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
3843
|
-
separator =
|
|
3845
|
+
separator = join56;
|
|
3844
3846
|
}
|
|
3845
3847
|
if (spacer !== "" && separator.length > 1) {
|
|
3846
3848
|
res = `
|
|
@@ -3881,7 +3883,7 @@ ${originalIndentation}`;
|
|
|
3881
3883
|
}
|
|
3882
3884
|
const originalIndentation = indentation;
|
|
3883
3885
|
let res = "";
|
|
3884
|
-
let
|
|
3886
|
+
let join56 = ",";
|
|
3885
3887
|
if (Array.isArray(value)) {
|
|
3886
3888
|
if (value.length === 0) {
|
|
3887
3889
|
return "[]";
|
|
@@ -3894,7 +3896,7 @@ ${originalIndentation}`;
|
|
|
3894
3896
|
indentation += spacer;
|
|
3895
3897
|
res += `
|
|
3896
3898
|
${indentation}`;
|
|
3897
|
-
|
|
3899
|
+
join56 = `,
|
|
3898
3900
|
${indentation}`;
|
|
3899
3901
|
}
|
|
3900
3902
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -3902,13 +3904,13 @@ ${indentation}`;
|
|
|
3902
3904
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3903
3905
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3904
3906
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
3905
|
-
res +=
|
|
3907
|
+
res += join56;
|
|
3906
3908
|
}
|
|
3907
3909
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
3908
3910
|
res += tmp !== void 0 ? tmp : "null";
|
|
3909
3911
|
if (value.length - 1 > maximumBreadth) {
|
|
3910
3912
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
3911
|
-
res += `${
|
|
3913
|
+
res += `${join56}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
3912
3914
|
}
|
|
3913
3915
|
if (spacer !== "") {
|
|
3914
3916
|
res += `
|
|
@@ -3921,7 +3923,7 @@ ${originalIndentation}`;
|
|
|
3921
3923
|
let whitespace = "";
|
|
3922
3924
|
if (spacer !== "") {
|
|
3923
3925
|
indentation += spacer;
|
|
3924
|
-
|
|
3926
|
+
join56 = `,
|
|
3925
3927
|
${indentation}`;
|
|
3926
3928
|
whitespace = " ";
|
|
3927
3929
|
}
|
|
@@ -3930,7 +3932,7 @@ ${indentation}`;
|
|
|
3930
3932
|
const tmp = stringifyArrayReplacer(key3, value[key3], stack, replacer, spacer, indentation);
|
|
3931
3933
|
if (tmp !== void 0) {
|
|
3932
3934
|
res += `${separator}${strEscape(key3)}:${whitespace}${tmp}`;
|
|
3933
|
-
separator =
|
|
3935
|
+
separator = join56;
|
|
3934
3936
|
}
|
|
3935
3937
|
}
|
|
3936
3938
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -3988,20 +3990,20 @@ ${originalIndentation}`;
|
|
|
3988
3990
|
indentation += spacer;
|
|
3989
3991
|
let res2 = `
|
|
3990
3992
|
${indentation}`;
|
|
3991
|
-
const
|
|
3993
|
+
const join57 = `,
|
|
3992
3994
|
${indentation}`;
|
|
3993
3995
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
3994
3996
|
let i = 0;
|
|
3995
3997
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
3996
3998
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
3997
3999
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
3998
|
-
res2 +=
|
|
4000
|
+
res2 += join57;
|
|
3999
4001
|
}
|
|
4000
4002
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
4001
4003
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
4002
4004
|
if (value.length - 1 > maximumBreadth) {
|
|
4003
4005
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
4004
|
-
res2 += `${
|
|
4006
|
+
res2 += `${join57}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
4005
4007
|
}
|
|
4006
4008
|
res2 += `
|
|
4007
4009
|
${originalIndentation}`;
|
|
@@ -4017,16 +4019,16 @@ ${originalIndentation}`;
|
|
|
4017
4019
|
return '"[Object]"';
|
|
4018
4020
|
}
|
|
4019
4021
|
indentation += spacer;
|
|
4020
|
-
const
|
|
4022
|
+
const join56 = `,
|
|
4021
4023
|
${indentation}`;
|
|
4022
4024
|
let res = "";
|
|
4023
4025
|
let separator = "";
|
|
4024
4026
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
4025
4027
|
if (isTypedArrayWithEntries(value)) {
|
|
4026
|
-
res += stringifyTypedArray(value,
|
|
4028
|
+
res += stringifyTypedArray(value, join56, maximumBreadth);
|
|
4027
4029
|
keys = keys.slice(value.length);
|
|
4028
4030
|
maximumPropertiesToStringify -= value.length;
|
|
4029
|
-
separator =
|
|
4031
|
+
separator = join56;
|
|
4030
4032
|
}
|
|
4031
4033
|
if (deterministic) {
|
|
4032
4034
|
keys = sort(keys, comparator);
|
|
@@ -4037,13 +4039,13 @@ ${indentation}`;
|
|
|
4037
4039
|
const tmp = stringifyIndent(key3, value[key3], stack, spacer, indentation);
|
|
4038
4040
|
if (tmp !== void 0) {
|
|
4039
4041
|
res += `${separator}${strEscape(key3)}: ${tmp}`;
|
|
4040
|
-
separator =
|
|
4042
|
+
separator = join56;
|
|
4041
4043
|
}
|
|
4042
4044
|
}
|
|
4043
4045
|
if (keyLength > maximumBreadth) {
|
|
4044
4046
|
const removedKeys = keyLength - maximumBreadth;
|
|
4045
4047
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
4046
|
-
separator =
|
|
4048
|
+
separator = join56;
|
|
4047
4049
|
}
|
|
4048
4050
|
if (separator !== "") {
|
|
4049
4051
|
res = `
|
|
@@ -4816,6 +4818,7 @@ function defaultSourcesEnabled() {
|
|
|
4816
4818
|
commands: true
|
|
4817
4819
|
},
|
|
4818
4820
|
cursor: { sessions: true, skills: true, agents: true, commands: true },
|
|
4821
|
+
hermes: { sessions: true },
|
|
4819
4822
|
shared: { skills: true },
|
|
4820
4823
|
common: { mcps: true, agentMd: true }
|
|
4821
4824
|
};
|
|
@@ -4892,6 +4895,7 @@ function mergeSources(base3, partial) {
|
|
|
4892
4895
|
codex: { ...base3.enabled.codex, ...partial.enabled?.codex ?? {} },
|
|
4893
4896
|
agy: { ...base3.enabled.agy, ...inherited, ...partial.enabled?.agy ?? {} },
|
|
4894
4897
|
cursor: { ...base3.enabled.cursor, ...partial.enabled?.cursor ?? {} },
|
|
4898
|
+
hermes: { ...base3.enabled.hermes, ...partial.enabled?.hermes ?? {} },
|
|
4895
4899
|
shared: { ...base3.enabled.shared, ...partial.enabled?.shared ?? {} },
|
|
4896
4900
|
common: { ...base3.enabled.common, ...partial.enabled?.common ?? {} }
|
|
4897
4901
|
};
|
|
@@ -4903,6 +4907,7 @@ function mergeSources(base3, partial) {
|
|
|
4903
4907
|
agyHome: partial.agyHome ?? base3.agyHome,
|
|
4904
4908
|
cursorHome: partial.cursorHome ?? base3.cursorHome,
|
|
4905
4909
|
cursorIdeHome: partial.cursorIdeHome ?? base3.cursorIdeHome,
|
|
4910
|
+
hermesHome: partial.hermesHome ?? base3.hermesHome,
|
|
4906
4911
|
extraClaudeHomes: partial.extraClaudeHomes ?? base3.extraClaudeHomes,
|
|
4907
4912
|
approvedHomes: partial.approvedHomes ?? base3.approvedHomes,
|
|
4908
4913
|
declinedHomes: partial.declinedHomes ?? base3.declinedHomes,
|
|
@@ -5200,6 +5205,13 @@ function grandfatherLegacyHomes() {
|
|
|
5200
5205
|
}
|
|
5201
5206
|
return { seeded };
|
|
5202
5207
|
}
|
|
5208
|
+
function defaultHermesHome() {
|
|
5209
|
+
if (process.platform === "win32") {
|
|
5210
|
+
const local = process.env.LOCALAPPDATA?.trim() || join3(homedir2(), "AppData", "Local");
|
|
5211
|
+
return join3(local, "hermes");
|
|
5212
|
+
}
|
|
5213
|
+
return join3(homedir2(), ".hermes");
|
|
5214
|
+
}
|
|
5203
5215
|
function primaryHomes() {
|
|
5204
5216
|
const home = homedir2();
|
|
5205
5217
|
const env = process.env;
|
|
@@ -5216,7 +5228,8 @@ function primaryHomes() {
|
|
|
5216
5228
|
env.CHAT_RECALL_CODEX_HOME || s?.codexHome || join3(home, ".codex"),
|
|
5217
5229
|
env.CHAT_RECALL_AGY_HOME || s?.agyHome || join3(home, ".gemini", "antigravity-cli"),
|
|
5218
5230
|
env.CHAT_RECALL_CURSOR_HOME || s?.cursorHome || join3(home, ".cursor"),
|
|
5219
|
-
dirOf(opencodeDb)
|
|
5231
|
+
dirOf(opencodeDb),
|
|
5232
|
+
env.CHAT_RECALL_HERMES_HOME || s?.hermesHome || env.HERMES_HOME?.trim() || defaultHermesHome()
|
|
5220
5233
|
];
|
|
5221
5234
|
return candidates2.map(normalizeHomePath);
|
|
5222
5235
|
}
|
|
@@ -5326,6 +5339,9 @@ function geminiHomeDir() {
|
|
|
5326
5339
|
function opencodeDbPath() {
|
|
5327
5340
|
return process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath || join4(homedir3(), ".local", "share", "opencode", "opencode.db");
|
|
5328
5341
|
}
|
|
5342
|
+
function hermesHomeDir() {
|
|
5343
|
+
return process.env.CHAT_RECALL_HERMES_HOME || sources().hermesHome || process.env.HERMES_HOME?.trim() || defaultHermesHome();
|
|
5344
|
+
}
|
|
5329
5345
|
function codexHomeDir() {
|
|
5330
5346
|
return process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome || join4(homedir3(), ".codex");
|
|
5331
5347
|
}
|
|
@@ -5427,6 +5443,22 @@ function opencodeDbPaths(opts = {}) {
|
|
|
5427
5443
|
dbs.push(primary);
|
|
5428
5444
|
return applyExclusions(dbs, opts.includeExcluded);
|
|
5429
5445
|
}
|
|
5446
|
+
function hermesDbPaths(opts = {}) {
|
|
5447
|
+
const root = hermesHomeDir();
|
|
5448
|
+
const dbs = [join4(root, "state.db")];
|
|
5449
|
+
try {
|
|
5450
|
+
const profiles = join4(root, "profiles");
|
|
5451
|
+
for (const entry of readdirSync3(profiles, { withFileTypes: true })) {
|
|
5452
|
+
if (!entry.isDirectory())
|
|
5453
|
+
continue;
|
|
5454
|
+
const p = join4(profiles, entry.name, "state.db");
|
|
5455
|
+
if (existsSync4(p))
|
|
5456
|
+
dbs.push(p);
|
|
5457
|
+
}
|
|
5458
|
+
} catch {
|
|
5459
|
+
}
|
|
5460
|
+
return applyExclusions(dbs, opts.includeExcluded);
|
|
5461
|
+
}
|
|
5430
5462
|
var sources, _sourceExclusionFilter;
|
|
5431
5463
|
var init_tool_paths = __esm({
|
|
5432
5464
|
"../engine/dist/core/tool-paths.js"() {
|
|
@@ -6405,7 +6437,7 @@ function canonicalEventsToMessages(events) {
|
|
|
6405
6437
|
switch (e.kind) {
|
|
6406
6438
|
case "user":
|
|
6407
6439
|
cur = null;
|
|
6408
|
-
messages.push({ line: e.line, role: "user", content: e.text ?? "", timestamp: e.tsIso });
|
|
6440
|
+
messages.push({ line: e.line, role: "user", content: e.text ?? "", timestamp: e.tsIso, ...e.origin ? { origin: e.origin } : {} });
|
|
6409
6441
|
break;
|
|
6410
6442
|
case "assistant_text":
|
|
6411
6443
|
cur = { line: e.line, role: "assistant", content: e.text ?? "", timestamp: e.tsIso };
|
|
@@ -6448,6 +6480,7 @@ var init_from_events = __esm({
|
|
|
6448
6480
|
// ../engine/dist/transcript/raw.js
|
|
6449
6481
|
var raw_exports = {};
|
|
6450
6482
|
__export(raw_exports, {
|
|
6483
|
+
RAW_PARSE_MAX_BYTES: () => RAW_PARSE_MAX_BYTES,
|
|
6451
6484
|
archiveRawSession: () => archiveRawSession,
|
|
6452
6485
|
buildRawContainer: () => buildRawContainer,
|
|
6453
6486
|
containerSrcHash: () => containerSrcHash,
|
|
@@ -6747,11 +6780,11 @@ async function archiveRawSession(store, sessionId) {
|
|
|
6747
6780
|
return await store.putRawSession(sessionId, exp.tool, Math.floor(exp.mtime), gz, size);
|
|
6748
6781
|
}
|
|
6749
6782
|
function detectForkPredecessor(sessionPath) {
|
|
6750
|
-
const { readFileSync:
|
|
6751
|
-
const { dirname: dirname26, join:
|
|
6783
|
+
const { readFileSync: readFileSync47, readdirSync: readdirSync33 } = requireFs();
|
|
6784
|
+
const { dirname: dirname26, join: join56, basename: basename26 } = requirePath();
|
|
6752
6785
|
let text;
|
|
6753
6786
|
try {
|
|
6754
|
-
text =
|
|
6787
|
+
text = readFileSync47(sessionPath, "utf-8");
|
|
6755
6788
|
} catch {
|
|
6756
6789
|
return null;
|
|
6757
6790
|
}
|
|
@@ -6785,7 +6818,7 @@ function detectForkPredecessor(sessionPath) {
|
|
|
6785
6818
|
if (!f.endsWith(".jsonl") || f === self || f === "sessions-index.json")
|
|
6786
6819
|
continue;
|
|
6787
6820
|
try {
|
|
6788
|
-
if (
|
|
6821
|
+
if (readFileSync47(join56(dir, f), "utf-8").includes(`"uuid":"${headParent}"`)) {
|
|
6789
6822
|
return basename26(f, ".jsonl");
|
|
6790
6823
|
}
|
|
6791
6824
|
} catch {
|
|
@@ -6799,7 +6832,7 @@ function requireFs() {
|
|
|
6799
6832
|
function requirePath() {
|
|
6800
6833
|
return pathMod;
|
|
6801
6834
|
}
|
|
6802
|
-
var MARKER_QUOTE;
|
|
6835
|
+
var RAW_PARSE_MAX_BYTES, MARKER_QUOTE;
|
|
6803
6836
|
var init_raw = __esm({
|
|
6804
6837
|
"../engine/dist/transcript/raw.js"() {
|
|
6805
6838
|
"use strict";
|
|
@@ -6807,6 +6840,7 @@ var init_raw = __esm({
|
|
|
6807
6840
|
init_claude();
|
|
6808
6841
|
init_codex();
|
|
6809
6842
|
init_from_events();
|
|
6843
|
+
RAW_PARSE_MAX_BYTES = 40 * 1024 * 1024;
|
|
6810
6844
|
MARKER_QUOTE = /\[REDACTED:[A-Za-z0-9_-]+\]"/g;
|
|
6811
6845
|
}
|
|
6812
6846
|
});
|
|
@@ -8080,6 +8114,71 @@ function readTailFromOffset(path, offset, maxBytes = TAIL_READ_MAX_BYTES) {
|
|
|
8080
8114
|
}
|
|
8081
8115
|
}
|
|
8082
8116
|
}
|
|
8117
|
+
function readSourcesFromOffset(paths, offset, maxBytes = TAIL_READ_MAX_BYTES) {
|
|
8118
|
+
let start = 0;
|
|
8119
|
+
let linesBefore = 0;
|
|
8120
|
+
for (let i = 0; i < paths.length; i++) {
|
|
8121
|
+
const path = paths[i];
|
|
8122
|
+
let size = 0;
|
|
8123
|
+
try {
|
|
8124
|
+
size = statSync6(path).size;
|
|
8125
|
+
} catch {
|
|
8126
|
+
size = 0;
|
|
8127
|
+
}
|
|
8128
|
+
const last = i === paths.length - 1;
|
|
8129
|
+
if (!last && offset >= start + size) {
|
|
8130
|
+
const lines = linesBeforeOffset(path, size);
|
|
8131
|
+
if (lines === void 0)
|
|
8132
|
+
return { text: "", newOffset: offset };
|
|
8133
|
+
linesBefore += lines + (size > 0 && !endsWithNewline(path, size) ? 1 : 0);
|
|
8134
|
+
start += size;
|
|
8135
|
+
continue;
|
|
8136
|
+
}
|
|
8137
|
+
const local = offset - start;
|
|
8138
|
+
const read = readTailFromOffset(path, local, maxBytes);
|
|
8139
|
+
const shift = (r) => ({
|
|
8140
|
+
...r,
|
|
8141
|
+
newOffset: start + r.newOffset,
|
|
8142
|
+
...r.baseLine !== void 0 ? { baseLine: linesBefore + r.baseLine } : {}
|
|
8143
|
+
});
|
|
8144
|
+
if (last || read.newOffset > local || local >= size)
|
|
8145
|
+
return shift(read);
|
|
8146
|
+
if (size - local > maxBytes)
|
|
8147
|
+
return { text: "", newOffset: start + size, skippedBytes: size - local };
|
|
8148
|
+
let fd = null;
|
|
8149
|
+
try {
|
|
8150
|
+
fd = openSync5(path, "r");
|
|
8151
|
+
const text = readAt(fd, local, size - local).toString("utf-8");
|
|
8152
|
+
return shift({ text, newOffset: size, baseLine: linesBeforeOffset(path, local) });
|
|
8153
|
+
} catch {
|
|
8154
|
+
return { text: "", newOffset: offset };
|
|
8155
|
+
} finally {
|
|
8156
|
+
if (fd !== null) {
|
|
8157
|
+
try {
|
|
8158
|
+
closeSync5(fd);
|
|
8159
|
+
} catch {
|
|
8160
|
+
}
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
}
|
|
8164
|
+
return { text: "", newOffset: offset };
|
|
8165
|
+
}
|
|
8166
|
+
function endsWithNewline(path, size) {
|
|
8167
|
+
let fd = null;
|
|
8168
|
+
try {
|
|
8169
|
+
fd = openSync5(path, "r");
|
|
8170
|
+
return readAt(fd, size - 1, 1)[0] === 10;
|
|
8171
|
+
} catch {
|
|
8172
|
+
return true;
|
|
8173
|
+
} finally {
|
|
8174
|
+
if (fd !== null) {
|
|
8175
|
+
try {
|
|
8176
|
+
closeSync5(fd);
|
|
8177
|
+
} catch {
|
|
8178
|
+
}
|
|
8179
|
+
}
|
|
8180
|
+
}
|
|
8181
|
+
}
|
|
8083
8182
|
function findNewline(fd, from, size) {
|
|
8084
8183
|
const block = Buffer.allocUnsafe(SKIP_SCAN_BYTES);
|
|
8085
8184
|
let pos = from;
|
|
@@ -8996,27 +9095,45 @@ var init_claude2 = __esm({
|
|
|
8996
9095
|
/**
|
|
8997
9096
|
* True when this session exists in MORE THAN ONE home.
|
|
8998
9097
|
*
|
|
8999
|
-
* Such a session cannot be tail-appended: `fileSize()` is the SUM across
|
|
9000
|
-
* copies while a byte offset addresses ONE file, so the two disagree by
|
|
9001
|
-
* construction and the "tail" is either empty or the wrong bytes. The caller
|
|
9002
|
-
* uses this to force a FULL sync, which ships the unioned container and is
|
|
9003
|
-
* correct regardless of how the halves are arranged.
|
|
9004
|
-
*
|
|
9005
9098
|
* Measured on ec05f266: ~/.claude 1715 records, ~/.claude-work 205 records,
|
|
9006
|
-
* zero overlap.
|
|
9007
|
-
*
|
|
9099
|
+
* zero overlap. `fileSize()` is the sum across the copies, and
|
|
9100
|
+
* `readFromOffset()` reads them joined end to end, primary first.
|
|
9008
9101
|
*/
|
|
9009
9102
|
spansMultipleSources(prefixedId) {
|
|
9010
9103
|
return findSessionFiles(this.toRawId(prefixedId)).length > 1;
|
|
9011
9104
|
}
|
|
9105
|
+
/**
|
|
9106
|
+
* The copies before the last one, each with its size. Claude Code writes to
|
|
9107
|
+
* the home of the profile that runs the session, so the live copy can grow,
|
|
9108
|
+
* appear, vanish or merge back into the primary. Each of those moves bytes
|
|
9109
|
+
* under an offset into the joined copies; this key changes with all of them.
|
|
9110
|
+
*/
|
|
9111
|
+
sourceLayout(prefixedId) {
|
|
9112
|
+
const copies = findSessionFiles(this.toRawId(prefixedId));
|
|
9113
|
+
if (copies.length < 2)
|
|
9114
|
+
return "";
|
|
9115
|
+
return copies.slice(0, -1).map((c) => {
|
|
9116
|
+
let size = -1;
|
|
9117
|
+
try {
|
|
9118
|
+
size = statSync7(c.path).size;
|
|
9119
|
+
} catch {
|
|
9120
|
+
}
|
|
9121
|
+
return `${c.path}:${size}`;
|
|
9122
|
+
}).join("|");
|
|
9123
|
+
}
|
|
9124
|
+
/**
|
|
9125
|
+
* Session 8de13d0a had 31 MB in ~/.claude and 2 MB in ~/.claude-work. Over
|
|
9126
|
+
* the 24 MB build ceiling a sync ships the transcript in chunks read here,
|
|
9127
|
+
* and this returned no text for a session in two homes. Each sync shipped
|
|
9128
|
+
* nothing, and the server stayed three hours behind.
|
|
9129
|
+
*/
|
|
9012
9130
|
async readFromOffset(prefixedId, offset, maxBytes) {
|
|
9013
|
-
const
|
|
9014
|
-
const copies = findSessionFiles(rawId);
|
|
9131
|
+
const copies = findSessionFiles(this.toRawId(prefixedId));
|
|
9015
9132
|
if (copies.length === 0)
|
|
9016
9133
|
return { text: "", newOffset: offset };
|
|
9017
|
-
if (copies.length
|
|
9018
|
-
return
|
|
9019
|
-
return
|
|
9134
|
+
if (copies.length === 1)
|
|
9135
|
+
return readTailFromOffset(copies[0].path, offset, maxBytes);
|
|
9136
|
+
return readSourcesFromOffset(copies.map((c) => c.path), offset, maxBytes);
|
|
9020
9137
|
}
|
|
9021
9138
|
};
|
|
9022
9139
|
claudeBackend = new ClaudeBackend();
|
|
@@ -12075,6 +12192,473 @@ var init_cursor = __esm({
|
|
|
12075
12192
|
}
|
|
12076
12193
|
});
|
|
12077
12194
|
|
|
12195
|
+
// ../engine/dist/core/backends/hermes.js
|
|
12196
|
+
import { existsSync as existsSync16 } from "fs";
|
|
12197
|
+
function firstUserPrompt(db, sessionId) {
|
|
12198
|
+
try {
|
|
12199
|
+
const row = db.prepare(`
|
|
12200
|
+
SELECT substr(content, 1, 400) AS text FROM messages
|
|
12201
|
+
WHERE session_id = ? AND role = 'user' AND active = 1 AND _compressed_summary = 0
|
|
12202
|
+
AND (display_kind IS NULL OR display_kind = 'steer')
|
|
12203
|
+
AND length(trim(content)) > 0
|
|
12204
|
+
ORDER BY id LIMIT 1
|
|
12205
|
+
`).get(sessionId);
|
|
12206
|
+
return row?.text ? flatString(row.text.slice(0, 200)) : "";
|
|
12207
|
+
} catch {
|
|
12208
|
+
return "";
|
|
12209
|
+
}
|
|
12210
|
+
}
|
|
12211
|
+
function messageRowsToEvents(rows) {
|
|
12212
|
+
const events = [];
|
|
12213
|
+
let line = 0;
|
|
12214
|
+
for (const r of rows) {
|
|
12215
|
+
line++;
|
|
12216
|
+
if (r.active === 0)
|
|
12217
|
+
continue;
|
|
12218
|
+
if (r.display_kind === "failed_turn" || r.display_kind === "hidden")
|
|
12219
|
+
continue;
|
|
12220
|
+
const ts = Math.round((r.timestamp || 0) * 1e3);
|
|
12221
|
+
const tsIso = ts ? new Date(ts).toISOString() : void 0;
|
|
12222
|
+
const text = (r.content ?? "").trim();
|
|
12223
|
+
if (r._compressed_summary === 1) {
|
|
12224
|
+
if (text)
|
|
12225
|
+
events.push({ kind: "summary", ts, tsIso, line, text });
|
|
12226
|
+
continue;
|
|
12227
|
+
}
|
|
12228
|
+
if (r.role === "user") {
|
|
12229
|
+
if (!text)
|
|
12230
|
+
continue;
|
|
12231
|
+
events.push({
|
|
12232
|
+
kind: "user",
|
|
12233
|
+
ts,
|
|
12234
|
+
tsIso,
|
|
12235
|
+
line,
|
|
12236
|
+
text,
|
|
12237
|
+
...r.display_kind === "process_complete" ? { origin: "task-notification" } : {}
|
|
12238
|
+
});
|
|
12239
|
+
continue;
|
|
12240
|
+
}
|
|
12241
|
+
if (r.role === "assistant") {
|
|
12242
|
+
if (text)
|
|
12243
|
+
events.push({ kind: "assistant_text", ts, tsIso, line, text });
|
|
12244
|
+
for (const call2 of parseToolCalls(r.tool_calls)) {
|
|
12245
|
+
const toolName = call2.function?.name ?? "";
|
|
12246
|
+
const toolInput = parseArguments(call2.function?.arguments);
|
|
12247
|
+
const command = toolName === "terminal" && typeof toolInput?.command === "string" ? toolInput.command : void 0;
|
|
12248
|
+
events.push({
|
|
12249
|
+
kind: "tool_use",
|
|
12250
|
+
ts,
|
|
12251
|
+
tsIso,
|
|
12252
|
+
line,
|
|
12253
|
+
toolName,
|
|
12254
|
+
toolUseId: call2.id || call2.call_id || `${r.id}:${toolName}`,
|
|
12255
|
+
toolInput,
|
|
12256
|
+
...command ? { command } : {}
|
|
12257
|
+
});
|
|
12258
|
+
}
|
|
12259
|
+
continue;
|
|
12260
|
+
}
|
|
12261
|
+
if (r.role === "tool") {
|
|
12262
|
+
const body = r.content ?? "";
|
|
12263
|
+
const { exitCode, isError } = toolResultStatus(body);
|
|
12264
|
+
events.push({
|
|
12265
|
+
kind: "tool_result",
|
|
12266
|
+
ts,
|
|
12267
|
+
tsIso,
|
|
12268
|
+
line,
|
|
12269
|
+
toolUseId: r.tool_call_id ?? void 0,
|
|
12270
|
+
toolName: r.tool_name ?? void 0,
|
|
12271
|
+
resultBody: body,
|
|
12272
|
+
resultIsError: isError,
|
|
12273
|
+
...exitCode !== void 0 ? { resultExitCode: exitCode } : {},
|
|
12274
|
+
resultBytes: Buffer.byteLength(body)
|
|
12275
|
+
});
|
|
12276
|
+
}
|
|
12277
|
+
}
|
|
12278
|
+
return events;
|
|
12279
|
+
}
|
|
12280
|
+
function parseToolCalls(json) {
|
|
12281
|
+
if (!json)
|
|
12282
|
+
return [];
|
|
12283
|
+
try {
|
|
12284
|
+
const calls = JSON.parse(json);
|
|
12285
|
+
return Array.isArray(calls) ? calls : [];
|
|
12286
|
+
} catch {
|
|
12287
|
+
return [];
|
|
12288
|
+
}
|
|
12289
|
+
}
|
|
12290
|
+
function parseArguments(args) {
|
|
12291
|
+
if (typeof args !== "string")
|
|
12292
|
+
return args ?? {};
|
|
12293
|
+
try {
|
|
12294
|
+
return JSON.parse(args);
|
|
12295
|
+
} catch {
|
|
12296
|
+
return { raw: args };
|
|
12297
|
+
}
|
|
12298
|
+
}
|
|
12299
|
+
function toolResultStatus(body) {
|
|
12300
|
+
if (!body.startsWith("{"))
|
|
12301
|
+
return { isError: false };
|
|
12302
|
+
try {
|
|
12303
|
+
const r = JSON.parse(body);
|
|
12304
|
+
const exitCode = typeof r.exit_code === "number" ? r.exit_code : void 0;
|
|
12305
|
+
const hasError = r.error !== void 0 && r.error !== null && r.error !== "";
|
|
12306
|
+
return { exitCode, isError: hasError || exitCode !== void 0 && exitCode !== 0 };
|
|
12307
|
+
} catch {
|
|
12308
|
+
return { isError: false };
|
|
12309
|
+
}
|
|
12310
|
+
}
|
|
12311
|
+
var PREFIX5, MESSAGE_COLUMNS, ARCHIVED_SESSION_COLUMNS, SESSION_MTIME_SQL, HermesBackend, hermesBackend;
|
|
12312
|
+
var init_hermes = __esm({
|
|
12313
|
+
"../engine/dist/core/backends/hermes.js"() {
|
|
12314
|
+
"use strict";
|
|
12315
|
+
init_sqlite_reader();
|
|
12316
|
+
init_tool_paths();
|
|
12317
|
+
init_session_outcome();
|
|
12318
|
+
init_session_git();
|
|
12319
|
+
init_generic_engine();
|
|
12320
|
+
init_flat_string();
|
|
12321
|
+
PREFIX5 = "hermes_";
|
|
12322
|
+
MESSAGE_COLUMNS = "id, role, content, tool_calls, tool_call_id, tool_name, timestamp, display_kind, active, _compressed_summary";
|
|
12323
|
+
ARCHIVED_SESSION_COLUMNS = [
|
|
12324
|
+
"id",
|
|
12325
|
+
"source",
|
|
12326
|
+
"title",
|
|
12327
|
+
"model",
|
|
12328
|
+
"cwd",
|
|
12329
|
+
"git_branch",
|
|
12330
|
+
"git_repo_root",
|
|
12331
|
+
"parent_session_id",
|
|
12332
|
+
"started_at",
|
|
12333
|
+
"ended_at",
|
|
12334
|
+
"end_reason",
|
|
12335
|
+
"message_count",
|
|
12336
|
+
"tool_call_count",
|
|
12337
|
+
"input_tokens",
|
|
12338
|
+
"output_tokens",
|
|
12339
|
+
"cache_read_tokens",
|
|
12340
|
+
"cache_write_tokens",
|
|
12341
|
+
"reasoning_tokens",
|
|
12342
|
+
"estimated_cost_usd",
|
|
12343
|
+
"actual_cost_usd"
|
|
12344
|
+
];
|
|
12345
|
+
SESSION_MTIME_SQL = `MAX(
|
|
12346
|
+
s.started_at,
|
|
12347
|
+
COALESCE(s.ended_at, 0),
|
|
12348
|
+
COALESCE(s.last_activity_at, 0),
|
|
12349
|
+
COALESCE((SELECT MAX(m.timestamp) FROM messages m WHERE m.session_id = s.id), 0)
|
|
12350
|
+
)`;
|
|
12351
|
+
HermesBackend = class {
|
|
12352
|
+
id = "hermes";
|
|
12353
|
+
idPrefix = PREFIX5;
|
|
12354
|
+
displayName = "Hermes";
|
|
12355
|
+
homeDir() {
|
|
12356
|
+
return hermesHomeDir();
|
|
12357
|
+
}
|
|
12358
|
+
/** Every Hermes database on this machine, the root profile first. */
|
|
12359
|
+
dbPaths() {
|
|
12360
|
+
return hermesDbPaths();
|
|
12361
|
+
}
|
|
12362
|
+
isAvailable() {
|
|
12363
|
+
return this.dbPaths().some((p) => existsSync16(p));
|
|
12364
|
+
}
|
|
12365
|
+
/** The database that holds this session. A session id is unique within a
|
|
12366
|
+
* database, and each named profile has its own. */
|
|
12367
|
+
dbPathFor(rawId) {
|
|
12368
|
+
const cached = this._dbForSession.get(rawId);
|
|
12369
|
+
if (cached)
|
|
12370
|
+
return cached;
|
|
12371
|
+
for (const path of this.dbPaths()) {
|
|
12372
|
+
const db = openSqliteReadonly(path);
|
|
12373
|
+
if (!db)
|
|
12374
|
+
continue;
|
|
12375
|
+
try {
|
|
12376
|
+
if (db.prepare("SELECT 1 AS ok FROM sessions WHERE id = ?").get(rawId)) {
|
|
12377
|
+
this._dbForSession.set(rawId, path);
|
|
12378
|
+
return path;
|
|
12379
|
+
}
|
|
12380
|
+
} catch {
|
|
12381
|
+
} finally {
|
|
12382
|
+
db.close();
|
|
12383
|
+
}
|
|
12384
|
+
}
|
|
12385
|
+
return null;
|
|
12386
|
+
}
|
|
12387
|
+
_dbForSession = /* @__PURE__ */ new Map();
|
|
12388
|
+
/** Tests, and anything that adds a profile mid-process. */
|
|
12389
|
+
_clearDbRouting() {
|
|
12390
|
+
this._dbForSession.clear();
|
|
12391
|
+
}
|
|
12392
|
+
// ── ID handling ────────────────────────────────────────────────
|
|
12393
|
+
matchesId(id) {
|
|
12394
|
+
return id.startsWith(PREFIX5);
|
|
12395
|
+
}
|
|
12396
|
+
toRawId(id) {
|
|
12397
|
+
return id.startsWith(PREFIX5) ? id.slice(PREFIX5.length) : id;
|
|
12398
|
+
}
|
|
12399
|
+
toPrefixedId(rawId) {
|
|
12400
|
+
return rawId.startsWith(PREFIX5) ? rawId : PREFIX5 + rawId;
|
|
12401
|
+
}
|
|
12402
|
+
// ── Location ───────────────────────────────────────────────────
|
|
12403
|
+
findSession(id) {
|
|
12404
|
+
const rawId = this.toRawId(id);
|
|
12405
|
+
const path = this.dbPathFor(rawId);
|
|
12406
|
+
if (!path)
|
|
12407
|
+
return null;
|
|
12408
|
+
const db = openSqliteReadonly(path);
|
|
12409
|
+
if (!db)
|
|
12410
|
+
return null;
|
|
12411
|
+
try {
|
|
12412
|
+
const row = db.prepare(`
|
|
12413
|
+
SELECT s.cwd, s.git_repo_root, ${SESSION_MTIME_SQL} AS mtime
|
|
12414
|
+
FROM sessions s WHERE s.id = ?
|
|
12415
|
+
`).get(rawId);
|
|
12416
|
+
if (!row)
|
|
12417
|
+
return null;
|
|
12418
|
+
return {
|
|
12419
|
+
path,
|
|
12420
|
+
format: "sqlite",
|
|
12421
|
+
projectDir: "",
|
|
12422
|
+
projectPath: row.git_repo_root || row.cwd || "",
|
|
12423
|
+
mtime: Math.round((row.mtime || 0) * 1e3)
|
|
12424
|
+
};
|
|
12425
|
+
} catch {
|
|
12426
|
+
return null;
|
|
12427
|
+
} finally {
|
|
12428
|
+
db.close();
|
|
12429
|
+
}
|
|
12430
|
+
}
|
|
12431
|
+
listSessions(opts = {}) {
|
|
12432
|
+
const byId = /* @__PURE__ */ new Map();
|
|
12433
|
+
for (const dbPath of this.dbPaths()) {
|
|
12434
|
+
if (!existsSync16(dbPath))
|
|
12435
|
+
continue;
|
|
12436
|
+
for (const ref of this.listSessionsInDb(dbPath, opts)) {
|
|
12437
|
+
const prior = byId.get(ref.rawId);
|
|
12438
|
+
if (!prior || ref.mtime > prior.mtime)
|
|
12439
|
+
byId.set(ref.rawId, ref);
|
|
12440
|
+
}
|
|
12441
|
+
}
|
|
12442
|
+
const all = [...byId.values()].sort((a, b) => b.mtime - a.mtime);
|
|
12443
|
+
return opts.limit ? all.slice(0, opts.limit) : all;
|
|
12444
|
+
}
|
|
12445
|
+
listSessionsInDb(dbPath, opts) {
|
|
12446
|
+
const cutoffSec = (opts.sinceMs ?? 0) / 1e3;
|
|
12447
|
+
const filter = opts.projectFilter?.toLowerCase();
|
|
12448
|
+
const db = openSqliteReadonly(dbPath);
|
|
12449
|
+
if (!db)
|
|
12450
|
+
return [];
|
|
12451
|
+
try {
|
|
12452
|
+
const rows = db.prepare(`
|
|
12453
|
+
SELECT * FROM (
|
|
12454
|
+
SELECT s.id, s.cwd, s.git_repo_root, s.started_at, s.message_count,
|
|
12455
|
+
${SESSION_MTIME_SQL} AS mtime
|
|
12456
|
+
FROM sessions s
|
|
12457
|
+
) WHERE mtime >= ? ORDER BY mtime DESC
|
|
12458
|
+
`).all(cutoffSec);
|
|
12459
|
+
const out = [];
|
|
12460
|
+
for (const row of rows) {
|
|
12461
|
+
const projectPath = row.git_repo_root || row.cwd || "";
|
|
12462
|
+
if (filter && !projectPath.toLowerCase().includes(filter))
|
|
12463
|
+
continue;
|
|
12464
|
+
const mtime = Math.round(row.mtime * 1e3);
|
|
12465
|
+
this._dbForSession.set(row.id, dbPath);
|
|
12466
|
+
out.push({
|
|
12467
|
+
toolId: "hermes",
|
|
12468
|
+
rawId: row.id,
|
|
12469
|
+
prefixedId: this.toPrefixedId(row.id),
|
|
12470
|
+
projectPath,
|
|
12471
|
+
projectDir: "",
|
|
12472
|
+
fullPath: dbPath,
|
|
12473
|
+
created: new Date(Math.round(row.started_at * 1e3)).toISOString(),
|
|
12474
|
+
modified: new Date(mtime).toISOString(),
|
|
12475
|
+
mtime,
|
|
12476
|
+
firstPrompt: opts.previews === false ? "" : firstUserPrompt(db, row.id),
|
|
12477
|
+
messageCount: opts.previews === false ? 0 : row.message_count ?? 0
|
|
12478
|
+
});
|
|
12479
|
+
if (opts.limit && out.length >= opts.limit)
|
|
12480
|
+
break;
|
|
12481
|
+
}
|
|
12482
|
+
return out;
|
|
12483
|
+
} catch {
|
|
12484
|
+
return [];
|
|
12485
|
+
} finally {
|
|
12486
|
+
db.close();
|
|
12487
|
+
}
|
|
12488
|
+
}
|
|
12489
|
+
/** Hermes writes a title for each session (a model-written one, or the
|
|
12490
|
+
* first prompt for a one-shot run). */
|
|
12491
|
+
getNativeTitle(rawId) {
|
|
12492
|
+
const path = this.dbPathFor(this.toRawId(rawId));
|
|
12493
|
+
if (!path)
|
|
12494
|
+
return null;
|
|
12495
|
+
const db = openSqliteReadonly(path);
|
|
12496
|
+
if (!db)
|
|
12497
|
+
return null;
|
|
12498
|
+
try {
|
|
12499
|
+
const row = db.prepare("SELECT title FROM sessions WHERE id = ?").get(this.toRawId(rawId));
|
|
12500
|
+
const t = row?.title?.trim();
|
|
12501
|
+
return t ? t.slice(0, 200) : null;
|
|
12502
|
+
} catch {
|
|
12503
|
+
return null;
|
|
12504
|
+
} finally {
|
|
12505
|
+
db.close();
|
|
12506
|
+
}
|
|
12507
|
+
}
|
|
12508
|
+
// ── Generic-engine inputs ───────────────────────────────────────
|
|
12509
|
+
fileToolMap = {
|
|
12510
|
+
write_file: "write",
|
|
12511
|
+
patch: "edit",
|
|
12512
|
+
read_file: "read"
|
|
12513
|
+
};
|
|
12514
|
+
/**
|
|
12515
|
+
* `write_file` carries `{ path, content }`. `patch` carries
|
|
12516
|
+
* `{ mode: 'replace', path, old_string, new_string }`; its other mode,
|
|
12517
|
+
* `patch`, is a multi-file V4A patch with no single before and after.
|
|
12518
|
+
*/
|
|
12519
|
+
extractEditDelta(toolName, input) {
|
|
12520
|
+
if (input == null || typeof input !== "object")
|
|
12521
|
+
return null;
|
|
12522
|
+
const inp = input;
|
|
12523
|
+
if (toolName === "write_file") {
|
|
12524
|
+
return { before: "", after: typeof inp.content === "string" ? inp.content : null };
|
|
12525
|
+
}
|
|
12526
|
+
if (toolName === "patch" && (inp.mode === void 0 || inp.mode === "replace")) {
|
|
12527
|
+
const before = typeof inp.old_string === "string" ? inp.old_string : null;
|
|
12528
|
+
const after = typeof inp.new_string === "string" ? inp.new_string : null;
|
|
12529
|
+
if (before === null && after === null)
|
|
12530
|
+
return null;
|
|
12531
|
+
return { before, after };
|
|
12532
|
+
}
|
|
12533
|
+
return null;
|
|
12534
|
+
}
|
|
12535
|
+
readEvents(rawId) {
|
|
12536
|
+
const id = this.toRawId(rawId);
|
|
12537
|
+
const path = this.dbPathFor(id);
|
|
12538
|
+
if (!path)
|
|
12539
|
+
return [];
|
|
12540
|
+
const db = openSqliteReadonly(path);
|
|
12541
|
+
if (!db)
|
|
12542
|
+
return [];
|
|
12543
|
+
try {
|
|
12544
|
+
const rows = db.prepare(`SELECT ${MESSAGE_COLUMNS} FROM messages WHERE session_id = ? ORDER BY id`).all(id);
|
|
12545
|
+
return messageRowsToEvents(rows);
|
|
12546
|
+
} catch {
|
|
12547
|
+
return [];
|
|
12548
|
+
} finally {
|
|
12549
|
+
db.close();
|
|
12550
|
+
}
|
|
12551
|
+
}
|
|
12552
|
+
/**
|
|
12553
|
+
* Events from the dump `exportRawSession` writes, for a session rebuilt from
|
|
12554
|
+
* the server's archive. The archive joins the lines of every dump it got, so
|
|
12555
|
+
* a row that changed (a rewind sets `active` to 0) is there more than once.
|
|
12556
|
+
* The last copy of each row id is the newest.
|
|
12557
|
+
*/
|
|
12558
|
+
readEventsFromText(text) {
|
|
12559
|
+
const rows = /* @__PURE__ */ new Map();
|
|
12560
|
+
for (const line of text.split("\n")) {
|
|
12561
|
+
if (!line.trim())
|
|
12562
|
+
continue;
|
|
12563
|
+
try {
|
|
12564
|
+
const rec = JSON.parse(line);
|
|
12565
|
+
if (rec.kind === "message" && rec.row) {
|
|
12566
|
+
rows.delete(rec.row.id);
|
|
12567
|
+
rows.set(rec.row.id, rec.row);
|
|
12568
|
+
}
|
|
12569
|
+
} catch {
|
|
12570
|
+
}
|
|
12571
|
+
}
|
|
12572
|
+
return messageRowsToEvents([...rows.values()].sort((a, b) => a.id - b.id));
|
|
12573
|
+
}
|
|
12574
|
+
// ── Per-session operations — all delegate to the generic engine ─
|
|
12575
|
+
extractTurns(id, opts = {}) {
|
|
12576
|
+
return extractTurnsFromEvents(this.toPrefixedId(id), this.readEvents(id), opts);
|
|
12577
|
+
}
|
|
12578
|
+
liveScanEdits(id) {
|
|
12579
|
+
const located = this.findSession(id);
|
|
12580
|
+
if (!located) {
|
|
12581
|
+
return { found: false, projectPath: "", projectDir: "", edits: [], fileMtime: 0, tool: "hermes" };
|
|
12582
|
+
}
|
|
12583
|
+
return liveScanEditsFromEvents(this.readEvents(id), this.fileToolMap, {
|
|
12584
|
+
sessionId: this.toPrefixedId(id),
|
|
12585
|
+
tool: "hermes",
|
|
12586
|
+
projectPath: located.projectPath,
|
|
12587
|
+
projectDir: located.projectDir,
|
|
12588
|
+
fileMtime: located.mtime,
|
|
12589
|
+
found: true
|
|
12590
|
+
});
|
|
12591
|
+
}
|
|
12592
|
+
replay(id) {
|
|
12593
|
+
const located = this.findSession(id);
|
|
12594
|
+
if (!located) {
|
|
12595
|
+
return { sessionId: this.toPrefixedId(id), found: false, projectPath: "", files: [], totalLinesAdded: 0, totalLinesRemoved: 0 };
|
|
12596
|
+
}
|
|
12597
|
+
return replayFromEvents(this.toPrefixedId(id), this.readEvents(id), this.fileToolMap, this.extractEditDelta.bind(this), {
|
|
12598
|
+
projectPath: located.projectPath,
|
|
12599
|
+
found: true
|
|
12600
|
+
});
|
|
12601
|
+
}
|
|
12602
|
+
computeOutcome(id, opts) {
|
|
12603
|
+
return computeOutcome(this.toPrefixedId(id), opts);
|
|
12604
|
+
}
|
|
12605
|
+
/** File edits since `sinceMs` across the sessions active since then. */
|
|
12606
|
+
collectRecentEdits(opts) {
|
|
12607
|
+
const refs = this.listSessions({ sinceMs: opts.sinceMs, projectFilter: opts.projectFilter, previews: false });
|
|
12608
|
+
const edits = [];
|
|
12609
|
+
for (const ref of opts.limitSessions ? refs.slice(0, opts.limitSessions) : refs) {
|
|
12610
|
+
for (const e of this.liveScanEdits(ref.rawId).edits) {
|
|
12611
|
+
if (e.ts >= opts.sinceMs)
|
|
12612
|
+
edits.push(e);
|
|
12613
|
+
}
|
|
12614
|
+
}
|
|
12615
|
+
return edits.sort((a, b) => b.ts - a.ts);
|
|
12616
|
+
}
|
|
12617
|
+
getCommits(id, files, startMs, endMs, bufferMinutes) {
|
|
12618
|
+
return getSessionCommits(this.toPrefixedId(id), files, startMs, endMs, bufferMinutes);
|
|
12619
|
+
}
|
|
12620
|
+
/**
|
|
12621
|
+
* The session row and its messages as JSONL, one row per line in id order.
|
|
12622
|
+
* Hermes rewrites and compacts its database, so the archive keeps the rows
|
|
12623
|
+
* as they were synced.
|
|
12624
|
+
*/
|
|
12625
|
+
exportRawSession(id) {
|
|
12626
|
+
const rawId = this.toRawId(id);
|
|
12627
|
+
const path = this.dbPathFor(rawId);
|
|
12628
|
+
if (!path)
|
|
12629
|
+
return null;
|
|
12630
|
+
const db = openSqliteReadonly(path);
|
|
12631
|
+
if (!db)
|
|
12632
|
+
return null;
|
|
12633
|
+
try {
|
|
12634
|
+
const have = new Set(db.prepare(`SELECT name FROM pragma_table_info('sessions')`).all().map((c) => c.name));
|
|
12635
|
+
const cols = ARCHIVED_SESSION_COLUMNS.filter((c) => have.has(c)).map((c) => `s.${c}`);
|
|
12636
|
+
const session = db.prepare(`
|
|
12637
|
+
SELECT ${[...cols, `${SESSION_MTIME_SQL} AS mtime`].join(", ")}
|
|
12638
|
+
FROM sessions s WHERE s.id = ?
|
|
12639
|
+
`).get(rawId);
|
|
12640
|
+
if (!session)
|
|
12641
|
+
return null;
|
|
12642
|
+
const rows = db.prepare(`SELECT ${MESSAGE_COLUMNS} FROM messages WHERE session_id = ? ORDER BY id`).all(rawId);
|
|
12643
|
+
const lines = [JSON.stringify({ kind: "session", row: session })];
|
|
12644
|
+
for (const r of rows)
|
|
12645
|
+
lines.push(JSON.stringify({ kind: "message", row: r }));
|
|
12646
|
+
return {
|
|
12647
|
+
tool: "hermes",
|
|
12648
|
+
mtime: Math.round(Number(session.mtime || 0) * 1e3),
|
|
12649
|
+
files: [{ name: `${rawId}.dump.jsonl`, bytes: Buffer.from(lines.join("\n") + "\n", "utf-8") }]
|
|
12650
|
+
};
|
|
12651
|
+
} catch {
|
|
12652
|
+
return null;
|
|
12653
|
+
} finally {
|
|
12654
|
+
db.close();
|
|
12655
|
+
}
|
|
12656
|
+
}
|
|
12657
|
+
};
|
|
12658
|
+
hermesBackend = new HermesBackend();
|
|
12659
|
+
}
|
|
12660
|
+
});
|
|
12661
|
+
|
|
12078
12662
|
// ../engine/dist/core/backends/index.js
|
|
12079
12663
|
var backends_exports = {};
|
|
12080
12664
|
__export(backends_exports, {
|
|
@@ -12082,6 +12666,7 @@ __export(backends_exports, {
|
|
|
12082
12666
|
ClaudeBackend: () => ClaudeBackend,
|
|
12083
12667
|
CodexBackend: () => CodexBackend,
|
|
12084
12668
|
CursorBackend: () => CursorBackend,
|
|
12669
|
+
HermesBackend: () => HermesBackend,
|
|
12085
12670
|
OpencodeBackend: () => OpencodeBackend,
|
|
12086
12671
|
agyBackend: () => agyBackend,
|
|
12087
12672
|
bootstrapBackends: () => bootstrapBackends,
|
|
@@ -12090,6 +12675,7 @@ __export(backends_exports, {
|
|
|
12090
12675
|
cursorBackend: () => cursorBackend,
|
|
12091
12676
|
getBackend: () => getBackend,
|
|
12092
12677
|
getBackendForId: () => getBackendForId,
|
|
12678
|
+
hermesBackend: () => hermesBackend,
|
|
12093
12679
|
listAllBackends: () => listAllBackends,
|
|
12094
12680
|
listAvailableBackends: () => listAvailableBackends,
|
|
12095
12681
|
opencodeBackend: () => opencodeBackend,
|
|
@@ -12102,6 +12688,7 @@ function bootstrapBackends() {
|
|
|
12102
12688
|
registerBackend(codexBackend);
|
|
12103
12689
|
registerBackend(agyBackend);
|
|
12104
12690
|
registerBackend(cursorBackend);
|
|
12691
|
+
registerBackend(hermesBackend);
|
|
12105
12692
|
}
|
|
12106
12693
|
var init_backends = __esm({
|
|
12107
12694
|
"../engine/dist/core/backends/index.js"() {
|
|
@@ -12112,6 +12699,7 @@ var init_backends = __esm({
|
|
|
12112
12699
|
init_codex2();
|
|
12113
12700
|
init_agy();
|
|
12114
12701
|
init_cursor();
|
|
12702
|
+
init_hermes();
|
|
12115
12703
|
init_tool_backend();
|
|
12116
12704
|
_setRegistryBootstrapper(bootstrapBackends);
|
|
12117
12705
|
}
|
|
@@ -12628,7 +13216,7 @@ var init_secret_redactor = __esm({
|
|
|
12628
13216
|
|
|
12629
13217
|
// ../engine/dist/core/source-discovery.js
|
|
12630
13218
|
import { createHash as createHash3 } from "crypto";
|
|
12631
|
-
import { existsSync as
|
|
13219
|
+
import { existsSync as existsSync17, readdirSync as readdirSync12, statSync as statSync14 } from "fs";
|
|
12632
13220
|
import { join as join18 } from "path";
|
|
12633
13221
|
function sourceId(path) {
|
|
12634
13222
|
return "src_" + createHash3("sha256").update(path).digest("hex").slice(0, 12);
|
|
@@ -12687,7 +13275,7 @@ function countTranscripts(root, tool) {
|
|
|
12687
13275
|
walk(root, 0);
|
|
12688
13276
|
return { sessions, newestMtime };
|
|
12689
13277
|
}
|
|
12690
|
-
function
|
|
13278
|
+
function countDbSessions(dbPath) {
|
|
12691
13279
|
try {
|
|
12692
13280
|
const st = statSync14(dbPath);
|
|
12693
13281
|
return { sessions: 0, newestMtime: st.mtimeMs };
|
|
@@ -12705,18 +13293,24 @@ function discoverSessionSources() {
|
|
|
12705
13293
|
];
|
|
12706
13294
|
for (const [tool, dirs] of dirTools) {
|
|
12707
13295
|
for (const [i, path] of dirs.entries()) {
|
|
12708
|
-
if (!
|
|
13296
|
+
if (!existsSync17(path))
|
|
12709
13297
|
continue;
|
|
12710
13298
|
const { sessions, newestMtime } = countTranscripts(path, tool);
|
|
12711
13299
|
out.push({ id: sourceId(path), tool, path, sessions, newestMtime, isPrimary: i === 0 });
|
|
12712
13300
|
}
|
|
12713
13301
|
}
|
|
12714
13302
|
for (const [i, path] of opencodeDbPaths({ includeExcluded: true }).entries()) {
|
|
12715
|
-
if (!
|
|
13303
|
+
if (!existsSync17(path))
|
|
12716
13304
|
continue;
|
|
12717
|
-
const { sessions, newestMtime } =
|
|
13305
|
+
const { sessions, newestMtime } = countDbSessions(path);
|
|
12718
13306
|
out.push({ id: sourceId(path), tool: "opencode", path, sessions, newestMtime, isPrimary: i === 0 });
|
|
12719
13307
|
}
|
|
13308
|
+
for (const [i, path] of hermesDbPaths({ includeExcluded: true }).entries()) {
|
|
13309
|
+
if (!existsSync17(path))
|
|
13310
|
+
continue;
|
|
13311
|
+
const { sessions, newestMtime } = countDbSessions(path);
|
|
13312
|
+
out.push({ id: sourceId(path), tool: "hermes", path, sessions, newestMtime, isPrimary: i === 0 });
|
|
13313
|
+
}
|
|
12720
13314
|
return out;
|
|
12721
13315
|
}
|
|
12722
13316
|
var excludedIds, SOURCE_ID_RE, MAX_DEPTH;
|
|
@@ -12732,7 +13326,7 @@ var init_source_discovery = __esm({
|
|
|
12732
13326
|
|
|
12733
13327
|
// ../engine/dist/core/home-discovery.js
|
|
12734
13328
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
12735
|
-
import { existsSync as
|
|
13329
|
+
import { existsSync as existsSync18, readdirSync as readdirSync13, readFileSync as readFileSync12, realpathSync as realpathSync2, statSync as statSync15 } from "fs";
|
|
12736
13330
|
import { homedir as homedir5, platform as osPlatform } from "os";
|
|
12737
13331
|
import { join as join19 } from "path";
|
|
12738
13332
|
function candidateRoots(plat = osPlatform(), env = process.env) {
|
|
@@ -12753,10 +13347,10 @@ function candidateRoots(plat = osPlatform(), env = process.env) {
|
|
|
12753
13347
|
add(env.XDG_CONFIG_HOME || join19(home, ".config"));
|
|
12754
13348
|
add(env.XDG_DATA_HOME || join19(home, ".local", "share"));
|
|
12755
13349
|
}
|
|
12756
|
-
return roots.filter((r) =>
|
|
13350
|
+
return roots.filter((r) => existsSync18(r));
|
|
12757
13351
|
}
|
|
12758
13352
|
function identifyHome(dir) {
|
|
12759
|
-
const has = (...parts) =>
|
|
13353
|
+
const has = (...parts) => existsSync18(join19(dir, ...parts));
|
|
12760
13354
|
if (has("projects") && dirHasTranscript(join19(dir, "projects"), (f) => f.endsWith(".jsonl"), 2))
|
|
12761
13355
|
return "claude";
|
|
12762
13356
|
if (has("sessions") && dirHasTranscript(join19(dir, "sessions"), (f) => f.startsWith("rollout-") && f.endsWith(".jsonl"), 4))
|
|
@@ -12767,6 +13361,8 @@ function identifyHome(dir) {
|
|
|
12767
13361
|
return "cursor";
|
|
12768
13362
|
if (has("opencode.db"))
|
|
12769
13363
|
return "opencode";
|
|
13364
|
+
if (has("state.db") && has("SOUL.md"))
|
|
13365
|
+
return "hermes";
|
|
12770
13366
|
return null;
|
|
12771
13367
|
}
|
|
12772
13368
|
function dirHasTranscript(root, match, depth) {
|
|
@@ -12794,7 +13390,8 @@ function countSessions(dir, tool) {
|
|
|
12794
13390
|
codex: { sub: "sessions", depth: 4, match: (f) => f.startsWith("rollout-") && f.endsWith(".jsonl") },
|
|
12795
13391
|
agy: { sub: "brain", depth: 4, match: (f) => f.endsWith(".jsonl") },
|
|
12796
13392
|
cursor: { sub: "chats", depth: 3, match: (f) => f === "store.db" },
|
|
12797
|
-
opencode: { sub: "", depth: 0, match: () => false }
|
|
13393
|
+
opencode: { sub: "", depth: 0, match: () => false },
|
|
13394
|
+
hermes: { sub: "", depth: 0, match: () => false }
|
|
12798
13395
|
};
|
|
12799
13396
|
const s = spec[tool];
|
|
12800
13397
|
if (!s.sub)
|
|
@@ -12837,6 +13434,8 @@ function declaredHomes(env = process.env, plat = osPlatform()) {
|
|
|
12837
13434
|
add(env.CHAT_RECALL_AGY_HOME);
|
|
12838
13435
|
add(env.CHAT_RECALL_CURSOR_HOME);
|
|
12839
13436
|
add(env.CHAT_RECALL_CURSOR_IDE_HOME);
|
|
13437
|
+
add(env.CHAT_RECALL_HERMES_HOME);
|
|
13438
|
+
add(env.HERMES_HOME);
|
|
12840
13439
|
for (const d of (env.CLAUDE_DIRS || "").split(","))
|
|
12841
13440
|
add(d);
|
|
12842
13441
|
if (plat === "win32") {
|
|
@@ -12936,6 +13535,15 @@ function discoverHomes(opts = {}) {
|
|
|
12936
13535
|
if (prior && !(via === "declared" && prior.via !== "declared"))
|
|
12937
13536
|
return;
|
|
12938
13537
|
found.set(real, { tool, path: real, via, sessions: countSessions(real, tool) });
|
|
13538
|
+
if (tool === "hermes") {
|
|
13539
|
+
try {
|
|
13540
|
+
for (const e of readdirSync13(join19(real, "profiles"), { withFileTypes: true })) {
|
|
13541
|
+
if (e.isDirectory())
|
|
13542
|
+
consider(join19(real, "profiles", e.name), via);
|
|
13543
|
+
}
|
|
13544
|
+
} catch {
|
|
13545
|
+
}
|
|
13546
|
+
}
|
|
12939
13547
|
};
|
|
12940
13548
|
for (const d of declaredHomes(env, plat))
|
|
12941
13549
|
consider(d, "declared");
|
|
@@ -13002,7 +13610,7 @@ var init_home_discovery = __esm({
|
|
|
13002
13610
|
|
|
13003
13611
|
// ../engine/dist/core/detector-install.js
|
|
13004
13612
|
import { createHash as createHash4 } from "crypto";
|
|
13005
|
-
import { existsSync as
|
|
13613
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync5, mkdtempSync, chmodSync as chmodSync2, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync4, readFileSync as readFileSync13, statSync as statSync16, copyFileSync as copyFileSync2 } from "fs";
|
|
13006
13614
|
import { join as join20 } from "path";
|
|
13007
13615
|
function managedDetectorPath(name) {
|
|
13008
13616
|
return join20(getDetectorBinDir(), name + exeSuffix());
|
|
@@ -13042,7 +13650,7 @@ function resolveDetector(name) {
|
|
|
13042
13650
|
const dir = configuredDir();
|
|
13043
13651
|
if (dir) {
|
|
13044
13652
|
const p2 = join20(dir, name + exeSuffix());
|
|
13045
|
-
if (
|
|
13653
|
+
if (existsSync19(p2))
|
|
13046
13654
|
return { path: p2, version: "operator-supplied", source: "configured" };
|
|
13047
13655
|
return { error: "not-installed" };
|
|
13048
13656
|
}
|
|
@@ -13050,7 +13658,7 @@ function resolveDetector(name) {
|
|
|
13050
13658
|
if (!spec.assets[platformKey()])
|
|
13051
13659
|
return { error: "unsupported-platform" };
|
|
13052
13660
|
const p = managedDetectorPath(name);
|
|
13053
|
-
if (!
|
|
13661
|
+
if (!existsSync19(p))
|
|
13054
13662
|
return { error: "not-installed" };
|
|
13055
13663
|
const receipt = readReceipt(name);
|
|
13056
13664
|
if (!receipt)
|
|
@@ -13106,7 +13714,7 @@ var init_detector_install = __esm({
|
|
|
13106
13714
|
|
|
13107
13715
|
// ../engine/dist/core/secret-scanner.js
|
|
13108
13716
|
import { spawnSync } from "child_process";
|
|
13109
|
-
import { existsSync as
|
|
13717
|
+
import { existsSync as existsSync20, unlinkSync, readFileSync as readFileSync14, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "fs";
|
|
13110
13718
|
import { tmpdir } from "os";
|
|
13111
13719
|
import { join as join21 } from "path";
|
|
13112
13720
|
function mask(s) {
|
|
@@ -13272,7 +13880,7 @@ function runTrufflehogDir(binary, dir, opts = {}) {
|
|
|
13272
13880
|
return out;
|
|
13273
13881
|
}
|
|
13274
13882
|
function scanDirForSecrets(dir, opts = {}) {
|
|
13275
|
-
if (!
|
|
13883
|
+
if (!existsSync20(dir))
|
|
13276
13884
|
return [];
|
|
13277
13885
|
const gitleaks = whichDetector("gitleaks");
|
|
13278
13886
|
const trufflehog = whichDetector("trufflehog");
|
|
@@ -13309,7 +13917,7 @@ function scanTenantRules(text, tenantRules) {
|
|
|
13309
13917
|
return out;
|
|
13310
13918
|
}
|
|
13311
13919
|
function scanFileForSecrets(filePath, opts = {}) {
|
|
13312
|
-
if (!
|
|
13920
|
+
if (!existsSync20(filePath))
|
|
13313
13921
|
return [];
|
|
13314
13922
|
const gitleaks = whichDetector("gitleaks");
|
|
13315
13923
|
const trufflehog = whichDetector("trufflehog");
|
|
@@ -13426,10 +14034,10 @@ var init_types = __esm({
|
|
|
13426
14034
|
|
|
13427
14035
|
// ../engine/dist/transcript/opencode.js
|
|
13428
14036
|
async function parseOpenCodeSubagents(parentSessionId) {
|
|
13429
|
-
const { existsSync:
|
|
14037
|
+
const { existsSync: existsSync52 } = await import("fs");
|
|
13430
14038
|
const { opencodeBackend: opencodeBackend2 } = await Promise.resolve().then(() => (init_opencode(), opencode_exports));
|
|
13431
14039
|
const dbPath = opencodeBackend2.dbPath();
|
|
13432
|
-
if (!
|
|
14040
|
+
if (!existsSync52(dbPath))
|
|
13433
14041
|
return [];
|
|
13434
14042
|
const realParent = parentSessionId.replace("opencode_", "");
|
|
13435
14043
|
const db = openSqliteReadonlyOrThrow(dbPath);
|
|
@@ -13470,10 +14078,10 @@ async function parseOpenCodeSubagents(parentSessionId) {
|
|
|
13470
14078
|
}
|
|
13471
14079
|
}
|
|
13472
14080
|
async function parseOpenCodeTranscript(sessionId) {
|
|
13473
|
-
const { existsSync:
|
|
14081
|
+
const { existsSync: existsSync52 } = await import("fs");
|
|
13474
14082
|
const { opencodeBackend: opencodeBackend2 } = await Promise.resolve().then(() => (init_opencode(), opencode_exports));
|
|
13475
14083
|
const dbPath = opencodeBackend2.dbPath();
|
|
13476
|
-
if (!
|
|
14084
|
+
if (!existsSync52(dbPath))
|
|
13477
14085
|
return [];
|
|
13478
14086
|
const realId = sessionId.replace("opencode_", "");
|
|
13479
14087
|
const db = openSqliteReadonlyOrThrow(dbPath);
|
|
@@ -13525,6 +14133,7 @@ var init_opencode2 = __esm({
|
|
|
13525
14133
|
// ../engine/dist/transcript/index.js
|
|
13526
14134
|
var transcript_exports = {};
|
|
13527
14135
|
__export(transcript_exports, {
|
|
14136
|
+
RAW_PARSE_MAX_BYTES: () => RAW_PARSE_MAX_BYTES,
|
|
13528
14137
|
TRANSCRIPT_VERSION: () => TRANSCRIPT_VERSION,
|
|
13529
14138
|
archiveRawSession: () => archiveRawSession,
|
|
13530
14139
|
buildRawContainer: () => buildRawContainer,
|
|
@@ -13703,7 +14312,7 @@ var init_transcript = __esm({
|
|
|
13703
14312
|
// ../engine/dist/core/project-resolver.js
|
|
13704
14313
|
import { execSync } from "child_process";
|
|
13705
14314
|
import { createHash as createHash5 } from "crypto";
|
|
13706
|
-
import { existsSync as
|
|
14315
|
+
import { existsSync as existsSync21, readFileSync as readFileSync15, realpathSync as realpathSync3, readdirSync as readdirSync14, statSync as statSync18 } from "fs";
|
|
13707
14316
|
import { basename as basename11, dirname as dirname14, isAbsolute, join as join22, resolve, sep } from "path";
|
|
13708
14317
|
function getProjectsConfigPath() {
|
|
13709
14318
|
return join22(getDataDir(), "projects.json");
|
|
@@ -13713,7 +14322,7 @@ function loadProjectsConfig() {
|
|
|
13713
14322
|
return cachedConfig.cfg;
|
|
13714
14323
|
}
|
|
13715
14324
|
const path = getProjectsConfigPath();
|
|
13716
|
-
if (!
|
|
14325
|
+
if (!existsSync21(path)) {
|
|
13717
14326
|
cachedConfig = { mtime: 0, cfg: {} };
|
|
13718
14327
|
return cachedConfig.cfg;
|
|
13719
14328
|
}
|
|
@@ -13853,7 +14462,7 @@ function findGitToplevel(realPath) {
|
|
|
13853
14462
|
let cur = realPath;
|
|
13854
14463
|
let last = "";
|
|
13855
14464
|
while (cur && cur !== last) {
|
|
13856
|
-
if (
|
|
14465
|
+
if (existsSync21(join22(cur, ".git")))
|
|
13857
14466
|
return cur;
|
|
13858
14467
|
last = cur;
|
|
13859
14468
|
cur = dirname14(cur);
|
|
@@ -13920,7 +14529,7 @@ function resolveAutoWorkspace(realPath, minRepos) {
|
|
|
13920
14529
|
let last = "";
|
|
13921
14530
|
let depth = 0;
|
|
13922
14531
|
while (cur && cur !== last && depth < AUTO_WORKSPACE_MAX_DEPTH) {
|
|
13923
|
-
if (!
|
|
14532
|
+
if (!existsSync21(join22(cur, ".git"))) {
|
|
13924
14533
|
const cached = workspaceCache.get(cur);
|
|
13925
14534
|
let qualifies;
|
|
13926
14535
|
if (cached === void 0) {
|
|
@@ -13956,7 +14565,7 @@ function countGitChildren(dir) {
|
|
|
13956
14565
|
const st = statSync18(child);
|
|
13957
14566
|
if (!st.isDirectory())
|
|
13958
14567
|
continue;
|
|
13959
|
-
if (
|
|
14568
|
+
if (existsSync21(join22(child, ".git")))
|
|
13960
14569
|
count++;
|
|
13961
14570
|
} catch {
|
|
13962
14571
|
}
|
|
@@ -14569,7 +15178,7 @@ var init_source_policy = __esm({
|
|
|
14569
15178
|
init_project_path_match();
|
|
14570
15179
|
init_settings();
|
|
14571
15180
|
cache2 = null;
|
|
14572
|
-
TOOLS = ["claude", "opencode", "codex", "agy", "cursor"];
|
|
15181
|
+
TOOLS = ["claude", "opencode", "codex", "agy", "cursor", "hermes"];
|
|
14573
15182
|
}
|
|
14574
15183
|
});
|
|
14575
15184
|
|
|
@@ -14664,7 +15273,7 @@ var init_source_registry = __esm({
|
|
|
14664
15273
|
});
|
|
14665
15274
|
|
|
14666
15275
|
// ../engine/dist/core/utils.js
|
|
14667
|
-
import { existsSync as
|
|
15276
|
+
import { existsSync as existsSync22, readdirSync as readdirSync15 } from "fs";
|
|
14668
15277
|
import { homedir as homedir6 } from "os";
|
|
14669
15278
|
import { join as join23 } from "path";
|
|
14670
15279
|
function splitByHeaders(markdown) {
|
|
@@ -14700,7 +15309,7 @@ function getClaudeDirs() {
|
|
|
14700
15309
|
const dirs = [];
|
|
14701
15310
|
const seen = /* @__PURE__ */ new Set();
|
|
14702
15311
|
const add = (dir) => {
|
|
14703
|
-
if (!seen.has(dir) &&
|
|
15312
|
+
if (!seen.has(dir) && existsSync22(dir)) {
|
|
14704
15313
|
seen.add(dir);
|
|
14705
15314
|
dirs.push(dir);
|
|
14706
15315
|
}
|
|
@@ -14719,7 +15328,7 @@ function getClaudeDirs() {
|
|
|
14719
15328
|
for (const entry of entries) {
|
|
14720
15329
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
14721
15330
|
const candidate = join23(home, entry.name);
|
|
14722
|
-
if (
|
|
15331
|
+
if (existsSync22(join23(candidate, "projects"))) {
|
|
14723
15332
|
add(candidate);
|
|
14724
15333
|
}
|
|
14725
15334
|
}
|
|
@@ -14732,7 +15341,7 @@ function discoverSubdirs(subdir) {
|
|
|
14732
15341
|
const result = [];
|
|
14733
15342
|
for (const claudeDir of getClaudeDirs()) {
|
|
14734
15343
|
const path = join23(claudeDir, subdir);
|
|
14735
|
-
if (
|
|
15344
|
+
if (existsSync22(path)) {
|
|
14736
15345
|
result.push(path);
|
|
14737
15346
|
}
|
|
14738
15347
|
}
|
|
@@ -14745,7 +15354,7 @@ var init_utils = __esm({
|
|
|
14745
15354
|
});
|
|
14746
15355
|
|
|
14747
15356
|
// ../engine/dist/parsers/plan-source.js
|
|
14748
|
-
import { existsSync as
|
|
15357
|
+
import { existsSync as existsSync23, readdirSync as readdirSync16, readFileSync as readFileSync16, statSync as statSync20 } from "fs";
|
|
14749
15358
|
import { homedir as homedir7 } from "os";
|
|
14750
15359
|
import { join as join24, basename as basename12 } from "path";
|
|
14751
15360
|
function parseFrontmatter(content) {
|
|
@@ -14803,7 +15412,7 @@ var init_plan_source = __esm({
|
|
|
14803
15412
|
return this._knownProjectDirs;
|
|
14804
15413
|
const projectsDir = claudeBackend.projectsDir();
|
|
14805
15414
|
this._knownProjectDirs = [];
|
|
14806
|
-
if (!
|
|
15415
|
+
if (!existsSync23(projectsDir))
|
|
14807
15416
|
return this._knownProjectDirs;
|
|
14808
15417
|
try {
|
|
14809
15418
|
const entries = readdirSync16(projectsDir, { withFileTypes: true });
|
|
@@ -14811,7 +15420,7 @@ var init_plan_source = __esm({
|
|
|
14811
15420
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
14812
15421
|
continue;
|
|
14813
15422
|
const projectPath = resolveProjectDirName(entry.name);
|
|
14814
|
-
if (
|
|
15423
|
+
if (existsSync23(projectPath)) {
|
|
14815
15424
|
this._knownProjectDirs.push(projectPath);
|
|
14816
15425
|
}
|
|
14817
15426
|
}
|
|
@@ -14835,7 +15444,7 @@ var init_plan_source = __esm({
|
|
|
14835
15444
|
async *discoverClaudePlans() {
|
|
14836
15445
|
const seenClaude = /* @__PURE__ */ new Set();
|
|
14837
15446
|
for (const plansDir of this.plansDirs) {
|
|
14838
|
-
if (!
|
|
15447
|
+
if (!existsSync23(plansDir))
|
|
14839
15448
|
continue;
|
|
14840
15449
|
const files = readdirSync16(plansDir).filter((f) => f.endsWith(".md"));
|
|
14841
15450
|
for (const file of files) {
|
|
@@ -14877,7 +15486,7 @@ var init_plan_source = __esm({
|
|
|
14877
15486
|
}
|
|
14878
15487
|
async *discoverOpenCodePlans() {
|
|
14879
15488
|
const plansDir = opencodeBackend.plansDir();
|
|
14880
|
-
if (!
|
|
15489
|
+
if (!existsSync23(plansDir))
|
|
14881
15490
|
return;
|
|
14882
15491
|
let files;
|
|
14883
15492
|
try {
|
|
@@ -14964,7 +15573,7 @@ var init_plan_source = __esm({
|
|
|
14964
15573
|
return "";
|
|
14965
15574
|
}
|
|
14966
15575
|
async parse(item) {
|
|
14967
|
-
if (!
|
|
15576
|
+
if (!existsSync23(item.filePath))
|
|
14968
15577
|
return [];
|
|
14969
15578
|
const content = readFileSync16(item.filePath, "utf-8");
|
|
14970
15579
|
const chunks = [];
|
|
@@ -15005,7 +15614,7 @@ var init_plan_source = __esm({
|
|
|
15005
15614
|
const projPath = join24(root, proj);
|
|
15006
15615
|
for (const sessionEntry of safeReaddir(projPath)) {
|
|
15007
15616
|
const subDir = join24(projPath, sessionEntry, "subagents");
|
|
15008
|
-
if (!
|
|
15617
|
+
if (!existsSync23(subDir))
|
|
15009
15618
|
continue;
|
|
15010
15619
|
for (const f of safeReaddir(subDir)) {
|
|
15011
15620
|
const m = f.match(/^agent-([a-z0-9_-]+)\.jsonl$/i);
|
|
@@ -15080,7 +15689,7 @@ var init_plan_source = __esm({
|
|
|
15080
15689
|
}
|
|
15081
15690
|
async *discoverAgyPlans() {
|
|
15082
15691
|
const brainDir = join24(agyBackend.homeDir(), "brain");
|
|
15083
|
-
if (!
|
|
15692
|
+
if (!existsSync23(brainDir))
|
|
15084
15693
|
return;
|
|
15085
15694
|
let sessionDirs;
|
|
15086
15695
|
try {
|
|
@@ -15135,7 +15744,7 @@ var init_plan_source = __esm({
|
|
|
15135
15744
|
});
|
|
15136
15745
|
|
|
15137
15746
|
// ../engine/dist/parsers/task-source.js
|
|
15138
|
-
import { existsSync as
|
|
15747
|
+
import { existsSync as existsSync24, readdirSync as readdirSync17, readFileSync as readFileSync17, statSync as statSync21 } from "fs";
|
|
15139
15748
|
import { join as join25 } from "path";
|
|
15140
15749
|
var MAX_CHUNK_CHARS2, TaskSource;
|
|
15141
15750
|
var init_task_source = __esm({
|
|
@@ -15165,7 +15774,7 @@ var init_task_source = __esm({
|
|
|
15165
15774
|
}
|
|
15166
15775
|
async *discoverClaudeTodos() {
|
|
15167
15776
|
const todosDir = claudeBackend.todosDir();
|
|
15168
|
-
if (!
|
|
15777
|
+
if (!existsSync24(todosDir))
|
|
15169
15778
|
return;
|
|
15170
15779
|
let files;
|
|
15171
15780
|
try {
|
|
@@ -15216,7 +15825,7 @@ var init_task_source = __esm({
|
|
|
15216
15825
|
}
|
|
15217
15826
|
}
|
|
15218
15827
|
async *discoverInDir(tasksDir) {
|
|
15219
|
-
if (!
|
|
15828
|
+
if (!existsSync24(tasksDir))
|
|
15220
15829
|
return;
|
|
15221
15830
|
const entries = readdirSync17(tasksDir, { withFileTypes: true });
|
|
15222
15831
|
for (const entry of entries) {
|
|
@@ -15258,7 +15867,7 @@ var init_task_source = __esm({
|
|
|
15258
15867
|
return this.parseAgentTodo(item);
|
|
15259
15868
|
}
|
|
15260
15869
|
const taskDir = item.filePath;
|
|
15261
|
-
if (!
|
|
15870
|
+
if (!existsSync24(taskDir))
|
|
15262
15871
|
return [];
|
|
15263
15872
|
const taskFiles = readdirSync17(taskDir).filter((f) => f.endsWith(".json"));
|
|
15264
15873
|
const tasks = this.readTasks(taskDir, taskFiles);
|
|
@@ -15319,7 +15928,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15319
15928
|
}];
|
|
15320
15929
|
}
|
|
15321
15930
|
async parseAgentTodo(item) {
|
|
15322
|
-
if (!
|
|
15931
|
+
if (!existsSync24(item.filePath))
|
|
15323
15932
|
return [];
|
|
15324
15933
|
let parsed;
|
|
15325
15934
|
try {
|
|
@@ -15371,7 +15980,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15371
15980
|
});
|
|
15372
15981
|
|
|
15373
15982
|
// ../engine/dist/parsers/claude-md-source.js
|
|
15374
|
-
import { existsSync as
|
|
15983
|
+
import { existsSync as existsSync25, readFileSync as readFileSync18, readdirSync as readdirSync18, statSync as statSync22 } from "fs";
|
|
15375
15984
|
import { homedir as homedir8 } from "os";
|
|
15376
15985
|
import { join as join26, basename as basename13, dirname as dirname15 } from "path";
|
|
15377
15986
|
import { createHash as createHash6 } from "crypto";
|
|
@@ -15379,13 +15988,13 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15379
15988
|
const dirs = [];
|
|
15380
15989
|
const seen = /* @__PURE__ */ new Set();
|
|
15381
15990
|
const addProject = (path) => {
|
|
15382
|
-
if (!seen.has(path) &&
|
|
15991
|
+
if (!seen.has(path) && existsSync25(path)) {
|
|
15383
15992
|
seen.add(path);
|
|
15384
15993
|
dirs.push(path);
|
|
15385
15994
|
}
|
|
15386
15995
|
};
|
|
15387
15996
|
const scanProjectsDir = (projectsDir) => {
|
|
15388
|
-
if (!
|
|
15997
|
+
if (!existsSync25(projectsDir))
|
|
15389
15998
|
return;
|
|
15390
15999
|
try {
|
|
15391
16000
|
const entries = readdirSync18(projectsDir, { withFileTypes: true });
|
|
@@ -15413,7 +16022,7 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15413
16022
|
} catch {
|
|
15414
16023
|
}
|
|
15415
16024
|
const gemProjects = agyBackend.sharedProjectsJson();
|
|
15416
|
-
if (
|
|
16025
|
+
if (existsSync25(gemProjects)) {
|
|
15417
16026
|
try {
|
|
15418
16027
|
const data = JSON.parse(readFileSync18(gemProjects, "utf-8"));
|
|
15419
16028
|
for (const path of Object.keys(data.projects || {}))
|
|
@@ -15422,7 +16031,7 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15422
16031
|
}
|
|
15423
16032
|
}
|
|
15424
16033
|
const ocDb = opencodeBackend.dbPath();
|
|
15425
|
-
if (
|
|
16034
|
+
if (existsSync25(ocDb)) {
|
|
15426
16035
|
try {
|
|
15427
16036
|
const db = openSqliteReadonlyOrThrow(ocDb);
|
|
15428
16037
|
try {
|
|
@@ -15473,7 +16082,7 @@ var init_claude_md_source = __esm({
|
|
|
15473
16082
|
for (const note of NOTE_FILES) {
|
|
15474
16083
|
const p = join26(homedir8(), note.filename);
|
|
15475
16084
|
const key2 = seenKey(p, note.tool);
|
|
15476
|
-
if (
|
|
16085
|
+
if (existsSync25(p) && !seen.has(key2)) {
|
|
15477
16086
|
seen.add(key2);
|
|
15478
16087
|
const item = this.fileToItem(p, note.filename, note.tool);
|
|
15479
16088
|
if (item)
|
|
@@ -15485,7 +16094,7 @@ var init_claude_md_source = __esm({
|
|
|
15485
16094
|
for (const note of NOTE_FILES) {
|
|
15486
16095
|
const p = join26(projectDir, note.filename);
|
|
15487
16096
|
const key2 = seenKey(p, note.tool);
|
|
15488
|
-
if (
|
|
16097
|
+
if (existsSync25(p) && !seen.has(key2)) {
|
|
15489
16098
|
seen.add(key2);
|
|
15490
16099
|
const item = this.fileToItem(p, note.filename, note.tool);
|
|
15491
16100
|
if (item)
|
|
@@ -15494,12 +16103,12 @@ var init_claude_md_source = __esm({
|
|
|
15494
16103
|
}
|
|
15495
16104
|
}
|
|
15496
16105
|
for (const searchDir of this.searchDirs) {
|
|
15497
|
-
if (!
|
|
16106
|
+
if (!existsSync25(searchDir))
|
|
15498
16107
|
continue;
|
|
15499
16108
|
for (const note of NOTE_FILES) {
|
|
15500
16109
|
const directPath = join26(searchDir, note.filename);
|
|
15501
16110
|
const key2 = seenKey(directPath, note.tool);
|
|
15502
|
-
if (
|
|
16111
|
+
if (existsSync25(directPath) && !seen.has(key2)) {
|
|
15503
16112
|
seen.add(key2);
|
|
15504
16113
|
const item = this.fileToItem(directPath, note.filename, note.tool);
|
|
15505
16114
|
if (item)
|
|
@@ -15514,7 +16123,7 @@ var init_claude_md_source = __esm({
|
|
|
15514
16123
|
for (const note of NOTE_FILES) {
|
|
15515
16124
|
const p = join26(searchDir, entry.name, note.filename);
|
|
15516
16125
|
const key2 = seenKey(p, note.tool);
|
|
15517
|
-
if (
|
|
16126
|
+
if (existsSync25(p) && !seen.has(key2)) {
|
|
15518
16127
|
seen.add(key2);
|
|
15519
16128
|
const item = this.fileToItem(p, note.filename, note.tool);
|
|
15520
16129
|
if (item)
|
|
@@ -15528,7 +16137,7 @@ var init_claude_md_source = __esm({
|
|
|
15528
16137
|
}
|
|
15529
16138
|
}
|
|
15530
16139
|
async parse(item) {
|
|
15531
|
-
if (!
|
|
16140
|
+
if (!existsSync25(item.filePath))
|
|
15532
16141
|
return [];
|
|
15533
16142
|
const content = readFileSync18(item.filePath, "utf-8");
|
|
15534
16143
|
const chunks = [];
|
|
@@ -15597,7 +16206,7 @@ var init_claude_md_source = __esm({
|
|
|
15597
16206
|
});
|
|
15598
16207
|
|
|
15599
16208
|
// ../engine/dist/parsers/agent-memory-source.js
|
|
15600
|
-
import { existsSync as
|
|
16209
|
+
import { existsSync as existsSync26, readFileSync as readFileSync19, readdirSync as readdirSync19, statSync as statSync23 } from "fs";
|
|
15601
16210
|
import { homedir as homedir9 } from "os";
|
|
15602
16211
|
import { join as join27, basename as basename14 } from "path";
|
|
15603
16212
|
function parseFrontmatter2(content) {
|
|
@@ -15631,7 +16240,7 @@ function discoverMemoryDirs() {
|
|
|
15631
16240
|
const out = [];
|
|
15632
16241
|
const seen = /* @__PURE__ */ new Set();
|
|
15633
16242
|
const add = (memoryDir, projectHash) => {
|
|
15634
|
-
if (!seen.has(memoryDir) &&
|
|
16243
|
+
if (!seen.has(memoryDir) && existsSync26(memoryDir)) {
|
|
15635
16244
|
seen.add(memoryDir);
|
|
15636
16245
|
out.push({ memoryDir, projectHash });
|
|
15637
16246
|
}
|
|
@@ -15647,7 +16256,7 @@ function discoverMemoryDirs() {
|
|
|
15647
16256
|
} catch {
|
|
15648
16257
|
}
|
|
15649
16258
|
for (const projectsDir of claudeRoots) {
|
|
15650
|
-
if (!
|
|
16259
|
+
if (!existsSync26(projectsDir))
|
|
15651
16260
|
continue;
|
|
15652
16261
|
try {
|
|
15653
16262
|
for (const entry of readdirSync19(projectsDir, { withFileTypes: true })) {
|
|
@@ -15696,7 +16305,7 @@ var init_agent_memory_source = __esm({
|
|
|
15696
16305
|
}
|
|
15697
16306
|
}
|
|
15698
16307
|
async parse(item) {
|
|
15699
|
-
if (!
|
|
16308
|
+
if (!existsSync26(item.filePath))
|
|
15700
16309
|
return [];
|
|
15701
16310
|
const content = readFileSync19(item.filePath, "utf-8");
|
|
15702
16311
|
const { body } = parseFrontmatter2(content);
|
|
@@ -15782,7 +16391,7 @@ var init_agent_memory_source = __esm({
|
|
|
15782
16391
|
});
|
|
15783
16392
|
|
|
15784
16393
|
// ../engine/dist/parsers/history-source.js
|
|
15785
|
-
import { existsSync as
|
|
16394
|
+
import { existsSync as existsSync27, readdirSync as readdirSync20, statSync as statSync24 } from "fs";
|
|
15786
16395
|
import { createReadStream as createReadStream3 } from "fs";
|
|
15787
16396
|
import { createInterface as createInterface2 } from "readline";
|
|
15788
16397
|
import { homedir as homedir10 } from "os";
|
|
@@ -15804,7 +16413,7 @@ var init_history_source = __esm({
|
|
|
15804
16413
|
const home = homedir10();
|
|
15805
16414
|
const paths = [];
|
|
15806
16415
|
const tryAdd = (p) => {
|
|
15807
|
-
if (
|
|
16416
|
+
if (existsSync27(p) && !paths.includes(p))
|
|
15808
16417
|
paths.push(p);
|
|
15809
16418
|
};
|
|
15810
16419
|
tryAdd(claudeBackend.historyFile());
|
|
@@ -15822,7 +16431,7 @@ var init_history_source = __esm({
|
|
|
15822
16431
|
async *discover() {
|
|
15823
16432
|
if (!isSourceEnabled("claude", "history"))
|
|
15824
16433
|
return;
|
|
15825
|
-
const historyPath = this.historyPaths.find((p) =>
|
|
16434
|
+
const historyPath = this.historyPaths.find((p) => existsSync27(p));
|
|
15826
16435
|
if (!historyPath)
|
|
15827
16436
|
return;
|
|
15828
16437
|
const stat3 = statSync24(historyPath);
|
|
@@ -15918,7 +16527,7 @@ var init_history_source = __esm({
|
|
|
15918
16527
|
async groupByProject() {
|
|
15919
16528
|
const groups = /* @__PURE__ */ new Map();
|
|
15920
16529
|
for (const historyPath of this.historyPaths) {
|
|
15921
|
-
if (!
|
|
16530
|
+
if (!existsSync27(historyPath))
|
|
15922
16531
|
continue;
|
|
15923
16532
|
const rl = createInterface2({
|
|
15924
16533
|
input: createReadStream3(historyPath),
|
|
@@ -15966,7 +16575,7 @@ var init_history_source = __esm({
|
|
|
15966
16575
|
});
|
|
15967
16576
|
|
|
15968
16577
|
// ../engine/dist/parsers/paste-source.js
|
|
15969
|
-
import { existsSync as
|
|
16578
|
+
import { existsSync as existsSync28, readdirSync as readdirSync21, readFileSync as readFileSync20, statSync as statSync25 } from "fs";
|
|
15970
16579
|
import { homedir as homedir11 } from "os";
|
|
15971
16580
|
import { join as join29, basename as basename15 } from "path";
|
|
15972
16581
|
var MAX_CHUNK_CHARS6, MAX_FILE_SIZE, PasteSource;
|
|
@@ -15987,7 +16596,7 @@ var init_paste_source = __esm({
|
|
|
15987
16596
|
const home = homedir11();
|
|
15988
16597
|
const dirs = [];
|
|
15989
16598
|
const tryAdd = (p) => {
|
|
15990
|
-
if (
|
|
16599
|
+
if (existsSync28(p) && !dirs.includes(p))
|
|
15991
16600
|
dirs.push(p);
|
|
15992
16601
|
};
|
|
15993
16602
|
tryAdd(claudeBackend.pasteCacheDir());
|
|
@@ -16007,7 +16616,7 @@ var init_paste_source = __esm({
|
|
|
16007
16616
|
return;
|
|
16008
16617
|
const seen = /* @__PURE__ */ new Set();
|
|
16009
16618
|
for (const cacheDir of this.cacheDirs) {
|
|
16010
|
-
if (!
|
|
16619
|
+
if (!existsSync28(cacheDir))
|
|
16011
16620
|
continue;
|
|
16012
16621
|
const files = readdirSync21(cacheDir).filter((f) => f.endsWith(".txt"));
|
|
16013
16622
|
for (const file of files) {
|
|
@@ -16041,7 +16650,7 @@ var init_paste_source = __esm({
|
|
|
16041
16650
|
}
|
|
16042
16651
|
}
|
|
16043
16652
|
async parse(item) {
|
|
16044
|
-
if (!
|
|
16653
|
+
if (!existsSync28(item.filePath))
|
|
16045
16654
|
return [];
|
|
16046
16655
|
const content = readFileSync20(item.filePath, "utf-8");
|
|
16047
16656
|
if (content.trim().length < 20)
|
|
@@ -16066,7 +16675,7 @@ var init_paste_source = __esm({
|
|
|
16066
16675
|
});
|
|
16067
16676
|
|
|
16068
16677
|
// ../engine/dist/parsers/antigravity-brain-source.js
|
|
16069
|
-
import { existsSync as
|
|
16678
|
+
import { existsSync as existsSync29, readdirSync as readdirSync22, readFileSync as readFileSync21, statSync as statSync26 } from "fs";
|
|
16070
16679
|
import { join as join30 } from "path";
|
|
16071
16680
|
var MAX_CHUNK_CHARS7, AntigravityBrainSource;
|
|
16072
16681
|
var init_antigravity_brain_source = __esm({
|
|
@@ -16085,7 +16694,7 @@ var init_antigravity_brain_source = __esm({
|
|
|
16085
16694
|
async *discover() {
|
|
16086
16695
|
if (!isSourceEnabled("agy", "brain"))
|
|
16087
16696
|
return;
|
|
16088
|
-
if (!
|
|
16697
|
+
if (!existsSync29(this.brainDir))
|
|
16089
16698
|
return;
|
|
16090
16699
|
const sessions = readdirSync22(this.brainDir, { withFileTypes: true });
|
|
16091
16700
|
for (const entry of sessions) {
|
|
@@ -16104,7 +16713,7 @@ var init_antigravity_brain_source = __esm({
|
|
|
16104
16713
|
const heading = content.split("\n").find((l) => l.startsWith("#"))?.replace(/^#+\s*/, "").trim() || file;
|
|
16105
16714
|
const metaPath = `${filePath}.metadata.json`;
|
|
16106
16715
|
let metaSummary = "";
|
|
16107
|
-
if (
|
|
16716
|
+
if (existsSync29(metaPath)) {
|
|
16108
16717
|
try {
|
|
16109
16718
|
const meta = JSON.parse(readFileSync21(metaPath, "utf-8"));
|
|
16110
16719
|
metaSummary = meta.summary || "";
|
|
@@ -16135,7 +16744,7 @@ var init_antigravity_brain_source = __esm({
|
|
|
16135
16744
|
}
|
|
16136
16745
|
}
|
|
16137
16746
|
async parse(item) {
|
|
16138
|
-
if (!
|
|
16747
|
+
if (!existsSync29(item.filePath))
|
|
16139
16748
|
return [];
|
|
16140
16749
|
const content = readFileSync21(item.filePath, "utf-8");
|
|
16141
16750
|
const chunks = [];
|
|
@@ -16178,7 +16787,7 @@ var init_antigravity_brain_source = __esm({
|
|
|
16178
16787
|
});
|
|
16179
16788
|
|
|
16180
16789
|
// ../engine/dist/parsers/opencode-source.js
|
|
16181
|
-
import { existsSync as
|
|
16790
|
+
import { existsSync as existsSync30 } from "fs";
|
|
16182
16791
|
var MAX_CHUNK_CHARS8, OpenCodeSource;
|
|
16183
16792
|
var init_opencode_source = __esm({
|
|
16184
16793
|
"../engine/dist/parsers/opencode-source.js"() {
|
|
@@ -16196,7 +16805,7 @@ var init_opencode_source = __esm({
|
|
|
16196
16805
|
async *discover() {
|
|
16197
16806
|
if (!isSourceEnabled("opencode", "sessions"))
|
|
16198
16807
|
return;
|
|
16199
|
-
if (!
|
|
16808
|
+
if (!existsSync30(this.dbPath))
|
|
16200
16809
|
return;
|
|
16201
16810
|
let db;
|
|
16202
16811
|
try {
|
|
@@ -16294,7 +16903,7 @@ var init_opencode_source = __esm({
|
|
|
16294
16903
|
}
|
|
16295
16904
|
}
|
|
16296
16905
|
async parse(item) {
|
|
16297
|
-
if (!
|
|
16906
|
+
if (!existsSync30(this.dbPath))
|
|
16298
16907
|
return [];
|
|
16299
16908
|
const sessionId = item.id.replace("opencode_", "");
|
|
16300
16909
|
const db = openSqliteReadonlyOrThrow(this.dbPath);
|
|
@@ -16366,7 +16975,7 @@ var init_opencode_source = __esm({
|
|
|
16366
16975
|
});
|
|
16367
16976
|
|
|
16368
16977
|
// ../engine/dist/parsers/opencode-todo-source.js
|
|
16369
|
-
import { existsSync as
|
|
16978
|
+
import { existsSync as existsSync31 } from "fs";
|
|
16370
16979
|
var OpenCodeTodoSource;
|
|
16371
16980
|
var init_opencode_todo_source = __esm({
|
|
16372
16981
|
"../engine/dist/parsers/opencode-todo-source.js"() {
|
|
@@ -16383,7 +16992,7 @@ var init_opencode_todo_source = __esm({
|
|
|
16383
16992
|
async *discover() {
|
|
16384
16993
|
if (!isSourceEnabled("opencode", "todos"))
|
|
16385
16994
|
return;
|
|
16386
|
-
if (!
|
|
16995
|
+
if (!existsSync31(this.dbPath))
|
|
16387
16996
|
return;
|
|
16388
16997
|
let db;
|
|
16389
16998
|
try {
|
|
@@ -16432,7 +17041,7 @@ var init_opencode_todo_source = __esm({
|
|
|
16432
17041
|
}
|
|
16433
17042
|
}
|
|
16434
17043
|
async parse(item) {
|
|
16435
|
-
if (!
|
|
17044
|
+
if (!existsSync31(this.dbPath))
|
|
16436
17045
|
return [];
|
|
16437
17046
|
const sessionId = item.extra?.sessionId || item.id.replace(`${opencodeBackend.idPrefix}todo_`, "");
|
|
16438
17047
|
const db = openSqliteReadonlyOrThrow(this.dbPath);
|
|
@@ -16480,7 +17089,7 @@ var init_opencode_todo_source = __esm({
|
|
|
16480
17089
|
});
|
|
16481
17090
|
|
|
16482
17091
|
// ../engine/dist/parsers/codex-session-source.js
|
|
16483
|
-
import { existsSync as
|
|
17092
|
+
import { existsSync as existsSync32, readdirSync as readdirSync23, readFileSync as readFileSync22, statSync as statSync27 } from "fs";
|
|
16484
17093
|
import { join as join31, basename as basename16 } from "path";
|
|
16485
17094
|
function getCodexSessionsDir() {
|
|
16486
17095
|
return codexBackend.sessionsDir();
|
|
@@ -16537,7 +17146,7 @@ var init_codex_session_source = __esm({
|
|
|
16537
17146
|
async *discover() {
|
|
16538
17147
|
if (!isSourceEnabled("codex", "sessions"))
|
|
16539
17148
|
return;
|
|
16540
|
-
if (!
|
|
17149
|
+
if (!existsSync32(this.sessionsDir))
|
|
16541
17150
|
return;
|
|
16542
17151
|
const jsonlFiles = this.collectJsonlFiles(this.sessionsDir);
|
|
16543
17152
|
for (const filePath of jsonlFiles) {
|
|
@@ -16596,7 +17205,7 @@ var init_codex_session_source = __esm({
|
|
|
16596
17205
|
}
|
|
16597
17206
|
}
|
|
16598
17207
|
async parse(item) {
|
|
16599
|
-
if (!
|
|
17208
|
+
if (!existsSync32(item.filePath))
|
|
16600
17209
|
return [];
|
|
16601
17210
|
const events = readJsonlLines(item.filePath);
|
|
16602
17211
|
const chunks = [];
|
|
@@ -16699,7 +17308,7 @@ var init_codex_session_source = __esm({
|
|
|
16699
17308
|
}
|
|
16700
17309
|
collectJsonlFiles(dir) {
|
|
16701
17310
|
const results = [];
|
|
16702
|
-
if (!
|
|
17311
|
+
if (!existsSync32(dir))
|
|
16703
17312
|
return results;
|
|
16704
17313
|
for (const entry of readdirSync23(dir, { withFileTypes: true })) {
|
|
16705
17314
|
const fullPath = join31(dir, entry.name);
|
|
@@ -16716,7 +17325,7 @@ var init_codex_session_source = __esm({
|
|
|
16716
17325
|
});
|
|
16717
17326
|
|
|
16718
17327
|
// ../engine/dist/parsers/diary-source.js
|
|
16719
|
-
import { existsSync as
|
|
17328
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync6, readdirSync as readdirSync24, readFileSync as readFileSync23, writeFileSync as writeFileSync5, statSync as statSync28 } from "fs";
|
|
16720
17329
|
import { join as join32, basename as basename17 } from "path";
|
|
16721
17330
|
var MAX_CHUNK_CHARS10, DiarySource;
|
|
16722
17331
|
var init_diary_source = __esm({
|
|
@@ -16732,7 +17341,7 @@ var init_diary_source = __esm({
|
|
|
16732
17341
|
}
|
|
16733
17342
|
/** Discover all diary entries across all agents. */
|
|
16734
17343
|
async *discover() {
|
|
16735
|
-
if (!
|
|
17344
|
+
if (!existsSync33(this.diaryDir))
|
|
16736
17345
|
return;
|
|
16737
17346
|
const agents = readdirSync24(this.diaryDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
16738
17347
|
for (const agentDir of agents) {
|
|
@@ -16767,7 +17376,7 @@ var init_diary_source = __esm({
|
|
|
16767
17376
|
}
|
|
16768
17377
|
}
|
|
16769
17378
|
async parse(item) {
|
|
16770
|
-
if (!
|
|
17379
|
+
if (!existsSync33(item.filePath))
|
|
16771
17380
|
return [];
|
|
16772
17381
|
const raw = readFileSync23(item.filePath, "utf-8");
|
|
16773
17382
|
const entry = JSON.parse(raw);
|
|
@@ -16807,7 +17416,7 @@ var init_diary_source = __esm({
|
|
|
16807
17416
|
static write(entry, diaryDir) {
|
|
16808
17417
|
const dir = diaryDir || getDiaryDir();
|
|
16809
17418
|
const agentDir = join32(dir, entry.agent.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
|
|
16810
|
-
if (!
|
|
17419
|
+
if (!existsSync33(agentDir)) {
|
|
16811
17420
|
mkdirSync6(agentDir, { recursive: true });
|
|
16812
17421
|
}
|
|
16813
17422
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
@@ -16826,7 +17435,7 @@ var init_diary_source = __esm({
|
|
|
16826
17435
|
static read(agentName, lastN = 10, diaryDir) {
|
|
16827
17436
|
const dir = diaryDir || getDiaryDir();
|
|
16828
17437
|
const agentDir = join32(dir, agentName.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
|
|
16829
|
-
if (!
|
|
17438
|
+
if (!existsSync33(agentDir))
|
|
16830
17439
|
return [];
|
|
16831
17440
|
const files = readdirSync24(agentDir).filter((f) => f.endsWith(".json")).sort().reverse().slice(0, lastN);
|
|
16832
17441
|
const entries = [];
|
|
@@ -16877,7 +17486,7 @@ var init_redact_inline = __esm({
|
|
|
16877
17486
|
});
|
|
16878
17487
|
|
|
16879
17488
|
// ../engine/dist/parsers/skills-source.js
|
|
16880
|
-
import { existsSync as
|
|
17489
|
+
import { existsSync as existsSync34, readdirSync as readdirSync25, readFileSync as readFileSync24, statSync as statSync29 } from "fs";
|
|
16881
17490
|
import { homedir as homedir12 } from "os";
|
|
16882
17491
|
import { join as join33 } from "path";
|
|
16883
17492
|
function rebuildBody(content) {
|
|
@@ -16917,7 +17526,7 @@ function resolveRoots() {
|
|
|
16917
17526
|
all.push({ path: join33(cursorHomeDir(), "skills"), tool: "cursor" });
|
|
16918
17527
|
all.push({ path: join33(cursorHomeDir(), "skills-cursor"), tool: "cursor", readonly: true });
|
|
16919
17528
|
}
|
|
16920
|
-
return all.filter((r) =>
|
|
17529
|
+
return all.filter((r) => existsSync34(r.path));
|
|
16921
17530
|
}
|
|
16922
17531
|
function parseFrontmatter3(text) {
|
|
16923
17532
|
const m = text.match(/^---\n([\s\S]*?)\n---/);
|
|
@@ -16959,7 +17568,7 @@ var init_skills_source = __esm({
|
|
|
16959
17568
|
return;
|
|
16960
17569
|
for (const { name: pluginName, dir } of codexBackend.installedPluginDirs()) {
|
|
16961
17570
|
const skillsDir = join33(dir, "skills");
|
|
16962
|
-
if (!
|
|
17571
|
+
if (!existsSync34(skillsDir))
|
|
16963
17572
|
continue;
|
|
16964
17573
|
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
16965
17574
|
}
|
|
@@ -16984,7 +17593,7 @@ var init_skills_source = __esm({
|
|
|
16984
17593
|
if (!st.isDirectory())
|
|
16985
17594
|
continue;
|
|
16986
17595
|
const skillMd = join33(skillDir, "SKILL.md");
|
|
16987
|
-
if (!
|
|
17596
|
+
if (!existsSync34(skillMd))
|
|
16988
17597
|
continue;
|
|
16989
17598
|
let content;
|
|
16990
17599
|
try {
|
|
@@ -17049,7 +17658,7 @@ var init_skills_source = __esm({
|
|
|
17049
17658
|
}
|
|
17050
17659
|
}
|
|
17051
17660
|
async parse(item) {
|
|
17052
|
-
if (!
|
|
17661
|
+
if (!existsSync34(item.filePath))
|
|
17053
17662
|
return [];
|
|
17054
17663
|
const content = readFileSync24(item.filePath, "utf-8");
|
|
17055
17664
|
if (!content.trim())
|
|
@@ -17074,11 +17683,11 @@ var init_skills_source = __esm({
|
|
|
17074
17683
|
});
|
|
17075
17684
|
|
|
17076
17685
|
// ../engine/dist/parsers/mcps-source.js
|
|
17077
|
-
import { existsSync as
|
|
17686
|
+
import { existsSync as existsSync35, readFileSync as readFileSync25, statSync as statSync30 } from "fs";
|
|
17078
17687
|
import { homedir as homedir13 } from "os";
|
|
17079
17688
|
import { join as join34 } from "path";
|
|
17080
17689
|
function readJson(path) {
|
|
17081
|
-
if (!
|
|
17690
|
+
if (!existsSync35(path))
|
|
17082
17691
|
return null;
|
|
17083
17692
|
try {
|
|
17084
17693
|
const raw = readFileSync25(path, "utf-8");
|
|
@@ -17241,7 +17850,7 @@ var init_mcps_source = __esm({
|
|
|
17241
17850
|
}
|
|
17242
17851
|
}
|
|
17243
17852
|
async *fromCodexToml(path) {
|
|
17244
|
-
if (!
|
|
17853
|
+
if (!existsSync35(path))
|
|
17245
17854
|
return;
|
|
17246
17855
|
let content;
|
|
17247
17856
|
try {
|
|
@@ -17414,7 +18023,7 @@ var init_toolkit_format = __esm({
|
|
|
17414
18023
|
});
|
|
17415
18024
|
|
|
17416
18025
|
// ../engine/dist/parsers/slash-commands-source.js
|
|
17417
|
-
import { existsSync as
|
|
18026
|
+
import { existsSync as existsSync36, readdirSync as readdirSync26, readFileSync as readFileSync26, statSync as statSync31 } from "fs";
|
|
17418
18027
|
import { join as join35, basename as basename18 } from "path";
|
|
17419
18028
|
function rebuildBody2(content) {
|
|
17420
18029
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17467,14 +18076,14 @@ var init_slash_commands_source = __esm({
|
|
|
17467
18076
|
if (isSourceEnabled("claude", "commands")) {
|
|
17468
18077
|
roots.push({ path: claudeBackend.commandsDir(), tool: "claude", scope: "user", projectPath: "", format: "md" });
|
|
17469
18078
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17470
|
-
if (
|
|
18079
|
+
if (existsSync36(projectsRoot)) {
|
|
17471
18080
|
try {
|
|
17472
18081
|
for (const entry of readdirSync26(projectsRoot, { withFileTypes: true })) {
|
|
17473
18082
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17474
18083
|
continue;
|
|
17475
18084
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17476
18085
|
const cmdDir = join35(projectPath, ".claude", "commands");
|
|
17477
|
-
if (
|
|
18086
|
+
if (existsSync36(cmdDir))
|
|
17478
18087
|
roots.push({ path: cmdDir, tool: "claude", scope: "project", projectPath, format: "md" });
|
|
17479
18088
|
}
|
|
17480
18089
|
} catch {
|
|
@@ -17536,7 +18145,7 @@ var init_slash_commands_source = __esm({
|
|
|
17536
18145
|
}
|
|
17537
18146
|
}
|
|
17538
18147
|
async parse(item) {
|
|
17539
|
-
if (!
|
|
18148
|
+
if (!existsSync36(item.filePath))
|
|
17540
18149
|
return [];
|
|
17541
18150
|
const content = readFileSync26(item.filePath, "utf-8");
|
|
17542
18151
|
if (!content.trim())
|
|
@@ -17561,7 +18170,7 @@ var init_slash_commands_source = __esm({
|
|
|
17561
18170
|
});
|
|
17562
18171
|
|
|
17563
18172
|
// ../engine/dist/parsers/subagents-source.js
|
|
17564
|
-
import { existsSync as
|
|
18173
|
+
import { existsSync as existsSync37, readdirSync as readdirSync27, readFileSync as readFileSync27, statSync as statSync32 } from "fs";
|
|
17565
18174
|
import { join as join36, basename as basename19 } from "path";
|
|
17566
18175
|
function rebuildBody3(content) {
|
|
17567
18176
|
const { text, redacted } = redactInlineSecrets(content);
|
|
@@ -17616,14 +18225,14 @@ var init_subagents_source = __esm({
|
|
|
17616
18225
|
if (isSourceEnabled("claude", "agents")) {
|
|
17617
18226
|
roots.push({ path: claudeBackend.agentsDir(), tool: "claude", scope: "user", projectPath: "", format: "md" });
|
|
17618
18227
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17619
|
-
if (
|
|
18228
|
+
if (existsSync37(projectsRoot)) {
|
|
17620
18229
|
try {
|
|
17621
18230
|
for (const entry of readdirSync27(projectsRoot, { withFileTypes: true })) {
|
|
17622
18231
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17623
18232
|
continue;
|
|
17624
18233
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17625
18234
|
const agentDir = join36(projectPath, ".claude", "agents");
|
|
17626
|
-
if (
|
|
18235
|
+
if (existsSync37(agentDir))
|
|
17627
18236
|
roots.push({ path: agentDir, tool: "claude", scope: "project", projectPath, format: "md" });
|
|
17628
18237
|
}
|
|
17629
18238
|
} catch {
|
|
@@ -17686,7 +18295,7 @@ var init_subagents_source = __esm({
|
|
|
17686
18295
|
}
|
|
17687
18296
|
}
|
|
17688
18297
|
async parse(item) {
|
|
17689
|
-
if (!
|
|
18298
|
+
if (!existsSync37(item.filePath))
|
|
17690
18299
|
return [];
|
|
17691
18300
|
const content = readFileSync27(item.filePath, "utf-8");
|
|
17692
18301
|
if (!content.trim())
|
|
@@ -17711,10 +18320,10 @@ var init_subagents_source = __esm({
|
|
|
17711
18320
|
});
|
|
17712
18321
|
|
|
17713
18322
|
// ../engine/dist/parsers/hooks-source.js
|
|
17714
|
-
import { existsSync as
|
|
18323
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28, readdirSync as readdirSync28, statSync as statSync33 } from "fs";
|
|
17715
18324
|
import { join as join37 } from "path";
|
|
17716
18325
|
function readJson2(path) {
|
|
17717
|
-
if (!
|
|
18326
|
+
if (!existsSync38(path))
|
|
17718
18327
|
return null;
|
|
17719
18328
|
try {
|
|
17720
18329
|
return JSON.parse(readFileSync28(path, "utf-8"));
|
|
@@ -17736,14 +18345,14 @@ var init_hooks_source = __esm({
|
|
|
17736
18345
|
return;
|
|
17737
18346
|
yield* this.fromSettings(claudeBackend.settingsFile(), "user", "");
|
|
17738
18347
|
const projectsRoot = claudeBackend.projectsDir();
|
|
17739
|
-
if (
|
|
18348
|
+
if (existsSync38(projectsRoot)) {
|
|
17740
18349
|
try {
|
|
17741
18350
|
for (const entry of readdirSync28(projectsRoot, { withFileTypes: true })) {
|
|
17742
18351
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17743
18352
|
continue;
|
|
17744
18353
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17745
18354
|
const settingsPath2 = join37(projectPath, ".claude", "settings.json");
|
|
17746
|
-
if (
|
|
18355
|
+
if (existsSync38(settingsPath2)) {
|
|
17747
18356
|
yield* this.fromSettings(settingsPath2, "project", projectPath);
|
|
17748
18357
|
}
|
|
17749
18358
|
}
|
|
@@ -17834,11 +18443,11 @@ var init_hooks_source = __esm({
|
|
|
17834
18443
|
});
|
|
17835
18444
|
|
|
17836
18445
|
// ../engine/dist/parsers/plugins-source.js
|
|
17837
|
-
import { existsSync as
|
|
18446
|
+
import { existsSync as existsSync39, readFileSync as readFileSync29, readdirSync as readdirSync29, statSync as statSync34 } from "fs";
|
|
17838
18447
|
import { homedir as homedir14 } from "os";
|
|
17839
18448
|
import { join as join38 } from "path";
|
|
17840
18449
|
function readJson3(path) {
|
|
17841
|
-
if (!
|
|
18450
|
+
if (!existsSync39(path))
|
|
17842
18451
|
return null;
|
|
17843
18452
|
try {
|
|
17844
18453
|
return JSON.parse(readFileSync29(path, "utf-8"));
|
|
@@ -17893,7 +18502,7 @@ var init_plugins_source = __esm({
|
|
|
17893
18502
|
}
|
|
17894
18503
|
}
|
|
17895
18504
|
const gemRoot = agyBackend.sharedExtensionsDir();
|
|
17896
|
-
if (isSourceEnabled("agy", "extensions") &&
|
|
18505
|
+
if (isSourceEnabled("agy", "extensions") && existsSync39(gemRoot)) {
|
|
17897
18506
|
let entries;
|
|
17898
18507
|
try {
|
|
17899
18508
|
entries = readdirSync29(gemRoot);
|
|
@@ -18069,6 +18678,8 @@ function toolOfId(id) {
|
|
|
18069
18678
|
return "codex";
|
|
18070
18679
|
if (id.startsWith("cursor_"))
|
|
18071
18680
|
return "cursor";
|
|
18681
|
+
if (id.startsWith("hermes_"))
|
|
18682
|
+
return "hermes";
|
|
18072
18683
|
return "claude";
|
|
18073
18684
|
}
|
|
18074
18685
|
function extractorVersionForTool(tool) {
|
|
@@ -18104,12 +18715,15 @@ var init_extractor_version = __esm({
|
|
|
18104
18715
|
// src/sync-ledger.ts
|
|
18105
18716
|
var sync_ledger_exports = {};
|
|
18106
18717
|
__export(sync_ledger_exports, {
|
|
18718
|
+
SETTLE_QUIET_MS: () => SETTLE_QUIET_MS,
|
|
18107
18719
|
_resetLedgerCacheForTests: () => _resetLedgerCacheForTests,
|
|
18108
18720
|
_resetUnackedCursorCount: () => _resetUnackedCursorCount,
|
|
18109
18721
|
fieldNeedsFullPass: () => fieldNeedsFullPass,
|
|
18110
18722
|
fieldNeedsScan: () => fieldNeedsScan,
|
|
18111
18723
|
flushLedger: () => flushLedger,
|
|
18112
18724
|
forceFieldRescan: () => forceFieldRescan,
|
|
18725
|
+
forgetFullCoverage: () => forgetFullCoverage,
|
|
18726
|
+
fullCoveredOffset: () => fullCoveredOffset,
|
|
18113
18727
|
getLedgerData: () => getLedgerData,
|
|
18114
18728
|
getSyncedMtimes: () => getSyncedMtimes,
|
|
18115
18729
|
getSyncedRows: () => getSyncedRows,
|
|
@@ -18361,6 +18975,13 @@ function markSynced(server, rows) {
|
|
|
18361
18975
|
base3.s = s;
|
|
18362
18976
|
}
|
|
18363
18977
|
if (r.hash !== void 0) base3.h = r.hash;
|
|
18978
|
+
const completesChunked = cursorFromCaller && r.chunkFinal === true && prev?.k === 1;
|
|
18979
|
+
if (cursorFromCaller && (r.full || completesChunked) && o > 0) base3.F = o;
|
|
18980
|
+
else if (prev?.F !== void 0) base3.F = prev.F;
|
|
18981
|
+
if (cursorFromCaller && r.chunkedHead) base3.k = 1;
|
|
18982
|
+
else if (prev?.k && !completesChunked && !(cursorFromCaller && r.full)) base3.k = 1;
|
|
18983
|
+
const layout = cursorFromCaller ? r.layout : prev?.L;
|
|
18984
|
+
if (layout) base3.L = layout;
|
|
18364
18985
|
forServer[r.id] = base3;
|
|
18365
18986
|
}
|
|
18366
18987
|
persist(data);
|
|
@@ -18434,6 +19055,14 @@ function _resetLedgerCacheForTests() {
|
|
|
18434
19055
|
diskStamp = null;
|
|
18435
19056
|
reconcileCache = null;
|
|
18436
19057
|
}
|
|
19058
|
+
function forgetFullCoverage(server, sessionId) {
|
|
19059
|
+
const data = load();
|
|
19060
|
+
const row = data[server]?.[sessionId];
|
|
19061
|
+
if (!row || typeof row !== "object") return;
|
|
19062
|
+
delete row.F;
|
|
19063
|
+
delete row.h;
|
|
19064
|
+
persist(data);
|
|
19065
|
+
}
|
|
18437
19066
|
function markFullResync(server, sessionId) {
|
|
18438
19067
|
const data = load();
|
|
18439
19068
|
const forServer = data[server];
|
|
@@ -18442,7 +19071,11 @@ function markFullResync(server, sessionId) {
|
|
|
18442
19071
|
delete forServer[sessionId];
|
|
18443
19072
|
persist(data);
|
|
18444
19073
|
}
|
|
18445
|
-
function
|
|
19074
|
+
function fullCoveredOffset(row) {
|
|
19075
|
+
if (row.F !== void 0) return row.F;
|
|
19076
|
+
return row.h ? row.s ?? 0 : 0;
|
|
19077
|
+
}
|
|
19078
|
+
function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly, nowMs = Date.now()) {
|
|
18446
19079
|
if (!row) return "full";
|
|
18447
19080
|
if (row.v < extractorVersion) return "full";
|
|
18448
19081
|
const offset = row.o ?? 0;
|
|
@@ -18450,10 +19083,13 @@ function syncMode(row, mtime, fileSize, extractorVersion, isAppendOnly) {
|
|
|
18450
19083
|
if (process.env.CHAT_RECALL_TAIL_APPEND !== "0" && isAppendOnly && fileSize > 0 && offset > 0 && fileSize > (row.s ?? 0)) {
|
|
18451
19084
|
return "append";
|
|
18452
19085
|
}
|
|
19086
|
+
if (isAppendOnly && offset > 0 && fileSize > 0 && fileSize === (row.s ?? 0) && !row.k && fullCoveredOffset(row) < offset && nowMs - Math.floor(mtime) >= SETTLE_QUIET_MS) {
|
|
19087
|
+
return "full";
|
|
19088
|
+
}
|
|
18453
19089
|
if (row.m >= Math.floor(mtime)) return "skip";
|
|
18454
19090
|
return "full";
|
|
18455
19091
|
}
|
|
18456
|
-
var ledgerPath, cache3, base, diskStamp, rowKey, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache;
|
|
19092
|
+
var ledgerPath, cache3, base, diskStamp, rowKey, LEDGER_FLUSH_MS, pendingWrite, flushTimer, itemVersionsPath, itemVersionsCache, inventoryPath, unackedCursorAttempts, reconcilePath, reconcileCache, SETTLE_QUIET_MS;
|
|
18457
19093
|
var init_sync_ledger = __esm({
|
|
18458
19094
|
"src/sync-ledger.ts"() {
|
|
18459
19095
|
"use strict";
|
|
@@ -18473,6 +19109,7 @@ var init_sync_ledger = __esm({
|
|
|
18473
19109
|
unackedCursorAttempts = 0;
|
|
18474
19110
|
reconcilePath = () => join39(getDataDir(), "sync-field-reconcile.json");
|
|
18475
19111
|
reconcileCache = null;
|
|
19112
|
+
SETTLE_QUIET_MS = 2 * 60 * 60 * 1e3;
|
|
18476
19113
|
}
|
|
18477
19114
|
});
|
|
18478
19115
|
|
|
@@ -18502,12 +19139,12 @@ var init_sync_fields = __esm({
|
|
|
18502
19139
|
});
|
|
18503
19140
|
|
|
18504
19141
|
// ../engine/dist/core/index-lock.js
|
|
18505
|
-
import { existsSync as
|
|
19142
|
+
import { existsSync as existsSync40, mkdirSync as mkdirSync8, openSync as openSync8, writeFileSync as writeFileSync7, readFileSync as readFileSync31, rmSync as rmSync4, statSync as statSync36, closeSync as closeSync8 } from "fs";
|
|
18506
19143
|
import { dirname as dirname17, join as join40 } from "path";
|
|
18507
19144
|
function acquireIndexLock(opts) {
|
|
18508
19145
|
const lockPath = lockFilePath(opts.file);
|
|
18509
19146
|
mkdirSync8(dirname17(lockPath), { recursive: true });
|
|
18510
|
-
if (
|
|
19147
|
+
if (existsSync40(lockPath)) {
|
|
18511
19148
|
if (!stealStaleLock(lockPath, opts.staleAfterMs ?? 10 * 6e4)) {
|
|
18512
19149
|
return null;
|
|
18513
19150
|
}
|
|
@@ -18615,7 +19252,7 @@ var init_http = __esm({
|
|
|
18615
19252
|
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18616
19253
|
} catch {
|
|
18617
19254
|
try {
|
|
18618
|
-
if (true) CLI_VERSION = "0.7.
|
|
19255
|
+
if (true) CLI_VERSION = "0.7.19";
|
|
18619
19256
|
} catch {
|
|
18620
19257
|
}
|
|
18621
19258
|
}
|
|
@@ -18712,7 +19349,7 @@ var init_derived = __esm({
|
|
|
18712
19349
|
|
|
18713
19350
|
// src/scan-pool.ts
|
|
18714
19351
|
import { Worker } from "node:worker_threads";
|
|
18715
|
-
import { existsSync as
|
|
19352
|
+
import { existsSync as existsSync41 } from "node:fs";
|
|
18716
19353
|
import { fileURLToPath } from "node:url";
|
|
18717
19354
|
import { cpus } from "node:os";
|
|
18718
19355
|
function poolSize() {
|
|
@@ -18727,7 +19364,7 @@ function workerScript() {
|
|
|
18727
19364
|
for (const rel of ["./scan-worker.js", "../dist/scan-worker.js"]) {
|
|
18728
19365
|
try {
|
|
18729
19366
|
const p = fileURLToPath(new URL(rel, import.meta.url));
|
|
18730
|
-
if (
|
|
19367
|
+
if (existsSync41(p)) return p;
|
|
18731
19368
|
} catch {
|
|
18732
19369
|
}
|
|
18733
19370
|
}
|
|
@@ -19109,7 +19746,7 @@ var init_telemetry = __esm({
|
|
|
19109
19746
|
init_sync_client();
|
|
19110
19747
|
cliVersion = () => {
|
|
19111
19748
|
try {
|
|
19112
|
-
return true ? "0.7.
|
|
19749
|
+
return true ? "0.7.19" : "dev";
|
|
19113
19750
|
} catch {
|
|
19114
19751
|
return "dev";
|
|
19115
19752
|
}
|
|
@@ -19119,6 +19756,150 @@ var init_telemetry = __esm({
|
|
|
19119
19756
|
}
|
|
19120
19757
|
});
|
|
19121
19758
|
|
|
19759
|
+
// src/raw-archive-parts.ts
|
|
19760
|
+
import { createReadStream as createReadStream4, createWriteStream, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, rmSync as rmSync5, statSync as statSync37 } from "node:fs";
|
|
19761
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
19762
|
+
import { join as join41 } from "node:path";
|
|
19763
|
+
import { randomBytes } from "node:crypto";
|
|
19764
|
+
import { createGzip } from "node:zlib";
|
|
19765
|
+
import { once } from "node:events";
|
|
19766
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
19767
|
+
async function* fileLines(path) {
|
|
19768
|
+
let rest = "";
|
|
19769
|
+
const decoder = new TextDecoder("utf-8");
|
|
19770
|
+
for await (const chunk of createReadStream4(path, { highWaterMark: 1024 * 1024 })) {
|
|
19771
|
+
rest += decoder.decode(chunk, { stream: true });
|
|
19772
|
+
let nl = rest.indexOf("\n");
|
|
19773
|
+
while (nl >= 0) {
|
|
19774
|
+
yield rest.slice(0, nl + 1);
|
|
19775
|
+
rest = rest.slice(nl + 1);
|
|
19776
|
+
nl = rest.indexOf("\n");
|
|
19777
|
+
}
|
|
19778
|
+
}
|
|
19779
|
+
rest += decoder.decode();
|
|
19780
|
+
if (rest) yield rest;
|
|
19781
|
+
}
|
|
19782
|
+
function* textLines(text) {
|
|
19783
|
+
let at = 0;
|
|
19784
|
+
while (at < text.length) {
|
|
19785
|
+
const nl = text.indexOf("\n", at);
|
|
19786
|
+
const end = nl < 0 ? text.length : nl + 1;
|
|
19787
|
+
yield text.slice(at, end);
|
|
19788
|
+
at = end;
|
|
19789
|
+
}
|
|
19790
|
+
}
|
|
19791
|
+
async function writeArchiveFile(source, meta, redact, dir = tmpdir2()) {
|
|
19792
|
+
const path = join41(dir, `cr-archive-${randomBytes(8).toString("hex")}.json.gz`);
|
|
19793
|
+
const gzip = createGzip({ level: 6 });
|
|
19794
|
+
const out = createWriteStream(path, { mode: 384 });
|
|
19795
|
+
const done = once(out, "finish");
|
|
19796
|
+
gzip.pipe(out);
|
|
19797
|
+
let size = 0;
|
|
19798
|
+
const write = async (s) => {
|
|
19799
|
+
size += Buffer.byteLength(s);
|
|
19800
|
+
if (!gzip.write(s)) await once(gzip, "drain");
|
|
19801
|
+
};
|
|
19802
|
+
try {
|
|
19803
|
+
await write(`{"v":1,"tool":${JSON.stringify(meta.tool)},"mtime":${Math.floor(meta.mtime)},"files":[`);
|
|
19804
|
+
for (const [i, f] of source.files.entries()) {
|
|
19805
|
+
await write(`${i ? "," : ""}{"name":${JSON.stringify(f.name)},"text":"`);
|
|
19806
|
+
const whole = () => source.kind === "memory" ? f.text : readFileSync33(f.path, "utf-8");
|
|
19807
|
+
if (!f.name.endsWith(".jsonl")) {
|
|
19808
|
+
await write(escapeJson(redact(whole())));
|
|
19809
|
+
} else {
|
|
19810
|
+
const lines = source.kind === "memory" ? textLines(f.text) : fileLines(f.path);
|
|
19811
|
+
for await (const line of lines) {
|
|
19812
|
+
const nl = line.endsWith("\n");
|
|
19813
|
+
const body = nl ? line.slice(0, -1) : line;
|
|
19814
|
+
await write(escapeJson((body ? redactJsonLine(body, redact) : body) + (nl ? "\n" : "")));
|
|
19815
|
+
}
|
|
19816
|
+
}
|
|
19817
|
+
await write('"}');
|
|
19818
|
+
}
|
|
19819
|
+
await write("]}");
|
|
19820
|
+
gzip.end();
|
|
19821
|
+
await done;
|
|
19822
|
+
} catch (err) {
|
|
19823
|
+
gzip.destroy();
|
|
19824
|
+
out.destroy();
|
|
19825
|
+
rmSync5(path, { force: true });
|
|
19826
|
+
throw err;
|
|
19827
|
+
}
|
|
19828
|
+
return { path, gzSize: statSync37(path).size, size };
|
|
19829
|
+
}
|
|
19830
|
+
async function putPart(url, body) {
|
|
19831
|
+
let last;
|
|
19832
|
+
for (let attempt = 1; attempt <= PART_ATTEMPTS; attempt++) {
|
|
19833
|
+
const ac = new AbortController();
|
|
19834
|
+
const timer = setTimeout(() => ac.abort(), PART_TIMEOUT_MS);
|
|
19835
|
+
try {
|
|
19836
|
+
const r = await fetch(url, { method: "PUT", body, signal: ac.signal });
|
|
19837
|
+
const etag = r.headers.get("etag");
|
|
19838
|
+
if (r.ok && etag) return etag;
|
|
19839
|
+
last = new Error(`part PUT answered ${r.status}`);
|
|
19840
|
+
if (r.status === 403 || r.status === 404) break;
|
|
19841
|
+
} catch (err) {
|
|
19842
|
+
last = err;
|
|
19843
|
+
} finally {
|
|
19844
|
+
clearTimeout(timer);
|
|
19845
|
+
}
|
|
19846
|
+
}
|
|
19847
|
+
throw last instanceof Error ? last : new Error(String(last));
|
|
19848
|
+
}
|
|
19849
|
+
async function uploadArchiveFile(base3, token, args) {
|
|
19850
|
+
const headers = { "content-type": "application/json" };
|
|
19851
|
+
if (token) headers.authorization = `Bearer ${token}`;
|
|
19852
|
+
const post = async (path, body) => {
|
|
19853
|
+
const r = await fetch(`${base3}/api/sync/raw-upload/${path}`, { method: "POST", headers, body: JSON.stringify(body) });
|
|
19854
|
+
const json = await r.json().catch(() => ({}));
|
|
19855
|
+
return { status: r.status, json };
|
|
19856
|
+
};
|
|
19857
|
+
const start = await post("start", {
|
|
19858
|
+
session_id: args.sessionId,
|
|
19859
|
+
tool: args.tool,
|
|
19860
|
+
mtime: Math.floor(args.mtime),
|
|
19861
|
+
size: args.file.size,
|
|
19862
|
+
gz_size: args.file.gzSize,
|
|
19863
|
+
project_id: args.projectId,
|
|
19864
|
+
project_path: args.projectPath
|
|
19865
|
+
});
|
|
19866
|
+
if (start.status === 501 || start.status === 404) return "unsupported";
|
|
19867
|
+
if (start.status !== 200) throw new Error(`raw upload start answered ${start.status}: ${start.json.error ?? ""}`);
|
|
19868
|
+
if (start.json.result === "unchanged" || start.json.result === "shrink-protected") return start.json.result;
|
|
19869
|
+
const urls = start.json.urls;
|
|
19870
|
+
const partBytes = Number(start.json.part_bytes);
|
|
19871
|
+
const parts = [];
|
|
19872
|
+
const fd = openSync9(args.file.path, "r");
|
|
19873
|
+
try {
|
|
19874
|
+
for (const [i, url] of urls.entries()) {
|
|
19875
|
+
const len = Math.min(partBytes, args.file.gzSize - i * partBytes);
|
|
19876
|
+
const buf = Buffer.allocUnsafe(len);
|
|
19877
|
+
let got = 0;
|
|
19878
|
+
while (got < len) {
|
|
19879
|
+
const n = readSync8(fd, buf, got, len - got, i * partBytes + got);
|
|
19880
|
+
if (n <= 0) break;
|
|
19881
|
+
got += n;
|
|
19882
|
+
}
|
|
19883
|
+
parts.push({ part_number: i + 1, etag: await putPart(url, buf.subarray(0, got)) });
|
|
19884
|
+
}
|
|
19885
|
+
} finally {
|
|
19886
|
+
closeSync9(fd);
|
|
19887
|
+
}
|
|
19888
|
+
const done = await post("complete", { session_id: args.sessionId, upload_id: start.json.upload_id, parts });
|
|
19889
|
+
if (done.status !== 200) throw new Error(`raw upload complete answered ${done.status}: ${done.json.error ?? ""}`);
|
|
19890
|
+
return done.json.result;
|
|
19891
|
+
}
|
|
19892
|
+
var escapeJson, PART_TIMEOUT_MS, PART_ATTEMPTS;
|
|
19893
|
+
var init_raw_archive_parts = __esm({
|
|
19894
|
+
"src/raw-archive-parts.ts"() {
|
|
19895
|
+
"use strict";
|
|
19896
|
+
init_transcript();
|
|
19897
|
+
escapeJson = (s) => JSON.stringify(s).slice(1, -1);
|
|
19898
|
+
PART_TIMEOUT_MS = 12e4;
|
|
19899
|
+
PART_ATTEMPTS = 3;
|
|
19900
|
+
}
|
|
19901
|
+
});
|
|
19902
|
+
|
|
19122
19903
|
// src/server-probe.ts
|
|
19123
19904
|
var server_probe_exports = {};
|
|
19124
19905
|
__export(server_probe_exports, {
|
|
@@ -19262,7 +20043,7 @@ __export(client_events_exports, {
|
|
|
19262
20043
|
isTelemetryEnabled: () => isTelemetryEnabled,
|
|
19263
20044
|
reportClientEvent: () => reportClientEvent
|
|
19264
20045
|
});
|
|
19265
|
-
import { readFileSync as
|
|
20046
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
19266
20047
|
function scrub(msg) {
|
|
19267
20048
|
if (!msg) return "";
|
|
19268
20049
|
const noHome = msg.replace(/\/(?:home|Users)\/[^/\s]+/g, "~");
|
|
@@ -19315,7 +20096,7 @@ var init_client_events = __esm({
|
|
|
19315
20096
|
init_secret_redactor();
|
|
19316
20097
|
CLI_VERSION2 = "0.0.0";
|
|
19317
20098
|
try {
|
|
19318
|
-
CLI_VERSION2 = JSON.parse(
|
|
20099
|
+
CLI_VERSION2 = JSON.parse(readFileSync34(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION2;
|
|
19319
20100
|
} catch {
|
|
19320
20101
|
}
|
|
19321
20102
|
}
|
|
@@ -19345,11 +20126,11 @@ __export(auto_update_exports, {
|
|
|
19345
20126
|
tarballUrl: () => tarballUrl
|
|
19346
20127
|
});
|
|
19347
20128
|
import { execSync as execSync2, execFileSync as execFileSync3 } from "node:child_process";
|
|
19348
|
-
import { readFileSync as
|
|
20129
|
+
import { readFileSync as readFileSync35, existsSync as existsSync42 } from "node:fs";
|
|
19349
20130
|
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
|
|
20131
|
+
import { writeFileSync as writeFileSync8, mkdtempSync as mkdtempSync3, rmSync as rmSync6, readdirSync as readdirSync30, statSync as statSync38, mkdirSync as mkdirSync9 } from "node:fs";
|
|
20132
|
+
import { join as join42, dirname as dirname18, sep as sep2, posix as pathPosix, win32 as pathWin32 } from "node:path";
|
|
20133
|
+
import { tmpdir as tmpdir3, homedir as homedir15 } from "node:os";
|
|
19353
20134
|
import { createHash as createHash7 } from "node:crypto";
|
|
19354
20135
|
function compareVersions(a, b) {
|
|
19355
20136
|
const pa = String(a).split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
|
|
@@ -19373,7 +20154,7 @@ function newerOf(a, b) {
|
|
|
19373
20154
|
function installedVersion() {
|
|
19374
20155
|
try {
|
|
19375
20156
|
const here = dirname18(fileURLToPath2(import.meta.url));
|
|
19376
|
-
const raw =
|
|
20157
|
+
const raw = readFileSync35(join42(here, "..", "package.json"), "utf-8");
|
|
19377
20158
|
return JSON.parse(raw).version || null;
|
|
19378
20159
|
} catch {
|
|
19379
20160
|
return null;
|
|
@@ -19386,7 +20167,7 @@ function planAutoUpdate(base3, caps, ownVersion3, flag) {
|
|
|
19386
20167
|
if (compareVersions(rel.version, ownVersion3) <= 0) return { update: false, reason: `already current (own ${ownVersion3} >= server ${rel.version})` };
|
|
19387
20168
|
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
20169
|
}
|
|
19389
|
-
function sweepStaleStaging(root =
|
|
20170
|
+
function sweepStaleStaging(root = tmpdir3(), now = Date.now()) {
|
|
19390
20171
|
const MKDTEMP_SUFFIX = /^cr-update-.{6}$/s;
|
|
19391
20172
|
const COLD_MS = 60 * 60 * 1e3;
|
|
19392
20173
|
let removed = 0;
|
|
@@ -19398,13 +20179,13 @@ function sweepStaleStaging(root = tmpdir2(), now = Date.now()) {
|
|
|
19398
20179
|
}
|
|
19399
20180
|
for (const name of entries) {
|
|
19400
20181
|
if (!MKDTEMP_SUFFIX.test(name)) continue;
|
|
19401
|
-
const dir =
|
|
20182
|
+
const dir = join42(root, name);
|
|
19402
20183
|
try {
|
|
19403
|
-
const st =
|
|
20184
|
+
const st = statSync38(dir);
|
|
19404
20185
|
if (!st.isDirectory() || now - st.mtimeMs < COLD_MS) continue;
|
|
19405
20186
|
const inside = readdirSync30(dir);
|
|
19406
20187
|
if (inside.length > 1 || inside.length === 1 && inside[0] !== "chat-recall.tgz") continue;
|
|
19407
|
-
|
|
20188
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19408
20189
|
removed++;
|
|
19409
20190
|
} catch {
|
|
19410
20191
|
}
|
|
@@ -19427,14 +20208,14 @@ async function executeAutoUpdate(plan, deps) {
|
|
|
19427
20208
|
}
|
|
19428
20209
|
const got = createHash7("sha256").update(buf).digest("hex");
|
|
19429
20210
|
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(
|
|
20211
|
+
const dir = mkdtempSync3(join42(tmpdir3(), "cr-update-"));
|
|
19431
20212
|
const discardStaging = () => {
|
|
19432
20213
|
try {
|
|
19433
|
-
|
|
20214
|
+
rmSync6(dir, { recursive: true, force: true });
|
|
19434
20215
|
} catch {
|
|
19435
20216
|
}
|
|
19436
20217
|
};
|
|
19437
|
-
const tgz =
|
|
20218
|
+
const tgz = join42(dir, "chat-recall.tgz");
|
|
19438
20219
|
writeFileSync8(tgz, buf);
|
|
19439
20220
|
if (deps.stopping?.()) {
|
|
19440
20221
|
discardStaging();
|
|
@@ -19506,7 +20287,7 @@ function resolveNpm(loc) {
|
|
|
19506
20287
|
}
|
|
19507
20288
|
function realInstall(tgz) {
|
|
19508
20289
|
const prefix = runningPrefix();
|
|
19509
|
-
const npm = resolveNpm({ execPath: process.execPath, prefix, platform: process.platform, env: process.env, exists:
|
|
20290
|
+
const npm = resolveNpm({ execPath: process.execPath, prefix, platform: process.platform, env: process.env, exists: existsSync42 });
|
|
19510
20291
|
if (prefix) {
|
|
19511
20292
|
npmInstall(npm, ["install", "-g", "--prefix", prefix, tgz]);
|
|
19512
20293
|
return;
|
|
@@ -19514,7 +20295,7 @@ function realInstall(tgz) {
|
|
|
19514
20295
|
try {
|
|
19515
20296
|
npmInstall(npm, ["install", "-g", tgz]);
|
|
19516
20297
|
} catch {
|
|
19517
|
-
npmInstall(npm, ["install", "-g", "--prefix",
|
|
20298
|
+
npmInstall(npm, ["install", "-g", "--prefix", join42(homedir15(), ".local"), tgz]);
|
|
19518
20299
|
}
|
|
19519
20300
|
}
|
|
19520
20301
|
function acquireUpdateLock() {
|
|
@@ -19531,12 +20312,12 @@ function realRestart(platform2) {
|
|
|
19531
20312
|
if (c) execSync2(c.cmd, { stdio: "ignore", ...c.shell ? { shell: c.shell } : {} });
|
|
19532
20313
|
}
|
|
19533
20314
|
function updateStatePath() {
|
|
19534
|
-
const dir = process.env.CHAT_RECALL_DATA_DIR ||
|
|
19535
|
-
return
|
|
20315
|
+
const dir = process.env.CHAT_RECALL_DATA_DIR || join42(homedir15(), ".chat-recall");
|
|
20316
|
+
return join42(dir, "auto-update-state.json");
|
|
19536
20317
|
}
|
|
19537
20318
|
function readUpdateState() {
|
|
19538
20319
|
try {
|
|
19539
|
-
return JSON.parse(
|
|
20320
|
+
return JSON.parse(readFileSync35(updateStatePath(), "utf8"));
|
|
19540
20321
|
} catch {
|
|
19541
20322
|
return {};
|
|
19542
20323
|
}
|
|
@@ -19643,9 +20424,9 @@ var init_auto_update = __esm({
|
|
|
19643
20424
|
});
|
|
19644
20425
|
|
|
19645
20426
|
// src/sync-client.ts
|
|
19646
|
-
import { join as
|
|
19647
|
-
import { readFileSync as
|
|
19648
|
-
import { tmpdir as
|
|
20427
|
+
import { join as join43, dirname as dirname19, basename as basename20 } from "node:path";
|
|
20428
|
+
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";
|
|
20429
|
+
import { tmpdir as tmpdir4, hostname as hostname2 } from "node:os";
|
|
19649
20430
|
import { createHash as createHash8 } from "node:crypto";
|
|
19650
20431
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
19651
20432
|
import { gzipSync as gzipSync3 } from "zlib";
|
|
@@ -19681,7 +20462,7 @@ function loadAllCredentials() {
|
|
|
19681
20462
|
const fromEnv = envCredentials();
|
|
19682
20463
|
if (fromEnv) return [{ serverUrl: fromEnv.serverUrl, token: fromEnv.token }];
|
|
19683
20464
|
try {
|
|
19684
|
-
const parsed = JSON.parse(
|
|
20465
|
+
const parsed = JSON.parse(readFileSync36(credPath(), "utf-8"));
|
|
19685
20466
|
if (Array.isArray(parsed?.targets)) return parsed.targets.filter((t) => t?.serverUrl).map((t) => ({ serverUrl: t.serverUrl, token: t.token || "" }));
|
|
19686
20467
|
if (parsed?.serverUrl) return [{ serverUrl: parsed.serverUrl, token: parsed.token || "" }];
|
|
19687
20468
|
} catch {
|
|
@@ -19740,11 +20521,11 @@ async function fetchTenantSecurityConfig(cred) {
|
|
|
19740
20521
|
}
|
|
19741
20522
|
}
|
|
19742
20523
|
function syncConfigCachePath() {
|
|
19743
|
-
return
|
|
20524
|
+
return join43(getDataDir(), "sync-config-cache.json");
|
|
19744
20525
|
}
|
|
19745
20526
|
function readPersistedSyncConfigs() {
|
|
19746
20527
|
try {
|
|
19747
|
-
return JSON.parse(
|
|
20528
|
+
return JSON.parse(readFileSync36(syncConfigCachePath(), "utf-8"));
|
|
19748
20529
|
} catch {
|
|
19749
20530
|
return {};
|
|
19750
20531
|
}
|
|
@@ -19987,7 +20768,7 @@ async function reconcileFieldsForTarget(cred, fullRefs, opts = {}) {
|
|
|
19987
20768
|
}
|
|
19988
20769
|
return { pushed, absent, scanned };
|
|
19989
20770
|
}
|
|
19990
|
-
function reapStaleScanDirs(dir =
|
|
20771
|
+
function reapStaleScanDirs(dir = tmpdir4(), maxAgeMs = 6 * 36e5, now = Date.now()) {
|
|
19991
20772
|
let reaped = 0;
|
|
19992
20773
|
let names;
|
|
19993
20774
|
try {
|
|
@@ -19997,10 +20778,10 @@ function reapStaleScanDirs(dir = tmpdir3(), maxAgeMs = 6 * 36e5, now = Date.now(
|
|
|
19997
20778
|
}
|
|
19998
20779
|
for (const name of names) {
|
|
19999
20780
|
if (!name.startsWith("cr-batchscan-")) continue;
|
|
20000
|
-
const p =
|
|
20781
|
+
const p = join43(dir, name);
|
|
20001
20782
|
try {
|
|
20002
|
-
if (now -
|
|
20003
|
-
|
|
20783
|
+
if (now - statSync39(p).mtimeMs < maxAgeMs) continue;
|
|
20784
|
+
rmSync7(p, { recursive: true, force: true });
|
|
20004
20785
|
reaped++;
|
|
20005
20786
|
} catch {
|
|
20006
20787
|
}
|
|
@@ -20014,7 +20795,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20014
20795
|
let scanned = 0, slices = 0, scanMs = 0;
|
|
20015
20796
|
if (items.length === 0) return { findings, scanned, slices, scanMs };
|
|
20016
20797
|
reapStaleScanDirs();
|
|
20017
|
-
let scanDir = mkdtempSync4(
|
|
20798
|
+
let scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20018
20799
|
let safeToId = /* @__PURE__ */ new Map();
|
|
20019
20800
|
let bytesInDir = 0;
|
|
20020
20801
|
const flushSlice = () => {
|
|
@@ -20032,7 +20813,7 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20032
20813
|
slices++;
|
|
20033
20814
|
}
|
|
20034
20815
|
try {
|
|
20035
|
-
|
|
20816
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20036
20817
|
} catch {
|
|
20037
20818
|
}
|
|
20038
20819
|
safeToId = /* @__PURE__ */ new Map();
|
|
@@ -20045,19 +20826,19 @@ function batchScanExternal(items, opts = {}) {
|
|
|
20045
20826
|
if (raw === null) continue;
|
|
20046
20827
|
const safe = item.id.replace(/[^A-Za-z0-9_-]/g, "");
|
|
20047
20828
|
safeToId.set(safe, item.id);
|
|
20048
|
-
writeFileSync9(
|
|
20829
|
+
writeFileSync9(join43(scanDir, `${safe}.txt`), raw);
|
|
20049
20830
|
bytesInDir += Buffer.byteLength(raw);
|
|
20050
20831
|
} catch {
|
|
20051
20832
|
}
|
|
20052
20833
|
if (bytesInDir >= maxBytes) {
|
|
20053
20834
|
flushSlice();
|
|
20054
|
-
scanDir = mkdtempSync4(
|
|
20835
|
+
scanDir = mkdtempSync4(join43(tmpdir4(), "cr-batchscan-"));
|
|
20055
20836
|
}
|
|
20056
20837
|
}
|
|
20057
20838
|
flushSlice();
|
|
20058
20839
|
} finally {
|
|
20059
20840
|
try {
|
|
20060
|
-
|
|
20841
|
+
rmSync7(scanDir, { recursive: true, force: true });
|
|
20061
20842
|
} catch {
|
|
20062
20843
|
}
|
|
20063
20844
|
}
|
|
@@ -20264,6 +21045,11 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20264
21045
|
};
|
|
20265
21046
|
const localSessionIds = /* @__PURE__ */ new Set();
|
|
20266
21047
|
const shippedHash = /* @__PURE__ */ new Map();
|
|
21048
|
+
const shippedLayout = /* @__PURE__ */ new Map();
|
|
21049
|
+
const layoutOf = (id) => {
|
|
21050
|
+
const layout = shippedLayout.get(id);
|
|
21051
|
+
return layout ? { layout } : {};
|
|
21052
|
+
};
|
|
20267
21053
|
const makeBatcher = (field, maxItems, flatten = false, onFlush, barrier) => {
|
|
20268
21054
|
let batch = [];
|
|
20269
21055
|
let batchBytes = 0;
|
|
@@ -20296,12 +21082,13 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20296
21082
|
markSynced(base3, rows.map((r) => {
|
|
20297
21083
|
const off = typeof r.from_offset === "number" ? r.from_offset : 0;
|
|
20298
21084
|
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 };
|
|
21085
|
+
return off > 0 ? { id: r.session_id, mtime: r.mtime, offset: off, size: off, hash, acked: true, full: true, ...layoutOf(r.session_id) } : { id: r.session_id, mtime: r.mtime, hash };
|
|
20300
21086
|
}));
|
|
20301
21087
|
} catch {
|
|
20302
21088
|
}
|
|
20303
21089
|
});
|
|
20304
21090
|
const appendResults = { uploaded: 0, fullResyncNeeded: /* @__PURE__ */ new Set() };
|
|
21091
|
+
const pendingArchives = [];
|
|
20305
21092
|
const postAppend = async (convs) => {
|
|
20306
21093
|
const headers = { "content-type": "application/json" };
|
|
20307
21094
|
if (cred.token) headers.authorization = `Bearer ${cred.token}`;
|
|
@@ -20336,8 +21123,11 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20336
21123
|
offset: c.from_offset,
|
|
20337
21124
|
size: c.from_offset,
|
|
20338
21125
|
// size = new offset (file grew to here)
|
|
20339
|
-
acked: true
|
|
21126
|
+
acked: true,
|
|
20340
21127
|
// server merged this tail
|
|
21128
|
+
chunkFinal: c.final === true,
|
|
21129
|
+
// completes a chunked full sync
|
|
21130
|
+
...layoutOf(c.session_id)
|
|
20341
21131
|
})));
|
|
20342
21132
|
} catch {
|
|
20343
21133
|
}
|
|
@@ -20369,9 +21159,9 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20369
21159
|
const mtime = conv.mtime;
|
|
20370
21160
|
try {
|
|
20371
21161
|
if (staged || !guarded) {
|
|
20372
|
-
markSynced(base3, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true }]);
|
|
21162
|
+
markSynced(base3, [{ id, mtime, offset: conv.from_offset, size: conv.from_offset, acked: true, chunkedHead: true, ...layoutOf(id) }]);
|
|
20373
21163
|
} 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 }]);
|
|
21164
|
+
markSynced(base3, [{ id, mtime, offset: guarded.o, size: guarded.o, acked: true, chunkedHead: true, ...layoutOf(id) }]);
|
|
20375
21165
|
} else {
|
|
20376
21166
|
markSynced(base3, [{ id, mtime }]);
|
|
20377
21167
|
}
|
|
@@ -20466,8 +21256,8 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20466
21256
|
if (!ledger) return ref.mtime >= (opts.sinceMs ?? 0) ? "full" : "skip";
|
|
20467
21257
|
const ack = ledger.get(ref.prefixedId);
|
|
20468
21258
|
const backend = backendFor(ref);
|
|
20469
|
-
const
|
|
20470
|
-
const isAO = !!backend?.isAppendOnly?.() &&
|
|
21259
|
+
const sameLayout = (ack?.L ?? "") === (backend?.sourceLayout?.(ref.prefixedId) ?? "");
|
|
21260
|
+
const isAO = !!backend?.isAppendOnly?.() && sameLayout;
|
|
20471
21261
|
const size = isAO ? backend?.fileSize?.(ref.prefixedId) ?? 0 : 0;
|
|
20472
21262
|
return syncMode(ack, ref.mtime, size, extractorVersionForTool(ref.toolId), isAO);
|
|
20473
21263
|
};
|
|
@@ -20514,6 +21304,9 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20514
21304
|
skipped++;
|
|
20515
21305
|
continue;
|
|
20516
21306
|
}
|
|
21307
|
+
const layout = backendFor(ref)?.sourceLayout?.(ref.prefixedId) ?? "";
|
|
21308
|
+
if (layout) shippedLayout.set(ref.prefixedId, layout);
|
|
21309
|
+
else shippedLayout.delete(ref.prefixedId);
|
|
20517
21310
|
trace?.(`build (${mode}) ${ref.prefixedId} \xB7 ${(sessionFileBytes(ref) / 1048576).toFixed(1)}MB`);
|
|
20518
21311
|
let promotedForFindings = false;
|
|
20519
21312
|
if (mode === "append" && ledger) {
|
|
@@ -20559,7 +21352,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20559
21352
|
const off = getBackendForId(ref.prefixedId)?.fileSize?.(ref.rawId) ?? 0;
|
|
20560
21353
|
const priorCursor = ackRow?.s ?? 0;
|
|
20561
21354
|
const safeToAck = off > 0 && off <= priorCursor;
|
|
20562
|
-
markSynced(base3, [safeToAck ? { id: ref.prefixedId, mtime: ref.mtime, offset: off, size: off, hash: built.srcHash, acked: true } : { id: ref.prefixedId, mtime: ref.mtime, hash: built.srcHash }]);
|
|
21355
|
+
markSynced(base3, [safeToAck ? { id: ref.prefixedId, mtime: ref.mtime, offset: off, size: off, hash: built.srcHash, acked: true, ...layoutOf(ref.prefixedId) } : { id: ref.prefixedId, mtime: ref.mtime, hash: built.srcHash }]);
|
|
20563
21356
|
} catch {
|
|
20564
21357
|
}
|
|
20565
21358
|
}
|
|
@@ -20580,6 +21373,14 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20580
21373
|
if (built.srcHash) shippedHash.set(ref.prefixedId, built.srcHash);
|
|
20581
21374
|
if (built.conv.chunked) await postChunkedHead(built.conv, sessionFileBytes(ref));
|
|
20582
21375
|
else await convBatch.add(built.conv);
|
|
21376
|
+
if (built.archive) {
|
|
21377
|
+
pendingArchives.push({
|
|
21378
|
+
id: ref.prefixedId,
|
|
21379
|
+
...built.archive,
|
|
21380
|
+
projectId: built.conv.project_id,
|
|
21381
|
+
projectPath: built.conv.project_path
|
|
21382
|
+
});
|
|
21383
|
+
}
|
|
20583
21384
|
if (built.findings.length > 0) await findingsBatch.add(built.findings);
|
|
20584
21385
|
if (upload.sessionMeta) {
|
|
20585
21386
|
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 +21533,30 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
20732
21533
|
await kgTripleBatch.drain();
|
|
20733
21534
|
await findingsBatch.drain();
|
|
20734
21535
|
await drainInflight();
|
|
21536
|
+
let archivesUnsupported = false;
|
|
21537
|
+
for (const a of pendingArchives) {
|
|
21538
|
+
try {
|
|
21539
|
+
if (!archivesUnsupported) {
|
|
21540
|
+
const r = await uploadArchiveFile(base3, cred.token, {
|
|
21541
|
+
sessionId: a.id,
|
|
21542
|
+
tool: a.tool,
|
|
21543
|
+
mtime: a.mtime,
|
|
21544
|
+
projectId: a.projectId,
|
|
21545
|
+
projectPath: a.projectPath,
|
|
21546
|
+
file: a.file
|
|
21547
|
+
});
|
|
21548
|
+
if (r === "unsupported") archivesUnsupported = true;
|
|
21549
|
+
}
|
|
21550
|
+
} catch (err) {
|
|
21551
|
+
console.error(`[sync] raw archive for ${a.id} not uploaded (tried again when the session is next quiet): ${err instanceof Error ? err.message : err}`);
|
|
21552
|
+
try {
|
|
21553
|
+
forgetFullCoverage(base3, a.id);
|
|
21554
|
+
} catch {
|
|
21555
|
+
}
|
|
21556
|
+
} finally {
|
|
21557
|
+
rmSync7(a.file.path, { force: true });
|
|
21558
|
+
}
|
|
21559
|
+
}
|
|
20735
21560
|
{
|
|
20736
21561
|
const sentHashes = loadInventoryHashes(base3);
|
|
20737
21562
|
const entries = [];
|
|
@@ -20837,6 +21662,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
20837
21662
|
let includeRaw = opts.includeRaw !== false;
|
|
20838
21663
|
let includeMeta = opts.includeMeta !== false;
|
|
20839
21664
|
let srcHash;
|
|
21665
|
+
const wantRaw = opts.includeRaw !== false;
|
|
20840
21666
|
const oversized = sessionBuildBytes(ref) > FULL_BUILD_MAX_BYTES;
|
|
20841
21667
|
let headOffsetEnd = 0;
|
|
20842
21668
|
let oversizedFindings = null;
|
|
@@ -21005,7 +21831,7 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21005
21831
|
} else if (opts.scanSecrets) {
|
|
21006
21832
|
let tmp = null;
|
|
21007
21833
|
try {
|
|
21008
|
-
tmp =
|
|
21834
|
+
tmp = join43(tmpdir4(), `cr-scan-${ref.prefixedId.replace(/[^A-Za-z0-9_-]/g, "")}-${mtime}.txt`);
|
|
21009
21835
|
writeFileSync9(tmp, rawText);
|
|
21010
21836
|
for (const f of scanFileForSecrets(tmp, { verifyOnly: opts.verifySecrets, tenantRules: opts.tenantRules })) {
|
|
21011
21837
|
const verifiedAt = f.verified ? (/* @__PURE__ */ new Date()).toISOString() : null;
|
|
@@ -21057,6 +21883,25 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21057
21883
|
}
|
|
21058
21884
|
const envTexts = envelope.messages.filter((m) => m.content?.trim());
|
|
21059
21885
|
const redactedText = envTexts.map((m) => m.content).join("\n");
|
|
21886
|
+
let archive;
|
|
21887
|
+
if (wantRaw && !raw_b64) {
|
|
21888
|
+
try {
|
|
21889
|
+
const redact = (t) => redactSecrets(t, { force: true, count });
|
|
21890
|
+
let source = null;
|
|
21891
|
+
let archiveMtime = Math.floor(ref.mtime) || 0;
|
|
21892
|
+
let archiveTool = ref.toolId;
|
|
21893
|
+
if (container) {
|
|
21894
|
+
source = { kind: "memory", files: container.files };
|
|
21895
|
+
archiveMtime = container.mtime;
|
|
21896
|
+
archiveTool = container.tool;
|
|
21897
|
+
} else if (oversized) {
|
|
21898
|
+
source = diskArchiveSource(ref);
|
|
21899
|
+
}
|
|
21900
|
+
if (source) archive = { file: await writeArchiveFile(source, { tool: archiveTool, mtime: archiveMtime }, redact), tool: archiveTool, mtime: archiveMtime };
|
|
21901
|
+
} catch (err) {
|
|
21902
|
+
console.error(`[sync] raw archive for ${ref.prefixedId} not written: ${err instanceof Error ? err.message : err}`);
|
|
21903
|
+
}
|
|
21904
|
+
}
|
|
21060
21905
|
return {
|
|
21061
21906
|
conv: {
|
|
21062
21907
|
session_id: ref.prefixedId,
|
|
@@ -21088,7 +21933,17 @@ async function buildConversationSync(ref, mtime, opts = {}) {
|
|
|
21088
21933
|
redactions: count.redactions,
|
|
21089
21934
|
findings,
|
|
21090
21935
|
scanMs,
|
|
21091
|
-
srcHash
|
|
21936
|
+
srcHash,
|
|
21937
|
+
archive
|
|
21938
|
+
};
|
|
21939
|
+
}
|
|
21940
|
+
function diskArchiveSource(ref) {
|
|
21941
|
+
if (ref.toolId !== "claude") return null;
|
|
21942
|
+
const groups = resolveSessionContentGroups(ref.rawId);
|
|
21943
|
+
if (groups.length === 0 || groups.some((g) => g.paths.length !== 1)) return null;
|
|
21944
|
+
return {
|
|
21945
|
+
kind: "disk",
|
|
21946
|
+
files: groups.map((g) => ({ name: g.name === "main" ? `${ref.rawId}.jsonl` : g.name, path: g.paths[0] }))
|
|
21092
21947
|
};
|
|
21093
21948
|
}
|
|
21094
21949
|
function parseTailMessages(tool, text) {
|
|
@@ -21244,14 +22099,15 @@ var init_sync_client = __esm({
|
|
|
21244
22099
|
init_telemetry();
|
|
21245
22100
|
init_collector_health();
|
|
21246
22101
|
init_live_session_scan();
|
|
22102
|
+
init_raw_archive_parts();
|
|
21247
22103
|
init_backends();
|
|
21248
22104
|
ownVersion = "0.0.0";
|
|
21249
22105
|
try {
|
|
21250
22106
|
const dir = dirname19(fileURLToPath3(import.meta.url));
|
|
21251
|
-
ownVersion = JSON.parse(
|
|
22107
|
+
ownVersion = JSON.parse(readFileSync36(join43(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
21252
22108
|
} catch {
|
|
21253
22109
|
try {
|
|
21254
|
-
if (true) ownVersion = "0.7.
|
|
22110
|
+
if (true) ownVersion = "0.7.19";
|
|
21255
22111
|
} catch {
|
|
21256
22112
|
}
|
|
21257
22113
|
}
|
|
@@ -21263,7 +22119,7 @@ var init_sync_client = __esm({
|
|
|
21263
22119
|
]);
|
|
21264
22120
|
walkProgressForUpload = null;
|
|
21265
22121
|
lastServerPackSpec = null;
|
|
21266
|
-
credPath = () =>
|
|
22122
|
+
credPath = () => join43(getDataDir(), "credentials.json");
|
|
21267
22123
|
_securityConfigCache = /* @__PURE__ */ new Map();
|
|
21268
22124
|
SECURITY_CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
21269
22125
|
_syncConfigCache = /* @__PURE__ */ new Map();
|
|
@@ -21286,8 +22142,8 @@ var init_sync_client = __esm({
|
|
|
21286
22142
|
});
|
|
21287
22143
|
|
|
21288
22144
|
// ../engine/dist/core/artifact-codec.js
|
|
21289
|
-
import { readFileSync as
|
|
21290
|
-
import { basename as basename21, join as
|
|
22145
|
+
import { readFileSync as readFileSync37 } from "fs";
|
|
22146
|
+
import { basename as basename21, join as join44 } from "path";
|
|
21291
22147
|
import { homedir as homedir16 } from "os";
|
|
21292
22148
|
function parseCommandText(content, format, fallbackName) {
|
|
21293
22149
|
if (format === "toml") {
|
|
@@ -21310,41 +22166,41 @@ function parseAgentText(content, format, fallbackName) {
|
|
|
21310
22166
|
return { name: fm.name || fallbackName, description: fm.description || "", tools: fm.tools, body: body.trim() };
|
|
21311
22167
|
}
|
|
21312
22168
|
function readCommand(filePath, format) {
|
|
21313
|
-
return parseCommandText(
|
|
22169
|
+
return parseCommandText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21314
22170
|
}
|
|
21315
22171
|
function readAgent(filePath, format) {
|
|
21316
|
-
return parseAgentText(
|
|
22172
|
+
return parseAgentText(readFileSync37(filePath, "utf-8"), format, base2(filePath));
|
|
21317
22173
|
}
|
|
21318
22174
|
function readInstructions(filePath, name) {
|
|
21319
|
-
const content =
|
|
22175
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
21320
22176
|
return { name, description: "", body: content };
|
|
21321
22177
|
}
|
|
21322
22178
|
function commandPath(tool, name) {
|
|
21323
22179
|
switch (tool) {
|
|
21324
22180
|
case "claude":
|
|
21325
|
-
return
|
|
22181
|
+
return join44(claudeBackend.commandsDir(), `${name}.md`);
|
|
21326
22182
|
case "agy":
|
|
21327
|
-
return
|
|
22183
|
+
return join44(join44(agyBackend.homeDir(), "commands"), `${name}.toml`);
|
|
21328
22184
|
case "opencode":
|
|
21329
|
-
return
|
|
22185
|
+
return join44(opencodeBackend.commandsDir(), `${name}.md`);
|
|
21330
22186
|
case "codex":
|
|
21331
|
-
return
|
|
22187
|
+
return join44(codexBackend.promptsDir(), `${name}.md`);
|
|
21332
22188
|
case "cursor":
|
|
21333
|
-
return
|
|
22189
|
+
return join44(cursorHomeDir(), "commands", `${name}.md`);
|
|
21334
22190
|
}
|
|
21335
22191
|
}
|
|
21336
22192
|
function agentPath(tool, name) {
|
|
21337
22193
|
switch (tool) {
|
|
21338
22194
|
case "claude":
|
|
21339
|
-
return
|
|
22195
|
+
return join44(claudeBackend.agentsDir(), `${name}.md`);
|
|
21340
22196
|
case "agy":
|
|
21341
|
-
return
|
|
22197
|
+
return join44(join44(agyBackend.homeDir(), "agents"), `${name}.md`);
|
|
21342
22198
|
case "opencode":
|
|
21343
|
-
return
|
|
22199
|
+
return join44(opencodeBackend.agentsDir(), `${name}.md`);
|
|
21344
22200
|
case "codex":
|
|
21345
|
-
return
|
|
22201
|
+
return join44(codexBackend.agentsDir(), `${name}.toml`);
|
|
21346
22202
|
case "cursor":
|
|
21347
|
-
return
|
|
22203
|
+
return join44(cursorHomeDir(), "agents", `${name}.md`);
|
|
21348
22204
|
}
|
|
21349
22205
|
}
|
|
21350
22206
|
function instructionsFilename(tool) {
|
|
@@ -21369,21 +22225,21 @@ function instructionsFilename(tool) {
|
|
|
21369
22225
|
function instructionsPath(tool, projectPath) {
|
|
21370
22226
|
const file = instructionsFilename(tool);
|
|
21371
22227
|
if (projectPath)
|
|
21372
|
-
return
|
|
22228
|
+
return join44(projectPath, file);
|
|
21373
22229
|
switch (tool) {
|
|
21374
22230
|
case "claude":
|
|
21375
|
-
return
|
|
22231
|
+
return join44(claudeBackend.homeDir(), file);
|
|
21376
22232
|
case "agy":
|
|
21377
|
-
return
|
|
22233
|
+
return join44(agyBackend.homeDir(), file);
|
|
21378
22234
|
case "codex":
|
|
21379
|
-
return
|
|
22235
|
+
return join44(codexBackend.homeDir(), file);
|
|
21380
22236
|
case "opencode":
|
|
21381
|
-
return
|
|
22237
|
+
return join44(homedir16(), ".config", "opencode", file);
|
|
21382
22238
|
// Cursor has no single user-scope instructions FILE — user-level guidance
|
|
21383
22239
|
// is User Rules plus ~/.cursor/rules/*.mdc. AGENTS.md at the home root is
|
|
21384
22240
|
// the closest equivalent and is what a mirror can actually write.
|
|
21385
22241
|
case "cursor":
|
|
21386
|
-
return
|
|
22242
|
+
return join44(cursorHomeDir(), file);
|
|
21387
22243
|
}
|
|
21388
22244
|
}
|
|
21389
22245
|
function emit(type, art, toTool, projectPath) {
|
|
@@ -21429,8 +22285,8 @@ var init_artifact_codec = __esm({
|
|
|
21429
22285
|
});
|
|
21430
22286
|
|
|
21431
22287
|
// ../engine/dist/core/toolkit-sync.js
|
|
21432
|
-
import { existsSync as
|
|
21433
|
-
import { dirname as dirname20, join as
|
|
22288
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync11, readFileSync as readFileSync38, writeFileSync as writeFileSync10, cpSync } from "fs";
|
|
22289
|
+
import { dirname as dirname20, join as join45, basename as basename22 } from "path";
|
|
21434
22290
|
import { homedir as homedir17 } from "os";
|
|
21435
22291
|
function rowFromMemoryItem(type, item) {
|
|
21436
22292
|
const extra = item.extra || {};
|
|
@@ -21451,23 +22307,23 @@ function skillsDirFor(tool) {
|
|
|
21451
22307
|
case "claude":
|
|
21452
22308
|
return claudeBackend.skillsDir();
|
|
21453
22309
|
case "agy":
|
|
21454
|
-
return
|
|
22310
|
+
return join45(agyBackend.homeDir(), "skills");
|
|
21455
22311
|
case "opencode":
|
|
21456
22312
|
return opencodeBackend.skillsDir();
|
|
21457
22313
|
case "codex":
|
|
21458
22314
|
return codexBackend.skillsDir();
|
|
21459
22315
|
// user skills, NOT .system
|
|
21460
22316
|
case "cursor":
|
|
21461
|
-
return
|
|
22317
|
+
return join45(cursorHomeDir(), "skills");
|
|
21462
22318
|
}
|
|
21463
22319
|
}
|
|
21464
22320
|
function copySkill(row, toTool) {
|
|
21465
22321
|
const skillDir = row.extra.skillDir || dirname20(row.filePath);
|
|
21466
|
-
if (!
|
|
22322
|
+
if (!existsSync43(skillDir))
|
|
21467
22323
|
return { ok: false, status: 404, error: `Source dir missing: ${skillDir}` };
|
|
21468
22324
|
const name = row.extra.skillName || basename22(skillDir);
|
|
21469
|
-
const targetDir =
|
|
21470
|
-
if (
|
|
22325
|
+
const targetDir = join45(skillsDirFor(toTool), name);
|
|
22326
|
+
if (existsSync43(targetDir))
|
|
21471
22327
|
return { ok: false, status: 409, error: `Already exists: ${targetDir}` };
|
|
21472
22328
|
try {
|
|
21473
22329
|
mkdirSync11(dirname20(targetDir), { recursive: true });
|
|
@@ -21481,28 +22337,28 @@ function readMcpEntry(tool, name) {
|
|
|
21481
22337
|
const home = homedir17();
|
|
21482
22338
|
const tries = [];
|
|
21483
22339
|
if (tool === "claude") {
|
|
21484
|
-
tries.push({ path:
|
|
21485
|
-
tries.push({ path:
|
|
22340
|
+
tries.push({ path: join45(home, ".mcp.json"), key: "mcpServers" });
|
|
22341
|
+
tries.push({ path: join45(home, ".claude.json"), key: "mcpServers" });
|
|
21486
22342
|
} else if (tool === "gemini") {
|
|
21487
|
-
tries.push({ path:
|
|
22343
|
+
tries.push({ path: join45(home, ".gemini", "settings.json"), key: "mcpServers" });
|
|
21488
22344
|
} else if (tool === "agy") {
|
|
21489
|
-
tries.push({ path:
|
|
22345
|
+
tries.push({ path: join45(home, ".gemini", "config", "mcp_config.json"), key: "mcpServers" });
|
|
21490
22346
|
} else if (tool === "cursor") {
|
|
21491
|
-
tries.push({ path:
|
|
22347
|
+
tries.push({ path: join45(cursorHomeDir(), "mcp.json"), key: "mcpServers" });
|
|
21492
22348
|
} else if (tool === "opencode") {
|
|
21493
|
-
tries.push({ path:
|
|
21494
|
-
tries.push({ path:
|
|
21495
|
-
tries.push({ path:
|
|
22349
|
+
tries.push({ path: join45(home, ".config", "opencode", "opencode.json"), key: "mcp" });
|
|
22350
|
+
tries.push({ path: join45(home, ".config", "opencode", "config.json"), key: "mcp" });
|
|
22351
|
+
tries.push({ path: join45(home, ".opencode", "config.json"), key: "mcp" });
|
|
21496
22352
|
} else if (tool === "codex") {
|
|
21497
|
-
const entry = readCodexMcpEntry(
|
|
22353
|
+
const entry = readCodexMcpEntry(join45(home, ".codex", "config.toml"), name);
|
|
21498
22354
|
if (entry)
|
|
21499
22355
|
return entry;
|
|
21500
22356
|
}
|
|
21501
22357
|
for (const t of tries) {
|
|
21502
|
-
if (!
|
|
22358
|
+
if (!existsSync43(t.path))
|
|
21503
22359
|
continue;
|
|
21504
22360
|
try {
|
|
21505
|
-
const cfg = JSON.parse(
|
|
22361
|
+
const cfg = JSON.parse(readFileSync38(t.path, "utf-8"));
|
|
21506
22362
|
const block = cfg[t.key] || {};
|
|
21507
22363
|
if (block[name])
|
|
21508
22364
|
return block[name];
|
|
@@ -21512,11 +22368,11 @@ function readMcpEntry(tool, name) {
|
|
|
21512
22368
|
return null;
|
|
21513
22369
|
}
|
|
21514
22370
|
function readCodexMcpEntry(path, target) {
|
|
21515
|
-
if (!
|
|
22371
|
+
if (!existsSync43(path))
|
|
21516
22372
|
return null;
|
|
21517
22373
|
let content;
|
|
21518
22374
|
try {
|
|
21519
|
-
content =
|
|
22375
|
+
content = readFileSync38(path, "utf-8");
|
|
21520
22376
|
} catch {
|
|
21521
22377
|
return null;
|
|
21522
22378
|
}
|
|
@@ -21566,8 +22422,8 @@ function readCodexMcpEntry(path, target) {
|
|
|
21566
22422
|
}
|
|
21567
22423
|
function writeCodexMcpEntry(path, name, entry) {
|
|
21568
22424
|
let content = "";
|
|
21569
|
-
if (
|
|
21570
|
-
content =
|
|
22425
|
+
if (existsSync43(path))
|
|
22426
|
+
content = readFileSync38(path, "utf-8");
|
|
21571
22427
|
const header = `[mcp_servers.${name}]`;
|
|
21572
22428
|
if (content.includes(header))
|
|
21573
22429
|
return false;
|
|
@@ -21603,7 +22459,7 @@ function writeCodexMcpEntry(path, name, entry) {
|
|
|
21603
22459
|
function writeMcpEntry(toTool, name, entry) {
|
|
21604
22460
|
const home = homedir17();
|
|
21605
22461
|
if (toTool === "codex") {
|
|
21606
|
-
const path2 =
|
|
22462
|
+
const path2 = join45(home, ".codex", "config.toml");
|
|
21607
22463
|
if (!writeCodexMcpEntry(path2, name, entry))
|
|
21608
22464
|
return { ok: false, status: 409, error: `MCP "${name}" already exists in ${path2}.` };
|
|
21609
22465
|
return { ok: true, targetPath: path2 };
|
|
@@ -21611,22 +22467,22 @@ function writeMcpEntry(toTool, name, entry) {
|
|
|
21611
22467
|
let path;
|
|
21612
22468
|
let key2;
|
|
21613
22469
|
if (toTool === "claude") {
|
|
21614
|
-
path =
|
|
22470
|
+
path = join45(home, ".mcp.json");
|
|
21615
22471
|
key2 = "mcpServers";
|
|
21616
22472
|
} else if (toTool === "agy") {
|
|
21617
|
-
path =
|
|
22473
|
+
path = join45(home, ".gemini", "config", "mcp_config.json");
|
|
21618
22474
|
key2 = "mcpServers";
|
|
21619
22475
|
} else if (toTool === "cursor") {
|
|
21620
|
-
path =
|
|
22476
|
+
path = join45(cursorHomeDir(), "mcp.json");
|
|
21621
22477
|
key2 = "mcpServers";
|
|
21622
22478
|
} else {
|
|
21623
|
-
path =
|
|
22479
|
+
path = join45(home, ".config", "opencode", "opencode.json");
|
|
21624
22480
|
key2 = "mcp";
|
|
21625
22481
|
}
|
|
21626
22482
|
let cfg = {};
|
|
21627
|
-
if (
|
|
22483
|
+
if (existsSync43(path)) {
|
|
21628
22484
|
try {
|
|
21629
|
-
cfg = JSON.parse(
|
|
22485
|
+
cfg = JSON.parse(readFileSync38(path, "utf-8"));
|
|
21630
22486
|
} catch {
|
|
21631
22487
|
return { ok: false, status: 500, error: `Target config is malformed: ${path}` };
|
|
21632
22488
|
}
|
|
@@ -21688,7 +22544,7 @@ function copyCommandOrAgent(type, row, toTool) {
|
|
|
21688
22544
|
return { ok: false, status: 404, error: `Source unreadable: ${e instanceof Error ? e.message : "failed"}` };
|
|
21689
22545
|
}
|
|
21690
22546
|
const out = emit(type, art, toTool);
|
|
21691
|
-
if (
|
|
22547
|
+
if (existsSync43(out.path))
|
|
21692
22548
|
return { ok: false, status: 409, error: `Already exists: ${out.path}` };
|
|
21693
22549
|
try {
|
|
21694
22550
|
mkdirSync11(dirname20(out.path), { recursive: true });
|
|
@@ -21708,7 +22564,7 @@ function copyInstructions(row, toTool) {
|
|
|
21708
22564
|
return { ok: false, status: 404, error: `Source unreadable: ${e instanceof Error ? e.message : "failed"}` };
|
|
21709
22565
|
}
|
|
21710
22566
|
const out = emit("instructions", art, toTool, row.projectPath || void 0);
|
|
21711
|
-
if (
|
|
22567
|
+
if (existsSync43(out.path))
|
|
21712
22568
|
return { ok: false, status: 409, error: `Already exists: ${out.path}` };
|
|
21713
22569
|
try {
|
|
21714
22570
|
mkdirSync11(dirname20(out.path), { recursive: true });
|
|
@@ -21851,11 +22707,11 @@ var init_toolkit_sync = __esm({
|
|
|
21851
22707
|
});
|
|
21852
22708
|
|
|
21853
22709
|
// ../engine/dist/core/which.js
|
|
21854
|
-
import { existsSync as
|
|
21855
|
-
import { join as
|
|
22710
|
+
import { existsSync as existsSync45, statSync as statSync41, accessSync, constants } from "node:fs";
|
|
22711
|
+
import { join as join47, isAbsolute as isAbsolute2, delimiter as delimiter2, sep as sep3 } from "node:path";
|
|
21856
22712
|
function executable(p) {
|
|
21857
22713
|
try {
|
|
21858
|
-
if (!
|
|
22714
|
+
if (!statSync41(p).isFile())
|
|
21859
22715
|
return false;
|
|
21860
22716
|
} catch {
|
|
21861
22717
|
return false;
|
|
@@ -21891,8 +22747,8 @@ function resolveOnPath(name) {
|
|
|
21891
22747
|
if (!dir)
|
|
21892
22748
|
continue;
|
|
21893
22749
|
for (const c of candidates(name)) {
|
|
21894
|
-
const full =
|
|
21895
|
-
if (
|
|
22750
|
+
const full = join47(dir, c);
|
|
22751
|
+
if (existsSync45(full) && executable(full))
|
|
21896
22752
|
return full;
|
|
21897
22753
|
}
|
|
21898
22754
|
}
|
|
@@ -21918,11 +22774,11 @@ __export(toolkit_pull_exports, {
|
|
|
21918
22774
|
platformRefusal: () => platformRefusal,
|
|
21919
22775
|
portableCommand: () => portableCommand
|
|
21920
22776
|
});
|
|
21921
|
-
import { existsSync as
|
|
21922
|
-
import { dirname as dirname22, join as
|
|
22777
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync13, statSync as statSync42, writeFileSync as writeFileSync12 } from "node:fs";
|
|
22778
|
+
import { dirname as dirname22, join as join48, basename as basename23, isAbsolute as isAbsolute3 } from "node:path";
|
|
21923
22779
|
function isExecutableFile(p) {
|
|
21924
22780
|
try {
|
|
21925
|
-
return
|
|
22781
|
+
return statSync42(p).isFile();
|
|
21926
22782
|
} catch {
|
|
21927
22783
|
return false;
|
|
21928
22784
|
}
|
|
@@ -22089,9 +22945,9 @@ function executePull(rows, opts = {}) {
|
|
|
22089
22945
|
const outcomes = [];
|
|
22090
22946
|
for (const { name, body, truncated, redacted, tools } of skills) {
|
|
22091
22947
|
for (const tool of tools) {
|
|
22092
|
-
const dir =
|
|
22093
|
-
const file =
|
|
22094
|
-
if (
|
|
22948
|
+
const dir = join48(skillsDirFor(tool), name);
|
|
22949
|
+
const file = join48(dir, "SKILL.md");
|
|
22950
|
+
if (existsSync46(file)) {
|
|
22095
22951
|
outcomes.push({ type: "skill", name, tool, status: "present" });
|
|
22096
22952
|
continue;
|
|
22097
22953
|
}
|
|
@@ -22136,7 +22992,7 @@ function executePull(rows, opts = {}) {
|
|
|
22136
22992
|
outcomes.push({ type, name, tool, status: "failed", reason: e instanceof Error ? e.message : "emit failed" });
|
|
22137
22993
|
continue;
|
|
22138
22994
|
}
|
|
22139
|
-
if (
|
|
22995
|
+
if (existsSync46(out.path)) {
|
|
22140
22996
|
outcomes.push({ type, name, tool, status: "present" });
|
|
22141
22997
|
continue;
|
|
22142
22998
|
}
|
|
@@ -22423,11 +23279,16 @@ async function repairAll(opts = {}) {
|
|
|
22423
23279
|
scanned++;
|
|
22424
23280
|
if (opts.verbose && scanned % 50 === 0) log6(`checked ${scanned}/${ids.length}\u2026`);
|
|
22425
23281
|
const arch = await fetchJson(`${primary.url}/api/conversations/${id}/raw-archive?count=1`, primary.token);
|
|
22426
|
-
const
|
|
22427
|
-
if (
|
|
22428
|
-
|
|
22429
|
-
|
|
22430
|
-
|
|
23282
|
+
const counted = arch && arch.messages !== null;
|
|
23283
|
+
if (counted) {
|
|
23284
|
+
const archiveMsgs = typeof arch?.messages === "number" ? arch.messages : 0;
|
|
23285
|
+
if (archiveMsgs < minMessages) continue;
|
|
23286
|
+
const meta = await fetchJson(`${primary.url}/api/conversations/${id}/metadata`, primary.token);
|
|
23287
|
+
const current = typeof meta?.messageCount === "number" ? meta.messageCount : 0;
|
|
23288
|
+
if (archiveMsgs <= current) continue;
|
|
23289
|
+
} else if (!arch) {
|
|
23290
|
+
continue;
|
|
23291
|
+
}
|
|
22431
23292
|
const r = await repairSession(id, { dryRun: !opts.apply, verbose: opts.verbose, server: opts.server });
|
|
22432
23293
|
if (r.status === "already-full") continue;
|
|
22433
23294
|
candidates2.push(r);
|
|
@@ -22455,8 +23316,8 @@ __export(shadow_prune_exports, {
|
|
|
22455
23316
|
DEFAULT_MAX_TOTAL_BYTES: () => DEFAULT_MAX_TOTAL_BYTES,
|
|
22456
23317
|
pruneShadow: () => pruneShadow
|
|
22457
23318
|
});
|
|
22458
|
-
import { readdirSync as readdirSync32, statSync as
|
|
22459
|
-
import { join as
|
|
23319
|
+
import { readdirSync as readdirSync32, statSync as statSync45, unlinkSync as unlinkSync3 } from "fs";
|
|
23320
|
+
import { join as join51 } from "path";
|
|
22460
23321
|
function listShadows(isFullyAcked) {
|
|
22461
23322
|
const out = [];
|
|
22462
23323
|
const root = shadowRoot();
|
|
@@ -22467,7 +23328,7 @@ function listShadows(isFullyAcked) {
|
|
|
22467
23328
|
return out;
|
|
22468
23329
|
}
|
|
22469
23330
|
for (const tool of tools) {
|
|
22470
|
-
const dir =
|
|
23331
|
+
const dir = join51(root, tool);
|
|
22471
23332
|
let names;
|
|
22472
23333
|
try {
|
|
22473
23334
|
names = readdirSync32(dir);
|
|
@@ -22477,10 +23338,10 @@ function listShadows(isFullyAcked) {
|
|
|
22477
23338
|
for (const name of names) {
|
|
22478
23339
|
if (!name.endsWith(".gz"))
|
|
22479
23340
|
continue;
|
|
22480
|
-
const path =
|
|
23341
|
+
const path = join51(dir, name);
|
|
22481
23342
|
let st;
|
|
22482
23343
|
try {
|
|
22483
|
-
st =
|
|
23344
|
+
st = statSync45(path);
|
|
22484
23345
|
} catch {
|
|
22485
23346
|
continue;
|
|
22486
23347
|
}
|
|
@@ -22595,9 +23456,9 @@ var init_code_intel = __esm({
|
|
|
22595
23456
|
});
|
|
22596
23457
|
|
|
22597
23458
|
// ../engine/dist/core/companions.js
|
|
22598
|
-
import { existsSync as
|
|
23459
|
+
import { existsSync as existsSync49, 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
23460
|
import { homedir as homedir19 } from "node:os";
|
|
22600
|
-
import { join as
|
|
23461
|
+
import { join as join52 } from "node:path";
|
|
22601
23462
|
import { execSync as execSync3 } from "node:child_process";
|
|
22602
23463
|
import { createHash as createHash13 } from "node:crypto";
|
|
22603
23464
|
function expectedCodeindexSha256(artifact) {
|
|
@@ -22646,7 +23507,7 @@ function checkCodeindexStatus() {
|
|
|
22646
23507
|
status.installed = true;
|
|
22647
23508
|
status.path = foundPath;
|
|
22648
23509
|
try {
|
|
22649
|
-
status.size =
|
|
23510
|
+
status.size = statSync46(foundPath).size;
|
|
22650
23511
|
} catch {
|
|
22651
23512
|
}
|
|
22652
23513
|
try {
|
|
@@ -22672,7 +23533,7 @@ async function downloadArtifact(artifact, dest) {
|
|
|
22672
23533
|
throw new Error(`Download failed: ${res.status} ${res.statusText}`);
|
|
22673
23534
|
if (!res.body)
|
|
22674
23535
|
throw new Error("Download returned empty body");
|
|
22675
|
-
const file =
|
|
23536
|
+
const file = createWriteStream2(dest);
|
|
22676
23537
|
await new Promise((resolve3, reject) => {
|
|
22677
23538
|
const reader = res.body.getReader();
|
|
22678
23539
|
const pump = async () => {
|
|
@@ -22707,7 +23568,7 @@ async function installCodeindex(opts = {}) {
|
|
|
22707
23568
|
if (!expected) {
|
|
22708
23569
|
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
23570
|
}
|
|
22710
|
-
const actual = createHash13("sha256").update(
|
|
23571
|
+
const actual = createHash13("sha256").update(readFileSync43(tmpPath)).digest("hex");
|
|
22711
23572
|
if (actual !== expected) {
|
|
22712
23573
|
throw new Error(`Checksum mismatch for ${status.artifactName}.
|
|
22713
23574
|
expected ${expected}
|
|
@@ -22718,7 +23579,7 @@ Refusing to install. The release may have been re-uploaded, or something is serv
|
|
|
22718
23579
|
renameSync5(tmpPath, CODEINDEX_BIN_PATH);
|
|
22719
23580
|
} catch (err) {
|
|
22720
23581
|
try {
|
|
22721
|
-
if (
|
|
23582
|
+
if (existsSync49(tmpPath))
|
|
22722
23583
|
unlinkSync4(tmpPath);
|
|
22723
23584
|
} catch {
|
|
22724
23585
|
}
|
|
@@ -22741,9 +23602,9 @@ var init_companions = __esm({
|
|
|
22741
23602
|
"x86_64-windows": "a96fc8c8949bb399a44cc0615b12e458460a529c69f01e8829cc39a20f45ab29",
|
|
22742
23603
|
"aarch64-windows": "42620d56272cd9ba9d785569d8d754d6b4a3e80f36f28db3e0c483fd600ed117"
|
|
22743
23604
|
};
|
|
22744
|
-
CODEINDEX_INSTALL_DIR =
|
|
23605
|
+
CODEINDEX_INSTALL_DIR = join52(homedir19(), ".local", "bin");
|
|
22745
23606
|
CODEINDEX_BIN_NAME = process.platform === "win32" ? "codeindex.exe" : "codeindex";
|
|
22746
|
-
CODEINDEX_BIN_PATH =
|
|
23607
|
+
CODEINDEX_BIN_PATH = join52(CODEINDEX_INSTALL_DIR, CODEINDEX_BIN_NAME);
|
|
22747
23608
|
}
|
|
22748
23609
|
});
|
|
22749
23610
|
|
|
@@ -22858,8 +23719,8 @@ __export(collector_exports, {
|
|
|
22858
23719
|
});
|
|
22859
23720
|
import { spawn as spawn2 } from "node:child_process";
|
|
22860
23721
|
import { execSync as execSync4 } from "node:child_process";
|
|
22861
|
-
import { readFileSync as
|
|
22862
|
-
import { join as
|
|
23722
|
+
import { readFileSync as readFileSync44 } from "node:fs";
|
|
23723
|
+
import { join as join53, basename as basename24 } from "node:path";
|
|
22863
23724
|
async function resolveCodeindexBin(autoInstall = true) {
|
|
22864
23725
|
let st = checkCodeindexStatus();
|
|
22865
23726
|
if (!st.installed && autoInstall)
|
|
@@ -23041,7 +23902,7 @@ async function collectCode(opts) {
|
|
|
23041
23902
|
}
|
|
23042
23903
|
const complexity = (r) => {
|
|
23043
23904
|
try {
|
|
23044
|
-
const txt =
|
|
23905
|
+
const txt = readFileSync44(join53(ws, r), "utf8");
|
|
23045
23906
|
if (txt.length > 2e6)
|
|
23046
23907
|
return 1;
|
|
23047
23908
|
const m = txt.match(CF_RE);
|
|
@@ -23805,15 +24666,15 @@ __export(service_installer_exports, {
|
|
|
23805
24666
|
uninstallService: () => uninstallService
|
|
23806
24667
|
});
|
|
23807
24668
|
import { execSync as execSync5 } from "child_process";
|
|
23808
|
-
import { existsSync as
|
|
24669
|
+
import { existsSync as existsSync50, mkdirSync as mkdirSync17, readFileSync as readFileSync45, rmSync as rmSync8, writeFileSync as writeFileSync16 } from "fs";
|
|
23809
24670
|
import { homedir as homedir20 } from "os";
|
|
23810
|
-
import { join as
|
|
24671
|
+
import { join as join54 } from "path";
|
|
23811
24672
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
23812
24673
|
function resolveDaemonPaths() {
|
|
23813
24674
|
const watchJs = fileURLToPath5(new URL("./watch.js", import.meta.url));
|
|
23814
24675
|
const node = process.execPath;
|
|
23815
|
-
const dataDir =
|
|
23816
|
-
const logFile =
|
|
24676
|
+
const dataDir = join54(homedir20(), ".chat-recall");
|
|
24677
|
+
const logFile = join54(dataDir, "watch.log");
|
|
23817
24678
|
return { watchJs, node, logFile, dataDir };
|
|
23818
24679
|
}
|
|
23819
24680
|
function tryCmd(cmd) {
|
|
@@ -23840,12 +24701,12 @@ function refreshServiceDefinition() {
|
|
|
23840
24701
|
if (process.platform !== "linux") return false;
|
|
23841
24702
|
try {
|
|
23842
24703
|
const { watchJs, node, logFile } = resolveDaemonPaths();
|
|
23843
|
-
const unitPath =
|
|
23844
|
-
if (!
|
|
23845
|
-
const current =
|
|
24704
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
24705
|
+
if (!existsSync50(unitPath)) return false;
|
|
24706
|
+
const current = readFileSync45(unitPath, "utf8");
|
|
23846
24707
|
if (!current.includes(watchJs)) return false;
|
|
23847
24708
|
const wanted = renderSystemdUnit(watchJs, node, logFile);
|
|
23848
|
-
if (
|
|
24709
|
+
if (readFileSync45(unitPath, "utf8") === wanted) return false;
|
|
23849
24710
|
writeFileSync16(unitPath, wanted);
|
|
23850
24711
|
execSync5("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
23851
24712
|
return true;
|
|
@@ -23871,8 +24732,8 @@ function installService() {
|
|
|
23871
24732
|
);
|
|
23872
24733
|
}
|
|
23873
24734
|
function installSystemd(watchJs, node, logFile) {
|
|
23874
|
-
const unitDir =
|
|
23875
|
-
const unitPath =
|
|
24735
|
+
const unitDir = join54(homedir20(), ".config", "systemd", "user");
|
|
24736
|
+
const unitPath = join54(unitDir, "chat-recall-watch.service");
|
|
23876
24737
|
const unit = renderSystemdUnit(watchJs, node, logFile);
|
|
23877
24738
|
mkdirSync17(unitDir, { recursive: true });
|
|
23878
24739
|
writeFileSync16(unitPath, unit);
|
|
@@ -23951,8 +24812,8 @@ function renderSystemdUnit(watchJs, node, logFile) {
|
|
|
23951
24812
|
}
|
|
23952
24813
|
function installLaunchd(watchJs, node, logFile) {
|
|
23953
24814
|
const label = "com.chat-recall.watch";
|
|
23954
|
-
const plistDir =
|
|
23955
|
-
const plistPath =
|
|
24815
|
+
const plistDir = join54(homedir20(), "Library", "LaunchAgents");
|
|
24816
|
+
const plistPath = join54(plistDir, `${label}.plist`);
|
|
23956
24817
|
const plist = renderLaunchdPlist(watchJs, node, logFile, label);
|
|
23957
24818
|
mkdirSync17(plistDir, { recursive: true });
|
|
23958
24819
|
writeFileSync16(plistPath, plist);
|
|
@@ -24008,9 +24869,9 @@ function uninstallService() {
|
|
|
24008
24869
|
removed = true;
|
|
24009
24870
|
} catch {
|
|
24010
24871
|
}
|
|
24011
|
-
const unitPath =
|
|
24012
|
-
if (
|
|
24013
|
-
|
|
24872
|
+
const unitPath = join54(homedir20(), ".config", "systemd", "user", "chat-recall-watch.service");
|
|
24873
|
+
if (existsSync50(unitPath)) {
|
|
24874
|
+
rmSync8(unitPath, { force: true });
|
|
24014
24875
|
removed = true;
|
|
24015
24876
|
}
|
|
24016
24877
|
try {
|
|
@@ -24020,14 +24881,14 @@ function uninstallService() {
|
|
|
24020
24881
|
return removed;
|
|
24021
24882
|
}
|
|
24022
24883
|
if (process.platform === "darwin") {
|
|
24023
|
-
const plistPath =
|
|
24884
|
+
const plistPath = join54(homedir20(), "Library", "LaunchAgents", "com.chat-recall.watch.plist");
|
|
24024
24885
|
try {
|
|
24025
24886
|
execSync5(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: "ignore" });
|
|
24026
24887
|
} catch {
|
|
24027
24888
|
}
|
|
24028
24889
|
let removed = false;
|
|
24029
|
-
if (
|
|
24030
|
-
|
|
24890
|
+
if (existsSync50(plistPath)) {
|
|
24891
|
+
rmSync8(plistPath, { force: true });
|
|
24031
24892
|
removed = true;
|
|
24032
24893
|
}
|
|
24033
24894
|
return removed;
|
|
@@ -24071,7 +24932,7 @@ init_settings();
|
|
|
24071
24932
|
init_sync_client();
|
|
24072
24933
|
init_http();
|
|
24073
24934
|
import chokidar from "chokidar";
|
|
24074
|
-
import { dirname as dirname25, basename as basename25, join as
|
|
24935
|
+
import { dirname as dirname25, basename as basename25, join as join55, resolve as resolve2, sep as sep4 } from "path";
|
|
24075
24936
|
import { homedir as homedir21 } from "os";
|
|
24076
24937
|
|
|
24077
24938
|
// src/intent-drain.ts
|
|
@@ -24084,13 +24945,13 @@ init_codex2();
|
|
|
24084
24945
|
init_cursor();
|
|
24085
24946
|
init_opencode();
|
|
24086
24947
|
init_agy();
|
|
24087
|
-
import { existsSync as
|
|
24088
|
-
import { join as
|
|
24948
|
+
import { existsSync as existsSync47, readFileSync as readFileSync40, writeFileSync as writeFileSync13, appendFileSync, mkdirSync as mkdirSync14 } from "node:fs";
|
|
24949
|
+
import { join as join49 } from "node:path";
|
|
24089
24950
|
|
|
24090
24951
|
// src/project-tasks.ts
|
|
24091
24952
|
init_http();
|
|
24092
|
-
import { existsSync as
|
|
24093
|
-
import { join as
|
|
24953
|
+
import { existsSync as existsSync44, readFileSync as readFileSync39, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12, statSync as statSync40 } from "node:fs";
|
|
24954
|
+
import { join as join46, dirname as dirname21 } from "node:path";
|
|
24094
24955
|
import { homedir as homedir18 } from "node:os";
|
|
24095
24956
|
|
|
24096
24957
|
// ../engine/dist/core/secret-task-status.js
|
|
@@ -24159,11 +25020,11 @@ function parseTaskFile(content) {
|
|
|
24159
25020
|
return out;
|
|
24160
25021
|
}
|
|
24161
25022
|
function ledgerPath2() {
|
|
24162
|
-
return
|
|
25023
|
+
return join46(homedir18(), ".chat-recall", "project-tasks-ledger.json");
|
|
24163
25024
|
}
|
|
24164
25025
|
function readLedger() {
|
|
24165
25026
|
try {
|
|
24166
|
-
return JSON.parse(
|
|
25027
|
+
return JSON.parse(readFileSync39(ledgerPath2(), "utf8"));
|
|
24167
25028
|
} catch {
|
|
24168
25029
|
return {};
|
|
24169
25030
|
}
|
|
@@ -24196,18 +25057,18 @@ async function pushProjectTaskStatuses(base3, authHeaders, opts = {}) {
|
|
|
24196
25057
|
continue;
|
|
24197
25058
|
}
|
|
24198
25059
|
for (const project of projects) {
|
|
24199
|
-
const file =
|
|
24200
|
-
if (!
|
|
25060
|
+
const file = join46(project, fk.filename);
|
|
25061
|
+
if (!existsSync44(file)) continue;
|
|
24201
25062
|
let mtime;
|
|
24202
25063
|
try {
|
|
24203
|
-
mtime =
|
|
25064
|
+
mtime = statSync40(file).mtimeMs;
|
|
24204
25065
|
} catch {
|
|
24205
25066
|
continue;
|
|
24206
25067
|
}
|
|
24207
25068
|
if (ledger[file] === mtime) continue;
|
|
24208
25069
|
let changed;
|
|
24209
25070
|
try {
|
|
24210
|
-
changed = parseTaskFile(
|
|
25071
|
+
changed = parseTaskFile(readFileSync39(file, "utf8")).filter((t) => t.kind === fk.kind);
|
|
24211
25072
|
} catch {
|
|
24212
25073
|
continue;
|
|
24213
25074
|
}
|
|
@@ -24258,16 +25119,16 @@ function instructionTargets(rootPath, isGlobal) {
|
|
|
24258
25119
|
const tools = installed.length ? installed : [INSTRUCTION_TOOLS[0]];
|
|
24259
25120
|
if (isGlobal) return [...new Set(tools.map((t) => instructionsPath(t.id)))];
|
|
24260
25121
|
if (!rootPath) return [];
|
|
24261
|
-
const present = INSTRUCTION_FILENAMES.map((f) =>
|
|
25122
|
+
const present = INSTRUCTION_FILENAMES.map((f) => join49(rootPath, f)).filter((p) => existsSync47(p));
|
|
24262
25123
|
if (present.length) return present;
|
|
24263
|
-
return [...new Set(tools.map((t) =>
|
|
25124
|
+
return [...new Set(tools.map((t) => join49(rootPath, instructionsFilename(t.id))))];
|
|
24264
25125
|
}
|
|
24265
25126
|
function applyCodeRecommendation(intent) {
|
|
24266
25127
|
try {
|
|
24267
25128
|
const meta = JSON.parse(intent.name || "{}");
|
|
24268
25129
|
if (intent.artifact_type === "write_tasks_file") {
|
|
24269
25130
|
if (!meta.rootPath || !meta.content) return { status: "error", result: JSON.stringify({ error: "missing rootPath or content" }) };
|
|
24270
|
-
const file =
|
|
25131
|
+
const file = join49(meta.rootPath, meta.filename || "CODE_TASKS.md");
|
|
24271
25132
|
writeFileSync13(file, meta.content);
|
|
24272
25133
|
return { status: "done", result: JSON.stringify({ wrote: file }) };
|
|
24273
25134
|
}
|
|
@@ -24286,7 +25147,7 @@ function applyCodeRecommendation(intent) {
|
|
|
24286
25147
|
mkdirSync14(dir, { recursive: true });
|
|
24287
25148
|
} catch {
|
|
24288
25149
|
}
|
|
24289
|
-
const existing =
|
|
25150
|
+
const existing = existsSync47(file) ? readFileSync40(file, "utf8") : "";
|
|
24290
25151
|
if (existing.includes(text)) {
|
|
24291
25152
|
skipped.push(file);
|
|
24292
25153
|
continue;
|
|
@@ -24385,10 +25246,10 @@ async function runIntent(intent, ctx) {
|
|
|
24385
25246
|
var ownVersion2 = "0.0.0";
|
|
24386
25247
|
try {
|
|
24387
25248
|
const dir = dirname23(fileURLToPath4(import.meta.url));
|
|
24388
|
-
ownVersion2 = JSON.parse(
|
|
25249
|
+
ownVersion2 = JSON.parse(readFileSync40(join49(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
24389
25250
|
} catch {
|
|
24390
25251
|
try {
|
|
24391
|
-
if (true) ownVersion2 = "0.7.
|
|
25252
|
+
if (true) ownVersion2 = "0.7.19";
|
|
24392
25253
|
} catch {
|
|
24393
25254
|
}
|
|
24394
25255
|
}
|
|
@@ -24453,14 +25314,14 @@ init_auto_update();
|
|
|
24453
25314
|
|
|
24454
25315
|
// src/code-index-cursor.ts
|
|
24455
25316
|
init_paths();
|
|
24456
|
-
import { readFileSync as
|
|
25317
|
+
import { readFileSync as readFileSync41, writeFileSync as writeFileSync14, mkdirSync as mkdirSync15, statSync as statSync43 } from "fs";
|
|
24457
25318
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
24458
25319
|
import { createHash as createHash10 } from "crypto";
|
|
24459
|
-
import { join as
|
|
24460
|
-
var cursorPath = () =>
|
|
25320
|
+
import { join as join50, dirname as dirname24 } from "path";
|
|
25321
|
+
var cursorPath = () => join50(getDataDir(), "code-index-cursor.json");
|
|
24461
25322
|
function readCursor() {
|
|
24462
25323
|
try {
|
|
24463
|
-
const raw = JSON.parse(
|
|
25324
|
+
const raw = JSON.parse(readFileSync41(cursorPath(), "utf-8"));
|
|
24464
25325
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
24465
25326
|
const out = {};
|
|
24466
25327
|
for (const [k, v] of Object.entries(raw)) {
|
|
@@ -24504,7 +25365,7 @@ function workspaceFingerprint(workspace, collectorVersion) {
|
|
|
24504
25365
|
const rel = entry.slice(3);
|
|
24505
25366
|
let stamp2 = "gone";
|
|
24506
25367
|
try {
|
|
24507
|
-
const s =
|
|
25368
|
+
const s = statSync43(join50(workspace, rel));
|
|
24508
25369
|
stamp2 = `${s.size}:${Math.floor(s.mtimeMs)}`;
|
|
24509
25370
|
} catch {
|
|
24510
25371
|
}
|
|
@@ -24640,13 +25501,13 @@ init_telemetry();
|
|
|
24640
25501
|
|
|
24641
25502
|
// src/self-restart.ts
|
|
24642
25503
|
import { spawn } from "child_process";
|
|
24643
|
-
import { readFileSync as
|
|
25504
|
+
import { readFileSync as readFileSync42 } from "fs";
|
|
24644
25505
|
import { createHash as createHash11 } from "crypto";
|
|
24645
25506
|
var EXIT_CODE_CODE_CHANGED = 75;
|
|
24646
25507
|
function codeFingerprint(entry = process.argv[1]) {
|
|
24647
25508
|
if (!entry) return null;
|
|
24648
25509
|
try {
|
|
24649
|
-
const buf =
|
|
25510
|
+
const buf = readFileSync42(entry);
|
|
24650
25511
|
return {
|
|
24651
25512
|
path: entry,
|
|
24652
25513
|
size: buf.byteLength,
|
|
@@ -24713,11 +25574,11 @@ function checkSelfRestart(opts) {
|
|
|
24713
25574
|
}
|
|
24714
25575
|
|
|
24715
25576
|
// src/log-rotate.ts
|
|
24716
|
-
import { statSync as
|
|
25577
|
+
import { statSync as statSync44, copyFileSync as copyFileSync3, truncateSync } from "fs";
|
|
24717
25578
|
var LOG_MAX_BYTES = 32 * 1024 * 1024;
|
|
24718
25579
|
function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
24719
25580
|
try {
|
|
24720
|
-
const size =
|
|
25581
|
+
const size = statSync44(logPath).size;
|
|
24721
25582
|
if (size < maxBytes) return { rotated: false, sizeBefore: 0 };
|
|
24722
25583
|
copyFileSync3(logPath, `${logPath}.1`);
|
|
24723
25584
|
truncateSync(logPath, 0);
|
|
@@ -24729,8 +25590,8 @@ function rotateLogIfLarge(logPath, maxBytes = LOG_MAX_BYTES) {
|
|
|
24729
25590
|
|
|
24730
25591
|
// src/collector-migrate.ts
|
|
24731
25592
|
init_http();
|
|
24732
|
-
import { existsSync as
|
|
24733
|
-
function selectProjectsToReindex(projects, current, existsFn =
|
|
25593
|
+
import { existsSync as existsSync48 } from "node:fs";
|
|
25594
|
+
function selectProjectsToReindex(projects, current, existsFn = existsSync48) {
|
|
24734
25595
|
const reindex = [];
|
|
24735
25596
|
const missing = [];
|
|
24736
25597
|
for (const p of projects) {
|
|
@@ -24772,8 +25633,8 @@ async function runCollectorMigration(opts) {
|
|
|
24772
25633
|
// auto-indexer/indexer.ts
|
|
24773
25634
|
init_sync_ledger();
|
|
24774
25635
|
init_collector_health();
|
|
24775
|
-
import { existsSync as
|
|
24776
|
-
var CLI_VERSION3 = true ? "0.7.
|
|
25636
|
+
import { existsSync as existsSync51, readFileSync as readFileSync46, statSync as statSync47 } from "fs";
|
|
25637
|
+
var CLI_VERSION3 = true ? "0.7.19" : "0.0.0";
|
|
24777
25638
|
var DEBOUNCE_MS = 5e3;
|
|
24778
25639
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
24779
25640
|
var TASKS_DIR = claudeBackend.tasksDir();
|
|
@@ -24782,8 +25643,8 @@ var DIARY_DIR = getDiaryDir();
|
|
|
24782
25643
|
var CODEX_SESSIONS_DIR = codexBackend.sessionsDir();
|
|
24783
25644
|
var OPENCODE_DB_PATH = opencodeBackend.dbPath();
|
|
24784
25645
|
var OPENCODE_DB_DIR = dirname25(OPENCODE_DB_PATH);
|
|
24785
|
-
var CURRENT_RESUME_PATH =
|
|
24786
|
-
var LAST_CLEANUP_PATH =
|
|
25646
|
+
var CURRENT_RESUME_PATH = join55(claudeBackend.homeDir(), "current-resume");
|
|
25647
|
+
var LAST_CLEANUP_PATH = join55(claudeBackend.homeDir(), ".last-cleanup");
|
|
24787
25648
|
var debounceTimer = null;
|
|
24788
25649
|
var ticks = new TickQueue({
|
|
24789
25650
|
onError: (kind, err) => daemonLog.error(`${kind} tick failed: ${err instanceof Error ? err.message : err}`)
|
|
@@ -24832,7 +25693,7 @@ var lastResumeAt = /* @__PURE__ */ new Map();
|
|
|
24832
25693
|
var RESUME_REARM_MS = 6e4;
|
|
24833
25694
|
async function onResumeSignal(path) {
|
|
24834
25695
|
try {
|
|
24835
|
-
const txt =
|
|
25696
|
+
const txt = readFileSync46(path, "utf-8");
|
|
24836
25697
|
const m = /--resume\s+([0-9a-fA-F-]{36})/.exec(txt);
|
|
24837
25698
|
if (!m) return;
|
|
24838
25699
|
const id = m[1];
|
|
@@ -24878,7 +25739,7 @@ var CLAUDE_SESSION_ROOTS = claudeProjectDirs();
|
|
|
24878
25739
|
var sessionWatcher = watchWithFallback("sessions", CLAUDE_SESSION_ROOTS.map((root) => `${root}/**/*.jsonl`), {
|
|
24879
25740
|
ignored: (p, stats) => {
|
|
24880
25741
|
if (/agent-/.test(p) || /^\./.test(basename25(p))) return true;
|
|
24881
|
-
const st = stats ??
|
|
25742
|
+
const st = stats ?? statSync47(p, { throwIfNoEntry: false });
|
|
24882
25743
|
if (!st || st.isDirectory()) return false;
|
|
24883
25744
|
return st.mtimeMs < Date.now() - WATCH_WINDOW_MS;
|
|
24884
25745
|
},
|
|
@@ -24925,6 +25786,16 @@ var opencodeWatcher = chokidar.watch(
|
|
|
24925
25786
|
...POLL(1e4)
|
|
24926
25787
|
}
|
|
24927
25788
|
);
|
|
25789
|
+
var HERMES_DB_PATHS = hermesBackend.dbPaths();
|
|
25790
|
+
var hermesWatcher = chokidar.watch(
|
|
25791
|
+
HERMES_DB_PATHS.flatMap((p) => [p, `${p}-wal`]),
|
|
25792
|
+
{
|
|
25793
|
+
persistent: true,
|
|
25794
|
+
ignoreInitial: true,
|
|
25795
|
+
awaitWriteFinish: { stabilityThreshold: 2500, pollInterval: 500 },
|
|
25796
|
+
...POLL(1e4)
|
|
25797
|
+
}
|
|
25798
|
+
);
|
|
24928
25799
|
var agentMemoryWatcher = chokidar.watch(CLAUDE_SESSION_ROOTS.map((root) => `${root}/*/memory/*.md`), {
|
|
24929
25800
|
persistent: true,
|
|
24930
25801
|
ignoreInitial: true,
|
|
@@ -24945,6 +25816,7 @@ var watchers = {
|
|
|
24945
25816
|
diary: diaryWatcher,
|
|
24946
25817
|
codex: codexWatcher,
|
|
24947
25818
|
opencode: opencodeWatcher,
|
|
25819
|
+
hermes: hermesWatcher,
|
|
24948
25820
|
agentMemory: agentMemoryWatcher,
|
|
24949
25821
|
cleanup: cleanupWatcher
|
|
24950
25822
|
};
|
|
@@ -24980,6 +25852,7 @@ daemonLog.info(` Watching history: ${HISTORY_PATH}`);
|
|
|
24980
25852
|
daemonLog.info(` Watching diary: ${DIARY_DIR}`);
|
|
24981
25853
|
daemonLog.info(` Watching codex: ${CODEX_SESSIONS_DIR}`);
|
|
24982
25854
|
daemonLog.info(` Watching opencode: ${OPENCODE_DB_DIR}`);
|
|
25855
|
+
daemonLog.info(` Watching hermes: ${HERMES_DB_PATHS.join(", ")}`);
|
|
24983
25856
|
daemonLog.info(` Watching agent memory: ${CLAUDE_SESSION_ROOTS.map((root) => `${root}/*/memory/`).join(", ")}`);
|
|
24984
25857
|
daemonLog.info(` Resume-guard: ${CURRENT_RESUME_PATH}`);
|
|
24985
25858
|
daemonLog.info(` Debounce: ${DEBOUNCE_MS}ms \xB7 ships via syncIncremental() to the configured server`);
|
|
@@ -25020,7 +25893,7 @@ if (BOOT_CODE) {
|
|
|
25020
25893
|
daemonLog.info(`running bundle ${BOOT_CODE.path} (${BOOT_CODE.size} bytes)`);
|
|
25021
25894
|
}
|
|
25022
25895
|
{
|
|
25023
|
-
const r = rotateLogIfLarge(
|
|
25896
|
+
const r = rotateLogIfLarge(join55(getDataDir(), "watch.log"));
|
|
25024
25897
|
if (r.rotated) {
|
|
25025
25898
|
daemonLog.info(`rotated watch.log at ${(r.sizeBefore / 1048576).toFixed(0)}MB \u2192 watch.log.1 (copy+truncate; the path is preserved)`);
|
|
25026
25899
|
}
|
|
@@ -25174,7 +26047,7 @@ function discoverWorkspaces() {
|
|
|
25174
26047
|
const isExcluded = (p) => excluded.some((x) => p.includes(x));
|
|
25175
26048
|
const candidates2 = [...newest.entries()].filter(([p]) => !isExcluded(p)).filter(([p]) => !isPersonalPath(p, includeProjects)).filter(([p]) => {
|
|
25176
26049
|
try {
|
|
25177
|
-
return
|
|
26050
|
+
return existsSync51(p);
|
|
25178
26051
|
} catch {
|
|
25179
26052
|
return false;
|
|
25180
26053
|
}
|
|
@@ -25206,7 +26079,7 @@ function isCodeWorkspace(p) {
|
|
|
25206
26079
|
}
|
|
25207
26080
|
return WORKSPACE_MARKERS.some((m) => {
|
|
25208
26081
|
try {
|
|
25209
|
-
return
|
|
26082
|
+
return existsSync51(join55(p, m));
|
|
25210
26083
|
} catch {
|
|
25211
26084
|
return false;
|
|
25212
26085
|
}
|