chat-recall 0.6.8 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +966 -909
- package/dist/cli.js.map +1 -1
- package/dist/mcp-relay.js +1 -1
- package/dist/mcp.js +1043 -775
- package/dist/scan-worker.js +325 -25
- package/dist/scan-worker.js.map +1 -1
- package/dist/sync-client.d.ts +13 -0
- package/dist/sync-client.d.ts.map +1 -1
- package/dist/sync-client.js +38 -4
- package/dist/sync-client.js.map +1 -1
- package/dist/watch.js +895 -856
- package/package.json +1 -1
package/dist/watch.js
CHANGED
|
@@ -5031,577 +5031,262 @@ var init_settings = __esm({
|
|
|
5031
5031
|
}
|
|
5032
5032
|
});
|
|
5033
5033
|
|
|
5034
|
-
// ../engine/dist/core/
|
|
5035
|
-
import {
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
} catch {
|
|
5044
|
-
return trimmed;
|
|
5045
|
-
}
|
|
5034
|
+
// ../engine/dist/core/secret-redactor.js
|
|
5035
|
+
import { statSync as statSync3 } from "fs";
|
|
5036
|
+
function secretOf(rule, m) {
|
|
5037
|
+
const raw = rule.secret != null ? m[rule.secret] : m[0];
|
|
5038
|
+
if (raw == null)
|
|
5039
|
+
return null;
|
|
5040
|
+
if (rule.where && !rule.where(raw))
|
|
5041
|
+
return null;
|
|
5042
|
+
return raw;
|
|
5046
5043
|
}
|
|
5047
|
-
function
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
const
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
for (const e of readdirSync2(parent, { withFileTypes: true })) {
|
|
5071
|
-
if (!e.isDirectory())
|
|
5072
|
-
continue;
|
|
5073
|
-
if (e.name === leaf || !e.name.startsWith(leaf + "-"))
|
|
5074
|
-
continue;
|
|
5075
|
-
if (e.name === ".claude-code")
|
|
5076
|
-
continue;
|
|
5077
|
-
add(join3(parent, e.name), marker);
|
|
5044
|
+
function looksLikeSecretToken(t) {
|
|
5045
|
+
if (t.length < 32)
|
|
5046
|
+
return false;
|
|
5047
|
+
if (/^[a-f0-9]+$/i.test(t))
|
|
5048
|
+
return true;
|
|
5049
|
+
return /[A-Z]/.test(t) && /[a-z]/.test(t) && /[0-9]/.test(t);
|
|
5050
|
+
}
|
|
5051
|
+
function findContextualSecrets(text) {
|
|
5052
|
+
if (!text)
|
|
5053
|
+
return [];
|
|
5054
|
+
const ranges = [];
|
|
5055
|
+
let m;
|
|
5056
|
+
SECRET_CONTEXT_RE.lastIndex = 0;
|
|
5057
|
+
while ((m = SECRET_CONTEXT_RE.exec(text)) !== null) {
|
|
5058
|
+
const winStart = m.index + m[0].length;
|
|
5059
|
+
const window = text.slice(winStart, winStart + 80);
|
|
5060
|
+
HIGH_ENTROPY_TOKEN_RE.lastIndex = 0;
|
|
5061
|
+
let tm;
|
|
5062
|
+
while ((tm = HIGH_ENTROPY_TOKEN_RE.exec(window)) !== null) {
|
|
5063
|
+
if (!looksLikeSecretToken(tm[0]))
|
|
5064
|
+
continue;
|
|
5065
|
+
if (/^[a-f0-9]+$/i.test(tm[0]) && /\b(?:commit|sha-?\d*|hash|digest|checksum|uuid|guid|etag|blob|ref)\b/i.test(window.slice(0, tm.index))) {
|
|
5066
|
+
continue;
|
|
5078
5067
|
}
|
|
5079
|
-
|
|
5068
|
+
ranges.push({ start: winStart + tm.index, end: winStart + tm.index + tm[0].length });
|
|
5069
|
+
break;
|
|
5080
5070
|
}
|
|
5081
5071
|
}
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
return { seeded: [] };
|
|
5090
|
-
}
|
|
5091
|
-
if (s.sources.homesGrandfathered)
|
|
5092
|
-
return { seeded: [] };
|
|
5093
|
-
const legacy = legacyAutoSyncedHomes();
|
|
5094
|
-
const approved = new Set((s.sources.approvedHomes ?? []).map(normalizeHomePath));
|
|
5095
|
-
const seeded = [];
|
|
5096
|
-
for (const p of legacy) {
|
|
5097
|
-
if (!approved.has(p)) {
|
|
5098
|
-
approved.add(p);
|
|
5099
|
-
seeded.push(p);
|
|
5072
|
+
ranges.sort((a, b) => a.start - b.start);
|
|
5073
|
+
const out = [];
|
|
5074
|
+
for (const r of ranges) {
|
|
5075
|
+
const last = out[out.length - 1];
|
|
5076
|
+
if (last && r.start < last.end) {
|
|
5077
|
+
last.end = Math.max(last.end, r.end);
|
|
5078
|
+
continue;
|
|
5100
5079
|
}
|
|
5080
|
+
out.push({ ...r });
|
|
5101
5081
|
}
|
|
5102
|
-
|
|
5103
|
-
s.sources.homesGrandfathered = true;
|
|
5104
|
-
try {
|
|
5105
|
-
saveSettings(s);
|
|
5106
|
-
} catch {
|
|
5107
|
-
return { seeded: [] };
|
|
5108
|
-
}
|
|
5109
|
-
return { seeded };
|
|
5082
|
+
return out;
|
|
5110
5083
|
}
|
|
5111
|
-
function
|
|
5112
|
-
const
|
|
5113
|
-
|
|
5114
|
-
|
|
5084
|
+
function isEnvRedactionRequested() {
|
|
5085
|
+
const v = process.env.CHAT_RECALL_REDACT_INDEX;
|
|
5086
|
+
if (v === void 0)
|
|
5087
|
+
return null;
|
|
5088
|
+
return v === "1" || v === "true" || v === "yes";
|
|
5089
|
+
}
|
|
5090
|
+
function settingsView() {
|
|
5091
|
+
let mtimeMs = -1;
|
|
5115
5092
|
try {
|
|
5116
|
-
|
|
5093
|
+
mtimeMs = statSync3(settingsFilePath()).mtimeMs;
|
|
5117
5094
|
} catch {
|
|
5118
|
-
s = void 0;
|
|
5119
5095
|
}
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
env.CHAT_RECALL_CODEX_HOME || s?.codexHome || join3(home, ".codex"),
|
|
5125
|
-
env.CHAT_RECALL_AGY_HOME || s?.agyHome || join3(home, ".gemini", "antigravity-cli"),
|
|
5126
|
-
env.CHAT_RECALL_CURSOR_HOME || s?.cursorHome || join3(home, ".cursor"),
|
|
5127
|
-
dirOf(opencodeDb)
|
|
5128
|
-
];
|
|
5129
|
-
return candidates2.map(normalizeHomePath);
|
|
5130
|
-
}
|
|
5131
|
-
function homeDecision(path) {
|
|
5132
|
-
const p = normalizeHomePath(path);
|
|
5133
|
-
if (primaryHomes().includes(p))
|
|
5134
|
-
return "primary";
|
|
5135
|
-
let s;
|
|
5096
|
+
if (cache && cache.mtimeMs === mtimeMs)
|
|
5097
|
+
return cache;
|
|
5098
|
+
let enabled = false;
|
|
5099
|
+
const extra = [];
|
|
5136
5100
|
try {
|
|
5137
|
-
s = loadSettings()
|
|
5101
|
+
const s = loadSettings();
|
|
5102
|
+
enabled = !!s.privacy?.redactIndex;
|
|
5103
|
+
for (const r of s.privacy?.redactionRules ?? []) {
|
|
5104
|
+
try {
|
|
5105
|
+
extra.push({ label: r.label, pattern: new RegExp(r.pattern, "g") });
|
|
5106
|
+
} catch {
|
|
5107
|
+
}
|
|
5108
|
+
}
|
|
5138
5109
|
} catch {
|
|
5139
|
-
return "pending";
|
|
5140
5110
|
}
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
if ((s.approvedHomes ?? []).map(normalizeHomePath).includes(p))
|
|
5144
|
-
return "approved";
|
|
5145
|
-
if ((s.extraClaudeHomes ?? []).map(normalizeHomePath).includes(p))
|
|
5146
|
-
return "approved";
|
|
5147
|
-
return "pending";
|
|
5148
|
-
}
|
|
5149
|
-
function isHomeSynced(path) {
|
|
5150
|
-
const d = homeDecision(path);
|
|
5151
|
-
return d === "primary" || d === "approved";
|
|
5111
|
+
cache = { mtimeMs, enabled, rules: [...DEFAULT_REDACTION_RULES, ...extra] };
|
|
5112
|
+
return cache;
|
|
5152
5113
|
}
|
|
5153
|
-
function
|
|
5154
|
-
const
|
|
5155
|
-
|
|
5114
|
+
function compileServerRule(spec) {
|
|
5115
|
+
const name = spec.name || "(unnamed)";
|
|
5116
|
+
if (!spec.regex)
|
|
5117
|
+
return { name, reason: "empty pattern" };
|
|
5118
|
+
if (spec.regex.length > MAX_PATTERN_LEN)
|
|
5119
|
+
return { name, reason: `pattern longer than ${MAX_PATTERN_LEN} chars` };
|
|
5120
|
+
let re;
|
|
5156
5121
|
try {
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5122
|
+
const flags = "g" + (spec.flags || "").replace(/[^ims]/g, "");
|
|
5123
|
+
re = new RegExp(spec.regex, flags);
|
|
5124
|
+
} catch (e) {
|
|
5125
|
+
return { name, reason: `invalid regex: ${e instanceof Error ? e.message : e}` };
|
|
5160
5126
|
}
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5127
|
+
if (re.test(""))
|
|
5128
|
+
return { name, reason: "matches the empty string (would redact everything)" };
|
|
5129
|
+
re.lastIndex = 0;
|
|
5130
|
+
if (re.test(CANARY))
|
|
5131
|
+
return { name, reason: "matches benign text \u2014 too broad" };
|
|
5132
|
+
re.lastIndex = 0;
|
|
5133
|
+
return { label: `${spec.source === "pack" ? "pack" : "tenant"}:${name}`, pattern: re };
|
|
5134
|
+
}
|
|
5135
|
+
function installServerRulePack(pack) {
|
|
5136
|
+
const rejected = [];
|
|
5137
|
+
const rules = [];
|
|
5138
|
+
for (const spec of pack.rules || []) {
|
|
5139
|
+
if (rules.length >= MAX_PACK_RULES) {
|
|
5140
|
+
rejected.push({ name: spec.name || "(unnamed)", reason: `pack exceeds ${MAX_PACK_RULES} rules` });
|
|
5141
|
+
continue;
|
|
5142
|
+
}
|
|
5143
|
+
const out = compileServerRule(spec);
|
|
5144
|
+
if ("reason" in out)
|
|
5145
|
+
rejected.push(out);
|
|
5146
|
+
else
|
|
5147
|
+
rules.push(out);
|
|
5172
5148
|
}
|
|
5173
|
-
|
|
5149
|
+
const version = pack.version || "";
|
|
5150
|
+
serverPack = { version, rules };
|
|
5151
|
+
return { version, accepted: rules.length, rejected };
|
|
5174
5152
|
}
|
|
5175
|
-
function
|
|
5176
|
-
return
|
|
5153
|
+
function serverRulePackVersion() {
|
|
5154
|
+
return serverPack ? serverPack.version || "unversioned" : null;
|
|
5177
5155
|
}
|
|
5178
|
-
function
|
|
5179
|
-
|
|
5156
|
+
function activeRules() {
|
|
5157
|
+
const base2 = settingsView().rules;
|
|
5158
|
+
return serverPack && serverPack.rules.length > 0 ? [...base2, ...serverPack.rules] : base2;
|
|
5180
5159
|
}
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
dirOf = (filePath) => dirname3(filePath);
|
|
5187
|
-
}
|
|
5188
|
-
});
|
|
5189
|
-
|
|
5190
|
-
// ../engine/dist/core/tool-paths.js
|
|
5191
|
-
import { existsSync as existsSync4, readdirSync as readdirSync3 } from "fs";
|
|
5192
|
-
import { homedir as homedir3 } from "os";
|
|
5193
|
-
import { join as join4, dirname as dirname4, basename } from "path";
|
|
5194
|
-
function claudeHomeDir() {
|
|
5195
|
-
return process.env.CHAT_RECALL_CLAUDE_HOME || sources().claudeHome || join4(homedir3(), ".claude");
|
|
5160
|
+
function isRedactionEnabled() {
|
|
5161
|
+
const env = isEnvRedactionRequested();
|
|
5162
|
+
if (env !== null)
|
|
5163
|
+
return env;
|
|
5164
|
+
return settingsView().enabled;
|
|
5196
5165
|
}
|
|
5197
|
-
function
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
}
|
|
5214
|
-
}
|
|
5215
|
-
}
|
|
5166
|
+
function redactSecrets(text, opts = {}) {
|
|
5167
|
+
if (!opts.force && !isRedactionEnabled())
|
|
5168
|
+
return text;
|
|
5169
|
+
if (!text)
|
|
5170
|
+
return text;
|
|
5171
|
+
const rules = opts.rules || activeRules();
|
|
5172
|
+
let out = text;
|
|
5173
|
+
for (const r of rules) {
|
|
5174
|
+
out = out.replace(r.pattern, (...args) => {
|
|
5175
|
+
const whole = args[0];
|
|
5176
|
+
const m = args.slice(0, args.length);
|
|
5177
|
+
const secret = secretOf(r, m);
|
|
5178
|
+
if (secret == null)
|
|
5179
|
+
return whole;
|
|
5180
|
+
if (opts.count)
|
|
5181
|
+
opts.count.redactions++;
|
|
5182
|
+
return whole.slice(0, whole.length - secret.length) + `[REDACTED:${r.label}]`;
|
|
5183
|
+
});
|
|
5216
5184
|
}
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5185
|
+
const ctx = findContextualSecrets(out);
|
|
5186
|
+
for (let i = ctx.length - 1; i >= 0; i--) {
|
|
5187
|
+
const { start, end } = ctx[i];
|
|
5188
|
+
if (opts.count)
|
|
5189
|
+
opts.count.redactions++;
|
|
5190
|
+
out = out.slice(0, start) + "[REDACTED:secret-context]" + out.slice(end);
|
|
5223
5191
|
}
|
|
5224
|
-
|
|
5225
|
-
dirs.push(join4(claudeHomeDir(), "projects"));
|
|
5226
|
-
return applyDecisions(dirs, opts.includeExcluded);
|
|
5227
|
-
}
|
|
5228
|
-
function _setSourceExclusionFilter(fn) {
|
|
5229
|
-
_sourceExclusionFilter = fn;
|
|
5230
|
-
}
|
|
5231
|
-
function geminiHomeDir() {
|
|
5232
|
-
return process.env.CHAT_RECALL_GEMINI_HOME || sources().geminiHome || join4(homedir3(), ".gemini");
|
|
5233
|
-
}
|
|
5234
|
-
function opencodeDbPath() {
|
|
5235
|
-
return process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath || join4(homedir3(), ".local", "share", "opencode", "opencode.db");
|
|
5236
|
-
}
|
|
5237
|
-
function codexHomeDir() {
|
|
5238
|
-
return process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome || join4(homedir3(), ".codex");
|
|
5239
|
-
}
|
|
5240
|
-
function agyHomeDir() {
|
|
5241
|
-
return process.env.CHAT_RECALL_AGY_HOME || sources().agyHome || join4(homedir3(), ".gemini", "antigravity-cli");
|
|
5192
|
+
return out;
|
|
5242
5193
|
}
|
|
5243
|
-
function
|
|
5244
|
-
|
|
5194
|
+
function maskSecret(s) {
|
|
5195
|
+
if (!s)
|
|
5196
|
+
return "";
|
|
5197
|
+
if (s.length <= 4)
|
|
5198
|
+
return "*".repeat(s.length);
|
|
5199
|
+
return "*".repeat(Math.min(s.length - 4, 60)) + s.slice(-4);
|
|
5245
5200
|
}
|
|
5246
|
-
function
|
|
5247
|
-
|
|
5201
|
+
function globalRegexFor(pattern) {
|
|
5202
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g";
|
|
5203
|
+
const key2 = pattern.source + "\0" + flags;
|
|
5204
|
+
let re = globalRegexCache.get(key2);
|
|
5205
|
+
if (!re) {
|
|
5206
|
+
re = new RegExp(pattern.source, flags);
|
|
5207
|
+
globalRegexCache.set(key2, re);
|
|
5208
|
+
}
|
|
5209
|
+
return re;
|
|
5248
5210
|
}
|
|
5249
|
-
function
|
|
5250
|
-
const
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5211
|
+
function makeLineResolver(text) {
|
|
5212
|
+
const starts = [];
|
|
5213
|
+
for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1))
|
|
5214
|
+
starts.push(i);
|
|
5215
|
+
return (index) => {
|
|
5216
|
+
let lo = 0, hi = starts.length;
|
|
5217
|
+
while (lo < hi) {
|
|
5218
|
+
const mid = lo + hi >> 1;
|
|
5219
|
+
if (starts[mid] < index)
|
|
5220
|
+
lo = mid + 1;
|
|
5221
|
+
else
|
|
5222
|
+
hi = mid;
|
|
5223
|
+
}
|
|
5224
|
+
return lo + 1;
|
|
5255
5225
|
};
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5226
|
+
}
|
|
5227
|
+
function scanTextForFindings(text, opts = {}) {
|
|
5228
|
+
if (!text)
|
|
5229
|
+
return [];
|
|
5230
|
+
const rules = opts.rules || activeRules();
|
|
5231
|
+
const findings = [];
|
|
5232
|
+
const seenSpans = /* @__PURE__ */ new Set();
|
|
5233
|
+
const lineAt = makeLineResolver(text);
|
|
5234
|
+
for (const r of rules) {
|
|
5235
|
+
const re = globalRegexFor(r.pattern);
|
|
5236
|
+
re.lastIndex = 0;
|
|
5237
|
+
let m;
|
|
5238
|
+
while ((m = re.exec(text)) !== null) {
|
|
5239
|
+
const secret = secretOf(r, m);
|
|
5240
|
+
if (secret == null) {
|
|
5241
|
+
if (re.lastIndex === m.index)
|
|
5242
|
+
re.lastIndex++;
|
|
5243
|
+
continue;
|
|
5267
5244
|
}
|
|
5268
|
-
|
|
5245
|
+
const at = m.index + (m[0].length - secret.length);
|
|
5246
|
+
const span = `${at}:${secret.length}`;
|
|
5247
|
+
if (!seenSpans.has(span)) {
|
|
5248
|
+
seenSpans.add(span);
|
|
5249
|
+
findings.push({ rule: r.label, line: lineAt(at), preview: maskSecret(secret) });
|
|
5250
|
+
}
|
|
5251
|
+
if (re.lastIndex === m.index)
|
|
5252
|
+
re.lastIndex++;
|
|
5269
5253
|
}
|
|
5270
5254
|
}
|
|
5271
|
-
|
|
5255
|
+
for (const { start, end } of findContextualSecrets(text)) {
|
|
5256
|
+
const line = lineAt(start);
|
|
5257
|
+
findings.push({ rule: "secret-context", line, preview: maskSecret(text.slice(start, end)) });
|
|
5258
|
+
}
|
|
5259
|
+
return findings;
|
|
5272
5260
|
}
|
|
5273
|
-
function
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
try {
|
|
5279
|
-
grandfatherLegacyHomes();
|
|
5280
|
-
const approved = kept.filter((r) => isHomeSynced(dirname4(r)));
|
|
5281
|
-
if (approved.length > 0)
|
|
5282
|
-
kept = approved;
|
|
5283
|
-
} catch {
|
|
5284
|
-
}
|
|
5261
|
+
function privacyView() {
|
|
5262
|
+
let mtimeMs = -1;
|
|
5263
|
+
try {
|
|
5264
|
+
mtimeMs = statSync3(settingsFilePath()).mtimeMs;
|
|
5265
|
+
} catch {
|
|
5285
5266
|
}
|
|
5286
|
-
if (
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5267
|
+
if (privacyCache && privacyCache.mtimeMs === mtimeMs)
|
|
5268
|
+
return privacyCache;
|
|
5269
|
+
let redactToolOutputs = false, redactFilePaths = false;
|
|
5270
|
+
try {
|
|
5271
|
+
const s = loadSettings();
|
|
5272
|
+
redactToolOutputs = !!s.privacy?.redactToolOutputs;
|
|
5273
|
+
redactFilePaths = !!s.privacy?.redactFilePaths;
|
|
5274
|
+
} catch {
|
|
5290
5275
|
}
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
function applyExclusions(roots, includeExcluded) {
|
|
5294
|
-
return applyDecisions(roots, includeExcluded);
|
|
5295
|
-
}
|
|
5296
|
-
function codexSessionDirs(opts = {}) {
|
|
5297
|
-
const overridden = !!(process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome);
|
|
5298
|
-
return applyExclusions(siblingHomes(codexHomeDir(), overridden, "sessions"), opts.includeExcluded);
|
|
5299
|
-
}
|
|
5300
|
-
function agyBrainDirs(opts = {}) {
|
|
5301
|
-
const overridden = !!(process.env.CHAT_RECALL_AGY_HOME || sources().agyHome);
|
|
5302
|
-
return applyExclusions(siblingHomes(agyHomeDir(), overridden, "brain"), opts.includeExcluded);
|
|
5303
|
-
}
|
|
5304
|
-
function cursorChatDirs(opts = {}) {
|
|
5305
|
-
const overridden = !!(process.env.CHAT_RECALL_CURSOR_HOME || sources().cursorHome);
|
|
5306
|
-
return applyExclusions(siblingHomes(cursorHomeDir(), overridden, "chats"), opts.includeExcluded);
|
|
5307
|
-
}
|
|
5308
|
-
function cursorIdeWorkspaceDirs(opts = {}) {
|
|
5309
|
-
const overridden = !!(process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome);
|
|
5310
|
-
return applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join4("User", "workspaceStorage")), opts.includeExcluded);
|
|
5276
|
+
privacyCache = { mtimeMs, redactToolOutputs, redactFilePaths };
|
|
5277
|
+
return privacyCache;
|
|
5311
5278
|
}
|
|
5312
|
-
function
|
|
5313
|
-
|
|
5314
|
-
const roots = applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join4("User", "globalStorage")), opts.includeExcluded);
|
|
5315
|
-
const dbs = [];
|
|
5316
|
-
for (const r of roots) {
|
|
5317
|
-
const p = join4(r, "state.vscdb");
|
|
5318
|
-
if (existsSync4(p) && !dbs.includes(p))
|
|
5319
|
-
dbs.push(p);
|
|
5320
|
-
}
|
|
5321
|
-
return dbs;
|
|
5279
|
+
function isToolOutputRedactionEnabled() {
|
|
5280
|
+
return privacyView().redactToolOutputs;
|
|
5322
5281
|
}
|
|
5323
|
-
function
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
const dirs = siblingHomes(dirname4(primary), overridden, "");
|
|
5328
|
-
const dbs = [];
|
|
5329
|
-
for (const d of dirs) {
|
|
5330
|
-
const p = join4(d, dbFile);
|
|
5331
|
-
if (existsSync4(p) && !dbs.includes(p))
|
|
5332
|
-
dbs.push(p);
|
|
5333
|
-
}
|
|
5334
|
-
if (dbs.length === 0)
|
|
5335
|
-
dbs.push(primary);
|
|
5336
|
-
return applyExclusions(dbs, opts.includeExcluded);
|
|
5282
|
+
function redactToolResultBody(toolName, body) {
|
|
5283
|
+
if (!body)
|
|
5284
|
+
return body;
|
|
5285
|
+
return `[redacted: ${toolName} output, ${body.length} chars]`;
|
|
5337
5286
|
}
|
|
5338
|
-
var
|
|
5339
|
-
var
|
|
5340
|
-
"../engine/dist/core/
|
|
5341
|
-
"use strict";
|
|
5342
|
-
init_home_approval();
|
|
5343
|
-
init_settings();
|
|
5344
|
-
sources = loadSourceSettings;
|
|
5345
|
-
_sourceExclusionFilter = null;
|
|
5346
|
-
}
|
|
5347
|
-
});
|
|
5348
|
-
|
|
5349
|
-
// ../engine/dist/core/secret-redactor.js
|
|
5350
|
-
import { statSync as statSync3 } from "fs";
|
|
5351
|
-
function secretOf(rule, m) {
|
|
5352
|
-
const raw = rule.secret != null ? m[rule.secret] : m[0];
|
|
5353
|
-
if (raw == null)
|
|
5354
|
-
return null;
|
|
5355
|
-
if (rule.where && !rule.where(raw))
|
|
5356
|
-
return null;
|
|
5357
|
-
return raw;
|
|
5358
|
-
}
|
|
5359
|
-
function looksLikeSecretToken(t) {
|
|
5360
|
-
if (t.length < 32)
|
|
5361
|
-
return false;
|
|
5362
|
-
if (/^[a-f0-9]+$/i.test(t))
|
|
5363
|
-
return true;
|
|
5364
|
-
return /[A-Z]/.test(t) && /[a-z]/.test(t) && /[0-9]/.test(t);
|
|
5365
|
-
}
|
|
5366
|
-
function findContextualSecrets(text) {
|
|
5367
|
-
if (!text)
|
|
5368
|
-
return [];
|
|
5369
|
-
const ranges = [];
|
|
5370
|
-
let m;
|
|
5371
|
-
SECRET_CONTEXT_RE.lastIndex = 0;
|
|
5372
|
-
while ((m = SECRET_CONTEXT_RE.exec(text)) !== null) {
|
|
5373
|
-
const winStart = m.index + m[0].length;
|
|
5374
|
-
const window = text.slice(winStart, winStart + 80);
|
|
5375
|
-
HIGH_ENTROPY_TOKEN_RE.lastIndex = 0;
|
|
5376
|
-
let tm;
|
|
5377
|
-
while ((tm = HIGH_ENTROPY_TOKEN_RE.exec(window)) !== null) {
|
|
5378
|
-
if (!looksLikeSecretToken(tm[0]))
|
|
5379
|
-
continue;
|
|
5380
|
-
if (/^[a-f0-9]+$/i.test(tm[0]) && /\b(?:commit|sha-?\d*|hash|digest|checksum|uuid|guid|etag|blob|ref)\b/i.test(window.slice(0, tm.index))) {
|
|
5381
|
-
continue;
|
|
5382
|
-
}
|
|
5383
|
-
ranges.push({ start: winStart + tm.index, end: winStart + tm.index + tm[0].length });
|
|
5384
|
-
break;
|
|
5385
|
-
}
|
|
5386
|
-
}
|
|
5387
|
-
ranges.sort((a, b) => a.start - b.start);
|
|
5388
|
-
const out = [];
|
|
5389
|
-
for (const r of ranges) {
|
|
5390
|
-
const last = out[out.length - 1];
|
|
5391
|
-
if (last && r.start < last.end) {
|
|
5392
|
-
last.end = Math.max(last.end, r.end);
|
|
5393
|
-
continue;
|
|
5394
|
-
}
|
|
5395
|
-
out.push({ ...r });
|
|
5396
|
-
}
|
|
5397
|
-
return out;
|
|
5398
|
-
}
|
|
5399
|
-
function isEnvRedactionRequested() {
|
|
5400
|
-
const v = process.env.CHAT_RECALL_REDACT_INDEX;
|
|
5401
|
-
if (v === void 0)
|
|
5402
|
-
return null;
|
|
5403
|
-
return v === "1" || v === "true" || v === "yes";
|
|
5404
|
-
}
|
|
5405
|
-
function settingsView() {
|
|
5406
|
-
let mtimeMs = -1;
|
|
5407
|
-
try {
|
|
5408
|
-
mtimeMs = statSync3(settingsFilePath()).mtimeMs;
|
|
5409
|
-
} catch {
|
|
5410
|
-
}
|
|
5411
|
-
if (cache && cache.mtimeMs === mtimeMs)
|
|
5412
|
-
return cache;
|
|
5413
|
-
let enabled = false;
|
|
5414
|
-
const extra = [];
|
|
5415
|
-
try {
|
|
5416
|
-
const s = loadSettings();
|
|
5417
|
-
enabled = !!s.privacy?.redactIndex;
|
|
5418
|
-
for (const r of s.privacy?.redactionRules ?? []) {
|
|
5419
|
-
try {
|
|
5420
|
-
extra.push({ label: r.label, pattern: new RegExp(r.pattern, "g") });
|
|
5421
|
-
} catch {
|
|
5422
|
-
}
|
|
5423
|
-
}
|
|
5424
|
-
} catch {
|
|
5425
|
-
}
|
|
5426
|
-
cache = { mtimeMs, enabled, rules: [...DEFAULT_REDACTION_RULES, ...extra] };
|
|
5427
|
-
return cache;
|
|
5428
|
-
}
|
|
5429
|
-
function compileServerRule(spec) {
|
|
5430
|
-
const name = spec.name || "(unnamed)";
|
|
5431
|
-
if (!spec.regex)
|
|
5432
|
-
return { name, reason: "empty pattern" };
|
|
5433
|
-
if (spec.regex.length > MAX_PATTERN_LEN)
|
|
5434
|
-
return { name, reason: `pattern longer than ${MAX_PATTERN_LEN} chars` };
|
|
5435
|
-
let re;
|
|
5436
|
-
try {
|
|
5437
|
-
const flags = "g" + (spec.flags || "").replace(/[^ims]/g, "");
|
|
5438
|
-
re = new RegExp(spec.regex, flags);
|
|
5439
|
-
} catch (e) {
|
|
5440
|
-
return { name, reason: `invalid regex: ${e instanceof Error ? e.message : e}` };
|
|
5441
|
-
}
|
|
5442
|
-
if (re.test(""))
|
|
5443
|
-
return { name, reason: "matches the empty string (would redact everything)" };
|
|
5444
|
-
re.lastIndex = 0;
|
|
5445
|
-
if (re.test(CANARY))
|
|
5446
|
-
return { name, reason: "matches benign text \u2014 too broad" };
|
|
5447
|
-
re.lastIndex = 0;
|
|
5448
|
-
return { label: `${spec.source === "pack" ? "pack" : "tenant"}:${name}`, pattern: re };
|
|
5449
|
-
}
|
|
5450
|
-
function installServerRulePack(pack) {
|
|
5451
|
-
const rejected = [];
|
|
5452
|
-
const rules = [];
|
|
5453
|
-
for (const spec of pack.rules || []) {
|
|
5454
|
-
if (rules.length >= MAX_PACK_RULES) {
|
|
5455
|
-
rejected.push({ name: spec.name || "(unnamed)", reason: `pack exceeds ${MAX_PACK_RULES} rules` });
|
|
5456
|
-
continue;
|
|
5457
|
-
}
|
|
5458
|
-
const out = compileServerRule(spec);
|
|
5459
|
-
if ("reason" in out)
|
|
5460
|
-
rejected.push(out);
|
|
5461
|
-
else
|
|
5462
|
-
rules.push(out);
|
|
5463
|
-
}
|
|
5464
|
-
const version = pack.version || "";
|
|
5465
|
-
serverPack = { version, rules };
|
|
5466
|
-
return { version, accepted: rules.length, rejected };
|
|
5467
|
-
}
|
|
5468
|
-
function serverRulePackVersion() {
|
|
5469
|
-
return serverPack ? serverPack.version || "unversioned" : null;
|
|
5470
|
-
}
|
|
5471
|
-
function activeRules() {
|
|
5472
|
-
const base2 = settingsView().rules;
|
|
5473
|
-
return serverPack && serverPack.rules.length > 0 ? [...base2, ...serverPack.rules] : base2;
|
|
5474
|
-
}
|
|
5475
|
-
function isRedactionEnabled() {
|
|
5476
|
-
const env = isEnvRedactionRequested();
|
|
5477
|
-
if (env !== null)
|
|
5478
|
-
return env;
|
|
5479
|
-
return settingsView().enabled;
|
|
5480
|
-
}
|
|
5481
|
-
function redactSecrets(text, opts = {}) {
|
|
5482
|
-
if (!opts.force && !isRedactionEnabled())
|
|
5483
|
-
return text;
|
|
5484
|
-
if (!text)
|
|
5485
|
-
return text;
|
|
5486
|
-
const rules = opts.rules || activeRules();
|
|
5487
|
-
let out = text;
|
|
5488
|
-
for (const r of rules) {
|
|
5489
|
-
out = out.replace(r.pattern, (...args) => {
|
|
5490
|
-
const whole = args[0];
|
|
5491
|
-
const m = args.slice(0, args.length);
|
|
5492
|
-
const secret = secretOf(r, m);
|
|
5493
|
-
if (secret == null)
|
|
5494
|
-
return whole;
|
|
5495
|
-
if (opts.count)
|
|
5496
|
-
opts.count.redactions++;
|
|
5497
|
-
return whole.slice(0, whole.length - secret.length) + `[REDACTED:${r.label}]`;
|
|
5498
|
-
});
|
|
5499
|
-
}
|
|
5500
|
-
const ctx = findContextualSecrets(out);
|
|
5501
|
-
for (let i = ctx.length - 1; i >= 0; i--) {
|
|
5502
|
-
const { start, end } = ctx[i];
|
|
5503
|
-
if (opts.count)
|
|
5504
|
-
opts.count.redactions++;
|
|
5505
|
-
out = out.slice(0, start) + "[REDACTED:secret-context]" + out.slice(end);
|
|
5506
|
-
}
|
|
5507
|
-
return out;
|
|
5508
|
-
}
|
|
5509
|
-
function maskSecret(s) {
|
|
5510
|
-
if (!s)
|
|
5511
|
-
return "";
|
|
5512
|
-
if (s.length <= 4)
|
|
5513
|
-
return "*".repeat(s.length);
|
|
5514
|
-
return "*".repeat(Math.min(s.length - 4, 60)) + s.slice(-4);
|
|
5515
|
-
}
|
|
5516
|
-
function globalRegexFor(pattern) {
|
|
5517
|
-
const flags = pattern.flags.includes("g") ? pattern.flags : pattern.flags + "g";
|
|
5518
|
-
const key2 = pattern.source + "\0" + flags;
|
|
5519
|
-
let re = globalRegexCache.get(key2);
|
|
5520
|
-
if (!re) {
|
|
5521
|
-
re = new RegExp(pattern.source, flags);
|
|
5522
|
-
globalRegexCache.set(key2, re);
|
|
5523
|
-
}
|
|
5524
|
-
return re;
|
|
5525
|
-
}
|
|
5526
|
-
function makeLineResolver(text) {
|
|
5527
|
-
const starts = [];
|
|
5528
|
-
for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1))
|
|
5529
|
-
starts.push(i);
|
|
5530
|
-
return (index) => {
|
|
5531
|
-
let lo = 0, hi = starts.length;
|
|
5532
|
-
while (lo < hi) {
|
|
5533
|
-
const mid = lo + hi >> 1;
|
|
5534
|
-
if (starts[mid] < index)
|
|
5535
|
-
lo = mid + 1;
|
|
5536
|
-
else
|
|
5537
|
-
hi = mid;
|
|
5538
|
-
}
|
|
5539
|
-
return lo + 1;
|
|
5540
|
-
};
|
|
5541
|
-
}
|
|
5542
|
-
function scanTextForFindings(text, opts = {}) {
|
|
5543
|
-
if (!text)
|
|
5544
|
-
return [];
|
|
5545
|
-
const rules = opts.rules || activeRules();
|
|
5546
|
-
const findings = [];
|
|
5547
|
-
const seenSpans = /* @__PURE__ */ new Set();
|
|
5548
|
-
const lineAt = makeLineResolver(text);
|
|
5549
|
-
for (const r of rules) {
|
|
5550
|
-
const re = globalRegexFor(r.pattern);
|
|
5551
|
-
re.lastIndex = 0;
|
|
5552
|
-
let m;
|
|
5553
|
-
while ((m = re.exec(text)) !== null) {
|
|
5554
|
-
const secret = secretOf(r, m);
|
|
5555
|
-
if (secret == null) {
|
|
5556
|
-
if (re.lastIndex === m.index)
|
|
5557
|
-
re.lastIndex++;
|
|
5558
|
-
continue;
|
|
5559
|
-
}
|
|
5560
|
-
const at = m.index + (m[0].length - secret.length);
|
|
5561
|
-
const span = `${at}:${secret.length}`;
|
|
5562
|
-
if (!seenSpans.has(span)) {
|
|
5563
|
-
seenSpans.add(span);
|
|
5564
|
-
findings.push({ rule: r.label, line: lineAt(at), preview: maskSecret(secret) });
|
|
5565
|
-
}
|
|
5566
|
-
if (re.lastIndex === m.index)
|
|
5567
|
-
re.lastIndex++;
|
|
5568
|
-
}
|
|
5569
|
-
}
|
|
5570
|
-
for (const { start, end } of findContextualSecrets(text)) {
|
|
5571
|
-
const line = lineAt(start);
|
|
5572
|
-
findings.push({ rule: "secret-context", line, preview: maskSecret(text.slice(start, end)) });
|
|
5573
|
-
}
|
|
5574
|
-
return findings;
|
|
5575
|
-
}
|
|
5576
|
-
function privacyView() {
|
|
5577
|
-
let mtimeMs = -1;
|
|
5578
|
-
try {
|
|
5579
|
-
mtimeMs = statSync3(settingsFilePath()).mtimeMs;
|
|
5580
|
-
} catch {
|
|
5581
|
-
}
|
|
5582
|
-
if (privacyCache && privacyCache.mtimeMs === mtimeMs)
|
|
5583
|
-
return privacyCache;
|
|
5584
|
-
let redactToolOutputs = false, redactFilePaths = false;
|
|
5585
|
-
try {
|
|
5586
|
-
const s = loadSettings();
|
|
5587
|
-
redactToolOutputs = !!s.privacy?.redactToolOutputs;
|
|
5588
|
-
redactFilePaths = !!s.privacy?.redactFilePaths;
|
|
5589
|
-
} catch {
|
|
5590
|
-
}
|
|
5591
|
-
privacyCache = { mtimeMs, redactToolOutputs, redactFilePaths };
|
|
5592
|
-
return privacyCache;
|
|
5593
|
-
}
|
|
5594
|
-
function isToolOutputRedactionEnabled() {
|
|
5595
|
-
return privacyView().redactToolOutputs;
|
|
5596
|
-
}
|
|
5597
|
-
function redactToolResultBody(toolName, body) {
|
|
5598
|
-
if (!body)
|
|
5599
|
-
return body;
|
|
5600
|
-
return `[redacted: ${toolName} output, ${body.length} chars]`;
|
|
5601
|
-
}
|
|
5602
|
-
var DEFAULT_REDACTION_RULES, SECRET_CONTEXT_RE, HIGH_ENTROPY_TOKEN_RE, cache, CANARY, MAX_PACK_RULES, MAX_PATTERN_LEN, serverPack, globalRegexCache, privacyCache;
|
|
5603
|
-
var init_secret_redactor = __esm({
|
|
5604
|
-
"../engine/dist/core/secret-redactor.js"() {
|
|
5287
|
+
var DEFAULT_REDACTION_RULES, SECRET_CONTEXT_RE, HIGH_ENTROPY_TOKEN_RE, cache, CANARY, MAX_PACK_RULES, MAX_PATTERN_LEN, serverPack, globalRegexCache, privacyCache;
|
|
5288
|
+
var init_secret_redactor = __esm({
|
|
5289
|
+
"../engine/dist/core/secret-redactor.js"() {
|
|
5605
5290
|
"use strict";
|
|
5606
5291
|
init_settings();
|
|
5607
5292
|
DEFAULT_REDACTION_RULES = [
|
|
@@ -5897,18 +5582,333 @@ function chunkSession(entry, content, maxChunks = 80, maxTokensPerChunk = 500) {
|
|
|
5897
5582
|
}
|
|
5898
5583
|
}
|
|
5899
5584
|
}
|
|
5900
|
-
return chunks.slice(0, maxChunks);
|
|
5585
|
+
return chunks.slice(0, maxChunks);
|
|
5586
|
+
}
|
|
5587
|
+
var INJECTED_BANNERS;
|
|
5588
|
+
var init_chunker = __esm({
|
|
5589
|
+
"../engine/dist/parsers/chunker.js"() {
|
|
5590
|
+
"use strict";
|
|
5591
|
+
init_secret_redactor();
|
|
5592
|
+
INJECTED_BANNERS = [
|
|
5593
|
+
/MCP issues detected\. ?Run \/mcp list for status\.?/g,
|
|
5594
|
+
/Context low[^\n]*Run \/compact[^\n]*/g,
|
|
5595
|
+
/API Error:[^\n]{0,120}/g
|
|
5596
|
+
];
|
|
5597
|
+
}
|
|
5598
|
+
});
|
|
5599
|
+
|
|
5600
|
+
// ../engine/dist/core/home-approval.js
|
|
5601
|
+
import { existsSync as existsSync3, readdirSync as readdirSync2, realpathSync } from "fs";
|
|
5602
|
+
import { homedir as homedir2 } from "os";
|
|
5603
|
+
import { join as join3, dirname as dirname3 } from "path";
|
|
5604
|
+
function normalizeHomePath(p) {
|
|
5605
|
+
const expanded = p.startsWith("~") ? join3(homedir2(), p.slice(1)) : p;
|
|
5606
|
+
const trimmed = expanded.replace(/[/\\]+$/, "");
|
|
5607
|
+
try {
|
|
5608
|
+
return realpathSync(trimmed);
|
|
5609
|
+
} catch {
|
|
5610
|
+
return trimmed;
|
|
5611
|
+
}
|
|
5612
|
+
}
|
|
5613
|
+
function legacyAutoSyncedHomes() {
|
|
5614
|
+
const home = homedir2();
|
|
5615
|
+
const out = [];
|
|
5616
|
+
const add = (dir, marker) => {
|
|
5617
|
+
if (!existsSync3(join3(dir, marker)))
|
|
5618
|
+
return;
|
|
5619
|
+
const n = normalizeHomePath(dir);
|
|
5620
|
+
if (!out.includes(n))
|
|
5621
|
+
out.push(n);
|
|
5622
|
+
};
|
|
5623
|
+
const bases = [
|
|
5624
|
+
{ base: join3(home, ".claude"), marker: "projects" },
|
|
5625
|
+
{ base: join3(home, ".gemini"), marker: "tmp" },
|
|
5626
|
+
{ base: join3(home, ".codex"), marker: "sessions" },
|
|
5627
|
+
{ base: join3(home, ".gemini", "antigravity-cli"), marker: "brain" },
|
|
5628
|
+
{ base: join3(home, ".local", "share", "opencode"), marker: "opencode.db" },
|
|
5629
|
+
{ base: join3(home, ".cursor"), marker: "chats" }
|
|
5630
|
+
];
|
|
5631
|
+
for (const { base: base2, marker } of bases) {
|
|
5632
|
+
add(base2, marker);
|
|
5633
|
+
const parent = dirname3(base2);
|
|
5634
|
+
const leaf = base2.slice(parent.length + 1);
|
|
5635
|
+
try {
|
|
5636
|
+
for (const e of readdirSync2(parent, { withFileTypes: true })) {
|
|
5637
|
+
if (!e.isDirectory())
|
|
5638
|
+
continue;
|
|
5639
|
+
if (e.name === leaf || !e.name.startsWith(leaf + "-"))
|
|
5640
|
+
continue;
|
|
5641
|
+
if (e.name === ".claude-code")
|
|
5642
|
+
continue;
|
|
5643
|
+
add(join3(parent, e.name), marker);
|
|
5644
|
+
}
|
|
5645
|
+
} catch {
|
|
5646
|
+
}
|
|
5647
|
+
}
|
|
5648
|
+
return out;
|
|
5649
|
+
}
|
|
5650
|
+
function grandfatherLegacyHomes() {
|
|
5651
|
+
let s;
|
|
5652
|
+
try {
|
|
5653
|
+
s = loadSettings();
|
|
5654
|
+
} catch {
|
|
5655
|
+
return { seeded: [] };
|
|
5656
|
+
}
|
|
5657
|
+
if (s.sources.homesGrandfathered)
|
|
5658
|
+
return { seeded: [] };
|
|
5659
|
+
const legacy = legacyAutoSyncedHomes();
|
|
5660
|
+
const approved = new Set((s.sources.approvedHomes ?? []).map(normalizeHomePath));
|
|
5661
|
+
const seeded = [];
|
|
5662
|
+
for (const p of legacy) {
|
|
5663
|
+
if (!approved.has(p)) {
|
|
5664
|
+
approved.add(p);
|
|
5665
|
+
seeded.push(p);
|
|
5666
|
+
}
|
|
5667
|
+
}
|
|
5668
|
+
s.sources.approvedHomes = [...approved];
|
|
5669
|
+
s.sources.homesGrandfathered = true;
|
|
5670
|
+
try {
|
|
5671
|
+
saveSettings(s);
|
|
5672
|
+
} catch {
|
|
5673
|
+
return { seeded: [] };
|
|
5674
|
+
}
|
|
5675
|
+
return { seeded };
|
|
5676
|
+
}
|
|
5677
|
+
function primaryHomes() {
|
|
5678
|
+
const home = homedir2();
|
|
5679
|
+
const env = process.env;
|
|
5680
|
+
let s;
|
|
5681
|
+
try {
|
|
5682
|
+
s = loadSettings().sources;
|
|
5683
|
+
} catch {
|
|
5684
|
+
s = void 0;
|
|
5685
|
+
}
|
|
5686
|
+
const opencodeDb = env.CHAT_RECALL_OPENCODE_DB || s?.opencodeDbPath || join3(home, ".local", "share", "opencode", "opencode.db");
|
|
5687
|
+
const candidates2 = [
|
|
5688
|
+
env.CHAT_RECALL_CLAUDE_HOME || s?.claudeHome || join3(home, ".claude"),
|
|
5689
|
+
env.CHAT_RECALL_GEMINI_HOME || s?.geminiHome || join3(home, ".gemini"),
|
|
5690
|
+
env.CHAT_RECALL_CODEX_HOME || s?.codexHome || join3(home, ".codex"),
|
|
5691
|
+
env.CHAT_RECALL_AGY_HOME || s?.agyHome || join3(home, ".gemini", "antigravity-cli"),
|
|
5692
|
+
env.CHAT_RECALL_CURSOR_HOME || s?.cursorHome || join3(home, ".cursor"),
|
|
5693
|
+
dirOf(opencodeDb)
|
|
5694
|
+
];
|
|
5695
|
+
return candidates2.map(normalizeHomePath);
|
|
5696
|
+
}
|
|
5697
|
+
function homeDecision(path) {
|
|
5698
|
+
const p = normalizeHomePath(path);
|
|
5699
|
+
if (primaryHomes().includes(p))
|
|
5700
|
+
return "primary";
|
|
5701
|
+
let s;
|
|
5702
|
+
try {
|
|
5703
|
+
s = loadSettings().sources;
|
|
5704
|
+
} catch {
|
|
5705
|
+
return "pending";
|
|
5706
|
+
}
|
|
5707
|
+
if ((s.declinedHomes ?? []).map(normalizeHomePath).includes(p))
|
|
5708
|
+
return "declined";
|
|
5709
|
+
if ((s.approvedHomes ?? []).map(normalizeHomePath).includes(p))
|
|
5710
|
+
return "approved";
|
|
5711
|
+
if ((s.extraClaudeHomes ?? []).map(normalizeHomePath).includes(p))
|
|
5712
|
+
return "approved";
|
|
5713
|
+
return "pending";
|
|
5714
|
+
}
|
|
5715
|
+
function isHomeSynced(path) {
|
|
5716
|
+
const d = homeDecision(path);
|
|
5717
|
+
return d === "primary" || d === "approved";
|
|
5718
|
+
}
|
|
5719
|
+
function setDecision(path, decision) {
|
|
5720
|
+
const p = normalizeHomePath(path);
|
|
5721
|
+
let s;
|
|
5722
|
+
try {
|
|
5723
|
+
s = loadSettings();
|
|
5724
|
+
} catch {
|
|
5725
|
+
return false;
|
|
5726
|
+
}
|
|
5727
|
+
const approved = new Set((s.sources.approvedHomes ?? []).map(normalizeHomePath));
|
|
5728
|
+
const declined = new Set((s.sources.declinedHomes ?? []).map(normalizeHomePath));
|
|
5729
|
+
approved.delete(p);
|
|
5730
|
+
declined.delete(p);
|
|
5731
|
+
(decision === "approved" ? approved : declined).add(p);
|
|
5732
|
+
s.sources.approvedHomes = [...approved];
|
|
5733
|
+
s.sources.declinedHomes = [...declined];
|
|
5734
|
+
try {
|
|
5735
|
+
saveSettings(s);
|
|
5736
|
+
} catch {
|
|
5737
|
+
return false;
|
|
5738
|
+
}
|
|
5739
|
+
return true;
|
|
5740
|
+
}
|
|
5741
|
+
function approveHome(path) {
|
|
5742
|
+
return setDecision(path, "approved");
|
|
5743
|
+
}
|
|
5744
|
+
function declineHome(path) {
|
|
5745
|
+
return setDecision(path, "declined");
|
|
5746
|
+
}
|
|
5747
|
+
var dirOf;
|
|
5748
|
+
var init_home_approval = __esm({
|
|
5749
|
+
"../engine/dist/core/home-approval.js"() {
|
|
5750
|
+
"use strict";
|
|
5751
|
+
init_settings();
|
|
5752
|
+
dirOf = (filePath) => dirname3(filePath);
|
|
5753
|
+
}
|
|
5754
|
+
});
|
|
5755
|
+
|
|
5756
|
+
// ../engine/dist/core/tool-paths.js
|
|
5757
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3 } from "fs";
|
|
5758
|
+
import { homedir as homedir3 } from "os";
|
|
5759
|
+
import { join as join4, dirname as dirname4, basename } from "path";
|
|
5760
|
+
function claudeHomeDir() {
|
|
5761
|
+
return process.env.CHAT_RECALL_CLAUDE_HOME || sources().claudeHome || join4(homedir3(), ".claude");
|
|
5762
|
+
}
|
|
5763
|
+
function claudeProjectDirs(opts = {}) {
|
|
5764
|
+
const home = homedir3();
|
|
5765
|
+
const dirs = [];
|
|
5766
|
+
const addHome = (d) => {
|
|
5767
|
+
const p = join4(d, "projects");
|
|
5768
|
+
if (existsSync4(p) && !dirs.includes(p))
|
|
5769
|
+
dirs.push(p);
|
|
5770
|
+
};
|
|
5771
|
+
addHome(claudeHomeDir());
|
|
5772
|
+
const homeOverridden = !!(process.env.CHAT_RECALL_CLAUDE_HOME || sources().claudeHome);
|
|
5773
|
+
if (!homeOverridden) {
|
|
5774
|
+
try {
|
|
5775
|
+
for (const entry of readdirSync3(home, { withFileTypes: true })) {
|
|
5776
|
+
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
5777
|
+
addHome(join4(home, entry.name));
|
|
5778
|
+
}
|
|
5779
|
+
}
|
|
5780
|
+
} catch {
|
|
5781
|
+
}
|
|
5782
|
+
}
|
|
5783
|
+
if (process.env.CLAUDE_DIRS) {
|
|
5784
|
+
for (const d of process.env.CLAUDE_DIRS.split(",")) {
|
|
5785
|
+
const t = d.trim();
|
|
5786
|
+
if (t)
|
|
5787
|
+
addHome(t.startsWith("~/") ? join4(home, t.slice(2)) : t);
|
|
5788
|
+
}
|
|
5789
|
+
}
|
|
5790
|
+
if (dirs.length === 0)
|
|
5791
|
+
dirs.push(join4(claudeHomeDir(), "projects"));
|
|
5792
|
+
return applyDecisions(dirs, opts.includeExcluded);
|
|
5793
|
+
}
|
|
5794
|
+
function _setSourceExclusionFilter(fn) {
|
|
5795
|
+
_sourceExclusionFilter = fn;
|
|
5796
|
+
}
|
|
5797
|
+
function geminiHomeDir() {
|
|
5798
|
+
return process.env.CHAT_RECALL_GEMINI_HOME || sources().geminiHome || join4(homedir3(), ".gemini");
|
|
5799
|
+
}
|
|
5800
|
+
function opencodeDbPath() {
|
|
5801
|
+
return process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath || join4(homedir3(), ".local", "share", "opencode", "opencode.db");
|
|
5802
|
+
}
|
|
5803
|
+
function codexHomeDir() {
|
|
5804
|
+
return process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome || join4(homedir3(), ".codex");
|
|
5805
|
+
}
|
|
5806
|
+
function agyHomeDir() {
|
|
5807
|
+
return process.env.CHAT_RECALL_AGY_HOME || sources().agyHome || join4(homedir3(), ".gemini", "antigravity-cli");
|
|
5808
|
+
}
|
|
5809
|
+
function cursorHomeDir() {
|
|
5810
|
+
return process.env.CHAT_RECALL_CURSOR_HOME || sources().cursorHome || join4(homedir3(), ".cursor");
|
|
5811
|
+
}
|
|
5812
|
+
function cursorIdeHomeDir() {
|
|
5813
|
+
return process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome || (process.platform === "darwin" ? join4(homedir3(), "Library", "Application Support", "Cursor") : join4(homedir3(), ".config", "Cursor"));
|
|
5814
|
+
}
|
|
5815
|
+
function siblingHomes(base2, overridden, suffix) {
|
|
5816
|
+
const roots = [];
|
|
5817
|
+
const add = (home) => {
|
|
5818
|
+
const root = suffix ? join4(home, suffix) : home;
|
|
5819
|
+
if (existsSync4(root) && !roots.includes(root))
|
|
5820
|
+
roots.push(root);
|
|
5821
|
+
};
|
|
5822
|
+
add(base2);
|
|
5823
|
+
if (!overridden) {
|
|
5824
|
+
const parent = dirname4(base2);
|
|
5825
|
+
const leaf = basename(base2);
|
|
5826
|
+
try {
|
|
5827
|
+
for (const entry of readdirSync3(parent, { withFileTypes: true })) {
|
|
5828
|
+
if (!entry.isDirectory())
|
|
5829
|
+
continue;
|
|
5830
|
+
if (entry.name === leaf || !entry.name.startsWith(leaf + "-"))
|
|
5831
|
+
continue;
|
|
5832
|
+
add(join4(parent, entry.name));
|
|
5833
|
+
}
|
|
5834
|
+
} catch {
|
|
5835
|
+
}
|
|
5836
|
+
}
|
|
5837
|
+
return roots;
|
|
5838
|
+
}
|
|
5839
|
+
function applyDecisions(roots, includeExcluded) {
|
|
5840
|
+
if (roots.length === 0)
|
|
5841
|
+
return roots;
|
|
5842
|
+
let kept = roots;
|
|
5843
|
+
if (!includeExcluded) {
|
|
5844
|
+
try {
|
|
5845
|
+
grandfatherLegacyHomes();
|
|
5846
|
+
const approved = kept.filter((r) => isHomeSynced(dirname4(r)));
|
|
5847
|
+
if (approved.length > 0)
|
|
5848
|
+
kept = approved;
|
|
5849
|
+
} catch {
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
if (!includeExcluded && _sourceExclusionFilter) {
|
|
5853
|
+
const notExcluded = kept.filter((r) => !_sourceExclusionFilter(r));
|
|
5854
|
+
if (notExcluded.length > 0)
|
|
5855
|
+
kept = notExcluded;
|
|
5856
|
+
}
|
|
5857
|
+
return kept;
|
|
5901
5858
|
}
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5859
|
+
function applyExclusions(roots, includeExcluded) {
|
|
5860
|
+
return applyDecisions(roots, includeExcluded);
|
|
5861
|
+
}
|
|
5862
|
+
function codexSessionDirs(opts = {}) {
|
|
5863
|
+
const overridden = !!(process.env.CHAT_RECALL_CODEX_HOME || sources().codexHome);
|
|
5864
|
+
return applyExclusions(siblingHomes(codexHomeDir(), overridden, "sessions"), opts.includeExcluded);
|
|
5865
|
+
}
|
|
5866
|
+
function agyBrainDirs(opts = {}) {
|
|
5867
|
+
const overridden = !!(process.env.CHAT_RECALL_AGY_HOME || sources().agyHome);
|
|
5868
|
+
return applyExclusions(siblingHomes(agyHomeDir(), overridden, "brain"), opts.includeExcluded);
|
|
5869
|
+
}
|
|
5870
|
+
function cursorChatDirs(opts = {}) {
|
|
5871
|
+
const overridden = !!(process.env.CHAT_RECALL_CURSOR_HOME || sources().cursorHome);
|
|
5872
|
+
return applyExclusions(siblingHomes(cursorHomeDir(), overridden, "chats"), opts.includeExcluded);
|
|
5873
|
+
}
|
|
5874
|
+
function cursorIdeWorkspaceDirs(opts = {}) {
|
|
5875
|
+
const overridden = !!(process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome);
|
|
5876
|
+
return applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join4("User", "workspaceStorage")), opts.includeExcluded);
|
|
5877
|
+
}
|
|
5878
|
+
function cursorIdeGlobalDbs(opts = {}) {
|
|
5879
|
+
const overridden = !!(process.env.CHAT_RECALL_CURSOR_IDE_HOME || sources().cursorIdeHome);
|
|
5880
|
+
const roots = applyExclusions(siblingHomes(cursorIdeHomeDir(), overridden, join4("User", "globalStorage")), opts.includeExcluded);
|
|
5881
|
+
const dbs = [];
|
|
5882
|
+
for (const r of roots) {
|
|
5883
|
+
const p = join4(r, "state.vscdb");
|
|
5884
|
+
if (existsSync4(p) && !dbs.includes(p))
|
|
5885
|
+
dbs.push(p);
|
|
5886
|
+
}
|
|
5887
|
+
return dbs;
|
|
5888
|
+
}
|
|
5889
|
+
function opencodeDbPaths(opts = {}) {
|
|
5890
|
+
const primary = opencodeDbPath();
|
|
5891
|
+
const overridden = !!(process.env.CHAT_RECALL_OPENCODE_DB || sources().opencodeDbPath);
|
|
5892
|
+
const dbFile = basename(primary);
|
|
5893
|
+
const dirs = siblingHomes(dirname4(primary), overridden, "");
|
|
5894
|
+
const dbs = [];
|
|
5895
|
+
for (const d of dirs) {
|
|
5896
|
+
const p = join4(d, dbFile);
|
|
5897
|
+
if (existsSync4(p) && !dbs.includes(p))
|
|
5898
|
+
dbs.push(p);
|
|
5899
|
+
}
|
|
5900
|
+
if (dbs.length === 0)
|
|
5901
|
+
dbs.push(primary);
|
|
5902
|
+
return applyExclusions(dbs, opts.includeExcluded);
|
|
5903
|
+
}
|
|
5904
|
+
var sources, _sourceExclusionFilter;
|
|
5905
|
+
var init_tool_paths = __esm({
|
|
5906
|
+
"../engine/dist/core/tool-paths.js"() {
|
|
5905
5907
|
"use strict";
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
/API Error:[^\n]{0,120}/g
|
|
5911
|
-
];
|
|
5908
|
+
init_home_approval();
|
|
5909
|
+
init_settings();
|
|
5910
|
+
sources = loadSourceSettings;
|
|
5911
|
+
_sourceExclusionFilter = null;
|
|
5912
5912
|
}
|
|
5913
5913
|
});
|
|
5914
5914
|
|
|
@@ -7622,13 +7622,26 @@ function resolveSessionContentGroups(sessionId) {
|
|
|
7622
7622
|
}
|
|
7623
7623
|
function withSessionReadCache(fn) {
|
|
7624
7624
|
readScopeDepth++;
|
|
7625
|
+
if (readScopeDepth === 1)
|
|
7626
|
+
derivedScope = /* @__PURE__ */ new Map();
|
|
7625
7627
|
try {
|
|
7626
7628
|
return fn();
|
|
7627
7629
|
} finally {
|
|
7628
|
-
if (--readScopeDepth === 0)
|
|
7630
|
+
if (--readScopeDepth === 0) {
|
|
7629
7631
|
readScope = null;
|
|
7632
|
+
derivedScope = null;
|
|
7633
|
+
}
|
|
7630
7634
|
}
|
|
7631
7635
|
}
|
|
7636
|
+
function memoInSessionScope(key2, compute) {
|
|
7637
|
+
if (!derivedScope)
|
|
7638
|
+
return compute();
|
|
7639
|
+
if (derivedScope.has(key2))
|
|
7640
|
+
return derivedScope.get(key2);
|
|
7641
|
+
const value = compute();
|
|
7642
|
+
derivedScope.set(key2, value);
|
|
7643
|
+
return value;
|
|
7644
|
+
}
|
|
7632
7645
|
function readSessionGroupText(group) {
|
|
7633
7646
|
let key2 = "";
|
|
7634
7647
|
if (readScopeDepth > 0) {
|
|
@@ -7740,7 +7753,7 @@ function findCodexSessionFileIn(root, sessionId) {
|
|
|
7740
7753
|
}
|
|
7741
7754
|
return scanDir(root);
|
|
7742
7755
|
}
|
|
7743
|
-
var scanScopeDepth, indexCache, readScope, readScopeDepth, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
7756
|
+
var scanScopeDepth, indexCache, readScope, readScopeDepth, derivedScope, geminiCache, MAX_EVENT_LINE_BYTES;
|
|
7744
7757
|
var init_live_session_scan = __esm({
|
|
7745
7758
|
"../engine/dist/core/live-session-scan.js"() {
|
|
7746
7759
|
"use strict";
|
|
@@ -7754,6 +7767,7 @@ var init_live_session_scan = __esm({
|
|
|
7754
7767
|
indexCache = null;
|
|
7755
7768
|
readScope = null;
|
|
7756
7769
|
readScopeDepth = 0;
|
|
7770
|
+
derivedScope = null;
|
|
7757
7771
|
geminiCache = null;
|
|
7758
7772
|
MAX_EVENT_LINE_BYTES = 8 * 1024 * 1024;
|
|
7759
7773
|
}
|
|
@@ -8031,6 +8045,28 @@ var init_session_git = __esm({
|
|
|
8031
8045
|
}
|
|
8032
8046
|
});
|
|
8033
8047
|
|
|
8048
|
+
// ../engine/dist/core/session-multi-tool.js
|
|
8049
|
+
function extractTurnsAny(sessionId, opts = {}) {
|
|
8050
|
+
const backend = getBackendForId(sessionId);
|
|
8051
|
+
if (!backend)
|
|
8052
|
+
return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
|
|
8053
|
+
return memoInSessionScope(`turns:${sessionId}:${opts.maxTurns ?? ""}:${opts.assistantMax ?? ""}`, () => backend.extractTurns(sessionId, opts));
|
|
8054
|
+
}
|
|
8055
|
+
function replaySessionAny(sessionId) {
|
|
8056
|
+
const backend = getBackendForId(sessionId);
|
|
8057
|
+
if (!backend)
|
|
8058
|
+
return { sessionId, found: false, projectPath: "", files: [], totalLinesAdded: 0, totalLinesRemoved: 0 };
|
|
8059
|
+
return memoInSessionScope(`replay:${sessionId}`, () => backend.replay(sessionId));
|
|
8060
|
+
}
|
|
8061
|
+
var init_session_multi_tool = __esm({
|
|
8062
|
+
"../engine/dist/core/session-multi-tool.js"() {
|
|
8063
|
+
"use strict";
|
|
8064
|
+
init_tool_backend();
|
|
8065
|
+
init_live_session_scan();
|
|
8066
|
+
init_backends();
|
|
8067
|
+
}
|
|
8068
|
+
});
|
|
8069
|
+
|
|
8034
8070
|
// ../engine/dist/core/session-outcome.js
|
|
8035
8071
|
function extractDecisionsFromTurn(turn) {
|
|
8036
8072
|
if (turn.kind !== "assistant_text" || !turn.text)
|
|
@@ -8127,7 +8163,7 @@ function computeOutcome(sessionId, opts = {}) {
|
|
|
8127
8163
|
};
|
|
8128
8164
|
if (!backend)
|
|
8129
8165
|
return notFound;
|
|
8130
|
-
const turnsRes =
|
|
8166
|
+
const turnsRes = extractTurnsAny(sessionId, { assistantMax: 2e3 });
|
|
8131
8167
|
if (!turnsRes.found)
|
|
8132
8168
|
return notFound;
|
|
8133
8169
|
const decisions = [];
|
|
@@ -8166,7 +8202,7 @@ function computeOutcome(sessionId, opts = {}) {
|
|
|
8166
8202
|
totalLinesAdded = fast.totalLinesAdded;
|
|
8167
8203
|
totalLinesRemoved = fast.totalLinesRemoved;
|
|
8168
8204
|
} else {
|
|
8169
|
-
const replay =
|
|
8205
|
+
const replay = replaySessionAny(sessionId);
|
|
8170
8206
|
filesChanged = replay.files.map((f) => f.file);
|
|
8171
8207
|
totalLinesAdded = replay.totalLinesAdded;
|
|
8172
8208
|
totalLinesRemoved = replay.totalLinesRemoved;
|
|
@@ -8205,6 +8241,7 @@ var init_session_outcome = __esm({
|
|
|
8205
8241
|
init_session_sentiment();
|
|
8206
8242
|
init_session_git();
|
|
8207
8243
|
init_tool_backend();
|
|
8244
|
+
init_session_multi_tool();
|
|
8208
8245
|
init_backends();
|
|
8209
8246
|
DECISION_PATTERNS = [
|
|
8210
8247
|
/\b(?:I'?ll|I will|I'?m going to|Going to|Let me|We'?ll|We will|We should|Let'?s|I'?m about to|I'?m going to)\b[^\n.!?]*[.!?]/i,
|
|
@@ -8674,6 +8711,7 @@ var UUID_RE, ClaudeBackend, claudeBackend;
|
|
|
8674
8711
|
var init_claude2 = __esm({
|
|
8675
8712
|
"../engine/dist/core/backends/claude.js"() {
|
|
8676
8713
|
"use strict";
|
|
8714
|
+
init_live_session_scan();
|
|
8677
8715
|
init_tool_paths();
|
|
8678
8716
|
init_live_session_scan();
|
|
8679
8717
|
init_session_outcome();
|
|
@@ -8936,6 +8974,9 @@ var init_claude2 = __esm({
|
|
|
8936
8974
|
* splits show up alongside the parent.
|
|
8937
8975
|
*/
|
|
8938
8976
|
readEvents(rawId) {
|
|
8977
|
+
return memoInSessionScope(`events:claude:${rawId}`, () => this.#readEventsUncached(rawId));
|
|
8978
|
+
}
|
|
8979
|
+
#readEventsUncached(rawId) {
|
|
8939
8980
|
const groups = resolveSessionContentGroups(rawId);
|
|
8940
8981
|
if (groups.length === 0)
|
|
8941
8982
|
return [];
|
|
@@ -12287,6 +12328,76 @@ var init_backends = __esm({
|
|
|
12287
12328
|
}
|
|
12288
12329
|
});
|
|
12289
12330
|
|
|
12331
|
+
// ../engine/dist/core/collector-health.js
|
|
12332
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "node:fs";
|
|
12333
|
+
import { join as join17, dirname as dirname13 } from "node:path";
|
|
12334
|
+
function applySyncOutcome(prior, outcome, now = Date.now()) {
|
|
12335
|
+
const t = { lastOkAt: prior?.lastOkAt ?? null, failures: prior?.failures ?? 0 };
|
|
12336
|
+
if (prior?.lastError !== void 0)
|
|
12337
|
+
t.lastError = prior.lastError;
|
|
12338
|
+
if (outcome.ok) {
|
|
12339
|
+
t.lastOkAt = now;
|
|
12340
|
+
t.failures = 0;
|
|
12341
|
+
delete t.lastError;
|
|
12342
|
+
return t;
|
|
12343
|
+
}
|
|
12344
|
+
if ((outcome.accepted ?? 0) > 0)
|
|
12345
|
+
t.lastOkAt = now;
|
|
12346
|
+
t.failures += 1;
|
|
12347
|
+
t.lastError = (outcome.error ?? "unknown error").slice(0, 160);
|
|
12348
|
+
return t;
|
|
12349
|
+
}
|
|
12350
|
+
function collectorHealthPath() {
|
|
12351
|
+
return healthPath();
|
|
12352
|
+
}
|
|
12353
|
+
function readCollectorHealth() {
|
|
12354
|
+
try {
|
|
12355
|
+
const h = JSON.parse(readFileSync11(healthPath(), "utf-8"));
|
|
12356
|
+
return h && h.v === 1 && typeof h.updatedAt === "number" ? h : null;
|
|
12357
|
+
} catch {
|
|
12358
|
+
return null;
|
|
12359
|
+
}
|
|
12360
|
+
}
|
|
12361
|
+
function writeCollectorHealth(h) {
|
|
12362
|
+
try {
|
|
12363
|
+
const p = healthPath();
|
|
12364
|
+
mkdirSync4(dirname13(p), { recursive: true });
|
|
12365
|
+
writeFileSync3(p, JSON.stringify(h));
|
|
12366
|
+
} catch {
|
|
12367
|
+
}
|
|
12368
|
+
}
|
|
12369
|
+
function updateCollectorHealth(patch) {
|
|
12370
|
+
const prior = readCollectorHealth();
|
|
12371
|
+
writeCollectorHealth({
|
|
12372
|
+
...prior,
|
|
12373
|
+
v: 1,
|
|
12374
|
+
updatedAt: Date.now(),
|
|
12375
|
+
startedAt: prior?.startedAt ?? Date.now(),
|
|
12376
|
+
restartsLastHour: prior?.restartsLastHour ?? 0,
|
|
12377
|
+
targets: prior?.targets ?? {},
|
|
12378
|
+
...patch
|
|
12379
|
+
});
|
|
12380
|
+
}
|
|
12381
|
+
function reportWalkProgress(p) {
|
|
12382
|
+
const now = Date.now();
|
|
12383
|
+
const boundary = p.complete || p.done === 0;
|
|
12384
|
+
if (!boundary && now - lastProgressWrite < PROGRESS_WRITE_INTERVAL_MS)
|
|
12385
|
+
return;
|
|
12386
|
+
lastProgressWrite = now;
|
|
12387
|
+
updateCollectorHealth({ progress: p });
|
|
12388
|
+
}
|
|
12389
|
+
var healthPath, PROGRESS_WRITE_INTERVAL_MS, lastProgressWrite, STALE_AFTER_MS;
|
|
12390
|
+
var init_collector_health = __esm({
|
|
12391
|
+
"../engine/dist/core/collector-health.js"() {
|
|
12392
|
+
"use strict";
|
|
12393
|
+
init_paths();
|
|
12394
|
+
healthPath = () => join17(getDataDir(), "collector-health.json");
|
|
12395
|
+
PROGRESS_WRITE_INTERVAL_MS = 2e3;
|
|
12396
|
+
lastProgressWrite = 0;
|
|
12397
|
+
STALE_AFTER_MS = 30 * 6e4;
|
|
12398
|
+
}
|
|
12399
|
+
});
|
|
12400
|
+
|
|
12290
12401
|
// ../engine/dist/core/credentials-env.js
|
|
12291
12402
|
function envCredentials(env = process.env) {
|
|
12292
12403
|
const token = (env.CHAT_RECALL_TOKEN || "").trim();
|
|
@@ -12308,7 +12419,7 @@ var init_credentials_env = __esm({
|
|
|
12308
12419
|
// ../engine/dist/core/source-discovery.js
|
|
12309
12420
|
import { createHash as createHash3 } from "crypto";
|
|
12310
12421
|
import { existsSync as existsSync16, readdirSync as readdirSync12, statSync as statSync14 } from "fs";
|
|
12311
|
-
import { join as
|
|
12422
|
+
import { join as join18 } from "path";
|
|
12312
12423
|
function sourceId(path) {
|
|
12313
12424
|
return "src_" + createHash3("sha256").update(path).digest("hex").slice(0, 12);
|
|
12314
12425
|
}
|
|
@@ -12347,7 +12458,7 @@ function countTranscripts(root, tool) {
|
|
|
12347
12458
|
return;
|
|
12348
12459
|
}
|
|
12349
12460
|
for (const e of entries) {
|
|
12350
|
-
const full =
|
|
12461
|
+
const full = join18(dir, e.name);
|
|
12351
12462
|
if (e.isDirectory()) {
|
|
12352
12463
|
walk(full, depth + 1);
|
|
12353
12464
|
continue;
|
|
@@ -12411,9 +12522,9 @@ var init_source_discovery = __esm({
|
|
|
12411
12522
|
|
|
12412
12523
|
// ../engine/dist/core/home-discovery.js
|
|
12413
12524
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
12414
|
-
import { existsSync as existsSync17, readdirSync as readdirSync13, readFileSync as
|
|
12525
|
+
import { existsSync as existsSync17, readdirSync as readdirSync13, readFileSync as readFileSync12, realpathSync as realpathSync2, statSync as statSync15 } from "fs";
|
|
12415
12526
|
import { homedir as homedir5, platform as osPlatform } from "os";
|
|
12416
|
-
import { join as
|
|
12527
|
+
import { join as join19 } from "path";
|
|
12417
12528
|
function candidateRoots(plat = osPlatform(), env = process.env) {
|
|
12418
12529
|
const home = homedir5();
|
|
12419
12530
|
const roots = [home];
|
|
@@ -12426,23 +12537,23 @@ function candidateRoots(plat = osPlatform(), env = process.env) {
|
|
|
12426
12537
|
add(env.LOCALAPPDATA);
|
|
12427
12538
|
add(env.USERPROFILE);
|
|
12428
12539
|
} else if (plat === "darwin") {
|
|
12429
|
-
add(
|
|
12540
|
+
add(join19(home, "Library", "Application Support"));
|
|
12430
12541
|
add(env.XDG_CONFIG_HOME);
|
|
12431
12542
|
} else {
|
|
12432
|
-
add(env.XDG_CONFIG_HOME ||
|
|
12433
|
-
add(env.XDG_DATA_HOME ||
|
|
12543
|
+
add(env.XDG_CONFIG_HOME || join19(home, ".config"));
|
|
12544
|
+
add(env.XDG_DATA_HOME || join19(home, ".local", "share"));
|
|
12434
12545
|
}
|
|
12435
12546
|
return roots.filter((r) => existsSync17(r));
|
|
12436
12547
|
}
|
|
12437
12548
|
function identifyHome(dir) {
|
|
12438
|
-
const has = (...parts) => existsSync17(
|
|
12439
|
-
if (has("projects") && dirHasTranscript(
|
|
12549
|
+
const has = (...parts) => existsSync17(join19(dir, ...parts));
|
|
12550
|
+
if (has("projects") && dirHasTranscript(join19(dir, "projects"), (f) => f.endsWith(".jsonl"), 2))
|
|
12440
12551
|
return "claude";
|
|
12441
|
-
if (has("sessions") && dirHasTranscript(
|
|
12552
|
+
if (has("sessions") && dirHasTranscript(join19(dir, "sessions"), (f) => f.startsWith("rollout-") && f.endsWith(".jsonl"), 4))
|
|
12442
12553
|
return "codex";
|
|
12443
|
-
if (has("brain") && dirHasTranscript(
|
|
12554
|
+
if (has("brain") && dirHasTranscript(join19(dir, "brain"), (f) => f.endsWith(".jsonl"), 4))
|
|
12444
12555
|
return "agy";
|
|
12445
|
-
if (has("chats") && dirHasTranscript(
|
|
12556
|
+
if (has("chats") && dirHasTranscript(join19(dir, "chats"), (f) => f === "store.db", 3))
|
|
12446
12557
|
return "cursor";
|
|
12447
12558
|
if (has("opencode.db"))
|
|
12448
12559
|
return "opencode";
|
|
@@ -12462,7 +12573,7 @@ function dirHasTranscript(root, match, depth) {
|
|
|
12462
12573
|
continue;
|
|
12463
12574
|
if (e.isFile() && match(e.name))
|
|
12464
12575
|
return true;
|
|
12465
|
-
if (e.isDirectory() && dirHasTranscript(
|
|
12576
|
+
if (e.isDirectory() && dirHasTranscript(join19(root, e.name), match, depth - 1))
|
|
12466
12577
|
return true;
|
|
12467
12578
|
}
|
|
12468
12579
|
return false;
|
|
@@ -12492,12 +12603,12 @@ function countSessions(dir, tool) {
|
|
|
12492
12603
|
if (SKIP.has(e.name))
|
|
12493
12604
|
continue;
|
|
12494
12605
|
if (e.isDirectory())
|
|
12495
|
-
walk(
|
|
12606
|
+
walk(join19(d, e.name), depth - 1);
|
|
12496
12607
|
else if (s.match(e.name))
|
|
12497
12608
|
n++;
|
|
12498
12609
|
}
|
|
12499
12610
|
};
|
|
12500
|
-
walk(
|
|
12611
|
+
walk(join19(dir, s.sub), s.depth);
|
|
12501
12612
|
return n;
|
|
12502
12613
|
}
|
|
12503
12614
|
function declaredHomes(env = process.env, plat = osPlatform()) {
|
|
@@ -12531,11 +12642,11 @@ function declaredHomes(env = process.env, plat = osPlatform()) {
|
|
|
12531
12642
|
return out;
|
|
12532
12643
|
}
|
|
12533
12644
|
const home = homedir5();
|
|
12534
|
-
const rcs = [".bashrc", ".bash_profile", ".zshrc", ".zprofile", ".profile"].map((f) =>
|
|
12645
|
+
const rcs = [".bashrc", ".bash_profile", ".zshrc", ".zprofile", ".profile"].map((f) => join19(home, f)).concat([join19(home, ".config", "fish", "config.fish")]);
|
|
12535
12646
|
for (const rc of rcs) {
|
|
12536
12647
|
let text;
|
|
12537
12648
|
try {
|
|
12538
|
-
text =
|
|
12649
|
+
text = readFileSync12(rc, "utf-8");
|
|
12539
12650
|
} catch {
|
|
12540
12651
|
continue;
|
|
12541
12652
|
}
|
|
@@ -12546,7 +12657,7 @@ function declaredHomes(env = process.env, plat = osPlatform()) {
|
|
|
12546
12657
|
add(d);
|
|
12547
12658
|
}
|
|
12548
12659
|
}
|
|
12549
|
-
return out.map((p) => p.startsWith("~") ?
|
|
12660
|
+
return out.map((p) => p.startsWith("~") ? join19(home, p.slice(1)) : p);
|
|
12550
12661
|
}
|
|
12551
12662
|
function runningToolHomes(plat = osPlatform()) {
|
|
12552
12663
|
const out = [];
|
|
@@ -12560,7 +12671,7 @@ function runningToolHomes(plat = osPlatform()) {
|
|
|
12560
12671
|
for (const pid of pids) {
|
|
12561
12672
|
let env;
|
|
12562
12673
|
try {
|
|
12563
|
-
env =
|
|
12674
|
+
env = readFileSync12(`/proc/${pid}/environ`, "utf-8");
|
|
12564
12675
|
} catch {
|
|
12565
12676
|
continue;
|
|
12566
12677
|
}
|
|
@@ -12640,7 +12751,7 @@ function walkForHomes(dir, depth, visit) {
|
|
|
12640
12751
|
for (const e of entries) {
|
|
12641
12752
|
if (!e.isDirectory() || SKIP.has(e.name))
|
|
12642
12753
|
continue;
|
|
12643
|
-
const child =
|
|
12754
|
+
const child = join19(dir, e.name);
|
|
12644
12755
|
visit(child);
|
|
12645
12756
|
walkForHomes(child, depth - 1, visit);
|
|
12646
12757
|
}
|
|
@@ -12681,20 +12792,20 @@ var init_home_discovery = __esm({
|
|
|
12681
12792
|
|
|
12682
12793
|
// ../engine/dist/core/detector-install.js
|
|
12683
12794
|
import { createHash as createHash4 } from "crypto";
|
|
12684
|
-
import { existsSync as existsSync18, mkdirSync as
|
|
12685
|
-
import { join as
|
|
12795
|
+
import { existsSync as existsSync18, 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";
|
|
12796
|
+
import { join as join20 } from "path";
|
|
12686
12797
|
function managedDetectorPath(name) {
|
|
12687
|
-
return
|
|
12798
|
+
return join20(getDetectorBinDir(), name + exeSuffix());
|
|
12688
12799
|
}
|
|
12689
12800
|
function receiptPath(name) {
|
|
12690
|
-
return
|
|
12801
|
+
return join20(getDetectorBinDir(), `${name}.receipt.json`);
|
|
12691
12802
|
}
|
|
12692
12803
|
function sha256File(path) {
|
|
12693
|
-
return createHash4("sha256").update(
|
|
12804
|
+
return createHash4("sha256").update(readFileSync13(path)).digest("hex");
|
|
12694
12805
|
}
|
|
12695
12806
|
function readReceipt(name) {
|
|
12696
12807
|
try {
|
|
12697
|
-
return JSON.parse(
|
|
12808
|
+
return JSON.parse(readFileSync13(receiptPath(name), "utf-8"));
|
|
12698
12809
|
} catch {
|
|
12699
12810
|
return null;
|
|
12700
12811
|
}
|
|
@@ -12720,7 +12831,7 @@ function configuredDir() {
|
|
|
12720
12831
|
function resolveDetector(name) {
|
|
12721
12832
|
const dir = configuredDir();
|
|
12722
12833
|
if (dir) {
|
|
12723
|
-
const p2 =
|
|
12834
|
+
const p2 = join20(dir, name + exeSuffix());
|
|
12724
12835
|
if (existsSync18(p2))
|
|
12725
12836
|
return { path: p2, version: "operator-supplied", source: "configured" };
|
|
12726
12837
|
return { error: "not-installed" };
|
|
@@ -12785,9 +12896,9 @@ var init_detector_install = __esm({
|
|
|
12785
12896
|
|
|
12786
12897
|
// ../engine/dist/core/secret-scanner.js
|
|
12787
12898
|
import { spawnSync } from "child_process";
|
|
12788
|
-
import { existsSync as existsSync19, unlinkSync, readFileSync as
|
|
12899
|
+
import { existsSync as existsSync19, unlinkSync, readFileSync as readFileSync14, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "fs";
|
|
12789
12900
|
import { tmpdir } from "os";
|
|
12790
|
-
import { join as
|
|
12901
|
+
import { join as join21 } from "path";
|
|
12791
12902
|
function mask(s) {
|
|
12792
12903
|
if (!s)
|
|
12793
12904
|
return "";
|
|
@@ -12815,7 +12926,7 @@ function whichDetector(bin) {
|
|
|
12815
12926
|
return null;
|
|
12816
12927
|
}
|
|
12817
12928
|
function spawnScoped(binary, args, opts) {
|
|
12818
|
-
const scratch = mkdtempSync2(
|
|
12929
|
+
const scratch = mkdtempSync2(join21(tmpdir(), "cr-scan-tmp-"));
|
|
12819
12930
|
try {
|
|
12820
12931
|
return spawnSync(binary, args, {
|
|
12821
12932
|
...opts,
|
|
@@ -12846,7 +12957,7 @@ function runGitleaks(binary, filePath) {
|
|
|
12846
12957
|
return [];
|
|
12847
12958
|
let parsed = [];
|
|
12848
12959
|
try {
|
|
12849
|
-
parsed = JSON.parse(
|
|
12960
|
+
parsed = JSON.parse(readFileSync14(reportPath, "utf-8")) || [];
|
|
12850
12961
|
} catch {
|
|
12851
12962
|
}
|
|
12852
12963
|
try {
|
|
@@ -12910,7 +13021,7 @@ function runGitleaksDir(binary, dir) {
|
|
|
12910
13021
|
}
|
|
12911
13022
|
let parsed = [];
|
|
12912
13023
|
try {
|
|
12913
|
-
parsed = JSON.parse(
|
|
13024
|
+
parsed = JSON.parse(readFileSync14(reportPath, "utf-8")) || [];
|
|
12914
13025
|
} catch {
|
|
12915
13026
|
}
|
|
12916
13027
|
try {
|
|
@@ -13001,7 +13112,7 @@ function scanFileForSecrets(filePath, opts = {}) {
|
|
|
13001
13112
|
out.push({ detector: "trufflehog", ...f });
|
|
13002
13113
|
if (opts.tenantRules && opts.tenantRules.length > 0) {
|
|
13003
13114
|
try {
|
|
13004
|
-
const text =
|
|
13115
|
+
const text = readFileSync14(filePath, "utf-8");
|
|
13005
13116
|
out.push(...scanTenantRules(text, opts.tenantRules));
|
|
13006
13117
|
} catch {
|
|
13007
13118
|
}
|
|
@@ -13377,10 +13488,10 @@ var init_transcript = __esm({
|
|
|
13377
13488
|
// ../engine/dist/core/project-resolver.js
|
|
13378
13489
|
import { execSync } from "child_process";
|
|
13379
13490
|
import { createHash as createHash5 } from "crypto";
|
|
13380
|
-
import { existsSync as existsSync20, readFileSync as
|
|
13381
|
-
import { basename as basename11, dirname as
|
|
13491
|
+
import { existsSync as existsSync20, readFileSync as readFileSync15, realpathSync as realpathSync3, readdirSync as readdirSync14, statSync as statSync18 } from "fs";
|
|
13492
|
+
import { basename as basename11, dirname as dirname14, isAbsolute, join as join22, resolve, sep } from "path";
|
|
13382
13493
|
function getProjectsConfigPath() {
|
|
13383
|
-
return
|
|
13494
|
+
return join22(getDataDir(), "projects.json");
|
|
13384
13495
|
}
|
|
13385
13496
|
function loadProjectsConfig() {
|
|
13386
13497
|
if (cachedConfig && cachedConfig.mtime === Number.MAX_SAFE_INTEGER) {
|
|
@@ -13395,7 +13506,7 @@ function loadProjectsConfig() {
|
|
|
13395
13506
|
if (cachedConfig && cachedConfig.mtime === mtime)
|
|
13396
13507
|
return cachedConfig.cfg;
|
|
13397
13508
|
try {
|
|
13398
|
-
const raw =
|
|
13509
|
+
const raw = readFileSync15(path, "utf-8");
|
|
13399
13510
|
const cfg = JSON.parse(raw);
|
|
13400
13511
|
cachedConfig = { mtime, cfg };
|
|
13401
13512
|
return cfg;
|
|
@@ -13491,7 +13602,7 @@ function matchDeclaredProject(realPath, projects) {
|
|
|
13491
13602
|
function matchChild(realPath, parentRoot, children) {
|
|
13492
13603
|
const sorted = [...children].sort((a, b) => b.path.length - a.path.length);
|
|
13493
13604
|
for (const c of sorted) {
|
|
13494
|
-
const childRoot = safeRealpath(
|
|
13605
|
+
const childRoot = safeRealpath(join22(parentRoot, c.path));
|
|
13495
13606
|
if (isInside(realPath, childRoot))
|
|
13496
13607
|
return c;
|
|
13497
13608
|
}
|
|
@@ -13526,10 +13637,10 @@ function findGitToplevel(realPath) {
|
|
|
13526
13637
|
let cur = realPath;
|
|
13527
13638
|
let last = "";
|
|
13528
13639
|
while (cur && cur !== last) {
|
|
13529
|
-
if (existsSync20(
|
|
13640
|
+
if (existsSync20(join22(cur, ".git")))
|
|
13530
13641
|
return cur;
|
|
13531
13642
|
last = cur;
|
|
13532
|
-
cur =
|
|
13643
|
+
cur = dirname14(cur);
|
|
13533
13644
|
}
|
|
13534
13645
|
return null;
|
|
13535
13646
|
}
|
|
@@ -13593,7 +13704,7 @@ function resolveAutoWorkspace(realPath, minRepos) {
|
|
|
13593
13704
|
let last = "";
|
|
13594
13705
|
let depth = 0;
|
|
13595
13706
|
while (cur && cur !== last && depth < AUTO_WORKSPACE_MAX_DEPTH) {
|
|
13596
|
-
if (!existsSync20(
|
|
13707
|
+
if (!existsSync20(join22(cur, ".git"))) {
|
|
13597
13708
|
const cached = workspaceCache.get(cur);
|
|
13598
13709
|
let qualifies;
|
|
13599
13710
|
if (cached === void 0) {
|
|
@@ -13608,7 +13719,7 @@ function resolveAutoWorkspace(realPath, minRepos) {
|
|
|
13608
13719
|
}
|
|
13609
13720
|
}
|
|
13610
13721
|
last = cur;
|
|
13611
|
-
cur =
|
|
13722
|
+
cur = dirname14(cur);
|
|
13612
13723
|
depth++;
|
|
13613
13724
|
}
|
|
13614
13725
|
return null;
|
|
@@ -13624,12 +13735,12 @@ function countGitChildren(dir) {
|
|
|
13624
13735
|
for (const name of entries) {
|
|
13625
13736
|
if (name.startsWith("."))
|
|
13626
13737
|
continue;
|
|
13627
|
-
const child =
|
|
13738
|
+
const child = join22(dir, name);
|
|
13628
13739
|
try {
|
|
13629
13740
|
const st = statSync18(child);
|
|
13630
13741
|
if (!st.isDirectory())
|
|
13631
13742
|
continue;
|
|
13632
|
-
if (existsSync20(
|
|
13743
|
+
if (existsSync20(join22(child, ".git")))
|
|
13633
13744
|
count++;
|
|
13634
13745
|
} catch {
|
|
13635
13746
|
}
|
|
@@ -14443,7 +14554,7 @@ var init_session_source = __esm({
|
|
|
14443
14554
|
// ../engine/dist/core/utils.js
|
|
14444
14555
|
import { existsSync as existsSync21, readdirSync as readdirSync15 } from "fs";
|
|
14445
14556
|
import { homedir as homedir6 } from "os";
|
|
14446
|
-
import { join as
|
|
14557
|
+
import { join as join23 } from "path";
|
|
14447
14558
|
function splitByHeaders(markdown) {
|
|
14448
14559
|
const lines = markdown.split("\n");
|
|
14449
14560
|
const sections = [];
|
|
@@ -14486,17 +14597,17 @@ function getClaudeDirs() {
|
|
|
14486
14597
|
for (const d of process.env.CLAUDE_DIRS.split(",")) {
|
|
14487
14598
|
const trimmed = d.trim();
|
|
14488
14599
|
if (trimmed) {
|
|
14489
|
-
add(trimmed.startsWith("~/") ?
|
|
14600
|
+
add(trimmed.startsWith("~/") ? join23(home, trimmed.slice(2)) : trimmed);
|
|
14490
14601
|
}
|
|
14491
14602
|
}
|
|
14492
14603
|
}
|
|
14493
|
-
add(
|
|
14604
|
+
add(join23(home, ".claude"));
|
|
14494
14605
|
try {
|
|
14495
14606
|
const entries = readdirSync15(home, { withFileTypes: true });
|
|
14496
14607
|
for (const entry of entries) {
|
|
14497
14608
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
14498
|
-
const candidate =
|
|
14499
|
-
if (existsSync21(
|
|
14609
|
+
const candidate = join23(home, entry.name);
|
|
14610
|
+
if (existsSync21(join23(candidate, "projects"))) {
|
|
14500
14611
|
add(candidate);
|
|
14501
14612
|
}
|
|
14502
14613
|
}
|
|
@@ -14508,12 +14619,12 @@ function getClaudeDirs() {
|
|
|
14508
14619
|
function discoverSubdirs(subdir) {
|
|
14509
14620
|
const result = [];
|
|
14510
14621
|
for (const claudeDir of getClaudeDirs()) {
|
|
14511
|
-
const path =
|
|
14622
|
+
const path = join23(claudeDir, subdir);
|
|
14512
14623
|
if (existsSync21(path)) {
|
|
14513
14624
|
result.push(path);
|
|
14514
14625
|
}
|
|
14515
14626
|
}
|
|
14516
|
-
return result.length > 0 ? result : [
|
|
14627
|
+
return result.length > 0 ? result : [join23(homedir6(), ".claude", subdir)];
|
|
14517
14628
|
}
|
|
14518
14629
|
var init_utils = __esm({
|
|
14519
14630
|
"../engine/dist/core/utils.js"() {
|
|
@@ -14522,9 +14633,9 @@ var init_utils = __esm({
|
|
|
14522
14633
|
});
|
|
14523
14634
|
|
|
14524
14635
|
// ../engine/dist/parsers/plan-source.js
|
|
14525
|
-
import { existsSync as existsSync22, readdirSync as readdirSync16, readFileSync as
|
|
14636
|
+
import { existsSync as existsSync22, readdirSync as readdirSync16, readFileSync as readFileSync16, statSync as statSync20 } from "fs";
|
|
14526
14637
|
import { homedir as homedir7 } from "os";
|
|
14527
|
-
import { join as
|
|
14638
|
+
import { join as join24, basename as basename12 } from "path";
|
|
14528
14639
|
function parseFrontmatter(content) {
|
|
14529
14640
|
if (!content.startsWith("---"))
|
|
14530
14641
|
return { body: content };
|
|
@@ -14619,12 +14730,12 @@ var init_plan_source = __esm({
|
|
|
14619
14730
|
if (seenClaude.has(file))
|
|
14620
14731
|
continue;
|
|
14621
14732
|
seenClaude.add(file);
|
|
14622
|
-
const filePath =
|
|
14733
|
+
const filePath = join24(plansDir, file);
|
|
14623
14734
|
try {
|
|
14624
14735
|
const stat3 = statSync20(filePath);
|
|
14625
14736
|
const planName = basename12(file, ".md");
|
|
14626
14737
|
const isAgentPlan = planName.includes("-agent-");
|
|
14627
|
-
const content =
|
|
14738
|
+
const content = readFileSync16(filePath, "utf-8");
|
|
14628
14739
|
const fm = parseFrontmatter(content);
|
|
14629
14740
|
const body = fm.body;
|
|
14630
14741
|
const firstLine = body.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || planName;
|
|
@@ -14663,10 +14774,10 @@ var init_plan_source = __esm({
|
|
|
14663
14774
|
return;
|
|
14664
14775
|
}
|
|
14665
14776
|
for (const file of files) {
|
|
14666
|
-
const filePath =
|
|
14777
|
+
const filePath = join24(plansDir, file);
|
|
14667
14778
|
try {
|
|
14668
14779
|
const stat3 = statSync20(filePath);
|
|
14669
|
-
const content =
|
|
14780
|
+
const content = readFileSync16(filePath, "utf-8");
|
|
14670
14781
|
const firstLine = content.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || file;
|
|
14671
14782
|
const planName = `${opencodeBackend.idPrefix}plan_${basename12(file, ".md")}`;
|
|
14672
14783
|
const projectPath = this.extractProjectPath(content);
|
|
@@ -14694,7 +14805,7 @@ var init_plan_source = __esm({
|
|
|
14694
14805
|
for (const match of content.matchAll(fullPathPattern)) {
|
|
14695
14806
|
let path = (match[1] || "").trim();
|
|
14696
14807
|
if (path.startsWith("~/")) {
|
|
14697
|
-
path =
|
|
14808
|
+
path = join24(homedir7(), path.slice(2));
|
|
14698
14809
|
}
|
|
14699
14810
|
for (const projectDir of knownProjects) {
|
|
14700
14811
|
if (path.startsWith(projectDir)) {
|
|
@@ -14743,7 +14854,7 @@ var init_plan_source = __esm({
|
|
|
14743
14854
|
async parse(item) {
|
|
14744
14855
|
if (!existsSync22(item.filePath))
|
|
14745
14856
|
return [];
|
|
14746
|
-
const content =
|
|
14857
|
+
const content = readFileSync16(item.filePath, "utf-8");
|
|
14747
14858
|
const chunks = [];
|
|
14748
14859
|
const { body } = parseFrontmatter(content);
|
|
14749
14860
|
const sections = splitByHeaders(body);
|
|
@@ -14779,9 +14890,9 @@ var init_plan_source = __esm({
|
|
|
14779
14890
|
const map = /* @__PURE__ */ new Map();
|
|
14780
14891
|
const root = claudeBackend.projectsDir();
|
|
14781
14892
|
for (const proj of safeReaddir(root)) {
|
|
14782
|
-
const projPath =
|
|
14893
|
+
const projPath = join24(root, proj);
|
|
14783
14894
|
for (const sessionEntry of safeReaddir(projPath)) {
|
|
14784
|
-
const subDir =
|
|
14895
|
+
const subDir = join24(projPath, sessionEntry, "subagents");
|
|
14785
14896
|
if (!existsSync22(subDir))
|
|
14786
14897
|
continue;
|
|
14787
14898
|
for (const f of safeReaddir(subDir)) {
|
|
@@ -14856,7 +14967,7 @@ var init_plan_source = __esm({
|
|
|
14856
14967
|
return links;
|
|
14857
14968
|
}
|
|
14858
14969
|
async *discoverAgyPlans() {
|
|
14859
|
-
const brainDir =
|
|
14970
|
+
const brainDir = join24(agyBackend.homeDir(), "brain");
|
|
14860
14971
|
if (!existsSync22(brainDir))
|
|
14861
14972
|
return;
|
|
14862
14973
|
let sessionDirs;
|
|
@@ -14866,7 +14977,7 @@ var init_plan_source = __esm({
|
|
|
14866
14977
|
return;
|
|
14867
14978
|
}
|
|
14868
14979
|
for (const rawId of sessionDirs) {
|
|
14869
|
-
const sessionPath =
|
|
14980
|
+
const sessionPath = join24(brainDir, rawId);
|
|
14870
14981
|
try {
|
|
14871
14982
|
if (!statSync20(sessionPath).isDirectory())
|
|
14872
14983
|
continue;
|
|
@@ -14880,10 +14991,10 @@ var init_plan_source = __esm({
|
|
|
14880
14991
|
continue;
|
|
14881
14992
|
}
|
|
14882
14993
|
for (const file of files) {
|
|
14883
|
-
const filePath =
|
|
14994
|
+
const filePath = join24(sessionPath, file);
|
|
14884
14995
|
try {
|
|
14885
14996
|
const stat3 = statSync20(filePath);
|
|
14886
|
-
const content =
|
|
14997
|
+
const content = readFileSync16(filePath, "utf-8");
|
|
14887
14998
|
const firstLine = content.split("\n").find((l) => l.trim())?.replace(/^#+\s*/, "").trim() || file;
|
|
14888
14999
|
const sessionLoc = agyBackend.findSession(rawId);
|
|
14889
15000
|
const projectPath = sessionLoc?.projectPath || this.extractProjectPath(content);
|
|
@@ -14912,8 +15023,8 @@ var init_plan_source = __esm({
|
|
|
14912
15023
|
});
|
|
14913
15024
|
|
|
14914
15025
|
// ../engine/dist/parsers/task-source.js
|
|
14915
|
-
import { existsSync as existsSync23, readdirSync as readdirSync17, readFileSync as
|
|
14916
|
-
import { join as
|
|
15026
|
+
import { existsSync as existsSync23, readdirSync as readdirSync17, readFileSync as readFileSync17, statSync as statSync21 } from "fs";
|
|
15027
|
+
import { join as join25 } from "path";
|
|
14917
15028
|
var MAX_CHUNK_CHARS2, TaskSource;
|
|
14918
15029
|
var init_task_source = __esm({
|
|
14919
15030
|
"../engine/dist/parsers/task-source.js"() {
|
|
@@ -14951,7 +15062,7 @@ var init_task_source = __esm({
|
|
|
14951
15062
|
return;
|
|
14952
15063
|
}
|
|
14953
15064
|
for (const file of files) {
|
|
14954
|
-
const filePath =
|
|
15065
|
+
const filePath = join25(todosDir, file);
|
|
14955
15066
|
let stat3;
|
|
14956
15067
|
try {
|
|
14957
15068
|
stat3 = statSync21(filePath);
|
|
@@ -14962,7 +15073,7 @@ var init_task_source = __esm({
|
|
|
14962
15073
|
continue;
|
|
14963
15074
|
let parsed;
|
|
14964
15075
|
try {
|
|
14965
|
-
const raw =
|
|
15076
|
+
const raw = readFileSync17(filePath, "utf-8");
|
|
14966
15077
|
parsed = JSON.parse(raw);
|
|
14967
15078
|
if (!Array.isArray(parsed) || parsed.length === 0)
|
|
14968
15079
|
continue;
|
|
@@ -15000,7 +15111,7 @@ var init_task_source = __esm({
|
|
|
15000
15111
|
if (!entry.isDirectory())
|
|
15001
15112
|
continue;
|
|
15002
15113
|
const sessionUuid = entry.name;
|
|
15003
|
-
const taskDir =
|
|
15114
|
+
const taskDir = join25(tasksDir, sessionUuid);
|
|
15004
15115
|
try {
|
|
15005
15116
|
const stat3 = statSync21(taskDir);
|
|
15006
15117
|
const taskFiles = readdirSync17(taskDir).filter((f) => f.endsWith(".json"));
|
|
@@ -15075,7 +15186,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15075
15186
|
text,
|
|
15076
15187
|
chunkType: "task_detail",
|
|
15077
15188
|
projectPath: item.projectPath,
|
|
15078
|
-
filePath:
|
|
15189
|
+
filePath: join25(taskDir, `${task.id}.json`),
|
|
15079
15190
|
mtime: item.mtime
|
|
15080
15191
|
});
|
|
15081
15192
|
}
|
|
@@ -15100,7 +15211,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15100
15211
|
return [];
|
|
15101
15212
|
let parsed;
|
|
15102
15213
|
try {
|
|
15103
|
-
parsed = JSON.parse(
|
|
15214
|
+
parsed = JSON.parse(readFileSync17(item.filePath, "utf-8"));
|
|
15104
15215
|
} catch {
|
|
15105
15216
|
return [];
|
|
15106
15217
|
}
|
|
@@ -15132,7 +15243,7 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15132
15243
|
});
|
|
15133
15244
|
for (const file of sorted) {
|
|
15134
15245
|
try {
|
|
15135
|
-
const content =
|
|
15246
|
+
const content = readFileSync17(join25(taskDir, file), "utf-8");
|
|
15136
15247
|
const task = JSON.parse(content);
|
|
15137
15248
|
if (task.subject) {
|
|
15138
15249
|
tasks.push(task);
|
|
@@ -15148,9 +15259,9 @@ ${task.description}`.slice(0, MAX_CHUNK_CHARS2);
|
|
|
15148
15259
|
});
|
|
15149
15260
|
|
|
15150
15261
|
// ../engine/dist/parsers/claude-md-source.js
|
|
15151
|
-
import { existsSync as existsSync24, readFileSync as
|
|
15262
|
+
import { existsSync as existsSync24, readFileSync as readFileSync18, readdirSync as readdirSync18, statSync as statSync22 } from "fs";
|
|
15152
15263
|
import { homedir as homedir8 } from "os";
|
|
15153
|
-
import { join as
|
|
15264
|
+
import { join as join26, basename as basename13, dirname as dirname15 } from "path";
|
|
15154
15265
|
import { createHash as createHash6 } from "crypto";
|
|
15155
15266
|
function discoverProjectDirs(claudeDir) {
|
|
15156
15267
|
const dirs = [];
|
|
@@ -15176,7 +15287,7 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15176
15287
|
}
|
|
15177
15288
|
};
|
|
15178
15289
|
if (claudeDir) {
|
|
15179
|
-
scanProjectsDir(
|
|
15290
|
+
scanProjectsDir(join26(claudeDir, "projects"));
|
|
15180
15291
|
return dirs;
|
|
15181
15292
|
}
|
|
15182
15293
|
const home = homedir8();
|
|
@@ -15184,7 +15295,7 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15184
15295
|
try {
|
|
15185
15296
|
for (const entry of readdirSync18(home, { withFileTypes: true })) {
|
|
15186
15297
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
15187
|
-
scanProjectsDir(
|
|
15298
|
+
scanProjectsDir(join26(home, entry.name, "projects"));
|
|
15188
15299
|
}
|
|
15189
15300
|
}
|
|
15190
15301
|
} catch {
|
|
@@ -15192,7 +15303,7 @@ function discoverProjectDirs(claudeDir) {
|
|
|
15192
15303
|
const gemProjects = agyBackend.sharedProjectsJson();
|
|
15193
15304
|
if (existsSync24(gemProjects)) {
|
|
15194
15305
|
try {
|
|
15195
|
-
const data = JSON.parse(
|
|
15306
|
+
const data = JSON.parse(readFileSync18(gemProjects, "utf-8"));
|
|
15196
15307
|
for (const path of Object.keys(data.projects || {}))
|
|
15197
15308
|
addProject(path);
|
|
15198
15309
|
} catch {
|
|
@@ -15248,7 +15359,7 @@ var init_claude_md_source = __esm({
|
|
|
15248
15359
|
const seen = /* @__PURE__ */ new Set();
|
|
15249
15360
|
const seenKey = (path, tool) => `${tool}:${path}`;
|
|
15250
15361
|
for (const note of NOTE_FILES) {
|
|
15251
|
-
const p =
|
|
15362
|
+
const p = join26(homedir8(), note.filename);
|
|
15252
15363
|
const key2 = seenKey(p, note.tool);
|
|
15253
15364
|
if (existsSync24(p) && !seen.has(key2)) {
|
|
15254
15365
|
seen.add(key2);
|
|
@@ -15260,7 +15371,7 @@ var init_claude_md_source = __esm({
|
|
|
15260
15371
|
const projectDirs = discoverProjectDirs(this.claudeDir);
|
|
15261
15372
|
for (const projectDir of projectDirs) {
|
|
15262
15373
|
for (const note of NOTE_FILES) {
|
|
15263
|
-
const p =
|
|
15374
|
+
const p = join26(projectDir, note.filename);
|
|
15264
15375
|
const key2 = seenKey(p, note.tool);
|
|
15265
15376
|
if (existsSync24(p) && !seen.has(key2)) {
|
|
15266
15377
|
seen.add(key2);
|
|
@@ -15274,7 +15385,7 @@ var init_claude_md_source = __esm({
|
|
|
15274
15385
|
if (!existsSync24(searchDir))
|
|
15275
15386
|
continue;
|
|
15276
15387
|
for (const note of NOTE_FILES) {
|
|
15277
|
-
const directPath =
|
|
15388
|
+
const directPath = join26(searchDir, note.filename);
|
|
15278
15389
|
const key2 = seenKey(directPath, note.tool);
|
|
15279
15390
|
if (existsSync24(directPath) && !seen.has(key2)) {
|
|
15280
15391
|
seen.add(key2);
|
|
@@ -15289,7 +15400,7 @@ var init_claude_md_source = __esm({
|
|
|
15289
15400
|
if (!entry.isDirectory())
|
|
15290
15401
|
continue;
|
|
15291
15402
|
for (const note of NOTE_FILES) {
|
|
15292
|
-
const p =
|
|
15403
|
+
const p = join26(searchDir, entry.name, note.filename);
|
|
15293
15404
|
const key2 = seenKey(p, note.tool);
|
|
15294
15405
|
if (existsSync24(p) && !seen.has(key2)) {
|
|
15295
15406
|
seen.add(key2);
|
|
@@ -15307,7 +15418,7 @@ var init_claude_md_source = __esm({
|
|
|
15307
15418
|
async parse(item) {
|
|
15308
15419
|
if (!existsSync24(item.filePath))
|
|
15309
15420
|
return [];
|
|
15310
|
-
const content =
|
|
15421
|
+
const content = readFileSync18(item.filePath, "utf-8");
|
|
15311
15422
|
const chunks = [];
|
|
15312
15423
|
const sections = splitByHeaders(content);
|
|
15313
15424
|
for (let i = 0; i < sections.length; i++) {
|
|
@@ -15346,10 +15457,10 @@ var init_claude_md_source = __esm({
|
|
|
15346
15457
|
fileToItem(filePath, filename, tool) {
|
|
15347
15458
|
try {
|
|
15348
15459
|
const stat3 = statSync22(filePath);
|
|
15349
|
-
const projectDir =
|
|
15460
|
+
const projectDir = dirname15(filePath);
|
|
15350
15461
|
const projectName = basename13(projectDir);
|
|
15351
15462
|
const projectPath = projectDir;
|
|
15352
|
-
const content =
|
|
15463
|
+
const content = readFileSync18(filePath, "utf-8");
|
|
15353
15464
|
const firstLine = content.split("\n").find((l) => l.trim() && !l.startsWith("#"))?.trim()?.slice(0, 200) || `${filename} for ${projectName}`;
|
|
15354
15465
|
const id = tool === "claude" ? projectName : `${projectName}_${tool}`;
|
|
15355
15466
|
return {
|
|
@@ -15374,9 +15485,9 @@ var init_claude_md_source = __esm({
|
|
|
15374
15485
|
});
|
|
15375
15486
|
|
|
15376
15487
|
// ../engine/dist/parsers/agent-memory-source.js
|
|
15377
|
-
import { existsSync as existsSync25, readFileSync as
|
|
15488
|
+
import { existsSync as existsSync25, readFileSync as readFileSync19, readdirSync as readdirSync19, statSync as statSync23 } from "fs";
|
|
15378
15489
|
import { homedir as homedir9 } from "os";
|
|
15379
|
-
import { join as
|
|
15490
|
+
import { join as join27, basename as basename14 } from "path";
|
|
15380
15491
|
function parseFrontmatter2(content) {
|
|
15381
15492
|
const fm = {};
|
|
15382
15493
|
let body = content;
|
|
@@ -15418,7 +15529,7 @@ function discoverMemoryDirs() {
|
|
|
15418
15529
|
try {
|
|
15419
15530
|
for (const entry of readdirSync19(home, { withFileTypes: true })) {
|
|
15420
15531
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
15421
|
-
claudeRoots.push(
|
|
15532
|
+
claudeRoots.push(join27(home, entry.name, "projects"));
|
|
15422
15533
|
}
|
|
15423
15534
|
}
|
|
15424
15535
|
} catch {
|
|
@@ -15430,7 +15541,7 @@ function discoverMemoryDirs() {
|
|
|
15430
15541
|
for (const entry of readdirSync19(projectsDir, { withFileTypes: true })) {
|
|
15431
15542
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
15432
15543
|
continue;
|
|
15433
|
-
add(
|
|
15544
|
+
add(join27(projectsDir, entry.name, "memory"), entry.name);
|
|
15434
15545
|
}
|
|
15435
15546
|
} catch {
|
|
15436
15547
|
}
|
|
@@ -15459,7 +15570,7 @@ var init_agent_memory_source = __esm({
|
|
|
15459
15570
|
for (const entry of readdirSync19(memoryDir, { withFileTypes: true })) {
|
|
15460
15571
|
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
15461
15572
|
continue;
|
|
15462
|
-
const filePath =
|
|
15573
|
+
const filePath = join27(memoryDir, entry.name);
|
|
15463
15574
|
if (seen.has(filePath))
|
|
15464
15575
|
continue;
|
|
15465
15576
|
seen.add(filePath);
|
|
@@ -15475,7 +15586,7 @@ var init_agent_memory_source = __esm({
|
|
|
15475
15586
|
async parse(item) {
|
|
15476
15587
|
if (!existsSync25(item.filePath))
|
|
15477
15588
|
return [];
|
|
15478
|
-
const content =
|
|
15589
|
+
const content = readFileSync19(item.filePath, "utf-8");
|
|
15479
15590
|
const { body } = parseFrontmatter2(content);
|
|
15480
15591
|
const chunks = [];
|
|
15481
15592
|
const sections = splitByHeaders(body);
|
|
@@ -15528,7 +15639,7 @@ var init_agent_memory_source = __esm({
|
|
|
15528
15639
|
fileToItem(filePath, filename, projectPath, _projectHash) {
|
|
15529
15640
|
try {
|
|
15530
15641
|
const stat3 = statSync23(filePath);
|
|
15531
|
-
const content =
|
|
15642
|
+
const content = readFileSync19(filePath, "utf-8");
|
|
15532
15643
|
const { fm } = parseFrontmatter2(content);
|
|
15533
15644
|
const stem = filename.replace(/\.md$/, "");
|
|
15534
15645
|
const idBase = fm.name || stem;
|
|
@@ -15563,7 +15674,7 @@ import { existsSync as existsSync26, readdirSync as readdirSync20, statSync as s
|
|
|
15563
15674
|
import { createReadStream as createReadStream3 } from "fs";
|
|
15564
15675
|
import { createInterface as createInterface2 } from "readline";
|
|
15565
15676
|
import { homedir as homedir10 } from "os";
|
|
15566
|
-
import { join as
|
|
15677
|
+
import { join as join28 } from "path";
|
|
15567
15678
|
var MAX_CHUNK_CHARS5, HistorySource;
|
|
15568
15679
|
var init_history_source = __esm({
|
|
15569
15680
|
"../engine/dist/parsers/history-source.js"() {
|
|
@@ -15588,12 +15699,12 @@ var init_history_source = __esm({
|
|
|
15588
15699
|
try {
|
|
15589
15700
|
for (const entry of readdirSync20(home, { withFileTypes: true })) {
|
|
15590
15701
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
15591
|
-
tryAdd(
|
|
15702
|
+
tryAdd(join28(home, entry.name, "history.jsonl"));
|
|
15592
15703
|
}
|
|
15593
15704
|
}
|
|
15594
15705
|
} catch {
|
|
15595
15706
|
}
|
|
15596
|
-
this.historyPaths = paths.length > 0 ? paths : [
|
|
15707
|
+
this.historyPaths = paths.length > 0 ? paths : [join28(home, ".claude", "history.jsonl")];
|
|
15597
15708
|
}
|
|
15598
15709
|
}
|
|
15599
15710
|
async *discover() {
|
|
@@ -15743,9 +15854,9 @@ var init_history_source = __esm({
|
|
|
15743
15854
|
});
|
|
15744
15855
|
|
|
15745
15856
|
// ../engine/dist/parsers/paste-source.js
|
|
15746
|
-
import { existsSync as existsSync27, readdirSync as readdirSync21, readFileSync as
|
|
15857
|
+
import { existsSync as existsSync27, readdirSync as readdirSync21, readFileSync as readFileSync20, statSync as statSync25 } from "fs";
|
|
15747
15858
|
import { homedir as homedir11 } from "os";
|
|
15748
|
-
import { join as
|
|
15859
|
+
import { join as join29, basename as basename15 } from "path";
|
|
15749
15860
|
var MAX_CHUNK_CHARS6, MAX_FILE_SIZE, PasteSource;
|
|
15750
15861
|
var init_paste_source = __esm({
|
|
15751
15862
|
"../engine/dist/parsers/paste-source.js"() {
|
|
@@ -15771,7 +15882,7 @@ var init_paste_source = __esm({
|
|
|
15771
15882
|
try {
|
|
15772
15883
|
for (const entry of readdirSync21(home, { withFileTypes: true })) {
|
|
15773
15884
|
if (entry.isDirectory() && entry.name.startsWith(".claude-") && entry.name !== ".claude-code") {
|
|
15774
|
-
tryAdd(
|
|
15885
|
+
tryAdd(join29(home, entry.name, "paste-cache"));
|
|
15775
15886
|
}
|
|
15776
15887
|
}
|
|
15777
15888
|
} catch {
|
|
@@ -15791,7 +15902,7 @@ var init_paste_source = __esm({
|
|
|
15791
15902
|
if (seen.has(file))
|
|
15792
15903
|
continue;
|
|
15793
15904
|
seen.add(file);
|
|
15794
|
-
const filePath =
|
|
15905
|
+
const filePath = join29(cacheDir, file);
|
|
15795
15906
|
try {
|
|
15796
15907
|
const stat3 = statSync25(filePath);
|
|
15797
15908
|
if (stat3.size > MAX_FILE_SIZE)
|
|
@@ -15799,7 +15910,7 @@ var init_paste_source = __esm({
|
|
|
15799
15910
|
if (stat3.size < 10)
|
|
15800
15911
|
continue;
|
|
15801
15912
|
const hash = basename15(file, ".txt");
|
|
15802
|
-
const content =
|
|
15913
|
+
const content = readFileSync20(filePath, "utf-8");
|
|
15803
15914
|
const firstLine = content.split("\n").find((l) => l.trim().length > 5)?.trim()?.slice(0, 100) || `Paste ${hash.slice(0, 8)}`;
|
|
15804
15915
|
yield {
|
|
15805
15916
|
id: hash,
|
|
@@ -15820,7 +15931,7 @@ var init_paste_source = __esm({
|
|
|
15820
15931
|
async parse(item) {
|
|
15821
15932
|
if (!existsSync27(item.filePath))
|
|
15822
15933
|
return [];
|
|
15823
|
-
const content =
|
|
15934
|
+
const content = readFileSync20(item.filePath, "utf-8");
|
|
15824
15935
|
if (content.trim().length < 20)
|
|
15825
15936
|
return [];
|
|
15826
15937
|
return [{
|
|
@@ -15843,8 +15954,8 @@ var init_paste_source = __esm({
|
|
|
15843
15954
|
});
|
|
15844
15955
|
|
|
15845
15956
|
// ../engine/dist/parsers/antigravity-brain-source.js
|
|
15846
|
-
import { existsSync as existsSync28, readdirSync as readdirSync22, readFileSync as
|
|
15847
|
-
import { join as
|
|
15957
|
+
import { existsSync as existsSync28, readdirSync as readdirSync22, readFileSync as readFileSync21, statSync as statSync26 } from "fs";
|
|
15958
|
+
import { join as join30 } from "path";
|
|
15848
15959
|
var MAX_CHUNK_CHARS7, AntigravityBrainSource;
|
|
15849
15960
|
var init_antigravity_brain_source = __esm({
|
|
15850
15961
|
"../engine/dist/parsers/antigravity-brain-source.js"() {
|
|
@@ -15868,22 +15979,22 @@ var init_antigravity_brain_source = __esm({
|
|
|
15868
15979
|
for (const entry of sessions) {
|
|
15869
15980
|
if (!entry.isDirectory())
|
|
15870
15981
|
continue;
|
|
15871
|
-
const sessionDir =
|
|
15982
|
+
const sessionDir = join30(this.brainDir, entry.name);
|
|
15872
15983
|
const files = readdirSync22(sessionDir).filter((f) => f.endsWith(".md") && !f.includes(".resolved") && !f.includes(".metadata"));
|
|
15873
15984
|
if (files.length === 0)
|
|
15874
15985
|
continue;
|
|
15875
15986
|
for (const file of files) {
|
|
15876
|
-
const filePath =
|
|
15987
|
+
const filePath = join30(sessionDir, file);
|
|
15877
15988
|
try {
|
|
15878
15989
|
const stat3 = statSync26(filePath);
|
|
15879
|
-
const content =
|
|
15990
|
+
const content = readFileSync21(filePath, "utf-8");
|
|
15880
15991
|
const firstLine = content.split("\n").find((l) => l.trim() && !l.startsWith("#"))?.trim() || "";
|
|
15881
15992
|
const heading = content.split("\n").find((l) => l.startsWith("#"))?.replace(/^#+\s*/, "").trim() || file;
|
|
15882
15993
|
const metaPath = `${filePath}.metadata.json`;
|
|
15883
15994
|
let metaSummary = "";
|
|
15884
15995
|
if (existsSync28(metaPath)) {
|
|
15885
15996
|
try {
|
|
15886
|
-
const meta = JSON.parse(
|
|
15997
|
+
const meta = JSON.parse(readFileSync21(metaPath, "utf-8"));
|
|
15887
15998
|
metaSummary = meta.summary || "";
|
|
15888
15999
|
} catch {
|
|
15889
16000
|
}
|
|
@@ -15914,7 +16025,7 @@ var init_antigravity_brain_source = __esm({
|
|
|
15914
16025
|
async parse(item) {
|
|
15915
16026
|
if (!existsSync28(item.filePath))
|
|
15916
16027
|
return [];
|
|
15917
|
-
const content =
|
|
16028
|
+
const content = readFileSync21(item.filePath, "utf-8");
|
|
15918
16029
|
const chunks = [];
|
|
15919
16030
|
const sections = splitByHeaders(content);
|
|
15920
16031
|
for (let i = 0; i < sections.length; i++) {
|
|
@@ -16257,8 +16368,8 @@ var init_opencode_todo_source = __esm({
|
|
|
16257
16368
|
});
|
|
16258
16369
|
|
|
16259
16370
|
// ../engine/dist/parsers/codex-session-source.js
|
|
16260
|
-
import { existsSync as existsSync31, readdirSync as readdirSync23, readFileSync as
|
|
16261
|
-
import { join as
|
|
16371
|
+
import { existsSync as existsSync31, readdirSync as readdirSync23, readFileSync as readFileSync22, statSync as statSync27 } from "fs";
|
|
16372
|
+
import { join as join31, basename as basename16 } from "path";
|
|
16262
16373
|
function getCodexSessionsDir() {
|
|
16263
16374
|
return codexBackend.sessionsDir();
|
|
16264
16375
|
}
|
|
@@ -16285,7 +16396,7 @@ function extractReasoningText(event) {
|
|
|
16285
16396
|
return "";
|
|
16286
16397
|
}
|
|
16287
16398
|
function readJsonlLines(filePath) {
|
|
16288
|
-
const text =
|
|
16399
|
+
const text = readFileSync22(filePath, "utf-8");
|
|
16289
16400
|
const lines = text.split("\n");
|
|
16290
16401
|
const events = [];
|
|
16291
16402
|
for (const line of lines) {
|
|
@@ -16320,7 +16431,7 @@ var init_codex_session_source = __esm({
|
|
|
16320
16431
|
for (const filePath of jsonlFiles) {
|
|
16321
16432
|
try {
|
|
16322
16433
|
const stat3 = statSync27(filePath);
|
|
16323
|
-
const lines =
|
|
16434
|
+
const lines = readFileSync22(filePath, "utf-8").split("\n");
|
|
16324
16435
|
const firstLine = lines.find((l) => l.trim());
|
|
16325
16436
|
if (!firstLine)
|
|
16326
16437
|
continue;
|
|
@@ -16479,7 +16590,7 @@ var init_codex_session_source = __esm({
|
|
|
16479
16590
|
if (!existsSync31(dir))
|
|
16480
16591
|
return results;
|
|
16481
16592
|
for (const entry of readdirSync23(dir, { withFileTypes: true })) {
|
|
16482
|
-
const fullPath =
|
|
16593
|
+
const fullPath = join31(dir, entry.name);
|
|
16483
16594
|
if (entry.isDirectory()) {
|
|
16484
16595
|
results.push(...this.collectJsonlFiles(fullPath));
|
|
16485
16596
|
} else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl")) {
|
|
@@ -16493,8 +16604,8 @@ var init_codex_session_source = __esm({
|
|
|
16493
16604
|
});
|
|
16494
16605
|
|
|
16495
16606
|
// ../engine/dist/parsers/diary-source.js
|
|
16496
|
-
import { existsSync as existsSync32, mkdirSync as
|
|
16497
|
-
import { join as
|
|
16607
|
+
import { existsSync as existsSync32, mkdirSync as mkdirSync6, readdirSync as readdirSync24, readFileSync as readFileSync23, writeFileSync as writeFileSync5, statSync as statSync28 } from "fs";
|
|
16608
|
+
import { join as join32, basename as basename17 } from "path";
|
|
16498
16609
|
var MAX_CHUNK_CHARS10, DiarySource;
|
|
16499
16610
|
var init_diary_source = __esm({
|
|
16500
16611
|
"../engine/dist/parsers/diary-source.js"() {
|
|
@@ -16513,13 +16624,13 @@ var init_diary_source = __esm({
|
|
|
16513
16624
|
return;
|
|
16514
16625
|
const agents = readdirSync24(this.diaryDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
16515
16626
|
for (const agentDir of agents) {
|
|
16516
|
-
const agentPath2 =
|
|
16627
|
+
const agentPath2 = join32(this.diaryDir, agentDir.name);
|
|
16517
16628
|
const files = readdirSync24(agentPath2).filter((f) => f.endsWith(".json"));
|
|
16518
16629
|
for (const file of files) {
|
|
16519
|
-
const filePath =
|
|
16630
|
+
const filePath = join32(agentPath2, file);
|
|
16520
16631
|
try {
|
|
16521
16632
|
const stat3 = statSync28(filePath);
|
|
16522
|
-
const raw =
|
|
16633
|
+
const raw = readFileSync23(filePath, "utf-8");
|
|
16523
16634
|
const entry = JSON.parse(raw);
|
|
16524
16635
|
const entryId = basename17(file, ".json");
|
|
16525
16636
|
const title = `[${entry.agent}] ${entry.topic}: ${entry.content.slice(0, 80)}`;
|
|
@@ -16546,7 +16657,7 @@ var init_diary_source = __esm({
|
|
|
16546
16657
|
async parse(item) {
|
|
16547
16658
|
if (!existsSync32(item.filePath))
|
|
16548
16659
|
return [];
|
|
16549
|
-
const raw =
|
|
16660
|
+
const raw = readFileSync23(item.filePath, "utf-8");
|
|
16550
16661
|
const entry = JSON.parse(raw);
|
|
16551
16662
|
if (!entry.content || entry.content.trim().length < 10)
|
|
16552
16663
|
return [];
|
|
@@ -16583,18 +16694,18 @@ var init_diary_source = __esm({
|
|
|
16583
16694
|
*/
|
|
16584
16695
|
static write(entry, diaryDir) {
|
|
16585
16696
|
const dir = diaryDir || getDiaryDir();
|
|
16586
|
-
const agentDir =
|
|
16697
|
+
const agentDir = join32(dir, entry.agent.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
|
|
16587
16698
|
if (!existsSync32(agentDir)) {
|
|
16588
|
-
|
|
16699
|
+
mkdirSync6(agentDir, { recursive: true });
|
|
16589
16700
|
}
|
|
16590
16701
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
16591
16702
|
const entryId = `diary_${entry.agent.toLowerCase()}_${ts}`;
|
|
16592
|
-
const filePath =
|
|
16703
|
+
const filePath = join32(agentDir, `${entryId}.json`);
|
|
16593
16704
|
const full = {
|
|
16594
16705
|
...entry,
|
|
16595
16706
|
timestamp: entry.timestamp || (/* @__PURE__ */ new Date()).toISOString()
|
|
16596
16707
|
};
|
|
16597
|
-
|
|
16708
|
+
writeFileSync5(filePath, JSON.stringify(full, null, 2), "utf-8");
|
|
16598
16709
|
return entryId;
|
|
16599
16710
|
}
|
|
16600
16711
|
/**
|
|
@@ -16602,14 +16713,14 @@ var init_diary_source = __esm({
|
|
|
16602
16713
|
*/
|
|
16603
16714
|
static read(agentName, lastN = 10, diaryDir) {
|
|
16604
16715
|
const dir = diaryDir || getDiaryDir();
|
|
16605
|
-
const agentDir =
|
|
16716
|
+
const agentDir = join32(dir, agentName.toLowerCase().replace(/[^a-z0-9_-]/g, "_"));
|
|
16606
16717
|
if (!existsSync32(agentDir))
|
|
16607
16718
|
return [];
|
|
16608
16719
|
const files = readdirSync24(agentDir).filter((f) => f.endsWith(".json")).sort().reverse().slice(0, lastN);
|
|
16609
16720
|
const entries = [];
|
|
16610
16721
|
for (const file of files) {
|
|
16611
16722
|
try {
|
|
16612
|
-
const raw =
|
|
16723
|
+
const raw = readFileSync23(join32(agentDir, file), "utf-8");
|
|
16613
16724
|
entries.push(JSON.parse(raw));
|
|
16614
16725
|
} catch {
|
|
16615
16726
|
continue;
|
|
@@ -16654,9 +16765,9 @@ var init_redact_inline = __esm({
|
|
|
16654
16765
|
});
|
|
16655
16766
|
|
|
16656
16767
|
// ../engine/dist/parsers/skills-source.js
|
|
16657
|
-
import { existsSync as existsSync33, readdirSync as readdirSync25, readFileSync as
|
|
16768
|
+
import { existsSync as existsSync33, readdirSync as readdirSync25, readFileSync as readFileSync24, statSync as statSync29 } from "fs";
|
|
16658
16769
|
import { homedir as homedir12 } from "os";
|
|
16659
|
-
import { join as
|
|
16770
|
+
import { join as join33 } from "path";
|
|
16660
16771
|
function rebuildBody(content) {
|
|
16661
16772
|
const { text, redacted } = redactInlineSecrets(content);
|
|
16662
16773
|
const out = {};
|
|
@@ -16674,25 +16785,25 @@ function resolveRoots() {
|
|
|
16674
16785
|
const home = homedir12();
|
|
16675
16786
|
const all = [];
|
|
16676
16787
|
if (isSourceEnabled("shared", "skills")) {
|
|
16677
|
-
all.push({ path:
|
|
16788
|
+
all.push({ path: join33(home, ".agents", "skills"), tool: "shared" });
|
|
16678
16789
|
}
|
|
16679
16790
|
if (isSourceEnabled("claude", "skills")) {
|
|
16680
16791
|
all.push({ path: claudeBackend.skillsDir(), tool: "claude" });
|
|
16681
16792
|
}
|
|
16682
16793
|
if (isSourceEnabled("agy", "skills")) {
|
|
16683
|
-
all.push({ path:
|
|
16794
|
+
all.push({ path: join33(agyBackend.homeDir(), "skills"), tool: "agy" });
|
|
16684
16795
|
all.push({ path: agyBackend.sharedSkillsDir(), tool: "agy" });
|
|
16685
16796
|
}
|
|
16686
16797
|
if (isSourceEnabled("opencode", "skills")) {
|
|
16687
|
-
all.push({ path:
|
|
16798
|
+
all.push({ path: join33(home, ".config", "opencode", "skills"), tool: "opencode" }, { path: join33(home, ".config", "opencode", "skill"), tool: "opencode" }, { path: join33(home, ".opencode", "skill"), tool: "opencode" }, { path: join33(home, ".opencode", "skills"), tool: "opencode" });
|
|
16688
16799
|
}
|
|
16689
16800
|
if (isSourceEnabled("codex", "skills")) {
|
|
16690
16801
|
all.push({ path: codexBackend.skillsDir(), tool: "codex", skipChildren: [".system"] });
|
|
16691
16802
|
all.push({ path: codexBackend.skillsSystemDir(), tool: "codex", readonly: true });
|
|
16692
16803
|
}
|
|
16693
16804
|
if (isSourceEnabled("cursor", "skills")) {
|
|
16694
|
-
all.push({ path:
|
|
16695
|
-
all.push({ path:
|
|
16805
|
+
all.push({ path: join33(cursorHomeDir(), "skills"), tool: "cursor" });
|
|
16806
|
+
all.push({ path: join33(cursorHomeDir(), "skills-cursor"), tool: "cursor", readonly: true });
|
|
16696
16807
|
}
|
|
16697
16808
|
return all.filter((r) => existsSync33(r.path));
|
|
16698
16809
|
}
|
|
@@ -16737,7 +16848,7 @@ var init_skills_source = __esm({
|
|
|
16737
16848
|
const codexPluginsDir = codexBackend.pluginsDir();
|
|
16738
16849
|
if (existsSync33(codexPluginsDir)) {
|
|
16739
16850
|
for (const pluginName of readdirSync25(codexPluginsDir)) {
|
|
16740
|
-
const skillsDir =
|
|
16851
|
+
const skillsDir = join33(codexPluginsDir, pluginName, "skills");
|
|
16741
16852
|
if (!existsSync33(skillsDir))
|
|
16742
16853
|
continue;
|
|
16743
16854
|
yield* this.fromSkillRoot({ path: skillsDir, tool: "codex" }, pluginName);
|
|
@@ -16754,7 +16865,7 @@ var init_skills_source = __esm({
|
|
|
16754
16865
|
for (const name of entries) {
|
|
16755
16866
|
if (root.skipChildren?.includes(name))
|
|
16756
16867
|
continue;
|
|
16757
|
-
const skillDir =
|
|
16868
|
+
const skillDir = join33(root.path, name);
|
|
16758
16869
|
let st;
|
|
16759
16870
|
try {
|
|
16760
16871
|
st = statSync29(skillDir);
|
|
@@ -16763,12 +16874,12 @@ var init_skills_source = __esm({
|
|
|
16763
16874
|
}
|
|
16764
16875
|
if (!st.isDirectory())
|
|
16765
16876
|
continue;
|
|
16766
|
-
const skillMd =
|
|
16877
|
+
const skillMd = join33(skillDir, "SKILL.md");
|
|
16767
16878
|
if (!existsSync33(skillMd))
|
|
16768
16879
|
continue;
|
|
16769
16880
|
let content;
|
|
16770
16881
|
try {
|
|
16771
|
-
content =
|
|
16882
|
+
content = readFileSync24(skillMd, "utf-8");
|
|
16772
16883
|
} catch {
|
|
16773
16884
|
continue;
|
|
16774
16885
|
}
|
|
@@ -16782,7 +16893,7 @@ var init_skills_source = __esm({
|
|
|
16782
16893
|
const subdirs = {};
|
|
16783
16894
|
try {
|
|
16784
16895
|
for (const sub of readdirSync25(skillDir)) {
|
|
16785
|
-
const subPath =
|
|
16896
|
+
const subPath = join33(skillDir, sub);
|
|
16786
16897
|
try {
|
|
16787
16898
|
const ss = statSync29(subPath);
|
|
16788
16899
|
if (ss.isDirectory()) {
|
|
@@ -16831,7 +16942,7 @@ var init_skills_source = __esm({
|
|
|
16831
16942
|
async parse(item) {
|
|
16832
16943
|
if (!existsSync33(item.filePath))
|
|
16833
16944
|
return [];
|
|
16834
|
-
const content =
|
|
16945
|
+
const content = readFileSync24(item.filePath, "utf-8");
|
|
16835
16946
|
if (!content.trim())
|
|
16836
16947
|
return [];
|
|
16837
16948
|
return [{
|
|
@@ -16854,14 +16965,14 @@ var init_skills_source = __esm({
|
|
|
16854
16965
|
});
|
|
16855
16966
|
|
|
16856
16967
|
// ../engine/dist/parsers/mcps-source.js
|
|
16857
|
-
import { existsSync as existsSync34, readdirSync as readdirSync26, readFileSync as
|
|
16968
|
+
import { existsSync as existsSync34, readdirSync as readdirSync26, readFileSync as readFileSync25, statSync as statSync30 } from "fs";
|
|
16858
16969
|
import { homedir as homedir13 } from "os";
|
|
16859
|
-
import { join as
|
|
16970
|
+
import { join as join34 } from "path";
|
|
16860
16971
|
function readJson(path) {
|
|
16861
16972
|
if (!existsSync34(path))
|
|
16862
16973
|
return null;
|
|
16863
16974
|
try {
|
|
16864
|
-
const raw =
|
|
16975
|
+
const raw = readFileSync25(path, "utf-8");
|
|
16865
16976
|
const stripped = path.endsWith(".jsonc") ? raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1") : raw;
|
|
16866
16977
|
return JSON.parse(stripped);
|
|
16867
16978
|
} catch {
|
|
@@ -16922,23 +17033,23 @@ var init_mcps_source = __esm({
|
|
|
16922
17033
|
if (!isSourceEnabled("common", "mcps"))
|
|
16923
17034
|
return;
|
|
16924
17035
|
const home = homedir13();
|
|
16925
|
-
yield* this.fromObject(readJson(
|
|
17036
|
+
yield* this.fromObject(readJson(join34(home, ".mcp.json"))?.mcpServers, {
|
|
16926
17037
|
tool: "claude",
|
|
16927
|
-
filePath:
|
|
17038
|
+
filePath: join34(home, ".mcp.json"),
|
|
16928
17039
|
scope: "global"
|
|
16929
17040
|
});
|
|
16930
|
-
yield* this.fromObject(readJson(
|
|
17041
|
+
yield* this.fromObject(readJson(join34(home, ".claude.json"))?.mcpServers, {
|
|
16931
17042
|
tool: "claude",
|
|
16932
|
-
filePath:
|
|
17043
|
+
filePath: join34(home, ".claude.json"),
|
|
16933
17044
|
scope: "user"
|
|
16934
17045
|
});
|
|
16935
17046
|
for (const path of [
|
|
16936
|
-
|
|
16937
|
-
|
|
16938
|
-
|
|
16939
|
-
|
|
16940
|
-
|
|
16941
|
-
|
|
17047
|
+
join34(home, ".config", "opencode", "opencode.json"),
|
|
17048
|
+
join34(home, ".config", "opencode", "opencode.jsonc"),
|
|
17049
|
+
join34(home, ".config", "opencode", "config.json"),
|
|
17050
|
+
join34(home, ".opencode", "opencode.json"),
|
|
17051
|
+
join34(home, ".opencode", "opencode.jsonc"),
|
|
17052
|
+
join34(home, ".opencode", "config.json")
|
|
16942
17053
|
]) {
|
|
16943
17054
|
yield* this.fromObject(readJson(path)?.mcp, {
|
|
16944
17055
|
tool: "opencode",
|
|
@@ -16953,13 +17064,13 @@ var init_mcps_source = __esm({
|
|
|
16953
17064
|
filePath: geminiSettings,
|
|
16954
17065
|
scope: "user"
|
|
16955
17066
|
});
|
|
16956
|
-
const cursorMcp =
|
|
17067
|
+
const cursorMcp = join34(cursorHomeDir(), "mcp.json");
|
|
16957
17068
|
yield* this.fromObject(readJson(cursorMcp)?.mcpServers, {
|
|
16958
17069
|
tool: "cursor",
|
|
16959
17070
|
filePath: cursorMcp,
|
|
16960
17071
|
scope: "user"
|
|
16961
17072
|
});
|
|
16962
|
-
const agyMcp =
|
|
17073
|
+
const agyMcp = join34(home, ".gemini", "config", "mcp_config.json");
|
|
16963
17074
|
yield* this.fromObject(readJson(agyMcp)?.mcpServers, {
|
|
16964
17075
|
tool: "agy",
|
|
16965
17076
|
filePath: agyMcp,
|
|
@@ -16969,7 +17080,7 @@ var init_mcps_source = __esm({
|
|
|
16969
17080
|
const pluginsDir = codexBackend.pluginsDir();
|
|
16970
17081
|
if (existsSync34(pluginsDir)) {
|
|
16971
17082
|
for (const plugin of readdirSync26(pluginsDir)) {
|
|
16972
|
-
const mcpPath =
|
|
17083
|
+
const mcpPath = join34(pluginsDir, plugin, ".mcp.json");
|
|
16973
17084
|
yield* this.fromObject(readJson(mcpPath)?.mcpServers, {
|
|
16974
17085
|
tool: "codex",
|
|
16975
17086
|
filePath: mcpPath,
|
|
@@ -17023,7 +17134,7 @@ var init_mcps_source = __esm({
|
|
|
17023
17134
|
return;
|
|
17024
17135
|
let content;
|
|
17025
17136
|
try {
|
|
17026
|
-
content =
|
|
17137
|
+
content = readFileSync25(path, "utf-8");
|
|
17027
17138
|
} catch {
|
|
17028
17139
|
return;
|
|
17029
17140
|
}
|
|
@@ -17192,8 +17303,8 @@ var init_toolkit_format = __esm({
|
|
|
17192
17303
|
});
|
|
17193
17304
|
|
|
17194
17305
|
// ../engine/dist/parsers/slash-commands-source.js
|
|
17195
|
-
import { existsSync as existsSync35, readdirSync as readdirSync27, readFileSync as
|
|
17196
|
-
import { join as
|
|
17306
|
+
import { existsSync as existsSync35, readdirSync as readdirSync27, readFileSync as readFileSync26, statSync as statSync31 } from "fs";
|
|
17307
|
+
import { join as join35, basename as basename18 } from "path";
|
|
17197
17308
|
function rebuildBody2(content) {
|
|
17198
17309
|
const { text, redacted } = redactInlineSecrets(content);
|
|
17199
17310
|
const out = {};
|
|
@@ -17251,7 +17362,7 @@ var init_slash_commands_source = __esm({
|
|
|
17251
17362
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17252
17363
|
continue;
|
|
17253
17364
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17254
|
-
const cmdDir =
|
|
17365
|
+
const cmdDir = join35(projectPath, ".claude", "commands");
|
|
17255
17366
|
if (existsSync35(cmdDir))
|
|
17256
17367
|
roots.push({ path: cmdDir, tool: "claude", scope: "project", projectPath, format: "md" });
|
|
17257
17368
|
}
|
|
@@ -17260,7 +17371,7 @@ var init_slash_commands_source = __esm({
|
|
|
17260
17371
|
}
|
|
17261
17372
|
}
|
|
17262
17373
|
if (isSourceEnabled("agy", "commands")) {
|
|
17263
|
-
roots.push({ path:
|
|
17374
|
+
roots.push({ path: join35(agyBackend.homeDir(), "commands"), tool: "agy", scope: "user", projectPath: "", format: "toml" });
|
|
17264
17375
|
roots.push({ path: agyBackend.sharedCommandsDir(), tool: "agy", scope: "user", projectPath: "", format: "toml" });
|
|
17265
17376
|
}
|
|
17266
17377
|
if (isSourceEnabled("opencode", "commands")) {
|
|
@@ -17270,7 +17381,7 @@ var init_slash_commands_source = __esm({
|
|
|
17270
17381
|
roots.push({ path: codexBackend.promptsDir(), tool: "codex", scope: "user", projectPath: "", format: "md" });
|
|
17271
17382
|
}
|
|
17272
17383
|
if (isSourceEnabled("cursor", "commands")) {
|
|
17273
|
-
roots.push({ path:
|
|
17384
|
+
roots.push({ path: join35(cursorHomeDir(), "commands"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
|
|
17274
17385
|
}
|
|
17275
17386
|
return roots;
|
|
17276
17387
|
}
|
|
@@ -17284,10 +17395,10 @@ var init_slash_commands_source = __esm({
|
|
|
17284
17395
|
continue;
|
|
17285
17396
|
}
|
|
17286
17397
|
for (const file of files) {
|
|
17287
|
-
const filePath =
|
|
17398
|
+
const filePath = join35(root.path, file);
|
|
17288
17399
|
try {
|
|
17289
17400
|
const stat3 = statSync31(filePath);
|
|
17290
|
-
const content =
|
|
17401
|
+
const content = readFileSync26(filePath, "utf-8");
|
|
17291
17402
|
const parsed = parseCommand(content, basename18(file, ext), root.format);
|
|
17292
17403
|
yield {
|
|
17293
17404
|
id: `${root.tool}_cmd_${root.scope}_${parsed.name}`,
|
|
@@ -17316,7 +17427,7 @@ var init_slash_commands_source = __esm({
|
|
|
17316
17427
|
async parse(item) {
|
|
17317
17428
|
if (!existsSync35(item.filePath))
|
|
17318
17429
|
return [];
|
|
17319
|
-
const content =
|
|
17430
|
+
const content = readFileSync26(item.filePath, "utf-8");
|
|
17320
17431
|
if (!content.trim())
|
|
17321
17432
|
return [];
|
|
17322
17433
|
return [{
|
|
@@ -17339,8 +17450,8 @@ var init_slash_commands_source = __esm({
|
|
|
17339
17450
|
});
|
|
17340
17451
|
|
|
17341
17452
|
// ../engine/dist/parsers/subagents-source.js
|
|
17342
|
-
import { existsSync as existsSync36, readdirSync as readdirSync28, readFileSync as
|
|
17343
|
-
import { join as
|
|
17453
|
+
import { existsSync as existsSync36, readdirSync as readdirSync28, readFileSync as readFileSync27, statSync as statSync32 } from "fs";
|
|
17454
|
+
import { join as join36, basename as basename19 } from "path";
|
|
17344
17455
|
function rebuildBody3(content) {
|
|
17345
17456
|
const { text, redacted } = redactInlineSecrets(content);
|
|
17346
17457
|
const out = {};
|
|
@@ -17400,7 +17511,7 @@ var init_subagents_source = __esm({
|
|
|
17400
17511
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17401
17512
|
continue;
|
|
17402
17513
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17403
|
-
const agentDir =
|
|
17514
|
+
const agentDir = join36(projectPath, ".claude", "agents");
|
|
17404
17515
|
if (existsSync36(agentDir))
|
|
17405
17516
|
roots.push({ path: agentDir, tool: "claude", scope: "project", projectPath, format: "md" });
|
|
17406
17517
|
}
|
|
@@ -17409,7 +17520,7 @@ var init_subagents_source = __esm({
|
|
|
17409
17520
|
}
|
|
17410
17521
|
}
|
|
17411
17522
|
if (isSourceEnabled("agy", "agents")) {
|
|
17412
|
-
roots.push({ path:
|
|
17523
|
+
roots.push({ path: join36(agyBackend.homeDir(), "agents"), tool: "agy", scope: "user", projectPath: "", format: "md" });
|
|
17413
17524
|
roots.push({ path: agyBackend.sharedAgentsDir(), tool: "agy", scope: "user", projectPath: "", format: "md" });
|
|
17414
17525
|
}
|
|
17415
17526
|
if (isSourceEnabled("opencode", "agents")) {
|
|
@@ -17419,7 +17530,7 @@ var init_subagents_source = __esm({
|
|
|
17419
17530
|
roots.push({ path: codexBackend.agentsDir(), tool: "codex", scope: "user", projectPath: "", format: "toml" });
|
|
17420
17531
|
}
|
|
17421
17532
|
if (isSourceEnabled("cursor", "agents")) {
|
|
17422
|
-
roots.push({ path:
|
|
17533
|
+
roots.push({ path: join36(cursorHomeDir(), "agents"), tool: "cursor", scope: "user", projectPath: "", format: "md" });
|
|
17423
17534
|
}
|
|
17424
17535
|
return roots;
|
|
17425
17536
|
}
|
|
@@ -17433,10 +17544,10 @@ var init_subagents_source = __esm({
|
|
|
17433
17544
|
continue;
|
|
17434
17545
|
}
|
|
17435
17546
|
for (const file of files) {
|
|
17436
|
-
const filePath =
|
|
17547
|
+
const filePath = join36(root.path, file);
|
|
17437
17548
|
try {
|
|
17438
17549
|
const stat3 = statSync32(filePath);
|
|
17439
|
-
const content =
|
|
17550
|
+
const content = readFileSync27(filePath, "utf-8");
|
|
17440
17551
|
const parsed = parseAgent(content, basename19(file, ext), root.format);
|
|
17441
17552
|
yield {
|
|
17442
17553
|
id: `${root.tool}_agent_${root.scope}_${parsed.name}`,
|
|
@@ -17466,7 +17577,7 @@ var init_subagents_source = __esm({
|
|
|
17466
17577
|
async parse(item) {
|
|
17467
17578
|
if (!existsSync36(item.filePath))
|
|
17468
17579
|
return [];
|
|
17469
|
-
const content =
|
|
17580
|
+
const content = readFileSync27(item.filePath, "utf-8");
|
|
17470
17581
|
if (!content.trim())
|
|
17471
17582
|
return [];
|
|
17472
17583
|
return [{
|
|
@@ -17489,13 +17600,13 @@ var init_subagents_source = __esm({
|
|
|
17489
17600
|
});
|
|
17490
17601
|
|
|
17491
17602
|
// ../engine/dist/parsers/hooks-source.js
|
|
17492
|
-
import { existsSync as existsSync37, readFileSync as
|
|
17493
|
-
import { join as
|
|
17603
|
+
import { existsSync as existsSync37, readFileSync as readFileSync28, readdirSync as readdirSync29, statSync as statSync33 } from "fs";
|
|
17604
|
+
import { join as join37 } from "path";
|
|
17494
17605
|
function readJson2(path) {
|
|
17495
17606
|
if (!existsSync37(path))
|
|
17496
17607
|
return null;
|
|
17497
17608
|
try {
|
|
17498
|
-
return JSON.parse(
|
|
17609
|
+
return JSON.parse(readFileSync28(path, "utf-8"));
|
|
17499
17610
|
} catch {
|
|
17500
17611
|
return null;
|
|
17501
17612
|
}
|
|
@@ -17520,7 +17631,7 @@ var init_hooks_source = __esm({
|
|
|
17520
17631
|
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
17521
17632
|
continue;
|
|
17522
17633
|
const projectPath = resolveProjectDirName(entry.name);
|
|
17523
|
-
const settingsPath2 =
|
|
17634
|
+
const settingsPath2 = join37(projectPath, ".claude", "settings.json");
|
|
17524
17635
|
if (existsSync37(settingsPath2)) {
|
|
17525
17636
|
yield* this.fromSettings(settingsPath2, "project", projectPath);
|
|
17526
17637
|
}
|
|
@@ -17612,14 +17723,14 @@ var init_hooks_source = __esm({
|
|
|
17612
17723
|
});
|
|
17613
17724
|
|
|
17614
17725
|
// ../engine/dist/parsers/plugins-source.js
|
|
17615
|
-
import { existsSync as existsSync38, readFileSync as
|
|
17726
|
+
import { existsSync as existsSync38, readFileSync as readFileSync29, readdirSync as readdirSync30, statSync as statSync34 } from "fs";
|
|
17616
17727
|
import { homedir as homedir14 } from "os";
|
|
17617
|
-
import { join as
|
|
17728
|
+
import { join as join38 } from "path";
|
|
17618
17729
|
function readJson3(path) {
|
|
17619
17730
|
if (!existsSync38(path))
|
|
17620
17731
|
return null;
|
|
17621
17732
|
try {
|
|
17622
|
-
return JSON.parse(
|
|
17733
|
+
return JSON.parse(readFileSync29(path, "utf-8"));
|
|
17623
17734
|
} catch {
|
|
17624
17735
|
return null;
|
|
17625
17736
|
}
|
|
@@ -17679,7 +17790,7 @@ var init_plugins_source = __esm({
|
|
|
17679
17790
|
entries = [];
|
|
17680
17791
|
}
|
|
17681
17792
|
for (const name of entries) {
|
|
17682
|
-
const dir =
|
|
17793
|
+
const dir = join38(gemRoot, name);
|
|
17683
17794
|
let st;
|
|
17684
17795
|
try {
|
|
17685
17796
|
st = statSync34(dir);
|
|
@@ -17688,7 +17799,7 @@ var init_plugins_source = __esm({
|
|
|
17688
17799
|
}
|
|
17689
17800
|
if (!st.isDirectory())
|
|
17690
17801
|
continue;
|
|
17691
|
-
const manifestPath =
|
|
17802
|
+
const manifestPath = join38(dir, "gemini-extension.json");
|
|
17692
17803
|
const manifest = readJson3(manifestPath);
|
|
17693
17804
|
if (!manifest || typeof manifest !== "object")
|
|
17694
17805
|
continue;
|
|
@@ -17727,7 +17838,7 @@ var init_plugins_source = __esm({
|
|
|
17727
17838
|
entries = [];
|
|
17728
17839
|
}
|
|
17729
17840
|
for (const name of entries) {
|
|
17730
|
-
const pluginDir =
|
|
17841
|
+
const pluginDir = join38(codexPluginsRoot, name);
|
|
17731
17842
|
let st;
|
|
17732
17843
|
try {
|
|
17733
17844
|
st = statSync34(pluginDir);
|
|
@@ -17736,11 +17847,11 @@ var init_plugins_source = __esm({
|
|
|
17736
17847
|
}
|
|
17737
17848
|
if (!st.isDirectory())
|
|
17738
17849
|
continue;
|
|
17739
|
-
const appJson = readJson3(
|
|
17740
|
-
const pluginJson = readJson3(
|
|
17850
|
+
const appJson = readJson3(join38(pluginDir, ".codex-plugin", ".app.json"));
|
|
17851
|
+
const pluginJson = readJson3(join38(pluginDir, ".codex-plugin", "plugin.json"));
|
|
17741
17852
|
const manifest = pluginJson || appJson || {};
|
|
17742
17853
|
let mcpServers = [];
|
|
17743
|
-
const mcpJson = readJson3(
|
|
17854
|
+
const mcpJson = readJson3(join38(pluginDir, ".mcp.json"));
|
|
17744
17855
|
if (mcpJson?.mcpServers)
|
|
17745
17856
|
mcpServers = Object.keys(mcpJson.mcpServers);
|
|
17746
17857
|
yield {
|
|
@@ -17748,7 +17859,7 @@ var init_plugins_source = __esm({
|
|
|
17748
17859
|
sourceType: "plugin",
|
|
17749
17860
|
title: manifest.name || name,
|
|
17750
17861
|
projectPath: "",
|
|
17751
|
-
filePath:
|
|
17862
|
+
filePath: join38(pluginDir, ".codex-plugin"),
|
|
17752
17863
|
mtime: st.mtimeMs,
|
|
17753
17864
|
contentPreview: (manifest.description || "").slice(0, 300),
|
|
17754
17865
|
extra: {
|
|
@@ -17908,8 +18019,8 @@ __export(sync_ledger_exports, {
|
|
|
17908
18019
|
syncMode: () => syncMode,
|
|
17909
18020
|
unackedCursorAttemptCount: () => unackedCursorAttemptCount
|
|
17910
18021
|
});
|
|
17911
|
-
import { readFileSync as
|
|
17912
|
-
import { join as
|
|
18022
|
+
import { readFileSync as readFileSync30, writeFileSync as writeFileSync6, renameSync as renameSync4, mkdirSync as mkdirSync7 } from "node:fs";
|
|
18023
|
+
import { join as join39, dirname as dirname16 } from "node:path";
|
|
17913
18024
|
function toRow(entry) {
|
|
17914
18025
|
if (entry === void 0) return void 0;
|
|
17915
18026
|
return typeof entry === "number" ? { m: entry, v: 0 } : entry;
|
|
@@ -17920,7 +18031,7 @@ function ledgerFilePath() {
|
|
|
17920
18031
|
function load() {
|
|
17921
18032
|
if (cache3) return cache3;
|
|
17922
18033
|
try {
|
|
17923
|
-
const parsed = JSON.parse(
|
|
18034
|
+
const parsed = JSON.parse(readFileSync30(ledgerPath(), "utf-8"));
|
|
17924
18035
|
cache3 = parsed && typeof parsed === "object" ? parsed : {};
|
|
17925
18036
|
} catch {
|
|
17926
18037
|
cache3 = {};
|
|
@@ -17929,9 +18040,9 @@ function load() {
|
|
|
17929
18040
|
}
|
|
17930
18041
|
function persistNow(data) {
|
|
17931
18042
|
const path = ledgerPath();
|
|
17932
|
-
|
|
18043
|
+
mkdirSync7(dirname16(path), { recursive: true });
|
|
17933
18044
|
const tmp = `${path}.tmp`;
|
|
17934
|
-
|
|
18045
|
+
writeFileSync6(tmp, JSON.stringify(data));
|
|
17935
18046
|
renameSync4(tmp, path);
|
|
17936
18047
|
pendingWrite = false;
|
|
17937
18048
|
}
|
|
@@ -17966,10 +18077,10 @@ function pruneLedgerTargets(configuredServers) {
|
|
|
17966
18077
|
try {
|
|
17967
18078
|
let prior = {};
|
|
17968
18079
|
try {
|
|
17969
|
-
prior = JSON.parse(
|
|
18080
|
+
prior = JSON.parse(readFileSync30(side, "utf-8"));
|
|
17970
18081
|
} catch {
|
|
17971
18082
|
}
|
|
17972
|
-
|
|
18083
|
+
writeFileSync6(side, JSON.stringify({ ...prior, ...orphans }));
|
|
17973
18084
|
} catch {
|
|
17974
18085
|
for (const n of names) data[n] = orphans[n];
|
|
17975
18086
|
return 0;
|
|
@@ -17990,7 +18101,7 @@ function flushLedger() {
|
|
|
17990
18101
|
function loadItemVersionsAll() {
|
|
17991
18102
|
if (itemVersionsCache) return itemVersionsCache;
|
|
17992
18103
|
try {
|
|
17993
|
-
const parsed = JSON.parse(
|
|
18104
|
+
const parsed = JSON.parse(readFileSync30(itemVersionsPath(), "utf-8"));
|
|
17994
18105
|
itemVersionsCache = parsed && typeof parsed === "object" ? parsed : {};
|
|
17995
18106
|
} catch {
|
|
17996
18107
|
itemVersionsCache = {};
|
|
@@ -18004,9 +18115,9 @@ function saveItemVersions(server, versions) {
|
|
|
18004
18115
|
const all = loadItemVersionsAll();
|
|
18005
18116
|
all[server] = { ...all[server] || {}, ...versions };
|
|
18006
18117
|
const path = itemVersionsPath();
|
|
18007
|
-
|
|
18118
|
+
mkdirSync7(dirname16(path), { recursive: true });
|
|
18008
18119
|
const tmp = `${path}.tmp`;
|
|
18009
|
-
|
|
18120
|
+
writeFileSync6(tmp, JSON.stringify(all));
|
|
18010
18121
|
renameSync4(tmp, path);
|
|
18011
18122
|
}
|
|
18012
18123
|
function getSyncedMtimes(server) {
|
|
@@ -18084,7 +18195,7 @@ function markFieldCoverage(server, field, rows) {
|
|
|
18084
18195
|
function loadReconcile() {
|
|
18085
18196
|
if (reconcileCache) return reconcileCache;
|
|
18086
18197
|
try {
|
|
18087
|
-
const parsed = JSON.parse(
|
|
18198
|
+
const parsed = JSON.parse(readFileSync30(reconcilePath(), "utf-8"));
|
|
18088
18199
|
reconcileCache = parsed && typeof parsed === "object" ? parsed : {};
|
|
18089
18200
|
} catch {
|
|
18090
18201
|
reconcileCache = {};
|
|
@@ -18093,9 +18204,9 @@ function loadReconcile() {
|
|
|
18093
18204
|
}
|
|
18094
18205
|
function persistReconcile(data) {
|
|
18095
18206
|
const path = reconcilePath();
|
|
18096
|
-
|
|
18207
|
+
mkdirSync7(dirname16(path), { recursive: true });
|
|
18097
18208
|
const tmp = `${path}.tmp`;
|
|
18098
|
-
|
|
18209
|
+
writeFileSync6(tmp, JSON.stringify(data));
|
|
18099
18210
|
renameSync4(tmp, path);
|
|
18100
18211
|
}
|
|
18101
18212
|
function stateFor(server) {
|
|
@@ -18153,15 +18264,15 @@ var init_sync_ledger = __esm({
|
|
|
18153
18264
|
"use strict";
|
|
18154
18265
|
init_paths();
|
|
18155
18266
|
init_extractor_version();
|
|
18156
|
-
ledgerPath = () =>
|
|
18267
|
+
ledgerPath = () => join39(getDataDir(), "sync-ledger.json");
|
|
18157
18268
|
cache3 = null;
|
|
18158
18269
|
LEDGER_FLUSH_MS = 2e3;
|
|
18159
18270
|
pendingWrite = false;
|
|
18160
18271
|
flushTimer = null;
|
|
18161
|
-
itemVersionsPath = () =>
|
|
18272
|
+
itemVersionsPath = () => join39(getDataDir(), "item-versions.json");
|
|
18162
18273
|
itemVersionsCache = null;
|
|
18163
18274
|
unackedCursorAttempts = 0;
|
|
18164
|
-
reconcilePath = () =>
|
|
18275
|
+
reconcilePath = () => join39(getDataDir(), "sync-field-reconcile.json");
|
|
18165
18276
|
reconcileCache = null;
|
|
18166
18277
|
}
|
|
18167
18278
|
});
|
|
@@ -18192,11 +18303,11 @@ var init_sync_fields = __esm({
|
|
|
18192
18303
|
});
|
|
18193
18304
|
|
|
18194
18305
|
// ../engine/dist/core/index-lock.js
|
|
18195
|
-
import { existsSync as existsSync39, mkdirSync as
|
|
18196
|
-
import { dirname as
|
|
18306
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync8, openSync as openSync7, writeFileSync as writeFileSync7, readFileSync as readFileSync31, rmSync as rmSync4, statSync as statSync35, closeSync as closeSync7 } from "fs";
|
|
18307
|
+
import { dirname as dirname17, join as join40 } from "path";
|
|
18197
18308
|
function acquireIndexLock(opts) {
|
|
18198
18309
|
const lockPath = lockFilePath();
|
|
18199
|
-
|
|
18310
|
+
mkdirSync8(dirname17(lockPath), { recursive: true });
|
|
18200
18311
|
if (existsSync39(lockPath)) {
|
|
18201
18312
|
if (!stealStaleLock(lockPath, opts.staleAfterMs ?? 10 * 6e4)) {
|
|
18202
18313
|
return null;
|
|
@@ -18212,7 +18323,7 @@ function acquireIndexLock(opts) {
|
|
|
18212
18323
|
}
|
|
18213
18324
|
const holder = { pid: process.pid, kind: opts.kind, startedAt: Date.now() };
|
|
18214
18325
|
try {
|
|
18215
|
-
|
|
18326
|
+
writeFileSync7(fd, JSON.stringify(holder));
|
|
18216
18327
|
} finally {
|
|
18217
18328
|
closeSync7(fd);
|
|
18218
18329
|
}
|
|
@@ -18224,7 +18335,7 @@ function acquireIndexLock(opts) {
|
|
|
18224
18335
|
return;
|
|
18225
18336
|
released = true;
|
|
18226
18337
|
try {
|
|
18227
|
-
const current = JSON.parse(
|
|
18338
|
+
const current = JSON.parse(readFileSync31(lockPath, "utf-8"));
|
|
18228
18339
|
if (current.pid !== holder.pid || current.startedAt !== holder.startedAt)
|
|
18229
18340
|
return;
|
|
18230
18341
|
} catch {
|
|
@@ -18238,7 +18349,7 @@ function acquireIndexLock(opts) {
|
|
|
18238
18349
|
};
|
|
18239
18350
|
}
|
|
18240
18351
|
function lockFilePath() {
|
|
18241
|
-
return
|
|
18352
|
+
return join40(getIndexDir(), ".compact.lock");
|
|
18242
18353
|
}
|
|
18243
18354
|
function stealStaleLock(lockPath, staleAfterMs) {
|
|
18244
18355
|
try {
|
|
@@ -18246,7 +18357,7 @@ function stealStaleLock(lockPath, staleAfterMs) {
|
|
|
18246
18357
|
const age = Date.now() - s.mtimeMs;
|
|
18247
18358
|
let payload;
|
|
18248
18359
|
try {
|
|
18249
|
-
payload = JSON.parse(
|
|
18360
|
+
payload = JSON.parse(readFileSync31(lockPath, "utf-8"));
|
|
18250
18361
|
} catch {
|
|
18251
18362
|
rmSync4(lockPath, { force: true });
|
|
18252
18363
|
return true;
|
|
@@ -18284,7 +18395,7 @@ var init_index_lock = __esm({
|
|
|
18284
18395
|
});
|
|
18285
18396
|
|
|
18286
18397
|
// src/http.ts
|
|
18287
|
-
import { readFileSync as
|
|
18398
|
+
import { readFileSync as readFileSync32 } from "node:fs";
|
|
18288
18399
|
function clientHeaders() {
|
|
18289
18400
|
return {
|
|
18290
18401
|
"x-chat-recall-cli": CLI_VERSION,
|
|
@@ -18302,10 +18413,10 @@ var init_http = __esm({
|
|
|
18302
18413
|
"use strict";
|
|
18303
18414
|
CLI_VERSION = "0.0.0";
|
|
18304
18415
|
try {
|
|
18305
|
-
CLI_VERSION = JSON.parse(
|
|
18416
|
+
CLI_VERSION = JSON.parse(readFileSync32(new URL("../package.json", import.meta.url), "utf-8")).version || CLI_VERSION;
|
|
18306
18417
|
} catch {
|
|
18307
18418
|
try {
|
|
18308
|
-
if (true) CLI_VERSION = "0.6.
|
|
18419
|
+
if (true) CLI_VERSION = "0.6.9";
|
|
18309
18420
|
} catch {
|
|
18310
18421
|
}
|
|
18311
18422
|
}
|
|
@@ -18330,27 +18441,6 @@ var init_redact_deep = __esm({
|
|
|
18330
18441
|
}
|
|
18331
18442
|
});
|
|
18332
18443
|
|
|
18333
|
-
// ../engine/dist/core/session-multi-tool.js
|
|
18334
|
-
function extractTurnsAny(sessionId, opts = {}) {
|
|
18335
|
-
const backend = getBackendForId(sessionId);
|
|
18336
|
-
if (!backend)
|
|
18337
|
-
return { sessionId, found: false, turns: [], startMs: 0, endMs: 0 };
|
|
18338
|
-
return backend.extractTurns(sessionId, opts);
|
|
18339
|
-
}
|
|
18340
|
-
function replaySessionAny(sessionId) {
|
|
18341
|
-
const backend = getBackendForId(sessionId);
|
|
18342
|
-
if (!backend)
|
|
18343
|
-
return { sessionId, found: false, projectPath: "", files: [], totalLinesAdded: 0, totalLinesRemoved: 0 };
|
|
18344
|
-
return backend.replay(sessionId);
|
|
18345
|
-
}
|
|
18346
|
-
var init_session_multi_tool = __esm({
|
|
18347
|
-
"../engine/dist/core/session-multi-tool.js"() {
|
|
18348
|
-
"use strict";
|
|
18349
|
-
init_tool_backend();
|
|
18350
|
-
init_backends();
|
|
18351
|
-
}
|
|
18352
|
-
});
|
|
18353
|
-
|
|
18354
18444
|
// src/derived.ts
|
|
18355
18445
|
function collectDerivedRows(ref, mtime, count, maxRowBytes) {
|
|
18356
18446
|
const id = ref.prefixedId;
|
|
@@ -18821,7 +18911,7 @@ var init_telemetry = __esm({
|
|
|
18821
18911
|
init_sync_client();
|
|
18822
18912
|
cliVersion = () => {
|
|
18823
18913
|
try {
|
|
18824
|
-
return true ? "0.6.
|
|
18914
|
+
return true ? "0.6.9" : "dev";
|
|
18825
18915
|
} catch {
|
|
18826
18916
|
return "dev";
|
|
18827
18917
|
}
|
|
@@ -18831,60 +18921,6 @@ var init_telemetry = __esm({
|
|
|
18831
18921
|
}
|
|
18832
18922
|
});
|
|
18833
18923
|
|
|
18834
|
-
// ../engine/dist/core/collector-health.js
|
|
18835
|
-
import { readFileSync as readFileSync32, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8 } from "node:fs";
|
|
18836
|
-
import { join as join40, dirname as dirname17 } from "node:path";
|
|
18837
|
-
function collectorHealthPath() {
|
|
18838
|
-
return healthPath();
|
|
18839
|
-
}
|
|
18840
|
-
function readCollectorHealth() {
|
|
18841
|
-
try {
|
|
18842
|
-
const h = JSON.parse(readFileSync32(healthPath(), "utf-8"));
|
|
18843
|
-
return h && h.v === 1 && typeof h.updatedAt === "number" ? h : null;
|
|
18844
|
-
} catch {
|
|
18845
|
-
return null;
|
|
18846
|
-
}
|
|
18847
|
-
}
|
|
18848
|
-
function writeCollectorHealth(h) {
|
|
18849
|
-
try {
|
|
18850
|
-
const p = healthPath();
|
|
18851
|
-
mkdirSync8(dirname17(p), { recursive: true });
|
|
18852
|
-
writeFileSync7(p, JSON.stringify(h));
|
|
18853
|
-
} catch {
|
|
18854
|
-
}
|
|
18855
|
-
}
|
|
18856
|
-
function updateCollectorHealth(patch) {
|
|
18857
|
-
const prior = readCollectorHealth();
|
|
18858
|
-
writeCollectorHealth({
|
|
18859
|
-
...prior,
|
|
18860
|
-
v: 1,
|
|
18861
|
-
updatedAt: Date.now(),
|
|
18862
|
-
startedAt: prior?.startedAt ?? Date.now(),
|
|
18863
|
-
restartsLastHour: prior?.restartsLastHour ?? 0,
|
|
18864
|
-
targets: prior?.targets ?? {},
|
|
18865
|
-
...patch
|
|
18866
|
-
});
|
|
18867
|
-
}
|
|
18868
|
-
function reportWalkProgress(p) {
|
|
18869
|
-
const now = Date.now();
|
|
18870
|
-
const boundary = p.complete || p.done === 0;
|
|
18871
|
-
if (!boundary && now - lastProgressWrite < PROGRESS_WRITE_INTERVAL_MS)
|
|
18872
|
-
return;
|
|
18873
|
-
lastProgressWrite = now;
|
|
18874
|
-
updateCollectorHealth({ progress: p });
|
|
18875
|
-
}
|
|
18876
|
-
var healthPath, PROGRESS_WRITE_INTERVAL_MS, lastProgressWrite, STALE_AFTER_MS;
|
|
18877
|
-
var init_collector_health = __esm({
|
|
18878
|
-
"../engine/dist/core/collector-health.js"() {
|
|
18879
|
-
"use strict";
|
|
18880
|
-
init_paths();
|
|
18881
|
-
healthPath = () => join40(getDataDir(), "collector-health.json");
|
|
18882
|
-
PROGRESS_WRITE_INTERVAL_MS = 2e3;
|
|
18883
|
-
lastProgressWrite = 0;
|
|
18884
|
-
STALE_AFTER_MS = 30 * 6e4;
|
|
18885
|
-
}
|
|
18886
|
-
});
|
|
18887
|
-
|
|
18888
18924
|
// src/server-probe.ts
|
|
18889
18925
|
var server_probe_exports = {};
|
|
18890
18926
|
__export(server_probe_exports, {
|
|
@@ -19571,10 +19607,11 @@ async function syncSessions(opts = {}) {
|
|
|
19571
19607
|
};
|
|
19572
19608
|
continue;
|
|
19573
19609
|
}
|
|
19610
|
+
acceptedUploads.set(cred.serverUrl, 0);
|
|
19574
19611
|
try {
|
|
19575
19612
|
const r = await syncToTarget(cred, opts);
|
|
19576
19613
|
noteTargetSuccess(cred.serverUrl);
|
|
19577
|
-
perTarget[cred.serverUrl] = { ok: true };
|
|
19614
|
+
perTarget[cred.serverUrl] = { ok: true, accepted: acceptedUploads.get(cred.serverUrl) ?? 0 };
|
|
19578
19615
|
agg = agg ? {
|
|
19579
19616
|
uploaded: agg.uploaded + r.uploaded,
|
|
19580
19617
|
skipped: agg.skipped + r.skipped,
|
|
@@ -19591,7 +19628,7 @@ async function syncSessions(opts = {}) {
|
|
|
19591
19628
|
} catch (e) {
|
|
19592
19629
|
const msg = e instanceof Error ? e.message : String(e);
|
|
19593
19630
|
errors.push(`${cred.serverUrl}: ${msg}`);
|
|
19594
|
-
perTarget[cred.serverUrl] = { ok: false, error: msg };
|
|
19631
|
+
perTarget[cred.serverUrl] = { ok: false, error: msg, accepted: acceptedUploads.get(cred.serverUrl) ?? 0 };
|
|
19595
19632
|
const next = noteTargetFailure(cred.serverUrl, msg);
|
|
19596
19633
|
const notice = breakerNotice(cred.serverUrl, next);
|
|
19597
19634
|
if (notice) console.error(`[sync] ${notice}`);
|
|
@@ -19830,7 +19867,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
19830
19867
|
return [];
|
|
19831
19868
|
}
|
|
19832
19869
|
});
|
|
19833
|
-
const MAX_BATCH_BYTES = 4 * 1024 * 1024;
|
|
19870
|
+
const MAX_BATCH_BYTES = Number(process.env.CHAT_RECALL_MAX_BATCH_BYTES) || (isLocalHost(cred.serverUrl) ? 4 * 1024 * 1024 : 1024 * 1024);
|
|
19834
19871
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
19835
19872
|
const explicitThrottle = typeof opts.throttleMs === "number" && opts.throttleMs > 0;
|
|
19836
19873
|
const throttleMs = explicitThrottle ? opts.throttleMs : 0;
|
|
@@ -19865,6 +19902,7 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
19865
19902
|
signal: ac.signal
|
|
19866
19903
|
});
|
|
19867
19904
|
if (res.ok) {
|
|
19905
|
+
acceptedUploads.set(cred.serverUrl, (acceptedUploads.get(cred.serverUrl) ?? 0) + 1);
|
|
19868
19906
|
const body2 = await res.json().catch(() => ({}));
|
|
19869
19907
|
if (typeof body2.telemetry === "boolean") {
|
|
19870
19908
|
setTelemetryEligible(base2, body2.telemetry);
|
|
@@ -19915,7 +19953,8 @@ async function syncToTargetInScope(cred, opts = {}) {
|
|
|
19915
19953
|
if (attempt >= RETRY_DELAYS_MS.length) throw new Error(`sync failed after ${attempt + 1} attempts: HTTP ${res.status} ${text}`);
|
|
19916
19954
|
const retryAfterS = Number(res.headers.get("retry-after"));
|
|
19917
19955
|
const waitMs = res.status === 429 && retryAfterS > 0 ? retryAfterS * 1e3 : RETRY_DELAYS_MS[attempt];
|
|
19918
|
-
|
|
19956
|
+
const why = res.status === 524 ? ` \u2014 the proxy cut the request at its time limit; the batch is too big for one request` : "";
|
|
19957
|
+
console.error(`[sync] HTTP ${res.status} from ${base2}${why} \u2014 backing off ${Math.round(waitMs / 1e3)}s (attempt ${attempt + 1})`);
|
|
19919
19958
|
await sleep(waitMs);
|
|
19920
19959
|
continue;
|
|
19921
19960
|
} catch (err) {
|
|
@@ -20774,7 +20813,7 @@ async function syncIncremental(opts = {}) {
|
|
|
20774
20813
|
lock.release();
|
|
20775
20814
|
}
|
|
20776
20815
|
}
|
|
20777
|
-
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, SYNC_RULES_REFUSAL, hashPath, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, FULL_BUILD_TAIL_BYTES, BATCH_SCAN_MAX_BYTES;
|
|
20816
|
+
var ownVersion, ERROR_CLASS, STANDING_FAILURE, walkProgressForUpload, lastServerPackSpec, credPath, _securityConfigCache, SECURITY_CONFIG_TTL_MS, _syncConfigCache, EMPTY_SYNC_CONFIG, SYNC_RULES_REFUSAL, hashPath, acceptedUploads, MAX_DERIVED_ROW_BYTES, isLocalHost, CAPS_TTL_MS, capsOk, advertisedIngestConc, advertisedGzipBody, FULL_BUILD_MAX_BYTES, FULL_BUILD_TAIL_BYTES, BATCH_SCAN_MAX_BYTES;
|
|
20778
20817
|
var init_sync_client = __esm({
|
|
20779
20818
|
"src/sync-client.ts"() {
|
|
20780
20819
|
"use strict";
|
|
@@ -20819,7 +20858,7 @@ var init_sync_client = __esm({
|
|
|
20819
20858
|
ownVersion = JSON.parse(readFileSync35(join42(dir, "../package.json"), "utf-8")).version || ownVersion;
|
|
20820
20859
|
} catch {
|
|
20821
20860
|
try {
|
|
20822
|
-
if (true) ownVersion = "0.6.
|
|
20861
|
+
if (true) ownVersion = "0.6.9";
|
|
20823
20862
|
} catch {
|
|
20824
20863
|
}
|
|
20825
20864
|
}
|
|
@@ -20838,6 +20877,7 @@ var init_sync_client = __esm({
|
|
|
20838
20877
|
EMPTY_SYNC_CONFIG = { excludeTools: [], excludeProjects: [], excludeSources: [], approveSources: [] };
|
|
20839
20878
|
SYNC_RULES_REFUSAL = /* @__PURE__ */ Symbol.for("chat-recall.syncRulesRefusal");
|
|
20840
20879
|
hashPath = (p) => p ? "p_" + createHash8("sha256").update(p).digest("hex").slice(0, 12) : "";
|
|
20880
|
+
acceptedUploads = /* @__PURE__ */ new Map();
|
|
20841
20881
|
MAX_DERIVED_ROW_BYTES = 2 * 1024 * 1024;
|
|
20842
20882
|
isLocalHost = isPrivateHost;
|
|
20843
20883
|
CAPS_TTL_MS = 60 * 6e4;
|
|
@@ -23582,6 +23622,7 @@ var init_service_installer = __esm({
|
|
|
23582
23622
|
// auto-indexer/indexer.ts
|
|
23583
23623
|
init_backends();
|
|
23584
23624
|
init_paths();
|
|
23625
|
+
init_collector_health();
|
|
23585
23626
|
init_settings();
|
|
23586
23627
|
init_sync_client();
|
|
23587
23628
|
init_http();
|
|
@@ -23903,7 +23944,7 @@ try {
|
|
|
23903
23944
|
ownVersion2 = JSON.parse(readFileSync39(join48(dir, "../package.json"), "utf-8")).version || ownVersion2;
|
|
23904
23945
|
} catch {
|
|
23905
23946
|
try {
|
|
23906
|
-
if (true) ownVersion2 = "0.6.
|
|
23947
|
+
if (true) ownVersion2 = "0.6.9";
|
|
23907
23948
|
} catch {
|
|
23908
23949
|
}
|
|
23909
23950
|
}
|
|
@@ -24251,7 +24292,7 @@ async function runCollectorMigration(opts) {
|
|
|
24251
24292
|
init_sync_ledger();
|
|
24252
24293
|
init_collector_health();
|
|
24253
24294
|
import { existsSync as existsSync49, readFileSync as readFileSync45, statSync as statSync44 } from "fs";
|
|
24254
|
-
var CLI_VERSION3 = true ? "0.6.
|
|
24295
|
+
var CLI_VERSION3 = true ? "0.6.9" : "0.0.0";
|
|
24255
24296
|
var DEBOUNCE_MS = 5e3;
|
|
24256
24297
|
var CLAUDE_DIR = claudeBackend.projectsDir();
|
|
24257
24298
|
var PLANS_DIR = claudeBackend.plansDir();
|
|
@@ -24288,7 +24329,7 @@ async function shipToServer(trigger) {
|
|
|
24288
24329
|
);
|
|
24289
24330
|
}
|
|
24290
24331
|
for (const [server, outcome] of Object.entries(result.perTarget ?? {})) {
|
|
24291
|
-
noteSyncOutcome(server, outcome.ok, outcome.error);
|
|
24332
|
+
noteSyncOutcome(server, outcome.ok, outcome.error, outcome.accepted ?? 0);
|
|
24292
24333
|
}
|
|
24293
24334
|
} catch (err) {
|
|
24294
24335
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -24556,6 +24597,9 @@ setTimeout(() => {
|
|
|
24556
24597
|
setInterval(() => {
|
|
24557
24598
|
ticks.request("housekeeping", TICK_PRIORITY.housekeeping, shadowPruneTick);
|
|
24558
24599
|
}, SHADOW_PRUNE_MS).unref();
|
|
24600
|
+
function _targetHealth() {
|
|
24601
|
+
return targetHealth;
|
|
24602
|
+
}
|
|
24559
24603
|
function syncTargetUrls() {
|
|
24560
24604
|
try {
|
|
24561
24605
|
return loadAllCredentials().map((c) => c.serverUrl);
|
|
@@ -24563,17 +24607,8 @@ function syncTargetUrls() {
|
|
|
24563
24607
|
return [];
|
|
24564
24608
|
}
|
|
24565
24609
|
}
|
|
24566
|
-
function noteSyncOutcome(server, ok, err) {
|
|
24567
|
-
|
|
24568
|
-
if (ok) {
|
|
24569
|
-
t.lastOkAt = Date.now();
|
|
24570
|
-
t.failures = 0;
|
|
24571
|
-
delete t.lastError;
|
|
24572
|
-
} else {
|
|
24573
|
-
t.failures += 1;
|
|
24574
|
-
t.lastError = (err ?? "unknown error").slice(0, 160);
|
|
24575
|
-
}
|
|
24576
|
-
targetHealth[server] = t;
|
|
24610
|
+
function noteSyncOutcome(server, ok, err, accepted = 0) {
|
|
24611
|
+
targetHealth[server] = applySyncOutcome(targetHealth[server], { ok, accepted, error: err });
|
|
24577
24612
|
publishHealth();
|
|
24578
24613
|
}
|
|
24579
24614
|
publishHealth();
|
|
@@ -24834,3 +24869,7 @@ process.on("exit", () => {
|
|
|
24834
24869
|
} catch {
|
|
24835
24870
|
}
|
|
24836
24871
|
});
|
|
24872
|
+
export {
|
|
24873
|
+
_targetHealth,
|
|
24874
|
+
noteSyncOutcome
|
|
24875
|
+
};
|