Skip to content

fix: resolve bundled hooks path on npm global install#11339

Open
matthewpoe wants to merge 2 commits intoopenclaw:mainfrom
matthewpoe:fix/bundled-hooks-path-resolution
Open

fix: resolve bundled hooks path on npm global install#11339
matthewpoe wants to merge 2 commits intoopenclaw:mainfrom
matthewpoe:fix/bundled-hooks-path-resolution

Conversation

@matthewpoe
Copy link

@matthewpoe matthewpoe commented Feb 7, 2026

Summary

Fixes #11331 (path resolution). The related build/packaging issue is tracked separately in #11348.

Problem

On npm global installs, the build bundles bundled-dir.ts into a flat chunk in dist/, so import.meta.url resolves to dist/ rather than dist/hooks/bundled-dir.js. The existing code does path.join(moduleDir, "bundled") which looks for dist/bundled, but the hooks live at dist/hooks/bundled.

This causes all four bundled hooks (session-memory, boot-md, command-logger, soul-evil) to be undiscoverable.

Fix

One-line change: add "hooks" to the path join so it correctly resolves to dist/hooks/bundled.

Verification

Setting OPENCLAW_BUNDLED_HOOKS_DIR to the correct path manually confirms the gateway discovers all four hook directories. This fix makes that the default behavior.

Greptile Overview

Greptile Summary

Updates resolveBundledHooksDir() to look for bundled hooks under dist/hooks/bundled when import.meta.url resolves to the flattened dist/ directory (observed on npm global installs).

However, the new join logic uses path.join(moduleDir, "hooks", "bundled"), which breaks the standard (non-flattened) layout where import.meta.url points at dist/hooks/bundled-dir.js (it would resolve to dist/hooks/hooks/bundled). The resolver should account for both layouts (or resolve from the package root) to avoid regressing non-global installs.

Confidence Score: 2/5

  • Not safe to merge as-is due to a likely regression in bundled hook discovery for non-flattened installs.
  • The change appears to fix the flattened dist/ bundle case, but it deterministically mis-resolves paths when import.meta.url points at dist/hooks/bundled-dir.js (standard output), causing bundled hooks to become undiscoverable in that scenario.
  • src/hooks/bundled-dir.ts

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

On npm global installs (Linux), the bundled code lives in dist/ rather
than dist/hooks/bundled-dir.js, so moduleDir resolves to dist/ and
path.join(moduleDir, 'bundled') looks for dist/bundled instead of
dist/hooks/bundled.

Adding 'hooks' to the path join fixes discovery for all four bundled
hooks (session-memory, boot-md, command-logger, soul-evil).

Fixes openclaw#11331
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 22 to 27
// npm: resolve `<packageRoot>/dist/hooks/bundled` relative to this module.
// When bundled, import.meta.url resolves to dist/, so we need hooks/bundled.
try {
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
const distBundled = path.join(moduleDir, "bundled");
const distBundled = path.join(moduleDir, "hooks", "bundled");
if (fs.existsSync(distBundled)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaks non-bundled npm layout

moduleDir here is dirname(fileURLToPath(import.meta.url)). In a standard (non-flattened) npm install where this module lives at dist/hooks/bundled-dir.js (as your previous comment described), moduleDir will be dist/hooks, so path.join(moduleDir, "hooks", "bundled") resolves to dist/hooks/hooks/bundled and bundled hooks won’t be discovered. This only works if import.meta.url points at dist/ (flattened bundle), so this change needs to handle both layouts (e.g., try moduleDir/bundled and moduleDir/hooks/bundled, or resolve from package root).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/hooks/bundled-dir.ts
Line: 22:27

Comment:
**Breaks non-bundled npm layout**

`moduleDir` here is `dirname(fileURLToPath(import.meta.url))`. In a standard (non-flattened) npm install where this module lives at `dist/hooks/bundled-dir.js` (as your previous comment described), `moduleDir` will be `dist/hooks`, so `path.join(moduleDir, "hooks", "bundled")` resolves to `dist/hooks/hooks/bundled` and bundled hooks won’t be discovered. This only works if `import.meta.url` points at `dist/` (flattened bundle), so this change needs to handle both layouts (e.g., try `moduleDir/bundled` and `moduleDir/hooks/bundled`, or resolve from package root).

How can I resolve this? If you propose a fix, please make it concise.

Try moduleDir/bundled first (non-flattened: dist/hooks/bundled-dir.js),
then moduleDir/hooks/bundled (flattened: dist/chunk.js). Covers both
install layouts without breaking either.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Bundled hooks broken on npm global install (Linux) — path resolution + missing handler files

1 participant

Comments