@theholocron/astromech 4.19.0 → 5.0.0-alpha.100
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 +99 -84
- package/dist/config/index.d.mts +17 -2
- package/dist/config/index.mjs +13 -3
- package/dist/index.d.mts +254 -106
- package/dist/index.mjs +708 -251
- package/dist/{schema-BegK4MsY.d.mts → schema-D01VYg43.d.mts} +11 -7
- package/package.json +11 -12
package/dist/index.d.mts
CHANGED
|
@@ -1,32 +1,33 @@
|
|
|
1
|
-
import { r as TasksConfig } from "./schema-
|
|
1
|
+
import { r as TasksConfig } from "./schema-D01VYg43.mjs";
|
|
2
2
|
//#region src/run.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* `holocron run <task> [job] [-- <passthrough>]` — run a registry task (or one
|
|
5
5
|
* of its sub-jobs) locally.
|
|
6
6
|
*
|
|
7
|
-
* A `job` argument only applies to tasks that declare `jobs
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* audit` runs every job in declared order.
|
|
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/`).
|
|
11
10
|
*
|
|
12
11
|
* Resolution:
|
|
13
12
|
*
|
|
14
|
-
* 0. task === "lint" (no job) → the linter aggregate (see below)
|
|
15
13
|
* J. job given → TASKS[task].jobs[job].local (unknown job → exit 1)
|
|
16
14
|
* 1. turbo.json defines the task → `turbo run <task>`
|
|
17
15
|
* 2. package.json has a `<task>` script → `<pm> run <task>`
|
|
18
16
|
* (unless it's the `holocron run …` thin caller — that recurses)
|
|
19
17
|
* 3. TASKS[task].local resolves → `<tool> <args> <org-flags> <passthrough>`
|
|
18
|
+
* 3b. TASKS[task].linterGroup → run each resolved linter natively (see below)
|
|
20
19
|
* 4. TASKS[task].jobs has entries → run each job in declared order
|
|
21
20
|
* 5. TASKS[task].local === null → "enforced in CI" (skip, even with --required)
|
|
22
21
|
* 5b. known task, nothing resolved → "no <task> task" (exit 0, or 1 with --required)
|
|
23
22
|
* 6. unknown task → "unknown task" (exit 1)
|
|
24
23
|
*
|
|
25
|
-
* `
|
|
26
|
-
*
|
|
27
|
-
* `
|
|
28
|
-
*
|
|
29
|
-
*
|
|
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.
|
|
30
31
|
*/
|
|
31
32
|
/** Minimal structural logger — `@theholocron/observability`'s `Logger` satisfies it. */
|
|
32
33
|
interface RunLogger {
|
|
@@ -70,8 +71,6 @@ interface RunTaskInput extends RunDeps {
|
|
|
70
71
|
dryRun?: boolean;
|
|
71
72
|
/** Turn "no such task for this repo" (normally exit 0) into a failure. */
|
|
72
73
|
required?: boolean;
|
|
73
|
-
/** The `lint` task's explicit linter list from `config.tasks`, if any. */
|
|
74
|
-
linters?: string[];
|
|
75
74
|
/** `turbo --filter=<pkg>` passthrough (monorepo). Ignored when the repo has no `turbo.json`. */
|
|
76
75
|
filter?: string;
|
|
77
76
|
}
|
|
@@ -107,68 +106,9 @@ interface CiReport {
|
|
|
107
106
|
interface CiInput extends RunDeps, CiOptions {
|
|
108
107
|
cwd: string;
|
|
109
108
|
config: TasksConfig;
|
|
110
|
-
/** Explicit linter list for the `lint` task (the config's lint entry `linters`). */
|
|
111
|
-
linters?: string[];
|
|
112
109
|
}
|
|
113
110
|
declare function runCi(input: CiInput): CiReport;
|
|
114
111
|
//#endregion
|
|
115
|
-
//#region src/super-linter.d.ts
|
|
116
|
-
/**
|
|
117
|
-
* `superLinterConfig()` — turn the resolved linter set into the exact
|
|
118
|
-
* super-linter `VALIDATE_*` / `FIX_*` env the CI `lint` job needs. The CLI
|
|
119
|
-
* serializes {@link SuperLinterConfig.env} as the `super-linter-env` input
|
|
120
|
-
* on each repo's generated `lint` thin caller; the reusable workflow
|
|
121
|
-
* expands it verbatim. This is the CI half of "lint parity" — the local
|
|
122
|
-
* half is the `holocron run lint` aggregate, driven by the same
|
|
123
|
-
* {@link resolveLinters}.
|
|
124
|
-
*/
|
|
125
|
-
interface SuperLinterConfig {
|
|
126
|
-
/**
|
|
127
|
-
* Enabled `VALIDATE_*` / `FIX_*` keys → `"true"`. Only enabled keys are
|
|
128
|
-
* present (super-linter allow-list mode). Ready for `JSON.stringify`.
|
|
129
|
-
*/
|
|
130
|
-
env: Record<string, string>;
|
|
131
|
-
/** Resolved linter names in execution order — for the human-readable comment. */
|
|
132
|
-
linters: string[];
|
|
133
|
-
/** Config-file inputs the resolved set honors (`eslint-config`, …). */
|
|
134
|
-
configInputs: Partial<Record<"eslint-config" | "prettier-config" | "yaml-config", true>>;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Resolve the super-linter env for a repo's `lint` task.
|
|
138
|
-
*
|
|
139
|
-
* @param opts.explicit the task's `linters` list, if any (else auto-detect)
|
|
140
|
-
* @param opts.rootFiles repo-root filenames (from `listDir(cwd)`)
|
|
141
|
-
* @param opts.includeFix emit `FIX_*` keys too (default `true`)
|
|
142
|
-
*/
|
|
143
|
-
declare function superLinterConfig(opts: {
|
|
144
|
-
explicit?: string[];
|
|
145
|
-
rootFiles: string[];
|
|
146
|
-
includeFix?: boolean;
|
|
147
|
-
}): SuperLinterConfig;
|
|
148
|
-
/**
|
|
149
|
-
* The always-on baseline env — every `always` linter, no detection. This is
|
|
150
|
-
* what the reusable `lint.yml`'s `super-linter-env` input defaults to, so a
|
|
151
|
-
* repo whose thin caller has not been re-synced yet behaves exactly as before.
|
|
152
|
-
*/
|
|
153
|
-
declare function baselineSuperLinterEnv(): Record<string, string>;
|
|
154
|
-
/**
|
|
155
|
-
* The `lint` thin caller's `with:` overrides + the `# linters: …` comment,
|
|
156
|
-
* from the resolved linter set. Shared by `createAstromech().thinCallers()`
|
|
157
|
-
* and the CLI's `sync` / `setup` workflow writers so the three stay in step.
|
|
158
|
-
*
|
|
159
|
-
* @param opts.explicit the `lint` task's `linters` list, if any
|
|
160
|
-
* @param opts.rootFiles repo-root filenames (auto-detect fallback)
|
|
161
|
-
* @param opts.extra per-repo `with:` overrides that win over the defaults
|
|
162
|
-
*/
|
|
163
|
-
declare function lintThinCallerWith(opts: {
|
|
164
|
-
explicit?: string[];
|
|
165
|
-
rootFiles: string[];
|
|
166
|
-
extra?: Record<string, unknown>;
|
|
167
|
-
}): {
|
|
168
|
-
withOverrides: Record<string, unknown>;
|
|
169
|
-
comments: Record<string, string>;
|
|
170
|
-
};
|
|
171
|
-
//#endregion
|
|
172
112
|
//#region src/thin-callers.d.ts
|
|
173
113
|
/**
|
|
174
114
|
* Workflow templates + thin-caller generation.
|
|
@@ -183,10 +123,17 @@ declare const KNOWN_WORKFLOWS: Set<string>;
|
|
|
183
123
|
* The GitHub status-check context a `required` task contributes to branch
|
|
184
124
|
* protection. Format: `"{workflow name} / {job name}"`.
|
|
185
125
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
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.
|
|
190
137
|
*/
|
|
191
138
|
declare const WORKFLOW_CHECK_CONTEXTS: Partial<Record<string, string>>;
|
|
192
139
|
/**
|
|
@@ -274,6 +221,16 @@ declare function normalizeWorkflowWith(raw: Record<string, unknown>): Record<str
|
|
|
274
221
|
*/
|
|
275
222
|
declare function deriveDeployPaths(raw: Record<string, unknown>): string[];
|
|
276
223
|
//#endregion
|
|
224
|
+
//#region src/turbo.d.ts
|
|
225
|
+
interface EnsureRootWorkspaceMemberResult {
|
|
226
|
+
content: string;
|
|
227
|
+
changed: boolean;
|
|
228
|
+
}
|
|
229
|
+
interface EnsureTurboDependencyResult {
|
|
230
|
+
content: string;
|
|
231
|
+
changed: boolean;
|
|
232
|
+
}
|
|
233
|
+
//#endregion
|
|
277
234
|
//#region src/astromech.d.ts
|
|
278
235
|
interface AstromechOptions {
|
|
279
236
|
/** Repo root. */
|
|
@@ -348,14 +305,6 @@ interface Astromech {
|
|
|
348
305
|
* when there is no config or `syncScripts: false`.
|
|
349
306
|
*/
|
|
350
307
|
packageScripts(): Record<string, string>;
|
|
351
|
-
/**
|
|
352
|
-
* The resolved super-linter env for this repo's `lint` task — the CI half
|
|
353
|
-
* of lint parity. `thinCallers()` already bakes `env` into the `lint` thin
|
|
354
|
-
* caller's `super-linter-env` input; this method exposes the full result
|
|
355
|
-
* for `holocron doctor` / diagnostics. Driven by the `lint` entry's
|
|
356
|
-
* `linters` list, else auto-detection from the repo's config files.
|
|
357
|
-
*/
|
|
358
|
-
superLinterConfig(): SuperLinterConfig;
|
|
359
308
|
/**
|
|
360
309
|
* The branch-protection required-status-check contexts for this repo —
|
|
361
310
|
* every `required: true` task's check context plus `extraRequiredChecks`,
|
|
@@ -370,6 +319,37 @@ interface Astromech {
|
|
|
370
319
|
* as {@link requiredChecks} — `holocron setup` owns writing the result.
|
|
371
320
|
*/
|
|
372
321
|
codecovConfig(existing: string | null): string;
|
|
322
|
+
/**
|
|
323
|
+
* The generated `turbo.json` for this repo's manifest, pretty-printed —
|
|
324
|
+
* write directly, no merge. `null` when no manifest task has turbo fan-out
|
|
325
|
+
* config (nothing to write). See {@link TurboTaskConfig} in `registry.ts`.
|
|
326
|
+
*/
|
|
327
|
+
turboConfig(): string | null;
|
|
328
|
+
/**
|
|
329
|
+
* Fixes #692: whenever {@link turboConfig} isn't `null`, this repo's root
|
|
330
|
+
* package needs to actually be a workspace member for the tasks it fans
|
|
331
|
+
* out — otherwise a root that's genuinely a directly-buildable package
|
|
332
|
+
* (not just an orchestrator) silently vanishes from `turbo run <task>`.
|
|
333
|
+
* Pass `pnpm-workspace.yaml`'s current content (or `""` if none exists —
|
|
334
|
+
* a no-op either way, since no `packages:` key means single-package mode
|
|
335
|
+
* already) and root `package.json`'s own `scripts` object — values and
|
|
336
|
+
* all, not just keys, so a task-name-matching script that's already the
|
|
337
|
+
* generated `holocron run <task> --` wrapper (predating this call, not
|
|
338
|
+
* written by it) is correctly excluded rather than treated as proof root
|
|
339
|
+
* is directly buildable (#846). `changed: false` means don't write
|
|
340
|
+
* anything — the file is already correct.
|
|
341
|
+
*/
|
|
342
|
+
ensureRootWorkspaceMember(workspaceYaml: string, rootScripts: Readonly<Record<string, string>>): EnsureRootWorkspaceMemberResult;
|
|
343
|
+
/**
|
|
344
|
+
* `turboConfig()` writes a `turbo.json` but never touches `package.json`
|
|
345
|
+
* — a repo with no local `turbo` devDependency falls back to whatever
|
|
346
|
+
* (if anything) is globally on `PATH`, per `run.ts`'s `resolveBin()`.
|
|
347
|
+
* Pass root `package.json`'s raw content and `pnpm-workspace.yaml`'s
|
|
348
|
+
* current content (checked for an existing `turbo` catalog entry, which
|
|
349
|
+
* takes precedence over the hardcoded fallback version). `changed: false`
|
|
350
|
+
* means don't write anything — `devDependencies.turbo` already exists.
|
|
351
|
+
*/
|
|
352
|
+
ensureTurboDependency(packageJson: string, workspaceYaml: string): EnsureTurboDependencyResult;
|
|
373
353
|
}
|
|
374
354
|
declare function createAstromech(options: AstromechOptions): Astromech;
|
|
375
355
|
//#endregion
|
|
@@ -472,11 +452,20 @@ declare const LINTER_NAMES: ReadonlySet<string>;
|
|
|
472
452
|
* Resolve the linter set for a repo. An `explicit` list (from `config.tasks`)
|
|
473
453
|
* picks the candidate set; otherwise the candidates are every `always` linter
|
|
474
454
|
* plus every `detect`-gated linter whose filenames are present at the repo
|
|
475
|
-
* root
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
455
|
+
* root, OR whose mapped `@theholocron/*-config` package resolves per
|
|
456
|
+
* {@link sharedConfigAvailable} — a repo can't run eslint with genuinely no
|
|
457
|
+
* config anywhere (super-linter FATALs if you ask it to,
|
|
458
|
+
* theholocron/holocron#654), but a *shared* one it has installed counts
|
|
459
|
+
* (holocron#795: proving `clients`' eslint.config.ts files reduce to zero
|
|
460
|
+
* remaining content is only half the story — the file itself was still load-
|
|
461
|
+
* bearing here as the sole "eslint is even configured" signal until this
|
|
462
|
+
* fallback existed). `always` linters are unconditional. Result is ordered
|
|
463
|
+
* by {@link LINTERS} declaration order.
|
|
464
|
+
*
|
|
465
|
+
* `sharedConfigAvailable` is caller-computed (`run.ts`'s `runLinterGroup`
|
|
466
|
+
* already resolves each linter's `resolveToolConfig()` per member to build
|
|
467
|
+
* its actual command — reusing that instead of duplicating the package-
|
|
468
|
+
* resolution logic here keeps this function itself pure and file-I/O-free).
|
|
480
469
|
*
|
|
481
470
|
* @throws when an `explicit` name is not in the registry — a typo is a
|
|
482
471
|
* config bug, not a linter to silently skip.
|
|
@@ -484,6 +473,7 @@ declare const LINTER_NAMES: ReadonlySet<string>;
|
|
|
484
473
|
declare function resolveLinters(opts: {
|
|
485
474
|
explicit?: string[];
|
|
486
475
|
rootFiles: string[];
|
|
476
|
+
sharedConfigAvailable?: ReadonlySet<string>;
|
|
487
477
|
}): Array<{
|
|
488
478
|
name: string;
|
|
489
479
|
def: LinterDef;
|
|
@@ -495,7 +485,19 @@ declare function resolveLinters(opts: {
|
|
|
495
485
|
* Actions. `holocron run <task>` and `holocron ci` resolve against this;
|
|
496
486
|
* adding a task here gives every repo that task.
|
|
497
487
|
*
|
|
498
|
-
* Keyed identically to the workflow templates — a task IS a workflow.
|
|
488
|
+
* Keyed identically to the workflow templates — a task IS a workflow. This
|
|
489
|
+
* is the canonical vocabulary table (epic #672, D11): every other artifact
|
|
490
|
+
* (`KNOWN_TASKS`, `thin-callers.ts`'s `KNOWN_WORKFLOWS`/`WORKFLOW_CHECK_CONTEXTS`,
|
|
491
|
+
* `CI_ORDER`) derives from these keys rather than hand-duplicating them —
|
|
492
|
+
* including the future GitHub App (#679), which imports this same table for
|
|
493
|
+
* config-schema validation instead of reimplementing its own copy.
|
|
494
|
+
*
|
|
495
|
+
* Task names are an intent-facing vocabulary (`verification.*`,
|
|
496
|
+
* `sourceQuality.*`, `security.*`, `delivery.*`, `platform.*`,
|
|
497
|
+
* `knowledge.*`), not tool names — `eslint`/`vitest`/`tsdown`/… stay
|
|
498
|
+
* internal to this file and `theholocron/configs`. See
|
|
499
|
+
* `.notes/tech-vocabulary-rename.spec.md` (#675) for the full mapping and
|
|
500
|
+
* the reasoning behind each namespace and decomposition.
|
|
499
501
|
*
|
|
500
502
|
* Spec: `docs/wiki/specifications/tech-astromech-task-runner.spec.md` (epic #581).
|
|
501
503
|
*/
|
|
@@ -514,40 +516,65 @@ interface LocalRunner {
|
|
|
514
516
|
/** The task is already a holocron subcommand (`sync`, `sync-wiki`). */
|
|
515
517
|
command?: string;
|
|
516
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* How a task fans out across every workspace via Turborepo — content-hash
|
|
521
|
+
* caching + `^`-prefixed cross-package ordering, epic #672 D9 (#681).
|
|
522
|
+
* Present only on tasks that genuinely run *per workspace* (a real build/
|
|
523
|
+
* compile/test step); whole-repo single-run tools (prettier, gitleaks,
|
|
524
|
+
* commitlint, yamllint, …) have no entry here — they stay off turbo.json
|
|
525
|
+
* entirely and run once, un-fanned-out, the way they already do.
|
|
526
|
+
*/
|
|
527
|
+
interface TurboTaskConfig {
|
|
528
|
+
/** Glob patterns turbo hashes to decide whether a cached run is still valid. */
|
|
529
|
+
inputs: string[];
|
|
530
|
+
/** Glob patterns turbo caches/restores after a run. Empty array for a task with no build artifact (lint, typecheck). */
|
|
531
|
+
outputs: string[];
|
|
532
|
+
/** Task names this depends on — a bare name runs in this package first; `^name` waits on every upstream workspace's task. */
|
|
533
|
+
dependsOn: string[];
|
|
534
|
+
}
|
|
517
535
|
/** One sub-job of a task — `performance` in `holocron run audit performance`. */
|
|
518
536
|
interface JobDef {
|
|
519
537
|
/** How the job runs locally; `null` → no local equivalent (enforced in CI). */
|
|
520
538
|
local: LocalRunner | null;
|
|
521
539
|
/**
|
|
522
|
-
* The CI status-check context this job reports as (
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* `
|
|
540
|
+
* The CI status-check context this job reports as (e.g.
|
|
541
|
+
* `platform.repoValidation / Validate registry consistency`) — every sub-job is a CI job.
|
|
542
|
+
* `holocron run <task>` and `holocron ci` label each job line with it;
|
|
543
|
+
* the task-level `… / Conclusion` context (only for tasks with several
|
|
544
|
+
* jobs) lives in `WORKFLOW_CHECK_CONTEXTS`.
|
|
526
545
|
*/
|
|
527
546
|
checkContext: string;
|
|
528
547
|
}
|
|
529
548
|
interface TaskDef {
|
|
530
549
|
/**
|
|
531
|
-
* `null` — the registry has no built-in runner (CodeQL, deploys,
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
550
|
+
* `null` — the registry has no built-in runner (CodeQL, deploys, the
|
|
551
|
+
* bundle-size job). An explicit turbo task or `package.json` script still
|
|
552
|
+
* runs (resolution steps 1–2); with neither, `holocron run` does nothing
|
|
553
|
+
* and `holocron ci` skips it — never a failure, even when the task is
|
|
554
|
+
* `required` (a CI-only check isn't a local one).
|
|
536
555
|
*/
|
|
537
556
|
local: LocalRunner | null;
|
|
538
557
|
/**
|
|
539
|
-
* Sub-jobs, keyed by slug
|
|
540
|
-
*
|
|
558
|
+
* Sub-jobs, keyed by slug. Declared order is run order: `holocron run
|
|
559
|
+
* <task>` (no job) runs each in turn.
|
|
541
560
|
*/
|
|
542
561
|
jobs?: Record<string, JobDef>;
|
|
543
562
|
/** Org-default flags injected by tool name. Removed by a repo override. */
|
|
544
563
|
flags?: Record<string, string[]>;
|
|
545
564
|
/**
|
|
546
|
-
* This task is
|
|
547
|
-
*
|
|
548
|
-
*
|
|
565
|
+
* This task is a linter-group aggregate: `holocron run <task>` resolves
|
|
566
|
+
* this fixed set of `linters.ts` entries (still gated by each linter's
|
|
567
|
+
* own `detect`/`always` rule) and runs each natively, instead of using
|
|
568
|
+
* `local`. Replaces the old single `lint` task's auto-detected linter
|
|
569
|
+
* list (`config.tasks[].linters`) — a repo's choice of which of these
|
|
570
|
+
* run is now just whether it includes this task in `tasks: [...]`, same
|
|
571
|
+
* as any other task. See `linters.ts` / `run.ts`.
|
|
549
572
|
*/
|
|
550
|
-
|
|
573
|
+
linterGroup?: string[];
|
|
574
|
+
/** Carries a `preview` mode (Cloudflare/Vercel deploy, npm dist-tag, Fern preview docs, …). Cross-cutting, not its own task. */
|
|
575
|
+
preview?: boolean;
|
|
576
|
+
/** Turborepo fan-out config for this task — see {@link TurboTaskConfig}. Omitted for whole-repo, non-fan-out tasks. */
|
|
577
|
+
turbo?: TurboTaskConfig;
|
|
551
578
|
}
|
|
552
579
|
declare const TASKS: Record<string, TaskDef>;
|
|
553
580
|
/** Every task name the registry knows. */
|
|
@@ -564,6 +591,58 @@ declare const CI_ORDER: string[];
|
|
|
564
591
|
/** Ordered (task contexts in {@link CI_ORDER}, then extras), de-duplicated. */
|
|
565
592
|
declare function requiredChecks(config: TasksConfig): string[];
|
|
566
593
|
//#endregion
|
|
594
|
+
//#region src/resolver.d.ts
|
|
595
|
+
/**
|
|
596
|
+
* Resolves the absolute path to a Bucket A tool's shared `@theholocron/*-config`
|
|
597
|
+
* entry point, installed in the consuming repo's own `node_modules` — and the
|
|
598
|
+
* CLI flag(s) to hand it via (`--config`, `--extends`, …). `run.ts` splices the
|
|
599
|
+
* result into the command it builds for a tool/detect runner or a linter-group
|
|
600
|
+
* entry, right after the tool's own args.
|
|
601
|
+
*
|
|
602
|
+
* Every mapped package's resolved entry point already carries a ready-to-use
|
|
603
|
+
* default export (a plain re-export for `prettier`/`commitlint`; an invoked,
|
|
604
|
+
* zero-arg preset for `eslint`/`vitest`/`tsdown` — verified end-to-end against
|
|
605
|
+
* each tool's real `--config`/`--extends` loader, not just the file's shape).
|
|
606
|
+
* A repo doesn't need this package installed at all — every lookup degrades to
|
|
607
|
+
* `[]` (no flag added, the tool falls back to its own auto-discovery of a
|
|
608
|
+
* local file, unchanged from today) rather than throwing.
|
|
609
|
+
*
|
|
610
|
+
* **Local file wins.** A `<tool>.config.*` sitting in `cwd` (whether it's
|
|
611
|
+
* pure boilerplate or has real per-package customization on top of the
|
|
612
|
+
* shared bundle, e.g. `mergeConfig(base, { test: { coverage: { exclude }
|
|
613
|
+
* } })`) always skips the splice, even when the shared package is also
|
|
614
|
+
* installed — an explicit `--config <shared path>` flag beats a tool's own
|
|
615
|
+
* auto-discovery every time, so splicing it unconditionally would silently
|
|
616
|
+
* discard that customization the file is still sitting right there on disk.
|
|
617
|
+
* The shared bundle is only ever the fallback for a package with *no* local
|
|
618
|
+
* file at all — that's still the "delete the file to go fully shared" path
|
|
619
|
+
* this was designed for (#676); it just isn't unconditional (#749).
|
|
620
|
+
*
|
|
621
|
+
* `semantic-release`, `devmoji`, `editorconfig-checker`, and `knip` are
|
|
622
|
+
* deliberately absent — `semantic-release-config`'s `defineConfig()` needs
|
|
623
|
+
* real per-repo data (branches, npm options) a static `--extends <path>` can't
|
|
624
|
+
* carry; `devmoji` runs through a git hook template, not `holocron run
|
|
625
|
+
* <task>`; `editorconfig-checker` has no shared-config package yet; `knip` is
|
|
626
|
+
* repo-specific by nature, never a shared-config candidate. See
|
|
627
|
+
* `.notes/tech-config-resolution.spec.md` (#676).
|
|
628
|
+
*/
|
|
629
|
+
interface ResolverDeps {
|
|
630
|
+
readFile: (path: string) => string;
|
|
631
|
+
fileExists: (path: string) => boolean;
|
|
632
|
+
}
|
|
633
|
+
/** Every tool name the resolver knows how to point at a shared config. */
|
|
634
|
+
declare const RESOLVABLE_TOOLS: ReadonlySet<string>;
|
|
635
|
+
/**
|
|
636
|
+
* `<flag> <absolute path>` for `tool`, resolved against `cwd`'s
|
|
637
|
+
* `node_modules` — or `[]` when the tool isn't mapped, `cwd` already has its
|
|
638
|
+
* own local config file for it (#749 — local always wins, customized or
|
|
639
|
+
* not), the shared package isn't installed, its `package.json` doesn't
|
|
640
|
+
* declare the export subpath this needs, or the resolved file doesn't
|
|
641
|
+
* actually exist on disk (a stale install, or a package version that
|
|
642
|
+
* predates the export existing).
|
|
643
|
+
*/
|
|
644
|
+
declare function resolveToolConfig(tool: string, cwd: string, deps: ResolverDeps): string[];
|
|
645
|
+
//#endregion
|
|
567
646
|
//#region src/reusable.d.ts
|
|
568
647
|
/**
|
|
569
648
|
* The **reusable** GitHub Actions surface pushed to `theholocron/.github` by
|
|
@@ -591,4 +670,73 @@ declare const WORKFLOW_TEMPLATE_PROPERTIES: Record<string, string>;
|
|
|
591
670
|
*/
|
|
592
671
|
declare function reusableTemplates(): Map<string, string>;
|
|
593
672
|
//#endregion
|
|
594
|
-
|
|
673
|
+
//#region src/tsconfig.d.ts
|
|
674
|
+
/**
|
|
675
|
+
* `tsconfig.json` generation — Bucket B (config-resolution workstream, #676):
|
|
676
|
+
* the file must stay committed (the TypeScript language server discovers it
|
|
677
|
+
* directly from disk, no `--config` override mechanism to hand it a path
|
|
678
|
+
* instead), but its content is fully derivable, so it's generated rather
|
|
679
|
+
* than hand-authored — the same category as `.editorconfig`
|
|
680
|
+
* ({@link "./templates/configs/editorconfig/create-config.js" createConfig})
|
|
681
|
+
* and {@link codecovConfig}.
|
|
682
|
+
*
|
|
683
|
+
* Surveyed every package-level `tsconfig.json` across the org (`holocron`,
|
|
684
|
+
* `clients`, `utils` — 20+ packages). `extends: "@theholocron/tsconfig/
|
|
685
|
+
* node-lts"`, `compilerOptions.baseUrl: "./"`, `compilerOptions.outDir:
|
|
686
|
+
* "./dist"`, `include: ["src/**\/*.ts"]`, and `exclude: ["node_modules",
|
|
687
|
+
* "dist"]` are uniform in every one — safe defaults here. `paths` (a `@/*`
|
|
688
|
+
* → `./src/*` import alias) is a real per-package choice, present in
|
|
689
|
+
* roughly 40% of packages checked — an opt-in parameter, not a default.
|
|
690
|
+
*
|
|
691
|
+
* Two fields checked and deliberately *not* absorbed as defaults, unlike
|
|
692
|
+
* `eslint-config`'s `tsconfigRootDir`/`settings.node` (which turned out
|
|
693
|
+
* redundant with the shared package's own behavior, `configs`#461):
|
|
694
|
+
* `compilerOptions.module`/`moduleResolution` (only `@theholocron/cli`
|
|
695
|
+
* overrides these, to `esnext`/`bundler` — a genuine deviation from the
|
|
696
|
+
* shared `node-lts` preset's `nodenext`/`nodenext`, needed for its bundler
|
|
697
|
+
* tooling, not something every package should inherit) and
|
|
698
|
+
* `compilerOptions.rootDir` (present in exactly two packages, always the
|
|
699
|
+
* same value `./src` that `include` already implies — an unnecessary
|
|
700
|
+
* override wherever it appears, not a pattern worth generalizing).
|
|
701
|
+
*
|
|
702
|
+
* Monorepo *root* `tsconfig.json` (a TS project-references "solution
|
|
703
|
+
* file" — `holocron`'s own root is `{ files: [], references: [...] }`,
|
|
704
|
+
* listing which packages to build) is a structurally different, genuinely
|
|
705
|
+
* per-repo document — out of scope here, same as Bucket C content.
|
|
706
|
+
*
|
|
707
|
+
* Not yet wired into `holocron setup`'s per-package write loop (every
|
|
708
|
+
* other Bucket B file there is a single repo-root file, safely
|
|
709
|
+
* overwritten every run — `tsconfig.json` is per-package, and most
|
|
710
|
+
* packages' files still carry real hand-authored content today, not yet
|
|
711
|
+
* migrated to a fully-generated state). That per-package iteration +
|
|
712
|
+
* safe-migration design is `#680`'s job, not duplicated here — this is
|
|
713
|
+
* the generator itself, ready for it to call.
|
|
714
|
+
*/
|
|
715
|
+
interface TsconfigOptions {
|
|
716
|
+
/** Human-readable name for the `display` field — the package's own name is the usual choice. */
|
|
717
|
+
display: string;
|
|
718
|
+
/**
|
|
719
|
+
* `@theholocron/tsconfig` variant. Defaults to `"node-lts"` — every
|
|
720
|
+
* checked package uses it; the other three (`astro`, `nextjs`, `react`)
|
|
721
|
+
* exist for a template repo's app-shaped packages, not the plain
|
|
722
|
+
* Node.js library packages this org's currently-migrated repos ship.
|
|
723
|
+
*/
|
|
724
|
+
variant?: "astro" | "nextjs" | "node-lts" | "react";
|
|
725
|
+
/**
|
|
726
|
+
* Add a `@/*` → `./src/*` path alias. A real per-package choice, not a
|
|
727
|
+
* default — roughly 40% of packages checked use one, the rest don't.
|
|
728
|
+
*/
|
|
729
|
+
paths?: boolean;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* A package-level `tsconfig.json` — the uniform shape confirmed across
|
|
733
|
+
* every package checked, parameterized only by the two fields that
|
|
734
|
+
* genuinely vary (`display`, `paths`). No scaffold/workflow header (matches
|
|
735
|
+
* `.alexrc.json`'s existing precedent for a strict-JSON Bucket B file —
|
|
736
|
+
* JSON has no comment syntax to carry one, and TypeScript's own tolerance
|
|
737
|
+
* for JSONC comments in `tsconfig.json` isn't worth relying on for a file
|
|
738
|
+
* this thin).
|
|
739
|
+
*/
|
|
740
|
+
declare function createTsconfig(options: TsconfigOptions): string;
|
|
741
|
+
//#endregion
|
|
742
|
+
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 };
|