@theholocron/cli 4.4.0 → 4.5.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
@@ -93,6 +93,21 @@ Writes `"holocron": "<holocronScript ?? 'holocron'>"` plus one
93
93
  `"<task>": "holocron run <task>"` per runnable task. `syncScripts: false`
94
94
  opts out entirely.
95
95
 
96
+ ### Lint parity
97
+
98
+ The `lint` task takes an optional `linters` array — one list that drives
99
+ **both** the CI `lint` job (super-linter's `VALIDATE_*` env, baked into the
100
+ generated `.github/workflows/lint.yml` thin caller as a `super-linter-env`
101
+ input) **and** `holocron run lint` locally. Omitted → auto-detected from the
102
+ config files present plus the org always-on set.
103
+
104
+ ```ts
105
+ export default defineConfig({
106
+ tasks: [{ name: "lint", linters: ["eslint", "prettier", "yamllint", "actionlint", "gitleaks"] }],
107
+ providers: { source: "github" },
108
+ });
109
+ ```
110
+
96
111
  ### Skills installer
97
112
 
98
113
  `holocron setup` can install shared skills from `@theholocron/skills` into the local repo:
package/dist/cli.mjs CHANGED
@@ -3,7 +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 { KNOWN_WORKFLOWS, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, createAstromech, deriveDeployPaths, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, normalizeWorkflowWith } from "@theholocron/astromech";
6
+ import { KNOWN_WORKFLOWS, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, createAstromech, deriveDeployPaths, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, lintThinCallerWith, normalizeWorkflowWith } from "@theholocron/astromech";
7
7
  import yargs from "yargs";
8
8
  import { hideBin } from "yargs/helpers";
9
9
  import { AuthError, ProviderApiError, ProviderApiError as ProviderApiError$1, createRestClient } from "@theholocron/http-client";
@@ -4371,10 +4371,21 @@ async function runSetup(input) {
4371
4371
  const name = typeof entry === "string" ? entry : entry.name;
4372
4372
  const rawWith = typeof entry === "object" ? entry.with : void 0;
4373
4373
  const normalized = rawWith ? normalizeWorkflowWith(rawWith) : void 0;
4374
- const withOverrides = name === "lint" ? {
4375
- "enable-auto-commit": true,
4376
- ...normalized ?? {}
4377
- } : normalized;
4374
+ let withOverrides = normalized;
4375
+ let comments;
4376
+ if (name === "lint") {
4377
+ let rootFiles = [];
4378
+ try {
4379
+ rootFiles = readdirSync(input.context.repoRoot);
4380
+ } catch {}
4381
+ const lint = lintThinCallerWith({
4382
+ explicit: typeof entry === "object" ? entry.linters : void 0,
4383
+ rootFiles,
4384
+ extra: normalized
4385
+ });
4386
+ withOverrides = lint.withOverrides;
4387
+ comments = lint.comments;
4388
+ }
4378
4389
  const additionalPaths = (typeof entry === "object" ? entry.paths : void 0) ?? (name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
4379
4390
  if (name === "test" && withOverrides) {
4380
4391
  const runUnit = withOverrides["run-unit"];
@@ -4406,7 +4417,7 @@ async function runSetup(input) {
4406
4417
  }
4407
4418
  }
4408
4419
  steps.push(await runStep("source", `write workflow ${name}`, dryRun, async () => {
4409
- await source.writeWorkflowFile(`${name}.yml`, `${workflowHeader$2()}${generateThinCallerContent(name, withOverrides, additionalPaths)}`);
4420
+ await source.writeWorkflowFile(`${name}.yml`, `${workflowHeader$2()}${generateThinCallerContent(name, withOverrides, additionalPaths, void 0, comments)}`);
4410
4421
  }));
4411
4422
  print(formatStep(steps[steps.length - 1]));
4412
4423
  }
@@ -5580,10 +5591,17 @@ async function runSync(input) {
5580
5591
  const name = typeof entry === "string" ? entry : entry.name;
5581
5592
  const rawWith = typeof entry === "object" ? entry.with : void 0;
5582
5593
  const normalized = rawWith ? normalizeWorkflowWith(rawWith) : void 0;
5583
- const withOverrides = name === "lint" ? {
5584
- "enable-auto-commit": true,
5585
- ...normalized ?? {}
5586
- } : normalized;
5594
+ let withOverrides = normalized;
5595
+ let comments;
5596
+ if (name === "lint") {
5597
+ const lint = lintThinCallerWith({
5598
+ explicit: typeof entry === "object" ? entry.linters : void 0,
5599
+ rootFiles: safeReaddir(input.context.repoRoot),
5600
+ extra: normalized
5601
+ });
5602
+ withOverrides = lint.withOverrides;
5603
+ comments = lint.comments;
5604
+ }
5587
5605
  const additionalPaths = (typeof entry === "object" ? entry.paths : void 0) ?? (name === "deploy" && rawWith ? deriveDeployPaths(rawWith) : void 0);
5588
5606
  if (!KNOWN_WORKFLOWS.has(name)) {
5589
5607
  steps.push({
@@ -5610,7 +5628,7 @@ async function runSync(input) {
5610
5628
  }
5611
5629
  }
5612
5630
  steps.push(await runSyncStep("local", `sync workflow ${name}`, dryRun, async () => {
5613
- const content = `${workflowHeader$1()}${generateThinCallerContent(name, withOverrides, additionalPaths)}`;
5631
+ const content = `${workflowHeader$1()}${generateThinCallerContent(name, withOverrides, additionalPaths, void 0, comments)}`;
5614
5632
  await writeWorkflowFile(input.context.repoRoot, `${name}.yml`, content);
5615
5633
  }));
5616
5634
  print(formatSyncStep(steps[steps.length - 1]));
@@ -5703,6 +5721,14 @@ function formatSyncStep(step) {
5703
5721
  const detail = step.message ? ` (${step.message})` : "";
5704
5722
  return ` ${icon} ${step.step}${detail}`;
5705
5723
  }
5724
+ /** Repo-root filenames for linter auto-detection; `[]` when the dir is unreadable. */
5725
+ function safeReaddir(dir) {
5726
+ try {
5727
+ return readdirSync(dir);
5728
+ } catch {
5729
+ return [];
5730
+ }
5731
+ }
5706
5732
  async function writePackageJsonField(repoRoot, field, value) {
5707
5733
  const pkgPath = join(repoRoot, "package.json");
5708
5734
  let content;