truecourse 0.7.0-next.1 → 0.7.0-next.3

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/cli.mjs CHANGED
@@ -972,8 +972,8 @@ var require_command = __commonJS({
972
972
  "node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
973
973
  var EventEmitter2 = __require("node:events").EventEmitter;
974
974
  var childProcess = __require("node:child_process");
975
- var path79 = __require("node:path");
976
- var fs68 = __require("node:fs");
975
+ var path80 = __require("node:path");
976
+ var fs69 = __require("node:fs");
977
977
  var process2 = __require("node:process");
978
978
  var { Argument: Argument2, humanReadableArgName } = require_argument();
979
979
  var { CommanderError: CommanderError2 } = require_error();
@@ -1905,11 +1905,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1905
1905
  let launchWithNode = false;
1906
1906
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1907
1907
  function findFile(baseDir, baseName) {
1908
- const localBin = path79.resolve(baseDir, baseName);
1909
- if (fs68.existsSync(localBin)) return localBin;
1910
- if (sourceExt.includes(path79.extname(baseName))) return void 0;
1908
+ const localBin = path80.resolve(baseDir, baseName);
1909
+ if (fs69.existsSync(localBin)) return localBin;
1910
+ if (sourceExt.includes(path80.extname(baseName))) return void 0;
1911
1911
  const foundExt = sourceExt.find(
1912
- (ext2) => fs68.existsSync(`${localBin}${ext2}`)
1912
+ (ext2) => fs69.existsSync(`${localBin}${ext2}`)
1913
1913
  );
1914
1914
  if (foundExt) return `${localBin}${foundExt}`;
1915
1915
  return void 0;
@@ -1921,21 +1921,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1921
1921
  if (this._scriptPath) {
1922
1922
  let resolvedScriptPath;
1923
1923
  try {
1924
- resolvedScriptPath = fs68.realpathSync(this._scriptPath);
1924
+ resolvedScriptPath = fs69.realpathSync(this._scriptPath);
1925
1925
  } catch (err) {
1926
1926
  resolvedScriptPath = this._scriptPath;
1927
1927
  }
1928
- executableDir = path79.resolve(
1929
- path79.dirname(resolvedScriptPath),
1928
+ executableDir = path80.resolve(
1929
+ path80.dirname(resolvedScriptPath),
1930
1930
  executableDir
1931
1931
  );
1932
1932
  }
1933
1933
  if (executableDir) {
1934
1934
  let localFile = findFile(executableDir, executableFile);
1935
1935
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1936
- const legacyName = path79.basename(
1936
+ const legacyName = path80.basename(
1937
1937
  this._scriptPath,
1938
- path79.extname(this._scriptPath)
1938
+ path80.extname(this._scriptPath)
1939
1939
  );
1940
1940
  if (legacyName !== this._name) {
1941
1941
  localFile = findFile(
@@ -1946,7 +1946,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1946
1946
  }
1947
1947
  executableFile = localFile || executableFile;
1948
1948
  }
1949
- launchWithNode = sourceExt.includes(path79.extname(executableFile));
1949
+ launchWithNode = sourceExt.includes(path80.extname(executableFile));
1950
1950
  let proc;
1951
1951
  if (process2.platform !== "win32") {
1952
1952
  if (launchWithNode) {
@@ -2786,7 +2786,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2786
2786
  * @return {Command}
2787
2787
  */
2788
2788
  nameFromFilename(filename) {
2789
- this._name = path79.basename(filename, path79.extname(filename));
2789
+ this._name = path80.basename(filename, path80.extname(filename));
2790
2790
  return this;
2791
2791
  }
2792
2792
  /**
@@ -2800,9 +2800,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2800
2800
  * @param {string} [path]
2801
2801
  * @return {(string|null|Command)}
2802
2802
  */
2803
- executableDir(path80) {
2804
- if (path80 === void 0) return this._executableDir;
2805
- this._executableDir = path80;
2803
+ executableDir(path81) {
2804
+ if (path81 === void 0) return this._executableDir;
2805
+ this._executableDir = path81;
2806
2806
  return this;
2807
2807
  }
2808
2808
  /**
@@ -5206,8 +5206,8 @@ var init_parseUtil = __esm({
5206
5206
  init_errors();
5207
5207
  init_en();
5208
5208
  makeIssue = (params) => {
5209
- const { data, path: path79, errorMaps, issueData } = params;
5210
- const fullPath = [...path79, ...issueData.path || []];
5209
+ const { data, path: path80, errorMaps, issueData } = params;
5210
+ const fullPath = [...path80, ...issueData.path || []];
5211
5211
  const fullIssue = {
5212
5212
  ...issueData,
5213
5213
  path: fullPath
@@ -5515,11 +5515,11 @@ var init_types = __esm({
5515
5515
  init_parseUtil();
5516
5516
  init_util();
5517
5517
  ParseInputLazyPath = class {
5518
- constructor(parent, value, path79, key4) {
5518
+ constructor(parent, value, path80, key4) {
5519
5519
  this._cachedPath = [];
5520
5520
  this.parent = parent;
5521
5521
  this.data = value;
5522
- this._path = path79;
5522
+ this._path = path80;
5523
5523
  this._key = key4;
5524
5524
  }
5525
5525
  get path() {
@@ -11976,10 +11976,10 @@ var require_src3 = __commonJS({
11976
11976
  var fs_1 = __require("fs");
11977
11977
  var debug_1 = __importDefault(require_src2());
11978
11978
  var log2 = debug_1.default("@kwsites/file-exists");
11979
- function check(path79, isFile, isDirectory) {
11980
- log2(`checking %s`, path79);
11979
+ function check(path80, isFile, isDirectory) {
11980
+ log2(`checking %s`, path80);
11981
11981
  try {
11982
- const stat = fs_1.statSync(path79);
11982
+ const stat = fs_1.statSync(path80);
11983
11983
  if (stat.isFile() && isFile) {
11984
11984
  log2(`[OK] path represents a file`);
11985
11985
  return true;
@@ -11999,8 +11999,8 @@ var require_src3 = __commonJS({
11999
11999
  throw e;
12000
12000
  }
12001
12001
  }
12002
- function exists2(path79, type2 = exports.READABLE) {
12003
- return check(path79, (type2 & exports.FILE) > 0, (type2 & exports.FOLDER) > 0);
12002
+ function exists2(path80, type2 = exports.READABLE) {
12003
+ return check(path80, (type2 & exports.FILE) > 0, (type2 & exports.FOLDER) > 0);
12004
12004
  }
12005
12005
  exports.exists = exists2;
12006
12006
  exports.FILE = 1;
@@ -12073,8 +12073,8 @@ function pathspec(...paths) {
12073
12073
  cache.set(key4, paths);
12074
12074
  return key4;
12075
12075
  }
12076
- function isPathSpec(path79) {
12077
- return path79 instanceof String && cache.has(path79);
12076
+ function isPathSpec(path80) {
12077
+ return path80 instanceof String && cache.has(path80);
12078
12078
  }
12079
12079
  function toPaths(pathSpec) {
12080
12080
  return cache.get(pathSpec) || [];
@@ -12118,8 +12118,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
12118
12118
  function forEachLineWithContent(input, callback) {
12119
12119
  return toLinesWithContent(input, true).map((line) => callback(line));
12120
12120
  }
12121
- function folderExists(path79) {
12122
- return (0, import_file_exists.exists)(path79, import_file_exists.FOLDER);
12121
+ function folderExists(path80) {
12122
+ return (0, import_file_exists.exists)(path80, import_file_exists.FOLDER);
12123
12123
  }
12124
12124
  function append(target, item) {
12125
12125
  if (Array.isArray(target)) {
@@ -12310,8 +12310,8 @@ function checkIsRepoRootTask() {
12310
12310
  commands,
12311
12311
  format: "utf-8",
12312
12312
  onError,
12313
- parser(path79) {
12314
- return /^\.(git)?$/.test(path79.trim());
12313
+ parser(path80) {
12314
+ return /^\.(git)?$/.test(path80.trim());
12315
12315
  }
12316
12316
  };
12317
12317
  }
@@ -12567,11 +12567,11 @@ function parseGrep(grep) {
12567
12567
  const paths = /* @__PURE__ */ new Set();
12568
12568
  const results = {};
12569
12569
  forEachLineWithContent(grep, (input) => {
12570
- const [path79, line, preview] = input.split(NULL);
12571
- paths.add(path79);
12572
- (results[path79] = results[path79] || []).push({
12570
+ const [path80, line, preview] = input.split(NULL);
12571
+ paths.add(path80);
12572
+ (results[path80] = results[path80] || []).push({
12573
12573
  line: asNumber(line),
12574
- path: path79,
12574
+ path: path80,
12575
12575
  preview
12576
12576
  });
12577
12577
  });
@@ -12868,14 +12868,14 @@ function hashObjectTask(filePath, write) {
12868
12868
  }
12869
12869
  return straightThroughStringTask(commands, true);
12870
12870
  }
12871
- function parseInit(bare, path79, text4) {
12871
+ function parseInit(bare, path80, text4) {
12872
12872
  const response = String(text4).trim();
12873
12873
  let result;
12874
12874
  if (result = initResponseRegex.exec(response)) {
12875
- return new InitSummary(bare, path79, false, result[1]);
12875
+ return new InitSummary(bare, path80, false, result[1]);
12876
12876
  }
12877
12877
  if (result = reInitResponseRegex.exec(response)) {
12878
- return new InitSummary(bare, path79, true, result[1]);
12878
+ return new InitSummary(bare, path80, true, result[1]);
12879
12879
  }
12880
12880
  let gitDir = "";
12881
12881
  const tokens = response.split(" ");
@@ -12886,12 +12886,12 @@ function parseInit(bare, path79, text4) {
12886
12886
  break;
12887
12887
  }
12888
12888
  }
12889
- return new InitSummary(bare, path79, /^re/i.test(response), gitDir);
12889
+ return new InitSummary(bare, path80, /^re/i.test(response), gitDir);
12890
12890
  }
12891
12891
  function hasBareCommand(command) {
12892
12892
  return command.includes(bareCommand);
12893
12893
  }
12894
- function initTask(bare = false, path79, customArgs) {
12894
+ function initTask(bare = false, path80, customArgs) {
12895
12895
  const commands = ["init", ...customArgs];
12896
12896
  if (bare && !hasBareCommand(commands)) {
12897
12897
  commands.splice(1, 0, bareCommand);
@@ -12900,7 +12900,7 @@ function initTask(bare = false, path79, customArgs) {
12900
12900
  commands,
12901
12901
  format: "utf-8",
12902
12902
  parser(text4) {
12903
- return parseInit(commands.includes("--bare"), path79, text4);
12903
+ return parseInit(commands.includes("--bare"), path80, text4);
12904
12904
  }
12905
12905
  };
12906
12906
  }
@@ -13179,14 +13179,14 @@ function splitLine(result, lineStr) {
13179
13179
  default:
13180
13180
  return;
13181
13181
  }
13182
- function data(index, workingDir, path79) {
13182
+ function data(index, workingDir, path80) {
13183
13183
  const raw = `${index}${workingDir}`;
13184
13184
  const handler = parsers6.get(raw);
13185
13185
  if (handler) {
13186
- handler(result, path79);
13186
+ handler(result, path80);
13187
13187
  }
13188
13188
  if (raw !== "##" && raw !== "!!") {
13189
- result.files.push(new FileStatusSummary(path79, index, workingDir));
13189
+ result.files.push(new FileStatusSummary(path80, index, workingDir));
13190
13190
  }
13191
13191
  }
13192
13192
  }
@@ -13373,8 +13373,8 @@ function deleteBranchTask(branch, forceDelete = false) {
13373
13373
  return task;
13374
13374
  }
13375
13375
  function toPath(input) {
13376
- const path79 = input.trim().replace(/^["']|["']$/g, "");
13377
- return path79 && normalize(path79);
13376
+ const path80 = input.trim().replace(/^["']|["']$/g, "");
13377
+ return path80 && normalize(path80);
13378
13378
  }
13379
13379
  function checkIgnoreTask(paths) {
13380
13380
  return {
@@ -13513,8 +13513,8 @@ function stashListTask(opt = {}, customArgs) {
13513
13513
  parser: parser4
13514
13514
  };
13515
13515
  }
13516
- function addSubModuleTask(repo, path79) {
13517
- return subModuleTask(["add", repo, path79]);
13516
+ function addSubModuleTask(repo, path80) {
13517
+ return subModuleTask(["add", repo, path80]);
13518
13518
  }
13519
13519
  function initSubModuleTask(customArgs) {
13520
13520
  return subModuleTask(["init", ...customArgs]);
@@ -14826,9 +14826,9 @@ var init_esm2 = __esm({
14826
14826
  "src/lib/responses/InitSummary.ts"() {
14827
14827
  "use strict";
14828
14828
  InitSummary = class {
14829
- constructor(bare, path79, existing, gitDir) {
14829
+ constructor(bare, path80, existing, gitDir) {
14830
14830
  this.bare = bare;
14831
- this.path = path79;
14831
+ this.path = path80;
14832
14832
  this.existing = existing;
14833
14833
  this.gitDir = gitDir;
14834
14834
  }
@@ -15362,12 +15362,12 @@ var init_esm2 = __esm({
15362
15362
  "use strict";
15363
15363
  fromPathRegex = /^(.+)\0(.+)$/;
15364
15364
  FileStatusSummary = class {
15365
- constructor(path79, index, working_dir) {
15366
- this.path = path79;
15365
+ constructor(path80, index, working_dir) {
15366
+ this.path = path80;
15367
15367
  this.index = index;
15368
15368
  this.working_dir = working_dir;
15369
15369
  if (index === "R" || working_dir === "R") {
15370
- const detail = fromPathRegex.exec(path79) || [null, path79, path79];
15370
+ const detail = fromPathRegex.exec(path80) || [null, path80, path80];
15371
15371
  this.from = detail[2] || "";
15372
15372
  this.path = detail[1] || "";
15373
15373
  }
@@ -15630,9 +15630,9 @@ var init_esm2 = __esm({
15630
15630
  next
15631
15631
  );
15632
15632
  }
15633
- hashObject(path79, write) {
15633
+ hashObject(path80, write) {
15634
15634
  return this._runTask(
15635
- hashObjectTask(path79, write === true),
15635
+ hashObjectTask(path80, write === true),
15636
15636
  trailingFunctionArgument(arguments)
15637
15637
  );
15638
15638
  }
@@ -16269,8 +16269,8 @@ var init_esm2 = __esm({
16269
16269
  }
16270
16270
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
16271
16271
  };
16272
- Git2.prototype.submoduleAdd = function(repo, path79, then) {
16273
- return this._runTask(addSubModuleTask2(repo, path79), trailingFunctionArgument2(arguments));
16272
+ Git2.prototype.submoduleAdd = function(repo, path80, then) {
16273
+ return this._runTask(addSubModuleTask2(repo, path80), trailingFunctionArgument2(arguments));
16274
16274
  };
16275
16275
  Git2.prototype.submoduleUpdate = function(args, then) {
16276
16276
  return this._runTask(
@@ -16896,7 +16896,7 @@ var require_ignore = __commonJS({
16896
16896
  // path matching.
16897
16897
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
16898
16898
  // @returns {TestResult} true if a file is ignored
16899
- test(path79, checkUnignored, mode) {
16899
+ test(path80, checkUnignored, mode) {
16900
16900
  let ignored = false;
16901
16901
  let unignored = false;
16902
16902
  let matchedRule;
@@ -16905,7 +16905,7 @@ var require_ignore = __commonJS({
16905
16905
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
16906
16906
  return;
16907
16907
  }
16908
- const matched = rule[mode].test(path79);
16908
+ const matched = rule[mode].test(path80);
16909
16909
  if (!matched) {
16910
16910
  return;
16911
16911
  }
@@ -16926,17 +16926,17 @@ var require_ignore = __commonJS({
16926
16926
  var throwError2 = (message, Ctor) => {
16927
16927
  throw new Ctor(message);
16928
16928
  };
16929
- var checkPath = (path79, originalPath, doThrow) => {
16930
- if (!isString(path79)) {
16929
+ var checkPath = (path80, originalPath, doThrow) => {
16930
+ if (!isString(path80)) {
16931
16931
  return doThrow(
16932
16932
  `path must be a string, but got \`${originalPath}\``,
16933
16933
  TypeError
16934
16934
  );
16935
16935
  }
16936
- if (!path79) {
16936
+ if (!path80) {
16937
16937
  return doThrow(`path must not be empty`, TypeError);
16938
16938
  }
16939
- if (checkPath.isNotRelative(path79)) {
16939
+ if (checkPath.isNotRelative(path80)) {
16940
16940
  const r = "`path.relative()`d";
16941
16941
  return doThrow(
16942
16942
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -16945,7 +16945,7 @@ var require_ignore = __commonJS({
16945
16945
  }
16946
16946
  return true;
16947
16947
  };
16948
- var isNotRelative = (path79) => REGEX_TEST_INVALID_PATH.test(path79);
16948
+ var isNotRelative = (path80) => REGEX_TEST_INVALID_PATH.test(path80);
16949
16949
  checkPath.isNotRelative = isNotRelative;
16950
16950
  checkPath.convert = (p2) => p2;
16951
16951
  var Ignore = class {
@@ -16975,19 +16975,19 @@ var require_ignore = __commonJS({
16975
16975
  }
16976
16976
  // @returns {TestResult}
16977
16977
  _test(originalPath, cache3, checkUnignored, slices) {
16978
- const path79 = originalPath && checkPath.convert(originalPath);
16978
+ const path80 = originalPath && checkPath.convert(originalPath);
16979
16979
  checkPath(
16980
- path79,
16980
+ path80,
16981
16981
  originalPath,
16982
16982
  this._strictPathCheck ? throwError2 : RETURN_FALSE
16983
16983
  );
16984
- return this._t(path79, cache3, checkUnignored, slices);
16984
+ return this._t(path80, cache3, checkUnignored, slices);
16985
16985
  }
16986
- checkIgnore(path79) {
16987
- if (!REGEX_TEST_TRAILING_SLASH.test(path79)) {
16988
- return this.test(path79);
16986
+ checkIgnore(path80) {
16987
+ if (!REGEX_TEST_TRAILING_SLASH.test(path80)) {
16988
+ return this.test(path80);
16989
16989
  }
16990
- const slices = path79.split(SLASH).filter(Boolean);
16990
+ const slices = path80.split(SLASH).filter(Boolean);
16991
16991
  slices.pop();
16992
16992
  if (slices.length) {
16993
16993
  const parent = this._t(
@@ -17000,18 +17000,18 @@ var require_ignore = __commonJS({
17000
17000
  return parent;
17001
17001
  }
17002
17002
  }
17003
- return this._rules.test(path79, false, MODE_CHECK_IGNORE);
17003
+ return this._rules.test(path80, false, MODE_CHECK_IGNORE);
17004
17004
  }
17005
- _t(path79, cache3, checkUnignored, slices) {
17006
- if (path79 in cache3) {
17007
- return cache3[path79];
17005
+ _t(path80, cache3, checkUnignored, slices) {
17006
+ if (path80 in cache3) {
17007
+ return cache3[path80];
17008
17008
  }
17009
17009
  if (!slices) {
17010
- slices = path79.split(SLASH).filter(Boolean);
17010
+ slices = path80.split(SLASH).filter(Boolean);
17011
17011
  }
17012
17012
  slices.pop();
17013
17013
  if (!slices.length) {
17014
- return cache3[path79] = this._rules.test(path79, checkUnignored, MODE_IGNORE);
17014
+ return cache3[path80] = this._rules.test(path80, checkUnignored, MODE_IGNORE);
17015
17015
  }
17016
17016
  const parent = this._t(
17017
17017
  slices.join(SLASH) + SLASH,
@@ -17019,29 +17019,29 @@ var require_ignore = __commonJS({
17019
17019
  checkUnignored,
17020
17020
  slices
17021
17021
  );
17022
- return cache3[path79] = parent.ignored ? parent : this._rules.test(path79, checkUnignored, MODE_IGNORE);
17022
+ return cache3[path80] = parent.ignored ? parent : this._rules.test(path80, checkUnignored, MODE_IGNORE);
17023
17023
  }
17024
- ignores(path79) {
17025
- return this._test(path79, this._ignoreCache, false).ignored;
17024
+ ignores(path80) {
17025
+ return this._test(path80, this._ignoreCache, false).ignored;
17026
17026
  }
17027
17027
  createFilter() {
17028
- return (path79) => !this.ignores(path79);
17028
+ return (path80) => !this.ignores(path80);
17029
17029
  }
17030
17030
  filter(paths) {
17031
17031
  return makeArray(paths).filter(this.createFilter());
17032
17032
  }
17033
17033
  // @returns {TestResult}
17034
- test(path79) {
17035
- return this._test(path79, this._testCache, true);
17034
+ test(path80) {
17035
+ return this._test(path80, this._testCache, true);
17036
17036
  }
17037
17037
  };
17038
17038
  var factory = (options) => new Ignore(options);
17039
- var isPathValid = (path79) => checkPath(path79 && checkPath.convert(path79), path79, RETURN_FALSE);
17039
+ var isPathValid = (path80) => checkPath(path80 && checkPath.convert(path80), path80, RETURN_FALSE);
17040
17040
  var setupWindows = () => {
17041
17041
  const makePosix = (str2) => /^\\\\\?\\/.test(str2) || /["<>|\u0000-\u001F]+/u.test(str2) ? str2 : str2.replace(/\\/g, "/");
17042
17042
  checkPath.convert = makePosix;
17043
17043
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
17044
- checkPath.isNotRelative = (path79) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path79) || isNotRelative(path79);
17044
+ checkPath.isNotRelative = (path80) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path80) || isNotRelative(path80);
17045
17045
  };
17046
17046
  if (
17047
17047
  // Detect `process` so that it can run in browsers.
@@ -18782,18 +18782,18 @@ function extractRouterMount(callNode, filePath) {
18782
18782
  const routerName = args[0]?.type === "identifier" ? args[0].text : null;
18783
18783
  if (!routerName)
18784
18784
  return null;
18785
- let path79 = "/";
18785
+ let path80 = "/";
18786
18786
  for (const arg of args) {
18787
18787
  if (arg.type === "keyword_argument") {
18788
18788
  const key4 = arg.childForFieldName("name")?.text;
18789
18789
  const value = arg.childForFieldName("value");
18790
18790
  if ((key4 === "url_prefix" || key4 === "prefix") && value) {
18791
- path79 = value.text.replace(/^["']|["']$/g, "");
18791
+ path80 = value.text.replace(/^["']|["']$/g, "");
18792
18792
  }
18793
18793
  }
18794
18794
  }
18795
18795
  return {
18796
- path: path79,
18796
+ path: path80,
18797
18797
  routerName,
18798
18798
  location: {
18799
18799
  filePath,
@@ -18817,11 +18817,11 @@ function extractChainedRoute(outerCall, filePath) {
18817
18817
  const innerArgs = innerCall.childForFieldName("arguments");
18818
18818
  if (!innerArgs)
18819
18819
  return null;
18820
- let path79 = null;
18820
+ let path80 = null;
18821
18821
  let httpMethod = methodName3 === "route" ? "GET" : methodName3.toUpperCase();
18822
18822
  for (const arg of innerArgs.namedChildren) {
18823
- if (!path79 && arg.type === "string") {
18824
- path79 = arg.text.replace(/^["']|["']$/g, "");
18823
+ if (!path80 && arg.type === "string") {
18824
+ path80 = arg.text.replace(/^["']|["']$/g, "");
18825
18825
  }
18826
18826
  if (arg.type === "keyword_argument") {
18827
18827
  const key4 = arg.childForFieldName("name")?.text;
@@ -18833,14 +18833,14 @@ function extractChainedRoute(outerCall, filePath) {
18833
18833
  }
18834
18834
  }
18835
18835
  }
18836
- if (!path79)
18836
+ if (!path80)
18837
18837
  return null;
18838
18838
  const outerArgs = outerCall.childForFieldName("arguments");
18839
18839
  const handlerArg = outerArgs?.namedChildren[0];
18840
18840
  const handlerName = handlerArg?.type === "identifier" ? handlerArg.text : "anonymous";
18841
18841
  return {
18842
18842
  httpMethod,
18843
- path: path79,
18843
+ path: path80,
18844
18844
  handlerName,
18845
18845
  location: {
18846
18846
  filePath,
@@ -18902,11 +18902,11 @@ function collectGroupPrefixes(root2) {
18902
18902
  const fn = child.childForFieldName("function");
18903
18903
  if (fn?.type === "member_access_expression" && fn.childForFieldName("name")?.text === "MapGroup") {
18904
18904
  const args = child.childForFieldName("arguments");
18905
- const path79 = args ? extractFirstStringArg(args) : null;
18906
- if (name && path79) {
18905
+ const path80 = args ? extractFirstStringArg(args) : null;
18906
+ if (name && path80) {
18907
18907
  const receiver = fn.childForFieldName("expression")?.text ?? "";
18908
18908
  const parentPrefix = prefixes.get(receiver) ?? "";
18909
- prefixes.set(name, joinRoute(parentPrefix, path79));
18909
+ prefixes.set(name, joinRoute(parentPrefix, path80));
18910
18910
  }
18911
18911
  }
18912
18912
  }
@@ -18930,9 +18930,9 @@ function extractClassRoutePrefix(classNode) {
18930
18930
  continue;
18931
18931
  const args = childOfType(attr, "attribute_argument_list");
18932
18932
  if (args) {
18933
- const path79 = extractFirstStringArg(args);
18934
- if (path79)
18935
- return path79;
18933
+ const path80 = extractFirstStringArg(args);
18934
+ if (path80)
18935
+ return path80;
18936
18936
  }
18937
18937
  }
18938
18938
  }
@@ -18955,16 +18955,16 @@ function extractAttributeRoute(methodNode, filePath, classContext) {
18955
18955
  httpMethod = method;
18956
18956
  const args = childOfType(attr, "attribute_argument_list");
18957
18957
  if (args) {
18958
- const path79 = extractFirstStringArg(args);
18959
- if (path79)
18960
- routePath = path79;
18958
+ const path80 = extractFirstStringArg(args);
18959
+ if (path80)
18960
+ routePath = path80;
18961
18961
  }
18962
18962
  } else if (name === "Route" && !routePath) {
18963
18963
  const args = childOfType(attr, "attribute_argument_list");
18964
18964
  if (args) {
18965
- const path79 = extractFirstStringArg(args);
18966
- if (path79)
18967
- routePath = path79;
18965
+ const path80 = extractFirstStringArg(args);
18966
+ if (path80)
18967
+ routePath = path80;
18968
18968
  }
18969
18969
  }
18970
18970
  }
@@ -18998,12 +18998,12 @@ function extractMinimalApiRoute(callNode, filePath, groupPrefixes) {
18998
18998
  const argsNode = callNode.childForFieldName("arguments");
18999
18999
  if (!argsNode)
19000
19000
  return null;
19001
- const path79 = extractFirstStringArg(argsNode);
19002
- if (path79 === null)
19001
+ const path80 = extractFirstStringArg(argsNode);
19002
+ if (path80 === null)
19003
19003
  return null;
19004
19004
  const receiver = funcNode.childForFieldName("expression")?.text ?? "";
19005
19005
  const prefix = groupPrefixes.get(receiver) ?? "";
19006
- let fullPath = joinRoute(prefix, path79);
19006
+ let fullPath = joinRoute(prefix, path80);
19007
19007
  if (!fullPath.startsWith("/"))
19008
19008
  fullPath = "/" + fullPath;
19009
19009
  let handlerName = "anonymous";
@@ -19030,11 +19030,11 @@ function childOfType(node2, type2) {
19030
19030
  }
19031
19031
  return null;
19032
19032
  }
19033
- function joinRoute(prefix, path79) {
19033
+ function joinRoute(prefix, path80) {
19034
19034
  const p2 = prefix.replace(/\/$/, "");
19035
- const s = path79.replace(/^\//, "");
19035
+ const s = path80.replace(/^\//, "");
19036
19036
  if (!p2)
19037
- return path79;
19037
+ return path80;
19038
19038
  if (!s)
19039
19039
  return p2;
19040
19040
  return `${p2}/${s}`;
@@ -19143,8 +19143,8 @@ function extractRoute(methodName3, argsNode, filePath, callNode) {
19143
19143
  const firstArg = argsNode.namedChild(0);
19144
19144
  if (!firstArg)
19145
19145
  return null;
19146
- const path79 = extractStringLiteral(firstArg);
19147
- if (!path79)
19146
+ const path80 = extractStringLiteral(firstArg);
19147
+ if (!path80)
19148
19148
  return null;
19149
19149
  const argCount = argsNode.namedChildCount;
19150
19150
  if (argCount < 2)
@@ -19157,7 +19157,7 @@ function extractRoute(methodName3, argsNode, filePath, callNode) {
19157
19157
  return null;
19158
19158
  return {
19159
19159
  httpMethod: methodName3.toUpperCase(),
19160
- path: path79,
19160
+ path: path80,
19161
19161
  handlerName,
19162
19162
  location: {
19163
19163
  filePath,
@@ -19174,8 +19174,8 @@ function extractMount(argsNode, filePath, callNode) {
19174
19174
  const firstArg = argsNode.namedChild(0);
19175
19175
  if (!firstArg)
19176
19176
  return null;
19177
- const path79 = extractStringLiteral(firstArg);
19178
- if (!path79)
19177
+ const path80 = extractStringLiteral(firstArg);
19178
+ if (!path80)
19179
19179
  return null;
19180
19180
  const secondArg = argsNode.namedChild(1);
19181
19181
  if (!secondArg)
@@ -19184,7 +19184,7 @@ function extractMount(argsNode, filePath, callNode) {
19184
19184
  if (!routerName)
19185
19185
  return null;
19186
19186
  return {
19187
- path: path79,
19187
+ path: path80,
19188
19188
  routerName,
19189
19189
  location: {
19190
19190
  filePath,
@@ -21715,11 +21715,11 @@ function buildCSharpSymbolIndex(files, rootPath) {
21715
21715
  byFullName.get(full).push(decl);
21716
21716
  }
21717
21717
  const stats = { resolvedRefs: 0, ambiguousRefs: 0 };
21718
- function resolveQualified(path79) {
21719
- const exact = byFullName.get(path79);
21718
+ function resolveQualified(path80) {
21719
+ const exact = byFullName.get(path80);
21720
21720
  if (exact)
21721
21721
  return exact;
21722
- const parts = path79.split(".");
21722
+ const parts = path80.split(".");
21723
21723
  for (let i = parts.length - 1; i > 0; i--) {
21724
21724
  const prefix = parts.slice(0, i).join(".");
21725
21725
  const found = byFullName.get(prefix);
@@ -21733,8 +21733,8 @@ function buildCSharpSymbolIndex(files, rootPath) {
21733
21733
  const firstDot = ref.name.indexOf(".");
21734
21734
  const head = ref.name.slice(0, firstDot);
21735
21735
  const aliasTarget2 = aliases.get(head);
21736
- const path79 = aliasTarget2 ? `${aliasTarget2}${ref.name.slice(firstDot)}` : ref.name;
21737
- return resolveQualified(path79).filter((d3) => isDeclVisibleFrom(d3, ctx.project, fileProjects.get(d3.filePath)));
21736
+ const path80 = aliasTarget2 ? `${aliasTarget2}${ref.name.slice(firstDot)}` : ref.name;
21737
+ return resolveQualified(path80).filter((d3) => isDeclVisibleFrom(d3, ctx.project, fileProjects.get(d3.filePath)));
21738
21738
  }
21739
21739
  const aliasTarget = aliases.get(ref.name);
21740
21740
  if (aliasTarget) {
@@ -24858,9 +24858,9 @@ function detectDockerComposeServices(rootPath, allFiles) {
24858
24858
  ];
24859
24859
  let composePath2 = null;
24860
24860
  for (const file of composeFiles) {
24861
- const path79 = join8(rootPath, file);
24862
- if (existsSync7(path79)) {
24863
- composePath2 = path79;
24861
+ const path80 = join8(rootPath, file);
24862
+ if (existsSync7(path80)) {
24863
+ composePath2 = path80;
24864
24864
  break;
24865
24865
  }
24866
24866
  }
@@ -28067,9 +28067,9 @@ function findSimpleCycles(component, componentSet, adjacency) {
28067
28067
  for (const next of successors) {
28068
28068
  if (!componentSet.has(next))
28069
28069
  continue;
28070
- if (next === start && path79.length >= 2) {
28071
- const chain = [...path79, start];
28072
- const minNode = path79.reduce((a, b) => a < b ? a : b);
28070
+ if (next === start && path80.length >= 2) {
28071
+ const chain = [...path80, start];
28072
+ const minNode = path80.reduce((a, b) => a < b ? a : b);
28073
28073
  if (minNode === start) {
28074
28074
  cycles.push(chain);
28075
28075
  }
@@ -28077,15 +28077,15 @@ function findSimpleCycles(component, componentSet, adjacency) {
28077
28077
  }
28078
28078
  if (!visited.has(next) && !seen.has(next)) {
28079
28079
  visited.add(next);
28080
- path79.push(next);
28080
+ path80.push(next);
28081
28081
  dfs2(next);
28082
- path79.pop();
28082
+ path80.pop();
28083
28083
  visited.delete(next);
28084
28084
  }
28085
28085
  }
28086
28086
  };
28087
28087
  var dfs = dfs2;
28088
- const path79 = [start];
28088
+ const path80 = [start];
28089
28089
  const visited = /* @__PURE__ */ new Set([start]);
28090
28090
  dfs2(start);
28091
28091
  seen.add(start);
@@ -28107,7 +28107,7 @@ function findShortestCycle(start, componentSet, adjacency) {
28107
28107
  visited.add(next);
28108
28108
  }
28109
28109
  while (queue.length > 0) {
28110
- const { node: node2, path: path79 } = queue.shift();
28110
+ const { node: node2, path: path80 } = queue.shift();
28111
28111
  const nexts = adjacency.get(node2);
28112
28112
  if (!nexts)
28113
28113
  continue;
@@ -28115,11 +28115,11 @@ function findShortestCycle(start, componentSet, adjacency) {
28115
28115
  if (!componentSet.has(next))
28116
28116
  continue;
28117
28117
  if (next === start) {
28118
- return [...path79, start];
28118
+ return [...path80, start];
28119
28119
  }
28120
28120
  if (!visited.has(next)) {
28121
28121
  visited.add(next);
28122
- queue.push({ node: next, path: [...path79, next] });
28122
+ queue.push({ node: next, path: [...path80, next] });
28123
28123
  }
28124
28124
  }
28125
28125
  }
@@ -105218,7 +105218,7 @@ function parseBlockedOnCapabilities(reason) {
105218
105218
  return [];
105219
105219
  return m[1].split(",").map((s) => s.trim()).filter(Boolean);
105220
105220
  }
105221
- var GuardWrittenScenarioSchema, GuardCoverageGapKindSchema, GuardCoverageGapSchema, GuardBirthFindingSchema, GuardGenerateErrorSchema, GuardExtractionFailureSchema, GuardOrphanedSectionSchema, GuardRecipeReportSchema, GuardGenerateUsageSchema, GuardGenerateReportSchema;
105221
+ var GuardWrittenScenarioSchema, GuardCoverageGapKindSchema, GuardCoverageGapSchema, GuardBirthFindingSchema, GuardGenerateErrorSchema, GuardEntryPreflightSchema, GuardExtractionFailureSchema, GuardOrphanedSectionSchema, GuardRecipeReportSchema, GuardGenerateUsageSchema, GuardGenerateReportSchema;
105222
105222
  var init_report = __esm({
105223
105223
  "packages/shared/dist/guard/report.js"() {
105224
105224
  "use strict";
@@ -105271,6 +105271,14 @@ var init_report = __esm({
105271
105271
  anchor: external_exports.string(),
105272
105272
  message: external_exports.string()
105273
105273
  }).strict();
105274
+ GuardEntryPreflightSchema = external_exports.object({
105275
+ /** Display form of the entry argv, e.g. `node tools/cli/dist/index.js`. */
105276
+ entry: external_exports.string(),
105277
+ /** The recipe build command, for the rebuild hint. */
105278
+ buildCommand: external_exports.string(),
105279
+ /** The full, UNTRUNCATED startup output the dead entry produced. */
105280
+ stderr: external_exports.string()
105281
+ }).strict();
105274
105282
  GuardExtractionFailureSchema = external_exports.object({
105275
105283
  doc: external_exports.string(),
105276
105284
  reason: external_exports.string()
@@ -105316,7 +105324,13 @@ var init_report = __esm({
105316
105324
  */
105317
105325
  birthPassed: external_exports.number().int().nonnegative().optional(),
105318
105326
  manifestPath: external_exports.string().optional(),
105319
- usage: GuardGenerateUsageSchema.optional()
105327
+ usage: GuardGenerateUsageSchema.optional(),
105328
+ /**
105329
+ * Present ONLY when the built entry failed to start — the whole birth phase was
105330
+ * short-circuited, so every changed section stayed unsettled. Optional so older
105331
+ * reports (written before this field existed) keep parsing.
105332
+ */
105333
+ entryPreflight: GuardEntryPreflightSchema.optional()
105320
105334
  }).strict();
105321
105335
  }
105322
105336
  });
@@ -111861,14 +111875,14 @@ var init_missing_error_status_code = __esm({
111861
111875
  });
111862
111876
 
111863
111877
  // packages/analyzer/dist/rules/architecture/visitors/javascript/route-without-auth-middleware.js
111864
- function isPublicPath(path79) {
111865
- return PUBLIC_PATH_PATTERNS.some((re2) => re2.test(path79));
111878
+ function isPublicPath(path80) {
111879
+ return PUBLIC_PATH_PATTERNS.some((re2) => re2.test(path80));
111866
111880
  }
111867
- function isUrlCredentialAuthedPath(path79) {
111868
- return URL_CREDENTIAL_PARAMS.test(path79);
111881
+ function isUrlCredentialAuthedPath(path80) {
111882
+ return URL_CREDENTIAL_PARAMS.test(path80);
111869
111883
  }
111870
- function isApiDocsPath(path79) {
111871
- return API_DOCS_PATH.test(path79);
111884
+ function isApiDocsPath(path80) {
111885
+ return API_DOCS_PATH.test(path80);
111872
111886
  }
111873
111887
  function isFrameworkRequestHandler(arg) {
111874
111888
  if (!arg)
@@ -112017,14 +112031,14 @@ var init_route_without_auth_middleware = __esm({
112017
112031
  return null;
112018
112032
  const firstArg = args.namedChildren[0];
112019
112033
  if (firstArg?.type === "string" || firstArg?.type === "template_string") {
112020
- const path79 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
112021
- if (isPublicPath(path79))
112034
+ const path80 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
112035
+ if (isPublicPath(path80))
112022
112036
  return null;
112023
- if (isUrlCredentialAuthedPath(path79))
112037
+ if (isUrlCredentialAuthedPath(path80))
112024
112038
  return null;
112025
- if (isApiDocsPath(path79))
112039
+ if (isApiDocsPath(path80))
112026
112040
  return null;
112027
- if (path79 === "*" || path79 === "(.*)" || path79 === "/*") {
112041
+ if (path80 === "*" || path80 === "(.*)" || path80 === "/*") {
112028
112042
  if (isFrameworkRequestHandler(args.namedChildren[args.namedChildren.length - 1])) {
112029
112043
  return null;
112030
112044
  }
@@ -146595,8 +146609,8 @@ var require_windows = __commonJS({
146595
146609
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
146596
146610
  module.exports = isexe;
146597
146611
  isexe.sync = sync;
146598
- var fs68 = __require("fs");
146599
- function checkPathExt(path79, options) {
146612
+ var fs69 = __require("fs");
146613
+ function checkPathExt(path80, options) {
146600
146614
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
146601
146615
  if (!pathext) {
146602
146616
  return true;
@@ -146607,25 +146621,25 @@ var require_windows = __commonJS({
146607
146621
  }
146608
146622
  for (var i = 0; i < pathext.length; i++) {
146609
146623
  var p2 = pathext[i].toLowerCase();
146610
- if (p2 && path79.substr(-p2.length).toLowerCase() === p2) {
146624
+ if (p2 && path80.substr(-p2.length).toLowerCase() === p2) {
146611
146625
  return true;
146612
146626
  }
146613
146627
  }
146614
146628
  return false;
146615
146629
  }
146616
- function checkStat(stat, path79, options) {
146630
+ function checkStat(stat, path80, options) {
146617
146631
  if (!stat.isSymbolicLink() && !stat.isFile()) {
146618
146632
  return false;
146619
146633
  }
146620
- return checkPathExt(path79, options);
146634
+ return checkPathExt(path80, options);
146621
146635
  }
146622
- function isexe(path79, options, cb) {
146623
- fs68.stat(path79, function(er, stat) {
146624
- cb(er, er ? false : checkStat(stat, path79, options));
146636
+ function isexe(path80, options, cb) {
146637
+ fs69.stat(path80, function(er, stat) {
146638
+ cb(er, er ? false : checkStat(stat, path80, options));
146625
146639
  });
146626
146640
  }
146627
- function sync(path79, options) {
146628
- return checkStat(fs68.statSync(path79), path79, options);
146641
+ function sync(path80, options) {
146642
+ return checkStat(fs69.statSync(path80), path80, options);
146629
146643
  }
146630
146644
  }
146631
146645
  });
@@ -146635,14 +146649,14 @@ var require_mode = __commonJS({
146635
146649
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
146636
146650
  module.exports = isexe;
146637
146651
  isexe.sync = sync;
146638
- var fs68 = __require("fs");
146639
- function isexe(path79, options, cb) {
146640
- fs68.stat(path79, function(er, stat) {
146652
+ var fs69 = __require("fs");
146653
+ function isexe(path80, options, cb) {
146654
+ fs69.stat(path80, function(er, stat) {
146641
146655
  cb(er, er ? false : checkStat(stat, options));
146642
146656
  });
146643
146657
  }
146644
- function sync(path79, options) {
146645
- return checkStat(fs68.statSync(path79), options);
146658
+ function sync(path80, options) {
146659
+ return checkStat(fs69.statSync(path80), options);
146646
146660
  }
146647
146661
  function checkStat(stat, options) {
146648
146662
  return stat.isFile() && checkMode(stat, options);
@@ -146666,7 +146680,7 @@ var require_mode = __commonJS({
146666
146680
  // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
146667
146681
  var require_isexe = __commonJS({
146668
146682
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
146669
- var fs68 = __require("fs");
146683
+ var fs69 = __require("fs");
146670
146684
  var core2;
146671
146685
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
146672
146686
  core2 = require_windows();
@@ -146675,7 +146689,7 @@ var require_isexe = __commonJS({
146675
146689
  }
146676
146690
  module.exports = isexe;
146677
146691
  isexe.sync = sync;
146678
- function isexe(path79, options, cb) {
146692
+ function isexe(path80, options, cb) {
146679
146693
  if (typeof options === "function") {
146680
146694
  cb = options;
146681
146695
  options = {};
@@ -146685,7 +146699,7 @@ var require_isexe = __commonJS({
146685
146699
  throw new TypeError("callback not provided");
146686
146700
  }
146687
146701
  return new Promise(function(resolve12, reject) {
146688
- isexe(path79, options || {}, function(er, is) {
146702
+ isexe(path80, options || {}, function(er, is) {
146689
146703
  if (er) {
146690
146704
  reject(er);
146691
146705
  } else {
@@ -146694,7 +146708,7 @@ var require_isexe = __commonJS({
146694
146708
  });
146695
146709
  });
146696
146710
  }
146697
- core2(path79, options || {}, function(er, is) {
146711
+ core2(path80, options || {}, function(er, is) {
146698
146712
  if (er) {
146699
146713
  if (er.code === "EACCES" || options && options.ignoreErrors) {
146700
146714
  er = null;
@@ -146704,9 +146718,9 @@ var require_isexe = __commonJS({
146704
146718
  cb(er, is);
146705
146719
  });
146706
146720
  }
146707
- function sync(path79, options) {
146721
+ function sync(path80, options) {
146708
146722
  try {
146709
- return core2.sync(path79, options || {});
146723
+ return core2.sync(path80, options || {});
146710
146724
  } catch (er) {
146711
146725
  if (options && options.ignoreErrors || er.code === "EACCES") {
146712
146726
  return false;
@@ -146722,7 +146736,7 @@ var require_isexe = __commonJS({
146722
146736
  var require_which = __commonJS({
146723
146737
  "node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
146724
146738
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
146725
- var path79 = __require("path");
146739
+ var path80 = __require("path");
146726
146740
  var COLON = isWindows ? ";" : ":";
146727
146741
  var isexe = require_isexe();
146728
146742
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -146760,7 +146774,7 @@ var require_which = __commonJS({
146760
146774
  return opt.all && found.length ? resolve12(found) : reject(getNotFoundError(cmd));
146761
146775
  const ppRaw = pathEnv[i];
146762
146776
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
146763
- const pCmd = path79.join(pathPart, cmd);
146777
+ const pCmd = path80.join(pathPart, cmd);
146764
146778
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
146765
146779
  resolve12(subStep(p2, i, 0));
146766
146780
  });
@@ -146787,7 +146801,7 @@ var require_which = __commonJS({
146787
146801
  for (let i = 0; i < pathEnv.length; i++) {
146788
146802
  const ppRaw = pathEnv[i];
146789
146803
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
146790
- const pCmd = path79.join(pathPart, cmd);
146804
+ const pCmd = path80.join(pathPart, cmd);
146791
146805
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
146792
146806
  for (let j2 = 0; j2 < pathExt.length; j2++) {
146793
146807
  const cur = p2 + pathExt[j2];
@@ -146835,7 +146849,7 @@ var require_path_key = __commonJS({
146835
146849
  var require_resolveCommand = __commonJS({
146836
146850
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
146837
146851
  "use strict";
146838
- var path79 = __require("path");
146852
+ var path80 = __require("path");
146839
146853
  var which = require_which();
146840
146854
  var getPathKey = require_path_key();
146841
146855
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -146853,7 +146867,7 @@ var require_resolveCommand = __commonJS({
146853
146867
  try {
146854
146868
  resolved = which.sync(parsed.command, {
146855
146869
  path: env[getPathKey({ env })],
146856
- pathExt: withoutPathExt ? path79.delimiter : void 0
146870
+ pathExt: withoutPathExt ? path80.delimiter : void 0
146857
146871
  });
146858
146872
  } catch (e) {
146859
146873
  } finally {
@@ -146862,7 +146876,7 @@ var require_resolveCommand = __commonJS({
146862
146876
  }
146863
146877
  }
146864
146878
  if (resolved) {
146865
- resolved = path79.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
146879
+ resolved = path80.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
146866
146880
  }
146867
146881
  return resolved;
146868
146882
  }
@@ -146916,8 +146930,8 @@ var require_shebang_command = __commonJS({
146916
146930
  if (!match4) {
146917
146931
  return null;
146918
146932
  }
146919
- const [path79, argument] = match4[0].replace(/#! ?/, "").split(" ");
146920
- const binary2 = path79.split("/").pop();
146933
+ const [path80, argument] = match4[0].replace(/#! ?/, "").split(" ");
146934
+ const binary2 = path80.split("/").pop();
146921
146935
  if (binary2 === "env") {
146922
146936
  return argument;
146923
146937
  }
@@ -146930,16 +146944,16 @@ var require_shebang_command = __commonJS({
146930
146944
  var require_readShebang = __commonJS({
146931
146945
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
146932
146946
  "use strict";
146933
- var fs68 = __require("fs");
146947
+ var fs69 = __require("fs");
146934
146948
  var shebangCommand = require_shebang_command();
146935
146949
  function readShebang(command) {
146936
146950
  const size = 150;
146937
146951
  const buffer = Buffer.alloc(size);
146938
146952
  let fd;
146939
146953
  try {
146940
- fd = fs68.openSync(command, "r");
146941
- fs68.readSync(fd, buffer, 0, size, 0);
146942
- fs68.closeSync(fd);
146954
+ fd = fs69.openSync(command, "r");
146955
+ fs69.readSync(fd, buffer, 0, size, 0);
146956
+ fs69.closeSync(fd);
146943
146957
  } catch (e) {
146944
146958
  }
146945
146959
  return shebangCommand(buffer.toString());
@@ -146952,7 +146966,7 @@ var require_readShebang = __commonJS({
146952
146966
  var require_parse = __commonJS({
146953
146967
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
146954
146968
  "use strict";
146955
- var path79 = __require("path");
146969
+ var path80 = __require("path");
146956
146970
  var resolveCommand = require_resolveCommand();
146957
146971
  var escape2 = require_escape();
146958
146972
  var readShebang = require_readShebang();
@@ -146977,7 +146991,7 @@ var require_parse = __commonJS({
146977
146991
  const needsShell = !isExecutableRegExp.test(commandFile);
146978
146992
  if (parsed.options.forceShell || needsShell) {
146979
146993
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
146980
- parsed.command = path79.normalize(parsed.command);
146994
+ parsed.command = path80.normalize(parsed.command);
146981
146995
  parsed.command = escape2.command(parsed.command);
146982
146996
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
146983
146997
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -147343,8 +147357,8 @@ var require_package = __commonJS({
147343
147357
  // node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
147344
147358
  var require_main = __commonJS({
147345
147359
  "node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
147346
- var fs68 = __require("fs");
147347
- var path79 = __require("path");
147360
+ var fs69 = __require("fs");
147361
+ var path80 = __require("path");
147348
147362
  var os15 = __require("os");
147349
147363
  var crypto6 = __require("crypto");
147350
147364
  var packageJson = require_package();
@@ -147452,7 +147466,7 @@ var require_main = __commonJS({
147452
147466
  if (options && options.path && options.path.length > 0) {
147453
147467
  if (Array.isArray(options.path)) {
147454
147468
  for (const filepath of options.path) {
147455
- if (fs68.existsSync(filepath)) {
147469
+ if (fs69.existsSync(filepath)) {
147456
147470
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
147457
147471
  }
147458
147472
  }
@@ -147460,15 +147474,15 @@ var require_main = __commonJS({
147460
147474
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
147461
147475
  }
147462
147476
  } else {
147463
- possibleVaultPath = path79.resolve(process.cwd(), ".env.vault");
147477
+ possibleVaultPath = path80.resolve(process.cwd(), ".env.vault");
147464
147478
  }
147465
- if (fs68.existsSync(possibleVaultPath)) {
147479
+ if (fs69.existsSync(possibleVaultPath)) {
147466
147480
  return possibleVaultPath;
147467
147481
  }
147468
147482
  return null;
147469
147483
  }
147470
147484
  function _resolveHome(envPath) {
147471
- return envPath[0] === "~" ? path79.join(os15.homedir(), envPath.slice(1)) : envPath;
147485
+ return envPath[0] === "~" ? path80.join(os15.homedir(), envPath.slice(1)) : envPath;
147472
147486
  }
147473
147487
  function _configVault(options) {
147474
147488
  const debug2 = Boolean(options && options.debug);
@@ -147485,7 +147499,7 @@ var require_main = __commonJS({
147485
147499
  return { parsed };
147486
147500
  }
147487
147501
  function configDotenv(options) {
147488
- const dotenvPath = path79.resolve(process.cwd(), ".env");
147502
+ const dotenvPath = path80.resolve(process.cwd(), ".env");
147489
147503
  let encoding = "utf8";
147490
147504
  const debug2 = Boolean(options && options.debug);
147491
147505
  const quiet = options && "quiet" in options ? options.quiet : true;
@@ -147509,13 +147523,13 @@ var require_main = __commonJS({
147509
147523
  }
147510
147524
  let lastError;
147511
147525
  const parsedAll = {};
147512
- for (const path80 of optionPaths) {
147526
+ for (const path81 of optionPaths) {
147513
147527
  try {
147514
- const parsed = DotenvModule.parse(fs68.readFileSync(path80, { encoding }));
147528
+ const parsed = DotenvModule.parse(fs69.readFileSync(path81, { encoding }));
147515
147529
  DotenvModule.populate(parsedAll, parsed, options);
147516
147530
  } catch (e) {
147517
147531
  if (debug2) {
147518
- _debug(`Failed to load ${path80} ${e.message}`);
147532
+ _debug(`Failed to load ${path81} ${e.message}`);
147519
147533
  }
147520
147534
  lastError = e;
147521
147535
  }
@@ -147530,7 +147544,7 @@ var require_main = __commonJS({
147530
147544
  const shortPaths = [];
147531
147545
  for (const filePath of optionPaths) {
147532
147546
  try {
147533
- const relative2 = path79.relative(process.cwd(), filePath);
147547
+ const relative2 = path80.relative(process.cwd(), filePath);
147534
147548
  shortPaths.push(relative2);
147535
147549
  } catch (e) {
147536
147550
  if (debug2) {
@@ -148389,8 +148403,8 @@ var init_cli_provider = __esm({
148389
148403
  this._repoId = repoId;
148390
148404
  }
148391
148405
  /** Set target repo path — used as cwd when spawning CLI so Read tool accesses the right files. */
148392
- setRepoPath(path79) {
148393
- this._repoPath = path79;
148406
+ setRepoPath(path80) {
148407
+ this._repoPath = path80;
148394
148408
  }
148395
148409
  flushUsage() {
148396
148410
  if (this._usageRecords.length === 0)
@@ -160491,11 +160505,11 @@ var require_mime_types = __commonJS({
160491
160505
  }
160492
160506
  return exts[0];
160493
160507
  }
160494
- function lookup(path79) {
160495
- if (!path79 || typeof path79 !== "string") {
160508
+ function lookup(path80) {
160509
+ if (!path80 || typeof path80 !== "string") {
160496
160510
  return false;
160497
160511
  }
160498
- var extension2 = extname("x." + path79).toLowerCase().substr(1);
160512
+ var extension2 = extname("x." + path80).toLowerCase().substr(1);
160499
160513
  if (!extension2) {
160500
160514
  return false;
160501
160515
  }
@@ -161600,11 +161614,11 @@ var require_form_data = __commonJS({
161600
161614
  "use strict";
161601
161615
  var CombinedStream = require_combined_stream();
161602
161616
  var util2 = __require("util");
161603
- var path79 = __require("path");
161617
+ var path80 = __require("path");
161604
161618
  var http = __require("http");
161605
161619
  var https = __require("https");
161606
161620
  var parseUrl = __require("url").parse;
161607
- var fs68 = __require("fs");
161621
+ var fs69 = __require("fs");
161608
161622
  var Stream = __require("stream").Stream;
161609
161623
  var crypto6 = __require("crypto");
161610
161624
  var mime = require_mime_types();
@@ -161671,7 +161685,7 @@ var require_form_data = __commonJS({
161671
161685
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
161672
161686
  callback(null, value.end + 1 - (value.start ? value.start : 0));
161673
161687
  } else {
161674
- fs68.stat(value.path, function(err, stat) {
161688
+ fs69.stat(value.path, function(err, stat) {
161675
161689
  if (err) {
161676
161690
  callback(err);
161677
161691
  return;
@@ -161728,11 +161742,11 @@ var require_form_data = __commonJS({
161728
161742
  FormData2.prototype._getContentDisposition = function(value, options) {
161729
161743
  var filename;
161730
161744
  if (typeof options.filepath === "string") {
161731
- filename = path79.normalize(options.filepath).replace(/\\/g, "/");
161745
+ filename = path80.normalize(options.filepath).replace(/\\/g, "/");
161732
161746
  } else if (options.filename || value && (value.name || value.path)) {
161733
- filename = path79.basename(options.filename || value && (value.name || value.path));
161747
+ filename = path80.basename(options.filename || value && (value.name || value.path));
161734
161748
  } else if (value && value.readable && hasOwn(value, "httpVersion")) {
161735
- filename = path79.basename(value.client._httpMessage.path || "");
161749
+ filename = path80.basename(value.client._httpMessage.path || "");
161736
161750
  }
161737
161751
  if (filename) {
161738
161752
  return 'filename="' + filename + '"';
@@ -162289,8 +162303,8 @@ var require_node2 = __commonJS({
162289
162303
  }
162290
162304
  break;
162291
162305
  case "FILE":
162292
- var fs68 = __require("fs");
162293
- stream2 = new fs68.SyncWriteStream(fd2, { autoClose: false });
162306
+ var fs69 = __require("fs");
162307
+ stream2 = new fs69.SyncWriteStream(fd2, { autoClose: false });
162294
162308
  stream2._type = "fs";
162295
162309
  break;
162296
162310
  case "PIPE":
@@ -163386,9 +163400,9 @@ var require_axios = __commonJS({
163386
163400
  function removeBrackets(key4) {
163387
163401
  return utils$1.endsWith(key4, "[]") ? key4.slice(0, -2) : key4;
163388
163402
  }
163389
- function renderKey(path79, key4, dots) {
163390
- if (!path79) return key4;
163391
- return path79.concat(key4).map(function each(token, i) {
163403
+ function renderKey(path80, key4, dots) {
163404
+ if (!path80) return key4;
163405
+ return path80.concat(key4).map(function each(token, i) {
163392
163406
  token = removeBrackets(token);
163393
163407
  return !dots && i ? "[" + token + "]" : token;
163394
163408
  }).join(dots ? "." : "");
@@ -163436,13 +163450,13 @@ var require_axios = __commonJS({
163436
163450
  }
163437
163451
  return value;
163438
163452
  }
163439
- function defaultVisitor(value, key4, path79) {
163453
+ function defaultVisitor(value, key4, path80) {
163440
163454
  let arr = value;
163441
163455
  if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
163442
- formData.append(renderKey(path79, key4, dots), convertValue(value));
163456
+ formData.append(renderKey(path80, key4, dots), convertValue(value));
163443
163457
  return false;
163444
163458
  }
163445
- if (value && !path79 && typeof value === "object") {
163459
+ if (value && !path80 && typeof value === "object") {
163446
163460
  if (utils$1.endsWith(key4, "{}")) {
163447
163461
  key4 = metaTokens ? key4 : key4.slice(0, -2);
163448
163462
  value = JSON.stringify(value);
@@ -163461,7 +163475,7 @@ var require_axios = __commonJS({
163461
163475
  if (isVisitable(value)) {
163462
163476
  return true;
163463
163477
  }
163464
- formData.append(renderKey(path79, key4, dots), convertValue(value));
163478
+ formData.append(renderKey(path80, key4, dots), convertValue(value));
163465
163479
  return false;
163466
163480
  }
163467
163481
  const stack2 = [];
@@ -163470,16 +163484,16 @@ var require_axios = __commonJS({
163470
163484
  convertValue,
163471
163485
  isVisitable
163472
163486
  });
163473
- function build8(value, path79) {
163487
+ function build8(value, path80) {
163474
163488
  if (utils$1.isUndefined(value)) return;
163475
163489
  if (stack2.indexOf(value) !== -1) {
163476
- throw Error("Circular reference detected in " + path79.join("."));
163490
+ throw Error("Circular reference detected in " + path80.join("."));
163477
163491
  }
163478
163492
  stack2.push(value);
163479
163493
  utils$1.forEach(value, function each(el, key4) {
163480
- const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4, path79, exposedHelpers);
163494
+ const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4, path80, exposedHelpers);
163481
163495
  if (result === true) {
163482
- build8(el, path79 ? path79.concat(key4) : [key4]);
163496
+ build8(el, path80 ? path80.concat(key4) : [key4]);
163483
163497
  }
163484
163498
  });
163485
163499
  stack2.pop();
@@ -163668,7 +163682,7 @@ var require_axios = __commonJS({
163668
163682
  };
163669
163683
  function toURLEncodedForm(data, options) {
163670
163684
  return toFormData(data, new platform.classes.URLSearchParams(), {
163671
- visitor: function(value, key4, path79, helpers) {
163685
+ visitor: function(value, key4, path80, helpers) {
163672
163686
  if (platform.isNode && utils$1.isBuffer(value)) {
163673
163687
  this.append(key4, value.toString("base64"));
163674
163688
  return false;
@@ -163696,11 +163710,11 @@ var require_axios = __commonJS({
163696
163710
  return obj;
163697
163711
  }
163698
163712
  function formDataToJSON(formData) {
163699
- function buildPath(path79, value, target, index) {
163700
- let name = path79[index++];
163713
+ function buildPath(path80, value, target, index) {
163714
+ let name = path80[index++];
163701
163715
  if (name === "__proto__") return true;
163702
163716
  const isNumericKey = Number.isFinite(+name);
163703
- const isLast = index >= path79.length;
163717
+ const isLast = index >= path80.length;
163704
163718
  name = !name && utils$1.isArray(target) ? target.length : name;
163705
163719
  if (isLast) {
163706
163720
  if (utils$1.hasOwnProp(target, name)) {
@@ -163713,7 +163727,7 @@ var require_axios = __commonJS({
163713
163727
  if (!target[name] || !utils$1.isObject(target[name])) {
163714
163728
  target[name] = [];
163715
163729
  }
163716
- const result = buildPath(path79, value, target[name], index);
163730
+ const result = buildPath(path80, value, target[name], index);
163717
163731
  if (result && utils$1.isArray(target[name])) {
163718
163732
  target[name] = arrayToObject(target[name]);
163719
163733
  }
@@ -165031,9 +165045,9 @@ var require_axios = __commonJS({
165031
165045
  auth = urlUsername + ":" + urlPassword;
165032
165046
  }
165033
165047
  auth && headers.delete("authorization");
165034
- let path79;
165048
+ let path80;
165035
165049
  try {
165036
- path79 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
165050
+ path80 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
165037
165051
  } catch (err) {
165038
165052
  const customErr = new Error(err.message);
165039
165053
  customErr.config = config2;
@@ -165043,7 +165057,7 @@ var require_axios = __commonJS({
165043
165057
  }
165044
165058
  headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
165045
165059
  const options = {
165046
- path: path79,
165060
+ path: path80,
165047
165061
  method,
165048
165062
  headers: headers.toJSON(),
165049
165063
  agents: {
@@ -165249,14 +165263,14 @@ var require_axios = __commonJS({
165249
165263
  var cookies = platform.hasStandardBrowserEnv ? (
165250
165264
  // Standard browser envs support document.cookie
165251
165265
  {
165252
- write(name, value, expires, path79, domain, secure, sameSite) {
165266
+ write(name, value, expires, path80, domain, secure, sameSite) {
165253
165267
  if (typeof document === "undefined") return;
165254
165268
  const cookie = [`${name}=${encodeURIComponent(value)}`];
165255
165269
  if (utils$1.isNumber(expires)) {
165256
165270
  cookie.push(`expires=${new Date(expires).toUTCString()}`);
165257
165271
  }
165258
- if (utils$1.isString(path79)) {
165259
- cookie.push(`path=${path79}`);
165272
+ if (utils$1.isString(path80)) {
165273
+ cookie.push(`path=${path80}`);
165260
165274
  }
165261
165275
  if (utils$1.isString(domain)) {
165262
165276
  cookie.push(`domain=${domain}`);
@@ -166777,8 +166791,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname10(proc
166777
166791
  return decodedFile;
166778
166792
  };
166779
166793
  }
166780
- function normalizeWindowsPath(path79) {
166781
- return path79.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
166794
+ function normalizeWindowsPath(path80) {
166795
+ return path80.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
166782
166796
  }
166783
166797
  async function addSourceContext(frames) {
166784
166798
  const filesToLines = {};
@@ -166823,9 +166837,9 @@ async function addSourceContext(frames) {
166823
166837
  LRU_FILE_CONTENTS_CACHE.reduce();
166824
166838
  return frames;
166825
166839
  }
166826
- function getContextLinesFromFile(path79, ranges, output) {
166840
+ function getContextLinesFromFile(path80, ranges, output) {
166827
166841
  return new Promise((resolve12) => {
166828
- const stream = createReadStream(path79);
166842
+ const stream = createReadStream(path80);
166829
166843
  const lineReaded = createInterface2({
166830
166844
  input: stream
166831
166845
  });
@@ -166843,7 +166857,7 @@ function getContextLinesFromFile(path79, ranges, output) {
166843
166857
  let rangeStart = range2[0];
166844
166858
  let rangeEnd = range2[1];
166845
166859
  function onStreamError() {
166846
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path79, 1);
166860
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path80, 1);
166847
166861
  lineReaded.close();
166848
166862
  lineReaded.removeAllListeners();
166849
166863
  destroyStreamAndResolve();
@@ -166920,8 +166934,8 @@ function clearLineContext(frame) {
166920
166934
  delete frame.context_line;
166921
166935
  delete frame.post_context;
166922
166936
  }
166923
- function shouldSkipContextLinesForFile(path79) {
166924
- return path79.startsWith("node:") || path79.endsWith(".min.js") || path79.endsWith(".min.cjs") || path79.endsWith(".min.mjs") || path79.startsWith("data:");
166937
+ function shouldSkipContextLinesForFile(path80) {
166938
+ return path80.startsWith("node:") || path80.endsWith(".min.js") || path80.endsWith(".min.cjs") || path80.endsWith(".min.mjs") || path80.startsWith("data:");
166925
166939
  }
166926
166940
  function shouldSkipContextLinesForFrame(frame) {
166927
166941
  if (frame.lineno !== void 0 && frame.lineno > MAX_CONTEXTLINES_LINENO) {
@@ -170270,7 +170284,7 @@ function readToolVersion() {
170270
170284
  if (cachedVersion)
170271
170285
  return cachedVersion;
170272
170286
  if (true) {
170273
- cachedVersion = "0.7.0-next.1";
170287
+ cachedVersion = "0.7.0-next.3";
170274
170288
  return cachedVersion;
170275
170289
  }
170276
170290
  try {
@@ -172676,13 +172690,13 @@ var init_pexprs_toFailure = __esm({
172676
172690
  return new Failure(this, "a Unicode [" + this.categoryOrProp + "] character", "description");
172677
172691
  };
172678
172692
  Alt.prototype.toFailure = function(grammar2) {
172679
- const fs68 = this.terms.map((t2) => t2.toFailure(grammar2));
172680
- const description = "(" + fs68.join(" or ") + ")";
172693
+ const fs69 = this.terms.map((t2) => t2.toFailure(grammar2));
172694
+ const description = "(" + fs69.join(" or ") + ")";
172681
172695
  return new Failure(this, description, "description");
172682
172696
  };
172683
172697
  Seq.prototype.toFailure = function(grammar2) {
172684
- const fs68 = this.factors.map((f2) => f2.toFailure(grammar2));
172685
- const description = "(" + fs68.join(" ") + ")";
172698
+ const fs69 = this.factors.map((f2) => f2.toFailure(grammar2));
172699
+ const description = "(" + fs69.join(" ") + ")";
172686
172700
  return new Failure(this, description, "description");
172687
172701
  };
172688
172702
  Iter.prototype.toFailure = function(grammar2) {
@@ -174519,9 +174533,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
174519
174533
  decl.withSuperGrammar(namespace[superGrammarName]);
174520
174534
  }
174521
174535
  },
174522
- Rule_define(n, fs68, d3, _2, b) {
174536
+ Rule_define(n, fs69, d3, _2, b) {
174523
174537
  currentRuleName = n.visit();
174524
- currentRuleFormals = fs68.children.map((c2) => c2.visit())[0] || [];
174538
+ currentRuleFormals = fs69.children.map((c2) => c2.visit())[0] || [];
174525
174539
  if (!decl.defaultStartRule && decl.ensureSuperGrammar() !== Grammar.ProtoBuiltInRules) {
174526
174540
  decl.withDefaultStartRule(currentRuleName);
174527
174541
  }
@@ -174530,9 +174544,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
174530
174544
  const source = this.source.trimmed();
174531
174545
  return decl.define(currentRuleName, currentRuleFormals, body, description, source);
174532
174546
  },
174533
- Rule_override(n, fs68, _2, b) {
174547
+ Rule_override(n, fs69, _2, b) {
174534
174548
  currentRuleName = n.visit();
174535
- currentRuleFormals = fs68.children.map((c2) => c2.visit())[0] || [];
174549
+ currentRuleFormals = fs69.children.map((c2) => c2.visit())[0] || [];
174536
174550
  const source = this.source.trimmed();
174537
174551
  decl.ensureSuperGrammarRuleForOverriding(currentRuleName, source);
174538
174552
  overriding = true;
@@ -174540,9 +174554,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
174540
174554
  overriding = false;
174541
174555
  return decl.override(currentRuleName, currentRuleFormals, body, null, source);
174542
174556
  },
174543
- Rule_extend(n, fs68, _2, b) {
174557
+ Rule_extend(n, fs69, _2, b) {
174544
174558
  currentRuleName = n.visit();
174545
- currentRuleFormals = fs68.children.map((c2) => c2.visit())[0] || [];
174559
+ currentRuleFormals = fs69.children.map((c2) => c2.visit())[0] || [];
174546
174560
  const body = b.visit();
174547
174561
  const source = this.source.trimmed();
174548
174562
  return decl.extend(currentRuleName, currentRuleFormals, body, null, source);
@@ -174569,8 +174583,8 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
174569
174583
  return builder.alt(...args).withSource(this.source);
174570
174584
  }
174571
174585
  },
174572
- Formals(opointy, fs68, cpointy) {
174573
- return fs68.visit();
174586
+ Formals(opointy, fs69, cpointy) {
174587
+ return fs69.visit();
174574
174588
  },
174575
174589
  Params(opointy, ps, cpointy) {
174576
174590
  return ps.visit();
@@ -174732,8 +174746,8 @@ function initPrototypeParser(grammar2) {
174732
174746
  formals: optFormals.children.map((c2) => c2.parse())[0] || []
174733
174747
  };
174734
174748
  },
174735
- Formals(oparen, fs68, cparen) {
174736
- return fs68.asIteration().children.map((c2) => c2.parse());
174749
+ Formals(oparen, fs69, cparen) {
174750
+ return fs69.asIteration().children.map((c2) => c2.parse());
174737
174751
  },
174738
174752
  name(first2, rest) {
174739
174753
  return this.sourceString;
@@ -178054,8 +178068,8 @@ function parseAndResolve(files) {
178054
178068
  const parsed = files.map((f2) => parseOne(f2.path, f2.source));
178055
178069
  return resolve10(parsed);
178056
178070
  }
178057
- function parseTcFile(path79, source) {
178058
- return parseOne(path79, source);
178071
+ function parseTcFile(path80, source) {
178072
+ return parseOne(path80, source);
178059
178073
  }
178060
178074
  var LineMap, OP_VALUES;
178061
178075
  var init_parser_ohm = __esm({
@@ -179444,13 +179458,13 @@ function extractStarletteRoutesFromFile(filePath, source, tree) {
179444
179458
  const identities = starletteIdentitiesForPath(rawPath);
179445
179459
  const line = node2.startPosition.row + 1;
179446
179460
  for (const method of methods) {
179447
- for (const path79 of identities) {
179461
+ for (const path80 of identities) {
179448
179462
  out.push({
179449
- identity: `${method} ${path79}`,
179463
+ identity: `${method} ${path80}`,
179450
179464
  contract: {
179451
179465
  protocol: "http",
179452
179466
  method,
179453
- path: path79,
179467
+ path: path80,
179454
179468
  responses: [],
179455
179469
  tags: []
179456
179470
  },
@@ -179627,14 +179641,14 @@ function parseRouteDecorator(dec, source, stringVars) {
179627
179641
  const args = call.childForFieldName("arguments");
179628
179642
  if (!args)
179629
179643
  return null;
179630
- let path79 = null;
179644
+ let path80 = null;
179631
179645
  let successStatus = "200";
179632
179646
  for (let i = 0; i < args.namedChildCount; i++) {
179633
179647
  const a = args.namedChild(i);
179634
179648
  if (!a)
179635
179649
  continue;
179636
- if (path79 === null && a.type === "string")
179637
- path79 = pyStr(a, source);
179650
+ if (path80 === null && a.type === "string")
179651
+ path80 = pyStr(a, source);
179638
179652
  else if (a.type === "keyword_argument") {
179639
179653
  const name = a.childForFieldName("name");
179640
179654
  const value = a.childForFieldName("value");
@@ -179643,17 +179657,17 @@ function parseRouteDecorator(dec, source, stringVars) {
179643
179657
  }
179644
179658
  }
179645
179659
  }
179646
- if (path79 === null) {
179660
+ if (path80 === null) {
179647
179661
  const firstArg = args.namedChild(0);
179648
179662
  if (firstArg?.type === "identifier") {
179649
179663
  const resolved = stringVars.get(source.slice(firstArg.startIndex, firstArg.endIndex));
179650
179664
  if (resolved !== void 0)
179651
- path79 = resolved;
179665
+ path80 = resolved;
179652
179666
  }
179653
179667
  }
179654
- if (path79 === null)
179668
+ if (path80 === null)
179655
179669
  return null;
179656
- return { method, path: path79, routerVar, successStatus };
179670
+ return { method, path: path80, routerVar, successStatus };
179657
179671
  }
179658
179672
  function extractResponses2(body, source, successStatus) {
179659
179673
  const byStatus = /* @__PURE__ */ new Map();
@@ -179786,9 +179800,9 @@ function looksLikeModel(p2, source) {
179786
179800
  const text4 = source.slice(type2.startIndex, type2.endIndex);
179787
179801
  return /^[A-Z]/.test(text4);
179788
179802
  }
179789
- function joinPath(prefix, path79) {
179803
+ function joinPath(prefix, path80) {
179790
179804
  const a = prefix.replace(/\/$/, "");
179791
- const b = path79.startsWith("/") ? path79 : `/${path79}`;
179805
+ const b = path80.startsWith("/") ? path80 : `/${path80}`;
179792
179806
  return a + b || "/";
179793
179807
  }
179794
179808
  function callName(call, source) {
@@ -196081,8 +196095,8 @@ async function runRulesReset({ ruleKey }) {
196081
196095
 
196082
196096
  // tools/cli/src/commands/contracts.ts
196083
196097
  init_dist4();
196084
- import fs65 from "node:fs";
196085
- import path72 from "node:path";
196098
+ import fs66 from "node:fs";
196099
+ import path73 from "node:path";
196086
196100
 
196087
196101
  // packages/spec-consolidator/dist/types.js
196088
196102
  init_zod();
@@ -197472,43 +197486,57 @@ function prefilterDocs(docs, manualIncludes = []) {
197472
197486
  if (reason)
197473
197487
  reasons.set(doc.path, reason);
197474
197488
  }
197475
- for (const { path: path79, reason } of dedupeNearDuplicates(docs.filter((d3) => !manualSet.has(d3.path) && !reasons.has(d3.path)))) {
197476
- reasons.set(path79, reason);
197489
+ for (const { path: path80, reason } of dedupeNearDuplicates(docs.filter((d3) => !manualSet.has(d3.path) && !reasons.has(d3.path)))) {
197490
+ reasons.set(path80, reason);
197477
197491
  }
197478
197492
  return {
197479
197493
  toClassify: docs.filter((d3) => !reasons.has(d3.path)),
197480
- skipped: [...reasons].map(([path79, reason]) => ({ path: path79, reason }))
197494
+ skipped: [...reasons].map(([path80, reason]) => ({ path: path80, reason }))
197481
197495
  };
197482
197496
  }
197497
+ async function planRelevanceWork(repoRoot5, docs, manualIncludes = []) {
197498
+ const manualSet = new Set(manualIncludes);
197499
+ const { toClassify, skipped } = prefilterDocs(docs, manualIncludes);
197500
+ const needsCall = [];
197501
+ const known = /* @__PURE__ */ new Map();
197502
+ await Promise.all(toClassify.map(async (doc) => {
197503
+ if (manualSet.has(doc.path)) {
197504
+ known.set(doc.path, { path: doc.path, include: true, reason: "manual include" });
197505
+ return;
197506
+ }
197507
+ const cached = await readCache4(repoRoot5, computeCacheKey5(doc));
197508
+ if (cached)
197509
+ known.set(doc.path, cached);
197510
+ else
197511
+ needsCall.push(doc);
197512
+ }));
197513
+ return { toClassify, prefilterSkipped: skipped, needsCall, known };
197514
+ }
197483
197515
  async function filterByRelevance(repoRoot5, docs, opts = {}) {
197484
197516
  if (opts.enabled === false || docs.length === 0) {
197485
197517
  return { included: docs, skipped: [] };
197486
197518
  }
197487
- const manualSet = new Set(opts.manualIncludes ?? []);
197488
197519
  const runner = opts.runner ?? spawnRelevanceRunner({ transport: opts.transport, model: opts.model, fallbackModel: opts.fallbackModel });
197489
197520
  const concurrency = opts.concurrency ?? defaultConcurrency();
197490
- const { toClassify, skipped: prefilterSkipped } = prefilterDocs(docs, opts.manualIncludes ?? []);
197491
- const prefilterReason = new Map(prefilterSkipped.map((s) => [s.path, s.reason]));
197521
+ const plan = await planRelevanceWork(repoRoot5, docs, opts.manualIncludes ?? []);
197522
+ const prefilterReason = new Map(plan.prefilterSkipped.map((s) => [s.path, s.reason]));
197492
197523
  const total = docs.length;
197493
197524
  let done = 0;
197494
197525
  const markDone = () => opts.onProgress?.(++done, total);
197495
197526
  opts.onProgress?.(0, total);
197496
- for (let i = 0; i < prefilterReason.size; i++)
197527
+ const resolvedUpfront = prefilterReason.size + plan.known.size;
197528
+ for (let i = 0; i < resolvedUpfront; i++)
197497
197529
  markDone();
197498
- const verdicts = /* @__PURE__ */ new Map();
197530
+ const verdicts = new Map(plan.known);
197531
+ const pending = plan.needsCall;
197499
197532
  let cursor = 0;
197500
197533
  let active11 = 0;
197501
197534
  await new Promise((resolve12) => {
197535
+ if (pending.length === 0)
197536
+ return resolve12();
197502
197537
  const launch = () => {
197503
- while (active11 < concurrency && cursor < toClassify.length) {
197504
- const doc = toClassify[cursor++];
197505
- if (manualSet.has(doc.path)) {
197506
- verdicts.set(doc.path, { path: doc.path, include: true, reason: "manual include" });
197507
- markDone();
197508
- if (cursor >= toClassify.length && active11 === 0)
197509
- resolve12();
197510
- continue;
197511
- }
197538
+ while (active11 < concurrency && cursor < pending.length) {
197539
+ const doc = pending[cursor++];
197512
197540
  active11++;
197513
197541
  classifyOne(repoRoot5, doc, runner).then((verdict) => {
197514
197542
  verdicts.set(doc.path, verdict);
@@ -197521,14 +197549,12 @@ async function filterByRelevance(repoRoot5, docs, opts = {}) {
197521
197549
  }).finally(() => {
197522
197550
  markDone();
197523
197551
  active11--;
197524
- if (cursor >= toClassify.length && active11 === 0)
197552
+ if (cursor >= pending.length && active11 === 0)
197525
197553
  resolve12();
197526
197554
  else
197527
197555
  launch();
197528
197556
  });
197529
197557
  }
197530
- if (cursor >= toClassify.length && active11 === 0)
197531
- resolve12();
197532
197558
  };
197533
197559
  launch();
197534
197560
  });
@@ -197725,9 +197751,6 @@ async function readCache4(scope, cacheKey) {
197725
197751
  async function writeCache4(scope, cacheKey, verdict) {
197726
197752
  await setCacheEntry(scope, CACHE_NAME5, cacheKey, verdict);
197727
197753
  }
197728
- async function readRelevanceCache(repoRoot5, doc) {
197729
- return readCache4(repoRoot5, computeCacheKey5(doc));
197730
- }
197731
197754
 
197732
197755
  // packages/spec-consolidator/dist/curate.js
197733
197756
  async function curate(repoRoot5, opts = {}) {
@@ -198034,8 +198057,8 @@ function canonicalIdentity(_kind, identity) {
198034
198057
  let id = identity.trim().replace(/\s+/g, " ");
198035
198058
  const op = HTTP_METHOD.exec(id);
198036
198059
  if (op) {
198037
- const path79 = op[2].replace(/\/+$/, "").replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, "{$1}");
198038
- id = `${op[1].toUpperCase()} ${path79}`;
198060
+ const path80 = op[2].replace(/\/+$/, "").replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, "{$1}");
198061
+ id = `${op[1].toUpperCase()} ${path80}`;
198039
198062
  }
198040
198063
  return id;
198041
198064
  }
@@ -201835,6 +201858,9 @@ var STAGE_DEFAULTS = {
201835
201858
  // Authoring an executable scenario faithful to a spec claim is the hard,
201836
201859
  // load-bearing call (a weak scenario is false confidence) — opus.
201837
201860
  "guard.generate": "opus",
201861
+ // The one evidence-retry per birth-failed claim — the same authoring task, so
201862
+ // the same tier; a distinct stage so retry spend is attributed to the birth line.
201863
+ "guard.retry": "opus",
201838
201864
  // Proposing a build/entry recipe is a modest structured task — sonnet.
201839
201865
  "guard.recipe": "sonnet",
201840
201866
  "rules.violationGen": "opus"
@@ -205044,6 +205070,10 @@ ${err.message}`;
205044
205070
  });
205045
205071
  }
205046
205072
 
205073
+ // packages/guard-runner/dist/preflight.js
205074
+ import fs51 from "node:fs";
205075
+ import path57 from "node:path";
205076
+
205047
205077
  // packages/guard-runner/dist/sandbox.js
205048
205078
  import fs50 from "node:fs";
205049
205079
  import os11 from "node:os";
@@ -205125,10 +205155,184 @@ function listSandboxFiles(dir) {
205125
205155
  return out.sort();
205126
205156
  }
205127
205157
 
205158
+ // packages/guard-runner/dist/executor.js
205159
+ import { spawn as spawn9 } from "node:child_process";
205160
+ var DEFAULT_STEP_TIMEOUT_MS = 3e4;
205161
+ function executeStep(opts) {
205162
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
205163
+ const [command, ...args] = opts.argv;
205164
+ const start = Date.now();
205165
+ return new Promise((resolve12) => {
205166
+ const child = spawn9(command, args, {
205167
+ cwd: opts.cwd,
205168
+ env: opts.env,
205169
+ stdio: ["pipe", "pipe", "pipe"]
205170
+ });
205171
+ let stdout = "";
205172
+ let stderr = "";
205173
+ let timedOut = false;
205174
+ let settled = false;
205175
+ const timer = setTimeout(() => {
205176
+ timedOut = true;
205177
+ child.kill("SIGKILL");
205178
+ }, timeoutMs);
205179
+ const finish = (capture) => {
205180
+ if (settled)
205181
+ return;
205182
+ settled = true;
205183
+ clearTimeout(timer);
205184
+ resolve12(capture);
205185
+ };
205186
+ child.stdout.on("data", (chunk3) => {
205187
+ stdout += chunk3.toString("utf-8");
205188
+ });
205189
+ child.stderr.on("data", (chunk3) => {
205190
+ stderr += chunk3.toString("utf-8");
205191
+ });
205192
+ child.on("error", (err) => {
205193
+ finish({
205194
+ exitCode: null,
205195
+ signal: null,
205196
+ stdout,
205197
+ stderr,
205198
+ timedOut,
205199
+ spawnError: err.message,
205200
+ durationMs: Date.now() - start
205201
+ });
205202
+ });
205203
+ child.on("close", (code, signal) => {
205204
+ finish({
205205
+ exitCode: code,
205206
+ signal,
205207
+ stdout,
205208
+ stderr,
205209
+ timedOut,
205210
+ durationMs: Date.now() - start
205211
+ });
205212
+ });
205213
+ if (opts.stdin !== void 0)
205214
+ child.stdin.write(opts.stdin);
205215
+ child.stdin.end();
205216
+ });
205217
+ }
205218
+
205219
+ // packages/guard-runner/dist/preflight.js
205220
+ var ENTRY_PROBE_ARGVS = [[], ["--help"]];
205221
+ var ENTRY_PREFLIGHT_TIMEOUT_MS = 2e4;
205222
+ var defaultEntryProbeExecutor = (fullArgv, world, timeoutMs) => executeStep({ argv: fullArgv, cwd: world.cwd, env: world.env, timeoutMs });
205223
+ async function preflightEntry(opts) {
205224
+ const exec3 = opts.exec ?? defaultEntryProbeExecutor;
205225
+ const timeoutMs = opts.timeoutMs ?? ENTRY_PREFLIGHT_TIMEOUT_MS;
205226
+ const entry = opts.displayEntry.join(" ");
205227
+ const sandbox = createSandbox({ recipeEnv: opts.recipeEnv });
205228
+ const probes = [];
205229
+ try {
205230
+ for (const argv of ENTRY_PROBE_ARGVS) {
205231
+ probes.push({
205232
+ argv: [...argv],
205233
+ capture: await exec3([...opts.resolvedEntry, ...argv], { cwd: sandbox.cwd, env: sandbox.env }, timeoutMs)
205234
+ });
205235
+ }
205236
+ } finally {
205237
+ sandbox.cleanup();
205238
+ }
205239
+ const ok = entryStarts(probes);
205240
+ return { ok, entry, stderr: ok ? "" : deadEntryOutput(opts, probes[0].capture, timeoutMs), probes };
205241
+ }
205242
+ function entryStarts(probes) {
205243
+ if (probes.some((p2) => startedCleanly(p2.capture)))
205244
+ return true;
205245
+ const shapes = probes.map((p2) => failureShape(p2.capture));
205246
+ return shapes.some((s) => s !== shapes[0]);
205247
+ }
205248
+ function startedCleanly(c2) {
205249
+ return !c2.spawnError && !c2.timedOut && c2.signal === null && c2.exitCode === 0;
205250
+ }
205251
+ function failureShape(c2) {
205252
+ return JSON.stringify({
205253
+ spawnError: c2.spawnError ?? null,
205254
+ signal: c2.signal ?? null,
205255
+ timedOut: c2.timedOut,
205256
+ exitCode: c2.exitCode,
205257
+ stdout: c2.stdout,
205258
+ stderr: c2.stderr
205259
+ });
205260
+ }
205261
+ function deadEntryOutput(opts, bare, timeoutMs) {
205262
+ const parts = [startupOutput(bare, timeoutMs)];
205263
+ if (opts.repoRoot) {
205264
+ const missing = missingEntryScript(opts.repoRoot, opts.displayEntry);
205265
+ if (missing)
205266
+ parts.push(formatMissingEntryScript(missing));
205267
+ }
205268
+ return parts.join("\n\n");
205269
+ }
205270
+ function startupOutput(c2, timeoutMs) {
205271
+ const parts = [];
205272
+ const primary = c2.stderr || c2.stdout;
205273
+ if (primary)
205274
+ parts.push(primary.trimEnd());
205275
+ if (c2.spawnError)
205276
+ parts.push(`failed to spawn: ${c2.spawnError}`);
205277
+ if (c2.timedOut)
205278
+ parts.push(`(the entry produced no output within ${timeoutMs}ms and was killed)`);
205279
+ if (parts.length === 0) {
205280
+ parts.push(c2.exitCode !== null ? `(the entry exited ${c2.exitCode} with no output)` : `(the entry was killed by ${c2.signal})`);
205281
+ }
205282
+ return parts.join("\n");
205283
+ }
205284
+ var MAX_SIBLINGS = 25;
205285
+ function missingEntryScript(repoRoot5, entry) {
205286
+ const [command, ...rest] = entry;
205287
+ const candidates = [];
205288
+ if (command && isPathLike(command))
205289
+ candidates.push(command);
205290
+ for (const arg of rest) {
205291
+ if (!arg.startsWith("-") && isPathLike(arg))
205292
+ candidates.push(arg);
205293
+ }
205294
+ for (const arg of candidates) {
205295
+ const resolved = path57.isAbsolute(arg) ? arg : path57.resolve(repoRoot5, arg);
205296
+ if (fs51.existsSync(resolved))
205297
+ continue;
205298
+ const parent = path57.dirname(resolved);
205299
+ const siblings = fs51.existsSync(parent) ? fs51.readdirSync(parent).sort() : null;
205300
+ return {
205301
+ arg,
205302
+ resolved,
205303
+ parentDir: path57.isAbsolute(arg) ? parent : path57.relative(repoRoot5, parent) || ".",
205304
+ siblings
205305
+ };
205306
+ }
205307
+ return null;
205308
+ }
205309
+ function formatMissingEntryScript(m) {
205310
+ const head = `entry file not found: ${m.arg} (resolved: ${m.resolved})`;
205311
+ if (m.siblings === null)
205312
+ return `${head}
205313
+ its directory ${m.parentDir}/ does not exist`;
205314
+ if (m.siblings.length === 0)
205315
+ return `${head}
205316
+ ${m.parentDir}/ is empty`;
205317
+ const shown = m.siblings.slice(0, MAX_SIBLINGS).join(", ");
205318
+ const more = m.siblings.length - MAX_SIBLINGS;
205319
+ return `${head}
205320
+ ${m.parentDir}/ contains: ${shown}${more > 0 ? ` \u2026 and ${more} more` : ""}`;
205321
+ }
205322
+ function isPathLike(arg) {
205323
+ return arg.includes("/") || arg.includes(path57.sep) || arg.startsWith(".");
205324
+ }
205325
+ function entryPreflightHeadline(entry, buildCommand) {
205326
+ return `The recipe entry \`${entry}\` failed to start \u2014 it crashes before it runs, so every scenario would fail identically. Rebuild it with \`${buildCommand}\` (its build output is likely stale or incomplete), then retry.`;
205327
+ }
205328
+ function formatEntryPreflightError(opts) {
205329
+ return [entryPreflightHeadline(opts.entry, opts.buildCommand), "", "Startup output:", opts.stderr].join("\n");
205330
+ }
205331
+
205128
205332
  // packages/guard-runner/dist/capabilities/git.js
205129
205333
  import { spawnSync as spawnSync2 } from "node:child_process";
205130
- import fs51 from "node:fs";
205131
- import path57 from "node:path";
205334
+ import fs52 from "node:fs";
205335
+ import path58 from "node:path";
205132
205336
  var GIT_IDENTITY = {
205133
205337
  GIT_AUTHOR_NAME: "TrueCourse Guard",
205134
205338
  GIT_AUTHOR_EMAIL: "guard@truecourse.dev",
@@ -205160,11 +205364,11 @@ function materializeGit(declaration, ctx) {
205160
205364
  }
205161
205365
  function requireFiles(files, ctx) {
205162
205366
  for (const rel of files) {
205163
- const target = path57.resolve(ctx.cwd, rel);
205164
- if (target !== ctx.cwd && !target.startsWith(ctx.cwd + path57.sep)) {
205367
+ const target = path58.resolve(ctx.cwd, rel);
205368
+ if (target !== ctx.cwd && !target.startsWith(ctx.cwd + path58.sep)) {
205165
205369
  throw new CapabilityError("git", `path escapes the sandbox: ${rel}`);
205166
205370
  }
205167
- if (!fs51.existsSync(target)) {
205371
+ if (!fs52.existsSync(target)) {
205168
205372
  throw new CapabilityError("git", `declared file does not exist in the sandbox: ${rel} (seed it via setup.files or an earlier commit)`);
205169
205373
  }
205170
205374
  }
@@ -205205,67 +205409,6 @@ function applyCapabilities(setup, ctx) {
205205
205409
  }
205206
205410
  }
205207
205411
 
205208
- // packages/guard-runner/dist/executor.js
205209
- import { spawn as spawn9 } from "node:child_process";
205210
- var DEFAULT_STEP_TIMEOUT_MS = 3e4;
205211
- function executeStep(opts) {
205212
- const timeoutMs = opts.timeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
205213
- const [command, ...args] = opts.argv;
205214
- const start = Date.now();
205215
- return new Promise((resolve12) => {
205216
- const child = spawn9(command, args, {
205217
- cwd: opts.cwd,
205218
- env: opts.env,
205219
- stdio: ["pipe", "pipe", "pipe"]
205220
- });
205221
- let stdout = "";
205222
- let stderr = "";
205223
- let timedOut = false;
205224
- let settled = false;
205225
- const timer = setTimeout(() => {
205226
- timedOut = true;
205227
- child.kill("SIGKILL");
205228
- }, timeoutMs);
205229
- const finish = (capture) => {
205230
- if (settled)
205231
- return;
205232
- settled = true;
205233
- clearTimeout(timer);
205234
- resolve12(capture);
205235
- };
205236
- child.stdout.on("data", (chunk3) => {
205237
- stdout += chunk3.toString("utf-8");
205238
- });
205239
- child.stderr.on("data", (chunk3) => {
205240
- stderr += chunk3.toString("utf-8");
205241
- });
205242
- child.on("error", (err) => {
205243
- finish({
205244
- exitCode: null,
205245
- signal: null,
205246
- stdout,
205247
- stderr,
205248
- timedOut,
205249
- spawnError: err.message,
205250
- durationMs: Date.now() - start
205251
- });
205252
- });
205253
- child.on("close", (code, signal) => {
205254
- finish({
205255
- exitCode: code,
205256
- signal,
205257
- stdout,
205258
- stderr,
205259
- timedOut,
205260
- durationMs: Date.now() - start
205261
- });
205262
- });
205263
- if (opts.stdin !== void 0)
205264
- child.stdin.write(opts.stdin);
205265
- child.stdin.end();
205266
- });
205267
- }
205268
-
205269
205412
  // packages/guard-runner/dist/normalizers.js
205270
205413
  var CANONICAL_ORDER = [
205271
205414
  "abs-paths",
@@ -205313,8 +205456,8 @@ function normalize7(text4, normalizers, ctx) {
205313
205456
  }
205314
205457
 
205315
205458
  // packages/guard-runner/dist/expect.js
205316
- import fs52 from "node:fs";
205317
- import path58 from "node:path";
205459
+ import fs53 from "node:fs";
205460
+ import path59 from "node:path";
205318
205461
  function evaluateExpect(params) {
205319
205462
  const { expect } = params;
205320
205463
  if (expect.exit !== void 0 && params.exitCode !== expect.exit) {
@@ -205385,8 +205528,8 @@ function matchStream(subject, matcher, value) {
205385
205528
  };
205386
205529
  }
205387
205530
  function matchFile3(rel, matcher, sandboxCwd, normalizeText) {
205388
- const target = path58.resolve(sandboxCwd, rel);
205389
- const exists2 = fs52.existsSync(target) && fs52.statSync(target).isFile();
205531
+ const target = path59.resolve(sandboxCwd, rel);
205532
+ const exists2 = fs53.existsSync(target) && fs53.statSync(target).isFile();
205390
205533
  if (matcher.exists === true || matcher.absent === false) {
205391
205534
  if (!exists2)
205392
205535
  return fileMiss(rel, "to exist", "missing");
@@ -205398,7 +205541,7 @@ function matchFile3(rel, matcher, sandboxCwd, normalizeText) {
205398
205541
  if (matcher.equals !== void 0 || matcher.contains !== void 0) {
205399
205542
  if (!exists2)
205400
205543
  return fileMiss(rel, "to exist for a content check", "missing");
205401
- const content = normalizeText(fs52.readFileSync(target, "utf-8"));
205544
+ const content = normalizeText(fs53.readFileSync(target, "utf-8"));
205402
205545
  if (matcher.equals !== void 0 && content !== matcher.equals) {
205403
205546
  return {
205404
205547
  subject: "files",
@@ -205428,11 +205571,11 @@ function fileMiss(rel, expectedPhrase, actualState) {
205428
205571
  }
205429
205572
 
205430
205573
  // packages/guard-runner/dist/evidence.js
205431
- import fs53 from "node:fs";
205432
- import path59 from "node:path";
205574
+ import fs54 from "node:fs";
205575
+ import path60 from "node:path";
205433
205576
  function writeEvidence(params) {
205434
205577
  const dir = evidenceScenarioDir(params.repoRoot, params.runId, params.scenarioId);
205435
- fs53.mkdirSync(dir, { recursive: true });
205578
+ fs54.mkdirSync(dir, { recursive: true });
205436
205579
  const failing = params.steps.find((s) => s.index === params.failingStep);
205437
205580
  const invocation = {
205438
205581
  scenarioId: params.scenarioId,
@@ -205511,7 +205654,7 @@ function indent(text4) {
205511
205654
  return body.split("\n").map((l) => ` ${l}`).join("\n");
205512
205655
  }
205513
205656
  function writeFile(dir, name, content) {
205514
- fs53.writeFileSync(path59.join(dir, name), content);
205657
+ fs54.writeFileSync(path60.join(dir, name), content);
205515
205658
  }
205516
205659
 
205517
205660
  // packages/guard-runner/dist/run-scenario.js
@@ -205660,15 +205803,15 @@ function toRecord(index, argv, stdin, repeat3, iterationsRun, capture, normText)
205660
205803
 
205661
205804
  // packages/guard-runner/dist/doc-index.js
205662
205805
  init_zod();
205663
- import fs54 from "node:fs";
205664
- import path61 from "node:path";
205806
+ import fs55 from "node:fs";
205807
+ import path62 from "node:path";
205665
205808
 
205666
205809
  // packages/guard-runner/dist/section-index.js
205667
- import path60 from "node:path";
205810
+ import path61 from "node:path";
205668
205811
  import crypto4 from "node:crypto";
205669
205812
  var MARKDOWN_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".markdown", ".mdown", ".mkd"]);
205670
205813
  function isMarkdownDoc(docPath) {
205671
- return MARKDOWN_EXTENSIONS.has(path60.extname(docPath).toLowerCase());
205814
+ return MARKDOWN_EXTENSIONS.has(path61.extname(docPath).toLowerCase());
205672
205815
  }
205673
205816
  function slugifyHeading(text4) {
205674
205817
  return text4.replace(/[`*_~]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -205721,7 +205864,7 @@ function sectionEndLine(headings, index, totalLines) {
205721
205864
  }
205722
205865
  function deriveSections(doc, content) {
205723
205866
  if (!isMarkdownDoc(doc)) {
205724
- const base2 = path60.basename(doc);
205867
+ const base2 = path61.basename(doc);
205725
205868
  return [
205726
205869
  {
205727
205870
  anchor: slugifyHeading(base2) || "document",
@@ -205822,11 +205965,11 @@ function resolveBinding(index, anchor, fingerprint2) {
205822
205965
  // packages/guard-runner/dist/doc-index.js
205823
205966
  var CorpusShape = external_exports.object({ docs: external_exports.array(external_exports.object({ ref: external_exports.string() }).passthrough()).optional() }).passthrough();
205824
205967
  function corpusKeptDocs(repoRoot5) {
205825
- const file = path61.join(repoRoot5, ".truecourse", "specs", "corpus.json");
205826
- if (!fs54.existsSync(file))
205968
+ const file = path62.join(repoRoot5, ".truecourse", "specs", "corpus.json");
205969
+ if (!fs55.existsSync(file))
205827
205970
  return [];
205828
205971
  try {
205829
- const parsed = CorpusShape.safeParse(JSON.parse(fs54.readFileSync(file, "utf-8")));
205972
+ const parsed = CorpusShape.safeParse(JSON.parse(fs55.readFileSync(file, "utf-8")));
205830
205973
  if (!parsed.success)
205831
205974
  return [];
205832
205975
  return (parsed.data.docs ?? []).map((d3) => d3.ref);
@@ -205841,25 +205984,25 @@ function indexRepoDocs(repoRoot5, boundDocs) {
205841
205984
  const indexes = /* @__PURE__ */ new Map();
205842
205985
  const missing = /* @__PURE__ */ new Set();
205843
205986
  for (const doc of wanted) {
205844
- const abs = path61.resolve(repoRoot5, doc);
205845
- if (!fs54.existsSync(abs) || !fs54.statSync(abs).isFile()) {
205987
+ const abs = path62.resolve(repoRoot5, doc);
205988
+ if (!fs55.existsSync(abs) || !fs55.statSync(abs).isFile()) {
205846
205989
  missing.add(doc);
205847
205990
  continue;
205848
205991
  }
205849
- indexes.set(doc, buildDocSectionIndex(doc, fs54.readFileSync(abs, "utf-8")));
205992
+ indexes.set(doc, buildDocSectionIndex(doc, fs55.readFileSync(abs, "utf-8")));
205850
205993
  }
205851
205994
  return { indexes, missing };
205852
205995
  }
205853
205996
 
205854
205997
  // packages/guard-runner/dist/manifest.js
205855
205998
  init_dist5();
205856
- import fs55 from "node:fs";
205999
+ import fs56 from "node:fs";
205857
206000
  function readManifest2(repoRoot5) {
205858
206001
  const file = manifestPath2(repoRoot5);
205859
- if (!fs55.existsSync(file))
206002
+ if (!fs56.existsSync(file))
205860
206003
  return null;
205861
206004
  try {
205862
- const parsed = GuardManifestSchema.safeParse(JSON.parse(fs55.readFileSync(file, "utf-8")));
206005
+ const parsed = GuardManifestSchema.safeParse(JSON.parse(fs56.readFileSync(file, "utf-8")));
205863
206006
  return parsed.success ? parsed.data : null;
205864
206007
  } catch {
205865
206008
  return null;
@@ -205896,16 +206039,28 @@ async function runGuard(opts) {
205896
206039
  }));
205897
206040
  const executable = planned.filter((p2) => p2.resolution.kind === "match" || p2.resolution.kind === "remap");
205898
206041
  const nonExecutable = planned.filter((p2) => p2.resolution.kind === "stale" || p2.resolution.kind === "orphaned");
205899
- if (!opts.skipBuild && executable.length > 0) {
206042
+ const buildsOwnEntry = !opts.skipBuild && executable.length > 0;
206043
+ if (buildsOwnEntry) {
205900
206044
  opts.onPhase?.("build");
205901
206045
  const build8 = await runBuild(repoRoot5, loaded.recipe.build, loaded.recipe.env);
205902
206046
  if (!build8.ok)
205903
206047
  return { status: "build-failed", build: build8, loadErrors };
205904
206048
  }
206049
+ const resolvedEntry = resolveEntry(repoRoot5, loaded.recipe.entry);
206050
+ if (buildsOwnEntry) {
206051
+ const preflight = await preflightEntry({
206052
+ resolvedEntry,
206053
+ displayEntry: loaded.recipe.entry,
206054
+ recipeEnv: loaded.recipe.env,
206055
+ repoRoot: repoRoot5
206056
+ });
206057
+ if (!preflight.ok) {
206058
+ return { status: "entry-preflight-failed", preflight, buildCommand: loaded.recipe.build, loadErrors };
206059
+ }
206060
+ }
205905
206061
  opts.onPhase?.("run", selected.length);
205906
206062
  const runId = buildRunId();
205907
206063
  const ranAt = (/* @__PURE__ */ new Date()).toISOString();
205908
- const resolvedEntry = resolveEntry(repoRoot5, loaded.recipe.entry);
205909
206064
  const stepTimeoutMs = opts.stepTimeoutMs ?? DEFAULT_STEP_TIMEOUT_MS;
205910
206065
  const concurrency = opts.concurrency ?? defaultRunConcurrency();
205911
206066
  const results = [];
@@ -206024,8 +206179,8 @@ init_dist5();
206024
206179
 
206025
206180
  // packages/guard-generator/dist/section-plan.js
206026
206181
  init_zod();
206027
- import fs56 from "node:fs";
206028
- import path62 from "node:path";
206182
+ import fs57 from "node:fs";
206183
+ import path63 from "node:path";
206029
206184
  import { createHash as createHash15 } from "node:crypto";
206030
206185
  init_dist5();
206031
206186
 
@@ -206340,12 +206495,12 @@ var CorpusShape2 = external_exports.object({
206340
206495
  docs: external_exports.array(external_exports.object({ ref: external_exports.string(), areaTags: external_exports.array(external_exports.string()).optional() }).passthrough()).optional()
206341
206496
  }).passthrough();
206342
206497
  function readCorpusAreaTags(repoRoot5) {
206343
- const file = path62.join(repoRoot5, ".truecourse", "specs", "corpus.json");
206498
+ const file = path63.join(repoRoot5, ".truecourse", "specs", "corpus.json");
206344
206499
  const map2 = /* @__PURE__ */ new Map();
206345
- if (!fs56.existsSync(file))
206500
+ if (!fs57.existsSync(file))
206346
206501
  return map2;
206347
206502
  try {
206348
- const parsed = CorpusShape2.safeParse(JSON.parse(fs56.readFileSync(file, "utf-8")));
206503
+ const parsed = CorpusShape2.safeParse(JSON.parse(fs57.readFileSync(file, "utf-8")));
206349
206504
  if (!parsed.success)
206350
206505
  return map2;
206351
206506
  for (const d3 of parsed.data.docs ?? [])
@@ -206364,17 +206519,17 @@ function generationInputsHash(fingerprint2, recipeFingerprint) {
206364
206519
  ].join("\0")).digest("hex");
206365
206520
  }
206366
206521
  function hasGuardUniverse(repoRoot5) {
206367
- return fs56.existsSync(path62.join(repoRoot5, ".truecourse", "specs", "corpus.json"));
206522
+ return fs57.existsSync(path63.join(repoRoot5, ".truecourse", "specs", "corpus.json"));
206368
206523
  }
206369
206524
  function planGuardWork(repoRoot5, recipeFingerprint) {
206370
206525
  const recipeFp = recipeFingerprint ?? computeRecipeFingerprint(repoRoot5);
206371
- const recipeMissing = !fs56.existsSync(recipePath(repoRoot5));
206526
+ const recipeMissing = !fs57.existsSync(recipePath(repoRoot5));
206372
206527
  const hasUniverse = hasGuardUniverse(repoRoot5);
206373
206528
  const { indexes } = indexRepoDocs(repoRoot5, []);
206374
206529
  const areaTags = readCorpusAreaTags(repoRoot5);
206375
206530
  const sections = [];
206376
206531
  for (const [doc, index] of indexes) {
206377
- const texts = extractSectionTexts(doc, fs56.readFileSync(path62.resolve(repoRoot5, doc), "utf-8"));
206532
+ const texts = extractSectionTexts(doc, fs57.readFileSync(path63.resolve(repoRoot5, doc), "utf-8"));
206378
206533
  for (const s of index.sections) {
206379
206534
  const t2 = texts.get(s.anchor);
206380
206535
  sections.push({
@@ -206419,7 +206574,7 @@ function collectWorkDocs(repoRoot5, plan) {
206419
206574
  }
206420
206575
  return [...byDoc].map(([doc, sections]) => ({
206421
206576
  doc,
206422
- content: fs56.readFileSync(path62.resolve(repoRoot5, doc), "utf-8"),
206577
+ content: fs57.readFileSync(path63.resolve(repoRoot5, doc), "utf-8"),
206423
206578
  sections
206424
206579
  }));
206425
206580
  }
@@ -206450,11 +206605,11 @@ function spawnGenerateRunner2(opts = {}) {
206450
206605
  return async (ctx) => {
206451
206606
  const refs = ctx.claims.map((c2) => c2.ref).join(",");
206452
206607
  const isRetry = ctx.claims.some((c2) => c2.retry);
206453
- const suffix = `${isRetry ? ":retry" : ""}${ctx.correction ? ":correction" : ""}`;
206608
+ const stage = isRetry ? "guard.retry" : "guard.generate";
206454
206609
  const raw = await transport({
206455
- id: `guard.generate:${ctx.doc}:${refs}${suffix}`,
206456
- stage: "guard.generate",
206457
- model: opts.model,
206610
+ id: `${stage}:${ctx.doc}:${refs}${ctx.correction ? ":correction" : ""}`,
206611
+ stage,
206612
+ model: isRetry ? opts.retryModel ?? opts.model : opts.model,
206458
206613
  fallbackModel: opts.fallbackModel,
206459
206614
  system: GENERATE_SYSTEM_PROMPT,
206460
206615
  user: buildAuthorUserPrompt(ctx),
@@ -206667,7 +206822,7 @@ function snap(raw, sections) {
206667
206822
 
206668
206823
  // packages/guard-generator/dist/ground.js
206669
206824
  init_zod();
206670
- import path63 from "node:path";
206825
+ import path64 from "node:path";
206671
206826
  import { createHash as createHash17 } from "node:crypto";
206672
206827
  var GROUND_CACHE_NAME = "guard/ground";
206673
206828
  var PROBE_TIMEOUT_MS = 2e4;
@@ -206723,7 +206878,7 @@ function toProbeArgv(fragment, programNames) {
206723
206878
  const tokens = fragment.trim().split(/\s+/).filter(Boolean);
206724
206879
  if (tokens.length === 0)
206725
206880
  return null;
206726
- if (programNames.has(tokens[0]) || programNames.has(path63.basename(tokens[0])))
206881
+ if (programNames.has(tokens[0]) || programNames.has(path64.basename(tokens[0])))
206727
206882
  tokens.shift();
206728
206883
  if (tokens.length === 0)
206729
206884
  return [];
@@ -206744,7 +206899,7 @@ function programNamesOf(entry) {
206744
206899
  return names;
206745
206900
  }
206746
206901
  function addName(set2, arg) {
206747
- const base2 = path63.basename(arg);
206902
+ const base2 = path64.basename(arg);
206748
206903
  if (base2)
206749
206904
  set2.add(base2);
206750
206905
  const stem = base2.replace(/\.[^.]+$/, "");
@@ -206766,12 +206921,15 @@ async function captureProbes(opts) {
206766
206921
  const cached = await getCacheEntry(opts.repoRoot, GROUND_CACHE_NAME, key4);
206767
206922
  if (cached) {
206768
206923
  const parsed = ProbeTranscriptSchema.safeParse(cached);
206769
- if (parsed.success)
206924
+ if (parsed.success) {
206925
+ opts.onProbeCaptured?.();
206770
206926
  return parsed.data;
206927
+ }
206771
206928
  }
206772
206929
  const capture = await exec3([...opts.resolvedEntry, ...argv], opts.recipeEnv);
206773
206930
  const transcript = toTranscript(argv, [...opts.displayEntry, ...argv], capture);
206774
206931
  await setCacheEntry(opts.repoRoot, GROUND_CACHE_NAME, key4, transcript);
206932
+ opts.onProbeCaptured?.();
206775
206933
  return transcript;
206776
206934
  }));
206777
206935
  }
@@ -206803,9 +206961,9 @@ function truncate3(text4) {
206803
206961
  }
206804
206962
 
206805
206963
  // packages/guard-generator/dist/recipe-discovery.js
206806
- import fs57 from "node:fs";
206964
+ import fs58 from "node:fs";
206807
206965
  import os13 from "node:os";
206808
- import path64 from "node:path";
206966
+ import path65 from "node:path";
206809
206967
  import { createHash as createHash18 } from "node:crypto";
206810
206968
  var RECIPE_CACHE_NAME = "guard/recipe";
206811
206969
  var DISCOVERY_INPUTS = ["package.json", "pnpm-lock.yaml", "package-lock.json", "yarn.lock", "turbo.json"];
@@ -206842,6 +207000,14 @@ async function discoverRecipe(repoRoot5, runner) {
206842
207000
  proposal
206843
207001
  };
206844
207002
  }
207003
+ const missing = missingEntryScript(repoRoot5, proposal.entry);
207004
+ if (missing) {
207005
+ return {
207006
+ status: "verify-failed",
207007
+ reason: `after \`${proposal.build}\`, ${formatMissingEntryScript(missing)}`,
207008
+ proposal
207009
+ };
207010
+ }
206845
207011
  const probe = await probeEntry(repoRoot5, proposal.entry);
206846
207012
  if (!probe.ok)
206847
207013
  return { status: "verify-failed", reason: probe.reason, proposal };
@@ -206851,13 +207017,13 @@ async function discoverRecipe(repoRoot5, runner) {
206851
207017
  ...proposal.env ? { env: proposal.env } : {}
206852
207018
  };
206853
207019
  const target = recipePath(repoRoot5);
206854
- fs57.mkdirSync(path64.dirname(target), { recursive: true });
206855
- fs57.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
207020
+ fs58.mkdirSync(path65.dirname(target), { recursive: true });
207021
+ fs58.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
206856
207022
  return {
206857
207023
  status: "discovered",
206858
207024
  recipe,
206859
207025
  fingerprint: computeRecipeFingerprint(repoRoot5),
206860
- wrotePath: path64.relative(repoRoot5, target)
207026
+ wrotePath: path65.relative(repoRoot5, target)
206861
207027
  };
206862
207028
  }
206863
207029
  async function proposeRecipeWithReask(input, runner) {
@@ -206882,14 +207048,14 @@ async function proposeRecipeWithReask(input, runner) {
206882
207048
  return { error: `recipe proposal invalid after re-ask: ${flattenZodError(reParsed.error)}` };
206883
207049
  }
206884
207050
  function readDiscoveryInputs(repoRoot5) {
206885
- const pkgPath = path64.join(repoRoot5, "package.json");
206886
- const packageJson = fs57.existsSync(pkgPath) ? fs57.readFileSync(pkgPath, "utf-8") : "(no package.json)";
206887
- const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs57.existsSync(path64.join(repoRoot5, f2)));
207051
+ const pkgPath = path65.join(repoRoot5, "package.json");
207052
+ const packageJson = fs58.existsSync(pkgPath) ? fs58.readFileSync(pkgPath, "utf-8") : "(no package.json)";
207053
+ const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs58.existsSync(path65.join(repoRoot5, f2)));
206888
207054
  return { packageJson, presentInputs };
206889
207055
  }
206890
207056
  async function probeEntry(repoRoot5, entry) {
206891
207057
  const resolved = resolveEntry(repoRoot5, entry);
206892
- const cwd = fs57.mkdtempSync(path64.join(os13.tmpdir(), "tc-guard-probe-"));
207058
+ const cwd = fs58.mkdtempSync(path65.join(os13.tmpdir(), "tc-guard-probe-"));
206893
207059
  try {
206894
207060
  for (const args of [["--help"], []]) {
206895
207061
  const capture = await executeStep({
@@ -206906,7 +207072,7 @@ async function probeEntry(repoRoot5, entry) {
206906
207072
  reason: `entrypoint ${JSON.stringify(entry)} did not answer to \`--help\` or a bare invocation`
206907
207073
  };
206908
207074
  } finally {
206909
- fs57.rmSync(cwd, { recursive: true, force: true });
207075
+ fs58.rmSync(cwd, { recursive: true, force: true });
206910
207076
  }
206911
207077
  }
206912
207078
 
@@ -206953,8 +207119,8 @@ async function birthValidate(repoRoot5, candidates, opts = {}) {
206953
207119
  }
206954
207120
 
206955
207121
  // packages/guard-generator/dist/serialize.js
206956
- import fs58 from "node:fs";
206957
- import path65 from "node:path";
207122
+ import fs59 from "node:fs";
207123
+ import path66 from "node:path";
206958
207124
  init_dist5();
206959
207125
  function anchorLeaf(anchor) {
206960
207126
  const segs = anchor.split("/").filter(Boolean);
@@ -206973,7 +207139,7 @@ function assignScenarioId(anchor, used) {
206973
207139
  function areaOrDocSlug(section) {
206974
207140
  if (section.areaTags.length > 0)
206975
207141
  return slugifyHeading(section.areaTags[0]) || "area";
206976
- const base2 = path65.basename(section.doc).replace(/\.[^.]+$/, "");
207142
+ const base2 = path66.basename(section.doc).replace(/\.[^.]+$/, "");
206977
207143
  return slugifyHeading(base2) || "doc";
206978
207144
  }
206979
207145
  function buildScenario(section, raw, id) {
@@ -206996,15 +207162,15 @@ function scenarioFileIndex(repoRoot5) {
206996
207162
  const root2 = scenariosDir(repoRoot5);
206997
207163
  const map2 = /* @__PURE__ */ new Map();
206998
207164
  const walk20 = (dir) => {
206999
- if (!fs58.existsSync(dir))
207165
+ if (!fs59.existsSync(dir))
207000
207166
  return;
207001
- for (const entry of fs58.readdirSync(dir, { withFileTypes: true })) {
207002
- const full = path65.join(dir, entry.name);
207167
+ for (const entry of fs59.readdirSync(dir, { withFileTypes: true })) {
207168
+ const full = path66.join(dir, entry.name);
207003
207169
  if (entry.isDirectory())
207004
207170
  walk20(full);
207005
207171
  else if (entry.isFile() && /\.ya?ml$/i.test(entry.name)) {
207006
207172
  try {
207007
- const doc = jsYaml.load(fs58.readFileSync(full, "utf-8"));
207173
+ const doc = jsYaml.load(fs59.readFileSync(full, "utf-8"));
207008
207174
  if (doc && typeof doc.id === "string")
207009
207175
  map2.set(doc.id, full);
207010
207176
  } catch {
@@ -207019,23 +207185,24 @@ function existingScenarioIds(repoRoot5) {
207019
207185
  return new Set(loadScenarios(repoRoot5).scenarios.map((s) => s.id));
207020
207186
  }
207021
207187
  function writeScenarioFile(repoRoot5, slug2, scenario) {
207022
- const dir = path65.join(scenariosDir(repoRoot5), slug2);
207023
- fs58.mkdirSync(dir, { recursive: true });
207024
- const file = path65.join(dir, `${scenario.id}.yaml`);
207025
- fs58.writeFileSync(file, jsYaml.dump(scenario, { lineWidth: -1, noRefs: true }));
207026
- return path65.relative(repoRoot5, file);
207188
+ const dir = path66.join(scenariosDir(repoRoot5), slug2);
207189
+ fs59.mkdirSync(dir, { recursive: true });
207190
+ const file = path66.join(dir, `${scenario.id}.yaml`);
207191
+ fs59.writeFileSync(file, jsYaml.dump(scenario, { lineWidth: -1, noRefs: true }));
207192
+ return path66.relative(repoRoot5, file);
207027
207193
  }
207028
207194
  function deleteScenarioFiles(repoRoot5, ids) {
207029
207195
  const index = scenarioFileIndex(repoRoot5);
207030
207196
  for (const id of ids) {
207031
207197
  const file = index.get(id);
207032
- if (file && fs58.existsSync(file))
207033
- fs58.rmSync(file);
207198
+ if (file && fs59.existsSync(file))
207199
+ fs59.rmSync(file);
207034
207200
  }
207035
207201
  }
207036
207202
 
207037
207203
  // packages/guard-generator/dist/generate.js
207038
207204
  var GENERATE_CACHE_NAME = "guard/generate";
207205
+ var ENTRY_PREFLIGHT_ANCHOR = "(entry preflight)";
207039
207206
  function defaultConcurrency3() {
207040
207207
  const env = process.env.TRUECOURSE_MAX_CONCURRENCY;
207041
207208
  if (env) {
@@ -207105,7 +207272,12 @@ async function generateGuards(options) {
207105
207272
  const limit = pLimit(Math.max(1, options.concurrency ?? defaultConcurrency3()));
207106
207273
  const batchSize = Math.max(1, options.batchSize ?? defaultGenerateBatch2());
207107
207274
  const extractRunner = options.extractRunner ?? spawnExtractRunner({ transport: options.transport, model: options.models?.extract, fallbackModel: options.models?.fallback });
207108
- const generateRunner = options.generateRunner ?? spawnGenerateRunner2({ transport: options.transport, model: options.models?.generate, fallbackModel: options.models?.fallback });
207275
+ const generateRunner = options.generateRunner ?? spawnGenerateRunner2({
207276
+ transport: options.transport,
207277
+ model: options.models?.generate,
207278
+ retryModel: options.models?.retry,
207279
+ fallbackModel: options.models?.fallback
207280
+ });
207109
207281
  const coverageGaps = [];
207110
207282
  const errors = [];
207111
207283
  const extractionFailures = [];
@@ -207176,11 +207348,15 @@ async function generateGuards(options) {
207176
207348
  return buildPromise;
207177
207349
  };
207178
207350
  let resolvedEntryMemo = null;
207351
+ let groundPlanned = 0;
207352
+ let groundCaptured = 0;
207179
207353
  const groundClaims = async (claimTexts) => {
207180
207354
  const probes = deriveProbes(claimTexts, recipe.entry);
207181
207355
  const build8 = await buildPromise;
207182
- if (!build8.ok)
207356
+ if (!build8.ok || probes.length === 0)
207183
207357
  return [];
207358
+ groundPlanned += probes.length;
207359
+ options.onGroundProgress?.(groundCaptured, groundPlanned);
207184
207360
  resolvedEntryMemo ??= resolveEntry(repoRoot5, recipe.entry);
207185
207361
  return captureProbes({
207186
207362
  repoRoot: repoRoot5,
@@ -207188,9 +207364,21 @@ async function generateGuards(options) {
207188
207364
  resolvedEntry: resolvedEntryMemo,
207189
207365
  displayEntry: recipe.entry,
207190
207366
  recipeFingerprint,
207191
- recipeEnv: recipe.env
207367
+ recipeEnv: recipe.env,
207368
+ onProbeCaptured: () => options.onGroundProgress?.(++groundCaptured, groundPlanned)
207192
207369
  });
207193
207370
  };
207371
+ let entryPreflightMemo = null;
207372
+ const preflightEntryOnce = () => {
207373
+ entryPreflightMemo ??= (async () => {
207374
+ const build8 = await buildPromise;
207375
+ if (!build8.ok)
207376
+ return null;
207377
+ resolvedEntryMemo ??= resolveEntry(repoRoot5, recipe.entry);
207378
+ return preflightEntry({ resolvedEntry: resolvedEntryMemo, displayEntry: recipe.entry, recipeEnv: recipe.env, repoRoot: repoRoot5 });
207379
+ })();
207380
+ return entryPreflightMemo;
207381
+ };
207194
207382
  const priorSections = readPriorManifest(repoRoot5);
207195
207383
  const manifestByKey = new Map(priorSections.map((e) => [`${e.doc}\0${e.anchor}`, e]));
207196
207384
  const usedIds = existingScenarioIds(repoRoot5);
@@ -207214,9 +207402,11 @@ async function generateGuards(options) {
207214
207402
  });
207215
207403
  settledKeys.add(k);
207216
207404
  writeWorkingManifest();
207405
+ options.onSectionSettled?.(settledKeys.size, plan.work.length);
207217
207406
  };
207218
207407
  const written = [];
207219
207408
  const birthFindings = [];
207409
+ let entryPreflightFailure = null;
207220
207410
  let birthTotal = 0;
207221
207411
  let birthSettled = 0;
207222
207412
  let birthPassed = 0;
@@ -207263,6 +207453,20 @@ async function generateGuards(options) {
207263
207453
  return;
207264
207454
  settleChain = settleChain.then(() => settleCliSection(sectionByKey.get(k), refsBySection.get(k)));
207265
207455
  };
207456
+ const deadEntry = async () => {
207457
+ const preflight = await preflightEntryOnce();
207458
+ if (!preflight || preflight.ok)
207459
+ return false;
207460
+ if (!entryPreflightFailure) {
207461
+ entryPreflightFailure = { entry: preflight.entry, buildCommand: recipe.build, stderr: preflight.stderr };
207462
+ errors.push({
207463
+ doc: preflight.entry,
207464
+ anchor: ENTRY_PREFLIGHT_ANCHOR,
207465
+ message: formatEntryPreflightError(entryPreflightFailure)
207466
+ });
207467
+ }
207468
+ return true;
207469
+ };
207266
207470
  async function settleCliSection(section, refs) {
207267
207471
  const k = key2(section);
207268
207472
  for (const id of priorIdsOf(k))
@@ -207297,6 +207501,8 @@ async function generateGuards(options) {
207297
207501
  const message = `build failed (\`${build8.command}\`)${build8.timedOut ? " \u2014 timed out" : ""}`;
207298
207502
  for (const c2 of round1)
207299
207503
  localErrors.push(errorFrom({ candidate: c2, result: { failure: { actual: message } } }));
207504
+ } else if (await deadEntry()) {
207505
+ return;
207300
207506
  } else {
207301
207507
  birthTotal += round1.length;
207302
207508
  const r1 = await birthValidate(repoRoot5, round1, { skipBuild: true, onPhase: options.onBirthPhase, onScenarioSettled: bumpBirth });
@@ -207373,6 +207579,8 @@ async function generateGuards(options) {
207373
207579
  const authorTotal = authTasks.length;
207374
207580
  let authorDone = 0;
207375
207581
  const bumpAuthor = (n) => options.onAuthorProgress?.(authorDone += n, authorTotal);
207582
+ if (authorTotal > 0)
207583
+ options.onAuthorProgress?.(authorDone, authorTotal);
207376
207584
  const missTasks = [];
207377
207585
  for (const t2 of authTasks) {
207378
207586
  const cached = await readAuthorCache(repoRoot5, t2.claim, t2.section, recipeFingerprint);
@@ -207444,7 +207652,8 @@ async function generateGuards(options) {
207444
207652
  extractionFailures,
207445
207653
  orphaned,
207446
207654
  birthPassed,
207447
- manifestPath: manifestPath2(repoRoot5)
207655
+ manifestPath: manifestPath2(repoRoot5),
207656
+ ...entryPreflightFailure ? { entryPreflight: entryPreflightFailure } : {}
207448
207657
  };
207449
207658
  }
207450
207659
  var key2 = (s) => `${s.doc}\0${s.anchor}`;
@@ -207649,8 +207858,8 @@ init_context_router();
207649
207858
 
207650
207859
  // packages/core/dist/services/llm/model-prices.js
207651
207860
  init_paths();
207652
- import fs59 from "node:fs";
207653
- import path66 from "node:path";
207861
+ import fs60 from "node:fs";
207862
+ import path67 from "node:path";
207654
207863
  var OPENROUTER_URL = "https://openrouter.ai/api/v1/models";
207655
207864
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
207656
207865
  var FETCH_TIMEOUT_MS = 8e3;
@@ -207666,11 +207875,11 @@ function tierOf(id) {
207666
207875
  return s.includes("opus") ? "opus" : s.includes("sonnet") ? "sonnet" : s.includes("haiku") ? "haiku" : null;
207667
207876
  }
207668
207877
  function cacheFilePath() {
207669
- return path66.join(getGlobalDir(), "cache", CACHE_FILE);
207878
+ return path67.join(getGlobalDir(), "cache", CACHE_FILE);
207670
207879
  }
207671
207880
  function readCache7() {
207672
207881
  try {
207673
- const t2 = JSON.parse(fs59.readFileSync(cacheFilePath(), "utf-8"));
207882
+ const t2 = JSON.parse(fs60.readFileSync(cacheFilePath(), "utf-8"));
207674
207883
  if (t2 && t2.tiers && t2.byId && typeof t2.fetchedAt === "number")
207675
207884
  return t2;
207676
207885
  } catch {
@@ -207679,8 +207888,8 @@ function readCache7() {
207679
207888
  }
207680
207889
  function writeCache7(t2) {
207681
207890
  try {
207682
- fs59.mkdirSync(path66.dirname(cacheFilePath()), { recursive: true });
207683
- fs59.writeFileSync(cacheFilePath(), JSON.stringify(t2));
207891
+ fs60.mkdirSync(path67.dirname(cacheFilePath()), { recursive: true });
207892
+ fs60.writeFileSync(cacheFilePath(), JSON.stringify(t2));
207684
207893
  } catch {
207685
207894
  }
207686
207895
  }
@@ -207833,12 +208042,14 @@ function previewChars() {
207833
208042
  return 60 * 50;
207834
208043
  }
207835
208044
  async function estimateScanTokens(repoRoot5, prices) {
208045
+ const decisions = readCorpusDecisions(repoRoot5);
208046
+ const manualIncludes = decisions.manualIncludes ?? [];
208047
+ const manualExcludes = new Set(decisions.manualExcludes ?? []);
207836
208048
  const docs = discoverDocs(repoRoot5);
207837
- const { toClassify } = prefilterDocs(docs);
207838
- const nClassify = toClassify.length;
207839
- const relevance = await Promise.all(toClassify.map((d3) => readRelevanceCache(repoRoot5, d3)));
207840
- const relevanceMissDocs = toClassify.filter((_2, i) => relevance[i] === null);
207841
- const cachedKeptDocs = toClassify.filter((_2, i) => relevance[i]?.include === true);
208049
+ const plan = await planRelevanceWork(repoRoot5, docs, manualIncludes);
208050
+ const nClassify = plan.toClassify.length;
208051
+ const relevanceMissDocs = plan.needsCall;
208052
+ const cachedKeptDocs = plan.toClassify.filter((d3) => plan.known.get(d3.path)?.include === true && !manualExcludes.has(d3.path));
207842
208053
  const cachedKeptTagged = await Promise.all(cachedKeptDocs.map((d3) => isAreaTagCached(repoRoot5, d3)));
207843
208054
  const cachedKeptTagMisses = cachedKeptTagged.filter((cached) => !cached).length;
207844
208055
  const estChangedKept = Math.round(relevanceMissDocs.length * KEEP_RATE);
@@ -208057,16 +208268,16 @@ function changedSubject(total, changed, noun) {
208057
208268
 
208058
208269
  // packages/core/dist/commands/spec-in-process.js
208059
208270
  init_dist8();
208060
- import fs64 from "node:fs";
208061
- import path71 from "node:path";
208271
+ import fs65 from "node:fs";
208272
+ import path72 from "node:path";
208062
208273
  init_git();
208063
208274
  import { createHash as createHash20, randomUUID as randomUUID27 } from "node:crypto";
208064
208275
 
208065
208276
  // packages/core/dist/lib/verify-store.js
208066
208277
  init_atomic_write();
208067
208278
  init_analysis_store();
208068
- import fs60 from "node:fs";
208069
- import path67 from "node:path";
208279
+ import fs61 from "node:fs";
208280
+ import path68 from "node:path";
208070
208281
 
208071
208282
  // packages/core/dist/types/verify-snapshot.js
208072
208283
  function driftKey(d3) {
@@ -208114,23 +208325,23 @@ var LATEST_FILE3 = "LATEST.json";
208114
208325
  var HISTORY_FILE3 = "history.json";
208115
208326
  var DIFF_FILE2 = "diff.json";
208116
208327
  function verifierDir(repoPath) {
208117
- return path67.join(repoPath, TRUECOURSE_DIR4, VERIFIER_DIR);
208328
+ return path68.join(repoPath, TRUECOURSE_DIR4, VERIFIER_DIR);
208118
208329
  }
208119
208330
  function runsDir(repoPath) {
208120
- return path67.join(verifierDir(repoPath), RUNS_DIR2);
208331
+ return path68.join(verifierDir(repoPath), RUNS_DIR2);
208121
208332
  }
208122
208333
  function verifyRunPath(repoPath, filename) {
208123
- return path67.join(runsDir(repoPath), filename);
208334
+ return path68.join(runsDir(repoPath), filename);
208124
208335
  }
208125
208336
  function verifyLatestPath(repoPath) {
208126
- return path67.join(verifierDir(repoPath), LATEST_FILE3);
208337
+ return path68.join(verifierDir(repoPath), LATEST_FILE3);
208127
208338
  }
208128
208339
  function verifyHistoryPath(repoPath) {
208129
- return path67.join(verifierDir(repoPath), HISTORY_FILE3);
208340
+ return path68.join(verifierDir(repoPath), HISTORY_FILE3);
208130
208341
  }
208131
208342
  function verifyDiffPath(repoPath, scope) {
208132
208343
  const file = scope ? `diff-${sanitizeScope(scope)}.json` : DIFF_FILE2;
208133
- return path67.join(verifierDir(repoPath), file);
208344
+ return path68.join(verifierDir(repoPath), file);
208134
208345
  }
208135
208346
  function sanitizeScope(scope) {
208136
208347
  return scope.replace(/[^a-zA-Z0-9._-]/g, "_");
@@ -208164,7 +208375,7 @@ var FileVerifyStore = class {
208164
208375
  const file = verifyLatestPath(repoPath);
208165
208376
  let mtime;
208166
208377
  try {
208167
- mtime = fs60.statSync(file).mtimeMs;
208378
+ mtime = fs61.statSync(file).mtimeMs;
208168
208379
  } catch (err) {
208169
208380
  if (err.code === "ENOENT") {
208170
208381
  latestCache2.delete(repoPath);
@@ -208175,7 +208386,7 @@ var FileVerifyStore = class {
208175
208386
  const cached = latestCache2.get(repoPath);
208176
208387
  if (cached && cached.mtime === mtime)
208177
208388
  return cached.data;
208178
- const data = JSON.parse(fs60.readFileSync(file, "utf-8"));
208389
+ const data = JSON.parse(fs61.readFileSync(file, "utf-8"));
208179
208390
  latestCache2.set(repoPath, { mtime, data });
208180
208391
  return data;
208181
208392
  }
@@ -208185,7 +208396,7 @@ var FileVerifyStore = class {
208185
208396
  }
208186
208397
  async deleteVerifyLatest(repoPath) {
208187
208398
  try {
208188
- fs60.unlinkSync(verifyLatestPath(repoPath));
208399
+ fs61.unlinkSync(verifyLatestPath(repoPath));
208189
208400
  } catch (err) {
208190
208401
  if (err.code !== "ENOENT")
208191
208402
  throw err;
@@ -208199,21 +208410,21 @@ var FileVerifyStore = class {
208199
208410
  }
208200
208411
  async readVerifyRun(repoPath, filename) {
208201
208412
  const file = verifyRunPath(repoPath, filename);
208202
- if (!fs60.existsSync(file))
208413
+ if (!fs61.existsSync(file))
208203
208414
  return null;
208204
- return JSON.parse(fs60.readFileSync(file, "utf-8"));
208415
+ return JSON.parse(fs61.readFileSync(file, "utf-8"));
208205
208416
  }
208206
208417
  async listVerifyRuns(repoPath) {
208207
208418
  const dir = runsDir(repoPath);
208208
- if (!fs60.existsSync(dir))
208419
+ if (!fs61.existsSync(dir))
208209
208420
  return [];
208210
- return fs60.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
208421
+ return fs61.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
208211
208422
  }
208212
208423
  async readVerifyHistory(repoPath) {
208213
208424
  const file = verifyHistoryPath(repoPath);
208214
- if (!fs60.existsSync(file))
208425
+ if (!fs61.existsSync(file))
208215
208426
  return { runs: [] };
208216
- return JSON.parse(fs60.readFileSync(file, "utf-8"));
208427
+ return JSON.parse(fs61.readFileSync(file, "utf-8"));
208217
208428
  }
208218
208429
  async appendVerifyHistory(repoPath, entry) {
208219
208430
  const history = await this.readVerifyHistory(repoPath);
@@ -208226,7 +208437,7 @@ var FileVerifyStore = class {
208226
208437
  if (!entry)
208227
208438
  return false;
208228
208439
  try {
208229
- fs60.unlinkSync(verifyRunPath(repoPath, entry.filename));
208440
+ fs61.unlinkSync(verifyRunPath(repoPath, entry.filename));
208230
208441
  } catch (err) {
208231
208442
  if (err.code !== "ENOENT")
208232
208443
  throw err;
@@ -208248,16 +208459,16 @@ var FileVerifyStore = class {
208248
208459
  }
208249
208460
  async readVerifyDiff(repoPath, scope) {
208250
208461
  const file = verifyDiffPath(repoPath, scope);
208251
- if (!fs60.existsSync(file))
208462
+ if (!fs61.existsSync(file))
208252
208463
  return null;
208253
- return JSON.parse(fs60.readFileSync(file, "utf-8"));
208464
+ return JSON.parse(fs61.readFileSync(file, "utf-8"));
208254
208465
  }
208255
208466
  async writeVerifyDiff(repoPath, diff, scope) {
208256
208467
  atomicWriteJson(verifyDiffPath(repoPath, scope), diff);
208257
208468
  }
208258
208469
  async deleteVerifyDiff(repoPath, scope) {
208259
208470
  try {
208260
- fs60.unlinkSync(verifyDiffPath(repoPath, scope));
208471
+ fs61.unlinkSync(verifyDiffPath(repoPath, scope));
208261
208472
  } catch (err) {
208262
208473
  if (err.code !== "ENOENT")
208263
208474
  throw err;
@@ -208291,8 +208502,8 @@ async function repoRef(repoRoot5, commitOverride) {
208291
208502
  }
208292
208503
 
208293
208504
  // packages/core/dist/lib/contract-store.js
208294
- import fs61 from "node:fs";
208295
- import path68 from "node:path";
208505
+ import fs62 from "node:fs";
208506
+ import path69 from "node:path";
208296
208507
  var KIND_REL = {
208297
208508
  contracts: [".truecourse", "contracts"],
208298
208509
  // The inferred tree lives at contracts/_inferred (matches `writeInferred`).
@@ -208302,13 +208513,13 @@ function countTcFiles(dir) {
208302
208513
  let n = 0;
208303
208514
  let entries;
208304
208515
  try {
208305
- entries = fs61.readdirSync(dir, { withFileTypes: true });
208516
+ entries = fs62.readdirSync(dir, { withFileTypes: true });
208306
208517
  } catch {
208307
208518
  return 0;
208308
208519
  }
208309
208520
  for (const e of entries) {
208310
208521
  if (e.isDirectory())
208311
- n += countTcFiles(path68.join(dir, e.name));
208522
+ n += countTcFiles(path69.join(dir, e.name));
208312
208523
  else if (e.isFile() && e.name.endsWith(".tc"))
208313
208524
  n += 1;
208314
208525
  }
@@ -208319,7 +208530,7 @@ function walkTcRel(dir, excludeInferred) {
208319
208530
  const walk20 = (rel) => {
208320
208531
  let entries;
208321
208532
  try {
208322
- entries = fs61.readdirSync(path68.join(dir, rel), { withFileTypes: true });
208533
+ entries = fs62.readdirSync(path69.join(dir, rel), { withFileTypes: true });
208323
208534
  } catch {
208324
208535
  return;
208325
208536
  }
@@ -208343,50 +208554,50 @@ function safeResolve(root2, rel) {
208343
208554
  return null;
208344
208555
  if (norm.split("/").some((s) => s === ".." || s === "." || s === ""))
208345
208556
  return null;
208346
- const base2 = path68.resolve(root2);
208347
- const dest = path68.resolve(base2, norm);
208348
- if (dest !== base2 && !dest.startsWith(base2 + path68.sep))
208557
+ const base2 = path69.resolve(root2);
208558
+ const dest = path69.resolve(base2, norm);
208559
+ if (dest !== base2 && !dest.startsWith(base2 + path69.sep))
208349
208560
  return null;
208350
208561
  return dest;
208351
208562
  }
208352
208563
  var FileContractStore = class {
208353
208564
  materializesInPlace = true;
208354
208565
  async saveContracts(ref, kind, _sourceDir) {
208355
- const dir = path68.join(ref.repoKey, ...KIND_REL[kind]);
208566
+ const dir = path69.join(ref.repoKey, ...KIND_REL[kind]);
208356
208567
  return { manifest: {}, fileCount: countTcFiles(dir), objectsWritten: 0, manifestHash: "" };
208357
208568
  }
208358
208569
  async loadContracts(ref, kind) {
208359
- const dir = path68.join(ref.repoKey, ...KIND_REL[kind]);
208360
- if (!fs61.existsSync(dir))
208570
+ const dir = path69.join(ref.repoKey, ...KIND_REL[kind]);
208571
+ if (!fs62.existsSync(dir))
208361
208572
  return null;
208362
208573
  return { dir, cleanup: async () => {
208363
208574
  } };
208364
208575
  }
208365
208576
  async hasContracts(ref, kind) {
208366
- return fs61.existsSync(path68.join(ref.repoKey, ...KIND_REL[kind]));
208577
+ return fs62.existsSync(path69.join(ref.repoKey, ...KIND_REL[kind]));
208367
208578
  }
208368
208579
  // The file impl reads the live repo tree, which is whatever is checked out —
208369
208580
  // there is no per-commit history, so `commitSha` is ignored (OSS is latest).
208370
208581
  async listContractFiles(repoKey, kind, _commitSha) {
208371
- return walkTcRel(path68.join(repoKey, ...KIND_REL[kind]), kind === "contracts");
208582
+ return walkTcRel(path69.join(repoKey, ...KIND_REL[kind]), kind === "contracts");
208372
208583
  }
208373
208584
  async readContractFile(repoKey, kind, relPath, _commitSha) {
208374
- const dest = safeResolve(path68.join(repoKey, ...KIND_REL[kind]), relPath);
208375
- if (!dest || !fs61.existsSync(dest) || !fs61.statSync(dest).isFile())
208585
+ const dest = safeResolve(path69.join(repoKey, ...KIND_REL[kind]), relPath);
208586
+ if (!dest || !fs62.existsSync(dest) || !fs62.statSync(dest).isFile())
208376
208587
  return null;
208377
- return fs61.readFileSync(dest, "utf-8");
208588
+ return fs62.readFileSync(dest, "utf-8");
208378
208589
  }
208379
208590
  async putContractFile(ref, kind, relPath, content) {
208380
- const dest = safeResolve(path68.join(ref.repoKey, ...KIND_REL[kind]), relPath);
208591
+ const dest = safeResolve(path69.join(ref.repoKey, ...KIND_REL[kind]), relPath);
208381
208592
  if (!dest)
208382
208593
  throw new Error(`[contract-store] unsafe contract path: ${relPath}`);
208383
- fs61.mkdirSync(path68.dirname(dest), { recursive: true });
208384
- fs61.writeFileSync(dest, content);
208594
+ fs62.mkdirSync(path69.dirname(dest), { recursive: true });
208595
+ fs62.writeFileSync(dest, content);
208385
208596
  }
208386
208597
  async deleteContractFile(ref, kind, relPath) {
208387
- const dest = safeResolve(path68.join(ref.repoKey, ...KIND_REL[kind]), relPath);
208598
+ const dest = safeResolve(path69.join(ref.repoKey, ...KIND_REL[kind]), relPath);
208388
208599
  if (dest)
208389
- fs61.rmSync(dest, { force: true });
208600
+ fs62.rmSync(dest, { force: true });
208390
208601
  }
208391
208602
  // OSS/local has no workspace concept (mirrors the spec store). Writing throws
208392
208603
  // (fail loud — a caller that reached here is mis-wired); reads are empty so an
@@ -208413,10 +208624,10 @@ var loadWorkspaceContracts = (ref, kind) => active8.loadWorkspaceContracts(ref,
208413
208624
  var contractsMaterializeInPlace = () => active8.materializesInPlace;
208414
208625
 
208415
208626
  // packages/core/dist/lib/spec-store.js
208416
- import fs62 from "node:fs";
208417
- import path69 from "node:path";
208627
+ import fs63 from "node:fs";
208628
+ import path70 from "node:path";
208418
208629
  function specPath(repoKey, artifact) {
208419
- return path69.join(repoKey, ".truecourse", "specs", `${artifact}.json`);
208630
+ return path70.join(repoKey, ".truecourse", "specs", `${artifact}.json`);
208420
208631
  }
208421
208632
  function isPrDecisionsRef(commitSha) {
208422
208633
  return /^_pr\/\d+$/.test(commitSha ?? "");
@@ -208429,18 +208640,18 @@ var FileSpecStore = class {
208429
208640
  throw new Error(PR_DECISIONS_FILE_ERROR);
208430
208641
  }
208431
208642
  const file = specPath(ref.repoKey, artifact);
208432
- fs62.mkdirSync(path69.dirname(file), { recursive: true });
208433
- fs62.writeFileSync(file, JSON.stringify(json2, null, 2) + "\n", "utf-8");
208643
+ fs63.mkdirSync(path70.dirname(file), { recursive: true });
208644
+ fs63.writeFileSync(file, JSON.stringify(json2, null, 2) + "\n", "utf-8");
208434
208645
  }
208435
208646
  async loadSpec(ref, artifact) {
208436
208647
  if (artifact === "decisions" && isPrDecisionsRef(ref.commitSha)) {
208437
208648
  throw new Error(PR_DECISIONS_FILE_ERROR);
208438
208649
  }
208439
208650
  const file = specPath(ref.repoKey, artifact);
208440
- if (!fs62.existsSync(file))
208651
+ if (!fs63.existsSync(file))
208441
208652
  return null;
208442
208653
  try {
208443
- return JSON.parse(fs62.readFileSync(file, "utf-8"));
208654
+ return JSON.parse(fs63.readFileSync(file, "utf-8"));
208444
208655
  } catch {
208445
208656
  return null;
208446
208657
  }
@@ -208450,8 +208661,8 @@ var FileSpecStore = class {
208450
208661
  throw new Error(PR_DECISIONS_FILE_ERROR);
208451
208662
  }
208452
208663
  const file = specPath(ref.repoKey, artifact);
208453
- if (fs62.existsSync(file))
208454
- fs62.rmSync(file);
208664
+ if (fs63.existsSync(file))
208665
+ fs63.rmSync(file);
208455
208666
  }
208456
208667
  // The file impl is single-document-per-repo, so "latest" === read the file.
208457
208668
  async loadLatest(repoKey, artifact) {
@@ -208478,23 +208689,23 @@ var loadLatestSpec = (repoKey, artifact) => active9.loadLatest(repoKey, artifact
208478
208689
  var specsMaterializeInPlace = () => active9.materializesInPlace;
208479
208690
 
208480
208691
  // packages/core/dist/lib/inferred-action-store.js
208481
- import fs63 from "node:fs";
208482
- import path70 from "node:path";
208692
+ import fs64 from "node:fs";
208693
+ import path71 from "node:path";
208483
208694
  function actionsFile(repoKey) {
208484
- return path70.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
208695
+ return path71.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
208485
208696
  }
208486
208697
  var FileInferredActionStore = class {
208487
208698
  read(repoKey) {
208488
208699
  try {
208489
- return JSON.parse(fs63.readFileSync(actionsFile(repoKey), "utf-8"));
208700
+ return JSON.parse(fs64.readFileSync(actionsFile(repoKey), "utf-8"));
208490
208701
  } catch {
208491
208702
  return [];
208492
208703
  }
208493
208704
  }
208494
208705
  write(repoKey, actions) {
208495
208706
  const file = actionsFile(repoKey);
208496
- fs63.mkdirSync(path70.dirname(file), { recursive: true });
208497
- fs63.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
208707
+ fs64.mkdirSync(path71.dirname(file), { recursive: true });
208708
+ fs64.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
208498
208709
  }
208499
208710
  async setAction(repoKey, action) {
208500
208711
  const next = this.read(repoKey).filter((a) => !(a.kind === action.kind && a.identity === action.identity));
@@ -208623,13 +208834,13 @@ function resolveTransport(options) {
208623
208834
  }
208624
208835
  return getDefaultTransport();
208625
208836
  }
208626
- var GENERATED_MARKER_REL = path71.join(".truecourse", "contracts", "result.json");
208837
+ var GENERATED_MARKER_REL = path72.join(".truecourse", "contracts", "result.json");
208627
208838
  function generatedMarkerPath(repoRoot5) {
208628
- return path71.join(repoRoot5, GENERATED_MARKER_REL);
208839
+ return path72.join(repoRoot5, GENERATED_MARKER_REL);
208629
208840
  }
208630
208841
  function stampGeneratedMarker(repoRoot5, summary) {
208631
208842
  const file = generatedMarkerPath(repoRoot5);
208632
- fs64.mkdirSync(path71.dirname(file), { recursive: true });
208843
+ fs65.mkdirSync(path72.dirname(file), { recursive: true });
208633
208844
  const body = {
208634
208845
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
208635
208846
  written: summary?.written ?? 0,
@@ -208637,7 +208848,7 @@ function stampGeneratedMarker(repoRoot5, summary) {
208637
208848
  validationIssues: summary?.validationIssues ?? [],
208638
208849
  enumerateFailures: summary?.enumerateFailures ?? []
208639
208850
  };
208640
- fs64.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
208851
+ fs65.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
208641
208852
  }
208642
208853
  function resolveCurateModels(repoRoot5) {
208643
208854
  return {
@@ -208761,22 +208972,22 @@ async function curateInProcess(repoRoot5, options = {}) {
208761
208972
  }
208762
208973
  }
208763
208974
  function buildPriorContracts(repoRoot5) {
208764
- const dir = path71.join(repoRoot5, ".truecourse", "contracts");
208765
- if (!fs64.existsSync(dir))
208975
+ const dir = path72.join(repoRoot5, ".truecourse", "contracts");
208976
+ if (!fs65.existsSync(dir))
208766
208977
  return void 0;
208767
208978
  const targets = [];
208768
208979
  const bodyByKey = /* @__PURE__ */ new Map();
208769
208980
  const walk20 = (d3) => {
208770
- for (const e of fs64.readdirSync(d3, { withFileTypes: true })) {
208981
+ for (const e of fs65.readdirSync(d3, { withFileTypes: true })) {
208771
208982
  if (e.isDirectory()) {
208772
208983
  if (e.name === "_inferred")
208773
208984
  continue;
208774
- walk20(path71.join(d3, e.name));
208985
+ walk20(path72.join(d3, e.name));
208775
208986
  } else if (e.name.endsWith(".tc")) {
208776
- const abs = path71.join(d3, e.name);
208777
- const src = fs64.readFileSync(abs, "utf-8");
208987
+ const abs = path72.join(d3, e.name);
208988
+ const src = fs65.readFileSync(abs, "utf-8");
208778
208989
  try {
208779
- const file = parser_ohm_exports.parseTcFile(path71.relative(dir, abs), src);
208990
+ const file = parser_ohm_exports.parseTcFile(path72.relative(dir, abs), src);
208780
208991
  for (const key4 of resolver_exports.resolve([file]).index.keys()) {
208781
208992
  const colon = key4.indexOf(":");
208782
208993
  if (colon < 0)
@@ -208936,18 +209147,18 @@ function resolverHardError(result) {
208936
209147
  const detail = reasons.length ? reasons.slice(0, 3).join("; ") : "duplicate or conflicting artifact identities";
208937
209148
  return new Error(`Contract corpus failed to resolve \u2014 ${detail}`);
208938
209149
  }
208939
- var LEGACY_VERIFY_STATE_REL = path71.join(".truecourse", ".cache", "verifier", "verify-state.json");
209150
+ var LEGACY_VERIFY_STATE_REL = path72.join(".truecourse", ".cache", "verifier", "verify-state.json");
208940
209151
  function legacyVerifyStatePath(repoRoot5) {
208941
- return path71.join(repoRoot5, LEGACY_VERIFY_STATE_REL);
209152
+ return path72.join(repoRoot5, LEGACY_VERIFY_STATE_REL);
208942
209153
  }
208943
209154
  async function withContracts(repoRoot5, options, tracker, fn) {
208944
- const fallbackPath = path71.join(repoRoot5, ".truecourse", "contracts");
209155
+ const fallbackPath = path72.join(repoRoot5, ".truecourse", "contracts");
208945
209156
  const wsMat = options.workspaceOrgId ? await loadWorkspaceContracts({ workspaceOrgId: options.workspaceOrgId }, "contracts") : null;
208946
209157
  let repoMat = null;
208947
209158
  try {
208948
209159
  let recorded;
208949
209160
  if (options.contractsDir) {
208950
- if (!fs64.existsSync(options.contractsDir)) {
209161
+ if (!fs65.existsSync(options.contractsDir)) {
208951
209162
  const err = new Error(`Contracts directory not found at ${options.contractsDir}. Run \`truecourse contracts generate\` first.`);
208952
209163
  tracker?.error("load", err.message);
208953
209164
  throw err;
@@ -208992,7 +209203,7 @@ async function verifyInProcess(repoRoot5, options = {}) {
208992
209203
  tracker?.start("compare");
208993
209204
  tracker?.done("compare", `${result.drifts.length} drift${result.drifts.length === 1 ? "" : "s"}`);
208994
209205
  if (options.ref) {
208995
- result.drifts = result.drifts.map((d3) => d3.filePath && path71.isAbsolute(d3.filePath) ? { ...d3, filePath: path71.relative(repoRoot5, d3.filePath).split(path71.sep).join("/") } : d3);
209206
+ result.drifts = result.drifts.map((d3) => d3.filePath && path72.isAbsolute(d3.filePath) ? { ...d3, filePath: path72.relative(repoRoot5, d3.filePath).split(path72.sep).join("/") } : d3);
208996
209207
  }
208997
209208
  const verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
208998
209209
  const { branch, commitHash } = await gitMeta(repoRoot5);
@@ -209036,7 +209247,7 @@ async function verifyInProcess(repoRoot5, options = {}) {
209036
209247
  bySeverity: summary.bySeverity
209037
209248
  });
209038
209249
  await deleteVerifyDiff(storeKey);
209039
- fs64.rmSync(legacyVerifyStatePath(repoRoot5), { force: true });
209250
+ fs65.rmSync(legacyVerifyStatePath(repoRoot5), { force: true });
209040
209251
  }
209041
209252
  const state = {
209042
209253
  verifiedAt,
@@ -209084,7 +209295,7 @@ async function runWithStash(repoRoot5, skipStash, tracker, fn) {
209084
209295
  const status = await stashGit.status();
209085
209296
  if (!status.isClean()) {
209086
209297
  const gitRoot = (await stashGit.revparse(["--show-toplevel"])).trim();
209087
- if (path71.resolve(repoRoot5) === path71.resolve(gitRoot)) {
209298
+ if (path72.resolve(repoRoot5) === path72.resolve(gitRoot)) {
209088
209299
  tracker?.detail?.("load", "Stashing pending changes...");
209089
209300
  const res = await stashGit.stash(["push", "--include-untracked", "-m", "truecourse-verify-stash"]);
209090
209301
  didStash = !res.includes("No local changes");
@@ -209186,7 +209397,7 @@ async function verifyDiffInProcess(repoRoot5, options = {}) {
209186
209397
  async function inferInProcess(repoRoot5, options = {}) {
209187
209398
  const startedAt = Date.now();
209188
209399
  const codeDir = options.codeDir ?? autodetectCodeDir(repoRoot5);
209189
- let contractsDir = options.contractsDir ?? path71.join(repoRoot5, ".truecourse", "contracts");
209400
+ let contractsDir = options.contractsDir ?? path72.join(repoRoot5, ".truecourse", "contracts");
209190
209401
  let releaseContracts = async () => {
209191
209402
  };
209192
209403
  if (!options.contractsDir && options.ref) {
@@ -209230,7 +209441,7 @@ async function persistInferred(repoRoot5, options, contractsDir, codeDir, starte
209230
209441
  });
209231
209442
  }
209232
209443
  if (!options.dryRun && options.ref) {
209233
- await saveContracts(options.ref, "contracts_inferred", path71.join(contractsDir, "_inferred"));
209444
+ await saveContracts(options.ref, "contracts_inferred", path72.join(contractsDir, "_inferred"));
209234
209445
  }
209235
209446
  const rendered = result.decisions.map((d3) => renderDecision(d3));
209236
209447
  const decisionPaths = rendered.map((r) => r.relPath);
@@ -209253,8 +209464,8 @@ async function persistInferred(repoRoot5, options, contractsDir, codeDir, starte
209253
209464
  return { infer: result, written, proposed, decisionPaths, summaries };
209254
209465
  }
209255
209466
  function autodetectCodeDir(repoRoot5) {
209256
- const codeSubdir = path71.join(repoRoot5, "code");
209257
- if (fs64.existsSync(codeSubdir) && fs64.statSync(codeSubdir).isDirectory()) {
209467
+ const codeSubdir = path72.join(repoRoot5, "code");
209468
+ if (fs65.existsSync(codeSubdir) && fs65.statSync(codeSubdir).isDirectory()) {
209258
209469
  return codeSubdir;
209259
209470
  }
209260
209471
  return repoRoot5;
@@ -209574,8 +209785,8 @@ async function runContractsGenerate(options = {}) {
209574
209785
  }
209575
209786
  async function runContractsList(options = {}) {
209576
209787
  const repoRoot5 = options.cwd ?? process.cwd();
209577
- const contractsDir = path72.join(repoRoot5, ".truecourse", "contracts");
209578
- if (!fs65.existsSync(contractsDir)) {
209788
+ const contractsDir = path73.join(repoRoot5, ".truecourse", "contracts");
209789
+ if (!fs66.existsSync(contractsDir)) {
209579
209790
  O2.info("No contracts found. Run `truecourse contracts generate` first.");
209580
209791
  return;
209581
209792
  }
@@ -209583,12 +209794,12 @@ async function runContractsList(options = {}) {
209583
209794
  const fileNodes = [];
209584
209795
  let parseErrors = 0;
209585
209796
  const visit = (dir) => {
209586
- for (const entry of fs65.readdirSync(dir, { withFileTypes: true })) {
209587
- const full = path72.join(dir, entry.name);
209797
+ for (const entry of fs66.readdirSync(dir, { withFileTypes: true })) {
209798
+ const full = path73.join(dir, entry.name);
209588
209799
  if (entry.isDirectory()) visit(full);
209589
209800
  else if (entry.isFile() && entry.name.endsWith(".tc")) {
209590
209801
  try {
209591
- fileNodes.push(parserOhm.parseTcFile(full, fs65.readFileSync(full, "utf-8")));
209802
+ fileNodes.push(parserOhm.parseTcFile(full, fs66.readFileSync(full, "utf-8")));
209592
209803
  } catch {
209593
209804
  parseErrors += 1;
209594
209805
  }
@@ -209615,7 +209826,7 @@ async function runContractsList(options = {}) {
209615
209826
  mt(`Contracts \u2014 ${artifacts.length} ${scope}artifact${artifacts.length === 1 ? "" : "s"}`);
209616
209827
  for (const a of artifacts) {
209617
209828
  const conf = a.confidence ? `[${a.confidence}] ` : "";
209618
- const loc = a.origin ? a.origin.lines[0] >= 0 ? `${a.origin.source}:${a.origin.lines[0]}` : a.origin.source : `${path72.relative(repoRoot5, a.declarationLoc.filePath)}:${a.declarationLoc.lineStart}`;
209829
+ const loc = a.origin ? a.origin.lines[0] >= 0 ? `${a.origin.source}:${a.origin.lines[0]}` : a.origin.source : `${path73.relative(repoRoot5, a.declarationLoc.filePath)}:${a.declarationLoc.lineStart}`;
209619
209830
  console.log(` ${conf}${a.ref.type}:${a.ref.identity} ${loc}`);
209620
209831
  }
209621
209832
  if (parseErrors > 0) {
@@ -209627,8 +209838,8 @@ async function runContractsList(options = {}) {
209627
209838
  }
209628
209839
  async function runContractsValidate(options = {}) {
209629
209840
  const repoRoot5 = options.cwd ?? process.cwd();
209630
- const contractsDir = path72.join(repoRoot5, ".truecourse", "contracts");
209631
- if (!fs65.existsSync(contractsDir)) {
209841
+ const contractsDir = path73.join(repoRoot5, ".truecourse", "contracts");
209842
+ if (!fs66.existsSync(contractsDir)) {
209632
209843
  O2.error("No .truecourse/contracts/ directory found.");
209633
209844
  process.exit(1);
209634
209845
  }
@@ -209636,14 +209847,14 @@ async function runContractsValidate(options = {}) {
209636
209847
  const fileNodes = [];
209637
209848
  const issues = [];
209638
209849
  const visit = (dir) => {
209639
- for (const entry of fs65.readdirSync(dir, { withFileTypes: true })) {
209640
- const full = path72.join(dir, entry.name);
209850
+ for (const entry of fs66.readdirSync(dir, { withFileTypes: true })) {
209851
+ const full = path73.join(dir, entry.name);
209641
209852
  if (entry.isDirectory()) visit(full);
209642
209853
  else if (entry.isFile() && entry.name.endsWith(".tc")) {
209643
209854
  try {
209644
- fileNodes.push(parserOhm.parseTcFile(full, fs65.readFileSync(full, "utf-8")));
209855
+ fileNodes.push(parserOhm.parseTcFile(full, fs66.readFileSync(full, "utf-8")));
209645
209856
  } catch (e) {
209646
- issues.push(`${path72.relative(repoRoot5, full)}: parse error: ${e instanceof Error ? e.message : e}`);
209857
+ issues.push(`${path73.relative(repoRoot5, full)}: parse error: ${e instanceof Error ? e.message : e}`);
209647
209858
  }
209648
209859
  }
209649
209860
  }
@@ -209651,11 +209862,11 @@ async function runContractsValidate(options = {}) {
209651
209862
  visit(contractsDir);
209652
209863
  const resolution = resolver.resolve(fileNodes);
209653
209864
  for (const err of resolution.errors) {
209654
- issues.push(`${path72.relative(repoRoot5, err.filePath)}:${err.line} ${err.message}`);
209865
+ issues.push(`${path73.relative(repoRoot5, err.filePath)}:${err.line} ${err.message}`);
209655
209866
  }
209656
209867
  const trulyUnresolved = resolution.unresolvedRefs.filter((u2) => u2.ref.type !== "Unknown");
209657
209868
  for (const u2 of trulyUnresolved) {
209658
- issues.push(`${path72.relative(repoRoot5, u2.usedAt.filePath)}:${u2.usedAt.lineStart} unresolved ${u2.ref.type}:${u2.ref.identity}`);
209869
+ issues.push(`${path73.relative(repoRoot5, u2.usedAt.filePath)}:${u2.usedAt.lineStart} unresolved ${u2.ref.type}:${u2.ref.identity}`);
209659
209870
  }
209660
209871
  if (issues.length === 0) {
209661
209872
  O2.success(`Validated ${resolution.index.size} artifact${resolution.index.size === 1 ? "" : "s"} \u2014 no issues.`);
@@ -209669,7 +209880,7 @@ async function runContractsValidate(options = {}) {
209669
209880
 
209670
209881
  // tools/cli/src/commands/spec.ts
209671
209882
  init_dist4();
209672
- import path73 from "node:path";
209883
+ import path74 from "node:path";
209673
209884
  init_progress();
209674
209885
  init_registry();
209675
209886
  var repoRoot = (opts = {}) => opts.cwd ?? process.cwd();
@@ -209795,7 +210006,7 @@ async function runVerify(opts = {}) {
209795
210006
  O2.message("");
209796
210007
  O2.message("Drifts:");
209797
210008
  for (const d3 of verify2.drifts.slice(0, 20)) {
209798
- const loc = d3.filePath ? ` ${path73.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
210009
+ const loc = d3.filePath ? ` ${path74.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
209799
210010
  O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
209800
210011
  O2.message(` \u2192 ${d3.message}`);
209801
210012
  }
@@ -209829,7 +210040,7 @@ async function runVerifyDiff(opts) {
209829
210040
  O2.message("");
209830
210041
  O2.message(`${label}:`);
209831
210042
  for (const d3 of drifts.slice(0, 20)) {
209832
- const loc = d3.filePath ? ` ${path73.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
210043
+ const loc = d3.filePath ? ` ${path74.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
209833
210044
  O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
209834
210045
  }
209835
210046
  if (drifts.length > 20) O2.message(` \u2026 (+${drifts.length - 20} more)`);
@@ -209884,8 +210095,8 @@ async function runInfer(opts = {}) {
209884
210095
 
209885
210096
  // tools/cli/src/commands/spec-conflicts.ts
209886
210097
  init_dist4();
209887
- import fs66 from "node:fs";
209888
- import path74 from "node:path";
210098
+ import fs67 from "node:fs";
210099
+ import path75 from "node:path";
209889
210100
  var root = (opts) => opts.cwd ?? process.cwd();
209890
210101
  var base = (ref) => ref.split("/").pop() ?? ref;
209891
210102
  function effectiveRelations2(corpus, repoRoot5) {
@@ -209932,7 +210143,7 @@ async function runSpecConflictsList(opts = {}) {
209932
210143
  function excerpt(repoRoot5, ref, note, max = 20) {
209933
210144
  let text4;
209934
210145
  try {
209935
- text4 = fs66.readFileSync(path74.join(repoRoot5, ref), "utf-8");
210146
+ text4 = fs67.readFileSync(path75.join(repoRoot5, ref), "utf-8");
209936
210147
  } catch {
209937
210148
  return ` (could not read ${ref})`;
209938
210149
  }
@@ -210157,7 +210368,7 @@ function fail3(msg) {
210157
210368
 
210158
210369
  // tools/cli/src/commands/drifts.ts
210159
210370
  init_dist4();
210160
- import path75 from "node:path";
210371
+ import path76 from "node:path";
210161
210372
  var DRIFT_SEVERITIES = [
210162
210373
  "critical",
210163
210374
  "high",
@@ -210194,7 +210405,7 @@ async function runDriftsList(opts = {}) {
210194
210405
  O2.message("");
210195
210406
  O2.message("Drifts:");
210196
210407
  for (const d3 of page) {
210197
- const loc = d3.filePath ? ` ${path75.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
210408
+ const loc = d3.filePath ? ` ${path76.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
210198
210409
  O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
210199
210410
  O2.message(` \u2192 ${d3.message}`);
210200
210411
  }
@@ -210225,7 +210436,7 @@ function parseDriftSeverityFlag(raw) {
210225
210436
 
210226
210437
  // tools/cli/src/commands/guard.ts
210227
210438
  init_dist4();
210228
- import path76 from "node:path";
210439
+ import path77 from "node:path";
210229
210440
  init_progress();
210230
210441
 
210231
210442
  // packages/core/dist/commands/guard-in-process.js
@@ -210240,12 +210451,14 @@ var GUARD_GENERATE_STEPS = [
210240
210451
  var GUARD_STEP_STAGES = {
210241
210452
  index: ["guard.recipe"],
210242
210453
  extract: ["guard.extract"],
210243
- author: ["guard.generate"]
210454
+ author: ["guard.generate"],
210455
+ validate: ["guard.retry"]
210244
210456
  };
210245
210457
  function resolveGuardModels(repoRoot5) {
210246
210458
  return {
210247
210459
  extract: resolveModel("guard.extract", void 0, repoRoot5),
210248
210460
  generate: resolveModel("guard.generate", void 0, repoRoot5),
210461
+ retry: resolveModel("guard.retry", void 0, repoRoot5),
210249
210462
  recipe: resolveModel("guard.recipe", void 0, repoRoot5),
210250
210463
  fallback: resolveFallbackModel(repoRoot5) ?? void 0
210251
210464
  };
@@ -210287,10 +210500,20 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210287
210500
  cur = ni;
210288
210501
  };
210289
210502
  const withUsage = (key4, base2) => `${base2}${stageUsageTag(GUARD_STEP_STAGES[key4] ?? [], repoRoot5)}`;
210503
+ let authorDone = 0;
210504
+ let authorTotal = 0;
210505
+ let authorFinished = false;
210506
+ let groundCaptured = 0;
210507
+ let groundPlanned = 0;
210508
+ const authorDetail = () => {
210509
+ const claims = `${authorDone}/${authorTotal} claim${authorTotal === 1 ? "" : "s"}`;
210510
+ const base2 = groundPlanned > 0 ? `grounding probes ${groundCaptured}/${groundPlanned} \xB7 authoring ${claims}` : claims;
210511
+ return withUsage("author", base2);
210512
+ };
210290
210513
  let building = false;
210291
- let birthSeen = false;
210292
210514
  let birthDone = 0;
210293
- let birthTotal = 0;
210515
+ let sectionsDone = 0;
210516
+ let sectionsTotal = 0;
210294
210517
  let retrySeen = false;
210295
210518
  let retryDone = 0;
210296
210519
  let retryTotal = 0;
@@ -210301,10 +210524,10 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210301
210524
  tracker?.start("validate");
210302
210525
  validateStarted = true;
210303
210526
  }
210304
- const parts = [building ? "building\u2026" : `birth ${birthDone}/${birthTotal}`];
210527
+ const parts = [`sections ${sectionsDone}/${sectionsTotal}`, building ? "building\u2026" : `birth ${birthDone}`];
210305
210528
  if (retrySeen)
210306
- parts.push(`retrying failed claims ${retryDone}/${retryTotal}`);
210307
- tracker?.detail("validate", parts.join(" \xB7 "));
210529
+ parts.push(`retrying ${retryDone}/${retryTotal}`);
210530
+ tracker?.detail("validate", withUsage("validate", parts.join(" \xB7 ")));
210308
210531
  };
210309
210532
  tracker?.start("index");
210310
210533
  try {
@@ -210316,6 +210539,7 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210316
210539
  generateRunner: options.generateRunner,
210317
210540
  recipeRunner: options.recipeRunner,
210318
210541
  onPlan: (total, work) => {
210542
+ sectionsTotal = work;
210319
210543
  tracker?.done("index", withUsage("index", `${work} of ${total} section${total === 1 ? "" : "s"} changed`));
210320
210544
  cur = STEPS.indexOf("extract");
210321
210545
  tracker?.start("extract", `0 views`);
@@ -210332,27 +210556,30 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210332
210556
  },
210333
210557
  onAuthorProgress: (done, total) => {
210334
210558
  advanceTo("author");
210335
- const detail = withUsage("author", `${done}/${total} claim${total === 1 ? "" : "s"}`);
210336
- if (done >= total)
210337
- tracker?.done("author", detail);
210338
- else
210339
- tracker?.detail("author", detail);
210340
- },
210341
- onBirthPhase: (phase, total) => {
210342
- if (phase === "build") {
210343
- building = true;
210559
+ authorDone = done;
210560
+ authorTotal = total;
210561
+ if (done >= total) {
210562
+ authorFinished = true;
210563
+ tracker?.done("author", withUsage("author", `${done}/${total} claim${total === 1 ? "" : "s"}`));
210344
210564
  } else {
210345
- building = false;
210346
- if (!birthSeen && total !== void 0)
210347
- birthTotal = total;
210565
+ tracker?.detail("author", authorDetail());
210348
210566
  }
210567
+ },
210568
+ onGroundProgress: (captured, planned) => {
210569
+ groundCaptured = captured;
210570
+ groundPlanned = planned;
210571
+ if (authorFinished)
210572
+ return;
210573
+ advanceTo("author");
210574
+ tracker?.detail("author", authorDetail());
210575
+ },
210576
+ onBirthPhase: (phase) => {
210577
+ building = phase === "build";
210349
210578
  renderValidate();
210350
210579
  },
210351
- onBirthProgress: (done, total) => {
210580
+ onBirthProgress: (done) => {
210352
210581
  building = false;
210353
- birthSeen = true;
210354
210582
  birthDone = done;
210355
- birthTotal = total;
210356
210583
  renderValidate();
210357
210584
  },
210358
210585
  onRetryProgress: (done, total) => {
@@ -210360,6 +210587,12 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210360
210587
  retryDone = done;
210361
210588
  retryTotal = total;
210362
210589
  renderValidate();
210590
+ },
210591
+ onSectionSettled: (settled, total) => {
210592
+ sectionsDone = settled;
210593
+ sectionsTotal = total;
210594
+ if (validateStarted)
210595
+ renderValidate();
210363
210596
  }
210364
210597
  });
210365
210598
  for (let i = cur; i < STEPS.length; i++)
@@ -210383,7 +210616,7 @@ async function guardGenerateInProcess(repoRoot5, options = {}) {
210383
210616
  }
210384
210617
  }
210385
210618
  }
210386
- var GUARD_USAGE_STAGES = ["guard.recipe", "guard.extract", "guard.generate"];
210619
+ var GUARD_USAGE_STAGES = ["guard.recipe", "guard.extract", "guard.generate", "guard.retry"];
210387
210620
  function sumGuardUsage() {
210388
210621
  const usage = getStageUsage();
210389
210622
  let calls = 0;
@@ -210431,6 +210664,8 @@ async function guardRunInProcess(repoRoot5, options = {}) {
210431
210664
  tracker?.done("run", `${n} scenario${n === 1 ? "" : "s"}`);
210432
210665
  } else if (result.status === "build-failed") {
210433
210666
  tracker?.error("build", `Build failed (\`${result.build.command}\`)${result.build.timedOut ? " \u2014 timed out" : ""}`);
210667
+ } else if (result.status === "entry-preflight-failed") {
210668
+ tracker?.error("build", `Entry failed to start: \`${result.preflight.entry}\` (rebuild via \`${result.buildCommand}\`)`);
210434
210669
  }
210435
210670
  return result;
210436
210671
  }
@@ -210494,6 +210729,15 @@ async function runGuardRun(opts = {}) {
210494
210729
  process.exit(1);
210495
210730
  return;
210496
210731
  }
210732
+ case "entry-preflight-failed": {
210733
+ O2.error(`The recipe entry \`${result.preflight.entry}\` failed to start \u2014 every scenario would fail identically.`);
210734
+ for (const line of result.preflight.stderr.trimEnd().split("\n")) console.log(` ${line}`);
210735
+ O2.step(`Rebuild it with \`${result.buildCommand}\` (its build output is likely stale or incomplete), then re-run \`truecourse guard run\`.`);
210736
+ printLoadErrors(result.loadErrors);
210737
+ gt("Aborted \u2014 the entry could not start; no scenarios ran.");
210738
+ process.exit(1);
210739
+ return;
210740
+ }
210497
210741
  case "ok":
210498
210742
  break;
210499
210743
  }
@@ -210576,6 +210820,13 @@ async function runGuardGenerate(opts = {}) {
210576
210820
  gt("Add or fix `.truecourse/scenarios/recipe.json` and retry.");
210577
210821
  process.exit(1);
210578
210822
  }
210823
+ if (guard.entryPreflight) {
210824
+ O2.error(`The recipe entry \`${guard.entryPreflight.entry}\` failed to start \u2014 every scenario would fail identically, so nothing was validated.`);
210825
+ for (const line of guard.entryPreflight.stderr.trimEnd().split("\n")) console.log(` ${line}`);
210826
+ O2.step(`Rebuild it with \`${guard.entryPreflight.buildCommand}\` (its build output is likely stale or incomplete), then re-run \`truecourse guard generate\`.`);
210827
+ gt("Aborted \u2014 the entry could not start; no scenarios were validated.");
210828
+ process.exit(1);
210829
+ }
210579
210830
  if (guard.recipe?.status === "discovered") {
210580
210831
  O2.step(`recipe wrote ${guard.recipe.wrotePath} \u2014 review and commit it`);
210581
210832
  }
@@ -210585,7 +210836,7 @@ async function runGuardGenerate(opts = {}) {
210585
210836
  return;
210586
210837
  }
210587
210838
  const report4 = readGuardResult(repoRoot5) ?? { ...guard, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
210588
- printGuardGenerateSummary(report4, path76.relative(repoRoot5, guardResultPath(repoRoot5)));
210839
+ printGuardGenerateSummary(report4, path77.relative(repoRoot5, guardResultPath(repoRoot5)));
210589
210840
  if (guard.written.length === 0 && guard.birthFindings.length === 0 && guard.errors.length === 0) {
210590
210841
  gt("No scenarios written.");
210591
210842
  return;
@@ -210783,7 +211034,7 @@ function printLoadErrors(loadErrors) {
210783
211034
 
210784
211035
  // tools/cli/src/commands/config.ts
210785
211036
  init_dist4();
210786
- import path77 from "node:path";
211037
+ import path78 from "node:path";
210787
211038
  var STAGE_LABEL = {
210788
211039
  "spec.relevance": "Spec \xB7 doc relevance",
210789
211040
  "spec.areaTag": "Spec \xB7 area tag",
@@ -210799,6 +211050,7 @@ var STAGE_LABEL = {
210799
211050
  "contract.gapJudge": "Contract \xB7 gap judge",
210800
211051
  "guard.extract": "Guard \xB7 claim extract",
210801
211052
  "guard.generate": "Guard \xB7 scenario gen",
211053
+ "guard.retry": "Guard \xB7 scenario retry",
210802
211054
  "guard.recipe": "Guard \xB7 recipe discover",
210803
211055
  "rules.violationGen": "Rules \xB7 violation gen"
210804
211056
  };
@@ -210813,7 +211065,7 @@ async function runConfigLlmShow(options = {}) {
210813
211065
  const repoRoot5 = options.cwd ?? process.cwd();
210814
211066
  const { stages, fallbackModel } = describeStageResolutions(repoRoot5);
210815
211067
  mt("LLM model resolution");
210816
- O2.info(`repoRoot ${path77.relative(process.cwd(), repoRoot5) || "."}`);
211068
+ O2.info(`repoRoot ${path78.relative(process.cwd(), repoRoot5) || "."}`);
210817
211069
  O2.info(`fallback ${fallbackModel ?? "(not configured)"}`);
210818
211070
  for (const stage of stages) {
210819
211071
  const label = STAGE_LABEL[stage.stageId];
@@ -210829,8 +211081,8 @@ async function runConfigLlmShow(options = {}) {
210829
211081
 
210830
211082
  // tools/cli/src/commands/hooks.ts
210831
211083
  import { execSync as execSync4 } from "node:child_process";
210832
- import fs67 from "node:fs";
210833
- import path78 from "node:path";
211084
+ import fs68 from "node:fs";
211085
+ import path79 from "node:path";
210834
211086
  init_dist4();
210835
211087
  init_paths();
210836
211088
  init_registry();
@@ -210864,17 +211116,17 @@ pre-commit:
210864
211116
  function findGitDir(from) {
210865
211117
  let dir = from;
210866
211118
  while (true) {
210867
- const gitPath = path78.join(dir, ".git");
210868
- if (fs67.existsSync(gitPath)) {
210869
- const stat = fs67.statSync(gitPath);
211119
+ const gitPath = path79.join(dir, ".git");
211120
+ if (fs68.existsSync(gitPath)) {
211121
+ const stat = fs68.statSync(gitPath);
210870
211122
  if (stat.isDirectory()) return gitPath;
210871
211123
  if (stat.isFile()) {
210872
- const content = fs67.readFileSync(gitPath, "utf-8").trim();
211124
+ const content = fs68.readFileSync(gitPath, "utf-8").trim();
210873
211125
  const match4 = content.match(/^gitdir:\s*(.+)$/);
210874
- if (match4) return path78.resolve(dir, match4[1]);
211126
+ if (match4) return path79.resolve(dir, match4[1]);
210875
211127
  }
210876
211128
  }
210877
- const parent = path78.dirname(dir);
211129
+ const parent = path79.dirname(dir);
210878
211130
  if (parent === dir) return null;
210879
211131
  dir = parent;
210880
211132
  }
@@ -210882,18 +211134,18 @@ function findGitDir(from) {
210882
211134
  function findProjectRoot(from) {
210883
211135
  let dir = from;
210884
211136
  while (true) {
210885
- if (fs67.existsSync(path78.join(dir, ".git"))) return dir;
210886
- const parent = path78.dirname(dir);
211137
+ if (fs68.existsSync(path79.join(dir, ".git"))) return dir;
211138
+ const parent = path79.dirname(dir);
210887
211139
  if (parent === dir) return null;
210888
211140
  dir = parent;
210889
211141
  }
210890
211142
  }
210891
211143
  function loadConfig(projectRoot) {
210892
- const configPath = path78.join(projectRoot, ".truecourse", "hooks.yaml");
210893
- if (!fs67.existsSync(configPath)) return null;
211144
+ const configPath = path79.join(projectRoot, ".truecourse", "hooks.yaml");
211145
+ if (!fs68.existsSync(configPath)) return null;
210894
211146
  let parsed;
210895
211147
  try {
210896
- const raw = fs67.readFileSync(configPath, "utf-8");
211148
+ const raw = fs68.readFileSync(configPath, "utf-8");
210897
211149
  parsed = jsYaml.load(raw) || {};
210898
211150
  } catch (err) {
210899
211151
  console.error(`Error parsing ${configPath}: ${err.message}`);
@@ -210944,11 +211196,11 @@ async function runHooksInstall() {
210944
211196
  } else {
210945
211197
  console.log(INSTALL_WARNING);
210946
211198
  }
210947
- const hooksDir = path78.join(gitDir, "hooks");
210948
- fs67.mkdirSync(hooksDir, { recursive: true });
210949
- const hookPath = path78.join(hooksDir, "pre-commit");
210950
- if (fs67.existsSync(hookPath)) {
210951
- const existing = fs67.readFileSync(hookPath, "utf-8");
211199
+ const hooksDir = path79.join(gitDir, "hooks");
211200
+ fs68.mkdirSync(hooksDir, { recursive: true });
211201
+ const hookPath = path79.join(hooksDir, "pre-commit");
211202
+ if (fs68.existsSync(hookPath)) {
211203
+ const existing = fs68.readFileSync(hookPath, "utf-8");
210952
211204
  if (!existing.includes(HOOK_IDENTIFIER)) {
210953
211205
  console.error(
210954
211206
  "Error: A pre-commit hook already exists and was not installed by TrueCourse."
@@ -210958,16 +211210,16 @@ async function runHooksInstall() {
210958
211210
  process.exit(1);
210959
211211
  }
210960
211212
  }
210961
- fs67.writeFileSync(hookPath, HOOK_SCRIPT, { mode: 493 });
211213
+ fs68.writeFileSync(hookPath, HOOK_SCRIPT, { mode: 493 });
210962
211214
  console.log("TrueCourse pre-commit hook installed.");
210963
211215
  console.log(` ${hookPath}`);
210964
211216
  const projectRoot = findProjectRoot(process.cwd());
210965
211217
  if (projectRoot) {
210966
- const cfgDir = path78.join(projectRoot, ".truecourse");
210967
- const cfgPath = path78.join(cfgDir, "hooks.yaml");
210968
- if (!fs67.existsSync(cfgPath)) {
210969
- fs67.mkdirSync(cfgDir, { recursive: true });
210970
- fs67.writeFileSync(cfgPath, HOOKS_YAML_TEMPLATE);
211218
+ const cfgDir = path79.join(projectRoot, ".truecourse");
211219
+ const cfgPath = path79.join(cfgDir, "hooks.yaml");
211220
+ if (!fs68.existsSync(cfgPath)) {
211221
+ fs68.mkdirSync(cfgDir, { recursive: true });
211222
+ fs68.writeFileSync(cfgPath, HOOKS_YAML_TEMPLATE);
210971
211223
  console.log(` ${cfgPath} (starter config \u2014 edit to customize, commit to share with the team)`);
210972
211224
  }
210973
211225
  }
@@ -210978,17 +211230,17 @@ function runHooksUninstall() {
210978
211230
  console.error("Error: Not a git repository.");
210979
211231
  process.exit(1);
210980
211232
  }
210981
- const hookPath = path78.join(gitDir, "hooks", "pre-commit");
210982
- if (!fs67.existsSync(hookPath)) {
211233
+ const hookPath = path79.join(gitDir, "hooks", "pre-commit");
211234
+ if (!fs68.existsSync(hookPath)) {
210983
211235
  console.log("No pre-commit hook installed.");
210984
211236
  return;
210985
211237
  }
210986
- const content = fs67.readFileSync(hookPath, "utf-8");
211238
+ const content = fs68.readFileSync(hookPath, "utf-8");
210987
211239
  if (!content.includes(HOOK_IDENTIFIER)) {
210988
211240
  console.error("Error: The pre-commit hook was not installed by TrueCourse. Leaving it in place.");
210989
211241
  process.exit(1);
210990
211242
  }
210991
- fs67.unlinkSync(hookPath);
211243
+ fs68.unlinkSync(hookPath);
210992
211244
  console.log("TrueCourse pre-commit hook removed.");
210993
211245
  }
210994
211246
  function runHooksStatus() {
@@ -210997,8 +211249,8 @@ function runHooksStatus() {
210997
211249
  console.error("Error: Not a git repository.");
210998
211250
  process.exit(1);
210999
211251
  }
211000
- const hookPath = path78.join(gitDir, "hooks", "pre-commit");
211001
- const installed = fs67.existsSync(hookPath) && fs67.readFileSync(hookPath, "utf-8").includes(HOOK_IDENTIFIER);
211252
+ const hookPath = path79.join(gitDir, "hooks", "pre-commit");
211253
+ const installed = fs68.existsSync(hookPath) && fs68.readFileSync(hookPath, "utf-8").includes(HOOK_IDENTIFIER);
211002
211254
  if (installed) {
211003
211255
  console.log("TrueCourse pre-commit hook: installed");
211004
211256
  console.log(` ${hookPath}`);
@@ -211107,7 +211359,7 @@ async function runHooksRun() {
211107
211359
 
211108
211360
  // tools/cli/src/index.ts
211109
211361
  var program2 = new Command();
211110
- program2.name("truecourse").version("0.7.0-next.1").description("TrueCourse CLI \u2014 analyze your repository and open the dashboard");
211362
+ program2.name("truecourse").version("0.7.0-next.3").description("TrueCourse CLI \u2014 analyze your repository and open the dashboard");
211111
211363
  var dashboardCmd = program2.command("dashboard").description("Start the TrueCourse dashboard and open it in your browser").option("--reconfigure", "Re-prompt for console vs background service mode").option("--service", "Run as a background service (skips mode prompt)").option("--console", "Run in this terminal (skips mode prompt)").action(async (options) => {
211112
211364
  if (options.service && options.console) {
211113
211365
  console.error("error: --service and --console are mutually exclusive");