@tokmizer/plugin 0.9.57 → 0.9.59
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +11 -0
- package/README.md +214 -8
- package/agent-plugins/amp.js +38 -0
- package/agent-plugins/hermes/__init__.py +53 -0
- package/agent-plugins/hermes/plugin.yaml +5 -0
- package/agent-plugins/kilo.js +72 -0
- package/agent-plugins/omp.js +32 -0
- package/agent-plugins/openclaw/index.js +58 -0
- package/agent-plugins/openclaw/openclaw.plugin.json +12 -0
- package/agent-plugins/openclaw/package.json +11 -0
- package/agent-plugins/opencode.js +72 -0
- package/agent-plugins/pi.js +30 -0
- package/codex-hooks/hooks.json +16 -0
- package/command-templates/tkr-gain.md +7 -2
- package/command-templates/tkr-status.md +5 -1
- package/command-templates/tkr-telemetry.md +3 -3
- package/command-templates/tkr-unlink.md +2 -2
- package/dist/bin/tkr-agent-hook.js +13 -0
- package/dist/bin/tkr-codex-hook.js +134 -40
- package/dist/bin/tkr-context-hook.js +4 -0
- package/dist/bin/tkr-copilot-hook.js +13 -0
- package/dist/bin/tkr-crush-hook.js +13 -0
- package/dist/bin/tkr-cursor-hook.js +13 -0
- package/dist/bin/tkr-daemon.js +194 -56
- package/dist/bin/tkr-droid-hook.js +13 -0
- package/dist/bin/tkr-exec +136 -42
- package/dist/bin/tkr-exec.js +136 -42
- package/dist/bin/tkr-gemini-hook.js +13 -0
- package/dist/bin/tkr-grok-hook.js +13 -0
- package/dist/bin/tkr-junie-hook.js +13 -0
- package/dist/bin/tkr-processor.js +166 -0
- package/dist/bin/tkr-qwen-hook.js +13 -0
- package/dist/bin/tkr-shim.js +138 -37
- package/dist/bin/tkr-shim.stable +1 -0
- package/dist/bin/tkr-trae-hook.js +13 -0
- package/dist/bin/tkr-zcode-hook.js +13 -0
- package/dist/bin/tkr.js +425 -157
- package/dist/hooks-host/post-tool-use.js +150 -49
- package/dist/hooks-host/pre-tool-use.js +10 -7
- package/dist/hooks-host/reducer-prompt-submit.js +2 -1
- package/dist/hooks-host/reducer-session-start.js +2 -1
- package/dist/hooks-host/reducer-stop.js +25 -16
- package/dist/hooks-host/session-recap.js +4 -3
- package/dist/index.js +160 -41
- package/dist/native/manifest.json +18 -8
- package/dist/native/single.json +38 -0
- package/dist/native/tkr-exec-darwin-arm64 +0 -0
- package/dist/native/tkr-exec-darwin-x64 +0 -0
- package/dist/native/tkr-exec-linux-arm64 +0 -0
- package/dist/native/tkr-exec-linux-x64 +0 -0
- package/dist/native/tkr-exec-win32-arm64.exe +0 -0
- package/dist/native/tkr-exec-win32-x64.exe +0 -0
- package/hooks/on-session-start.d.mts +1 -0
- package/hooks/on-session-start.mjs +37 -34
- package/package.json +26 -3
- package/scripts/README-INSTALL.md +50 -14
- package/scripts/install-mac-linux.sh +77 -7
- package/scripts/install-native.mjs +177 -25
- package/codex-plugin/plugin.json +0 -7
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
|
|
4
|
+
const TKR = __TKR_ARGV__;
|
|
5
|
+
const CONTEXT_FILE = __TKR_CONTEXT_FILE__;
|
|
6
|
+
const ARGS = ["rewrite", "--host", "opencode"];
|
|
7
|
+
|
|
8
|
+
function rewrite(command, session) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
11
|
+
try {
|
|
12
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
13
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
14
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
15
|
+
});
|
|
16
|
+
child.stdin?.on("error", () => {});
|
|
17
|
+
child.stdin?.end(command);
|
|
18
|
+
} catch {
|
|
19
|
+
resolve(null);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const contexts = new Map();
|
|
25
|
+
|
|
26
|
+
function readContext() {
|
|
27
|
+
try {
|
|
28
|
+
const text = readFileSync(CONTEXT_FILE, "utf8").trim();
|
|
29
|
+
return text || null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function reducerContext(session) {
|
|
36
|
+
const key = typeof session === "string" && session ? session : "";
|
|
37
|
+
if (contexts.has(key)) return contexts.get(key);
|
|
38
|
+
const text = readContext();
|
|
39
|
+
if (text === null) return null;
|
|
40
|
+
if (contexts.size >= 64) contexts.delete(contexts.keys().next().value);
|
|
41
|
+
contexts.set(key, text);
|
|
42
|
+
return text;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function addReducer(session, output) {
|
|
46
|
+
try {
|
|
47
|
+
if (!output || !Array.isArray(output.system)) return;
|
|
48
|
+
const text = reducerContext(session);
|
|
49
|
+
if (text) output.system.push(text);
|
|
50
|
+
} catch {}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function apply(tool, container, session) {
|
|
54
|
+
try {
|
|
55
|
+
if ((tool !== "bash" && tool !== "shell") || !container || typeof container !== "object") return;
|
|
56
|
+
const rewritten = await rewrite(container.command, session);
|
|
57
|
+
if (rewritten) container.command = rewritten;
|
|
58
|
+
} catch {}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default {
|
|
62
|
+
id: "tokmizer",
|
|
63
|
+
async setup(ctx) {
|
|
64
|
+
await ctx?.tool?.hook?.("execute.before", (event) => apply(event?.tool, event?.input, event?.sessionID));
|
|
65
|
+
},
|
|
66
|
+
async server() {
|
|
67
|
+
return {
|
|
68
|
+
"tool.execute.before": (input, output) => apply(input?.tool, output?.args, input?.sessionID),
|
|
69
|
+
"experimental.chat.system.transform": (input, output) => addReducer(input?.sessionID, output)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const TKR = __TKR_ARGV__;
|
|
4
|
+
const ARGS = ["rewrite", "--host", "pi"];
|
|
5
|
+
|
|
6
|
+
function rewrite(command, session) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (typeof command !== "string" || !command.trim()) return resolve(null);
|
|
9
|
+
try {
|
|
10
|
+
const args = [...TKR.slice(1), ...ARGS, ...(typeof session === "string" && session ? ["--session", session] : [])];
|
|
11
|
+
const child = execFile(TKR[0], args, { timeout: 3000, windowsHide: true, encoding: "utf8", maxBuffer: 1 << 20 }, (error, stdout) => {
|
|
12
|
+
resolve(!error && typeof stdout === "string" && stdout.trim() ? stdout : null);
|
|
13
|
+
});
|
|
14
|
+
child.stdin?.on("error", () => {});
|
|
15
|
+
child.stdin?.end(command);
|
|
16
|
+
} catch {
|
|
17
|
+
resolve(null);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default function (pi) {
|
|
23
|
+
pi.on("tool_call", async (event) => {
|
|
24
|
+
try {
|
|
25
|
+
if (event?.toolName !== "bash" || !event.input || typeof event.input !== "object") return;
|
|
26
|
+
const rewritten = await rewrite(event.input.command);
|
|
27
|
+
if (rewritten) event.input.command = rewritten;
|
|
28
|
+
} catch {}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Show estimated token reductions in recorded tool outputs.
|
|
3
|
-
argument-hint: [--day | --week | --month]
|
|
3
|
+
argument-hint: [--day | --week | --month] [--project [path]] [--csv | --graph | --history | --by-rule | --failures | --quota [pro|5x|20x]]
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Show the user Tokmizer's recorded tool-output reductions.
|
|
@@ -17,11 +17,16 @@ Choose the scope the user requested:
|
|
|
17
17
|
- Today or `--day`: `gain --day` for the current local calendar day.
|
|
18
18
|
- Last seven days or `--week`: `gain --week`.
|
|
19
19
|
- Last thirty days or `--month`: `gain --month`.
|
|
20
|
+
- Only this project (or a given directory): add `--project` or `--project <path>`. It covers the live local journal only; older rotated history is not included, and commands recorded before this field existed are excluded.
|
|
21
|
+
- Export or alternative views, combinable with a period: `--csv` (one row per day), `--graph` (per-day bar chart, default last 30 days), `--history` (last 20 recorded commands).
|
|
22
|
+
- Savings per rule: `--by-rule` (custom filters by name, built-in rules grouped by command).
|
|
23
|
+
- Commands left unchanged and why: `--failures`.
|
|
24
|
+
- Share of a Claude plan budget: `--quota`, optionally followed by `pro`, `5x` or `20x` (default `pro`, last 30 days unless a period is given). Only when the user asks for it; it is a labelled estimate with its formula, not a plan limit.
|
|
20
25
|
- This session: `session` for session coverage. This command reports routing counts, not token or dollar savings.
|
|
21
26
|
|
|
22
27
|
Show the CLI output verbatim inside a fenced code block: do not summarize, translate, reformat or rebuild it as a table. After the block, add at most one short sentence. Keep its measurement scope and caveats. Token counts are estimates from output bytes, not model tokenizer counts. Dollar values use reference input prices and do not measure a bill reduction. Percentages apply only to the recorded tool outputs, not all tokens used by the agent.
|
|
23
28
|
|
|
24
|
-
Keep modeled reducer estimates separate from observed output reductions. Do not add them together, invent replay or repeated-context savings, or infer avoided model calls. Do not turn a period's estimate into a monthly projection or paid-plan payback. A comparison with another optimizer requires measurements on the same workload; these local totals alone do not establish one.
|
|
29
|
+
Keep modeled reducer estimates separate from observed output reductions. Do not add them together, invent replay or repeated-context savings, or infer avoided model calls. Do not turn a period's estimate into a monthly projection or paid-plan payback, except the projection printed by `--quota`, kept with its estimate label. A comparison with another optimizer requires measurements on the same workload; these local totals alone do not establish one.
|
|
25
30
|
|
|
26
31
|
If the output shows zero activity, report that no activity was recorded in the selected scope. This does not establish whether the optimizer is configured or running.
|
|
27
32
|
|
|
@@ -10,6 +10,10 @@ Run the bundled CLI:
|
|
|
10
10
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" status
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Print the output as is. It includes the token state, whether the device is linked and whether `/power` is available right now. Tokmizer is free: there is no plan or subscription to mention.
|
|
13
|
+
Print the output as is. It includes the network state, the token state, whether the device is linked and whether `/power` is available right now. Tokmizer is free: there is no plan or subscription to mention.
|
|
14
|
+
|
|
15
|
+
If the user asks what Tokmizer sends over the network, answer plainly. No account or email is needed. Tokmizer contacts tokmizer.com to keep its rules up to date and to improve the product. It sends a random install ID, the computer name, OS and CPU model, a hash of the network card address and of the user name, and the plugin version. This is not anonymous: the same machine always gives the same values. Command contents and output are never sent. Usage stats (command names, token counts and install health counts) are sent only if the user turned them on.
|
|
16
|
+
|
|
17
|
+
If the output shows `Network: off`, explain that nothing leaves the machine and Tokmizer keeps compressing with the rules already on it. To turn it back on: `tkr network on`. To turn everything off: `tkr network off`; usage stats only: `tkr telemetry off`.
|
|
14
18
|
|
|
15
19
|
If the command fails because the plugin files are missing, tokmizer was uninstalled. Offer to clean up: delete the tokmizer-managed `tkr*.md` copies (they end with a `managed-by: tokmizer` marker) from `~/.claude/commands/`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Show or change Tokmizer
|
|
2
|
+
description: Show or change Tokmizer usage stats (status, on, off, forget).
|
|
3
3
|
argument-hint: status | on | off | forget
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -11,11 +11,11 @@ Pick the subcommand from the user's request. Default to `status` when they only
|
|
|
11
11
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" telemetry status
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
- `telemetry status` shows whether
|
|
14
|
+
- `telemetry status` shows whether usage stats are on or off, the network state, whether an account is linked, what is sent and the local record count.
|
|
15
15
|
- `telemetry on` turns it on.
|
|
16
16
|
- `telemetry off` turns it off.
|
|
17
17
|
- `telemetry forget` erases telemetry data stored on this machine.
|
|
18
18
|
|
|
19
|
-
Print the output as is. If the user asks what is collected, tell them:
|
|
19
|
+
Print the output as is. If the user asks what is collected, tell them: command names and token counts only, never arguments, output or file contents. Like every request to tokmizer.com, they come with the install ID and a fingerprint of the machine, so they are not anonymous. They are sent with or without an account; without one they are tied to the install's key, and linking an account later moves them to it. Detailed rows are kept 90 days. The online dashboard at https://tokmizer.com needs telemetry on to show savings. To stop every connection, not only usage stats, the user runs `tkr network off`.
|
|
20
20
|
|
|
21
21
|
If the command fails because the plugin files are missing, tokmizer was uninstalled. Offer to clean up: delete the tokmizer-managed `tkr*.md` copies (they end with a `managed-by: tokmizer` marker) from `~/.claude/commands/`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Unlink this machine from your Tokmizer account (it keeps working
|
|
2
|
+
description: Unlink this machine from your Tokmizer account (it keeps working without an account).
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
Unlink the local plugin from the user's Tokmizer account.
|
|
@@ -10,6 +10,6 @@ Run the bundled CLI:
|
|
|
10
10
|
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/tkr.js" unlink
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Print the output as is. After unlinking, the plugin keeps working
|
|
13
|
+
Print the output as is. After unlinking, the plugin keeps working without an account; a new install token is created on the next online run. To link another account, the user runs `tkr link` with the key from their dashboard.
|
|
14
14
|
|
|
15
15
|
If the command fails because the plugin files are missing, tokmizer was uninstalled. Offer to clean up: delete the tokmizer-managed `tkr*.md` copies (they end with a `managed-by: tokmizer` marker) from `~/.claude/commands/`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __tkrCreateRequire } from "node:module"; const require = __tkrCreateRequire(import.meta.url);
|
|
3
|
+
function N(t=5e3){return new Promise(e=>{let n=[],r=process.stdin,o=!1,i=()=>{o||(o=!0,clearTimeout(c),r.off("data",s),r.pause(),r.unref?.(),e(Buffer.concat(n).toString("utf8")))},s=u=>{n.push(Buffer.isBuffer(u)?u:Buffer.from(u))},c=setTimeout(i,t);r.on("data",s).once("end",i).once("error",i),r.resume()})}function U(){return!1}import Gt from"node:os";import{join as Zt}from"node:path";function $(){return process.env.TOKMIZER_HOME||Zt(Gt.homedir(),".tokmizer")}import{rmSync as Kt,statSync as qt}from"node:fs";import{join as Yt}from"node:path";function dt(){return Yt($(),"fail-open")}var Vt=24*36e5;function S(t=Date.now()){try{if(t-qt(dt()).mtimeMs<Vt)return!0;Kt(dt(),{force:!0})}catch{}return!1}function v(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}var Ur=String.raw`(?:'(?:(?:[^']|'\\'')*[\\/])?tkr(?:\.(?:exe|cmd|bat|ps1))?'|"(?:[^"]*[\\/])?tkr(?:\.(?:exe|cmd|bat|ps1))?"|(?:[^\s'"]*[\\/])?tkr(?:\.(?:exe|cmd|bat|ps1))?)`;import{appendFileSync as re,chmodSync as oe,mkdirSync as se,existsSync as ie,readFileSync as Gr,rmSync as Zr}from"node:fs";import{dirname as ce,join as ue}from"node:path";import{readFileSync as Qt,renameSync as te,statSync as ee,writeFileSync as ne}from"node:fs";function pt(t,e,n){try{if(ee(t).size<=e)return;let r=Qt(t,"utf8").split(`
|
|
4
|
+
`).filter(c=>c.trim()!==""),o=[],i=0;for(let c=r.length-1;c>=0;c-=1){let u=r[c],l=Buffer.byteLength(u)+1;if(i+l>n)break;o.push(u),i+=l}o.reverse();let s=`${t}.tmp-${process.pid}`;ne(s,o.length?`${o.join(`
|
|
5
|
+
`)}
|
|
6
|
+
`:"",{mode:384}),te(s,t)}catch{}}var le="usage.jsonl";var mt=2*1024*1024;function ae(){return ue($(),le)}function k(t,e,n=ae()){try{let r=ce(n);ie(r)||se(r,{recursive:!0,mode:448});let o=t.replace(/[^A-Za-z0-9._-]/g,"").slice(0,64)||"unknown";re(n,`{"t":${Math.floor(Date.now()/1e3)},"s":"${o}","o":${e?1:0}}
|
|
7
|
+
`,{mode:384}),oe(n,384),pt(n,mt,mt/2)}catch{}}import{existsSync as B,readFileSync as nt,readdirSync as rt}from"node:fs";import{homedir as A}from"node:os";import{fileURLToPath as Be}from"node:url";import{dirname as At,join as f,resolve as We}from"node:path";import{execFileSync as Ce}from"node:child_process";import{mkdirSync as He,readFileSync as bt,renameSync as Pe,statSync as Ne,writeFileSync as Ie}from"node:fs";import{join as St}from"node:path";import{closeSync as fe,openSync as de,readSync as pe,readdirSync as me,readFileSync as ge,statSync as ht}from"node:fs";import{homedir as he}from"node:os";import{isAbsolute as ke,join as z,resolve as _e}from"node:path";var be=/^[A-Za-z0-9._+@%:,/-]+$/,Se=new Set(["7f454c46","feedface","feedfacf","cefaedfe","cffaedfe","cafebabe","bebafeca"]),ye=32,we=4*1024*1024;function Q(t){let e;try{e=de(t,"r");let n=Buffer.alloc(4),r=pe(e,n,0,4,0);return r>=2&&n[0]===35&&n[1]===33?"#!":r===4?n.toString("hex"):null}catch{return null}finally{e!==void 0&&fe(e)}}function I(t,e=process.platform){try{let n=ht(t);if(!n.isFile())return!1;if(e==="win32")return!0;if((n.mode&73)===0)return!1;let r=Q(t);return r==="#!"||r!==null&&Se.has(r)}catch{return!1}}function xe(t){if(/\.[A-Za-z0-9]+$/.test(t))return[t];let e=(process.env.PATHEXT??".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);return[t,...e.map(n=>t+n.toLowerCase())]}function E(t,e,n,r=process.platform){if(!be.test(t))return!1;let o=r==="win32";if(t.includes("/"))return I(_e(e??process.cwd(),t),r);if(!n)return!1;let i=o?xe(t):[t];for(let s of n.split(o?";":":"))if(!(!s||!ke(s))){for(let c of i)if(I(z(s,c),r))return!0}return!1}var $e=/^eval \$'([^\s'()=]+) \(\) /,ve=/^([^\s'"()=]+) \(\) \{$/,Oe=/^alias -- ([^\s=]+)=(.*)$/,Ee=/^# (?:Shell Options|Aliases|Shopt|Check for |Shadow )/,Ae=/^export PATH=(.*)$/,Re=/^(?:--colou?r(?:=\S+)?|-G)$/;function gt(t){return t.length>=2&&t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/'\\''/g,"'"):t.length>=2&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t}function Te(t,e){let n="";for(let r of t.split(`
|
|
8
|
+
`)){let o=Ae.exec(r);if(o&&n!=="# Functions"){let i=gt(o[1].trim());/[$`\\]/.test(i)||e.paths.push(i);continue}if(r.startsWith("# ")&&(n!=="# Functions"||Ee.test(r))){n=r;continue}if(n==="# Functions"){let i=$e.exec(r)??ve.exec(r);i&&e.functions.add(i[1])}else if(n==="# Aliases"){let i=Oe.exec(r);i&&e.aliases.set(i[1],gt(i[2].trim()))}}}function X(t){return t?.code==="ENOENT"}function kt(t){let e={functions:new Set,aliases:new Map,paths:[],uncertain:!1},n=z(t||z(he(),".claude"),"shell-snapshots"),r=[];try{for(let o of me(n)){if(!o.startsWith("snapshot-")||!o.endsWith(".sh"))continue;let i=z(n,o);try{let s=ht(i);s.isFile()&&r.push({path:i,mtime:s.mtimeMs,size:s.size})}catch(s){X(s)||(e.uncertain=!0)}}}catch(o){return X(o)||(e.uncertain=!0),e}r=r.sort((o,i)=>i.mtime-o.mtime).slice(0,ye);for(let o of r)try{if(o.size>we)throw new Error("snapshot too large");Te(ge(o.path,"utf8"),e)}catch(i){X(i)||(e.uncertain=!0)}return e}function _t(t,e){if(e.uncertain||e.functions.has(t))return!0;let n=e.aliases.get(t);if(n===void 0)return!1;let r=n.trim().split(/\s+/);return r[0]!==t||!r.slice(1).every(o=>Re.test(o))}var Le="exec-probe.json",je=6e4;function Fe(){return St($(),Le)}function De(t){try{let e=JSON.parse(bt(t,"utf8"));if(e==null||typeof e!="object")return null;let n=e;return typeof n.key!="string"||typeof n.ok!="boolean"?null:{key:n.key,ok:n.ok,at:typeof n.at=="number"?n.at:0,skipped:typeof n.skipped=="number"&&n.skipped>=0?n.skipped:0}}catch{return null}}function Me(t,e){try{He(St(t,".."),{recursive:!0,mode:448});let n=`${t}.${process.pid}.tmp`;Ie(n,JSON.stringify(e),{mode:384}),Pe(n,t)}catch{}}function Ue(t){try{return Ce(t,["--native-check"],{encoding:"utf8",timeout:2e3,maxBuffer:1024,stdio:["ignore","pipe","ignore"],windowsHide:!0}).startsWith("tokmizer-native ")}catch{return!1}}function ze(t,e){try{let r=bt(t,"utf8").split(`
|
|
9
|
+
`,1)[0].slice(2).trim().split(/\s+/),o=r[0]??"";return o==="/usr/bin/env"?E(r[1]??"",void 0,e):I(o)}catch{return!1}}function Je(t,e,n){try{let r=Ne(t);return[t,r.size,r.mtimeMs,r.ino,r.mode,e?n??"":""].join("|")}catch{return`${t}|missing`}}function tt(t,e=process.platform,n=process.env.PATH,r=Fe(),o=Date.now()){let i=e!=="win32"&&Q(t)==="#!",s=Je(t,i,n),c=De(r);if(c?.key===s&&(c.ok||o-c.at<je))return c.ok;let u=I(t,e)&&(i?ze(t,n):Ue(t));return Me(r,{key:s,ok:u,at:o,skipped:(c?.skipped??0)+(u?0:1)}),u}var Ge=new Set(["tkr","tkr-exec","token","claude","cd","export","source","echo","mkdir","rm","mv","cp","chmod","ln","true","false",":","test","[","exit","return","nohup","sudo","doas","env"]),Ze=new Set(["for","while","until","if","then","else","elif","fi","do","done","case","esac","select","function","time","coproc","in","!","[[","]]","{","}",".","declare","typeset","local","readonly","unset","set","shift","trap","wait","read","eval","exec","break","continue","pushd","popd","dirs","alias","unalias","hash","ulimit","umask","getopts","let","shopt","builtin","command","compgen","complete","disown","suspend","jobs","fg","bg","kill","history","fc","bind","enable","caller","type","printf","pwd","times","logout","mapfile","readarray","help","which","print","whence","where","autoload","zmodload","setopt","unsetopt","emulate","noglob","rehash","functions","bindkey","zle","vared","sched","limit","unlimit","zstyle","zparseopts","ttyctl"]),yt=new Set(["sh","bash","zsh","dash","ksh","fish","python","python3","python2","node","ruby","perl","php","awk","sed","deno","bun"]),wt="(?:dev|start|serve|watch|preview)",Ke=new RegExp(`^(?:\\S*/)?(?:bun\\s+(?:install|i|add|remove|rm|update|outdated|audit|test|build|pm|x)(?:\\s|$)|bun\\s+run\\s+(?!${wt}(?:\\s|$))[A-Za-z0-9:_-]+(?:\\s|$)|deno\\s+(?:test|lint|fmt|check|compile|install|info|doc|bench|outdated)(?:\\s|$)|deno\\s+task\\s+(?!${wt}(?:\\s|$))[A-Za-z0-9:_-]+(?:\\s|$)|php\\s+-l(?:\\s|$)|php\\s+(?:\\S*/)?(?:phpunit|pest|paratest|phpstan|pint|ecs|php-cs-fixer|psalm|rector|run-tests\\.php)(?:\\s|$)|php\\s+artisan\\s+(?!(?:serve|tinker|queue:work|queue:listen|horizon|octane:start|reverb:start|schedule:work|pail|dev)(?:\\s|$))\\S)`),qe=/(?:^|\s)--watch(?:\s|=|$)/;function Ye(t){return Ke.test(t)&&!qe.test(t)}var Ve=/^((?:\S*\/)?(sh|bash|zsh|dash|ksh|fish)\s+(-[elux]*c[elux]*)\s+)(['"])/,Xe=/[()$]|(?:^|[;&|\n]\s*)(?:and|or|not|begin|end|if|else|switch|case|while|for|function|return)(?:\s|;|$)/,Rt=3;function Tt(t){let e=Ve.exec(t);if(!e)return null;let n=e[2]==="fish";if(n&&e[3]!=="-c")return null;let r=e[4],o=e[1].length+1,i=t.indexOf(r,o);if(i<=o)return null;let s=t.slice(i+1);if(s&&!/^\s/.test(s))return null;let c=t.slice(o,i);return r==='"'&&/[$`\\!]/.test(c)||n&&Xe.test(c)?null:{script:c,start:o,end:i,quote:r}}var Qe=new Set(["cd","export","set","unset","source",".","true",":","pushd","popd"]);function tn(t){return st(t).filter(n=>{if(n.kind!=="cmd"||n.unsafe)return!1;let r=Ht(n.text);return r!==""&&!Qe.has(r)&&!ot.test(r)}).length>1}function en(t,e,n,r,o){if(n>=Rt)return null;let i=Tt(t);if(!i)return null;let{script:s,start:c,end:u,quote:l}=i,a=[],p=Pt(s,e,n+1,r,g=>a.push(g));if(p===s||l==='"'&&/["$`]/.test(p))return null;let _=l==="'"?p.replace(/'/g,"'\\''"):p,d=`${t.slice(0,c)}${_}${t.slice(u)}`,y=tn(s);if(o)for(let g of y?[t,...a]:a)o(g);return y?`${e} ${d}`:d}var xt=/(?:^|\s)(?:--follow|-[0-9a-zA-Z]*f[a-zA-Z]*)(?:\s|=|$)/,nn=new Set(["docker","podman","kubectl","nerdctl","docker-compose","stern","flyctl"]);function rn(t,e){let n=W(e);return n==="tail"||n==="journalctl"?xt.test(t):n==="stern"?!0:nn.has(n)?/\blogs?\b/.test(t)&&xt.test(t):!1}var ot=/^[A-Za-z_][A-Za-z0-9_]*\+?=/,on=/^[A-Za-z_][A-Za-z0-9_-]*\s*\(\s*\)/,sn=/(?:^|[;&|\n({])\s*[A-Za-z_][A-Za-z0-9_-]*\s*\(\s*\)/;function W(t){let e=t.lastIndexOf("/");return e===-1?t:t.slice(e+1)}function Ct(t){let e=new Array(t.length).fill(!1),n=[],r=0;for(;r<t.length;){let o=t[r],i=t[r+1],s=n[n.length-1];if(s==="'"){o==="'"&&n.pop(),r+=1;continue}if(o==="\\"){if(i===void 0)return null;r+=2;continue}if(s==="$'"){o==="'"&&n.pop(),r+=1;continue}if(o==="$"&&(i==="("||i==="{")){n.push(i==="("?")":"}"),r+=2;continue}if(o==="`"){s==="`"?n.pop():n.push("`"),r+=1;continue}if(s==='"'){o==='"'&&n.pop(),r+=1;continue}if(o==="$"&&i==="'"){n.push("$'"),r+=2;continue}if(o==="'"||o==='"'){n.push(o),r+=1;continue}if(o==="("||o==="{"&&s==="}"){n.push(o==="("?")":"}"),r+=1;continue}if(o===s){n.pop(),r+=1;continue}if(o===")"&&s===void 0)return null;e[r]=s===void 0,r+=1}return n.length===0?e:null}function $t(t){let e=Ct(t);if(!e)return!0;for(let n=0;n<t.length;n++)if(e[n]&&t[n]===">")return!0;return!1}function st(t){let e=Ct(t);if(!e)return[{kind:"cmd",text:t,unsafe:!0}];let n=[],r="",o=0,i=()=>{r.length>0&&(n.push({kind:"cmd",text:r}),r="")},s=(c,u)=>{i(),n.push({kind:"sep",text:c}),o+=u};for(;o<t.length;){let c=t[o],u=t[o+1];if(e[o]){if(c===">"&&u==="|"){r+=">|",o+=2;continue}if(c==="&"&&u==="&"){s("&&",2);continue}if(c==="&"&&u!==">"){let l=r.replace(/\s+$/,""),a=l[l.length-1];if(a!==">"&&a!=="<"&&a!=="&"){s("&",1);continue}}if(c==="|"&&u==="|"){s("||",2);continue}if(c==="|"&&u==="&"){s("|&",2);continue}if(c===";"&&u===";"){let l=t[o+2]==="&";s(l?";;&":";;",l?3:2);continue}if(c===";"||c===`
|
|
10
|
+
`||c==="|"){s(c,1);continue}}r+=c,o+=1}return i(),n}function Ht(t){return t.trim().split(/\s+/)[0]??""}function b(t,e=process.platform){try{let n=At(Be(import.meta.url)),r=e==="win32",o=t&&t!=="claude-code"&&t!=="codex"&&!r?`TOKMIZER_HOST=${t} `:"";if(r&&(!t||t==="claude-code")){let c=f(n,"..","bin","tkr-exec.exe");if(B(c))return tt(c,e)?`'${c.replace(/\\/g,"/").replace(/'/g,"'\\''")}'`:null}let i=f(n,"..","bin","tkr-exec");if(!r&&B(i))return tt(i,e)?`${o}'${i.replace(/'/g,"'\\''")}'`:null;if(U()){let c=r?process.execPath.replace(/\\/g,"/"):process.execPath;return`${o}'${c.replace(/'/g,"'\\''")}' exec`}let s=f(n,"..","bin","tkr-exec.js");return B(s)?`${o}node '${s.replace(/'/g,"'\\''")}'`:null}catch{return null}}function cn(t,e="tkr-exec",n=()=>!0,r){return Pt(t,e,0,n,r)}function Pt(t,e,n,r,o){if(t.includes("<<")||sn.test(t))return t;let i=st(t),s=[];for(let c=0;c<i.length;c++){let u=i[c];if(u.kind==="sep"||u.unsafe){s.push(u.text);continue}let l=u.text.trim();if(!l){s.push(u.text);continue}let a=Ht(l),p=i[c+1],_=p?.kind==="sep"&&(p.text==="|"||p.text==="|&"),d=p?.kind==="sep"&&p.text==="&",y=!_&&!d&&!$t(u.text)&&!u.text.includes("<(")&&!u.text.includes(">(")?en(l,e,n,r,o):null;if(y!==null){s.push(`${u.text.match(/^\s*/)?.[0]??""}${y}${u.text.match(/\s*$/)?.[0]??""}`);continue}if(l===e||l.startsWith(e)&&/^\s/.test(l.slice(e.length))||Ge.has(a)||Ze.has(a)||(yt.has(a)||yt.has(W(a)))&&!Ye(l)||ot.test(a)||a.startsWith("(")||a.startsWith("#")||a.startsWith("<")||a.startsWith(">")||on.test(l)||rn(l,a)||a.endsWith(")")||_||d||$t(u.text)||u.text.includes("<(")||u.text.includes(">(")||a==="node"&&l.includes("tkr-exec.js")||!r(a)){s.push(u.text);continue}let g=u.text.match(/^\s*/)?.[0]??"",M=u.text.match(/\s*$/)?.[0]??"";o?.(l),s.push(`${g}${e} ${l}${M}`)}return s.join("")}var un=new Set(["command","workdir","timeout_ms","yield_time_ms","max_output_tokens","shell","login","tty","description"]),ln=new Set(["cd","cat","head","tail","ls","tree","find","grep","rg","wc","nl","sort","cut","diff","stat","file","du","df","ps","jq","yq","pwd","which"]),an=new Set(["log","diff","show","status","blame","ls-files","rev-parse","describe","shortlog"]),fn={find:/^-(?:delete|exec|execdir|ok|okdir|fprint|fls)/,sort:/^(?:-[^-]*o|--output|--compress-program)/,rg:/^(?:--pre|-[^-]*z|--search-zip)/,yq:/^(?:-[^-]*[is]|--inplace|--split-exp)/,file:/^(?:-C|--compile)/,tree:/^(?:-o|--output|-R$|-H$)/,git:/^(?:--output|--ext-diff|--textconv|-c$|--exec-path|--git-dir|--work-tree)/,eslint:/^--fix/},J=["test","run test","run build","run lint","run typecheck"],dn={npm:new Set(J),pnpm:new Set([...J,"build","lint","typecheck"]),yarn:new Set([...J,"build","lint","typecheck"]),bun:new Set(J),cargo:new Set(["test","build","check","clippy"]),go:new Set(["test","build","vet"]),mvn:new Set(["test","compile","verify"]),gradle:new Set(["test","build","check"]),dotnet:new Set(["test","build"])},pn=new Set(["pytest","tsc","vitest","jest","eslint","mypy"]);function Nt(t,e,n=0){if(/\$|`|<\(|>\(|\\\r?\n/.test(t)||/>/.test(t.replace(/2>&1|[12]?>\s*\/dev\/null/g,"")))return!1;for(let r of st(t)){if(r.kind==="sep")continue;if(r.unsafe)return!1;let o=n<Rt?Tt(r.text.trim()):null;if(o){if(!Nt(o.script,e,n+1))return!1;continue}let i=r.text.trim().split(/\s+/).filter(Boolean).map(l=>l.replace(/['"\\]/g,""));if(i.length===0)continue;if(i.some(l=>ot.test(l)))return!1;let s=W(i[0]);if(s!==i[0])return!1;let c=fn[s];if(c&&i.slice(1).some(l=>c.test(l)))return!1;if((s==="git"?an.has(i[1]??""):ln.has(s))||e&&pn.has(s))continue;let u=e?dn[s]:void 0;if(!(u&&(u.has(i[1]??"")||i[1]==="run"&&u.has(`run ${i[2]??""}`))))return!1}return!0}function It(t,e,n=b(e),r=k,o=Z(),i=process.env.PATH){if(!h(t)||t.tool_name!=="Bash")return null;let s=t.tool_input;if(!h(s)||s.run_in_background)return null;let c=s.command;if(typeof c!="string"||!c||e==="codex"&&Object.keys(s).some(d=>!un.has(d)))return null;let u=typeof t.cwd=="string"&&t.cwd?t.cwd:s.workdir,l=typeof u=="string"&&u?u:void 0,a=typeof t.session_id=="string"&&t.session_id?t.session_id:"unknown",p=typeof t.permission_mode=="string"?t.permission_mode:void 0,_=w(c,{host:e,sessionId:a,cwd:l,claudeDirs:o,pathEnv:i,permissionMode:p},n,r);return _?JSON.stringify({hookSpecificOutput:e==="codex"?{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:{...s,command:_}}:{hookEventName:"PreToolUse",updatedInput:{...s,command:_}}}):null}function mn(t,e){if(!B(t))return"missing";try{let n=nt(t,"utf8");return JSON.parse(e?Lt(n):n)}catch{return"unreadable"}}function Lt(t){let e="",n=!1;for(let r=0;r<t.length;r++){let o=t[r];if(n){e+=o,o==="\\"?e+=t[++r]??"":o==='"'&&(n=!1);continue}if(o==='"')n=!0,e+=o;else if(o==="/"&&t[r+1]==="/"){for(;r<t.length&&t[r]!==`
|
|
11
|
+
`;)r++;e+=`
|
|
12
|
+
`}else if(o==="/"&&t[r+1]==="*"){if(r=t.indexOf("*/",r+2),r===-1)return"";r+=1}else e+=o}return e.replace(/,(\s*[}\]])/g,"$1")}function G(t){let e=[],n=We(t);for(;;){e.push(n);let r=At(n);if(r===n)return e;n=r}}function gn(){let t=process.platform==="darwin"?"/Library/Application Support/ClaudeCode":process.platform==="win32"?"C:\\Program Files\\ClaudeCode":"/etc/claude-code",e=[f(t,"managed-settings.json")];try{for(let n of rt(f(t,"managed-settings.d")))n.endsWith(".json")&&e.push(f(t,"managed-settings.d",n))}catch{return e}return e}function j(t,e,n,r){let o=[];for(let i of t){let s=mn(i,e);if(s!=="missing"&&(s==="unreadable"||!h(s)||!n(s,o)))return"unreadable"}return{matchers:o,complete:r}}function L(t){return t===void 0?[]:Array.isArray(t)?t.filter(e=>typeof e=="string"):null}function Z(){return{projectDir:process.env.CLAUDE_PROJECT_DIR,configDir:process.env.CLAUDE_CONFIG_DIR}}function hn(t,e){let n=d=>[f(d,"settings.json"),f(d,"settings.local.json")],r=d=>n(f(d,".claude")),o=f(A(),".claude"),i=[[gn(),"managed"],[n(e.configDir||o),"loaded"],[e.configDir?n(o):[],"extra"],[e.projectDir?r(e.projectDir):[],"project"],[G(t).flatMap(r),"extra"]],s=[],c={managed:!1,loaded:!1,project:!1,extra:!1},u=!1,l="managed",a=(d,y)=>{let g=d.permissions;if(l==="managed"&&(d.allowManagedPermissionRulesOnly===!0||h(g)&&g.allowManagedPermissionRulesOnly===!0)&&(u=!0),g===void 0)return!0;if(!h(g))return!1;for(let M of["deny","ask","allow"]){let at=L(g[M]);if(!at)return!1;for(let Wt of at){let P=/^\s*Bash\s*(?:\(([\s\S]*)\))?\s*$/.exec(Wt);P&&(M!=="allow"?y.push(O((P[1]??"*").replace(/:\*$/," *"))):P[1]===void 0||P[1].trim()==="*"?c[l]=!0:s.push(O(P[1].replace(/:\*$/," *"))))}}return!0},p=[];for(let[d,y]of i){l=y;let g=j(d,!1,a,!0);if(g==="unreadable")return"unreadable";p.push(...g.matchers)}let _=c.managed||c.loaded&&!u;return{matchers:[...p,..._?[]:s],complete:!0,allow:s,allowsEverything:_}}function kn(t){let e=[f(A(),".cursor","cli-config.json"),...G(t).map(n=>f(n,".cursor","cli.json"))];return j(e,!0,(n,r)=>{let o=n.permissions;if(o===void 0)return!0;if(!h(o))return!1;let i=L(o.deny);if(!i)return!1;for(let s of i){let c=/^\s*Shell\s*(?:\(([\s\S]*)\))?\s*$/.exec(s);if(!c)continue;let u=c[1]??"*",l=u.indexOf(":");r.push(O(l===-1?`${u} *`:`${u.slice(0,l)} ${u.slice(l+1)}`))}return!0},!1)}function _n(){return process.platform==="darwin"?"/Library/Application Support/GeminiCli":process.platform==="win32"?"C:\\ProgramData\\gemini-cli":"/etc/gemini-cli"}var jt=/^\s*(?:run_shell_command|ShellTool)\s*(?:\(([\s\S]*)\))?\s*$/;function bn(t,e){let n=t.tools;if(n!==void 0&&!h(n))return!1;let r=[L(t.excludeTools),L(h(n)?n.exclude:void 0)];for(let o of r){if(!o)return!1;for(let i of o){let s=jt.exec(i);s&&e.push(O(s[1]===void 0?"*":`${s[1]}*`))}}return!0}function vt(t){try{return JSON.parse(t)}catch{return null}}function Sn(t){let e=t.trim();if(e.startsWith('"""')||e.startsWith("'''"))return null;if(e.startsWith("[")){if(!/\]\s*(?:#.*)?$/.test(e))return null;let n=[];for(let r of e.matchAll(/"((?:\\.|[^"\\])*)"|'([^']*)'/g)){let o=r[2]??vt(`"${r[1]}"`);if(o===null)return null;n.push(o)}return n}if(e.startsWith('"')){let n=/^"((?:\\.|[^"\\])*)"/.exec(e);return n?vt(`"${n[1]}"`):null}if(e.startsWith("'")){let n=/^'([^']*)'/.exec(e);return n?n[1]:null}return e.replace(/\s*#.*$/,"")}function yn(t,e){for(let n of t.split(/^\s*\[\[\s*rule\s*\]\]\s*$/m).slice(1)){let r={};for(let u of n.split(/\r?\n/)){if(/^\s*\[/.test(u))break;let l=/^\s*([A-Za-z_]+)\s*=\s*(.*)$/.exec(u);if(!l)continue;let a=Sn(l[2]);if(a===null)return!1;r[l[1]]=a}let o=r.decision;if(o!=="deny"&&o!=="ask_user"||!(r.toolName===void 0?["*"]:[r.toolName].flat()).some(u=>u==="*"||jt.test(u)))continue;let s=r.commandPrefix===void 0?[]:[r.commandPrefix].flat(),c=[r.commandRegex,r.argsPattern].flat().filter(u=>typeof u=="string");if(s.length===0&&c.length===0){e.push(()=>!0);continue}for(let u of s)e.push(O(`${u}*`));for(let u of c){let l;try{l=new RegExp(u)}catch{return!1}e.push(a=>l.test(JSON.stringify({command:a}))||it(l,a))}}return!0}function Ot(t){try{return rt(t).filter(e=>e.endsWith(".toml")).map(e=>f(t,e))}catch{return[]}}function wn(t){let e=_n(),n=[f(e,"system-defaults.json"),f(e,"settings.json"),process.env.GEMINI_CLI_SYSTEM_SETTINGS_PATH,process.env.GEMINI_CLI_SYSTEM_DEFAULTS_PATH,f(A(),".gemini","settings.json"),...G(t).map(o=>f(o,".gemini","settings.json"))].filter(o=>!!o),r=j(n,!0,bn,!1);if(r==="unreadable")return r;for(let o of[...Ot(f(A(),".gemini","policies")),...Ot(f(e,"policies"))]){let i;try{i=nt(o,"utf8")}catch{return"unreadable"}if(!yn(i,r.matchers))return"unreadable"}return r}function et(t,e){if(t===void 0)return!0;if(typeof t=="string")return t!=="allow"&&e.push(()=>!0),!0;if(!h(t))return!1;for(let n of["bash","shell","*"]){let r=t[n];if(r!==void 0){if(typeof r=="string"){r!=="allow"&&e.push(()=>!0);continue}if(!h(r))return!1;for(let[o,i]of Object.entries(r))i!=="allow"&&e.push(O(o.replace(/\?/g,"*")))}}return!0}function Et(t,e){if(t.permissions!==void 0||!et(t.permission,e))return!1;for(let n of["agent","agents","mode"]){let r=t[n];if(r!==void 0){if(!h(r))return!1;for(let o of Object.values(r))if(h(o)&&(o.permissions!==void 0||!et(o.permission,e)))return!1}}return!0}function xn(t){for(let e of t)for(let n of["agent","agents","mode","modes"]){let r;try{r=rt(f(e,n))}catch{continue}for(let o of r)try{if(o.endsWith(".md")&&/permission/i.test(nt(f(e,n,o),"utf8")))return!0}catch{return!0}}return!1}function $n(t){let e=f(process.env.XDG_CONFIG_HOME||f(A(),".config"),"opencode"),n=G(t),r=[e,...n.map(c=>f(c,".opencode"))];if(xn(r))return"unreadable";let o=["opencode.json","opencode.jsonc","config.json"],i=[...o.map(c=>f(e,c)),process.env.OPENCODE_CONFIG,...n.flatMap(c=>[...o.slice(0,2).map(u=>f(c,u)),...o.slice(0,2).map(u=>f(c,".opencode",u))])].filter(c=>!!c),s=j(i,!0,Et,!0);if(s==="unreadable")return s;for(let c of[process.env.OPENCODE_CONFIG_CONTENT,process.env.OPENCODE_PERMISSION]){if(!c)continue;let u;try{u=JSON.parse(Lt(c))}catch{return"unreadable"}if(!(c===process.env.OPENCODE_PERMISSION?et(u,s.matchers):h(u)&&Et(u,s.matchers)))return"unreadable"}return s}function vn(){return j([f(A(),".gemini","antigravity-cli","settings.json")],!0,(t,e)=>{let n=t.permissions;if(n===void 0)return!0;if(!h(n))return!1;for(let r of["deny","ask"]){let o=L(n[r]);if(!o)return!1;for(let i of o){let s=/^\s*command\s*\(([\s\S]*)\)\s*$/.exec(i);if(!s)continue;let c=s[1].trim();if(!c.startsWith("regex:")){e.push(O(c==="*"?"*":`${c} *`));continue}let u;try{u=new RegExp(c.slice(6))}catch{return!1}e.push(l=>it(u,l))}}return!0},!1)}function h(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function On(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function En(t){let e=t.trim().replace(/\s+/g," "),n=e.endsWith(" *")&&e.length>2,r=(n?e.slice(0,-2):e).split("*").map(On).join("[\\s\\S]*");return new RegExp(`^${r}${n?"(?: [\\s\\S]*)?":""}(?= |$)`)}var An=512;function Rn(t){let e=t.replace(/['"\\]/g,"").split(/[\s;&|(){}<>`$]+/).filter(Boolean);return[e,e.map(W)]}function it(t,e){if(t.test(e)||t.test(e.trim().replace(/\s+/g," ")))return!0;for(let n of Rn(e)){if(n.length>An)return!0;for(let r=0;r<n.length;r++)if(t.test(n.slice(r).join(" ")))return!0}return!1}function O(t){let e=En(t);return n=>it(e,n)}var Tn={"claude-code":hn,cursor:kn,"gemini-cli":wn,opencode:$n,antigravity:vn},Cn=new Set(["codex"]),Hn=/(?:^|[\s=:/~])\.(?:git|claude|vscode|idea|husky)(?=[/\s;|&)]|$)|(?:^|[\s=:/~])\.(?:bashrc|bash_profile|bash_login|bash_logout|profile|zshrc|zprofile|zshenv|zlogin|zlogout|gitconfig|gitmodules|ripgreprc|mcp\.json)(?![A-Za-z0-9_])/;function Pn(t,e,n){let r=Tn[t];return r?r(e??process.cwd(),n):{matchers:[],complete:!1}}function Nn(t,e,n){return t==="unreadable"||Hn.test(e.replace(/['"\\]/g,""))||t.matchers.some(r=>r(e))?!1:t.complete||Nt(e,!Cn.has(n))}var In=new Set(["default","acceptEdits","dontAsk"]);function Ln(t,e){return e.host!=="claude-code"||e.permissionMode==="bypassPermissions"?!0:t!=="unreadable"&&t.allowsEverything===!0&&In.has(e.permissionMode??"")}function jn(t,e){let n="pathEnv"in t?t.pathEnv:process.env.PATH,r;return o=>t.host!=="claude-code"?E(o,t.cwd,n):(r??=kt(e.configDir),!E(o,t.cwd,n)&&!r.paths.some(i=>E(o,t.cwd,i))?!1:o.includes("/")||!_t(o,r))}function w(t,e,n,r){if(!n||/["\\$`;&|<>(){}]|'\\''/.test(n))return null;let o=e.claudeDirs??Z(),i=Pn(e.host,e.cwd,o),s=Nn(i,t,e.host)?cn(t,n,jn(e,o)):t;return s!==t&&i!=="unreadable"&&(i.matchers.some(c=>c(s))||(i.allow??[]).some(c=>c(s)&&!c(t)))&&(s=t),r(e.sessionId,s!==t),s===t||!Ln(i,e)?null:s}function R(t,e,n="unknown",r=b(e),o=k){return t?w(t,{host:e,sessionId:n},S()?null:r,o):null}function m(t,e){let n=t[e];return typeof n=="string"&&n?n:null}function F(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function Fn(t){return m(t,"prompt_id")||m(t,"scratchpad_dir")?!0:F(t.effort)}function Dn(t){return m(t,"tool_use_id")?.startsWith("toolu_")===!0||/^claude/i.test(m(t,"model")??"")}var Mn=new Set(["BeforeTool","AfterTool","BeforeAgent","AfterAgent","BeforeModel","AfterModel","BeforeToolSelection"]),Un=new Set(["preToolUse","postToolUse","beforeShellExecution","afterShellExecution","beforeSubmitPrompt","sessionStart","sessionEnd","stop"]),zn=new Set(["pre_tool","post_tool"]),Jn=new Set(["before_tool_call","after_tool_call"]),Bn=new Set(["runTerminalCommand","run_in_terminal"]),Wn=[["codex",t=>m(t,"turn_id")!==null],["claude-code",Fn],["cursor",t=>m(t,"cursor_version")!==null||m(t,"generation_id")!==null||m(t,"conversation_id")!==null||Array.isArray(t.workspace_roots)||Un.has(m(t,"hook_event_name")??"")],["gemini-cli",t=>Mn.has(m(t,"hook_event_name")??"")],["qwen-code",t=>t.hook_event_name==="PreToolUse"&&t.tool_name==="run_shell_command"],["vibe",t=>zn.has(m(t,"hook_event_name")??"")],["antigravity",t=>F(t.toolCall)],["copilot",t=>m(t,"toolName")!==null&&"toolArgs"in t||Bn.has(m(t,"tool_name")??"")],["grok",t=>t.toolName==="run_terminal_command"||t.tool_name==="run_terminal_command"||F(t.toolInput)&&!("toolArgs"in t)],["droid",t=>t.tool_name==="Execute"],["trae",t=>t.tool_name==="RunCommand"],["crush",t=>t.hook_event_name===void 0&&m(t,"event")!==null&&!Jn.has(m(t,"event"))]],Gn=new Set(["codex","antigravity"]);function Zn(t){return F(t)?Wn.filter(([,e])=>e(t)).map(([e])=>e):[]}function Ft(t,e){if(!F(t))return null;let n=Zn(t);return n.length>1?null:n.length===1?n[0]:Dn(t)&&Gn.has(e)?"claude-code":e==="codex"?null:e}var ct=JSON.stringify({permission:"allow"});function Dt(t,e=b("cursor"),n=k){if(t.tool_name!=="Shell")return ct;let r=t.tool_input??{},o=r.command;if(typeof o!="string"||!o)return ct;let i=typeof r.working_directory=="string"?r.working_directory:void 0,s=w(o,{host:"cursor",sessionId:t.conversation_id??"unknown",cwd:i},S()?null:e,n);return s?JSON.stringify({permission:"allow",updated_input:{...r,command:s}}):ct}var K="{}";function Mt(t,e=b("gemini-cli"),n=k){if(t.hook_event_name!=="BeforeTool"||t.tool_name!=="run_shell_command")return K;let r=t.tool_input??{};if(r.is_background)return K;let o=r.command;if(typeof o!="string"||!o)return K;let i=typeof t.cwd=="string"?t.cwd:void 0,s=w(o,{host:"gemini-cli",sessionId:t.session_id??"unknown",cwd:i},S()?null:e,n);return s?JSON.stringify({hookSpecificOutput:{tool_input:{command:s}}}):K}var x="{}",Kn=new Set(["runTerminalCommand","run_in_terminal","Bash","bash"]),qn=["run_in_background","is_background","isBackground"];function q(t){return t!=null&&typeof t=="object"&&!Array.isArray(t)}function Yn(t){let e=t.session_id??t.sessionId;return typeof e=="string"&&e?e:"unknown"}function Vn(t,e){let n=t.cwd??e.cwd??e.workdir??e.working_directory;return typeof n=="string"&&n?n:void 0}function Y(t,e,n,r,o){if(!q(e)||qn.some(s=>e[s]===!0))return null;let i=e.command;return typeof i!="string"||!i?null:w(i,{host:t,sessionId:Yn(n),cwd:Vn(n,e)},S()?null:r,o)}function C(t,e){return JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{...t,command:e}}})}function Xn(t){if(q(t))return t;if(typeof t!="string")return null;try{let e=JSON.parse(t);return q(e)?e:null}catch{return null}}function Qn(t,e,n){if(typeof t.tool_name=="string"){if(!Kn.has(t.tool_name))return x;let i=t.tool_input,s=Y("copilot",i,t,e,n);return s?C(i,s):x}if(t.toolName!=="bash")return x;let r=Xn(t.toolArgs),o=Y("copilot",r,t,e,n);return o?JSON.stringify({modifiedArgs:{...r,command:o}}):x}function T(t,e,n){return(r,o,i)=>{if(r.tool_name!==e)return x;let s=r.tool_input,c=Y(t,s,r,o,i);return c?n(s,c):x}}var tr=new Set(["run_terminal_command","Bash","bash"]);function er(t,e,n){let r=t.toolName??t.tool_name;if(typeof r!="string"||!tr.has(r))return x;let o=t.toolInput??t.tool_input,i=Y("grok",o,t,e,n);return i?C(o,i):x}var nr={copilot:Qn,droid:T("droid","Execute",C),trae:T("trae","RunCommand",C),"qwen-code":T("qwen-code","run_shell_command",C),crush:T("crush","bash",(t,e)=>JSON.stringify({updated_input:{command:e}})),junie:T("junie","Bash",(t,e)=>JSON.stringify({updatedInput:{...t,command:e}})),zcode:T("zcode","Bash",C),grok:er};function Ut(t,e,n=b(t),r=k){return q(e)?nr[t](e,n,r):x}function H(t){return S()?null:b(t)}function rr(t,e,n={}){let r=n.recordUsage??k;switch(t){case"claude-code":case"codex":return e.hook_event_name!==void 0&&e.hook_event_name!=="PreToolUse"?"":It(e,t,H(t),r,n.claudeDirs??Z(),n.pathEnv??process.env.PATH)??"";case"cursor":return Dt(e,H(t),r);case"gemini-cli":return Mt(e,H(t),r);case"vibe":return ut(e,(o,i)=>R(o,"vibe",i,H(t),r));case"antigravity":return lt(e,(o,i)=>R(o,"antigravity",i,H(t),r));default:return Ut(t,e,H(t),r)}}function D(t,e,n={}){let r=Ft(t,e);return r?rr(r,t,n):n.fallback??""}var or=new Set(["bash","file_system.bash"]),V=JSON.stringify({decision:"allow"});function ut(t,e=(n,r)=>R(n,"vibe",r)){if(!v(t)||t.hook_event_name!=="pre_tool"||typeof t.tool_name!="string"||!or.has(t.tool_name))return"";let n=t.tool_input;if(!v(n)||typeof n.command!="string"||!n.command)return"";let r=e(n.command,typeof t.session_id=="string"?t.session_id:"unknown");return r?JSON.stringify({hook_specific_output:{tool_input:{...n,command:r}}}):""}function lt(t,e=(n,r)=>R(n,"antigravity",r)){if(!v(t)||!v(t.toolCall)||t.toolCall.name!=="run_command")return V;let n=t.toolCall.args;if(!v(n)||typeof n.CommandLine!="string"||!n.CommandLine)return V;let r=e(n.CommandLine,typeof t.conversationId=="string"?t.conversationId:"unknown");return r?JSON.stringify({decision:"allow",overwrite:{CommandLine:r}}):V}var zt={vibe:{build:t=>ut(t),fallback:""},antigravity:{build:t=>lt(t),fallback:V}};function Jt(t){return zt[t??""]?.fallback??""}function sr(t,e){let n=zt[t??""];if(!n)return"";let r;try{r=JSON.parse(e.replace(/^/,""))}catch{return n.fallback}return v(r)?D(r,t,{fallback:n.fallback}):n.build(r)}async function Bt(t){process.stdout.write(sr(t,await N()))}Bt(process.argv[2]).catch(t=>{process.stderr.write(`tkr-agent-hook: ${t.message}
|
|
13
|
+
`),process.stdout.write(Jt(process.argv[2])),process.exit(0)});
|