token-goat 2.6.36 → 2.8.1
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 +36 -8
- package/SECURITY.md +46 -17
- package/dist/{token-goat-chunk-UFOVM7ZN.mjs → token-goat-chunk-2G6RAB4G.mjs} +1391 -378
- package/dist/token-goat-chunk-324QOJYZ.mjs +91 -0
- package/dist/token-goat-chunk-5CVKO3DA.mjs +185 -0
- package/dist/{token-goat-chunk-65BKISIS.mjs → token-goat-chunk-73MF6YWW.mjs} +4 -4
- package/dist/{token-goat-chunk-MGOUYAA2.mjs → token-goat-chunk-7JDXDERZ.mjs} +1 -1
- package/dist/{token-goat-hook-chunk-BDR6C6IE.mjs → token-goat-chunk-AOBZUFNJ.mjs} +318 -51
- package/dist/{token-goat-chunk-V465YKOR.mjs → token-goat-chunk-ELDJRLHZ.mjs} +492 -28
- package/dist/{token-goat-chunk-CNDOJ3ZP.mjs → token-goat-chunk-I6TOUPLP.mjs} +2 -2
- package/dist/token-goat-chunk-R4SR7MQY.mjs +486 -0
- package/dist/{token-goat-chunk-IYTVE6KN.mjs → token-goat-chunk-RMDQFTQD.mjs} +226 -150
- package/dist/{token-goat-chunk-KYFJC37X.mjs → token-goat-chunk-VBXBLGTO.mjs} +792 -144
- package/dist/{token-goat-chunk-DG53MVNJ.mjs → token-goat-chunk-WN5T5EW5.mjs} +212 -212
- package/dist/{token-goat-chunk-VYMGEVZS.mjs → token-goat-chunk-XEDQH5DA.mjs} +317 -11
- package/dist/{token-goat-chunk-LN6OUHTV.mjs → token-goat-chunk-Y2SYNH3S.mjs} +5 -5
- package/dist/token-goat-chunk-YUGNM3KL.mjs +23 -0
- package/dist/token-goat-hook.mjs +7 -7
- package/dist/token-goat.core.mjs +5 -5
- package/package.json +12 -8
- package/dist/token-goat-chunk-FRTBMRP7.mjs +0 -10048
- package/dist/token-goat-hook-chunk-3QYSN4QV.mjs +0 -14764
- package/dist/token-goat-hook-chunk-3ZDBWJDF.mjs +0 -13659
- package/dist/token-goat-hook-chunk-5UH54CW6.mjs +0 -912
- package/dist/token-goat-hook-chunk-6ODM3MP7.mjs +0 -706
- package/dist/token-goat-hook-chunk-A77A26A7.mjs +0 -18184
- package/dist/token-goat-hook-chunk-BUOCULAM.mjs +0 -29
- package/dist/token-goat-hook-chunk-C6GIABOX.mjs +0 -15971
- package/dist/token-goat-hook-chunk-E257IGSN.mjs +0 -153
- package/dist/token-goat-hook-chunk-MW5HPEGD.mjs +0 -10411
- package/dist/token-goat-hook-chunk-QSCYNJ2B.mjs +0 -23
- package/dist/token-goat-hook-chunk-RFRLWOQH.mjs +0 -11
- package/dist/token-goat-hook-chunk-XUMIVYEN.mjs +0 -109
- package/dist/token-goat-hook-chunk-Y2WHX2P3.mjs +0 -6463
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
+
copilotCliMcpToolsDir,
|
|
5
|
+
estimateTokensFromLength,
|
|
4
6
|
isBlobStale,
|
|
5
7
|
isBuildCommand,
|
|
6
8
|
loadBlob,
|
|
7
9
|
sanitizeFtsQuery,
|
|
8
10
|
storeBlob
|
|
9
|
-
} from "./token-goat-chunk-
|
|
11
|
+
} from "./token-goat-chunk-2G6RAB4G.mjs";
|
|
10
12
|
import {
|
|
11
13
|
SYMBOL_BODY_CHAR_CAP,
|
|
12
14
|
extractErrorMessage,
|
|
@@ -16,11 +18,94 @@ import {
|
|
|
16
18
|
redactSecrets,
|
|
17
19
|
runGit,
|
|
18
20
|
shortFingerprint
|
|
19
|
-
} from "./token-goat-chunk-
|
|
21
|
+
} from "./token-goat-chunk-ELDJRLHZ.mjs";
|
|
20
22
|
import {
|
|
21
23
|
registerReset
|
|
22
24
|
} from "./token-goat-chunk-AO2QD2AG.mjs";
|
|
23
25
|
|
|
26
|
+
// src/copilot_mcp_tools.ts
|
|
27
|
+
import fs from "node:fs";
|
|
28
|
+
import path from "node:path";
|
|
29
|
+
function wireShapeLength(tools) {
|
|
30
|
+
const wire = tools.map((tool) => {
|
|
31
|
+
const out = {};
|
|
32
|
+
if (typeof tool.name === "string") out["name"] = tool.name;
|
|
33
|
+
if (typeof tool.description === "string") out["description"] = tool.description;
|
|
34
|
+
if (tool.inputSchema !== void 0) out["inputSchema"] = tool.inputSchema;
|
|
35
|
+
return out;
|
|
36
|
+
});
|
|
37
|
+
return JSON.stringify(wire).length;
|
|
38
|
+
}
|
|
39
|
+
function readCopilotMcpTools(dir = copilotCliMcpToolsDir()) {
|
|
40
|
+
let entries;
|
|
41
|
+
try {
|
|
42
|
+
entries = fs.readdirSync(dir);
|
|
43
|
+
} catch {
|
|
44
|
+
return { cacheFound: false, servers: [], unreadable: 0 };
|
|
45
|
+
}
|
|
46
|
+
const newest = /* @__PURE__ */ new Map();
|
|
47
|
+
let unreadable = 0;
|
|
48
|
+
for (const entry of entries) {
|
|
49
|
+
if (!entry.toLowerCase().endsWith(".json")) continue;
|
|
50
|
+
let parsed;
|
|
51
|
+
try {
|
|
52
|
+
parsed = JSON.parse(fs.readFileSync(path.join(dir, entry), "utf8"));
|
|
53
|
+
} catch {
|
|
54
|
+
unreadable += 1;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
58
|
+
unreadable += 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const record = parsed;
|
|
62
|
+
const serverName = typeof record.serverName === "string" ? record.serverName.trim() : "";
|
|
63
|
+
if (serverName === "") {
|
|
64
|
+
unreadable += 1;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const tools = Array.isArray(record.tools) ? record.tools : [];
|
|
68
|
+
const updatedAt = typeof record.updatedAt === "string" ? record.updatedAt : "";
|
|
69
|
+
const definitionBytes = wireShapeLength(tools);
|
|
70
|
+
const candidate = {
|
|
71
|
+
serverName,
|
|
72
|
+
toolCount: tools.length,
|
|
73
|
+
definitionBytes,
|
|
74
|
+
estimatedTokens: estimateTokensFromLength(definitionBytes),
|
|
75
|
+
updatedAt,
|
|
76
|
+
// `tools` is an unchecked cast off a JSON array, so every element is
|
|
77
|
+
// treated as untrusted here rather than trusted to match CachedTool.
|
|
78
|
+
toolNames: tools.map((t) => t?.name).filter((n) => typeof n === "string" && n !== "")
|
|
79
|
+
};
|
|
80
|
+
const existing = newest.get(serverName);
|
|
81
|
+
if (existing === void 0 || candidate.updatedAt > existing.updatedAt) newest.set(serverName, candidate);
|
|
82
|
+
}
|
|
83
|
+
const servers = [...newest.values()].sort(
|
|
84
|
+
(a, b) => b.definitionBytes - a.definitionBytes || a.serverName.localeCompare(b.serverName)
|
|
85
|
+
);
|
|
86
|
+
return { cacheFound: true, servers, unreadable };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/copilot_mcp_names.ts
|
|
90
|
+
var _cached = null;
|
|
91
|
+
function copilotMcpToolNameMap() {
|
|
92
|
+
if (_cached) return _cached;
|
|
93
|
+
const map = /* @__PURE__ */ new Map();
|
|
94
|
+
try {
|
|
95
|
+
for (const server of readCopilotMcpTools().servers) {
|
|
96
|
+
for (const toolName of server.toolNames) {
|
|
97
|
+
map.set(`${server.serverName}-${toolName}`, `mcp__${server.serverName}__${toolName}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
_cached = map;
|
|
103
|
+
return map;
|
|
104
|
+
}
|
|
105
|
+
function canonicalizeCopilotMcpToolName(toolName) {
|
|
106
|
+
return copilotMcpToolNameMap().get(toolName) ?? toolName;
|
|
107
|
+
}
|
|
108
|
+
|
|
24
109
|
// src/hooks_cli.ts
|
|
25
110
|
var _LOG = {
|
|
26
111
|
warn: (msg, ...args) => console.warn(`[hooks_cli] ${msg}`, ...args),
|
|
@@ -150,6 +235,12 @@ function normalizePayload(payload, harness = "claude") {
|
|
|
150
235
|
result2["_tg_harness"] = harness;
|
|
151
236
|
return result2;
|
|
152
237
|
}
|
|
238
|
+
if (harness === "copilot_cli") {
|
|
239
|
+
const result2 = { ...obj };
|
|
240
|
+
result2["tool_name"] = canonicalizeCopilotMcpToolName(toolName);
|
|
241
|
+
result2["_tg_harness"] = harness;
|
|
242
|
+
return result2;
|
|
243
|
+
}
|
|
153
244
|
if (harness === "kimi") {
|
|
154
245
|
const result2 = remapToolName(obj, toolName, KIMI_TOOL_NAME_MAP, KIMI_INPUT_KEY_MAP);
|
|
155
246
|
result2["_tg_harness"] = harness;
|
|
@@ -373,11 +464,11 @@ function gitStateFingerprintSync(cwd) {
|
|
|
373
464
|
}
|
|
374
465
|
}
|
|
375
466
|
var DIR_FINGERPRINT_LISTING_CAP_ENTRIES = 1e4;
|
|
376
|
-
function dirStateFingerprintSync(
|
|
467
|
+
function dirStateFingerprintSync(path2) {
|
|
377
468
|
try {
|
|
378
|
-
const stat = statSync(
|
|
469
|
+
const stat = statSync(path2);
|
|
379
470
|
if (!stat.isDirectory()) return null;
|
|
380
|
-
const entries = readdirSync(
|
|
471
|
+
const entries = readdirSync(path2);
|
|
381
472
|
if (entries.length <= DIR_FINGERPRINT_LISTING_CAP_ENTRIES) {
|
|
382
473
|
return shortFingerprint(entries.slice().sort().join("\0"));
|
|
383
474
|
}
|
|
@@ -387,12 +478,12 @@ function dirStateFingerprintSync(path) {
|
|
|
387
478
|
}
|
|
388
479
|
}
|
|
389
480
|
var FILE_FINGERPRINT_CONTENT_CAP_BYTES = 2 * 1024 * 1024;
|
|
390
|
-
function fileStateFingerprintSync(
|
|
481
|
+
function fileStateFingerprintSync(path2) {
|
|
391
482
|
try {
|
|
392
|
-
const stat = statSync(
|
|
483
|
+
const stat = statSync(path2);
|
|
393
484
|
if (!stat.isFile()) return null;
|
|
394
485
|
if (stat.size <= FILE_FINGERPRINT_CONTENT_CAP_BYTES) {
|
|
395
|
-
return shortFingerprint(readFileSync(
|
|
486
|
+
return shortFingerprint(readFileSync(path2));
|
|
396
487
|
}
|
|
397
488
|
return shortFingerprint(`${stat.mtimeMs}\0${stat.size}`);
|
|
398
489
|
} catch {
|
|
@@ -715,9 +806,11 @@ var HOOK_EVENTS = [
|
|
|
715
806
|
"notification",
|
|
716
807
|
"stop",
|
|
717
808
|
"pre_compact",
|
|
809
|
+
"post_compact",
|
|
718
810
|
"user_prompt_submit",
|
|
719
811
|
"subagent_stop",
|
|
720
|
-
"session_start"
|
|
812
|
+
"session_start",
|
|
813
|
+
"post_tool_use_failure"
|
|
721
814
|
];
|
|
722
815
|
|
|
723
816
|
// src/cli_commands.ts
|
|
@@ -855,10 +948,10 @@ function readStdinJson(timeoutMs = DEFAULT_STDIN_TIMEOUT_MS, maxBytes = MAX_STDI
|
|
|
855
948
|
}
|
|
856
949
|
|
|
857
950
|
// src/symbol_body_probe.ts
|
|
858
|
-
import * as
|
|
951
|
+
import * as fs2 from "fs";
|
|
859
952
|
var OVERSIZED_BODY_PROBE_SQL = `SELECT 1 FROM symbols WHERE LENGTH(body) > ${SYMBOL_BODY_CHAR_CAP} LIMIT 1`;
|
|
860
953
|
function checkSymbolBodySize(dbPath) {
|
|
861
|
-
if (!
|
|
954
|
+
if (!fs2.existsSync(dbPath)) {
|
|
862
955
|
return { name: "Symbol body size", status: "ok", message: "no database yet" };
|
|
863
956
|
}
|
|
864
957
|
try {
|
|
@@ -881,7 +974,210 @@ function checkSymbolBodySize(dbPath) {
|
|
|
881
974
|
}
|
|
882
975
|
}
|
|
883
976
|
|
|
977
|
+
// src/resident_context.ts
|
|
978
|
+
import * as fs3 from "node:fs";
|
|
979
|
+
var LARGE_TASK_LIST_BYTES = 2e4;
|
|
980
|
+
var LARGE_SKILL_BODY_BYTES = 2e4;
|
|
981
|
+
var SKILL_BODY_REPEAT_THRESHOLD = 2;
|
|
982
|
+
var RESIDENT_TAIL_MAX_BYTES = 1048576;
|
|
983
|
+
function createResidentContextStats() {
|
|
984
|
+
return {
|
|
985
|
+
attachmentsByType: /* @__PURE__ */ new Map(),
|
|
986
|
+
latestTaskList: null,
|
|
987
|
+
taskReminderCount: 0,
|
|
988
|
+
taskReminderBytes: 0,
|
|
989
|
+
skillBodies: /* @__PURE__ */ new Map(),
|
|
990
|
+
compactionCount: 0
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
function bump(map, key, bytes) {
|
|
994
|
+
const entry = map.get(key);
|
|
995
|
+
if (entry === void 0) map.set(key, { count: 1, bytes });
|
|
996
|
+
else {
|
|
997
|
+
entry.count += 1;
|
|
998
|
+
entry.bytes += bytes;
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
function messageText(message) {
|
|
1002
|
+
if (message === null || typeof message !== "object") return "";
|
|
1003
|
+
const content = message["content"];
|
|
1004
|
+
if (typeof content === "string") return content;
|
|
1005
|
+
if (!Array.isArray(content)) return "";
|
|
1006
|
+
let out = "";
|
|
1007
|
+
for (const block of content) {
|
|
1008
|
+
if (block === null || typeof block !== "object") continue;
|
|
1009
|
+
const text = block["text"];
|
|
1010
|
+
if (typeof text === "string") out += text;
|
|
1011
|
+
}
|
|
1012
|
+
return out;
|
|
1013
|
+
}
|
|
1014
|
+
function skillNameFromBody(text) {
|
|
1015
|
+
const dir = /^Base directory for this skill:\s*(.+?)\s*$/m.exec(text);
|
|
1016
|
+
if (dir?.[1] !== void 0) {
|
|
1017
|
+
const segments = dir[1].split(/[\\/]/).filter((s) => s.length > 0);
|
|
1018
|
+
const last = segments[segments.length - 1];
|
|
1019
|
+
if (last !== void 0 && last.length > 0) return last;
|
|
1020
|
+
}
|
|
1021
|
+
const heading = /^#\s+(.+?)\s*$/m.exec(text);
|
|
1022
|
+
if (heading?.[1] !== void 0 && heading[1].length > 0) return heading[1];
|
|
1023
|
+
return null;
|
|
1024
|
+
}
|
|
1025
|
+
function readTaskList(attachment, bytes) {
|
|
1026
|
+
const snapshot = {
|
|
1027
|
+
bytes,
|
|
1028
|
+
itemCount: typeof attachment["itemCount"] === "number" ? attachment["itemCount"] : 0,
|
|
1029
|
+
completed: 0,
|
|
1030
|
+
inProgress: 0,
|
|
1031
|
+
pending: 0,
|
|
1032
|
+
descriptionBytes: 0,
|
|
1033
|
+
completedDescriptionBytes: 0
|
|
1034
|
+
};
|
|
1035
|
+
const content = attachment["content"];
|
|
1036
|
+
if (!Array.isArray(content)) return snapshot;
|
|
1037
|
+
if (content.length > snapshot.itemCount) snapshot.itemCount = content.length;
|
|
1038
|
+
for (const item of content) {
|
|
1039
|
+
if (item === null || typeof item !== "object") continue;
|
|
1040
|
+
const record = item;
|
|
1041
|
+
const status = typeof record["status"] === "string" ? record["status"] : "";
|
|
1042
|
+
const description = typeof record["description"] === "string" ? record["description"] : "";
|
|
1043
|
+
snapshot.descriptionBytes += description.length;
|
|
1044
|
+
if (status === "completed") {
|
|
1045
|
+
snapshot.completed += 1;
|
|
1046
|
+
snapshot.completedDescriptionBytes += description.length;
|
|
1047
|
+
} else if (status === "in_progress") snapshot.inProgress += 1;
|
|
1048
|
+
else if (status === "pending") snapshot.pending += 1;
|
|
1049
|
+
}
|
|
1050
|
+
return snapshot;
|
|
1051
|
+
}
|
|
1052
|
+
function collectInvokedSkills(acc, record) {
|
|
1053
|
+
const skills = record["skills"];
|
|
1054
|
+
if (!Array.isArray(skills)) return;
|
|
1055
|
+
for (const entry of skills) {
|
|
1056
|
+
if (entry === null || typeof entry !== "object") continue;
|
|
1057
|
+
const skill = entry;
|
|
1058
|
+
const content = skill["content"];
|
|
1059
|
+
if (typeof content !== "string" || content.length < LARGE_SKILL_BODY_BYTES) continue;
|
|
1060
|
+
const name = skillName(skill);
|
|
1061
|
+
if (name !== null) bump(acc.skillBodies, name, content.length);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
function skillName(skill) {
|
|
1065
|
+
const name = skill["name"];
|
|
1066
|
+
if (typeof name === "string" && name.trim() !== "") return name.trim();
|
|
1067
|
+
const path2 = skill["path"];
|
|
1068
|
+
if (typeof path2 !== "string") return null;
|
|
1069
|
+
const segments = path2.split(/[\\/]/).filter((part) => part !== "");
|
|
1070
|
+
const last = segments[segments.length - 1];
|
|
1071
|
+
return last === void 0 || last === "" ? null : last;
|
|
1072
|
+
}
|
|
1073
|
+
function accumulateResidentLine(acc, parsed, bytes) {
|
|
1074
|
+
try {
|
|
1075
|
+
if (parsed === null || typeof parsed !== "object") return;
|
|
1076
|
+
const line = parsed;
|
|
1077
|
+
if (line["type"] === "system" && line["subtype"] === "compact_boundary") acc.compactionCount += 1;
|
|
1078
|
+
const attachment = line["attachment"];
|
|
1079
|
+
if (attachment !== null && typeof attachment === "object") {
|
|
1080
|
+
const record = attachment;
|
|
1081
|
+
const type = typeof record["type"] === "string" ? record["type"] : "unknown";
|
|
1082
|
+
bump(acc.attachmentsByType, type, bytes);
|
|
1083
|
+
if (type === "task_reminder") {
|
|
1084
|
+
acc.taskReminderCount += 1;
|
|
1085
|
+
acc.taskReminderBytes += bytes;
|
|
1086
|
+
acc.latestTaskList = readTaskList(record, bytes);
|
|
1087
|
+
}
|
|
1088
|
+
if (type === "invoked_skills") collectInvokedSkills(acc, record);
|
|
1089
|
+
}
|
|
1090
|
+
if (line["isMeta"] === true && line["type"] === "user") {
|
|
1091
|
+
const text = messageText(line["message"]);
|
|
1092
|
+
if (text.length >= LARGE_SKILL_BODY_BYTES) {
|
|
1093
|
+
const skill = skillNameFromBody(text);
|
|
1094
|
+
if (skill !== null) bump(acc.skillBodies, skill, text.length);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
} catch {
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
function summarizeResidentContext(acc) {
|
|
1101
|
+
const attachmentClasses = [...acc.attachmentsByType.entries()].map(([type, v]) => ({ type, count: v.count, bytes: v.bytes })).sort((a, b) => b.bytes - a.bytes || a.type.localeCompare(b.type));
|
|
1102
|
+
const repeatedSkillBodies = [...acc.skillBodies.entries()].filter(([, v]) => v.count >= SKILL_BODY_REPEAT_THRESHOLD).map(([skill, v]) => ({ skill, count: v.count, bytes: v.bytes })).sort((a, b) => b.bytes - a.bytes || a.skill.localeCompare(b.skill));
|
|
1103
|
+
return {
|
|
1104
|
+
attachmentClasses,
|
|
1105
|
+
totalAttachmentBytes: attachmentClasses.reduce((n, c) => n + c.bytes, 0),
|
|
1106
|
+
latestTaskList: acc.latestTaskList,
|
|
1107
|
+
taskReminderCount: acc.taskReminderCount,
|
|
1108
|
+
taskReminderBytes: acc.taskReminderBytes,
|
|
1109
|
+
repeatedSkillBodies,
|
|
1110
|
+
compactionCount: acc.compactionCount
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
function formatBytes(bytes) {
|
|
1114
|
+
if (bytes >= 1e6) return `${(bytes / 1048576).toFixed(1)} MB`;
|
|
1115
|
+
if (bytes >= 1e3) return `${Math.round(bytes / 1024)} KB`;
|
|
1116
|
+
return `${bytes} B`;
|
|
1117
|
+
}
|
|
1118
|
+
function formatTokenEstimate(tokens) {
|
|
1119
|
+
return tokens >= 1e3 ? `${Math.round(tokens / 1e3)}K` : String(tokens);
|
|
1120
|
+
}
|
|
1121
|
+
function taskListPruneHint(snapshot) {
|
|
1122
|
+
if (snapshot === null) return null;
|
|
1123
|
+
if (snapshot.bytes < LARGE_TASK_LIST_BYTES) return null;
|
|
1124
|
+
if (snapshot.completed === 0) return null;
|
|
1125
|
+
const tokens = formatTokenEstimate(estimateTokensFromLength(snapshot.bytes));
|
|
1126
|
+
const prunable = formatBytes(snapshot.completedDescriptionBytes);
|
|
1127
|
+
return `Your task list is ${formatBytes(snapshot.bytes)} (~${tokens} tok est) and is re-injected in full whenever it changes; ${snapshot.completed} of ${snapshot.itemCount} items are already completed and their descriptions alone are ${prunable}. Prune completed items or shorten their descriptions with TaskUpdate. Check ownership first if other agents share this list.`;
|
|
1128
|
+
}
|
|
1129
|
+
function repeatedSkillBodyHint(injections) {
|
|
1130
|
+
const worst = injections[0];
|
|
1131
|
+
if (worst === void 0) return null;
|
|
1132
|
+
if (worst.count < SKILL_BODY_REPEAT_THRESHOLD || worst.bytes < LARGE_SKILL_BODY_BYTES) return null;
|
|
1133
|
+
const tokens = formatTokenEstimate(estimateTokensFromLength(worst.bytes));
|
|
1134
|
+
return `The \`${worst.skill}\` skill body has been injected ${worst.count} times this session (${formatBytes(worst.bytes)} total, ~${tokens} tok est). Slash expansion and the Skill tool both send the whole body every time, and no hook can intercept either. If it is already loaded, work from it instead of re-invoking; to reread one part, use \`token-goat skill-section ${worst.skill} '<heading>'\`.`;
|
|
1135
|
+
}
|
|
1136
|
+
function readTranscriptTail(transcriptPath, maxBytes = RESIDENT_TAIL_MAX_BYTES) {
|
|
1137
|
+
let fd = null;
|
|
1138
|
+
try {
|
|
1139
|
+
const stat = fs3.statSync(transcriptPath);
|
|
1140
|
+
if (!stat.isFile() || stat.size === 0) return [];
|
|
1141
|
+
const start = Math.max(0, stat.size - maxBytes);
|
|
1142
|
+
const length = stat.size - start;
|
|
1143
|
+
fd = fs3.openSync(transcriptPath, "r");
|
|
1144
|
+
const buf = Buffer.allocUnsafe(length);
|
|
1145
|
+
const read = fs3.readSync(fd, buf, 0, length, start);
|
|
1146
|
+
const lines = buf.subarray(0, read).toString("utf8").split("\n");
|
|
1147
|
+
if (start > 0) lines.shift();
|
|
1148
|
+
return lines;
|
|
1149
|
+
} catch {
|
|
1150
|
+
return [];
|
|
1151
|
+
} finally {
|
|
1152
|
+
if (fd !== null) {
|
|
1153
|
+
try {
|
|
1154
|
+
fs3.closeSync(fd);
|
|
1155
|
+
} catch {
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
function lineMayCarryResidentSignal(line) {
|
|
1161
|
+
return line.includes('"task_reminder"') || line.includes('"compact_boundary"') || line.includes('"invoked_skills"') || line.includes('"isMeta"');
|
|
1162
|
+
}
|
|
1163
|
+
function accumulateResidentLines(lines) {
|
|
1164
|
+
const acc = createResidentContextStats();
|
|
1165
|
+
for (const line of lines) {
|
|
1166
|
+
const trimmed = line.trim();
|
|
1167
|
+
if (trimmed === "") continue;
|
|
1168
|
+
let parsed;
|
|
1169
|
+
try {
|
|
1170
|
+
parsed = JSON.parse(trimmed);
|
|
1171
|
+
} catch {
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
accumulateResidentLine(acc, parsed, trimmed.length);
|
|
1175
|
+
}
|
|
1176
|
+
return acc;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
884
1179
|
export {
|
|
1180
|
+
readCopilotMcpTools,
|
|
885
1181
|
GEMINI_TOOL_NAME_MAP,
|
|
886
1182
|
normalizePayload,
|
|
887
1183
|
isRecallCacheType,
|
|
@@ -907,6 +1203,16 @@ export {
|
|
|
907
1203
|
filterCommandManifest,
|
|
908
1204
|
formatCommandManifest,
|
|
909
1205
|
checkSymbolBodySize,
|
|
1206
|
+
createResidentContextStats,
|
|
1207
|
+
accumulateResidentLine,
|
|
1208
|
+
summarizeResidentContext,
|
|
1209
|
+
formatBytes,
|
|
1210
|
+
formatTokenEstimate,
|
|
1211
|
+
taskListPruneHint,
|
|
1212
|
+
repeatedSkillBodyHint,
|
|
1213
|
+
readTranscriptTail,
|
|
1214
|
+
lineMayCarryResidentSignal,
|
|
1215
|
+
accumulateResidentLines,
|
|
910
1216
|
MAX_STDIN_BYTES,
|
|
911
1217
|
readStdinJson
|
|
912
1218
|
};
|
|
@@ -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-VBXBLGTO.mjs";
|
|
11
|
+
import "./token-goat-chunk-RMDQFTQD.mjs";
|
|
12
|
+
import "./token-goat-chunk-XEDQH5DA.mjs";
|
|
13
|
+
import "./token-goat-chunk-2G6RAB4G.mjs";
|
|
14
|
+
import "./token-goat-chunk-ELDJRLHZ.mjs";
|
|
15
15
|
import "./token-goat-chunk-AO2QD2AG.mjs";
|
|
16
16
|
import "./token-goat-chunk-AEX54RUZ.mjs";
|
|
17
17
|
export {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createRequire as __cjsRequire } from 'node:module';
|
|
2
|
+
const require = __cjsRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
buildEvent,
|
|
5
|
+
relay,
|
|
6
|
+
relayInProcess
|
|
7
|
+
} from "./token-goat-chunk-AOBZUFNJ.mjs";
|
|
8
|
+
import {
|
|
9
|
+
MAX_STDIN_BYTES,
|
|
10
|
+
readStdinJson
|
|
11
|
+
} from "./token-goat-chunk-XEDQH5DA.mjs";
|
|
12
|
+
import "./token-goat-chunk-2G6RAB4G.mjs";
|
|
13
|
+
import "./token-goat-chunk-7JDXDERZ.mjs";
|
|
14
|
+
import "./token-goat-chunk-ELDJRLHZ.mjs";
|
|
15
|
+
import "./token-goat-chunk-AO2QD2AG.mjs";
|
|
16
|
+
import "./token-goat-chunk-AEX54RUZ.mjs";
|
|
17
|
+
export {
|
|
18
|
+
MAX_STDIN_BYTES,
|
|
19
|
+
buildEvent,
|
|
20
|
+
readStdinJson,
|
|
21
|
+
relay,
|
|
22
|
+
relayInProcess
|
|
23
|
+
};
|
package/dist/token-goat-hook.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
|
relayInProcess
|
|
5
|
-
} from "./token-goat-
|
|
6
|
-
import "./token-goat-
|
|
7
|
-
import "./token-goat-
|
|
8
|
-
import "./token-goat-
|
|
9
|
-
import "./token-goat-
|
|
10
|
-
import "./token-goat-
|
|
11
|
-
import "./token-goat-
|
|
5
|
+
} from "./token-goat-chunk-AOBZUFNJ.mjs";
|
|
6
|
+
import "./token-goat-chunk-XEDQH5DA.mjs";
|
|
7
|
+
import "./token-goat-chunk-2G6RAB4G.mjs";
|
|
8
|
+
import "./token-goat-chunk-7JDXDERZ.mjs";
|
|
9
|
+
import "./token-goat-chunk-ELDJRLHZ.mjs";
|
|
10
|
+
import "./token-goat-chunk-AO2QD2AG.mjs";
|
|
11
|
+
import "./token-goat-chunk-AEX54RUZ.mjs";
|
|
12
12
|
export {
|
|
13
13
|
relayInProcess
|
|
14
14
|
};
|
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-VBXBLGTO.mjs";
|
|
6
|
+
import "./token-goat-chunk-RMDQFTQD.mjs";
|
|
7
|
+
import "./token-goat-chunk-XEDQH5DA.mjs";
|
|
8
|
+
import "./token-goat-chunk-2G6RAB4G.mjs";
|
|
9
9
|
import {
|
|
10
10
|
installEpipeGuard
|
|
11
|
-
} from "./token-goat-chunk-
|
|
11
|
+
} from "./token-goat-chunk-ELDJRLHZ.mjs";
|
|
12
12
|
import "./token-goat-chunk-AO2QD2AG.mjs";
|
|
13
13
|
import "./token-goat-chunk-AEX54RUZ.mjs";
|
|
14
14
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-goat",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.1",
|
|
4
4
|
"description": "Surgical token-reduction companion for Claude Code and other AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/token-goat.mjs",
|
|
@@ -30,7 +30,9 @@
|
|
|
30
30
|
"typecheck:vscode-extension": "npm --prefix vscode-extension run compile",
|
|
31
31
|
"typecheck:vscode-extension:tests": "npm --prefix vscode-extension run typecheck:tests",
|
|
32
32
|
"dev": "tsx src/main.ts",
|
|
33
|
-
"prepare": "node scripts/install-git-hooks.mjs"
|
|
33
|
+
"prepare": "node scripts/install-git-hooks.mjs",
|
|
34
|
+
"schema:copilot": "node scripts/extract_harness_schema.mjs auto --harness copilot_cli --out schemas/copilot_cli.hooks.json",
|
|
35
|
+
"schema:copilot:check": "node scripts/extract_harness_schema.mjs auto --harness copilot_cli --out schemas/copilot_cli.hooks.json --check"
|
|
34
36
|
},
|
|
35
37
|
"contributors": [
|
|
36
38
|
{
|
|
@@ -56,24 +58,28 @@
|
|
|
56
58
|
],
|
|
57
59
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
58
60
|
"engines": {
|
|
59
|
-
"node": ">=22.
|
|
61
|
+
"node": ">=22.16.0"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"better-sqlite3": "^12.11.1",
|
|
63
64
|
"jsonc-parser": "^3.3.1"
|
|
64
65
|
},
|
|
65
66
|
"devDependencies": {
|
|
66
67
|
"@eslint/js": "^10.0.1",
|
|
68
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
67
69
|
"@types/better-sqlite3": "^9.6.0",
|
|
68
70
|
"@types/node": "^26.2.0",
|
|
71
|
+
"@xenova/transformers": "^2.17.2",
|
|
72
|
+
"better-sqlite3": "^12.11.1",
|
|
69
73
|
"commander": "^15.0.0",
|
|
70
74
|
"csv-parse": "^7.0.2",
|
|
71
75
|
"esbuild": "^0.28.2",
|
|
72
76
|
"eslint": "^10.8.1",
|
|
73
77
|
"exceljs": "^4.4.0",
|
|
78
|
+
"fast-xml-parser": "^5.9.3",
|
|
74
79
|
"html-to-text": "^10.0.1",
|
|
75
80
|
"js-yaml": "^5.2.1",
|
|
76
81
|
"lefthook": "^2.1.10",
|
|
82
|
+
"onnxruntime-node": "^1.27.0",
|
|
77
83
|
"smol-toml": "^1.8.0",
|
|
78
84
|
"tsx": "^4.23.12",
|
|
79
85
|
"typescript": "^6.0.3",
|
|
@@ -82,9 +88,6 @@
|
|
|
82
88
|
"zod": "^4.4.3"
|
|
83
89
|
},
|
|
84
90
|
"optionalDependencies": {
|
|
85
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
86
|
-
"@xenova/transformers": "^2.17.2",
|
|
87
|
-
"fast-xml-parser": "^5.9.3",
|
|
88
91
|
"fflate": "^0.8.3",
|
|
89
92
|
"pdfjs-dist": "^6.1.200",
|
|
90
93
|
"puppeteer-core": "^25.8.0",
|
|
@@ -108,6 +111,7 @@
|
|
|
108
111
|
"deepmerge-ts": "^8.0.1",
|
|
109
112
|
"uuid": "^14.0.1",
|
|
110
113
|
"sharp": "^0.35.3",
|
|
111
|
-
"unzipper": "^0.12.5"
|
|
114
|
+
"unzipper": "^0.12.5",
|
|
115
|
+
"adm-zip": "^0.6.0"
|
|
112
116
|
}
|
|
113
117
|
}
|