@orkestrel/scaffold 0.0.107 → 0.0.109

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.
Files changed (164) hide show
  1. package/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +326 -91
  2. package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +110 -14
  3. package/dist/agents/skills/orkestrel-dispatch/scripts/chain.js +280 -0
  4. package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +188 -26
  5. package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +142 -43
  6. package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +240 -62
  7. package/dist/agents/skills/orkestrel-dispatch/scripts/patch.js +323 -0
  8. package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +169 -32
  9. package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +368 -27
  10. package/dist/agents/skills/orkestrel-falsify/scripts/mutate.js +560 -0
  11. package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +1052 -205
  12. package/dist/agents/skills/orkestrel-harden/scripts/measure.js +361 -0
  13. package/dist/agents/skills/orkestrel-harden/scripts/titles.js +455 -80
  14. package/dist/agents/skills/orkestrel-parallel/scripts/cases.js +327 -0
  15. package/dist/agents/skills/orkestrel-publish/scripts/compare.js +298 -51
  16. package/dist/agents/skills/orkestrel-publish/scripts/pins.js +170 -13
  17. package/dist/agents/skills/orkestrel-publish/scripts/swap.js +956 -191
  18. package/dist/agents/skills/orkestrel-publish/scripts/wave.js +707 -112
  19. package/dist/agents/skills/orkestrel-publish/scripts/window.js +235 -41
  20. package/dist/agents/skills/orkestrel-scout/scripts/map.js +341 -54
  21. package/dist/agents/templates/brief.md +1 -1
  22. package/dist/bin/main.js +51 -46
  23. package/dist/bin/main.js.map +1 -1
  24. package/dist/host/AGENTS.md +26 -20
  25. package/dist/host/agents/orchestration.md +98 -58
  26. package/dist/host/agents/platforms/posix.md +15 -0
  27. package/dist/host/agents/platforms/windows.md +37 -0
  28. package/dist/host/agents/skills/orkestrel-align/SKILL.md +10 -13
  29. package/dist/host/agents/skills/orkestrel-align/references/fleet.md +4 -10
  30. package/dist/host/agents/skills/orkestrel-align/references/integration.md +1 -1
  31. package/dist/host/agents/skills/orkestrel-build/SKILL.md +16 -48
  32. package/dist/host/agents/skills/orkestrel-build/agents/openai.yaml +1 -1
  33. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +19 -16
  34. package/dist/host/agents/skills/orkestrel-debrief/agents/openai.yaml +1 -1
  35. package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +15 -28
  36. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +5 -6
  37. package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +12 -14
  38. package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +36 -24
  39. package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +14 -11
  40. package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +366 -75
  41. package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +126 -16
  42. package/dist/host/agents/skills/orkestrel-dispatch/scripts/chain.ts +323 -0
  43. package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +220 -31
  44. package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +176 -33
  45. package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +294 -59
  46. package/dist/host/agents/skills/orkestrel-dispatch/scripts/patch.ts +401 -0
  47. package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +199 -34
  48. package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +428 -27
  49. package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +10 -8
  50. package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +1 -5
  51. package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
  52. package/dist/host/agents/skills/orkestrel-falsify/scripts/mutate.ts +701 -0
  53. package/dist/host/agents/skills/orkestrel-harden/SKILL.md +16 -12
  54. package/dist/host/agents/skills/orkestrel-harden/references/bindings.md +23 -81
  55. package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +4 -5
  56. package/dist/host/agents/skills/orkestrel-harden/references/contract.md +2 -0
  57. package/dist/host/agents/skills/orkestrel-harden/references/document.md +33 -0
  58. package/dist/host/agents/skills/orkestrel-harden/references/equivalence.md +6 -3
  59. package/dist/host/agents/skills/orkestrel-harden/references/hardening.md +8 -4
  60. package/dist/host/agents/skills/orkestrel-harden/references/research.md +2 -0
  61. package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +1272 -279
  62. package/dist/host/agents/skills/orkestrel-harden/scripts/measure.ts +425 -0
  63. package/dist/host/agents/skills/orkestrel-harden/scripts/titles.ts +603 -98
  64. package/dist/host/agents/skills/orkestrel-journey/SKILL.md +75 -98
  65. package/dist/host/agents/skills/orkestrel-journey/references/captures.md +54 -17
  66. package/dist/host/agents/skills/orkestrel-journey/references/decide.md +1 -20
  67. package/dist/host/agents/skills/orkestrel-journey/references/layer.md +21 -31
  68. package/dist/host/agents/skills/orkestrel-journey/references/styles.md +1 -1
  69. package/dist/host/agents/skills/orkestrel-parallel/SKILL.md +91 -30
  70. package/dist/host/agents/skills/orkestrel-parallel/agents/openai.yaml +2 -2
  71. package/dist/host/agents/skills/orkestrel-parallel/references/claude.md +34 -0
  72. package/dist/host/agents/skills/orkestrel-parallel/references/codex.md +29 -0
  73. package/dist/host/agents/skills/orkestrel-parallel/references/cursor.md +29 -0
  74. package/dist/host/agents/skills/orkestrel-parallel/references/t3.md +31 -0
  75. package/dist/host/agents/skills/orkestrel-parallel/scripts/cases.ts +389 -0
  76. package/dist/host/agents/skills/orkestrel-polish/SKILL.md +16 -20
  77. package/dist/host/agents/skills/orkestrel-polish/references/capture-harness.md +16 -26
  78. package/dist/host/agents/skills/orkestrel-publish/SKILL.md +12 -26
  79. package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +2 -2
  80. package/dist/host/agents/skills/orkestrel-publish/references/adopt.md +23 -0
  81. package/dist/host/agents/skills/orkestrel-publish/references/release.md +4 -4
  82. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +12 -10
  83. package/dist/host/agents/skills/orkestrel-publish/references/window.md +20 -25
  84. package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +348 -59
  85. package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +202 -22
  86. package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1061 -191
  87. package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +812 -140
  88. package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +280 -38
  89. package/dist/host/agents/skills/orkestrel-scout/SKILL.md +3 -3
  90. package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +428 -70
  91. package/dist/host/agents/templates/brief.md +1 -1
  92. package/dist/host/agents/transports/claude-cli.md +3 -3
  93. package/dist/host/agents/transports/codex.md +3 -8
  94. package/dist/host/agents/transports/cursor.md +2 -3
  95. package/dist/host/claude/AGENTS.md +7 -10
  96. package/dist/host/claude/agents/analyst.md +3 -3
  97. package/dist/host/claude/agents/astra.md +3 -3
  98. package/dist/host/claude/agents/builder.md +1 -1
  99. package/dist/host/claude/agents/checker.md +1 -1
  100. package/dist/host/claude/agents/distiller.md +1 -1
  101. package/dist/host/claude/agents/grok.md +1 -1
  102. package/dist/host/claude/agents/opus.md +2 -2
  103. package/dist/host/claude/agents/orkestrel.md +57 -90
  104. package/dist/host/claude/agents/researcher.md +1 -1
  105. package/dist/host/claude/agents/reviewer.md +4 -0
  106. package/dist/host/claude/agents/scout.md +1 -1
  107. package/dist/host/claude/agents/verifier.md +1 -1
  108. package/dist/host/claude/rules/application.md +14 -21
  109. package/dist/host/claude/rules/architecture.md +34 -44
  110. package/dist/host/claude/rules/browser.md +3 -4
  111. package/dist/host/claude/rules/campaign.md +55 -0
  112. package/dist/host/claude/rules/documentation.md +26 -11
  113. package/dist/host/claude/rules/names.md +9 -4
  114. package/dist/host/claude/rules/patterns.md +6 -7
  115. package/dist/host/claude/rules/portability.md +2 -3
  116. package/dist/host/claude/rules/quality.md +4 -5
  117. package/dist/host/claude/rules/styles.md +2 -2
  118. package/dist/host/claude/rules/tests.md +57 -114
  119. package/dist/host/claude/rules/typescript.md +8 -10
  120. package/dist/host/claude/rules/workspace.md +21 -19
  121. package/dist/host/claude/rules/writing.md +3 -3
  122. package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +1 -1
  123. package/dist/host/claude/skills/orkestrel-harden/SKILL.md +1 -1
  124. package/dist/host/claude/skills/orkestrel-parallel/SKILL.md +1 -1
  125. package/dist/host/claude/skills/orkestrel-publish/SKILL.md +1 -1
  126. package/dist/host/claude/skills/orkestrel-scout/SKILL.md +1 -1
  127. package/dist/host/codex/agents/analyst.toml +9 -3
  128. package/dist/host/codex/agents/astra.toml +3 -4
  129. package/dist/host/codex/agents/builder.toml +1 -1
  130. package/dist/host/codex/agents/opus.toml +3 -4
  131. package/dist/host/codex/agents/orkestrel.toml +1 -1
  132. package/dist/host/codex/agents/researcher.toml +2 -2
  133. package/dist/host/codex/agents/verifier.toml +1 -1
  134. package/dist/host/codex/config.toml +3 -3
  135. package/dist/host/configs/helpers.ts +21 -1
  136. package/dist/host/configs/policy.ts +405 -16
  137. package/dist/host/cursor/rules/orchestration.mdc +1 -0
  138. package/dist/host/dotfiles/oxlintrc.json +141 -5
  139. package/dist/host/guides/agent.md +111 -134
  140. package/dist/host/guides/capture.md +801 -0
  141. package/dist/host/guides/probe.md +27 -8
  142. package/dist/host/guides/scaffold.md +152 -19
  143. package/dist/host/guides/study.md +534 -440
  144. package/dist/host/guides/test.md +111 -44
  145. package/dist/host/manifest.json +199 -242
  146. package/dist/host/tests/config.test.ts +1558 -219
  147. package/dist/host/tests/policy.test.ts +127 -1
  148. package/dist/host/tests/setupPolicy.ts +1389 -39
  149. package/dist/src/core/index.cjs +239 -87
  150. package/dist/src/core/index.cjs.map +1 -1
  151. package/dist/src/core/index.d.cts +123 -39
  152. package/dist/src/core/index.d.ts +123 -39
  153. package/dist/src/core/index.js +234 -86
  154. package/dist/src/core/index.js.map +1 -1
  155. package/dist/src/server/index.cjs +20 -27
  156. package/dist/src/server/index.cjs.map +1 -1
  157. package/dist/src/server/index.js +21 -28
  158. package/dist/src/server/index.js.map +1 -1
  159. package/package.json +11 -11
  160. package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +0 -283
  161. package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +0 -25
  162. package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +0 -333
  163. package/dist/host/agents/skills/orkestrel-parallel/references/harnesses.md +0 -19
  164. package/dist/host/guides/supervisor.md +0 -4890
@@ -4,7 +4,7 @@ let _orkestrel_template = require("@orkestrel/template");
4
4
  let _orkestrel_emitter = require("@orkestrel/emitter");
5
5
  var package_default = {
6
6
  name: "@orkestrel/scaffold",
7
- version: "0.0.107",
7
+ version: "0.0.109",
8
8
  description: "Scaffold workspaces with commands: new, audit, repair, catalog, and overwrite.",
9
9
  keywords: [
10
10
  "audit",
@@ -81,7 +81,7 @@ var package_default = {
81
81
  "test:templates": "vitest run --config vite.config.ts --no-cache --reporter=dot --project templates",
82
82
  "test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
83
83
  "test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
84
- "test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
84
+ "test:bench": "vitest bench --config vite.config.ts --no-cache --project \"probe (bench)\" --mode benchmark",
85
85
  "test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup",
86
86
  "build": "npm run clean && npm run build:src && npm run build:host && npm run build:skills && npm run build:inventory",
87
87
  "build:src": "npm run build:src:core && npm run build:src:server && npm run build:src:bin",
@@ -103,25 +103,24 @@ var package_default = {
103
103
  "@orkestrel/template": "^0.0.10"
104
104
  },
105
105
  devDependencies: {
106
- "@microsoft/api-extractor": "^7.59.4",
106
+ "@microsoft/api-extractor": "^7.60.0",
107
107
  "@orkestrel/browser": "^0.0.29",
108
108
  "@orkestrel/guide": "^0.0.25",
109
109
  "@orkestrel/html": "^0.0.12",
110
- "@orkestrel/probe": "^0.0.24",
111
- "@orkestrel/test": "^0.0.29",
110
+ "@orkestrel/probe": "^0.0.25",
111
+ "@orkestrel/test": "^0.0.30",
112
112
  "@types/node": "^24.19.2",
113
- "@vitest/browser-playwright": "^4.1.11",
114
- "oxfmt": "^0.74.0",
115
- "oxlint": "^1.89.0",
116
- "playwright": "^1.63.0",
117
- "typescript": "^6.0.3",
113
+ "@vitest/browser-playwright": "^5.0.5",
114
+ "oxfmt": "^0.75.0",
115
+ "oxlint": "^1.90.0",
116
+ "playwright": "^1.64.1",
117
+ "typescript": "^7.0.2",
118
118
  "vite": "^8.3.5",
119
- "vitest": "^4.1.12"
119
+ "vitest": "^5.0.5"
120
120
  },
121
121
  engines: { "node": ">=22.18.0" }
122
122
  };
123
- //#endregion
124
- //#region src/core/constants.ts
123
+ // src/core/constants.ts
125
124
  /**
126
125
  * Lists the `Environment` values, frozen.
127
126
  *
@@ -331,6 +330,7 @@ var CANON_PATHS = Object.freeze([
331
330
  ".claude/AGENTS.md",
332
331
  ".mcp.json",
333
332
  ".agents/orchestration.md",
333
+ ".agents/platforms",
334
334
  ".agents/skills",
335
335
  ".agents/templates",
336
336
  ".agents/transports",
@@ -439,19 +439,19 @@ var CATALOG_AGENT_PATH = ".claude/agents/orkestrel.md";
439
439
  *
440
440
  * @remarks
441
441
  * The catalog verb rewrites the region between this marker and
442
- * {@link CATALOG_CLOSING_MARKER} and leaves every other byte of the file alone,
442
+ * {@link CATALOG_END_MARKER} and leaves every other byte of the file alone,
443
443
  * so the writer and every proof that reads the rendered file read the pair from
444
444
  * here rather than repeating a literal that only agrees by inspection.
445
445
  */
446
- var CATALOG_OPENING_MARKER = "<!-- orkestrel:catalog -->";
446
+ var CATALOG_START_MARKER = "<!-- orkestrel:catalog -->";
447
447
  /**
448
448
  * Names the marker closing the package table inside {@link CATALOG_AGENT_PATH}.
449
449
  *
450
450
  * @remarks
451
- * It pairs with {@link CATALOG_OPENING_MARKER}; a file missing either marker is
451
+ * It pairs with {@link CATALOG_START_MARKER}; a file missing either marker is
452
452
  * refused rather than rewritten.
453
453
  */
454
- var CATALOG_CLOSING_MARKER = "<!-- /orkestrel:catalog -->";
454
+ var CATALOG_END_MARKER = "<!-- /orkestrel:catalog -->";
455
455
  /**
456
456
  * Lists the package-facing skills a target receives pointers for, frozen and alphabetical.
457
457
  *
@@ -657,7 +657,7 @@ var WORKSPACE_DEV_ENGINES = Object.freeze({ packageManager: Object.freeze({
657
657
  version: `>=${MINIMUM_NPM_VERSION}`,
658
658
  onFail: "error"
659
659
  }) });
660
- /** Holds the tooling versions scaffold and every generated workspace share. */
660
+ /** Holds the baseline tooling versions, before framework holds apply. */
661
661
  var BASE_DEV_DEPENDENCIES = Object.freeze({
662
662
  "@orkestrel/guide": package_default.devDependencies["@orkestrel/guide"],
663
663
  "@orkestrel/probe": package_default.devDependencies["@orkestrel/probe"],
@@ -671,6 +671,19 @@ var BASE_DEV_DEPENDENCIES = Object.freeze({
671
671
  vitest: package_default.devDependencies.vitest
672
672
  });
673
673
  /**
674
+ * Holds foreign tool ranges required by selected browser frameworks, frozen.
675
+ *
676
+ * @remarks
677
+ * A selected framework overrides the baseline floor with its held range. `audit` names the hold
678
+ * where it would report a newer served major and reports a declaration past that hold. The
679
+ * constants proof ties the held range to the baseline manifest and the framework's planned range.
680
+ */
681
+ var TOOLCHAIN_HOLDS = Object.freeze({ typescript: Object.freeze({
682
+ framework: "vue",
683
+ range: "^6.0.3",
684
+ reason: "Vue workspaces require TypeScript 6.0.3 because no stable vue-tsc runs on TypeScript 7: @volar/typescript@2.4.30 declares peer typescript <7, and the TypeScript 7.0 announcement directs Vue projects to stay on TypeScript 6.0"
685
+ }) });
686
+ /**
674
687
  * Lists the development dependencies that roll declarations up for published source.
675
688
  *
676
689
  * @remarks
@@ -694,6 +707,45 @@ var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
694
707
  */
695
708
  var BROWSE_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/browser": package_default.devDependencies["@orkestrel/browser"] });
696
709
  /**
710
+ * Names the development dependency a browser application's journey axis adds.
711
+ *
712
+ * @remarks
713
+ * Scaffold does not install this package, so its range is a seed. The planner withholds it
714
+ * from the workspaces {@link CAPTURE_UPSTREAM} lists.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * import { CAPTURE_DEV_DEPENDENCIES } from '@orkestrel/scaffold'
719
+ *
720
+ * CAPTURE_DEV_DEPENDENCIES['@orkestrel/capture'] // '^0.0.1'
721
+ * ```
722
+ */
723
+ var CAPTURE_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/capture": "^0.0.1" });
724
+ /**
725
+ * Lists the capture package and its fleet runtime dependency closure, frozen.
726
+ *
727
+ * @remarks
728
+ * The sorted list includes `@orkestrel/capture` and its transitive `@orkestrel/*` dependencies
729
+ * and peers, read from capture's installed manifests, and moves with the capture pin.
730
+ * A listed workspace cannot receive the capture development dependency without closing a cycle.
731
+ * Scaffold does not install capture, so the proof checks planning against this list; the
732
+ * installed closure-equality proof lands when scaffold installs capture.
733
+ *
734
+ * @example
735
+ * ```ts
736
+ * import { CAPTURE_UPSTREAM } from '@orkestrel/scaffold'
737
+ *
738
+ * CAPTURE_UPSTREAM.includes('@orkestrel/process') // true
739
+ * ```
740
+ */
741
+ var CAPTURE_UPSTREAM = Object.freeze([
742
+ "@orkestrel/capture",
743
+ "@orkestrel/contract",
744
+ "@orkestrel/emitter",
745
+ "@orkestrel/process",
746
+ "@orkestrel/timeout"
747
+ ]);
748
+ /**
697
749
  * Lists the packages `@orkestrel/browser` depends on at runtime, directly or transitively, frozen.
698
750
  *
699
751
  * @remarks
@@ -749,8 +801,7 @@ var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
749
801
  "@orkestrel/router": "^0.0.10",
750
802
  "@orkestrel/server": "^0.0.14"
751
803
  });
752
- //#endregion
753
- //#region src/core/templates.ts
804
+ // src/core/templates.ts
754
805
  /**
755
806
  * Holds formatter-stable template text for every configuration artifact.
756
807
  *
@@ -1248,6 +1299,7 @@ export function appJourney(
1248
1299
  variant: JourneyVariant,
1249
1300
  variants: readonly JourneyVariant[],
1250
1301
  mode?: string,
1302
+ override?: UserConfig,
1251
1303
  ): UserConfig {
1252
1304
  const application = resolveApplication(mode, applications)
1253
1305
  const browser = applications[application]()
@@ -1269,7 +1321,7 @@ export function appJourney(
1269
1321
  },
1270
1322
  },
1271
1323
  }
1272
- return mergeOverride(project)
1324
+ return mergeOverride(project, override)
1273
1325
  }
1274
1326
  `,
1275
1327
  showcase: `
@@ -1370,7 +1422,30 @@ export function appServer(override?: UserConfig): UserConfig {
1370
1422
  browser: { enabled: false },
1371
1423
  },
1372
1424
  }
1373
- return mergeOverride(project, override)
1425
+ // Fills the missing codeSplitting of each merged output with false and adds no output,
1426
+ // so an override's output list keeps its own members and their order. A member that
1427
+ // already supplies a value is returned as written, found by property lookup, so a value
1428
+ // an inherited getter supplies survives.
1429
+ const merged = mergeOverride(project, override)
1430
+ const rolldown = merged.build?.rolldownOptions
1431
+ const output = rolldown?.output
1432
+ const unsplit = { codeSplitting: false }
1433
+ return {
1434
+ ...merged,
1435
+ build: {
1436
+ ...merged.build,
1437
+ rolldownOptions: {
1438
+ ...rolldown,
1439
+ output: Array.isArray(output)
1440
+ ? output.map((member) =>
1441
+ member.codeSplitting === undefined ? { ...member, ...unsplit } : member,
1442
+ )
1443
+ : output?.codeSplitting === undefined
1444
+ ? { ...output, ...unsplit }
1445
+ : output,
1446
+ },
1447
+ },
1448
+ }
1374
1449
  }
1375
1450
  `
1376
1451
  }),
@@ -1533,8 +1608,9 @@ export function service(override?: UserConfig): UserConfig {
1533
1608
  return mergeOverride(project, override)
1534
1609
  }
1535
1610
  `,
1536
- studies: `// Authored study proofs run installed packages through bounded subprocesses and protocol fixtures,
1537
- // so this project is isolated in its own gate script, test:studies.
1611
+ studies: `// The @orkestrel/study engine drives these proofs, running installed packages through bounded
1612
+ // subprocesses and protocol fixtures, so this project is isolated in its own gate script,
1613
+ // test:studies.
1538
1614
  export function studies(override?: UserConfig): UserConfig {
1539
1615
  const project: UserConfig = {
1540
1616
  resolve,
@@ -1572,9 +1648,9 @@ export function studies(override?: UserConfig): UserConfig {
1572
1648
  `,
1573
1649
  probe: `// A workbench, not a proof. No gate selects this project. Run in test mode by the
1574
1650
  // \`test:probe\` script, it collects \`tmp/probes/**/*.test.ts\`. Run in benchmark mode by the
1575
- // \`test:bench\` script, the same workbench also collects \`tests/**/*.test.ts\` for a \`bench\` block,
1576
- // so a suite may carry a bench beside its ordinary tests without a second project. The mode
1577
- // guard around each \`bench\` call keeps it out of test mode, so it never executes there.
1651
+ // \`test:bench\` script, it collects \`*.bench.ts\` files under \`tmp/probes\` and \`tests\`.
1652
+ // Each benchmark is a regular test that uses its context's \`bench\` fixture and awaits
1653
+ // \`bench(name, options, fn).run()\` or \`bench.compare(...)\`.
1578
1654
  export function probe(override?: UserConfig): UserConfig {
1579
1655
  const project: UserConfig = {
1580
1656
  resolve,
@@ -1587,7 +1663,7 @@ export function probe(override?: UserConfig): UserConfig {
1587
1663
  fileParallelism: false,
1588
1664
  sequence: { groupOrder: 1 },
1589
1665
  pool: 'threads',
1590
- benchmark: { include: ['tmp/probes/**/*.test.ts', 'tests/**/*.test.ts'] },
1666
+ benchmark: { include: ['tmp/probes/**/*.bench.ts', 'tests/**/*.bench.ts'] },
1591
1667
  },
1592
1668
  }
1593
1669
  return mergeOverride(project, override)
@@ -2602,11 +2678,14 @@ export const DISTRIBUTION_NPM = process.platform === 'win32' ? 'npm.cmd' : 'npm'
2602
2678
  // process: the command and its plain-text diagnostics are the same across the
2603
2679
  // compiler majors this toolchain supports, and its in-process API is not. It is
2604
2680
  // resolved from the workspace under proof, so a consumer of the packed artifact is
2605
- // checked by the same compiler that workspace's own \`check\` script runs.
2681
+ // checked by the same compiler that workspace's own \`check\` script runs. TypeScript 7 exports
2682
+ // \`package.json\` but not \`bin/tsc\`, so the path is joined from the manifest's directory.
2683
+ /** Names the TypeScript manifest installed by the workspace under proof. */
2684
+ export const DISTRIBUTION_TYPESCRIPT = createRequire(
2685
+ join(DISTRIBUTION_ROOT, 'package.json'),
2686
+ ).resolve('typescript/package.json')
2606
2687
  /** Names the compiler installed by the workspace under proof. */
2607
- export const DISTRIBUTION_COMPILER = createRequire(join(DISTRIBUTION_ROOT, 'package.json')).resolve(
2608
- 'typescript/bin/tsc',
2609
- )
2688
+ export const DISTRIBUTION_COMPILER = join(dirname(DISTRIBUTION_TYPESCRIPT), 'bin', 'tsc')
2610
2689
  // Windows needs a shell to launch a \`.cmd\`: Node refuses one directly since the
2611
2690
  // batch-argument hardening, and \`spawnSync\` returns \`EINVAL\` with a null status
2612
2691
  // rather than an exit code a caller can read. Every following argument is a literal or
@@ -2874,6 +2953,50 @@ export function readDistributionManifestName(path: string): string {
2874
2953
  return manifest.name
2875
2954
  }
2876
2955
 
2956
+ // A host carries a package's required peers at its own root. A consumer that carries none leaves
2957
+ // npm to place them, and npm can then resolve an optional peer of a peer to a release the
2958
+ // package's own range refuses, so the consumer declares them as a host would.
2959
+ /**
2960
+ * Reads the peers a host must carry: every peer dependency its metadata does not mark optional.
2961
+ *
2962
+ * @param path - The manifest to read.
2963
+ * @returns Each required peer's name mapped to its declared range.
2964
+ */
2965
+ export function readDistributionPeers(path: string): Readonly<Record<string, string>> {
2966
+ const manifest = readDistributionJSON(path)
2967
+ if (!isDistributionRecord(manifest) || !isDistributionRecord(manifest.peerDependencies)) {
2968
+ return {}
2969
+ }
2970
+ const meta = isDistributionRecord(manifest.peerDependenciesMeta)
2971
+ ? manifest.peerDependenciesMeta
2972
+ : undefined
2973
+ const peers = Object.entries(manifest.peerDependencies).filter(
2974
+ (entry): entry is [string, string] => typeof entry[1] === 'string',
2975
+ )
2976
+ return Object.fromEntries(
2977
+ peers.filter(([name]) => {
2978
+ const entry = meta?.[name]
2979
+ return !isDistributionRecord(entry) || entry.optional !== true
2980
+ }),
2981
+ )
2982
+ }
2983
+
2984
+ /**
2985
+ * Writes the consumer manifest, declaring the required peers as dependencies.
2986
+ *
2987
+ * @param peers - Each required peer's name mapped to its declared range.
2988
+ * @returns The manifest text; the bare manifest when the package declares no required peer.
2989
+ */
2990
+ export function createDistributionConsumerManifest(
2991
+ peers: Readonly<Record<string, string>>,
2992
+ ): string {
2993
+ const manifest: unknown = JSON.parse(DISTRIBUTION_CONSUMER_MANIFEST)
2994
+ if (Object.keys(peers).length === 0 || !isDistributionRecord(manifest)) {
2995
+ return DISTRIBUTION_CONSUMER_MANIFEST
2996
+ }
2997
+ return \`\${JSON.stringify({ ...manifest, dependencies: peers })}\\n\`
2998
+ }
2999
+
2877
3000
  /**
2878
3001
  * Writes a consumer file after creating its parent directory.
2879
3002
  *
@@ -3508,7 +3631,8 @@ export function buildDistributionStage(scratch: string): DistributionStage {
3508
3631
  if (archives.length !== 1 || archive === undefined) {
3509
3632
  throw new Error(\`npm pack wrote no single archive: \${archives.join(', ')}\`)
3510
3633
  }
3511
- writeDistributionFile(join(consumer, 'package.json'), DISTRIBUTION_CONSUMER_MANIFEST)
3634
+ const peers = readDistributionPeers(join(DISTRIBUTION_ROOT, 'package.json'))
3635
+ writeDistributionFile(join(consumer, 'package.json'), createDistributionConsumerManifest(peers))
3512
3636
  writeDistributionFile(join(consumer, DISTRIBUTION_ESM_DRIVER), DISTRIBUTION_ESM_DRIVER_SOURCE)
3513
3637
  writeDistributionFile(join(consumer, DISTRIBUTION_CJS_DRIVER), DISTRIBUTION_CJS_DRIVER_SOURCE)
3514
3638
  const install = runDistributionNpm(
@@ -4591,8 +4715,7 @@ printf '%s\\n' \\
4591
4715
  `
4592
4716
  })
4593
4717
  });
4594
- //#endregion
4595
- //#region src/core/errors.ts
4718
+ // src/core/errors.ts
4596
4719
  /**
4597
4720
  * Represents the one error this package throws, carrying the coded reason it was raised.
4598
4721
  *
@@ -4661,8 +4784,7 @@ var ScaffoldError = class extends Error {
4661
4784
  function isScaffoldError(value) {
4662
4785
  return (0, _orkestrel_contract.isInstance)(value, ScaffoldError);
4663
4786
  }
4664
- //#endregion
4665
- //#region src/core/validators.ts
4787
+ // src/core/validators.ts
4666
4788
  /**
4667
4789
  * Narrows a value to a logical target-relative path.
4668
4790
  *
@@ -5221,8 +5343,7 @@ var isCompilerOptions = (0, _orkestrel_contract.recordOf)({
5221
5343
  on: isCompilerHooks,
5222
5344
  error: _orkestrel_contract.isFunction
5223
5345
  }, true);
5224
- //#endregion
5225
- //#region src/core/cloners.ts
5346
+ // src/core/cloners.ts
5226
5347
  /**
5227
5348
  * Snapshots an untrusted value into exact JSON data the caller owns.
5228
5349
  *
@@ -5269,8 +5390,7 @@ function cloneValue(value) {
5269
5390
  const outcome = (0, _orkestrel_contract.attempt)(() => (0, _orkestrel_contract.cloneJSONValue)(value));
5270
5391
  return outcome.success ? outcome.value : void 0;
5271
5392
  }
5272
- //#endregion
5273
- //#region src/core/parsers.ts
5393
+ // src/core/parsers.ts
5274
5394
  /**
5275
5395
  * Coerces an extension value or a `surface:name` selection into an extension.
5276
5396
  * @param value - An extension record or its selection text.
@@ -5385,8 +5505,7 @@ function parseSnapshot(value) {
5385
5505
  function parseCompilerOptions(value) {
5386
5506
  return isCompilerOptions(value) ? value : void 0;
5387
5507
  }
5388
- //#endregion
5389
- //#region src/core/helpers.ts
5508
+ // src/core/helpers.ts
5390
5509
  /**
5391
5510
  * Encodes bytes as exact lowercase hexadecimal text.
5392
5511
  *
@@ -6405,9 +6524,9 @@ function manifestToDependencies(manifest) {
6405
6524
  function renderSkillPointer(canonical, name) {
6406
6525
  const lines = canonical.split(/\r\n|\n/u);
6407
6526
  if (lines[0] !== "---") return void 0;
6408
- const closing = lines.indexOf("---", 1);
6409
- if (closing === -1) return void 0;
6410
- return `${lines.slice(0, closing + 1).join("\n")}\n${(0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.orchestration.skill, { name })}`;
6527
+ const end = lines.indexOf("---", 1);
6528
+ if (end === -1) return void 0;
6529
+ return `${lines.slice(0, end + 1).join("\n")}\n${(0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.orchestration.skill, { name })}`;
6411
6530
  }
6412
6531
  /**
6413
6532
  * Scans manifest text for its strings and object braces, in order.
@@ -6453,8 +6572,7 @@ function scanManifestTokens(text) {
6453
6572
  }
6454
6573
  return tokens;
6455
6574
  }
6456
- //#endregion
6457
- //#region src/core/compilers.ts
6575
+ // src/core/compilers.ts
6458
6576
  /**
6459
6577
  * Projects a blueprint into browser extensions restricted to occupied browser axes.
6460
6578
  * @param blueprint - The workspace specification.
@@ -6630,8 +6748,10 @@ function srcToExports(src) {
6630
6748
  * @returns The merged set, sorted by package name.
6631
6749
  *
6632
6750
  * @remarks
6633
- * The shared toolchain is the baseline every generated workspace carries, and
6634
- * each declared axis adds the set its host needs. A declared extra or peer is
6751
+ * The shared toolchain is the baseline every generated workspace carries.
6752
+ * A selected browser framework applies its toolchain hold before the host-specific sets.
6753
+ * Vue faces on either axis select TypeScript 6.0.3; other workspaces select TypeScript 7.0.2.
6754
+ * Each declared axis adds the set its host needs. A declared extra or peer is
6635
6755
  * applied after those, so a workspace that pins a range for a package the
6636
6756
  * conditional sets also name gets the range it declared. An extra that restates
6637
6757
  * a shared toolchain pin never reaches here, because the gate refuses it. A peer
@@ -6646,6 +6766,11 @@ function srcToExports(src) {
6646
6766
  * to drive. A workspace {@link BROWSE_UPSTREAM} names receives nothing either, because
6647
6767
  * `@orkestrel/browser` depends on it at runtime and the declaration would close a cycle.
6648
6768
  *
6769
+ * A journey axis with a browser application receives {@link CAPTURE_DEV_DEPENDENCIES}.
6770
+ * A workspace {@link CAPTURE_UPSTREAM} names receives no capture seed, because it is capture
6771
+ * itself or a member of capture's runtime closure. A browser source, styles surface, or browser
6772
+ * setup alone selects no capture dependency.
6773
+ *
6649
6774
  * A peer is declared here as well as under `peerDependencies`, because a peer is
6650
6775
  * not installed by the workspace that declares it and developing against one
6651
6776
  * requires it present. A runtime dependency is the opposite case and is removed:
@@ -6672,7 +6797,9 @@ function blueprintToDevDependencies(blueprint) {
6672
6797
  const own = blueprint.src.length > 0 || sheets ? `@orkestrel/${blueprint.name}` : blueprint.name;
6673
6798
  const prior = {
6674
6799
  ...BASE_DEV_DEPENDENCIES,
6800
+ ...Object.fromEntries(Object.entries(blueprintToToolchainHolds(blueprint)).map(([name, hold]) => [name, hold.range])),
6675
6801
  ...rendered && !BROWSE_UPSTREAM.includes(own) ? BROWSE_DEV_DEPENDENCIES : {},
6802
+ ...blueprint.journey && blueprint.app.includes("browser") && !CAPTURE_UPSTREAM.includes(own) ? CAPTURE_DEV_DEPENDENCIES : {},
6676
6803
  ...sheets ? STYLES_DEV_DEPENDENCIES : {},
6677
6804
  ...blueprint.src.length > 0 || blueprint.bin ? DECLARATION_DEV_DEPENDENCIES : {},
6678
6805
  ...blueprint.src.includes("browser") || blueprint.setup.includes("browser") || sheets ? SOURCE_BROWSER_DEV_DEPENDENCIES : {},
@@ -6692,6 +6819,21 @@ function blueprintToDevDependencies(blueprint) {
6692
6819
  return Object.fromEntries(Object.entries(merged).filter(([name]) => name !== own && !runtime.has(name)).sort(([left], [right]) => (0, _orkestrel_contract.compareValues)(left, right)));
6693
6820
  }
6694
6821
  /**
6822
+ * Projects a blueprint into the toolchain holds its browser frameworks require.
6823
+ * @param blueprint - The workspace specification.
6824
+ * @returns The held tools for selected browser framework faces; empty without a framework.
6825
+ * @example
6826
+ * ```ts
6827
+ * import { blueprintToToolchainHolds, createBlueprint } from '@orkestrel/scaffold'
6828
+ *
6829
+ * blueprintToToolchainHolds(createBlueprint('router', { src: ['core'] })) // {}
6830
+ * ```
6831
+ */
6832
+ function blueprintToToolchainHolds(blueprint) {
6833
+ const frameworks = blueprintToFaces(blueprint).map((face) => face.name);
6834
+ return Object.fromEntries(Object.entries(TOOLCHAIN_HOLDS).filter(([, hold]) => frameworks.includes(hold.framework)));
6835
+ }
6836
+ /**
6695
6837
  * Projects the scoped npm overrides required by a selected browser showcase.
6696
6838
  *
6697
6839
  * @param blueprint - The workspace specification.
@@ -6828,6 +6970,9 @@ function replaceManifestOverride(manifest, path, range) {
6828
6970
  * The configuration paths interpolated here are the same ones `SRC_MATRIX` and
6829
6971
  * `APP_MATRIX` list as each environment's configuration files, so a rename in
6830
6972
  * either matrix is a rename in both places.
6973
+ * A browser application's journey axis adds `journey` (`capture journey`) and `capture`
6974
+ * (`capture frames`) beside `test:journey`. The scoped commands take an explicit selection;
6975
+ * the whole-suite `test:journey` invocation remains in the test chain.
6831
6976
  *
6832
6977
  * @example
6833
6978
  * ```ts
@@ -6926,6 +7071,8 @@ function blueprintToScripts(blueprint) {
6926
7071
  ...blueprint.setup.includes("browser") ? { "test:setup:browser": `${vitest} --project setup:browser` } : {},
6927
7072
  ...blueprint.journey && blueprint.app.includes("browser") ? {
6928
7073
  "test:journey": journey,
7074
+ journey: "capture journey",
7075
+ capture: "capture frames",
6929
7076
  ...Object.fromEntries(application.map((name) => [`test:journey:${name}`, `${journey} --mode ${name}`]))
6930
7077
  } : {},
6931
7078
  ...blueprint.skills ? { "test:skills": `${vitest} --project skills` } : {},
@@ -6933,7 +7080,7 @@ function blueprintToScripts(blueprint) {
6933
7080
  ...blueprint.conformance ? { "test:conformance": `${vitest} --project conformance` } : {},
6934
7081
  ...blueprint.tree ? { "test:tree": `${vitest} --project tree` } : {},
6935
7082
  "test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
6936
- "test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
7083
+ "test:bench": "vitest bench --config vite.config.ts --no-cache --project \"probe (bench)\" --mode benchmark",
6937
7084
  ...publishes ? { "test:distribution": `${vitest} --project distribution` } : {},
6938
7085
  ...integrates ? { "test:integration": `${vitest} --project integration` } : {},
6939
7086
  ...blueprint.service ? { "test:service": `${vitest} --project service` } : {},
@@ -6998,6 +7145,8 @@ function blueprintToScripts(blueprint) {
6998
7145
  * rewrites, and one carrying skills adds `test:skills`. Publishing adds the pack and publication lifecycle scripts.
6999
7146
  * Sheet and framework faces add their check and build scripts, application frameworks add dev scripts,
7000
7147
  * and selected showcases and journeys add their mode scripts.
7148
+ * A browser application's journey axis also adds `journey` and `capture`. Their generated
7149
+ * commands are writable and have no predecessor forms; customized values remain caller-owned.
7001
7150
  * Aggregate test scripts and
7002
7151
  * maintainer-owned gate chains stay outside the region.
7003
7152
  *
@@ -7029,7 +7178,7 @@ function blueprintToWritableScripts(blueprint) {
7029
7178
  const sheet = sheets.some((face) => name === `build:src:${face}` || name === `check:src:${face}`);
7030
7179
  const framework = blueprintToFaces(blueprint).some((extension) => extension.surface === "browser" && extension.axes.some((axis) => name === `check:${axis}:${extension.name}` || name === `build:${axis}:${extension.name}` || axis === "app" && name === `dev:${extension.name}`));
7031
7180
  const showcase = name === "showcase" || name.startsWith("showcase:") || name === "build:showcase" || name.startsWith("build:showcase:");
7032
- if (!direct && !sheet && !framework && !showcase) return [];
7181
+ if (!direct && !sheet && !framework && !showcase && !(name === "journey" || name === "capture")) return [];
7033
7182
  return [{
7034
7183
  name,
7035
7184
  command,
@@ -7254,7 +7403,8 @@ function blueprintToRootTsconfig(blueprint) {
7254
7403
  * Projects a blueprint into the project labels its root Vitest configuration registers.
7255
7404
  *
7256
7405
  * @param blueprint - The workspace specification.
7257
- * @returns Project labels in registration order, including wrapper-registered sheet faces.
7406
+ * @returns Project labels in registration order, including wrapper-registered sheet faces and
7407
+ * the probe benchmark variant.
7258
7408
  *
7259
7409
  * @example
7260
7410
  * ```ts
@@ -7288,7 +7438,8 @@ function blueprintToProjects(blueprint) {
7288
7438
  ...blueprint.studies ? ["studies"] : [],
7289
7439
  ...blueprint.src.length > 0 || styled ? ["distribution"] : [],
7290
7440
  ...blueprint.integration ? ["integration"] : [],
7291
- "probe"
7441
+ "probe",
7442
+ "probe (bench)"
7292
7443
  ];
7293
7444
  }
7294
7445
  /**
@@ -8470,9 +8621,9 @@ function insertManifestSection(manifest, section, dependencies, present) {
8470
8621
  const root = tokens.find((token) => token.text === "}" && token.depth === 0)?.index;
8471
8622
  if (bounds === void 0) {
8472
8623
  if (present || root === void 0) return void 0;
8473
- const breaking = head === void 0 ? -1 : manifest.lastIndexOf("\n", head);
8474
- const margin = breaking < 0 ? "" : manifest.slice(breaking + 1, head);
8475
- const gap = breaking < 0 || /\S/u.test(margin) ? "" : `\n${margin}`;
8624
+ const lineBreak = head === void 0 ? -1 : manifest.lastIndexOf("\n", head);
8625
+ const margin = lineBreak < 0 ? "" : manifest.slice(lineBreak + 1, head);
8626
+ const gap = lineBreak < 0 || /\S/u.test(margin) ? "" : `\n${margin}`;
8476
8627
  const block = `${JSON.stringify(section)}: {${lines.map((line) => `${gap === "" ? "" : `${gap}${margin}`}${line}`).join(",")}${gap}}`;
8477
8628
  const tail = manifest.slice(1, root).trimEnd().length;
8478
8629
  const [position, insertion] = neighbor === void 0 ? [tail + 1, manifest.charAt(tail) === "{" ? block : `,${gap}${block}`] : section === "devDependencies" ? [neighbor.close + 1, `,${gap}${block}`] : [neighbor.start, `${block},${gap}`];
@@ -8494,11 +8645,11 @@ function insertManifestSection(manifest, section, dependencies, present) {
8494
8645
  const first = declarations[0];
8495
8646
  const last = declarations.at(-1);
8496
8647
  if (first === void 0 || last === void 0) {
8497
- const opening = manifest.lastIndexOf("\n", open);
8498
- const level = opening < 0 ? "" : /^\s*/u.exec(manifest.slice(opening + 1, open))?.[0] ?? "";
8499
- const separator = opening < 0 ? "" : `\n${level}${level}`;
8500
- const ending = opening < 0 ? "" : `\n${level}`;
8501
- return `${manifest.slice(0, open + 1)}${lines.map((line) => `${separator}${line}`).join(",")}${ending}${manifest.slice(close)}`;
8648
+ const lineBreak = manifest.lastIndexOf("\n", open);
8649
+ const level = lineBreak < 0 ? "" : /^\s*/u.exec(manifest.slice(lineBreak + 1, open))?.[0] ?? "";
8650
+ const separator = lineBreak < 0 ? "" : `\n${level}${level}`;
8651
+ const suffix = lineBreak < 0 ? "" : `\n${level}`;
8652
+ return `${manifest.slice(0, open + 1)}${lines.map((line) => `${separator}${line}`).join(",")}${suffix}${manifest.slice(close)}`;
8502
8653
  }
8503
8654
  const newline = manifest.lastIndexOf("\n", first.start);
8504
8655
  const indent = newline < 0 ? "" : manifest.slice(newline + 1, first.start);
@@ -8609,10 +8760,10 @@ function replaceManifestScripts(manifest, scripts) {
8609
8760
  }];
8610
8761
  });
8611
8762
  const missing = scripts.filter((script) => !written.has(script.name));
8612
- const opening = manifest.lastIndexOf("\n", start);
8613
- const level = opening < 0 ? "" : /^\s*/u.exec(manifest.slice(opening + 1, start))?.[0] ?? "";
8614
- const emptySeparator = opening < 0 ? "" : `\n${level}${level}`;
8615
- const emptyClosing = opening < 0 ? "" : `\n${level}`;
8763
+ const lineBreak = manifest.lastIndexOf("\n", start);
8764
+ const level = lineBreak < 0 ? "" : /^\s*/u.exec(manifest.slice(lineBreak + 1, start))?.[0] ?? "";
8765
+ const emptySeparator = lineBreak < 0 ? "" : `\n${level}${level}`;
8766
+ const emptySuffix = lineBreak < 0 ? "" : `\n${level}`;
8616
8767
  const tail = start + manifest.slice(start, end - 1).trimEnd().length;
8617
8768
  const newline = first === void 0 ? -1 : manifest.lastIndexOf("\n", first);
8618
8769
  const indent = first === void 0 || newline < 0 ? "" : manifest.slice(newline + 1, first);
@@ -8628,7 +8779,7 @@ function replaceManifestScripts(manifest, scripts) {
8628
8779
  const appended = missing.length === 0 ? [] : first === void 0 ? [{
8629
8780
  start: start + 1,
8630
8781
  end: end - 1,
8631
- text: `${missing.map((script) => `${emptySeparator}${JSON.stringify(script.name)}: ${JSON.stringify(script.command)}`).join(",")}${emptyClosing}`
8782
+ text: `${missing.map((script) => `${emptySeparator}${JSON.stringify(script.name)}: ${JSON.stringify(script.command)}`).join(",")}${emptySuffix}`
8632
8783
  }] : [...Map.groupBy(placements, ({ anchor }) => anchor)].map(([anchor, group]) => ({
8633
8784
  start: anchor,
8634
8785
  end: anchor,
@@ -9099,8 +9250,7 @@ function overridesToQuestions(overrides, artifacts) {
9099
9250
  }] : []];
9100
9251
  });
9101
9252
  }
9102
- //#endregion
9103
- //#region src/core/factories.ts
9253
+ // src/core/factories.ts
9104
9254
  /**
9105
9255
  * Constructs a {@link Blueprint} from a name and the fields that differ from the defaults.
9106
9256
  *
@@ -9177,8 +9327,7 @@ function createBlueprint(name, input) {
9177
9327
  if (blueprint === void 0) throw new ScaffoldError("INVALID", "The filled record is not a blueprint.", { name });
9178
9328
  return blueprint;
9179
9329
  }
9180
- //#endregion
9181
- //#region src/core/Compiler.ts
9330
+ // src/core/Compiler.ts
9182
9331
  /**
9183
9332
  * Represents the compile spine: draft, gate, pin, run in that order over a blueprint.
9184
9333
  *
@@ -9190,7 +9339,7 @@ function createBlueprint(name, input) {
9190
9339
  * records the coded reason beside them; the stages after a failed one never run,
9191
9340
  * so the records stop where the compile stopped.
9192
9341
  *
9193
- * The compile fails closed on one rule: a scaffolding carries a plan exactly
9342
+ * The compile fails closed on one rule: a compile result carries a plan exactly
9194
9343
  * when no question blocks. A refused blueprint is answered rather than raised,
9195
9344
  * so a caller reads the refusal from the value it asked for.
9196
9345
  *
@@ -9215,10 +9364,10 @@ function createBlueprint(name, input) {
9215
9364
  * import { Compiler, createBlueprint } from '@orkestrel/scaffold'
9216
9365
  *
9217
9366
  * const compiler = new Compiler()
9218
- * const scaffolding = compiler.compile(createBlueprint('router', { src: ['core'] }))
9367
+ * const result = compiler.compile(createBlueprint('router', { src: ['core'] }))
9219
9368
  *
9220
- * scaffolding.plan?.artifacts // every planned file, in group order
9221
- * scaffolding.stages // one CompileRecord per stage that ran
9369
+ * result.plan?.artifacts // every planned file, in group order
9370
+ * result.stages // one CompileRecord per stage that ran
9222
9371
  * compiler.destroy()
9223
9372
  * ```
9224
9373
  */
@@ -9255,7 +9404,7 @@ var Compiler = class {
9255
9404
  *
9256
9405
  * @param blueprint - The workspace specification to compile.
9257
9406
  * @param groups - The artifact groups to cover; every group when absent.
9258
- * @returns The scaffolding, carrying a plan only when the gate passed.
9407
+ * @returns The compile result, carrying a plan only when the gate passed.
9259
9408
  * @throws {@link ScaffoldError} coded `INVALID` when an argument is not the
9260
9409
  * exact shape, and `DESTROYED` when the compiler has been torn down.
9261
9410
  *
@@ -9284,10 +9433,10 @@ var Compiler = class {
9284
9433
  compile(blueprint, groups) {
9285
9434
  this.#assertAlive();
9286
9435
  const accepted = this.#accept(blueprint, parseBlueprint, "blueprint");
9287
- const scaffolding = this.#scaffold(accepted, this.#select(groups));
9288
- if (scaffolding.plan === void 0) this.#emitter.emit("block", scaffolding.questions);
9289
- this.#emitter.emit("compile", scaffolding);
9290
- return scaffolding;
9436
+ const result = this.#scaffold(accepted, this.#select(groups));
9437
+ if (result.plan === void 0) this.#emitter.emit("block", result.questions);
9438
+ this.#emitter.emit("compile", result);
9439
+ return result;
9291
9440
  }
9292
9441
  /**
9293
9442
  * Compiles a blueprint and compares its plan to a target's current content.
@@ -9323,11 +9472,11 @@ var Compiler = class {
9323
9472
  this.#assertAlive();
9324
9473
  const accepted = this.#accept(blueprint, parseBlueprint, "blueprint");
9325
9474
  const observed = this.#accept(current, parseSnapshot, "current");
9326
- const scaffolding = this.#scaffold(accepted, this.#select(groups));
9327
- if (scaffolding.plan === void 0) this.#emitter.emit("block", scaffolding.questions);
9475
+ const compiled = this.#scaffold(accepted, this.#select(groups));
9476
+ if (compiled.plan === void 0) this.#emitter.emit("block", compiled.questions);
9328
9477
  const result = {
9329
- findings: scaffolding.plan === void 0 ? [] : planToFindings(scaffolding.plan, observed),
9330
- questions: scaffolding.questions
9478
+ findings: compiled.plan === void 0 ? [] : planToFindings(compiled.plan, observed),
9479
+ questions: compiled.questions
9331
9480
  };
9332
9481
  this.#emitter.emit("audit", result);
9333
9482
  return result;
@@ -9478,7 +9627,6 @@ var Compiler = class {
9478
9627
  return error;
9479
9628
  }
9480
9629
  };
9481
- //#endregion
9482
9630
  exports.APP_BROWSER_DEV_DEPENDENCIES = APP_BROWSER_DEV_DEPENDENCIES;
9483
9631
  exports.APP_DEV_DEPENDENCIES = APP_DEV_DEPENDENCIES;
9484
9632
  exports.APP_MATRIX = APP_MATRIX;
@@ -9492,9 +9640,11 @@ exports.BIN_OUTPUT_PATH = BIN_OUTPUT_PATH;
9492
9640
  exports.BROWSE_DEV_DEPENDENCIES = BROWSE_DEV_DEPENDENCIES;
9493
9641
  exports.BROWSE_UPSTREAM = BROWSE_UPSTREAM;
9494
9642
  exports.CANON_PATHS = CANON_PATHS;
9643
+ exports.CAPTURE_DEV_DEPENDENCIES = CAPTURE_DEV_DEPENDENCIES;
9644
+ exports.CAPTURE_UPSTREAM = CAPTURE_UPSTREAM;
9495
9645
  exports.CATALOG_AGENT_PATH = CATALOG_AGENT_PATH;
9496
- exports.CATALOG_CLOSING_MARKER = CATALOG_CLOSING_MARKER;
9497
- exports.CATALOG_OPENING_MARKER = CATALOG_OPENING_MARKER;
9646
+ exports.CATALOG_END_MARKER = CATALOG_END_MARKER;
9647
+ exports.CATALOG_START_MARKER = CATALOG_START_MARKER;
9498
9648
  exports.CONFIG_TEMPLATES = CONFIG_TEMPLATES;
9499
9649
  exports.CONFORMANCE_TEST_PATH = CONFORMANCE_TEST_PATH;
9500
9650
  exports.CONTROL_CHARACTER_PATTERN = CONTROL_CHARACTER_PATTERN;
@@ -9567,6 +9717,7 @@ exports.TAB_WIDTH = TAB_WIDTH;
9567
9717
  exports.TARGET_SKILL_NAMES = TARGET_SKILL_NAMES;
9568
9718
  exports.THEMES_BARREL_PATH = THEMES_BARREL_PATH;
9569
9719
  exports.THEMES_ENTRY_PATH = THEMES_ENTRY_PATH;
9720
+ exports.TOOLCHAIN_HOLDS = TOOLCHAIN_HOLDS;
9570
9721
  exports.TREE_TEST_PATH = TREE_TEST_PATH;
9571
9722
  exports.VERSION_PATTERN = VERSION_PATTERN;
9572
9723
  exports.WORKSPACE_DEV_ENGINES = WORKSPACE_DEV_ENGINES;
@@ -9595,6 +9746,7 @@ exports.blueprintToScripts = blueprintToScripts;
9595
9746
  exports.blueprintToSheets = blueprintToSheets;
9596
9747
  exports.blueprintToSourceArtifacts = blueprintToSourceArtifacts;
9597
9748
  exports.blueprintToTestArtifacts = blueprintToTestArtifacts;
9749
+ exports.blueprintToToolchainHolds = blueprintToToolchainHolds;
9598
9750
  exports.blueprintToWritableScripts = blueprintToWritableScripts;
9599
9751
  exports.bytesToHex = bytesToHex;
9600
9752
  exports.catalogToLayers = catalogToLayers;