@goodfoot/agent-hooks 1.0.9 → 1.0.10
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/CHANGELOG.md +8 -4
- package/README.md +2 -0
- package/dist/agents/antigravity/cli-support.js +4 -2
- package/dist/agents/antigravity/scaffold.js +1 -1
- package/dist/agents/codex/cli-support.js +4 -2
- package/dist/agents/codex/scaffold.js +1 -1
- package/dist/agents/opencode/cli-support.js +1 -1
- package/dist/cli.js +32 -8
- package/dist/scaffold.js +1 -1
- package/package.json +1 -1
- package/types/cli.d.ts +15 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
# @goodfoot/agent-hooks npm package changelog
|
|
2
2
|
|
|
3
|
-
## 1.0.
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
3
|
+
## 1.0.10
|
|
4
|
+
- Fixed scaffolded hook bundles to work when the install path is a symlink or otherwise differs from the project root, so hooks resolve correctly across repository layouts
|
|
5
|
+
- Improved stack traces from hooks by making source map resolution reliable in relocated or symlinked installs
|
|
6
|
+
- Applied the portability fixes consistently across the Claude Code, Codex, and Antigravity entry points
|
|
7
|
+
|
|
8
|
+
## 1.0.10
|
|
9
|
+
|
|
10
|
+
Makes compiled bundles portable across ordinary hoisted workspace layouts by anchoring esbuild's module-boundary comments and sourcemap source paths at the directory that owns the resolved `node_modules`. Inline sourcemaps are now disabled by default for smaller, reviewable build artifacts and remain available with the explicit `--sourcemap` flag.
|
|
7
11
|
|
|
8
12
|
## 1.0.9
|
|
9
13
|
|
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
**Build AI coding agent hooks in TypeScript — one package, any supported agent.**
|
|
4
4
|
|
|
5
|
+
Compiled bundles omit inline sourcemaps by default. Pass `--sourcemap` when original TypeScript locations are needed in runtime stack traces.
|
|
6
|
+
|
|
5
7
|
`@goodfoot/agent-hooks` is the unified successor to `@goodfoot/claude-code-hooks` and
|
|
6
8
|
`@goodfoot/codex-hooks`: a shared agent-neutral core (hook factory primitive, transport
|
|
7
9
|
driver, `Logger`, env/stdin utilities) with a per-agent entry point on top. Write
|
|
@@ -22,7 +22,7 @@ import * as path from "node:path";
|
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
23
|
import * as esbuild from "esbuild";
|
|
24
24
|
import ts from "typescript";
|
|
25
|
-
import { buildEsbuildLoaderMap, discoverHookSourceFiles, parseEsbuildLoaderFlag, pruneStaleHashedBundles, sha256Prefix8, symlinkVisiblePath, } from "../../cli.js";
|
|
25
|
+
import { buildEsbuildLoaderMap, discoverHookSourceFiles, moduleWorkingDir, parseEsbuildLoaderFlag, pruneStaleHashedBundles, sha256Prefix8, symlinkVisiblePath, } from "../../cli.js";
|
|
26
26
|
import { DEFAULT_TIMEOUT_SECONDS, GROUPED_EVENTS, HOOK_FACTORY_TO_EVENT } from "./constants.js";
|
|
27
27
|
import { HOOK_EVENT_NAMES } from "./events.js";
|
|
28
28
|
/** The matcher emitted when a grouped event's config names none. `"*"` matches every tool. */
|
|
@@ -82,9 +82,10 @@ export function analyzeAntigravityHookFile(sourcePath) {
|
|
|
82
82
|
* Bundles one hook source into a self-contained ESM executable whose entry
|
|
83
83
|
* wrapper calls this agent's `execute`.
|
|
84
84
|
*/
|
|
85
|
-
export async function compileAntigravityHook(sourcePath, loaders, sourcemap =
|
|
85
|
+
export async function compileAntigravityHook(sourcePath, loaders, sourcemap = false) {
|
|
86
86
|
const resolveDir = path.dirname(sourcePath);
|
|
87
87
|
const runtimeAbsolute = symlinkVisiblePath(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "./transport.js"), resolveDir);
|
|
88
|
+
const absWorkingDir = moduleWorkingDir(runtimeAbsolute, resolveDir);
|
|
88
89
|
const runtimeRelative = path.relative(resolveDir, runtimeAbsolute).replace(/\\/g, "/");
|
|
89
90
|
const runtimeSpecifier = runtimeRelative.startsWith(".") ? runtimeRelative : `./${runtimeRelative}`;
|
|
90
91
|
const entry = [
|
|
@@ -94,6 +95,7 @@ export async function compileAntigravityHook(sourcePath, loaders, sourcemap = tr
|
|
|
94
95
|
``,
|
|
95
96
|
].join("\n");
|
|
96
97
|
const built = await esbuild.build({
|
|
98
|
+
absWorkingDir,
|
|
97
99
|
stdin: {
|
|
98
100
|
contents: entry,
|
|
99
101
|
resolveDir,
|
|
@@ -50,7 +50,7 @@ function packageJson(projectName, outputPath) {
|
|
|
50
50
|
lint: "biome check .",
|
|
51
51
|
typecheck: "tsc --noEmit",
|
|
52
52
|
},
|
|
53
|
-
dependencies: { [PACKAGE_NAME]: "^1.0.
|
|
53
|
+
dependencies: { [PACKAGE_NAME]: "^1.0.10" },
|
|
54
54
|
devDependencies: {
|
|
55
55
|
"@biomejs/biome": "2.4.9",
|
|
56
56
|
"@types/node": "^24.0.0",
|
|
@@ -15,7 +15,7 @@ import * as path from "node:path";
|
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
16
|
import * as esbuild from "esbuild";
|
|
17
17
|
import ts from "typescript";
|
|
18
|
-
import { buildEsbuildLoaderMap, discoverHookSourceFiles, parseEsbuildLoaderFlag, pruneStaleHashedBundles, sha256Prefix8, symlinkVisiblePath, } from "../../cli.js";
|
|
18
|
+
import { buildEsbuildLoaderMap, discoverHookSourceFiles, moduleWorkingDir, parseEsbuildLoaderFlag, pruneStaleHashedBundles, sha256Prefix8, symlinkVisiblePath, } from "../../cli.js";
|
|
19
19
|
import { EVENTS_WITH_MATCHER, HOOK_FACTORY_TO_EVENT } from "./constants.js";
|
|
20
20
|
/**
|
|
21
21
|
* Extracts Codex hook metadata (event name, matcher, timeout in
|
|
@@ -88,9 +88,10 @@ export function analyzeCodexHookFile(sourcePath) {
|
|
|
88
88
|
* Compiles one Codex hook to a self-contained ESM executable whose entry
|
|
89
89
|
* wrapper imports this package's Codex runtime module (`execute`).
|
|
90
90
|
*/
|
|
91
|
-
export async function compileCodexHook(sourcePath, loaders, sourcemap =
|
|
91
|
+
export async function compileCodexHook(sourcePath, loaders, sourcemap = false) {
|
|
92
92
|
const resolveDir = path.dirname(sourcePath);
|
|
93
93
|
const runtimePathAbsolute = symlinkVisiblePath(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "./transport.js"), resolveDir);
|
|
94
|
+
const absWorkingDir = moduleWorkingDir(runtimePathAbsolute, resolveDir);
|
|
94
95
|
let relativeRuntimePath = path.relative(resolveDir, runtimePathAbsolute).replace(/\\/g, "/");
|
|
95
96
|
if (!relativeRuntimePath.startsWith(".")) {
|
|
96
97
|
relativeRuntimePath = `./${relativeRuntimePath}`;
|
|
@@ -102,6 +103,7 @@ execute(hook);
|
|
|
102
103
|
`;
|
|
103
104
|
const baseName = path.basename(sourcePath, path.extname(sourcePath));
|
|
104
105
|
const result = await esbuild.build({
|
|
106
|
+
absWorkingDir,
|
|
105
107
|
stdin: {
|
|
106
108
|
contents: wrapperContent,
|
|
107
109
|
resolveDir,
|
|
@@ -23,7 +23,7 @@ import { buildEsbuildLoaderMap, discoverHookSourceFiles, parseEsbuildLoaderFlag
|
|
|
23
23
|
* Bundles one OpenCode plugin entry to a self-contained ESM artifact. The
|
|
24
24
|
* source file's own default export is preserved unchanged — no wrapper.
|
|
25
25
|
*/
|
|
26
|
-
export async function compileOpenCodePlugin(sourcePath, loaders, sourcemap =
|
|
26
|
+
export async function compileOpenCodePlugin(sourcePath, loaders, sourcemap = false) {
|
|
27
27
|
const result = await esbuild.build({
|
|
28
28
|
entryPoints: [sourcePath],
|
|
29
29
|
loader: loaders,
|
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ import { scaffoldProject } from "./scaffold.js";
|
|
|
26
26
|
// ============================================================================
|
|
27
27
|
// Constants
|
|
28
28
|
// ============================================================================
|
|
29
|
-
const VERSION = "1.0.
|
|
29
|
+
const VERSION = "1.0.10";
|
|
30
30
|
const DEFAULT_ESBUILD_LOADERS = {
|
|
31
31
|
".md": "text",
|
|
32
32
|
};
|
|
@@ -142,13 +142,13 @@ Optional Arguments:
|
|
|
142
142
|
--no-stable-names
|
|
143
143
|
Restore the pre-1.7 behavior: hashed compiled bundles (<name>.<hash>.mjs).
|
|
144
144
|
|
|
145
|
-
--sourcemap
|
|
145
|
+
--sourcemap
|
|
146
146
|
Embed an inline sourcemap in each compiled bundle so stack traces show
|
|
147
147
|
original TypeScript source locations.
|
|
148
148
|
|
|
149
|
-
--no-sourcemap
|
|
150
|
-
Emit bundles without the inline sourcemap, shrinking compiled output
|
|
151
|
-
|
|
149
|
+
--no-sourcemap (default)
|
|
150
|
+
Emit bundles without the inline sourcemap, shrinking compiled output.
|
|
151
|
+
The content hash is unaffected.
|
|
152
152
|
|
|
153
153
|
-h, --help
|
|
154
154
|
Show this help message.
|
|
@@ -257,7 +257,7 @@ function parseArgs(argv) {
|
|
|
257
257
|
// as true, while the Codex branch defaults by command context
|
|
258
258
|
// (plugin mode → stable, otherwise hashed).
|
|
259
259
|
stableNames: undefined,
|
|
260
|
-
sourcemap:
|
|
260
|
+
sourcemap: false,
|
|
261
261
|
};
|
|
262
262
|
for (let i = 0; i < argv.length; i++) {
|
|
263
263
|
const arg = argv[i];
|
|
@@ -642,6 +642,28 @@ function symlinkVisiblePath(realPath, resolveDir) {
|
|
|
642
642
|
dir = parent;
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* Returns the stable project anchor for a module reached through node_modules.
|
|
647
|
+
*
|
|
648
|
+
* esbuild otherwise uses process.cwd() when rendering module-boundary comments
|
|
649
|
+
* and sourcemap source paths. A workspace script normally runs from the
|
|
650
|
+
* consuming package, while its dependencies may be hoisted several directories
|
|
651
|
+
* higher, making those emitted paths depend on the consumer's nesting depth.
|
|
652
|
+
* Anchoring at the directory which owns the visible node_modules keeps the
|
|
653
|
+
* canonical `node_modules/...` form in every such layout.
|
|
654
|
+
*/
|
|
655
|
+
function moduleWorkingDir(modulePath, fallback) {
|
|
656
|
+
for (let dir = path.dirname(modulePath);;) {
|
|
657
|
+
if (path.basename(dir) === "node_modules") {
|
|
658
|
+
return path.dirname(dir);
|
|
659
|
+
}
|
|
660
|
+
const parent = path.dirname(dir);
|
|
661
|
+
if (parent === dir) {
|
|
662
|
+
return fallback;
|
|
663
|
+
}
|
|
664
|
+
dir = parent;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
645
667
|
/**
|
|
646
668
|
* Compiles a TypeScript hook file to a self-contained ESM executable.
|
|
647
669
|
*
|
|
@@ -672,6 +694,7 @@ async function compileHook(options) {
|
|
|
672
694
|
// nesting depth.
|
|
673
695
|
const resolveDir = path.dirname(sourcePath);
|
|
674
696
|
const runtimePathAbsolute = symlinkVisiblePath(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "./agents/claude-code/transport.js"), resolveDir);
|
|
697
|
+
const absWorkingDir = moduleWorkingDir(runtimePathAbsolute, resolveDir);
|
|
675
698
|
// Compute relative paths from resolveDir to avoid absolute paths in source maps.
|
|
676
699
|
// This ensures reproducible builds regardless of checkout directory.
|
|
677
700
|
const relativeSourcePath = `./${path.basename(sourcePath)}`;
|
|
@@ -731,6 +754,7 @@ execute(hook);
|
|
|
731
754
|
].join("\n");
|
|
732
755
|
// Common esbuild options
|
|
733
756
|
const commonOptions = {
|
|
757
|
+
absWorkingDir,
|
|
734
758
|
stdin: stdinOptions,
|
|
735
759
|
loader: loaders,
|
|
736
760
|
format: "esm",
|
|
@@ -784,7 +808,7 @@ execute(hook);
|
|
|
784
808
|
// output minus the trailing sourceMappingURL comment (verified on esbuild
|
|
785
809
|
// 0.24.2), so the sourcemap-free content is emitted directly. The content
|
|
786
810
|
// hash is always derived from pass-1 output, so it is unchanged by the flag.
|
|
787
|
-
if (sourcemap
|
|
811
|
+
if (sourcemap !== true) {
|
|
788
812
|
return { content: contentForHash, contentHash };
|
|
789
813
|
}
|
|
790
814
|
const resultWithSourcemap = await esbuild.build({
|
|
@@ -1447,4 +1471,4 @@ if (isDirectExecution) {
|
|
|
1447
1471
|
// Shared build primitives reused by the per-agent CLI branches (single
|
|
1448
1472
|
// source for driver logic — the duplication check forbids re-deriving these
|
|
1449
1473
|
// inside agents/*).
|
|
1450
|
-
export { analyzeHookFile, buildLoaderMap, buildLoaderMap as buildEsbuildLoaderMap, compileHook, detectHookContext, discoverHookFiles, discoverHookFiles as discoverHookSourceFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateContentHash as sha256Prefix8, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, parseArgs, parseLoaderFlag, parseLoaderFlag as parseEsbuildLoaderFlag, pruneStaleHashedBundles, readExistingHooksJson, removeOldGeneratedFiles, symlinkVisiblePath, validateArgs, };
|
|
1474
|
+
export { analyzeHookFile, buildLoaderMap, buildLoaderMap as buildEsbuildLoaderMap, compileHook, detectHookContext, discoverHookFiles, discoverHookFiles as discoverHookSourceFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateContentHash as sha256Prefix8, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, moduleWorkingDir, parseArgs, parseLoaderFlag, parseLoaderFlag as parseEsbuildLoaderFlag, pruneStaleHashedBundles, readExistingHooksJson, removeOldGeneratedFiles, symlinkVisiblePath, validateArgs, };
|
package/dist/scaffold.js
CHANGED
|
@@ -131,7 +131,7 @@ function generatePackageJson(projectName, outputPath) {
|
|
|
131
131
|
typecheck: "tsc --noEmit",
|
|
132
132
|
},
|
|
133
133
|
dependencies: {
|
|
134
|
-
"@goodfoot/agent-hooks": "^1.0.
|
|
134
|
+
"@goodfoot/agent-hooks": "^1.0.10",
|
|
135
135
|
},
|
|
136
136
|
devDependencies: {
|
|
137
137
|
"@biomejs/biome": "2.4.16",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodfoot/agent-hooks",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "Unified agent hooks library: shared core runtime with per-agent entry points for Claude Code, Codex, and Antigravity",
|
|
5
5
|
"homepage": "https://github.com/goodfoot-io/marketplace/tree/main/packages/agent-hooks",
|
|
6
6
|
"repository": {
|
package/types/cli.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ interface CliArgs {
|
|
|
54
54
|
pluginRoot?: boolean;
|
|
55
55
|
/** Emit hash-free `<name>.mjs` bundles. Defaults to true; set false with --no-stable-names. */
|
|
56
56
|
stableNames?: boolean;
|
|
57
|
-
/** Embed an inline sourcemap in compiled bundles. Defaults to
|
|
57
|
+
/** Embed an inline sourcemap in compiled bundles. Defaults to false; enable with --sourcemap. */
|
|
58
58
|
sourcemap?: boolean;
|
|
59
59
|
}
|
|
60
60
|
type HookLoaderMap = Record<string, esbuild.Loader>;
|
|
@@ -173,14 +173,14 @@ interface CompileHookOptions {
|
|
|
173
173
|
logEnvVar?: string;
|
|
174
174
|
/** Explicit esbuild loaders for non-code imports. */
|
|
175
175
|
loaders: HookLoaderMap;
|
|
176
|
-
/** Embed an inline sourcemap in the compiled content. Defaults to
|
|
176
|
+
/** Embed an inline sourcemap in the compiled content. Defaults to false; enable with --sourcemap. */
|
|
177
177
|
sourcemap?: boolean;
|
|
178
178
|
}
|
|
179
179
|
/**
|
|
180
180
|
* Result of compiling a hook.
|
|
181
181
|
*/
|
|
182
182
|
interface CompileHookResult {
|
|
183
|
-
/** Compiled content, with inline sourcemaps
|
|
183
|
+
/** Compiled content, with inline sourcemaps when enabled. */
|
|
184
184
|
content: string;
|
|
185
185
|
/** Stable content hash generated from sourcemap-free output. */
|
|
186
186
|
contentHash: string;
|
|
@@ -203,6 +203,17 @@ interface CompileHookResult {
|
|
|
203
203
|
* checkout-local.
|
|
204
204
|
*/
|
|
205
205
|
declare function symlinkVisiblePath(realPath: string, resolveDir: string): string;
|
|
206
|
+
/**
|
|
207
|
+
* Returns the stable project anchor for a module reached through node_modules.
|
|
208
|
+
*
|
|
209
|
+
* esbuild otherwise uses process.cwd() when rendering module-boundary comments
|
|
210
|
+
* and sourcemap source paths. A workspace script normally runs from the
|
|
211
|
+
* consuming package, while its dependencies may be hoisted several directories
|
|
212
|
+
* higher, making those emitted paths depend on the consumer's nesting depth.
|
|
213
|
+
* Anchoring at the directory which owns the visible node_modules keeps the
|
|
214
|
+
* canonical `node_modules/...` form in every such layout.
|
|
215
|
+
*/
|
|
216
|
+
declare function moduleWorkingDir(modulePath: string, fallback: string): string;
|
|
206
217
|
/**
|
|
207
218
|
* Compiles a TypeScript hook file to a self-contained ESM executable.
|
|
208
219
|
*
|
|
@@ -312,4 +323,4 @@ declare function extractPreservedHooks(existingHooksJson: HooksJson): Partial<Re
|
|
|
312
323
|
*/
|
|
313
324
|
declare function mergeHooksJson(newHooksJson: HooksJson, preservedHooks: Partial<Record<HookEventName, MatcherEntry[]>>): HooksJson;
|
|
314
325
|
export type { CliArgs, CompiledHook, HookConfig, HookLoaderMap, HookMetadata, HooksJson, MatcherEntry };
|
|
315
|
-
export { analyzeHookFile, buildLoaderMap, buildLoaderMap as buildEsbuildLoaderMap, compileHook, detectHookContext, discoverHookFiles, discoverHookFiles as discoverHookSourceFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateContentHash as sha256Prefix8, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, parseArgs, parseLoaderFlag, parseLoaderFlag as parseEsbuildLoaderFlag, pruneStaleHashedBundles, readExistingHooksJson, removeOldGeneratedFiles, symlinkVisiblePath, validateArgs, };
|
|
326
|
+
export { analyzeHookFile, buildLoaderMap, buildLoaderMap as buildEsbuildLoaderMap, compileHook, detectHookContext, discoverHookFiles, discoverHookFiles as discoverHookSourceFiles, extractPreservedHooks, generateCommandPath, generateContentHash, generateContentHash as sha256Prefix8, generateHooksJson, groupHooksByEventAndMatcher, HOOK_FACTORY_TO_EVENT, mergeHooksJson, moduleWorkingDir, parseArgs, parseLoaderFlag, parseLoaderFlag as parseEsbuildLoaderFlag, pruneStaleHashedBundles, readExistingHooksJson, removeOldGeneratedFiles, symlinkVisiblePath, validateArgs, };
|