@theholocron/cli 5.0.0-alpha.17 → 5.0.0-alpha.171
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 +224 -53
- package/dist/cli.mjs +3402 -1776
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +221 -49
- package/dist/index.mjs +141 -49
- package/dist/plugin/capabilities.d.mts +208 -51
- package/dist/plugin/capabilities.mjs +2 -1
- package/package.json +19 -13
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
|
|
21
|
-
missing a required positional (`holocron deploy`, `holocron
|
|
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? ›
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
?
|
|
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` |
|
|
45
|
-
| `repo-aware` | `./holocron.config
|
|
46
|
-
| `workspace` | the `@theholocron/holocron-plugin-*` packages resolvable | `doctor`, `setup`, `sync`, `secrets
|
|
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
|
|
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.
|
|
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 --
|
|
409
|
-
holocron doctor --
|
|
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): `--
|
|
414
|
-
`HOLOCRON_LOG_LEVEL` → `log.level` in `holocron.config` →
|
|
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.
|
|
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
|
-
(`
|
|
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
|
|
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
|
|
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`,
|
|
481
|
-
`
|
|
482
|
-
`
|
|
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
|