token-goat 2.9.8 → 2.9.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/README.md +2 -2
- package/SECURITY.md +1 -1
- package/dist/{token-goat-chunk-TXZY7C24.mjs → token-goat-chunk-BYDDWQ2T.mjs} +96 -14
- package/dist/{token-goat-chunk-3YANZKER.mjs → token-goat-chunk-DRH4CVGF.mjs} +5 -5
- package/dist/{token-goat-chunk-Q4VCAIBR.mjs → token-goat-chunk-K5GKX6ND.mjs} +5 -5
- package/dist/{token-goat-chunk-JZYJH76S.mjs → token-goat-chunk-KIEOFWLL.mjs} +20 -1
- package/dist/{token-goat-chunk-6RAUVAKW.mjs → token-goat-chunk-L6Q2XM5X.mjs} +2 -2
- package/dist/{token-goat-chunk-EZZ7IJYM.mjs → token-goat-chunk-LQ3SGWIW.mjs} +3 -3
- package/dist/{token-goat-chunk-REHUP2OE.mjs → token-goat-chunk-OBDTBOQA.mjs} +1 -1
- package/dist/{token-goat-chunk-XYLPMQ6I.mjs → token-goat-chunk-P5SQX2VK.mjs} +81 -7
- package/dist/{token-goat-chunk-2SBHUPBF.mjs → token-goat-chunk-PNMGVJ4C.mjs} +7 -7
- package/dist/{token-goat-chunk-VEEHPNBV.mjs → token-goat-chunk-QCHD2ENV.mjs} +2 -2
- package/dist/{token-goat-chunk-WT5OLTT6.mjs → token-goat-chunk-WBPVYAEO.mjs} +2 -2
- package/dist/token-goat-hook.mjs +5 -5
- package/dist/token-goat.core.mjs +5 -5
- package/docs/security.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Restart your AI sessions. Run `token-goat stats` a couple of minutes after your
|
|
|
37
37
|
|
|
38
38
|
> **Built and continually improved, free, by one person. If it saves you tokens, drop a ⭐️ at the top of this page. One click. Makes my day. Also, if you'd like anything added, [drop me a line](mailto:token-goat@dfkhelper.com).**
|
|
39
39
|
|
|
40
|
-
[Install](docs/install.md) · [CLI](docs/cli.md) · [What gets installed?](docs/install.md#what-gets-installed) · [Stats](#stats-display) · [Security & uninstall](docs/security.md)
|
|
40
|
+
[Install](docs/install.md) · [CLI](docs/cli.md) · [Architecture Q&A](docs/architecture-qa.html) · [What gets installed?](docs/install.md#what-gets-installed) · [Stats](#stats-display) · [Security & uninstall](docs/security.md)
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
@@ -323,7 +323,7 @@ corpus of captured shell output through the real compression path and reports ho
|
|
|
323
323
|
result got, alongside a count of the lines each case is not allowed to lose. Deleting output makes
|
|
324
324
|
the first number look better, so the second one is what keeps the first honest.
|
|
325
325
|
|
|
326
|
-
Every command, with its flags, its output, and the comparison workflows that chain them: **[CLI reference](docs/cli.md)**.
|
|
326
|
+
Every command, with its flags, its output, and the comparison workflows that chain them: **[CLI reference](docs/cli.md)**. For architectural analysis, empirical evaluations, and technical answers to common engineering questions: **[Architecture & Technical Q&A](docs/architecture-qa.html)**.
|
|
327
327
|
|
|
328
328
|
## MCP server
|
|
329
329
|
|
package/SECURITY.md
CHANGED
|
@@ -101,7 +101,7 @@ For a scanner that ingests a bill of materials rather than a lockfile, `npm run
|
|
|
101
101
|
|
|
102
102
|
## Verifying what you installed
|
|
103
103
|
|
|
104
|
-
Every published version is built and pushed by one workflow, [`.github/workflows/publish.yml`](.github/workflows/publish.yml), which runs only when a GitHub release is published (or manually, and then only from `main`). It publishes with npm provenance, so npm holds a signed attestation tying the tarball to the commit and workflow run that produced it. Nothing is ever published from a
|
|
104
|
+
Every published version is built and pushed by one workflow, [`.github/workflows/publish.yml`](.github/workflows/publish.yml), which runs only when a GitHub release is published (or manually, and then only from `main`). It publishes with npm provenance, so npm holds a signed attestation tying the tarball to the commit and workflow run that produced it. Nothing is ever published from a developer workstation.
|
|
105
105
|
|
|
106
106
|
To check a copy you already have:
|
|
107
107
|
|
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
toDisplayPath,
|
|
102
102
|
toKB,
|
|
103
103
|
withFileLock
|
|
104
|
-
} from "./token-goat-chunk-
|
|
104
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
105
105
|
import {
|
|
106
106
|
registerReset
|
|
107
107
|
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
@@ -10268,6 +10268,47 @@ function modelDir() {
|
|
|
10268
10268
|
function downloadUrl(file) {
|
|
10269
10269
|
return `https://huggingface.co/${DEFAULT_MODEL}/resolve/${PINNED_MODEL_REVISION}/${file.name}`;
|
|
10270
10270
|
}
|
|
10271
|
+
function sharedModelCacheDir() {
|
|
10272
|
+
const raw = process.env["TOKEN_GOAT_MODEL_CACHE_DIR"]?.trim();
|
|
10273
|
+
if (!raw) return null;
|
|
10274
|
+
return path7.join(raw, ...DEFAULT_MODEL.split("/"), PINNED_MODEL_REVISION);
|
|
10275
|
+
}
|
|
10276
|
+
async function copyFromSharedCache(shared, file, target) {
|
|
10277
|
+
const source = path7.join(shared, file.name);
|
|
10278
|
+
const temp = `${target}.${process.pid}.shared`;
|
|
10279
|
+
try {
|
|
10280
|
+
if (!fs11.existsSync(source)) return false;
|
|
10281
|
+
fs11.copyFileSync(source, temp);
|
|
10282
|
+
if (await sha256Of(temp) !== file.sha256) {
|
|
10283
|
+
fs11.rmSync(temp, { force: true, maxRetries: 20, retryDelay: 25 });
|
|
10284
|
+
fs11.rmSync(source, { force: true, maxRetries: 20, retryDelay: 25 });
|
|
10285
|
+
return false;
|
|
10286
|
+
}
|
|
10287
|
+
fs11.renameSync(temp, target);
|
|
10288
|
+
return true;
|
|
10289
|
+
} catch {
|
|
10290
|
+
try {
|
|
10291
|
+
fs11.rmSync(temp, { force: true, maxRetries: 20, retryDelay: 25 });
|
|
10292
|
+
} catch {
|
|
10293
|
+
}
|
|
10294
|
+
return false;
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10297
|
+
function publishToSharedCache(shared, file, target) {
|
|
10298
|
+
const destination = path7.join(shared, file.name);
|
|
10299
|
+
const temp = `${destination}.${process.pid}.partial`;
|
|
10300
|
+
try {
|
|
10301
|
+
if (fs11.existsSync(destination)) return;
|
|
10302
|
+
fs11.mkdirSync(path7.dirname(destination), { recursive: true });
|
|
10303
|
+
fs11.copyFileSync(target, temp);
|
|
10304
|
+
fs11.renameSync(temp, destination);
|
|
10305
|
+
} catch {
|
|
10306
|
+
try {
|
|
10307
|
+
fs11.rmSync(temp, { force: true, maxRetries: 20, retryDelay: 25 });
|
|
10308
|
+
} catch {
|
|
10309
|
+
}
|
|
10310
|
+
}
|
|
10311
|
+
}
|
|
10271
10312
|
var _ort = null;
|
|
10272
10313
|
var _ortError = null;
|
|
10273
10314
|
var _ortLoadAttempted = false;
|
|
@@ -10363,6 +10404,7 @@ async function ensureModelFiles(modelName = DEFAULT_MODEL) {
|
|
|
10363
10404
|
ensureDataDirPrivate();
|
|
10364
10405
|
const dir = modelDir();
|
|
10365
10406
|
const offline = loadConfig().network.offline;
|
|
10407
|
+
const shared = sharedModelCacheDir();
|
|
10366
10408
|
for (const file of MODEL_FILES) {
|
|
10367
10409
|
const target = path7.join(dir, file.name);
|
|
10368
10410
|
if (fs11.existsSync(target)) {
|
|
@@ -10370,6 +10412,10 @@ async function ensureModelFiles(modelName = DEFAULT_MODEL) {
|
|
|
10370
10412
|
if (digest === file.sha256) continue;
|
|
10371
10413
|
fs11.rmSync(target, { force: true });
|
|
10372
10414
|
}
|
|
10415
|
+
if (shared) {
|
|
10416
|
+
fs11.mkdirSync(path7.dirname(target), { recursive: true });
|
|
10417
|
+
if (await copyFromSharedCache(shared, file, target)) continue;
|
|
10418
|
+
}
|
|
10373
10419
|
if (offline) {
|
|
10374
10420
|
throw new Error(
|
|
10375
10421
|
`Offline mode is on (network.offline): refusing to download ${file.name} for the embedding model. Copy the pinned files into ${dir} on a connected machine to use semantic search here.`
|
|
@@ -10380,6 +10426,7 @@ async function ensureModelFiles(modelName = DEFAULT_MODEL) {
|
|
|
10380
10426
|
`Downloading the embedding model, once (${file.name}, ${Math.round(file.bytes / 1024 / 1024)} MB) into ${dir}`
|
|
10381
10427
|
);
|
|
10382
10428
|
await download(file, target);
|
|
10429
|
+
if (shared) publishToSharedCache(shared, file, target);
|
|
10383
10430
|
}
|
|
10384
10431
|
return dir;
|
|
10385
10432
|
}
|
|
@@ -20023,6 +20070,41 @@ function readIntToolInput(event, key) {
|
|
|
20023
20070
|
}
|
|
20024
20071
|
return void 0;
|
|
20025
20072
|
}
|
|
20073
|
+
function readRequestedSliceWindow(event) {
|
|
20074
|
+
const rawOffset = readIntToolInput(event, "offset");
|
|
20075
|
+
const rawLimit = readIntToolInput(event, "limit");
|
|
20076
|
+
if (rawOffset !== void 0 || rawLimit !== void 0) {
|
|
20077
|
+
return {
|
|
20078
|
+
offset: rawOffset !== void 0 && rawOffset >= 1 ? Math.floor(rawOffset) : 1,
|
|
20079
|
+
limit: rawLimit !== void 0 && rawLimit > 0 ? Math.floor(rawLimit) : void 0,
|
|
20080
|
+
isExplicitSlice: true
|
|
20081
|
+
};
|
|
20082
|
+
}
|
|
20083
|
+
const rawRange = event.toolInput["view_range"] ?? event.toolInput["lines"] ?? event.toolInput["range"];
|
|
20084
|
+
if (Array.isArray(rawRange) && rawRange.length >= 1) {
|
|
20085
|
+
const rawStart = Number(rawRange[0]);
|
|
20086
|
+
const startVal = Number.isFinite(rawStart) && rawStart >= 1 ? Math.floor(rawStart) : 1;
|
|
20087
|
+
if (rawRange.length >= 2) {
|
|
20088
|
+
const rawEnd = Number(rawRange[1]);
|
|
20089
|
+
if (rawEnd === -1) {
|
|
20090
|
+
return { offset: startVal, isExplicitSlice: true };
|
|
20091
|
+
}
|
|
20092
|
+
if (Number.isFinite(rawEnd) && rawEnd >= startVal) {
|
|
20093
|
+
const lineCount = Math.floor(rawEnd - startVal + 1);
|
|
20094
|
+
return { offset: startVal, limit: lineCount, isExplicitSlice: true };
|
|
20095
|
+
}
|
|
20096
|
+
}
|
|
20097
|
+
return { offset: startVal, isExplicitSlice: true };
|
|
20098
|
+
}
|
|
20099
|
+
const startLine = readIntToolInput(event, "start_line") ?? readIntToolInput(event, "startLine") ?? readIntToolInput(event, "start");
|
|
20100
|
+
const endLine = readIntToolInput(event, "end_line") ?? readIntToolInput(event, "endLine") ?? readIntToolInput(event, "end");
|
|
20101
|
+
if (startLine !== void 0 || endLine !== void 0) {
|
|
20102
|
+
const effectiveStart = startLine !== void 0 && startLine >= 1 ? Math.floor(startLine) : 1;
|
|
20103
|
+
const effectiveLimit = endLine !== void 0 && endLine >= effectiveStart ? Math.floor(endLine - effectiveStart + 1) : void 0;
|
|
20104
|
+
return { offset: effectiveStart, limit: effectiveLimit, isExplicitSlice: true };
|
|
20105
|
+
}
|
|
20106
|
+
return { isExplicitSlice: false };
|
|
20107
|
+
}
|
|
20026
20108
|
function readStartLine(event) {
|
|
20027
20109
|
const resp = event.raw["tool_response"];
|
|
20028
20110
|
if (resp === null || typeof resp !== "object") return 1;
|
|
@@ -20086,11 +20168,10 @@ function scanRequestedSlice(absPath, offset, limit) {
|
|
|
20086
20168
|
}
|
|
20087
20169
|
}
|
|
20088
20170
|
function estimateRequestedSlice(event, absPath) {
|
|
20089
|
-
const
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
const
|
|
20093
|
-
const scan = scanRequestedSlice(absPath, effectiveOffset, limit);
|
|
20171
|
+
const window2 = readRequestedSliceWindow(event);
|
|
20172
|
+
if (window2.limit === void 0 || window2.limit <= 0) return { kind: "unbounded" };
|
|
20173
|
+
const effectiveOffset = window2.offset !== void 0 && window2.offset >= 1 ? window2.offset : 1;
|
|
20174
|
+
const scan = scanRequestedSlice(absPath, effectiveOffset, window2.limit);
|
|
20094
20175
|
if (scan === null) return { kind: "unbounded" };
|
|
20095
20176
|
if (scan.nearSingleLine) return { kind: "nearSingleLine" };
|
|
20096
20177
|
if (scan.trustworthy) return { kind: "bytes", bytes: scan.bytes };
|
|
@@ -20330,7 +20411,7 @@ function preReadHandlerInner(event) {
|
|
|
20330
20411
|
} catch {
|
|
20331
20412
|
}
|
|
20332
20413
|
}
|
|
20333
|
-
const compactUnrangedRead =
|
|
20414
|
+
const compactUnrangedRead = !readRequestedSliceWindow(event).isExplicitSlice;
|
|
20334
20415
|
if (event.toolName !== "Grep" && compactUnrangedRead && loadConfig().hints.stable_doc_compacts && _isDocFile(normalized)) {
|
|
20335
20416
|
const compactPath = compactPathFor(normalized);
|
|
20336
20417
|
if (isCompactFresh(compactPath, normalized)) {
|
|
@@ -20413,7 +20494,7 @@ function preReadHandlerInner(event) {
|
|
|
20413
20494
|
}
|
|
20414
20495
|
return denyOutput(message);
|
|
20415
20496
|
}
|
|
20416
|
-
const unrangedRead =
|
|
20497
|
+
const unrangedRead = !readRequestedSliceWindow(event).isExplicitSlice;
|
|
20417
20498
|
if (loadConfig().hints.subagent_markdown_first_read_deny && event.agentId !== void 0 && unrangedRead && SUBAGENT_MD_FIRST_READ_DENY_EXT_RE.test(basename12) && markdownSize !== null && markdownSize >= SUBAGENT_MD_FIRST_READ_DENY_BYTES) {
|
|
20418
20499
|
recordStat("subagent_markdown_first_read_deny", 0, 0);
|
|
20419
20500
|
return denyOutput(
|
|
@@ -20783,9 +20864,9 @@ function readWindowFromDisk(event, normalized) {
|
|
|
20783
20864
|
const size = statSize(normalized);
|
|
20784
20865
|
if (size === null || size > SLICE_ESTIMATE_SCAN_CAP_BYTES) return null;
|
|
20785
20866
|
const text = decodeSource(fs21.readFileSync(normalized));
|
|
20786
|
-
const
|
|
20787
|
-
const
|
|
20788
|
-
const
|
|
20867
|
+
const window2 = readRequestedSliceWindow(event);
|
|
20868
|
+
const start = window2.offset !== void 0 && window2.offset >= 1 ? window2.offset : 1;
|
|
20869
|
+
const limit = window2.limit;
|
|
20789
20870
|
if (start === 1 && (limit === void 0 || limit <= 0)) return text;
|
|
20790
20871
|
const lines2 = text.split("\n");
|
|
20791
20872
|
const from = start - 1;
|
|
@@ -20908,7 +20989,7 @@ function elideAlreadyServedLines(event, respText) {
|
|
|
20908
20989
|
function structuralFoldInputs(event, respText) {
|
|
20909
20990
|
const filePath = getFilePath(event);
|
|
20910
20991
|
if (filePath === void 0) return null;
|
|
20911
|
-
if (
|
|
20992
|
+
if (readRequestedSliceWindow(event).isExplicitSlice) return null;
|
|
20912
20993
|
if (isTruncatedReadDelivery(event, respText)) return null;
|
|
20913
20994
|
if (redactSecrets(respText).count > 0) return null;
|
|
20914
20995
|
const parsed = parseNumberedReadResult(respText, readStartLine(event));
|
|
@@ -20943,14 +21024,15 @@ function foldCodeBodies(event, respText) {
|
|
|
20943
21024
|
if (filePath === void 0) return null;
|
|
20944
21025
|
const normalized = normalizePath(filePath);
|
|
20945
21026
|
if (isImagePath(normalized)) return null;
|
|
20946
|
-
const
|
|
21027
|
+
const sliceWin = readRequestedSliceWindow(event);
|
|
21028
|
+
const requestedOffset = sliceWin.offset;
|
|
20947
21029
|
if (requestedOffset !== void 0 && readStartLine(event) !== requestedOffset) return null;
|
|
20948
21030
|
if (isTruncatedReadDelivery(event, respText)) return null;
|
|
20949
21031
|
if (redactSecrets(respText).count > 0) return null;
|
|
20950
21032
|
const parsed = parseNumberedReadResult(respText, readStartLine(event));
|
|
20951
21033
|
if (parsed === null) return null;
|
|
20952
21034
|
const shown = displaySafePath(toDisplayPath(findProject(getCwd(event) ?? process.cwd())?.root, normalized));
|
|
20953
|
-
const folded = foldDelivery(parsed.rows, normalized, shown,
|
|
21035
|
+
const folded = foldDelivery(parsed.rows, normalized, shown, sliceWin.isExplicitSlice);
|
|
20954
21036
|
if (folded === null) return null;
|
|
20955
21037
|
const rewritten = [...parsed.header, fenceUntrustedFileContent(folded.numbered.join("\n")), ...parsed.trailer].join("\n");
|
|
20956
21038
|
const originalBytes = Buffer.byteLength(respText, "utf-8");
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
expandGlobs,
|
|
8
8
|
leftoverIntegrations,
|
|
9
9
|
run
|
|
10
|
-
} from "./token-goat-chunk-
|
|
11
|
-
import "./token-goat-chunk-
|
|
12
|
-
import "./token-goat-chunk-
|
|
13
|
-
import "./token-goat-chunk-
|
|
14
|
-
import "./token-goat-chunk-
|
|
10
|
+
} from "./token-goat-chunk-PNMGVJ4C.mjs";
|
|
11
|
+
import "./token-goat-chunk-L6Q2XM5X.mjs";
|
|
12
|
+
import "./token-goat-chunk-QCHD2ENV.mjs";
|
|
13
|
+
import "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
14
|
+
import "./token-goat-chunk-KIEOFWLL.mjs";
|
|
15
15
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
16
16
|
import "./token-goat-chunk-A37V4PBF.mjs";
|
|
17
17
|
export {
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
buildEvent,
|
|
5
5
|
relay,
|
|
6
6
|
relayInProcess
|
|
7
|
-
} from "./token-goat-chunk-
|
|
7
|
+
} from "./token-goat-chunk-P5SQX2VK.mjs";
|
|
8
8
|
import {
|
|
9
9
|
MAX_STDIN_BYTES,
|
|
10
10
|
readStdinJson
|
|
11
|
-
} from "./token-goat-chunk-
|
|
12
|
-
import "./token-goat-chunk-
|
|
13
|
-
import "./token-goat-chunk-
|
|
14
|
-
import "./token-goat-chunk-
|
|
11
|
+
} from "./token-goat-chunk-QCHD2ENV.mjs";
|
|
12
|
+
import "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
13
|
+
import "./token-goat-chunk-OBDTBOQA.mjs";
|
|
14
|
+
import "./token-goat-chunk-KIEOFWLL.mjs";
|
|
15
15
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
16
16
|
import "./token-goat-chunk-A37V4PBF.mjs";
|
|
17
17
|
export {
|
|
@@ -12,7 +12,7 @@ init_define_import_meta_env();
|
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
function resolveVersion() {
|
|
14
14
|
if (true) {
|
|
15
|
-
return "2.9.
|
|
15
|
+
return "2.9.9";
|
|
16
16
|
}
|
|
17
17
|
const require2 = createRequire(import.meta.url);
|
|
18
18
|
const pkg = require2("../package.json");
|
|
@@ -9636,6 +9636,25 @@ function remapToolInput(copilotToolName, input) {
|
|
|
9636
9636
|
if (idKey !== undefined && idKey in out) {
|
|
9637
9637
|
out = Object.assign({}, out, { bash_id: out[idKey] })
|
|
9638
9638
|
}
|
|
9639
|
+
if (Array.isArray(out.view_range) && out.view_range.length >= 1) {
|
|
9640
|
+
const rawStart = Number(out.view_range[0])
|
|
9641
|
+
if (Number.isFinite(rawStart) && rawStart >= 1) {
|
|
9642
|
+
const mapped = { offset: Math.floor(rawStart) }
|
|
9643
|
+
if (out.view_range.length >= 2) {
|
|
9644
|
+
const rawEnd = Number(out.view_range[1])
|
|
9645
|
+
if (Number.isFinite(rawEnd) && rawEnd >= rawStart) {
|
|
9646
|
+
mapped.limit = Math.floor(rawEnd - rawStart + 1)
|
|
9647
|
+
}
|
|
9648
|
+
}
|
|
9649
|
+
out = Object.assign({}, out, mapped)
|
|
9650
|
+
}
|
|
9651
|
+
}
|
|
9652
|
+
if ('old_str' in out && !('old_string' in out)) {
|
|
9653
|
+
out = Object.assign({}, out, { old_string: out.old_str })
|
|
9654
|
+
}
|
|
9655
|
+
if ('new_str' in out && !('new_string' in out)) {
|
|
9656
|
+
out = Object.assign({}, out, { new_string: out.new_str })
|
|
9657
|
+
}
|
|
9639
9658
|
return out
|
|
9640
9659
|
}
|
|
9641
9660
|
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
walkProject,
|
|
68
68
|
yamlLineClosesQuote,
|
|
69
69
|
yamlOpenQuoteAfter
|
|
70
|
-
} from "./token-goat-chunk-
|
|
70
|
+
} from "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
71
71
|
import {
|
|
72
72
|
Database,
|
|
73
73
|
PER_FILE_COUNTERFACTUAL_CEILING,
|
|
@@ -125,7 +125,7 @@ import {
|
|
|
125
125
|
unsupportedLanguageName,
|
|
126
126
|
windowsCmdQuoteArg,
|
|
127
127
|
withExtension
|
|
128
|
-
} from "./token-goat-chunk-
|
|
128
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
129
129
|
import {
|
|
130
130
|
registerReset
|
|
131
131
|
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
runSkeleton,
|
|
26
26
|
runSymbol,
|
|
27
27
|
withPinnedReads
|
|
28
|
-
} from "./token-goat-chunk-
|
|
28
|
+
} from "./token-goat-chunk-L6Q2XM5X.mjs";
|
|
29
29
|
import {
|
|
30
30
|
buildProjectMap,
|
|
31
31
|
embeddingsDepsAvailable,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
getProjectIndexCounts,
|
|
35
35
|
isWorkerRunning,
|
|
36
36
|
mapLookupBytesSaved
|
|
37
|
-
} from "./token-goat-chunk-
|
|
37
|
+
} from "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
38
38
|
import {
|
|
39
39
|
ENV_KEYS,
|
|
40
40
|
VERSION,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
recordStat,
|
|
49
49
|
resolveProjectRoot,
|
|
50
50
|
savedTokensFromBytes
|
|
51
|
-
} from "./token-goat-chunk-
|
|
51
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
52
52
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
53
53
|
import {
|
|
54
54
|
init_define_import_meta_env
|
|
@@ -2,7 +2,7 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
detectHarness
|
|
5
|
-
} from "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
6
6
|
import {
|
|
7
7
|
init_define_import_meta_env
|
|
8
8
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
storeWebOutput,
|
|
19
19
|
summarizeResidentContext,
|
|
20
20
|
taskListPruneHint
|
|
21
|
-
} from "./token-goat-chunk-
|
|
21
|
+
} from "./token-goat-chunk-QCHD2ENV.mjs";
|
|
22
22
|
import {
|
|
23
23
|
BASH_OUTPUT_SUBDIR,
|
|
24
24
|
GENERIC_SERVED_OUTPUT_KEY,
|
|
@@ -125,12 +125,12 @@ import {
|
|
|
125
125
|
wasCliReadThisSession,
|
|
126
126
|
wasFileReadThisSession,
|
|
127
127
|
wasHintShown
|
|
128
|
-
} from "./token-goat-chunk-
|
|
128
|
+
} from "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
129
129
|
import {
|
|
130
130
|
bashOutputCapBytes,
|
|
131
131
|
canRunWrappedShell,
|
|
132
132
|
deliveredOutputBytes
|
|
133
|
-
} from "./token-goat-chunk-
|
|
133
|
+
} from "./token-goat-chunk-OBDTBOQA.mjs";
|
|
134
134
|
import {
|
|
135
135
|
BODY_FIRST_TOOL_RESPONSE_KEYS,
|
|
136
136
|
ENV_KEYS,
|
|
@@ -194,7 +194,7 @@ import {
|
|
|
194
194
|
stripAnsiEscapes,
|
|
195
195
|
toDisplayPath,
|
|
196
196
|
toKB
|
|
197
|
-
} from "./token-goat-chunk-
|
|
197
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
198
198
|
import {
|
|
199
199
|
init_define_import_meta_env
|
|
200
200
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -798,7 +798,7 @@ init_define_import_meta_env();
|
|
|
798
798
|
var TRACKED_SKILL = "token-goat";
|
|
799
799
|
var MAX_COMMANDS_SHOWN = 8;
|
|
800
800
|
async function currentCommandNames() {
|
|
801
|
-
const { buildProgram } = await import("./token-goat-chunk-
|
|
801
|
+
const { buildProgram } = await import("./token-goat-chunk-DRH4CVGF.mjs");
|
|
802
802
|
return flattenCommandNames(buildCommandManifest(buildProgram()));
|
|
803
803
|
}
|
|
804
804
|
async function recordSkillVersionSnapshot(sessionId, skillName) {
|
|
@@ -9994,8 +9994,8 @@ registerHook("post_tool_use", postTaskOutputHandler, { toolName: "TaskOutput" })
|
|
|
9994
9994
|
|
|
9995
9995
|
// src/hooks_tool_failure.ts
|
|
9996
9996
|
init_define_import_meta_env();
|
|
9997
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
9998
|
-
import { dirname as dirname2 } from "node:path";
|
|
9997
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, statSync as statSync4, writeFileSync as writeFileSync2 } from "node:fs";
|
|
9998
|
+
import { dirname as dirname2, relative } from "node:path";
|
|
9999
9999
|
var FAILURE_SUFFIX = ".tool-failures.json";
|
|
10000
10000
|
var MAX_TRACKED_FAILURES = 64;
|
|
10001
10001
|
var SIGNATURE_ERROR_CHARS = 200;
|
|
@@ -10045,6 +10045,71 @@ function repeatFailureNotice(toolName) {
|
|
|
10045
10045
|
const tool = toolName === void 0 || toolName === "" ? "This tool" : displaySafeText(toolName);
|
|
10046
10046
|
return `[token-goat] ${tool} just failed with the same error as an earlier call this session. Retrying it unchanged will fail the same way -- change the arguments, the tool, or the approach.`;
|
|
10047
10047
|
}
|
|
10048
|
+
var MAX_EDIT_DIAGNOSE_BYTES = 10 * 1024 * 1024;
|
|
10049
|
+
function diagnoseEditFailure(event, errorText) {
|
|
10050
|
+
const toolName = getToolName(event);
|
|
10051
|
+
if (!toolName || !/^(edit|str_replace_editor)$/i.test(toolName)) {
|
|
10052
|
+
return null;
|
|
10053
|
+
}
|
|
10054
|
+
const isMultiple = /multiple matches|not unique|found \d+ matches|matches \d+ times|more than one match/i.test(errorText);
|
|
10055
|
+
const isNotFound = /no match|not found|could not find|zero matches|string to replace.*not found/i.test(errorText);
|
|
10056
|
+
if (!isMultiple && !isNotFound) {
|
|
10057
|
+
return null;
|
|
10058
|
+
}
|
|
10059
|
+
const filePath = getFilePath(event) ?? (typeof event.toolInput["path"] === "string" ? event.toolInput["path"] : void 0);
|
|
10060
|
+
if (!filePath) return null;
|
|
10061
|
+
const oldString = typeof event.toolInput["old_string"] === "string" ? event.toolInput["old_string"] : typeof event.toolInput["old_str"] === "string" ? event.toolInput["old_str"] : typeof event.toolInput["target"] === "string" ? event.toolInput["target"] : void 0;
|
|
10062
|
+
if (oldString === void 0 || oldString === "") return null;
|
|
10063
|
+
const absPath = normalizePath(filePath);
|
|
10064
|
+
if (!existsSync2(absPath)) return null;
|
|
10065
|
+
try {
|
|
10066
|
+
const stat = statSync4(absPath);
|
|
10067
|
+
if (stat.size > MAX_EDIT_DIAGNOSE_BYTES) return null;
|
|
10068
|
+
const fileContent = readFileSync3(absPath, "utf8");
|
|
10069
|
+
const relDisplay = displaySafeText(relative(process.cwd(), absPath).replace(/\\/g, "/") || absPath);
|
|
10070
|
+
if (isMultiple) {
|
|
10071
|
+
const matchLines = [];
|
|
10072
|
+
let pos = 0;
|
|
10073
|
+
while (pos < fileContent.length) {
|
|
10074
|
+
const idx = fileContent.indexOf(oldString, pos);
|
|
10075
|
+
if (idx === -1) break;
|
|
10076
|
+
const line = fileContent.slice(0, idx).split("\n").length;
|
|
10077
|
+
matchLines.push(line);
|
|
10078
|
+
pos = idx + Math.max(1, oldString.length);
|
|
10079
|
+
}
|
|
10080
|
+
if (matchLines.length > 1) {
|
|
10081
|
+
const lineList = matchLines.slice(0, 5).join(", ");
|
|
10082
|
+
const overflow = matchLines.length > 5 ? ` (+${matchLines.length - 5} more)` : "";
|
|
10083
|
+
return `[token-goat] Edit failed: string matched ${matchLines.length} times in ${relDisplay} on lines ${lineList}${overflow}. Include 2-3 lines of surrounding context to make old_str unique.`;
|
|
10084
|
+
}
|
|
10085
|
+
}
|
|
10086
|
+
if (isNotFound) {
|
|
10087
|
+
const normOld = oldString.replace(/\r\n/g, "\n");
|
|
10088
|
+
const normFile = fileContent.replace(/\r\n/g, "\n");
|
|
10089
|
+
if (normFile.includes(normOld)) {
|
|
10090
|
+
return `[token-goat] Edit failed: string not found in ${relDisplay}, but matches with normalized line endings. Check CRLF vs LF line endings or whitespace.`;
|
|
10091
|
+
}
|
|
10092
|
+
const firstLine = oldString.split(/\r?\n/)[0]?.trim() ?? "";
|
|
10093
|
+
if (firstLine.length >= 10) {
|
|
10094
|
+
const fileLines = fileContent.split("\n");
|
|
10095
|
+
const similarLines = [];
|
|
10096
|
+
for (let i = 0; i < fileLines.length; i++) {
|
|
10097
|
+
const lineText = fileLines[i];
|
|
10098
|
+
if (lineText !== void 0 && lineText.includes(firstLine)) {
|
|
10099
|
+
similarLines.push(i + 1);
|
|
10100
|
+
if (similarLines.length >= 3) break;
|
|
10101
|
+
}
|
|
10102
|
+
}
|
|
10103
|
+
if (similarLines.length > 0) {
|
|
10104
|
+
return `[token-goat] Edit failed: string not found in ${relDisplay}. A similar line was found on line ${similarLines.join(", ")} \u2014 view that range to copy exact text.`;
|
|
10105
|
+
}
|
|
10106
|
+
}
|
|
10107
|
+
return `[token-goat] Edit failed: string not found in ${relDisplay}. View the target lines to copy the exact current content and indentation.`;
|
|
10108
|
+
}
|
|
10109
|
+
} catch {
|
|
10110
|
+
}
|
|
10111
|
+
return null;
|
|
10112
|
+
}
|
|
10048
10113
|
function postToolUseFailureHandler(event) {
|
|
10049
10114
|
try {
|
|
10050
10115
|
if (!event.sessionId) return passOutput();
|
|
@@ -10056,6 +10121,7 @@ function postToolUseFailureHandler(event) {
|
|
|
10056
10121
|
const signature = failureSignature(toolName, errorText);
|
|
10057
10122
|
const ledger = readLedger(target);
|
|
10058
10123
|
const priorState = ledger.seen[signature];
|
|
10124
|
+
const editDiagnostic = diagnoseEditFailure(event, errorText);
|
|
10059
10125
|
if (priorState === void 0) {
|
|
10060
10126
|
ledger.seen[signature] = false;
|
|
10061
10127
|
ledger.order.push(signature);
|
|
@@ -10064,11 +10130,19 @@ function postToolUseFailureHandler(event) {
|
|
|
10064
10130
|
if (evicted !== void 0) delete ledger.seen[evicted];
|
|
10065
10131
|
}
|
|
10066
10132
|
writeLedger(target, ledger);
|
|
10133
|
+
if (editDiagnostic !== null) {
|
|
10134
|
+
ledger.seen[signature] = true;
|
|
10135
|
+
writeLedger(target, ledger);
|
|
10136
|
+
return contextOutput(editDiagnostic);
|
|
10137
|
+
}
|
|
10067
10138
|
return passOutput();
|
|
10068
10139
|
}
|
|
10069
10140
|
if (priorState) return passOutput();
|
|
10070
10141
|
ledger.seen[signature] = true;
|
|
10071
10142
|
writeLedger(target, ledger);
|
|
10143
|
+
if (editDiagnostic !== null) {
|
|
10144
|
+
return contextOutput(editDiagnostic);
|
|
10145
|
+
}
|
|
10072
10146
|
return contextOutput(repeatFailureNotice(toolName));
|
|
10073
10147
|
} catch {
|
|
10074
10148
|
return passOutput();
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
runZipRead,
|
|
87
87
|
symbolNamesInFile,
|
|
88
88
|
upsertNote
|
|
89
|
-
} from "./token-goat-chunk-
|
|
89
|
+
} from "./token-goat-chunk-L6Q2XM5X.mjs";
|
|
90
90
|
import {
|
|
91
91
|
DEFAULT_RECONCILE_BUDGET_MS,
|
|
92
92
|
GEMINI_TOOL_NAME_MAP,
|
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
runReconcile,
|
|
109
109
|
storeWebOutput,
|
|
110
110
|
summarizeResidentContext
|
|
111
|
-
} from "./token-goat-chunk-
|
|
111
|
+
} from "./token-goat-chunk-QCHD2ENV.mjs";
|
|
112
112
|
import {
|
|
113
113
|
AGENT_SALT_MARKER,
|
|
114
114
|
BASH_OUTPUT_SUBDIR,
|
|
@@ -238,7 +238,7 @@ import {
|
|
|
238
238
|
visionTokensSavedByText,
|
|
239
239
|
walkProject,
|
|
240
240
|
writeCompact
|
|
241
|
-
} from "./token-goat-chunk-
|
|
241
|
+
} from "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
242
242
|
import {
|
|
243
243
|
C,
|
|
244
244
|
CONFIG_KEY_ENV_OVERRIDES,
|
|
@@ -372,7 +372,7 @@ import {
|
|
|
372
372
|
withFileLock,
|
|
373
373
|
withRetryOnLock,
|
|
374
374
|
writeJsonSettings
|
|
375
|
-
} from "./token-goat-chunk-
|
|
375
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
376
376
|
import {
|
|
377
377
|
__export,
|
|
378
378
|
init_define_import_meta_env
|
|
@@ -15761,7 +15761,7 @@ async function cmdMcpServe() {
|
|
|
15761
15761
|
let StdioServerTransport;
|
|
15762
15762
|
try {
|
|
15763
15763
|
;
|
|
15764
|
-
({ createMcpServer } = await import("./token-goat-chunk-
|
|
15764
|
+
({ createMcpServer } = await import("./token-goat-chunk-LQ3SGWIW.mjs"));
|
|
15765
15765
|
({ StdioServerTransport } = await import("./token-goat-chunk-EVC4TOLE.mjs"));
|
|
15766
15766
|
} catch (err2) {
|
|
15767
15767
|
process.stderr.write(
|
|
@@ -15786,7 +15786,7 @@ async function cmdHook(event, opts) {
|
|
|
15786
15786
|
if (typeof opts.harness === "string" && opts.harness.length > 0) {
|
|
15787
15787
|
process.env[ENV_KEYS.HARNESS_OVERRIDE] = opts.harness;
|
|
15788
15788
|
}
|
|
15789
|
-
const { relay } = await import("./token-goat-chunk-
|
|
15789
|
+
const { relay } = await import("./token-goat-chunk-K5GKX6ND.mjs");
|
|
15790
15790
|
await relay(event);
|
|
15791
15791
|
}
|
|
15792
15792
|
async function cmdInstall(opts) {
|
|
@@ -16719,7 +16719,7 @@ function emitExtraFileArgsNote(command, first, extras, opts = {}) {
|
|
|
16719
16719
|
}
|
|
16720
16720
|
async function cmdCompress(opts) {
|
|
16721
16721
|
try {
|
|
16722
|
-
const bashRunner = await import("./token-goat-chunk-
|
|
16722
|
+
const bashRunner = await import("./token-goat-chunk-WBPVYAEO.mjs");
|
|
16723
16723
|
if (opts.compress === false) {
|
|
16724
16724
|
process.exitCode = bashRunner.runRaw(opts.cmd, parseTimeout(opts.timeout, bashRunner.DEFAULT_TIMEOUT_SECONDS));
|
|
16725
16725
|
return;
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isBlobStale,
|
|
10
10
|
loadBlob,
|
|
11
11
|
storeBlob
|
|
12
|
-
} from "./token-goat-chunk-
|
|
12
|
+
} from "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
13
13
|
import {
|
|
14
14
|
SYMBOL_BODY_CHAR_CAP,
|
|
15
15
|
copilotCliMcpToolsDir,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveIndexPath,
|
|
26
26
|
shortFingerprint,
|
|
27
27
|
toDisplayPath
|
|
28
|
-
} from "./token-goat-chunk-
|
|
28
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
29
29
|
import {
|
|
30
30
|
registerReset
|
|
31
31
|
} from "./token-goat-chunk-EEIDFMEM.mjs";
|
|
@@ -3,7 +3,7 @@ const require = __cjsRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
deliveredOutputBytes,
|
|
5
5
|
wrappedShell
|
|
6
|
-
} from "./token-goat-chunk-
|
|
6
|
+
} from "./token-goat-chunk-OBDTBOQA.mjs";
|
|
7
7
|
import {
|
|
8
8
|
ToolFilter,
|
|
9
9
|
capTokens,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
recordStat,
|
|
16
16
|
selectFilter,
|
|
17
17
|
shlexSplit
|
|
18
|
-
} from "./token-goat-chunk-
|
|
18
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
19
19
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
20
20
|
import {
|
|
21
21
|
init_define_import_meta_env
|
package/dist/token-goat-hook.mjs
CHANGED
|
@@ -2,11 +2,11 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
relayInProcess
|
|
5
|
-
} from "./token-goat-chunk-
|
|
6
|
-
import "./token-goat-chunk-
|
|
7
|
-
import "./token-goat-chunk-
|
|
8
|
-
import "./token-goat-chunk-
|
|
9
|
-
import "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-P5SQX2VK.mjs";
|
|
6
|
+
import "./token-goat-chunk-QCHD2ENV.mjs";
|
|
7
|
+
import "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
8
|
+
import "./token-goat-chunk-OBDTBOQA.mjs";
|
|
9
|
+
import "./token-goat-chunk-KIEOFWLL.mjs";
|
|
10
10
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
11
11
|
import {
|
|
12
12
|
init_define_import_meta_env
|
package/dist/token-goat.core.mjs
CHANGED
|
@@ -2,13 +2,13 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
run
|
|
5
|
-
} from "./token-goat-chunk-
|
|
6
|
-
import "./token-goat-chunk-
|
|
7
|
-
import "./token-goat-chunk-
|
|
8
|
-
import "./token-goat-chunk-
|
|
5
|
+
} from "./token-goat-chunk-PNMGVJ4C.mjs";
|
|
6
|
+
import "./token-goat-chunk-L6Q2XM5X.mjs";
|
|
7
|
+
import "./token-goat-chunk-QCHD2ENV.mjs";
|
|
8
|
+
import "./token-goat-chunk-BYDDWQ2T.mjs";
|
|
9
9
|
import {
|
|
10
10
|
installEpipeGuard
|
|
11
|
-
} from "./token-goat-chunk-
|
|
11
|
+
} from "./token-goat-chunk-KIEOFWLL.mjs";
|
|
12
12
|
import "./token-goat-chunk-EEIDFMEM.mjs";
|
|
13
13
|
import {
|
|
14
14
|
init_define_import_meta_env
|
package/docs/security.md
CHANGED
|
@@ -15,7 +15,7 @@ Outbound network is reserved to these explicit cases:
|
|
|
15
15
|
- Google Drive API calls, only if you already authorized Drive in Claude Code. Token-goat never prompts for its own auth.
|
|
16
16
|
- Image fetches from URLs: either explicit via `token-goat fetch-image <url>`, or when the AI agent issues a WebFetch call that returns image content — the hook intercepts and shrinks the image. The URL always originates from the agent's work, not from token-goat itself.
|
|
17
17
|
- `token-goat screenshot <url>` navigates a headless browser to the URL you give it, subject to the target restrictions described below.
|
|
18
|
-
- The first `token-goat semantic` run on a machine downloads the embedding model from `huggingface.co`, pinned to an immutable commit rather than a mutable branch and checked against a recorded SHA-256 and byte length before it is used, and only once `onnxruntime-node` has been installed (see below — it is not part of a default install). Subsequent runs use the local cache, re-verify it, and make no network call. Skip the download entirely by setting `indexing.embeddings_enabled = false` (it is on by default), in which case `semantic` falls back to full-text search.
|
|
18
|
+
- The first `token-goat semantic` run on a machine downloads the embedding model from `huggingface.co`, pinned to an immutable commit rather than a mutable branch and checked against a recorded SHA-256 and byte length before it is used, and only once `onnxruntime-node` has been installed (see below — it is not part of a default install). Subsequent runs use the local cache, re-verify it, and make no network call. Setting `TOKEN_GOAT_MODEL_CACHE_DIR` adds one more place to look before the network: a directory you name that outlives any single data root, which is how a continuous-integration job stops refetching the weights once per worker. A file taken from there is checked against the same recorded digest as a downloaded one and dropped from the shared directory if it fails, so a tampered copy costs a download and cannot substitute different weights. It is an environment variable only, so no project config file can point it anywhere. Skip the download entirely by setting `indexing.embeddings_enabled = false` (it is on by default), in which case `semantic` falls back to full-text search.
|
|
19
19
|
- The first optical-character read of an image downloads the English language data (about 4 MB) from `cdn.jsdelivr.net`, at a fixed version path. Subsequent reads use the local cache. This happens for an explicit `token-goat image-text`, and also for the automatic text extraction the image-shrink hook performs when the agent reads a screenshot; turn the automatic one off with `image_shrink.ocr_enabled = false`.
|
|
20
20
|
|
|
21
21
|
**One switch for all of it.** Set `network.offline = true` (env `TOKEN_GOAT_OFFLINE`) and every one of the paths above refuses instead of connecting, saying so rather than failing quietly. Anything already cached keeps working: a machine that has the embedding model still runs `semantic`, and one that has the language data still reads text out of images. This is one of the settings a per-project config file may not touch, so cloning a repository cannot switch it back off.
|