T-1RLU-move-sdlc-tool-to-apps-sdlc
Status: closed/done · Impact: high · Complexity: large
Today the repo root doubles as the @sksizer/sdlc package AND the monorepo
workspace-root. That conflation makes the SDLC release run a whole-repo
bun test (which sweeps unrelated vitest app suites) and tangles SDLC’s build
and deps with the monorepo. Move the SDLC tool (plugin/) into apps/sdlc/ and
slim the root into a pure workspace-root, so SDLC is one app among peers with its
own scoped build/test/deps. This is Phase -1 of the distribution revamp
(D-2APS-sdlc-standalone-binary-app); it lands before the binary work so that
targets the final layout.
| Location | Role today |
|---|---|
package.json (root) | IS the @sksizer/sdlc manifest (name, bin plugin/cli/sdlc.js, files [plugin,vendor], deps) AND the workspace-root. |
plugin/ (642 files) | The SDLC source tree: cli/, lib/, skills/, conventions/, .claude-plugin/, site-template/. |
tsconfig*.json, sdlc.yaml, lefthook.yml, release.yml, moon.yml, .rumdl.toml, justfile | Encode plugin/… paths and plugin/cli/sdlc.ts invocations. |
.claude/settings.json | Registers the dev-repo plugin marketplace at ./plugin. |
docs/planning/** | The SDLC data corpus — resolved as <projectRoot>/docs/planning/…, decoupled from where code lives. |
Proposed
Section titled “Proposed”plugin/ becomes apps/sdlc/ (flat rename); the @sksizer/sdlc identity moves
into apps/sdlc/package.json; root becomes a private workspace-root. The SDLC
release scopes to apps/sdlc/. The published artifact keeps its inner plugin/
prefix — build-artifact already relocates the emitted tree, so bin,
NODE_MODULES_MARKETPLACE_PATH, and the release smoke stay byte-identical and
zero consumer churn results. docs/planning and the rest of the monorepo stay
put.
Approach
Section titled “Approach”Land as ONE squash-merge (the git mv + repoints are atomic — the repo does not
build in between). Ordered for reviewability:
git mv plugin apps/sdlcandgit mv README.md apps/sdlc/README.mdas a pure move commit (git log --followintact).- tsconfig:
@lib/@clialias bases + include/exclude →apps/sdlc/…. - In-code source-tree literals (~15) → introduce ONE
pluginSourceDir()resolver (mirroring the configurabledocs_sitepattern) rather than editing each. - Module-relative hops: keep counts; fix the two anchors that target the app
root’s parent (
info-report.ts×4,_install.tsre-descent — add anapps/sdlccandidate, keep theplugincandidate for the installed artifact). - Launcher +
dev use/status/linkliteral contract (plugin/cli/sdlc.ts→apps/sdlc/cli/sdlc.ts, byte-identical across the three sites). .claude/dev-harness repoints — CRITICAL first:.claude/settings.jsonmarketplace./plugin→./apps/sdlc; then project-check imports/joins.build-artifact.ts: source reads →apps/sdlc; dest writes stayplugin/(keeps the published prefix).- package.json split: new
apps/sdlc/package.json(identity;markdown-contractfile: repointed../../vendor/…; declareesbuild); slim root to@sksizer/dev-monorepo, add explicitapps/sdlctoworkspaces;bun install. - Root config invocations (
sdlc.yaml,lefthook.yml,moon.yml,release.yml,.rumdl.toml,justfile, siblingmoon.ymlcommand strings). - Final relink + full verification.
Files to touch
Section titled “Files to touch”| Location | Kind | Change |
|---|---|---|
plugin/ | modify | git mv → apps/sdlc/ (whole tree; internals unchanged). |
README.md | modify | git mv → apps/sdlc/README.md. |
package.json | modify | Split: identity out to apps/sdlc/package.json; root → pure workspace-root. |
tsconfig.json, tsconfig.build.json | modify | Alias bases + include/exclude → apps/sdlc. |
plugin/lib/services/plugin/ops/build-artifact.ts | modify | Source reads → apps/sdlc; dest writes stay plugin/. |
plugin/lib/util/*, plugin/cli/sdlc (launcher), harness/ops/_install.ts | modify | Root/hop resolvers + launcher redirect; pluginSourceDir() resolver. |
.claude/settings.json, .claude/hooks/**, .claude/scripts/**, .claude/skills/project-check/** | modify | Marketplace path + skills/entities/CLI joins → apps/sdlc. |
sdlc.yaml, lefthook.yml, moon.yml, .github/workflows/release.yml, .rumdl.toml, justfile | modify | Invocations plugin/cli/sdlc.ts → apps/sdlc/cli/sdlc.ts; rumdl plugin → apps/sdlc. |
apps/sdlc/moon.yml | new | SDLC build/site moon tasks (relocated from root). |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
git grep "plugin/cli/sdlc" ':!apps/sdlc' ':!dist-pkg'andgit grep "\"plugin\"" -- apps/sdlc/libreturn only intended (published-prefix) hits. - AC-2:
bunx tsc --noEmitclean;bun run apps/sdlc/cli/sdlc.ts --helpworks. - AC-3: Bare-CLI resolver (the untested seam) —
env -u CLAUDE_PLUGIN_ROOT bun run apps/sdlc/cli/sdlc.ts project doctor --output jsonresolves a real manifest root and version (not “unknown”). - AC-4: The dev repo loads the plugin (
.claude/settings.jsonrepointed) —sdlc//sdlc:inforeports the loaded root =apps/sdlc. - AC-5:
build-artifact --out dist-pkgthennode dist-pkg/plugin/cli/sdlc.js project doctorwork (published prefix unchanged); the bundledplugin/lib/_vendor/markdown-contract.jsis present. - AC-6: All pre-commit gates pass;
bun testandbun test ./.claudegreen; the release dry-run is green with the version tag readingapps/sdlc/package.json.
Out of scope
Section titled “Out of scope”- Compiling SDLC to a bun binary (the spike is proven on branch
spike/bun-binary-compile; productionization is the next phase of D-2APS-sdlc-standalone-binary-app). - Changing the published artifact’s inner
plugin/prefix (deliberately kept).
Dependencies
Section titled “Dependencies”- A freeze window: drain/close in-flight
plugin/**PRs first (a tree-rename conflicts irrecoverably with concurrent edits inside the moved tree), quiesce the orchestrator, then land in one squash-merge rebased against latestorigin/main.
Discovery context
Section titled “Discovery context”Surfaced across the v0.3.1 release effort: repeated plain-Node artifact
regressions (a vendored markdown-contract, a .ts-source @sksizer/agent-plugin)
and the whole-repo bun test sweeping vitest app suites all trace to SDLC being
the repo root. A parallel workflow produced the full step-by-step plan with
per-file line anchors (the biggest risk: the untested bare-CLI plugin-root
resolver, AC-3).