Skip to content

T-0PIB-site-build-scaffold-asset

Status: closed/done · Impact: medium · Complexity: large

D-0014 wants downstream consumers to build the planning-docs site with one command. The pieces mostly exist — the Astro scaffold already ships inside the plugin (plugin/site-template/) and sdlc docs generate site materializes and fills it — but the build half (install site deps, run Astro) lives only in the dev repo’s Bun-specific build:doc-site root script. This task ships sdlc site build: scaffold → generate → deps → astro build, runnable in any consumer, and points the dev repo’s own deploy path at it.

LocationRole today
plugin/site-template/the Astro/Starlight scaffold, shipped as a plugin asset (excluded from tsconfig; copy-not-compile)
plugin/lib/services/docs/site.tsdocs generate site: materializeScaffold copies the template into <projectRoot>/<docsSiteDir>, then generates content; locates the template module-relative
plugin/lib/config/load.ts#docsSiteDirsite output dir from sdlc.yaml docs_site (default site) — already project-root-relative
sites/df-docs/the dev repo’s own consumer-side site instance (site.yaml, supplemental/); scaffold materialized in, content gitignored, Cloudflare-rebuilt
package.jsonbuild:doc-site script: bun install && bun run plugin/cli/sdlc.ts docs generate site && (cd sites/df-docs && bun install && bunx astro build) — Bun-specific, dev-repo-only shape of exactly what the verb must do
plugin/site-template/package.jsonscaffold scripts (fixed by T-T0O9 to call the installed sdlc bin)
sdlc.yamlquality_checks / lefthook reference docs generate site — generation only, no build

sdlc site build [--project-root …] [--out <dir>] is the one-command consumer surface: ensures the scaffold is materialized (delegating to the existing docs generate site path), installs site dependencies with whichever package manager the host has (bun, else npm), runs astro build, reports the dist path (copying it to --out when given) with a stable stdout marker. The dev repo’s build:doc-site script becomes a thin call to the verb, so Cloudflare and consumers exercise the identical path. Consumers own only site.yaml and supplemental/.

  1. Add op plugin/lib/services/docs/ops/site-build.ts (path: ['site','build']; the docs service dir already hosts the generation machinery it composes): a. Run the existing generate-site pipeline (materialize scaffold if absent, regenerate content) against the resolved project root. b. Detect the package manager: bun if on PATH, else npm; run <pm> install in the site dir (skippable via --no-install for CI that pre-installs). c. Run astro build via the detected runner (bunx/npx), cwd the site dir. d. Emit SITE: built <abs dist path>; with --out, copy dist there and emit that path instead. Non-zero astro exit propagates with astro’s own diagnostic.
  2. Route the dev repo through it: build:doc-site becomes bun install && bun run plugin/cli/sdlc.ts site build — one place owns the sequence; Cloudflare config needs no change beyond the script it already calls.
  3. Wire a moon task (root:build-site or on the df-docs project) so the graph knows the site build; keep lefthook/sdlc.yaml generation gates untouched (they check drift, not builds).
  4. Tests: op test with a fixture project (tiny docs/planning/ corpus + sdlc.yaml) asserting scaffold materialization, generation, and the marker line — stubbing the <pm> install/astro build spawns via the runner seam; one integration smoke in the dev repo running the real thing against sites/df-docs.
  5. Document the consumer flow in the README distribution section (install → sdlc site build → deploy dist/ anywhere static).
LocationKindChange
plugin/lib/services/docs/ops/site-build.tsnewthe site build op: generate → pm install → astro build → marker/--out
plugin/lib/services/docs/tests/modifyop test with fixture project + stubbed spawns
plugin/lib/services/docs/site.tsmodifyexport the generate/materialize entry the op composes (if not already callable in-process)
package.jsonmodifybuild:doc-site delegates to site build
moon.ymlmodifysite-build task wiring
README.mdmodifyconsumer site-build flow
  • AC-1: in the dev repo, sdlc site build exits 0 and produces sites/df-docs/dist/ with the built Starlight site; bun run build:doc-site goes through the verb and produces the identical result.
  • AC-2: in a fixture consumer project (scratch dir with docs/planning/ + sdlc.yaml, plugin installed), sdlc site build materializes the scaffold, builds, and prints the SITE: built <path> marker.
  • AC-3: with Bun absent from PATH (Node+npm only), sdlc site build completes in the fixture project.
  • AC-4: --out <dir> places the built site at <dir> and the marker names it; --no-install skips dependency installation.
  • AC-5: sdlc --help lists the site noun; existing docs generate site behavior and its lefthook/quality gates are unchanged.
  • Scaffold content redesign or Starlight upgrades — the template ships as-is; this is plumbing.
  • Deploy integration (Cloudflare config, CI deploy jobs) — consumers deploy dist/ however they like; the dev repo’s Cloudflare setup already calls build:doc-site.
  • Supplemental-prose drift checking (/dev-update-docs territory).
  • Publishing the scaffold separately — it stays an asset inside the one artifact (T-XTGT copies it into the staged tree).
  • none hard to build in the dev repo. T-T0O9 fixes the scaffold’s own scripts (complementary); Bun-free AC-3 requires T-WGV4; running from an installed artifact requires T-XTGT. Last in the wave alongside T-521G.
  • D-0014 Migration step 8 (the D-0010 follow-up). The scaffold-as-asset half shipped earlier than D-0014 assumed (plugin/site-template/ + materializeScaffold already exist); the remaining gap is the build half and its consumer/runtime-agnostic packaging.

← Back to Tasks