@theholocron/astromech 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/dist/index.d.mts CHANGED
@@ -1,34 +1,223 @@
1
- import { r as TasksConfig } from "./schema-D01VYg43.mjs";
2
- //#region src/run.d.ts
1
+ import { r as TasksConfig } from "./schema.type-BJmfOafW.mjs";
2
+ //#region src/generators/codecov/codecov.type.d.ts
3
+ interface WorkspacePackage$1 {
4
+ slug: string;
5
+ name: string;
6
+ /** Which workspace root the package was discovered under. Defaults to `"packages"`. */
7
+ dir?: "packages" | "apps" | "plugins";
8
+ }
9
+ //#endregion
10
+ //#region src/generators/codecov/codecov.d.ts
11
+ declare function codecovComponentBlock(packages: WorkspacePackage$1[]): string;
3
12
  /**
4
- * `holocron run <task> [job] [-- <passthrough>]` — run a registry task (or one
5
- * of its sub-jobs) locally.
13
+ * Ensure every codecov status default carries `if_not_found: success`, so an
14
+ * infra-only PR (dep bump, config, lockfile — no coverable change) passes
15
+ * instead of hanging forever on a required check codecov never posts.
6
16
  *
7
- * A `job` argument only applies to tasks that declare `jobs`; for any other
8
- * task it is folded back into the passthrough (`holocron run delivery.build
9
- * src/`).
17
+ * Injects the key on the line after each `target:` that sits inside a status
18
+ * block (`coverage.status.*.default` or a `statuses:` list item — indent ≥ 8,
19
+ * or ≥ 8 for a `- type:` list entry), when the immediate sibling lines do not
20
+ * already declare it.
21
+ */
22
+ declare function ensureIfNotFound(yaml: string): string;
23
+ declare function mergeCodecovComponents(existing: string, packages: WorkspacePackage$1[]): string;
24
+ /**
25
+ * Every public `packages/*`, `apps/*`, and `plugins/*` workspace, sorted by
26
+ * slug. `[]` when none of the three directories exist. Monorepo templates
27
+ * (Next.js, React, …) ship user-facing code under `apps/` alongside library
28
+ * code under `packages/`; `holocron` itself splits vendor plugin packages
29
+ * into their own `plugins/*` root — every recognized root needs a codecov
30
+ * component so `codecov/patch/<slug>` actually posts for each.
31
+ */
32
+ declare function readWorkspacePackages(repoRoot: string): WorkspacePackage$1[];
33
+ /** A brand-new `codecov.yml` — the scaffold header + the base template + this repo's component list. */
34
+ declare function createCodecovConfig(packages: WorkspacePackage$1[]): string;
35
+ /**
36
+ * The full pipeline `holocron repo setup` needs: read this repo's public
37
+ * `packages/*`, then either merge them into an `existing` `codecov.yml` or
38
+ * scaffold a new one.
39
+ */
40
+ declare function codecovConfig(repoRoot: string, existing: string | null): string;
41
+ //#endregion
42
+ //#region src/generators/github-action-reusable-workflows/github-action-reusable-workflows.d.ts
43
+ /**
44
+ * The **reusable** GitHub Actions surface pushed to `theholocron/.github` by
45
+ * `holocron sync github` — the `workflow_call` implementations and composite
46
+ * actions that every repo's thin callers delegate to.
10
47
  *
11
- * Resolution:
48
+ * `theholocron/.github` is a **pure sync target**: `.github/workflows/*`,
49
+ * `.github/actions/*` and `workflow-templates/*` there are generated from the
50
+ * `.yml` files in `src/templates/reusable/` and pushed verbatim (with a
51
+ * "do not edit" header). Never hand-edit them in `.github`.
12
52
  *
13
- * J. job given → TASKS[task].jobs[job].local (unknown job → exit 1)
14
- * 1. turbo.json defines the task → `turbo run <task>`
15
- * 2. package.json has a `<task>` script → `<pm> run <task>`
16
- * (unless it's the `holocron run …` thin caller — that recurses)
17
- * 3. TASKS[task].local resolves → `<tool> <args> <org-flags> <passthrough>`
18
- * 3b. TASKS[task].linterGroup → run each resolved linter natively (see below)
19
- * 4. TASKS[task].jobs has entries → run each job in declared order
20
- * 5. TASKS[task].local === null → "enforced in CI" (skip, even with --required)
21
- * 5b. known task, nothing resolved → "no <task> task" (exit 0, or 1 with --required)
22
- * 6. unknown task → "unknown task" (exit 1)
53
+ * Not to be confused with `WORKFLOW_TEMPLATES` in `github-action-thin-callers.ts` — those are
54
+ * the *thin-caller bases* written into each consumer repo's `.github/workflows/`.
55
+ */
56
+ /** `workflow_call` implementations → `.github/workflows/<name>.yml`. */
57
+ declare const REUSABLE_WORKFLOWS: Record<string, string>;
58
+ /** Composite actions → `.github/actions/<name>/action.yml` (key includes `/action`). */
59
+ declare const REUSABLE_ACTIONS: Record<string, string>;
60
+ /** GitHub starter-workflow metadata → `workflow-templates/<name>.properties.json`. */
61
+ declare const WORKFLOW_TEMPLATE_PROPERTIES: Record<string, string>;
62
+ /**
63
+ * The complete file batch `holocron sync github` pushes to `theholocron/.github`:
64
+ * path → content. YAML gets the "do not edit" header; the starter-workflow
65
+ * `.properties.json` files are left bare (native JSON, not a commented file).
66
+ */
67
+ declare function reusableTemplates(): Map<string, string>;
68
+ //#endregion
69
+ //#region src/generators/github-action-thin-callers/github-action-thin-callers.type.d.ts
70
+ interface PreviewConfig {
71
+ /** Cloudflare Pages project name shared across all repos for previews. */
72
+ project: string;
73
+ /**
74
+ * Base domain for preview URLs (e.g. `"preview.theholocron.dev"`).
75
+ * When set, `holocron repo setup` automatically provisions:
76
+ * - Cloudflare Pages custom domain `*.<domain>` on the project
77
+ * - DNS wildcard CNAME `*.<domain>` → `<project>.pages.dev`
78
+ *
79
+ * Preview URLs resolve as `<repo>-pr-<n>.<domain>`.
80
+ */
81
+ domain?: string;
82
+ }
83
+ /** Org-level context used to derive preview defaults from `preview: true`. */
84
+ interface OrgContext {
85
+ /** GitHub org name — becomes the prefix of the default project: `<org>-preview`. */
86
+ org?: string;
87
+ /** Org canonical domain — becomes `preview.<domain>` for the default preview domain. */
88
+ domain?: string;
89
+ /** Project name — injected as the `name` input to the deploy reusable when `docs: true`. */
90
+ repoName?: string;
91
+ }
92
+ //#endregion
93
+ //#region src/generators/github-action-thin-callers/github-action-thin-callers.d.ts
94
+ declare const WORKFLOW_TEMPLATES: Record<string, string>;
95
+ declare const KNOWN_WORKFLOWS: Set<string>;
96
+ /**
97
+ * The GitHub status-check context a `required` task contributes to branch
98
+ * protection. Format: `"{workflow name} / {job name}"`.
23
99
  *
24
- * A `linterGroup` task (`sourceQuality.staticAnalysis`, etc.) runs its fixed
25
- * set of `linters.ts` entries, each still gated by that linter's own
26
- * `detect`/`always` rule — every entry runs its `localBin` natively when
27
- * found on PATH. Missing tools are flagged; the exit code is the worst of
28
- * the lot. Unlike the old single `lint` task, this check runs *after*
29
- * turbo/`package.json` resolution (step 3b, not step 0) — a `linterGroup`
30
- * task is a normal turbo-delegatable task like any other.
100
+ * Most of these are single-job workflows now (D3's decomposition split what
101
+ * used to be multi-job `lint`/`audit` into one task per concern) — the
102
+ * context names that job directly, no `Conclusion` aggregator needed; a
103
+ * single job's own conclusion already *is* the workflow's conclusion.
104
+ * `Conclusion` fan-in jobs are kept only where a task genuinely has several
105
+ * conditionally-run jobs feeding one required check:
106
+ * `verification.unitTests` (unit / Storybook / Chromatic / interaction /
107
+ * user-flow, each gated by its own `run-*` input) and
108
+ * `platform.repoValidation` (its three script jobs all must pass). Only
109
+ * merge-gating workflows are listed. `astromech.requiredChecks()` reads this
110
+ * for every `required` task.
31
111
  */
112
+ declare const WORKFLOW_CHECK_CONTEXTS: Partial<Record<string, string>>;
113
+ /**
114
+ * Generate the thin caller content for a workflow, optionally injecting or
115
+ * merging `with:` overrides into the jobs block.
116
+ *
117
+ * Two strategies are used depending on the template:
118
+ * - Templates that already have a `with:` block (e.g. lint):
119
+ * the override entries are merged in, replacing existing keys and appending
120
+ * new ones.
121
+ * - Templates that end with ` secrets: inherit`: a new `with:` block is
122
+ * injected immediately before `secrets: inherit`.
123
+ * If neither pattern matches the template, a warning is emitted and the
124
+ * base template is returned unchanged.
125
+ */
126
+ declare function generateThinCallerContent(name: string, withOverrides?: Record<string, unknown>, additionalPaths?: string[],
127
+ /** Optional sink for the "could not inject `with:`" warning. */
128
+ logger?: {
129
+ warn(obj: Record<string, unknown>, msg: string): void;
130
+ },
131
+ /**
132
+ * `with:` key → a `# comment` line rendered immediately above that entry.
133
+ * Only honored when injecting a fresh `with:` block (no template today
134
+ * ships one), which is the path `lint` takes.
135
+ */
136
+ comments?: Record<string, string>): string;
137
+ /**
138
+ * Extract the Cloudflare Pages preview config from a deploy workflow's `with:` object.
139
+ *
140
+ * Accepts three forms:
141
+ * - `preview: true` — derive both project and domain from org context
142
+ * - `preview: { project: "..." }` — explicit project; domain derived from context if omitted
143
+ * - `preview: { project: "...", domain: "..." }` — fully explicit
144
+ *
145
+ * Returns null when `preview:` is absent, false, or can't be resolved.
146
+ */
147
+ declare function extractPreviewConfig(raw: Record<string, unknown>, ctx?: OrgContext): PreviewConfig | null;
148
+ /**
149
+ * Generate the full thin-caller YAML for a `deploy.yml` that handles both
150
+ * production (push to main → GitHub Pages) and preview (pull_request →
151
+ * Cloudflare Pages) in a single file.
152
+ *
153
+ * Both jobs receive the same docs/storybook `with:` inputs. If the per-repo
154
+ * config supplies `cloudflare-project` it is forwarded; otherwise the reusable
155
+ * falls back to the `CLOUDFLARE_PAGES_PROJECT` org variable — set that once and
156
+ * all repos with a `deploy` workflow get previews without per-repo config.
157
+ */
158
+ declare function generateCombinedDeployContent(deployWith: Record<string, unknown>, paths: string[], preview: Pick<PreviewConfig, "project">): string;
159
+ /**
160
+ * Expand structured with-values to flat GitHub Actions inputs before
161
+ * generating the thin caller. Handles:
162
+ * - deploy shorthand: docs/storybook → type + storybook-projects
163
+ * - preview: stripped (handled separately via extractPreviewConfig)
164
+ * - chromatic-projects entries' untraced array → newline-joined string
165
+ * - plain arrays → JSON-stringified for YAML scalar quoting
166
+ *
167
+ * Used by both `holocron repo setup` and `sync-workflow-templates`.
168
+ */
169
+ declare function normalizeWorkflowWith(raw: Record<string, unknown>): Record<string, unknown>;
170
+ /**
171
+ * Derive on.push.paths entries from the deploy with: shorthand.
172
+ * Used by both `holocron repo setup` and `sync-workflow-templates`.
173
+ */
174
+ declare function deriveDeployPaths(raw: Record<string, unknown>): string[];
175
+ //#endregion
176
+ //#region src/generators/required-checks/required-checks.d.ts
177
+ /** Ordered (task contexts in {@link CI_ORDER}, then extras), de-duplicated. */
178
+ declare function requiredChecks(config: TasksConfig): string[];
179
+ //#endregion
180
+ //#region src/generators/tsconfig/tsconfig.type.d.ts
181
+ interface TsconfigOptions {
182
+ /** Human-readable name for the `display` field — the package's own name is the usual choice. */
183
+ display: string;
184
+ /**
185
+ * `@theholocron/tsconfig` variant. Defaults to `"node-lts"` — every
186
+ * checked package uses it; the other three (`astro`, `nextjs`, `react`)
187
+ * exist for a template repo's app-shaped packages, not the plain
188
+ * Node.js library packages this org's currently-migrated repos ship.
189
+ */
190
+ variant?: "astro" | "nextjs" | "node-lts" | "react";
191
+ /**
192
+ * Add a `@/*` → `./src/*` path alias. A real per-package choice, not a
193
+ * default — roughly 40% of packages checked use one, the rest don't.
194
+ */
195
+ paths?: boolean;
196
+ }
197
+ //#endregion
198
+ //#region src/generators/tsconfig/tsconfig.d.ts
199
+ /**
200
+ * A package-level `tsconfig.json` — the uniform shape confirmed across
201
+ * every package checked, parameterized only by the two fields that
202
+ * genuinely vary (`display`, `paths`). No scaffold/workflow header (matches
203
+ * `.alexrc.json`'s existing precedent for a strict-JSON Bucket B file —
204
+ * JSON has no comment syntax to carry one, and TypeScript's own tolerance
205
+ * for JSONC comments in `tsconfig.json` isn't worth relying on for a file
206
+ * this thin).
207
+ */
208
+ declare function createTsconfig(options: TsconfigOptions): string;
209
+ //#endregion
210
+ //#region src/generators/turbo/turbo.type.d.ts
211
+ interface EnsureRootWorkspaceMemberResult {
212
+ content: string;
213
+ changed: boolean;
214
+ }
215
+ interface EnsureTurboDependencyResult {
216
+ content: string;
217
+ changed: boolean;
218
+ }
219
+ //#endregion
220
+ //#region src/tasks/run/run.type.d.ts
32
221
  /** Minimal structural logger — `@theholocron/observability`'s `Logger` satisfies it. */
33
222
  interface RunLogger {
34
223
  debug(obj: Record<string, unknown>, msg?: string): void;
@@ -80,9 +269,11 @@ interface RunTaskReport {
80
269
  command?: string;
81
270
  message?: string;
82
271
  }
272
+ //#endregion
273
+ //#region src/tasks/run/run.d.ts
83
274
  declare function runTask(input: RunTaskInput): RunTaskReport;
84
275
  //#endregion
85
- //#region src/ci.d.ts
276
+ //#region src/tasks/ci/ci.type.d.ts
86
277
  interface CiOptions {
87
278
  /** Print the plan without running anything. */
88
279
  dryRun?: boolean;
@@ -107,127 +298,178 @@ interface CiInput extends RunDeps, CiOptions {
107
298
  cwd: string;
108
299
  config: TasksConfig;
109
300
  }
301
+ //#endregion
302
+ //#region src/tasks/ci/ci.d.ts
110
303
  declare function runCi(input: CiInput): CiReport;
111
304
  //#endregion
112
- //#region src/thin-callers.d.ts
113
- /**
114
- * Workflow templates + thin-caller generation.
115
- *
116
- * `WORKFLOW_TEMPLATES` holds each reusable `.github/workflows/<name>.yml`
117
- * (synced to `theholocron/.github`); `generateThinCallerContent` wraps one
118
- * into the thin caller `holocron setup` / `holocron sync` write locally.
119
- */
120
- declare const WORKFLOW_TEMPLATES: Record<string, string>;
121
- declare const KNOWN_WORKFLOWS: Set<string>;
122
- /**
123
- * The GitHub status-check context a `required` task contributes to branch
124
- * protection. Format: `"{workflow name} / {job name}"`.
125
- *
126
- * Most of these are single-job workflows now (D3's decomposition split what
127
- * used to be multi-job `lint`/`audit` into one task per concern) — the
128
- * context names that job directly, no `Conclusion` aggregator needed; a
129
- * single job's own conclusion already *is* the workflow's conclusion.
130
- * `Conclusion` fan-in jobs are kept only where a task genuinely has several
131
- * conditionally-run jobs feeding one required check:
132
- * `verification.unitTests` (unit / Storybook / Chromatic / interaction /
133
- * user-flow, each gated by its own `run-*` input) and
134
- * `platform.repoValidation` (its three script jobs all must pass). Only
135
- * merge-gating workflows are listed. `astromech.requiredChecks()` reads this
136
- * for every `required` task.
137
- */
138
- declare const WORKFLOW_CHECK_CONTEXTS: Partial<Record<string, string>>;
139
- /**
140
- * Generate the thin caller content for a workflow, optionally injecting or
141
- * merging `with:` overrides into the jobs block.
142
- *
143
- * Two strategies are used depending on the template:
144
- * - Templates that already have a `with:` block (e.g. lint):
145
- * the override entries are merged in, replacing existing keys and appending
146
- * new ones.
147
- * - Templates that end with ` secrets: inherit`: a new `with:` block is
148
- * injected immediately before `secrets: inherit`.
149
- * If neither pattern matches the template, a warning is emitted and the
150
- * base template is returned unchanged.
151
- */
152
- declare function generateThinCallerContent(name: string, withOverrides?: Record<string, unknown>, additionalPaths?: string[],
153
- /** Optional sink for the "could not inject `with:`" warning. */
154
- logger?: {
155
- warn(obj: Record<string, unknown>, msg: string): void;
156
- },
157
- /**
158
- * `with:` key → a `# comment` line rendered immediately above that entry.
159
- * Only honored when injecting a fresh `with:` block (no template today
160
- * ships one), which is the path `lint` takes.
161
- */
162
- comments?: Record<string, string>): string;
163
- interface PreviewConfig {
164
- /** Cloudflare Pages project name shared across all repos for previews. */
165
- project: string;
305
+ //#region src/utils/create-header/create-header.type.d.ts
306
+ /** Comment style produced by workflowHeader. */
307
+ type WorkflowHeaderFormat = "yaml" | "cjs" | "shebang";
308
+ interface CreateHeaderOptions {
309
+ /** Path within theholocron/holocron that owns the file being generated. */
310
+ source: string;
311
+ /** CLI command that produces the file. Defaults to "holocron repo setup". */
312
+ tool?: string;
313
+ /** Set true only when writing to theholocron/.github itself. */
314
+ forPrimary?: boolean;
315
+ }
316
+ interface HeaderFunctions {
166
317
  /**
167
- * Base domain for preview URLs (e.g. `"preview.theholocron.dev"`).
168
- * When set, `holocron setup` automatically provisions:
169
- * - Cloudflare Pages custom domain `*.<domain>` on the project
170
- * - DNS wildcard CNAME `*.<domain>` → `<project>.pages.dev`
318
+ * "AUTO-GENERATED — do not edit" header for files managed on every run.
171
319
  *
172
- * Preview URLs resolve as `<repo>-pr-<n>.<domain>`.
320
+ * format:
321
+ * "yaml" — `# …` comment lines (YAML, text, ignore files)
322
+ * "cjs" — `/* … *\/` block comment (CommonJS modules)
323
+ * "shebang" — `#!/bin/sh` on line 1, then yaml header (shell scripts)
173
324
  */
174
- domain?: string;
175
- }
176
- /** Org-level context used to derive preview defaults from `preview: true`. */
177
- interface OrgContext {
178
- /** GitHub org name — becomes the prefix of the default project: `<org>-preview`. */
179
- org?: string;
180
- /** Org canonical domain — becomes `preview.<domain>` for the default preview domain. */
181
- domain?: string;
182
- /** Project name — injected as the `name` input to the deploy reusable when `docs: true`. */
183
- repoName?: string;
325
+ workflowHeader(format?: WorkflowHeaderFormat): string;
326
+ /**
327
+ * "Scaffolded — edit this file freely" header for one-time generated files
328
+ * that the user is expected to take over (e.g. codecov.yml).
329
+ */
330
+ scaffoldHeader(): string;
184
331
  }
332
+ //#endregion
333
+ //#region src/utils/create-header/create-header.d.ts
185
334
  /**
186
- * Extract the Cloudflare Pages preview config from a deploy workflow's `with:` object.
335
+ * Factory that binds `source` and `tool` once and returns all header
336
+ * constructors for auto-generated files. Prefer this over passing source
337
+ * as a positional argument at every call site.
187
338
  *
188
- * Accepts three forms:
189
- * - `preview: true` — derive both project and domain from org context
190
- * - `preview: { project: "..." }` — explicit project; domain derived from context if omitted
191
- * - `preview: { project: "...", domain: "..." }` — fully explicit
339
+ * @example
340
+ * const { workflowHeader, scaffoldHeader } = createHeader({
341
+ * source: "packages/astromech/src/templates/configs/editorconfig/create-config.ts",
342
+ * });
192
343
  *
193
- * Returns null when `preview:` is absent, false, or can't be resolved.
194
- */
195
- declare function extractPreviewConfig(raw: Record<string, unknown>, ctx?: OrgContext): PreviewConfig | null;
196
- /**
197
- * Generate the full thin-caller YAML for a `deploy.yml` that handles both
198
- * production (push to main → GitHub Pages) and preview (pull_request →
199
- * Cloudflare Pages) in a single file.
344
+ * export function createConfig(): string {
345
+ * return `${workflowHeader()}${body}`;
346
+ * }
200
347
  *
201
- * Both jobs receive the same docs/storybook `with:` inputs. If the per-repo
202
- * config supplies `cloudflare-project` it is forwarded; otherwise the reusable
203
- * falls back to the `CLOUDFLARE_PAGES_PROJECT` org variable — set that once and
204
- * all repos with a `deploy` workflow get previews without per-repo config.
348
+ * ## Which header to use
349
+ *
350
+ * | Function | When to use | User can edit? |
351
+ * |-------------------|----------------------------------------------------|----------------|
352
+ * | `workflowHeader` | Files overwritten on every setup / sync-github run | No — "AUTO-GENERATED — do not edit" |
353
+ * | `scaffoldHeader` | Files written once; user takes ownership after | Yes — "Scaffolded — edit this file freely" |
354
+ *
355
+ * ## `workflowHeader` formats
356
+ *
357
+ * | Format | Comment style | Used for |
358
+ * |---------------------|------------------------|-------------------------------------------------------|
359
+ * | `"yaml"` (default) | `# …` lines | YAML workflows, ignore files, `.editorconfig`, labeler|
360
+ * | `"cjs"` | `/* … *\/` block | CommonJS config files (`.cjs`) |
361
+ * | `"shebang"` | `#!/bin/sh` + `# …` | Shell scripts (`prepare-commit-msg`, hooks) |
205
362
  */
206
- declare function generateCombinedDeployContent(deployWith: Record<string, unknown>, paths: string[], preview: Pick<PreviewConfig, "project">): string;
363
+ declare function createHeader(options: CreateHeaderOptions): HeaderFunctions;
364
+ //#endregion
365
+ //#region src/utils/default-list-dirs/default-list-dirs.d.ts
366
+ declare const defaultListDirs: (path: string) => string[];
367
+ //#endregion
368
+ //#region src/utils/default-read-json/default-read-json.d.ts
369
+ declare const defaultReadJson: (path: string) => unknown;
370
+ //#endregion
371
+ //#region src/utils/default-run/default-run.type.d.ts
372
+ interface SpawnResult {
373
+ status: number | null;
374
+ stdout: string;
375
+ stderr: string;
376
+ }
377
+ type Run = (command: string, args: string[], options: Record<string, unknown>) => SpawnResult;
378
+ //#endregion
379
+ //#region src/tasks/deploy-on-release/workspace-packages/workspace-packages.type.d.ts
380
+ /** A workspace package: absolute folder, and what its `package.json` says. */
381
+ interface WorkspacePackage {
382
+ name: string;
383
+ dir: string;
384
+ version: string | undefined;
385
+ dependencies: Record<string, string>;
386
+ }
387
+ interface Tree {
388
+ readJson: (path: string) => unknown;
389
+ listDirs: (path: string) => string[];
390
+ }
391
+ //#endregion
392
+ //#region src/tasks/deploy-on-release/workspace-packages/workspace-packages.d.ts
207
393
  /**
208
- * Expand structured with-values to flat GitHub Actions inputs before
209
- * generating the thin caller. Handles:
210
- * - deploy shorthand: docs/storybook → type + storybook-projects
211
- * - preview: stripped (handled separately via extractPreviewConfig)
212
- * - run-chromatic object → run-chromatic: true + chromatic-projects
213
- * - plain arrays → JSON-stringified for YAML scalar quoting
214
- *
215
- * Used by both `holocron setup` and `sync-workflow-templates`.
394
+ * Every package under `<repoRoot>/packages/*`, `<repoRoot>/apps/*` and
395
+ * `<repoRoot>/plugins/*` with a readable, named `package.json` — `holocron`'s
396
+ * own layout splits vendor plugin packages into `plugins/*` and deployable
397
+ * apps into `apps/*`, siblings to `packages/*`.
216
398
  */
217
- declare function normalizeWorkflowWith(raw: Record<string, unknown>): Record<string, unknown>;
399
+ declare function workspacePackages(repoRoot: string, { readJson, listDirs }: Tree): WorkspacePackage[];
400
+ //#endregion
401
+ //#region src/tasks/deploy-on-release/deploy-on-release.type.d.ts
402
+ interface DeployOnReleaseOptions {
403
+ cwd: string;
404
+ /** The release's channel: its prerelease identifier (`alpha`); empty or `main` for a stable release. */
405
+ channel: string;
406
+ /** The previous release's commit; omitted when there is none, so every deploying channel match deploys. */
407
+ from?: string;
408
+ /** The release commit. Default `HEAD`. */
409
+ to?: string;
410
+ /** Where progress lines go (stdout in the CLI). */
411
+ print: (line: string) => void;
412
+ dryRun?: boolean;
413
+ }
414
+ interface DeployOnReleaseDeps extends Partial<Tree> {
415
+ run?: Run;
416
+ sleep?: (ms: number) => Promise<void>;
417
+ now?: () => number;
418
+ /** Reads a package folder's task manifest; `loadTasksConfig` by default. */
419
+ loadTasks?: (dir: string) => Promise<TasksConfig>;
420
+ }
421
+ interface DeployOnReleaseResult {
422
+ pkg: string;
423
+ status: "ok" | "fail" | "skip" | "dry-run";
424
+ message: string;
425
+ }
426
+ interface DeployOnReleaseReport {
427
+ /** `fail` if any package's deploy failed; `skip` if none applied to this release; else `ok`. */
428
+ status: "ok" | "fail" | "skip";
429
+ results: DeployOnReleaseResult[];
430
+ }
431
+ //#endregion
432
+ //#region src/tasks/deploy-on-release/deploy-on-release.d.ts
218
433
  /**
219
- * Derive on.push.paths entries from the deploy with: shorthand.
220
- * Used by both `holocron setup` and `sync-workflow-templates`.
434
+ * Deploys every package whose manifest declares a release-time deploy that
435
+ * applies to this release. Never throws for a deploy problem: each package's
436
+ * outcome is in the report, and `status: "fail"` is the caller's exit code.
221
437
  */
222
- declare function deriveDeployPaths(raw: Record<string, unknown>): string[];
438
+ declare function deployOnRelease(options: DeployOnReleaseOptions, { run, readJson, listDirs, sleep, now, loadTasks }?: DeployOnReleaseDeps): Promise<DeployOnReleaseReport>;
223
439
  //#endregion
224
- //#region src/turbo.d.ts
225
- interface EnsureRootWorkspaceMemberResult {
226
- content: string;
227
- changed: boolean;
440
+ //#region src/tasks/group/group.type.d.ts
441
+ interface GroupOptions {
442
+ /** Print the resolved commands without running anything. */
443
+ dryRun?: boolean;
444
+ /** `turbo --filter=<pkg>` passthrough (monorepo). */
445
+ filter?: string;
446
+ }
447
+ interface GroupJobReport {
448
+ task: string;
449
+ status: "ok" | "fail" | "skip" | "dry-run";
450
+ command?: string;
451
+ message?: string;
452
+ }
453
+ interface GroupReport {
454
+ /** `"unknown"` when the namespace matches zero configured tasks. */
455
+ status: "ok" | "fail" | "dry-run" | "unknown";
456
+ jobs: GroupJobReport[];
457
+ }
458
+ interface GroupInput extends RunDeps, GroupOptions {
459
+ cwd: string;
460
+ config: TasksConfig;
461
+ /** The bare namespace, e.g. `"sourceQuality"` — matched against `"sourceQuality."`-prefixed task names. */
462
+ namespace: string;
228
463
  }
229
464
  //#endregion
230
- //#region src/astromech.d.ts
465
+ //#region src/tasks/group/group.d.ts
466
+ declare function runGroup(input: GroupInput): GroupReport;
467
+ //#endregion
468
+ //#region src/tasks/match-namespace/match-namespace.d.ts
469
+ /** Every configured task whose name starts with `"<namespace>."`, in manifest declaration order. */
470
+ declare function matchNamespace(config: TasksConfig, namespace: string): string[];
471
+ //#endregion
472
+ //#region src/astromech.type.d.ts
231
473
  interface AstromechOptions {
232
474
  /** Repo root. */
233
475
  cwd: string;
@@ -272,8 +514,15 @@ interface RunOptions {
272
514
  filter?: string;
273
515
  }
274
516
  interface Astromech {
275
- /** Run one task — or one of its sub-jobs (`opts.job`) — locally. */
276
- run(task: string, opts?: RunOptions): RunTaskReport;
517
+ /**
518
+ * Run one task — or one of its sub-jobs (`opts.job`) — locally. When
519
+ * `task` isn't an exact registry task but matches the prefix of one or
520
+ * more configured tasks (`"sourceQuality"` against `sourceQuality.*`),
521
+ * runs every matching task in sequence instead ({@link GroupReport}) —
522
+ * `opts.job` is ignored for a namespace match, since a job belongs to
523
+ * one task, not a namespace.
524
+ */
525
+ run(task: string, opts?: RunOptions): RunTaskReport | GroupReport;
277
526
  /**
278
527
  * Run the merge-gating checks locally, in CI order — "will CI pass?".
279
528
  * Default scope: `required: true` tasks (falls back to every `ci: true`
@@ -288,7 +537,7 @@ interface Astromech {
288
537
  */
289
538
  thinCallers(): Map<string, string>;
290
539
  /**
291
- * The complete reusable-workflow batch `holocron sync-github` pushes to
540
+ * The complete reusable-workflow batch `holocron sync github` pushes to
292
541
  * `theholocron/.github` — repo-relative path → content, "do not edit" header
293
542
  * already applied to the YAML. Config-independent (the same for every repo).
294
543
  */
@@ -301,10 +550,19 @@ interface Astromech {
301
550
  * when there is no config or `syncScripts: false`.
302
551
  */
303
552
  packageScripts(): Record<string, string>;
553
+ /**
554
+ * Task names this repo's manifest can actually run locally — the same
555
+ * filter {@link packageScripts} applies (skips `local: false` and tasks
556
+ * with no local runner at all), but independent of `syncScripts`: a repo
557
+ * that opts out of generated `package.json` scripts still has real
558
+ * runnable tasks. Empty when there is no config. Backs `holocron`'s own
559
+ * interactive task picker (`run` with no task given).
560
+ */
561
+ runnableTasks(): string[];
304
562
  /**
305
563
  * The branch-protection required-status-check contexts for this repo —
306
564
  * every `required: true` task's check context plus `extraRequiredChecks`,
307
- * ordered and de-duplicated. `holocron setup` prepends `"DCO"` and applies
565
+ * ordered and de-duplicated. `holocron repo setup` prepends `"DCO"` and applies
308
566
  * the list; this method is policy-free (manifest only).
309
567
  */
310
568
  requiredChecks(): string[];
@@ -312,7 +570,7 @@ interface Astromech {
312
570
  * This repo's `codecov.yml` — component `paths` derived from `packages/*`.
313
571
  * Pass the current file's content (`null` if none exists yet) to either
314
572
  * merge the component list in or scaffold a fresh file. Policy-free same
315
- * as {@link requiredChecks} — `holocron setup` owns writing the result.
573
+ * as {@link requiredChecks} — `holocron repo setup` owns writing the result.
316
574
  */
317
575
  codecovConfig(existing: string | null): string;
318
576
  /**
@@ -328,151 +586,30 @@ interface Astromech {
328
586
  * (not just an orchestrator) silently vanishes from `turbo run <task>`.
329
587
  * Pass `pnpm-workspace.yaml`'s current content (or `""` if none exists —
330
588
  * a no-op either way, since no `packages:` key means single-package mode
331
- * already) and root `package.json`'s own `scripts` keys. `changed: false`
332
- * means don't write anything — the file is already correct.
589
+ * already) and root `package.json`'s own `scripts` object — values and
590
+ * all, not just keys, so a task-name-matching script that's already the
591
+ * generated `holocron run <task> --` wrapper (predating this call, not
592
+ * written by it) is correctly excluded rather than treated as proof root
593
+ * is directly buildable (#846). `changed: false` means don't write
594
+ * anything — the file is already correct.
333
595
  */
334
- ensureRootWorkspaceMember(workspaceYaml: string, rootScripts: readonly string[]): EnsureRootWorkspaceMemberResult;
335
- }
336
- declare function createAstromech(options: AstromechOptions): Astromech;
337
- //#endregion
338
- //#region src/codecov.d.ts
339
- /**
340
- * `codecov.yml` generation — a manifest-derived artifact (component `paths`
341
- * come from workspace packages; the status targets track the `test` task's
342
- * coverage setup), the same category as the reusable `test.yml` this package
343
- * also generates. Moved out of `@theholocron/cli` (theholocron/holocron#650)
344
- * — `holocron setup`'s codecov step now calls {@link codecovConfig} instead
345
- * of importing this logic directly.
346
- */
347
- interface WorkspacePackage {
348
- slug: string;
349
- name: string;
350
- /** Which workspace root the package was discovered under. Defaults to `"packages"`. */
351
- dir?: "packages" | "apps";
352
- }
353
- declare function codecovComponentBlock(packages: WorkspacePackage[]): string;
354
- /**
355
- * Ensure every codecov status default carries `if_not_found: success`, so an
356
- * infra-only PR (dep bump, config, lockfile — no coverable change) passes
357
- * instead of hanging forever on a required check codecov never posts.
358
- *
359
- * Injects the key on the line after each `target:` that sits inside a status
360
- * block (`coverage.status.*.default` or a `statuses:` list item — indent ≥ 8,
361
- * or ≥ 8 for a `- type:` list entry), when the immediate sibling lines do not
362
- * already declare it.
363
- */
364
- declare function ensureIfNotFound(yaml: string): string;
365
- declare function mergeCodecovComponents(existing: string, packages: WorkspacePackage[]): string;
366
- /**
367
- * Every public `packages/*` and `apps/*` workspace, sorted by slug. `[]`
368
- * when neither directory exists. Monorepo templates (Next.js, React, …)
369
- * ship user-facing code under `apps/` alongside library code under
370
- * `packages/` — both need a codecov component so `codecov/patch/<slug>`
371
- * actually posts for each.
372
- */
373
- declare function readWorkspacePackages(repoRoot: string): WorkspacePackage[];
374
- /** A brand-new `codecov.yml` — the scaffold header + the base template + this repo's component list. */
375
- declare function createCodecovConfig(packages: WorkspacePackage[]): string;
376
- /**
377
- * The full pipeline `holocron setup` needs: read this repo's public
378
- * `packages/*`, then either merge them into an `existing` `codecov.yml` or
379
- * scaffold a new one.
380
- */
381
- declare function codecovConfig(repoRoot: string, existing: string | null): string;
382
- //#endregion
383
- //#region src/linters.d.ts
384
- /**
385
- * The linter registry — one list of linter names (from `config.tasks`'
386
- * `{ name: "lint", linters: [...] }`, or auto-detected) maps to both the
387
- * CI super-linter `VALIDATE_*` env and the native local run. This table is
388
- * the single source of truth for that mapping; {@link superLinterConfig}
389
- * (CI) and the `holocron run lint` aggregate (local) both read it.
390
- *
391
- * Spec: `docs/wiki/specifications/tech-astromech-task-runner.spec.md` "Lint parity".
392
- */
393
- interface LinterDef {
596
+ ensureRootWorkspaceMember(workspaceYaml: string, rootScripts: Readonly<Record<string, string>>): EnsureRootWorkspaceMemberResult;
394
597
  /**
395
- * super-linter `VALIDATE_*` keys this linter turns on. Setting any
396
- * `VALIDATE_*` puts super-linter in allow-list mode, so emitting only the
397
- * enabled keys makes it run exactly this set.
598
+ * `turboConfig()` writes a `turbo.json` but never touches `package.json`
599
+ * — a repo with no local `turbo` devDependency falls back to whatever
600
+ * (if anything) is globally on `PATH`, per `run.ts`'s `resolveBin()`.
601
+ * Pass root `package.json`'s raw content and `pnpm-workspace.yaml`'s
602
+ * current content (checked for an existing `turbo` catalog entry, which
603
+ * takes precedence over the hardcoded fallback version). `changed: false`
604
+ * means don't write anything — `devDependencies.turbo` already exists.
398
605
  */
399
- validate: string[];
400
- /** super-linter `FIX_*` keys (auto-commit / `--write` parity). */
401
- fix?: string[];
402
- /**
403
- * Local binary, resolved from `node_modules/.bin` then `PATH`. Absent →
404
- * the linter has no meaningful local run (`holocron run lint` prints
405
- * "CI only"); CI still enforces it.
406
- */
407
- localBin?: string;
408
- /** Args for `localBin` in CHECK mode — never `--write` / `--fix`. */
409
- localArgs?: string[];
410
- /**
411
- * Shown by `holocron run lint` when `localBin` is set but not found on
412
- * PATH — the "you're missing a tool the repo needs" nudge.
413
- */
414
- installHint?: string;
415
- /**
416
- * Repo-root filenames that auto-enable this linter when the `lint` task
417
- * has no explicit `linters` list. Ignored when {@link always} is set.
418
- */
419
- detect?: string[];
420
- /** Enabled regardless of detection (the org baseline). */
421
- always?: boolean;
422
- /** Reusable-workflow config-file input this linter honors, if any. */
423
- configInput?: "eslint-config" | "prettier-config" | "yaml-config";
606
+ ensureTurboDependency(packageJson: string, workspaceYaml: string): EnsureTurboDependencyResult;
424
607
  }
425
- /**
426
- * Known linters, in execution order. `always` entries are the current
427
- * hard-coded super-linter baseline; `prettier` is always-on because the org
428
- * applies it universally (super-linter only lints files that exist).
429
- */
430
- declare const LINTERS: Record<string, LinterDef>;
431
- /** Every linter name the registry knows. */
432
- declare const LINTER_NAMES: ReadonlySet<string>;
433
- /**
434
- * Resolve the linter set for a repo. An `explicit` list (from `config.tasks`)
435
- * picks the candidate set; otherwise the candidates are every `always` linter
436
- * plus every `detect`-gated linter whose filenames are present at the repo
437
- * root. Either way, a `detect`-gated linter (eslint, markdownlint) only makes
438
- * the final set when its config file is actually present — a repo can't run
439
- * eslint without an `eslint.config.*`, and super-linter FATALs if you ask it
440
- * to (theholocron/holocron#654). `always` linters are unconditional. Result
441
- * is ordered by {@link LINTERS} declaration order.
442
- *
443
- * @throws when an `explicit` name is not in the registry — a typo is a
444
- * config bug, not a linter to silently skip.
445
- */
446
- declare function resolveLinters(opts: {
447
- explicit?: string[];
448
- rootFiles: string[];
449
- }): Array<{
450
- name: string;
451
- def: LinterDef;
452
- }>;
453
608
  //#endregion
454
- //#region src/registry.d.ts
455
- /**
456
- * The task registry — how each task runs *locally*, without GitHub
457
- * Actions. `holocron run <task>` and `holocron ci` resolve against this;
458
- * adding a task here gives every repo that task.
459
- *
460
- * Keyed identically to the workflow templates — a task IS a workflow. This
461
- * is the canonical vocabulary table (epic #672, D11): every other artifact
462
- * (`KNOWN_TASKS`, `thin-callers.ts`'s `KNOWN_WORKFLOWS`/`WORKFLOW_CHECK_CONTEXTS`,
463
- * `CI_ORDER`) derives from these keys rather than hand-duplicating them —
464
- * including the future GitHub App (#679), which imports this same table for
465
- * config-schema validation instead of reimplementing its own copy.
466
- *
467
- * Task names are an intent-facing vocabulary (`verification.*`,
468
- * `sourceQuality.*`, `security.*`, `delivery.*`, `platform.*`,
469
- * `knowledge.*`), not tool names — `eslint`/`vitest`/`tsdown`/… stay
470
- * internal to this file and `theholocron/configs`. See
471
- * `.notes/tech-vocabulary-rename.spec.md` (#675) for the full mapping and
472
- * the reasoning behind each namespace and decomposition.
473
- *
474
- * Spec: `docs/wiki/specifications/tech-astromech-task-runner.spec.md` (epic #581).
475
- */
609
+ //#region src/astromech.d.ts
610
+ declare function createAstromech(options: AstromechOptions): Astromech;
611
+ //#endregion
612
+ //#region src/registry/registry.type.d.ts
476
613
  /** How to run one task (or job) locally. */
477
614
  interface LocalRunner {
478
615
  /** Binary to invoke — resolved from `node_modules/.bin` then PATH. */
@@ -511,7 +648,7 @@ interface JobDef {
511
648
  /**
512
649
  * The CI status-check context this job reports as (e.g.
513
650
  * `platform.repoValidation / Validate registry consistency`) — every sub-job is a CI job.
514
- * `holocron run <task>` and `holocron ci` label each job line with it;
651
+ * `holocron run <task>` and `holocron run ci` label each job line with it;
515
652
  * the task-level `… / Conclusion` context (only for tasks with several
516
653
  * jobs) lives in `WORKFLOW_CHECK_CONTEXTS`.
517
654
  */
@@ -522,7 +659,7 @@ interface TaskDef {
522
659
  * `null` — the registry has no built-in runner (CodeQL, deploys, the
523
660
  * bundle-size job). An explicit turbo task or `package.json` script still
524
661
  * runs (resolution steps 1–2); with neither, `holocron run` does nothing
525
- * and `holocron ci` skips it — never a failure, even when the task is
662
+ * and `holocron run ci` skips it — never a failure, even when the task is
526
663
  * `required` (a CI-only check isn't a local one).
527
664
  */
528
665
  local: LocalRunner | null;
@@ -548,155 +685,124 @@ interface TaskDef {
548
685
  /** Turborepo fan-out config for this task — see {@link TurboTaskConfig}. Omitted for whole-repo, non-fan-out tasks. */
549
686
  turbo?: TurboTaskConfig;
550
687
  }
688
+ //#endregion
689
+ //#region src/registry/registry.d.ts
690
+ /**
691
+ * The task registry — how each task runs *locally*, without GitHub
692
+ * Actions. `holocron run <task>` and `holocron run ci` resolve against this;
693
+ * adding a task here gives every repo that task.
694
+ *
695
+ * Keyed identically to the workflow templates — a task IS a workflow. This
696
+ * is the canonical vocabulary table (epic #672, D11): every other artifact
697
+ * (`KNOWN_TASKS`, `thin-callers.ts`'s `KNOWN_WORKFLOWS`/`WORKFLOW_CHECK_CONTEXTS`,
698
+ * `CI_ORDER`) derives from these keys rather than hand-duplicating them —
699
+ * including the future GitHub App (#679), which imports this same table for
700
+ * config-schema validation instead of reimplementing its own copy.
701
+ *
702
+ * Task names are an intent-facing vocabulary (`verification.*`,
703
+ * `sourceQuality.*`, `security.*`, `delivery.*`, `platform.*`,
704
+ * `knowledge.*`), not tool names — `eslint`/`vitest`/`tsdown`/… stay
705
+ * internal to this file and `theholocron/configs`. See
706
+ * `docs/wiki/specifications/tech-vocabulary-rename.spec.md` (#675) for the full mapping and
707
+ * the reasoning behind each namespace and decomposition.
708
+ *
709
+ * Spec: `docs/wiki/specifications/tech-astromech-task-runner.spec.md` (epic #581).
710
+ */
551
711
  declare const TASKS: Record<string, TaskDef>;
552
712
  /** Every task name the registry knows. */
553
713
  declare const KNOWN_TASKS: Set<string>;
554
714
  /**
555
- * The order `holocron ci` runs tasks in — cheapest / fastest signal first, so
715
+ * The order `holocron run ci` runs tasks in — cheapest / fastest signal first, so
556
716
  * an agent or a `pre-push` hook fails early. Tasks not listed here run last, in
557
717
  * manifest order. (The generated thin callers carry no `needs:` — cross-workflow
558
- * ordering lives in `theholocron/.github` — so `holocron ci` declares its own.)
718
+ * ordering lives in `theholocron/.github` — so `holocron run ci` declares its own.)
559
719
  */
560
720
  declare const CI_ORDER: string[];
561
721
  //#endregion
562
- //#region src/required-checks.d.ts
563
- /** Ordered (task contexts in {@link CI_ORDER}, then extras), de-duplicated. */
564
- declare function requiredChecks(config: TasksConfig): string[];
565
- //#endregion
566
- //#region src/resolver.d.ts
722
+ //#region src/tasks/deploy-on-release/default-paths/default-paths.d.ts
567
723
  /**
568
- * Resolves the absolute path to a Bucket A tool's shared `@theholocron/*-config`
569
- * entry point, installed in the consuming repo's own `node_modules` — and the
570
- * CLI flag(s) to hand it via (`--config`, `--extends`, …). `run.ts` splices the
571
- * result into the command it builds for a tool/detect runner or a linter-group
572
- * entry, right after the tool's own args.
573
- *
574
- * Every mapped package's resolved entry point already carries a ready-to-use
575
- * default export (a plain re-export for `prettier`/`commitlint`; an invoked,
576
- * zero-arg preset for `eslint`/`vitest`/`tsdown` — verified end-to-end against
577
- * each tool's real `--config`/`--extends` loader, not just the file's shape).
578
- * A repo doesn't need this package installed at all — every lookup degrades to
579
- * `[]` (no flag added, the tool falls back to its own auto-discovery of a
580
- * local file, unchanged from today) rather than throwing, so this is additive
581
- * and safe to run unconditionally.
724
+ * The paths a release must touch to redeploy `pkg` when its manifest doesn't
725
+ * list them: its own folder plus the folder of every
726
+ * {@link workspaceDependencies} entry. Derived rather than listed so a new or
727
+ * dropped workspace dependency needs no second edit.
582
728
  *
583
- * `semantic-release`, `devmoji`, `editorconfig-checker`, and `knip` are
584
- * deliberately absent — `semantic-release-config`'s `defineConfig()` needs
585
- * real per-repo data (branches, npm options) a static `--extends <path>` can't
586
- * carry; `devmoji` runs through a git hook template, not `holocron run
587
- * <task>`; `editorconfig-checker` has no shared-config package yet; `knip` is
588
- * repo-specific by nature, never a shared-config candidate. See
589
- * `.notes/tech-config-resolution.spec.md` (#676).
590
- */
591
- interface ResolverDeps {
592
- readFile: (path: string) => string;
593
- fileExists: (path: string) => boolean;
594
- }
595
- /** Every tool name the resolver knows how to point at a shared config. */
596
- declare const RESOLVABLE_TOOLS: ReadonlySet<string>;
597
- /**
598
- * `<flag> <absolute path>` for `tool`, resolved against `cwd`'s
599
- * `node_modules` — or `[]` when the tool isn't mapped, the package isn't
600
- * installed, its `package.json` doesn't declare the export subpath this
601
- * needs, or the resolved file doesn't actually exist on disk (a stale
602
- * install, or a package version that predates the export existing).
729
+ * @returns Repo-relative prefixes, each ending in `/`.
603
730
  */
604
- declare function resolveToolConfig(tool: string, cwd: string, deps: ResolverDeps): string[];
731
+ declare function defaultPaths(repoRoot: string, pkg: WorkspacePackage, all: WorkspacePackage[]): string[];
605
732
  //#endregion
606
- //#region src/reusable.d.ts
733
+ //#region src/templates/configs/alexjs/create-config.d.ts
734
+ declare function createRcConfig(): string;
735
+ declare function createIgnoreConfig(): string;
736
+ //#endregion
737
+ //#region src/templates/configs/commit-msg/create-config.d.ts
607
738
  /**
608
- * The **reusable** GitHub Actions surface pushed to `theholocron/.github` by
609
- * `holocron sync-github` — the `workflow_call` implementations and composite
610
- * actions that every repo's thin callers delegate to.
739
+ * `.husky/commit-msg` — lints the commit message via `holocron run lint
740
+ * commit-msg` (holocron#789), the real programmatic replacement for
741
+ * shelling out to `commitlint --edit`. Installed by `holocron repo setup` when
742
+ * hooks are enabled. Same `__HOLOCRON_SCRIPT__` substitution as `pre-push`.
611
743
  *
612
- * `theholocron/.github` is a **pure sync target**: `.github/workflows/*`,
613
- * `.github/actions/*` and `workflow-templates/*` there are generated from the
614
- * `.yml` files in `src/templates/reusable/` and pushed verbatim (with a
615
- * "do not edit" header). Never hand-edit them in `.github`.
616
- *
617
- * Not to be confused with `WORKFLOW_TEMPLATES` in `thin-callers.ts` — those are
618
- * the *thin-caller bases* written into each consumer repo's `.github/workflows/`.
744
+ * @param holocronScript - the command that invokes the CLI. Defaults to
745
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
619
746
  */
620
- /** `workflow_call` implementations → `.github/workflows/<name>.yml`. */
621
- declare const REUSABLE_WORKFLOWS: Record<string, string>;
622
- /** Composite actions → `.github/actions/<name>/action.yml` (key includes `/action`). */
623
- declare const REUSABLE_ACTIONS: Record<string, string>;
624
- /** GitHub starter-workflow metadata → `workflow-templates/<name>.properties.json`. */
625
- declare const WORKFLOW_TEMPLATE_PROPERTIES: Record<string, string>;
747
+ declare function createConfig(holocronScript?: string): string;
748
+ //#endregion
749
+ //#region src/templates/configs/dependabot/create-config.d.ts
750
+ declare function createConfig$1(): string;
751
+ //#endregion
752
+ //#region src/templates/configs/devmoji/create-config.d.ts
753
+ declare function createConfig$2(): string;
754
+ //#endregion
755
+ //#region src/templates/configs/editorconfig/create-config.d.ts
756
+ declare function createConfig$3(): string;
757
+ //#endregion
758
+ //#region src/templates/configs/editorconfig-checker/create-config.d.ts
626
759
  /**
627
- * The complete file batch `holocron sync-github` pushes to `theholocron/.github`:
628
- * path → content. YAML gets the "do not edit" header; the starter-workflow
629
- * `.properties.json` files are left bare (native JSON, not a commented file).
760
+ * The generated `.editorconfig-checker.json`.
761
+ *
762
+ * Deliberately carries no `"Version"` key: editorconfig-checker treats it as a
763
+ * hard gate and exits non-zero the moment the running binary's version differs
764
+ * — which it does the instant a contributor's local install (Homebrew tracks
765
+ * latest) drifts from the version super-linter bundles in CI, breaking
766
+ * `holocron run lint` / the pre-push hook for everyone (#618). The config
767
+ * options here (`Exclude`, `Disable`) are stable across releases, so pinning
768
+ * buys nothing.
630
769
  */
631
- declare function reusableTemplates(): Map<string, string>;
770
+ declare function createConfig$4(): string;
632
771
  //#endregion
633
- //#region src/tsconfig.d.ts
772
+ //#region src/templates/configs/labeler/create-config.d.ts
773
+ declare function createConfig$5(): string;
774
+ //#endregion
775
+ //#region src/templates/configs/pre-commit/create-config.d.ts
634
776
  /**
635
- * `tsconfig.json` generation — Bucket B (config-resolution workstream, #676):
636
- * the file must stay committed (the TypeScript language server discovers it
637
- * directly from disk, no `--config` override mechanism to hand it a path
638
- * instead), but its content is fully derivable, so it's generated rather
639
- * than hand-authored — the same category as `.editorconfig`
640
- * ({@link "./templates/configs/editorconfig/create-config.js" createConfig})
641
- * and {@link codecovConfig}.
642
- *
643
- * Surveyed every package-level `tsconfig.json` across the org (`holocron`,
644
- * `clients`, `utils` — 20+ packages). `extends: "@theholocron/tsconfig/
645
- * node-lts"`, `compilerOptions.baseUrl: "./"`, `compilerOptions.outDir:
646
- * "./dist"`, `include: ["src/**\/*.ts"]`, and `exclude: ["node_modules",
647
- * "dist"]` are uniform in every one — safe defaults here. `paths` (a `@/*`
648
- * → `./src/*` import alias) is a real per-package choice, present in
649
- * roughly 40% of packages checked — an opt-in parameter, not a default.
650
- *
651
- * Two fields checked and deliberately *not* absorbed as defaults, unlike
652
- * `eslint-config`'s `tsconfigRootDir`/`settings.node` (which turned out
653
- * redundant with the shared package's own behavior, `configs`#461):
654
- * `compilerOptions.module`/`moduleResolution` (only `@theholocron/cli`
655
- * overrides these, to `esnext`/`bundler` — a genuine deviation from the
656
- * shared `node-lts` preset's `nodenext`/`nodenext`, needed for its bundler
657
- * tooling, not something every package should inherit) and
658
- * `compilerOptions.rootDir` (present in exactly two packages, always the
659
- * same value `./src` that `include` already implies — an unnecessary
660
- * override wherever it appears, not a pattern worth generalizing).
777
+ * `.husky/pre-commit` — runs GitLeaks (scoped to staged changes) and
778
+ * lint-staged before every commit. Installed by `holocron repo setup` when hooks
779
+ * are enabled (default for `protection: "strict"`). `git commit --no-verify`
780
+ * bypasses it.
661
781
  *
662
- * Monorepo *root* `tsconfig.json` (a TS project-references "solution
663
- * file" — `holocron`'s own root is `{ files: [], references: [...] }`,
664
- * listing which packages to build) is a structurally different, genuinely
665
- * per-repo document — out of scope here, same as Bucket C content.
666
- *
667
- * Not yet wired into `holocron setup`'s per-package write loop (every
668
- * other Bucket B file there is a single repo-root file, safely
669
- * overwritten every run — `tsconfig.json` is per-package, and most
670
- * packages' files still carry real hand-authored content today, not yet
671
- * migrated to a fully-generated state). That per-package iteration +
672
- * safe-migration design is `#680`'s job, not duplicated here — this is
673
- * the generator itself, ready for it to call.
782
+ * `gitleaks protect --staged` (not `gitleaks git`) is deliberate: the latter
783
+ * scans the entire commit history on every invocation, so once any false
784
+ * positive lands in a past commit — a fake test token, an example key in a
785
+ * doc — every future commit is permanently blocked, regardless of what's
786
+ * actually staged.
674
787
  */
675
- interface TsconfigOptions {
676
- /** Human-readable name for the `display` field — the package's own name is the usual choice. */
677
- display: string;
678
- /**
679
- * `@theholocron/tsconfig` variant. Defaults to `"node-lts"` — every
680
- * checked package uses it; the other three (`astro`, `nextjs`, `react`)
681
- * exist for a template repo's app-shaped packages, not the plain
682
- * Node.js library packages this org's currently-migrated repos ship.
683
- */
684
- variant?: "astro" | "nextjs" | "node-lts" | "react";
685
- /**
686
- * Add a `@/*` → `./src/*` path alias. A real per-package choice, not a
687
- * default — roughly 40% of packages checked use one, the rest don't.
688
- */
689
- paths?: boolean;
690
- }
788
+ declare function createConfig$6(): string;
789
+ //#endregion
790
+ //#region src/templates/configs/pre-push/create-config.d.ts
691
791
  /**
692
- * A package-level `tsconfig.json` — the uniform shape confirmed across
693
- * every package checked, parameterized only by the two fields that
694
- * genuinely vary (`display`, `paths`). No scaffold/workflow header (matches
695
- * `.alexrc.json`'s existing precedent for a strict-JSON Bucket B file —
696
- * JSON has no comment syntax to carry one, and TypeScript's own tolerance
697
- * for JSONC comments in `tsconfig.json` isn't worth relying on for a file
698
- * this thin).
792
+ * `.husky/pre-push` — runs `holocron run ci` (the merge-gating checks, in CI order)
793
+ * before every push. Installed by `holocron repo setup` when hooks are enabled
794
+ * (default for `protection: "strict"`). `git push --no-verify` bypasses it.
795
+ *
796
+ * @param holocronScript - the command that invokes the CLI. Defaults to
797
+ * `pnpm exec holocron`; the source repo passes `node packages/cli/dist/cli.mjs`.
699
798
  */
700
- declare function createTsconfig(options: TsconfigOptions): string;
799
+ declare function createConfig$7(holocronScript?: string): string;
800
+ //#endregion
801
+ //#region src/templates/configs/prepare-commit-msg/create-config.d.ts
802
+ declare function createConfig$8(): string;
803
+ //#endregion
804
+ //#region src/templates/configs/yamllint/create-config.d.ts
805
+ declare function createConfig$9(): string;
806
+ declare function createIgnoreConfig$1(): string;
701
807
  //#endregion
702
- export { type Astromech, type AstromechOptions, CI_ORDER, type CiJobReport, type CiOptions, type CiReport, type ExecFn, type JobDef, KNOWN_TASKS, KNOWN_WORKFLOWS, LINTERS, LINTER_NAMES, type LinterDef, type LocalRunner, type OrgContext, type PreviewConfig, RESOLVABLE_TOOLS, REUSABLE_ACTIONS, REUSABLE_WORKFLOWS, type ResolverDeps, 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, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, resolveLinters, resolveToolConfig, reusableTemplates, runCi, runTask };
808
+ export { type Astromech, type AstromechOptions, CI_ORDER, type CiJobReport, type CiOptions, type CiReport, type CreateHeaderOptions, type DeployOnReleaseOptions, type DeployOnReleaseReport, type DeployOnReleaseResult, type WorkspacePackage as DeployWorkspacePackage, 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$1 as 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, defaultListDirs, defaultPaths, defaultReadJson, deployOnRelease, deriveDeployPaths, ensureIfNotFound, extractPreviewConfig, generateCombinedDeployContent, generateThinCallerContent, matchNamespace, mergeCodecovComponents, normalizeWorkflowWith, readWorkspacePackages, requiredChecks, reusableTemplates, runCi, runGroup, runTask, workspacePackages };