@mnci/cli 1.9.1 → 1.11.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
@@ -75,6 +75,43 @@ each a single cross-platform command:
75
75
  | `npm run python:install` | fixed Python toolchain (ruff/pytest/build/twine) + editable-install every Python project — the same two guards CI runs, for local dev |
76
76
  | `prepare` | `husky` (commit-msg lint hook) |
77
77
 
78
+ ## Every `add` also wires local-dev commands
79
+
80
+ Every `mnci add` (and the inline `internal-lib` case) finishes by calling
81
+ `registerProjectCommands` (`commands/add/shared.ts`), which writes up to three
82
+ root `package.json` scripts for the project just added:
83
+
84
+ | Script | Runs | When it's added |
85
+ | -------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
86
+ | `<name>:build` | `nx run <name>:build` | the kind has a `build` target (not every kind does — a private lib with nothing to publish, or a Python function app deployed as source, has none) |
87
+ | `<name>:qa` | `nx run <name>:lint && nx run <name>:test` | always — every kind has both |
88
+ | `<name>:start` | the kind's real local-dev command | only kinds with a genuine dev-server story — never a library |
89
+
90
+ The same three (when present) are appended as VS Code Tasks into the
91
+ workspace's `<workspace-name>.code-workspace` file, so they also show up
92
+ under **Terminal → Run Task** / the Command Palette — `build`/`qa` grouped
93
+ accordingly, `start` marked `isBackground` since it runs a process that
94
+ doesn't exit on its own. Re-running `add` for the same project name
95
+ overwrites its own scripts/tasks rather than duplicating them.
96
+
97
+ `:start` resolves differently per kind — an existing generator target where
98
+ one already exists, a small `nx:run-commands` target mnci writes where none
99
+ did:
100
+
101
+ | Kind(s) | `:start` runs |
102
+ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
103
+ | `react-app`, `node-app` | `nx run <name>:serve` — the generator's own inferred dev-server target |
104
+ | `node-function-app`, `python-function-app` | `nx run <name>:start` → `func start` (Azure Functions Core Tools, install separately — never a prerequisite for `add` itself) |
105
+ | `python-app` | `nx run <name>:start` → `python3 main.py` — mnci writes a runnable `main.py`, since the plugin's own sample module has no entry point |
106
+ | `go-app` | `nx run <name>:start` → `go run .` |
107
+ | `flutter-app` | `nx run <name>:start` → `flutter run -d chrome` (web is the only platform this plugin builds for) |
108
+ | every library, `go-function-app` | no `:start` at all — see below |
109
+
110
+ **`go-function-app` is a known gap, not an oversight**: unlike the Node and
111
+ Python function-app kinds, it writes no `host.json`/custom-handler config, so
112
+ there is nothing for `func start` to attach to. Shipping a `:start` script
113
+ that would just fail felt worse than being upfront that it doesn't exist yet.
114
+
78
115
  ## What `new` actually does
79
116
 
80
117
  1. `npx create-nx-workspace@latest <name> --preset=ts` — npm workspaces +
@@ -84,15 +121,18 @@ each a single cross-platform command:
84
121
  default for): independent versioning from **conventional commits**,
85
122
  `{projectName}@{version}` tags, **tag-only git** (`commit: false`) — nothing
86
123
  is ever pushed to `main`; future runs resolve versions from tag names.
87
- 3. Writes `.npmrc` (Azure Artifacts feed or public npm — scope routing makes
88
- accidental public publishes impossible), `commitlint.config.mjs`, a husky
89
- `commit-msg` hook, the chosen CI provider's pipeline file(s)
124
+ 3. Writes `eslint.config.mjs` (three lines importing `@mnci/eslint-config` —
125
+ the whole linting opinion, in one root config), `.prettierrc.json` +
126
+ `.prettierignore`, `.npmrc` (comment-only — see **Known gaps** below),
127
+ `commitlint.config.mjs`, a husky `commit-msg` hook, the chosen CI provider's
128
+ pipeline file(s)
90
129
  (`azure-pipelines.yml` and/or `.github/workflows/ci.yml`, `--ci`, default
91
130
  `azure`; `github`/`both` also gets `.github/dependabot.yml` — weekly
92
131
  dependency-update PRs), a `<workspace-name>.code-workspace` file (VS Code
93
- workspace configuration with folder structure, ESLint/Prettier settings, and
94
- recommended extensions — open it in VS Code via `File > Open Workspace from
95
- File`), and the curated root scripts.
132
+ workspace configuration with folder structure, ESLint/Prettier settings,
133
+ recommended extensions, and an empty `tasks` array that `mnci add` fills in
134
+ per project — see below — open it in VS Code via `File > Open Workspace
135
+ from File`), and the curated root scripts.
96
136
  4. Installs the chosen **stack** (see below), `husky` + `@commitlint/*` for
97
137
  real, so versions resolve at generation time.
98
138
 
@@ -105,9 +145,23 @@ this existed; nothing let an already-generated workspace pick one up.
105
145
  same options `new` would have and calls the exact same `applyOverlay` `new`
106
146
  itself calls — the one function that does every bit of `mnci`-owned file
107
147
  writing (`nx.json`'s `release`/`sync`/`generators`/`mnci` blocks, `.npmrc`,
108
- `commitlint.config.mjs`, `.husky/commit-msg`, the CI pipeline file(s), and the
109
- curated root `package.json` scripts). Nothing else in the workspace — app/lib
110
- source, `project.json` targets from `mnci add` — is ever touched.
148
+ `eslint.config.mjs`, `.prettierrc.json`, `commitlint.config.mjs`,
149
+ `.husky/commit-msg`, the CI pipeline file(s), and the curated root
150
+ `package.json` scripts). Nothing else in the workspace — app/lib source,
151
+ `project.json` targets from `mnci add` — is ever touched.
152
+
153
+ `upgrade` also **deletes** things, which is stronger than the overwriting it
154
+ has always done — one more reason to run `git diff` first, as the command's own
155
+ output tells you to:
156
+
157
+ - `create-nx-workspace`'s `.prettierrc` and `.vscode/`, both superseded (by
158
+ `.prettierrc.json`, which Prettier would otherwise never reach, and by the
159
+ `.code-workspace` file).
160
+ - **every per-project `eslint.config.*` under `apps/`, `libs/` and
161
+ `packages/`.** This is the migration path for a workspace generated before
162
+ mnci owned linting: without it an upgrade would install the root config while
163
+ each project kept linting against its own stale copy. The root config is never
164
+ touched, and neither is a config anywhere outside those three directories.
111
165
 
112
166
  ```sh
113
167
  mnci upgrade # re-apply from persisted config alone
@@ -144,13 +198,33 @@ stack:
144
198
  | --------------- | ------------------ | ------- | ---------------------------------------------------------------------------------------- |
145
199
  | `--test-runner` | `jest` \| `vitest` | `jest` | `nx.json` generator `unitTestRunner` default; the hand-built function app follows it too |
146
200
 
147
- **Linting and formatting are unified across the workspace**: every project uses
148
- **ESLint + Prettier** with the JavaScript Standard Style configuration (no
149
- semicolons, single quotes, 2-space indents). ESLint is a per-project Nx target
150
- handling code quality (correctness only), while Prettier handles all formatting.
151
- Both are automatically configured; `npm run lint` checks code quality, `npm run
152
- format` (write) and `npm run format:check` (CI-safe) handle formatting. The CI
153
- runs lint/test/build only — formatting is left as a local/pre-commit step.
201
+ **Linting and formatting are unified across the workspace, from exactly one
202
+ config file each.** The root `eslint.config.mjs` is three lines importing
203
+ [`@mnci/eslint-config`](../eslint-config/README.md); every `@nx/*` generator
204
+ drops a config into the project it creates, and `mnci add` deletes it. Projects
205
+ still get their `lint` target: `@nx/eslint/plugin` infers it by mapping config
206
+ _directories_ onto the project roots beneath them, so the root config covers
207
+ them all. (Verified, not assumed — and the e2e enforces both "every project has
208
+ a `lint` target" and "the root config genuinely reports violations in a project
209
+ with no config of its own", because a future Nx change there would silently
210
+ switch linting off workspace-wide.)
211
+
212
+ ESLint handles code quality only; **Prettier owns all formatting**, configured
213
+ for JavaScript Standard Style (no semicolons, single quotes, 2-space indents, no
214
+ trailing commas). `mnci` runs Prettier itself at the end of `new` and every
215
+ `add`, so a generated workspace passes its own `format:check` immediately — Nx's
216
+ generators emit semicolons and double quotes, and without that pass the first
217
+ commit buries every real change under generator noise.
218
+
219
+ One caveat worth knowing: `space-before-function-paren`, Standard's signature
220
+ rule, is **not** enforced. Prettier rewrites `function f (a)` to `function f(a)`
221
+ on every run and has closed the corresponding option permanently, so enabling it
222
+ would make `npm run lint` and `npm run format:check` mutually unsatisfiable.
223
+ Choosing Prettier means accepting its call there.
224
+
225
+ `npm run lint` checks code quality; `npm run format` (write) and
226
+ `npm run format:check` (CI-safe) handle formatting. The CI runs lint/test/build
227
+ only — formatting is left as a local/pre-commit step.
154
228
 
155
229
  TypeScript is not a question — every workspace runs the **dual compiler** from
156
230
  [Nx's TS 7 guide](https://nx.dev/docs/technologies/typescript/guides/typescript-7):
@@ -428,6 +502,13 @@ than a surprise:
428
502
 
429
503
  ## Known gaps (accepted for the experiment)
430
504
 
505
+ - **The generated `.npmrc` is empty (comments only), so `npm publish` will not
506
+ authenticate.** This is a deliberate deferral, not an oversight: the previous
507
+ file claimed here that scope routing made accidental public publishes
508
+ impossible, when in fact no `@scope:registry` line was ever emitted. Rather
509
+ than ship half-wired auth, the CI token export (`NODE_AUTH_TOKEN`/`PAT`) is
510
+ left in place so wiring it later is one line, and the generated `.npmrc`
511
+ carries a comment saying so. Publish-path e2e assertions are relaxed to match.
431
512
  - No `doctor`/`resurrect`/`spell` — out of scope until the model is proven.
432
513
  - **Flutter apps build for web only.** Android would require the Android SDK and
433
514
  NDK on every build agent; iOS is impossible on a Linux agent regardless. Add