fix(memos-local-openclaw): ship compiled JS for OpenClaw plugin loader (#1619)#1622
Open
fancyboi999 wants to merge 2 commits intoMemTensor:mainfrom
Open
Conversation
MemTensor#1619) The npm package previously published only TypeScript source, so OpenClaw 2026.5.4's plugin loader rejected it with "expected ./dist/index.js, ./dist/index.mjs, ./dist/index.cjs". - tsconfig: rootDir=., include root index.ts, emit ESM (ES2022) - package.json / openclaw.plugin.json: entry -> dist/index.js, files include dist, prepublishOnly does a clean tsc build - scripts/fix-esm-imports.cjs: append .js suffix to relative imports in dist/ so Node's native ESM loader can resolve them (moduleResolution: bundler omits suffixes during emit) - src/shared/plugin-root.ts: marker-based plugin-root lookup, replacing fragile __dirname/../.. paths that no longer match the new dist/src/* layout (4 call sites unified) - src/openclaw-sdk.d.ts: dev-time type shim for openclaw/plugin-sdk - index.ts: add type annotations + null guard so the previously uncompiled root entry passes strict-mode tsc Verified: tsc compiles clean, fix-esm-imports rewrites 32 files, Node 25 ESM loader resolves dist/index.js -> exports {id, register}, which matches OpenClaw's plugin contract.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes the OpenClaw plugin packaging/build pipeline for @memtensor/memos-local-openclaw-plugin so it publishes compiled ESM (dist/index.js + declarations) that OpenClaw’s plugin loader can actually load, and updates runtime path resolution to be stable across src/ vs dist/src/ layouts.
Changes:
- Reconfigured TypeScript compilation to include the real plugin entry (
index.ts) and emit ESM intodist/. - Updated package + OpenClaw manifests to reference
./dist/index.js, and ensureddist/is included in the published npm package. - Added a post-build import-rewrite script and consolidated plugin-root path discovery via a shared helper.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/memos-local-openclaw/tsconfig.json | Switch to ESM output, include root index.ts, and adjust module resolution for bundler-style imports. |
| apps/memos-local-openclaw/package.json | Publish compiled output (main/types → dist/*), ship dist/, and build on publish. |
| apps/memos-local-openclaw/openclaw.plugin.json | Point OpenClaw manifest extensions at the compiled entry (./dist/index.js). |
| apps/memos-local-openclaw/index.ts | Minimal strict-mode type/guard fixes so the real plugin entry compiles under strict. |
| apps/memos-local-openclaw/src/shared/plugin-root.ts | New shared helper to find the plugin install root reliably across emit layouts. |
| apps/memos-local-openclaw/src/viewer/server.ts | Replace fragile __dirname traversal with findPluginRoot(import.meta.url) usage. |
| apps/memos-local-openclaw/src/telemetry.ts | Resolve telemetry credentials via plugin-root discovery instead of __dirname assumptions. |
| apps/memos-local-openclaw/src/storage/ensure-binding.ts | Update plugin-root resolution for prebuild/native binding restore flow under ESM. |
| apps/memos-local-openclaw/src/skill/bundled-memory-guide.ts | Resolve bundled skill markdown via plugin-root discovery for dist layout. |
| apps/memos-local-openclaw/src/openclaw-sdk.d.ts | Add a dev-time module shim for the runtime-injected OpenClaw SDK. |
| apps/memos-local-openclaw/scripts/fix-esm-imports.cjs | New post-build script to add .js suffixes required by Node’s native ESM loader. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…import rewrite
- plugin-root.ts: tighten the matching predicate from substring
`includes("memos-local")` to an exact-match Set
({memos-local-openclaw-plugin, @memtensor/memos-local-openclaw-plugin}).
In monorepo layouts the sibling `memos-local-plugin` could otherwise
be selected as the root by accident.
- fix-esm-imports.cjs: extend regex to also rewrite side-effect
imports (`import "./polyfills";`). Verified with a negative test
that bare identifiers like `important` are not falsely matched.
Re-verified end-to-end: tsc clean, 32 files rewritten, Node 25 ESM
loader resolves dist/index.js -> exports {id, register}.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1619.
The
@memtensor/memos-local-openclaw-pluginnpm package was publishing TypeScript source only, so OpenClaw 2026.5.4's plugin loader rejected it withexpected ./dist/index.js, ./dist/index.mjs, ./dist/index.cjs. Investigating theapps/memos-local-openclaw/source surfaced three layers of misconfiguration that all had to be fixed together — just adding a build step would not have sufficed:tsconfig.jsonhadrootDir: "src"+include: ["src"], so the OpenClaw plugin entry (rootindex.ts) was never in the compile graph at all. The pre-existingdist/index.jsfromnpm run buildwas actuallysrc/index.ts's output (a separate library-style entry), not the plugin entry — a silent footgun.package.jsonmain/openclaw.extensionspointed atindex.ts,prepublishOnlywas a placeholder echo, andfilesdid not includedist.import.meta.url, and severalsrc/*files use bare__dirname. ESM-only on the entry side, CJS-only on the helper side — both had to be reconciled before any build output could actually load.Changes
tsconfig.json→rootDir: ".", include rootindex.ts, emit ESM (module: ESNext,moduleResolution: bundler,target: ES2022)import.meta.urlmain→dist/index.js;filesincludesdist;openclaw.extensions→./dist/index.js;prepublishOnly→rm -rf dist && tsc && node scripts/fix-esm-imports.cjsopenclaw.plugin.jsonextensions→./dist/index.jsscripts/fix-esm-imports.cjs(~50 lines, no new deps)moduleResolution: bundleremits relative imports without.jssuffixes, but Node's native ESM loader requires them. Rewriting at build time keeps source cleansrc/shared/plugin-root.ts(findPluginRoot(import.meta.url))dist/src/*layout is one level deeper than the olddist/*, so every hard-coded__dirname/../..inbundled-memory-guide.ts,ensure-binding.ts,telemetry.ts, andviewer/server.tswould have silently pointed at the wrong directory. Marker-based lookup (walks up to apackage.jsonwhose name starts withmemos-local) decouples runtime path resolution from emit layout.viewer/server.tsalready had a 6-level local version of this — now consolidatedsrc/openclaw-sdk.d.ts(declare module "openclaw/plugin-sdk")index.ts— 5×(context: any)annotations, 1×?? []null guardanystyleVerification
dist/index.js, exporting{id, register, ...}— matches the OpenClaw plugin contractnpm packnow ships compiled artifacts; rawindex.tsandsrc/*.tsno longer publishedmainbaseline (same 4 pre-existing failures inaccuracy.test.ts,task-processor.test.ts,update-install.test.ts); no regressions from this changeTest plan
1.0.11or1.0.9-beta.2) andnpm publishcurl -fsSL https://cdn.memtensor.com.cn/memos-local-openclaw/install.sh | bash~/.openclaw/extensions/memos-local-openclaw-plugin/dist/index.jsexistsplugins.slots.memoryresolves tomemos-local-openclaw-pluginwithout the previous "plugin not found" errormemory_search,memory_get,memory_viewertools register correctly