@orkestrel/scaffold 0.0.10 → 0.0.12

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.
@@ -614,8 +614,9 @@ function orkestrelTokenIssue(normalized, catalog) {
614
614
  /** Parse a strict command-line argument vector. */
615
615
  function parseArguments(argv) {
616
616
  if (argv.some((argument) => !isTerminalText(argument))) throw new ScaffoldError("INVALID", "Command arguments must not contain control characters");
617
+ const args = argv[0] === "--" ? argv.slice(1) : [...argv];
617
618
  return parseArgs({
618
- args: argv[0] === "--" ? argv.slice(1) : [...argv],
619
+ args,
619
620
  allowPositionals: true,
620
621
  options: {
621
622
  src: { type: "string" },
@@ -873,6 +874,34 @@ var CLI = class {
873
874
  const full = diffPlan(compiled, readTarget(target, compiled.artifacts.map((artifact) => artifact.path)));
874
875
  return full.drifted + full.missing + full.foreign;
875
876
  }
877
+ /** Compile and audit the selected repair ownership boundary for one structural snapshot. */
878
+ #prepareRepair(spec, target, host, generated, json) {
879
+ const [compiled] = this.#compile(spec, json);
880
+ const scoped = {
881
+ ...compiled,
882
+ blueprint: {
883
+ ...compiled.blueprint,
884
+ overrides: []
885
+ },
886
+ artifacts: compiled.artifacts.filter((artifact) => artifact.origin === "host" || generated && artifact.origin === "computed" && artifact.path !== "package.json")
887
+ };
888
+ let plan;
889
+ try {
890
+ plan = hydratePlan(scoped, host);
891
+ } catch (error) {
892
+ this.#error(error, json);
893
+ }
894
+ try {
895
+ const audit = diffPlan(plan, readTarget(target, plan.artifacts.map((artifact) => artifact.path)));
896
+ return [
897
+ compiled,
898
+ plan,
899
+ audit
900
+ ];
901
+ } catch (error) {
902
+ this.#error(error, json);
903
+ }
904
+ }
876
905
  /** Reject a cancelled prompt (ctrl-c) with the shared `CANCELLED_MESSAGE` — exit 1, nothing written. */
877
906
  async #guard(promise) {
878
907
  try {
@@ -947,9 +976,11 @@ var CLI = class {
947
976
  */
948
977
  #names(host) {
949
978
  const names = attempt(() => {
950
- const full = locateHostSource(readHostManifest(host), ".claude/agents/orkestrel.md", host);
979
+ const manifest = readHostManifest(host);
980
+ const full = locateHostSource(manifest, ".claude/agents/orkestrel.md", host);
951
981
  if (full === void 0 || !existsSync(full)) return void 0;
952
- return catalogNames(readFileText(host, relative(host, full).replaceAll("\\", "/"), "TARGET", "host"));
982
+ const relative$1 = relative(host, full).replaceAll("\\", "/");
983
+ return catalogNames(readFileText(host, relative$1, "TARGET", "host"));
953
984
  });
954
985
  return names.success ? names.value : void 0;
955
986
  }
@@ -1216,29 +1247,12 @@ var CLI = class {
1216
1247
  } catch (error) {
1217
1248
  this.#error(error, json);
1218
1249
  }
1219
- const [compiled] = this.#compile(spec, json);
1220
1250
  const generated = values.generated === true;
1221
- const scoped = {
1222
- ...compiled,
1223
- blueprint: {
1224
- ...compiled.blueprint,
1225
- overrides: []
1226
- },
1227
- artifacts: compiled.artifacts.filter((artifact) => artifact.origin === "host" || generated && artifact.origin === "computed" && artifact.path !== "package.json")
1228
- };
1229
1251
  const host = values.from?.[0] ?? hostRoot();
1230
- let plan;
1231
- try {
1232
- plan = hydratePlan(scoped, host);
1233
- } catch (error) {
1234
- this.#error(error, json);
1235
- }
1236
- let audit;
1237
- try {
1238
- audit = diffPlan(plan, readTarget(target, plan.artifacts.map((artifact) => artifact.path)));
1239
- } catch (error) {
1240
- this.#error(error, json);
1241
- }
1252
+ const prepared = this.#prepareRepair(spec, target, host, generated, json);
1253
+ const compiled = prepared[0];
1254
+ let plan = prepared[1];
1255
+ let audit = prepared[2];
1242
1256
  if (!json) {
1243
1257
  this.#reporter.line(generated ? REPAIR_GENERATED_SCOPE : REPAIR_SCOPE);
1244
1258
  this.#reporter.section("Audit");
@@ -1268,6 +1282,21 @@ var CLI = class {
1268
1282
  if (values.prune && !json) if (prunePaths.length === 0) this.#reporter.line(PRUNE_EMPTY);
1269
1283
  else for (const line of prunePreview(prunePaths)) this.#reporter.line(line);
1270
1284
  const doPrune = prunePaths.length > 0 && await this.#prune(terminal, pruneConfirmMessage(prunePaths.length), values, json);
1285
+ let currentGlobal;
1286
+ try {
1287
+ currentGlobal = deriveBlueprint(target).global;
1288
+ } catch (error) {
1289
+ this.#error(error, json);
1290
+ }
1291
+ if (currentGlobal !== spec.global) {
1292
+ spec = {
1293
+ ...spec,
1294
+ global: currentGlobal
1295
+ };
1296
+ const refreshed = this.#prepareRepair(spec, target, host, generated, json);
1297
+ plan = refreshed[1];
1298
+ audit = refreshed[2];
1299
+ }
1271
1300
  const spinner = this.#spinner("repairing", json);
1272
1301
  spinner?.start();
1273
1302
  const materializer = createMaterializer({ host });
@@ -1304,7 +1333,10 @@ var CLI = class {
1304
1333
  try {
1305
1334
  const spec = deriveBlueprint(directory);
1306
1335
  const scaffolding = compiler.compile(spec);
1307
- if (!scaffolding.plan) throw new ScaffoldError("INVALID", scaffolding.questions.map((question) => question.text).join("; "));
1336
+ if (!scaffolding.plan) {
1337
+ const message = scaffolding.questions.map((question) => question.text).join("; ");
1338
+ throw new ScaffoldError("INVALID", message);
1339
+ }
1308
1340
  scoped = {
1309
1341
  ...scaffolding.plan,
1310
1342
  blueprint: {
@@ -1318,8 +1350,9 @@ var CLI = class {
1318
1350
  compiler.destroy();
1319
1351
  }
1320
1352
  const plan = hydratePlan(scoped, host);
1353
+ const paths = plan.artifacts.map((artifact) => artifact.path);
1321
1354
  const rawAudit = {
1322
- ...diffPlan(plan, readTarget(directory, plan.artifacts.map((artifact) => artifact.path))),
1355
+ ...diffPlan(plan, readTarget(directory, paths)),
1323
1356
  questions
1324
1357
  };
1325
1358
  const audit = this.#scan(rawAudit, directory, host, plan.blueprint.service);
@@ -1475,7 +1508,8 @@ var CLI = class {
1475
1508
  const endParts = current.split(CATALOG_END_MARKER);
1476
1509
  if (startIndex === -1 || endIndex === -1 || endIndex < startIndex || startParts.length !== 2 || endParts.length !== 2) this.#error(new ScaffoldError("TARGET", `Expected exactly one ordered "${CATALOG_START_MARKER}" / "${CATALOG_END_MARKER}" pair in ${agentPath}`, { path: agentPath }), json);
1477
1510
  const updated = `${current.slice(0, startIndex + CATALOG_START_MARKER.length)}\n\n${block}\n${current.slice(endIndex)}`;
1478
- const oldRows = catalogNames(current.slice(startIndex + CATALOG_START_MARKER.length, endIndex)).length;
1511
+ const oldBlock = current.slice(startIndex + CATALOG_START_MARKER.length, endIndex);
1512
+ const oldRows = catalogNames(oldBlock).length;
1479
1513
  const shrink = entries.length < oldRows ? oldRows - entries.length : void 0;
1480
1514
  if (updated === current) {
1481
1515
  if (json) this.#write(catalogResultOf(entries, false));
@@ -1513,7 +1547,8 @@ var CLI = class {
1513
1547
  }]);
1514
1548
  const staged = attempt(() => {
1515
1549
  validateWriteDirectories(transaction);
1516
- mkdirSync(dirname(resolvePhysicalPath(transaction.stage, CATALOG_AGENT_PATH, "WRITE", "staging")), { recursive: true });
1550
+ const destination = resolvePhysicalPath(transaction.stage, CATALOG_AGENT_PATH, "WRITE", "staging");
1551
+ mkdirSync(dirname(destination), { recursive: true });
1517
1552
  validateWriteDirectories(transaction);
1518
1553
  const contained = resolvePhysicalPath(transaction.stage, CATALOG_AGENT_PATH, "WRITE", "staging");
1519
1554
  writeFileSync(contained, updated, {