@theholocron/cli 5.0.0-alpha.128 → 5.0.0-alpha.129
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 +10 -10
- package/dist/cli.mjs +55 -51
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -54,11 +54,11 @@ entirely, straight to the real run, for when you already know what you want.
|
|
|
54
54
|
|
|
55
55
|
Every command is tagged with how much of a repo it needs:
|
|
56
56
|
|
|
57
|
-
| Context | Needs | Examples
|
|
58
|
-
| ------------ | -------------------------------------------------------- |
|
|
59
|
-
| `global` | the CLI binary alone | `version`, `clone`, `new`, `upgrade node`, `auth set` / `check`, `plugin create`, `skills …` |
|
|
60
|
-
| `repo-aware` | `./holocron.config`, walking up from cwd, no plugins | `run`, `ci`, `config show`, `sync-readme`
|
|
61
|
-
| `workspace` | the `@theholocron/holocron-plugin-*` packages resolvable | `doctor`, `setup`, `sync`, `secrets sync`, `deploy`
|
|
57
|
+
| Context | Needs | Examples |
|
|
58
|
+
| ------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| `global` | the CLI binary alone | `version`, `clone`, `new`, `upgrade node`, `auth set` / `check`, `plugin create`, `run lint commit-msg`, `skills …` |
|
|
60
|
+
| `repo-aware` | `./holocron.config`, walking up from cwd, no plugins | `run`, `run ci`, `config show`, `sync-readme` |
|
|
61
|
+
| `workspace` | the `@theholocron/holocron-plugin-*` packages resolvable | `doctor`, `setup`, `sync`, `secrets sync`, `deploy` |
|
|
62
62
|
|
|
63
63
|
A `workspace` command run from a bare global install (no plugins next to the
|
|
64
64
|
CLI) fails with one actionable line — install the plugins as devDependencies or
|
|
@@ -252,7 +252,7 @@ export default defineConfig({
|
|
|
252
252
|
});
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
`holocron setup` writes `.husky/pre-push` (runs `holocron ci` before every
|
|
255
|
+
`holocron setup` writes `.husky/pre-push` (runs `holocron run ci` before every
|
|
256
256
|
push) and `.husky/pre-commit` (runs `gitleaks protect --staged` + `lint-staged`
|
|
257
257
|
before every commit — scoped to staged changes, not the whole history, so a
|
|
258
258
|
past false positive can't permanently block future commits) and sets
|
|
@@ -298,7 +298,7 @@ export default defineConfig({
|
|
|
298
298
|
`@theholocron/astromech`'s `loadTasksConfig` merges it over
|
|
299
299
|
`holocron.config`'s `tasks` — **task arrays concatenate**
|
|
300
300
|
(`holocron.config` first), the dedicated file **wins on scalars**,
|
|
301
|
-
`extraRequiredChecks` concatenate. `holocron run` / `holocron ci` /
|
|
301
|
+
`extraRequiredChecks` concatenate. `holocron run` / `holocron run ci` /
|
|
302
302
|
`holocron setup` / `holocron sync` all read the merged result, so the
|
|
303
303
|
split is transparent. Useful for keeping the capability/provider config
|
|
304
304
|
and the "what this repo runs" manifest in separate files (this repo does).
|
|
@@ -343,10 +343,10 @@ delivery.deploy`. A package that doesn't apply is skipped; a failed deploy
|
|
|
343
343
|
exits non-zero. The shared `delivery.publish` workflow runs it as its own
|
|
344
344
|
`deploy` job after the release job (opt in with `deploy-on-release: true`).
|
|
345
345
|
|
|
346
|
-
### `holocron ci`
|
|
346
|
+
### `holocron run ci`
|
|
347
347
|
|
|
348
348
|
```bash
|
|
349
|
-
holocron ci [--all] [--filter <pkg>] [--dry-run]
|
|
349
|
+
holocron run ci [--all] [--filter <pkg>] [--dry-run]
|
|
350
350
|
```
|
|
351
351
|
|
|
352
352
|
Runs the merge-gating checks locally, in CI order, exiting non-zero on the
|
|
@@ -466,7 +466,7 @@ export default acmeConfig;
|
|
|
466
466
|
shape (`const { repo, workflows } = node()` + `repo.requiredChecks` +
|
|
467
467
|
`workflows:`) to the current composed-preset API (`const preset = node()` +
|
|
468
468
|
`...preset` + `tasks:` + `extraRequiredChecks:`). Mechanical transforms only —
|
|
469
|
-
review the result, then `pnpm install && holocron ci`. `--pins-only` skips
|
|
469
|
+
review the result, then `pnpm install && holocron run ci`. `--pins-only` skips
|
|
470
470
|
the config migration; `--dry-run` prints without writing.
|
|
471
471
|
|
|
472
472
|
## Auth — fine-grained tokens
|
package/dist/cli.mjs
CHANGED
|
@@ -330,9 +330,9 @@ const COMMAND_CONTEXTS = {
|
|
|
330
330
|
"skills install": "global",
|
|
331
331
|
"skills remove": "global",
|
|
332
332
|
"skills update": "global",
|
|
333
|
-
"lint commit-msg": "global",
|
|
333
|
+
"run lint commit-msg": "global",
|
|
334
334
|
run: "repo-aware",
|
|
335
|
-
ci: "repo-aware",
|
|
335
|
+
"run ci": "repo-aware",
|
|
336
336
|
"deploy-on-release": "repo-aware",
|
|
337
337
|
"config show": "repo-aware",
|
|
338
338
|
"sync-readme": "repo-aware",
|
|
@@ -4521,12 +4521,12 @@ function createIgnoreConfig$1() {
|
|
|
4521
4521
|
}
|
|
4522
4522
|
//#endregion
|
|
4523
4523
|
//#region src/templates/configs/commit-msg/commit-msg
|
|
4524
|
-
var commit_msg_default = "__HOLOCRON_SCRIPT__ lint commit-msg \"$1\"\n";
|
|
4524
|
+
var commit_msg_default = "__HOLOCRON_SCRIPT__ run lint commit-msg \"$1\"\n";
|
|
4525
4525
|
//#endregion
|
|
4526
4526
|
//#region src/templates/configs/commit-msg/create-config.ts
|
|
4527
4527
|
const { workflowHeader: workflowHeader$8 } = createHeader({ source: "packages/cli/src/templates/configs/commit-msg/create-config.ts" });
|
|
4528
4528
|
/**
|
|
4529
|
-
* `.husky/commit-msg` — lints the commit message via `holocron lint
|
|
4529
|
+
* `.husky/commit-msg` — lints the commit message via `holocron run lint
|
|
4530
4530
|
* commit-msg` (holocron#789), the real programmatic replacement for
|
|
4531
4531
|
* shelling out to `commitlint --edit`. Installed by `holocron setup` when
|
|
4532
4532
|
* hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.
|
|
@@ -4623,12 +4623,12 @@ function createConfig$3() {
|
|
|
4623
4623
|
}
|
|
4624
4624
|
//#endregion
|
|
4625
4625
|
//#region src/templates/configs/pre-push/pre-push
|
|
4626
|
-
var pre_push_default = "# Run the merge-gating checks locally before pushing — the same set CI runs.\n# Bypass once with: git push --no-verify\n\n# CI runners (semantic-release, super-linter auto-commit, bots) push without a\n# built dev environment — the hook has nothing to add there.\n[ -n \"$CI\" ] && exit 0\n\n__HOLOCRON_SCRIPT__ ci\n";
|
|
4626
|
+
var pre_push_default = "# Run the merge-gating checks locally before pushing — the same set CI runs.\n# Bypass once with: git push --no-verify\n\n# CI runners (semantic-release, super-linter auto-commit, bots) push without a\n# built dev environment — the hook has nothing to add there.\n[ -n \"$CI\" ] && exit 0\n\n__HOLOCRON_SCRIPT__ run ci\n";
|
|
4627
4627
|
//#endregion
|
|
4628
4628
|
//#region src/templates/configs/pre-push/create-config.ts
|
|
4629
4629
|
const { workflowHeader: workflowHeader$4 } = createHeader({ source: "packages/cli/src/templates/configs/pre-push/create-config.ts" });
|
|
4630
4630
|
/**
|
|
4631
|
-
* `.husky/pre-push` — runs `holocron ci` (the merge-gating checks, in CI order)
|
|
4631
|
+
* `.husky/pre-push` — runs `holocron run ci` (the merge-gating checks, in CI order)
|
|
4632
4632
|
* before every push. Installed by `holocron setup` when hooks are enabled
|
|
4633
4633
|
* (default for `protection: "strict"`). `git push --no-verify` bypasses it.
|
|
4634
4634
|
*
|
|
@@ -5647,7 +5647,7 @@ async function runSetup(input) {
|
|
|
5647
5647
|
if (hooksEnabled) {
|
|
5648
5648
|
steps.push(await runStep("source", "write .husky/pre-push", dryRun, async () => {
|
|
5649
5649
|
await source.writeRepoFile(".husky/pre-push", createConfig$2(config.holocronScript));
|
|
5650
|
-
return "runs `holocron ci` before push — bypass with `git push --no-verify`";
|
|
5650
|
+
return "runs `holocron run ci` before push — bypass with `git push --no-verify`";
|
|
5651
5651
|
}));
|
|
5652
5652
|
print(formatStep(steps[steps.length - 1]));
|
|
5653
5653
|
steps.push(await runStep("source", "write .husky/pre-commit", dryRun, async () => {
|
|
@@ -7614,7 +7614,7 @@ async function runSyncGithub(input) {
|
|
|
7614
7614
|
* This applies the mechanical transforms and flags anything that needs a
|
|
7615
7615
|
* human eye.
|
|
7616
7616
|
*
|
|
7617
|
-
* After running, `pnpm install && holocron ci`.
|
|
7617
|
+
* After running, `pnpm install && holocron run ci`.
|
|
7618
7618
|
*/
|
|
7619
7619
|
const FETCH_TIMEOUT_MS$1 = 4e3;
|
|
7620
7620
|
/** Resolve a package's `latest` dist-tag from the npm registry. */
|
|
@@ -7681,7 +7681,7 @@ function isLegacyConfig(content) {
|
|
|
7681
7681
|
}
|
|
7682
7682
|
/**
|
|
7683
7683
|
* Apply the mechanical 7.x → 8.x transforms to a `holocron.config.ts`. Best
|
|
7684
|
-
* effort — the result should always be reviewed and run through `holocron ci`.
|
|
7684
|
+
* effort — the result should always be reviewed and run through `holocron run ci`.
|
|
7685
7685
|
*/
|
|
7686
7686
|
function migrateConfig(content) {
|
|
7687
7687
|
const transforms = [];
|
|
@@ -7807,7 +7807,7 @@ async function runUpgradeDeps(input = {}) {
|
|
|
7807
7807
|
print("");
|
|
7808
7808
|
if (bumps.length === 0 && !configMigrated) print("Nothing to do — already up to date.");
|
|
7809
7809
|
else {
|
|
7810
|
-
print(`Next: ${dryRun ? "run without --dry-run, then " : ""}\`pnpm install && holocron ci\``);
|
|
7810
|
+
print(`Next: ${dryRun ? "run without --dry-run, then " : ""}\`pnpm install && holocron run ci\``);
|
|
7811
7811
|
if (configMigrated) print(" review holocron.config.ts before committing.");
|
|
7812
7812
|
}
|
|
7813
7813
|
const status = dryRun ? "dry-run" : "ok";
|
|
@@ -8050,7 +8050,7 @@ async function lintCommitMessage(message, loaded) {
|
|
|
8050
8050
|
//#endregion
|
|
8051
8051
|
//#region src/commit-lint/lint-commit-msg-file.ts
|
|
8052
8052
|
/**
|
|
8053
|
-
* `holocron lint commit-msg <file>` — a real programmatic replacement for
|
|
8053
|
+
* `holocron run lint commit-msg <file>` — a real programmatic replacement for
|
|
8054
8054
|
* shelling out to `commitlint --edit "$1"` from `.husky/commit-msg`
|
|
8055
8055
|
* (holocron#789). Matches that CLI's own contract exactly: `file` is a
|
|
8056
8056
|
* path to the commit message being written (the arg git's `commit-msg`
|
|
@@ -8194,9 +8194,10 @@ const numeric = (value) => /^\d+$/.test(value) ? true : "enter a number";
|
|
|
8194
8194
|
* The full command surface, hand-maintained in parallel with `cli.ts`'s
|
|
8195
8195
|
* yargs registrations (this module does not introspect yargs at runtime).
|
|
8196
8196
|
* `run <task>` is deliberately excluded — it's CI/scripting-oriented, and an
|
|
8197
|
-
* interactive prompt in front of it would work against that. `
|
|
8198
|
-
*
|
|
8199
|
-
*
|
|
8197
|
+
* interactive prompt in front of it would work against that. (`run ci` is a
|
|
8198
|
+
* concrete, prompt-free entry, so it stays.) `run lint commit-msg <file>` is
|
|
8199
|
+
* excluded for the same reason: it's invoked exclusively from
|
|
8200
|
+
* `.husky/commit-msg "$1"`, never typed by a human.
|
|
8200
8201
|
*/
|
|
8201
8202
|
const COMMAND_REGISTRY = [
|
|
8202
8203
|
{
|
|
@@ -8287,7 +8288,7 @@ const COMMAND_REGISTRY = [
|
|
|
8287
8288
|
supportsDryRun: true
|
|
8288
8289
|
},
|
|
8289
8290
|
{
|
|
8290
|
-
name: "ci",
|
|
8291
|
+
name: "run ci",
|
|
8291
8292
|
description: "Run the merge-gating checks locally, in CI order — 'will CI pass?'",
|
|
8292
8293
|
positionals: [],
|
|
8293
8294
|
supportsDryRun: true
|
|
@@ -9165,7 +9166,7 @@ try {
|
|
|
9165
9166
|
describe: "Repo coords (\"owner/name\"). Defaults to plugin-specific resolution."
|
|
9166
9167
|
}).option("hooks", {
|
|
9167
9168
|
type: "boolean",
|
|
9168
|
-
describe: "Install git hooks (.husky/pre-push → holocron ci). Default: on for protection:'strict'. --no-hooks to skip."
|
|
9169
|
+
describe: "Install git hooks (.husky/pre-push → holocron run ci). Default: on for protection:'strict'. --no-hooks to skip."
|
|
9169
9170
|
}), async (argv) => {
|
|
9170
9171
|
const tokens = tokenContext(argv.token);
|
|
9171
9172
|
if (!tokens) return;
|
|
@@ -9454,13 +9455,13 @@ try {
|
|
|
9454
9455
|
},
|
|
9455
9456
|
...argv.steps && argv.steps.length > 0 ? { steps: argv.steps } : {}
|
|
9456
9457
|
})).summary.fail > 0) process.exitCode = 1;
|
|
9457
|
-
}).command("run <task> [job] [passthrough..]", "Run a task locally (test, typecheck, lint, build, audit) — figures out turbo / the tool / the package manager", (y) => y.positional("task", {
|
|
9458
|
+
}).command("run <task> [job] [passthrough..]", "Run a task locally (test, typecheck, lint, build, audit) — figures out turbo / the tool / the package manager. `run ci` runs every merge-gating check; `run lint commit-msg <file>` lints a commit message.", (y) => y.positional("task", {
|
|
9458
9459
|
type: "string",
|
|
9459
9460
|
demandOption: true,
|
|
9460
|
-
describe: "Task name (test, typecheck, lint, build, audit). See `holocron run --help`."
|
|
9461
|
+
describe: "Task name (test, typecheck, lint, build, audit, or `ci` for the merge-gating suite). See `holocron run --help`."
|
|
9461
9462
|
}).positional("job", {
|
|
9462
9463
|
type: "string",
|
|
9463
|
-
describe: "Sub-job within the task (e.g. `holocron run audit performance`). Omit to run every job.
|
|
9464
|
+
describe: "Sub-job within the task (e.g. `holocron run audit performance`, `holocron run lint commit-msg <file>`). Omit to run every job."
|
|
9464
9465
|
}).positional("passthrough", {
|
|
9465
9466
|
type: "string",
|
|
9466
9467
|
array: true,
|
|
@@ -9469,11 +9470,43 @@ try {
|
|
|
9469
9470
|
type: "boolean",
|
|
9470
9471
|
default: false,
|
|
9471
9472
|
describe: "Fail (exit 1) if this repo has no such task, instead of skipping."
|
|
9473
|
+
}).option("all", {
|
|
9474
|
+
type: "boolean",
|
|
9475
|
+
default: false,
|
|
9476
|
+
describe: "With `run ci`: run every `ci: true` task, not just the required ones."
|
|
9472
9477
|
}).option("filter", {
|
|
9473
9478
|
type: "string",
|
|
9474
9479
|
describe: "turbo --filter=<pkg> passthrough (monorepo)."
|
|
9475
9480
|
}), async (argv) => {
|
|
9476
|
-
const { logger } = buildCliLogger(argv, { command: "run" });
|
|
9481
|
+
const { logger } = buildCliLogger(argv, { command: argv.task === "ci" ? "run ci" : argv.task === "lint" && argv.job === "commit-msg" ? "run lint commit-msg" : "run" });
|
|
9482
|
+
const passthrough = [...argv.passthrough ?? [], ...argv["--"] ?? []];
|
|
9483
|
+
if (argv.task === "lint" && argv.job === "commit-msg") {
|
|
9484
|
+
const file = passthrough[0];
|
|
9485
|
+
if (!file) {
|
|
9486
|
+
reportError("run lint commit-msg: missing <file> (the commit message file git passes as $1).");
|
|
9487
|
+
process.exitCode = 1;
|
|
9488
|
+
return;
|
|
9489
|
+
}
|
|
9490
|
+
const result = await lintCommitMsgFile(file, argv.cwd);
|
|
9491
|
+
if (!result.valid) {
|
|
9492
|
+
for (const violation of result.violations) console.error(`✖ ${violation.rule}: ${violation.message}`);
|
|
9493
|
+
process.exitCode = 1;
|
|
9494
|
+
}
|
|
9495
|
+
return;
|
|
9496
|
+
}
|
|
9497
|
+
if (argv.task === "ci") {
|
|
9498
|
+
const ciConfig = await loadTasksConfig(argv.cwd).catch(() => void 0);
|
|
9499
|
+
if (createAstromech({
|
|
9500
|
+
cwd: argv.cwd,
|
|
9501
|
+
logger,
|
|
9502
|
+
config: ciConfig
|
|
9503
|
+
}).ci({
|
|
9504
|
+
dryRun: argv.dryRun,
|
|
9505
|
+
scope: argv.all ? "all" : "required",
|
|
9506
|
+
...argv.filter ? { filter: argv.filter } : {}
|
|
9507
|
+
}).status === "fail") process.exitCode = 1;
|
|
9508
|
+
return;
|
|
9509
|
+
}
|
|
9477
9510
|
const config = await loadTasksConfig(argv.cwd).catch(() => void 0);
|
|
9478
9511
|
const report = createAstromech({
|
|
9479
9512
|
cwd: argv.cwd,
|
|
@@ -9481,31 +9514,12 @@ try {
|
|
|
9481
9514
|
config
|
|
9482
9515
|
}).run(argv.task, {
|
|
9483
9516
|
...argv.job !== void 0 ? { job: argv.job } : {},
|
|
9484
|
-
passthrough
|
|
9517
|
+
passthrough,
|
|
9485
9518
|
dryRun: argv.dryRun,
|
|
9486
9519
|
required: argv.required,
|
|
9487
9520
|
...argv.filter ? { filter: argv.filter } : {}
|
|
9488
9521
|
});
|
|
9489
9522
|
if (report.status === "fail" || report.status === "unknown") process.exitCode = 1;
|
|
9490
|
-
}).command("ci", "Run the merge-gating checks locally, in CI order — 'will CI pass?'", (y) => y.option("all", {
|
|
9491
|
-
type: "boolean",
|
|
9492
|
-
default: false,
|
|
9493
|
-
describe: "Run every `ci: true` task, not just the required ones."
|
|
9494
|
-
}).option("filter", {
|
|
9495
|
-
type: "string",
|
|
9496
|
-
describe: "turbo --filter=<pkg> passthrough (monorepo)."
|
|
9497
|
-
}), async (argv) => {
|
|
9498
|
-
const { logger } = buildCliLogger(argv, { command: "ci" });
|
|
9499
|
-
const config = await loadTasksConfig(argv.cwd).catch(() => void 0);
|
|
9500
|
-
if (createAstromech({
|
|
9501
|
-
cwd: argv.cwd,
|
|
9502
|
-
logger,
|
|
9503
|
-
config
|
|
9504
|
-
}).ci({
|
|
9505
|
-
dryRun: argv.dryRun,
|
|
9506
|
-
scope: argv.all ? "all" : "required",
|
|
9507
|
-
...argv.filter ? { filter: argv.filter } : {}
|
|
9508
|
-
}).status === "fail") process.exitCode = 1;
|
|
9509
9523
|
}).command("deploy-on-release", "Deploy every workspace package whose delivery.deploy task is `on: release` — run by the delivery.publish workflow's deploy job", (y) => y.option("channel", {
|
|
9510
9524
|
type: "string",
|
|
9511
9525
|
default: "",
|
|
@@ -9525,17 +9539,7 @@ try {
|
|
|
9525
9539
|
dryRun: argv.dryRun,
|
|
9526
9540
|
print: (line) => console.log(line)
|
|
9527
9541
|
})).status === "fail") process.exitCode = 1;
|
|
9528
|
-
}).command("
|
|
9529
|
-
type: "string",
|
|
9530
|
-
demandOption: true,
|
|
9531
|
-
describe: "Path to the commit message file (git's commit-msg hook passes this as $1)."
|
|
9532
|
-
}), async (argv) => {
|
|
9533
|
-
const result = await lintCommitMsgFile(argv.file, argv.cwd);
|
|
9534
|
-
if (!result.valid) {
|
|
9535
|
-
for (const violation of result.violations) console.error(`✖ ${violation.rule}: ${violation.message}`);
|
|
9536
|
-
process.exitCode = 1;
|
|
9537
|
-
}
|
|
9538
|
-
}), () => {}).command("sync-github", "Sync workflow templates and composite actions to theholocron/.github", (y) => y.option("repo", {
|
|
9542
|
+
}).command("sync-github", "Sync workflow templates and composite actions to theholocron/.github", (y) => y.option("repo", {
|
|
9539
9543
|
type: "string",
|
|
9540
9544
|
default: "theholocron/.github",
|
|
9541
9545
|
describe: "Target org/repo (default: theholocron/.github)"
|