@orkestrel/scaffold 0.0.48 → 0.0.50

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/bin/main.js CHANGED
@@ -3,8 +3,8 @@ import { align, renderTable, strip, stripControls, width } from "@orkestrel/cons
3
3
  import { attempt, isRecord, isString, parseJSON } from "@orkestrel/contract";
4
4
  import { createMarkdown, flattenText, isTableNode } from "@orkestrel/markdown";
5
5
  import { executeSync } from "@orkestrel/process/server";
6
- import { BIN_ENTRY_PATH, CATALOG_AGENT_PATH, CONFORMANCE_TEST_PATH, Compiler, DEPENDENCY_NAME_PATTERN, DISTRIBUTION_TEST_PATH, ENVIRONMENTS, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, INTEGRATION_TEST_PATH, MAX_MANIFEST_BYTES, SERVICE_SETUP_PATH, SHOWCASE_CONFIG_PATH, ScaffoldError, blueprintToDevDependencies, blueprintToRootVite, blueprintToScripts, compareVersions, createBlueprint, extractRangeMajor, extractVersion, isScaffoldError, manifestToDependencies, manifestToName, nameToGuide, replacePlanRanges } from "../src/core/index.js";
7
- import { Materializer, Upstream, isExactCaseFile, isPhysicalDirectory, isRepository, listFiles, readFileText, readSnapshot, resolveContainedPath } from "../src/server/index.js";
6
+ import { BIN_ENTRY_PATH, CATALOG_AGENT_PATH, CONFORMANCE_TEST_PATH, Compiler, DEPENDENCY_NAME_PATTERN, ENVIRONMENTS, GLOBAL_SETUP_PATH, GROUPS, GUIDES_TEST_PATH, HOST_PATHS, INTEGRATION_TEST_PATH, MAX_MANIFEST_BYTES, SERVICE_SETUP_PATH, SHOWCASE_CONFIG_PATH, ScaffoldError, blueprintToDevDependencies, blueprintToRootVite, blueprintToScripts, blueprintToTestArtifacts, blueprintToWritableScripts, compareVersions, createBlueprint, extractRangeMajor, extractVersion, isDeferredPath, isScaffoldError, manifestToDependencies, manifestToName, nameToGuide, replaceManifestScripts, replacePlanRanges } from "../src/core/index.js";
7
+ import { Materializer, Upstream, filesToHost, isExactCaseFile, isPhysicalDirectory, isWorktree, listFiles, readFileText, readHostFloor, readSnapshot, resolveContainedPath } from "../src/server/index.js";
8
8
  import { parseArgs } from "node:util";
9
9
  //#region src/bin/constants.ts
10
10
  /**
@@ -86,6 +86,7 @@ var COMMAND_OPTIONS = Object.freeze({
86
86
  groups: Object.freeze({ type: "string" }),
87
87
  all: Object.freeze({ type: "boolean" }),
88
88
  dirty: Object.freeze({ type: "boolean" }),
89
+ offline: Object.freeze({ type: "boolean" }),
89
90
  from: Object.freeze({
90
91
  type: "string",
91
92
  multiple: true
@@ -109,10 +110,12 @@ var OPTION_SUMMARY = Object.freeze({
109
110
  "--groups <list>": "the artifact groups to cover; every group when absent",
110
111
  "--all": "fetch a guide for every package the organization publishes, not the declared ones alone",
111
112
  "--dirty": "delete from a tree carrying uncommitted changes",
113
+ "--offline": "use the distributed dependency and vendored-host floors without reading upstream",
112
114
  "--from <path>": "read the data root from a local path instead of the bundled one; catalog alone accepts it more than once",
113
115
  "--target <path>": "the directory the verb operates on; the working directory when absent",
114
116
  "--json": "emit one machine-readable value instead of a report",
115
- ORKESTREL_SCAFFOLD_REGISTRY: "the registry base mapped to upstream.registry.base"
117
+ ORKESTREL_SCAFFOLD_REGISTRY: "the registry base mapped to upstream.registry.base",
118
+ ORKESTREL_SCAFFOLD_REPOSITORY: "the repository base mapped to upstream.repository.base"
116
119
  });
117
120
  /**
118
121
  * The options each verb takes, in usage order, frozen.
@@ -129,18 +132,21 @@ var VERB_OPTIONS = Object.freeze({
129
132
  "--app <list>",
130
133
  "--bin",
131
134
  "--deps <list>",
135
+ "--offline",
132
136
  "--from <path>",
133
137
  "--target <path>",
134
138
  "--json"
135
139
  ]),
136
140
  audit: Object.freeze([
137
141
  "--groups <list>",
142
+ "--offline",
138
143
  "--from <path>",
139
144
  "--target <path>",
140
145
  "--json"
141
146
  ]),
142
147
  repair: Object.freeze([
143
148
  "--groups <list>",
149
+ "--offline",
144
150
  "--from <path>",
145
151
  "--target <path>",
146
152
  "--json"
@@ -154,6 +160,7 @@ var VERB_OPTIONS = Object.freeze({
154
160
  overwrite: Object.freeze([
155
161
  "--groups <list>",
156
162
  "--dirty",
163
+ "--offline",
157
164
  "--from <path>",
158
165
  "--target <path>",
159
166
  "--json"
@@ -256,6 +263,22 @@ function optionToName(option) {
256
263
  return token.startsWith("--") ? token.slice(2) : token;
257
264
  }
258
265
  /**
266
+ * Project process environment endpoints into upstream reader options.
267
+ *
268
+ * @param environment - The process environment to read.
269
+ * @returns The configured endpoint groups, or `undefined` when neither endpoint
270
+ * is configured.
271
+ */
272
+ function environmentToUpstream(environment) {
273
+ const registry = environment.ORKESTREL_SCAFFOLD_REGISTRY;
274
+ const repository = environment.ORKESTREL_SCAFFOLD_REPOSITORY;
275
+ if (registry === void 0 && repository === void 0) return void 0;
276
+ return {
277
+ ...registry === void 0 ? {} : { registry: { base: registry } },
278
+ ...repository === void 0 ? {} : { repository: { base: repository } }
279
+ };
280
+ }
281
+ /**
259
282
  * Render one verb's synopsis.
260
283
  *
261
284
  * @param verb - The verb to describe.
@@ -355,6 +378,7 @@ function argvToCommand(argv) {
355
378
  const src = typeof values.src === "string" ? values.src : void 0;
356
379
  const app = typeof values.app === "string" ? values.app : void 0;
357
380
  const bin = values.bin === true;
381
+ const offline = values.offline === true;
358
382
  const dependencies = typeof values.deps === "string" ? values.deps : void 0;
359
383
  const target = typeof values.target === "string" ? values.target : void 0;
360
384
  const json = values.json === true;
@@ -374,6 +398,7 @@ function argvToCommand(argv) {
374
398
  ...src === void 0 ? {} : { src },
375
399
  ...app === void 0 ? {} : { app },
376
400
  ...bin ? { bin } : {},
401
+ ...offline ? { offline } : {},
377
402
  ...dependencies === void 0 ? {} : { dependencies }
378
403
  };
379
404
  case "audit": return {
@@ -381,14 +406,16 @@ function argvToCommand(argv) {
381
406
  json,
382
407
  ...location,
383
408
  ...source,
384
- ...selection
409
+ ...selection,
410
+ ...offline ? { offline } : {}
385
411
  };
386
412
  case "repair": return {
387
413
  verb,
388
414
  json,
389
415
  ...location,
390
416
  ...source,
391
- ...selection
417
+ ...selection,
418
+ ...offline ? { offline } : {}
392
419
  };
393
420
  case "catalog": return {
394
421
  verb,
@@ -401,6 +428,7 @@ function argvToCommand(argv) {
401
428
  verb,
402
429
  json,
403
430
  dirty: values.dirty === true,
431
+ ...offline ? { offline } : {},
404
432
  ...location,
405
433
  ...source,
406
434
  ...selection
@@ -435,27 +463,43 @@ function auditToExit(audit) {
435
463
  return blocked || drifted ? 1 : 0;
436
464
  }
437
465
  /**
438
- * Read the fleet rows and planned foreign tools a target manifest declares.
466
+ * Read the runtime and development rows a writing verb may raise.
439
467
  *
440
468
  * @param manifest - The target manifest text.
441
469
  * @param blueprint - The workspace shape that supplies the planned tool set.
442
- * @returns The declared fleet rows followed by declared planned foreign rows.
470
+ * @returns The declared fleet rows and planned foreign tools in their writable sections.
443
471
  */
444
- function manifestToPlannedDependencies(manifest, blueprint) {
445
- const dependencies = [...dependenciesToFleet(manifestToDependencies(manifest))];
472
+ function manifestToWritableDependencies(manifest, blueprint) {
473
+ const declared = manifestToDependencies(manifest);
474
+ const runtime = [...dependenciesToFleet(declared.runtime)];
475
+ const development = [...dependenciesToFleet(declared.development)];
446
476
  const parsed = parseJSON(manifest);
447
- if (!isRecord(parsed)) return dependencies;
448
- const runtime = isRecord(parsed.dependencies) ? parsed.dependencies : {};
449
- const development = isRecord(parsed.devDependencies) ? parsed.devDependencies : {};
477
+ if (!isRecord(parsed)) return {
478
+ runtime,
479
+ development
480
+ };
481
+ const runtimeRecord = isRecord(parsed.dependencies) ? parsed.dependencies : {};
482
+ const developmentRecord = isRecord(parsed.devDependencies) ? parsed.devDependencies : {};
450
483
  for (const name of Object.keys(blueprintToDevDependencies(blueprint)).sort()) {
451
484
  if (name.startsWith("@orkestrel/")) continue;
452
- const range = runtime[name] ?? development[name];
453
- if (isString(range)) dependencies.push({
485
+ const runtimeRange = runtimeRecord[name];
486
+ if (isString(runtimeRange)) {
487
+ runtime.push({
488
+ name,
489
+ range: runtimeRange
490
+ });
491
+ continue;
492
+ }
493
+ const developmentRange = developmentRecord[name];
494
+ if (isString(developmentRange)) development.push({
454
495
  name,
455
- range
496
+ range: developmentRange
456
497
  });
457
498
  }
458
- return dependencies;
499
+ return {
500
+ runtime,
501
+ development
502
+ };
459
503
  }
460
504
  /**
461
505
  * Keep only dependencies published by the Orkestrel fleet.
@@ -467,6 +511,26 @@ function dependenciesToFleet(dependencies) {
467
511
  return dependencies.filter((dependency) => dependency.name.startsWith("@orkestrel/"));
468
512
  }
469
513
  /**
514
+ * Project declared concrete ranges to their distributed release floors.
515
+ *
516
+ * @param dependencies - The declarations whose floor versions to read.
517
+ * @returns One found floor per declaration, or `undefined` when any range names
518
+ * no concrete version.
519
+ */
520
+ function dependenciesToFloors(dependencies) {
521
+ const releases = [];
522
+ for (const dependency of dependencies) {
523
+ const version = dependency.range.startsWith("^") || dependency.range.startsWith("~") ? dependency.range.slice(1) : dependency.range;
524
+ if (extractVersion(version) === void 0) return void 0;
525
+ releases.push({
526
+ ...dependency,
527
+ lookup: "found",
528
+ latest: version
529
+ });
530
+ }
531
+ return releases;
532
+ }
533
+ /**
470
534
  * Read the exit code registry release evidence earns.
471
535
  *
472
536
  * @param releases - The release verdicts to measure.
@@ -682,71 +746,101 @@ var CLI = class CLI {
682
746
  const plan = this.#compile(blueprint);
683
747
  const manifest = plan.artifacts.find((artifact) => artifact.path === "package.json" && artifact.origin !== "host");
684
748
  if (manifest === void 0 || manifest.origin === "host") throw new ScaffoldError("BLOCKED", "The compiled plan carries no replaceable manifest.");
685
- const releases = await this.#lookup(dependenciesToFleet(manifestToDependencies(manifest.content)));
686
- const resolved = replacePlanRanges(plan, this.#pin(releases));
749
+ const declarations = manifestToDependencies(manifest.content);
750
+ const versions = await this.#versions({
751
+ runtime: dependenciesToFleet(declarations.runtime),
752
+ development: dependenciesToFleet(declarations.development)
753
+ }, command.offline === true);
754
+ this.#assertVersions(versions);
755
+ const resolved = replacePlanRanges(plan, versions.pins);
687
756
  if (resolved === void 0) throw new ScaffoldError("BLOCKED", "The compiled plan ranges could not be replaced.");
688
- const materializer = new Materializer(command.from === void 0 ? void 0 : { host: command.from });
757
+ const host = await this.#host(command.from, void 0, command.offline === true);
689
758
  try {
690
- const result = materializer.materialize(resolved, target);
691
- if (command.json === true) this.#report(result);
759
+ const result = host.materializer.materialize(resolved, target);
760
+ const outcome = {
761
+ ...result,
762
+ provenance: {
763
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
764
+ ...host.baseline === void 0 ? {} : { host: host.baseline }
765
+ }
766
+ };
767
+ if (command.json === true) this.#report(outcome);
692
768
  else {
693
769
  this.#say(`Scaffolded ${blueprint.name} into ${result.target}.`);
694
770
  this.#say(this.#tally(result));
695
771
  }
772
+ if (versions.forced || host.forced) this.#reportBaselines(outcome.provenance);
696
773
  return 0;
697
774
  } finally {
698
- materializer.destroy();
775
+ host.materializer.destroy();
699
776
  }
700
777
  }
701
778
  async #inspect(command) {
702
779
  const target = command.target ?? ".";
703
780
  const manifest = this.#manifest(target);
704
781
  const blueprint = this.#derive(target);
705
- const declared = manifestToPlannedDependencies(manifest, blueprint);
706
- const releases = await this.#lookup(declared);
707
- const questions = [...this.#targetQuestions(target, blueprint), ...releasesToQuestions(releases)];
708
- const materializer = new Materializer(command.from === void 0 ? void 0 : { host: command.from });
782
+ const groups = this.#groups(command.groups);
783
+ const declared = manifestToWritableDependencies(manifest, blueprint);
784
+ const versions = await this.#versions(declared, command.offline === true);
785
+ const questions = [...this.#targetQuestions(target, blueprint, groups), ...releasesToQuestions(versions.releases)];
786
+ const host = await this.#host(command.from, target, command.offline === true);
709
787
  try {
710
- const [measured] = this.#survey(materializer, blueprint, target, this.#groups(command.groups));
788
+ const [measured] = this.#survey(host.materializer, blueprint, target, groups);
711
789
  const audit = questions.length === 0 ? measured : {
712
790
  ...measured,
713
791
  questions: [...measured.questions, ...questions]
714
792
  };
715
793
  const outcome = {
716
794
  ...audit,
717
- releases
795
+ releases: versions.releases,
796
+ provenance: {
797
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
798
+ ...host.baseline === void 0 ? {} : { host: host.baseline }
799
+ }
718
800
  };
719
801
  if (command.json === true) this.#report(outcome);
720
802
  else {
721
803
  this.#present(audit);
722
- this.#reportReleases(releases);
804
+ if (command.offline !== true) this.#reportReleases(versions.releases);
723
805
  }
724
- return Math.max(auditToExit(audit), releasesToExit(releases));
806
+ if (versions.forced || host.forced) this.#reportBaselines(outcome.provenance);
807
+ if (command.offline === true) return auditToExit(audit);
808
+ return Math.max(auditToExit(audit), releasesToExit(versions.releases), versions.forced || host.forced ? 1 : 0);
725
809
  } finally {
726
- materializer.destroy();
810
+ host.materializer.destroy();
727
811
  }
728
812
  }
729
813
  async #restore(command) {
730
814
  const target = command.target ?? ".";
731
815
  const groups = this.#groups(command.groups);
732
816
  const blueprint = this.#derive(target);
733
- this.#assertTarget(target, blueprint);
734
- const materializer = new Materializer(command.from === void 0 ? void 0 : { host: command.from });
817
+ this.#assertTarget(target, blueprint, groups);
818
+ const host = await this.#host(command.from, target, command.offline === true);
735
819
  try {
736
- const [audit, plan] = this.#survey(materializer, blueprint, target, groups);
820
+ const [audit, plan] = this.#survey(host.materializer, blueprint, target, groups);
737
821
  if (plan === void 0) {
738
- if (command.json === true) this.#report(audit);
822
+ if (command.json === true) this.#report({
823
+ ...audit,
824
+ provenance: { ...host.baseline === void 0 ? {} : { host: host.baseline } }
825
+ });
739
826
  else this.#present(audit);
740
827
  return 1;
741
828
  }
742
- const releases = await this.#lookup(manifestToPlannedDependencies(this.#manifest(target), blueprint));
743
- const pins = this.#pin(releases);
744
- const result = this.#merge(materializer.repair(plan, audit, target), materializer.declare(pins, target));
745
- const [terminal] = this.#survey(materializer, this.#derive(target), target, groups);
829
+ const versions = await this.#versions(manifestToWritableDependencies(this.#manifest(target), blueprint), command.offline === true);
830
+ this.#assertVersions(versions);
831
+ const result = this.#merge(host.materializer.repair(plan, audit, target), host.materializer.declare({
832
+ pins: versions.pins,
833
+ scripts: blueprintToWritableScripts(blueprint)
834
+ }, target));
835
+ const [terminal] = this.#survey(host.materializer, this.#derive(target), target, groups);
746
836
  const outcome = {
747
837
  ...result,
748
838
  audit: terminal,
749
- releases
839
+ releases: versions.releases,
840
+ provenance: {
841
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
842
+ ...host.baseline === void 0 ? {} : { host: host.baseline }
843
+ }
750
844
  };
751
845
  if (command.json === true) this.#report(outcome);
752
846
  else {
@@ -754,9 +848,11 @@ var CLI = class CLI {
754
848
  this.#reportReplacements(audit, terminal);
755
849
  this.#say(this.#tally(result));
756
850
  }
851
+ if (versions.forced || host.forced) this.#reportBaselines(outcome.provenance);
852
+ if (command.offline !== true && (versions.forced || host.forced)) return 1;
757
853
  return auditToExit(terminal);
758
854
  } finally {
759
- materializer.destroy();
855
+ host.materializer.destroy();
760
856
  }
761
857
  }
762
858
  async #refresh(command) {
@@ -765,13 +861,22 @@ var CLI = class CLI {
765
861
  if (extra.length > 0) this.#warn(`Read the data root from ${String(host)}. The other ${String(extra.length)} local root${extra.length === 1 ? "" : "s"} named by --from reach nothing this run does.`);
766
862
  const previous = this.#previous(target);
767
863
  const fetched = await this.#fetch(target, command.all === true);
768
- const releases = this.#catalogReleases(dependenciesToFleet(manifestToDependencies(this.#manifest(target))), fetched.entries);
769
- const pins = this.#pin(releases);
864
+ const declarations = manifestToDependencies(this.#manifest(target));
865
+ const writable = {
866
+ runtime: dependenciesToFleet(declarations.runtime),
867
+ development: dependenciesToFleet(declarations.development)
868
+ };
869
+ const releases = this.#catalogReleases([...writable.runtime, ...writable.development], fetched.entries);
870
+ const pins = this.#pin(releases, writable);
770
871
  this.#assertFetched(fetched.entries, fetched.mirrors);
771
- const materializer = new Materializer(host === void 0 ? void 0 : { host });
872
+ const guides = fetched.mirrors.length === 0 ? void 0 : fetched.mirrors.some((mirror) => mirror.lookup === "failed") ? "floor" : "live";
873
+ const materializer = new Materializer({ host: host ?? readHostFloor() });
772
874
  let result;
773
875
  try {
774
- result = this.#merge(this.#publish(materializer, target, fetched.entries, fetched.mirrors), materializer.declare(pins, target));
876
+ result = this.#merge(this.#publish(materializer, target, fetched.entries, fetched.mirrors), materializer.declare({
877
+ pins,
878
+ scripts: []
879
+ }, target));
775
880
  } finally {
776
881
  materializer.destroy();
777
882
  }
@@ -780,38 +885,49 @@ var CLI = class CLI {
780
885
  entries: fetched.entries,
781
886
  mirrors: fetched.mirrors,
782
887
  dropped: previous.filter((name) => !fetched.entries.some((entry) => entry.name === name)),
783
- releases
888
+ releases,
889
+ provenance: {
890
+ versions: "live",
891
+ ...guides === void 0 ? {} : { guides }
892
+ }
784
893
  };
785
894
  if (command.json === true) this.#report(outcome);
786
895
  else this.#recount(outcome);
787
- return 0;
896
+ return guides === "floor" ? 1 : 0;
788
897
  }
789
898
  async #replace(command) {
790
899
  const target = command.target ?? ".";
791
900
  const groups = this.#groups(command.groups);
792
901
  const blueprint = this.#derive(target);
793
- this.#assertTarget(target, blueprint);
794
- const repository = this.#repository(target);
795
- if (repository.dirty.length > 0 && command.dirty !== true) throw new ScaffoldError("TARGET", `The target at ${target} carries ${String(repository.dirty.length)} uncommitted change${repository.dirty.length === 1 ? "" : "s"}. Commit them, or pass --dirty to waive the refusal.`, {
902
+ this.#assertTarget(target, blueprint, groups);
903
+ const worktree = this.#worktree(target);
904
+ if (worktree.dirty.length > 0 && command.dirty !== true) throw new ScaffoldError("TARGET", `The target at ${target} carries ${String(worktree.dirty.length)} uncommitted change${worktree.dirty.length === 1 ? "" : "s"}. Commit them, or pass --dirty to waive the refusal.`, {
796
905
  target,
797
- dirty: repository.dirty.length
906
+ dirty: worktree.dirty.length
798
907
  });
799
- const materializer = new Materializer(command.from === void 0 ? void 0 : { host: command.from });
908
+ const host = await this.#host(command.from, target, command.offline === true);
800
909
  try {
801
- const [audit, plan] = this.#survey(materializer, blueprint, target, groups);
910
+ const [audit, plan] = this.#survey(host.materializer, blueprint, target, groups);
802
911
  if (plan === void 0) {
803
- if (command.json === true) this.#report(audit);
912
+ if (command.json === true) this.#report({
913
+ ...audit,
914
+ provenance: { ...host.baseline === void 0 ? {} : { host: host.baseline } }
915
+ });
804
916
  else this.#present(audit);
805
917
  return 1;
806
918
  }
807
- const repaired = materializer.repair(plan, audit, target);
808
- const removed = materializer.remove(plan, audit, command.dirty === true ? {
809
- tracked: repository.tracked,
919
+ const declared = {
920
+ pins: manifestToWritableDependencies(this.#manifest(target), blueprint),
921
+ scripts: blueprintToWritableScripts(blueprint)
922
+ };
923
+ const repaired = host.materializer.repair(plan, audit, target);
924
+ const removed = host.materializer.remove(plan, audit, command.dirty === true ? {
925
+ tracked: worktree.tracked,
810
926
  dirty: []
811
- } : repository, target);
927
+ } : worktree, target);
812
928
  const offline = this.#merge(repaired, removed);
813
- const online = await this.#reconcile(materializer, target, manifestToPlannedDependencies(this.#manifest(target), blueprint));
814
- const [terminal] = this.#survey(materializer, blueprint, target, groups);
929
+ const online = command.offline === true ? await this.#offline(host.materializer, target, declared, host.baseline) : await this.#reconcile(host.materializer, target, declared, host.baseline, host.forced);
930
+ const [terminal] = this.#survey(host.materializer, blueprint, target, groups);
815
931
  const outcome = {
816
932
  ...online,
817
933
  ...this.#merge(offline, online),
@@ -827,23 +943,64 @@ var CLI = class CLI {
827
943
  if (online.note !== void 0) return 1;
828
944
  return auditToExit(terminal);
829
945
  } finally {
830
- materializer.destroy();
946
+ host.materializer.destroy();
831
947
  }
832
948
  }
833
- async #reconcile(materializer, target, declared) {
949
+ async #offline(materializer, target, declared, host) {
950
+ const versions = await this.#versions(declared.pins, true);
951
+ this.#assertVersions(versions);
952
+ return {
953
+ ...materializer.declare({
954
+ pins: versions.pins,
955
+ scripts: declared.scripts
956
+ }, target),
957
+ entries: [],
958
+ mirrors: [],
959
+ dropped: [],
960
+ releases: versions.releases,
961
+ provenance: {
962
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
963
+ ...host === void 0 ? {} : { host }
964
+ },
965
+ note: "The catalog step did not complete: USAGE: 'catalog' does not take --offline."
966
+ };
967
+ }
968
+ async #reconcile(materializer, target, declared, host, hostForced) {
834
969
  const previous = this.#previous(target);
835
970
  let releases = [];
971
+ let provenance = { ...host === void 0 ? {} : { host } };
836
972
  try {
837
- releases = await this.#lookup(declared);
838
- const pins = this.#pin(releases);
973
+ const versions = await this.#versions(declared.pins, false);
974
+ releases = versions.releases;
975
+ provenance = {
976
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
977
+ ...host === void 0 ? {} : { host }
978
+ };
979
+ this.#assertVersions(versions);
839
980
  const fetched = await this.#fetch(target, false);
840
981
  this.#assertFetched(fetched.entries, fetched.mirrors);
982
+ const guides = fetched.mirrors.length === 0 ? void 0 : fetched.mirrors.some((mirror) => mirror.lookup === "failed") ? "floor" : "live";
983
+ provenance = {
984
+ ...versions.baseline === void 0 ? {} : { versions: versions.baseline },
985
+ ...guides === void 0 ? {} : { guides },
986
+ ...host === void 0 ? {} : { host }
987
+ };
988
+ const written = this.#merge(this.#publish(materializer, target, fetched.entries, fetched.mirrors), materializer.declare({
989
+ pins: versions.pins,
990
+ scripts: declared.scripts
991
+ }, target));
992
+ const floors = [];
993
+ if (hostForced) floors.push("host");
994
+ if (versions.forced) floors.push("versions");
995
+ if (guides === "floor") floors.push("guides");
841
996
  return {
842
- ...this.#merge(this.#publish(materializer, target, fetched.entries, fetched.mirrors), materializer.declare(pins, target)),
997
+ ...written,
843
998
  entries: fetched.entries,
844
999
  mirrors: fetched.mirrors,
845
1000
  dropped: previous.filter((name) => !fetched.entries.some((entry) => entry.name === name)),
846
- releases
1001
+ releases,
1002
+ provenance,
1003
+ ...floors.length === 0 ? {} : { note: `The ${floors.join(", ")} step used the distributed floor after its upstream read did not complete.` }
847
1004
  };
848
1005
  } catch (error) {
849
1006
  return {
@@ -855,10 +1012,121 @@ var CLI = class CLI {
855
1012
  mirrors: [],
856
1013
  dropped: [],
857
1014
  releases,
1015
+ provenance,
858
1016
  note: `The catalog step did not complete: ${errorToEnvelope(error).error.message}`
859
1017
  };
860
1018
  }
861
1019
  }
1020
+ async #host(from, target, offline) {
1021
+ if (from !== void 0) return {
1022
+ materializer: new Materializer({ host: from }),
1023
+ forced: false
1024
+ };
1025
+ const floor = readHostFloor();
1026
+ if (offline) return {
1027
+ materializer: new Materializer({ host: floor }),
1028
+ baseline: "floor",
1029
+ forced: false
1030
+ };
1031
+ const paths = floor.manifest.entries.filter((entry) => !isDeferredPath(entry.destination)).map((entry) => entry.destination);
1032
+ const current = target === void 0 ? floor.bytes : readSnapshot(target, paths);
1033
+ const upstream = new Upstream(this.#upstream);
1034
+ try {
1035
+ const files = await upstream.read(paths, current);
1036
+ const live = filesToHost(files, floor);
1037
+ return {
1038
+ materializer: new Materializer({ host: live ?? floor }),
1039
+ baseline: live === void 0 ? "floor" : "live",
1040
+ forced: live === void 0
1041
+ };
1042
+ } finally {
1043
+ upstream.destroy();
1044
+ }
1045
+ }
1046
+ async #versions(declared, offline) {
1047
+ const dependencies = [...declared.runtime, ...declared.development];
1048
+ if (dependencies.length === 0) return {
1049
+ releases: [],
1050
+ pins: {
1051
+ runtime: [],
1052
+ development: []
1053
+ },
1054
+ forced: false,
1055
+ complete: true
1056
+ };
1057
+ const floors = dependenciesToFloors(dependencies);
1058
+ const floorPins = floors === void 0 ? void 0 : {
1059
+ runtime: floors.slice(0, declared.runtime.length).map((release) => ({
1060
+ name: release.name,
1061
+ range: release.range
1062
+ })),
1063
+ development: floors.slice(declared.runtime.length).map((release) => ({
1064
+ name: release.name,
1065
+ range: release.range
1066
+ }))
1067
+ };
1068
+ if (offline) {
1069
+ if (floors === void 0 || floorPins === void 0) return {
1070
+ releases: [],
1071
+ pins: {
1072
+ runtime: [],
1073
+ development: []
1074
+ },
1075
+ baseline: "floor",
1076
+ forced: false,
1077
+ complete: false
1078
+ };
1079
+ return {
1080
+ releases: floors,
1081
+ pins: floorPins,
1082
+ baseline: "floor",
1083
+ forced: false,
1084
+ complete: true
1085
+ };
1086
+ }
1087
+ const releases = await this.#lookup(dependencies);
1088
+ if (releases.filter((release) => release.lookup === "missing" || release.lookup === "unmatched").length > 0) return {
1089
+ releases,
1090
+ pins: {
1091
+ runtime: [],
1092
+ development: []
1093
+ },
1094
+ baseline: "live",
1095
+ forced: false,
1096
+ complete: false
1097
+ };
1098
+ if (releases.some((release) => release.lookup === "failed")) {
1099
+ if (floorPins === void 0) return {
1100
+ releases,
1101
+ pins: {
1102
+ runtime: [],
1103
+ development: []
1104
+ },
1105
+ baseline: "floor",
1106
+ forced: true,
1107
+ complete: false
1108
+ };
1109
+ return {
1110
+ releases,
1111
+ pins: floorPins,
1112
+ baseline: "floor",
1113
+ forced: true,
1114
+ complete: true
1115
+ };
1116
+ }
1117
+ return {
1118
+ releases,
1119
+ pins: this.#pin(releases, declared),
1120
+ baseline: "live",
1121
+ forced: false,
1122
+ complete: true
1123
+ };
1124
+ }
1125
+ #assertVersions(versions) {
1126
+ if (versions.complete) return;
1127
+ const names = versions.releases.filter((release) => release.lookup !== "found").map((release) => release.name);
1128
+ throw new ScaffoldError("FETCH", names.length === 0 ? "A declared dependency names no concrete floor." : `The registry named no release for ${names.join(", ")}.`, { names: names.length });
1129
+ }
862
1130
  async #lookup(declared) {
863
1131
  if (declared.length === 0) return [];
864
1132
  const upstream = new Upstream(this.#upstream);
@@ -889,7 +1157,12 @@ var CLI = class CLI {
889
1157
  async #fetch(target, all) {
890
1158
  const manifest = this.#manifest(target);
891
1159
  const own = manifestToName(manifest);
892
- const declared = manifestToDependencies(manifest).map((dependency) => dependency.name);
1160
+ const dependencies = manifestToDependencies(manifest);
1161
+ const declared = [...new Set([
1162
+ ...dependencies.runtime,
1163
+ ...dependencies.development,
1164
+ ...dependencies.peer
1165
+ ].map((dependency) => dependency.name))];
893
1166
  const upstream = new Upstream(this.#upstream);
894
1167
  try {
895
1168
  const entries = await upstream.catalog();
@@ -921,20 +1194,30 @@ var CLI = class CLI {
921
1194
  });
922
1195
  }
923
1196
  #assertFetched(entries, mirrors) {
924
- const failed = [...entries.filter((entry) => entry.lookup !== "found").map((entry) => entry.name), ...mirrors.filter((mirror) => mirror.lookup !== "found").map((mirror) => mirror.name)];
1197
+ const failed = [...entries.filter((entry) => entry.lookup !== "found").map((entry) => entry.name), ...mirrors.filter((mirror) => mirror.lookup !== "found" && mirror.lookup !== "failed").map((mirror) => mirror.name)];
925
1198
  if (failed.length === 0) return;
926
1199
  throw new ScaffoldError("FETCH", `Upstream produced no complete catalog answer for ${failed.join(", ")}.`, { names: failed.length });
927
1200
  }
928
- #pin(releases) {
1201
+ #pin(releases, declared) {
929
1202
  const refused = releases.filter((release) => release.lookup !== "found");
930
1203
  if (refused.length > 0) throw new ScaffoldError("FETCH", `The registry named no release for ${refused.map((release) => release.name).join(", ")}.`, { names: refused.length });
931
- return releases.map((release) => {
1204
+ const dependencies = [...declared.runtime, ...declared.development];
1205
+ const pins = [];
1206
+ for (let index = 0; index < releases.length; index += 1) {
1207
+ const release = releases[index];
1208
+ const dependency = dependencies[index];
1209
+ if (release === void 0 || dependency === void 0) throw new ScaffoldError("FETCH", "The release answer has no matching declaration.");
932
1210
  if (release.lookup !== "found") throw new ScaffoldError("FETCH", `The registry named no release for ${release.name}.`);
933
- return {
934
- name: release.name,
1211
+ pins.push({
1212
+ name: dependency.name,
935
1213
  range: `^${release.latest}`
936
- };
937
- });
1214
+ });
1215
+ }
1216
+ if (pins.length !== dependencies.length) throw new ScaffoldError("FETCH", "The release answer does not match the declaration set.");
1217
+ return {
1218
+ runtime: pins.slice(0, declared.runtime.length),
1219
+ development: pins.slice(declared.runtime.length)
1220
+ };
938
1221
  }
939
1222
  #compile(blueprint, groups) {
940
1223
  const compiler = new Compiler();
@@ -967,7 +1250,6 @@ var CLI = class CLI {
967
1250
  const bin = resolveContainedPath(target, BIN_ENTRY_PATH);
968
1251
  const tests = resolveContainedPath(target, "tests");
969
1252
  const guides = resolveContainedPath(target, GUIDES_TEST_PATH);
970
- const distribution = resolveContainedPath(target, DISTRIBUTION_TEST_PATH);
971
1253
  const integration = resolveContainedPath(target, INTEGRATION_TEST_PATH);
972
1254
  const conformance = resolveContainedPath(target, CONFORMANCE_TEST_PATH);
973
1255
  const service = resolveContainedPath(target, SERVICE_SETUP_PATH);
@@ -976,7 +1258,7 @@ var CLI = class CLI {
976
1258
  return createBlueprint(declared.slice(declared.lastIndexOf("/") + 1), {
977
1259
  src: this.#probe(target, "src"),
978
1260
  app: this.#probe(target, "app"),
979
- dependencies: manifestToDependencies(manifest),
1261
+ dependencies: manifestToDependencies(manifest).runtime,
980
1262
  bin: bin !== void 0 && isExactCaseFile(bin),
981
1263
  setup: tests !== void 0 && listFiles(tests).some((path) => {
982
1264
  if (path.includes("/") || !path.startsWith("setup") || !path.endsWith(".test.ts")) return false;
@@ -984,7 +1266,6 @@ var CLI = class CLI {
984
1266
  return proof !== void 0 && isExactCaseFile(proof);
985
1267
  }),
986
1268
  guides: guides !== void 0 && isExactCaseFile(guides),
987
- distribution: distribution !== void 0 && isExactCaseFile(distribution),
988
1269
  integration: integration !== void 0 && isExactCaseFile(integration),
989
1270
  conformance: conformance !== void 0 && isExactCaseFile(conformance),
990
1271
  service: service !== void 0 && isExactCaseFile(service),
@@ -1115,7 +1396,8 @@ var CLI = class CLI {
1115
1396
  };
1116
1397
  }
1117
1398
  #projectQuestion(target, blueprint, writing = false) {
1118
- const manifest = this.#manifest(target);
1399
+ const text = this.#manifest(target);
1400
+ const manifest = replaceManifestScripts(text, blueprintToWritableScripts(blueprint)) ?? text;
1119
1401
  const planned = blueprintToRootVite(blueprint);
1120
1402
  const parsed = parseJSON(manifest);
1121
1403
  const scripts = isRecord(parsed) && isRecord(parsed.scripts) ? parsed.scripts : {};
@@ -1135,13 +1417,15 @@ var CLI = class CLI {
1135
1417
  const projects = [...absent].sort();
1136
1418
  if (unresolved) return {
1137
1419
  field: "projects",
1138
- message: `The manifest at ${target} contains a Vitest project expression that cannot be resolved statically.${projects.length === 0 ? "" : ` It also names projects the planned configuration does not register: ${projects.join(", ")}.`} ${writing ? "Replace it with a literal --project value or remove the script before using a scaffold writing verb." : "Replace it with a literal --project value before relying on the planned configuration."}`,
1139
- blocking: false
1420
+ message: `The manifest at ${target} contains a Vitest project expression that cannot be resolved statically.${projects.length === 0 ? "" : ` It also names projects the planned vite.config.ts does not register: ${projects.join(", ")}.`} ${writing ? "The configs group is blocked. Replace the expression with a literal --project value before selecting configs, or exclude configs from --groups." : "Replace it with a literal --project value before relying on the planned configuration."}`,
1421
+ blocking: false,
1422
+ groups: ["configs"]
1140
1423
  };
1141
1424
  if (projects.length > 0) return {
1142
1425
  field: "projects",
1143
- message: writing ? `The manifest at ${target} names ${projects.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration does not register: ${projects.join(", ")}. To continue, remove the ${projects.length === 1 ? "script that names it" : "scripts that name them"} or do not use scaffold writing verbs on a workspace that needs ${projects.length === 1 ? "a custom Vitest project" : "custom Vitest projects"}.` : `The manifest at ${target} names ${projects.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration does not register: ${projects.join(", ")}. Add ${projects.length === 1 ? "the project" : "each project"} to vite.config.ts or remove the ${projects.length === 1 ? "script that names it" : "scripts that name them"}.`,
1144
- blocking: false
1426
+ message: writing ? `The configs group is blocked because the manifest at ${target} names ${projects.length === 1 ? "a Vitest project" : "Vitest projects"} the planned vite.config.ts does not register: ${projects.join(", ")}. Remove the ${projects.length === 1 ? "script that names it" : "scripts that name them"} before selecting configs, or exclude configs from --groups.` : `The manifest at ${target} names ${projects.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration does not register: ${projects.join(", ")}. Add ${projects.length === 1 ? "the project" : "each project"} to vite.config.ts or remove the ${projects.length === 1 ? "script that names it" : "scripts that name them"}.`,
1427
+ blocking: false,
1428
+ groups: ["configs"]
1145
1429
  };
1146
1430
  const expected = blueprintToScripts(blueprint);
1147
1431
  const expectedLines = /* @__PURE__ */ new Map();
@@ -1175,8 +1459,9 @@ var CLI = class CLI {
1175
1459
  }
1176
1460
  if (unresolved) return {
1177
1461
  field: "projects",
1178
- message: `The manifest at ${target} contains a ${gateNames} chain that cannot be resolved statically. ${writing ? "Replace it with literal npm run script names before using a scaffold writing verb." : "Replace it with literal npm run script names before relying on the planned configuration."}`,
1179
- blocking: false
1462
+ message: `The manifest at ${target} contains a ${gateNames} chain that cannot be resolved statically. ${writing ? "The configs group is blocked. Replace it with literal npm run script names before selecting configs, or exclude configs from --groups." : "Replace it with literal npm run script names before relying on the planned configuration."}`,
1463
+ blocking: false,
1464
+ groups: ["configs"]
1180
1465
  };
1181
1466
  const missing = [...expectedLines].filter(([project]) => !reachable.has(project)).sort(([left], [right]) => left.localeCompare(right));
1182
1467
  if (missing.length === 0) return void 0;
@@ -1194,8 +1479,9 @@ var CLI = class CLI {
1194
1479
  }
1195
1480
  return {
1196
1481
  field: "projects",
1197
- message: `The manifest at ${target} does not reach ${names.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration registers: ${names.join(", ")}. No chain from ${gateNames} invokes ${names.length === 1 ? "it" : "them"}. ${remedies.join(" ")}`,
1198
- blocking: false
1482
+ message: `${writing ? "The configs group is blocked because " : ""}the manifest at ${target} does not reach ${names.length === 1 ? "a Vitest project" : "Vitest projects"} the planned configuration registers: ${names.join(", ")}. No chain from ${gateNames} invokes ${names.length === 1 ? "it" : "them"}. ${remedies.join(" ")}${writing ? " Exclude configs from --groups to write another group." : ""}`,
1483
+ blocking: false,
1484
+ groups: ["configs"]
1199
1485
  };
1200
1486
  }
1201
1487
  #dependencyQuestion(target, blueprint, writing = false) {
@@ -1204,8 +1490,9 @@ var CLI = class CLI {
1204
1490
  const malformed = ["dependencies", "devDependencies"].filter((section) => parsed[section] !== void 0 && !isRecord(parsed[section]));
1205
1491
  if (malformed.length > 0) return {
1206
1492
  field: "dependencies",
1207
- message: `The manifest at ${target} declares ${malformed.join(" and ")} as ${malformed.length === 1 ? "a value" : "values"} that ${malformed.length === 1 ? "is" : "are"} not ${malformed.length === 1 ? "an object" : "objects"}. Replace ${malformed.length === 1 ? "it" : "them"} with ${malformed.length === 1 ? "an object" : "objects"} before ${writing ? "using a scaffold writing verb" : "relying on the planned dependency set"}.`,
1208
- blocking: false
1493
+ message: `The manifest at ${target} declares ${malformed.join(" and ")} as ${malformed.length === 1 ? "a value" : "values"} that ${malformed.length === 1 ? "is" : "are"} not ${malformed.length === 1 ? "an object" : "objects"}. ${writing ? `The configs and tests groups are blocked. Replace ${malformed.length === 1 ? "it" : "them"} with ${malformed.length === 1 ? "an object" : "objects"} before selecting configs or tests, or exclude those groups from --groups.` : `Replace ${malformed.length === 1 ? "it" : "them"} with ${malformed.length === 1 ? "an object" : "objects"} before relying on the planned dependency set.`}`,
1494
+ blocking: false,
1495
+ groups: ["configs", "tests"]
1209
1496
  };
1210
1497
  const dependencies = isRecord(parsed.dependencies) ? parsed.dependencies : {};
1211
1498
  const development = isRecord(parsed.devDependencies) ? parsed.devDependencies : {};
@@ -1215,20 +1502,56 @@ var CLI = class CLI {
1215
1502
  const lines = missing.map(([name, range]) => `${JSON.stringify(name)}: ${JSON.stringify(range)},`);
1216
1503
  return {
1217
1504
  field: "dependencies",
1218
- message: `The manifest at ${target} does not declare ${names.length === 1 ? "a planned dependency" : "planned dependencies"}: ${names.join(", ")}. ${writing ? "To continue, add" : "Add"} ${lines.length === 1 ? "this exact dependency line" : "these exact dependency lines"} to dependencies or devDependencies in package.json: ${lines.join(" ")}`,
1219
- blocking: false
1505
+ message: `The manifest at ${target} does not declare ${names.length === 1 ? "a planned dependency" : "planned dependencies"}: ${names.join(", ")}. ${writing ? "The configs and tests groups are blocked. Add" : "Add"} ${lines.length === 1 ? "this exact dependency line" : "these exact dependency lines"} to dependencies or devDependencies in package.json: ${lines.join(" ")}${writing ? " Add the dependency before selecting configs or tests, or exclude those groups from --groups." : ""}`,
1506
+ blocking: false,
1507
+ groups: ["configs", "tests"]
1508
+ };
1509
+ }
1510
+ #setupQuestion(target, blueprint) {
1511
+ const tests = resolveContainedPath(target, "tests");
1512
+ if (tests === void 0) return void 0;
1513
+ const entries = listFiles(tests).filter((path) => !path.includes("/"));
1514
+ const proofs = new Set(entries.filter((path) => path.endsWith(".test.ts")));
1515
+ const seeds = new Map(blueprintToTestArtifacts(blueprint).map(({ path, content }) => [path, content.trim()]));
1516
+ const modules = entries.filter((path) => {
1517
+ if (!path.startsWith("setup") || !path.endsWith(".ts")) return false;
1518
+ if (path.endsWith(".test.ts") || HOST_PATHS.includes(`tests/${path}`)) return false;
1519
+ if (proofs.has(`${path.slice(0, -3)}.test.ts`)) return false;
1520
+ if (resolveContainedPath(tests, path) === void 0) return false;
1521
+ const content = (readFileText(tests, path) ?? "").trim();
1522
+ return content !== "" && content !== (seeds.get(`tests/${path}`) ?? "");
1523
+ }).sort();
1524
+ if (modules.length === 0) return void 0;
1525
+ const single = modules.length === 1;
1526
+ const named = modules.map((path) => `tests/${path}`).join(", ");
1527
+ const remedies = modules.map((path) => `tests/${path.slice(0, -3)}.test.ts`).join(", ");
1528
+ const remedy = single ? `Add ${remedies} to cover it.` : `Add ${remedies}, each covering the module of the same name.`;
1529
+ return {
1530
+ field: "setup",
1531
+ message: `The target at ${target} carries ${single ? "a test setup module" : "test setup modules"} that no proof covers: ${named}. ${remedy} The proof's subject is behavior only this workspace can assert, so scaffold does not write it.`,
1532
+ blocking: false,
1533
+ groups: ["tests"]
1220
1534
  };
1221
1535
  }
1222
- #targetQuestions(target, blueprint, writing = false) {
1536
+ #targetQuestions(target, blueprint, groups, writing = false) {
1223
1537
  const questions = [];
1224
1538
  const project = this.#projectQuestion(target, blueprint, writing);
1225
1539
  if (project !== void 0) questions.push(project);
1226
1540
  const dependency = this.#dependencyQuestion(target, blueprint, writing);
1227
1541
  if (dependency !== void 0) questions.push(dependency);
1228
- return questions;
1542
+ if (!writing) {
1543
+ const setup = this.#setupQuestion(target, blueprint);
1544
+ if (setup !== void 0) questions.push(setup);
1545
+ }
1546
+ return questions.filter((question) => groups === void 0 || question.groups.some((group) => groups.includes(group))).map(({ field, message, blocking, candidates }) => ({
1547
+ field,
1548
+ message,
1549
+ blocking,
1550
+ ...candidates === void 0 ? {} : { candidates }
1551
+ }));
1229
1552
  }
1230
- #assertTarget(target, blueprint) {
1231
- const questions = this.#targetQuestions(target, blueprint, true);
1553
+ #assertTarget(target, blueprint, groups) {
1554
+ const questions = this.#targetQuestions(target, blueprint, groups, true);
1232
1555
  if (questions.length === 0) return;
1233
1556
  throw new ScaffoldError("TARGET", questions.map((question) => question.message).join(" "), { target });
1234
1557
  }
@@ -1255,7 +1578,7 @@ var CLI = class CLI {
1255
1578
  }
1256
1579
  return names;
1257
1580
  }
1258
- #repository(target) {
1581
+ #worktree(target) {
1259
1582
  const tracked = this.#inventory(target, ["ls-files", "-z"]);
1260
1583
  const dirty = this.#inventory(target, [
1261
1584
  "status",
@@ -1267,7 +1590,7 @@ var CLI = class CLI {
1267
1590
  tracked,
1268
1591
  dirty
1269
1592
  };
1270
- if (!isRepository(state)) throw new ScaffoldError("TARGET", `The git state at ${target} is not a readable inventory.`, {
1593
+ if (!isWorktree(state)) throw new ScaffoldError("TARGET", `The git state at ${target} is not a readable inventory.`, {
1271
1594
  target,
1272
1595
  tracked: tracked.length,
1273
1596
  dirty: dirty.length
@@ -1315,6 +1638,13 @@ var CLI = class CLI {
1315
1638
  removed: [...first.removed, ...second.removed]
1316
1639
  };
1317
1640
  }
1641
+ #reportBaselines(provenance) {
1642
+ const baselines = [];
1643
+ if (provenance.versions !== void 0) baselines.push(`versions=${provenance.versions}`);
1644
+ if (provenance.guides !== void 0) baselines.push(`guides=${provenance.guides}`);
1645
+ if (provenance.host !== void 0) baselines.push(`host=${provenance.host}`);
1646
+ this.#warn(`Upstream fallback selected the distributed baseline: ${baselines.join(", ")}.`);
1647
+ }
1318
1648
  #present(audit) {
1319
1649
  for (const question of audit.questions) this.#warn(`${question.field}: ${question.message}`);
1320
1650
  const rows = audit.findings.filter((finding) => finding.drift !== "aligned").map((finding) => [
@@ -1393,7 +1723,7 @@ process.stdout.on("error", (error) => {
1393
1723
  if ("code" in error && error.code === "EPIPE") return;
1394
1724
  throw error;
1395
1725
  });
1396
- process.exitCode = await new CLI(process.env.ORKESTREL_SCAFFOLD_REGISTRY === void 0 ? void 0 : { upstream: { registry: { base: process.env.ORKESTREL_SCAFFOLD_REGISTRY } } }).execute(process.argv.slice(2));
1726
+ process.exitCode = await new CLI({ upstream: environmentToUpstream(process.env) }).execute(process.argv.slice(2));
1397
1727
  //#endregion
1398
1728
 
1399
1729
  //# sourceMappingURL=main.js.map