@theholocron/cli 5.0.0-alpha.11 → 5.0.0-alpha.110

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
@@ -21,7 +21,7 @@ Run `holocron` with no command, a parent command with no subcommand
21
21
  missing a required positional (`holocron deploy`, `holocron secret set`), and
22
22
  you get a prompt instead of a `--help` dead end:
23
23
 
24
- ```
24
+ ```console
25
25
  $ holocron
26
26
  ? What would you like to do? › dep
27
27
  ────────────────────────────────────────────────
@@ -112,6 +112,52 @@ Additional `repo` fields recognised by `holocron setup`:
112
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
113
  | `repo.properties` | `RepoProperties` | Org-level custom property values synced to the GitHub dashboard. |
114
114
 
115
+ ### Custom properties synced to GitHub
116
+
117
+ `holocron setup` and `holocron sync` both call `syncProperties()` with two
118
+ kinds of fields — always one-way (`holocron.config.ts` → resolved →
119
+ properties; properties are never a second editable source of truth):
120
+
121
+ **Manual** — `repo.properties` states these explicitly:
122
+
123
+ | Property | Value |
124
+ | ------------------------ | ---------------------------------------------- |
125
+ | `lifecycle` | `"active" \| "experimental" \| "deprecated"` |
126
+ | `open_source` | `boolean` |
127
+ | `runtime_environment` | `"node" \| "browser" \| "universal" \| "none"` |
128
+ | `uses_external_packages` | `boolean` |
129
+
130
+ **Derived** — computed from resolved config + `package.json`, not a config field:
131
+
132
+ | Property | Value |
133
+ | ---------------------------------- | ---------------------------------------------------------------------------------------- |
134
+ | `monorepo` | `boolean` — whether `pnpm-workspace.yaml` exists |
135
+ | `holocron_branch_protection_level` | the active `repo.protection` preset |
136
+ | `holocron_profile` | repo archetype: `library` / `cli` / `plugin` / `template` / `app` / `docs` / `platform` |
137
+ | `holocron_capabilities` | provider capability keys actually wired in `providers: {}` (`multi_select`) |
138
+ | `holocron_stack` | detected build/framework tooling — `next`, `vite`, `astro`, `tsdown`, … (`multi_select`) |
139
+ | `holocron_compliance` | `"compliant" \| "non-compliant"` against a minimal `source` + `ci` baseline |
140
+
141
+ Field definitions and derivation heuristics:
142
+ `.notes/tech-holocron-platform.spec.md` → "Custom-properties sync — field
143
+ definitions (#677)".
144
+
145
+ The four derived fields' pure computation —
146
+ `deriveProfile()`/`deriveStack()`/`deriveCapabilities()`/`deriveCompliance()`
147
+ (plus their `HolocronProfile`/`DeriveProfileInput`/`PackageJsonLike` types)
148
+ — is exported from this package's public entry point, separate from the
149
+ local-filesystem reads (`readWorkspacePackageJsons()`) that gather their
150
+ inputs here. `@theholocron/sentinel`'s `syncPropertiesFromConfig()` reuses
151
+ these functions unchanged, gathering the same inputs over the GitHub API
152
+ instead (D8 — one derivation, two input sources, not two
153
+ implementations).
154
+
155
+ `missingCapabilities(capabilities)` is `deriveCompliance()`'s sibling —
156
+ same `REQUIRED_BASELINE` table, but returns _which_ required capabilities
157
+ are absent rather than whether any are. `@theholocron/sentinel`'s
158
+ `postCheckRun()` uses it to name what's missing on the check run it
159
+ posts, instead of reporting pass/fail.
160
+
115
161
  ### Required status checks (`protection: "strict"`)
116
162
 
117
163
  `holocron setup` builds the branch-protection required-check list from the
@@ -146,6 +192,26 @@ lockfile — no coverable change) passes instead of hanging on a `codecov/*`
146
192
  required check that never posts. A re-run of `holocron setup` backfills both into
147
193
  an existing repo.
148
194
 
195
+ ### Default branch (`repo.defaultBranch`)
196
+
197
+ ```ts
198
+ export default defineConfig({
199
+ repo: { protection: "strict", defaultBranch: "alpha" },
200
+ providers: { source: "github" },
201
+ });
202
+ ```
203
+
204
+ `holocron setup` syncs GitHub's repo-level default branch (`HEAD`) — what a
205
+ fresh clone checks out, what `gh pr create`/the compare UI target by default,
206
+ and what Sentinel's `validateConfig()` reads (it only ever reads config from
207
+ the repo's default branch, never a PR ref — a deliberate security boundary).
208
+ Omit this field to leave GitHub's current setting untouched; most repos never
209
+ need it. It exists for a repo using a `main`/`alpha` prerelease-channel split
210
+ where active development happens on a non-`main` branch: set this to that
211
+ branch so Sentinel validates against what's actually being developed, then
212
+ change it back once that branch merges to `main` for a stable cut and stops
213
+ being the active branch.
214
+
149
215
  ### Git hooks
150
216
 
151
217
  ```ts
@@ -230,6 +296,23 @@ job execute the same thing — at a turbo root both are
230
296
  `turbo run test -- --coverage` (the registry's org-default flags flow through
231
297
  turbo's `--`).
232
298
 
299
+ ### `holocron deploy-on-release`
300
+
301
+ ```bash
302
+ holocron deploy-on-release [--channel <alpha|main>] [--from <commit>] [--to <commit>] [--dry-run]
303
+ ```
304
+
305
+ Deploys every workspace package whose own `holocron.config` declares
306
+ `{ name: "delivery.deploy", with: { on: "release" } }` (holocron#930), when the
307
+ release (`--channel`: its prerelease identifier, or `main`/empty for a stable
308
+ release) is on the task's `channel` (default `main`, the stable release) and changes the package or one of its
309
+ `workspace:*` dependencies between `--from` (the previous release's commit,
310
+ omitted when there is none) and `--to` (default `HEAD`). It waits for npm to
311
+ serve the release's new dependency versions, then runs `pnpm --filter <pkg>
312
+ delivery.deploy`. A package that doesn't apply is skipped; a failed deploy
313
+ exits non-zero. The shared `delivery.publish` workflow runs it as its own
314
+ `deploy` job after the release job (opt in with `deploy-on-release: true`).
315
+
233
316
  ### `holocron ci`
234
317
 
235
318
  ```bash
@@ -247,6 +330,23 @@ Order comes from the `CI_ORDER` constant in `@theholocron/astromech`
247
330
  expands into its sub-jobs (each under its own `audit / …` check context)
248
331
  unless the repo ships its own `"audit"` script.
249
332
 
333
+ ### `holocron deploy`
334
+
335
+ `holocron deploy <branch>` (a Git-linked deployment) and `holocron deploy
336
+ --files <dir>` (a directory of build output, no linked repo) both trigger a
337
+ deployment through the configured `deployment` capability, then **wait for
338
+ it to finish**. The command reports success, exit code 0, only when the
339
+ deployment reaches `ready`. A deployment that ends `error` or `cancelled`,
340
+ or is still building after 10 minutes, is a failure: the exit code is
341
+ non-zero and the output includes the provider's own reason
342
+ (`DeploymentRecord.errorMessage`, e.g. Vercel's `Command "npm install"
343
+ exited with 1`). Providers build asynchronously, so accepting a deployment
344
+ isn't the same as it going live (holocron#911).
345
+
346
+ Provider plugins support this through the `Deployment` capability's
347
+ existing `getDeployment(id)`. They should set `errorMessage` on the
348
+ returned `DeploymentRecord` whenever the provider exposes one.
349
+
250
350
  ### Lint parity
251
351
 
252
352
  The `lint` task takes an optional `linters` array — one list that drives
@@ -355,7 +455,7 @@ holocron auth set github.admin ghp_xxx # setup, secrets, environments
355
455
 
356
456
  The resolution chain per capability is:
357
457
 
358
- ```
458
+ ```text
359
459
  --token flag → HOLOCRON_<FEATURE>_TOKEN env var → keyring("github.<feature>")
360
460
  ```
361
461
 
@@ -427,6 +527,31 @@ holds the orchestration + the Holocron-specific credential resolution
427
527
  (`telemetry/resolve.ts`). See the
428
528
  [telemetry guide](https://docs.theholocron.dev/holocron/telemetry/).
429
529
 
530
+ ### ESLint bundle options
531
+
532
+ Most repos need nothing here — `@theholocron/eslint-config`'s `library()`
533
+ bundle resolves with zero committed file (Bucket A: `eslint --config
534
+ <shared path>`, no per-repo `eslint.config.ts` needed). A package with a
535
+ genuine, deliberate exception — e.g. Web Crypto globals a Node-targeted
536
+ package still needs, exempted via `library()`'s own `browserPackages`
537
+ option in that package's own `eslint.config.ts` — should also declare the
538
+ same paths in `holocron.config`'s `eslint.browserPackages`:
539
+
540
+ ```ts
541
+ export default defineConfig({
542
+ eslint: {
543
+ browserPackages: ["packages/github-client/src/app-auth"],
544
+ },
545
+ });
546
+ ```
547
+
548
+ This doesn't replace the package's own `eslint.config.ts` (local/CI linting
549
+ still resolves that file directly) — it's the signal Sentinel's centralized
550
+ static-analysis check (holocron#849/#858) reads instead, since that check
551
+ never reads a PR's own committed config files. Without it, Sentinel flags a
552
+ false-positive `eslint-plugin-n` node-builtins finding on exactly the files
553
+ the local override exists to exempt.
554
+
430
555
  ## What's in here
431
556
 
432
557
  - `src/capabilities/` — the 14 capability interfaces that providers