mandrel 1.60.0 → 1.62.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.
Files changed (49) hide show
  1. package/.agents/README.md +74 -32
  2. package/.agents/docs/SDLC.md +18 -12
  3. package/.agents/docs/configuration.md +61 -4
  4. package/.agents/docs/quality-gates.md +796 -0
  5. package/.agents/docs/workflows.md +3 -4
  6. package/.agents/runtime-deps.json +2 -2
  7. package/.agents/scripts/README.md +1 -1
  8. package/.agents/scripts/agents-bootstrap-github.js +23 -119
  9. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +46 -0
  10. package/.agents/scripts/lib/bootstrap/gh-preflight.js +7 -9
  11. package/.agents/scripts/lib/bootstrap/manifest.js +21 -1
  12. package/.agents/scripts/lib/bootstrap/merge-methods.js +31 -16
  13. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +32 -11
  14. package/.agents/scripts/lib/config/sync-agentrc.js +1 -1
  15. package/.agents/scripts/lib/detect-package-manager.js +72 -0
  16. package/.agents/scripts/lib/errors/index.js +4 -4
  17. package/.agents/scripts/lib/label-taxonomy.js +2 -2
  18. package/.agents/scripts/lib/onboard/detect-stack.js +10 -10
  19. package/.agents/scripts/lib/onboard/init-tail.js +218 -0
  20. package/.agents/scripts/lib/onboard/scaffold-docs.js +18 -3
  21. package/.agents/scripts/lib/runtime-deps/preflight.js +6 -6
  22. package/.agents/scripts/lib/worktree/node-modules-strategy.js +5 -2
  23. package/.agents/workflows/agents-update.md +14 -29
  24. package/.agents/workflows/deliver.md +87 -26
  25. package/.agents/workflows/helpers/agents-sync-config.md +3 -2
  26. package/.agents/workflows/helpers/deliver-epic.md +12 -5
  27. package/.agents/workflows/helpers/deliver-stories.md +13 -7
  28. package/.agents/workflows/plan.md +48 -4
  29. package/README.md +18 -30
  30. package/bin/mandrel.js +235 -16
  31. package/docs/CHANGELOG.md +36 -0
  32. package/lib/cli/doctor.js +45 -3
  33. package/lib/cli/init.js +66 -7
  34. package/lib/cli/registry.js +42 -146
  35. package/lib/cli/sync.js +122 -23
  36. package/lib/cli/uninstall.js +42 -7
  37. package/lib/cli/update.js +257 -198
  38. package/lib/cli/version-helpers.js +59 -0
  39. package/package.json +6 -6
  40. package/.agents/workflows/onboard.md +0 -208
  41. package/lib/cli/__tests__/migrate.test.js +0 -268
  42. package/lib/cli/__tests__/sync-local-zone.test.js +0 -247
  43. package/lib/cli/__tests__/sync.test.js +0 -372
  44. package/lib/cli/__tests__/update-changelog-surface.test.js +0 -357
  45. package/lib/cli/__tests__/update-major.test.js +0 -217
  46. package/lib/cli/__tests__/update-reexec.test.js +0 -513
  47. package/lib/cli/__tests__/update.test.js +0 -696
  48. package/lib/cli/__tests__/version-check.test.js +0 -398
  49. package/lib/migrations/__tests__/index.test.js +0 -216
package/.agents/README.md CHANGED
@@ -42,9 +42,9 @@ also forwarded to `bootstrap.js`); a non-TTY run without `--assume-yes` defaults
42
42
  to **files-only**, so the side-effecting GitHub provisioning never runs
43
43
  unattended.
44
44
 
45
- After it completes, run **`/onboard`** inside Claude Code for the guided first
46
- run — stack detection, docs scaffolding, a `mandrel doctor` readiness gate, and
47
- a started `/plan` handoff.
45
+ After it completes, `mandrel init` runs the onboarding tail automatically
46
+ stack detection, docs scaffolding offer, a `mandrel doctor` readiness gate,
47
+ and a printed `/plan` handoff — so you land at planning in one command.
48
48
 
49
49
  ### Manual Install
50
50
 
@@ -112,7 +112,7 @@ clone produces zero file mutations.
112
112
  ## Upgrading and local additions
113
113
 
114
114
  Once installed, the ongoing upgrade path is **`mandrel update`** — it bumps
115
- `mandrel` to the newest non-major version, re-runs `mandrel sync`,
115
+ `mandrel` to the newest published version, re-runs `mandrel sync`,
116
116
  applies version-keyed migrations, and verifies the install with
117
117
  `mandrel doctor`. The lockfile bump is left **staged for you to review and
118
118
  commit** (the command performs no `git` mutation):
@@ -122,12 +122,9 @@ npx mandrel update # update → sync → migrate → doctor
122
122
  npx mandrel update --dry-run # preview the target version + ordered steps
123
123
  ```
124
124
 
125
- A **major** crossing (e.g. `1.x 2.0`) is **gated**: Mandrel lives on the
126
- 1.x line under release-please `always-bump-minor`, so a major is a deliberate
127
- operator decision. `mandrel update` refuses a major bump, points at the
128
- [`docs/upgrade-major.md`](../docs/upgrade-major.md) runbook, and exits
129
- without touching anything — re-run with `--major` to adopt it. Minor and
130
- patch bumps are never gated. Migrations can also be run on their own:
125
+ Major crossings are applied like any other bump Mandrel ships hard
126
+ cutovers, so the release notes in the surfaced changelog are the migration
127
+ guide. Migrations can also be run on their own:
131
128
 
132
129
  ```bash
133
130
  npx mandrel migrate --from <version> --to <version> [--dry-run]
@@ -143,6 +140,61 @@ workflow fragments there rather than editing synced files in place.
143
140
 
144
141
  ---
145
142
 
143
+ ## CLI subcommand reference
144
+
145
+ Run `mandrel --help` for a subcommand list. Each subcommand supports
146
+ `--dry-run` (where noted) to preview without writing.
147
+
148
+ | Subcommand | Purpose | Key flags |
149
+ | ---------- | ------- | --------- |
150
+ | `init` | Install + configure mandrel in the current project (cold-start). | `--assume-yes`, `--skip-github`, `--dry-run` |
151
+ | `sync` | Re-materialize `.agents/` from the installed package payload. | `--dry-run` |
152
+ | `sync-commands` | Regenerate `.claude/commands/` from `.agents/workflows/`. | — |
153
+ | `doctor` | Run readiness checks and print per-check remedies. | — |
154
+ | `update` | Upgrade mandrel to the newest published version. | `--dry-run`, `--install-cmd` |
155
+ | `migrate` | Apply version-keyed migrations for a version range. | `--from`, `--to`, `--dry-run` |
156
+ | `explain` | Print resolved config values with their sources. | `--json` |
157
+ | `uninstall` | Reverse a recorded install using the install ledger. | `--include-github`, `--dry-run` |
158
+
159
+ ### `mandrel explain`
160
+
161
+ Prints every resolved `.agentrc.json` config key — its effective value, the
162
+ source layer it came from (`[agentrc]` or `[default]`), and a one-line
163
+ meaning. Secret-shaped keys are redacted. Useful for debugging unexpected
164
+ behavior when multiple config sources overlap.
165
+
166
+ ```bash
167
+ mandrel explain # human-readable config report
168
+ mandrel explain --json # same report as JSON
169
+ ```
170
+
171
+ ### `mandrel sync-commands`
172
+
173
+ Regenerates the flat `.claude/commands/` projection from `.agents/workflows/`.
174
+ The bootstrap wires a `UserPromptSubmit` hook that runs this automatically on
175
+ every Claude Code prompt submission, so manual runs are rarely needed.
176
+
177
+ ```bash
178
+ mandrel sync-commands # rebuild .claude/commands/
179
+ ```
180
+
181
+ ### `mandrel uninstall`
182
+
183
+ Reverses a recorded install using the install ledger
184
+ (`.agents/.install-manifest.json`). Each ledger entry is a
185
+ mutation-manifest record; uninstall walks reversible entries and undoes
186
+ exactly what the install applied, without touching pre-existing operator
187
+ content. GitHub-side state (labels, branch protection, Projects board)
188
+ requires manual reversal and is surfaced as a follow-up checklist.
189
+
190
+ ```bash
191
+ mandrel uninstall # reverse all local install mutations
192
+ mandrel uninstall --dry-run # preview what would be reversed
193
+ mandrel uninstall --include-github # acknowledge GitHub-side manual steps
194
+ ```
195
+
196
+ ---
197
+
146
198
  ## Automatic system-prompt wiring
147
199
 
148
200
  The bootstrap wires the framework system prompt into a project-root
@@ -209,9 +261,10 @@ a single vendored manifest that ships inside the bundle:
209
261
  - **[`runtime-deps.json`](runtime-deps.json)** — the single source of
210
262
  truth. Its `dependencies` block lists the **required** packages (`ajv`,
211
263
  `ajv-formats`, `js-yaml`, `minimatch`, `picomatch`, `string-argv`,
212
- `typescript`, `typhonjs-escomplex`); its `optionalDependencies` block
213
- lists packages used only behind graceful-degradation paths (`chokidar`
214
- for `quality:watch`, `@commitlint/load` for commit-subject sizing).
264
+ `typhonjs-escomplex`); its `optionalDependencies` block lists packages
265
+ used behind graceful-degradation paths (`typescript` for TS-source
266
+ scoring in the maintainability engine, `chokidar` for `quality:watch`,
267
+ `@commitlint/load` for commit-subject sizing).
215
268
 
216
269
  **How a consumer satisfies them:** `bootstrap` (above) merges the required
217
270
  set into your `package.json` `dependencies` and runs your package manager's
@@ -268,7 +321,7 @@ See [`docs/SDLC.md` § Ticket hierarchy](docs/SDLC.md) for the diagram and execu
268
321
  | The Epic planning and delivery process | [`docs/SDLC.md`](docs/SDLC.md) |
269
322
  | The system prompt loaded by your AI tool | [`instructions.md`](instructions.md) |
270
323
  | Every `.agentrc.json` key, default, and override | [`docs/configuration.md`](docs/configuration.md) (under `.agents/`) |
271
- | Quality-gate runbooks (CRAP, MI, lint, friction) plus the baseline envelope, component model, and writer/reader contract | [`docs/quality-gates.md`](../docs/quality-gates.md) |
324
+ | Quality-gate runbooks (CRAP, MI, lint, friction) plus the baseline envelope, component model, and writer/reader contract | [`.agents/docs/quality-gates.md`](docs/quality-gates.md) |
272
325
  | Slash-command workflow definitions | [`workflows/`](workflows/) |
273
326
  | Render the signals span-tree (debug helper) | [`workflows/helpers/signals.md`](workflows/helpers/signals.md) |
274
327
  | Persona behavior packs | [`personas/`](personas/) |
@@ -504,8 +557,8 @@ envelope, every gate reads through one shared module
504
557
  and every refresher writes through one shared writer
505
558
  ([`.agents/scripts/lib/baselines/writer.js`](scripts/lib/baselines/writer.js)).
506
559
 
507
- See the [Baseline reference](../docs/quality-gates.md#baseline-reference)
508
- section of `docs/quality-gates.md` for the full reference: envelope shape,
560
+ See the [Baseline reference](docs/quality-gates.md#baseline-reference)
561
+ section of `.agents/docs/quality-gates.md` for the full reference: envelope shape,
509
562
  per-kind axes, component model, path canonicalisation, writer/reader
510
563
  contract, kernel-version friction, and — most relevant to consumers — the
511
564
  **floor override** path. Consumers add a `floors` block
@@ -790,22 +843,11 @@ yanks the claim back from whoever legitimately took over.
790
843
 
791
844
  ## Root config vs distributed templates
792
845
 
793
- Three `.agentrc`-shaped files live in this repository and are easy to
794
- confuse:
795
-
796
- | File | Audience | Role |
797
- | --------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
798
- | `.agentrc.json` (repo root) | The framework dogfooding itself | Live config used when running `/epic-*`, `/deliver` against this repo. Exercises the framework end-to-end. |
799
- | `.agents/starter-agentrc.json` | Downstream consumer repos | Bootstrap delta-seed a consumer copies via `cp .agents/starter-agentrc.json .agentrc.json`. Minimum schema-required keys. |
800
- | `.agents/docs/agentrc-reference.json` | Operators and reviewers | Exhaustive editor reference enumerating every schema key with its framework default. Not a copy target. |
801
-
802
- The three files share a schema; where they legitimately diverge (target
803
- dirs, repo identifiers, version-file pointer) is documented in
804
- [`docs/configuration.md` § Root dogfood vs distributed template](docs/configuration.md#root-dogfood-vs-distributed-template).
805
- Edit `agentrc-reference.json` when a framework default changes; edit
806
- `starter-agentrc.json` only when the bootstrap seed itself needs new
807
- schema-required keys; edit the root `.agentrc.json` for changes that
808
- only affect this repo's own dogfood runs.
846
+ Three `.agentrc`-shaped files live in this repository and serve different
847
+ audiences. Their roles, audiences, and the keys where they legitimately
848
+ diverge are documented in
849
+ [`docs/configuration.md` § Root dogfood vs distributed templates](docs/configuration.md#root-dogfood-vs-distributed-templates)
850
+ that section is the canonical single home for this table.
809
851
 
810
852
  ---
811
853
 
@@ -143,6 +143,11 @@ From zero to shipped:
143
143
  a halt), re-run `/deliver <epicId>` — the wave loop picks up
144
144
  incomplete Stories from the dispatch manifest automatically. Standalone
145
145
  Stories (no `Epic: #N` reference) use `/deliver <storyId>` instead.
146
+ Mixed input — several Epics, or Epics plus standalone Stories — is
147
+ accepted in one invocation: `/deliver` composes a **sequential segment
148
+ plan** (the standalone-Story set as one segment, delivered first, then
149
+ each Epic as its own segment in input order) and executes the segments
150
+ one at a time through the same two path helpers, never interleaved.
146
151
 
147
152
  That is the whole happy path. Everything below is **detail** — branching
148
153
  conventions, HITL escalation, audit gates — that you only need when the
@@ -225,9 +230,7 @@ graph LR
225
230
 
226
231
  subgraph Phase0 ["Phase 0: Bootstrap"]
227
232
  direction TB
228
- Z["👤 npx mandrel init<br/>(install → sync → prompt → bootstrap.js)"]:::manual
229
- Z2["👤 /onboard (guided first run)"]:::manual
230
- Z --> Z2
233
+ Z["👤 npx mandrel init<br/>(install → sync → prompt → bootstrap.js → onboarding tail → /plan handoff)"]:::manual
231
234
  end
232
235
 
233
236
  subgraph Phase1 ["Phase 1: Initiation"]
@@ -257,7 +260,7 @@ graph LR
257
260
  H["🤖 Auto-merge armed → PR lands when checks pass<br/>(👤 operator may disarm to merge manually)"]:::agentic
258
261
  end
259
262
 
260
- Z2 --> A
263
+ Z --> A
261
264
  A --> C
262
265
  D --> E
263
266
  G --> H
@@ -304,9 +307,11 @@ files-only so the GitHub provisioning never runs unattended. `bootstrap.js`:
304
307
  promotion gate.
305
308
 
306
309
  When `.agents/` is already materialized you can run the bootstrap directly
307
- (`node .agents/scripts/bootstrap.js`). After bootstrap, run **`/onboard`**
308
- inside Claude Code for the guided first run — stack detection, docs
309
- scaffolding, a `mandrel doctor` readiness gate, and a started `/plan`.
310
+ (`node .agents/scripts/bootstrap.js`). The guided first-run steps (stack
311
+ detection, docs scaffolding, `mandrel doctor` readiness gate, and `/plan`
312
+ handoff) are now part of `mandrel init`'s configure path run
313
+ `mandrel init` again to pick them up if you bootstrapped via the script
314
+ directly.
310
315
 
311
316
  > [!NOTE] Bootstrap runs once per repository. It is safe to re-run — existing
312
317
  > labels, fields, and branch-protection entries are preserved; missing ones
@@ -664,10 +669,12 @@ side-effects rather than inline calls at phase boundaries; the
664
669
  | **Standalone Story — plan** | `/plan` | Plan a one-off Story that does not belong to an Epic backlog. |
665
670
  | **Standalone Story — deliver** | `/deliver <storyId> [<storyId>...]` | Deliver one or more standalone Stories authored by `/plan`. |
666
671
  | **Standalone Story (worker)** | *helper* `helpers/single-story-deliver <storyId>` | Per-Story sub-agent called internally by `/deliver`; not an operator slash command. |
672
+ | **Mixed set** | `/deliver <ids...>` | Any mix of ≥1 Epics and standalone Stories. The router composes a sequential segment plan — standalone segment first, then Epic segments in input order — delegating each segment to the path helpers above. |
667
673
 
668
- The operator-facing entry points are `/deliver` (for Epics) and
669
- `/deliver` (for standalone Stories). The `helpers/` layer sits below
670
- both and is never invoked directly by the operator.
674
+ The single operator-facing entry point is `/deliver` it routes a lone
675
+ Epic, a standalone-Story set, or a mixed set (via the sequential segment
676
+ plan) to the right path helper(s). The `helpers/` layer sits below it and
677
+ is never invoked directly by the operator.
671
678
 
672
679
  ### Story-centric branching
673
680
 
@@ -1403,8 +1410,7 @@ For Stories already in flight, use one of the three options above.
1403
1410
 
1404
1411
  | Command | Purpose |
1405
1412
  | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1406
- | `npx mandrel init` | Cold-start command — install `mandrel` (if absent), `mandrel sync`, then prompt to run `bootstrap.js` (provisions repo + Projects V2 board, labels, branch protection). |
1407
- | `/onboard` | Guided first run after bootstrap — stack detection, docs scaffolding, `mandrel doctor` readiness gate, started `/plan` handoff. |
1413
+ | `npx mandrel init` | Cold-start command — install `mandrel` (if absent), `mandrel sync`, bootstrap.js (provisions repo + Projects V2 board, labels, branch protection), then onboarding tail (stack detection, docs scaffolding, doctor gate, `/plan` handoff). |
1408
1414
  | `/plan` | Ideation entry — sharpen idea, search duplicates, open Epic, then PRD + Tech Spec + decomposition. |
1409
1415
  | `/plan --idea "<seed>"` | Same ideation entry with pre-supplied seed. |
1410
1416
  | `/plan <epicId>` | Existing-Epic mode — PRD + Tech Spec + decomposition for an Epic Issue already opened. |
@@ -376,7 +376,7 @@ branch protection on the base branch.
376
376
 
377
377
  | Field | Required | Default | Purpose |
378
378
  | ---------------- | -------- | ------- | ----------------------------------------------------------------------- |
379
- | `enforce` | No | `true` | When `true`, `node .agents/scripts/bootstrap.js` calls `ensureMainBranchProtection(...)`. |
379
+ | `enforce` | No | `true` | When `true`, `node .agents/scripts/bootstrap.js` calls `applyBranchProtection(...)`. |
380
380
  | `requiredChecks` | No | `[]` | Array of `{ name, cmd[] }` entries used both as required-status-check expectations on the PR and as local close-validation gate invocations. |
381
381
 
382
382
  Each `requiredChecks` entry takes the shape:
@@ -770,14 +770,14 @@ the lint ratchet, and the CRAP/MI gates.
770
770
 
771
771
  | File | Owner | Refresh |
772
772
  | --------------------------------- | ------------------------------------ | ---------------------------------------------------------------------- |
773
- | `baselines/lint.json` | `lint-baseline.js` | `node .agents/scripts/lint-baseline.js --refresh` |
773
+ | `baselines/lint.json` | `lint-baseline.js` | `node .agents/scripts/lint-baseline.js capture` |
774
774
  | `baselines/crap.json` | `update-crap-baseline.js` | `npm run crap:update` |
775
775
  | `baselines/maintainability.json` | `update-maintainability-baseline.js` | `npm run maintainability:update` |
776
776
 
777
777
  These files are the contract. They are read by every gate (Story close, push
778
778
  hook, CI) and are regenerated only via tagged `baseline-refresh:` commits
779
779
  with a non-empty body. The convention is operator-enforced; see the CRAP
780
- section of [`docs/quality-gates.md`](../../docs/quality-gates.md) for the policy.
780
+ section of [`quality-gates.md`](quality-gates.md) for the policy.
781
781
 
782
782
  Paths are configured in `delivery.quality.gates.<tier>.baselinePath`. The
783
783
  default values match the canonical layout above; override only when a
@@ -1024,6 +1024,63 @@ move and the allowlist response in the same diff.
1024
1024
 
1025
1025
  ---
1026
1026
 
1027
+ ## CLI subcommand quick-reference
1028
+
1029
+ `mandrel --help` prints the full subcommand list. Each subcommand that
1030
+ mutates state supports `--dry-run` to preview without writing. The table
1031
+ below covers every dispatch-visible subcommand:
1032
+
1033
+ | Subcommand | What it does | Key flags |
1034
+ | ---------- | ------------ | --------- |
1035
+ | `init` | Install and configure mandrel in the current project. | `--assume-yes`, `--skip-github`, `--dry-run` |
1036
+ | `sync` | Re-materialize `.agents/` from the installed package payload. | `--dry-run`, `--force` |
1037
+ | `sync-commands` | Rebuild `.claude/commands/` from `.agents/workflows/`. | — |
1038
+ | `doctor` | Run readiness checks and report remedies. | — |
1039
+ | `update` | Upgrade mandrel to the newest published version. | `--dry-run`, `--install-cmd` |
1040
+ | `migrate` | Apply version-keyed migrations for a version range. | `--from`, `--to`, `--dry-run` |
1041
+ | `explain` | Print resolved config values with sources. | `--json` |
1042
+ | `uninstall` | Reverse a recorded install using the install ledger. | `--include-github`, `--dry-run` |
1043
+
1044
+ ### `mandrel explain`
1045
+
1046
+ Prints every resolved config key — its effective value, its source layer
1047
+ (`[agentrc]` or `[default]`), and a one-line description. Secret-shaped
1048
+ values are shown as `<redacted>`. Useful when debugging unexpected behavior
1049
+ caused by config layering.
1050
+
1051
+ ```bash
1052
+ mandrel explain # human-readable report
1053
+ mandrel explain --json # JSON report for scripting
1054
+ ```
1055
+
1056
+ ### `mandrel sync-commands`
1057
+
1058
+ Regenerates the flat `.claude/commands/` tree from `.agents/workflows/`. The
1059
+ bootstrap wires a `UserPromptSubmit` hook so this runs automatically on every
1060
+ Claude Code prompt; manual invocations are only needed when the hook is absent
1061
+ or the commands/ tree is manually deleted.
1062
+
1063
+ ```bash
1064
+ mandrel sync-commands
1065
+ ```
1066
+
1067
+ ### `mandrel uninstall`
1068
+
1069
+ Reverses a recorded install using the install ledger
1070
+ (`.agents/.install-manifest.json`). Restoration is marker-based and
1071
+ non-destructive: operator-authored content that pre-existed the install
1072
+ is preserved; only install-created files and framework additions are removed.
1073
+ GitHub-side state is never acted on automatically; it is surfaced as a
1074
+ manual checklist.
1075
+
1076
+ ```bash
1077
+ mandrel uninstall # reverse all local mutations
1078
+ mandrel uninstall --dry-run # preview without writing
1079
+ mandrel uninstall --include-github # acknowledge GitHub-side follow-ups
1080
+ ```
1081
+
1082
+ ---
1083
+
1027
1084
  ## Cross-references
1028
1085
 
1029
1086
  - JSON Schema mirror —
@@ -1035,6 +1092,6 @@ move and the allowlist response in the same diff.
1035
1092
  - Bootstrap script —
1036
1093
  [`bootstrap.js`](../scripts/bootstrap.js)
1037
1094
  - Quality gates runbook (CRAP onboarding, MI ratchet, lint ratchet) —
1038
- [`docs/quality-gates.md`](../../docs/quality-gates.md)
1095
+ [`quality-gates.md`](quality-gates.md)
1039
1096
  - Activation pointers (slash commands, personas, skills) —
1040
1097
  [`.agents/README.md`](../README.md)