@theholocron/astromech 5.0.0-alpha.31 → 5.0.0-alpha.32

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
@@ -226,6 +226,10 @@ interface EnsureRootWorkspaceMemberResult {
226
226
  content: string;
227
227
  changed: boolean;
228
228
  }
229
+ interface EnsureTurboDependencyResult {
230
+ content: string;
231
+ changed: boolean;
232
+ }
229
233
  //#endregion
230
234
  //#region src/astromech.d.ts
231
235
  interface AstromechOptions {
@@ -332,6 +336,16 @@ interface Astromech {
332
336
  * means don't write anything — the file is already correct.
333
337
  */
334
338
  ensureRootWorkspaceMember(workspaceYaml: string, rootScripts: readonly string[]): EnsureRootWorkspaceMemberResult;
339
+ /**
340
+ * `turboConfig()` writes a `turbo.json` but never touches `package.json`
341
+ * — a repo with no local `turbo` devDependency falls back to whatever
342
+ * (if anything) is globally on `PATH`, per `run.ts`'s `resolveBin()`.
343
+ * Pass root `package.json`'s raw content and `pnpm-workspace.yaml`'s
344
+ * current content (checked for an existing `turbo` catalog entry, which
345
+ * takes precedence over the hardcoded fallback version). `changed: false`
346
+ * means don't write anything — `devDependencies.turbo` already exists.
347
+ */
348
+ ensureTurboDependency(packageJson: string, workspaceYaml: string): EnsureTurboDependencyResult;
335
349
  }
336
350
  declare function createAstromech(options: AstromechOptions): Astromech;
337
351
  //#endregion
package/dist/index.mjs CHANGED
@@ -1510,6 +1510,54 @@ function ensureRootWorkspaceMember(workspaceYaml, rootScripts, taskNames) {
1510
1510
  changed: true
1511
1511
  };
1512
1512
  }
1513
+ /**
1514
+ * Fallback pin when a repo's own `pnpm-workspace.yaml` has no `turbo`
1515
+ * catalog entry yet — matches this repo's own catalog version (the
1516
+ * canonical source-of-truth repo for the whole org's tooling).
1517
+ */
1518
+ const DEFAULT_TURBO_VERSION = "^2.10.12";
1519
+ /**
1520
+ * Ensures `turbo` is declared in `package.json#devDependencies` — found
1521
+ * the hard way rolling this out to `observability` (predates #691):
1522
+ * `turboConfig()` writes a `turbo.json` the moment any task has fan-out
1523
+ * config, but never touches `package.json`, so a repo that predates this
1524
+ * feature (or never had `turbo` installed for any other reason) ends up
1525
+ * with a `turbo.json` and nothing local to run it. `resolveBin()`
1526
+ * (`run.ts`) falls back to a bare `turbo` on `PATH` when
1527
+ * `node_modules/.bin/turbo` doesn't exist — on a machine with no global
1528
+ * `turbo` at all that's a hard failure for every task; on one that
1529
+ * happens to have an unrelated global install, silent version skew
1530
+ * (confirmed empirically: a global 2.6.0 rejected this repo's generated
1531
+ * `turbo.json` outright — `Found an unknown key "globalDependencies"`,
1532
+ * a schema key from a newer version than the one actually resolved).
1533
+ *
1534
+ * Prefers `"catalog:"` when the repo's own `pnpm-workspace.yaml` already
1535
+ * has a `turbo` catalog entry — matches every already-migrated repo
1536
+ * (`holocron`, `clients`, …) — falling back to a real pinned version
1537
+ * otherwise. Never touches an existing `devDependencies.turbo` entry, so
1538
+ * a repo pinning its own version on purpose is left alone — idempotent,
1539
+ * a no-op once set either way.
1540
+ */
1541
+ function ensureTurboDependency(packageJson, workspaceYaml) {
1542
+ const pkg = JSON.parse(packageJson);
1543
+ if (typeof pkg.devDependencies?.turbo === "string") return {
1544
+ content: packageJson,
1545
+ changed: false
1546
+ };
1547
+ const hasTurboCatalogEntry = /^\s*turbo:\s*\S/m.test(workspaceYaml);
1548
+ const devDependencies = {
1549
+ ...pkg.devDependencies,
1550
+ turbo: hasTurboCatalogEntry ? "catalog:" : DEFAULT_TURBO_VERSION
1551
+ };
1552
+ const updated = {
1553
+ ...pkg,
1554
+ devDependencies
1555
+ };
1556
+ return {
1557
+ content: `${JSON.stringify(updated, null, 2)}\n`,
1558
+ changed: true
1559
+ };
1560
+ }
1513
1561
  //#endregion
1514
1562
  //#region src/astromech.ts
1515
1563
  /**
@@ -1615,7 +1663,8 @@ function createAstromech(options) {
1615
1663
  turboConfig: () => turboConfig(options.config ?? {}),
1616
1664
  ensureRootWorkspaceMember: (workspaceYaml, rootScripts) => {
1617
1665
  return ensureRootWorkspaceMember(workspaceYaml, rootScripts, (options.config?.tasks ?? []).map(normalizeTaskEntry).filter((e) => e.local !== false).map((e) => e.name));
1618
- }
1666
+ },
1667
+ ensureTurboDependency: (packageJson, workspaceYaml) => ensureTurboDependency(packageJson, workspaceYaml)
1619
1668
  };
1620
1669
  }
1621
1670
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/astromech",
3
- "version": "5.0.0-alpha.31",
3
+ "version": "5.0.0-alpha.32",
4
4
  "description": "The Holocron task runner — one task manifest drives `holocron run`, `holocron ci`, the CI workflows, package.json scripts, linters, and required checks.",
5
5
  "keywords": [
6
6
  "ci",
@@ -37,7 +37,7 @@
37
37
  "dist"
38
38
  ],
39
39
  "dependencies": {
40
- "@theholocron/datapad": "5.0.0-alpha.31"
40
+ "@theholocron/datapad": "5.0.0-alpha.32"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@theholocron/eslint-config": "^8.0.0",
@@ -53,7 +53,7 @@
53
53
  "tsdown": "^0.22.14",
54
54
  "typescript": "^5.9.3",
55
55
  "vitest": "^4.1.11",
56
- "@theholocron/rollup-plugin-transform-template": "5.0.0-alpha.31"
56
+ "@theholocron/rollup-plugin-transform-template": "5.0.0-alpha.32"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">=22"