fix: compile bundled hook handlers during build#11488
fix: compile bundled hook handlers during build#11488ssh-22-dev wants to merge 5 commits intoopenclaw:mainfrom
Conversation
Bundled hooks (session-memory, command-logger, etc.) have handler.ts files that were never compiled to handler.js during build. Only HOOK.md metadata was copied. This caused "No hooks found" on all npm/git installs. Add scripts/build-hooks.ts to compile handlers with esbuild after tsdown. Fixes openclaw#11348
package.json
Outdated
| "android:run": "cd apps/android && ./gradlew :app:installDebug && adb shell am start -n ai.openclaw.android/.MainActivity", | ||
| "android:test": "cd apps/android && ./gradlew :app:testDebugUnitTest", | ||
| "build": "pnpm canvas:a2ui:bundle && tsdown && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-compat.ts", | ||
| "build": "pnpm canvas:a2ui:bundle && tsdown && node --import tsx scripts/build-hooks.ts && pnpm build:plugin-sdk:dts && node --import tsx scripts/write-plugin-sdk-entry-dts.ts && node --import tsx scripts/canvas-a2ui-copy.ts && node --import tsx scripts/copy-hook-metadata.ts && node --import tsx scripts/write-build-info.ts && node --import tsx scripts/write-cli-compat.ts", |
There was a problem hiding this comment.
Trailing whitespace in script
The build script line ends with extra spaces after the closing quote, which will fail formatting checks in repos that enforce JSON formatting (and adds noise to diffs). Please remove the trailing whitespace at the end of this line.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix With AI
This is a comment left during a code review.
Path: package.json
Line: 35:35
Comment:
**Trailing whitespace in script**
The `build` script line ends with extra spaces after the closing quote, which will fail formatting checks in repos that enforce JSON formatting (and adds noise to diffs). Please remove the trailing whitespace at the end of this line.
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise.
scripts/build-hooks.ts
Outdated
| const HOOKS_SRC = "src/hooks/bundled"; | ||
| const HOOKS_DIST = "dist/hooks/bundled"; |
There was a problem hiding this comment.
CWD-dependent paths
HOOKS_SRC/HOOKS_DIST are relative paths, so running this script from anywhere other than repo root will read/write the wrong locations. Since it’s wired into pnpm build this usually works, but it will break if the build pipeline invokes it with a different working directory. Anchoring these paths to the project root (like copy-hook-metadata.ts does) avoids that class of build failures.
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/build-hooks.ts
Line: 13:14
Comment:
**CWD-dependent paths**
`HOOKS_SRC`/`HOOKS_DIST` are relative paths, so running this script from anywhere other than repo root will read/write the wrong locations. Since it’s wired into `pnpm build` this usually works, but it will break if the build pipeline invokes it with a different working directory. Anchoring these paths to the project root (like `copy-hook-metadata.ts` does) avoids that class of build failures.
How can I resolve this? If you propose a fix, please make it concise.|
@greptile-apps can you check again to see if the issues are resolved? |
| outfile: join(HOOKS_DIST, hook, "handler.js"), | ||
| external: EXTERNAL_DEPS, | ||
| logLevel: "warning", |
There was a problem hiding this comment.
Missing output directory
outfile targets dist/hooks/bundled/${hook}/handler.js, but this script never creates dist/hooks/bundled/${hook} (or even dist/hooks/bundled) beforehand. On a clean build where those directories don’t exist, esbuild will fail with ENOENT and this script will eventually process.exit(1), breaking pnpm build and still not emitting handler files. Create the output dir (e.g., mkdirSync(join(HOOKS_DIST, hook), { recursive: true })) before calling build().
Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/build-hooks.ts
Line: 54:56
Comment:
**Missing output directory**
`outfile` targets `dist/hooks/bundled/${hook}/handler.js`, but this script never creates `dist/hooks/bundled/${hook}` (or even `dist/hooks/bundled`) beforehand. On a clean build where those directories don’t exist, esbuild will fail with ENOENT and this script will eventually `process.exit(1)`, breaking `pnpm build` and still not emitting handler files. Create the output dir (e.g., `mkdirSync(join(HOOKS_DIST, hook), { recursive: true })`) before calling `build()`.
How can I resolve this? If you propose a fix, please make it concise.esbuild fails with ENOENT on clean builds when dist/hooks/bundled/<hook> doesn't exist. Add mkdirSync with recursive flag before build call.
|
@greptile-apps another go at this, please? |
|
@greptile-apps The project's engines.node is >=22.12.0, so target: "node22" is aligned with the minimum supported version. One final check, please. |
|
I had a branch I was ready to push to fix this then saw you got it. Thanks! |
|
Closing in favor of #9295 which takes a cleaner approach (native tsdown entries vs. separate esbuild script) and fixes both the path resolution and handler compilation issues in one PR. Thanks @patrickshao! |
Summary
Fixes #11348. Bundled hook
handler.tsfiles are not compiled tohandler.jsduring build, causing all hooks to fail on npm/git installs.lobster-biscuit
Repro Steps
npm install -g openclaw@latest(or clone +pnpm build)ls dist/hooks/bundled/session-memory/→ onlyHOOK.md, nohandler.jsopenclaw hooks list --verbose→ "No hooks found"Root Cause
tsdown.config.tsonly compiles main entry points.scripts/copy-hook-metadata.tscopiesHOOK.mdbut never compileshandler.ts→handler.js. Hook discovery requireshandler.jsto exist.Behavior Changes
scripts/build-hooks.tsruns aftertsdownsrc/hooks/bundled/*/handler.ts→dist/hooks/bundled/*/handler.jsCodebase and GitHub Search
copy-hook-metadata.tsfor patterns (existence check, path anchoring)tsdown.config.ts— hooks not included as entry pointsTests
Manual Testing
Prerequisites
Steps
pnpm install && pnpm buildls dist/hooks/bundled/*/handler.js— should list handler filesopenclaw hooks list --verbose— should show hooks as "ready"Evidence
Verified on VPS with npm global install — hooks now load correctly.
Sign-Off
Greptile Overview
Greptile Summary
This PR updates the build pipeline to ensure bundled hook handlers are included in published artifacts. It adds a new
scripts/build-hooks.tsstep (run aftertsdown) that scanssrc/hooks/bundled/*/handler.tsand uses esbuild to emitdist/hooks/bundled/*/handler.js, so hook discovery works on npm/git installs where onlydist/**is present.Confidence Score: 5/5