@theholocron/astromech 5.0.0-alpha.152 → 5.0.0-alpha.153

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
@@ -230,3 +230,19 @@ Automated via semantic-release. See [CHANGELOG.md](../../CHANGELOG.md).
230
230
  ## Documentation
231
231
 
232
232
  <https://theholocron.github.io/holocron/>
233
+
234
+ ## Lint — `@theholocron/astromech/lint`
235
+
236
+ The lint tools' own data and checks, in a subpath so the runner and the
237
+ config surface don't pull `@commitlint/*` in:
238
+
239
+ - `lintCommitMsgFile(file, cwd)` / `lintCommitMessage(message, config)` —
240
+ what `holocron run lint commit-msg <file>` (the `commit-msg` hook) runs.
241
+ - `ALEX_CONFIG`, `ALEX_IGNORE_PATTERNS`, `PRETTIER_IGNORE_PATTERNS`,
242
+ `EDITORCONFIG_CHECKER_EXCLUDE` and `isEditorConfigExcluded(path)` — read
243
+ from the same templates `holocron repo setup` writes, so Sentinel's central
244
+ checks skip exactly what each repo's own CI skips.
245
+
246
+ The root entry also exports the config-file generators `holocron repo setup`
247
+ writes (`createEditorconfig`, `createAlexrc`, `createPrePush`, …) and
248
+ `createHeader`.
@@ -0,0 +1,41 @@
1
+ //#region src/templates/configs/alexjs/alexrc.json
2
+ var alexrc_default = { allow: [
3
+ "dead",
4
+ "execute",
5
+ "execution",
6
+ "executes",
7
+ "failure",
8
+ "failures",
9
+ "hook",
10
+ "hooks",
11
+ "husky",
12
+ "period"
13
+ ] };
14
+ //#endregion
15
+ //#region src/templates/configs/editorconfig-checker/editorconfig-checker.json
16
+ var editorconfig_checker_default = {
17
+ Verbose: false,
18
+ Format: "",
19
+ Debug: false,
20
+ IgnoreDefaults: false,
21
+ SpacesAfterTabs: false,
22
+ NoColor: false,
23
+ Exclude: [
24
+ "(^|.+/)LICENSE$",
25
+ "^public/.*",
26
+ "\\.md$",
27
+ "\\.mdx$"
28
+ ],
29
+ AllowedContentTypes: [],
30
+ PassedFiles: [],
31
+ Disable: {
32
+ "EndOfLine": false,
33
+ "Indentation": false,
34
+ "InsertFinalNewline": false,
35
+ "TrimTrailingWhitespace": false,
36
+ "IndentSize": false,
37
+ "MaxLineLength": false
38
+ }
39
+ };
40
+ //#endregion
41
+ export { alexrc_default as n, editorconfig_checker_default as t };
package/dist/index.d.mts CHANGED
@@ -637,4 +637,139 @@ declare function matchNamespace(config: TasksConfig, namespace: string): string[
637
637
  //#region src/tasks/run/run.d.ts
638
638
  declare function runTask(input: RunTaskInput): RunTaskReport;
639
639
  //#endregion
640
- export { type Astromech, type AstromechOptions, CI_ORDER, type CiJobReport, type CiOptions, type CiReport, type DeployOnReleaseOptions, type DeployOnReleaseReport, type DeployOnReleaseResult, type ExecFn, type GroupJobReport, type GroupOptions, type GroupReport, type JobDef, KNOWN_TASKS, KNOWN_WORKFLOWS, type LocalRunner, type OrgContext, type PreviewConfig, REUSABLE_ACTIONS, REUSABLE_WORKFLOWS, type RunLogger, type RunOptions, type RunTaskInput, type RunTaskReport, TASKS, type TaskDef, type TsconfigOptions, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, WORKFLOW_TEMPLATE_PROPERTIES, type WorkspacePackage, codecovComponentBlock, codecovConfig, createAstromech, createCodecovConfig, createTsconfig, deployOnRelease, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, matchNamespace, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, reusableTemplates, runCi, runGroup, runTask };
640
+ //#region src/templates/configs/alexjs/create-config.d.ts
641
+ declare function createRcConfig(): string;
642
+ declare function createIgnoreConfig(): string;
643
+ //#endregion
644
+ //#region src/templates/configs/commit-msg/create-config.d.ts
645
+ /**
646
+ * `.husky/commit-msg` — lints the commit message via `holocron run lint
647
+ * commit-msg` (holocron#789), the real programmatic replacement for
648
+ * shelling out to `commitlint --edit`. Installed by `holocron repo setup` when
649
+ * hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.
650
+ *
651
+ * @param holocronScript - the command that invokes the CLI. Defaults to
652
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
653
+ */
654
+ declare function createConfig(holocronScript?: string): string;
655
+ //#endregion
656
+ //#region src/templates/configs/dependabot/create-config.d.ts
657
+ declare function createConfig$1(): string;
658
+ //#endregion
659
+ //#region src/templates/configs/devmoji/create-config.d.ts
660
+ declare function createConfig$2(): string;
661
+ //#endregion
662
+ //#region src/templates/configs/editorconfig/create-config.d.ts
663
+ declare function createConfig$3(): string;
664
+ //#endregion
665
+ //#region src/templates/configs/editorconfig-checker/create-config.d.ts
666
+ /**
667
+ * The generated `.editorconfig-checker.json`.
668
+ *
669
+ * Deliberately carries no `"Version"` key: editorconfig-checker treats it as a
670
+ * hard gate and exits non-zero the moment the running binary's version differs
671
+ * — which it does the instant a contributor's local install (Homebrew tracks
672
+ * latest) drifts from the version super-linter bundles in CI, breaking
673
+ * `holocron run lint` / the pre-push hook for everyone (#618). The config
674
+ * options here (`Exclude`, `Disable`) are stable across releases, so pinning
675
+ * buys nothing.
676
+ */
677
+ declare function createConfig$4(): string;
678
+ //#endregion
679
+ //#region src/templates/configs/labeler/create-config.d.ts
680
+ declare function createConfig$5(): string;
681
+ //#endregion
682
+ //#region src/templates/configs/pre-commit/create-config.d.ts
683
+ /**
684
+ * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and
685
+ * lint-staged before every commit. Installed by `holocron repo setup` when hooks
686
+ * are enabled (default for `protection: "strict"`). `git commit --no-verify`
687
+ * bypasses it.
688
+ *
689
+ * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter
690
+ * scans the entire commit history on every invocation, so once any false
691
+ * positive lands in a past commit — a fake test token, an example key in a
692
+ * doc — every future commit is permanently blocked, regardless of what's
693
+ * actually staged.
694
+ */
695
+ declare function createConfig$6(): string;
696
+ //#endregion
697
+ //#region src/templates/configs/pre-push/create-config.d.ts
698
+ /**
699
+ * `.husky/pre-push` — runs `holocron run ci` (the merge-gating checks, in CI order)
700
+ * before every push. Installed by `holocron repo setup` when hooks are enabled
701
+ * (default for `protection: "strict"`). `git push --no-verify` bypasses it.
702
+ *
703
+ * @param holocronScript - the command that invokes the CLI. Defaults to
704
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
705
+ */
706
+ declare function createConfig$7(holocronScript?: string): string;
707
+ //#endregion
708
+ //#region src/templates/configs/prepare-commit-msg/create-config.d.ts
709
+ declare function createConfig$8(): string;
710
+ //#endregion
711
+ //#region src/templates/configs/yamllint/create-config.d.ts
712
+ declare function createConfig$9(): string;
713
+ declare function createIgnoreConfig$1(): string;
714
+ //#endregion
715
+ //#region src/utils/create-header.type.d.ts
716
+ /** Comment style produced by workflowHeader. */
717
+ type WorkflowHeaderFormat = "yaml" | "cjs" | "shebang";
718
+ interface CreateHeaderOptions {
719
+ /** Path within theholocron/holocron that owns the file being generated. */
720
+ source: string;
721
+ /** CLI command that produces the file. Defaults to "holocron repo setup". */
722
+ tool?: string;
723
+ /** Set true only when writing to theholocron/.github itself. */
724
+ forPrimary?: boolean;
725
+ }
726
+ interface HeaderFunctions {
727
+ /**
728
+ * "AUTO-GENERATED — do not edit" header for files managed on every run.
729
+ *
730
+ * format:
731
+ * "yaml" — `# …` comment lines (YAML, text, ignore files)
732
+ * "cjs" — `/* … *\/` block comment (CommonJS modules)
733
+ * "shebang" — `#!/bin/sh` on line 1, then yaml header (shell scripts)
734
+ */
735
+ workflowHeader(format?: WorkflowHeaderFormat): string;
736
+ /**
737
+ * "Scaffolded — edit this file freely" header for one-time generated files
738
+ * that the user is expected to take over (e.g. codecov.yml).
739
+ */
740
+ scaffoldHeader(): string;
741
+ }
742
+ //#endregion
743
+ //#region src/utils/create-header.d.ts
744
+ /**
745
+ * Factory that binds `source` and `tool` once and returns all header
746
+ * constructors for auto-generated files. Prefer this over passing source
747
+ * as a positional argument at every call site.
748
+ *
749
+ * @example
750
+ * const { workflowHeader, scaffoldHeader } = createHeader({
751
+ * source: "packages/astromech/src/templates/configs/editorconfig/create-config.ts",
752
+ * });
753
+ *
754
+ * export function createConfig(): string {
755
+ * return `${workflowHeader()}${body}`;
756
+ * }
757
+ *
758
+ * ## Which header to use
759
+ *
760
+ * | Function | When to use | User can edit? |
761
+ * |-------------------|----------------------------------------------------|----------------|
762
+ * | `workflowHeader` | Files overwritten on every setup / sync-github run | No — "AUTO-GENERATED — do not edit" |
763
+ * | `scaffoldHeader` | Files written once; user takes ownership after | Yes — "Scaffolded — edit this file freely" |
764
+ *
765
+ * ## `workflowHeader` formats
766
+ *
767
+ * | Format | Comment style | Used for |
768
+ * |---------------------|------------------------|-------------------------------------------------------|
769
+ * | `"yaml"` (default) | `# …` lines | YAML workflows, ignore files, `.editorconfig`, labeler|
770
+ * | `"cjs"` | `/* … *\/` block | CommonJS config files (`.cjs`) |
771
+ * | `"shebang"` | `#!/bin/sh` + `# …` | Shell scripts (`prepare-commit-msg`, hooks) |
772
+ */
773
+ declare function createHeader(options: CreateHeaderOptions): HeaderFunctions;
774
+ //#endregion
775
+ export { type Astromech, type AstromechOptions, CI_ORDER, type CiJobReport, type CiOptions, type CiReport, type CreateHeaderOptions, type DeployOnReleaseOptions, type DeployOnReleaseReport, type DeployOnReleaseResult, type ExecFn, type GroupJobReport, type GroupOptions, type GroupReport, type HeaderFunctions, type JobDef, KNOWN_TASKS, KNOWN_WORKFLOWS, type LocalRunner, type OrgContext, type PreviewConfig, REUSABLE_ACTIONS, REUSABLE_WORKFLOWS, type RunLogger, type RunOptions, type RunTaskInput, type RunTaskReport, TASKS, type TaskDef, type TsconfigOptions, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, WORKFLOW_TEMPLATE_PROPERTIES, type WorkflowHeaderFormat, type WorkspacePackage, codecovComponentBlock, codecovConfig, createIgnoreConfig as createAlexignore, createRcConfig as createAlexrc, createAstromech, createCodecovConfig, createConfig as createCommitMsg, createConfig$1 as createDependabot, createConfig$2 as createDevmoji, createConfig$3 as createEditorconfig, createConfig$4 as createEditorconfigChecker, createHeader, createConfig$5 as createLabeler, createConfig$6 as createPreCommit, createConfig$7 as createPrePush, createConfig$8 as createPrepareCommitMsg, createTsconfig, createIgnoreConfig$1 as createYamlignore, createConfig$9 as createYamllint, deployOnRelease, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, matchNamespace, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, reusableTemplates, runCi, runGroup, runTask };
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { r as normalizeTaskEntry, t as loadTasksConfig } from "./load-ToVjaKPr.mjs";
2
+ import { n as alexrc_default, t as editorconfig_checker_default } from "./editorconfig-checker-DPejtR5z.mjs";
2
3
  import { existsSync, readFileSync, readdirSync } from "node:fs";
3
4
  import { dependencyNames, detectPackageManager, listWorkspacePackagesSync, readPackageJsonSync } from "@theholocron/pkg-utils";
4
5
  import { stringifyJson } from "@theholocron/json-utils";
@@ -2348,4 +2349,214 @@ async function deployOnRelease(options, { run = defaultRun, readJson = defaultRe
2348
2349
  };
2349
2350
  }
2350
2351
  //#endregion
2351
- export { CI_ORDER, KNOWN_TASKS, KNOWN_WORKFLOWS, REUSABLE_ACTIONS, REUSABLE_WORKFLOWS, TASKS, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, WORKFLOW_TEMPLATE_PROPERTIES, codecovComponentBlock, codecovConfig, createAstromech, createCodecovConfig, createTsconfig, deployOnRelease, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, matchNamespace, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, reusableTemplates, runCi, runGroup, runTask };
2352
+ //#region src/utils/create-header.ts
2353
+ /**
2354
+ * Factory that binds `source` and `tool` once and returns all header
2355
+ * constructors for auto-generated files. Prefer this over passing source
2356
+ * as a positional argument at every call site.
2357
+ *
2358
+ * @example
2359
+ * const { workflowHeader, scaffoldHeader } = createHeader({
2360
+ * source: "packages/astromech/src/templates/configs/editorconfig/create-config.ts",
2361
+ * });
2362
+ *
2363
+ * export function createConfig(): string {
2364
+ * return `${workflowHeader()}${body}`;
2365
+ * }
2366
+ *
2367
+ * ## Which header to use
2368
+ *
2369
+ * | Function | When to use | User can edit? |
2370
+ * |-------------------|----------------------------------------------------|----------------|
2371
+ * | `workflowHeader` | Files overwritten on every setup / sync-github run | No — "AUTO-GENERATED — do not edit" |
2372
+ * | `scaffoldHeader` | Files written once; user takes ownership after | Yes — "Scaffolded — edit this file freely" |
2373
+ *
2374
+ * ## `workflowHeader` formats
2375
+ *
2376
+ * | Format | Comment style | Used for |
2377
+ * |---------------------|------------------------|-------------------------------------------------------|
2378
+ * | `"yaml"` (default) | `# …` lines | YAML workflows, ignore files, `.editorconfig`, labeler|
2379
+ * | `"cjs"` | `/* … *\/` block | CommonJS config files (`.cjs`) |
2380
+ * | `"shebang"` | `#!/bin/sh` + `# …` | Shell scripts (`prepare-commit-msg`, hooks) |
2381
+ */
2382
+ function createHeader(options) {
2383
+ const { source, tool = "holocron repo setup", forPrimary = false } = options;
2384
+ const doNotEdit = forPrimary ? `AUTO-GENERATED — do not edit in theholocron/.github directly.` : `AUTO-GENERATED — do not edit directly.`;
2385
+ return {
2386
+ workflowHeader(format = "yaml") {
2387
+ if (format === "cjs") return [
2388
+ `/* ${doNotEdit}`,
2389
+ ` * Source: theholocron/holocron · ${source}`,
2390
+ ` * Tool: ${tool}`,
2391
+ ` * Changes: edit source in theholocron/holocron`,
2392
+ ` */`,
2393
+ ``
2394
+ ].join("\n");
2395
+ const yamlLines = [
2396
+ `# ${doNotEdit}`,
2397
+ `# Source: theholocron/holocron · ${source}`,
2398
+ `# Tool: ${tool}`,
2399
+ `# Changes: edit source in theholocron/holocron`,
2400
+ ``
2401
+ ].join("\n");
2402
+ if (format === "shebang") return `#!/bin/sh\n\n${yamlLines}`;
2403
+ return yamlLines;
2404
+ },
2405
+ scaffoldHeader() {
2406
+ return [
2407
+ `# Scaffolded by holocron repo setup — edit this file freely.`,
2408
+ `# Source: theholocron/holocron · ${source}`,
2409
+ ``
2410
+ ].join("\n");
2411
+ }
2412
+ };
2413
+ }
2414
+ //#endregion
2415
+ //#region src/templates/configs/alexjs/alexignore
2416
+ var alexignore_default = ".github/*\nCHANGELOG.md\nLICENSE\n";
2417
+ //#endregion
2418
+ //#region src/templates/configs/alexjs/create-config.ts
2419
+ const { workflowHeader: workflowHeader$9 } = createHeader({ source: "packages/astromech/src/templates/configs/alexjs/create-config.ts" });
2420
+ function createRcConfig() {
2421
+ return stringifyJson(alexrc_default);
2422
+ }
2423
+ function createIgnoreConfig() {
2424
+ return `${workflowHeader$9()}${alexignore_default}`;
2425
+ }
2426
+ //#endregion
2427
+ //#region src/templates/configs/commit-msg/commit-msg
2428
+ var commit_msg_default = "__HOLOCRON_SCRIPT__ run lint commit-msg \"$1\"\n";
2429
+ //#endregion
2430
+ //#region src/templates/configs/commit-msg/create-config.ts
2431
+ const { workflowHeader: workflowHeader$8 } = createHeader({ source: "packages/astromech/src/templates/configs/commit-msg/create-config.ts" });
2432
+ /**
2433
+ * `.husky/commit-msg` — lints the commit message via `holocron run lint
2434
+ * commit-msg` (holocron#789), the real programmatic replacement for
2435
+ * shelling out to `commitlint --edit`. Installed by `holocron repo setup` when
2436
+ * hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.
2437
+ *
2438
+ * @param holocronScript - the command that invokes the CLI. Defaults to
2439
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
2440
+ */
2441
+ function createConfig(holocronScript = "pnpm exec holocron") {
2442
+ return `${workflowHeader$8("shebang")}${commit_msg_default.replace("__HOLOCRON_SCRIPT__", holocronScript)}`;
2443
+ }
2444
+ //#endregion
2445
+ //#region src/templates/configs/dependabot/dependabot.yml
2446
+ var dependabot_default = "version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n prefix-development: \"chore(deps-dev)\"\n groups:\n security-patches:\n applies-to: security-updates\n patterns:\n - \"*\"\n all-dependencies:\n update-types:\n - minor\n - patch\n\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n groups:\n all-actions:\n patterns:\n - \"*\"\n";
2447
+ //#endregion
2448
+ //#region src/templates/configs/dependabot/create-config.ts
2449
+ const { workflowHeader: workflowHeader$7 } = createHeader({ source: "packages/astromech/src/templates/configs/dependabot/create-config.ts" });
2450
+ function createConfig$1() {
2451
+ return `${workflowHeader$7()}${dependabot_default}`;
2452
+ }
2453
+ //#endregion
2454
+ //#region src/templates/configs/devmoji/create-config.ts
2455
+ const { workflowHeader: workflowHeader$6 } = createHeader({ source: "packages/astromech/src/templates/configs/devmoji/create-config.ts" });
2456
+ function createConfig$2() {
2457
+ return [
2458
+ workflowHeader$6("cjs"),
2459
+ `/* eslint-disable */`,
2460
+ `const { defineConfig } = require("@theholocron/devmoji-config");`,
2461
+ `module.exports = defineConfig();`,
2462
+ ``
2463
+ ].join("\n");
2464
+ }
2465
+ //#endregion
2466
+ //#region src/templates/configs/editorconfig/editorconfig
2467
+ var editorconfig_default = "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = tab\nindent_size = 4\n\n[.gitattributes]\nindent_style = space\nindent_size = 2\n\n[*.{json,yml,yaml}]\nindent_style = space\nindent_size = 2\n\n[*.{md,mdx}]\ntrim_trailing_whitespace = false\nindent_style = unset\n\n[.*{rc,ignore}]\nindent_style = space\nindent_size = 2\n";
2468
+ //#endregion
2469
+ //#region src/templates/configs/editorconfig/create-config.ts
2470
+ const { workflowHeader: workflowHeader$5 } = createHeader({ source: "packages/astromech/src/templates/configs/editorconfig/create-config.ts" });
2471
+ function createConfig$3() {
2472
+ return `${workflowHeader$5()}${editorconfig_default}`;
2473
+ }
2474
+ //#endregion
2475
+ //#region src/templates/configs/editorconfig-checker/create-config.ts
2476
+ /**
2477
+ * The generated `.editorconfig-checker.json`.
2478
+ *
2479
+ * Deliberately carries no `"Version"` key: editorconfig-checker treats it as a
2480
+ * hard gate and exits non-zero the moment the running binary's version differs
2481
+ * — which it does the instant a contributor's local install (Homebrew tracks
2482
+ * latest) drifts from the version super-linter bundles in CI, breaking
2483
+ * `holocron run lint` / the pre-push hook for everyone (#618). The config
2484
+ * options here (`Exclude`, `Disable`) are stable across releases, so pinning
2485
+ * buys nothing.
2486
+ */
2487
+ function createConfig$4() {
2488
+ return stringifyJson(editorconfig_checker_default);
2489
+ }
2490
+ //#endregion
2491
+ //#region src/templates/configs/labeler/labeler.yml
2492
+ var labeler_default = "bug:\n - \"^fix\"\n\nchore:\n - '^chore(?!\\(deps)'\n\nci:\n - \"^ci\"\n\ndependencies:\n - '^chore\\(deps'\n\ndocumentation:\n - \"^docs\"\n\nenhancement:\n - \"^feat\"\n\nperformance:\n - \"^perf\"\n\nrefactor:\n - \"^refactor\"\n\ntest:\n - \"^test\"\n";
2493
+ //#endregion
2494
+ //#region src/templates/configs/labeler/create-config.ts
2495
+ const { workflowHeader: workflowHeader$4 } = createHeader({ source: "packages/astromech/src/templates/configs/labeler/create-config.ts" });
2496
+ function createConfig$5() {
2497
+ return `${workflowHeader$4()}${labeler_default}`;
2498
+ }
2499
+ //#endregion
2500
+ //#region src/templates/configs/pre-commit/pre-commit
2501
+ var pre_commit_default = "# Run GitLeaks against staged changes only — a full `gitleaks git` history\n# scan re-flags every pre-existing (already-merged) finding on every commit,\n# permanently blocking the repo once any false positive lands in history.\n# CI's super-linter GITLEAKS validator is likewise scoped to changed files.\ngitleaks protect --staged --no-banner\n\n# Exit with non-zero if secrets are detected by GitLeaks\nif [ $? -ne 0 ]; then\n echo \"Secrets detected by GitLeaks, aborting commit!\"\n exit 1\nfi\n\n# Run lint-staged with a custom config\nnpx lint-staged --config @theholocron/lint-staged-config\n";
2502
+ //#endregion
2503
+ //#region src/templates/configs/pre-commit/create-config.ts
2504
+ const { workflowHeader: workflowHeader$3 } = createHeader({ source: "packages/astromech/src/templates/configs/pre-commit/create-config.ts" });
2505
+ /**
2506
+ * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and
2507
+ * lint-staged before every commit. Installed by `holocron repo setup` when hooks
2508
+ * are enabled (default for `protection: "strict"`). `git commit --no-verify`
2509
+ * bypasses it.
2510
+ *
2511
+ * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter
2512
+ * scans the entire commit history on every invocation, so once any false
2513
+ * positive lands in a past commit — a fake test token, an example key in a
2514
+ * doc — every future commit is permanently blocked, regardless of what's
2515
+ * actually staged.
2516
+ */
2517
+ function createConfig$6() {
2518
+ return `${workflowHeader$3("shebang")}${pre_commit_default}`;
2519
+ }
2520
+ //#endregion
2521
+ //#region src/templates/configs/pre-push/pre-push
2522
+ 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";
2523
+ //#endregion
2524
+ //#region src/templates/configs/pre-push/create-config.ts
2525
+ const { workflowHeader: workflowHeader$2 } = createHeader({ source: "packages/astromech/src/templates/configs/pre-push/create-config.ts" });
2526
+ /**
2527
+ * `.husky/pre-push` — runs `holocron run ci` (the merge-gating checks, in CI order)
2528
+ * before every push. Installed by `holocron repo setup` when hooks are enabled
2529
+ * (default for `protection: "strict"`). `git push --no-verify` bypasses it.
2530
+ *
2531
+ * @param holocronScript - the command that invokes the CLI. Defaults to
2532
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
2533
+ */
2534
+ function createConfig$7(holocronScript = "pnpm exec holocron") {
2535
+ return `${workflowHeader$2("shebang")}${pre_push_default.replace("__HOLOCRON_SCRIPT__", holocronScript)}`;
2536
+ }
2537
+ //#endregion
2538
+ //#region src/templates/configs/prepare-commit-msg/prepare-commit-msg
2539
+ var prepare_commit_msg_default = "NAME=$(git config user.name)\nEMAIL=$(git config user.email)\n\nif [ -z \"$NAME\" ]; then\n echo \"empty git config user.name\"\n exit 1\nfi\n\nif [ -z \"$EMAIL\" ]; then\n echo \"empty git config user.email\"\n exit 1\nfi\n\ngit interpret-trailers --if-exists doNothing --trailer \\\n \"Signed-off-by: $NAME <$EMAIL>\" \\\n --in-place \"$1\"\n\n# --config <resolved shared path> (config-resolution workstream, #676) — falls\n# back to devmoji's own auto-discovery of a local devmoji.config.cjs when the\n# shared package's built dist/ isn't present (not installed, or a stale\n# install predating this file).\nDEVMOJI_CONFIG=\"node_modules/@theholocron/devmoji-config/dist/index.cjs\"\nif [ -f \"$DEVMOJI_CONFIG\" ]; then\n npx devmoji --config \"$DEVMOJI_CONFIG\" -e\nelse\n npx devmoji -e\nfi\n";
2540
+ //#endregion
2541
+ //#region src/templates/configs/prepare-commit-msg/create-config.ts
2542
+ const { workflowHeader: workflowHeader$1 } = createHeader({ source: "packages/astromech/src/templates/configs/prepare-commit-msg/create-config.ts" });
2543
+ function createConfig$8() {
2544
+ return `${workflowHeader$1("shebang")}${prepare_commit_msg_default}`;
2545
+ }
2546
+ //#endregion
2547
+ //#region src/templates/configs/yamllint/.yamlignore
2548
+ var _yamlignore_default = "pnpm-lock.yaml\n";
2549
+ //#endregion
2550
+ //#region src/templates/configs/yamllint/.yamllint.yml
2551
+ var _yamllint_default = "---\nextends: default\n\nignore-from-file:\n - .gitignore\n - .yamlignore\n\nrules:\n comments:\n min-spaces-from-content: 1\n require-starting-space: true\n\n comments-indentation: {}\n\n document-start:\n ignore: |\n .github/*.yml\n\n indentation:\n spaces: consistent\n indent-sequences: consistent\n\n line-length: disable\n";
2552
+ //#endregion
2553
+ //#region src/templates/configs/yamllint/create-config.ts
2554
+ const { workflowHeader } = createHeader({ source: "packages/astromech/src/templates/configs/yamllint/create-config.ts" });
2555
+ function createConfig$9() {
2556
+ return `${workflowHeader()}${_yamllint_default}`;
2557
+ }
2558
+ function createIgnoreConfig$1() {
2559
+ return `${workflowHeader()}${_yamlignore_default}`;
2560
+ }
2561
+ //#endregion
2562
+ export { CI_ORDER, KNOWN_TASKS, KNOWN_WORKFLOWS, REUSABLE_ACTIONS, REUSABLE_WORKFLOWS, TASKS, WORKFLOW_CHECK_CONTEXTS, WORKFLOW_TEMPLATES, WORKFLOW_TEMPLATE_PROPERTIES, codecovComponentBlock, codecovConfig, createIgnoreConfig as createAlexignore, createRcConfig as createAlexrc, createAstromech, createCodecovConfig, createConfig as createCommitMsg, createConfig$1 as createDependabot, createConfig$2 as createDevmoji, createConfig$3 as createEditorconfig, createConfig$4 as createEditorconfigChecker, createHeader, createConfig$5 as createLabeler, createConfig$6 as createPreCommit, createConfig$7 as createPrePush, createConfig$8 as createPrepareCommitMsg, createTsconfig, createIgnoreConfig$1 as createYamlignore, createConfig$9 as createYamllint, deployOnRelease, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, matchNamespace, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, reusableTemplates, runCi, runGroup, runTask };
@@ -0,0 +1,99 @@
1
+ import { QualifiedConfig } from "@commitlint/types";
2
+ //#region src/lint/alex-config.d.ts
3
+ /**
4
+ * The org's canonical `alex` (inclusive-language) config, as raw parsed
5
+ * data rather than the pre-rendered file strings `createRcConfig()`/
6
+ * `createIgnoreConfig()` produce for `holocron repo setup` to write into a
7
+ * repo's own `.alexrc.json`/`.alexignore`.
8
+ *
9
+ * `.alexrc.json` is explicitly "generated by `holocron repo setup` — do not
10
+ * edit manually" (this repo's own `AGENTS.md`) — the real source of truth
11
+ * is this JSON file, one canonical copy, not each repo's synced one. A
12
+ * central Sentinel check (holocron#769/#793) reads it directly rather
13
+ * than fetching each repo's own copy via the Contents API — the same "one
14
+ * config, not N copies" reasoning `@theholocron/commitlint-config` already
15
+ * established for commit-message linting.
16
+ */
17
+ declare const ALEX_CONFIG: {
18
+ allow: string[];
19
+ };
20
+ //#endregion
21
+ //#region src/lint/alex-ignore-patterns.d.ts
22
+ /**
23
+ * Glob-ish path patterns `alex` skips. Kept as a literal here rather than
24
+ * importing `../templates/configs/alexjs/alexignore` directly — that file
25
+ * (like `commit-msg`/`pre-push`) is deliberately extensionless, matching
26
+ * the real filename `holocron repo setup` writes, which ECMAScript's own
27
+ * module resolution (`moduleResolution: "nodenext"`) can't import across
28
+ * a package boundary without an extension. Keep in sync with that file by
29
+ * hand; it changes rarely.
30
+ */
31
+ declare const ALEX_IGNORE_PATTERNS: string[];
32
+ //#endregion
33
+ //#region src/lint/editorconfig-checker-exclude.d.ts
34
+ /**
35
+ * The paths editorconfig-checker skips, read from the same
36
+ * `editorconfig-checker.json` template `holocron repo setup` writes as a repo's
37
+ * `.editorconfig-checker.json` — so Sentinel's central editorconfig check
38
+ * (holocron#927) excludes exactly what CI's editorconfig-checker does, from
39
+ * one source.
40
+ *
41
+ * The exclusion that matters most is `\.md$` / `\.mdx$`: the generated
42
+ * `.editorconfig` gives every file tab indentation, but
43
+ * `@theholocron/prettier-config` formats markdown with spaces, so a README's
44
+ * indented code example would fail one tool or the other. Markdown is left
45
+ * to prettier and markdownlint.
46
+ *
47
+ * Each entry is a regular-expression source, matched against a
48
+ * repo-relative path, as editorconfig-checker itself treats them.
49
+ */
50
+ declare const EDITORCONFIG_CHECKER_EXCLUDE: readonly string[];
51
+ //#endregion
52
+ //#region src/lint/is-editorconfig-excluded.d.ts
53
+ /** `true` when `path` matches any {@link EDITORCONFIG_CHECKER_EXCLUDE} pattern. */
54
+ declare function isEditorConfigExcluded(path: string): boolean;
55
+ //#endregion
56
+ //#region src/lint/lint-message.type.d.ts
57
+ interface CommitMessageViolation {
58
+ /** Rule name, e.g. `"subject-empty"`. */
59
+ rule: string;
60
+ /** commitlint's own message for the failure, e.g. `"subject may not be empty"`. */
61
+ message: string;
62
+ }
63
+ //#endregion
64
+ //#region src/lint/lint-commit-msg-file.type.d.ts
65
+ interface LintCommitMsgFileResult {
66
+ valid: boolean;
67
+ violations: CommitMessageViolation[];
68
+ }
69
+ //#endregion
70
+ //#region src/lint/lint-commit-msg-file.d.ts
71
+ declare function lintCommitMsgFile(filePath: string, cwd?: string): Promise<LintCommitMsgFileResult>;
72
+ //#endregion
73
+ //#region src/lint/lint-message.d.ts
74
+ declare function lintCommitMessage(message: string, loaded: QualifiedConfig): Promise<CommitMessageViolation[]>;
75
+ //#endregion
76
+ //#region src/lint/prettier-ignore-patterns.d.ts
77
+ /**
78
+ * The org's canonical prettier ignore-pattern list for a central Sentinel
79
+ * check (holocron#769/#819) — the `PRETTIER_CONFIG` object itself doesn't
80
+ * need a home here, since `@theholocron/prettier-config`'s default export
81
+ * already *is* one canonical, importable config (the same "one config,
82
+ * not N copies" reasoning `@theholocron/commitlint-config` established for
83
+ * commit-message linting, and `ALEX_CONFIG` established for inclusive
84
+ * language) — only the ignore list is a Sentinel-specific decision that
85
+ * belongs alongside `ALEX_IGNORE_PATTERNS`, not inside the config package.
86
+ *
87
+ * Reuses `ALEX_IGNORE_PATTERNS`' own entries (`.github/*`, `CHANGELOG.md`,
88
+ * `LICENSE` all independently confirmed to fail a real `prettier.check()`
89
+ * today — machine-generated or unparseable content, same reasoning that
90
+ * excluded them from alex), plus `pnpm-lock.yaml` — prettier-specific
91
+ * (alex never reads a lockfile, but prettier would try to reformat it):
92
+ * machine-written by pnpm's own writer, and not gitignored (lockfiles are
93
+ * tracked), so prettier picks it up by default. Reformatting it
94
+ * fights every subsequent `pnpm install` (this repo's own `.prettierignore`
95
+ * already excludes it for that exact reason).
96
+ */
97
+ declare const PRETTIER_IGNORE_PATTERNS: string[];
98
+ //#endregion
99
+ export { ALEX_CONFIG, ALEX_IGNORE_PATTERNS, type CommitMessageViolation, EDITORCONFIG_CHECKER_EXCLUDE, type LintCommitMsgFileResult, PRETTIER_IGNORE_PATTERNS, isEditorConfigExcluded, lintCommitMessage, lintCommitMsgFile };
@@ -0,0 +1,143 @@
1
+ import { n as alexrc_default, t as editorconfig_checker_default } from "../editorconfig-checker-DPejtR5z.mjs";
2
+ import { readFile } from "node:fs/promises";
3
+ import load from "@commitlint/load";
4
+ import lint from "@commitlint/lint";
5
+ //#region src/lint/alex-config.ts
6
+ /**
7
+ * The org's canonical `alex` (inclusive-language) config, as raw parsed
8
+ * data rather than the pre-rendered file strings `createRcConfig()`/
9
+ * `createIgnoreConfig()` produce for `holocron repo setup` to write into a
10
+ * repo's own `.alexrc.json`/`.alexignore`.
11
+ *
12
+ * `.alexrc.json` is explicitly "generated by `holocron repo setup` — do not
13
+ * edit manually" (this repo's own `AGENTS.md`) — the real source of truth
14
+ * is this JSON file, one canonical copy, not each repo's synced one. A
15
+ * central Sentinel check (holocron#769/#793) reads it directly rather
16
+ * than fetching each repo's own copy via the Contents API — the same "one
17
+ * config, not N copies" reasoning `@theholocron/commitlint-config` already
18
+ * established for commit-message linting.
19
+ */
20
+ const ALEX_CONFIG = alexrc_default;
21
+ //#endregion
22
+ //#region src/lint/alex-ignore-patterns.ts
23
+ /**
24
+ * Glob-ish path patterns `alex` skips. Kept as a literal here rather than
25
+ * importing `../templates/configs/alexjs/alexignore` directly — that file
26
+ * (like `commit-msg`/`pre-push`) is deliberately extensionless, matching
27
+ * the real filename `holocron repo setup` writes, which ECMAScript's own
28
+ * module resolution (`moduleResolution: "nodenext"`) can't import across
29
+ * a package boundary without an extension. Keep in sync with that file by
30
+ * hand; it changes rarely.
31
+ */
32
+ const ALEX_IGNORE_PATTERNS = [
33
+ ".github/*",
34
+ "CHANGELOG.md",
35
+ "LICENSE"
36
+ ];
37
+ //#endregion
38
+ //#region src/lint/editorconfig-checker-exclude.ts
39
+ /**
40
+ * The paths editorconfig-checker skips, read from the same
41
+ * `editorconfig-checker.json` template `holocron repo setup` writes as a repo's
42
+ * `.editorconfig-checker.json` — so Sentinel's central editorconfig check
43
+ * (holocron#927) excludes exactly what CI's editorconfig-checker does, from
44
+ * one source.
45
+ *
46
+ * The exclusion that matters most is `\.md$` / `\.mdx$`: the generated
47
+ * `.editorconfig` gives every file tab indentation, but
48
+ * `@theholocron/prettier-config` formats markdown with spaces, so a README's
49
+ * indented code example would fail one tool or the other. Markdown is left
50
+ * to prettier and markdownlint.
51
+ *
52
+ * Each entry is a regular-expression source, matched against a
53
+ * repo-relative path, as editorconfig-checker itself treats them.
54
+ */
55
+ const EDITORCONFIG_CHECKER_EXCLUDE = editorconfig_checker_default.Exclude;
56
+ //#endregion
57
+ //#region src/lint/is-editorconfig-excluded.ts
58
+ /** `true` when `path` matches any {@link EDITORCONFIG_CHECKER_EXCLUDE} pattern. */
59
+ function isEditorConfigExcluded(path) {
60
+ return EDITORCONFIG_CHECKER_EXCLUDE.some((pattern) => new RegExp(pattern).test(path));
61
+ }
62
+ //#endregion
63
+ //#region src/lint/lint-message.ts
64
+ /**
65
+ * Lints one commit message string against an already-loaded commitlint
66
+ * config. The genuinely environment-independent half of commit-message
67
+ * linting (holocron#789) — *obtaining* a `QualifiedConfig` differs by
68
+ * caller (Sentinel isolates itself from any ambient config since it runs
69
+ * standalone, away from a real repo checkout; `lintCommitMsgFile` below
70
+ * lets cosmiconfig discover the invoking repo's own
71
+ * `commitlint.config.*`, matching `commitlint --edit`'s own contract) —
72
+ * but linting one message against a loaded config is identical either way.
73
+ *
74
+ * Real `@commitlint/lint` — the same programmatic API `@commitlint/cli`
75
+ * itself uses internally — never a reimplementation of commitlint's rules.
76
+ */
77
+ /** `parserPreset.parserOpts`, if the loaded config sets one — same lookup `@commitlint/cli`'s own `selectParserOpts()` does. */
78
+ function selectParserOpts(parserPreset) {
79
+ return parserPreset?.parserOpts;
80
+ }
81
+ async function lintCommitMessage(message, loaded) {
82
+ const opts = {
83
+ /* istanbul ignore next -- see comment above */
84
+ parserOpts: selectParserOpts(loaded.parserPreset) ?? {},
85
+ plugins: loaded.plugins,
86
+ /* istanbul ignore next -- see comment above */
87
+ ignores: loaded.ignores ?? [],
88
+ defaultIgnores: loaded.defaultIgnores !== false
89
+ };
90
+ const outcome = await lint(message, loaded.rules, opts);
91
+ if (outcome.valid) return [];
92
+ return outcome.errors.map((error) => ({
93
+ rule: error.name,
94
+ message: error.message
95
+ }));
96
+ }
97
+ //#endregion
98
+ //#region src/lint/lint-commit-msg-file.ts
99
+ /**
100
+ * `holocron run lint commit-msg <file>` — a real programmatic replacement for
101
+ * shelling out to `commitlint --edit "$1"` from `.husky/commit-msg`
102
+ * (holocron#789). Matches that CLI's own contract exactly: `file` is a
103
+ * path to the commit message being written (the arg git's `commit-msg`
104
+ * hook passes as `$1`), no `--config` override needed — `@commitlint/load`
105
+ * runs from `cwd` with no seed, so cosmiconfig's own normal upward search
106
+ * discovers the invoking repo's real `commitlint.config.*` file, exactly
107
+ * as `commitlint --edit` (no `--config` flag) already does today. Unlike
108
+ * Sentinel's `loadIsolatedConfig()`, no isolation is needed here — this
109
+ * runs inside a real repo checkout with a real `node_modules`, not
110
+ * standalone on a server.
111
+ */
112
+ async function lintCommitMsgFile(filePath, cwd = process.cwd()) {
113
+ const violations = await lintCommitMessage(await readFile(filePath, "utf8"), await load({}, { cwd }));
114
+ return {
115
+ valid: violations.length === 0,
116
+ violations
117
+ };
118
+ }
119
+ //#endregion
120
+ //#region src/lint/prettier-ignore-patterns.ts
121
+ /**
122
+ * The org's canonical prettier ignore-pattern list for a central Sentinel
123
+ * check (holocron#769/#819) — the `PRETTIER_CONFIG` object itself doesn't
124
+ * need a home here, since `@theholocron/prettier-config`'s default export
125
+ * already *is* one canonical, importable config (the same "one config,
126
+ * not N copies" reasoning `@theholocron/commitlint-config` established for
127
+ * commit-message linting, and `ALEX_CONFIG` established for inclusive
128
+ * language) — only the ignore list is a Sentinel-specific decision that
129
+ * belongs alongside `ALEX_IGNORE_PATTERNS`, not inside the config package.
130
+ *
131
+ * Reuses `ALEX_IGNORE_PATTERNS`' own entries (`.github/*`, `CHANGELOG.md`,
132
+ * `LICENSE` all independently confirmed to fail a real `prettier.check()`
133
+ * today — machine-generated or unparseable content, same reasoning that
134
+ * excluded them from alex), plus `pnpm-lock.yaml` — prettier-specific
135
+ * (alex never reads a lockfile, but prettier would try to reformat it):
136
+ * machine-written by pnpm's own writer, and not gitignored (lockfiles are
137
+ * tracked), so prettier picks it up by default. Reformatting it
138
+ * fights every subsequent `pnpm install` (this repo's own `.prettierignore`
139
+ * already excludes it for that exact reason).
140
+ */
141
+ const PRETTIER_IGNORE_PATTERNS = [...ALEX_IGNORE_PATTERNS, "pnpm-lock.yaml"];
142
+ //#endregion
143
+ export { ALEX_CONFIG, ALEX_IGNORE_PATTERNS, EDITORCONFIG_CHECKER_EXCLUDE, PRETTIER_IGNORE_PATTERNS, isEditorConfigExcluded, lintCommitMessage, lintCommitMsgFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/astromech",
3
- "version": "5.0.0-alpha.152",
3
+ "version": "5.0.0-alpha.153",
4
4
  "description": "The Holocron task runner — one task manifest drives `holocron run`, `holocron run ci`, the CI workflows, package.json scripts, linters, and required checks.",
5
5
  "keywords": [
6
6
  "ci",
@@ -31,18 +31,28 @@
31
31
  "types": "./dist/config/index.d.mts",
32
32
  "import": "./dist/config/index.mjs",
33
33
  "default": "./dist/config/index.mjs"
34
+ },
35
+ "./lint": {
36
+ "types": "./dist/lint/index.d.mts",
37
+ "import": "./dist/lint/index.mjs",
38
+ "default": "./dist/lint/index.mjs"
34
39
  }
35
40
  },
36
41
  "files": [
37
42
  "dist"
38
43
  ],
39
44
  "dependencies": {
40
- "@theholocron/fs-utils": "^1.13.0",
41
- "@theholocron/json-utils": "^1.13.0",
42
- "@theholocron/pkg-utils": "^1.13.0",
43
- "@theholocron/datapad": "5.0.0-alpha.152"
45
+ "@commitlint/lint": "^21.2.3",
46
+ "@commitlint/load": "^21.2.3",
47
+ "@commitlint/types": "^21.2.3",
48
+ "@theholocron/fs-utils": "^1.15.1",
49
+ "@theholocron/json-utils": "^1.15.1",
50
+ "@theholocron/pkg-utils": "^1.15.1",
51
+ "@theholocron/datapad": "5.0.0-alpha.153"
44
52
  },
45
53
  "devDependencies": {
54
+ "@commitlint/config-conventional": "^21.2.3",
55
+ "@theholocron/commitlint-config": "^8.7.1",
46
56
  "@theholocron/eslint-config": "^8.7.1",
47
57
  "@theholocron/tsconfig": "^8.7.1",
48
58
  "@theholocron/tsdown-config": "^8.7.1",
@@ -56,7 +66,7 @@
56
66
  "tsdown": "^0.22.14",
57
67
  "typescript": "^5.9.3",
58
68
  "vitest": "^4.1.11",
59
- "@theholocron/rollup-plugin-transform-template": "5.0.0-alpha.152"
69
+ "@theholocron/rollup-plugin-transform-template": "5.0.0-alpha.153"
60
70
  },
61
71
  "engines": {
62
72
  "node": ">=22"