token-goat 2.6.7 → 2.6.8

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.
Files changed (2) hide show
  1. package/dist/token-goat.mjs +91 -19
  2. package/package.json +1 -1
@@ -137045,7 +137045,7 @@ init_define_import_meta_env();
137045
137045
  import { createRequire } from "node:module";
137046
137046
  function resolveVersion() {
137047
137047
  if (true) {
137048
- return "2.6.7";
137048
+ return "2.6.8";
137049
137049
  }
137050
137050
  const require2 = createRequire(import.meta.url);
137051
137051
  const pkg = require2("../package.json");
@@ -140600,11 +140600,25 @@ function main() {
140600
140600
  process.stdout.write('{}')
140601
140601
  return
140602
140602
  }
140603
- const res = spawnSync('token-goat hook ' + eventName, {
140604
- input,
140605
- encoding: 'utf8',
140606
- shell: true,
140607
- })
140603
+ // process.argv[3], when present, is the absolute path to the token-goat CLI entry
140604
+ // that ran 'token-goat install --codex' (baked in by hookCommandFor in
140605
+ // codex_install.ts). Invoking it directly via process.execPath sidesteps PATH/shell
140606
+ // resolution for this inner call, the same single-point-of-failure class fixed for
140607
+ // the Copilot CLI bridge's inner hook call (a bare 'token-goat' on PATH failing to
140608
+ // resolve crashes this call, and Codex -- like Copilot -- fails closed on a
140609
+ // non-zero-exit hook). Falls back to the old PATH-based shell:true invocation when
140610
+ // argv[3] is absent (an older cached hook config).
140611
+ const entryPath = process.argv[3]
140612
+ const res = entryPath
140613
+ ? spawnSync(process.execPath, [entryPath, 'hook', eventName], {
140614
+ input,
140615
+ encoding: 'utf8',
140616
+ })
140617
+ : spawnSync('token-goat hook ' + eventName, {
140618
+ input,
140619
+ encoding: 'utf8',
140620
+ shell: true,
140621
+ })
140608
140622
  if (res.status !== 0 || !res.stdout) {
140609
140623
  process.stdout.write('{}')
140610
140624
  return
@@ -140969,7 +140983,9 @@ function groupHasTokenGoat2(groups, matcher) {
140969
140983
  return false;
140970
140984
  }
140971
140985
  function hookCommandFor(scriptPath, eventArg) {
140972
- return `node "${scriptPath}" ${eventArg}`;
140986
+ const entryPath = process.argv[1];
140987
+ const entryArg = entryPath ? ` "${entryPath}"` : "";
140988
+ return `"${process.execPath}" "${scriptPath}" ${eventArg}${entryArg}`;
140973
140989
  }
140974
140990
  function installCodex() {
140975
140991
  const configPath2 = codexConfigPath();
@@ -143130,8 +143146,7 @@ var MAX_OUTPUT_LINES = 60;
143130
143146
  function extractMarkdownHeadings(content) {
143131
143147
  const headings = [];
143132
143148
  const lines = content.split("\n");
143133
- for (let i = 0; i < lines.length; i++) {
143134
- const line = lines[i];
143149
+ for (const [i, line] of eachUnfencedLine(lines)) {
143135
143150
  if (!line) continue;
143136
143151
  const match2 = /^(#+)\s+(.+?)\s*$/.exec(line);
143137
143152
  if (!match2 || match2.length < 3) continue;
@@ -169515,6 +169530,7 @@ import { spawnSync } from "node:child_process";
169515
169530
  import * as fs from "node:fs";
169516
169531
  import * as os from "node:os";
169517
169532
  import * as path from "node:path";
169533
+ import { fileURLToPath } from "node:url";
169518
169534
 
169519
169535
  // pi built-in tool names -> token-goat internal tool names
169520
169536
  const TOOL_TO_TG: Record<string, string> = {
@@ -169541,18 +169557,58 @@ const ARGS_TO_TG: Record<string, Record<string, string>> = {
169541
169557
  // it's excluded here rather than spawning a hook call that always no-ops.
169542
169558
  const PRE_HOOK_TOOLS = new Set(["Read", "Grep", "Bash", "WebFetch"]);
169543
169559
 
169560
+ // resolveEntryPath reads a sidecar JSON file (token-goat-entry.json, written by
169561
+ // installPi next to this extension file) containing the absolute path to the
169562
+ // token-goat CLI entry that was running at install time. Unlike Codex/Copilot,
169563
+ // this extension has no per-invocation command line to bake a path into (pi
169564
+ // loads it once as a module, then calls into it via pi.on(...) handlers), so
169565
+ // the sidecar file is the install-time channel for this value instead. Returns
169566
+ // undefined (triggering the PATH-based fallback below) if the sidecar is
169567
+ // missing, unreadable, or points at a path that no longer exists -- e.g. an
169568
+ // older install predating this file, or a moved/removed token-goat install.
169569
+ function resolveEntryPath(): string | undefined {
169570
+ try {
169571
+ const here = path.dirname(fileURLToPath(import.meta.url));
169572
+ const sidecarPath = path.join(here, "token-goat-entry.json");
169573
+ const parsed = JSON.parse(fs.readFileSync(sidecarPath, "utf8")) as { entryPath?: unknown };
169574
+ if (typeof parsed.entryPath === "string" && parsed.entryPath && fs.existsSync(parsed.entryPath)) {
169575
+ return parsed.entryPath;
169576
+ }
169577
+ } catch {
169578
+ // fall through to undefined
169579
+ }
169580
+ return undefined;
169581
+ }
169582
+
169544
169583
  function callHook(event: string, payload: Record<string, unknown>): Record<string, unknown> | null {
169545
169584
  try {
169546
169585
  // TOKEN_GOAT_HARNESS_OVERRIDE=pi guarantees detectHarness() resolves to
169547
169586
  // 'pi' for every call this bridge makes, instead of relying on a guessed
169548
169587
  // ambient env var pi-coding-agent may or may not set.
169549
- const r = spawnSync("token-goat", ["hook", event], {
169550
- input: JSON.stringify(payload),
169551
- encoding: "utf8",
169552
- timeout: 5000,
169553
- windowsHide: true,
169554
- env: { ...process.env, TOKEN_GOAT_HARNESS_OVERRIDE: "pi" },
169555
- });
169588
+ //
169589
+ // Invoking "token-goat" as a bare command here depends on PATH resolution
169590
+ // (the npm global bin being on whatever PATH pi-coding-agent's own process
169591
+ // inherits) -- the same class of single-point-of-failure fixed for the
169592
+ // Codex/Copilot CLI bridges' hook commands. When resolveEntryPath() finds a
169593
+ // baked install-time path, invoke it directly via process.execPath instead,
169594
+ // sidestepping PATH entirely; otherwise fall back to the old PATH-based
169595
+ // lookup (e.g. an extension installed before this fix).
169596
+ const entryPath = resolveEntryPath();
169597
+ const r = entryPath
169598
+ ? spawnSync(process.execPath, [entryPath, "hook", event], {
169599
+ input: JSON.stringify(payload),
169600
+ encoding: "utf8",
169601
+ timeout: 5000,
169602
+ windowsHide: true,
169603
+ env: { ...process.env, TOKEN_GOAT_HARNESS_OVERRIDE: "pi" },
169604
+ })
169605
+ : spawnSync("token-goat", ["hook", event], {
169606
+ input: JSON.stringify(payload),
169607
+ encoding: "utf8",
169608
+ timeout: 5000,
169609
+ windowsHide: true,
169610
+ env: { ...process.env, TOKEN_GOAT_HARNESS_OVERRIDE: "pi" },
169611
+ });
169556
169612
  if (r.error) return null;
169557
169613
  const out = r.stdout?.trim();
169558
169614
  if (!out) return null;
@@ -169731,6 +169787,9 @@ function piLocalExtensionPath() {
169731
169787
  function piExtensionPath(opts = {}) {
169732
169788
  return opts.local === true ? piLocalExtensionPath() : piGlobalExtensionPath();
169733
169789
  }
169790
+ function piEntrySidecarPath(opts = {}) {
169791
+ return path28.join(path28.dirname(piExtensionPath(opts)), "token-goat-entry.json");
169792
+ }
169734
169793
  function installPi(opts = {}) {
169735
169794
  const extensionPath = piExtensionPath(opts);
169736
169795
  let existing;
@@ -169739,6 +169798,11 @@ function installPi(opts = {}) {
169739
169798
  } catch {
169740
169799
  existing = void 0;
169741
169800
  }
169801
+ const entryPath = process.argv[1];
169802
+ if (entryPath) {
169803
+ ensureDirSync(path28.dirname(extensionPath));
169804
+ atomicWriteText(piEntrySidecarPath(opts), JSON.stringify({ entryPath }));
169805
+ }
169742
169806
  if (existing === PI_EXTENSION_SCRIPT) {
169743
169807
  return { extensionPath, alreadyInstalled: true };
169744
169808
  }
@@ -169748,6 +169812,10 @@ function installPi(opts = {}) {
169748
169812
  }
169749
169813
  function uninstallPi(opts = {}) {
169750
169814
  const extensionPath = piExtensionPath(opts);
169815
+ try {
169816
+ fs25.unlinkSync(piEntrySidecarPath(opts));
169817
+ } catch {
169818
+ }
169751
169819
  try {
169752
169820
  fs25.unlinkSync(extensionPath);
169753
169821
  return true;
@@ -194704,7 +194772,7 @@ function getHintFor(command2) {
194704
194772
  return "Request a narrower sub-heading, e.g. 'doc.md::Section#2'.";
194705
194773
  }
194706
194774
  if (cmd === "lines") {
194707
- return "Request a smaller line range, e.g. 'file.py::100-150'.";
194775
+ return "Request a smaller line range, e.g. 'file.py@100-150'.";
194708
194776
  }
194709
194777
  if (cmd === "bash-output" || cmd === "web-output") {
194710
194778
  return "Use --grep PATTERN, --section HEADING, or --tail N to narrow the cached output.";
@@ -197781,6 +197849,10 @@ function parseDiffHunks(diffText) {
197781
197849
  currentFile = fileMatch[1] ?? null;
197782
197850
  continue;
197783
197851
  }
197852
+ if (line === "+++ /dev/null") {
197853
+ currentFile = null;
197854
+ continue;
197855
+ }
197784
197856
  const hunkMatch = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/.exec(line);
197785
197857
  if (hunkMatch !== null && currentFile !== null) {
197786
197858
  const newStart = parseInt(hunkMatch[1], 10);
@@ -205089,7 +205161,7 @@ function buildProgram() {
205089
205161
  () => runSkeleton({
205090
205162
  file: file2,
205091
205163
  ...opts.json === true ? { json: true } : {},
205092
- ...opts.minLines !== void 0 ? { minLines: Number.parseInt(opts.minLines, 10) } : {},
205164
+ ...opts.minLines !== void 0 ? { minLines: requireNonNegativeInt("--min-lines", opts.minLines) } : {},
205093
205165
  ...opts.forceRefresh === true ? { forceRefresh: true } : {},
205094
205166
  ...opts.stats === true ? { stats: true } : {}
205095
205167
  })
@@ -205100,7 +205172,7 @@ function buildProgram() {
205100
205172
  () => runOutline({
205101
205173
  file: file2,
205102
205174
  ...opts.json === true ? { json: true } : {},
205103
- ...opts.minLines !== void 0 ? { minLines: Number.parseInt(opts.minLines, 10) } : {},
205175
+ ...opts.minLines !== void 0 ? { minLines: requireNonNegativeInt("--min-lines", opts.minLines) } : {},
205104
205176
  ...opts.forceRefresh === true ? { forceRefresh: true } : {},
205105
205177
  ...opts.stats === true ? { stats: true } : {}
205106
205178
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "token-goat",
3
- "version": "2.6.7",
3
+ "version": "2.6.8",
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",