@theholocron/cli 5.0.0-alpha.17 → 5.0.0-alpha.170

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
@@ -17,17 +17,25 @@ holocron --help
17
17
  ## Interactive mode
18
18
 
19
19
  Run `holocron` with no command, a parent command with no subcommand
20
- (`holocron auth`, `holocron skills`, `holocron upgrade`), or a leaf command
21
- missing a required positional (`holocron deploy`, `holocron secret set`), and
22
- you get a prompt instead of a `--help` dead end:
23
-
24
- ```
20
+ (`holocron auth`, `holocron repo`, `holocron repo upgrade`, …), or a leaf command
21
+ missing a required positional (`holocron deploy`, `holocron secrets set`), and
22
+ you get a prompt instead of a `--help` dead end.
23
+
24
+ The menu mirrors the command tree: each level shows only the next word, and a
25
+ group (marked `›`) opens its own submenu, as deep as the commands nest. Nothing
26
+ is shown as a `<command> <subcommand>` path — `config show` is `config ›` then
27
+ `show`. Every submenu has a `← back` item, and a command that is also a group
28
+ (`repo sync`, `deploy`) has a `(run it)` item at the top of its submenu. Typing
29
+ searches the whole tree — `upgrade` at the top finds the `repo` group — with
30
+ name matches ranked above description matches.
31
+
32
+ ```console
25
33
  $ holocron
26
- ? What would you like to do? › dep
27
- ────────────────────────────────────────────────
28
- ❯ deploy Trigger a deployment via the configured `deployment` capability
29
-
30
- ? Branch to deploy: › main
34
+ ? What would you like to do? › repo
35
+ ❯ repo ›
36
+ ? repo — choose a subcommand: › upgrade
37
+ ? repo upgrade — choose a subcommand: › node
38
+ ? Target Node.js major version: › 24
31
39
  ```
32
40
 
33
41
  The picked command spawns as a normal `holocron <command> …` invocation —
@@ -35,15 +43,30 @@ The picked command spawns as a normal `holocron <command> …` invocation —
35
43
  through. A non-interactive shell (CI, a script, a pipe) gets the old
36
44
  hard-failure message instead of hanging on a prompt.
37
45
 
46
+ For a command whose handler honours `--dry-run` (most of them — everything
47
+ except `auth *` and `config show`), the menu always previews it first — a
48
+ dry run doesn't mutate anything, so there's nothing to ask permission for —
49
+ then asks the one real decision:
50
+
51
+ ```console
52
+ ...dry-run output...
53
+ ? Dry run complete — proceed with the real run? › yes
54
+ ```
55
+
56
+ A preview that reports nothing would actually change (e.g. `clone` finding
57
+ every repo already cloned) skips that question too — there'd be nothing for
58
+ the real run to do either. `--skip-dry-run` opts out of the preview
59
+ entirely, straight to the real run, for when you already know what you want.
60
+
38
61
  ## Execution contexts
39
62
 
40
63
  Every command is tagged with how much of a repo it needs:
41
64
 
42
- | Context | Needs | Examples |
43
- | ------------ | -------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
44
- | `global` | just the CLI binary | `version`, `clone`, `new`, `upgrade node`, `auth set` / `check`, `plugin create`, `skills …` |
45
- | `repo-aware` | `./holocron.config` in cwd, no plugins | `run`, `ci`, `config show`, `sync-readme` |
46
- | `workspace` | the `@theholocron/holocron-plugin-*` packages resolvable | `doctor`, `setup`, `sync`, `secrets sync`, `deploy` |
65
+ | Context | Needs | Examples |
66
+ | ------------ | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
67
+ | `global` | the CLI binary alone | `version`, `clone`, `new repo` / `plugin`, `repo upgrade …`, `auth set` / `check`, `package …`, `run lint commit-msg`, `skills …` |
68
+ | `repo-aware` | `./holocron.config`, walking up from cwd, no plugins | `run`, `run ci`, `config show`, `repo sync readme`, `deploy on-release` |
69
+ | `workspace` | the `@theholocron/holocron-plugin-*` packages resolvable | `doctor`, `repo setup`, `repo sync`, `secrets …`, `deploy`, `sync github` |
47
70
 
48
71
  A `workspace` command run from a bare global install (no plugins next to the
49
72
  CLI) fails with one actionable line — install the plugins as devDependencies or
@@ -51,6 +74,21 @@ use `pnpm exec holocron <cmd>`. `auth check` degrades to "token present,
51
74
  verification skipped" instead. `holocron --help` prints the grouping; see
52
75
  [Execution Contexts](https://theholocron.github.io/holocron/execution-contexts).
53
76
 
77
+ ### Viewing the resolved config
78
+
79
+ `holocron config show` prints the resolved config. On a TTY it opens a foldable
80
+ tree by default; piped or redirected, it always emits plain, valid JSON
81
+ (`holocron config show | jq`).
82
+
83
+ ```console
84
+ holocron config show # TTY: foldable tree (↑↓ move, →/⏎ expand, ← collapse, E/C all, q quit)
85
+ holocron config show --depth 2 # static coloured tree, anything nested deeper than 2 levels collapsed
86
+ holocron config show --no-interactive # static coloured tree, fully expanded
87
+ ```
88
+
89
+ Passing `--interactive` explicitly needs a TTY on stdin and stdout and fails
90
+ with a one-line message otherwise; the default falls back to static output. It has no extra dependencies — nothing to install.
91
+
54
92
  ## Config file
55
93
 
56
94
  Holocron reads `holocron.config.{json,js,ts}` from the project root
@@ -103,18 +141,18 @@ A minimal config — for repos with a `package.json` and a GitHub remote
103
141
 
104
142
  ### repo options
105
143
 
106
- Additional `repo` fields recognised by `holocron setup`:
144
+ Additional `repo` fields recognised by `holocron repo setup`:
107
145
 
108
- | Field | Type | Description |
109
- | ----------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
110
- | `repo.teams` | `Array<string \| { slug, permission }>` | GitHub teams granted repo access. String shorthand defaults to `push` (Write). `holocron setup` also writes `.github/CODEOWNERS` for teams with `push`/`maintain`/`admin`. |
111
- | `repo.topics` | `string[]` | GitHub topics set on the repository. |
112
- | `repo.protection` | `"balanced" \| "strict" \| "none"` | Branch-protection preset applied by `holocron setup`. For `"strict"`, the required status checks are derived from the task manifest — see below. |
113
- | `repo.properties` | `RepoProperties` | Org-level custom property values synced to the GitHub dashboard. |
146
+ | Field | Type | Description |
147
+ | ----------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
148
+ | `repo.teams` | `Array<string \| { slug, permission }>` | GitHub teams granted repo access. String shorthand defaults to `push` (Write). `holocron repo setup` also writes `.github/CODEOWNERS` for teams with `push`/`maintain`/`admin`. |
149
+ | `repo.topics` | `string[]` | GitHub topics set on the repository. |
150
+ | `repo.protection` | `"balanced" \| "strict" \| "none"` | Branch-protection preset applied by `holocron repo setup`. For `"strict"`, the required status checks are derived from the task manifest — see below. |
151
+ | `repo.properties` | `RepoProperties` | Org-level custom property values synced to the GitHub dashboard. |
114
152
 
115
153
  ### Custom properties synced to GitHub
116
154
 
117
- `holocron setup` and `holocron sync` both call `syncProperties()` with two
155
+ `holocron repo setup` and `holocron repo sync` both call `syncProperties()` with two
118
156
  kinds of fields — always one-way (`holocron.config.ts` → resolved →
119
157
  properties; properties are never a second editable source of truth):
120
158
 
@@ -142,9 +180,25 @@ Field definitions and derivation heuristics:
142
180
  `.notes/tech-holocron-platform.spec.md` → "Custom-properties sync — field
143
181
  definitions (#677)".
144
182
 
183
+ The four derived fields' pure computation —
184
+ `deriveProfile()`/`deriveStack()`/`deriveCapabilities()`/`deriveCompliance()`
185
+ (plus their `HolocronProfile`/`DeriveProfileInput`/`PackageJsonLike` types)
186
+ — is exported from this package's public entry point, separate from the
187
+ local-filesystem reads (`readWorkspacePackageJsons()`) that gather their
188
+ inputs here. `@theholocron/sentinel`'s `syncPropertiesFromConfig()` reuses
189
+ these functions unchanged, gathering the same inputs over the GitHub API
190
+ instead (D8 — one derivation, two input sources, not two
191
+ implementations).
192
+
193
+ `missingCapabilities(capabilities)` is `deriveCompliance()`'s sibling —
194
+ same `REQUIRED_BASELINE` table, but returns _which_ required capabilities
195
+ are absent rather than whether any are. `@theholocron/sentinel`'s
196
+ `postCheckRun()` uses it to name what's missing on the check run it
197
+ posts, instead of reporting pass/fail.
198
+
145
199
  ### Required status checks (`protection: "strict"`)
146
200
 
147
- `holocron setup` builds the branch-protection required-check list from the
201
+ `holocron repo setup` builds the branch-protection required-check list from the
148
202
  manifest, not a hand-maintained array:
149
203
 
150
204
  - `"DCO"` (hard-prepended), then
@@ -170,12 +224,32 @@ The generated ruleset also sets `require_extra_approval_for_unattributed_changes
170
224
  false` — with `required_approving_review_count: 0` and a single maintainer, the
171
225
  GitHub default (`true`) is an unsatisfiable block on any PR with an
172
226
  unverified/unattributed commit. Repository-admin bypass still covers the real
173
- risk. And the `codecov.yml` `holocron setup` writes carries `if_not_found:
227
+ risk. And the `codecov.yml` `holocron repo setup` writes carries `if_not_found:
174
228
  success` on every status default, so an infra-only PR (dep bump, config,
175
229
  lockfile — no coverable change) passes instead of hanging on a `codecov/*`
176
- required check that never posts. A re-run of `holocron setup` backfills both into
230
+ required check that never posts. A re-run of `holocron repo setup` backfills both into
177
231
  an existing repo.
178
232
 
233
+ ### Default branch (`repo.defaultBranch`)
234
+
235
+ ```ts
236
+ export default defineConfig({
237
+ repo: { protection: "strict", defaultBranch: "alpha" },
238
+ providers: { source: "github" },
239
+ });
240
+ ```
241
+
242
+ `holocron repo setup` syncs GitHub's repo-level default branch (`HEAD`) — what a
243
+ fresh clone checks out, what `gh pr create`/the compare UI target by default,
244
+ and what Sentinel's `validateConfig()` reads (it only ever reads config from
245
+ the repo's default branch, never a PR ref — a deliberate security boundary).
246
+ Omit this field to leave GitHub's current setting untouched; most repos never
247
+ need it. It exists for a repo using a `main`/`alpha` prerelease-channel split
248
+ where active development happens on a non-`main` branch: set this to that
249
+ branch so Sentinel validates against what's actually being developed, then
250
+ change it back once that branch merges to `main` for a stable cut and stops
251
+ being the active branch.
252
+
179
253
  ### Git hooks
180
254
 
181
255
  ```ts
@@ -186,7 +260,7 @@ export default defineConfig({
186
260
  });
187
261
  ```
188
262
 
189
- `holocron setup` writes `.husky/pre-push` (runs `holocron ci` before every
263
+ `holocron repo setup` writes `.husky/pre-push` (runs `holocron run ci` before every
190
264
  push) and `.husky/pre-commit` (runs `gitleaks protect --staged` + `lint-staged`
191
265
  before every commit — scoped to staged changes, not the whole history, so a
192
266
  past false positive can't permanently block future commits) and sets
@@ -197,7 +271,7 @@ setup --hooks` / `--no-hooks` override per run. Bypass one push with `git push
197
271
 
198
272
  ### Task scripts
199
273
 
200
- `holocron sync` reconciles `package.json#scripts` from the `tasks` manifest
274
+ `holocron repo sync` reconciles `package.json#scripts` from the `tasks` manifest
201
275
  (merge, never clobber — only the managed keys are touched):
202
276
 
203
277
  ```ts
@@ -232,8 +306,8 @@ export default defineConfig({
232
306
  `@theholocron/astromech`'s `loadTasksConfig` merges it over
233
307
  `holocron.config`'s `tasks` — **task arrays concatenate**
234
308
  (`holocron.config` first), the dedicated file **wins on scalars**,
235
- `extraRequiredChecks` concatenate. `holocron run` / `holocron ci` /
236
- `holocron setup` / `holocron sync` all read the merged result, so the
309
+ `extraRequiredChecks` concatenate. `holocron run` / `holocron run ci` /
310
+ `holocron repo setup` / `holocron repo sync` all read the merged result, so the
237
311
  split is transparent. Useful for keeping the capability/provider config
238
312
  and the "what this repo runs" manifest in separate files (this repo does).
239
313
 
@@ -260,10 +334,27 @@ job execute the same thing — at a turbo root both are
260
334
  `turbo run test -- --coverage` (the registry's org-default flags flow through
261
335
  turbo's `--`).
262
336
 
263
- ### `holocron ci`
337
+ ### `holocron deploy on-release`
338
+
339
+ ```bash
340
+ holocron deploy on-release [--channel <alpha|main>] [--from <commit>] [--to <commit>] [--dry-run]
341
+ ```
342
+
343
+ Deploys every workspace package whose own `holocron.config` declares
344
+ `{ name: "delivery.deploy", with: { on: "release" } }` (holocron#930), when the
345
+ release (`--channel`: its prerelease identifier, or `main`/empty for a stable
346
+ release) is on the task's `channel` (default `main`, the stable release) and changes the package or one of its
347
+ `workspace:*` dependencies between `--from` (the previous release's commit,
348
+ omitted when there is none) and `--to` (default `HEAD`). It waits for npm to
349
+ serve the release's new dependency versions, then runs `pnpm --filter <pkg>
350
+ delivery.deploy`. A package that doesn't apply is skipped; a deploy that
351
+ doesn't succeed exits non-zero. The shared `delivery.publish` workflow runs it as its own
352
+ `deploy` job after the release job (opt in with `deploy-on-release: true`).
353
+
354
+ ### `holocron run ci`
264
355
 
265
356
  ```bash
266
- holocron ci [--all] [--filter <pkg>] [--dry-run]
357
+ holocron run ci [--all] [--filter <pkg>] [--dry-run]
267
358
  ```
268
359
 
269
360
  Runs the merge-gating checks locally, in CI order, exiting non-zero on the
@@ -277,6 +368,46 @@ Order comes from the `CI_ORDER` constant in `@theholocron/astromech`
277
368
  expands into its sub-jobs (each under its own `audit / …` check context)
278
369
  unless the repo ships its own `"audit"` script.
279
370
 
371
+ ### `holocron deploy`
372
+
373
+ `holocron deploy <branch>` (a Git-linked deployment) and `holocron deploy
374
+ --files <dir>` (a directory of build output, no linked repo) both trigger a
375
+ deployment through the configured `deployment` capability, then **wait for
376
+ it to finish**. The command reports success, exit code 0, only when the
377
+ deployment reaches `ready`. A deployment that ends `error` or `cancelled`,
378
+ or is still building after 10 minutes, is a failure: the exit code is
379
+ non-zero and the output includes the provider's own reason
380
+ (`DeploymentRecord.errorMessage`, e.g. Vercel's `Command "npm install"
381
+ exited with 1`). Providers build asynchronously, so accepting a deployment
382
+ isn't the same as it going live (holocron#911).
383
+
384
+ Provider plugins support this through the `Deployment` capability's
385
+ existing `getDeployment(id)`. They should set `errorMessage` on the
386
+ returned `DeploymentRecord` whenever the provider exposes one.
387
+
388
+ ### `holocron monitoring check <url>`
389
+
390
+ Runs every configured `monitoring` check against `<url>` instead of each
391
+ check's own configured `url` — no vendor API call, only a plain HTTP
392
+ request evaluated locally against the exact same `assertions` already in
393
+ `holocron.config.ts`. Built for CI: the `delivery.previewCheck` task runs
394
+ this against a PR's Vercel preview deployment (triggered by
395
+ `deployment_status`, not `push`/`pull_request`), reusing the production
396
+ check definitions to catch a breaking change before merge instead of
397
+ after (holocron#1010).
398
+
399
+ ```ts
400
+ export default defineConfig({
401
+ tasks: ["delivery.previewCheck"],
402
+ providers: {
403
+ monitoring: ["checkly", { accountId: "...", checks: [/* ... */] }],
404
+ },
405
+ });
406
+ ```
407
+
408
+ Exits non-zero if any check fails — the job's own pass/fail is what
409
+ posts as the GitHub check, no separate reporting step needed.
410
+
280
411
  ### Lint parity
281
412
 
282
413
  The `lint` task takes an optional `linters` array — one list that drives
@@ -294,7 +425,7 @@ export default defineConfig({
294
425
 
295
426
  ### Skills installer
296
427
 
297
- `holocron setup` can install shared skills from `@theholocron/skills` into the local repo:
428
+ `holocron repo setup` can install shared skills from `@theholocron/skills` into the local repo:
298
429
 
299
430
  ```ts
300
431
  export default defineConfig({
@@ -357,16 +488,16 @@ export default acmeConfig;
357
488
 
358
489
  ## Upgrading
359
490
 
360
- - **`holocron upgrade node <to>`** — patches every Node.js version pin
491
+ - **`holocron repo upgrade node <to>`** — patches every Node.js version pin
361
492
  (`engines.node`, `.nvmrc`, `.node-version`, `.github/workflows/*`,
362
493
  `Dockerfile`, `.tool-versions`) to a new major.
363
- - **`holocron upgrade deps`** — bumps every `@theholocron/*` pin in
494
+ - **`holocron repo upgrade deps`** — bumps every `@theholocron/*` pin in
364
495
  `pnpm-workspace.yaml` (`catalog:` and every named `catalogs.*`) to its latest
365
496
  published version, then migrates `holocron.config.ts` from the 7.x preset
366
497
  shape (`const { repo, workflows } = node()` + `repo.requiredChecks` +
367
498
  `workflows:`) to the current composed-preset API (`const preset = node()` +
368
499
  `...preset` + `tasks:` + `extraRequiredChecks:`). Mechanical transforms only —
369
- review the result, then `pnpm install && holocron ci`. `--pins-only` skips
500
+ review the result, then `pnpm install && holocron run ci`. `--pins-only` skips
370
501
  the config migration; `--dry-run` prints without writing.
371
502
 
372
503
  ## Auth — fine-grained tokens
@@ -385,7 +516,7 @@ holocron auth set github.admin ghp_xxx # setup, secrets, environments
385
516
 
386
517
  The resolution chain per capability is:
387
518
 
388
- ```
519
+ ```text
389
520
  --token flag → HOLOCRON_<FEATURE>_TOKEN env var → keyring("github.<feature>")
390
521
  ```
391
522
 
@@ -402,16 +533,21 @@ holocron auth list # show all stored providers
402
533
  ## Logging
403
534
 
404
535
  Operational output goes through `@theholocron/observability/logger` — separate
405
- from the user-facing `print` surface. Global flags:
536
+ from the user-facing `print` surface. Local/interactive runs are quiet by
537
+ default: no colorized or raw structured console output, regardless of the
538
+ resolved level (Axiom shipping, when configured, is unaffected). CI is
539
+ untouched — its existing stdout output still appears. Global flags:
406
540
 
407
541
  ```sh
408
- holocron doctor --verbose # log level → debug (full structured output)
409
- holocron doctor --quiet # log level → error (suppress info + warn)
542
+ holocron doctor --log debug # show console output at this level (opt back in)
543
+ holocron doctor --verbose # log level → debug, and shows console output
544
+ holocron doctor --quiet # log level → error, and shows console output
410
545
  holocron doctor --debug # print "Run ID: <uuid>" at command end for Axiom lookup
411
546
  ```
412
547
 
413
- Level resolution (highest priority first): `--verbose` / `--quiet` →
414
- `HOLOCRON_LOG_LEVEL` → `log.level` in `holocron.config` → `"info"`.
548
+ Level resolution (highest priority first): `--log <level>` → `--verbose` /
549
+ `--quiet` → `HOLOCRON_LOG_LEVEL` → `log.level` in `holocron.config` →
550
+ `"info"`.
415
551
 
416
552
  ```ts
417
553
  export default defineConfig({
@@ -423,7 +559,16 @@ Axiom shipping activates when a token (`HOLOCRON_AXIOM_TOKEN` / `AXIOM_TOKEN`
423
559
  → OS keyring `axiom.<org>` → `axiom`) **and** a dataset
424
560
  (`HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` → `log.axiom.dataset` in
425
561
  `holocron.config`) both resolve; env vars win. The token is never read from a
426
- config file. See the [logging guide](https://docs.theholocron.dev/holocron/logging/).
562
+ config file.
563
+
564
+ The dataset side of that resolution is **execution-context-aware** (ADR-0012):
565
+ a `global`-context command (`clone`, `new`, `auth set`, `upgrade node`, `plugin
566
+ create`, …) always ships to holocron's own dataset regardless of `$PWD` — it
567
+ isn't "about" any repo, so routing it through whichever repo's `.envrc`
568
+ happens to be active would be wrong. `repo-aware` / `workspace` commands
569
+ (`doctor`, `deploy`, `sync`, …) keep the env-var/config chain above, so a
570
+ per-repo `HOLOCRON_AXIOM_DATASET` — e.g. via a `.envrc` + `direnv` — separates
571
+ each consuming repo's logs. See the [logging guide](https://docs.theholocron.dev/holocron/logging/).
427
572
 
428
573
  ### Telemetry
429
574
 
@@ -452,34 +597,60 @@ export default defineConfig({
452
597
 
453
598
  Each SDK sits behind an interface from `@theholocron/observability` —
454
599
  `ErrorSink` (Sentry) / `AnalyticsSink` (PostHog); the adapters, and the only
455
- `@sentry/node` / `posthog-node` imports, live in that package. `telemetry.ts`
600
+ `@sentry/node` / `posthog-node` imports, live in that package. `observability/telemetry.ts`
456
601
  holds the orchestration + the Holocron-specific credential resolution
457
- (`telemetry/resolve.ts`). See the
602
+ (`observability/resolve-telemetry.ts`). See the
458
603
  [telemetry guide](https://docs.theholocron.dev/holocron/telemetry/).
459
604
 
605
+ ### ESLint bundle options
606
+
607
+ Most repos need nothing here — `@theholocron/eslint-config`'s `library()`
608
+ bundle resolves with zero committed file (Bucket A: `eslint --config
609
+ <shared path>`, no per-repo `eslint.config.ts` needed). A package with a
610
+ genuine, deliberate exception — e.g. Web Crypto globals a Node-targeted
611
+ package still needs, exempted via `library()`'s own `browserPackages`
612
+ option in that package's own `eslint.config.ts` — should also declare the
613
+ same paths in `holocron.config`'s `eslint.browserPackages`:
614
+
615
+ ```ts
616
+ export default defineConfig({
617
+ eslint: {
618
+ browserPackages: ["packages/github-client/src/app-auth"],
619
+ },
620
+ });
621
+ ```
622
+
623
+ This doesn't replace the package's own `eslint.config.ts` (local/CI linting
624
+ still resolves that file directly) — it's the signal Sentinel's centralized
625
+ static-analysis check (holocron#849/#858) reads instead, since that check
626
+ never reads a PR's own committed config files. Without it, Sentinel flags a
627
+ false-positive `eslint-plugin-n` node-builtins finding on exactly the files
628
+ the local override exists to exempt.
629
+
460
630
  ## What's in here
461
631
 
462
- - `src/capabilities/` — the 14 capability interfaces that providers
463
- implement
632
+ - `src/plugin/capabilities.ts` — the 18 capability interfaces that
633
+ providers implement
464
634
  - `src/config.ts` — config schema, `defineConfig`, `resolveConfig`,
465
635
  `CapabilityConfigPackage`
466
636
  - `src/config/load-config.ts` — `loadConfig` — reads `holocron.config.*`
467
637
  (file discovery via [`@theholocron/datapad`](../datapad))
468
638
  - `src/define-config.ts` — `defineConfig` typed pass-through
469
- - `src/logger.ts` — CLI-side `@theholocron/observability/logger` wiring
639
+ - `src/observability/logger.ts` — CLI-side `@theholocron/observability/logger` wiring
470
640
  (`buildCliLogger`, `resolveLogLevel`)
471
641
  - `src/loader.ts` — `PluginLoader` — dynamic-imports plugins, resolves
472
642
  capability config packages, builds the capability registry
473
643
  - `src/cli.ts` — yargs entry, dispatches subcommands. `holocron run` / `ci` are
474
644
  delegated to [`@theholocron/astromech`](../astromech) (`createAstromech`).
475
- `holocron sync` / `holocron setup` write each repo's `.github/workflows/*.yml`
476
- thin callers from `astromech.thinCallers()`; `holocron sync-github` pushes the
645
+ `holocron repo sync` / `holocron repo setup` write each repo's `.github/workflows/*.yml`
646
+ thin callers from `astromech.thinCallers()`; `holocron sync github` pushes the
477
647
  reusable `workflow_call` implementations + composite actions from
478
648
  `astromech.reusableTemplates()` to `theholocron/.github` (a pure sync target —
479
649
  never hand-edit its `.github/workflows/*`).
480
- - `src/commands/` — `setup`, `sync`, `doctor`, `deploy`, `secret set`,
481
- `secrets sync`, `publish`, `bump-versions`, `sync-github`, `upgrade node`,
482
- `upgrade deps`, `plugin create`, `auth`
650
+ - `src/commands/` — `repo setup`, `repo sync`, `doctor`, `deploy`,
651
+ `monitoring check`, `secrets set`, `secrets sync`, `package publish`,
652
+ `package bump-versions`, `sync github`, `repo upgrade node`,
653
+ `repo upgrade deps`, `new plugin`, `auth`
483
654
  - `src/interactive-menu.ts` — the interactive fallback: `COMMAND_REGISTRY`,
484
655
  `launchMenu` (Layers 1–2, picks + spawns a fresh `holocron <command>`),
485
656
  `promptForPositionals` (Layer 3, called inline from each leaf command's