@orkestrel/scaffold 0.0.4 → 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.
@@ -2,8 +2,8 @@
2
2
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
3
3
  import { basename, dirname, join, relative } from "node:path";
4
4
  import * as tls from "node:tls";
5
- import { DEPENDENCY_NAME_PATTERN, ENVIRONMENTS, GROUPS, MAX_ARTIFACT_BYTES, NAME_PATTERN, ScaffoldError, blueprint, blueprintToPlan, catalogNames, catalogToBlock, createCompiler, dependency, diffPlan, isScaffoldError, manifestToDependencies, planToSummary } from "../src/core/index.js";
6
- import { WriteTransaction, catalogPackages, commitWriteTransaction, createMaterializer, createSync, deriveBlueprint, digestFile, digestText, discardWriteTransaction, discoverPackages, hostRoot, hydratePlan, isFilesystemPath, isRealDirectory, isTerminalText, isVacant, locateHostSource, pruneTargets, readFileText, readHostManifest, readManifest, readTarget, resolvePhysicalPath, validateWriteDirectories } from "../src/server/index.js";
5
+ import { DEPENDENCY_NAME_PATTERN, ENVIRONMENTS, GROUPS, MAX_ARTIFACT_BYTES, NAME_PATTERN, ScaffoldError, blueprint, catalogNames, catalogToBlock, createCompiler, dependency, diffPlan, isScaffoldError, manifestToDependencies, manifestToName, planToSummary } from "../src/core/index.js";
6
+ import { WriteTransaction, catalogPackages, commitWriteTransaction, createMaterializer, createSync, deriveBlueprint, digestFile, digestText, discardWriteTransaction, discoverPackages, hostRoot, hydratePlan, isFilesystemPath, isRealDirectory, isTerminalText, isVacant, locateHostSource, parseSyncOptions, pruneTargets, readFileText, readHostManifest, readManifest, readTarget, resolvePhysicalPath, validateWriteDirectories } from "../src/server/index.js";
7
7
  import { createReporter, createSpinner, createStyler } from "@orkestrel/console";
8
8
  import { createServerSink } from "@orkestrel/console/server";
9
9
  import { attempt } from "@orkestrel/contract";
@@ -660,6 +660,7 @@ function isVerb(value) {
660
660
  //#region src/bin/CLI.ts
661
661
  /** Stateful command-line orchestration and its process boundary. */
662
662
  var CLI = class {
663
+ #sync;
663
664
  #sink = createServerSink();
664
665
  #tty = process.stdout.isTTY === true;
665
666
  #styler = createStyler({ enabled: process.env.NO_COLOR === void 0 && this.#tty });
@@ -669,6 +670,14 @@ var CLI = class {
669
670
  styler: this.#styler
670
671
  });
671
672
  #json = false;
673
+ /**
674
+ * Create command-line orchestration with optional upstream endpoint settings.
675
+ *
676
+ * @param sync - Sync settings used by every live dependency operation.
677
+ */
678
+ constructor(sync) {
679
+ this.#sync = parseSyncOptions(sync);
680
+ }
672
681
  /** Execute one command-line argument vector. */
673
682
  async run(argv) {
674
683
  this.#trust();
@@ -743,15 +752,16 @@ var CLI = class {
743
752
  this.#error(contained.error, json);
744
753
  }
745
754
  /** Compile a spec and report unresolved blocking questions through the shared CLI error path. */
746
- #compile(spec, json) {
755
+ #compile(spec, json, groups) {
747
756
  const compiler = createCompiler();
748
757
  try {
749
- const scaffolding = compiler.compile(spec);
758
+ const scaffolding = compiler.compile(spec, groups);
750
759
  if (!scaffolding.plan) {
751
- const message = scaffolding.questions.map((question) => question.text).join("; ");
760
+ const blocking = scaffolding.questions.filter((question) => question.blocking);
761
+ const message = (blocking.length > 0 ? blocking : scaffolding.questions).map((question) => question.text).join("; ");
752
762
  this.#fail(message, json);
753
763
  }
754
- return scaffolding.plan;
764
+ return [scaffolding.plan, scaffolding.questions];
755
765
  } finally {
756
766
  compiler.destroy();
757
767
  }
@@ -966,7 +976,7 @@ var CLI = class {
966
976
  if (catalog === void 0) this.#reporter.line(CATALOG_UNRESOLVED_NOTE);
967
977
  depNames = await this.#prompt(terminal, catalog);
968
978
  }
969
- const sync = createSync();
979
+ const sync = createSync(this.#sync);
970
980
  let versions;
971
981
  try {
972
982
  versions = await sync.versions(depNames.map((depName) => dependency(depName, "*")));
@@ -976,7 +986,7 @@ var CLI = class {
976
986
  const unresolved = versions.filter((version) => version.freshness !== "current" && version.freshness !== "behind" || version.latest === "").map((version) => version.name);
977
987
  if (unresolved.length > 0) this.#fail(unresolvedVersion(unresolved), json);
978
988
  const deps = versions.map((version) => dependency(version.name, `^${version.latest}`));
979
- const plan = this.#compile(blueprint(name, {
989
+ const [plan] = this.#compile(blueprint(name, {
980
990
  src,
981
991
  app,
982
992
  dependencies: deps
@@ -1012,7 +1022,10 @@ var CLI = class {
1012
1022
  /** `scaffold pull` — refresh vendored dependency mirrors and report range drift. */
1013
1023
  async #pull(values, json) {
1014
1024
  const target = this.#contain(values.target ?? ".", json);
1015
- const sync = createSync(values.strict === void 0 ? void 0 : { strict: values.strict });
1025
+ const sync = createSync(values.strict === void 0 ? this.#sync : {
1026
+ ...this.#sync,
1027
+ strict: values.strict
1028
+ });
1016
1029
  try {
1017
1030
  let report;
1018
1031
  try {
@@ -1067,7 +1080,7 @@ var CLI = class {
1067
1080
  if (unrecognized.length > 0) this.#usage(`Group "${unrecognized.join("\", \"")}" is not recognized`, json);
1068
1081
  groups = GROUPS.filter((group) => groupsInput.includes(group));
1069
1082
  }
1070
- const compiled = blueprintToPlan(spec, groups);
1083
+ const [compiled, questions] = this.#compile(spec, json, groups);
1071
1084
  const host = values.from?.[0] ?? hostRoot();
1072
1085
  let plan;
1073
1086
  try {
@@ -1076,15 +1089,20 @@ var CLI = class {
1076
1089
  this.#error(error, json);
1077
1090
  }
1078
1091
  const artifactPaths = plan.artifacts.map((artifact) => artifact.path);
1079
- const rawAudit = diffPlan(plan, readTarget(target, artifactPaths));
1092
+ const rawAudit = {
1093
+ ...diffPlan(plan, readTarget(target, artifactPaths)),
1094
+ questions
1095
+ };
1080
1096
  const scanned = this.#scanSafe(rawAudit, target, host);
1081
1097
  const audit = scanned.audit;
1082
1098
  let drifted = !audit.clean;
1083
1099
  let live;
1084
1100
  if (values.live) {
1085
- const sync = createSync();
1101
+ const sync = createSync(this.#sync);
1086
1102
  try {
1087
- const guides = await sync.guides(deps);
1103
+ const manifestName = manifestToName(readManifest(target));
1104
+ const guideDependencies = deps.filter((entry) => entry.name !== manifestName);
1105
+ const guides = await sync.guides(guideDependencies);
1088
1106
  const versions = await sync.versions(deps);
1089
1107
  const entries = [...guides, ...versions];
1090
1108
  drifted ||= entries.some((entry) => entry.freshness !== "current");
@@ -1108,6 +1126,7 @@ var CLI = class {
1108
1126
  return;
1109
1127
  }
1110
1128
  if (scanned.skipped) this.#reporter.line(SCAN_SKIPPED);
1129
+ for (const question of audit.questions) if (!question.blocking) this.#reporter.line(`warning: ${question.text}`);
1111
1130
  this.#reporter.line(comparisonLine(true));
1112
1131
  this.#reporter.table(auditTable(audit, plan));
1113
1132
  this.#reporter.line(auditVerdict(audit, plan));
@@ -1150,9 +1169,13 @@ var CLI = class {
1150
1169
  } catch (error) {
1151
1170
  this.#error(error, json);
1152
1171
  }
1153
- const compiled = this.#compile(spec, json);
1172
+ const [compiled] = this.#compile(spec, json);
1154
1173
  const scoped = {
1155
1174
  ...compiled,
1175
+ blueprint: {
1176
+ ...compiled.blueprint,
1177
+ overrides: []
1178
+ },
1156
1179
  artifacts: compiled.artifacts.filter((artifact) => artifact.origin === "host")
1157
1180
  };
1158
1181
  const host = values.from?.[0] ?? hostRoot();
@@ -1228,19 +1251,28 @@ var CLI = class {
1228
1251
  try {
1229
1252
  const compiler = createCompiler();
1230
1253
  let scoped;
1254
+ let questions;
1231
1255
  try {
1232
1256
  const spec = deriveBlueprint(directory);
1233
1257
  const scaffolding = compiler.compile(spec);
1234
1258
  if (!scaffolding.plan) throw new ScaffoldError("INVALID", scaffolding.questions.map((question) => question.text).join("; "));
1235
1259
  scoped = {
1236
1260
  ...scaffolding.plan,
1261
+ blueprint: {
1262
+ ...scaffolding.plan.blueprint,
1263
+ overrides: []
1264
+ },
1237
1265
  artifacts: scaffolding.plan.artifacts.filter((artifact) => artifact.origin === "host")
1238
1266
  };
1267
+ questions = scaffolding.questions;
1239
1268
  } finally {
1240
1269
  compiler.destroy();
1241
1270
  }
1242
1271
  const plan = hydratePlan(scoped, host);
1243
- const rawAudit = diffPlan(plan, readTarget(directory, plan.artifacts.map((artifact) => artifact.path)));
1272
+ const rawAudit = {
1273
+ ...diffPlan(plan, readTarget(directory, plan.artifacts.map((artifact) => artifact.path))),
1274
+ questions
1275
+ };
1244
1276
  const audit = this.#scan(rawAudit, directory, host);
1245
1277
  repos.push({
1246
1278
  name,
@@ -1256,12 +1288,15 @@ var CLI = class {
1256
1288
  }
1257
1289
  }
1258
1290
  if (!json) {
1259
- for (const repo of repos) this.#reporter.line(fleetRepoLine(repo.name, repo.audit.clean ? { state: "clean" } : {
1260
- state: "drifted",
1261
- drifted: repo.audit.drifted,
1262
- missing: repo.audit.missing,
1263
- foreign: repo.audit.foreign
1264
- }));
1291
+ for (const repo of repos) {
1292
+ this.#reporter.line(fleetRepoLine(repo.name, repo.audit.clean ? { state: "clean" } : {
1293
+ state: "drifted",
1294
+ drifted: repo.audit.drifted,
1295
+ missing: repo.audit.missing,
1296
+ foreign: repo.audit.foreign
1297
+ }));
1298
+ for (const question of repo.audit.questions) if (!question.blocking) this.#reporter.line(`${repo.name}: warning: ${question.text}`);
1299
+ }
1265
1300
  for (const failure of failures) this.#reporter.line(fleetRepoLine(failure.name, {
1266
1301
  state: "failed",
1267
1302
  message: failure.message
@@ -1339,7 +1374,7 @@ var CLI = class {
1339
1374
  this.#error(error, json);
1340
1375
  }
1341
1376
  } else {
1342
- const sync = createSync();
1377
+ const sync = createSync(this.#sync);
1343
1378
  sync.emitter.on("package", (name, note) => {
1344
1379
  if (note !== "") notes.set(name, note);
1345
1380
  });