truecourse 0.7.0-next.7 → 0.7.0-next.9
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 +1144 -594
- package/package.json +1 -1
- package/public/assets/index-B2b9Ua5r.css +1 -0
- package/public/assets/{index-D7hFPhQQ.js → index-T8VBc6FT.js} +213 -213
- package/public/index.html +2 -2
- package/roslyn-host/csharp-roslyn-host.dll +0 -0
- package/roslyn-host/csharp-roslyn-host.pdb +0 -0
- package/server.mjs +1382 -776
- package/public/assets/index-CMCPeAwv.css +0 -1
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
|
|
976
|
-
var
|
|
975
|
+
var path81 = __require("node:path");
|
|
976
|
+
var fs72 = __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 =
|
|
1909
|
-
if (
|
|
1910
|
-
if (sourceExt.includes(
|
|
1908
|
+
const localBin = path81.resolve(baseDir, baseName);
|
|
1909
|
+
if (fs72.existsSync(localBin)) return localBin;
|
|
1910
|
+
if (sourceExt.includes(path81.extname(baseName))) return void 0;
|
|
1911
1911
|
const foundExt = sourceExt.find(
|
|
1912
|
-
(ext2) =>
|
|
1912
|
+
(ext2) => fs72.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 =
|
|
1924
|
+
resolvedScriptPath = fs72.realpathSync(this._scriptPath);
|
|
1925
1925
|
} catch (err) {
|
|
1926
1926
|
resolvedScriptPath = this._scriptPath;
|
|
1927
1927
|
}
|
|
1928
|
-
executableDir =
|
|
1929
|
-
|
|
1928
|
+
executableDir = path81.resolve(
|
|
1929
|
+
path81.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 =
|
|
1936
|
+
const legacyName = path81.basename(
|
|
1937
1937
|
this._scriptPath,
|
|
1938
|
-
|
|
1938
|
+
path81.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(
|
|
1949
|
+
launchWithNode = sourceExt.includes(path81.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 =
|
|
2789
|
+
this._name = path81.basename(filename, path81.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(
|
|
2804
|
-
if (
|
|
2805
|
-
this._executableDir =
|
|
2803
|
+
executableDir(path82) {
|
|
2804
|
+
if (path82 === void 0) return this._executableDir;
|
|
2805
|
+
this._executableDir = path82;
|
|
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:
|
|
5210
|
-
const fullPath = [...
|
|
5209
|
+
const { data, path: path81, errorMaps, issueData } = params;
|
|
5210
|
+
const fullPath = [...path81, ...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,
|
|
5518
|
+
constructor(parent, value, path81, key4) {
|
|
5519
5519
|
this._cachedPath = [];
|
|
5520
5520
|
this.parent = parent;
|
|
5521
5521
|
this.data = value;
|
|
5522
|
-
this._path =
|
|
5522
|
+
this._path = path81;
|
|
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(
|
|
11980
|
-
log2(`checking %s`,
|
|
11979
|
+
function check(path81, isFile, isDirectory) {
|
|
11980
|
+
log2(`checking %s`, path81);
|
|
11981
11981
|
try {
|
|
11982
|
-
const stat = fs_1.statSync(
|
|
11982
|
+
const stat = fs_1.statSync(path81);
|
|
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(
|
|
12003
|
-
return check(
|
|
12002
|
+
function exists2(path81, type2 = exports.READABLE) {
|
|
12003
|
+
return check(path81, (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(
|
|
12077
|
-
return
|
|
12076
|
+
function isPathSpec(path81) {
|
|
12077
|
+
return path81 instanceof String && cache.has(path81);
|
|
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(
|
|
12122
|
-
return (0, import_file_exists.exists)(
|
|
12121
|
+
function folderExists(path81) {
|
|
12122
|
+
return (0, import_file_exists.exists)(path81, 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(
|
|
12314
|
-
return /^\.(git)?$/.test(
|
|
12313
|
+
parser(path81) {
|
|
12314
|
+
return /^\.(git)?$/.test(path81.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 [
|
|
12571
|
-
paths.add(
|
|
12572
|
-
(results[
|
|
12570
|
+
const [path81, line, preview] = input.split(NULL);
|
|
12571
|
+
paths.add(path81);
|
|
12572
|
+
(results[path81] = results[path81] || []).push({
|
|
12573
12573
|
line: asNumber(line),
|
|
12574
|
-
path:
|
|
12574
|
+
path: path81,
|
|
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,
|
|
12871
|
+
function parseInit(bare, path81, text4) {
|
|
12872
12872
|
const response = String(text4).trim();
|
|
12873
12873
|
let result;
|
|
12874
12874
|
if (result = initResponseRegex.exec(response)) {
|
|
12875
|
-
return new InitSummary(bare,
|
|
12875
|
+
return new InitSummary(bare, path81, false, result[1]);
|
|
12876
12876
|
}
|
|
12877
12877
|
if (result = reInitResponseRegex.exec(response)) {
|
|
12878
|
-
return new InitSummary(bare,
|
|
12878
|
+
return new InitSummary(bare, path81, true, result[1]);
|
|
12879
12879
|
}
|
|
12880
12880
|
let gitDir = "";
|
|
12881
12881
|
const tokens = response.split(" ");
|
|
@@ -12886,12 +12886,12 @@ function parseInit(bare, path80, text4) {
|
|
|
12886
12886
|
break;
|
|
12887
12887
|
}
|
|
12888
12888
|
}
|
|
12889
|
-
return new InitSummary(bare,
|
|
12889
|
+
return new InitSummary(bare, path81, /^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,
|
|
12894
|
+
function initTask(bare = false, path81, 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, path80, customArgs) {
|
|
|
12900
12900
|
commands,
|
|
12901
12901
|
format: "utf-8",
|
|
12902
12902
|
parser(text4) {
|
|
12903
|
-
return parseInit(commands.includes("--bare"),
|
|
12903
|
+
return parseInit(commands.includes("--bare"), path81, 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,
|
|
13182
|
+
function data(index, workingDir, path81) {
|
|
13183
13183
|
const raw = `${index}${workingDir}`;
|
|
13184
13184
|
const handler = parsers6.get(raw);
|
|
13185
13185
|
if (handler) {
|
|
13186
|
-
handler(result,
|
|
13186
|
+
handler(result, path81);
|
|
13187
13187
|
}
|
|
13188
13188
|
if (raw !== "##" && raw !== "!!") {
|
|
13189
|
-
result.files.push(new FileStatusSummary(
|
|
13189
|
+
result.files.push(new FileStatusSummary(path81, 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
|
|
13377
|
-
return
|
|
13376
|
+
const path81 = input.trim().replace(/^["']|["']$/g, "");
|
|
13377
|
+
return path81 && normalize(path81);
|
|
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,
|
|
13517
|
-
return subModuleTask(["add", repo,
|
|
13516
|
+
function addSubModuleTask(repo, path81) {
|
|
13517
|
+
return subModuleTask(["add", repo, path81]);
|
|
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,
|
|
14829
|
+
constructor(bare, path81, existing, gitDir) {
|
|
14830
14830
|
this.bare = bare;
|
|
14831
|
-
this.path =
|
|
14831
|
+
this.path = path81;
|
|
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(
|
|
15366
|
-
this.path =
|
|
15365
|
+
constructor(path81, index, working_dir) {
|
|
15366
|
+
this.path = path81;
|
|
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(
|
|
15370
|
+
const detail = fromPathRegex.exec(path81) || [null, path81, path81];
|
|
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(
|
|
15633
|
+
hashObject(path81, write) {
|
|
15634
15634
|
return this._runTask(
|
|
15635
|
-
hashObjectTask(
|
|
15635
|
+
hashObjectTask(path81, 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,
|
|
16273
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
16272
|
+
Git2.prototype.submoduleAdd = function(repo, path81, then) {
|
|
16273
|
+
return this._runTask(addSubModuleTask2(repo, path81), 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(
|
|
16899
|
+
test(path81, 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(
|
|
16908
|
+
const matched = rule[mode].test(path81);
|
|
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 = (
|
|
16930
|
-
if (!isString(
|
|
16929
|
+
var checkPath = (path81, originalPath, doThrow) => {
|
|
16930
|
+
if (!isString(path81)) {
|
|
16931
16931
|
return doThrow(
|
|
16932
16932
|
`path must be a string, but got \`${originalPath}\``,
|
|
16933
16933
|
TypeError
|
|
16934
16934
|
);
|
|
16935
16935
|
}
|
|
16936
|
-
if (!
|
|
16936
|
+
if (!path81) {
|
|
16937
16937
|
return doThrow(`path must not be empty`, TypeError);
|
|
16938
16938
|
}
|
|
16939
|
-
if (checkPath.isNotRelative(
|
|
16939
|
+
if (checkPath.isNotRelative(path81)) {
|
|
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 = (
|
|
16948
|
+
var isNotRelative = (path81) => REGEX_TEST_INVALID_PATH.test(path81);
|
|
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
|
|
16978
|
+
const path81 = originalPath && checkPath.convert(originalPath);
|
|
16979
16979
|
checkPath(
|
|
16980
|
-
|
|
16980
|
+
path81,
|
|
16981
16981
|
originalPath,
|
|
16982
16982
|
this._strictPathCheck ? throwError2 : RETURN_FALSE
|
|
16983
16983
|
);
|
|
16984
|
-
return this._t(
|
|
16984
|
+
return this._t(path81, cache3, checkUnignored, slices);
|
|
16985
16985
|
}
|
|
16986
|
-
checkIgnore(
|
|
16987
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
16988
|
-
return this.test(
|
|
16986
|
+
checkIgnore(path81) {
|
|
16987
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path81)) {
|
|
16988
|
+
return this.test(path81);
|
|
16989
16989
|
}
|
|
16990
|
-
const slices =
|
|
16990
|
+
const slices = path81.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(
|
|
17003
|
+
return this._rules.test(path81, false, MODE_CHECK_IGNORE);
|
|
17004
17004
|
}
|
|
17005
|
-
_t(
|
|
17006
|
-
if (
|
|
17007
|
-
return cache3[
|
|
17005
|
+
_t(path81, cache3, checkUnignored, slices) {
|
|
17006
|
+
if (path81 in cache3) {
|
|
17007
|
+
return cache3[path81];
|
|
17008
17008
|
}
|
|
17009
17009
|
if (!slices) {
|
|
17010
|
-
slices =
|
|
17010
|
+
slices = path81.split(SLASH).filter(Boolean);
|
|
17011
17011
|
}
|
|
17012
17012
|
slices.pop();
|
|
17013
17013
|
if (!slices.length) {
|
|
17014
|
-
return cache3[
|
|
17014
|
+
return cache3[path81] = this._rules.test(path81, 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[
|
|
17022
|
+
return cache3[path81] = parent.ignored ? parent : this._rules.test(path81, checkUnignored, MODE_IGNORE);
|
|
17023
17023
|
}
|
|
17024
|
-
ignores(
|
|
17025
|
-
return this._test(
|
|
17024
|
+
ignores(path81) {
|
|
17025
|
+
return this._test(path81, this._ignoreCache, false).ignored;
|
|
17026
17026
|
}
|
|
17027
17027
|
createFilter() {
|
|
17028
|
-
return (
|
|
17028
|
+
return (path81) => !this.ignores(path81);
|
|
17029
17029
|
}
|
|
17030
17030
|
filter(paths) {
|
|
17031
17031
|
return makeArray(paths).filter(this.createFilter());
|
|
17032
17032
|
}
|
|
17033
17033
|
// @returns {TestResult}
|
|
17034
|
-
test(
|
|
17035
|
-
return this._test(
|
|
17034
|
+
test(path81) {
|
|
17035
|
+
return this._test(path81, this._testCache, true);
|
|
17036
17036
|
}
|
|
17037
17037
|
};
|
|
17038
17038
|
var factory = (options) => new Ignore(options);
|
|
17039
|
-
var isPathValid = (
|
|
17039
|
+
var isPathValid = (path81) => checkPath(path81 && checkPath.convert(path81), path81, 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 = (
|
|
17044
|
+
checkPath.isNotRelative = (path81) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path81) || isNotRelative(path81);
|
|
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
|
|
18785
|
+
let path81 = "/";
|
|
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
|
-
|
|
18791
|
+
path81 = value.text.replace(/^["']|["']$/g, "");
|
|
18792
18792
|
}
|
|
18793
18793
|
}
|
|
18794
18794
|
}
|
|
18795
18795
|
return {
|
|
18796
|
-
path:
|
|
18796
|
+
path: path81,
|
|
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
|
|
18820
|
+
let path81 = null;
|
|
18821
18821
|
let httpMethod = methodName3 === "route" ? "GET" : methodName3.toUpperCase();
|
|
18822
18822
|
for (const arg of innerArgs.namedChildren) {
|
|
18823
|
-
if (!
|
|
18824
|
-
|
|
18823
|
+
if (!path81 && arg.type === "string") {
|
|
18824
|
+
path81 = 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 (!
|
|
18836
|
+
if (!path81)
|
|
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:
|
|
18843
|
+
path: path81,
|
|
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
|
|
18906
|
-
if (name &&
|
|
18905
|
+
const path81 = args ? extractFirstStringArg(args) : null;
|
|
18906
|
+
if (name && path81) {
|
|
18907
18907
|
const receiver = fn.childForFieldName("expression")?.text ?? "";
|
|
18908
18908
|
const parentPrefix = prefixes.get(receiver) ?? "";
|
|
18909
|
-
prefixes.set(name, joinRoute(parentPrefix,
|
|
18909
|
+
prefixes.set(name, joinRoute(parentPrefix, path81));
|
|
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
|
|
18934
|
-
if (
|
|
18935
|
-
return
|
|
18933
|
+
const path81 = extractFirstStringArg(args);
|
|
18934
|
+
if (path81)
|
|
18935
|
+
return path81;
|
|
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
|
|
18959
|
-
if (
|
|
18960
|
-
routePath =
|
|
18958
|
+
const path81 = extractFirstStringArg(args);
|
|
18959
|
+
if (path81)
|
|
18960
|
+
routePath = path81;
|
|
18961
18961
|
}
|
|
18962
18962
|
} else if (name === "Route" && !routePath) {
|
|
18963
18963
|
const args = childOfType(attr, "attribute_argument_list");
|
|
18964
18964
|
if (args) {
|
|
18965
|
-
const
|
|
18966
|
-
if (
|
|
18967
|
-
routePath =
|
|
18965
|
+
const path81 = extractFirstStringArg(args);
|
|
18966
|
+
if (path81)
|
|
18967
|
+
routePath = path81;
|
|
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
|
|
19002
|
-
if (
|
|
19001
|
+
const path81 = extractFirstStringArg(argsNode);
|
|
19002
|
+
if (path81 === 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,
|
|
19006
|
+
let fullPath = joinRoute(prefix, path81);
|
|
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,
|
|
19033
|
+
function joinRoute(prefix, path81) {
|
|
19034
19034
|
const p2 = prefix.replace(/\/$/, "");
|
|
19035
|
-
const s =
|
|
19035
|
+
const s = path81.replace(/^\//, "");
|
|
19036
19036
|
if (!p2)
|
|
19037
|
-
return
|
|
19037
|
+
return path81;
|
|
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
|
|
19147
|
-
if (!
|
|
19146
|
+
const path81 = extractStringLiteral(firstArg);
|
|
19147
|
+
if (!path81)
|
|
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:
|
|
19160
|
+
path: path81,
|
|
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
|
|
19178
|
-
if (!
|
|
19177
|
+
const path81 = extractStringLiteral(firstArg);
|
|
19178
|
+
if (!path81)
|
|
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:
|
|
19187
|
+
path: path81,
|
|
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(
|
|
21719
|
-
const exact = byFullName.get(
|
|
21718
|
+
function resolveQualified(path81) {
|
|
21719
|
+
const exact = byFullName.get(path81);
|
|
21720
21720
|
if (exact)
|
|
21721
21721
|
return exact;
|
|
21722
|
-
const parts =
|
|
21722
|
+
const parts = path81.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
|
|
21737
|
-
return resolveQualified(
|
|
21736
|
+
const path81 = aliasTarget2 ? `${aliasTarget2}${ref.name.slice(firstDot)}` : ref.name;
|
|
21737
|
+
return resolveQualified(path81).filter((d3) => isDeclVisibleFrom(d3, ctx.project, fileProjects.get(d3.filePath)));
|
|
21738
21738
|
}
|
|
21739
21739
|
const aliasTarget = aliases.get(ref.name);
|
|
21740
21740
|
if (aliasTarget) {
|
|
@@ -24855,9 +24855,9 @@ function detectDockerComposeServices(rootPath, allFiles) {
|
|
|
24855
24855
|
];
|
|
24856
24856
|
let composePath2 = null;
|
|
24857
24857
|
for (const file of composeFiles) {
|
|
24858
|
-
const
|
|
24859
|
-
if (existsSync7(
|
|
24860
|
-
composePath2 =
|
|
24858
|
+
const path81 = join8(rootPath, file);
|
|
24859
|
+
if (existsSync7(path81)) {
|
|
24860
|
+
composePath2 = path81;
|
|
24861
24861
|
break;
|
|
24862
24862
|
}
|
|
24863
24863
|
}
|
|
@@ -28077,9 +28077,9 @@ function findSimpleCycles(component, componentSet, adjacency) {
|
|
|
28077
28077
|
for (const next of successors) {
|
|
28078
28078
|
if (!componentSet.has(next))
|
|
28079
28079
|
continue;
|
|
28080
|
-
if (next === start &&
|
|
28081
|
-
const chain = [...
|
|
28082
|
-
const minNode =
|
|
28080
|
+
if (next === start && path81.length >= 2) {
|
|
28081
|
+
const chain = [...path81, start];
|
|
28082
|
+
const minNode = path81.reduce((a, b) => a < b ? a : b);
|
|
28083
28083
|
if (minNode === start) {
|
|
28084
28084
|
cycles.push(chain);
|
|
28085
28085
|
}
|
|
@@ -28087,15 +28087,15 @@ function findSimpleCycles(component, componentSet, adjacency) {
|
|
|
28087
28087
|
}
|
|
28088
28088
|
if (!visited.has(next) && !seen.has(next)) {
|
|
28089
28089
|
visited.add(next);
|
|
28090
|
-
|
|
28090
|
+
path81.push(next);
|
|
28091
28091
|
dfs2(next);
|
|
28092
|
-
|
|
28092
|
+
path81.pop();
|
|
28093
28093
|
visited.delete(next);
|
|
28094
28094
|
}
|
|
28095
28095
|
}
|
|
28096
28096
|
};
|
|
28097
28097
|
var dfs = dfs2;
|
|
28098
|
-
const
|
|
28098
|
+
const path81 = [start];
|
|
28099
28099
|
const visited = /* @__PURE__ */ new Set([start]);
|
|
28100
28100
|
dfs2(start);
|
|
28101
28101
|
seen.add(start);
|
|
@@ -28117,7 +28117,7 @@ function findShortestCycle(start, componentSet, adjacency) {
|
|
|
28117
28117
|
visited.add(next);
|
|
28118
28118
|
}
|
|
28119
28119
|
while (queue.length > 0) {
|
|
28120
|
-
const { node: node2, path:
|
|
28120
|
+
const { node: node2, path: path81 } = queue.shift();
|
|
28121
28121
|
const nexts = adjacency.get(node2);
|
|
28122
28122
|
if (!nexts)
|
|
28123
28123
|
continue;
|
|
@@ -28125,11 +28125,11 @@ function findShortestCycle(start, componentSet, adjacency) {
|
|
|
28125
28125
|
if (!componentSet.has(next))
|
|
28126
28126
|
continue;
|
|
28127
28127
|
if (next === start) {
|
|
28128
|
-
return [...
|
|
28128
|
+
return [...path81, start];
|
|
28129
28129
|
}
|
|
28130
28130
|
if (!visited.has(next)) {
|
|
28131
28131
|
visited.add(next);
|
|
28132
|
-
queue.push({ node: next, path: [...
|
|
28132
|
+
queue.push({ node: next, path: [...path81, next] });
|
|
28133
28133
|
}
|
|
28134
28134
|
}
|
|
28135
28135
|
}
|
|
@@ -105838,11 +105838,8 @@ var init_guard = __esm({
|
|
|
105838
105838
|
});
|
|
105839
105839
|
|
|
105840
105840
|
// packages/shared/dist/spec/overlap-resolution.js
|
|
105841
|
-
function
|
|
105842
|
-
return
|
|
105843
|
-
const samePair = r.older === a && r.newer === b || r.older === b && r.newer === a;
|
|
105844
|
-
return samePair && (r.scope === void 0 || areas.includes(r.scope));
|
|
105845
|
-
});
|
|
105841
|
+
function normalizeQuote(text4) {
|
|
105842
|
+
return text4.replace(/[`*_~]/g, "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
105846
105843
|
}
|
|
105847
105844
|
function dedupeCrossAreaOverlaps(entries) {
|
|
105848
105845
|
const byPair = /* @__PURE__ */ new Map();
|
|
@@ -105916,9 +105913,23 @@ function dedupeCrossAreaOverlaps(entries) {
|
|
|
105916
105913
|
});
|
|
105917
105914
|
return merged;
|
|
105918
105915
|
}
|
|
105916
|
+
function resolutionMatchesConflict(r, a, b, sections) {
|
|
105917
|
+
if (!samePair(r.docA, r.docB, a, b))
|
|
105918
|
+
return false;
|
|
105919
|
+
const rSide = (doc) => doc === r.docA ? { anchor: r.anchorA, quote: r.quoteA } : { anchor: r.anchorB, quote: r.quoteB };
|
|
105920
|
+
const cSide = (doc) => (sections ?? []).find((s) => s.doc === doc);
|
|
105921
|
+
const bothHaveQuotes = !!r.quoteA && !!r.quoteB && !!cSide(a)?.quote && !!cSide(b)?.quote;
|
|
105922
|
+
if (bothHaveQuotes) {
|
|
105923
|
+
const quoteMatch = (doc) => normalizeQuote(rSide(doc).quote ?? "") === normalizeQuote(cSide(doc)?.quote ?? "");
|
|
105924
|
+
return quoteMatch(a) && quoteMatch(b);
|
|
105925
|
+
}
|
|
105926
|
+
const anchorMatch = (doc) => anchorKey(rSide(doc).anchor) === anchorKey(cSide(doc)?.heading);
|
|
105927
|
+
return anchorMatch(a) && anchorMatch(b);
|
|
105928
|
+
}
|
|
105929
|
+
function matchResolution(decisions, a, b, sections) {
|
|
105930
|
+
return (decisions.conflictResolutions ?? []).find((r) => resolutionMatchesConflict(r, a, b, sections));
|
|
105931
|
+
}
|
|
105919
105932
|
function buildCorpusConflicts(corpus, decisions) {
|
|
105920
|
-
const userRelations = decisions.relations ?? [];
|
|
105921
|
-
const effectiveRels = [...corpus.relations, ...userRelations];
|
|
105922
105933
|
const excludes = new Set(decisions.manualExcludes ?? []);
|
|
105923
105934
|
const entries = [];
|
|
105924
105935
|
for (const area of corpus.areas)
|
|
@@ -105928,43 +105939,46 @@ function buildCorpusConflicts(corpus, decisions) {
|
|
|
105928
105939
|
const flagged = [];
|
|
105929
105940
|
for (const m of mergedOverlaps) {
|
|
105930
105941
|
const [a, b] = m.overlap.docs;
|
|
105931
|
-
const
|
|
105932
|
-
const userRelation = coveringRelationInAreas(userRelations, a, b, m.areas);
|
|
105942
|
+
const sections = m.overlap.sections ? [...m.overlap.sections] : void 0;
|
|
105933
105943
|
const excludedRef = excludes.has(a) ? a : excludes.has(b) ? b : void 0;
|
|
105944
|
+
const resolution = matchResolution(decisions, a, b, sections);
|
|
105934
105945
|
flagged.push({
|
|
105935
105946
|
area: m.area,
|
|
105936
105947
|
areas: m.areas,
|
|
105937
105948
|
a,
|
|
105938
105949
|
b,
|
|
105939
105950
|
note: m.overlap.note ?? "",
|
|
105940
|
-
|
|
105941
|
-
|
|
105942
|
-
...
|
|
105943
|
-
...
|
|
105944
|
-
...excludedRef ? { excludedRef } : {}
|
|
105951
|
+
...sections ? { sections } : {},
|
|
105952
|
+
resolved: excludedRef !== void 0 || resolution !== void 0,
|
|
105953
|
+
...excludedRef ? { excludedRef } : {},
|
|
105954
|
+
...resolution ? { resolution } : {}
|
|
105945
105955
|
});
|
|
105946
105956
|
}
|
|
105947
|
-
|
|
105948
|
-
const samePair = o.a === r.older && o.b === r.newer || o.a === r.newer && o.b === r.older;
|
|
105949
|
-
return samePair && (r.scope === void 0 || o.areas.includes(r.scope));
|
|
105950
|
-
});
|
|
105951
|
-
const synthesized = userRelations.filter((r) => !coversFlagged(r)).map((r) => ({
|
|
105952
|
-
area: r.scope ?? "",
|
|
105953
|
-
areas: r.scope ? [r.scope] : [],
|
|
105954
|
-
a: r.older,
|
|
105955
|
-
b: r.newer,
|
|
105956
|
-
note: r.note ?? "",
|
|
105957
|
-
resolved: true,
|
|
105958
|
-
synthesized: true,
|
|
105959
|
-
relation: r,
|
|
105960
|
-
userRelation: r
|
|
105961
|
-
}));
|
|
105962
|
-
return [...flagged, ...synthesized];
|
|
105957
|
+
return flagged;
|
|
105963
105958
|
}
|
|
105964
105959
|
function openConflicts(corpus, decisions) {
|
|
105965
105960
|
return buildCorpusConflicts(corpus, decisions).filter((c2) => !c2.resolved);
|
|
105966
105961
|
}
|
|
105967
|
-
|
|
105962
|
+
function orphanedConflictResolutions(corpus, decisions) {
|
|
105963
|
+
const resolutions = decisions.conflictResolutions ?? [];
|
|
105964
|
+
if (resolutions.length === 0)
|
|
105965
|
+
return [];
|
|
105966
|
+
const conflicts2 = buildCorpusConflicts(corpus, decisions);
|
|
105967
|
+
return resolutions.filter((r) => !conflicts2.some((c2) => resolutionMatchesConflict(r, c2.a, c2.b, c2.sections)));
|
|
105968
|
+
}
|
|
105969
|
+
function suppressedClaims(corpus, decisions) {
|
|
105970
|
+
const out = [];
|
|
105971
|
+
for (const c2 of buildCorpusConflicts(corpus, decisions)) {
|
|
105972
|
+
const r = c2.resolution;
|
|
105973
|
+
if (!r || r.verdict === "dismissed")
|
|
105974
|
+
continue;
|
|
105975
|
+
const loser = r.verdict === "a" ? { doc: r.docB, anchor: r.anchorB, quote: r.quoteB } : { doc: r.docA, anchor: r.anchorA, quote: r.quoteA };
|
|
105976
|
+
if (loser.quote && loser.quote.trim())
|
|
105977
|
+
out.push({ doc: loser.doc, anchor: loser.anchor, quote: loser.quote });
|
|
105978
|
+
}
|
|
105979
|
+
return out;
|
|
105980
|
+
}
|
|
105981
|
+
var PREAMBLE_PTR, NUL, unorderedPairKey, sectionPointerKeys, preambleCount, samePair, anchorKey;
|
|
105968
105982
|
var init_overlap_resolution = __esm({
|
|
105969
105983
|
"packages/shared/dist/spec/overlap-resolution.js"() {
|
|
105970
105984
|
"use strict";
|
|
@@ -105973,6 +105987,8 @@ var init_overlap_resolution = __esm({
|
|
|
105973
105987
|
unorderedPairKey = (a, b) => a < b ? `${a}${NUL}${b}` : `${b}${NUL}${a}`;
|
|
105974
105988
|
sectionPointerKeys = (ov) => (ov.sections ?? []).map((s) => `${s.doc}${NUL}${s.heading ?? PREAMBLE_PTR}`);
|
|
105975
105989
|
preambleCount = (ov) => (ov.sections ?? []).filter((s) => s.heading === null || s.heading === void 0).length;
|
|
105990
|
+
samePair = (a1, b1, a2, b2) => a1 === a2 && b1 === b2 || a1 === b2 && b1 === a2;
|
|
105991
|
+
anchorKey = (h) => h === null || h === void 0 ? null : h.replace(/[`*_~]/g, "").trim().toLowerCase();
|
|
105976
105992
|
}
|
|
105977
105993
|
});
|
|
105978
105994
|
|
|
@@ -112402,14 +112418,14 @@ var init_missing_error_status_code = __esm({
|
|
|
112402
112418
|
});
|
|
112403
112419
|
|
|
112404
112420
|
// packages/analyzer/dist/rules/architecture/visitors/javascript/route-without-auth-middleware.js
|
|
112405
|
-
function isPublicPath(
|
|
112406
|
-
return PUBLIC_PATH_PATTERNS.some((re2) => re2.test(
|
|
112421
|
+
function isPublicPath(path81) {
|
|
112422
|
+
return PUBLIC_PATH_PATTERNS.some((re2) => re2.test(path81));
|
|
112407
112423
|
}
|
|
112408
|
-
function isUrlCredentialAuthedPath(
|
|
112409
|
-
return URL_CREDENTIAL_PARAMS.test(
|
|
112424
|
+
function isUrlCredentialAuthedPath(path81) {
|
|
112425
|
+
return URL_CREDENTIAL_PARAMS.test(path81);
|
|
112410
112426
|
}
|
|
112411
|
-
function isApiDocsPath(
|
|
112412
|
-
return API_DOCS_PATH.test(
|
|
112427
|
+
function isApiDocsPath(path81) {
|
|
112428
|
+
return API_DOCS_PATH.test(path81);
|
|
112413
112429
|
}
|
|
112414
112430
|
function isFrameworkRequestHandler(arg) {
|
|
112415
112431
|
if (!arg)
|
|
@@ -112558,14 +112574,14 @@ var init_route_without_auth_middleware = __esm({
|
|
|
112558
112574
|
return null;
|
|
112559
112575
|
const firstArg = args.namedChildren[0];
|
|
112560
112576
|
if (firstArg?.type === "string" || firstArg?.type === "template_string") {
|
|
112561
|
-
const
|
|
112562
|
-
if (isPublicPath(
|
|
112577
|
+
const path81 = firstArg.text.replace(/^['"`]|['"`]$/g, "");
|
|
112578
|
+
if (isPublicPath(path81))
|
|
112563
112579
|
return null;
|
|
112564
|
-
if (isUrlCredentialAuthedPath(
|
|
112580
|
+
if (isUrlCredentialAuthedPath(path81))
|
|
112565
112581
|
return null;
|
|
112566
|
-
if (isApiDocsPath(
|
|
112582
|
+
if (isApiDocsPath(path81))
|
|
112567
112583
|
return null;
|
|
112568
|
-
if (
|
|
112584
|
+
if (path81 === "*" || path81 === "(.*)" || path81 === "/*") {
|
|
112569
112585
|
if (isFrameworkRequestHandler(args.namedChildren[args.namedChildren.length - 1])) {
|
|
112570
112586
|
return null;
|
|
112571
112587
|
}
|
|
@@ -147471,8 +147487,8 @@ var require_windows = __commonJS({
|
|
|
147471
147487
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
|
|
147472
147488
|
module.exports = isexe;
|
|
147473
147489
|
isexe.sync = sync;
|
|
147474
|
-
var
|
|
147475
|
-
function checkPathExt(
|
|
147490
|
+
var fs72 = __require("fs");
|
|
147491
|
+
function checkPathExt(path81, options) {
|
|
147476
147492
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
147477
147493
|
if (!pathext) {
|
|
147478
147494
|
return true;
|
|
@@ -147483,25 +147499,25 @@ var require_windows = __commonJS({
|
|
|
147483
147499
|
}
|
|
147484
147500
|
for (var i = 0; i < pathext.length; i++) {
|
|
147485
147501
|
var p2 = pathext[i].toLowerCase();
|
|
147486
|
-
if (p2 &&
|
|
147502
|
+
if (p2 && path81.substr(-p2.length).toLowerCase() === p2) {
|
|
147487
147503
|
return true;
|
|
147488
147504
|
}
|
|
147489
147505
|
}
|
|
147490
147506
|
return false;
|
|
147491
147507
|
}
|
|
147492
|
-
function checkStat(stat,
|
|
147508
|
+
function checkStat(stat, path81, options) {
|
|
147493
147509
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
147494
147510
|
return false;
|
|
147495
147511
|
}
|
|
147496
|
-
return checkPathExt(
|
|
147512
|
+
return checkPathExt(path81, options);
|
|
147497
147513
|
}
|
|
147498
|
-
function isexe(
|
|
147499
|
-
|
|
147500
|
-
cb(er, er ? false : checkStat(stat,
|
|
147514
|
+
function isexe(path81, options, cb) {
|
|
147515
|
+
fs72.stat(path81, function(er, stat) {
|
|
147516
|
+
cb(er, er ? false : checkStat(stat, path81, options));
|
|
147501
147517
|
});
|
|
147502
147518
|
}
|
|
147503
|
-
function sync(
|
|
147504
|
-
return checkStat(
|
|
147519
|
+
function sync(path81, options) {
|
|
147520
|
+
return checkStat(fs72.statSync(path81), path81, options);
|
|
147505
147521
|
}
|
|
147506
147522
|
}
|
|
147507
147523
|
});
|
|
@@ -147511,14 +147527,14 @@ var require_mode = __commonJS({
|
|
|
147511
147527
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
|
|
147512
147528
|
module.exports = isexe;
|
|
147513
147529
|
isexe.sync = sync;
|
|
147514
|
-
var
|
|
147515
|
-
function isexe(
|
|
147516
|
-
|
|
147530
|
+
var fs72 = __require("fs");
|
|
147531
|
+
function isexe(path81, options, cb) {
|
|
147532
|
+
fs72.stat(path81, function(er, stat) {
|
|
147517
147533
|
cb(er, er ? false : checkStat(stat, options));
|
|
147518
147534
|
});
|
|
147519
147535
|
}
|
|
147520
|
-
function sync(
|
|
147521
|
-
return checkStat(
|
|
147536
|
+
function sync(path81, options) {
|
|
147537
|
+
return checkStat(fs72.statSync(path81), options);
|
|
147522
147538
|
}
|
|
147523
147539
|
function checkStat(stat, options) {
|
|
147524
147540
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -147542,7 +147558,7 @@ var require_mode = __commonJS({
|
|
|
147542
147558
|
// node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
|
|
147543
147559
|
var require_isexe = __commonJS({
|
|
147544
147560
|
"node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
|
|
147545
|
-
var
|
|
147561
|
+
var fs72 = __require("fs");
|
|
147546
147562
|
var core2;
|
|
147547
147563
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
147548
147564
|
core2 = require_windows();
|
|
@@ -147551,7 +147567,7 @@ var require_isexe = __commonJS({
|
|
|
147551
147567
|
}
|
|
147552
147568
|
module.exports = isexe;
|
|
147553
147569
|
isexe.sync = sync;
|
|
147554
|
-
function isexe(
|
|
147570
|
+
function isexe(path81, options, cb) {
|
|
147555
147571
|
if (typeof options === "function") {
|
|
147556
147572
|
cb = options;
|
|
147557
147573
|
options = {};
|
|
@@ -147561,7 +147577,7 @@ var require_isexe = __commonJS({
|
|
|
147561
147577
|
throw new TypeError("callback not provided");
|
|
147562
147578
|
}
|
|
147563
147579
|
return new Promise(function(resolve12, reject) {
|
|
147564
|
-
isexe(
|
|
147580
|
+
isexe(path81, options || {}, function(er, is) {
|
|
147565
147581
|
if (er) {
|
|
147566
147582
|
reject(er);
|
|
147567
147583
|
} else {
|
|
@@ -147570,7 +147586,7 @@ var require_isexe = __commonJS({
|
|
|
147570
147586
|
});
|
|
147571
147587
|
});
|
|
147572
147588
|
}
|
|
147573
|
-
core2(
|
|
147589
|
+
core2(path81, options || {}, function(er, is) {
|
|
147574
147590
|
if (er) {
|
|
147575
147591
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
147576
147592
|
er = null;
|
|
@@ -147580,9 +147596,9 @@ var require_isexe = __commonJS({
|
|
|
147580
147596
|
cb(er, is);
|
|
147581
147597
|
});
|
|
147582
147598
|
}
|
|
147583
|
-
function sync(
|
|
147599
|
+
function sync(path81, options) {
|
|
147584
147600
|
try {
|
|
147585
|
-
return core2.sync(
|
|
147601
|
+
return core2.sync(path81, options || {});
|
|
147586
147602
|
} catch (er) {
|
|
147587
147603
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
147588
147604
|
return false;
|
|
@@ -147598,7 +147614,7 @@ var require_isexe = __commonJS({
|
|
|
147598
147614
|
var require_which = __commonJS({
|
|
147599
147615
|
"node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
|
|
147600
147616
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
147601
|
-
var
|
|
147617
|
+
var path81 = __require("path");
|
|
147602
147618
|
var COLON = isWindows ? ";" : ":";
|
|
147603
147619
|
var isexe = require_isexe();
|
|
147604
147620
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -147636,7 +147652,7 @@ var require_which = __commonJS({
|
|
|
147636
147652
|
return opt.all && found.length ? resolve12(found) : reject(getNotFoundError(cmd));
|
|
147637
147653
|
const ppRaw = pathEnv[i];
|
|
147638
147654
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
147639
|
-
const pCmd =
|
|
147655
|
+
const pCmd = path81.join(pathPart, cmd);
|
|
147640
147656
|
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
147641
147657
|
resolve12(subStep(p2, i, 0));
|
|
147642
147658
|
});
|
|
@@ -147663,7 +147679,7 @@ var require_which = __commonJS({
|
|
|
147663
147679
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
147664
147680
|
const ppRaw = pathEnv[i];
|
|
147665
147681
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
147666
|
-
const pCmd =
|
|
147682
|
+
const pCmd = path81.join(pathPart, cmd);
|
|
147667
147683
|
const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
147668
147684
|
for (let j2 = 0; j2 < pathExt.length; j2++) {
|
|
147669
147685
|
const cur = p2 + pathExt[j2];
|
|
@@ -147711,7 +147727,7 @@ var require_path_key = __commonJS({
|
|
|
147711
147727
|
var require_resolveCommand = __commonJS({
|
|
147712
147728
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
|
|
147713
147729
|
"use strict";
|
|
147714
|
-
var
|
|
147730
|
+
var path81 = __require("path");
|
|
147715
147731
|
var which = require_which();
|
|
147716
147732
|
var getPathKey = require_path_key();
|
|
147717
147733
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -147729,7 +147745,7 @@ var require_resolveCommand = __commonJS({
|
|
|
147729
147745
|
try {
|
|
147730
147746
|
resolved = which.sync(parsed.command, {
|
|
147731
147747
|
path: env[getPathKey({ env })],
|
|
147732
|
-
pathExt: withoutPathExt ?
|
|
147748
|
+
pathExt: withoutPathExt ? path81.delimiter : void 0
|
|
147733
147749
|
});
|
|
147734
147750
|
} catch (e) {
|
|
147735
147751
|
} finally {
|
|
@@ -147738,7 +147754,7 @@ var require_resolveCommand = __commonJS({
|
|
|
147738
147754
|
}
|
|
147739
147755
|
}
|
|
147740
147756
|
if (resolved) {
|
|
147741
|
-
resolved =
|
|
147757
|
+
resolved = path81.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
147742
147758
|
}
|
|
147743
147759
|
return resolved;
|
|
147744
147760
|
}
|
|
@@ -147792,8 +147808,8 @@ var require_shebang_command = __commonJS({
|
|
|
147792
147808
|
if (!match4) {
|
|
147793
147809
|
return null;
|
|
147794
147810
|
}
|
|
147795
|
-
const [
|
|
147796
|
-
const binary2 =
|
|
147811
|
+
const [path81, argument] = match4[0].replace(/#! ?/, "").split(" ");
|
|
147812
|
+
const binary2 = path81.split("/").pop();
|
|
147797
147813
|
if (binary2 === "env") {
|
|
147798
147814
|
return argument;
|
|
147799
147815
|
}
|
|
@@ -147806,16 +147822,16 @@ var require_shebang_command = __commonJS({
|
|
|
147806
147822
|
var require_readShebang = __commonJS({
|
|
147807
147823
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
|
|
147808
147824
|
"use strict";
|
|
147809
|
-
var
|
|
147825
|
+
var fs72 = __require("fs");
|
|
147810
147826
|
var shebangCommand = require_shebang_command();
|
|
147811
147827
|
function readShebang(command) {
|
|
147812
147828
|
const size = 150;
|
|
147813
147829
|
const buffer = Buffer.alloc(size);
|
|
147814
147830
|
let fd;
|
|
147815
147831
|
try {
|
|
147816
|
-
fd =
|
|
147817
|
-
|
|
147818
|
-
|
|
147832
|
+
fd = fs72.openSync(command, "r");
|
|
147833
|
+
fs72.readSync(fd, buffer, 0, size, 0);
|
|
147834
|
+
fs72.closeSync(fd);
|
|
147819
147835
|
} catch (e) {
|
|
147820
147836
|
}
|
|
147821
147837
|
return shebangCommand(buffer.toString());
|
|
@@ -147828,7 +147844,7 @@ var require_readShebang = __commonJS({
|
|
|
147828
147844
|
var require_parse = __commonJS({
|
|
147829
147845
|
"node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports, module) {
|
|
147830
147846
|
"use strict";
|
|
147831
|
-
var
|
|
147847
|
+
var path81 = __require("path");
|
|
147832
147848
|
var resolveCommand = require_resolveCommand();
|
|
147833
147849
|
var escape2 = require_escape();
|
|
147834
147850
|
var readShebang = require_readShebang();
|
|
@@ -147853,7 +147869,7 @@ var require_parse = __commonJS({
|
|
|
147853
147869
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
147854
147870
|
if (parsed.options.forceShell || needsShell) {
|
|
147855
147871
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
147856
|
-
parsed.command =
|
|
147872
|
+
parsed.command = path81.normalize(parsed.command);
|
|
147857
147873
|
parsed.command = escape2.command(parsed.command);
|
|
147858
147874
|
parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
|
|
147859
147875
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -148219,8 +148235,8 @@ var require_package = __commonJS({
|
|
|
148219
148235
|
// node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
|
|
148220
148236
|
var require_main = __commonJS({
|
|
148221
148237
|
"node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
|
|
148222
|
-
var
|
|
148223
|
-
var
|
|
148238
|
+
var fs72 = __require("fs");
|
|
148239
|
+
var path81 = __require("path");
|
|
148224
148240
|
var os15 = __require("os");
|
|
148225
148241
|
var crypto6 = __require("crypto");
|
|
148226
148242
|
var packageJson = require_package();
|
|
@@ -148328,7 +148344,7 @@ var require_main = __commonJS({
|
|
|
148328
148344
|
if (options && options.path && options.path.length > 0) {
|
|
148329
148345
|
if (Array.isArray(options.path)) {
|
|
148330
148346
|
for (const filepath of options.path) {
|
|
148331
|
-
if (
|
|
148347
|
+
if (fs72.existsSync(filepath)) {
|
|
148332
148348
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
148333
148349
|
}
|
|
148334
148350
|
}
|
|
@@ -148336,15 +148352,15 @@ var require_main = __commonJS({
|
|
|
148336
148352
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
148337
148353
|
}
|
|
148338
148354
|
} else {
|
|
148339
|
-
possibleVaultPath =
|
|
148355
|
+
possibleVaultPath = path81.resolve(process.cwd(), ".env.vault");
|
|
148340
148356
|
}
|
|
148341
|
-
if (
|
|
148357
|
+
if (fs72.existsSync(possibleVaultPath)) {
|
|
148342
148358
|
return possibleVaultPath;
|
|
148343
148359
|
}
|
|
148344
148360
|
return null;
|
|
148345
148361
|
}
|
|
148346
148362
|
function _resolveHome(envPath) {
|
|
148347
|
-
return envPath[0] === "~" ?
|
|
148363
|
+
return envPath[0] === "~" ? path81.join(os15.homedir(), envPath.slice(1)) : envPath;
|
|
148348
148364
|
}
|
|
148349
148365
|
function _configVault(options) {
|
|
148350
148366
|
const debug2 = Boolean(options && options.debug);
|
|
@@ -148361,7 +148377,7 @@ var require_main = __commonJS({
|
|
|
148361
148377
|
return { parsed };
|
|
148362
148378
|
}
|
|
148363
148379
|
function configDotenv(options) {
|
|
148364
|
-
const dotenvPath =
|
|
148380
|
+
const dotenvPath = path81.resolve(process.cwd(), ".env");
|
|
148365
148381
|
let encoding = "utf8";
|
|
148366
148382
|
const debug2 = Boolean(options && options.debug);
|
|
148367
148383
|
const quiet = options && "quiet" in options ? options.quiet : true;
|
|
@@ -148385,13 +148401,13 @@ var require_main = __commonJS({
|
|
|
148385
148401
|
}
|
|
148386
148402
|
let lastError;
|
|
148387
148403
|
const parsedAll = {};
|
|
148388
|
-
for (const
|
|
148404
|
+
for (const path82 of optionPaths) {
|
|
148389
148405
|
try {
|
|
148390
|
-
const parsed = DotenvModule.parse(
|
|
148406
|
+
const parsed = DotenvModule.parse(fs72.readFileSync(path82, { encoding }));
|
|
148391
148407
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
148392
148408
|
} catch (e) {
|
|
148393
148409
|
if (debug2) {
|
|
148394
|
-
_debug(`Failed to load ${
|
|
148410
|
+
_debug(`Failed to load ${path82} ${e.message}`);
|
|
148395
148411
|
}
|
|
148396
148412
|
lastError = e;
|
|
148397
148413
|
}
|
|
@@ -148406,7 +148422,7 @@ var require_main = __commonJS({
|
|
|
148406
148422
|
const shortPaths = [];
|
|
148407
148423
|
for (const filePath of optionPaths) {
|
|
148408
148424
|
try {
|
|
148409
|
-
const relative2 =
|
|
148425
|
+
const relative2 = path81.relative(process.cwd(), filePath);
|
|
148410
148426
|
shortPaths.push(relative2);
|
|
148411
148427
|
} catch (e) {
|
|
148412
148428
|
if (debug2) {
|
|
@@ -149265,8 +149281,8 @@ var init_cli_provider = __esm({
|
|
|
149265
149281
|
this._repoId = repoId;
|
|
149266
149282
|
}
|
|
149267
149283
|
/** Set target repo path — used as cwd when spawning CLI so Read tool accesses the right files. */
|
|
149268
|
-
setRepoPath(
|
|
149269
|
-
this._repoPath =
|
|
149284
|
+
setRepoPath(path81) {
|
|
149285
|
+
this._repoPath = path81;
|
|
149270
149286
|
}
|
|
149271
149287
|
flushUsage() {
|
|
149272
149288
|
if (this._usageRecords.length === 0)
|
|
@@ -161397,11 +161413,11 @@ var require_mime_types = __commonJS({
|
|
|
161397
161413
|
}
|
|
161398
161414
|
return exts[0];
|
|
161399
161415
|
}
|
|
161400
|
-
function lookup(
|
|
161401
|
-
if (!
|
|
161416
|
+
function lookup(path81) {
|
|
161417
|
+
if (!path81 || typeof path81 !== "string") {
|
|
161402
161418
|
return false;
|
|
161403
161419
|
}
|
|
161404
|
-
var extension2 = extname("x." +
|
|
161420
|
+
var extension2 = extname("x." + path81).toLowerCase().substr(1);
|
|
161405
161421
|
if (!extension2) {
|
|
161406
161422
|
return false;
|
|
161407
161423
|
}
|
|
@@ -162506,11 +162522,11 @@ var require_form_data = __commonJS({
|
|
|
162506
162522
|
"use strict";
|
|
162507
162523
|
var CombinedStream = require_combined_stream();
|
|
162508
162524
|
var util2 = __require("util");
|
|
162509
|
-
var
|
|
162525
|
+
var path81 = __require("path");
|
|
162510
162526
|
var http = __require("http");
|
|
162511
162527
|
var https = __require("https");
|
|
162512
162528
|
var parseUrl = __require("url").parse;
|
|
162513
|
-
var
|
|
162529
|
+
var fs72 = __require("fs");
|
|
162514
162530
|
var Stream = __require("stream").Stream;
|
|
162515
162531
|
var crypto6 = __require("crypto");
|
|
162516
162532
|
var mime = require_mime_types();
|
|
@@ -162577,7 +162593,7 @@ var require_form_data = __commonJS({
|
|
|
162577
162593
|
if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
|
|
162578
162594
|
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
|
162579
162595
|
} else {
|
|
162580
|
-
|
|
162596
|
+
fs72.stat(value.path, function(err, stat) {
|
|
162581
162597
|
if (err) {
|
|
162582
162598
|
callback(err);
|
|
162583
162599
|
return;
|
|
@@ -162634,11 +162650,11 @@ var require_form_data = __commonJS({
|
|
|
162634
162650
|
FormData2.prototype._getContentDisposition = function(value, options) {
|
|
162635
162651
|
var filename;
|
|
162636
162652
|
if (typeof options.filepath === "string") {
|
|
162637
|
-
filename =
|
|
162653
|
+
filename = path81.normalize(options.filepath).replace(/\\/g, "/");
|
|
162638
162654
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
162639
|
-
filename =
|
|
162655
|
+
filename = path81.basename(options.filename || value && (value.name || value.path));
|
|
162640
162656
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
162641
|
-
filename =
|
|
162657
|
+
filename = path81.basename(value.client._httpMessage.path || "");
|
|
162642
162658
|
}
|
|
162643
162659
|
if (filename) {
|
|
162644
162660
|
return 'filename="' + filename + '"';
|
|
@@ -163195,8 +163211,8 @@ var require_node2 = __commonJS({
|
|
|
163195
163211
|
}
|
|
163196
163212
|
break;
|
|
163197
163213
|
case "FILE":
|
|
163198
|
-
var
|
|
163199
|
-
stream2 = new
|
|
163214
|
+
var fs72 = __require("fs");
|
|
163215
|
+
stream2 = new fs72.SyncWriteStream(fd2, { autoClose: false });
|
|
163200
163216
|
stream2._type = "fs";
|
|
163201
163217
|
break;
|
|
163202
163218
|
case "PIPE":
|
|
@@ -164292,9 +164308,9 @@ var require_axios = __commonJS({
|
|
|
164292
164308
|
function removeBrackets(key4) {
|
|
164293
164309
|
return utils$1.endsWith(key4, "[]") ? key4.slice(0, -2) : key4;
|
|
164294
164310
|
}
|
|
164295
|
-
function renderKey(
|
|
164296
|
-
if (!
|
|
164297
|
-
return
|
|
164311
|
+
function renderKey(path81, key4, dots) {
|
|
164312
|
+
if (!path81) return key4;
|
|
164313
|
+
return path81.concat(key4).map(function each(token, i) {
|
|
164298
164314
|
token = removeBrackets(token);
|
|
164299
164315
|
return !dots && i ? "[" + token + "]" : token;
|
|
164300
164316
|
}).join(dots ? "." : "");
|
|
@@ -164342,13 +164358,13 @@ var require_axios = __commonJS({
|
|
|
164342
164358
|
}
|
|
164343
164359
|
return value;
|
|
164344
164360
|
}
|
|
164345
|
-
function defaultVisitor(value, key4,
|
|
164361
|
+
function defaultVisitor(value, key4, path81) {
|
|
164346
164362
|
let arr = value;
|
|
164347
164363
|
if (utils$1.isReactNative(formData) && utils$1.isReactNativeBlob(value)) {
|
|
164348
|
-
formData.append(renderKey(
|
|
164364
|
+
formData.append(renderKey(path81, key4, dots), convertValue(value));
|
|
164349
164365
|
return false;
|
|
164350
164366
|
}
|
|
164351
|
-
if (value && !
|
|
164367
|
+
if (value && !path81 && typeof value === "object") {
|
|
164352
164368
|
if (utils$1.endsWith(key4, "{}")) {
|
|
164353
164369
|
key4 = metaTokens ? key4 : key4.slice(0, -2);
|
|
164354
164370
|
value = JSON.stringify(value);
|
|
@@ -164367,7 +164383,7 @@ var require_axios = __commonJS({
|
|
|
164367
164383
|
if (isVisitable(value)) {
|
|
164368
164384
|
return true;
|
|
164369
164385
|
}
|
|
164370
|
-
formData.append(renderKey(
|
|
164386
|
+
formData.append(renderKey(path81, key4, dots), convertValue(value));
|
|
164371
164387
|
return false;
|
|
164372
164388
|
}
|
|
164373
164389
|
const stack2 = [];
|
|
@@ -164376,16 +164392,16 @@ var require_axios = __commonJS({
|
|
|
164376
164392
|
convertValue,
|
|
164377
164393
|
isVisitable
|
|
164378
164394
|
});
|
|
164379
|
-
function build8(value,
|
|
164395
|
+
function build8(value, path81) {
|
|
164380
164396
|
if (utils$1.isUndefined(value)) return;
|
|
164381
164397
|
if (stack2.indexOf(value) !== -1) {
|
|
164382
|
-
throw Error("Circular reference detected in " +
|
|
164398
|
+
throw Error("Circular reference detected in " + path81.join("."));
|
|
164383
164399
|
}
|
|
164384
164400
|
stack2.push(value);
|
|
164385
164401
|
utils$1.forEach(value, function each(el, key4) {
|
|
164386
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4,
|
|
164402
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key4) ? key4.trim() : key4, path81, exposedHelpers);
|
|
164387
164403
|
if (result === true) {
|
|
164388
|
-
build8(el,
|
|
164404
|
+
build8(el, path81 ? path81.concat(key4) : [key4]);
|
|
164389
164405
|
}
|
|
164390
164406
|
});
|
|
164391
164407
|
stack2.pop();
|
|
@@ -164574,7 +164590,7 @@ var require_axios = __commonJS({
|
|
|
164574
164590
|
};
|
|
164575
164591
|
function toURLEncodedForm(data, options) {
|
|
164576
164592
|
return toFormData(data, new platform.classes.URLSearchParams(), {
|
|
164577
|
-
visitor: function(value, key4,
|
|
164593
|
+
visitor: function(value, key4, path81, helpers) {
|
|
164578
164594
|
if (platform.isNode && utils$1.isBuffer(value)) {
|
|
164579
164595
|
this.append(key4, value.toString("base64"));
|
|
164580
164596
|
return false;
|
|
@@ -164602,11 +164618,11 @@ var require_axios = __commonJS({
|
|
|
164602
164618
|
return obj;
|
|
164603
164619
|
}
|
|
164604
164620
|
function formDataToJSON(formData) {
|
|
164605
|
-
function buildPath(
|
|
164606
|
-
let name =
|
|
164621
|
+
function buildPath(path81, value, target, index) {
|
|
164622
|
+
let name = path81[index++];
|
|
164607
164623
|
if (name === "__proto__") return true;
|
|
164608
164624
|
const isNumericKey = Number.isFinite(+name);
|
|
164609
|
-
const isLast = index >=
|
|
164625
|
+
const isLast = index >= path81.length;
|
|
164610
164626
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
164611
164627
|
if (isLast) {
|
|
164612
164628
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -164619,7 +164635,7 @@ var require_axios = __commonJS({
|
|
|
164619
164635
|
if (!target[name] || !utils$1.isObject(target[name])) {
|
|
164620
164636
|
target[name] = [];
|
|
164621
164637
|
}
|
|
164622
|
-
const result = buildPath(
|
|
164638
|
+
const result = buildPath(path81, value, target[name], index);
|
|
164623
164639
|
if (result && utils$1.isArray(target[name])) {
|
|
164624
164640
|
target[name] = arrayToObject(target[name]);
|
|
164625
164641
|
}
|
|
@@ -165937,9 +165953,9 @@ var require_axios = __commonJS({
|
|
|
165937
165953
|
auth = urlUsername + ":" + urlPassword;
|
|
165938
165954
|
}
|
|
165939
165955
|
auth && headers.delete("authorization");
|
|
165940
|
-
let
|
|
165956
|
+
let path81;
|
|
165941
165957
|
try {
|
|
165942
|
-
|
|
165958
|
+
path81 = buildURL(parsed.pathname + parsed.search, config2.params, config2.paramsSerializer).replace(/^\?/, "");
|
|
165943
165959
|
} catch (err) {
|
|
165944
165960
|
const customErr = new Error(err.message);
|
|
165945
165961
|
customErr.config = config2;
|
|
@@ -165949,7 +165965,7 @@ var require_axios = __commonJS({
|
|
|
165949
165965
|
}
|
|
165950
165966
|
headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
|
|
165951
165967
|
const options = {
|
|
165952
|
-
path:
|
|
165968
|
+
path: path81,
|
|
165953
165969
|
method,
|
|
165954
165970
|
headers: headers.toJSON(),
|
|
165955
165971
|
agents: {
|
|
@@ -166155,14 +166171,14 @@ var require_axios = __commonJS({
|
|
|
166155
166171
|
var cookies = platform.hasStandardBrowserEnv ? (
|
|
166156
166172
|
// Standard browser envs support document.cookie
|
|
166157
166173
|
{
|
|
166158
|
-
write(name, value, expires,
|
|
166174
|
+
write(name, value, expires, path81, domain, secure, sameSite) {
|
|
166159
166175
|
if (typeof document === "undefined") return;
|
|
166160
166176
|
const cookie = [`${name}=${encodeURIComponent(value)}`];
|
|
166161
166177
|
if (utils$1.isNumber(expires)) {
|
|
166162
166178
|
cookie.push(`expires=${new Date(expires).toUTCString()}`);
|
|
166163
166179
|
}
|
|
166164
|
-
if (utils$1.isString(
|
|
166165
|
-
cookie.push(`path=${
|
|
166180
|
+
if (utils$1.isString(path81)) {
|
|
166181
|
+
cookie.push(`path=${path81}`);
|
|
166166
166182
|
}
|
|
166167
166183
|
if (utils$1.isString(domain)) {
|
|
166168
166184
|
cookie.push(`domain=${domain}`);
|
|
@@ -167683,8 +167699,8 @@ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname10(proc
|
|
|
167683
167699
|
return decodedFile;
|
|
167684
167700
|
};
|
|
167685
167701
|
}
|
|
167686
|
-
function normalizeWindowsPath(
|
|
167687
|
-
return
|
|
167702
|
+
function normalizeWindowsPath(path81) {
|
|
167703
|
+
return path81.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
|
|
167688
167704
|
}
|
|
167689
167705
|
async function addSourceContext(frames) {
|
|
167690
167706
|
const filesToLines = {};
|
|
@@ -167729,9 +167745,9 @@ async function addSourceContext(frames) {
|
|
|
167729
167745
|
LRU_FILE_CONTENTS_CACHE.reduce();
|
|
167730
167746
|
return frames;
|
|
167731
167747
|
}
|
|
167732
|
-
function getContextLinesFromFile(
|
|
167748
|
+
function getContextLinesFromFile(path81, ranges, output) {
|
|
167733
167749
|
return new Promise((resolve12) => {
|
|
167734
|
-
const stream = createReadStream(
|
|
167750
|
+
const stream = createReadStream(path81);
|
|
167735
167751
|
const lineReaded = createInterface2({
|
|
167736
167752
|
input: stream
|
|
167737
167753
|
});
|
|
@@ -167749,7 +167765,7 @@ function getContextLinesFromFile(path80, ranges, output) {
|
|
|
167749
167765
|
let rangeStart = range2[0];
|
|
167750
167766
|
let rangeEnd = range2[1];
|
|
167751
167767
|
function onStreamError() {
|
|
167752
|
-
LRU_FILE_CONTENTS_FS_READ_FAILED.set(
|
|
167768
|
+
LRU_FILE_CONTENTS_FS_READ_FAILED.set(path81, 1);
|
|
167753
167769
|
lineReaded.close();
|
|
167754
167770
|
lineReaded.removeAllListeners();
|
|
167755
167771
|
destroyStreamAndResolve();
|
|
@@ -167826,8 +167842,8 @@ function clearLineContext(frame) {
|
|
|
167826
167842
|
delete frame.context_line;
|
|
167827
167843
|
delete frame.post_context;
|
|
167828
167844
|
}
|
|
167829
|
-
function shouldSkipContextLinesForFile(
|
|
167830
|
-
return
|
|
167845
|
+
function shouldSkipContextLinesForFile(path81) {
|
|
167846
|
+
return path81.startsWith("node:") || path81.endsWith(".min.js") || path81.endsWith(".min.cjs") || path81.endsWith(".min.mjs") || path81.startsWith("data:");
|
|
167831
167847
|
}
|
|
167832
167848
|
function shouldSkipContextLinesForFrame(frame) {
|
|
167833
167849
|
if (frame.lineno !== void 0 && frame.lineno > MAX_CONTEXTLINES_LINENO) {
|
|
@@ -171176,7 +171192,7 @@ function readToolVersion() {
|
|
|
171176
171192
|
if (cachedVersion)
|
|
171177
171193
|
return cachedVersion;
|
|
171178
171194
|
if (true) {
|
|
171179
|
-
cachedVersion = "0.7.0-next.
|
|
171195
|
+
cachedVersion = "0.7.0-next.9";
|
|
171180
171196
|
return cachedVersion;
|
|
171181
171197
|
}
|
|
171182
171198
|
try {
|
|
@@ -173582,13 +173598,13 @@ var init_pexprs_toFailure = __esm({
|
|
|
173582
173598
|
return new Failure(this, "a Unicode [" + this.categoryOrProp + "] character", "description");
|
|
173583
173599
|
};
|
|
173584
173600
|
Alt.prototype.toFailure = function(grammar2) {
|
|
173585
|
-
const
|
|
173586
|
-
const description = "(" +
|
|
173601
|
+
const fs72 = this.terms.map((t2) => t2.toFailure(grammar2));
|
|
173602
|
+
const description = "(" + fs72.join(" or ") + ")";
|
|
173587
173603
|
return new Failure(this, description, "description");
|
|
173588
173604
|
};
|
|
173589
173605
|
Seq.prototype.toFailure = function(grammar2) {
|
|
173590
|
-
const
|
|
173591
|
-
const description = "(" +
|
|
173606
|
+
const fs72 = this.factors.map((f2) => f2.toFailure(grammar2));
|
|
173607
|
+
const description = "(" + fs72.join(" ") + ")";
|
|
173592
173608
|
return new Failure(this, description, "description");
|
|
173593
173609
|
};
|
|
173594
173610
|
Iter.prototype.toFailure = function(grammar2) {
|
|
@@ -175425,9 +175441,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
|
|
|
175425
175441
|
decl.withSuperGrammar(namespace[superGrammarName]);
|
|
175426
175442
|
}
|
|
175427
175443
|
},
|
|
175428
|
-
Rule_define(n,
|
|
175444
|
+
Rule_define(n, fs72, d3, _2, b) {
|
|
175429
175445
|
currentRuleName = n.visit();
|
|
175430
|
-
currentRuleFormals =
|
|
175446
|
+
currentRuleFormals = fs72.children.map((c2) => c2.visit())[0] || [];
|
|
175431
175447
|
if (!decl.defaultStartRule && decl.ensureSuperGrammar() !== Grammar.ProtoBuiltInRules) {
|
|
175432
175448
|
decl.withDefaultStartRule(currentRuleName);
|
|
175433
175449
|
}
|
|
@@ -175436,9 +175452,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
|
|
|
175436
175452
|
const source = this.source.trimmed();
|
|
175437
175453
|
return decl.define(currentRuleName, currentRuleFormals, body, description, source);
|
|
175438
175454
|
},
|
|
175439
|
-
Rule_override(n,
|
|
175455
|
+
Rule_override(n, fs72, _2, b) {
|
|
175440
175456
|
currentRuleName = n.visit();
|
|
175441
|
-
currentRuleFormals =
|
|
175457
|
+
currentRuleFormals = fs72.children.map((c2) => c2.visit())[0] || [];
|
|
175442
175458
|
const source = this.source.trimmed();
|
|
175443
175459
|
decl.ensureSuperGrammarRuleForOverriding(currentRuleName, source);
|
|
175444
175460
|
overriding = true;
|
|
@@ -175446,9 +175462,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
|
|
|
175446
175462
|
overriding = false;
|
|
175447
175463
|
return decl.override(currentRuleName, currentRuleFormals, body, null, source);
|
|
175448
175464
|
},
|
|
175449
|
-
Rule_extend(n,
|
|
175465
|
+
Rule_extend(n, fs72, _2, b) {
|
|
175450
175466
|
currentRuleName = n.visit();
|
|
175451
|
-
currentRuleFormals =
|
|
175467
|
+
currentRuleFormals = fs72.children.map((c2) => c2.visit())[0] || [];
|
|
175452
175468
|
const body = b.visit();
|
|
175453
175469
|
const source = this.source.trimmed();
|
|
175454
175470
|
return decl.extend(currentRuleName, currentRuleFormals, body, null, source);
|
|
@@ -175475,8 +175491,8 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
|
|
|
175475
175491
|
return builder.alt(...args).withSource(this.source);
|
|
175476
175492
|
}
|
|
175477
175493
|
},
|
|
175478
|
-
Formals(opointy,
|
|
175479
|
-
return
|
|
175494
|
+
Formals(opointy, fs72, cpointy) {
|
|
175495
|
+
return fs72.visit();
|
|
175480
175496
|
},
|
|
175481
175497
|
Params(opointy, ps, cpointy) {
|
|
175482
175498
|
return ps.visit();
|
|
@@ -175638,8 +175654,8 @@ function initPrototypeParser(grammar2) {
|
|
|
175638
175654
|
formals: optFormals.children.map((c2) => c2.parse())[0] || []
|
|
175639
175655
|
};
|
|
175640
175656
|
},
|
|
175641
|
-
Formals(oparen,
|
|
175642
|
-
return
|
|
175657
|
+
Formals(oparen, fs72, cparen) {
|
|
175658
|
+
return fs72.asIteration().children.map((c2) => c2.parse());
|
|
175643
175659
|
},
|
|
175644
175660
|
name(first2, rest) {
|
|
175645
175661
|
return this.sourceString;
|
|
@@ -178960,8 +178976,8 @@ function parseAndResolve(files) {
|
|
|
178960
178976
|
const parsed = files.map((f2) => parseOne(f2.path, f2.source));
|
|
178961
178977
|
return resolve10(parsed);
|
|
178962
178978
|
}
|
|
178963
|
-
function parseTcFile(
|
|
178964
|
-
return parseOne(
|
|
178979
|
+
function parseTcFile(path81, source) {
|
|
178980
|
+
return parseOne(path81, source);
|
|
178965
178981
|
}
|
|
178966
178982
|
var LineMap, OP_VALUES;
|
|
178967
178983
|
var init_parser_ohm = __esm({
|
|
@@ -180350,13 +180366,13 @@ function extractStarletteRoutesFromFile(filePath, source, tree) {
|
|
|
180350
180366
|
const identities = starletteIdentitiesForPath(rawPath);
|
|
180351
180367
|
const line = node2.startPosition.row + 1;
|
|
180352
180368
|
for (const method of methods) {
|
|
180353
|
-
for (const
|
|
180369
|
+
for (const path81 of identities) {
|
|
180354
180370
|
out.push({
|
|
180355
|
-
identity: `${method} ${
|
|
180371
|
+
identity: `${method} ${path81}`,
|
|
180356
180372
|
contract: {
|
|
180357
180373
|
protocol: "http",
|
|
180358
180374
|
method,
|
|
180359
|
-
path:
|
|
180375
|
+
path: path81,
|
|
180360
180376
|
responses: [],
|
|
180361
180377
|
tags: []
|
|
180362
180378
|
},
|
|
@@ -180533,14 +180549,14 @@ function parseRouteDecorator(dec, source, stringVars) {
|
|
|
180533
180549
|
const args = call.childForFieldName("arguments");
|
|
180534
180550
|
if (!args)
|
|
180535
180551
|
return null;
|
|
180536
|
-
let
|
|
180552
|
+
let path81 = null;
|
|
180537
180553
|
let successStatus = "200";
|
|
180538
180554
|
for (let i = 0; i < args.namedChildCount; i++) {
|
|
180539
180555
|
const a = args.namedChild(i);
|
|
180540
180556
|
if (!a)
|
|
180541
180557
|
continue;
|
|
180542
|
-
if (
|
|
180543
|
-
|
|
180558
|
+
if (path81 === null && a.type === "string")
|
|
180559
|
+
path81 = pyStr(a, source);
|
|
180544
180560
|
else if (a.type === "keyword_argument") {
|
|
180545
180561
|
const name = a.childForFieldName("name");
|
|
180546
180562
|
const value = a.childForFieldName("value");
|
|
@@ -180549,17 +180565,17 @@ function parseRouteDecorator(dec, source, stringVars) {
|
|
|
180549
180565
|
}
|
|
180550
180566
|
}
|
|
180551
180567
|
}
|
|
180552
|
-
if (
|
|
180568
|
+
if (path81 === null) {
|
|
180553
180569
|
const firstArg = args.namedChild(0);
|
|
180554
180570
|
if (firstArg?.type === "identifier") {
|
|
180555
180571
|
const resolved = stringVars.get(source.slice(firstArg.startIndex, firstArg.endIndex));
|
|
180556
180572
|
if (resolved !== void 0)
|
|
180557
|
-
|
|
180573
|
+
path81 = resolved;
|
|
180558
180574
|
}
|
|
180559
180575
|
}
|
|
180560
|
-
if (
|
|
180576
|
+
if (path81 === null)
|
|
180561
180577
|
return null;
|
|
180562
|
-
return { method, path:
|
|
180578
|
+
return { method, path: path81, routerVar, successStatus };
|
|
180563
180579
|
}
|
|
180564
180580
|
function extractResponses2(body, source, successStatus) {
|
|
180565
180581
|
const byStatus = /* @__PURE__ */ new Map();
|
|
@@ -180692,9 +180708,9 @@ function looksLikeModel(p2, source) {
|
|
|
180692
180708
|
const text4 = source.slice(type2.startIndex, type2.endIndex);
|
|
180693
180709
|
return /^[A-Z]/.test(text4);
|
|
180694
180710
|
}
|
|
180695
|
-
function joinPath(prefix,
|
|
180711
|
+
function joinPath(prefix, path81) {
|
|
180696
180712
|
const a = prefix.replace(/\/$/, "");
|
|
180697
|
-
const b =
|
|
180713
|
+
const b = path81.startsWith("/") ? path81 : `/${path81}`;
|
|
180698
180714
|
return a + b || "/";
|
|
180699
180715
|
}
|
|
180700
180716
|
function callName(call, source) {
|
|
@@ -197012,8 +197028,8 @@ async function runRulesReset({ ruleKey }) {
|
|
|
197012
197028
|
|
|
197013
197029
|
// tools/cli/src/commands/contracts.ts
|
|
197014
197030
|
init_dist4();
|
|
197015
|
-
import
|
|
197016
|
-
import
|
|
197031
|
+
import fs69 from "node:fs";
|
|
197032
|
+
import path74 from "node:path";
|
|
197017
197033
|
|
|
197018
197034
|
// packages/spec-consolidator/dist/types.js
|
|
197019
197035
|
init_zod();
|
|
@@ -197051,6 +197067,26 @@ var RelationSchema = external_exports.object({
|
|
|
197051
197067
|
/** Optional human-readable rationale. */
|
|
197052
197068
|
note: external_exports.string().optional()
|
|
197053
197069
|
});
|
|
197070
|
+
var ConflictResolutionSchema = external_exports.object({
|
|
197071
|
+
/** Repo-relative path / DocRef of the first doc in the dispute. */
|
|
197072
|
+
docA: external_exports.string(),
|
|
197073
|
+
/** docA's conflicting section heading, or `null` for its preamble/lead. */
|
|
197074
|
+
anchorA: external_exports.string().nullable(),
|
|
197075
|
+
/** docA's verbatim disputed sentence, when the detector captured one. */
|
|
197076
|
+
quoteA: external_exports.string().optional(),
|
|
197077
|
+
/** Repo-relative path / DocRef of the second doc in the dispute. */
|
|
197078
|
+
docB: external_exports.string(),
|
|
197079
|
+
/** docB's conflicting section heading, or `null` for its preamble/lead. */
|
|
197080
|
+
anchorB: external_exports.string().nullable(),
|
|
197081
|
+
/** docB's verbatim disputed sentence, when the detector captured one. */
|
|
197082
|
+
quoteB: external_exports.string().optional(),
|
|
197083
|
+
/** Which side wins, or `dismissed` (not a real conflict). */
|
|
197084
|
+
verdict: external_exports.enum(["a", "b", "dismissed"]),
|
|
197085
|
+
/** ISO timestamp the resolution was recorded. */
|
|
197086
|
+
resolvedAt: external_exports.string(),
|
|
197087
|
+
/** Optional human-readable rationale. */
|
|
197088
|
+
note: external_exports.string().optional()
|
|
197089
|
+
});
|
|
197054
197090
|
var ManualAreaSchema = external_exports.object({
|
|
197055
197091
|
/** Repo-relative path / DocRef of the doc. */
|
|
197056
197092
|
doc: external_exports.string(),
|
|
@@ -197075,7 +197111,13 @@ var DecisionsFileSchema = external_exports.object({
|
|
|
197075
197111
|
/** User-authored doc→doc relations (replace/precedence/keep-both). */
|
|
197076
197112
|
relations: external_exports.array(RelationSchema).default([]),
|
|
197077
197113
|
/** User overrides of a doc's auto-assigned area tags. */
|
|
197078
|
-
manualAreas: external_exports.array(ManualAreaSchema).default([])
|
|
197114
|
+
manualAreas: external_exports.array(ManualAreaSchema).default([]),
|
|
197115
|
+
/**
|
|
197116
|
+
* SECTION-scoped conflict verdicts (plan item 31) — pick-a-side / dismissal on
|
|
197117
|
+
* one flagged disagreement, keyed by dispute identity. Optional with a `[]`
|
|
197118
|
+
* default so a decisions.json written before item 31 still parses.
|
|
197119
|
+
*/
|
|
197120
|
+
conflictResolutions: external_exports.array(ConflictResolutionSchema).default([])
|
|
197079
197121
|
});
|
|
197080
197122
|
|
|
197081
197123
|
// packages/spec-consolidator/dist/corpus-types.js
|
|
@@ -197210,7 +197252,17 @@ var OverlapSectionSchema = external_exports.object({
|
|
|
197210
197252
|
* from older corpora still parses; `null` is the preamble marker the viewer
|
|
197211
197253
|
* bands as the pre-first-heading block.
|
|
197212
197254
|
*/
|
|
197213
|
-
heading: external_exports.string().nullable()
|
|
197255
|
+
heading: external_exports.string().nullable(),
|
|
197256
|
+
/**
|
|
197257
|
+
* A short verbatim excerpt (≤ ~25 words) of the disputed sentence, copied from
|
|
197258
|
+
* the doc — the model's evidence for the heading it picked. Persisted (optional,
|
|
197259
|
+
* so older corpora without it still parse) for verification transparency and so
|
|
197260
|
+
* the viewer can later highlight the exact disputed sentence, not just band the
|
|
197261
|
+
* section. Consumed at assembly by `verifyOverlapSections` to anchor the pointer
|
|
197262
|
+
* by exact location; NOT part of the cross-area dedup identity (that stays
|
|
197263
|
+
* doc + heading).
|
|
197264
|
+
*/
|
|
197265
|
+
quote: external_exports.string().optional()
|
|
197214
197266
|
});
|
|
197215
197267
|
var OverlapSchema = external_exports.object({
|
|
197216
197268
|
/** The two docs that overlap, by ref. */
|
|
@@ -198003,13 +198055,241 @@ import { createHash as createHash7 } from "node:crypto";
|
|
|
198003
198055
|
import fs26 from "node:fs";
|
|
198004
198056
|
init_transport();
|
|
198005
198057
|
init_dist5();
|
|
198058
|
+
|
|
198059
|
+
// packages/spec-consolidator/dist/pointer-verifier.js
|
|
198060
|
+
init_dist5();
|
|
198061
|
+
var MIN_MEANINGFUL_SCORE = 1.5;
|
|
198062
|
+
var NEGLIGIBLE_RATIO = 0.25;
|
|
198063
|
+
var STOPWORDS2 = /* @__PURE__ */ new Set([
|
|
198064
|
+
"the",
|
|
198065
|
+
"a",
|
|
198066
|
+
"an",
|
|
198067
|
+
"and",
|
|
198068
|
+
"or",
|
|
198069
|
+
"but",
|
|
198070
|
+
"if",
|
|
198071
|
+
"then",
|
|
198072
|
+
"else",
|
|
198073
|
+
"of",
|
|
198074
|
+
"to",
|
|
198075
|
+
"in",
|
|
198076
|
+
"on",
|
|
198077
|
+
"at",
|
|
198078
|
+
"by",
|
|
198079
|
+
"for",
|
|
198080
|
+
"with",
|
|
198081
|
+
"as",
|
|
198082
|
+
"is",
|
|
198083
|
+
"are",
|
|
198084
|
+
"was",
|
|
198085
|
+
"were",
|
|
198086
|
+
"be",
|
|
198087
|
+
"been",
|
|
198088
|
+
"being",
|
|
198089
|
+
"it",
|
|
198090
|
+
"its",
|
|
198091
|
+
"this",
|
|
198092
|
+
"that",
|
|
198093
|
+
"these",
|
|
198094
|
+
"those",
|
|
198095
|
+
"they",
|
|
198096
|
+
"them",
|
|
198097
|
+
"their",
|
|
198098
|
+
"there",
|
|
198099
|
+
"here",
|
|
198100
|
+
"no",
|
|
198101
|
+
"not",
|
|
198102
|
+
"yes",
|
|
198103
|
+
"so",
|
|
198104
|
+
"than",
|
|
198105
|
+
"too",
|
|
198106
|
+
"very",
|
|
198107
|
+
"can",
|
|
198108
|
+
"could",
|
|
198109
|
+
"will",
|
|
198110
|
+
"would",
|
|
198111
|
+
"shall",
|
|
198112
|
+
"should",
|
|
198113
|
+
"may",
|
|
198114
|
+
"might",
|
|
198115
|
+
"must",
|
|
198116
|
+
"do",
|
|
198117
|
+
"does",
|
|
198118
|
+
"did",
|
|
198119
|
+
"done",
|
|
198120
|
+
"has",
|
|
198121
|
+
"have",
|
|
198122
|
+
"had",
|
|
198123
|
+
"from",
|
|
198124
|
+
"up",
|
|
198125
|
+
"out",
|
|
198126
|
+
"down",
|
|
198127
|
+
"over",
|
|
198128
|
+
"under",
|
|
198129
|
+
"again",
|
|
198130
|
+
"we",
|
|
198131
|
+
"you",
|
|
198132
|
+
"your",
|
|
198133
|
+
"our",
|
|
198134
|
+
"us",
|
|
198135
|
+
"i",
|
|
198136
|
+
"he",
|
|
198137
|
+
"she",
|
|
198138
|
+
"his",
|
|
198139
|
+
"her",
|
|
198140
|
+
"each",
|
|
198141
|
+
"any",
|
|
198142
|
+
"all",
|
|
198143
|
+
"both",
|
|
198144
|
+
"some",
|
|
198145
|
+
"such",
|
|
198146
|
+
"only",
|
|
198147
|
+
"own",
|
|
198148
|
+
"same",
|
|
198149
|
+
"more",
|
|
198150
|
+
"most",
|
|
198151
|
+
"other",
|
|
198152
|
+
"into",
|
|
198153
|
+
"about",
|
|
198154
|
+
"when",
|
|
198155
|
+
"where",
|
|
198156
|
+
"which",
|
|
198157
|
+
"who",
|
|
198158
|
+
"whom",
|
|
198159
|
+
"what",
|
|
198160
|
+
"how",
|
|
198161
|
+
"why",
|
|
198162
|
+
"per",
|
|
198163
|
+
"via",
|
|
198164
|
+
"also"
|
|
198165
|
+
]);
|
|
198166
|
+
function tokenize(text4, drop) {
|
|
198167
|
+
const lowered = text4.toLowerCase().replace(/[`*_~#>]/g, " ");
|
|
198168
|
+
const out = [];
|
|
198169
|
+
for (const raw of lowered.split(/[^a-z0-9]+/)) {
|
|
198170
|
+
if (raw.length < 2)
|
|
198171
|
+
continue;
|
|
198172
|
+
if (STOPWORDS2.has(raw))
|
|
198173
|
+
continue;
|
|
198174
|
+
if (drop.has(raw))
|
|
198175
|
+
continue;
|
|
198176
|
+
out.push(raw);
|
|
198177
|
+
}
|
|
198178
|
+
return out;
|
|
198179
|
+
}
|
|
198180
|
+
function pathWords(p2) {
|
|
198181
|
+
return p2.toLowerCase().split(/[^a-z0-9]+/).filter((t2) => t2.length >= 2);
|
|
198182
|
+
}
|
|
198183
|
+
var HEADING_RE = /^ {0,3}#{1,6}\s+(.*)$/;
|
|
198184
|
+
function splitDocSections(body, drop) {
|
|
198185
|
+
const raws = [];
|
|
198186
|
+
let cur = { heading: "", text: "" };
|
|
198187
|
+
for (const line of body.split(/\r?\n/)) {
|
|
198188
|
+
const m = HEADING_RE.exec(line);
|
|
198189
|
+
if (m) {
|
|
198190
|
+
if (cur.text.trim() || cur.heading)
|
|
198191
|
+
raws.push(cur);
|
|
198192
|
+
cur = { heading: m[1].trim(), text: `${line}
|
|
198193
|
+
` };
|
|
198194
|
+
} else {
|
|
198195
|
+
cur.text += `${line}
|
|
198196
|
+
`;
|
|
198197
|
+
}
|
|
198198
|
+
}
|
|
198199
|
+
if (cur.text.trim() || cur.heading)
|
|
198200
|
+
raws.push(cur);
|
|
198201
|
+
return raws.map((r) => ({
|
|
198202
|
+
realHeading: r.heading === "" ? null : r.heading,
|
|
198203
|
+
tokens: new Set(tokenize(r.text, drop)),
|
|
198204
|
+
text: r.text
|
|
198205
|
+
}));
|
|
198206
|
+
}
|
|
198207
|
+
function headingKey(h) {
|
|
198208
|
+
return h.replace(/[`*_~]/g, "").trim().toLowerCase();
|
|
198209
|
+
}
|
|
198210
|
+
function locateQuote(sections, quote) {
|
|
198211
|
+
const needle = normalizeQuote(quote);
|
|
198212
|
+
if (!needle)
|
|
198213
|
+
return [];
|
|
198214
|
+
const hits = [];
|
|
198215
|
+
for (let i = 0; i < sections.length; i++) {
|
|
198216
|
+
if (normalizeQuote(sections[i].text).includes(needle))
|
|
198217
|
+
hits.push(i);
|
|
198218
|
+
}
|
|
198219
|
+
return hits;
|
|
198220
|
+
}
|
|
198221
|
+
function scoreSections(sections, noteTokens) {
|
|
198222
|
+
const N = sections.length;
|
|
198223
|
+
const df = /* @__PURE__ */ new Map();
|
|
198224
|
+
for (const s of sections)
|
|
198225
|
+
for (const t2 of s.tokens)
|
|
198226
|
+
df.set(t2, (df.get(t2) ?? 0) + 1);
|
|
198227
|
+
const idf = (t2) => {
|
|
198228
|
+
const d3 = df.get(t2) ?? 0;
|
|
198229
|
+
if (d3 === 0)
|
|
198230
|
+
return 0;
|
|
198231
|
+
return Math.max(0, Math.log2((N + 1) / (d3 + 1)));
|
|
198232
|
+
};
|
|
198233
|
+
return sections.map((s) => {
|
|
198234
|
+
let score = 0;
|
|
198235
|
+
for (const t2 of noteTokens)
|
|
198236
|
+
if (s.tokens.has(t2))
|
|
198237
|
+
score += idf(t2);
|
|
198238
|
+
return score;
|
|
198239
|
+
});
|
|
198240
|
+
}
|
|
198241
|
+
function verifyOverlapSections(input) {
|
|
198242
|
+
const { docs, note, sections, bodyOf } = input;
|
|
198243
|
+
if (sections.length === 0)
|
|
198244
|
+
return [...sections];
|
|
198245
|
+
const drop = /* @__PURE__ */ new Set([...pathWords(docs[0]), ...pathWords(docs[1])]);
|
|
198246
|
+
const noteTokens = new Set(tokenize(note, drop));
|
|
198247
|
+
return sections.map((ptr) => {
|
|
198248
|
+
const body = bodyOf(ptr.doc);
|
|
198249
|
+
if (body === void 0)
|
|
198250
|
+
return { ...ptr };
|
|
198251
|
+
const candidates = splitDocSections(body, drop);
|
|
198252
|
+
if (candidates.length === 0)
|
|
198253
|
+
return { ...ptr };
|
|
198254
|
+
let pointedIdx;
|
|
198255
|
+
if (ptr.heading === null) {
|
|
198256
|
+
pointedIdx = 0;
|
|
198257
|
+
} else {
|
|
198258
|
+
const key4 = headingKey(ptr.heading);
|
|
198259
|
+
pointedIdx = candidates.findIndex((c2) => c2.realHeading !== null && headingKey(c2.realHeading) === key4);
|
|
198260
|
+
}
|
|
198261
|
+
if (ptr.quote !== void 0) {
|
|
198262
|
+
const hits = locateQuote(candidates, ptr.quote);
|
|
198263
|
+
if (hits.length > 0) {
|
|
198264
|
+
if (pointedIdx >= 0 && hits.includes(pointedIdx))
|
|
198265
|
+
return { ...ptr };
|
|
198266
|
+
const target = hits[0];
|
|
198267
|
+
return { ...ptr, heading: target === 0 ? null : candidates[target].realHeading };
|
|
198268
|
+
}
|
|
198269
|
+
}
|
|
198270
|
+
if (noteTokens.size === 0)
|
|
198271
|
+
return { ...ptr };
|
|
198272
|
+
const scores = scoreSections(candidates, noteTokens);
|
|
198273
|
+
let bestIdx = 0;
|
|
198274
|
+
for (let i = 1; i < scores.length; i++)
|
|
198275
|
+
if (scores[i] > scores[bestIdx])
|
|
198276
|
+
bestIdx = i;
|
|
198277
|
+
const bestScore = scores[bestIdx];
|
|
198278
|
+
const pointedScore = pointedIdx >= 0 ? scores[pointedIdx] : 0;
|
|
198279
|
+
const reanchor = bestIdx !== pointedIdx && bestScore >= MIN_MEANINGFUL_SCORE && pointedScore < MIN_MEANINGFUL_SCORE && pointedScore <= NEGLIGIBLE_RATIO * bestScore;
|
|
198280
|
+
if (!reanchor)
|
|
198281
|
+
return { ...ptr };
|
|
198282
|
+
return { ...ptr, heading: bestIdx === 0 ? null : candidates[bestIdx].realHeading };
|
|
198283
|
+
});
|
|
198284
|
+
}
|
|
198285
|
+
|
|
198286
|
+
// packages/spec-consolidator/dist/overlap-detector.js
|
|
198006
198287
|
var DEFAULT_MAX_PAIRS_PER_AREA = 60;
|
|
198007
198288
|
async function flagOverlaps(repoRoot5, areas, docs, opts = {}) {
|
|
198008
198289
|
const result = /* @__PURE__ */ new Map();
|
|
198009
198290
|
if (opts.enabled === false)
|
|
198010
198291
|
return result;
|
|
198011
198292
|
const byPath = new Map(docs.map((d3) => [d3.path, d3]));
|
|
198012
|
-
const resolved = resolvedPairKeys(opts.relations ?? []);
|
|
198013
198293
|
const maxPairs = opts.maxPairsPerArea ?? DEFAULT_MAX_PAIRS_PER_AREA;
|
|
198014
198294
|
const vocab = opts.vocab;
|
|
198015
198295
|
const pairs2 = [];
|
|
@@ -198024,8 +198304,6 @@ async function flagOverlaps(repoRoot5, areas, docs, opts = {}) {
|
|
|
198024
198304
|
const b = byPath.get(y);
|
|
198025
198305
|
if (!a || !b)
|
|
198026
198306
|
return;
|
|
198027
|
-
if (isResolved(resolved, area.id, x, y))
|
|
198028
|
-
return;
|
|
198029
198307
|
const key4 = x < y ? `${x}\0${y}` : `${y}\0${x}`;
|
|
198030
198308
|
if (seen.has(key4))
|
|
198031
198309
|
return;
|
|
@@ -198092,6 +198370,19 @@ async function flagOverlaps(repoRoot5, areas, docs, opts = {}) {
|
|
|
198092
198370
|
};
|
|
198093
198371
|
launch();
|
|
198094
198372
|
});
|
|
198373
|
+
for (const list of result.values()) {
|
|
198374
|
+
for (const overlap of list) {
|
|
198375
|
+
overlap.sections = verifyOverlapSections({
|
|
198376
|
+
docs: overlap.docs,
|
|
198377
|
+
note: overlap.note,
|
|
198378
|
+
sections: overlap.sections,
|
|
198379
|
+
bodyOf: (ref) => {
|
|
198380
|
+
const d3 = byPath.get(ref);
|
|
198381
|
+
return d3 ? docBody2(d3) : void 0;
|
|
198382
|
+
}
|
|
198383
|
+
});
|
|
198384
|
+
}
|
|
198385
|
+
}
|
|
198095
198386
|
const entries = [...result].flatMap(([area, list]) => list.map((overlap) => ({ area, overlap })));
|
|
198096
198387
|
const merged = dedupeCrossAreaOverlaps(entries);
|
|
198097
198388
|
result.clear();
|
|
@@ -198115,22 +198406,6 @@ async function examineOne(repoRoot5, areaId, a, b, runner) {
|
|
|
198115
198406
|
await writeCache3(repoRoot5, cacheKey, verdict);
|
|
198116
198407
|
return verdict;
|
|
198117
198408
|
}
|
|
198118
|
-
function resolvedPairKeys(relations) {
|
|
198119
|
-
const set2 = /* @__PURE__ */ new Set();
|
|
198120
|
-
for (const r of relations) {
|
|
198121
|
-
if (r.scope)
|
|
198122
|
-
set2.add(scopedKey2(r.scope, r.older, r.newer));
|
|
198123
|
-
else
|
|
198124
|
-
set2.add(globalKey(r.older, r.newer));
|
|
198125
|
-
}
|
|
198126
|
-
return set2;
|
|
198127
|
-
}
|
|
198128
|
-
var sortedPair = (x, y) => [x, y].sort().join(" ");
|
|
198129
|
-
var globalKey = (x, y) => `* ${sortedPair(x, y)}`;
|
|
198130
|
-
var scopedKey2 = (scope, x, y) => `${scope} ${sortedPair(x, y)}`;
|
|
198131
|
-
function isResolved(set2, areaId, x, y) {
|
|
198132
|
-
return set2.has(globalKey(x, y)) || set2.has(scopedKey2(areaId, x, y));
|
|
198133
|
-
}
|
|
198134
198409
|
var OVERLAP_DETECTOR_SYSTEM_PROMPT = `You compare TWO documentation files that both cover the same AREA of a software system and decide whether they may DISAGREE.
|
|
198135
198410
|
|
|
198136
198411
|
${OUTPUT_ONLY_GUARDRAIL}
|
|
@@ -198146,9 +198421,12 @@ NOT a disagreement (do NOT flag):
|
|
|
198146
198421
|
|
|
198147
198422
|
Bias: when there is a PLAUSIBLE contradiction a human should check, flag it. When the docs are clearly complementary or agree, do not.
|
|
198148
198423
|
|
|
198149
|
-
When you flag an overlap,
|
|
198424
|
+
When you flag an overlap, point at WHERE each side's disputed claim lives. Below each doc you are given a CLOSED list of that doc's section options \u2014 its headings, plus a "lead" option. Do NOT recall or guess a heading; SELECT from the list. For EACH side output a pointer with two fields:
|
|
198425
|
+
- \`heading\`: EXACTLY one of that doc's listed section headings, copied verbatim \u2014 OR the JSON literal \`null\` (not the string "null", not "") for the LEAD, the text ABOVE its first heading (or, when the doc opens straight with a title, that opening title block). Never emit a heading that is not one of the listed options.
|
|
198426
|
+
- \`quote\`: a SHORT verbatim excerpt (\u2264 25 words) of the disputed sentence, copied EXACTLY from that doc \u2014 the words that state the claim in dispute. This is your evidence for the heading you picked; copy it, do not paraphrase.
|
|
198427
|
+
List one entry per side; omit a side only when it genuinely has no conflicting passage.
|
|
198150
198428
|
|
|
198151
|
-
PREAMBLE:
|
|
198429
|
+
PREAMBLE: use \`heading\`: \`null\` ONLY for that lead/preamble block; whenever the disputed passage is under a listed heading, select that heading verbatim.
|
|
198152
198430
|
|
|
198153
198431
|
In the NOTE, refer to each doc by its FILENAME (the basename shown in the header, e.g. \`users.md\`) \u2014 NEVER "doc A" / "doc B", which mean nothing to the reader.
|
|
198154
198432
|
|
|
@@ -198156,13 +198434,19 @@ Output ONLY a JSON object, no prose, no code fences:
|
|
|
198156
198434
|
|
|
198157
198435
|
{ "overlap": true,
|
|
198158
198436
|
"note": "users.md uses auth0_id; identity.md uses auth0_sub for the same user column",
|
|
198159
|
-
"sections": [
|
|
198437
|
+
"sections": [
|
|
198438
|
+
{ "side": "A", "heading": "User model", "quote": "the auth0_id column stores the Auth0 subject" },
|
|
198439
|
+
{ "side": "B", "heading": "Identity", "quote": "we persist the Auth0 subject in auth0_sub" }
|
|
198440
|
+
] }
|
|
198160
198441
|
|
|
198161
|
-
Preamble example \u2014 doc A's claim is a README
|
|
198442
|
+
Preamble example \u2014 doc A's disputed claim is a README tagline ABOVE its first heading, so its side uses \`heading\`: null and quotes that tagline verbatim:
|
|
198162
198443
|
|
|
198163
198444
|
{ "overlap": true,
|
|
198164
198445
|
"note": "README.md lists C# as a supported language in the preamble; plan.md's Tech Stack omits it",
|
|
198165
|
-
"sections": [
|
|
198446
|
+
"sections": [
|
|
198447
|
+
{ "side": "A", "heading": null, "quote": "Supports TypeScript, Python, and C# out of the box" },
|
|
198448
|
+
{ "side": "B", "heading": "Tech Stack", "quote": "The stack is TypeScript and Python" }
|
|
198449
|
+
] }
|
|
198166
198450
|
|
|
198167
198451
|
Use { "overlap": false, "note": "", "sections": [] } when they are complementary or agree. The note is shown to the user \u2014 name the specific thing that differs.`;
|
|
198168
198452
|
var OVERLAP_PREVIEW_LINES = 120;
|
|
@@ -198196,31 +198480,59 @@ function hasConcernHeading(doc, concern, vocab) {
|
|
|
198196
198480
|
}
|
|
198197
198481
|
return false;
|
|
198198
198482
|
}
|
|
198483
|
+
function sectionHeadings(body) {
|
|
198484
|
+
const out = [];
|
|
198485
|
+
for (const line of body.split(/\r?\n/)) {
|
|
198486
|
+
const m = /^ {0,3}#{1,6}\s+(.*)$/.exec(line);
|
|
198487
|
+
if (!m)
|
|
198488
|
+
continue;
|
|
198489
|
+
const text4 = m[1].replace(/\s*#*\s*$/, "").trim();
|
|
198490
|
+
if (text4)
|
|
198491
|
+
out.push(text4);
|
|
198492
|
+
}
|
|
198493
|
+
return out;
|
|
198494
|
+
}
|
|
198495
|
+
function sectionOptions(slice5) {
|
|
198496
|
+
const lines = [" - the lead (text above the first heading, or the opening title block) \u2192 use heading: null"];
|
|
198497
|
+
for (const h of sectionHeadings(slice5))
|
|
198498
|
+
lines.push(` - ${h}`);
|
|
198499
|
+
return lines;
|
|
198500
|
+
}
|
|
198199
198501
|
function buildOverlapUserPrompt(areaId, a, b) {
|
|
198200
198502
|
const slice5 = (d3) => docBody2(d3).split(/\r?\n/).slice(0, OVERLAP_PREVIEW_LINES).join("\n");
|
|
198503
|
+
const sliceA = slice5(a);
|
|
198504
|
+
const sliceB = slice5(b);
|
|
198201
198505
|
return [
|
|
198202
198506
|
`Area: ${areaId}`,
|
|
198203
198507
|
"",
|
|
198204
198508
|
`--- doc A: ${a.path} ---`,
|
|
198205
|
-
|
|
198509
|
+
sliceA,
|
|
198206
198510
|
`--- end doc A ---`,
|
|
198207
198511
|
"",
|
|
198208
198512
|
`--- doc B: ${b.path} ---`,
|
|
198209
|
-
|
|
198513
|
+
sliceB,
|
|
198210
198514
|
`--- end doc B ---`,
|
|
198211
198515
|
"",
|
|
198516
|
+
"SECTION OPTIONS \u2014 each side pointer MUST be one of these (verbatim), or the lead (heading: null):",
|
|
198517
|
+
"",
|
|
198518
|
+
`doc A (${a.path}):`,
|
|
198519
|
+
...sectionOptions(sliceA),
|
|
198520
|
+
"",
|
|
198521
|
+
`doc B (${b.path}):`,
|
|
198522
|
+
...sectionOptions(sliceB),
|
|
198523
|
+
"",
|
|
198212
198524
|
"Return the JSON object as specified."
|
|
198213
198525
|
].join("\n");
|
|
198214
198526
|
}
|
|
198215
198527
|
var LlmOverlapSchema = external_exports.object({
|
|
198216
198528
|
overlap: external_exports.boolean(),
|
|
198217
198529
|
note: external_exports.string().default(""),
|
|
198218
|
-
sections: external_exports.array(external_exports.object({ side: external_exports.enum(["A", "B"]), heading: external_exports.string().nullable() })).default([])
|
|
198530
|
+
sections: external_exports.array(external_exports.object({ side: external_exports.enum(["A", "B"]), heading: external_exports.string().nullable(), quote: external_exports.string().optional() })).default([])
|
|
198219
198531
|
});
|
|
198220
198532
|
var OverlapVerdictSchema = external_exports.object({
|
|
198221
198533
|
overlap: external_exports.boolean(),
|
|
198222
198534
|
note: external_exports.string().default(""),
|
|
198223
|
-
sections: external_exports.array(external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable() })).default([])
|
|
198535
|
+
sections: external_exports.array(external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable(), quote: external_exports.string().optional() })).default([])
|
|
198224
198536
|
});
|
|
198225
198537
|
function spawnOverlapRunner(opts = {}) {
|
|
198226
198538
|
const transport = opts.transport ?? cliTransport({ bin: opts.bin });
|
|
@@ -198240,7 +198552,11 @@ function spawnOverlapRunner(opts = {}) {
|
|
|
198240
198552
|
return {
|
|
198241
198553
|
overlap: inner.overlap,
|
|
198242
198554
|
note: inner.note,
|
|
198243
|
-
sections: inner.sections.map((s) => ({
|
|
198555
|
+
sections: inner.sections.map((s) => ({
|
|
198556
|
+
doc: s.side === "A" ? a.path : b.path,
|
|
198557
|
+
heading: s.heading,
|
|
198558
|
+
...s.quote !== void 0 ? { quote: s.quote } : {}
|
|
198559
|
+
}))
|
|
198244
198560
|
};
|
|
198245
198561
|
};
|
|
198246
198562
|
}
|
|
@@ -198402,12 +198718,12 @@ function prefilterDocs(docs, manualIncludes = []) {
|
|
|
198402
198718
|
if (reason)
|
|
198403
198719
|
reasons.set(doc.path, reason);
|
|
198404
198720
|
}
|
|
198405
|
-
for (const { path:
|
|
198406
|
-
reasons.set(
|
|
198721
|
+
for (const { path: path81, reason } of dedupeNearDuplicates(docs.filter((d3) => !manualSet.has(d3.path) && !reasons.has(d3.path)))) {
|
|
198722
|
+
reasons.set(path81, reason);
|
|
198407
198723
|
}
|
|
198408
198724
|
return {
|
|
198409
198725
|
toClassify: docs.filter((d3) => !reasons.has(d3.path)),
|
|
198410
|
-
skipped: [...reasons].map(([
|
|
198726
|
+
skipped: [...reasons].map(([path81, reason]) => ({ path: path81, reason }))
|
|
198411
198727
|
};
|
|
198412
198728
|
}
|
|
198413
198729
|
async function planRelevanceWork(repoRoot5, docs, manualIncludes = []) {
|
|
@@ -198725,7 +199041,6 @@ async function curate(repoRoot5, opts = {}) {
|
|
|
198725
199041
|
const overlapsByArea = await flagOverlaps(repoRoot5, grouped.areas, docs, {
|
|
198726
199042
|
runner: opts.overlapRunner,
|
|
198727
199043
|
enabled: opts.disableOverlapDetection !== true,
|
|
198728
|
-
relations,
|
|
198729
199044
|
vocab,
|
|
198730
199045
|
transport: opts.transport,
|
|
198731
199046
|
model: models.overlap,
|
|
@@ -198771,7 +199086,8 @@ var EMPTY_DECISIONS = {
|
|
|
198771
199086
|
manualIncludes: [],
|
|
198772
199087
|
manualExcludes: [],
|
|
198773
199088
|
relations: [],
|
|
198774
|
-
manualAreas: []
|
|
199089
|
+
manualAreas: [],
|
|
199090
|
+
conflictResolutions: []
|
|
198775
199091
|
};
|
|
198776
199092
|
function readCorpusDecisions(repoRoot5) {
|
|
198777
199093
|
const file = path31.join(repoRoot5, ".truecourse", "specs", "decisions.json");
|
|
@@ -198793,7 +199109,8 @@ var EMPTY_DECISIONS2 = {
|
|
|
198793
199109
|
manualIncludes: [],
|
|
198794
199110
|
manualExcludes: [],
|
|
198795
199111
|
relations: [],
|
|
198796
|
-
manualAreas: []
|
|
199112
|
+
manualAreas: [],
|
|
199113
|
+
conflictResolutions: []
|
|
198797
199114
|
};
|
|
198798
199115
|
function decisionsPath(repoRoot5) {
|
|
198799
199116
|
return path32.join(repoRoot5, ".truecourse", "specs", "decisions.json");
|
|
@@ -198973,8 +199290,8 @@ function canonicalIdentity(_kind, identity) {
|
|
|
198973
199290
|
let id = identity.trim().replace(/\s+/g, " ");
|
|
198974
199291
|
const op = HTTP_METHOD.exec(id);
|
|
198975
199292
|
if (op) {
|
|
198976
|
-
const
|
|
198977
|
-
id = `${op[1].toUpperCase()} ${
|
|
199293
|
+
const path81 = op[2].replace(/\/+$/, "").replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, "{$1}");
|
|
199294
|
+
id = `${op[1].toUpperCase()} ${path81}`;
|
|
198978
199295
|
}
|
|
198979
199296
|
return id;
|
|
198980
199297
|
}
|
|
@@ -202871,6 +203188,7 @@ function describeStageResolutions(repoDir = resolveRepoDir(process.cwd())) {
|
|
|
202871
203188
|
}
|
|
202872
203189
|
|
|
202873
203190
|
// packages/core/dist/commands/spec-in-process.js
|
|
203191
|
+
init_dist5();
|
|
202874
203192
|
init_transport();
|
|
202875
203193
|
|
|
202876
203194
|
// packages/core/dist/lib/llm-call-log.js
|
|
@@ -207137,8 +207455,8 @@ init_dist5();
|
|
|
207137
207455
|
|
|
207138
207456
|
// packages/guard-generator/dist/section-plan.js
|
|
207139
207457
|
init_zod();
|
|
207140
|
-
import
|
|
207141
|
-
import
|
|
207458
|
+
import fs60 from "node:fs";
|
|
207459
|
+
import path64 from "node:path";
|
|
207142
207460
|
import { createHash as createHash15 } from "node:crypto";
|
|
207143
207461
|
init_dist5();
|
|
207144
207462
|
|
|
@@ -207280,6 +207598,11 @@ function buildExtractUserPrompt(ctx) {
|
|
|
207280
207598
|
ctx.viewText,
|
|
207281
207599
|
'"""'
|
|
207282
207600
|
];
|
|
207601
|
+
if (ctx.suppressed && ctx.suppressed.length > 0) {
|
|
207602
|
+
lines.push("", "RESOLVED \u2014 STALE, DO NOT EXTRACT. A conflict resolution judged the following", "sentence(s) in this document stale (another document is authoritative here).", "Extract NO claim that asserts what any of them says \u2014 treat them as if absent:");
|
|
207603
|
+
for (const q2 of ctx.suppressed)
|
|
207604
|
+
lines.push(`- "${q2}"`);
|
|
207605
|
+
}
|
|
207283
207606
|
if (ctx.correction) {
|
|
207284
207607
|
lines.push("", "CORRECTION \u2014 your previous response was NOT valid. You returned:", ctx.correction.invalidOutput, 'Return exactly ONE JSON object with "claims" and "untestable" arrays matching', 'the schema above, and NOTHING else. Every "driver" is one of cli|api|web|tui;', 'every "sectionAnchor" is an anchor copied verbatim from the outline.');
|
|
207285
207608
|
}
|
|
@@ -207448,17 +207771,127 @@ function buildRecipeUserPrompt(input) {
|
|
|
207448
207771
|
return lines.join("\n");
|
|
207449
207772
|
}
|
|
207450
207773
|
|
|
207451
|
-
// packages/guard-generator/dist/
|
|
207774
|
+
// packages/guard-generator/dist/suppression.js
|
|
207775
|
+
init_zod();
|
|
207776
|
+
init_dist5();
|
|
207777
|
+
import fs59 from "node:fs";
|
|
207778
|
+
import path63 from "node:path";
|
|
207779
|
+
var OverlapSectionShape = external_exports.object({ doc: external_exports.string(), heading: external_exports.string().nullable().optional(), quote: external_exports.string().optional() }).passthrough();
|
|
207780
|
+
var OverlapShape = external_exports.object({
|
|
207781
|
+
docs: external_exports.tuple([external_exports.string(), external_exports.string()]),
|
|
207782
|
+
note: external_exports.string().optional(),
|
|
207783
|
+
sections: external_exports.array(OverlapSectionShape).optional(),
|
|
207784
|
+
areas: external_exports.array(external_exports.string()).optional()
|
|
207785
|
+
}).passthrough();
|
|
207786
|
+
var RelationShape = external_exports.object({ older: external_exports.string(), newer: external_exports.string(), scope: external_exports.string().optional() }).passthrough();
|
|
207452
207787
|
var CorpusShape2 = external_exports.object({
|
|
207788
|
+
areas: external_exports.array(external_exports.object({ id: external_exports.string(), overlaps: external_exports.array(OverlapShape).optional() }).passthrough()).optional(),
|
|
207789
|
+
relations: external_exports.array(RelationShape).optional()
|
|
207790
|
+
}).passthrough();
|
|
207791
|
+
var ConflictResolutionShape = external_exports.object({
|
|
207792
|
+
docA: external_exports.string(),
|
|
207793
|
+
anchorA: external_exports.string().nullable().optional(),
|
|
207794
|
+
quoteA: external_exports.string().optional(),
|
|
207795
|
+
docB: external_exports.string(),
|
|
207796
|
+
anchorB: external_exports.string().nullable().optional(),
|
|
207797
|
+
quoteB: external_exports.string().optional(),
|
|
207798
|
+
verdict: external_exports.enum(["a", "b", "dismissed"]),
|
|
207799
|
+
resolvedAt: external_exports.string().optional(),
|
|
207800
|
+
note: external_exports.string().optional()
|
|
207801
|
+
}).passthrough();
|
|
207802
|
+
var DecisionsShape = external_exports.object({
|
|
207803
|
+
relations: external_exports.array(RelationShape).optional(),
|
|
207804
|
+
manualExcludes: external_exports.array(external_exports.string()).optional(),
|
|
207805
|
+
conflictResolutions: external_exports.array(ConflictResolutionShape).optional()
|
|
207806
|
+
}).passthrough();
|
|
207807
|
+
function readJsonTolerant(file, schema2) {
|
|
207808
|
+
if (!fs59.existsSync(file))
|
|
207809
|
+
return void 0;
|
|
207810
|
+
try {
|
|
207811
|
+
const parsed = schema2.safeParse(JSON.parse(fs59.readFileSync(file, "utf-8")));
|
|
207812
|
+
return parsed.success ? parsed.data : void 0;
|
|
207813
|
+
} catch {
|
|
207814
|
+
return void 0;
|
|
207815
|
+
}
|
|
207816
|
+
}
|
|
207817
|
+
function readSuppressedClaims(repoRoot5) {
|
|
207818
|
+
const specDir = path63.join(repoRoot5, ".truecourse", "specs");
|
|
207819
|
+
const corpus = readJsonTolerant(path63.join(specDir, "corpus.json"), CorpusShape2);
|
|
207820
|
+
if (!corpus)
|
|
207821
|
+
return [];
|
|
207822
|
+
const decisions = readJsonTolerant(path63.join(specDir, "decisions.json"), DecisionsShape);
|
|
207823
|
+
const corpusLike = {
|
|
207824
|
+
areas: (corpus.areas ?? []).map((a) => ({
|
|
207825
|
+
id: a.id,
|
|
207826
|
+
overlaps: (a.overlaps ?? []).map((o) => ({
|
|
207827
|
+
docs: o.docs,
|
|
207828
|
+
note: o.note,
|
|
207829
|
+
sections: (o.sections ?? []).map((s) => ({ doc: s.doc, heading: s.heading ?? null, quote: s.quote })),
|
|
207830
|
+
areas: o.areas
|
|
207831
|
+
}))
|
|
207832
|
+
})),
|
|
207833
|
+
relations: corpus.relations ?? []
|
|
207834
|
+
};
|
|
207835
|
+
const decisionsLike = {
|
|
207836
|
+
relations: decisions?.relations ?? [],
|
|
207837
|
+
manualExcludes: decisions?.manualExcludes ?? [],
|
|
207838
|
+
conflictResolutions: (decisions?.conflictResolutions ?? []).map((r) => ({
|
|
207839
|
+
docA: r.docA,
|
|
207840
|
+
anchorA: r.anchorA ?? null,
|
|
207841
|
+
quoteA: r.quoteA,
|
|
207842
|
+
docB: r.docB,
|
|
207843
|
+
anchorB: r.anchorB ?? null,
|
|
207844
|
+
quoteB: r.quoteB,
|
|
207845
|
+
verdict: r.verdict,
|
|
207846
|
+
resolvedAt: r.resolvedAt,
|
|
207847
|
+
note: r.note
|
|
207848
|
+
}))
|
|
207849
|
+
};
|
|
207850
|
+
return suppressedClaims(corpusLike, decisionsLike);
|
|
207851
|
+
}
|
|
207852
|
+
function readSuppressionIndex(repoRoot5) {
|
|
207853
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
207854
|
+
for (const claim of readSuppressedClaims(repoRoot5)) {
|
|
207855
|
+
const list = map2.get(claim.doc);
|
|
207856
|
+
if (list)
|
|
207857
|
+
list.push(claim.quote);
|
|
207858
|
+
else
|
|
207859
|
+
map2.set(claim.doc, [claim.quote]);
|
|
207860
|
+
}
|
|
207861
|
+
return map2;
|
|
207862
|
+
}
|
|
207863
|
+
function suppressedQuotesIn(text4, docQuotes) {
|
|
207864
|
+
if (docQuotes.length === 0)
|
|
207865
|
+
return [];
|
|
207866
|
+
const haystack = normalizeQuote(text4);
|
|
207867
|
+
const seen = /* @__PURE__ */ new Set();
|
|
207868
|
+
const hits = [];
|
|
207869
|
+
for (const q2 of docQuotes) {
|
|
207870
|
+
const needle = normalizeQuote(q2);
|
|
207871
|
+
if (!needle || seen.has(needle) || !haystack.includes(needle))
|
|
207872
|
+
continue;
|
|
207873
|
+
seen.add(needle);
|
|
207874
|
+
hits.push(q2);
|
|
207875
|
+
}
|
|
207876
|
+
return hits.sort((a, b) => normalizeQuote(a) < normalizeQuote(b) ? -1 : 1);
|
|
207877
|
+
}
|
|
207878
|
+
function suppressionKey(quotes) {
|
|
207879
|
+
if (quotes.length === 0)
|
|
207880
|
+
return "";
|
|
207881
|
+
return [...quotes].map(normalizeQuote).sort().join("\0");
|
|
207882
|
+
}
|
|
207883
|
+
|
|
207884
|
+
// packages/guard-generator/dist/section-plan.js
|
|
207885
|
+
var CorpusShape3 = external_exports.object({
|
|
207453
207886
|
docs: external_exports.array(external_exports.object({ ref: external_exports.string(), areaTags: external_exports.array(external_exports.string()).optional() }).passthrough()).optional()
|
|
207454
207887
|
}).passthrough();
|
|
207455
207888
|
function readCorpusAreaTags(repoRoot5) {
|
|
207456
|
-
const file =
|
|
207889
|
+
const file = path64.join(repoRoot5, ".truecourse", "specs", "corpus.json");
|
|
207457
207890
|
const map2 = /* @__PURE__ */ new Map();
|
|
207458
|
-
if (!
|
|
207891
|
+
if (!fs60.existsSync(file))
|
|
207459
207892
|
return map2;
|
|
207460
207893
|
try {
|
|
207461
|
-
const parsed =
|
|
207894
|
+
const parsed = CorpusShape3.safeParse(JSON.parse(fs60.readFileSync(file, "utf-8")));
|
|
207462
207895
|
if (!parsed.success)
|
|
207463
207896
|
return map2;
|
|
207464
207897
|
for (const d3 of parsed.data.docs ?? [])
|
|
@@ -207467,29 +207900,35 @@ function readCorpusAreaTags(repoRoot5) {
|
|
|
207467
207900
|
}
|
|
207468
207901
|
return map2;
|
|
207469
207902
|
}
|
|
207470
|
-
function generationInputsHash(fingerprint2, recipeFingerprint) {
|
|
207471
|
-
|
|
207903
|
+
function generationInputsHash(fingerprint2, recipeFingerprint, suppressionFingerprint = "") {
|
|
207904
|
+
const parts = [
|
|
207472
207905
|
fingerprint2,
|
|
207473
207906
|
recipeFingerprint,
|
|
207474
207907
|
String(GUARD_FORMAT_VERSION),
|
|
207475
207908
|
EXTRACT_PROMPT_FINGERPRINT2,
|
|
207476
207909
|
GENERATE_PROMPT_FINGERPRINT
|
|
207477
|
-
]
|
|
207910
|
+
];
|
|
207911
|
+
if (suppressionFingerprint)
|
|
207912
|
+
parts.push(suppressionFingerprint);
|
|
207913
|
+
return "sha256:" + createHash15("sha256").update(parts.join("\0")).digest("hex");
|
|
207478
207914
|
}
|
|
207479
207915
|
function hasGuardUniverse(repoRoot5) {
|
|
207480
|
-
return
|
|
207916
|
+
return fs60.existsSync(path64.join(repoRoot5, ".truecourse", "specs", "corpus.json"));
|
|
207481
207917
|
}
|
|
207482
207918
|
function planGuardWork(repoRoot5, recipeFingerprint) {
|
|
207483
207919
|
const recipeFp = recipeFingerprint ?? computeRecipeFingerprint(repoRoot5);
|
|
207484
|
-
const recipeMissing = !
|
|
207920
|
+
const recipeMissing = !fs60.existsSync(recipePath(repoRoot5));
|
|
207485
207921
|
const hasUniverse = hasGuardUniverse(repoRoot5);
|
|
207486
207922
|
const { indexes } = indexRepoDocs(repoRoot5, []);
|
|
207487
207923
|
const areaTags = readCorpusAreaTags(repoRoot5);
|
|
207924
|
+
const suppressionIndex = readSuppressionIndex(repoRoot5);
|
|
207488
207925
|
const sections = [];
|
|
207489
207926
|
for (const [doc, index] of indexes) {
|
|
207490
|
-
const texts = extractSectionTexts(doc,
|
|
207927
|
+
const texts = extractSectionTexts(doc, fs60.readFileSync(path64.resolve(repoRoot5, doc), "utf-8"));
|
|
207928
|
+
const docQuotes = suppressionIndex.get(doc) ?? [];
|
|
207491
207929
|
for (const s of index.sections) {
|
|
207492
207930
|
const t2 = texts.get(s.anchor);
|
|
207931
|
+
const fullText = t2?.fullText ?? "";
|
|
207493
207932
|
sections.push({
|
|
207494
207933
|
doc,
|
|
207495
207934
|
anchor: s.anchor,
|
|
@@ -207497,8 +207936,9 @@ function planGuardWork(repoRoot5, recipeFingerprint) {
|
|
|
207497
207936
|
headingText: s.headingText,
|
|
207498
207937
|
level: s.level,
|
|
207499
207938
|
ownText: t2?.ownText ?? "",
|
|
207500
|
-
fullText
|
|
207501
|
-
areaTags: areaTags.get(doc) ?? []
|
|
207939
|
+
fullText,
|
|
207940
|
+
areaTags: areaTags.get(doc) ?? [],
|
|
207941
|
+
suppressionFingerprint: suppressionKey(suppressedQuotesIn(fullText, docQuotes))
|
|
207502
207942
|
});
|
|
207503
207943
|
}
|
|
207504
207944
|
}
|
|
@@ -207511,12 +207951,12 @@ function planGuardWork(repoRoot5, recipeFingerprint) {
|
|
|
207511
207951
|
const key4 = `${s.doc}\0${s.anchor}`;
|
|
207512
207952
|
seen.add(key4);
|
|
207513
207953
|
const prior = byKey.get(key4);
|
|
207514
|
-
const inputsHash = generationInputsHash(s.fingerprint, recipeFp);
|
|
207954
|
+
const inputsHash = generationInputsHash(s.fingerprint, recipeFp, s.suppressionFingerprint);
|
|
207515
207955
|
if (!prior || prior.generationInputsHash !== inputsHash)
|
|
207516
207956
|
work.push(s);
|
|
207517
207957
|
}
|
|
207518
207958
|
const orphaned = (manifest?.sections ?? []).filter((e) => !seen.has(`${e.doc}\0${e.anchor}`));
|
|
207519
|
-
return { hasUniverse, sections, work, orphaned, recipeFingerprint: recipeFp, recipeMissing };
|
|
207959
|
+
return { hasUniverse, sections, work, orphaned, recipeFingerprint: recipeFp, recipeMissing, suppressionIndex };
|
|
207520
207960
|
}
|
|
207521
207961
|
function collectWorkDocs(repoRoot5, plan) {
|
|
207522
207962
|
const workDocs = new Set(plan.work.map((s) => s.doc));
|
|
@@ -207532,8 +207972,9 @@ function collectWorkDocs(repoRoot5, plan) {
|
|
|
207532
207972
|
}
|
|
207533
207973
|
return [...byDoc].map(([doc, sections]) => ({
|
|
207534
207974
|
doc,
|
|
207535
|
-
content:
|
|
207536
|
-
sections
|
|
207975
|
+
content: fs60.readFileSync(path64.resolve(repoRoot5, doc), "utf-8"),
|
|
207976
|
+
sections,
|
|
207977
|
+
suppressedQuotes: plan.suppressionIndex.get(doc) ?? []
|
|
207537
207978
|
}));
|
|
207538
207979
|
}
|
|
207539
207980
|
|
|
@@ -207616,8 +208057,13 @@ function flattenZodError(error) {
|
|
|
207616
208057
|
// packages/guard-generator/dist/extract.js
|
|
207617
208058
|
var EXTRACT_CACHE_NAME2 = "guard/extract";
|
|
207618
208059
|
var EXTRACT_VIEW_BUDGET = 16e3;
|
|
207619
|
-
function viewCacheKey(viewText) {
|
|
207620
|
-
|
|
208060
|
+
function viewCacheKey(viewText, suppressed = []) {
|
|
208061
|
+
const base2 = `${EXTRACT_PROMPT_FINGERPRINT2}::${sha(viewText)}`;
|
|
208062
|
+
const suppression = suppressionKey(suppressed);
|
|
208063
|
+
return createHash16("sha256").update(suppression ? `${base2}::${suppression}` : base2).digest("hex");
|
|
208064
|
+
}
|
|
208065
|
+
function suppressedForView(doc, viewText) {
|
|
208066
|
+
return suppressedQuotesIn(viewText, doc.suppressedQuotes);
|
|
207621
208067
|
}
|
|
207622
208068
|
function sha(text4) {
|
|
207623
208069
|
return createHash16("sha256").update(text4).digest("hex");
|
|
@@ -207663,7 +208109,7 @@ function countExtractViews(doc) {
|
|
|
207663
208109
|
async function countUncachedExtractViews(repoRoot5, doc) {
|
|
207664
208110
|
let n = 0;
|
|
207665
208111
|
for (const v of planViews(doc)) {
|
|
207666
|
-
if (!await getCacheEntry(repoRoot5, EXTRACT_CACHE_NAME2, viewCacheKey(v.text)))
|
|
208112
|
+
if (!await getCacheEntry(repoRoot5, EXTRACT_CACHE_NAME2, viewCacheKey(v.text, suppressedForView(doc, v.text))))
|
|
207667
208113
|
n++;
|
|
207668
208114
|
}
|
|
207669
208115
|
return n;
|
|
@@ -207672,7 +208118,7 @@ async function extractDocClaims(repoRoot5, doc, runner, limit, onView) {
|
|
|
207672
208118
|
const outline = outlineOf(doc.sections);
|
|
207673
208119
|
const views = planViews(doc);
|
|
207674
208120
|
const run = limit ?? ((fn) => fn());
|
|
207675
|
-
const attempts = await Promise.all(views.map((v) => run(() => extractView(repoRoot5, doc.doc, outline, v, runner)).then((got) => {
|
|
208121
|
+
const attempts = await Promise.all(views.map((v) => run(() => extractView(repoRoot5, doc.doc, outline, v, suppressedForView(doc, v.text), runner)).then((got) => {
|
|
207676
208122
|
onView?.();
|
|
207677
208123
|
return got;
|
|
207678
208124
|
})));
|
|
@@ -207693,15 +208139,21 @@ async function extractDocClaims(repoRoot5, doc, runner, limit, onView) {
|
|
|
207693
208139
|
return { ok: false, reason: firstError || "all extraction views failed" };
|
|
207694
208140
|
return { ok: true, data: snap(merged, doc.sections), complete: failedViews === 0, failedViews };
|
|
207695
208141
|
}
|
|
207696
|
-
async function extractView(repoRoot5, docPath, outline, view, runner) {
|
|
207697
|
-
const cacheKey = viewCacheKey(view.text);
|
|
208142
|
+
async function extractView(repoRoot5, docPath, outline, view, suppressed, runner) {
|
|
208143
|
+
const cacheKey = viewCacheKey(view.text, suppressed);
|
|
207698
208144
|
const cached = await getCacheEntry(repoRoot5, EXTRACT_CACHE_NAME2, cacheKey);
|
|
207699
208145
|
if (cached) {
|
|
207700
208146
|
const parsed = DocExtractionSchema.safeParse(cached);
|
|
207701
208147
|
if (parsed.success)
|
|
207702
208148
|
return { data: parsed.data };
|
|
207703
208149
|
}
|
|
207704
|
-
const ctx = {
|
|
208150
|
+
const ctx = {
|
|
208151
|
+
doc: docPath,
|
|
208152
|
+
outline,
|
|
208153
|
+
viewText: view.text,
|
|
208154
|
+
view: view.view,
|
|
208155
|
+
...suppressed.length > 0 ? { suppressed } : {}
|
|
208156
|
+
};
|
|
207705
208157
|
const attempt = await callExtractWithReask(ctx, runner);
|
|
207706
208158
|
if ("data" in attempt)
|
|
207707
208159
|
await setCacheEntry(repoRoot5, EXTRACT_CACHE_NAME2, cacheKey, attempt.data);
|
|
@@ -207780,7 +208232,7 @@ function snap(raw, sections) {
|
|
|
207780
208232
|
|
|
207781
208233
|
// packages/guard-generator/dist/ground.js
|
|
207782
208234
|
init_zod();
|
|
207783
|
-
import
|
|
208235
|
+
import path65 from "node:path";
|
|
207784
208236
|
import { createHash as createHash17 } from "node:crypto";
|
|
207785
208237
|
var GROUND_CACHE_NAME = "guard/ground";
|
|
207786
208238
|
var PROBE_TIMEOUT_MS = 2e4;
|
|
@@ -207836,7 +208288,7 @@ function toProbeArgv(fragment, programNames) {
|
|
|
207836
208288
|
const tokens = fragment.trim().split(/\s+/).filter(Boolean);
|
|
207837
208289
|
if (tokens.length === 0)
|
|
207838
208290
|
return null;
|
|
207839
|
-
if (programNames.has(tokens[0]) || programNames.has(
|
|
208291
|
+
if (programNames.has(tokens[0]) || programNames.has(path65.basename(tokens[0])))
|
|
207840
208292
|
tokens.shift();
|
|
207841
208293
|
if (tokens.length === 0)
|
|
207842
208294
|
return [];
|
|
@@ -207857,7 +208309,7 @@ function programNamesOf(entry) {
|
|
|
207857
208309
|
return names;
|
|
207858
208310
|
}
|
|
207859
208311
|
function addName(set2, arg) {
|
|
207860
|
-
const base2 =
|
|
208312
|
+
const base2 = path65.basename(arg);
|
|
207861
208313
|
if (base2)
|
|
207862
208314
|
set2.add(base2);
|
|
207863
208315
|
const stem = base2.replace(/\.[^.]+$/, "");
|
|
@@ -207919,9 +208371,9 @@ function truncate3(text4) {
|
|
|
207919
208371
|
}
|
|
207920
208372
|
|
|
207921
208373
|
// packages/guard-generator/dist/recipe-discovery.js
|
|
207922
|
-
import
|
|
208374
|
+
import fs61 from "node:fs";
|
|
207923
208375
|
import os13 from "node:os";
|
|
207924
|
-
import
|
|
208376
|
+
import path66 from "node:path";
|
|
207925
208377
|
import { createHash as createHash18 } from "node:crypto";
|
|
207926
208378
|
var RECIPE_CACHE_NAME = "guard/recipe";
|
|
207927
208379
|
var DISCOVERY_INPUTS = ["package.json", "pnpm-lock.yaml", "package-lock.json", "yarn.lock", "turbo.json"];
|
|
@@ -207975,13 +208427,13 @@ async function discoverRecipe(repoRoot5, runner) {
|
|
|
207975
208427
|
...proposal.env ? { env: proposal.env } : {}
|
|
207976
208428
|
};
|
|
207977
208429
|
const target = recipePath(repoRoot5);
|
|
207978
|
-
|
|
207979
|
-
|
|
208430
|
+
fs61.mkdirSync(path66.dirname(target), { recursive: true });
|
|
208431
|
+
fs61.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
|
|
207980
208432
|
return {
|
|
207981
208433
|
status: "discovered",
|
|
207982
208434
|
recipe,
|
|
207983
208435
|
fingerprint: computeRecipeFingerprint(repoRoot5),
|
|
207984
|
-
wrotePath:
|
|
208436
|
+
wrotePath: path66.relative(repoRoot5, target)
|
|
207985
208437
|
};
|
|
207986
208438
|
}
|
|
207987
208439
|
async function proposeRecipeWithReask(input, runner) {
|
|
@@ -208006,14 +208458,14 @@ async function proposeRecipeWithReask(input, runner) {
|
|
|
208006
208458
|
return { error: `recipe proposal invalid after re-ask: ${flattenZodError(reParsed.error)}` };
|
|
208007
208459
|
}
|
|
208008
208460
|
function readDiscoveryInputs(repoRoot5) {
|
|
208009
|
-
const pkgPath =
|
|
208010
|
-
const packageJson =
|
|
208011
|
-
const presentInputs = DISCOVERY_INPUTS.filter((f2) =>
|
|
208461
|
+
const pkgPath = path66.join(repoRoot5, "package.json");
|
|
208462
|
+
const packageJson = fs61.existsSync(pkgPath) ? fs61.readFileSync(pkgPath, "utf-8") : "(no package.json)";
|
|
208463
|
+
const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs61.existsSync(path66.join(repoRoot5, f2)));
|
|
208012
208464
|
return { packageJson, presentInputs };
|
|
208013
208465
|
}
|
|
208014
208466
|
async function probeEntry(repoRoot5, entry) {
|
|
208015
208467
|
const resolved = resolveEntry(repoRoot5, entry);
|
|
208016
|
-
const cwd =
|
|
208468
|
+
const cwd = fs61.mkdtempSync(path66.join(os13.tmpdir(), "tc-guard-probe-"));
|
|
208017
208469
|
try {
|
|
208018
208470
|
for (const args of [["--help"], []]) {
|
|
208019
208471
|
const capture = await executeStep({
|
|
@@ -208030,7 +208482,7 @@ async function probeEntry(repoRoot5, entry) {
|
|
|
208030
208482
|
reason: `entrypoint ${JSON.stringify(entry)} did not answer to \`--help\` or a bare invocation`
|
|
208031
208483
|
};
|
|
208032
208484
|
} finally {
|
|
208033
|
-
|
|
208485
|
+
fs61.rmSync(cwd, { recursive: true, force: true });
|
|
208034
208486
|
}
|
|
208035
208487
|
}
|
|
208036
208488
|
|
|
@@ -208077,8 +208529,8 @@ async function birthValidate(repoRoot5, candidates, opts = {}) {
|
|
|
208077
208529
|
}
|
|
208078
208530
|
|
|
208079
208531
|
// packages/guard-generator/dist/serialize.js
|
|
208080
|
-
import
|
|
208081
|
-
import
|
|
208532
|
+
import fs62 from "node:fs";
|
|
208533
|
+
import path67 from "node:path";
|
|
208082
208534
|
init_dist5();
|
|
208083
208535
|
function anchorLeaf(anchor) {
|
|
208084
208536
|
const segs = anchor.split("/").filter(Boolean);
|
|
@@ -208097,7 +208549,7 @@ function assignScenarioId(anchor, used) {
|
|
|
208097
208549
|
function areaOrDocSlug(section) {
|
|
208098
208550
|
if (section.areaTags.length > 0)
|
|
208099
208551
|
return slugifyHeading(section.areaTags[0]) || "area";
|
|
208100
|
-
const base2 =
|
|
208552
|
+
const base2 = path67.basename(section.doc).replace(/\.[^.]+$/, "");
|
|
208101
208553
|
return slugifyHeading(base2) || "doc";
|
|
208102
208554
|
}
|
|
208103
208555
|
function buildScenario(section, raw, id) {
|
|
@@ -208120,15 +208572,15 @@ function scenarioFileIndex(repoRoot5) {
|
|
|
208120
208572
|
const root2 = scenariosDir(repoRoot5);
|
|
208121
208573
|
const map2 = /* @__PURE__ */ new Map();
|
|
208122
208574
|
const walk20 = (dir) => {
|
|
208123
|
-
if (!
|
|
208575
|
+
if (!fs62.existsSync(dir))
|
|
208124
208576
|
return;
|
|
208125
|
-
for (const entry of
|
|
208126
|
-
const full =
|
|
208577
|
+
for (const entry of fs62.readdirSync(dir, { withFileTypes: true })) {
|
|
208578
|
+
const full = path67.join(dir, entry.name);
|
|
208127
208579
|
if (entry.isDirectory())
|
|
208128
208580
|
walk20(full);
|
|
208129
208581
|
else if (entry.isFile() && /\.ya?ml$/i.test(entry.name)) {
|
|
208130
208582
|
try {
|
|
208131
|
-
const doc = jsYaml.load(
|
|
208583
|
+
const doc = jsYaml.load(fs62.readFileSync(full, "utf-8"));
|
|
208132
208584
|
if (doc && typeof doc.id === "string")
|
|
208133
208585
|
map2.set(doc.id, full);
|
|
208134
208586
|
} catch {
|
|
@@ -208146,18 +208598,18 @@ function serializeScenarioYaml(scenario) {
|
|
|
208146
208598
|
return jsYaml.dump(scenario, { lineWidth: -1, noRefs: true });
|
|
208147
208599
|
}
|
|
208148
208600
|
function writeScenarioFile(repoRoot5, slug2, scenario) {
|
|
208149
|
-
const dir =
|
|
208150
|
-
|
|
208151
|
-
const file =
|
|
208152
|
-
|
|
208153
|
-
return
|
|
208601
|
+
const dir = path67.join(scenariosDir(repoRoot5), slug2);
|
|
208602
|
+
fs62.mkdirSync(dir, { recursive: true });
|
|
208603
|
+
const file = path67.join(dir, `${scenario.id}.yaml`);
|
|
208604
|
+
fs62.writeFileSync(file, serializeScenarioYaml(scenario));
|
|
208605
|
+
return path67.relative(repoRoot5, file);
|
|
208154
208606
|
}
|
|
208155
208607
|
function deleteScenarioFiles(repoRoot5, ids) {
|
|
208156
208608
|
const index = scenarioFileIndex(repoRoot5);
|
|
208157
208609
|
for (const id of ids) {
|
|
208158
208610
|
const file = index.get(id);
|
|
208159
|
-
if (file &&
|
|
208160
|
-
|
|
208611
|
+
if (file && fs62.existsSync(file))
|
|
208612
|
+
fs62.rmSync(file);
|
|
208161
208613
|
}
|
|
208162
208614
|
}
|
|
208163
208615
|
|
|
@@ -208377,7 +208829,7 @@ async function generateGuards(options) {
|
|
|
208377
208829
|
anchor: section.anchor,
|
|
208378
208830
|
fingerprint: section.fingerprint,
|
|
208379
208831
|
scenarioIds: scenarioIds.slice().sort(),
|
|
208380
|
-
generationInputsHash: generationInputsHash(section.fingerprint, recipeFingerprint),
|
|
208832
|
+
generationInputsHash: generationInputsHash(section.fingerprint, recipeFingerprint, section.suppressionFingerprint),
|
|
208381
208833
|
...classification ? { classification } : {}
|
|
208382
208834
|
});
|
|
208383
208835
|
settledKeys.add(k);
|
|
@@ -208862,8 +209314,8 @@ init_context_router();
|
|
|
208862
209314
|
|
|
208863
209315
|
// packages/core/dist/services/llm/model-prices.js
|
|
208864
209316
|
init_paths();
|
|
208865
|
-
import
|
|
208866
|
-
import
|
|
209317
|
+
import fs63 from "node:fs";
|
|
209318
|
+
import path68 from "node:path";
|
|
208867
209319
|
var OPENROUTER_URL = "https://openrouter.ai/api/v1/models";
|
|
208868
209320
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
208869
209321
|
var FETCH_TIMEOUT_MS = 8e3;
|
|
@@ -208879,11 +209331,11 @@ function tierOf(id) {
|
|
|
208879
209331
|
return s.includes("opus") ? "opus" : s.includes("sonnet") ? "sonnet" : s.includes("haiku") ? "haiku" : null;
|
|
208880
209332
|
}
|
|
208881
209333
|
function cacheFilePath() {
|
|
208882
|
-
return
|
|
209334
|
+
return path68.join(getGlobalDir(), "cache", CACHE_FILE);
|
|
208883
209335
|
}
|
|
208884
209336
|
function readCache7() {
|
|
208885
209337
|
try {
|
|
208886
|
-
const t2 = JSON.parse(
|
|
209338
|
+
const t2 = JSON.parse(fs63.readFileSync(cacheFilePath(), "utf-8"));
|
|
208887
209339
|
if (t2 && t2.tiers && t2.byId && typeof t2.fetchedAt === "number")
|
|
208888
209340
|
return t2;
|
|
208889
209341
|
} catch {
|
|
@@ -208892,8 +209344,8 @@ function readCache7() {
|
|
|
208892
209344
|
}
|
|
208893
209345
|
function writeCache7(t2) {
|
|
208894
209346
|
try {
|
|
208895
|
-
|
|
208896
|
-
|
|
209347
|
+
fs63.mkdirSync(path68.dirname(cacheFilePath()), { recursive: true });
|
|
209348
|
+
fs63.writeFileSync(cacheFilePath(), JSON.stringify(t2));
|
|
208897
209349
|
} catch {
|
|
208898
209350
|
}
|
|
208899
209351
|
}
|
|
@@ -209272,16 +209724,16 @@ function changedSubject(total, changed, noun) {
|
|
|
209272
209724
|
|
|
209273
209725
|
// packages/core/dist/commands/spec-in-process.js
|
|
209274
209726
|
init_dist8();
|
|
209275
|
-
import
|
|
209276
|
-
import
|
|
209727
|
+
import fs68 from "node:fs";
|
|
209728
|
+
import path73 from "node:path";
|
|
209277
209729
|
init_git();
|
|
209278
209730
|
import { createHash as createHash20, randomUUID as randomUUID27 } from "node:crypto";
|
|
209279
209731
|
|
|
209280
209732
|
// packages/core/dist/lib/verify-store.js
|
|
209281
209733
|
init_atomic_write();
|
|
209282
209734
|
init_analysis_store();
|
|
209283
|
-
import
|
|
209284
|
-
import
|
|
209735
|
+
import fs64 from "node:fs";
|
|
209736
|
+
import path69 from "node:path";
|
|
209285
209737
|
|
|
209286
209738
|
// packages/core/dist/types/verify-snapshot.js
|
|
209287
209739
|
function driftKey(d3) {
|
|
@@ -209329,23 +209781,23 @@ var LATEST_FILE3 = "LATEST.json";
|
|
|
209329
209781
|
var HISTORY_FILE3 = "history.json";
|
|
209330
209782
|
var DIFF_FILE2 = "diff.json";
|
|
209331
209783
|
function verifierDir(repoPath) {
|
|
209332
|
-
return
|
|
209784
|
+
return path69.join(repoPath, TRUECOURSE_DIR4, VERIFIER_DIR);
|
|
209333
209785
|
}
|
|
209334
209786
|
function runsDir(repoPath) {
|
|
209335
|
-
return
|
|
209787
|
+
return path69.join(verifierDir(repoPath), RUNS_DIR2);
|
|
209336
209788
|
}
|
|
209337
209789
|
function verifyRunPath(repoPath, filename) {
|
|
209338
|
-
return
|
|
209790
|
+
return path69.join(runsDir(repoPath), filename);
|
|
209339
209791
|
}
|
|
209340
209792
|
function verifyLatestPath(repoPath) {
|
|
209341
|
-
return
|
|
209793
|
+
return path69.join(verifierDir(repoPath), LATEST_FILE3);
|
|
209342
209794
|
}
|
|
209343
209795
|
function verifyHistoryPath(repoPath) {
|
|
209344
|
-
return
|
|
209796
|
+
return path69.join(verifierDir(repoPath), HISTORY_FILE3);
|
|
209345
209797
|
}
|
|
209346
209798
|
function verifyDiffPath(repoPath, scope) {
|
|
209347
209799
|
const file = scope ? `diff-${sanitizeScope(scope)}.json` : DIFF_FILE2;
|
|
209348
|
-
return
|
|
209800
|
+
return path69.join(verifierDir(repoPath), file);
|
|
209349
209801
|
}
|
|
209350
209802
|
function sanitizeScope(scope) {
|
|
209351
209803
|
return scope.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -209379,7 +209831,7 @@ var FileVerifyStore = class {
|
|
|
209379
209831
|
const file = verifyLatestPath(repoPath);
|
|
209380
209832
|
let mtime;
|
|
209381
209833
|
try {
|
|
209382
|
-
mtime =
|
|
209834
|
+
mtime = fs64.statSync(file).mtimeMs;
|
|
209383
209835
|
} catch (err) {
|
|
209384
209836
|
if (err.code === "ENOENT") {
|
|
209385
209837
|
latestCache2.delete(repoPath);
|
|
@@ -209390,7 +209842,7 @@ var FileVerifyStore = class {
|
|
|
209390
209842
|
const cached = latestCache2.get(repoPath);
|
|
209391
209843
|
if (cached && cached.mtime === mtime)
|
|
209392
209844
|
return cached.data;
|
|
209393
|
-
const data = JSON.parse(
|
|
209845
|
+
const data = JSON.parse(fs64.readFileSync(file, "utf-8"));
|
|
209394
209846
|
latestCache2.set(repoPath, { mtime, data });
|
|
209395
209847
|
return data;
|
|
209396
209848
|
}
|
|
@@ -209400,7 +209852,7 @@ var FileVerifyStore = class {
|
|
|
209400
209852
|
}
|
|
209401
209853
|
async deleteVerifyLatest(repoPath) {
|
|
209402
209854
|
try {
|
|
209403
|
-
|
|
209855
|
+
fs64.unlinkSync(verifyLatestPath(repoPath));
|
|
209404
209856
|
} catch (err) {
|
|
209405
209857
|
if (err.code !== "ENOENT")
|
|
209406
209858
|
throw err;
|
|
@@ -209414,21 +209866,21 @@ var FileVerifyStore = class {
|
|
|
209414
209866
|
}
|
|
209415
209867
|
async readVerifyRun(repoPath, filename) {
|
|
209416
209868
|
const file = verifyRunPath(repoPath, filename);
|
|
209417
|
-
if (!
|
|
209869
|
+
if (!fs64.existsSync(file))
|
|
209418
209870
|
return null;
|
|
209419
|
-
return JSON.parse(
|
|
209871
|
+
return JSON.parse(fs64.readFileSync(file, "utf-8"));
|
|
209420
209872
|
}
|
|
209421
209873
|
async listVerifyRuns(repoPath) {
|
|
209422
209874
|
const dir = runsDir(repoPath);
|
|
209423
|
-
if (!
|
|
209875
|
+
if (!fs64.existsSync(dir))
|
|
209424
209876
|
return [];
|
|
209425
|
-
return
|
|
209877
|
+
return fs64.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
|
|
209426
209878
|
}
|
|
209427
209879
|
async readVerifyHistory(repoPath) {
|
|
209428
209880
|
const file = verifyHistoryPath(repoPath);
|
|
209429
|
-
if (!
|
|
209881
|
+
if (!fs64.existsSync(file))
|
|
209430
209882
|
return { runs: [] };
|
|
209431
|
-
return JSON.parse(
|
|
209883
|
+
return JSON.parse(fs64.readFileSync(file, "utf-8"));
|
|
209432
209884
|
}
|
|
209433
209885
|
async appendVerifyHistory(repoPath, entry) {
|
|
209434
209886
|
const history = await this.readVerifyHistory(repoPath);
|
|
@@ -209441,7 +209893,7 @@ var FileVerifyStore = class {
|
|
|
209441
209893
|
if (!entry)
|
|
209442
209894
|
return false;
|
|
209443
209895
|
try {
|
|
209444
|
-
|
|
209896
|
+
fs64.unlinkSync(verifyRunPath(repoPath, entry.filename));
|
|
209445
209897
|
} catch (err) {
|
|
209446
209898
|
if (err.code !== "ENOENT")
|
|
209447
209899
|
throw err;
|
|
@@ -209463,16 +209915,16 @@ var FileVerifyStore = class {
|
|
|
209463
209915
|
}
|
|
209464
209916
|
async readVerifyDiff(repoPath, scope) {
|
|
209465
209917
|
const file = verifyDiffPath(repoPath, scope);
|
|
209466
|
-
if (!
|
|
209918
|
+
if (!fs64.existsSync(file))
|
|
209467
209919
|
return null;
|
|
209468
|
-
return JSON.parse(
|
|
209920
|
+
return JSON.parse(fs64.readFileSync(file, "utf-8"));
|
|
209469
209921
|
}
|
|
209470
209922
|
async writeVerifyDiff(repoPath, diff, scope) {
|
|
209471
209923
|
atomicWriteJson(verifyDiffPath(repoPath, scope), diff);
|
|
209472
209924
|
}
|
|
209473
209925
|
async deleteVerifyDiff(repoPath, scope) {
|
|
209474
209926
|
try {
|
|
209475
|
-
|
|
209927
|
+
fs64.unlinkSync(verifyDiffPath(repoPath, scope));
|
|
209476
209928
|
} catch (err) {
|
|
209477
209929
|
if (err.code !== "ENOENT")
|
|
209478
209930
|
throw err;
|
|
@@ -209506,8 +209958,8 @@ async function repoRef(repoRoot5, commitOverride) {
|
|
|
209506
209958
|
}
|
|
209507
209959
|
|
|
209508
209960
|
// packages/core/dist/lib/contract-store.js
|
|
209509
|
-
import
|
|
209510
|
-
import
|
|
209961
|
+
import fs65 from "node:fs";
|
|
209962
|
+
import path70 from "node:path";
|
|
209511
209963
|
var KIND_REL = {
|
|
209512
209964
|
contracts: [".truecourse", "contracts"],
|
|
209513
209965
|
// The inferred tree lives at contracts/_inferred (matches `writeInferred`).
|
|
@@ -209517,13 +209969,13 @@ function countTcFiles(dir) {
|
|
|
209517
209969
|
let n = 0;
|
|
209518
209970
|
let entries;
|
|
209519
209971
|
try {
|
|
209520
|
-
entries =
|
|
209972
|
+
entries = fs65.readdirSync(dir, { withFileTypes: true });
|
|
209521
209973
|
} catch {
|
|
209522
209974
|
return 0;
|
|
209523
209975
|
}
|
|
209524
209976
|
for (const e of entries) {
|
|
209525
209977
|
if (e.isDirectory())
|
|
209526
|
-
n += countTcFiles(
|
|
209978
|
+
n += countTcFiles(path70.join(dir, e.name));
|
|
209527
209979
|
else if (e.isFile() && e.name.endsWith(".tc"))
|
|
209528
209980
|
n += 1;
|
|
209529
209981
|
}
|
|
@@ -209534,7 +209986,7 @@ function walkTcRel(dir, excludeInferred) {
|
|
|
209534
209986
|
const walk20 = (rel) => {
|
|
209535
209987
|
let entries;
|
|
209536
209988
|
try {
|
|
209537
|
-
entries =
|
|
209989
|
+
entries = fs65.readdirSync(path70.join(dir, rel), { withFileTypes: true });
|
|
209538
209990
|
} catch {
|
|
209539
209991
|
return;
|
|
209540
209992
|
}
|
|
@@ -209558,50 +210010,50 @@ function safeResolve(root2, rel) {
|
|
|
209558
210010
|
return null;
|
|
209559
210011
|
if (norm.split("/").some((s) => s === ".." || s === "." || s === ""))
|
|
209560
210012
|
return null;
|
|
209561
|
-
const base2 =
|
|
209562
|
-
const dest =
|
|
209563
|
-
if (dest !== base2 && !dest.startsWith(base2 +
|
|
210013
|
+
const base2 = path70.resolve(root2);
|
|
210014
|
+
const dest = path70.resolve(base2, norm);
|
|
210015
|
+
if (dest !== base2 && !dest.startsWith(base2 + path70.sep))
|
|
209564
210016
|
return null;
|
|
209565
210017
|
return dest;
|
|
209566
210018
|
}
|
|
209567
210019
|
var FileContractStore = class {
|
|
209568
210020
|
materializesInPlace = true;
|
|
209569
210021
|
async saveContracts(ref, kind, _sourceDir) {
|
|
209570
|
-
const dir =
|
|
210022
|
+
const dir = path70.join(ref.repoKey, ...KIND_REL[kind]);
|
|
209571
210023
|
return { manifest: {}, fileCount: countTcFiles(dir), objectsWritten: 0, manifestHash: "" };
|
|
209572
210024
|
}
|
|
209573
210025
|
async loadContracts(ref, kind) {
|
|
209574
|
-
const dir =
|
|
209575
|
-
if (!
|
|
210026
|
+
const dir = path70.join(ref.repoKey, ...KIND_REL[kind]);
|
|
210027
|
+
if (!fs65.existsSync(dir))
|
|
209576
210028
|
return null;
|
|
209577
210029
|
return { dir, cleanup: async () => {
|
|
209578
210030
|
} };
|
|
209579
210031
|
}
|
|
209580
210032
|
async hasContracts(ref, kind) {
|
|
209581
|
-
return
|
|
210033
|
+
return fs65.existsSync(path70.join(ref.repoKey, ...KIND_REL[kind]));
|
|
209582
210034
|
}
|
|
209583
210035
|
// The file impl reads the live repo tree, which is whatever is checked out —
|
|
209584
210036
|
// there is no per-commit history, so `commitSha` is ignored (OSS is latest).
|
|
209585
210037
|
async listContractFiles(repoKey, kind, _commitSha) {
|
|
209586
|
-
return walkTcRel(
|
|
210038
|
+
return walkTcRel(path70.join(repoKey, ...KIND_REL[kind]), kind === "contracts");
|
|
209587
210039
|
}
|
|
209588
210040
|
async readContractFile(repoKey, kind, relPath, _commitSha) {
|
|
209589
|
-
const dest = safeResolve(
|
|
209590
|
-
if (!dest || !
|
|
210041
|
+
const dest = safeResolve(path70.join(repoKey, ...KIND_REL[kind]), relPath);
|
|
210042
|
+
if (!dest || !fs65.existsSync(dest) || !fs65.statSync(dest).isFile())
|
|
209591
210043
|
return null;
|
|
209592
|
-
return
|
|
210044
|
+
return fs65.readFileSync(dest, "utf-8");
|
|
209593
210045
|
}
|
|
209594
210046
|
async putContractFile(ref, kind, relPath, content) {
|
|
209595
|
-
const dest = safeResolve(
|
|
210047
|
+
const dest = safeResolve(path70.join(ref.repoKey, ...KIND_REL[kind]), relPath);
|
|
209596
210048
|
if (!dest)
|
|
209597
210049
|
throw new Error(`[contract-store] unsafe contract path: ${relPath}`);
|
|
209598
|
-
|
|
209599
|
-
|
|
210050
|
+
fs65.mkdirSync(path70.dirname(dest), { recursive: true });
|
|
210051
|
+
fs65.writeFileSync(dest, content);
|
|
209600
210052
|
}
|
|
209601
210053
|
async deleteContractFile(ref, kind, relPath) {
|
|
209602
|
-
const dest = safeResolve(
|
|
210054
|
+
const dest = safeResolve(path70.join(ref.repoKey, ...KIND_REL[kind]), relPath);
|
|
209603
210055
|
if (dest)
|
|
209604
|
-
|
|
210056
|
+
fs65.rmSync(dest, { force: true });
|
|
209605
210057
|
}
|
|
209606
210058
|
// OSS/local has no workspace concept (mirrors the spec store). Writing throws
|
|
209607
210059
|
// (fail loud — a caller that reached here is mis-wired); reads are empty so an
|
|
@@ -209628,10 +210080,10 @@ var loadWorkspaceContracts = (ref, kind) => active8.loadWorkspaceContracts(ref,
|
|
|
209628
210080
|
var contractsMaterializeInPlace = () => active8.materializesInPlace;
|
|
209629
210081
|
|
|
209630
210082
|
// packages/core/dist/lib/spec-store.js
|
|
209631
|
-
import
|
|
209632
|
-
import
|
|
210083
|
+
import fs66 from "node:fs";
|
|
210084
|
+
import path71 from "node:path";
|
|
209633
210085
|
function specPath(repoKey, artifact) {
|
|
209634
|
-
return
|
|
210086
|
+
return path71.join(repoKey, ".truecourse", "specs", `${artifact}.json`);
|
|
209635
210087
|
}
|
|
209636
210088
|
function isPrDecisionsRef(commitSha) {
|
|
209637
210089
|
return /^_pr\/\d+$/.test(commitSha ?? "");
|
|
@@ -209644,18 +210096,18 @@ var FileSpecStore = class {
|
|
|
209644
210096
|
throw new Error(PR_DECISIONS_FILE_ERROR);
|
|
209645
210097
|
}
|
|
209646
210098
|
const file = specPath(ref.repoKey, artifact);
|
|
209647
|
-
|
|
209648
|
-
|
|
210099
|
+
fs66.mkdirSync(path71.dirname(file), { recursive: true });
|
|
210100
|
+
fs66.writeFileSync(file, JSON.stringify(json2, null, 2) + "\n", "utf-8");
|
|
209649
210101
|
}
|
|
209650
210102
|
async loadSpec(ref, artifact) {
|
|
209651
210103
|
if (artifact === "decisions" && isPrDecisionsRef(ref.commitSha)) {
|
|
209652
210104
|
throw new Error(PR_DECISIONS_FILE_ERROR);
|
|
209653
210105
|
}
|
|
209654
210106
|
const file = specPath(ref.repoKey, artifact);
|
|
209655
|
-
if (!
|
|
210107
|
+
if (!fs66.existsSync(file))
|
|
209656
210108
|
return null;
|
|
209657
210109
|
try {
|
|
209658
|
-
return JSON.parse(
|
|
210110
|
+
return JSON.parse(fs66.readFileSync(file, "utf-8"));
|
|
209659
210111
|
} catch {
|
|
209660
210112
|
return null;
|
|
209661
210113
|
}
|
|
@@ -209665,8 +210117,8 @@ var FileSpecStore = class {
|
|
|
209665
210117
|
throw new Error(PR_DECISIONS_FILE_ERROR);
|
|
209666
210118
|
}
|
|
209667
210119
|
const file = specPath(ref.repoKey, artifact);
|
|
209668
|
-
if (
|
|
209669
|
-
|
|
210120
|
+
if (fs66.existsSync(file))
|
|
210121
|
+
fs66.rmSync(file);
|
|
209670
210122
|
}
|
|
209671
210123
|
// The file impl is single-document-per-repo, so "latest" === read the file.
|
|
209672
210124
|
async loadLatest(repoKey, artifact) {
|
|
@@ -209693,23 +210145,23 @@ var loadLatestSpec = (repoKey, artifact) => active9.loadLatest(repoKey, artifact
|
|
|
209693
210145
|
var specsMaterializeInPlace = () => active9.materializesInPlace;
|
|
209694
210146
|
|
|
209695
210147
|
// packages/core/dist/lib/inferred-action-store.js
|
|
209696
|
-
import
|
|
209697
|
-
import
|
|
210148
|
+
import fs67 from "node:fs";
|
|
210149
|
+
import path72 from "node:path";
|
|
209698
210150
|
function actionsFile(repoKey) {
|
|
209699
|
-
return
|
|
210151
|
+
return path72.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
|
|
209700
210152
|
}
|
|
209701
210153
|
var FileInferredActionStore = class {
|
|
209702
210154
|
read(repoKey) {
|
|
209703
210155
|
try {
|
|
209704
|
-
return JSON.parse(
|
|
210156
|
+
return JSON.parse(fs67.readFileSync(actionsFile(repoKey), "utf-8"));
|
|
209705
210157
|
} catch {
|
|
209706
210158
|
return [];
|
|
209707
210159
|
}
|
|
209708
210160
|
}
|
|
209709
210161
|
write(repoKey, actions) {
|
|
209710
210162
|
const file = actionsFile(repoKey);
|
|
209711
|
-
|
|
209712
|
-
|
|
210163
|
+
fs67.mkdirSync(path72.dirname(file), { recursive: true });
|
|
210164
|
+
fs67.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
|
|
209713
210165
|
}
|
|
209714
210166
|
async setAction(repoKey, action) {
|
|
209715
210167
|
const next = this.read(repoKey).filter((a) => !(a.kind === action.kind && a.identity === action.identity));
|
|
@@ -209838,13 +210290,13 @@ function resolveTransport(options) {
|
|
|
209838
210290
|
}
|
|
209839
210291
|
return getDefaultTransport();
|
|
209840
210292
|
}
|
|
209841
|
-
var GENERATED_MARKER_REL =
|
|
210293
|
+
var GENERATED_MARKER_REL = path73.join(".truecourse", "contracts", "result.json");
|
|
209842
210294
|
function generatedMarkerPath(repoRoot5) {
|
|
209843
|
-
return
|
|
210295
|
+
return path73.join(repoRoot5, GENERATED_MARKER_REL);
|
|
209844
210296
|
}
|
|
209845
210297
|
function stampGeneratedMarker(repoRoot5, summary) {
|
|
209846
210298
|
const file = generatedMarkerPath(repoRoot5);
|
|
209847
|
-
|
|
210299
|
+
fs68.mkdirSync(path73.dirname(file), { recursive: true });
|
|
209848
210300
|
const body = {
|
|
209849
210301
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
209850
210302
|
written: summary?.written ?? 0,
|
|
@@ -209852,7 +210304,7 @@ function stampGeneratedMarker(repoRoot5, summary) {
|
|
|
209852
210304
|
validationIssues: summary?.validationIssues ?? [],
|
|
209853
210305
|
enumerateFailures: summary?.enumerateFailures ?? []
|
|
209854
210306
|
};
|
|
209855
|
-
|
|
210307
|
+
fs68.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
|
|
209856
210308
|
}
|
|
209857
210309
|
function resolveCurateModels(repoRoot5) {
|
|
209858
210310
|
return {
|
|
@@ -209976,22 +210428,22 @@ async function curateInProcess(repoRoot5, options = {}) {
|
|
|
209976
210428
|
}
|
|
209977
210429
|
}
|
|
209978
210430
|
function buildPriorContracts(repoRoot5) {
|
|
209979
|
-
const dir =
|
|
209980
|
-
if (!
|
|
210431
|
+
const dir = path73.join(repoRoot5, ".truecourse", "contracts");
|
|
210432
|
+
if (!fs68.existsSync(dir))
|
|
209981
210433
|
return void 0;
|
|
209982
210434
|
const targets = [];
|
|
209983
210435
|
const bodyByKey = /* @__PURE__ */ new Map();
|
|
209984
210436
|
const walk20 = (d3) => {
|
|
209985
|
-
for (const e of
|
|
210437
|
+
for (const e of fs68.readdirSync(d3, { withFileTypes: true })) {
|
|
209986
210438
|
if (e.isDirectory()) {
|
|
209987
210439
|
if (e.name === "_inferred")
|
|
209988
210440
|
continue;
|
|
209989
|
-
walk20(
|
|
210441
|
+
walk20(path73.join(d3, e.name));
|
|
209990
210442
|
} else if (e.name.endsWith(".tc")) {
|
|
209991
|
-
const abs =
|
|
209992
|
-
const src =
|
|
210443
|
+
const abs = path73.join(d3, e.name);
|
|
210444
|
+
const src = fs68.readFileSync(abs, "utf-8");
|
|
209993
210445
|
try {
|
|
209994
|
-
const file = parser_ohm_exports.parseTcFile(
|
|
210446
|
+
const file = parser_ohm_exports.parseTcFile(path73.relative(dir, abs), src);
|
|
209995
210447
|
for (const key4 of resolver_exports.resolve([file]).index.keys()) {
|
|
209996
210448
|
const colon = key4.indexOf(":");
|
|
209997
210449
|
if (colon < 0)
|
|
@@ -210151,18 +210603,18 @@ function resolverHardError(result) {
|
|
|
210151
210603
|
const detail = reasons.length ? reasons.slice(0, 3).join("; ") : "duplicate or conflicting artifact identities";
|
|
210152
210604
|
return new Error(`Contract corpus failed to resolve \u2014 ${detail}`);
|
|
210153
210605
|
}
|
|
210154
|
-
var LEGACY_VERIFY_STATE_REL =
|
|
210606
|
+
var LEGACY_VERIFY_STATE_REL = path73.join(".truecourse", ".cache", "verifier", "verify-state.json");
|
|
210155
210607
|
function legacyVerifyStatePath(repoRoot5) {
|
|
210156
|
-
return
|
|
210608
|
+
return path73.join(repoRoot5, LEGACY_VERIFY_STATE_REL);
|
|
210157
210609
|
}
|
|
210158
210610
|
async function withContracts(repoRoot5, options, tracker, fn) {
|
|
210159
|
-
const fallbackPath =
|
|
210611
|
+
const fallbackPath = path73.join(repoRoot5, ".truecourse", "contracts");
|
|
210160
210612
|
const wsMat = options.workspaceOrgId ? await loadWorkspaceContracts({ workspaceOrgId: options.workspaceOrgId }, "contracts") : null;
|
|
210161
210613
|
let repoMat = null;
|
|
210162
210614
|
try {
|
|
210163
210615
|
let recorded;
|
|
210164
210616
|
if (options.contractsDir) {
|
|
210165
|
-
if (!
|
|
210617
|
+
if (!fs68.existsSync(options.contractsDir)) {
|
|
210166
210618
|
const err = new Error(`Contracts directory not found at ${options.contractsDir}. Run \`truecourse contracts generate\` first.`);
|
|
210167
210619
|
tracker?.error("load", err.message);
|
|
210168
210620
|
throw err;
|
|
@@ -210207,7 +210659,7 @@ async function verifyInProcess(repoRoot5, options = {}) {
|
|
|
210207
210659
|
tracker?.start("compare");
|
|
210208
210660
|
tracker?.done("compare", `${result.drifts.length} drift${result.drifts.length === 1 ? "" : "s"}`);
|
|
210209
210661
|
if (options.ref) {
|
|
210210
|
-
result.drifts = result.drifts.map((d3) => d3.filePath &&
|
|
210662
|
+
result.drifts = result.drifts.map((d3) => d3.filePath && path73.isAbsolute(d3.filePath) ? { ...d3, filePath: path73.relative(repoRoot5, d3.filePath).split(path73.sep).join("/") } : d3);
|
|
210211
210663
|
}
|
|
210212
210664
|
const verifiedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
210213
210665
|
const { branch, commitHash } = await gitMeta(repoRoot5);
|
|
@@ -210251,7 +210703,7 @@ async function verifyInProcess(repoRoot5, options = {}) {
|
|
|
210251
210703
|
bySeverity: summary.bySeverity
|
|
210252
210704
|
});
|
|
210253
210705
|
await deleteVerifyDiff(storeKey);
|
|
210254
|
-
|
|
210706
|
+
fs68.rmSync(legacyVerifyStatePath(repoRoot5), { force: true });
|
|
210255
210707
|
}
|
|
210256
210708
|
const state = {
|
|
210257
210709
|
verifiedAt,
|
|
@@ -210299,7 +210751,7 @@ async function runWithStash(repoRoot5, skipStash, tracker, fn) {
|
|
|
210299
210751
|
const status = await stashGit.status();
|
|
210300
210752
|
if (!status.isClean()) {
|
|
210301
210753
|
const gitRoot = (await stashGit.revparse(["--show-toplevel"])).trim();
|
|
210302
|
-
if (
|
|
210754
|
+
if (path73.resolve(repoRoot5) === path73.resolve(gitRoot)) {
|
|
210303
210755
|
tracker?.detail?.("load", "Stashing pending changes...");
|
|
210304
210756
|
const res = await stashGit.stash(["push", "--include-untracked", "-m", "truecourse-verify-stash"]);
|
|
210305
210757
|
didStash = !res.includes("No local changes");
|
|
@@ -210401,7 +210853,7 @@ async function verifyDiffInProcess(repoRoot5, options = {}) {
|
|
|
210401
210853
|
async function inferInProcess(repoRoot5, options = {}) {
|
|
210402
210854
|
const startedAt = Date.now();
|
|
210403
210855
|
const codeDir = options.codeDir ?? autodetectCodeDir(repoRoot5);
|
|
210404
|
-
let contractsDir = options.contractsDir ??
|
|
210856
|
+
let contractsDir = options.contractsDir ?? path73.join(repoRoot5, ".truecourse", "contracts");
|
|
210405
210857
|
let releaseContracts = async () => {
|
|
210406
210858
|
};
|
|
210407
210859
|
if (!options.contractsDir && options.ref) {
|
|
@@ -210445,7 +210897,7 @@ async function persistInferred(repoRoot5, options, contractsDir, codeDir, starte
|
|
|
210445
210897
|
});
|
|
210446
210898
|
}
|
|
210447
210899
|
if (!options.dryRun && options.ref) {
|
|
210448
|
-
await saveContracts(options.ref, "contracts_inferred",
|
|
210900
|
+
await saveContracts(options.ref, "contracts_inferred", path73.join(contractsDir, "_inferred"));
|
|
210449
210901
|
}
|
|
210450
210902
|
const rendered = result.decisions.map((d3) => renderDecision(d3));
|
|
210451
210903
|
const decisionPaths = rendered.map((r) => r.relPath);
|
|
@@ -210468,8 +210920,8 @@ async function persistInferred(repoRoot5, options, contractsDir, codeDir, starte
|
|
|
210468
210920
|
return { infer: result, written, proposed, decisionPaths, summaries };
|
|
210469
210921
|
}
|
|
210470
210922
|
function autodetectCodeDir(repoRoot5) {
|
|
210471
|
-
const codeSubdir =
|
|
210472
|
-
if (
|
|
210923
|
+
const codeSubdir = path73.join(repoRoot5, "code");
|
|
210924
|
+
if (fs68.existsSync(codeSubdir) && fs68.statSync(codeSubdir).isDirectory()) {
|
|
210473
210925
|
return codeSubdir;
|
|
210474
210926
|
}
|
|
210475
210927
|
return repoRoot5;
|
|
@@ -210479,7 +210931,8 @@ var EMPTY_DECISIONS3 = {
|
|
|
210479
210931
|
manualIncludes: [],
|
|
210480
210932
|
manualExcludes: [],
|
|
210481
210933
|
relations: [],
|
|
210482
|
-
manualAreas: []
|
|
210934
|
+
manualAreas: [],
|
|
210935
|
+
conflictResolutions: []
|
|
210483
210936
|
};
|
|
210484
210937
|
var DECISIONS_REF = "_repo";
|
|
210485
210938
|
var prDecisionsRef = (pr) => `_pr/${pr}`;
|
|
@@ -210533,7 +210986,12 @@ function mergeDecisions(base2, overlay) {
|
|
|
210533
210986
|
...(base2.manualAreas ?? []).filter((a) => !overlayAreaDocs.has(a.doc)),
|
|
210534
210987
|
...overlay.manualAreas ?? []
|
|
210535
210988
|
];
|
|
210536
|
-
|
|
210989
|
+
const overlayResKeys = new Set((overlay.conflictResolutions ?? []).map(conflictResolutionKey));
|
|
210990
|
+
const conflictResolutions = [
|
|
210991
|
+
...(base2.conflictResolutions ?? []).filter((r) => !overlayResKeys.has(conflictResolutionKey(r))),
|
|
210992
|
+
...overlay.conflictResolutions ?? []
|
|
210993
|
+
];
|
|
210994
|
+
return { version: 1, manualIncludes, manualExcludes, relations, manualAreas, conflictResolutions };
|
|
210537
210995
|
}
|
|
210538
210996
|
function uniqueStrings(items) {
|
|
210539
210997
|
return [...new Set(items)];
|
|
@@ -210542,6 +211000,13 @@ function getCorpus(repoKey) {
|
|
|
210542
211000
|
return loadLatestSpec(repoKey, "corpus");
|
|
210543
211001
|
}
|
|
210544
211002
|
var relationKey = (r) => `${[r.older, r.newer].sort().join(" ")} ${r.scope ?? ""}`;
|
|
211003
|
+
var conflictResolutionKey = (r) => {
|
|
211004
|
+
const sides = [
|
|
211005
|
+
`${r.docA}#${r.anchorA ?? ""}`,
|
|
211006
|
+
`${r.docB}#${r.anchorB ?? ""}`
|
|
211007
|
+
].sort();
|
|
211008
|
+
return sides.join(" \0 ");
|
|
211009
|
+
};
|
|
210545
211010
|
function applyAddRelation(existing, input) {
|
|
210546
211011
|
if (input.older === input.newer) {
|
|
210547
211012
|
throw new Error("addRelation: older and newer must be different docs");
|
|
@@ -210554,20 +211019,22 @@ function applyAddRelation(existing, input) {
|
|
|
210554
211019
|
manualIncludes: existing.manualIncludes ?? [],
|
|
210555
211020
|
manualExcludes: existing.manualExcludes ?? [],
|
|
210556
211021
|
relations: [...dedup, relation],
|
|
210557
|
-
manualAreas: existing.manualAreas ?? []
|
|
211022
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211023
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
210558
211024
|
};
|
|
210559
211025
|
}
|
|
210560
211026
|
function applyRemoveRelation(existing, input) {
|
|
210561
211027
|
const matches = (r) => {
|
|
210562
|
-
const
|
|
210563
|
-
return
|
|
211028
|
+
const samePair2 = r.older === input.older && r.newer === input.newer || r.older === input.newer && r.newer === input.older;
|
|
211029
|
+
return samePair2 && (input.scope === void 0 || r.scope === input.scope);
|
|
210564
211030
|
};
|
|
210565
211031
|
return {
|
|
210566
211032
|
version: 1,
|
|
210567
211033
|
manualIncludes: existing.manualIncludes ?? [],
|
|
210568
211034
|
manualExcludes: existing.manualExcludes ?? [],
|
|
210569
211035
|
relations: (existing.relations ?? []).filter((r) => !matches(r)),
|
|
210570
|
-
manualAreas: existing.manualAreas ?? []
|
|
211036
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211037
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
210571
211038
|
};
|
|
210572
211039
|
}
|
|
210573
211040
|
function applyAddManualInclude(existing, docPath) {
|
|
@@ -210580,7 +211047,8 @@ function applyAddManualInclude(existing, docPath) {
|
|
|
210580
211047
|
manualIncludes: includes.includes(docPath) ? includes : [...includes, docPath],
|
|
210581
211048
|
manualExcludes: excludes.filter((p2) => p2 !== docPath),
|
|
210582
211049
|
relations: existing.relations ?? [],
|
|
210583
|
-
manualAreas: existing.manualAreas ?? []
|
|
211050
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211051
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
210584
211052
|
};
|
|
210585
211053
|
}
|
|
210586
211054
|
function applyRemoveManualInclude(existing, docPath) {
|
|
@@ -210589,7 +211057,8 @@ function applyRemoveManualInclude(existing, docPath) {
|
|
|
210589
211057
|
manualIncludes: (existing.manualIncludes ?? []).filter((p2) => p2 !== docPath),
|
|
210590
211058
|
manualExcludes: existing.manualExcludes ?? [],
|
|
210591
211059
|
relations: existing.relations ?? [],
|
|
210592
|
-
manualAreas: existing.manualAreas ?? []
|
|
211060
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211061
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
210593
211062
|
};
|
|
210594
211063
|
}
|
|
210595
211064
|
function applyAddManualExclude(existing, docPath) {
|
|
@@ -210602,7 +211071,8 @@ function applyAddManualExclude(existing, docPath) {
|
|
|
210602
211071
|
manualIncludes: includes.filter((p2) => p2 !== docPath),
|
|
210603
211072
|
manualExcludes: excludes.includes(docPath) ? excludes : [...excludes, docPath],
|
|
210604
211073
|
relations: existing.relations ?? [],
|
|
210605
|
-
manualAreas: existing.manualAreas ?? []
|
|
211074
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211075
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
210606
211076
|
};
|
|
210607
211077
|
}
|
|
210608
211078
|
function applyRemoveManualExclude(existing, docPath) {
|
|
@@ -210611,7 +211081,23 @@ function applyRemoveManualExclude(existing, docPath) {
|
|
|
210611
211081
|
manualIncludes: existing.manualIncludes ?? [],
|
|
210612
211082
|
manualExcludes: (existing.manualExcludes ?? []).filter((p2) => p2 !== docPath),
|
|
210613
211083
|
relations: existing.relations ?? [],
|
|
210614
|
-
manualAreas: existing.manualAreas ?? []
|
|
211084
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211085
|
+
conflictResolutions: existing.conflictResolutions ?? []
|
|
211086
|
+
};
|
|
211087
|
+
}
|
|
211088
|
+
function applyAddConflictResolution(existing, input) {
|
|
211089
|
+
if (input.docA === input.docB) {
|
|
211090
|
+
throw new Error("addConflictResolution: docA and docB must be different docs");
|
|
211091
|
+
}
|
|
211092
|
+
const key4 = conflictResolutionKey(input);
|
|
211093
|
+
const dedup = (existing.conflictResolutions ?? []).filter((r) => conflictResolutionKey(r) !== key4);
|
|
211094
|
+
return {
|
|
211095
|
+
version: 1,
|
|
211096
|
+
manualIncludes: existing.manualIncludes ?? [],
|
|
211097
|
+
manualExcludes: existing.manualExcludes ?? [],
|
|
211098
|
+
relations: existing.relations ?? [],
|
|
211099
|
+
manualAreas: existing.manualAreas ?? [],
|
|
211100
|
+
conflictResolutions: [...dedup, input]
|
|
210615
211101
|
};
|
|
210616
211102
|
}
|
|
210617
211103
|
async function addRelation(repoRoot5, input, opts) {
|
|
@@ -210648,6 +211134,11 @@ async function removeManualExclude(repoRoot5, docPath, opts) {
|
|
|
210648
211134
|
await storeDecisions(repoRoot5, next, opts);
|
|
210649
211135
|
return next;
|
|
210650
211136
|
}
|
|
211137
|
+
async function addConflictResolution(repoRoot5, input, opts) {
|
|
211138
|
+
const next = applyAddConflictResolution(await loadDecisions(repoRoot5, opts), input);
|
|
211139
|
+
await storeDecisions(repoRoot5, next, opts);
|
|
211140
|
+
return next;
|
|
211141
|
+
}
|
|
210651
211142
|
|
|
210652
211143
|
// tools/cli/src/commands/contracts.ts
|
|
210653
211144
|
init_progress();
|
|
@@ -210824,8 +211315,8 @@ async function runContractsGenerate(options = {}) {
|
|
|
210824
211315
|
}
|
|
210825
211316
|
async function runContractsList(options = {}) {
|
|
210826
211317
|
const repoRoot5 = options.cwd ?? process.cwd();
|
|
210827
|
-
const contractsDir =
|
|
210828
|
-
if (!
|
|
211318
|
+
const contractsDir = path74.join(repoRoot5, ".truecourse", "contracts");
|
|
211319
|
+
if (!fs69.existsSync(contractsDir)) {
|
|
210829
211320
|
O2.info("No contracts found. Run `truecourse contracts generate` first.");
|
|
210830
211321
|
return;
|
|
210831
211322
|
}
|
|
@@ -210833,12 +211324,12 @@ async function runContractsList(options = {}) {
|
|
|
210833
211324
|
const fileNodes = [];
|
|
210834
211325
|
let parseErrors = 0;
|
|
210835
211326
|
const visit = (dir) => {
|
|
210836
|
-
for (const entry of
|
|
210837
|
-
const full =
|
|
211327
|
+
for (const entry of fs69.readdirSync(dir, { withFileTypes: true })) {
|
|
211328
|
+
const full = path74.join(dir, entry.name);
|
|
210838
211329
|
if (entry.isDirectory()) visit(full);
|
|
210839
211330
|
else if (entry.isFile() && entry.name.endsWith(".tc")) {
|
|
210840
211331
|
try {
|
|
210841
|
-
fileNodes.push(parserOhm.parseTcFile(full,
|
|
211332
|
+
fileNodes.push(parserOhm.parseTcFile(full, fs69.readFileSync(full, "utf-8")));
|
|
210842
211333
|
} catch {
|
|
210843
211334
|
parseErrors += 1;
|
|
210844
211335
|
}
|
|
@@ -210865,7 +211356,7 @@ async function runContractsList(options = {}) {
|
|
|
210865
211356
|
mt(`Contracts \u2014 ${artifacts.length} ${scope}artifact${artifacts.length === 1 ? "" : "s"}`);
|
|
210866
211357
|
for (const a of artifacts) {
|
|
210867
211358
|
const conf = a.confidence ? `[${a.confidence}] ` : "";
|
|
210868
|
-
const loc = a.origin ? a.origin.lines[0] >= 0 ? `${a.origin.source}:${a.origin.lines[0]}` : a.origin.source : `${
|
|
211359
|
+
const loc = a.origin ? a.origin.lines[0] >= 0 ? `${a.origin.source}:${a.origin.lines[0]}` : a.origin.source : `${path74.relative(repoRoot5, a.declarationLoc.filePath)}:${a.declarationLoc.lineStart}`;
|
|
210869
211360
|
console.log(` ${conf}${a.ref.type}:${a.ref.identity} ${loc}`);
|
|
210870
211361
|
}
|
|
210871
211362
|
if (parseErrors > 0) {
|
|
@@ -210877,8 +211368,8 @@ async function runContractsList(options = {}) {
|
|
|
210877
211368
|
}
|
|
210878
211369
|
async function runContractsValidate(options = {}) {
|
|
210879
211370
|
const repoRoot5 = options.cwd ?? process.cwd();
|
|
210880
|
-
const contractsDir =
|
|
210881
|
-
if (!
|
|
211371
|
+
const contractsDir = path74.join(repoRoot5, ".truecourse", "contracts");
|
|
211372
|
+
if (!fs69.existsSync(contractsDir)) {
|
|
210882
211373
|
O2.error("No .truecourse/contracts/ directory found.");
|
|
210883
211374
|
process.exit(1);
|
|
210884
211375
|
}
|
|
@@ -210886,14 +211377,14 @@ async function runContractsValidate(options = {}) {
|
|
|
210886
211377
|
const fileNodes = [];
|
|
210887
211378
|
const issues = [];
|
|
210888
211379
|
const visit = (dir) => {
|
|
210889
|
-
for (const entry of
|
|
210890
|
-
const full =
|
|
211380
|
+
for (const entry of fs69.readdirSync(dir, { withFileTypes: true })) {
|
|
211381
|
+
const full = path74.join(dir, entry.name);
|
|
210891
211382
|
if (entry.isDirectory()) visit(full);
|
|
210892
211383
|
else if (entry.isFile() && entry.name.endsWith(".tc")) {
|
|
210893
211384
|
try {
|
|
210894
|
-
fileNodes.push(parserOhm.parseTcFile(full,
|
|
211385
|
+
fileNodes.push(parserOhm.parseTcFile(full, fs69.readFileSync(full, "utf-8")));
|
|
210895
211386
|
} catch (e) {
|
|
210896
|
-
issues.push(`${
|
|
211387
|
+
issues.push(`${path74.relative(repoRoot5, full)}: parse error: ${e instanceof Error ? e.message : e}`);
|
|
210897
211388
|
}
|
|
210898
211389
|
}
|
|
210899
211390
|
}
|
|
@@ -210901,11 +211392,11 @@ async function runContractsValidate(options = {}) {
|
|
|
210901
211392
|
visit(contractsDir);
|
|
210902
211393
|
const resolution = resolver.resolve(fileNodes);
|
|
210903
211394
|
for (const err of resolution.errors) {
|
|
210904
|
-
issues.push(`${
|
|
211395
|
+
issues.push(`${path74.relative(repoRoot5, err.filePath)}:${err.line} ${err.message}`);
|
|
210905
211396
|
}
|
|
210906
211397
|
const trulyUnresolved = resolution.unresolvedRefs.filter((u2) => u2.ref.type !== "Unknown");
|
|
210907
211398
|
for (const u2 of trulyUnresolved) {
|
|
210908
|
-
issues.push(`${
|
|
211399
|
+
issues.push(`${path74.relative(repoRoot5, u2.usedAt.filePath)}:${u2.usedAt.lineStart} unresolved ${u2.ref.type}:${u2.ref.identity}`);
|
|
210909
211400
|
}
|
|
210910
211401
|
if (issues.length === 0) {
|
|
210911
211402
|
O2.success(`Validated ${resolution.index.size} artifact${resolution.index.size === 1 ? "" : "s"} \u2014 no issues.`);
|
|
@@ -210919,7 +211410,7 @@ async function runContractsValidate(options = {}) {
|
|
|
210919
211410
|
|
|
210920
211411
|
// tools/cli/src/commands/spec.ts
|
|
210921
211412
|
init_dist4();
|
|
210922
|
-
import
|
|
211413
|
+
import path75 from "node:path";
|
|
210923
211414
|
init_dist5();
|
|
210924
211415
|
init_progress();
|
|
210925
211416
|
init_registry();
|
|
@@ -210970,17 +211461,18 @@ async function runSpecScan(opts = {}) {
|
|
|
210970
211461
|
O2.warn("Manual includes outside spec.include (never discovered \u2014 widen the scope to pick them up):");
|
|
210971
211462
|
for (const inc of s.outOfScopeManualIncludes) O2.message(` \u2022 ${inc}`);
|
|
210972
211463
|
}
|
|
210973
|
-
|
|
211464
|
+
const open = openConflicts(curate2.corpus, curate2.decisions);
|
|
211465
|
+
if (open.length > 0) {
|
|
210974
211466
|
O2.message("");
|
|
210975
|
-
O2.message("Open overlaps (
|
|
210976
|
-
for (const o of
|
|
211467
|
+
O2.message("Open overlaps (two docs may disagree \u2014 pick a side or dismiss with `spec conflicts resolve`):");
|
|
211468
|
+
for (const o of open.slice(0, 10)) {
|
|
210977
211469
|
O2.message(` \u2022 ${o.area}: ${o.a} \u2194 ${o.b}`);
|
|
210978
211470
|
}
|
|
210979
|
-
if (
|
|
210980
|
-
O2.message(` \u2026 (+${
|
|
211471
|
+
if (open.length > 10) {
|
|
211472
|
+
O2.message(` \u2026 (+${open.length - 10} more)`);
|
|
210981
211473
|
}
|
|
210982
211474
|
}
|
|
210983
|
-
const openCount =
|
|
211475
|
+
const openCount = open.length;
|
|
210984
211476
|
gt(
|
|
210985
211477
|
openCount === 0 ? "Corpus written to .truecourse/specs/corpus.json. Run `truecourse guard generate`." : `Corpus written to .truecourse/specs/corpus.json. ${openCount} conflict${openCount === 1 ? "" : "s"} to resolve (\`truecourse spec conflicts list\`), then \`truecourse guard generate\`.`
|
|
210986
211478
|
);
|
|
@@ -211012,6 +211504,14 @@ async function runSpecStatus(opts = {}) {
|
|
|
211012
211504
|
const ov = area.overlaps.length ? ` \xB7 ${area.overlaps.length} overlap${area.overlaps.length === 1 ? "" : "s"}` : "";
|
|
211013
211505
|
O2.message(` ${area.id.padEnd(30)} ${area.docRefs.length} doc${area.docRefs.length === 1 ? "" : "s"}${ov}`);
|
|
211014
211506
|
}
|
|
211507
|
+
const orphaned = orphanedConflictResolutions(corpus, decisions);
|
|
211508
|
+
if (orphaned.length > 0) {
|
|
211509
|
+
O2.message("");
|
|
211510
|
+
O2.warn(
|
|
211511
|
+
`${orphaned.length} orphaned conflict resolution${orphaned.length === 1 ? "" : "s"} (no longer match a flagged dispute \u2014 review with \`spec conflicts list\`):`
|
|
211512
|
+
);
|
|
211513
|
+
for (const o of orphaned.slice(0, 10)) O2.message(` \u2022 ${o.docA} \u2194 ${o.docB} (${o.verdict})`);
|
|
211514
|
+
}
|
|
211015
211515
|
gt(
|
|
211016
211516
|
open === 0 ? "No open overlaps \u2014 run `truecourse guard generate`." : "Open overlaps \u2014 see `truecourse spec conflicts list`."
|
|
211017
211517
|
);
|
|
@@ -211039,7 +211539,7 @@ async function runVerify(opts = {}) {
|
|
|
211039
211539
|
O2.message("");
|
|
211040
211540
|
O2.message("Drifts:");
|
|
211041
211541
|
for (const d3 of verify2.drifts.slice(0, 20)) {
|
|
211042
|
-
const loc = d3.filePath ? ` ${
|
|
211542
|
+
const loc = d3.filePath ? ` ${path75.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
|
|
211043
211543
|
O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
|
|
211044
211544
|
O2.message(` \u2192 ${d3.message}`);
|
|
211045
211545
|
}
|
|
@@ -211073,7 +211573,7 @@ async function runVerifyDiff(opts) {
|
|
|
211073
211573
|
O2.message("");
|
|
211074
211574
|
O2.message(`${label}:`);
|
|
211075
211575
|
for (const d3 of drifts.slice(0, 20)) {
|
|
211076
|
-
const loc = d3.filePath ? ` ${
|
|
211576
|
+
const loc = d3.filePath ? ` ${path75.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
|
|
211077
211577
|
O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
|
|
211078
211578
|
}
|
|
211079
211579
|
if (drifts.length > 20) O2.message(` \u2026 (+${drifts.length - 20} more)`);
|
|
@@ -211128,8 +211628,8 @@ async function runInfer(opts = {}) {
|
|
|
211128
211628
|
|
|
211129
211629
|
// tools/cli/src/commands/spec-conflicts.ts
|
|
211130
211630
|
init_dist4();
|
|
211131
|
-
import
|
|
211132
|
-
import
|
|
211631
|
+
import fs70 from "node:fs";
|
|
211632
|
+
import path76 from "node:path";
|
|
211133
211633
|
init_dist5();
|
|
211134
211634
|
var root = (opts) => opts.cwd ?? process.cwd();
|
|
211135
211635
|
var base = (ref) => ref.split("/").pop() ?? ref;
|
|
@@ -211141,25 +211641,47 @@ function loadCorpusOrExit(repoRoot5) {
|
|
|
211141
211641
|
}
|
|
211142
211642
|
return corpus;
|
|
211143
211643
|
}
|
|
211644
|
+
function resolvedLabel(c2) {
|
|
211645
|
+
if (c2.resolution) {
|
|
211646
|
+
if (c2.resolution.verdict === "dismissed") return "dismissed (not a real conflict)";
|
|
211647
|
+
const winner = c2.resolution.verdict === "a" ? c2.resolution.docA : c2.resolution.docB;
|
|
211648
|
+
return `${base(winner)} is right (loser\u2019s claim suppressed at generate)`;
|
|
211649
|
+
}
|
|
211650
|
+
if (c2.excludedRef) return `${base(c2.excludedRef)} excluded`;
|
|
211651
|
+
return "resolved";
|
|
211652
|
+
}
|
|
211144
211653
|
async function runSpecConflictsList(opts = {}) {
|
|
211145
211654
|
const repoRoot5 = root(opts);
|
|
211146
211655
|
const corpus = loadCorpusOrExit(repoRoot5);
|
|
211147
|
-
const
|
|
211656
|
+
const decisions = readCorpusDecisions(repoRoot5);
|
|
211657
|
+
const conflicts2 = buildCorpusConflicts(corpus, decisions);
|
|
211148
211658
|
const open = conflicts2.filter((c2) => !c2.resolved);
|
|
211149
|
-
const
|
|
211150
|
-
mt("Overlaps (
|
|
211151
|
-
|
|
211152
|
-
|
|
211153
|
-
|
|
211154
|
-
|
|
211659
|
+
const orphaned = orphanedConflictResolutions(corpus, decisions);
|
|
211660
|
+
mt("Overlaps (where two docs\u2019 sections may disagree)");
|
|
211661
|
+
conflicts2.forEach((c2, i) => {
|
|
211662
|
+
const n = i + 1;
|
|
211663
|
+
if (c2.resolved) {
|
|
211664
|
+
O2.step(`${n}. ${c2.area} \xB7 ${base(c2.a)} \u2194 ${base(c2.b)} \u2014 resolved: ${resolvedLabel(c2)}`);
|
|
211665
|
+
} else {
|
|
211666
|
+
O2.warn(`${n}. ${c2.area} \xB7 ${base(c2.a)} \u2194 ${base(c2.b)}${c2.note ? ` \xB7 ${c2.note}` : ""}`);
|
|
211667
|
+
O2.message(` pick a side: truecourse spec conflicts resolve ${n} --right ${c2.a} (or --right ${c2.b}, or --dismiss)`);
|
|
211668
|
+
}
|
|
211669
|
+
});
|
|
211670
|
+
if (conflicts2.length === 0) O2.step("No overlaps flagged.");
|
|
211671
|
+
if (orphaned.length > 0) {
|
|
211672
|
+
O2.warn(
|
|
211673
|
+
`${orphaned.length} orphaned resolution${orphaned.length === 1 ? "" : "s"} \u2014 recorded but no longer match a flagged conflict (the docs changed):`
|
|
211674
|
+
);
|
|
211675
|
+
for (const o of orphaned) O2.message(` ${base(o.docA)} \u2194 ${base(o.docB)} (${o.verdict})`);
|
|
211155
211676
|
}
|
|
211156
|
-
|
|
211157
|
-
|
|
211677
|
+
gt(
|
|
211678
|
+
`${open.length} open \xB7 ${conflicts2.length - open.length} resolved${orphaned.length ? ` \xB7 ${orphaned.length} orphaned` : ""}. Inspect with \`spec conflicts show <area>\`.`
|
|
211679
|
+
);
|
|
211158
211680
|
}
|
|
211159
211681
|
function excerpt(repoRoot5, ref, note, max = 20) {
|
|
211160
211682
|
let text4;
|
|
211161
211683
|
try {
|
|
211162
|
-
text4 =
|
|
211684
|
+
text4 = fs70.readFileSync(path76.join(repoRoot5, ref), "utf-8");
|
|
211163
211685
|
} catch {
|
|
211164
211686
|
return ` (could not read ${ref})`;
|
|
211165
211687
|
}
|
|
@@ -211183,47 +211705,76 @@ async function runSpecConflictsShow(area, opts = {}) {
|
|
|
211183
211705
|
for (const ov of a.overlaps) {
|
|
211184
211706
|
const [da, db] = ov.docs;
|
|
211185
211707
|
const c2 = conflicts2.find(
|
|
211186
|
-
(x) => x.area === area && (x.a === da && x.b === db || x.a === db && x.b === da)
|
|
211708
|
+
(x) => (x.areas.includes(area) || x.area === area) && (x.a === da && x.b === db || x.a === db && x.b === da)
|
|
211187
211709
|
);
|
|
211188
211710
|
O2.warn(`${base(da)} \u2194 ${base(db)}${ov.note ? ` \xB7 ${ov.note}` : ""}`);
|
|
211189
|
-
|
|
211190
|
-
else if (c2?.excludedRef) O2.message(` resolved \u2192 ${c2.excludedRef} excluded`);
|
|
211191
|
-
else O2.message(" open");
|
|
211711
|
+
O2.message(c2 && c2.resolved ? ` resolved \u2192 ${resolvedLabel(c2)}` : " open");
|
|
211192
211712
|
O2.message(` ${da}:`);
|
|
211193
211713
|
O2.message(excerpt(repoRoot5, da, ov.note));
|
|
211194
211714
|
O2.message(` ${db}:`);
|
|
211195
211715
|
O2.message(excerpt(repoRoot5, db, ov.note));
|
|
211196
211716
|
}
|
|
211197
|
-
gt("resolve with `spec conflicts resolve <area> --
|
|
211717
|
+
gt("resolve with `spec conflicts resolve <n|area> --right <docPath>` (pick a side) or `--dismiss`.");
|
|
211718
|
+
}
|
|
211719
|
+
function pickConflict(target, conflicts2, right) {
|
|
211720
|
+
if (/^\d+$/.test(target)) {
|
|
211721
|
+
const idx = Number(target) - 1;
|
|
211722
|
+
if (idx < 0 || idx >= conflicts2.length) {
|
|
211723
|
+
return { error: `No conflict #${target}. Run \`spec conflicts list\` (${conflicts2.length} listed).` };
|
|
211724
|
+
}
|
|
211725
|
+
return conflicts2[idx];
|
|
211726
|
+
}
|
|
211727
|
+
let inArea = conflicts2.filter((c2) => c2.areas.includes(target) || c2.area === target);
|
|
211728
|
+
if (inArea.length === 0) return { error: `No conflicts in area ${target}. List them with \`spec conflicts list\`.` };
|
|
211729
|
+
if (right) inArea = inArea.filter((c2) => c2.a === right || c2.b === right);
|
|
211730
|
+
if (inArea.length === 0) return { error: `No conflict in ${target} involves ${right}.` };
|
|
211731
|
+
if (inArea.length > 1) {
|
|
211732
|
+
return { error: `Area ${target} has ${inArea.length} conflicts \u2014 address one by its number (\`spec conflicts list\`).` };
|
|
211733
|
+
}
|
|
211734
|
+
return inArea[0];
|
|
211735
|
+
}
|
|
211736
|
+
function buildResolution(c2, verdict, note) {
|
|
211737
|
+
const secOf = (doc) => (c2.sections ?? []).find((s) => s.doc === doc);
|
|
211738
|
+
return {
|
|
211739
|
+
docA: c2.a,
|
|
211740
|
+
anchorA: secOf(c2.a)?.heading ?? null,
|
|
211741
|
+
quoteA: secOf(c2.a)?.quote,
|
|
211742
|
+
docB: c2.b,
|
|
211743
|
+
anchorB: secOf(c2.b)?.heading ?? null,
|
|
211744
|
+
quoteB: secOf(c2.b)?.quote,
|
|
211745
|
+
verdict,
|
|
211746
|
+
resolvedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
211747
|
+
note
|
|
211748
|
+
};
|
|
211198
211749
|
}
|
|
211199
|
-
async function runSpecConflictsResolve(
|
|
211750
|
+
async function runSpecConflictsResolve(target, opts) {
|
|
211200
211751
|
const repoRoot5 = root(opts);
|
|
211201
|
-
if (!opts.older || !opts.newer) return fail("resolve needs --older <path> and --newer <path>");
|
|
211202
|
-
if (opts.older === opts.newer) return fail("--older and --newer must be different docs");
|
|
211203
211752
|
const corpus = loadCorpusOrExit(repoRoot5);
|
|
211204
|
-
const
|
|
211205
|
-
if (!
|
|
211206
|
-
|
|
211207
|
-
|
|
211208
|
-
|
|
211753
|
+
const decisions = readCorpusDecisions(repoRoot5);
|
|
211754
|
+
if (!opts.right && !opts.dismiss) {
|
|
211755
|
+
return fail("Pass --right <docPath> (pick a side) or --dismiss. Doc-level relations live in `spec chains add` and never resolve a conflict.");
|
|
211756
|
+
}
|
|
211757
|
+
if (opts.right && opts.dismiss) return fail("Pass either --right <docPath> or --dismiss, not both.");
|
|
211758
|
+
const conflicts2 = buildCorpusConflicts(corpus, decisions);
|
|
211759
|
+
const picked = pickConflict(target, conflicts2, opts.right);
|
|
211760
|
+
if ("error" in picked) return fail(picked.error);
|
|
211761
|
+
let verdict;
|
|
211762
|
+
if (opts.dismiss) {
|
|
211763
|
+
verdict = "dismissed";
|
|
211764
|
+
} else {
|
|
211765
|
+
if (opts.right !== picked.a && opts.right !== picked.b) {
|
|
211766
|
+
return fail(`--right must be one of the disputing docs: ${picked.a} or ${picked.b}.`);
|
|
211767
|
+
}
|
|
211768
|
+
verdict = opts.right === picked.a ? "a" : "b";
|
|
211769
|
+
}
|
|
211770
|
+
await addConflictResolution(repoRoot5, buildResolution(picked, verdict, opts.note));
|
|
211771
|
+
if (verdict === "dismissed") {
|
|
211772
|
+
gt(`Dismissed: ${base(picked.a)} \u2194 ${base(picked.b)} is not a real conflict.`);
|
|
211773
|
+
} else {
|
|
211774
|
+
const winner = verdict === "a" ? picked.a : picked.b;
|
|
211775
|
+
const loser = verdict === "a" ? picked.b : picked.a;
|
|
211776
|
+
gt(`Recorded: ${base(winner)} is right. ${base(loser)}\u2019s disputed claim is suppressed at \`truecourse guard generate\`.`);
|
|
211209
211777
|
}
|
|
211210
|
-
const conflict = buildCorpusConflicts(corpus, readCorpusDecisions(repoRoot5)).find(
|
|
211211
|
-
(c2) => c2.a === opts.older && c2.b === opts.newer || c2.a === opts.newer && c2.b === opts.older
|
|
211212
|
-
);
|
|
211213
|
-
const scope = conflict && conflict.areas.length > 1 ? void 0 : area;
|
|
211214
|
-
await addRelation(repoRoot5, {
|
|
211215
|
-
type: opts.type,
|
|
211216
|
-
older: opts.older,
|
|
211217
|
-
newer: opts.newer,
|
|
211218
|
-
scope,
|
|
211219
|
-
detectedFrom: "manual",
|
|
211220
|
-
note: opts.note
|
|
211221
|
-
});
|
|
211222
|
-
const s = fe();
|
|
211223
|
-
s.start("Re-scanning to apply the relation");
|
|
211224
|
-
await curateInProcess(repoRoot5, {});
|
|
211225
|
-
s.stop("Re-scanned");
|
|
211226
|
-
gt(`Recorded ${opts.type}: ${opts.older} \u21D2 ${opts.newer} (scope ${scope ?? "all areas"}).`);
|
|
211227
211778
|
}
|
|
211228
211779
|
function fail(msg) {
|
|
211229
211780
|
pt(msg);
|
|
@@ -211392,7 +211943,7 @@ function fail3(msg) {
|
|
|
211392
211943
|
|
|
211393
211944
|
// tools/cli/src/commands/drifts.ts
|
|
211394
211945
|
init_dist4();
|
|
211395
|
-
import
|
|
211946
|
+
import path77 from "node:path";
|
|
211396
211947
|
var DRIFT_SEVERITIES = [
|
|
211397
211948
|
"critical",
|
|
211398
211949
|
"high",
|
|
@@ -211429,7 +211980,7 @@ async function runDriftsList(opts = {}) {
|
|
|
211429
211980
|
O2.message("");
|
|
211430
211981
|
O2.message("Drifts:");
|
|
211431
211982
|
for (const d3 of page) {
|
|
211432
|
-
const loc = d3.filePath ? ` ${
|
|
211983
|
+
const loc = d3.filePath ? ` ${path77.relative(root2, d3.filePath)}:${d3.lineStart ?? "?"}` : "";
|
|
211433
211984
|
O2.message(` [${d3.severity}] ${d3.obligationKey}${loc}`);
|
|
211434
211985
|
O2.message(` \u2192 ${d3.message}`);
|
|
211435
211986
|
}
|
|
@@ -211460,7 +212011,7 @@ function parseDriftSeverityFlag(raw) {
|
|
|
211460
212011
|
|
|
211461
212012
|
// tools/cli/src/commands/guard.ts
|
|
211462
212013
|
init_dist4();
|
|
211463
|
-
import
|
|
212014
|
+
import path78 from "node:path";
|
|
211464
212015
|
init_progress();
|
|
211465
212016
|
|
|
211466
212017
|
// packages/core/dist/commands/guard-in-process.js
|
|
@@ -211905,7 +212456,7 @@ async function runGuardGenerate(opts = {}) {
|
|
|
211905
212456
|
return;
|
|
211906
212457
|
}
|
|
211907
212458
|
const report4 = readGuardResult(repoRoot5) ?? { ...guard, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
211908
|
-
printGuardGenerateSummary(report4,
|
|
212459
|
+
printGuardGenerateSummary(report4, path78.relative(repoRoot5, guardResultPath(repoRoot5)));
|
|
211909
212460
|
if (guard.written.length === 0 && guard.birthFindings.length === 0 && guard.errors.length === 0) {
|
|
211910
212461
|
gt("No scenarios written.");
|
|
211911
212462
|
return;
|
|
@@ -212113,7 +212664,7 @@ function printLoadErrors(loadErrors) {
|
|
|
212113
212664
|
|
|
212114
212665
|
// tools/cli/src/commands/config.ts
|
|
212115
212666
|
init_dist4();
|
|
212116
|
-
import
|
|
212667
|
+
import path79 from "node:path";
|
|
212117
212668
|
var STAGE_LABEL = {
|
|
212118
212669
|
"spec.relevance": "Spec \xB7 doc relevance",
|
|
212119
212670
|
"spec.areaTag": "Spec \xB7 area tag",
|
|
@@ -212144,7 +212695,7 @@ async function runConfigLlmShow(options = {}) {
|
|
|
212144
212695
|
const repoRoot5 = options.cwd ?? process.cwd();
|
|
212145
212696
|
const { stages, fallbackModel } = describeStageResolutions(repoRoot5);
|
|
212146
212697
|
mt("LLM model resolution");
|
|
212147
|
-
O2.info(`repoRoot ${
|
|
212698
|
+
O2.info(`repoRoot ${path79.relative(process.cwd(), repoRoot5) || "."}`);
|
|
212148
212699
|
O2.info(`fallback ${fallbackModel ?? "(not configured)"}`);
|
|
212149
212700
|
for (const stage of stages) {
|
|
212150
212701
|
const label = STAGE_LABEL[stage.stageId];
|
|
@@ -212160,8 +212711,8 @@ async function runConfigLlmShow(options = {}) {
|
|
|
212160
212711
|
|
|
212161
212712
|
// tools/cli/src/commands/hooks.ts
|
|
212162
212713
|
import { execSync as execSync4 } from "node:child_process";
|
|
212163
|
-
import
|
|
212164
|
-
import
|
|
212714
|
+
import fs71 from "node:fs";
|
|
212715
|
+
import path80 from "node:path";
|
|
212165
212716
|
init_dist4();
|
|
212166
212717
|
init_paths();
|
|
212167
212718
|
init_registry();
|
|
@@ -212195,17 +212746,17 @@ pre-commit:
|
|
|
212195
212746
|
function findGitDir(from) {
|
|
212196
212747
|
let dir = from;
|
|
212197
212748
|
while (true) {
|
|
212198
|
-
const gitPath =
|
|
212199
|
-
if (
|
|
212200
|
-
const stat =
|
|
212749
|
+
const gitPath = path80.join(dir, ".git");
|
|
212750
|
+
if (fs71.existsSync(gitPath)) {
|
|
212751
|
+
const stat = fs71.statSync(gitPath);
|
|
212201
212752
|
if (stat.isDirectory()) return gitPath;
|
|
212202
212753
|
if (stat.isFile()) {
|
|
212203
|
-
const content =
|
|
212754
|
+
const content = fs71.readFileSync(gitPath, "utf-8").trim();
|
|
212204
212755
|
const match4 = content.match(/^gitdir:\s*(.+)$/);
|
|
212205
|
-
if (match4) return
|
|
212756
|
+
if (match4) return path80.resolve(dir, match4[1]);
|
|
212206
212757
|
}
|
|
212207
212758
|
}
|
|
212208
|
-
const parent =
|
|
212759
|
+
const parent = path80.dirname(dir);
|
|
212209
212760
|
if (parent === dir) return null;
|
|
212210
212761
|
dir = parent;
|
|
212211
212762
|
}
|
|
@@ -212213,18 +212764,18 @@ function findGitDir(from) {
|
|
|
212213
212764
|
function findProjectRoot(from) {
|
|
212214
212765
|
let dir = from;
|
|
212215
212766
|
while (true) {
|
|
212216
|
-
if (
|
|
212217
|
-
const parent =
|
|
212767
|
+
if (fs71.existsSync(path80.join(dir, ".git"))) return dir;
|
|
212768
|
+
const parent = path80.dirname(dir);
|
|
212218
212769
|
if (parent === dir) return null;
|
|
212219
212770
|
dir = parent;
|
|
212220
212771
|
}
|
|
212221
212772
|
}
|
|
212222
212773
|
function loadConfig(projectRoot) {
|
|
212223
|
-
const configPath =
|
|
212224
|
-
if (!
|
|
212774
|
+
const configPath = path80.join(projectRoot, ".truecourse", "hooks.yaml");
|
|
212775
|
+
if (!fs71.existsSync(configPath)) return null;
|
|
212225
212776
|
let parsed;
|
|
212226
212777
|
try {
|
|
212227
|
-
const raw =
|
|
212778
|
+
const raw = fs71.readFileSync(configPath, "utf-8");
|
|
212228
212779
|
parsed = jsYaml.load(raw) || {};
|
|
212229
212780
|
} catch (err) {
|
|
212230
212781
|
console.error(`Error parsing ${configPath}: ${err.message}`);
|
|
@@ -212275,11 +212826,11 @@ async function runHooksInstall() {
|
|
|
212275
212826
|
} else {
|
|
212276
212827
|
console.log(INSTALL_WARNING);
|
|
212277
212828
|
}
|
|
212278
|
-
const hooksDir =
|
|
212279
|
-
|
|
212280
|
-
const hookPath =
|
|
212281
|
-
if (
|
|
212282
|
-
const existing =
|
|
212829
|
+
const hooksDir = path80.join(gitDir, "hooks");
|
|
212830
|
+
fs71.mkdirSync(hooksDir, { recursive: true });
|
|
212831
|
+
const hookPath = path80.join(hooksDir, "pre-commit");
|
|
212832
|
+
if (fs71.existsSync(hookPath)) {
|
|
212833
|
+
const existing = fs71.readFileSync(hookPath, "utf-8");
|
|
212283
212834
|
if (!existing.includes(HOOK_IDENTIFIER)) {
|
|
212284
212835
|
console.error(
|
|
212285
212836
|
"Error: A pre-commit hook already exists and was not installed by TrueCourse."
|
|
@@ -212289,16 +212840,16 @@ async function runHooksInstall() {
|
|
|
212289
212840
|
process.exit(1);
|
|
212290
212841
|
}
|
|
212291
212842
|
}
|
|
212292
|
-
|
|
212843
|
+
fs71.writeFileSync(hookPath, HOOK_SCRIPT, { mode: 493 });
|
|
212293
212844
|
console.log("TrueCourse pre-commit hook installed.");
|
|
212294
212845
|
console.log(` ${hookPath}`);
|
|
212295
212846
|
const projectRoot = findProjectRoot(process.cwd());
|
|
212296
212847
|
if (projectRoot) {
|
|
212297
|
-
const cfgDir =
|
|
212298
|
-
const cfgPath =
|
|
212299
|
-
if (!
|
|
212300
|
-
|
|
212301
|
-
|
|
212848
|
+
const cfgDir = path80.join(projectRoot, ".truecourse");
|
|
212849
|
+
const cfgPath = path80.join(cfgDir, "hooks.yaml");
|
|
212850
|
+
if (!fs71.existsSync(cfgPath)) {
|
|
212851
|
+
fs71.mkdirSync(cfgDir, { recursive: true });
|
|
212852
|
+
fs71.writeFileSync(cfgPath, HOOKS_YAML_TEMPLATE);
|
|
212302
212853
|
console.log(` ${cfgPath} (starter config \u2014 edit to customize, commit to share with the team)`);
|
|
212303
212854
|
}
|
|
212304
212855
|
}
|
|
@@ -212309,17 +212860,17 @@ function runHooksUninstall() {
|
|
|
212309
212860
|
console.error("Error: Not a git repository.");
|
|
212310
212861
|
process.exit(1);
|
|
212311
212862
|
}
|
|
212312
|
-
const hookPath =
|
|
212313
|
-
if (!
|
|
212863
|
+
const hookPath = path80.join(gitDir, "hooks", "pre-commit");
|
|
212864
|
+
if (!fs71.existsSync(hookPath)) {
|
|
212314
212865
|
console.log("No pre-commit hook installed.");
|
|
212315
212866
|
return;
|
|
212316
212867
|
}
|
|
212317
|
-
const content =
|
|
212868
|
+
const content = fs71.readFileSync(hookPath, "utf-8");
|
|
212318
212869
|
if (!content.includes(HOOK_IDENTIFIER)) {
|
|
212319
212870
|
console.error("Error: The pre-commit hook was not installed by TrueCourse. Leaving it in place.");
|
|
212320
212871
|
process.exit(1);
|
|
212321
212872
|
}
|
|
212322
|
-
|
|
212873
|
+
fs71.unlinkSync(hookPath);
|
|
212323
212874
|
console.log("TrueCourse pre-commit hook removed.");
|
|
212324
212875
|
}
|
|
212325
212876
|
function runHooksStatus() {
|
|
@@ -212328,8 +212879,8 @@ function runHooksStatus() {
|
|
|
212328
212879
|
console.error("Error: Not a git repository.");
|
|
212329
212880
|
process.exit(1);
|
|
212330
212881
|
}
|
|
212331
|
-
const hookPath =
|
|
212332
|
-
const installed =
|
|
212882
|
+
const hookPath = path80.join(gitDir, "hooks", "pre-commit");
|
|
212883
|
+
const installed = fs71.existsSync(hookPath) && fs71.readFileSync(hookPath, "utf-8").includes(HOOK_IDENTIFIER);
|
|
212333
212884
|
if (installed) {
|
|
212334
212885
|
console.log("TrueCourse pre-commit hook: installed");
|
|
212335
212886
|
console.log(` ${hookPath}`);
|
|
@@ -212438,7 +212989,7 @@ async function runHooksRun() {
|
|
|
212438
212989
|
|
|
212439
212990
|
// tools/cli/src/index.ts
|
|
212440
212991
|
var program2 = new Command();
|
|
212441
|
-
program2.name("truecourse").version("0.7.0-next.
|
|
212992
|
+
program2.name("truecourse").version("0.7.0-next.9").description("TrueCourse CLI \u2014 analyze your repository and open the dashboard");
|
|
212442
212993
|
function warnDiscontinued(command) {
|
|
212443
212994
|
process.stderr.write(
|
|
212444
212995
|
`\u26A0 \`${command}\` is discontinued in favor of \`truecourse guard\` \u2014 see the README. Planned removal: 0.8.
|
|
@@ -212519,19 +213070,18 @@ specCmd.command("status").description("Summary of docs, areas, relations, and op
|
|
|
212519
213070
|
await runSpecStatus();
|
|
212520
213071
|
});
|
|
212521
213072
|
var conflictsCmd = specCmd.command("conflicts").description("Inspect and resolve flagged within-area doc overlaps (agent-friendly)");
|
|
212522
|
-
conflictsCmd.command("list").description("List flagged overlaps still awaiting a
|
|
213073
|
+
conflictsCmd.command("list").description("List flagged overlaps still awaiting a verdict").action(async () => {
|
|
212523
213074
|
await runSpecConflictsList();
|
|
212524
213075
|
});
|
|
212525
213076
|
conflictsCmd.command("show <area>").description("Show an area's overlapping docs with prose excerpts").action(async (area) => {
|
|
212526
213077
|
await runSpecConflictsShow(area);
|
|
212527
213078
|
});
|
|
212528
|
-
conflictsCmd.command("resolve <area>").description("Resolve
|
|
212529
|
-
|
|
212530
|
-
|
|
212531
|
-
|
|
212532
|
-
|
|
212533
|
-
}
|
|
212534
|
-
await runSpecConflictsResolve(area, { older: opts.older, newer: opts.newer, type: type2, note: opts.note });
|
|
213079
|
+
conflictsCmd.command("resolve <n|area>").description("Resolve a flagged overlap: pick a side (--right) or dismiss it (--dismiss)").option("--right <path>", "Pick a side: this doc is right; the other side's disputed claim is suppressed at generate").option("--dismiss", "Not a real conflict \u2014 dismiss the detector false-positive").option("--note <text>", "Optional rationale").action(async (target, opts) => {
|
|
213080
|
+
await runSpecConflictsResolve(target, {
|
|
213081
|
+
right: opts.right,
|
|
213082
|
+
dismiss: opts.dismiss,
|
|
213083
|
+
note: opts.note
|
|
213084
|
+
});
|
|
212535
213085
|
});
|
|
212536
213086
|
var chainsCmd = specCmd.command("chains").description("Manage doc\u2192doc relations (supersession / precedence overrides)");
|
|
212537
213087
|
chainsCmd.command("list").description("List effective relations (auto-detected + user-authored)").action(async () => {
|