@mnci/cli 4.3.2 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,57 @@ first-party (or established community) Nx equivalent:
24
24
  | Hand-written Azure Function templates | `@nx/node:application` (plain Node app) + a thin Azure Functions v4 overlay |
25
25
  | doctor/drift sync of tool-owned files | Nothing to drift: this CLI owns 5 small files, Nx owns the rest |
26
26
 
27
+ ## How this package is organised
28
+
29
+ Source is arranged in **vertical slices**: one folder per outcome, each with an
30
+ `index.ts` that is its whole public API. A sibling is reached only through that
31
+ barrel, never by a path into its files, and a file's suffix says what role it
32
+ plays (`.use-case`, `.client`, `.repository`, `.algorithm`, `.validator`,
33
+ `.handler`). Tests sit beside what they test.
34
+
35
+ ```
36
+ src/
37
+ main.ts the CLI transport — decodes argv, calls one use case
38
+ workspace-overlay/ the config files mnci owns and rewrites
39
+ workspace-creation/ mnci new, and the interactive wizard
40
+ workspace-upgrade/ mnci upgrade
41
+ workspace-diagnostics/ mnci doctor
42
+ project-scaffolding/ mnci add — one use case per kind, plus post-generation repairs
43
+ rollup-library/ what a rollup-bundled library needs repaired to build, type and publish
44
+ dependency-management/ mnci sync / mnci up, and the manifest + registry + semver machinery
45
+ nx-workspace/ runs the Nx and npm CLIs, always via an argv array
46
+ terminal/ prompts in, coloured status out
47
+ file-system/ JSON, JSONC workspace files, ensured writes
48
+ project-name/ name validation
49
+ cli-version/ the update check
50
+ ```
51
+
52
+ The dependency graph is acyclic and flows one way: `main` → the command
53
+ slices → the infrastructure slices → `file-system` as a leaf. That is checked,
54
+ not assumed — and now enforced: the root `eslint.config.mjs` turns on
55
+ `@mnci/eslint-config`'s `verticalSlices` rules for `packages/cli/src`, so a
56
+ deep sibling import, a file without a role suffix, a nested subfeature or a
57
+ cycle between slices fails `npm run lint` rather than needing someone to
58
+ re-run the checks by hand. It is scoped to this package deliberately; the
59
+ config file says which packages were measured and why they are excluded.
60
+
61
+ ### Exceptions, and when they go away
62
+
63
+ Two places hold more than the one responsibility their name claims, and are
64
+ named here because the next reader deserves to know before opening them:
65
+
66
+ | Path | Rule waived | Why, and removal condition |
67
+ |---|---|---|
68
+ | `workspace-overlay/overlay.use-case.ts` | one responsibility per file | ~3.5k lines covering CI YAML for two providers, `.npmrc`, `nuget.config`, the VS Code workspace, release config and the CI guard scripts. Splitting it is a decomposition, not a move, so it was deliberately kept out of the change that created these slices. **Temporary** — removed when that decomposition lands. |
69
+ | `rollup-library/repair-rollup-config.use-case.spec.ts` | a test takes its subject's basename | It also holds the `withUpgradedDeclarationSpecifierPlugin` describe, whose subject is `rollup-config.algorithm.ts`. That transform shares three fixtures with the repairs that apply it (`OLD_DTS_PLUGIN_CONFIG`, `EXTENSION_ONLY_DTS_PLUGIN_CONFIG`, `loadWriteBundle`), and duplicating them across two spec files is the worse trade. **Permanent** unless those fixtures stop being shared. |
70
+
71
+ `rollup-library/` exists because of the own-the-concept rule. Its contents used
72
+ to live in `project-scaffolding`, which meant `workspace-diagnostics` and
73
+ `workspace-upgrade` depended on the scaffolding slice **only** to reach repair
74
+ helpers — they have no interest in adding a project. The concept now sits in its
75
+ own slice that depends on nothing above it (`file-system` alone), and all three
76
+ consumers point at it.
77
+
27
78
  ## Commands (deliberately just six)
28
79
 
29
80
  ```sh
@@ -301,7 +352,7 @@ each a single cross-platform command:
301
352
  ## Every `add` also wires local-dev commands
302
353
 
303
354
  Every `mnci add` (and the inline `internal-lib` case) finishes by calling
304
- `registerProjectCommands` (`commands/add/shared.ts`), which writes up to three
355
+ `registerProjectCommands` (`project-scaffolding/post-generation.use-case.ts`), which writes up to three
305
356
  root `package.json` scripts for the project just added:
306
357
 
307
358
  | Script | Runs | When it's added |
@@ -401,7 +452,7 @@ from File`), and the curated root scripts.
401
452
 
402
453
  ## `mnci upgrade`: re-applying the overlay to an existing workspace
403
454
 
404
- Every fix to `overlay.ts` — a release-config correction, a CI guard rewritten,
455
+ Every fix to `workspace-overlay/overlay.use-case.ts` — a release-config correction, a CI guard rewritten,
405
456
  a new Windows code path — only ever reached _future_ `mnci new` calls until
406
457
  this existed; nothing let an already-generated workspace pick one up.
407
458
  `mnci upgrade`, run from the workspace root, closes that gap: it resolves the
@@ -611,7 +662,7 @@ default `azure`): `azure` writes `azure-pipelines.yml`, `github` writes
611
662
  `.github/workflows/ci.yml`, `both` writes both — pick `github` for a
612
663
  GitHub-hosted repo, or `both` while migrating between the two. Whichever
613
664
  provider(s), the pipeline does the **exact same thing**: both files are built
614
- from the same shared guard scripts (`overlay.ts`'s `PYTHON_INSTALL_GUARD`,
665
+ from the same shared guard scripts (`workspace-overlay/overlay.use-case.ts`'s `PYTHON_INSTALL_GUARD`,
615
666
  `PACK_APPS_GUARD`, `releaseGuard`, `AFFECTED_OR_ALL_GUARD`), so they can never
616
667
  drift on what CI actually runs — only the provider's own syntax differs. That
617
668
  matters most for the last of those: the two providers detect a pull request
@@ -855,7 +906,7 @@ is base64-encoded throughout — that's the raw value Azure Artifacts' "Connect
855
906
  to feed" instructions give you. npm's `.npmrc` `_password` field expects
856
907
  exactly that pre-encoded form, so it's used as-is. `twine`/pypi basic auth, by
857
908
  contrast, wants the **raw** token — so the shared `releaseGuard` fragment
858
- (`overlay.ts`, used by both `azurePipelinesYaml` and `githubActionsYaml`)
909
+ (`workspace-overlay/overlay.use-case.ts`, used by both `azurePipelinesYaml` and `githubActionsYaml`)
859
910
  explicitly _decodes_ the same `PAT`
860
911
  (`Buffer.from(process.env.PAT, 'base64').toString()`) before handing it to
861
912
  `TWINE_PASSWORD`. Both are correct for their protocol today, but it's an easy
@@ -1185,7 +1236,7 @@ pipeline installs `golangci-lint` itself (see below).
1185
1236
  | `go-internal-lib` | `libs/<name>` | private shared code, lint + test only — a non-`main` package produces no binary |
1186
1237
 
1187
1238
  - **One root `go.mod`**, matching how TS uses one root `package.json` and
1188
- Python one root `requirements-dev.txt`. `add/go.ts` bootstraps it on the
1239
+ Python one root `requirements-dev.txt`. `project-scaffolding/go.use-case.ts` bootstraps it on the
1189
1240
  first Go `add` by running the plugin's `init` then `convert-to-one-mod`
1190
1241
  generators, in that order — `convert-to-one-mod` refuses once `go.work`
1191
1242
  lists any module, so it has to happen before the first Go project exists.