fix(coding-agent): ship omp:// docs to npm consumers

exports resolve to TypeScript source, where the build-time PI_DOCS_EMBED
placeholder is empty and the dev-tree fallback resolved docs to an
unreachable node_modules/docs, so OmpProtocolHandler.complete()/.resolve()
threw ENOENT for every npm/SDK consumer.

- bundle-dist.ts writes the docs corpus to dist/docs-index.generated.txt
  (shipped via package.json files), reusing the same payload it inlines
  into dist/cli.js.
- docs-index.ts reads the shipped embed when the env embed is empty and
  the on-disk docs/ directory is absent, and degrades to an empty index
  (with a warning) instead of propagating ENOENT.
- Added a generator-to-runtime payload round-trip test.

Fixes #8134
This commit is contained in:
roboomp
2026-08-10 05:33:50 +00:00
parent 45e12e5bb7
commit 7ffe1eb877
5 changed files with 102 additions and 22 deletions
+8 -1
View File
@@ -69,6 +69,7 @@ async function cleanBundleOutputs(): Promise<void> {
.filter(
entry =>
entry === "cli.js" ||
entry === "docs-index.generated.txt" ||
entry.endsWith(".node") ||
entry.endsWith(".js.map") ||
(entry.startsWith("CHANGELOG-") && entry.endsWith(".md")) ||
@@ -85,6 +86,11 @@ async function main(): Promise<void> {
// archive the same way compiled binaries do (scripts/build-binary.ts). Reset
// afterwards to keep the checked-in placeholder empty.
await runCommand(["bun", "--cwd=../stats", "run", "gen:stats"]);
// One payload for both consumers: inlined into dist/cli.js via `--define` for
// the bundled CLI entrypoint, and written to dist/docs-index.generated.txt so
// SDK consumers importing `@oh-my-pi/pi-coding-agent/*` (TypeScript source, no
// build-time embed) can still resolve omp:// docs (see src/internal-urls/docs-index.ts).
const docsPayload = await buildDocsIndexPayload();
try {
// Build in-process: the docs embed payload is far larger than Linux's
// 128KiB per-argv-string cap, so it can never be passed as a CLI
@@ -96,7 +102,7 @@ async function main(): Promise<void> {
external: [...ALWAYS_EXTERNAL, ...RUNTIME_EXTERNAL],
define: {
"process.env.PI_BUNDLED": JSON.stringify("true"),
"process.env.PI_DOCS_EMBED": JSON.stringify((await buildDocsIndexPayload()).payload),
"process.env.PI_DOCS_EMBED": JSON.stringify(docsPayload.payload),
},
minify: {
whitespace: true,
@@ -113,6 +119,7 @@ async function main(): Promise<void> {
await runCommand(["bun", "--cwd=../stats", "run", "gen:stats:reset"]);
}
await ensureShebang();
await Bun.write(path.join(outDir, "docs-index.generated.txt"), docsPayload.payload);
const stat = await fs.stat(cliPath);
const elapsedMs = (Bun.nanoseconds() - start) / 1_000_000;
process.stdout.write(