token-goat 2.6.11 → 2.6.12
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/token-goat.mjs +231 -84
- package/package.json +1 -1
package/dist/token-goat.mjs
CHANGED
|
@@ -130752,7 +130752,7 @@ var init_cliui = __esm({
|
|
|
130752
130752
|
|
|
130753
130753
|
// node_modules/escalade/sync/index.mjs
|
|
130754
130754
|
import { dirname as dirname18, resolve as resolve11 } from "path";
|
|
130755
|
-
import { readdirSync as
|
|
130755
|
+
import { readdirSync as readdirSync9, statSync as statSync19 } from "fs";
|
|
130756
130756
|
function sync_default(start, callback) {
|
|
130757
130757
|
let dir = resolve11(".", start);
|
|
130758
130758
|
let tmp, stats = statSync19(dir);
|
|
@@ -130760,7 +130760,7 @@ function sync_default(start, callback) {
|
|
|
130760
130760
|
dir = dirname18(dir);
|
|
130761
130761
|
}
|
|
130762
130762
|
while (true) {
|
|
130763
|
-
tmp = callback(dir,
|
|
130763
|
+
tmp = callback(dir, readdirSync9(dir));
|
|
130764
130764
|
if (tmp) return resolve11(dir, tmp);
|
|
130765
130765
|
dir = dirname18(tmp = dir);
|
|
130766
130766
|
if (tmp === dir) break;
|
|
@@ -178698,7 +178698,7 @@ init_define_import_meta_env();
|
|
|
178698
178698
|
import { createRequire } from "node:module";
|
|
178699
178699
|
function resolveVersion() {
|
|
178700
178700
|
if (true) {
|
|
178701
|
-
return "2.6.
|
|
178701
|
+
return "2.6.12";
|
|
178702
178702
|
}
|
|
178703
178703
|
const require3 = createRequire(import.meta.url);
|
|
178704
178704
|
const pkg = require3("../package.json");
|
|
@@ -183058,6 +183058,21 @@ const FILE_PATH_ARG_KEY = {
|
|
|
183058
183058
|
create: 'path',
|
|
183059
183059
|
}
|
|
183060
183060
|
|
|
183061
|
+
// Copilot spawns a brand-new process for every single hook invocation (no long-lived plugin
|
|
183062
|
+
// process the way OpenClaw's is -- OPENCLAW_HOOK_SCRIPT's own \`copilot-\${process.pid}-\${Date.now()}\`
|
|
183063
|
+
// fallback is safe there specifically because that process lives for the whole session, so the
|
|
183064
|
+
// pid stays constant across calls). If Copilot ever omits \`sessionId\` from a payload, falling
|
|
183065
|
+
// back to \`process.pid\` here would mint a DIFFERENT id on every single call for what's really
|
|
183066
|
+
// the same session, since process.pid varies per invocation -- breaking token-goat's
|
|
183067
|
+
// session-based dedup/state ledger, which never accumulates across calls as a result. Derive a
|
|
183068
|
+
// stable id instead from the one thing that's actually constant across calls for the same
|
|
183069
|
+
// session: the working directory Copilot reports in \`payload.cwd\`.
|
|
183070
|
+
function stableFallbackSessionId(cwd) {
|
|
183071
|
+
const key = typeof cwd === 'string' && cwd ? cwd : process.cwd()
|
|
183072
|
+
const hash = require('node:crypto').createHash('sha256').update(key).digest('hex').slice(0, 16)
|
|
183073
|
+
return 'copilot-' + hash
|
|
183074
|
+
}
|
|
183075
|
+
|
|
183061
183076
|
function remapToolInput(copilotToolName, input) {
|
|
183062
183077
|
const pathKey = FILE_PATH_ARG_KEY[copilotToolName]
|
|
183063
183078
|
if (pathKey === undefined || !input || typeof input !== 'object' || !(pathKey in input)) {
|
|
@@ -183100,7 +183115,7 @@ function main() {
|
|
|
183100
183115
|
|
|
183101
183116
|
const toolName = payload && payload.toolName
|
|
183102
183117
|
const canonical = {
|
|
183103
|
-
session_id: (payload && payload.sessionId) ||
|
|
183118
|
+
session_id: (payload && payload.sessionId) || stableFallbackSessionId(payload && payload.cwd),
|
|
183104
183119
|
cwd: payload && payload.cwd,
|
|
183105
183120
|
}
|
|
183106
183121
|
if (toolName) {
|
|
@@ -183757,6 +183772,7 @@ registerReset(() => {
|
|
|
183757
183772
|
var SAFE_RE = /[^a-zA-Z0-9_-]/g;
|
|
183758
183773
|
var MAX_FILES = 500;
|
|
183759
183774
|
var SESSIONS_SUBDIR = "sessions";
|
|
183775
|
+
var AGENT_SALT_MARKER = ":agent:".replace(SAFE_RE, "_");
|
|
183760
183776
|
function sessionPath(sessionId) {
|
|
183761
183777
|
if (!sessionId) return null;
|
|
183762
183778
|
const safe = sessionId.replace(SAFE_RE, "_").slice(0, 64);
|
|
@@ -183945,6 +183961,25 @@ function readSessionStateFile(sessionId) {
|
|
|
183945
183961
|
if (!p) return null;
|
|
183946
183962
|
return readDiskState(p);
|
|
183947
183963
|
}
|
|
183964
|
+
function listSiblingSessionStates(sessionId) {
|
|
183965
|
+
if (!sessionId) return [];
|
|
183966
|
+
const safeSessionId = sessionId.replace(SAFE_RE, "_");
|
|
183967
|
+
if (!safeSessionId) return [];
|
|
183968
|
+
const prefix = `${safeSessionId}${AGENT_SALT_MARKER}`;
|
|
183969
|
+
const dir = path12.join(tokenGoatHome(), SESSIONS_SUBDIR);
|
|
183970
|
+
const out2 = [];
|
|
183971
|
+
try {
|
|
183972
|
+
if (!fs10.existsSync(dir)) return out2;
|
|
183973
|
+
for (const file2 of fs10.readdirSync(dir)) {
|
|
183974
|
+
if (!file2.endsWith(".json") || !file2.startsWith(prefix)) continue;
|
|
183975
|
+
const state = readDiskState(path12.join(dir, file2));
|
|
183976
|
+
if (state !== null) out2.push(state);
|
|
183977
|
+
}
|
|
183978
|
+
} catch {
|
|
183979
|
+
return out2;
|
|
183980
|
+
}
|
|
183981
|
+
return out2;
|
|
183982
|
+
}
|
|
183948
183983
|
function loadSessionState(sessionId) {
|
|
183949
183984
|
const p = sessionPath(sessionId);
|
|
183950
183985
|
if (!p) return;
|
|
@@ -184189,7 +184224,7 @@ function findLatestSessionId() {
|
|
|
184189
184224
|
return null;
|
|
184190
184225
|
}
|
|
184191
184226
|
const files = fs11.readdirSync(sessionsDir);
|
|
184192
|
-
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
184227
|
+
const jsonFiles = files.filter((f) => f.endsWith(".json") && !f.includes(AGENT_SALT_MARKER));
|
|
184193
184228
|
if (jsonFiles.length === 0) {
|
|
184194
184229
|
return null;
|
|
184195
184230
|
}
|
|
@@ -184843,7 +184878,7 @@ function rerankHits(hits, query, topK) {
|
|
|
184843
184878
|
return { hit, index, adjusted: hit.distance - boost + penalty };
|
|
184844
184879
|
});
|
|
184845
184880
|
scored.sort((a, b) => a.adjusted - b.adjusted || a.index - b.index);
|
|
184846
|
-
return scored.slice(0, topK).map((entry) => entry.hit);
|
|
184881
|
+
return scored.slice(0, topK).map((entry) => ({ ...entry.hit, adjustedDistance: entry.adjusted }));
|
|
184847
184882
|
}
|
|
184848
184883
|
function mergeNearbyHits(hits, proximity = 20) {
|
|
184849
184884
|
if (hits.length <= 1) {
|
|
@@ -184868,6 +184903,7 @@ function mergeNearbyHits(hits, proximity = 20) {
|
|
|
184868
184903
|
let curStart = current.startLine;
|
|
184869
184904
|
let curEnd = current.endLine;
|
|
184870
184905
|
let curDist = current.distance;
|
|
184906
|
+
let curAdjusted = current.adjustedDistance ?? current.distance;
|
|
184871
184907
|
const mergedTexts = [current.text];
|
|
184872
184908
|
for (let i = 1; i < fileHits.length; i++) {
|
|
184873
184909
|
const hit = fileHits[i];
|
|
@@ -184878,6 +184914,7 @@ function mergeNearbyHits(hits, proximity = 20) {
|
|
|
184878
184914
|
if (gap <= proximity) {
|
|
184879
184915
|
curEnd = Math.max(curEnd, hit.endLine);
|
|
184880
184916
|
curDist = Math.min(curDist, hit.distance);
|
|
184917
|
+
curAdjusted = Math.min(curAdjusted, hit.adjustedDistance ?? hit.distance);
|
|
184881
184918
|
mergedTexts.push(hit.text);
|
|
184882
184919
|
} else {
|
|
184883
184920
|
merged.push({
|
|
@@ -184886,12 +184923,14 @@ function mergeNearbyHits(hits, proximity = 20) {
|
|
|
184886
184923
|
endLine: curEnd,
|
|
184887
184924
|
kind: current.kind,
|
|
184888
184925
|
distance: curDist,
|
|
184926
|
+
adjustedDistance: curAdjusted,
|
|
184889
184927
|
text: mergedTexts.join("\n---\n")
|
|
184890
184928
|
});
|
|
184891
184929
|
current = hit;
|
|
184892
184930
|
curStart = hit.startLine;
|
|
184893
184931
|
curEnd = hit.endLine;
|
|
184894
184932
|
curDist = hit.distance;
|
|
184933
|
+
curAdjusted = hit.adjustedDistance ?? hit.distance;
|
|
184895
184934
|
mergedTexts.length = 0;
|
|
184896
184935
|
mergedTexts.push(hit.text);
|
|
184897
184936
|
}
|
|
@@ -184902,10 +184941,11 @@ function mergeNearbyHits(hits, proximity = 20) {
|
|
|
184902
184941
|
endLine: curEnd,
|
|
184903
184942
|
kind: current.kind,
|
|
184904
184943
|
distance: curDist,
|
|
184944
|
+
adjustedDistance: curAdjusted,
|
|
184905
184945
|
text: mergedTexts.join("\n---\n")
|
|
184906
184946
|
});
|
|
184907
184947
|
}
|
|
184908
|
-
merged.sort((a, b) => a.distance - b.distance);
|
|
184948
|
+
merged.sort((a, b) => (a.adjustedDistance ?? a.distance) - (b.adjustedDistance ?? b.distance));
|
|
184909
184949
|
return merged;
|
|
184910
184950
|
}
|
|
184911
184951
|
async function indexFile(db, filePath, content, boundaries = []) {
|
|
@@ -185271,8 +185311,10 @@ function findMultilineCloser(line, from2, state) {
|
|
|
185271
185311
|
return m ? { maskEnd: m[0].length } : null;
|
|
185272
185312
|
}
|
|
185273
185313
|
case "tripleQuote": {
|
|
185274
|
-
const
|
|
185275
|
-
|
|
185314
|
+
const n = state.identifier !== "" ? parseInt(state.identifier, 10) : 3;
|
|
185315
|
+
const re = new RegExp(`"{${n},}`);
|
|
185316
|
+
const m = re.exec(line.slice(from2));
|
|
185317
|
+
return m === null ? null : { maskEnd: from2 + m.index + m[0].length };
|
|
185276
185318
|
}
|
|
185277
185319
|
case "verbatim": {
|
|
185278
185320
|
let j = from2;
|
|
@@ -185308,15 +185350,20 @@ function findMultilineOpener(line, from2, lang) {
|
|
|
185308
185350
|
}
|
|
185309
185351
|
if (lang === "kotlin") {
|
|
185310
185352
|
const idx = line.indexOf('"""', from2);
|
|
185311
|
-
if (idx === -1) return null;
|
|
185353
|
+
if (idx === -1 || isInsideStringLiteral(line, idx)) return null;
|
|
185312
185354
|
const closeIdx = line.indexOf('"""', idx + 3);
|
|
185313
185355
|
if (closeIdx !== -1) {
|
|
185314
|
-
return { openStart: idx, closesSameLine: closeIdx + 3, state: { kind: "tripleQuote", identifier: "" } };
|
|
185356
|
+
return { openStart: idx, closesSameLine: closeIdx + 3, state: { kind: "tripleQuote", identifier: "3" } };
|
|
185315
185357
|
}
|
|
185316
|
-
return { openStart: idx, closesSameLine: null, state: { kind: "tripleQuote", identifier: "" } };
|
|
185358
|
+
return { openStart: idx, closesSameLine: null, state: { kind: "tripleQuote", identifier: "3" } };
|
|
185317
185359
|
}
|
|
185318
185360
|
if (lang === "csharp") {
|
|
185319
|
-
const
|
|
185361
|
+
const tripleRe = /"{3,}/g;
|
|
185362
|
+
tripleRe.lastIndex = from2;
|
|
185363
|
+
const tripleM = tripleRe.exec(line);
|
|
185364
|
+
let tripleIdx = tripleM ? tripleM.index : -1;
|
|
185365
|
+
const tripleLen = tripleM ? tripleM[0].length : 0;
|
|
185366
|
+
if (tripleIdx !== -1 && isInsideStringLiteral(line, tripleIdx)) tripleIdx = -1;
|
|
185320
185367
|
const verbRe = /\$?@\$?"/g;
|
|
185321
185368
|
verbRe.lastIndex = from2;
|
|
185322
185369
|
const verbM = verbRe.exec(line);
|
|
@@ -185324,11 +185371,13 @@ function findMultilineOpener(line, from2, lang) {
|
|
|
185324
185371
|
if (tripleIdx === -1 && verbIdx === -1) return null;
|
|
185325
185372
|
const useTriple = tripleIdx !== -1 && (verbIdx === -1 || tripleIdx < verbIdx);
|
|
185326
185373
|
if (useTriple) {
|
|
185327
|
-
const
|
|
185328
|
-
|
|
185329
|
-
|
|
185374
|
+
const closeRe = new RegExp(`"{${tripleLen},}`);
|
|
185375
|
+
const closeM = closeRe.exec(line.slice(tripleIdx + tripleLen));
|
|
185376
|
+
if (closeM !== null) {
|
|
185377
|
+
const closeIdx = tripleIdx + tripleLen + closeM.index;
|
|
185378
|
+
return { openStart: tripleIdx, closesSameLine: closeIdx + closeM[0].length, state: { kind: "tripleQuote", identifier: String(tripleLen) } };
|
|
185330
185379
|
}
|
|
185331
|
-
return { openStart: tripleIdx, closesSameLine: null, state: { kind: "tripleQuote", identifier:
|
|
185380
|
+
return { openStart: tripleIdx, closesSameLine: null, state: { kind: "tripleQuote", identifier: String(tripleLen) } };
|
|
185332
185381
|
}
|
|
185333
185382
|
const quoteIdx = verbIdx + (verbM?.[0].length ?? 1) - 1;
|
|
185334
185383
|
const closer = findMultilineCloser(line, quoteIdx + 1, { kind: "verbatim", identifier: "" });
|
|
@@ -186009,6 +186058,16 @@ var KIND_MAP = /* @__PURE__ */ new Map([
|
|
|
186009
186058
|
]);
|
|
186010
186059
|
var MAX_SYMBOLS = 500;
|
|
186011
186060
|
var MAX_HEADING_LEN = 120;
|
|
186061
|
+
function stripGraphqlDescriptions(text) {
|
|
186062
|
+
let state = null;
|
|
186063
|
+
const outLines = [];
|
|
186064
|
+
for (const line of text.split("\n")) {
|
|
186065
|
+
const { code, state: nextState } = stripMultilineStringSpan(line, state, "kotlin");
|
|
186066
|
+
state = nextState;
|
|
186067
|
+
outLines.push(stripStringLiterals(code));
|
|
186068
|
+
}
|
|
186069
|
+
return outLines.join("\n");
|
|
186070
|
+
}
|
|
186012
186071
|
function extractGraphql(content, filePath) {
|
|
186013
186072
|
const symbols = [];
|
|
186014
186073
|
const sections = [];
|
|
@@ -186022,7 +186081,7 @@ function extractGraphql(content, filePath) {
|
|
|
186022
186081
|
imports.push({ kind: "import", target, line });
|
|
186023
186082
|
}
|
|
186024
186083
|
}
|
|
186025
|
-
const stripped = stripHashComments(content);
|
|
186084
|
+
const stripped = stripGraphqlDescriptions(stripHashComments(content));
|
|
186026
186085
|
const totalLines = content.split("\n").length;
|
|
186027
186086
|
for (const m of stripped.matchAll(TYPE_RE)) {
|
|
186028
186087
|
const keyword = m.groups?.["keyword"] ?? "";
|
|
@@ -186102,6 +186161,37 @@ var PATTERNS = [
|
|
|
186102
186161
|
[TYPE_RE2, "sql_type"],
|
|
186103
186162
|
[SCHEMA_RE3, "sql_schema"]
|
|
186104
186163
|
];
|
|
186164
|
+
function stripSqlStringLiterals(text) {
|
|
186165
|
+
let out2 = "";
|
|
186166
|
+
let i = 0;
|
|
186167
|
+
while (i < text.length) {
|
|
186168
|
+
const ch2 = text[i];
|
|
186169
|
+
if (ch2 === "'") {
|
|
186170
|
+
const quote = ch2;
|
|
186171
|
+
out2 += quote;
|
|
186172
|
+
i++;
|
|
186173
|
+
while (i < text.length) {
|
|
186174
|
+
const c = text[i];
|
|
186175
|
+
if (c === quote) {
|
|
186176
|
+
if (text[i + 1] === quote) {
|
|
186177
|
+
out2 += " ";
|
|
186178
|
+
i += 2;
|
|
186179
|
+
continue;
|
|
186180
|
+
}
|
|
186181
|
+
out2 += quote;
|
|
186182
|
+
i++;
|
|
186183
|
+
break;
|
|
186184
|
+
}
|
|
186185
|
+
out2 += c === "\n" ? "\n" : " ";
|
|
186186
|
+
i++;
|
|
186187
|
+
}
|
|
186188
|
+
continue;
|
|
186189
|
+
}
|
|
186190
|
+
out2 += ch2;
|
|
186191
|
+
i++;
|
|
186192
|
+
}
|
|
186193
|
+
return out2;
|
|
186194
|
+
}
|
|
186105
186195
|
function unquote(name2) {
|
|
186106
186196
|
if (name2.length >= 2 && (name2[0] === '"' && name2[name2.length - 1] === '"' || name2[0] === "`" && name2[name2.length - 1] === "`" || name2[0] === "[" && name2[name2.length - 1] === "]")) {
|
|
186107
186197
|
return name2.slice(1, -1);
|
|
@@ -186116,9 +186206,10 @@ function extractSql(content, filePath) {
|
|
|
186116
186206
|
let stripped = stripSqlLineComments(content);
|
|
186117
186207
|
stripped = stripCstyleComments(stripped);
|
|
186118
186208
|
const totalLines = content.split("\n").length;
|
|
186209
|
+
const noStrings = stripSqlStringLiterals(stripped);
|
|
186119
186210
|
for (const [pattern, kind] of PATTERNS) {
|
|
186120
186211
|
pattern.lastIndex = 0;
|
|
186121
|
-
for (const m of
|
|
186212
|
+
for (const m of noStrings.matchAll(pattern)) {
|
|
186122
186213
|
const rawName = m[1];
|
|
186123
186214
|
if (rawName) {
|
|
186124
186215
|
const name2 = unquote(rawName).trim();
|
|
@@ -186590,8 +186681,8 @@ function extractApex(content, filePath) {
|
|
|
186590
186681
|
const seen = /* @__PURE__ */ new Set();
|
|
186591
186682
|
const lineIndex = buildLineIndex(content);
|
|
186592
186683
|
const rawLines = content.split(/\r?\n/);
|
|
186593
|
-
const
|
|
186594
|
-
const code =
|
|
186684
|
+
const stringFree = stripStringLiterals(content);
|
|
186685
|
+
const code = stripCstyleComments(stringFree, /\/\/.*$/gm);
|
|
186595
186686
|
const emit5 = (name2, kind, span, docstring = "") => {
|
|
186596
186687
|
if (!name2 || symbols.length >= MAX_SYMBOLS6) return;
|
|
186597
186688
|
const key = `${name2}\0${kind}\0${span.startLine}`;
|
|
@@ -187778,8 +187869,17 @@ function buildEmbeddingBoundaries(filePath, content, dbPath) {
|
|
|
187778
187869
|
const symbols = querySymbols({ filePath, limit: 1e4 }, dbPath);
|
|
187779
187870
|
return symbols.map((s) => ({ start: s.lineStart, end: s.lineEnd, kind: "symbol" }));
|
|
187780
187871
|
}
|
|
187872
|
+
var DISABLED_EMBED_SHA_PREFIX = "disabled:";
|
|
187873
|
+
function disabledEmbedSha(sha) {
|
|
187874
|
+
return DISABLED_EMBED_SHA_PREFIX + sha;
|
|
187875
|
+
}
|
|
187781
187876
|
async function indexFileEmbeddings(filePath, dbPath = globalDbPath(), sha) {
|
|
187782
|
-
if (!loadConfig().indexing.embeddings_enabled)
|
|
187877
|
+
if (!loadConfig().indexing.embeddings_enabled) {
|
|
187878
|
+
if (sha !== void 0) {
|
|
187879
|
+
getDb(dbPath).prepare(`UPDATE files SET embed_sha = ? WHERE ${pathEqClause("path")}`).run(disabledEmbedSha(sha), foldPath(filePath));
|
|
187880
|
+
}
|
|
187881
|
+
return;
|
|
187882
|
+
}
|
|
187783
187883
|
if (filePath.toLowerCase().endsWith(".profile-meta.xml")) {
|
|
187784
187884
|
deleteFileEmbeddings(getDb(dbPath), filePath);
|
|
187785
187885
|
return;
|
|
@@ -188285,7 +188385,8 @@ function makeIndexer(dbPath) {
|
|
|
188285
188385
|
if (!parseUnchanged) {
|
|
188286
188386
|
indexFileSync(absPath, dbPath);
|
|
188287
188387
|
}
|
|
188288
|
-
const
|
|
188388
|
+
const embeddingsEnabled = loadConfig().indexing?.embeddings_enabled ?? true;
|
|
188389
|
+
const embedUnchanged = parseUnchanged && entry?.embedSha === (embeddingsEnabled ? sha : disabledEmbedSha(sha));
|
|
188289
188390
|
if (embedUnchanged) {
|
|
188290
188391
|
return false;
|
|
188291
188392
|
}
|
|
@@ -189461,7 +189562,7 @@ import * as fs19 from "fs/promises";
|
|
|
189461
189562
|
import { createHash as createHash4 } from "crypto";
|
|
189462
189563
|
import { resolve as resolve7 } from "path";
|
|
189463
189564
|
import { homedir as homedir7 } from "os";
|
|
189464
|
-
import { readdirSync as
|
|
189565
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync14, existsSync as existsSync13, statSync as statSync11, unlinkSync as unlinkSync7 } from "node:fs";
|
|
189465
189566
|
var COMPACT_END_MARKER = "<!-- COMPACT_END -->";
|
|
189466
189567
|
var SKILLS_OUTPUT_SUBDIR = "skills";
|
|
189467
189568
|
var _skillOutputsDirOverride = null;
|
|
@@ -189725,7 +189826,7 @@ function getCompactAnySessionSync(skillName) {
|
|
|
189725
189826
|
const name2 = safeSkillName(skillName);
|
|
189726
189827
|
if (!name2) return null;
|
|
189727
189828
|
const dir = skillOutputsDir();
|
|
189728
|
-
const entries =
|
|
189829
|
+
const entries = readdirSync7(dir, { withFileTypes: true });
|
|
189729
189830
|
const suffix = `@${sanitizeSkillId(name2)}@compact`;
|
|
189730
189831
|
for (const entry of entries) {
|
|
189731
189832
|
if (!entry.isFile() || !entry.name.endsWith("@compact")) continue;
|
|
@@ -189904,7 +190005,7 @@ function pruneSkillOutputs(maxCount = DEFAULT_MAX_COUNT, maxAgeMs = DEFAULT_MAX_
|
|
|
189904
190005
|
if (!existsSync13(dir)) return 0;
|
|
189905
190006
|
const cutoff = Date.now() - maxAgeMs;
|
|
189906
190007
|
const entries = [];
|
|
189907
|
-
for (const file2 of
|
|
190008
|
+
for (const file2 of readdirSync7(dir)) {
|
|
189908
190009
|
if (!file2.endsWith(".meta")) continue;
|
|
189909
190010
|
const outputId = file2.slice(0, -".meta".length);
|
|
189910
190011
|
let ts;
|
|
@@ -190655,7 +190756,6 @@ function preReadHandler(event) {
|
|
|
190655
190756
|
const headings = extractMarkdownHeadings(fileContent);
|
|
190656
190757
|
if (headings.length >= 3) {
|
|
190657
190758
|
const alreadyRead = wasFileReadThisSession(normalized);
|
|
190658
|
-
recordActualRead(event, normalized);
|
|
190659
190759
|
const hintText = formatHeadingTree(headings, normalized);
|
|
190660
190760
|
const wellKnown = getWellKnownSections(basename17);
|
|
190661
190761
|
const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' + normalized + "::" + s + '"').join(" | ") : "";
|
|
@@ -190663,9 +190763,13 @@ function preReadHandler(event) {
|
|
|
190663
190763
|
let message = hintText + wellKnownText + changelogExtra;
|
|
190664
190764
|
const tooLargeForFirstRead = markdownSize !== null && markdownSize >= largeFileDenyBytes();
|
|
190665
190765
|
if (alreadyRead || tooLargeForFirstRead) {
|
|
190766
|
+
if (alreadyRead) {
|
|
190767
|
+
recordActualRead(event, normalized);
|
|
190768
|
+
}
|
|
190666
190769
|
message += ' To edit it anyway, use `token-goat replace "' + normalized + '" --old-from <oldfile> --new-from <newfile>` for a snippet edit, or `token-goat write-file "' + normalized + "\" --from <newfile>` to rewrite the whole file \u2014 Read/Edit's own precondition can't be satisfied after this deny.";
|
|
190667
190770
|
return denyOutput(message);
|
|
190668
190771
|
}
|
|
190772
|
+
recordActualRead(event, normalized);
|
|
190669
190773
|
return contextOutput(message);
|
|
190670
190774
|
}
|
|
190671
190775
|
}
|
|
@@ -191023,8 +191127,31 @@ function renderReadRow(entry) {
|
|
|
191023
191127
|
const edited = entry.wasEdited ? ", edited" : "";
|
|
191024
191128
|
return `- ${entry.path} (${kb}kb, ${entry.readCount} ${plural2}${edited})`;
|
|
191025
191129
|
}
|
|
191026
|
-
function
|
|
191027
|
-
const
|
|
191130
|
+
function mergeManifestFiles(parent, siblingFiles) {
|
|
191131
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
191132
|
+
for (const f of parent) byPath.set(foldPath(f.path), f);
|
|
191133
|
+
for (const f of siblingFiles) {
|
|
191134
|
+
const key = foldPath(f.path);
|
|
191135
|
+
const prev = byPath.get(key);
|
|
191136
|
+
if (prev === void 0) {
|
|
191137
|
+
byPath.set(key, f);
|
|
191138
|
+
continue;
|
|
191139
|
+
}
|
|
191140
|
+
byPath.set(key, {
|
|
191141
|
+
path: prev.path,
|
|
191142
|
+
readCount: Math.max(prev.readCount, f.readCount),
|
|
191143
|
+
lastReadAt: Math.max(prev.lastReadAt, f.lastReadAt),
|
|
191144
|
+
wasEdited: prev.wasEdited || f.wasEdited,
|
|
191145
|
+
sizeBytes: f.lastReadAt >= prev.lastReadAt ? f.sizeBytes : prev.sizeBytes,
|
|
191146
|
+
...prev.wasTruncated || f.wasTruncated ? { wasTruncated: true } : {}
|
|
191147
|
+
});
|
|
191148
|
+
}
|
|
191149
|
+
return Array.from(byPath.values());
|
|
191150
|
+
}
|
|
191151
|
+
function buildManifest2(sessionId) {
|
|
191152
|
+
const ownFiles = [...getSessionFiles().values()];
|
|
191153
|
+
const siblingFiles = sessionId !== void 0 ? listSiblingSessionStates(sessionId).flatMap((s) => s.files) : [];
|
|
191154
|
+
const files = siblingFiles.length > 0 ? mergeManifestFiles(ownFiles, siblingFiles) : ownFiles;
|
|
191028
191155
|
const editedFiles = files.filter((f) => f.wasEdited);
|
|
191029
191156
|
const readFiles = files.filter((f) => f.readCount > 0 && !f.wasEdited);
|
|
191030
191157
|
const webFetches = [...getSessionWebFetches().entries()];
|
|
@@ -191068,8 +191195,8 @@ function buildManifest2() {
|
|
|
191068
191195
|
}
|
|
191069
191196
|
return lines.join("\n");
|
|
191070
191197
|
}
|
|
191071
|
-
function preCompactHandler(
|
|
191072
|
-
return contextOutput(buildManifest2());
|
|
191198
|
+
function preCompactHandler(event) {
|
|
191199
|
+
return contextOutput(buildManifest2(event.sessionId));
|
|
191073
191200
|
}
|
|
191074
191201
|
registerHook("pre_compact", preCompactHandler);
|
|
191075
191202
|
|
|
@@ -197334,7 +197461,6 @@ var _byId2 = /* @__PURE__ */ new Map();
|
|
|
197334
197461
|
var COMMAND_PATTERNS = {
|
|
197335
197462
|
gitMutable: /^\s*git\s+(diff|status)\b/i,
|
|
197336
197463
|
gitImmutable: /^\s*git\s+show\s+[0-9a-f]{40}\b/i,
|
|
197337
|
-
gitDiffUnscoped: /^\s*git\s+diff\b/i,
|
|
197338
197464
|
gitDiffScoped: /\s--\s+\S/,
|
|
197339
197465
|
dirListing: /^\s*(?:ls|eza|exa|dir|Get-ChildItem|gci)\b/i,
|
|
197340
197466
|
depList: /^\s*(?:npm\s+(?:-\S+\s+)*(?:ls|list)\b|pip\s+(?:-\S+\s+)*(?:list|freeze)\b|uv\s+pip\s+(?:-\S+\s+)*(?:list|freeze)\b|pnpm\s+(?:-\S+\s+)*(?:list|ls)\b|yarn\s+(?:-\S+\s+)*(?:list)\b|cargo\s+(?:-\S+\s+)*tree\b|bundle\s+(?:-\S+\s+)*(?:list|show)\b|composer\s+(?:-\S+\s+)*show\b)/i,
|
|
@@ -212436,6 +212562,9 @@ async function relay(eventName) {
|
|
|
212436
212562
|
const rawPayload = await readStdinJson();
|
|
212437
212563
|
const payload = eventName === "pre_tool_use" || eventName === "post_tool_use" ? normalizePayload(rawPayload, harnessForNormalization()) : rawPayload;
|
|
212438
212564
|
const event = buildEvent(eventName, payload);
|
|
212565
|
+
if (!process.env["CLAUDE_CODE_SESSION_ID"] && event.sessionId) {
|
|
212566
|
+
process.env["CLAUDE_CODE_SESSION_ID"] = event.sessionId;
|
|
212567
|
+
}
|
|
212439
212568
|
const stateKey = sessionStateKey(event);
|
|
212440
212569
|
try {
|
|
212441
212570
|
loadSessionState(stateKey);
|
|
@@ -238004,6 +238133,19 @@ function trimToBudget(text, budgetTokens, command2) {
|
|
|
238004
238133
|
const marker = `[token-goat: output capped at ~${budgetTokens} tokens to protect context \u2014 showing ${shown} of ${totalLines} lines. ${hint}]`;
|
|
238005
238134
|
return kept.join("\n") + "\n" + marker;
|
|
238006
238135
|
}
|
|
238136
|
+
function capJsonRows(items, budgetTokens) {
|
|
238137
|
+
const totalCount = items.length;
|
|
238138
|
+
const charBudget = Math.max(1, budgetTokens * 3);
|
|
238139
|
+
const kept = [];
|
|
238140
|
+
let used = 0;
|
|
238141
|
+
for (const item of items) {
|
|
238142
|
+
const cost = JSON.stringify(item).length + 2;
|
|
238143
|
+
if (kept.length > 0 && used + cost > charBudget) break;
|
|
238144
|
+
kept.push(item);
|
|
238145
|
+
used += cost;
|
|
238146
|
+
}
|
|
238147
|
+
return { items: kept, truncated: kept.length < totalCount, totalCount };
|
|
238148
|
+
}
|
|
238007
238149
|
function getHintFor(command2) {
|
|
238008
238150
|
const cmd = (command2 || "").toLowerCase().trim();
|
|
238009
238151
|
if (cmd === "symbol") {
|
|
@@ -238018,6 +238160,9 @@ function getHintFor(command2) {
|
|
|
238018
238160
|
if (cmd === "bash-output" || cmd === "web-output") {
|
|
238019
238161
|
return "Use --grep PATTERN, --section HEADING, or --tail N to narrow the cached output.";
|
|
238020
238162
|
}
|
|
238163
|
+
if (cmd === "semantic") {
|
|
238164
|
+
return "Narrow your query text or pass --limit to reduce the number of matches returned.";
|
|
238165
|
+
}
|
|
238021
238166
|
return "Narrow your query or raise overflow_guard max_tokens in config.";
|
|
238022
238167
|
}
|
|
238023
238168
|
|
|
@@ -240781,6 +240926,11 @@ function guardText(text, command2) {
|
|
|
240781
240926
|
const cfg = loadConfig();
|
|
240782
240927
|
return cfg.overflow_guard.enabled ? trimToBudget(text, cfg.overflow_guard.max_tokens, command2) : text;
|
|
240783
240928
|
}
|
|
240929
|
+
function guardJsonRows(items) {
|
|
240930
|
+
const cfg = loadConfig();
|
|
240931
|
+
if (!cfg.overflow_guard.enabled) return { items: [...items], truncated: false, totalCount: items.length };
|
|
240932
|
+
return capJsonRows(items, cfg.overflow_guard.max_tokens);
|
|
240933
|
+
}
|
|
240784
240934
|
function findSpecSeparator(spec) {
|
|
240785
240935
|
return spec.lastIndexOf("::");
|
|
240786
240936
|
}
|
|
@@ -240819,7 +240969,9 @@ function runSymbol(opts) {
|
|
|
240819
240969
|
return { text: `No matches for '${opts.name ?? "*"}'`, code: 1 };
|
|
240820
240970
|
}
|
|
240821
240971
|
if (opts.json === true) {
|
|
240822
|
-
|
|
240972
|
+
const capped = guardJsonRows(results);
|
|
240973
|
+
const payload = capped.truncated ? { results: capped.items, truncated: true, totalCount: capped.totalCount } : results;
|
|
240974
|
+
return { text: JSON.stringify(payload, null, 2), code: 0 };
|
|
240823
240975
|
}
|
|
240824
240976
|
const blocks = results.map((sym) => {
|
|
240825
240977
|
const header = `# ${sym.name} (${sym.kind}) \u2014 ${sym.filePath}:${sym.lineStart}-${sym.lineEnd}`;
|
|
@@ -241061,7 +241213,8 @@ function runRefs(opts) {
|
|
|
241061
241213
|
const results = queryRefs(queryOpts);
|
|
241062
241214
|
if (results.length > 0) anyFound = true;
|
|
241063
241215
|
if (opts.json === true) {
|
|
241064
|
-
|
|
241216
|
+
const capped = guardJsonRows(results);
|
|
241217
|
+
jsonOut[sym] = capped.truncated ? { references: capped.items, truncated: true, totalCount: capped.totalCount } : capped.items;
|
|
241065
241218
|
continue;
|
|
241066
241219
|
}
|
|
241067
241220
|
if (results.length === 0) {
|
|
@@ -241094,7 +241247,9 @@ function runRefsSingle(opts) {
|
|
|
241094
241247
|
return 1;
|
|
241095
241248
|
}
|
|
241096
241249
|
if (opts.json === true) {
|
|
241097
|
-
|
|
241250
|
+
const capped = guardJsonRows(results);
|
|
241251
|
+
const payload = capped.truncated ? { references: capped.items, truncated: true, totalCount: capped.totalCount } : results;
|
|
241252
|
+
emit3(JSON.stringify(payload, null, 2));
|
|
241098
241253
|
return 0;
|
|
241099
241254
|
}
|
|
241100
241255
|
const lines = opts.callers === true ? renderCallerGroups(results) : results.map((ref) => `${ref.filePath}:${ref.line}: ${ref.context}`);
|
|
@@ -241132,20 +241287,16 @@ function runSkeleton(opts) {
|
|
|
241132
241287
|
const filtered = opts.minLines !== void 0 ? symbols.filter((s) => s.lineEnd - s.lineStart + 1 >= (opts.minLines ?? 0)) : symbols;
|
|
241133
241288
|
const refCounts = opts.stats === true ? queryRefCounts(filtered.map((s) => s.name)) : void 0;
|
|
241134
241289
|
if (opts.json === true) {
|
|
241135
|
-
|
|
241136
|
-
|
|
241137
|
-
|
|
241138
|
-
|
|
241139
|
-
|
|
241140
|
-
|
|
241141
|
-
|
|
241142
|
-
|
|
241143
|
-
|
|
241144
|
-
|
|
241145
|
-
2
|
|
241146
|
-
),
|
|
241147
|
-
code: 0
|
|
241148
|
-
};
|
|
241290
|
+
const rows = filtered.map((s) => ({
|
|
241291
|
+
name: s.name,
|
|
241292
|
+
kind: s.kind,
|
|
241293
|
+
lineStart: s.lineStart,
|
|
241294
|
+
lineEnd: s.lineEnd,
|
|
241295
|
+
...refCounts !== void 0 ? { refCount: refCounts.get(s.name) ?? 0, hasDoc: s.docstring.trim().length > 0 } : {}
|
|
241296
|
+
}));
|
|
241297
|
+
const capped = guardJsonRows(rows);
|
|
241298
|
+
const payload = capped.truncated ? { symbols: capped.items, truncated: true, totalCount: capped.totalCount } : rows;
|
|
241299
|
+
return { text: JSON.stringify(payload, null, 2), code: 0 };
|
|
241149
241300
|
}
|
|
241150
241301
|
const totalLines = filtered.length > 0 ? Math.max(...filtered.map((s) => s.lineEnd)) : 0;
|
|
241151
241302
|
const lines = [`# Skeleton: ${opts.file} (${filtered.length} symbols, ${totalLines} lines)`];
|
|
@@ -241168,18 +241319,14 @@ function runOutline(opts) {
|
|
|
241168
241319
|
const filtered = opts.minLines !== void 0 ? symbols.filter((s) => s.lineEnd - s.lineStart + 1 >= (opts.minLines ?? 0)) : symbols;
|
|
241169
241320
|
const refCounts = opts.stats === true ? queryRefCounts(filtered.map((s) => s.name)) : void 0;
|
|
241170
241321
|
if (opts.json === true) {
|
|
241171
|
-
|
|
241172
|
-
|
|
241173
|
-
|
|
241174
|
-
|
|
241175
|
-
|
|
241176
|
-
|
|
241177
|
-
|
|
241178
|
-
|
|
241179
|
-
2
|
|
241180
|
-
),
|
|
241181
|
-
code: 0
|
|
241182
|
-
};
|
|
241322
|
+
const rows = refCounts !== void 0 ? filtered.map((s) => ({
|
|
241323
|
+
...s,
|
|
241324
|
+
refCount: refCounts.get(s.name) ?? 0,
|
|
241325
|
+
hasDoc: s.docstring.trim().length > 0
|
|
241326
|
+
})) : filtered;
|
|
241327
|
+
const capped = guardJsonRows(rows);
|
|
241328
|
+
const payload = capped.truncated ? { symbols: capped.items, truncated: true, totalCount: capped.totalCount } : rows;
|
|
241329
|
+
return { text: JSON.stringify(payload, null, 2), code: 0 };
|
|
241183
241330
|
}
|
|
241184
241331
|
const lines = [`# Outline: ${opts.file} (${filtered.length} symbols)`];
|
|
241185
241332
|
for (const sym of filtered) {
|
|
@@ -241852,7 +241999,7 @@ async function runSemantic(query, opts) {
|
|
|
241852
241999
|
(h) => `# ${h.filePath}:${h.startLine}-${h.endLine} (distance ${h.distance.toFixed(3)})
|
|
241853
242000
|
${previewLines(h.text, 3)}`
|
|
241854
242001
|
);
|
|
241855
|
-
return { text: blocks2.join("\n\n"), code: 0 };
|
|
242002
|
+
return { text: guardText(blocks2.join("\n\n"), "semantic"), code: 0 };
|
|
241856
242003
|
}
|
|
241857
242004
|
const results = searchSymbolsFts(query, n);
|
|
241858
242005
|
if (results.length === 0) {
|
|
@@ -241860,7 +242007,7 @@ ${previewLines(h.text, 3)}`
|
|
|
241860
242007
|
}
|
|
241861
242008
|
const blocks = results.map((s) => `${symbolHeader(s)}
|
|
241862
242009
|
${previewLines(s.body, 3)}`);
|
|
241863
|
-
return { text: blocks.join("\n\n"), code: 0 };
|
|
242010
|
+
return { text: guardText(blocks.join("\n\n"), "semantic"), code: 0 };
|
|
241864
242011
|
}
|
|
241865
242012
|
|
|
241866
242013
|
// src/mcp_server.ts
|
|
@@ -246909,6 +247056,9 @@ var CACHE_ENV_GATES = [
|
|
|
246909
247056
|
function pad(s, n) {
|
|
246910
247057
|
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
246911
247058
|
}
|
|
247059
|
+
function listParentSessionBlobs() {
|
|
247060
|
+
return listBlobs(SESSIONS_SUBDIR).filter((b) => !b.id.includes(AGENT_SALT_MARKER)).sort((a, b) => b.mtime - a.mtime);
|
|
247061
|
+
}
|
|
246912
247062
|
function cmdBashHistory(opts) {
|
|
246913
247063
|
let limit = 30;
|
|
246914
247064
|
if (opts.limit !== void 0) {
|
|
@@ -247111,7 +247261,7 @@ function cmdCompactHint(opts) {
|
|
|
247111
247261
|
}
|
|
247112
247262
|
}
|
|
247113
247263
|
function cmdSessionSummary(opts) {
|
|
247114
|
-
const blobs =
|
|
247264
|
+
const blobs = listParentSessionBlobs();
|
|
247115
247265
|
if (blobs.length === 0) {
|
|
247116
247266
|
if (opts.json === true) {
|
|
247117
247267
|
process.stdout.write(JSON.stringify({ sessionCount: 0, message: "no session blobs found" }, null, 2) + "\n");
|
|
@@ -247144,7 +247294,7 @@ function cmdSessionSummary(opts) {
|
|
|
247144
247294
|
}
|
|
247145
247295
|
function cmdCost(opts) {
|
|
247146
247296
|
if (opts.session === true) {
|
|
247147
|
-
const blobs =
|
|
247297
|
+
const blobs = listParentSessionBlobs();
|
|
247148
247298
|
if (blobs.length === 0) {
|
|
247149
247299
|
if (opts.json === true) {
|
|
247150
247300
|
process.stdout.write(JSON.stringify({ session: true, message: "no session blobs found" }, null, 2) + "\n");
|
|
@@ -247481,6 +247631,11 @@ function levenshtein2(a, b, cap = 3) {
|
|
|
247481
247631
|
function closestKeys(unknown2, known) {
|
|
247482
247632
|
return known.map((k) => ({ k, d: levenshtein2(unknown2, k) })).filter((x) => x.d <= 3).sort((a, b) => a.d - b.d).slice(0, 3).map((x) => x.k);
|
|
247483
247633
|
}
|
|
247634
|
+
function didYouMeanKeySuffix(unknownKey) {
|
|
247635
|
+
const knownKeys = flattenConfig(defaultConfig()).map(([k]) => k);
|
|
247636
|
+
const suggestions = closestKeys(unknownKey, knownKeys);
|
|
247637
|
+
return suggestions.length > 0 ? ` (did you mean: ${suggestions.join(", ")}?)` : "";
|
|
247638
|
+
}
|
|
247484
247639
|
function walkGet(obj, parts) {
|
|
247485
247640
|
let cur = obj;
|
|
247486
247641
|
for (const part of parts) {
|
|
@@ -247557,15 +247712,13 @@ function cmdConfig(opts) {
|
|
|
247557
247712
|
}
|
|
247558
247713
|
if (action === "get") {
|
|
247559
247714
|
if (!opts.key) {
|
|
247560
|
-
|
|
247561
|
-
throw new Error("missing key");
|
|
247715
|
+
throw new Error("config get requires a key (e.g. compact_assist.enabled)");
|
|
247562
247716
|
}
|
|
247563
247717
|
const parts = opts.key.split(".");
|
|
247564
247718
|
const cfg = loadConfig();
|
|
247565
247719
|
const result = walkGet(cfg, parts);
|
|
247566
247720
|
if (!result.found) {
|
|
247567
|
-
|
|
247568
|
-
throw new Error(`key not found: ${opts.key}`);
|
|
247721
|
+
throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
|
|
247569
247722
|
}
|
|
247570
247723
|
if (opts.json === true) {
|
|
247571
247724
|
emit4(JSON.stringify({ key: opts.key, value: result.value }, null, 2));
|
|
@@ -247576,28 +247729,23 @@ function cmdConfig(opts) {
|
|
|
247576
247729
|
}
|
|
247577
247730
|
if (action === "set") {
|
|
247578
247731
|
if (!opts.key) {
|
|
247579
|
-
|
|
247580
|
-
throw new Error("missing key");
|
|
247732
|
+
throw new Error("config set requires a key (e.g. compact_assist.enabled)");
|
|
247581
247733
|
}
|
|
247582
247734
|
if (opts.value === void 0) {
|
|
247583
|
-
|
|
247584
|
-
throw new Error("missing value");
|
|
247735
|
+
throw new Error("config set requires a value");
|
|
247585
247736
|
}
|
|
247586
247737
|
const parts = opts.key.split(".");
|
|
247587
247738
|
const cfg = loadPersistedConfig();
|
|
247588
247739
|
const ref = walkParent(cfg, parts);
|
|
247589
247740
|
if (!ref) {
|
|
247590
|
-
|
|
247591
|
-
throw new Error(`key not found: ${opts.key}`);
|
|
247741
|
+
throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
|
|
247592
247742
|
}
|
|
247593
247743
|
const existing = ref.parent[ref.leaf];
|
|
247594
247744
|
if (existing === void 0) {
|
|
247595
|
-
|
|
247596
|
-
throw new Error(`key not found: ${opts.key}`);
|
|
247745
|
+
throw new Error(`key not found: ${opts.key}${didYouMeanKeySuffix(opts.key)}`);
|
|
247597
247746
|
}
|
|
247598
247747
|
if (typeof existing === "object" && existing !== null && !Array.isArray(existing)) {
|
|
247599
|
-
|
|
247600
|
-
throw new Error(`cannot set a whole config section: ${opts.key}`);
|
|
247748
|
+
throw new Error(`config set: '${opts.key}' is a section, not a settable field \u2014 set an individual key within it instead (e.g. ${opts.key}.<field>)`);
|
|
247601
247749
|
}
|
|
247602
247750
|
const defaultAtKey = walkGet(defaultConfig(), parts);
|
|
247603
247751
|
const coerced = coerce2(opts.value, existing, defaultAtKey.found ? defaultAtKey.value : void 0);
|
|
@@ -247606,8 +247754,7 @@ function cmdConfig(opts) {
|
|
|
247606
247754
|
const revalidated = buildPersistedConfig(cfg);
|
|
247607
247755
|
const revalidatedResult = walkGet(revalidated, parts);
|
|
247608
247756
|
if (revalidatedResult.found && revalidatedResult.value !== coerced) {
|
|
247609
|
-
|
|
247610
|
-
throw new Error(`value out of range for ${opts.key}: ${coerced}`);
|
|
247757
|
+
throw new Error(`config set: ${opts.key} = ${coerced} is outside the allowed range (would be clamped to ${String(revalidatedResult.value)}); rejected`);
|
|
247611
247758
|
}
|
|
247612
247759
|
}
|
|
247613
247760
|
saveConfigSafe(cfg);
|
|
@@ -247687,8 +247834,7 @@ function cmdConfig(opts) {
|
|
|
247687
247834
|
emit4(`config validate: ${findings.length} issue(s) found`);
|
|
247688
247835
|
return;
|
|
247689
247836
|
}
|
|
247690
|
-
|
|
247691
|
-
throw new Error(`unknown config action: ${action}`);
|
|
247837
|
+
throw new Error(`config: unknown action '${action}'. Use list, get, set, or validate.`);
|
|
247692
247838
|
}
|
|
247693
247839
|
function cmdProject(opts) {
|
|
247694
247840
|
const { action } = opts;
|
|
@@ -247978,7 +248124,8 @@ async function cmdIndex(pathArg, opts = {}) {
|
|
|
247978
248124
|
const sha = fingerprintFile(key);
|
|
247979
248125
|
const entry = sha !== null ? getFileEntry(key, dbPath) : null;
|
|
247980
248126
|
const parseUnchanged = sha !== null && entry?.sha === sha;
|
|
247981
|
-
const
|
|
248127
|
+
const embeddingsEnabled = loadConfig().indexing?.embeddings_enabled ?? true;
|
|
248128
|
+
const embedUnchanged = parseUnchanged && sha !== null && entry?.embedSha === (embeddingsEnabled ? sha : disabledEmbedSha(sha));
|
|
247982
248129
|
if (parseUnchanged && embedUnchanged) {
|
|
247983
248130
|
skipped += 1;
|
|
247984
248131
|
continue;
|