@orkestrel/scaffold 0.0.5 → 0.0.6

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.
@@ -104,9 +104,12 @@ var APP_MATRIX = Object.freeze({
104
104
  * The root docs (`AGENTS.md` / `CLAUDE.md`), `LICENSE`, `.agents`, `.claude`, `.codex`,
105
105
  * the four SessionStart hook scripts (`scripts/deps.sh` / `scripts/cursor.sh` /
106
106
  * `scripts/codex.sh` / `scripts/ollama.sh`), the repository coding-law policy module,
107
- * the line's seven byte-identical root dotfiles, and the two guides-grouped mirrors every repo carries: the line-wide
108
- * dev-tooling guide (`guides/src/guide.md`) and the
109
- * scaffold engine's own self-guide (`guides/src/scaffold.md`).
107
+ * the line's seven byte-identical root dotfiles, and the two guides-grouped
108
+ * mirror candidates: the line-wide dev-tooling guide
109
+ * (`guides/src/guide.md`) and the scaffold engine's own self-guide
110
+ * (`guides/src/scaffold.md`). `stageHost` vendors both; each plan carries the
111
+ * subset selected by `selectHostPaths`, omitting the target blueprint's own
112
+ * guide.
110
113
  */
111
114
  var HOST_PATHS = Object.freeze([
112
115
  "AGENTS.md",
@@ -218,15 +221,15 @@ var DEFAULT_VERSION = "0.0.1";
218
221
  /** The `engines.node` range the `blueprint` builder fills. */
219
222
  var DEFAULT_ENGINES = `>=${MINIMUM_NODE_VERSION}`;
220
223
  /** The devDependency range generated packages pin `@orkestrel/scaffold` at. */
221
- var SCAFFOLD_RANGE = "^0.0.5";
224
+ var SCAFFOLD_RANGE = "^0.0.6";
222
225
  /** Tooling versions shared by scaffold and every generated workspace. */
223
226
  var BASE_DEV_DEPENDENCIES = Object.freeze({
224
227
  "@microsoft/api-extractor": "^7.58.12",
225
228
  "@orkestrel/guide": "^0.0.5",
226
229
  "@orkestrel/scaffold": SCAFFOLD_RANGE,
227
- "@types/node": "^26.1.1",
228
- oxfmt: "^0.60.0",
229
- oxlint: "^1.75.0",
230
+ "@types/node": "^26.1.2",
231
+ oxfmt: "^0.61.0",
232
+ oxlint: "^1.76.0",
230
233
  typescript: "^6.0.3",
231
234
  vite: "^8.1.5",
232
235
  "vite-plugin-dts": "^5.0.3",
@@ -1140,6 +1143,22 @@ function snapshotOf(current) {
1140
1143
  return Object.fromEntries(entries);
1141
1144
  }
1142
1145
  /**
1146
+ * Select host paths without the guide owned by the target blueprint.
1147
+ *
1148
+ * @param paths - Host artifact paths in deterministic input order.
1149
+ * @param name - The target blueprint's unscoped package name.
1150
+ * @returns Every host path except `guides/src/<name>.md`, in input order.
1151
+ *
1152
+ * @example
1153
+ * ```ts
1154
+ * selectHostPaths(['guides/src/guide.md', 'LICENSE'], 'guide') // ['LICENSE']
1155
+ * ```
1156
+ */
1157
+ function selectHostPaths(paths, name) {
1158
+ const guide = `guides/src/${name}.md`;
1159
+ return paths.filter((path) => path !== guide);
1160
+ }
1161
+ /**
1143
1162
  * Find the first exact or portable case-insensitive path collision.
1144
1163
  *
1145
1164
  * @param paths - Portable paths in deterministic input order.
@@ -1442,6 +1461,29 @@ function manifestToDependencies(manifestText) {
1442
1461
  return dependencies;
1443
1462
  }
1444
1463
  /**
1464
+ * Project a `package.json` text to its own string `name`.
1465
+ *
1466
+ * @param manifest - The `package.json` file content.
1467
+ * @returns The own string `name`, or `undefined` when the manifest exceeds its
1468
+ * byte ceiling, is malformed, has a non-object root, or has no own string
1469
+ * `name`.
1470
+ *
1471
+ * @example
1472
+ * ```ts
1473
+ * import { manifestToName } from '@orkestrel/scaffold'
1474
+ *
1475
+ * manifestToName('{"name":"@orkestrel/router"}') // '@orkestrel/router'
1476
+ * manifestToName('{}') // undefined
1477
+ * ```
1478
+ */
1479
+ function manifestToName(manifest) {
1480
+ if (manifest.length > 1048576 || contentByteLength(manifest) > 1048576) return;
1481
+ const parsed = (0, _orkestrel_contract.parseJSON)(manifest);
1482
+ if (!(0, _orkestrel_contract.isRecord)(parsed)) return void 0;
1483
+ const name = ownDataValue(parsed, "name");
1484
+ return typeof name === "string" ? name : void 0;
1485
+ }
1486
+ /**
1445
1487
  * Compare a declared range to the registry latest.
1446
1488
  *
1447
1489
  * @param range - The declared semver range.
@@ -2146,6 +2188,7 @@ var isPlan = (0, _orkestrel_contract.andOf)((0, _orkestrel_contract.andOf)((0, _
2146
2188
  function validatePlan(plan) {
2147
2189
  const blueprintValidation = validateBlueprint(plan.blueprint);
2148
2190
  const questions = [...blueprintValidation.questions];
2191
+ const warnings = [...blueprintValidation.warnings];
2149
2192
  if (!hasValidPlanBytes(plan)) questions.push({
2150
2193
  field: "artifacts",
2151
2194
  text: "Plan artifact content exceeds the retained byte limits",
@@ -2170,16 +2213,20 @@ function validatePlan(plan) {
2170
2213
  });
2171
2214
  continue;
2172
2215
  }
2173
- if (artifact.path === "package.json") questions.push({
2174
- field: "overrides",
2175
- text: "Override path \"package.json\" targets the blueprint-owned publication boundary",
2176
- blocking: true
2177
- });
2216
+ if (artifact.path === "package.json") {
2217
+ questions.push({
2218
+ field: "overrides",
2219
+ text: "Override path \"package.json\" targets the blueprint-owned publication boundary",
2220
+ blocking: true
2221
+ });
2222
+ continue;
2223
+ }
2224
+ warnings.push(`Override path "${item.path}" replaces its planned artifact content`);
2178
2225
  }
2179
2226
  return {
2180
2227
  valid: questions.length === 0,
2181
2228
  questions,
2182
- warnings: blueprintValidation.warnings
2229
+ warnings
2183
2230
  };
2184
2231
  }
2185
2232
  /** Determine whether every guide body fits the public UTF-8 artifact byte limit. */
@@ -7097,6 +7144,7 @@ function singleSrcViteConfig(environment) {
7097
7144
  const machinery = viteMachinery([environment]);
7098
7145
  const header = viteHeader(machinery);
7099
7146
  if (environment === "browser") return `${header}
7147
+ if (!hasChromium) console.warn('browser projects skipped: Chromium absent (${SRC_MATRIX.browser.project})')
7100
7148
  ${EXPORT_KEYWORD} const srcBrowser = (config?: UserConfig): UserConfig =>
7101
7149
  mergeConfig(
7102
7150
  {
@@ -7155,7 +7203,7 @@ ${EXPORT_KEYWORD} const guides = (config?: UserConfig): UserConfig =>
7155
7203
  export default defineConfig({
7156
7204
  resolve,
7157
7205
  test: {
7158
- projects: [srcBrowser, policy, guides],
7206
+ projects: [...(hasChromium ? [srcBrowser] : []), policy, guides],
7159
7207
  },
7160
7208
  })
7161
7209
  `;
@@ -7381,14 +7429,18 @@ ${EXPORT_KEYWORD} const integration = (config?: UserConfig): UserConfig =>
7381
7429
  const blocks = nonCore.map((environment) => environment === "browser" ? browserBlock : serverBlock).join("") + binBlock;
7382
7430
  const projectNames = [
7383
7431
  ...hasCore ? ["srcCore"] : [],
7384
- ...nonCore.map((environment) => `src${pascalCase(environment)}`),
7432
+ ...nonCore.map((environment) => environment === "browser" ? "...(hasChromium ? [srcBrowser] : [])" : `src${pascalCase(environment)}`),
7385
7433
  "policy",
7386
7434
  "guides",
7387
7435
  ...engine ? ["srcBin"] : [],
7388
7436
  ...engine ? ["integration"] : []
7389
7437
  ];
7438
+ const inlineProjects = ` projects: [${projectNames.join(", ")}],`;
7439
+ const renderedProjects = computeColumnWidth(inlineProjects) <= 100 ? inlineProjects : ` projects: [
7440
+ ${projectNames.map((project) => ` ${project},`).join("\n")}
7441
+ ],`;
7390
7442
  return `${header}
7391
- ${EXPORT_KEYWORD} const srcCore = (config?: UserConfig): UserConfig =>
7443
+ ${machinery.browser ? `if (!hasChromium) console.warn('browser projects skipped: Chromium absent (${SRC_MATRIX.browser.project})')\n` : ""}${EXPORT_KEYWORD} const srcCore = (config?: UserConfig): UserConfig =>
7392
7444
  mergeConfig(
7393
7445
  {
7394
7446
  resolve,
@@ -7427,7 +7479,7 @@ ${blocks}
7427
7479
  export default defineConfig({
7428
7480
  resolve,
7429
7481
  test: {
7430
- projects: [${projectNames.join(", ")}],
7482
+ ${renderedProjects}
7431
7483
  },
7432
7484
  })
7433
7485
  `;
@@ -7475,7 +7527,7 @@ ${EXPORT_KEYWORD} const srcCore = (config?: UserConfig): UserConfig =>
7475
7527
  `);
7476
7528
  }
7477
7529
  if (src.includes("browser")) {
7478
- projects.push("srcBrowser");
7530
+ projects.push("...(hasChromium ? [srcBrowser] : [])");
7479
7531
  const coreOutput = hasSourceCore ? `
7480
7532
  output: { paths: { '@src/core': '../core/index.js' } },` : "";
7481
7533
  const coreExternal = hasSourceCore ? `id === '@src/core' || ` : "";
@@ -7592,7 +7644,7 @@ ${EXPORT_KEYWORD} const appCore = (config?: UserConfig): UserConfig =>
7592
7644
  `);
7593
7645
  }
7594
7646
  if (app.includes("browser")) {
7595
- projects.push("appBrowser()");
7647
+ projects.push("...(hasChromium ? [appBrowser()] : [])");
7596
7648
  blocks.push(`
7597
7649
  ${EXPORT_KEYWORD} function appBrowser(...config: readonly never[]): UserConfig {
7598
7650
  if (config.length > 0) {
@@ -7726,8 +7778,22 @@ ${EXPORT_KEYWORD} const integration = (config?: UserConfig): UserConfig =>
7726
7778
  )
7727
7779
  `);
7728
7780
  }
7781
+ const projectNames = [
7782
+ ...projects,
7783
+ "policy",
7784
+ "guides"
7785
+ ];
7786
+ const inlineProjects = ` projects: [${projectNames.join(", ")}],`;
7787
+ const renderedProjects = computeColumnWidth(inlineProjects) <= 100 ? inlineProjects : ` projects: [
7788
+ ${projectNames.map((project) => ` ${project},`).join("\n")}
7789
+ ],`;
7790
+ const browserProjects = [...src.includes("browser") ? [SRC_MATRIX.browser.project] : [], ...app.includes("browser") ? [APP_MATRIX.browser.project] : []];
7791
+ const browserNotice = serializeTypeScriptString(`browser projects skipped: Chromium absent (${browserProjects.join(", ")})`);
7792
+ const inlineBrowserNotice = `if (!hasChromium) console.warn(${browserNotice})`;
7793
+ const renderedBrowserNotice = browserProjects.length === 0 ? void 0 : computeColumnWidth(inlineBrowserNotice) <= 100 ? inlineBrowserNotice : `if (!hasChromium)
7794
+ console.warn(${browserNotice})`;
7729
7795
  return `${header}
7730
- ${policyViteProject()}
7796
+ ${renderedBrowserNotice === void 0 ? "" : `${renderedBrowserNotice}\n`}${policyViteProject()}
7731
7797
  ${EXPORT_KEYWORD} const guides = (config?: UserConfig): UserConfig =>
7732
7798
  mergeConfig(
7733
7799
  {
@@ -7747,17 +7813,13 @@ ${blocks.join("")}
7747
7813
  export default defineConfig({
7748
7814
  resolve,
7749
7815
  test: {
7750
- projects: [${[
7751
- ...projects,
7752
- "policy",
7753
- "guides"
7754
- ].join(", ")}],
7816
+ ${renderedProjects}
7755
7817
  },
7756
7818
  })
7757
7819
  `;
7758
7820
  }
7759
7821
  /**
7760
- * `configs/src/tsconfig.core.json` — unchanged core shape.
7822
+ * `configs/src/tsconfig.core.json` — host-neutral core with web interop declarations.
7761
7823
  *
7762
7824
  * @returns The core environment `tsconfig` file content, newline-terminated.
7763
7825
  *
@@ -7770,7 +7832,7 @@ function coreTsconfig() {
7770
7832
  return formatJson({
7771
7833
  extends: "../../tsconfig.json",
7772
7834
  compilerOptions: {
7773
- lib: ["ESNext"],
7835
+ lib: ["ESNext", "WebWorker"],
7774
7836
  types: [],
7775
7837
  noEmit: false,
7776
7838
  declaration: true,
@@ -7925,7 +7987,7 @@ function appTsconfig(environment, hasCore) {
7925
7987
  "ESNext",
7926
7988
  "DOM",
7927
7989
  "DOM.Iterable"
7928
- ] : ["ESNext"],
7990
+ ] : environment === "core" ? ["ESNext", "WebWorker"] : ["ESNext"],
7929
7991
  types: environment === "browser" ? ["vite/client", "vue"] : environment === "server" ? ["node"] : []
7930
7992
  },
7931
7993
  include
@@ -8527,12 +8589,15 @@ function guideTests(spec, pascal) {
8527
8589
  }
8528
8590
  /**
8529
8591
  * Draft the `guides` group's artifacts — the package's own filled guide stub,
8530
- * the guides index, and any vendored dependency guide mirrors.
8592
+ * the guides index, and vendored dependency guide mirrors whose paths are
8593
+ * neither the package's own guide nor already carried by the selected host
8594
+ * set.
8531
8595
  *
8532
8596
  * @param spec - The `Blueprint` to derive guide artifacts from.
8533
8597
  * @param pascal - The package's PascalCase entity name.
8534
8598
  * @param members - The blueprint's derived `Member[]`.
8535
- * @returns The `guides` group's `Artifact[]`.
8599
+ * @returns The `guides` group's `Artifact[]`, with one contributor per guide
8600
+ * path.
8536
8601
  *
8537
8602
  * @example
8538
8603
  * ```ts
@@ -8585,14 +8650,16 @@ function guideArtifacts(spec, pascal, members) {
8585
8650
  ]]),
8586
8651
  directory: alignTable(["Directory", "Guide"], sourceDirectories.map((directory) => [directory, `[\`${spec.name}.md\`](src/${spec.name}.md)`]))
8587
8652
  })];
8653
+ const guidePath = `guides/src/${spec.name}.md`;
8588
8654
  for (const dep of spec.dependencies) {
8589
8655
  if (!vendoredGuides.includes(dep.name)) continue;
8590
- const short = dep.name.replace("@orkestrel/", "");
8656
+ const path = `guides/src/${dep.name.replace("@orkestrel/", "")}.md`;
8657
+ if (HOST_PATHS.includes(path) || path === guidePath) continue;
8591
8658
  artifacts.push({
8592
- path: `guides/src/${short}.md`,
8659
+ path,
8593
8660
  group: "guides",
8594
8661
  origin: "host",
8595
- source: `guides/src/${short}.md`
8662
+ source: path
8596
8663
  });
8597
8664
  }
8598
8665
  return artifacts;
@@ -8628,7 +8695,7 @@ function applyOverrides(artifacts, overrides) {
8628
8695
  /**
8629
8696
  * The full pure compilation: draft a blueprint's artifacts — the manifest and
8630
8697
  * exports combination rules over the per-environment `SRC_MATRIX` rows, plus
8631
- * `HOST_PATHS` and `overrides` — then pin.
8698
+ * the `selectHostPaths` selection of `HOST_PATHS` and `overrides` — then pin.
8632
8699
  *
8633
8700
  * @param blueprint - The `Blueprint` to compile.
8634
8701
  * @param groups - An optional `Group[]` selection (default: all groups).
@@ -8672,7 +8739,7 @@ npm install @orkestrel/${blueprint.name}
8672
8739
  origin: "computed",
8673
8740
  content: ciWorkflow(blueprint)
8674
8741
  });
8675
- for (const path of HOST_PATHS) {
8742
+ for (const path of selectHostPaths(HOST_PATHS, blueprint.name)) {
8676
8743
  const group = hostGroup(path);
8677
8744
  if (!selected.includes(group)) continue;
8678
8745
  artifacts.push({
@@ -8795,7 +8862,10 @@ var Compiler = class Compiler {
8795
8862
  this.#emitter.emit("audit", result);
8796
8863
  return result;
8797
8864
  }
8798
- const result = diffPlan(scaffolding.plan, current);
8865
+ const result = {
8866
+ ...diffPlan(scaffolding.plan, current),
8867
+ questions: scaffolding.questions
8868
+ };
8799
8869
  this.#emitter.emit("audit", result);
8800
8870
  return result;
8801
8871
  }
@@ -8859,7 +8929,16 @@ var Compiler = class Compiler {
8859
8929
  const validation = validatePlan(draft);
8860
8930
  const dependencyQuestions = this.#dependencyQuestions(blueprint);
8861
8931
  const blocking = [...validation.questions];
8862
- const questions = [...blocking, ...dependencyQuestions];
8932
+ const warningQuestions = validation.warnings.map((text) => ({
8933
+ field: "overrides",
8934
+ text,
8935
+ blocking: false
8936
+ }));
8937
+ const questions = [
8938
+ ...blocking,
8939
+ ...warningQuestions,
8940
+ ...dependencyQuestions
8941
+ ];
8863
8942
  stages.push({
8864
8943
  stage: "gate",
8865
8944
  input: draft,
@@ -8952,9 +9031,11 @@ var Compiler = class Compiler {
8952
9031
  }
8953
9032
  #pointerArtifacts(blueprint) {
8954
9033
  const artifacts = [];
9034
+ const guidePath = `guides/src/${blueprint.name}.md`;
8955
9035
  for (const item of blueprint.dependencies) {
8956
9036
  if (Compiler.#vendored.includes(item.name)) continue;
8957
9037
  const path = `guides/src/${item.name.replace("@orkestrel/", "")}.md`;
9038
+ if (path === guidePath || HOST_PATHS.includes(path)) continue;
8958
9039
  artifacts.push({
8959
9040
  path,
8960
9041
  group: "guides",
@@ -9307,6 +9388,7 @@ exports.isScaffoldError = isScaffoldError;
9307
9388
  exports.isSyncReport = isSyncReport;
9308
9389
  exports.isWorkspaceName = isWorkspaceName;
9309
9390
  exports.manifestToDependencies = manifestToDependencies;
9391
+ exports.manifestToName = manifestToName;
9310
9392
  exports.member = member;
9311
9393
  exports.memberShape = memberShape;
9312
9394
  exports.override = override;
@@ -9335,6 +9417,7 @@ exports.renderObject = renderObject;
9335
9417
  exports.renderValue = renderValue;
9336
9418
  exports.rootTsconfig = rootTsconfig;
9337
9419
  exports.rootViteConfig = rootViteConfig;
9420
+ exports.selectHostPaths = selectHostPaths;
9338
9421
  exports.serializeTypeScriptString = serializeTypeScriptString;
9339
9422
  exports.singleSrcViteConfig = singleSrcViteConfig;
9340
9423
  exports.snapshotOf = snapshotOf;