@theholocron/cli 3.65.0 → 4.0.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.
package/README.md CHANGED
@@ -209,13 +209,15 @@ all three. See the [telemetry guide](https://docs.theholocron.dev/holocron/telem
209
209
  implement
210
210
  - `src/config.ts` — config schema, `defineConfig`, `resolveConfig`,
211
211
  `CapabilityConfigPackage`
212
- - `src/load-config.ts` — `loadConfig` — reads JSON/JS/TS config files
212
+ - `src/config/load-config.ts` — `loadConfig` — reads `holocron.config.*`
213
+ (file discovery via [`@theholocron/datapad`](../datapad))
213
214
  - `src/define-config.ts` — `defineConfig` typed pass-through
214
215
  - `src/logger.ts` — CLI-side `@theholocron/logger` wiring (`buildCliLogger`,
215
216
  `resolveLogLevel`)
216
217
  - `src/loader.ts` — `PluginLoader` — dynamic-imports plugins, resolves
217
218
  capability config packages, builds the capability registry
218
- - `src/cli.ts` — yargs entry, dispatches subcommands
219
+ - `src/cli.ts` — yargs entry, dispatches subcommands. `holocron run` is
220
+ delegated to [`@theholocron/astromech`](../astromech) (`createAstromech`).
219
221
  - `src/commands/` — `setup`, `sync`, `doctor`, `deploy`, `secret set`,
220
222
  `secrets sync`, `npm publish-initial`, `sync-github`, `upgrade node`,
221
223
  `plugin create`, `auth`
package/dist/cli.mjs CHANGED
@@ -3,6 +3,7 @@ import { createRequire } from "node:module";
3
3
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
4
4
  import path, { basename, dirname, join, relative, resolve } from "node:path";
5
5
  import { checkbox, input, select } from "@inquirer/prompts";
6
+ import { createAstromech } from "@theholocron/astromech";
6
7
  import yargs from "yargs";
7
8
  import { hideBin } from "yargs/helpers";
8
9
  import { AuthError, ProviderApiError, ProviderApiError as ProviderApiError$1, createRestClient } from "@theholocron/http-client";
@@ -278,7 +279,7 @@ function resolveConfig(raw) {
278
279
  org: raw.org,
279
280
  domain: raw.domain,
280
281
  repo: raw.repo,
281
- workflows: raw.workflows,
282
+ tasks: raw.tasks,
282
283
  providers,
283
284
  apps: raw.apps ?? [],
284
285
  doctor: raw.doctor ?? {},
@@ -4592,7 +4593,7 @@ async function runSetup(input) {
4592
4593
  }, { skipCodes: SECURITY_SKIP_CODES[method] }));
4593
4594
  print(formatStep(steps[steps.length - 1]));
4594
4595
  }
4595
- const usesAdvancedCodeQL = (config.workflows ?? []).map((e) => typeof e === "string" ? e : e.name).includes("codeql");
4596
+ const usesAdvancedCodeQL = (config.tasks ?? []).map((e) => typeof e === "string" ? e : e.name).includes("codeql");
4596
4597
  steps.push(await runStep("source", usesAdvancedCodeQL ? "disableDefaultCodeScanning" : "enableCodeScanning", dryRun, async () => {
4597
4598
  if (usesAdvancedCodeQL) await source.disableDefaultCodeScanning();
4598
4599
  else return await source.enableCodeScanning();
@@ -4603,7 +4604,7 @@ async function runSetup(input) {
4603
4604
  await source.updateRepoSettings(BALANCED_REPO_SETTINGS);
4604
4605
  }));
4605
4606
  print(formatStep(steps[steps.length - 1]));
4606
- const configuredWorkflowNames = [...new Set((config.workflows ?? []).map((entry) => typeof entry === "string" ? entry : entry.name))];
4607
+ const configuredWorkflowNames = [...new Set((config.tasks ?? []).map((entry) => typeof entry === "string" ? entry : entry.name))];
4607
4608
  const requiredChecks = effectivePreset === "strict" ? [
4608
4609
  "DCO",
4609
4610
  ...configuredWorkflowNames.flatMap((name) => {
@@ -4616,11 +4617,11 @@ async function runSetup(input) {
4616
4617
  print(formatStep(steps[steps.length - 1]));
4617
4618
  }
4618
4619
  }
4619
- const workflows = config.workflows;
4620
- if (loader.has("source") && workflows && workflows.length > 0) {
4620
+ const tasks = config.tasks;
4621
+ if (loader.has("source") && tasks && tasks.length > 0) {
4621
4622
  const source = loader.get("source");
4622
4623
  print(style.step("workflows"));
4623
- for (const entry of workflows) {
4624
+ for (const entry of tasks) {
4624
4625
  const name = typeof entry === "string" ? entry : entry.name;
4625
4626
  const rawWith = typeof entry === "object" ? entry.with : void 0;
4626
4627
  const normalized = rawWith ? normalizeWorkflowWith(rawWith) : void 0;
@@ -4664,7 +4665,7 @@ async function runSetup(input) {
4664
4665
  print(formatStep(steps[steps.length - 1]));
4665
4666
  }
4666
4667
  }
4667
- if (loader.has("source") && (config.workflows ?? []).map((e) => typeof e === "string" ? e : e.name).includes("bookkeeping")) {
4668
+ if (loader.has("source") && (config.tasks ?? []).map((e) => typeof e === "string" ? e : e.name).includes("bookkeeping")) {
4668
4669
  const source = loader.get("source");
4669
4670
  steps.push(await runStep("source", "write .github/labeler.yml", dryRun, async () => {
4670
4671
  await source.writeRepoFile(".github/labeler.yml", `${workflowHeader$2()}${labeler_default}`);
@@ -4713,7 +4714,7 @@ async function runSetup(input) {
4713
4714
  }));
4714
4715
  print(formatStep(steps[steps.length - 1]));
4715
4716
  {
4716
- const hasTestWorkflow = (config.workflows ?? []).map((e) => typeof e === "string" ? e : e.name).includes("test");
4717
+ const hasTestWorkflow = (config.tasks ?? []).map((e) => typeof e === "string" ? e : e.name).includes("test");
4717
4718
  const packages = await readWorkspacePackages(input.context.repoRoot);
4718
4719
  const existing = await readFile(join(input.context.repoRoot, "codecov.yml"), "utf8").catch(() => null);
4719
4720
  if (!hasTestWorkflow && existing == null) steps.push({
@@ -4867,7 +4868,7 @@ async function runSetup(input) {
4867
4868
  if (loader.has("deployment")) {
4868
4869
  const deploy = loader.get("deployment");
4869
4870
  print(style.step("deployment"));
4870
- const deployEntry = (config.workflows ?? []).map((e) => typeof e === "string" ? { name: e } : e).find((e) => e.name === "deploy");
4871
+ const deployEntry = (config.tasks ?? []).map((e) => typeof e === "string" ? { name: e } : e).find((e) => e.name === "deploy");
4871
4872
  const previewCfg = deployEntry?.with ? extractPreviewConfig(deployEntry.with, {
4872
4873
  org: config.org,
4873
4874
  domain: config.domain
@@ -5817,16 +5818,16 @@ async function runSync(input) {
5817
5818
  print(formatSyncStep(steps[steps.length - 1]));
5818
5819
  }
5819
5820
  if (stepName === "workflows") {
5820
- const workflowEntries = config.workflows ?? [];
5821
- if (workflowEntries.length === 0) {
5821
+ const taskEntries = config.tasks ?? [];
5822
+ if (taskEntries.length === 0) {
5822
5823
  steps.push({
5823
5824
  capability: "local",
5824
5825
  step: "sync workflows",
5825
5826
  status: "skip",
5826
- message: "no workflows configured"
5827
+ message: "no tasks configured"
5827
5828
  });
5828
5829
  print(formatSyncStep(steps[steps.length - 1]));
5829
- } else for (const entry of workflowEntries) {
5830
+ } else for (const entry of taskEntries) {
5830
5831
  const name = typeof entry === "string" ? entry : entry.name;
5831
5832
  const rawWith = typeof entry === "object" ? entry.with : void 0;
5832
5833
  const normalized = rawWith ? normalizeWorkflowWith(rawWith) : void 0;
@@ -7228,6 +7229,29 @@ try {
7228
7229
  },
7229
7230
  ...argv.steps && argv.steps.length > 0 ? { steps: argv.steps } : {}
7230
7231
  })).summary.fail > 0) process.exitCode = 1;
7232
+ }).command("run <task> [passthrough..]", "Run a task locally (test, typecheck, lint, build) — figures out turbo / the tool / the package manager", (y) => y.positional("task", {
7233
+ type: "string",
7234
+ demandOption: true,
7235
+ describe: "Task name (test, typecheck, lint, build). See `holocron run --help`."
7236
+ }).positional("passthrough", {
7237
+ type: "string",
7238
+ array: true,
7239
+ describe: "Args forwarded to the tool — put them after `--`."
7240
+ }).option("required", {
7241
+ type: "boolean",
7242
+ default: false,
7243
+ describe: "Fail (exit 1) if this repo has no such task, instead of skipping."
7244
+ }), (argv) => {
7245
+ const { logger } = buildCliLogger(argv, { command: "run" });
7246
+ const report = createAstromech({
7247
+ cwd: argv.cwd,
7248
+ logger
7249
+ }).run(argv.task, {
7250
+ passthrough: argv.passthrough ?? [],
7251
+ dryRun: argv.dryRun,
7252
+ required: argv.required
7253
+ });
7254
+ if (report.status === "fail" || report.status === "unknown") process.exitCode = 1;
7231
7255
  }).command("sync-github", "Sync workflow templates and composite actions to theholocron/.github", (y) => y.option("repo", {
7232
7256
  type: "string",
7233
7257
  default: "theholocron/.github",