Goal
Root package.json is crowded with docs-only tooling mixed in with the library. Extract the VitePress docs site into its own private workspace package so root only owns the library + repo-wide tooling.
Keep docs/ where it is — just give it its own package.json and move docs-only deps/scripts in.
Context (verified)
apps/docs/ and packages/dreamcli/ are untracked local cruft (0 tracked files — stale dist//cache//coverage/ from an old monorepo experiment). Not relevant; real source is /docs + /src. Can be nuked separately.
- Docs build couples to root:
docs/.vitepress/config.ts imports ../../package.json, ../../tsconfig.json, introspects /src for the API reference, reads /examples. Fine for a workspace member (relative reads stay relative to the config file).
- Catalog (
typescript, @types/node, @types/bun) lives in root and applies to all members → docs can use catalog:.
- Root is published (
@kjanat/dreamcli, public) → docs package must be private: true.
Decided approach
Thin root aliases — root keeps docs:* scripts but they delegate (run --dir docs <task>), so ci, dev, and the Cloudflare Build command keep working unchanged.
New docs/package.json (private member)
Root package.json changes
- Drop 8 docs-only devDeps:
vitepress, vite, @shikijs/transformers, @shikijs/vitepress-twoslash, floating-vue, mermaid, typedoc, wrangler.
docs:* → thin aliases: "docs:build": "run --dir docs build" (same for dev/preview/deploy/upload). ci + dev unchanged (call the aliases).
upgrade: retarget the vitepress bump into docs (… && bun --cwd docs add -D vitepress@next).
workspaces: ["./examples/*", "./docs"].
Stays at root (do NOT move)
yaml + @iarna/toml — library config-format parsing (src/core/config/index.ts, src/core/cli/index.ts).
@types/deno — src/runtime/deno.ts.
- repo-wide tooling:
biome, dprint, knip, publint, tsdown, vitest, @vitest/coverage-v8, @arethetypeswrong/core, @typescript/native-preview, runner-run, catalog deps.
Unchanged
- Cloudflare Build command (
bun --bun vitepress build docs) — resolves via workspace hoist.
wrangler.jsonc — assets dir still ./docs/.vitepress/dist/.
Caveat
Bun hoists workspace deps to root node_modules, so root can still physically resolve vitepress/typedoc. This declutters manifest ownership + the dep graph, not physical isolation — which is also what keeps the CF command and any root test touching typedoc working.
Verify after
bun install relinks the new member
bun run docs:build produces docs/.vitepress/dist/
bun run ci passes (docs:build step)
bun run test still green (typedoc hoisted)
Goal
Root
package.jsonis crowded with docs-only tooling mixed in with the library. Extract the VitePress docs site into its own private workspace package so root only owns the library + repo-wide tooling.Keep
docs/where it is — just give it its ownpackage.jsonand move docs-only deps/scripts in.Context (verified)
apps/docs/andpackages/dreamcli/are untracked local cruft (0 tracked files — staledist//cache//coverage/from an old monorepo experiment). Not relevant; real source is/docs+/src. Can be nuked separately.docs/.vitepress/config.tsimports../../package.json,../../tsconfig.json, introspects/srcfor the API reference, reads/examples. Fine for a workspace member (relative reads stay relative to the config file).typescript,@types/node,@types/bun) lives in root and applies to all members → docs can usecatalog:.@kjanat/dreamcli, public) → docs package must beprivate: true.Decided approach
Thin root aliases — root keeps
docs:*scripts but they delegate (run --dir docs <task>), soci,dev, and the Cloudflare Build command keep working unchanged.New
docs/package.json(private member){ "name": "@kjanat/dreamcli-docs", "private": true, "type": "module", "scripts": { "build": "bun --bun vitepress build .", "dev": "bun --bun vitepress dev . --host --port ${PORT:-5173}", "preview": "bun --bun vitepress preview .", "deploy": "wrangler deploy", "upload": "wrangler versions upload" }, "dependencies": { "@kjanat/dreamcli": "workspace:*" }, "devDependencies": { "vitepress": "^2.0.0-alpha.17", "vite": "^8.1.0", "@shikijs/transformers": "^4.2.0", "@shikijs/vitepress-twoslash": "^4.2.0", "floating-vue": "^5.2.2", "mermaid": "^11.15.0", "typedoc": "^0.28.19", "wrangler": "^4.104.0", "typescript": "catalog:", "@types/node": "catalog:" } }Root
package.jsonchangesvitepress,vite,@shikijs/transformers,@shikijs/vitepress-twoslash,floating-vue,mermaid,typedoc,wrangler.docs:*→ thin aliases:"docs:build": "run --dir docs build"(same for dev/preview/deploy/upload).ci+devunchanged (call the aliases).upgrade: retarget the vitepress bump into docs (… && bun --cwd docs add -D vitepress@next).workspaces:["./examples/*", "./docs"].Stays at root (do NOT move)
yaml+@iarna/toml— library config-format parsing (src/core/config/index.ts,src/core/cli/index.ts).@types/deno—src/runtime/deno.ts.biome,dprint,knip,publint,tsdown,vitest,@vitest/coverage-v8,@arethetypeswrong/core,@typescript/native-preview,runner-run, catalog deps.Unchanged
bun --bun vitepress build docs) — resolves via workspace hoist.wrangler.jsonc— assets dir still./docs/.vitepress/dist/.Caveat
Bun hoists workspace deps to root
node_modules, so root can still physically resolve vitepress/typedoc. This declutters manifest ownership + the dep graph, not physical isolation — which is also what keeps the CF command and any root test touching typedoc working.Verify after
bun installrelinks the new memberbun run docs:buildproducesdocs/.vitepress/dist/bun run cipasses (docs:build step)bun run teststill green (typedoc hoisted)