Closes the long-standing 'jiti picks stale .js over updated .ts' trap
that silently shipped wrong code at least 5 times during sim e2e. Root
cause was three things compounding:
1. tsconfig.plugin.json had outDir=plugin (same as rootDir), so tsc
emitted compiled .js next to .ts sources. jiti's extension resolver
prefers .js, so the moment a .ts changed without a matching rebuild,
the .js won and the new code never ran.
2. The .js artifacts were tracked in git, so even on clean clones the
stale files came back.
3. There was no install script. Every deploy was an ad-hoc tar + rsync
that copied both .ts and .js to the same target dir, recreating the
race on the install side.
This commit fixes all three together:
- tsconfig.plugin.json: outDir=dist/dialectic, module/moduleResolution
flipped from ESNext/bundler to NodeNext/NodeNext (so emitted .js
works under plain Node ESM at runtime, the only thing jiti and the
openclaw gateway actually use).
- .gitignore: /dist/ + plugin/**/*.{js,mjs,cjs,js.map,d.ts}, then
git rm --cached the 4 existing tracked .js files.
- scripts/install.mjs (new, ESM): mirrors Fabric.OpenclawPlugin's
install.mjs pattern — detect, checkDeps, build (clean dist/ first),
install (copy dist/dialectic/ + openclaw.plugin.json + package.json
to ~/.openclaw/plugins/dialectic/), configure (plugins.allow,
plugins.load.paths, plugins.entries.<id>.enabled). Supports
--install / --build-only / --uninstall / --skip-check / --verbose /
--openclaw-profile-path / --backend-url.
Verified on sim dind-t2: install.mjs --install produces a plugin
directory with ONLY .js files (no .ts left behind), gateway loads it,
8 tools register cleanly, dialectic_list_topics + fabric-guild-list
work end-to-end.
Plugin is now fully ESM-clean: type=module + NodeNext + .js import
extensions + no bundler-only knobs. Matches the project-wide invariant
[[project-fabric-esm]] (every Fabric subproject is ESM).
27 lines
975 B
JSON
27 lines
975 B
JSON
{
|
|
"compilerOptions": {
|
|
"target": "ES2022",
|
|
// NodeNext (not ESNext/bundler) so the emitted .js works under
|
|
// plain Node.js ESM at runtime — jiti + the openclaw gateway
|
|
// both run on Node, not under a bundler.
|
|
"module": "NodeNext",
|
|
"moduleResolution": "NodeNext",
|
|
// Emit compiled JS into a separate dist/ tree so build artifacts
|
|
// never collide with .ts sources. With outDir === rootDir,
|
|
// tsc produces src/foo.js next to src/foo.ts, and jiti picks
|
|
// .js (its default extension-resolve order) — which silently
|
|
// shipped stale code several times during sim e2e. Isolating
|
|
// dist/ removes the entire race.
|
|
"outDir": "dist/dialectic",
|
|
"rootDir": "plugin",
|
|
"declaration": false,
|
|
"strict": true,
|
|
"esModuleInterop": true,
|
|
"skipLibCheck": true,
|
|
"forceConsistentCasingInFileNames": true,
|
|
"allowJs": false
|
|
},
|
|
"include": ["plugin/**/*.ts"],
|
|
"exclude": ["plugin/**/*.js", "dist/**/*"]
|
|
}
|