agentsmesh 0.35.0 → 0.37.0
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/CHANGELOG.md +44 -0
- package/README.md +2 -0
- package/dist/canonical.js +242 -123
- package/dist/canonical.js.map +1 -1
- package/dist/cli.js +257 -250
- package/dist/engine.js +398 -157
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +419 -166
- package/dist/index.js.map +1 -1
- package/dist/{init-C3pMnqoU.d.ts → init-BtgoRmIs.d.ts} +5 -6
- package/dist/lessons.d.ts +2 -2
- package/dist/lessons.js +198 -61
- package/dist/lessons.js.map +1 -1
- package/dist/targets.js +231 -103
- package/dist/targets.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { stringify, parse, parseDocument, YAMLSeq, YAMLMap, isMap, Document, isSeq, isScalar, Scalar, Pair } from 'yaml';
|
|
3
3
|
import { readFileSync, existsSync, mkdirSync, writeFileSync, constants, rmSync, renameSync, readdirSync, realpathSync, statSync } from 'fs';
|
|
4
|
-
import { join, resolve, relative, sep, dirname, basename, win32, posix
|
|
5
|
-
import { mkdir, access, readdir, rm, readFile, writeFile, stat, lstat,
|
|
4
|
+
import { join, resolve, relative, sep, dirname, basename, extname, win32, posix } from 'path';
|
|
5
|
+
import { mkdir, access, readdir, rm, readFile, writeFile, stat, lstat, open, realpath, rename, mkdtemp, cp } from 'fs/promises';
|
|
6
6
|
import { setTimeout as setTimeout$1 } from 'timers/promises';
|
|
7
|
+
import { createHash, randomUUID } from 'crypto';
|
|
7
8
|
import { parse as parse$1, stringify as stringify$1 } from 'smol-toml';
|
|
8
9
|
import { Buffer } from 'buffer';
|
|
9
10
|
import { homedir, hostname, tmpdir } from 'os';
|
|
10
|
-
import { createHash } from 'crypto';
|
|
11
11
|
import { execFile } from 'child_process';
|
|
12
12
|
import { fileURLToPath, pathToFileURL, URL as URL$1 } from 'url';
|
|
13
13
|
import { promisify } from 'util';
|
|
@@ -894,6 +894,12 @@ function shouldNormalizeLineEndings(path) {
|
|
|
894
894
|
const base = basename(path).toLowerCase();
|
|
895
895
|
return TEXT_DOTFILES.has(base);
|
|
896
896
|
}
|
|
897
|
+
function isBinaryPayloadPath(path) {
|
|
898
|
+
return BINARY_EXTENSIONS.has(extname(path).toLowerCase());
|
|
899
|
+
}
|
|
900
|
+
function payloadEncodingFor(path) {
|
|
901
|
+
return isBinaryPayloadPath(path) ? "latin1" : "utf-8";
|
|
902
|
+
}
|
|
897
903
|
function normalizeLineEndings(content) {
|
|
898
904
|
return content.replace(/\r\n?/g, "\n");
|
|
899
905
|
}
|
|
@@ -905,7 +911,7 @@ function normalizeTextPayload(path, content) {
|
|
|
905
911
|
const withoutBom = content.startsWith(UTF8_BOM) ? content.slice(UTF8_BOM.length) : content;
|
|
906
912
|
return normalizeLineEndings(withoutBom);
|
|
907
913
|
}
|
|
908
|
-
var UTF8_BOM, TEXT_EXTENSIONS, TEXT_DOTFILES, EXECUTABLE_SCRIPT_EXTENSIONS;
|
|
914
|
+
var UTF8_BOM, TEXT_EXTENSIONS, TEXT_DOTFILES, BINARY_EXTENSIONS, EXECUTABLE_SCRIPT_EXTENSIONS;
|
|
909
915
|
var init_fs_text_encoding = __esm({
|
|
910
916
|
"src/utils/filesystem/fs-text-encoding.ts"() {
|
|
911
917
|
UTF8_BOM = "\uFEFF";
|
|
@@ -950,9 +956,109 @@ var init_fs_text_encoding = __esm({
|
|
|
950
956
|
".rooignore",
|
|
951
957
|
".antigravityignore"
|
|
952
958
|
]);
|
|
959
|
+
BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
960
|
+
".png",
|
|
961
|
+
".jpg",
|
|
962
|
+
".jpeg",
|
|
963
|
+
".gif",
|
|
964
|
+
".bmp",
|
|
965
|
+
".ico",
|
|
966
|
+
".webp",
|
|
967
|
+
".avif",
|
|
968
|
+
".tiff",
|
|
969
|
+
".pdf",
|
|
970
|
+
".zip",
|
|
971
|
+
".gz",
|
|
972
|
+
".tgz",
|
|
973
|
+
".bz2",
|
|
974
|
+
".xz",
|
|
975
|
+
".7z",
|
|
976
|
+
".rar",
|
|
977
|
+
".jar",
|
|
978
|
+
".woff",
|
|
979
|
+
".woff2",
|
|
980
|
+
".ttf",
|
|
981
|
+
".otf",
|
|
982
|
+
".eot",
|
|
983
|
+
".mp3",
|
|
984
|
+
".mp4",
|
|
985
|
+
".wav",
|
|
986
|
+
".ogg",
|
|
987
|
+
".webm",
|
|
988
|
+
".mov",
|
|
989
|
+
".wasm",
|
|
990
|
+
".bin",
|
|
991
|
+
".dat",
|
|
992
|
+
".db",
|
|
993
|
+
".sqlite",
|
|
994
|
+
".so",
|
|
995
|
+
".dylib",
|
|
996
|
+
".dll",
|
|
997
|
+
".exe",
|
|
998
|
+
".class",
|
|
999
|
+
".pyc",
|
|
1000
|
+
// Office and design documents are zip or proprietary containers.
|
|
1001
|
+
".xlsx",
|
|
1002
|
+
".xls",
|
|
1003
|
+
".docx",
|
|
1004
|
+
".doc",
|
|
1005
|
+
".pptx",
|
|
1006
|
+
".ppt",
|
|
1007
|
+
".odt",
|
|
1008
|
+
".ods",
|
|
1009
|
+
".psd",
|
|
1010
|
+
".ai",
|
|
1011
|
+
".sketch",
|
|
1012
|
+
".fig",
|
|
1013
|
+
".heic",
|
|
1014
|
+
".heif",
|
|
1015
|
+
// Archives, columnar data, models and compressed payloads.
|
|
1016
|
+
".tar",
|
|
1017
|
+
".zst",
|
|
1018
|
+
".br",
|
|
1019
|
+
".lz4",
|
|
1020
|
+
".parquet",
|
|
1021
|
+
".avro",
|
|
1022
|
+
".orc",
|
|
1023
|
+
".pkl",
|
|
1024
|
+
".npy",
|
|
1025
|
+
".npz",
|
|
1026
|
+
".onnx",
|
|
1027
|
+
".pt",
|
|
1028
|
+
".safetensors",
|
|
1029
|
+
".gguf",
|
|
1030
|
+
".sqlite3",
|
|
1031
|
+
".avi",
|
|
1032
|
+
".mkv",
|
|
1033
|
+
".flac",
|
|
1034
|
+
".aac",
|
|
1035
|
+
".m4a",
|
|
1036
|
+
".ttc"
|
|
1037
|
+
]);
|
|
953
1038
|
EXECUTABLE_SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".sh", ".bash", ".zsh"]);
|
|
954
1039
|
}
|
|
955
1040
|
});
|
|
1041
|
+
async function renameWithRetry(from, to, options = {}) {
|
|
1042
|
+
const attempts = options.attempts ?? 5;
|
|
1043
|
+
const delayMs = options.delayMs ?? 50;
|
|
1044
|
+
for (let attempt = 0; ; attempt++) {
|
|
1045
|
+
try {
|
|
1046
|
+
await rename(from, to);
|
|
1047
|
+
return;
|
|
1048
|
+
} catch (err) {
|
|
1049
|
+
const code = err.code;
|
|
1050
|
+
const transient = code !== void 0 && TRANSIENT_RENAME_CODES.has(code);
|
|
1051
|
+
if (!transient || attempt >= attempts - 1) throw err;
|
|
1052
|
+
await setTimeout$1(delayMs * 2 ** attempt);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
var TRANSIENT_RENAME_CODES;
|
|
1057
|
+
var init_rename_retry = __esm({
|
|
1058
|
+
"src/utils/filesystem/rename-retry.ts"() {
|
|
1059
|
+
TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "ENOTEMPTY", "EEXIST"]);
|
|
1060
|
+
}
|
|
1061
|
+
});
|
|
956
1062
|
function shouldSkipRecursiveBranch(segments) {
|
|
957
1063
|
if (segments.length > MAX_RECURSIVE_DEPTH) return true;
|
|
958
1064
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -1043,30 +1149,10 @@ var init_fs_traverse = __esm({
|
|
|
1043
1149
|
MAX_SEGMENT_REPETITIONS = 3;
|
|
1044
1150
|
}
|
|
1045
1151
|
});
|
|
1046
|
-
async function renameWithRetry(from, to, options = {}) {
|
|
1047
|
-
const attempts = options.attempts ?? 5;
|
|
1048
|
-
const delayMs = options.delayMs ?? 50;
|
|
1049
|
-
for (let attempt = 0; ; attempt++) {
|
|
1050
|
-
try {
|
|
1051
|
-
await rename(from, to);
|
|
1052
|
-
return;
|
|
1053
|
-
} catch (err) {
|
|
1054
|
-
const code = err.code;
|
|
1055
|
-
const transient = code !== void 0 && TRANSIENT_RENAME_CODES.has(code);
|
|
1056
|
-
if (!transient || attempt >= attempts - 1) throw err;
|
|
1057
|
-
await setTimeout$1(delayMs * 2 ** attempt);
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
var TRANSIENT_RENAME_CODES;
|
|
1062
|
-
var init_rename_retry = __esm({
|
|
1063
|
-
"src/utils/filesystem/rename-retry.ts"() {
|
|
1064
|
-
TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "ENOTEMPTY", "EEXIST"]);
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
1152
|
async function readFileSafe(path) {
|
|
1068
1153
|
try {
|
|
1069
|
-
const data = await readFile(path,
|
|
1154
|
+
const data = await readFile(path, payloadEncodingFor(path));
|
|
1155
|
+
if (isBinaryPayloadPath(path)) return data;
|
|
1070
1156
|
return data.startsWith(UTF8_BOM) ? data.slice(UTF8_BOM.length) : data;
|
|
1071
1157
|
} catch (err) {
|
|
1072
1158
|
const e = err;
|
|
@@ -1090,40 +1176,28 @@ async function writeFileAtomic(path, content, options) {
|
|
|
1090
1176
|
{ errnoCode: "EISDIR" }
|
|
1091
1177
|
);
|
|
1092
1178
|
}
|
|
1093
|
-
if (info.isSymbolicLink()) {
|
|
1094
|
-
await unlink(path).catch((e) => {
|
|
1095
|
-
if (e.code !== "ENOENT") throw e;
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
1179
|
} catch (err) {
|
|
1099
1180
|
if (err instanceof FileSystemError) throw err;
|
|
1100
1181
|
const e = err;
|
|
1101
1182
|
if (e.code !== "ENOENT") throw err;
|
|
1102
1183
|
}
|
|
1103
|
-
const tmpPath = `${path}.tmp`;
|
|
1184
|
+
const tmpPath = `${path}.tmp-${randomUUID()}`;
|
|
1104
1185
|
const payload = shouldNormalizeLineEndings(path) ? normalizeLineEndings(content) : content;
|
|
1105
1186
|
const mode = executableModeFor(path);
|
|
1187
|
+
let handle;
|
|
1188
|
+
let ownsTemporaryFile = false;
|
|
1106
1189
|
try {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
}
|
|
1115
|
-
const writeOpts = {
|
|
1116
|
-
encoding: "utf-8",
|
|
1117
|
-
flag: "w"
|
|
1118
|
-
};
|
|
1119
|
-
if (mode !== void 0) writeOpts.mode = mode;
|
|
1120
|
-
await writeFile(tmpPath, payload, writeOpts);
|
|
1121
|
-
await rename(tmpPath, path);
|
|
1122
|
-
if (mode !== void 0) {
|
|
1123
|
-
await chmod(path, mode);
|
|
1124
|
-
}
|
|
1190
|
+
handle = await open(tmpPath, "wx", mode);
|
|
1191
|
+
ownsTemporaryFile = true;
|
|
1192
|
+
await handle.writeFile(payload, payloadEncodingFor(path));
|
|
1193
|
+
if (mode !== void 0) await handle.chmod(mode);
|
|
1194
|
+
await handle.close();
|
|
1195
|
+
handle = void 0;
|
|
1196
|
+
await renameWithRetry(tmpPath, path);
|
|
1125
1197
|
} catch (err) {
|
|
1126
|
-
await
|
|
1198
|
+
await handle?.close().catch(() => {
|
|
1199
|
+
});
|
|
1200
|
+
if (ownsTemporaryFile) await rm(tmpPath, { force: true }).catch(() => {
|
|
1127
1201
|
});
|
|
1128
1202
|
const e = err;
|
|
1129
1203
|
throw new FileSystemError(
|
|
@@ -1148,6 +1222,7 @@ var init_fs = __esm({
|
|
|
1148
1222
|
"src/utils/filesystem/fs.ts"() {
|
|
1149
1223
|
init_errors();
|
|
1150
1224
|
init_fs_text_encoding();
|
|
1225
|
+
init_rename_retry();
|
|
1151
1226
|
init_fs_traverse();
|
|
1152
1227
|
init_fs_text_encoding();
|
|
1153
1228
|
init_rename_retry();
|
|
@@ -2302,43 +2377,92 @@ function isGlobAdjacent(content, start, end) {
|
|
|
2302
2377
|
const next = end < content.length ? content.at(end) : "";
|
|
2303
2378
|
return prev === "*" || next === "*";
|
|
2304
2379
|
}
|
|
2380
|
+
var NON_REWRITABLE_BARE_FILES, PATH_TOKEN, LINE_NUMBER_SUFFIX;
|
|
2381
|
+
var init_link_rebaser_helpers = __esm({
|
|
2382
|
+
"src/core/reference/link-rebaser-helpers.ts"() {
|
|
2383
|
+
init_path_helpers();
|
|
2384
|
+
init_link_format_registry();
|
|
2385
|
+
NON_REWRITABLE_BARE_FILES = /* @__PURE__ */ new Set([
|
|
2386
|
+
"AGENTS.md",
|
|
2387
|
+
"CLAUDE.md",
|
|
2388
|
+
"GEMINI.md",
|
|
2389
|
+
"codex.md",
|
|
2390
|
+
".windsurfrules",
|
|
2391
|
+
".cursorrules"
|
|
2392
|
+
]);
|
|
2393
|
+
PATH_TOKEN = /(?:\.\.[\\/]|\.\/|\.\\|\/[A-Za-z0-9._-]|[A-Za-z]:[\\/][A-Za-z0-9._-]|\.agentsmesh[\\/]|\.claude[\\/]|\.cursor[\\/]|\.github[\\/]|\.continue[\\/]|\.junie[\\/]|\.kiro[\\/]|\.gemini[\\/]|\.clinerules[\\/]|\.cline[\\/]|\.codex[\\/]|\.agents[\\/]|\.windsurf[\\/]|\.roo[\\/]|(?:[A-Za-z0-9._-]+[\\/])+|[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+)[A-Za-z0-9._@%+~:\\/-]*/g;
|
|
2394
|
+
LINE_NUMBER_SUFFIX = /(?::(\d+)){1,2}$/;
|
|
2395
|
+
}
|
|
2396
|
+
});
|
|
2397
|
+
|
|
2398
|
+
// src/core/reference/protected-ranges.ts
|
|
2399
|
+
function inlineCodeRanges(content) {
|
|
2400
|
+
const ranges = [];
|
|
2401
|
+
let openStart = -1;
|
|
2402
|
+
let openLength = 0;
|
|
2403
|
+
for (const match of content.matchAll(/`+/g)) {
|
|
2404
|
+
const start = match.index;
|
|
2405
|
+
const length = match[0].length;
|
|
2406
|
+
if (openStart === -1) {
|
|
2407
|
+
openStart = start;
|
|
2408
|
+
openLength = length;
|
|
2409
|
+
continue;
|
|
2410
|
+
}
|
|
2411
|
+
if (length === openLength) {
|
|
2412
|
+
ranges.push([openStart, start + length]);
|
|
2413
|
+
openStart = -1;
|
|
2414
|
+
openLength = 0;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
return ranges;
|
|
2418
|
+
}
|
|
2419
|
+
function extendAcrossBalancedParens(content, end) {
|
|
2420
|
+
let cursor = end;
|
|
2421
|
+
while (content[cursor] === "(") {
|
|
2422
|
+
let depth = 0;
|
|
2423
|
+
let scan = cursor;
|
|
2424
|
+
while (scan < content.length) {
|
|
2425
|
+
const ch = content[scan];
|
|
2426
|
+
if (ch === "(") depth += 1;
|
|
2427
|
+
else if (ch === ")") {
|
|
2428
|
+
depth -= 1;
|
|
2429
|
+
if (depth === 0) break;
|
|
2430
|
+
} else if (ch === void 0 || /\s/.test(ch)) return cursor;
|
|
2431
|
+
scan += 1;
|
|
2432
|
+
}
|
|
2433
|
+
if (depth !== 0) return cursor;
|
|
2434
|
+
cursor = scan + 1;
|
|
2435
|
+
while (cursor < content.length && !/[\s<>()\]]/.test(content.charAt(cursor))) cursor += 1;
|
|
2436
|
+
}
|
|
2437
|
+
return cursor;
|
|
2438
|
+
}
|
|
2305
2439
|
function protectedRanges(content) {
|
|
2306
2440
|
const ranges = [];
|
|
2307
2441
|
for (const pattern of getLinkFormatRegistry().protectedSchemes) {
|
|
2308
2442
|
const globalPattern = pattern.flags.includes("g") ? pattern : new RegExp(pattern.source, `${pattern.flags}g`);
|
|
2309
2443
|
for (const match of content.matchAll(globalPattern)) {
|
|
2310
|
-
|
|
2444
|
+
const start = match.index;
|
|
2445
|
+
ranges.push([start, extendAcrossBalancedParens(content, start + match[0].length)]);
|
|
2311
2446
|
}
|
|
2312
2447
|
}
|
|
2313
2448
|
for (const match of content.matchAll(FENCED_CODE_BLOCK)) {
|
|
2314
|
-
ranges.push([match.index
|
|
2449
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2315
2450
|
}
|
|
2316
2451
|
for (const match of content.matchAll(ROOT_GENERATION_CONTRACT_BLOCK)) {
|
|
2317
|
-
ranges.push([match.index
|
|
2452
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2318
2453
|
}
|
|
2319
2454
|
for (const match of content.matchAll(EMBEDDED_RULES_BLOCK)) {
|
|
2320
|
-
ranges.push([match.index
|
|
2455
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2321
2456
|
}
|
|
2322
2457
|
return ranges;
|
|
2323
2458
|
}
|
|
2324
|
-
var
|
|
2325
|
-
var
|
|
2326
|
-
"src/core/reference/
|
|
2327
|
-
init_path_helpers();
|
|
2459
|
+
var FENCED_CODE_BLOCK, ROOT_GENERATION_CONTRACT_BLOCK, EMBEDDED_RULES_BLOCK;
|
|
2460
|
+
var init_protected_ranges = __esm({
|
|
2461
|
+
"src/core/reference/protected-ranges.ts"() {
|
|
2328
2462
|
init_link_format_registry();
|
|
2329
|
-
NON_REWRITABLE_BARE_FILES = /* @__PURE__ */ new Set([
|
|
2330
|
-
"AGENTS.md",
|
|
2331
|
-
"CLAUDE.md",
|
|
2332
|
-
"GEMINI.md",
|
|
2333
|
-
"codex.md",
|
|
2334
|
-
".windsurfrules",
|
|
2335
|
-
".cursorrules"
|
|
2336
|
-
]);
|
|
2337
2463
|
FENCED_CODE_BLOCK = /^(?:```|~~~)[^\n]*\n[\s\S]*?^(?:```|~~~)/gm;
|
|
2338
2464
|
ROOT_GENERATION_CONTRACT_BLOCK = /<!-- agentsmesh:root-generation-contract:start -->[\s\S]*?<!-- agentsmesh:root-generation-contract:end -->/g;
|
|
2339
2465
|
EMBEDDED_RULES_BLOCK = /<!-- agentsmesh:embedded-rules:start -->[\s\S]*?<!-- agentsmesh:embedded-rules:end -->/g;
|
|
2340
|
-
PATH_TOKEN = /(?:\.\.[\\/]|\.\/|\.\\|\/[A-Za-z0-9._-]|[A-Za-z]:[\\/][A-Za-z0-9._-]|\.agentsmesh[\\/]|\.claude[\\/]|\.cursor[\\/]|\.github[\\/]|\.continue[\\/]|\.junie[\\/]|\.kiro[\\/]|\.gemini[\\/]|\.clinerules[\\/]|\.cline[\\/]|\.codex[\\/]|\.agents[\\/]|\.windsurf[\\/]|\.roo[\\/]|(?:[A-Za-z0-9._-]+[\\/])+|[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+)[A-Za-z0-9._@%+~:\\/-]*/g;
|
|
2341
|
-
LINE_NUMBER_SUFFIX = /(?::(\d+)){1,2}$/;
|
|
2342
2466
|
}
|
|
2343
2467
|
});
|
|
2344
2468
|
|
|
@@ -2831,6 +2955,7 @@ var init_link_rebaser = __esm({
|
|
|
2831
2955
|
"src/core/reference/link-rebaser.ts"() {
|
|
2832
2956
|
init_path_helpers();
|
|
2833
2957
|
init_link_rebaser_helpers();
|
|
2958
|
+
init_protected_ranges();
|
|
2834
2959
|
init_link_rebaser_output();
|
|
2835
2960
|
init_link_rebaser_resolution();
|
|
2836
2961
|
init_link_uri_encoding();
|
|
@@ -7254,6 +7379,60 @@ var init_embedded_rules = __esm({
|
|
|
7254
7379
|
}
|
|
7255
7380
|
});
|
|
7256
7381
|
|
|
7382
|
+
// src/utils/text/json-comments.ts
|
|
7383
|
+
function stripJsonComments(text) {
|
|
7384
|
+
let result2 = "";
|
|
7385
|
+
let i = 0;
|
|
7386
|
+
const len = text.length;
|
|
7387
|
+
while (i < len) {
|
|
7388
|
+
const ch = text[i];
|
|
7389
|
+
if (ch === '"') {
|
|
7390
|
+
result2 += ch;
|
|
7391
|
+
i++;
|
|
7392
|
+
while (i < len) {
|
|
7393
|
+
const sc = text[i];
|
|
7394
|
+
result2 += sc;
|
|
7395
|
+
if (sc === "\\") {
|
|
7396
|
+
i++;
|
|
7397
|
+
if (i < len) {
|
|
7398
|
+
result2 += text[i];
|
|
7399
|
+
}
|
|
7400
|
+
} else if (sc === '"') {
|
|
7401
|
+
break;
|
|
7402
|
+
}
|
|
7403
|
+
i++;
|
|
7404
|
+
}
|
|
7405
|
+
i++;
|
|
7406
|
+
continue;
|
|
7407
|
+
}
|
|
7408
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
7409
|
+
i += 2;
|
|
7410
|
+
while (i < len) {
|
|
7411
|
+
if (text[i] === "*" && text[i + 1] === "/") {
|
|
7412
|
+
i += 2;
|
|
7413
|
+
break;
|
|
7414
|
+
}
|
|
7415
|
+
i++;
|
|
7416
|
+
}
|
|
7417
|
+
continue;
|
|
7418
|
+
}
|
|
7419
|
+
if (ch === "/" && text[i + 1] === "/") {
|
|
7420
|
+
i += 2;
|
|
7421
|
+
while (i < len && text[i] !== "\n") {
|
|
7422
|
+
i++;
|
|
7423
|
+
}
|
|
7424
|
+
continue;
|
|
7425
|
+
}
|
|
7426
|
+
result2 += ch;
|
|
7427
|
+
i++;
|
|
7428
|
+
}
|
|
7429
|
+
return result2;
|
|
7430
|
+
}
|
|
7431
|
+
var init_json_comments = __esm({
|
|
7432
|
+
"src/utils/text/json-comments.ts"() {
|
|
7433
|
+
}
|
|
7434
|
+
});
|
|
7435
|
+
|
|
7257
7436
|
// src/canonical/features/syntax-error.ts
|
|
7258
7437
|
function failSyntax(filePath2, cause, onParseError) {
|
|
7259
7438
|
const error = new CanonicalParseError(filePath2, cause);
|
|
@@ -7303,54 +7482,6 @@ function parseServer(raw) {
|
|
|
7303
7482
|
env
|
|
7304
7483
|
};
|
|
7305
7484
|
}
|
|
7306
|
-
function stripJsonComments(text) {
|
|
7307
|
-
let result2 = "";
|
|
7308
|
-
let i = 0;
|
|
7309
|
-
const len = text.length;
|
|
7310
|
-
while (i < len) {
|
|
7311
|
-
const ch = text[i];
|
|
7312
|
-
if (ch === '"') {
|
|
7313
|
-
result2 += ch;
|
|
7314
|
-
i++;
|
|
7315
|
-
while (i < len) {
|
|
7316
|
-
const sc = text[i];
|
|
7317
|
-
result2 += sc;
|
|
7318
|
-
if (sc === "\\") {
|
|
7319
|
-
i++;
|
|
7320
|
-
if (i < len) {
|
|
7321
|
-
result2 += text[i];
|
|
7322
|
-
}
|
|
7323
|
-
} else if (sc === '"') {
|
|
7324
|
-
break;
|
|
7325
|
-
}
|
|
7326
|
-
i++;
|
|
7327
|
-
}
|
|
7328
|
-
i++;
|
|
7329
|
-
continue;
|
|
7330
|
-
}
|
|
7331
|
-
if (ch === "/" && text[i + 1] === "*") {
|
|
7332
|
-
i += 2;
|
|
7333
|
-
while (i < len) {
|
|
7334
|
-
if (text[i] === "*" && text[i + 1] === "/") {
|
|
7335
|
-
i += 2;
|
|
7336
|
-
break;
|
|
7337
|
-
}
|
|
7338
|
-
i++;
|
|
7339
|
-
}
|
|
7340
|
-
continue;
|
|
7341
|
-
}
|
|
7342
|
-
if (ch === "/" && text[i + 1] === "/") {
|
|
7343
|
-
i += 2;
|
|
7344
|
-
while (i < len && text[i] !== "\n") {
|
|
7345
|
-
i++;
|
|
7346
|
-
}
|
|
7347
|
-
continue;
|
|
7348
|
-
}
|
|
7349
|
-
result2 += ch;
|
|
7350
|
-
i++;
|
|
7351
|
-
}
|
|
7352
|
-
return result2;
|
|
7353
|
-
}
|
|
7354
7485
|
async function parseMcp(mcpPath, onParseError) {
|
|
7355
7486
|
const content = await readFileSafe(mcpPath);
|
|
7356
7487
|
if (!content) return null;
|
|
@@ -7373,6 +7504,7 @@ async function parseMcp(mcpPath, onParseError) {
|
|
|
7373
7504
|
}
|
|
7374
7505
|
var init_mcp = __esm({
|
|
7375
7506
|
"src/canonical/features/mcp.ts"() {
|
|
7507
|
+
init_json_comments();
|
|
7376
7508
|
init_syntax_error();
|
|
7377
7509
|
init_fs();
|
|
7378
7510
|
}
|
|
@@ -8704,7 +8836,7 @@ ${rawBody}`;
|
|
|
8704
8836
|
});
|
|
8705
8837
|
}
|
|
8706
8838
|
function generateMcp3(canonical) {
|
|
8707
|
-
if (!canonical.mcp
|
|
8839
|
+
if (!canonical.mcp) return [];
|
|
8708
8840
|
const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
|
|
8709
8841
|
return [{ path: CLAUDE_MCP_JSON, content }];
|
|
8710
8842
|
}
|
|
@@ -8739,14 +8871,12 @@ function generatePermissions4(canonical) {
|
|
|
8739
8871
|
if (!canonical.permissions) return [];
|
|
8740
8872
|
const { allow, deny } = canonical.permissions;
|
|
8741
8873
|
const ask = canonical.permissions.ask ?? [];
|
|
8742
|
-
if (allow.length === 0 && deny.length === 0 && ask.length === 0) return [];
|
|
8743
8874
|
const content = JSON.stringify({ permissions: { allow, deny, ask } }, null, 2);
|
|
8744
8875
|
return [{ path: CLAUDE_SETTINGS, content }];
|
|
8745
8876
|
}
|
|
8746
8877
|
function generateHooks3(canonical) {
|
|
8747
|
-
if (!canonical.hooks
|
|
8878
|
+
if (!canonical.hooks) return [];
|
|
8748
8879
|
const claudeHooks = buildClaudeHooksObjectFromCanonical(canonical);
|
|
8749
|
-
if (Object.keys(claudeHooks).length === 0) return [];
|
|
8750
8880
|
const content = JSON.stringify({ hooks: claudeHooks }, null, 2);
|
|
8751
8881
|
return [{ path: CLAUDE_SETTINGS, content }];
|
|
8752
8882
|
}
|
|
@@ -20564,9 +20694,9 @@ var init_config_toml = __esm({
|
|
|
20564
20694
|
function isValidKimiPermissionPattern(pattern) {
|
|
20565
20695
|
const trimmed = pattern.trim();
|
|
20566
20696
|
if (trimmed.length === 0) return false;
|
|
20567
|
-
const
|
|
20568
|
-
if (
|
|
20569
|
-
return trimmed.endsWith(")") &&
|
|
20697
|
+
const open2 = trimmed.indexOf("(");
|
|
20698
|
+
if (open2 === -1) return true;
|
|
20699
|
+
return trimmed.endsWith(")") && open2 > 0;
|
|
20570
20700
|
}
|
|
20571
20701
|
function listOf(permissions, key) {
|
|
20572
20702
|
return permissions[key] ?? [];
|
|
@@ -29756,6 +29886,7 @@ function rewriteGeneratedReferences(results, canonical, config, projectRoot, sco
|
|
|
29756
29886
|
// src/core/reference/validate-generated-markdown-links.ts
|
|
29757
29887
|
init_path_helpers();
|
|
29758
29888
|
init_link_rebaser_helpers();
|
|
29889
|
+
init_protected_ranges();
|
|
29759
29890
|
|
|
29760
29891
|
// src/utils/output/color.ts
|
|
29761
29892
|
function noColorRequested() {
|
|
@@ -29838,7 +29969,7 @@ var logger = {
|
|
|
29838
29969
|
|
|
29839
29970
|
// src/core/reference/validate-generated-markdown-links.ts
|
|
29840
29971
|
var INLINE_MD_LINK = /!?\[[^\]]*\]\(([^)]+)\)/g;
|
|
29841
|
-
var REF_LINK_DEF = /^\s*\[[^\]\n]+\]:\s*(?:<([^>\n]*)>|(\S+))/gm;
|
|
29972
|
+
var REF_LINK_DEF = /^\s*\[(?!\^)[^\]\n]+\]:\s*(?:<([^>\n]*)>|(\S+))/gm;
|
|
29842
29973
|
function isMarkdownLikeOutput(relativePath) {
|
|
29843
29974
|
return relativePath.endsWith(".md") || relativePath.endsWith(".mdc");
|
|
29844
29975
|
}
|
|
@@ -29971,7 +30102,7 @@ function findBrokenMarkdownLinks(results, projectRoot) {
|
|
|
29971
30102
|
projectRoot,
|
|
29972
30103
|
pathApi(projectRoot).join(projectRoot, result2.path)
|
|
29973
30104
|
);
|
|
29974
|
-
const protectedR = protectedRanges(result2.content);
|
|
30105
|
+
const protectedR = [...protectedRanges(result2.content), ...inlineCodeRanges(result2.content)];
|
|
29975
30106
|
const visitDestination = (raw, matchIndex) => {
|
|
29976
30107
|
if (isOffsetInRanges(matchIndex, protectedR)) return;
|
|
29977
30108
|
const checked = resolveMarkdownLinkTargets(raw, projectRoot, destinationAbs);
|
|
@@ -30065,28 +30196,10 @@ function ruleNameFromSource(source) {
|
|
|
30065
30196
|
|
|
30066
30197
|
// src/core/generate/collision.ts
|
|
30067
30198
|
init_fs_text_encoding();
|
|
30199
|
+
|
|
30200
|
+
// src/core/generate/collision-agents.ts
|
|
30068
30201
|
init_target_ids();
|
|
30069
30202
|
var AGENTS_SUFFIX = "AGENTS.md";
|
|
30070
|
-
function statusRank(status) {
|
|
30071
|
-
switch (status) {
|
|
30072
|
-
case "created":
|
|
30073
|
-
return 3;
|
|
30074
|
-
case "updated":
|
|
30075
|
-
return 2;
|
|
30076
|
-
case "unchanged":
|
|
30077
|
-
return 1;
|
|
30078
|
-
case "skipped":
|
|
30079
|
-
return 0;
|
|
30080
|
-
}
|
|
30081
|
-
}
|
|
30082
|
-
function mergeDuplicateMetadata(preferred, other) {
|
|
30083
|
-
if (statusRank(other.status) <= statusRank(preferred.status)) return preferred;
|
|
30084
|
-
return {
|
|
30085
|
-
...preferred,
|
|
30086
|
-
status: other.status,
|
|
30087
|
-
currentContent: other.currentContent ?? preferred.currentContent
|
|
30088
|
-
};
|
|
30089
|
-
}
|
|
30090
30203
|
function trimmedContent(content) {
|
|
30091
30204
|
return content.trim();
|
|
30092
30205
|
}
|
|
@@ -30120,15 +30233,82 @@ function richerAgentsResult(left, right) {
|
|
|
30120
30233
|
}
|
|
30121
30234
|
return null;
|
|
30122
30235
|
}
|
|
30236
|
+
function contentLines(content) {
|
|
30237
|
+
const lines = /* @__PURE__ */ new Set();
|
|
30238
|
+
for (const line of content.split("\n")) {
|
|
30239
|
+
const trimmed = line.trim();
|
|
30240
|
+
if (trimmed !== "") lines.add(trimmed);
|
|
30241
|
+
}
|
|
30242
|
+
return lines;
|
|
30243
|
+
}
|
|
30244
|
+
function covers(outer, inner) {
|
|
30245
|
+
for (const line of inner) {
|
|
30246
|
+
if (!outer.has(line)) return false;
|
|
30247
|
+
}
|
|
30248
|
+
return true;
|
|
30249
|
+
}
|
|
30250
|
+
var EMBEDDED_RULES_BLOCK2 = /(<!-- agentsmesh:embedded-rules:start -->)([\s\S]*?)(<!-- agentsmesh:embedded-rules:end -->)/;
|
|
30251
|
+
var EMBEDDED_RULE_UNIT = /<!-- agentsmesh:embedded-rule:start [\s\S]*?<!-- agentsmesh:embedded-rule:end -->/g;
|
|
30252
|
+
function embeddedRuleUnits(block) {
|
|
30253
|
+
return [...block.matchAll(EMBEDDED_RULE_UNIT)].map((m) => m[0]);
|
|
30254
|
+
}
|
|
30255
|
+
function mergedEmbeddedRulesResult(left, right) {
|
|
30256
|
+
if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
|
|
30257
|
+
if (normalizeAgentsContent(left.content) !== normalizeAgentsContent(right.content)) return null;
|
|
30258
|
+
const leftBlock = EMBEDDED_RULES_BLOCK2.exec(left.content);
|
|
30259
|
+
const rightBlock = EMBEDDED_RULES_BLOCK2.exec(right.content);
|
|
30260
|
+
if (!leftBlock?.[2] || !rightBlock?.[2]) return null;
|
|
30261
|
+
const leftUnits = embeddedRuleUnits(leftBlock[2]);
|
|
30262
|
+
const rightUnits = embeddedRuleUnits(rightBlock[2]);
|
|
30263
|
+
if (leftUnits.length === 0 && rightUnits.length === 0) return null;
|
|
30264
|
+
const added = rightUnits.filter((unit) => !leftUnits.includes(unit));
|
|
30265
|
+
if (added.length === 0) return left;
|
|
30266
|
+
const merged = [...leftUnits, ...added].join("\n\n");
|
|
30267
|
+
const content = left.content.replace(
|
|
30268
|
+
EMBEDDED_RULES_BLOCK2,
|
|
30269
|
+
(_full, start, _inner, end) => `${start}
|
|
30270
|
+
|
|
30271
|
+
${merged}
|
|
30272
|
+
|
|
30273
|
+
${end}`
|
|
30274
|
+
);
|
|
30275
|
+
logger.warn(
|
|
30276
|
+
`${left.path} is shared by ${left.target} and ${right.target}, so their target-scoped rules were combined into one file \u2014 every target reading it sees all of them.`
|
|
30277
|
+
);
|
|
30278
|
+
return { ...left, content };
|
|
30279
|
+
}
|
|
30123
30280
|
function richerCodexAgentsResult(left, right) {
|
|
30124
30281
|
if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
|
|
30125
30282
|
const codex = left.target === CODEX_CLI_TARGET_ID ? left : right.target === CODEX_CLI_TARGET_ID ? right : null;
|
|
30126
30283
|
const other = codex === left ? right : left;
|
|
30127
30284
|
if (!codex) return null;
|
|
30128
|
-
const
|
|
30129
|
-
const
|
|
30130
|
-
if (
|
|
30131
|
-
|
|
30285
|
+
const codexLines = contentLines(codex.content);
|
|
30286
|
+
const otherLines = contentLines(other.content);
|
|
30287
|
+
if (covers(codexLines, otherLines)) return codex;
|
|
30288
|
+
if (covers(otherLines, codexLines)) return other;
|
|
30289
|
+
return null;
|
|
30290
|
+
}
|
|
30291
|
+
|
|
30292
|
+
// src/core/generate/collision.ts
|
|
30293
|
+
function statusRank(status) {
|
|
30294
|
+
switch (status) {
|
|
30295
|
+
case "created":
|
|
30296
|
+
return 3;
|
|
30297
|
+
case "updated":
|
|
30298
|
+
return 2;
|
|
30299
|
+
case "unchanged":
|
|
30300
|
+
return 1;
|
|
30301
|
+
case "skipped":
|
|
30302
|
+
return 0;
|
|
30303
|
+
}
|
|
30304
|
+
}
|
|
30305
|
+
function mergeDuplicateMetadata(preferred, other) {
|
|
30306
|
+
if (statusRank(other.status) <= statusRank(preferred.status)) return preferred;
|
|
30307
|
+
return {
|
|
30308
|
+
...preferred,
|
|
30309
|
+
status: other.status,
|
|
30310
|
+
currentContent: other.currentContent ?? preferred.currentContent
|
|
30311
|
+
};
|
|
30132
30312
|
}
|
|
30133
30313
|
function resolveOutputCollisions(results) {
|
|
30134
30314
|
const deduped = [];
|
|
@@ -30145,6 +30325,11 @@ function resolveOutputCollisions(results) {
|
|
|
30145
30325
|
deduped[existingIdx] = richer;
|
|
30146
30326
|
continue;
|
|
30147
30327
|
}
|
|
30328
|
+
const mergedRules = mergedEmbeddedRulesResult(existing, result2);
|
|
30329
|
+
if (mergedRules) {
|
|
30330
|
+
deduped[existingIdx] = refreshResultStatus(mergedRules);
|
|
30331
|
+
continue;
|
|
30332
|
+
}
|
|
30148
30333
|
const richerCodex = richerCodexAgentsResult(existing, result2);
|
|
30149
30334
|
if (richerCodex) {
|
|
30150
30335
|
deduped[existingIdx] = richerCodex;
|
|
@@ -30710,6 +30895,14 @@ function redactUrlSecrets(message) {
|
|
|
30710
30895
|
}
|
|
30711
30896
|
);
|
|
30712
30897
|
}
|
|
30898
|
+
function stripUrlCredentials(url) {
|
|
30899
|
+
return url.replace(
|
|
30900
|
+
URL_WITH_CREDENTIALS,
|
|
30901
|
+
(_full, scheme, _userinfo, rest) => {
|
|
30902
|
+
return `${scheme}${rest}`;
|
|
30903
|
+
}
|
|
30904
|
+
);
|
|
30905
|
+
}
|
|
30713
30906
|
function gitProtocolOptIns() {
|
|
30714
30907
|
const on = (v) => v === "1" || v === "true";
|
|
30715
30908
|
return {
|
|
@@ -31108,6 +31301,7 @@ async function sweepStaleCache(cacheDir, maxAgeMs) {
|
|
|
31108
31301
|
var MAX_CACHE_KEY_LENGTH = 80;
|
|
31109
31302
|
var CACHE_KEY_HASH_LENGTH = 12;
|
|
31110
31303
|
function buildCacheKey(provider, identifier, ref) {
|
|
31304
|
+
identifier = stripUrlCredentials(identifier);
|
|
31111
31305
|
const safe = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/^\.+/, "_");
|
|
31112
31306
|
const [org, repo] = provider === "github" ? identifier.split("/", 2) : [];
|
|
31113
31307
|
const readable = org && repo ? `${safe(org)}--${safe(repo)}--${safe(ref)}` : `${safe(provider)}__${safe(identifier)}__${safe(ref)}`;
|
|
@@ -34466,8 +34660,59 @@ async function diffOutputChecksums(rootBase, lockOutputs) {
|
|
|
34466
34660
|
|
|
34467
34661
|
// src/core/generate/stale-cleanup.ts
|
|
34468
34662
|
init_fs();
|
|
34663
|
+
async function canonicalizePath(path) {
|
|
34664
|
+
try {
|
|
34665
|
+
return await realpath(path);
|
|
34666
|
+
} catch (error) {
|
|
34667
|
+
if (error.code !== "ENOENT") throw error;
|
|
34668
|
+
const parent = dirname(path);
|
|
34669
|
+
if (parent === path) return resolve(path);
|
|
34670
|
+
return join(await canonicalizePath(parent), basename(path));
|
|
34671
|
+
}
|
|
34672
|
+
}
|
|
34673
|
+
function isPathInside(target34, root) {
|
|
34674
|
+
return target34 === root || target34.startsWith(root.endsWith(sep) ? root : `${root}${sep}`);
|
|
34675
|
+
}
|
|
34676
|
+
var display = (path) => path.replaceAll("\\", "/");
|
|
34677
|
+
async function assertPathInsideRoot(root, target34) {
|
|
34678
|
+
const rootAbs = resolve(root);
|
|
34679
|
+
const targetAbs = resolve(target34);
|
|
34680
|
+
if (!isPathInside(targetAbs, rootAbs)) {
|
|
34681
|
+
throw new Error(`Unsafe filesystem path: ${display(target34)} is outside ${display(rootAbs)}`);
|
|
34682
|
+
}
|
|
34683
|
+
let realTarget;
|
|
34684
|
+
let realRoot;
|
|
34685
|
+
try {
|
|
34686
|
+
[realTarget, realRoot] = await Promise.all([
|
|
34687
|
+
canonicalizePath(targetAbs),
|
|
34688
|
+
canonicalizePath(rootAbs)
|
|
34689
|
+
]);
|
|
34690
|
+
} catch (cause) {
|
|
34691
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
34692
|
+
throw new Error(
|
|
34693
|
+
`Unsafe filesystem path: ${display(target34)} could not be resolved (${detail})`,
|
|
34694
|
+
{ cause }
|
|
34695
|
+
);
|
|
34696
|
+
}
|
|
34697
|
+
if (isPathInside(realTarget, realRoot)) return;
|
|
34698
|
+
throw new Error(
|
|
34699
|
+
`Unsafe filesystem path: ${display(target34)} resolves to ${display(realTarget)} outside ${display(realRoot)}`
|
|
34700
|
+
);
|
|
34701
|
+
}
|
|
34702
|
+
|
|
34703
|
+
// src/core/generate/stale-cleanup.ts
|
|
34469
34704
|
init_builtin_targets();
|
|
34470
34705
|
init_registry();
|
|
34706
|
+
init_builtin_targets();
|
|
34707
|
+
function retainedDirs(inactiveTargets, scope) {
|
|
34708
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
34709
|
+
for (const target34 of inactiveTargets) {
|
|
34710
|
+
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) dirs.add(dir);
|
|
34711
|
+
}
|
|
34712
|
+
return dirs;
|
|
34713
|
+
}
|
|
34714
|
+
|
|
34715
|
+
// src/core/generate/stale-cleanup.ts
|
|
34471
34716
|
async function listFiles2(root, base = root) {
|
|
34472
34717
|
const entries = await readdir(root, { withFileTypes: true });
|
|
34473
34718
|
const files = [];
|
|
@@ -34481,13 +34726,6 @@ async function listFiles2(root, base = root) {
|
|
|
34481
34726
|
}
|
|
34482
34727
|
return files;
|
|
34483
34728
|
}
|
|
34484
|
-
function retainedDirs(inactiveTargets, scope) {
|
|
34485
|
-
const dirs = /* @__PURE__ */ new Set();
|
|
34486
|
-
for (const target34 of inactiveTargets) {
|
|
34487
|
-
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) dirs.add(dir);
|
|
34488
|
-
}
|
|
34489
|
-
return dirs;
|
|
34490
|
-
}
|
|
34491
34729
|
function primaryEmitted(target34, scope, expected) {
|
|
34492
34730
|
const descriptor34 = getBuiltinTargetDefinition(target34) ?? getDescriptor(target34);
|
|
34493
34731
|
const primary = getTargetLayout(target34, scope)?.rootInstructionPath ?? descriptor34?.generators.primaryRootInstructionPath;
|
|
@@ -34514,6 +34752,7 @@ async function findStaleGeneratedOutputs(args) {
|
|
|
34514
34752
|
for (const dir of managed.dirs) {
|
|
34515
34753
|
if (retained.has(dir)) continue;
|
|
34516
34754
|
const absDir = join(args.projectRoot, dir);
|
|
34755
|
+
await assertPathInsideRoot(args.projectRoot, absDir);
|
|
34517
34756
|
if (!await exists(absDir)) continue;
|
|
34518
34757
|
for (const file of await listFiles2(absDir)) {
|
|
34519
34758
|
const relPath = `${dir}/${file}`.replace(/\/+/g, "/");
|
|
@@ -34525,6 +34764,7 @@ async function findStaleGeneratedOutputs(args) {
|
|
|
34525
34764
|
const found = [];
|
|
34526
34765
|
for (const relPath of stale) {
|
|
34527
34766
|
if (expected.has(relPath) || coOwned.has(relPath)) continue;
|
|
34767
|
+
await assertPathInsideRoot(args.projectRoot, dirname(join(args.projectRoot, relPath)));
|
|
34528
34768
|
if (await exists(join(args.projectRoot, relPath))) found.push(relPath);
|
|
34529
34769
|
}
|
|
34530
34770
|
return found.sort();
|
|
@@ -34538,6 +34778,7 @@ async function findUntrackedManagedDirFiles(args) {
|
|
|
34538
34778
|
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) {
|
|
34539
34779
|
if (retained.has(dir)) continue;
|
|
34540
34780
|
const absDir = join(args.projectRoot, dir);
|
|
34781
|
+
await assertPathInsideRoot(args.projectRoot, absDir);
|
|
34541
34782
|
if (!await exists(absDir)) continue;
|
|
34542
34783
|
for (const file of await listFiles2(absDir)) {
|
|
34543
34784
|
const relPath = `${dir}/${file}`.replace(/\/+/g, "/");
|
|
@@ -35084,8 +35325,8 @@ function isBroadGlob(pattern) {
|
|
|
35084
35325
|
const p = pattern.trim();
|
|
35085
35326
|
if (p === "*" || p === "**") return true;
|
|
35086
35327
|
if (!p.includes("**")) return false;
|
|
35087
|
-
const
|
|
35088
|
-
return
|
|
35328
|
+
const basename78 = p.slice(p.lastIndexOf("/") + 1);
|
|
35329
|
+
return basename78.startsWith("*");
|
|
35089
35330
|
}
|
|
35090
35331
|
function inspectCapturedLesson(graph, lessonId, knownPaths) {
|
|
35091
35332
|
const lesson = graph.lessons[lessonId];
|
|
@@ -35191,8 +35432,7 @@ async function acquireProcessLock(lockPath, opts = {}) {
|
|
|
35191
35432
|
if (acquired) return acquired;
|
|
35192
35433
|
const existing = await inspectLock(lockPath);
|
|
35193
35434
|
if (existing !== "young" && isStale(existing, stale)) {
|
|
35194
|
-
await rm(lockPath, { recursive: true, force: true })
|
|
35195
|
-
});
|
|
35435
|
+
await rm(lockPath, { recursive: true, force: true });
|
|
35196
35436
|
continue;
|
|
35197
35437
|
}
|
|
35198
35438
|
if (attempt >= retries) {
|
|
@@ -35216,7 +35456,13 @@ async function tryAcquire(lockPath) {
|
|
|
35216
35456
|
started: Date.now(),
|
|
35217
35457
|
hostname: getHostname()
|
|
35218
35458
|
};
|
|
35219
|
-
|
|
35459
|
+
try {
|
|
35460
|
+
await writeFile(metadataPath, JSON.stringify(metadata), "utf-8");
|
|
35461
|
+
} catch (error) {
|
|
35462
|
+
await rm(lockPath, { recursive: true, force: true }).catch(() => {
|
|
35463
|
+
});
|
|
35464
|
+
throw error;
|
|
35465
|
+
}
|
|
35220
35466
|
let released = false;
|
|
35221
35467
|
const cleanup = () => {
|
|
35222
35468
|
if (released) return;
|
|
@@ -35288,7 +35534,7 @@ function getHostname() {
|
|
|
35288
35534
|
return hostname();
|
|
35289
35535
|
}
|
|
35290
35536
|
function sleep2(ms) {
|
|
35291
|
-
return new Promise((
|
|
35537
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
35292
35538
|
}
|
|
35293
35539
|
|
|
35294
35540
|
// src/lessons/lessons-lock.ts
|
|
@@ -35641,6 +35887,11 @@ function recallLogPath(projectRoot) {
|
|
|
35641
35887
|
return join(lessonsPaths(projectRoot).base, "recall-log.jsonl");
|
|
35642
35888
|
}
|
|
35643
35889
|
|
|
35890
|
+
// src/lessons/lexical-retrieval.ts
|
|
35891
|
+
new Set(
|
|
35892
|
+
"top left right bottom before after first last next new old use used using run make keep set get add all any each every not no never always only one two more less same other than then into from over under out up down off via per so if else when where which what who how why do does did done can could should would will may might has have had are was were been being also still just even very both either such these those they them their we you your our he she his her my me our us own same here there now then again once about above below between during through until while because but by need needs needed way ways thing things".split(" ")
|
|
35893
|
+
);
|
|
35894
|
+
|
|
35644
35895
|
// src/lessons/ranking-signals.ts
|
|
35645
35896
|
function buildFanout(graph) {
|
|
35646
35897
|
const fanout = /* @__PURE__ */ new Map();
|
|
@@ -35707,7 +35958,7 @@ function rankLessons(graph, query, matches, options = {}) {
|
|
|
35707
35958
|
const narrowness = buildNarrowness(graph);
|
|
35708
35959
|
const coherence = buildTopicCoherence(matches);
|
|
35709
35960
|
const matchedTriggerIds = collectMatchedTriggerIds(graph, query);
|
|
35710
|
-
const scored = matches.map(({ id, lesson }) => {
|
|
35961
|
+
const scored = matches.map(({ id, lesson, lexical }) => {
|
|
35711
35962
|
const hitTriggers = lesson.triggers.filter((t) => matchedTriggerIds.has(t));
|
|
35712
35963
|
let specificity = 0;
|
|
35713
35964
|
for (const t of hitTriggers) {
|
|
@@ -35723,7 +35974,8 @@ function rankLessons(graph, query, matches, options = {}) {
|
|
|
35723
35974
|
matchedTriggers: hitTriggers,
|
|
35724
35975
|
// Absent from the log ⇒ neutral 1, so a lesson with no outcome data never
|
|
35725
35976
|
// sinks below one that has merely been recorded.
|
|
35726
|
-
effectiveness: options.effectiveness?.get(id) ?? 1
|
|
35977
|
+
effectiveness: options.effectiveness?.get(id) ?? 1,
|
|
35978
|
+
lexical
|
|
35727
35979
|
};
|
|
35728
35980
|
});
|
|
35729
35981
|
const bm25Ranks = rankMap(scored.map((s) => ({ id: s.id, value: s.bm25 })));
|
|
@@ -35738,7 +35990,8 @@ function rankLessons(graph, query, matches, options = {}) {
|
|
|
35738
35990
|
matchedTriggers: s.matchedTriggers,
|
|
35739
35991
|
bm25: s.bm25,
|
|
35740
35992
|
specificity: s.specificity,
|
|
35741
|
-
topicCoherence: s.topicCoherence
|
|
35993
|
+
topicCoherence: s.topicCoherence,
|
|
35994
|
+
...s.lexical === true ? { lexical: true } : {}
|
|
35742
35995
|
}
|
|
35743
35996
|
})).sort((a, b) => {
|
|
35744
35997
|
if (b.score !== a.score) return b.score - a.score;
|