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/engine.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { parse, stringify, parseDocument, isMap, Document, isSeq, isScalar, Scalar, Pair, YAMLSeq } from 'yaml';
|
|
3
3
|
import { existsSync, readFileSync, constants, readdirSync, realpathSync, statSync } from 'fs';
|
|
4
|
-
import { basename, join, dirname, relative, win32, posix, sep, resolve
|
|
5
|
-
import { readFile, rm, mkdir, readdir, lstat,
|
|
4
|
+
import { basename, join, dirname, relative, extname, win32, posix, sep, resolve } from 'path';
|
|
5
|
+
import { readFile, rm, mkdir, readdir, lstat, open, access, stat, realpath, rename, writeFile, mkdtemp, cp } from 'fs/promises';
|
|
6
6
|
import { setTimeout } from 'timers/promises';
|
|
7
|
+
import { randomUUID, createHash } 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, 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';
|
|
@@ -845,6 +845,12 @@ function shouldNormalizeLineEndings(path) {
|
|
|
845
845
|
const base = basename(path).toLowerCase();
|
|
846
846
|
return TEXT_DOTFILES.has(base);
|
|
847
847
|
}
|
|
848
|
+
function isBinaryPayloadPath(path) {
|
|
849
|
+
return BINARY_EXTENSIONS.has(extname(path).toLowerCase());
|
|
850
|
+
}
|
|
851
|
+
function payloadEncodingFor(path) {
|
|
852
|
+
return isBinaryPayloadPath(path) ? "latin1" : "utf-8";
|
|
853
|
+
}
|
|
848
854
|
function normalizeLineEndings(content) {
|
|
849
855
|
return content.replace(/\r\n?/g, "\n");
|
|
850
856
|
}
|
|
@@ -856,7 +862,7 @@ function normalizeTextPayload(path, content) {
|
|
|
856
862
|
const withoutBom = content.startsWith(UTF8_BOM) ? content.slice(UTF8_BOM.length) : content;
|
|
857
863
|
return normalizeLineEndings(withoutBom);
|
|
858
864
|
}
|
|
859
|
-
var UTF8_BOM, TEXT_EXTENSIONS, TEXT_DOTFILES, EXECUTABLE_SCRIPT_EXTENSIONS;
|
|
865
|
+
var UTF8_BOM, TEXT_EXTENSIONS, TEXT_DOTFILES, BINARY_EXTENSIONS, EXECUTABLE_SCRIPT_EXTENSIONS;
|
|
860
866
|
var init_fs_text_encoding = __esm({
|
|
861
867
|
"src/utils/filesystem/fs-text-encoding.ts"() {
|
|
862
868
|
UTF8_BOM = "\uFEFF";
|
|
@@ -901,9 +907,109 @@ var init_fs_text_encoding = __esm({
|
|
|
901
907
|
".rooignore",
|
|
902
908
|
".antigravityignore"
|
|
903
909
|
]);
|
|
910
|
+
BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
911
|
+
".png",
|
|
912
|
+
".jpg",
|
|
913
|
+
".jpeg",
|
|
914
|
+
".gif",
|
|
915
|
+
".bmp",
|
|
916
|
+
".ico",
|
|
917
|
+
".webp",
|
|
918
|
+
".avif",
|
|
919
|
+
".tiff",
|
|
920
|
+
".pdf",
|
|
921
|
+
".zip",
|
|
922
|
+
".gz",
|
|
923
|
+
".tgz",
|
|
924
|
+
".bz2",
|
|
925
|
+
".xz",
|
|
926
|
+
".7z",
|
|
927
|
+
".rar",
|
|
928
|
+
".jar",
|
|
929
|
+
".woff",
|
|
930
|
+
".woff2",
|
|
931
|
+
".ttf",
|
|
932
|
+
".otf",
|
|
933
|
+
".eot",
|
|
934
|
+
".mp3",
|
|
935
|
+
".mp4",
|
|
936
|
+
".wav",
|
|
937
|
+
".ogg",
|
|
938
|
+
".webm",
|
|
939
|
+
".mov",
|
|
940
|
+
".wasm",
|
|
941
|
+
".bin",
|
|
942
|
+
".dat",
|
|
943
|
+
".db",
|
|
944
|
+
".sqlite",
|
|
945
|
+
".so",
|
|
946
|
+
".dylib",
|
|
947
|
+
".dll",
|
|
948
|
+
".exe",
|
|
949
|
+
".class",
|
|
950
|
+
".pyc",
|
|
951
|
+
// Office and design documents are zip or proprietary containers.
|
|
952
|
+
".xlsx",
|
|
953
|
+
".xls",
|
|
954
|
+
".docx",
|
|
955
|
+
".doc",
|
|
956
|
+
".pptx",
|
|
957
|
+
".ppt",
|
|
958
|
+
".odt",
|
|
959
|
+
".ods",
|
|
960
|
+
".psd",
|
|
961
|
+
".ai",
|
|
962
|
+
".sketch",
|
|
963
|
+
".fig",
|
|
964
|
+
".heic",
|
|
965
|
+
".heif",
|
|
966
|
+
// Archives, columnar data, models and compressed payloads.
|
|
967
|
+
".tar",
|
|
968
|
+
".zst",
|
|
969
|
+
".br",
|
|
970
|
+
".lz4",
|
|
971
|
+
".parquet",
|
|
972
|
+
".avro",
|
|
973
|
+
".orc",
|
|
974
|
+
".pkl",
|
|
975
|
+
".npy",
|
|
976
|
+
".npz",
|
|
977
|
+
".onnx",
|
|
978
|
+
".pt",
|
|
979
|
+
".safetensors",
|
|
980
|
+
".gguf",
|
|
981
|
+
".sqlite3",
|
|
982
|
+
".avi",
|
|
983
|
+
".mkv",
|
|
984
|
+
".flac",
|
|
985
|
+
".aac",
|
|
986
|
+
".m4a",
|
|
987
|
+
".ttc"
|
|
988
|
+
]);
|
|
904
989
|
EXECUTABLE_SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([".sh", ".bash", ".zsh"]);
|
|
905
990
|
}
|
|
906
991
|
});
|
|
992
|
+
async function renameWithRetry(from, to, options = {}) {
|
|
993
|
+
const attempts = options.attempts ?? 5;
|
|
994
|
+
const delayMs = options.delayMs ?? 50;
|
|
995
|
+
for (let attempt = 0; ; attempt++) {
|
|
996
|
+
try {
|
|
997
|
+
await rename(from, to);
|
|
998
|
+
return;
|
|
999
|
+
} catch (err) {
|
|
1000
|
+
const code = err.code;
|
|
1001
|
+
const transient = code !== void 0 && TRANSIENT_RENAME_CODES.has(code);
|
|
1002
|
+
if (!transient || attempt >= attempts - 1) throw err;
|
|
1003
|
+
await setTimeout(delayMs * 2 ** attempt);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
var TRANSIENT_RENAME_CODES;
|
|
1008
|
+
var init_rename_retry = __esm({
|
|
1009
|
+
"src/utils/filesystem/rename-retry.ts"() {
|
|
1010
|
+
TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "ENOTEMPTY", "EEXIST"]);
|
|
1011
|
+
}
|
|
1012
|
+
});
|
|
907
1013
|
function shouldSkipRecursiveBranch(segments) {
|
|
908
1014
|
if (segments.length > MAX_RECURSIVE_DEPTH) return true;
|
|
909
1015
|
const counts = /* @__PURE__ */ new Map();
|
|
@@ -994,30 +1100,10 @@ var init_fs_traverse = __esm({
|
|
|
994
1100
|
MAX_SEGMENT_REPETITIONS = 3;
|
|
995
1101
|
}
|
|
996
1102
|
});
|
|
997
|
-
async function renameWithRetry(from, to, options = {}) {
|
|
998
|
-
const attempts = options.attempts ?? 5;
|
|
999
|
-
const delayMs = options.delayMs ?? 50;
|
|
1000
|
-
for (let attempt = 0; ; attempt++) {
|
|
1001
|
-
try {
|
|
1002
|
-
await rename(from, to);
|
|
1003
|
-
return;
|
|
1004
|
-
} catch (err) {
|
|
1005
|
-
const code = err.code;
|
|
1006
|
-
const transient = code !== void 0 && TRANSIENT_RENAME_CODES.has(code);
|
|
1007
|
-
if (!transient || attempt >= attempts - 1) throw err;
|
|
1008
|
-
await setTimeout(delayMs * 2 ** attempt);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
var TRANSIENT_RENAME_CODES;
|
|
1013
|
-
var init_rename_retry = __esm({
|
|
1014
|
-
"src/utils/filesystem/rename-retry.ts"() {
|
|
1015
|
-
TRANSIENT_RENAME_CODES = /* @__PURE__ */ new Set(["EPERM", "EACCES", "EBUSY", "ENOTEMPTY", "EEXIST"]);
|
|
1016
|
-
}
|
|
1017
|
-
});
|
|
1018
1103
|
async function readFileSafe(path) {
|
|
1019
1104
|
try {
|
|
1020
|
-
const data = await readFile(path,
|
|
1105
|
+
const data = await readFile(path, payloadEncodingFor(path));
|
|
1106
|
+
if (isBinaryPayloadPath(path)) return data;
|
|
1021
1107
|
return data.startsWith(UTF8_BOM) ? data.slice(UTF8_BOM.length) : data;
|
|
1022
1108
|
} catch (err) {
|
|
1023
1109
|
const e = err;
|
|
@@ -1041,40 +1127,28 @@ async function writeFileAtomic(path, content, options) {
|
|
|
1041
1127
|
{ errnoCode: "EISDIR" }
|
|
1042
1128
|
);
|
|
1043
1129
|
}
|
|
1044
|
-
if (info.isSymbolicLink()) {
|
|
1045
|
-
await unlink(path).catch((e) => {
|
|
1046
|
-
if (e.code !== "ENOENT") throw e;
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
1130
|
} catch (err) {
|
|
1050
1131
|
if (err instanceof FileSystemError) throw err;
|
|
1051
1132
|
const e = err;
|
|
1052
1133
|
if (e.code !== "ENOENT") throw err;
|
|
1053
1134
|
}
|
|
1054
|
-
const tmpPath = `${path}.tmp`;
|
|
1135
|
+
const tmpPath = `${path}.tmp-${randomUUID()}`;
|
|
1055
1136
|
const payload = shouldNormalizeLineEndings(path) ? normalizeLineEndings(content) : content;
|
|
1056
1137
|
const mode = executableModeFor(path);
|
|
1138
|
+
let handle;
|
|
1139
|
+
let ownsTemporaryFile = false;
|
|
1057
1140
|
try {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
}
|
|
1066
|
-
const writeOpts = {
|
|
1067
|
-
encoding: "utf-8",
|
|
1068
|
-
flag: "w"
|
|
1069
|
-
};
|
|
1070
|
-
if (mode !== void 0) writeOpts.mode = mode;
|
|
1071
|
-
await writeFile(tmpPath, payload, writeOpts);
|
|
1072
|
-
await rename(tmpPath, path);
|
|
1073
|
-
if (mode !== void 0) {
|
|
1074
|
-
await chmod(path, mode);
|
|
1075
|
-
}
|
|
1141
|
+
handle = await open(tmpPath, "wx", mode);
|
|
1142
|
+
ownsTemporaryFile = true;
|
|
1143
|
+
await handle.writeFile(payload, payloadEncodingFor(path));
|
|
1144
|
+
if (mode !== void 0) await handle.chmod(mode);
|
|
1145
|
+
await handle.close();
|
|
1146
|
+
handle = void 0;
|
|
1147
|
+
await renameWithRetry(tmpPath, path);
|
|
1076
1148
|
} catch (err) {
|
|
1077
|
-
await
|
|
1149
|
+
await handle?.close().catch(() => {
|
|
1150
|
+
});
|
|
1151
|
+
if (ownsTemporaryFile) await rm(tmpPath, { force: true }).catch(() => {
|
|
1078
1152
|
});
|
|
1079
1153
|
const e = err;
|
|
1080
1154
|
throw new FileSystemError(
|
|
@@ -1099,6 +1173,7 @@ var init_fs = __esm({
|
|
|
1099
1173
|
"src/utils/filesystem/fs.ts"() {
|
|
1100
1174
|
init_errors();
|
|
1101
1175
|
init_fs_text_encoding();
|
|
1176
|
+
init_rename_retry();
|
|
1102
1177
|
init_fs_traverse();
|
|
1103
1178
|
init_fs_text_encoding();
|
|
1104
1179
|
init_rename_retry();
|
|
@@ -2251,43 +2326,92 @@ function isGlobAdjacent(content, start, end) {
|
|
|
2251
2326
|
const next = end < content.length ? content.at(end) : "";
|
|
2252
2327
|
return prev === "*" || next === "*";
|
|
2253
2328
|
}
|
|
2329
|
+
var NON_REWRITABLE_BARE_FILES, PATH_TOKEN, LINE_NUMBER_SUFFIX;
|
|
2330
|
+
var init_link_rebaser_helpers = __esm({
|
|
2331
|
+
"src/core/reference/link-rebaser-helpers.ts"() {
|
|
2332
|
+
init_path_helpers();
|
|
2333
|
+
init_link_format_registry();
|
|
2334
|
+
NON_REWRITABLE_BARE_FILES = /* @__PURE__ */ new Set([
|
|
2335
|
+
"AGENTS.md",
|
|
2336
|
+
"CLAUDE.md",
|
|
2337
|
+
"GEMINI.md",
|
|
2338
|
+
"codex.md",
|
|
2339
|
+
".windsurfrules",
|
|
2340
|
+
".cursorrules"
|
|
2341
|
+
]);
|
|
2342
|
+
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;
|
|
2343
|
+
LINE_NUMBER_SUFFIX = /(?::(\d+)){1,2}$/;
|
|
2344
|
+
}
|
|
2345
|
+
});
|
|
2346
|
+
|
|
2347
|
+
// src/core/reference/protected-ranges.ts
|
|
2348
|
+
function inlineCodeRanges(content) {
|
|
2349
|
+
const ranges = [];
|
|
2350
|
+
let openStart = -1;
|
|
2351
|
+
let openLength = 0;
|
|
2352
|
+
for (const match of content.matchAll(/`+/g)) {
|
|
2353
|
+
const start = match.index;
|
|
2354
|
+
const length = match[0].length;
|
|
2355
|
+
if (openStart === -1) {
|
|
2356
|
+
openStart = start;
|
|
2357
|
+
openLength = length;
|
|
2358
|
+
continue;
|
|
2359
|
+
}
|
|
2360
|
+
if (length === openLength) {
|
|
2361
|
+
ranges.push([openStart, start + length]);
|
|
2362
|
+
openStart = -1;
|
|
2363
|
+
openLength = 0;
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
return ranges;
|
|
2367
|
+
}
|
|
2368
|
+
function extendAcrossBalancedParens(content, end) {
|
|
2369
|
+
let cursor = end;
|
|
2370
|
+
while (content[cursor] === "(") {
|
|
2371
|
+
let depth = 0;
|
|
2372
|
+
let scan = cursor;
|
|
2373
|
+
while (scan < content.length) {
|
|
2374
|
+
const ch = content[scan];
|
|
2375
|
+
if (ch === "(") depth += 1;
|
|
2376
|
+
else if (ch === ")") {
|
|
2377
|
+
depth -= 1;
|
|
2378
|
+
if (depth === 0) break;
|
|
2379
|
+
} else if (ch === void 0 || /\s/.test(ch)) return cursor;
|
|
2380
|
+
scan += 1;
|
|
2381
|
+
}
|
|
2382
|
+
if (depth !== 0) return cursor;
|
|
2383
|
+
cursor = scan + 1;
|
|
2384
|
+
while (cursor < content.length && !/[\s<>()\]]/.test(content.charAt(cursor))) cursor += 1;
|
|
2385
|
+
}
|
|
2386
|
+
return cursor;
|
|
2387
|
+
}
|
|
2254
2388
|
function protectedRanges(content) {
|
|
2255
2389
|
const ranges = [];
|
|
2256
2390
|
for (const pattern of getLinkFormatRegistry().protectedSchemes) {
|
|
2257
2391
|
const globalPattern = pattern.flags.includes("g") ? pattern : new RegExp(pattern.source, `${pattern.flags}g`);
|
|
2258
2392
|
for (const match of content.matchAll(globalPattern)) {
|
|
2259
|
-
|
|
2393
|
+
const start = match.index;
|
|
2394
|
+
ranges.push([start, extendAcrossBalancedParens(content, start + match[0].length)]);
|
|
2260
2395
|
}
|
|
2261
2396
|
}
|
|
2262
2397
|
for (const match of content.matchAll(FENCED_CODE_BLOCK)) {
|
|
2263
|
-
ranges.push([match.index
|
|
2398
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2264
2399
|
}
|
|
2265
2400
|
for (const match of content.matchAll(ROOT_GENERATION_CONTRACT_BLOCK)) {
|
|
2266
|
-
ranges.push([match.index
|
|
2401
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2267
2402
|
}
|
|
2268
2403
|
for (const match of content.matchAll(EMBEDDED_RULES_BLOCK)) {
|
|
2269
|
-
ranges.push([match.index
|
|
2404
|
+
ranges.push([match.index, match.index + match[0].length]);
|
|
2270
2405
|
}
|
|
2271
2406
|
return ranges;
|
|
2272
2407
|
}
|
|
2273
|
-
var
|
|
2274
|
-
var
|
|
2275
|
-
"src/core/reference/
|
|
2276
|
-
init_path_helpers();
|
|
2408
|
+
var FENCED_CODE_BLOCK, ROOT_GENERATION_CONTRACT_BLOCK, EMBEDDED_RULES_BLOCK;
|
|
2409
|
+
var init_protected_ranges = __esm({
|
|
2410
|
+
"src/core/reference/protected-ranges.ts"() {
|
|
2277
2411
|
init_link_format_registry();
|
|
2278
|
-
NON_REWRITABLE_BARE_FILES = /* @__PURE__ */ new Set([
|
|
2279
|
-
"AGENTS.md",
|
|
2280
|
-
"CLAUDE.md",
|
|
2281
|
-
"GEMINI.md",
|
|
2282
|
-
"codex.md",
|
|
2283
|
-
".windsurfrules",
|
|
2284
|
-
".cursorrules"
|
|
2285
|
-
]);
|
|
2286
2412
|
FENCED_CODE_BLOCK = /^(?:```|~~~)[^\n]*\n[\s\S]*?^(?:```|~~~)/gm;
|
|
2287
2413
|
ROOT_GENERATION_CONTRACT_BLOCK = /<!-- agentsmesh:root-generation-contract:start -->[\s\S]*?<!-- agentsmesh:root-generation-contract:end -->/g;
|
|
2288
2414
|
EMBEDDED_RULES_BLOCK = /<!-- agentsmesh:embedded-rules:start -->[\s\S]*?<!-- agentsmesh:embedded-rules:end -->/g;
|
|
2289
|
-
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;
|
|
2290
|
-
LINE_NUMBER_SUFFIX = /(?::(\d+)){1,2}$/;
|
|
2291
2415
|
}
|
|
2292
2416
|
});
|
|
2293
2417
|
|
|
@@ -2780,6 +2904,7 @@ var init_link_rebaser = __esm({
|
|
|
2780
2904
|
"src/core/reference/link-rebaser.ts"() {
|
|
2781
2905
|
init_path_helpers();
|
|
2782
2906
|
init_link_rebaser_helpers();
|
|
2907
|
+
init_protected_ranges();
|
|
2783
2908
|
init_link_rebaser_output();
|
|
2784
2909
|
init_link_rebaser_resolution();
|
|
2785
2910
|
init_link_uri_encoding();
|
|
@@ -7203,6 +7328,60 @@ var init_embedded_rules = __esm({
|
|
|
7203
7328
|
}
|
|
7204
7329
|
});
|
|
7205
7330
|
|
|
7331
|
+
// src/utils/text/json-comments.ts
|
|
7332
|
+
function stripJsonComments(text) {
|
|
7333
|
+
let result2 = "";
|
|
7334
|
+
let i = 0;
|
|
7335
|
+
const len = text.length;
|
|
7336
|
+
while (i < len) {
|
|
7337
|
+
const ch = text[i];
|
|
7338
|
+
if (ch === '"') {
|
|
7339
|
+
result2 += ch;
|
|
7340
|
+
i++;
|
|
7341
|
+
while (i < len) {
|
|
7342
|
+
const sc = text[i];
|
|
7343
|
+
result2 += sc;
|
|
7344
|
+
if (sc === "\\") {
|
|
7345
|
+
i++;
|
|
7346
|
+
if (i < len) {
|
|
7347
|
+
result2 += text[i];
|
|
7348
|
+
}
|
|
7349
|
+
} else if (sc === '"') {
|
|
7350
|
+
break;
|
|
7351
|
+
}
|
|
7352
|
+
i++;
|
|
7353
|
+
}
|
|
7354
|
+
i++;
|
|
7355
|
+
continue;
|
|
7356
|
+
}
|
|
7357
|
+
if (ch === "/" && text[i + 1] === "*") {
|
|
7358
|
+
i += 2;
|
|
7359
|
+
while (i < len) {
|
|
7360
|
+
if (text[i] === "*" && text[i + 1] === "/") {
|
|
7361
|
+
i += 2;
|
|
7362
|
+
break;
|
|
7363
|
+
}
|
|
7364
|
+
i++;
|
|
7365
|
+
}
|
|
7366
|
+
continue;
|
|
7367
|
+
}
|
|
7368
|
+
if (ch === "/" && text[i + 1] === "/") {
|
|
7369
|
+
i += 2;
|
|
7370
|
+
while (i < len && text[i] !== "\n") {
|
|
7371
|
+
i++;
|
|
7372
|
+
}
|
|
7373
|
+
continue;
|
|
7374
|
+
}
|
|
7375
|
+
result2 += ch;
|
|
7376
|
+
i++;
|
|
7377
|
+
}
|
|
7378
|
+
return result2;
|
|
7379
|
+
}
|
|
7380
|
+
var init_json_comments = __esm({
|
|
7381
|
+
"src/utils/text/json-comments.ts"() {
|
|
7382
|
+
}
|
|
7383
|
+
});
|
|
7384
|
+
|
|
7206
7385
|
// src/canonical/features/syntax-error.ts
|
|
7207
7386
|
function failSyntax(filePath2, cause, onParseError) {
|
|
7208
7387
|
const error = new CanonicalParseError(filePath2, cause);
|
|
@@ -7252,54 +7431,6 @@ function parseServer(raw) {
|
|
|
7252
7431
|
env
|
|
7253
7432
|
};
|
|
7254
7433
|
}
|
|
7255
|
-
function stripJsonComments(text) {
|
|
7256
|
-
let result2 = "";
|
|
7257
|
-
let i = 0;
|
|
7258
|
-
const len = text.length;
|
|
7259
|
-
while (i < len) {
|
|
7260
|
-
const ch = text[i];
|
|
7261
|
-
if (ch === '"') {
|
|
7262
|
-
result2 += ch;
|
|
7263
|
-
i++;
|
|
7264
|
-
while (i < len) {
|
|
7265
|
-
const sc = text[i];
|
|
7266
|
-
result2 += sc;
|
|
7267
|
-
if (sc === "\\") {
|
|
7268
|
-
i++;
|
|
7269
|
-
if (i < len) {
|
|
7270
|
-
result2 += text[i];
|
|
7271
|
-
}
|
|
7272
|
-
} else if (sc === '"') {
|
|
7273
|
-
break;
|
|
7274
|
-
}
|
|
7275
|
-
i++;
|
|
7276
|
-
}
|
|
7277
|
-
i++;
|
|
7278
|
-
continue;
|
|
7279
|
-
}
|
|
7280
|
-
if (ch === "/" && text[i + 1] === "*") {
|
|
7281
|
-
i += 2;
|
|
7282
|
-
while (i < len) {
|
|
7283
|
-
if (text[i] === "*" && text[i + 1] === "/") {
|
|
7284
|
-
i += 2;
|
|
7285
|
-
break;
|
|
7286
|
-
}
|
|
7287
|
-
i++;
|
|
7288
|
-
}
|
|
7289
|
-
continue;
|
|
7290
|
-
}
|
|
7291
|
-
if (ch === "/" && text[i + 1] === "/") {
|
|
7292
|
-
i += 2;
|
|
7293
|
-
while (i < len && text[i] !== "\n") {
|
|
7294
|
-
i++;
|
|
7295
|
-
}
|
|
7296
|
-
continue;
|
|
7297
|
-
}
|
|
7298
|
-
result2 += ch;
|
|
7299
|
-
i++;
|
|
7300
|
-
}
|
|
7301
|
-
return result2;
|
|
7302
|
-
}
|
|
7303
7434
|
async function parseMcp(mcpPath, onParseError) {
|
|
7304
7435
|
const content = await readFileSafe(mcpPath);
|
|
7305
7436
|
if (!content) return null;
|
|
@@ -7322,6 +7453,7 @@ async function parseMcp(mcpPath, onParseError) {
|
|
|
7322
7453
|
}
|
|
7323
7454
|
var init_mcp = __esm({
|
|
7324
7455
|
"src/canonical/features/mcp.ts"() {
|
|
7456
|
+
init_json_comments();
|
|
7325
7457
|
init_syntax_error();
|
|
7326
7458
|
init_fs();
|
|
7327
7459
|
}
|
|
@@ -8653,7 +8785,7 @@ ${rawBody}`;
|
|
|
8653
8785
|
});
|
|
8654
8786
|
}
|
|
8655
8787
|
function generateMcp3(canonical) {
|
|
8656
|
-
if (!canonical.mcp
|
|
8788
|
+
if (!canonical.mcp) return [];
|
|
8657
8789
|
const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
|
|
8658
8790
|
return [{ path: CLAUDE_MCP_JSON, content }];
|
|
8659
8791
|
}
|
|
@@ -8688,14 +8820,12 @@ function generatePermissions4(canonical) {
|
|
|
8688
8820
|
if (!canonical.permissions) return [];
|
|
8689
8821
|
const { allow, deny } = canonical.permissions;
|
|
8690
8822
|
const ask = canonical.permissions.ask ?? [];
|
|
8691
|
-
if (allow.length === 0 && deny.length === 0 && ask.length === 0) return [];
|
|
8692
8823
|
const content = JSON.stringify({ permissions: { allow, deny, ask } }, null, 2);
|
|
8693
8824
|
return [{ path: CLAUDE_SETTINGS, content }];
|
|
8694
8825
|
}
|
|
8695
8826
|
function generateHooks3(canonical) {
|
|
8696
|
-
if (!canonical.hooks
|
|
8827
|
+
if (!canonical.hooks) return [];
|
|
8697
8828
|
const claudeHooks = buildClaudeHooksObjectFromCanonical(canonical);
|
|
8698
|
-
if (Object.keys(claudeHooks).length === 0) return [];
|
|
8699
8829
|
const content = JSON.stringify({ hooks: claudeHooks }, null, 2);
|
|
8700
8830
|
return [{ path: CLAUDE_SETTINGS, content }];
|
|
8701
8831
|
}
|
|
@@ -20513,9 +20643,9 @@ var init_config_toml = __esm({
|
|
|
20513
20643
|
function isValidKimiPermissionPattern(pattern) {
|
|
20514
20644
|
const trimmed = pattern.trim();
|
|
20515
20645
|
if (trimmed.length === 0) return false;
|
|
20516
|
-
const
|
|
20517
|
-
if (
|
|
20518
|
-
return trimmed.endsWith(")") &&
|
|
20646
|
+
const open2 = trimmed.indexOf("(");
|
|
20647
|
+
if (open2 === -1) return true;
|
|
20648
|
+
return trimmed.endsWith(")") && open2 > 0;
|
|
20519
20649
|
}
|
|
20520
20650
|
function listOf(permissions, key) {
|
|
20521
20651
|
return permissions[key] ?? [];
|
|
@@ -29705,6 +29835,7 @@ function rewriteGeneratedReferences(results, canonical, config, projectRoot, sco
|
|
|
29705
29835
|
// src/core/reference/validate-generated-markdown-links.ts
|
|
29706
29836
|
init_path_helpers();
|
|
29707
29837
|
init_link_rebaser_helpers();
|
|
29838
|
+
init_protected_ranges();
|
|
29708
29839
|
|
|
29709
29840
|
// src/utils/output/color.ts
|
|
29710
29841
|
function noColorRequested() {
|
|
@@ -29787,7 +29918,7 @@ var logger = {
|
|
|
29787
29918
|
|
|
29788
29919
|
// src/core/reference/validate-generated-markdown-links.ts
|
|
29789
29920
|
var INLINE_MD_LINK = /!?\[[^\]]*\]\(([^)]+)\)/g;
|
|
29790
|
-
var REF_LINK_DEF = /^\s*\[[^\]\n]+\]:\s*(?:<([^>\n]*)>|(\S+))/gm;
|
|
29921
|
+
var REF_LINK_DEF = /^\s*\[(?!\^)[^\]\n]+\]:\s*(?:<([^>\n]*)>|(\S+))/gm;
|
|
29791
29922
|
function isMarkdownLikeOutput(relativePath) {
|
|
29792
29923
|
return relativePath.endsWith(".md") || relativePath.endsWith(".mdc");
|
|
29793
29924
|
}
|
|
@@ -29920,7 +30051,7 @@ function findBrokenMarkdownLinks(results, projectRoot) {
|
|
|
29920
30051
|
projectRoot,
|
|
29921
30052
|
pathApi(projectRoot).join(projectRoot, result2.path)
|
|
29922
30053
|
);
|
|
29923
|
-
const protectedR = protectedRanges(result2.content);
|
|
30054
|
+
const protectedR = [...protectedRanges(result2.content), ...inlineCodeRanges(result2.content)];
|
|
29924
30055
|
const visitDestination = (raw, matchIndex) => {
|
|
29925
30056
|
if (isOffsetInRanges(matchIndex, protectedR)) return;
|
|
29926
30057
|
const checked = resolveMarkdownLinkTargets(raw, projectRoot, destinationAbs);
|
|
@@ -30014,28 +30145,10 @@ function ruleNameFromSource(source) {
|
|
|
30014
30145
|
|
|
30015
30146
|
// src/core/generate/collision.ts
|
|
30016
30147
|
init_fs_text_encoding();
|
|
30148
|
+
|
|
30149
|
+
// src/core/generate/collision-agents.ts
|
|
30017
30150
|
init_target_ids();
|
|
30018
30151
|
var AGENTS_SUFFIX = "AGENTS.md";
|
|
30019
|
-
function statusRank(status) {
|
|
30020
|
-
switch (status) {
|
|
30021
|
-
case "created":
|
|
30022
|
-
return 3;
|
|
30023
|
-
case "updated":
|
|
30024
|
-
return 2;
|
|
30025
|
-
case "unchanged":
|
|
30026
|
-
return 1;
|
|
30027
|
-
case "skipped":
|
|
30028
|
-
return 0;
|
|
30029
|
-
}
|
|
30030
|
-
}
|
|
30031
|
-
function mergeDuplicateMetadata(preferred, other) {
|
|
30032
|
-
if (statusRank(other.status) <= statusRank(preferred.status)) return preferred;
|
|
30033
|
-
return {
|
|
30034
|
-
...preferred,
|
|
30035
|
-
status: other.status,
|
|
30036
|
-
currentContent: other.currentContent ?? preferred.currentContent
|
|
30037
|
-
};
|
|
30038
|
-
}
|
|
30039
30152
|
function trimmedContent(content) {
|
|
30040
30153
|
return content.trim();
|
|
30041
30154
|
}
|
|
@@ -30069,15 +30182,82 @@ function richerAgentsResult(left, right) {
|
|
|
30069
30182
|
}
|
|
30070
30183
|
return null;
|
|
30071
30184
|
}
|
|
30185
|
+
function contentLines(content) {
|
|
30186
|
+
const lines = /* @__PURE__ */ new Set();
|
|
30187
|
+
for (const line of content.split("\n")) {
|
|
30188
|
+
const trimmed = line.trim();
|
|
30189
|
+
if (trimmed !== "") lines.add(trimmed);
|
|
30190
|
+
}
|
|
30191
|
+
return lines;
|
|
30192
|
+
}
|
|
30193
|
+
function covers(outer, inner) {
|
|
30194
|
+
for (const line of inner) {
|
|
30195
|
+
if (!outer.has(line)) return false;
|
|
30196
|
+
}
|
|
30197
|
+
return true;
|
|
30198
|
+
}
|
|
30199
|
+
var EMBEDDED_RULES_BLOCK2 = /(<!-- agentsmesh:embedded-rules:start -->)([\s\S]*?)(<!-- agentsmesh:embedded-rules:end -->)/;
|
|
30200
|
+
var EMBEDDED_RULE_UNIT = /<!-- agentsmesh:embedded-rule:start [\s\S]*?<!-- agentsmesh:embedded-rule:end -->/g;
|
|
30201
|
+
function embeddedRuleUnits(block) {
|
|
30202
|
+
return [...block.matchAll(EMBEDDED_RULE_UNIT)].map((m) => m[0]);
|
|
30203
|
+
}
|
|
30204
|
+
function mergedEmbeddedRulesResult(left, right) {
|
|
30205
|
+
if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
|
|
30206
|
+
if (normalizeAgentsContent(left.content) !== normalizeAgentsContent(right.content)) return null;
|
|
30207
|
+
const leftBlock = EMBEDDED_RULES_BLOCK2.exec(left.content);
|
|
30208
|
+
const rightBlock = EMBEDDED_RULES_BLOCK2.exec(right.content);
|
|
30209
|
+
if (!leftBlock?.[2] || !rightBlock?.[2]) return null;
|
|
30210
|
+
const leftUnits = embeddedRuleUnits(leftBlock[2]);
|
|
30211
|
+
const rightUnits = embeddedRuleUnits(rightBlock[2]);
|
|
30212
|
+
if (leftUnits.length === 0 && rightUnits.length === 0) return null;
|
|
30213
|
+
const added = rightUnits.filter((unit) => !leftUnits.includes(unit));
|
|
30214
|
+
if (added.length === 0) return left;
|
|
30215
|
+
const merged = [...leftUnits, ...added].join("\n\n");
|
|
30216
|
+
const content = left.content.replace(
|
|
30217
|
+
EMBEDDED_RULES_BLOCK2,
|
|
30218
|
+
(_full, start, _inner, end) => `${start}
|
|
30219
|
+
|
|
30220
|
+
${merged}
|
|
30221
|
+
|
|
30222
|
+
${end}`
|
|
30223
|
+
);
|
|
30224
|
+
logger.warn(
|
|
30225
|
+
`${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.`
|
|
30226
|
+
);
|
|
30227
|
+
return { ...left, content };
|
|
30228
|
+
}
|
|
30072
30229
|
function richerCodexAgentsResult(left, right) {
|
|
30073
30230
|
if (!left.path.endsWith(AGENTS_SUFFIX) || left.path !== right.path) return null;
|
|
30074
30231
|
const codex = left.target === CODEX_CLI_TARGET_ID ? left : right.target === CODEX_CLI_TARGET_ID ? right : null;
|
|
30075
30232
|
const other = codex === left ? right : left;
|
|
30076
30233
|
if (!codex) return null;
|
|
30077
|
-
const
|
|
30078
|
-
const
|
|
30079
|
-
if (
|
|
30080
|
-
|
|
30234
|
+
const codexLines = contentLines(codex.content);
|
|
30235
|
+
const otherLines = contentLines(other.content);
|
|
30236
|
+
if (covers(codexLines, otherLines)) return codex;
|
|
30237
|
+
if (covers(otherLines, codexLines)) return other;
|
|
30238
|
+
return null;
|
|
30239
|
+
}
|
|
30240
|
+
|
|
30241
|
+
// src/core/generate/collision.ts
|
|
30242
|
+
function statusRank(status) {
|
|
30243
|
+
switch (status) {
|
|
30244
|
+
case "created":
|
|
30245
|
+
return 3;
|
|
30246
|
+
case "updated":
|
|
30247
|
+
return 2;
|
|
30248
|
+
case "unchanged":
|
|
30249
|
+
return 1;
|
|
30250
|
+
case "skipped":
|
|
30251
|
+
return 0;
|
|
30252
|
+
}
|
|
30253
|
+
}
|
|
30254
|
+
function mergeDuplicateMetadata(preferred, other) {
|
|
30255
|
+
if (statusRank(other.status) <= statusRank(preferred.status)) return preferred;
|
|
30256
|
+
return {
|
|
30257
|
+
...preferred,
|
|
30258
|
+
status: other.status,
|
|
30259
|
+
currentContent: other.currentContent ?? preferred.currentContent
|
|
30260
|
+
};
|
|
30081
30261
|
}
|
|
30082
30262
|
function resolveOutputCollisions(results) {
|
|
30083
30263
|
const deduped = [];
|
|
@@ -30094,6 +30274,11 @@ function resolveOutputCollisions(results) {
|
|
|
30094
30274
|
deduped[existingIdx] = richer;
|
|
30095
30275
|
continue;
|
|
30096
30276
|
}
|
|
30277
|
+
const mergedRules = mergedEmbeddedRulesResult(existing, result2);
|
|
30278
|
+
if (mergedRules) {
|
|
30279
|
+
deduped[existingIdx] = refreshResultStatus(mergedRules);
|
|
30280
|
+
continue;
|
|
30281
|
+
}
|
|
30097
30282
|
const richerCodex = richerCodexAgentsResult(existing, result2);
|
|
30098
30283
|
if (richerCodex) {
|
|
30099
30284
|
deduped[existingIdx] = richerCodex;
|
|
@@ -30659,6 +30844,14 @@ function redactUrlSecrets(message) {
|
|
|
30659
30844
|
}
|
|
30660
30845
|
);
|
|
30661
30846
|
}
|
|
30847
|
+
function stripUrlCredentials(url) {
|
|
30848
|
+
return url.replace(
|
|
30849
|
+
URL_WITH_CREDENTIALS,
|
|
30850
|
+
(_full, scheme, _userinfo, rest) => {
|
|
30851
|
+
return `${scheme}${rest}`;
|
|
30852
|
+
}
|
|
30853
|
+
);
|
|
30854
|
+
}
|
|
30662
30855
|
function gitProtocolOptIns() {
|
|
30663
30856
|
const on = (v) => v === "1" || v === "true";
|
|
30664
30857
|
return {
|
|
@@ -31057,6 +31250,7 @@ async function sweepStaleCache(cacheDir, maxAgeMs) {
|
|
|
31057
31250
|
var MAX_CACHE_KEY_LENGTH = 80;
|
|
31058
31251
|
var CACHE_KEY_HASH_LENGTH = 12;
|
|
31059
31252
|
function buildCacheKey(provider, identifier, ref) {
|
|
31253
|
+
identifier = stripUrlCredentials(identifier);
|
|
31060
31254
|
const safe = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_").replace(/^\.+/, "_");
|
|
31061
31255
|
const [org, repo] = provider === "github" ? identifier.split("/", 2) : [];
|
|
31062
31256
|
const readable = org && repo ? `${safe(org)}--${safe(repo)}--${safe(ref)}` : `${safe(provider)}__${safe(identifier)}__${safe(ref)}`;
|
|
@@ -34329,8 +34523,59 @@ async function diffOutputChecksums(rootBase, lockOutputs) {
|
|
|
34329
34523
|
|
|
34330
34524
|
// src/core/generate/stale-cleanup.ts
|
|
34331
34525
|
init_fs();
|
|
34526
|
+
async function canonicalizePath(path) {
|
|
34527
|
+
try {
|
|
34528
|
+
return await realpath(path);
|
|
34529
|
+
} catch (error) {
|
|
34530
|
+
if (error.code !== "ENOENT") throw error;
|
|
34531
|
+
const parent = dirname(path);
|
|
34532
|
+
if (parent === path) return resolve(path);
|
|
34533
|
+
return join(await canonicalizePath(parent), basename(path));
|
|
34534
|
+
}
|
|
34535
|
+
}
|
|
34536
|
+
function isPathInside(target34, root) {
|
|
34537
|
+
return target34 === root || target34.startsWith(root.endsWith(sep) ? root : `${root}${sep}`);
|
|
34538
|
+
}
|
|
34539
|
+
var display = (path) => path.replaceAll("\\", "/");
|
|
34540
|
+
async function assertPathInsideRoot(root, target34) {
|
|
34541
|
+
const rootAbs = resolve(root);
|
|
34542
|
+
const targetAbs = resolve(target34);
|
|
34543
|
+
if (!isPathInside(targetAbs, rootAbs)) {
|
|
34544
|
+
throw new Error(`Unsafe filesystem path: ${display(target34)} is outside ${display(rootAbs)}`);
|
|
34545
|
+
}
|
|
34546
|
+
let realTarget;
|
|
34547
|
+
let realRoot;
|
|
34548
|
+
try {
|
|
34549
|
+
[realTarget, realRoot] = await Promise.all([
|
|
34550
|
+
canonicalizePath(targetAbs),
|
|
34551
|
+
canonicalizePath(rootAbs)
|
|
34552
|
+
]);
|
|
34553
|
+
} catch (cause) {
|
|
34554
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
34555
|
+
throw new Error(
|
|
34556
|
+
`Unsafe filesystem path: ${display(target34)} could not be resolved (${detail})`,
|
|
34557
|
+
{ cause }
|
|
34558
|
+
);
|
|
34559
|
+
}
|
|
34560
|
+
if (isPathInside(realTarget, realRoot)) return;
|
|
34561
|
+
throw new Error(
|
|
34562
|
+
`Unsafe filesystem path: ${display(target34)} resolves to ${display(realTarget)} outside ${display(realRoot)}`
|
|
34563
|
+
);
|
|
34564
|
+
}
|
|
34565
|
+
|
|
34566
|
+
// src/core/generate/stale-cleanup.ts
|
|
34332
34567
|
init_builtin_targets();
|
|
34333
34568
|
init_registry();
|
|
34569
|
+
init_builtin_targets();
|
|
34570
|
+
function retainedDirs(inactiveTargets, scope) {
|
|
34571
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
34572
|
+
for (const target34 of inactiveTargets) {
|
|
34573
|
+
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) dirs.add(dir);
|
|
34574
|
+
}
|
|
34575
|
+
return dirs;
|
|
34576
|
+
}
|
|
34577
|
+
|
|
34578
|
+
// src/core/generate/stale-cleanup.ts
|
|
34334
34579
|
async function listFiles2(root, base = root) {
|
|
34335
34580
|
const entries = await readdir(root, { withFileTypes: true });
|
|
34336
34581
|
const files = [];
|
|
@@ -34344,13 +34589,6 @@ async function listFiles2(root, base = root) {
|
|
|
34344
34589
|
}
|
|
34345
34590
|
return files;
|
|
34346
34591
|
}
|
|
34347
|
-
function retainedDirs(inactiveTargets, scope) {
|
|
34348
|
-
const dirs = /* @__PURE__ */ new Set();
|
|
34349
|
-
for (const target34 of inactiveTargets) {
|
|
34350
|
-
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) dirs.add(dir);
|
|
34351
|
-
}
|
|
34352
|
-
return dirs;
|
|
34353
|
-
}
|
|
34354
34592
|
function primaryEmitted(target34, scope, expected) {
|
|
34355
34593
|
const descriptor34 = getBuiltinTargetDefinition(target34) ?? getDescriptor(target34);
|
|
34356
34594
|
const primary = getTargetLayout(target34, scope)?.rootInstructionPath ?? descriptor34?.generators.primaryRootInstructionPath;
|
|
@@ -34377,6 +34615,7 @@ async function findStaleGeneratedOutputs(args) {
|
|
|
34377
34615
|
for (const dir of managed.dirs) {
|
|
34378
34616
|
if (retained.has(dir)) continue;
|
|
34379
34617
|
const absDir = join(args.projectRoot, dir);
|
|
34618
|
+
await assertPathInsideRoot(args.projectRoot, absDir);
|
|
34380
34619
|
if (!await exists(absDir)) continue;
|
|
34381
34620
|
for (const file of await listFiles2(absDir)) {
|
|
34382
34621
|
const relPath = `${dir}/${file}`.replace(/\/+/g, "/");
|
|
@@ -34388,6 +34627,7 @@ async function findStaleGeneratedOutputs(args) {
|
|
|
34388
34627
|
const found = [];
|
|
34389
34628
|
for (const relPath of stale) {
|
|
34390
34629
|
if (expected.has(relPath) || coOwned.has(relPath)) continue;
|
|
34630
|
+
await assertPathInsideRoot(args.projectRoot, dirname(join(args.projectRoot, relPath)));
|
|
34391
34631
|
if (await exists(join(args.projectRoot, relPath))) found.push(relPath);
|
|
34392
34632
|
}
|
|
34393
34633
|
return found.sort();
|
|
@@ -34401,6 +34641,7 @@ async function findUntrackedManagedDirFiles(args) {
|
|
|
34401
34641
|
for (const dir of getTargetManagedOutputs(target34, scope)?.dirs ?? []) {
|
|
34402
34642
|
if (retained.has(dir)) continue;
|
|
34403
34643
|
const absDir = join(args.projectRoot, dir);
|
|
34644
|
+
await assertPathInsideRoot(args.projectRoot, absDir);
|
|
34404
34645
|
if (!await exists(absDir)) continue;
|
|
34405
34646
|
for (const file of await listFiles2(absDir)) {
|
|
34406
34647
|
const relPath = `${dir}/${file}`.replace(/\/+/g, "/");
|