@lousy-agents/lint 5.14.10 → 5.15.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/dist/116.js CHANGED
@@ -2,9 +2,6 @@ export const __rspack_esm_id = 116;
2
2
  export const __rspack_esm_ids = [116];
3
3
  export const __webpack_modules__ = {
4
4
  8711(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
- __webpack_require__.d(__webpack_exports__, {
6
- prompt: () => (prompt)
7
- });
8
5
  /* import */ var node_util__rspack_import_0 = __webpack_require__(7975);
9
6
  /* import */ var node_process__rspack_import_1 = __webpack_require__(1708);
10
7
  /* import */ var node_readline__rspack_import_2 = __webpack_require__(481);
@@ -290,6 +287,10 @@ async function prompt(message, opts = {}) {
290
287
 
291
288
 
292
289
 
290
+ __webpack_require__.d(__webpack_exports__, {
291
+ prompt: () => (prompt)
292
+ });
293
+
293
294
 
294
295
  },
295
296
 
package/dist/316.js CHANGED
@@ -4,9 +4,6 @@ export const __webpack_modules__ = {
4
4
  5375(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
5
  var zlib__rspack_import_11_namespace_cache;
6
6
  __webpack_require__.r(__webpack_exports__);
7
- __webpack_require__.d(__webpack_exports__, {
8
- t: () => (ce)
9
- });
10
7
  /* import */ var _rolldown_runtime_mjs__rspack_import_14 = __webpack_require__(421);
11
8
  /* import */ var node_fs__rspack_import_0 = __webpack_require__(3024);
12
9
  /* import */ var node_fs_promises__rspack_import_1 = __webpack_require__(1455);
@@ -2954,6 +2951,10 @@ var Da = (e) => {
2954
2951
  };
2955
2952
 
2956
2953
 
2954
+ __webpack_require__.d(__webpack_exports__, {
2955
+ t: () => (ce)
2956
+ });
2957
+
2957
2958
 
2958
2959
  },
2959
2960
 
package/dist/475.js CHANGED
@@ -1729,10 +1729,10 @@ class FSWatcher extends external_node_events_.EventEmitter {
1729
1729
  const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
1730
1730
  let stream = readdirp(root, options);
1731
1731
  this._streams.add(stream);
1732
- stream.once(STR_CLOSE, () => {
1732
+ stream.once((/* inlined export .STR_CLOSE */"close"), () => {
1733
1733
  stream = undefined;
1734
1734
  });
1735
- stream.once(STR_END, () => {
1735
+ stream.once((/* inlined export .STR_END */"end"), () => {
1736
1736
  if (stream) {
1737
1737
  this._streams.delete(stream);
1738
1738
  stream = undefined;
package/dist/653.js CHANGED
@@ -3,13 +3,6 @@ export const __rspack_esm_ids = [653];
3
3
  export const __webpack_modules__ = {
4
4
  292(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
5
  __webpack_require__.r(__webpack_exports__);
6
- __webpack_require__.d(__webpack_exports__, {
7
- a: () => (y),
8
- i: () => (S),
9
- n: () => (ne),
10
- r: () => (C),
11
- t: () => (oe)
12
- });
13
6
  /* import */ var _rolldown_runtime_mjs__rspack_import_8 = __webpack_require__(421);
14
7
  /* import */ var node_module__rspack_import_0 = __webpack_require__(8995);
15
8
  /* import */ var node_fs__rspack_import_1 = __webpack_require__(3024);
@@ -689,12 +682,18 @@ async function fe(e = {}) {
689
682
  }
690
683
 
691
684
 
685
+ __webpack_require__.d(__webpack_exports__, {
686
+ t: () => (oe)
687
+ }, {
688
+ a: y,
689
+ i: S,
690
+ n: ne,
691
+ r: C
692
+ });
693
+
692
694
 
693
695
  },
694
696
  421(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
695
- __webpack_require__.d(__webpack_exports__, {
696
- t: () => (__exportAll)
697
- });
698
697
  /* import */ var node_module__rspack_import_0 = __webpack_require__(8995);
699
698
 
700
699
  //#region \0rolldown/runtime.js
@@ -711,6 +710,10 @@ var __exportAll = (all, no_symbols) => {
711
710
  //#endregion
712
711
 
713
712
 
713
+ __webpack_require__.d(__webpack_exports__, {
714
+ t: () => (__exportAll)
715
+ });
716
+
714
717
 
715
718
  },
716
719
  8900(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
package/dist/index.js CHANGED
@@ -566,7 +566,7 @@ module.exports = webpackEmptyAsyncContext;
566
566
 
567
567
 
568
568
  },
569
- 4403(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
569
+ 9884(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
570
570
 
571
571
  // EXPORTS
572
572
  __webpack_require__.d(__webpack_exports__, {
@@ -1302,6 +1302,191 @@ function guardedRmSync(params) {
1302
1302
  }), { verifyAfter: params.verifyAfter });
1303
1303
  }
1304
1304
 
1305
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/deny-mutations.js
1306
+
1307
+
1308
+
1309
+
1310
+ async function pathExists(filePath) {
1311
+ try {
1312
+ await promises_.lstat(filePath);
1313
+ return true;
1314
+ }
1315
+ catch (err) {
1316
+ if (!path_isNotFoundPathError(err)) {
1317
+ throw err;
1318
+ }
1319
+ return false;
1320
+ }
1321
+ }
1322
+ async function resolvePathViaExistingAncestor(targetPath) {
1323
+ const normalized = external_node_path_.resolve(targetPath);
1324
+ let cursor = normalized;
1325
+ const missingSuffix = [];
1326
+ while (external_node_path_.dirname(cursor) !== cursor && !(await pathExists(cursor))) {
1327
+ missingSuffix.unshift(external_node_path_.basename(cursor));
1328
+ cursor = external_node_path_.dirname(cursor);
1329
+ }
1330
+ if (!(await pathExists(cursor))) {
1331
+ return normalized;
1332
+ }
1333
+ try {
1334
+ const resolvedAncestor = external_node_path_.resolve(await promises_.realpath(cursor));
1335
+ return missingSuffix.length === 0
1336
+ ? resolvedAncestor
1337
+ : external_node_path_.resolve(resolvedAncestor, ...missingSuffix);
1338
+ }
1339
+ catch {
1340
+ return normalized;
1341
+ }
1342
+ }
1343
+ async function comparablePaths(rawPath) {
1344
+ path_assertNoNulPathInput(rawPath, "path contains a NUL byte");
1345
+ const resolved = external_node_path_.resolve(rawPath);
1346
+ return new Set([resolved, await resolvePathViaExistingAncestor(resolved)]);
1347
+ }
1348
+ function isSamePath(left, right) {
1349
+ return path_isPathInside(left, right) && path_isPathInside(right, left);
1350
+ }
1351
+ function hasPolicyEntries(policy) {
1352
+ return Boolean(policy?.paths?.length || policy?.prefixes?.length);
1353
+ }
1354
+ function policyPathEntries(entries) {
1355
+ const paths = [];
1356
+ for (const entry of entries ?? []) {
1357
+ if (entry.length === 0) {
1358
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be non-empty");
1359
+ }
1360
+ path_assertNoNulPathInput(entry, "deny mutation path contains a NUL byte");
1361
+ if (!external_node_path_.isAbsolute(entry)) {
1362
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be absolute");
1363
+ }
1364
+ paths.push(entry);
1365
+ }
1366
+ return paths;
1367
+ }
1368
+ async function assertMutationNotDenied(filePath, policy, options = {}) {
1369
+ if (!hasPolicyEntries(policy)) {
1370
+ return;
1371
+ }
1372
+ const targetPaths = await comparablePaths(filePath);
1373
+ for (const deniedPath of policyPathEntries(policy.paths)) {
1374
+ const deniedPaths = await comparablePaths(deniedPath);
1375
+ for (const target of targetPaths) {
1376
+ for (const denied of deniedPaths) {
1377
+ if (isSamePath(denied, target) ||
1378
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
1379
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
1380
+ }
1381
+ }
1382
+ }
1383
+ }
1384
+ for (const deniedPrefix of policyPathEntries(policy.prefixes)) {
1385
+ const deniedPaths = await comparablePaths(deniedPrefix);
1386
+ for (const target of targetPaths) {
1387
+ for (const denied of deniedPaths) {
1388
+ if (path_isPathInside(denied, target) ||
1389
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
1390
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
1391
+ }
1392
+ }
1393
+ }
1394
+ }
1395
+ }
1396
+ function mergeDenyMutationPolicies(defaultPolicy, callPolicy) {
1397
+ if (!defaultPolicy) {
1398
+ return callPolicy;
1399
+ }
1400
+ if (!callPolicy) {
1401
+ return defaultPolicy;
1402
+ }
1403
+ return {
1404
+ paths: [...(defaultPolicy.paths ?? []), ...(callPolicy.paths ?? [])],
1405
+ prefixes: [...(defaultPolicy.prefixes ?? []), ...(callPolicy.prefixes ?? [])],
1406
+ };
1407
+ }
1408
+
1409
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/opened-realpath.js
1410
+
1411
+
1412
+
1413
+
1414
+
1415
+ async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
1416
+ const handleStat = await handle.stat();
1417
+ const fdCandidates = process.platform === "linux"
1418
+ ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
1419
+ : process.platform === "win32"
1420
+ ? []
1421
+ : [`/dev/fd/${handle.fd}`];
1422
+ for (const fdPath of fdCandidates) {
1423
+ try {
1424
+ const fdRealPath = await promises_.realpath(fdPath);
1425
+ const fdRealStat = await promises_.stat(fdRealPath);
1426
+ if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
1427
+ return fdRealPath;
1428
+ }
1429
+ }
1430
+ catch {
1431
+ // try next fd path
1432
+ }
1433
+ }
1434
+ try {
1435
+ const ioRealPath = await promises_.realpath(ioPath);
1436
+ const ioRealStat = await promises_.stat(ioRealPath);
1437
+ if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
1438
+ return ioRealPath;
1439
+ }
1440
+ }
1441
+ catch (err) {
1442
+ if (!path_isNotFoundPathError(err)) {
1443
+ throw err;
1444
+ }
1445
+ }
1446
+ const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
1447
+ if (parentResolved) {
1448
+ return parentResolved;
1449
+ }
1450
+ throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
1451
+ }
1452
+ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
1453
+ let parentReal;
1454
+ try {
1455
+ parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
1456
+ }
1457
+ catch (err) {
1458
+ if (path_isNotFoundPathError(err)) {
1459
+ return null;
1460
+ }
1461
+ throw err;
1462
+ }
1463
+ let entries;
1464
+ try {
1465
+ entries = await promises_.readdir(parentReal);
1466
+ }
1467
+ catch (err) {
1468
+ if (path_isNotFoundPathError(err)) {
1469
+ return null;
1470
+ }
1471
+ throw err;
1472
+ }
1473
+ for (const entry of entries.toSorted()) {
1474
+ const candidatePath = external_node_path_.join(parentReal, entry);
1475
+ try {
1476
+ const candidateStat = await promises_.lstat(candidatePath);
1477
+ if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
1478
+ return await promises_.realpath(candidatePath);
1479
+ }
1480
+ }
1481
+ catch (err) {
1482
+ if (!path_isNotFoundPathError(err)) {
1483
+ throw err;
1484
+ }
1485
+ }
1486
+ }
1487
+ return null;
1488
+ }
1489
+
1305
1490
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/pinned-python-config.js
1306
1491
  let overrideConfig = {};
1307
1492
  function parseMode(value) {
@@ -2148,7 +2333,7 @@ async function runPinnedWriteHelper(params) {
2148
2333
  relativeParentPath: params.relativeParentPath,
2149
2334
  });
2150
2335
  if (getFsSafePythonConfig().mode === "off") {
2151
- return await runPinnedWriteFallbackOrThrow(params);
2336
+ return await runPinnedWriteFallback(params);
2152
2337
  }
2153
2338
  if (params.input.kind === "stream") {
2154
2339
  try {
@@ -2156,7 +2341,7 @@ async function runPinnedWriteHelper(params) {
2156
2341
  }
2157
2342
  catch (error) {
2158
2343
  if (canFallbackFromPythonError(error)) {
2159
- return await runPinnedWriteFallbackOrThrow(params, error);
2344
+ return await runPinnedWriteFallback(params);
2160
2345
  }
2161
2346
  throw error;
2162
2347
  }
@@ -2180,7 +2365,7 @@ async function runPinnedWriteHelper(params) {
2180
2365
  }
2181
2366
  catch (error) {
2182
2367
  if (canFallbackFromPythonError(error)) {
2183
- return await runPinnedWriteFallbackOrThrow(params, error);
2368
+ return await runPinnedWriteFallback(params);
2184
2369
  }
2185
2370
  throw error;
2186
2371
  }
@@ -2207,12 +2392,6 @@ async function runPinnedCopyHelper(params) {
2207
2392
  },
2208
2393
  });
2209
2394
  }
2210
- async function runPinnedWriteFallbackOrThrow(params, cause) {
2211
- if (process.platform !== "win32") {
2212
- throw new errors_FsSafeError("helper-unavailable", "Python helper is required for pinned writes on this platform", { cause });
2213
- }
2214
- return await runPinnedWriteFallback(params);
2215
- }
2216
2395
  async function runPinnedWriteFallback(params) {
2217
2396
  const parentPath = params.relativeParentPath
2218
2397
  ? external_node_path_.join(params.rootPath, ...params.relativeParentPath.split("/"))
@@ -2335,7 +2514,7 @@ async function resolveRootPath(params) {
2335
2514
  const absolutePath = external_node_path_.resolve(params.absolutePath);
2336
2515
  const rootCanonicalPath = params.rootCanonicalPath
2337
2516
  ? external_node_path_.resolve(params.rootCanonicalPath)
2338
- : await resolvePathViaExistingAncestor(rootPath);
2517
+ : await root_path_resolvePathViaExistingAncestor(rootPath);
2339
2518
  const context = createBoundaryResolutionContext({
2340
2519
  resolveParams: params,
2341
2520
  rootPath,
@@ -2704,7 +2883,7 @@ async function resolveOutsideLexicalCanonicalPathAsync(params) {
2704
2883
  if (path_isPathInside(params.rootPath, params.absolutePath)) {
2705
2884
  return undefined;
2706
2885
  }
2707
- return await resolvePathViaExistingAncestor(params.absolutePath);
2886
+ return await root_path_resolvePathViaExistingAncestor(params.absolutePath);
2708
2887
  }
2709
2888
  function resolveOutsideLexicalCanonicalPathSync(params) {
2710
2889
  if (isPathInside(params.rootPath, params.absolutePath)) {
@@ -2751,11 +2930,11 @@ function buildResolvedRootPath(params) {
2751
2930
  kind: params.kind.kind,
2752
2931
  };
2753
2932
  }
2754
- async function resolvePathViaExistingAncestor(targetPath) {
2933
+ async function root_path_resolvePathViaExistingAncestor(targetPath) {
2755
2934
  const normalized = external_node_path_.resolve(targetPath);
2756
2935
  let cursor = normalized;
2757
2936
  const missingSuffix = [];
2758
- while (!isFilesystemRoot(cursor) && !(await pathExists(cursor))) {
2937
+ while (!isFilesystemRoot(cursor) && !(await root_path_pathExists(cursor))) {
2759
2938
  missingSuffix.unshift(external_node_path_.basename(cursor));
2760
2939
  const parent = external_node_path_.dirname(cursor);
2761
2940
  if (parent === cursor) {
@@ -2763,7 +2942,7 @@ async function resolvePathViaExistingAncestor(targetPath) {
2763
2942
  }
2764
2943
  cursor = parent;
2765
2944
  }
2766
- if (!(await pathExists(cursor))) {
2945
+ if (!(await root_path_pathExists(cursor))) {
2767
2946
  return normalized;
2768
2947
  }
2769
2948
  try {
@@ -2875,7 +3054,7 @@ function shortPath(value) {
2875
3054
  function isFilesystemRoot(candidate) {
2876
3055
  return external_node_path_.parse(candidate).root === candidate;
2877
3056
  }
2878
- async function pathExists(targetPath) {
3057
+ async function root_path_pathExists(targetPath) {
2879
3058
  try {
2880
3059
  await promises_.lstat(targetPath);
2881
3060
  return true;
@@ -2897,7 +3076,7 @@ async function resolveSymlinkHopPath(symlinkPath) {
2897
3076
  }
2898
3077
  const linkTarget = await promises_.readlink(symlinkPath);
2899
3078
  const linkAbsolute = external_node_path_.resolve(external_node_path_.dirname(symlinkPath), linkTarget);
2900
- return resolvePathViaExistingAncestor(linkAbsolute);
3079
+ return root_path_resolvePathViaExistingAncestor(linkAbsolute);
2901
3080
  }
2902
3081
  }
2903
3082
  function resolveSymlinkHopPathSync(symlinkPath) {
@@ -2966,6 +3145,23 @@ function path_policy_shortPath(value) {
2966
3145
  return value;
2967
3146
  }
2968
3147
 
3148
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/read-opened-file.js
3149
+
3150
+ async function read_opened_file_readOpenedFileSafely(params) {
3151
+ if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
3152
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
3153
+ }
3154
+ const buffer = await params.opened.handle.readFile();
3155
+ if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
3156
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
3157
+ }
3158
+ return {
3159
+ buffer,
3160
+ realPath: params.opened.realPath,
3161
+ stat: params.opened.stat,
3162
+ };
3163
+ }
3164
+
2969
3165
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/path-stat.js
2970
3166
  function pathStatFromStats(stat) {
2971
3167
  return {
@@ -3293,6 +3489,10 @@ async function serializePathWrite(key, run) {
3293
3489
 
3294
3490
 
3295
3491
 
3492
+
3493
+
3494
+
3495
+
3296
3496
 
3297
3497
 
3298
3498
 
@@ -3491,6 +3691,7 @@ class RootHandle {
3491
3691
  mkdir: this.defaults.mkdir,
3492
3692
  mode: this.defaults.mode,
3493
3693
  ...options,
3694
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3494
3695
  append: writeMode === "append",
3495
3696
  truncateExisting: writeMode === "replace",
3496
3697
  });
@@ -3502,18 +3703,29 @@ class RootHandle {
3502
3703
  mkdir: this.defaults.mkdir,
3503
3704
  mode: this.defaults.mode,
3504
3705
  ...options,
3706
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3505
3707
  });
3506
3708
  }
3507
- async remove(relativePath) {
3709
+ async remove(relativePath, options = {}) {
3508
3710
  assertValidRootRelativePath(relativePath);
3509
- await removePathInRoot(this.context, relativePath);
3711
+ await removePathInRoot(this.context, {
3712
+ relativePath,
3713
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3714
+ });
3510
3715
  }
3511
- async mkdir(relativePath) {
3716
+ async mkdir(relativePath, options = {}) {
3512
3717
  assertValidRootRelativePath(relativePath);
3513
- await mkdirPathInRoot(this.context, { relativePath });
3718
+ await mkdirPathInRoot(this.context, {
3719
+ relativePath,
3720
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3721
+ });
3514
3722
  }
3515
- async ensureRoot() {
3516
- await mkdirPathInRoot(this.context, { relativePath: "", allowRoot: true });
3723
+ async ensureRoot(options = {}) {
3724
+ await mkdirPathInRoot(this.context, {
3725
+ relativePath: "",
3726
+ allowRoot: true,
3727
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3728
+ });
3517
3729
  }
3518
3730
  async write(relativePath, data, options = {}) {
3519
3731
  await writeFileInRoot(this.context, {
@@ -3522,6 +3734,7 @@ class RootHandle {
3522
3734
  mkdir: this.defaults.mkdir,
3523
3735
  mode: this.defaults.mode,
3524
3736
  ...options,
3737
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3525
3738
  });
3526
3739
  }
3527
3740
  async create(relativePath, data, options = {}) {
@@ -3531,6 +3744,7 @@ class RootHandle {
3531
3744
  mkdir: this.defaults.mkdir,
3532
3745
  mode: this.defaults.mode,
3533
3746
  ...options,
3747
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3534
3748
  overwrite: false,
3535
3749
  });
3536
3750
  }
@@ -3553,6 +3767,7 @@ class RootHandle {
3553
3767
  mkdir: this.defaults.mkdir,
3554
3768
  mode: this.defaults.mode,
3555
3769
  ...options,
3770
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
3556
3771
  });
3557
3772
  }
3558
3773
  async exists(relativePath) {
@@ -3596,6 +3811,12 @@ class RootHandle {
3596
3811
  async move(fromRelative, toRelative, options = {}) {
3597
3812
  assertValidRootRelativePath(fromRelative);
3598
3813
  assertValidRootRelativePath(toRelative);
3814
+ const denyMutations = mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations);
3815
+ await assertMoveMutationAllowed(this.context, {
3816
+ fromRelative,
3817
+ toRelative,
3818
+ denyMutations,
3819
+ });
3599
3820
  try {
3600
3821
  await runPinnedHelper("rename", this.rootReal, {
3601
3822
  from: fromRelative,
@@ -3607,6 +3828,7 @@ class RootHandle {
3607
3828
  if (canFallbackFromPythonError(error)) {
3608
3829
  await movePathFallback(this.context, {
3609
3830
  fromRelative,
3831
+ denyMutations,
3610
3832
  overwrite: options.overwrite ?? false,
3611
3833
  toRelative,
3612
3834
  });
@@ -3655,7 +3877,7 @@ async function openFileInRoot(root, params) {
3655
3877
  async function readFileInRoot(root, params) {
3656
3878
  const opened = await openFileInRoot(root, params);
3657
3879
  try {
3658
- return await readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
3880
+ return await read_opened_file_readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
3659
3881
  }
3660
3882
  finally {
3661
3883
  await opened.handle.close().catch(() => { });
@@ -3688,20 +3910,6 @@ async function openLocalFileSafely(params) {
3688
3910
  assertNoNulPathInput(params.filePath, "file path contains a NUL byte");
3689
3911
  return await openVerifiedLocalFile(params.filePath);
3690
3912
  }
3691
- async function readOpenedFileSafely(params) {
3692
- if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
3693
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
3694
- }
3695
- const buffer = await params.opened.handle.readFile();
3696
- if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
3697
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
3698
- }
3699
- return {
3700
- buffer,
3701
- realPath: params.opened.realPath,
3702
- stat: params.opened.stat,
3703
- };
3704
- }
3705
3913
  function emitWriteBoundaryWarning(reason) {
3706
3914
  logWarn(`security: fs-safe write boundary warning (${reason})`);
3707
3915
  }
@@ -3742,82 +3950,9 @@ async function verifyAtomicWriteResult(params) {
3742
3950
  await opened.handle.close().catch(() => { });
3743
3951
  }
3744
3952
  }
3745
- async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
3746
- const handleStat = await handle.stat();
3747
- const fdCandidates = process.platform === "linux"
3748
- ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
3749
- : process.platform === "win32"
3750
- ? []
3751
- : [`/dev/fd/${handle.fd}`];
3752
- for (const fdPath of fdCandidates) {
3753
- try {
3754
- const fdRealPath = await promises_.realpath(fdPath);
3755
- const fdRealStat = await promises_.stat(fdRealPath);
3756
- if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
3757
- return fdRealPath;
3758
- }
3759
- }
3760
- catch {
3761
- // try next fd path
3762
- }
3763
- }
3764
- try {
3765
- const ioRealPath = await promises_.realpath(ioPath);
3766
- const ioRealStat = await promises_.stat(ioRealPath);
3767
- if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
3768
- return ioRealPath;
3769
- }
3770
- }
3771
- catch (err) {
3772
- if (!path_isNotFoundPathError(err)) {
3773
- throw err;
3774
- }
3775
- }
3776
- const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
3777
- if (parentResolved) {
3778
- return parentResolved;
3779
- }
3780
- throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
3781
- }
3782
- async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
3783
- let parentReal;
3784
- try {
3785
- parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
3786
- }
3787
- catch (err) {
3788
- if (path_isNotFoundPathError(err)) {
3789
- return null;
3790
- }
3791
- throw err;
3792
- }
3793
- let entries;
3794
- try {
3795
- entries = await promises_.readdir(parentReal);
3796
- }
3797
- catch (err) {
3798
- if (path_isNotFoundPathError(err)) {
3799
- return null;
3800
- }
3801
- throw err;
3802
- }
3803
- for (const entry of entries.toSorted()) {
3804
- const candidatePath = external_node_path_.join(parentReal, entry);
3805
- try {
3806
- const candidateStat = await promises_.lstat(candidatePath);
3807
- if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
3808
- return await promises_.realpath(candidatePath);
3809
- }
3810
- }
3811
- catch (err) {
3812
- if (!path_isNotFoundPathError(err)) {
3813
- throw err;
3814
- }
3815
- }
3816
- }
3817
- return null;
3818
- }
3819
3953
  async function openWritableFileInRoot(root, params) {
3820
3954
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, params.relativePath);
3955
+ await assertMutationNotDenied(resolved, params.denyMutations);
3821
3956
  try {
3822
3957
  await assertNoPathAliasEscape({
3823
3958
  absolutePath: resolved,
@@ -3944,6 +4079,7 @@ async function appendFileInRoot(root, params) {
3944
4079
  relativePath: params.relativePath,
3945
4080
  mkdir: params.mkdir,
3946
4081
  mode: params.mode,
4082
+ denyMutations: params.denyMutations,
3947
4083
  truncateExisting: false,
3948
4084
  append: true,
3949
4085
  });
@@ -3971,8 +4107,8 @@ async function appendFileInRoot(root, params) {
3971
4107
  await target.handle.close().catch(() => { });
3972
4108
  }
3973
4109
  }
3974
- async function removePathInRoot(root, relativePath) {
3975
- const resolved = await resolvePinnedRemovePathInRoot(root, relativePath);
4110
+ async function removePathInRoot(root, params) {
4111
+ const resolved = await resolvePinnedRemovePathInRoot(root, params.relativePath, params.denyMutations);
3976
4112
  if (process.platform === "win32") {
3977
4113
  await removePathFallback(resolved);
3978
4114
  return;
@@ -4020,7 +4156,7 @@ async function writeFileInRoot(root, params) {
4020
4156
  });
4021
4157
  return;
4022
4158
  }
4023
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
4159
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
4024
4160
  await serializePathWrite(pinned.targetPath, async () => {
4025
4161
  let identity;
4026
4162
  try {
@@ -4076,7 +4212,7 @@ async function copyFileInRoot(root, params) {
4076
4212
  });
4077
4213
  return;
4078
4214
  }
4079
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
4215
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
4080
4216
  await serializePathWrite(pinned.targetPath, async () => {
4081
4217
  let identity;
4082
4218
  try {
@@ -4120,8 +4256,9 @@ async function copyFileInRoot(root, params) {
4120
4256
  await source.handle.close().catch(() => { });
4121
4257
  }
4122
4258
  }
4123
- async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode) {
4259
+ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode, denyMutations) {
4124
4260
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, relativePath);
4261
+ await assertMutationNotDenied(resolved, denyMutations);
4125
4262
  try {
4126
4263
  await assertNoPathAliasEscape({
4127
4264
  absolutePath: resolved,
@@ -4178,12 +4315,16 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode)
4178
4315
  async function resolvePinnedPathInRoot(root, params) {
4179
4316
  return await resolvePinnedOperationPathInRoot(root, {
4180
4317
  allowRoot: params.allowRoot,
4318
+ denyMutations: params.denyMutations,
4319
+ protectDenyMutationAncestors: false,
4181
4320
  relativePath: params.relativePath,
4182
4321
  policy: PATH_ALIAS_POLICIES.strict,
4183
4322
  });
4184
4323
  }
4185
- async function resolvePinnedRemovePathInRoot(root, relativePath) {
4324
+ async function resolvePinnedRemovePathInRoot(root, relativePath, denyMutations) {
4186
4325
  return await resolvePinnedOperationPathInRoot(root, {
4326
+ denyMutations,
4327
+ protectDenyMutationAncestors: true,
4187
4328
  relativePath,
4188
4329
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
4189
4330
  });
@@ -4195,6 +4336,7 @@ async function resolvePinnedOperationPathInRoot(root, params) {
4195
4336
  });
4196
4337
  const relativeResolved = external_node_path_.relative(resolved.rootReal, resolved.canonicalPath);
4197
4338
  if ((relativeResolved === "" || relativeResolved === ".") && params.allowRoot === true) {
4339
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations);
4198
4340
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix: "" };
4199
4341
  }
4200
4342
  const firstSegment = relativeResolved.split(external_node_path_.sep)[0];
@@ -4208,6 +4350,9 @@ async function resolvePinnedOperationPathInRoot(root, params) {
4208
4350
  if (!path_isPathInside(resolved.rootWithSep, resolved.canonicalPath)) {
4209
4351
  throw new errors_FsSafeError("outside-workspace", "file is outside workspace root");
4210
4352
  }
4353
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
4354
+ protectAncestors: params.protectDenyMutationAncestors,
4355
+ });
4211
4356
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
4212
4357
  }
4213
4358
  async function resolvePinnedRootPathInRoot(root, params) {
@@ -4285,13 +4430,21 @@ async function listPathFallback(root, relativePath, withFileTypes) {
4285
4430
  throw error;
4286
4431
  }
4287
4432
  }
4433
+ async function assertMoveMutationAllowed(root, params) {
4434
+ const source = await resolvePathInRoot(root, params.fromRelative);
4435
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
4436
+ const target = await resolvePathInRoot(root, params.toRelative);
4437
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
4438
+ }
4288
4439
  async function movePathFallback(root, params) {
4289
4440
  const source = await resolvePathInRoot(root, params.fromRelative);
4441
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
4290
4442
  await resolvePinnedRootPathInRoot(root, {
4291
4443
  relativePath: params.fromRelative,
4292
4444
  policy: PATH_ALIAS_POLICIES.strict,
4293
4445
  });
4294
4446
  const target = await resolvePathInRoot(root, params.toRelative);
4447
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
4295
4448
  await resolvePinnedRootPathInRoot(root, {
4296
4449
  relativePath: params.toRelative,
4297
4450
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
@@ -4375,6 +4528,7 @@ async function writeFileFallback(root, params) {
4375
4528
  relativePath: params.relativePath,
4376
4529
  mkdir: params.mkdir,
4377
4530
  mode: params.mode,
4531
+ denyMutations: params.denyMutations,
4378
4532
  truncateExisting: false,
4379
4533
  });
4380
4534
  const destinationPath = target.realPath;
@@ -4420,6 +4574,7 @@ async function writeFileFallback(root, params) {
4420
4574
  }
4421
4575
  async function writeMissingFileFallback(root, params) {
4422
4576
  const { rootReal, resolved } = await resolvePathInRoot(root, params.relativePath);
4577
+ await assertMutationNotDenied(resolved, params.denyMutations);
4423
4578
  try {
4424
4579
  await assertNoPathAliasEscape({
4425
4580
  absolutePath: resolved,
@@ -4493,6 +4648,7 @@ async function copyFileFallback(root, params, source) {
4493
4648
  relativePath: params.relativePath,
4494
4649
  mkdir: params.mkdir,
4495
4650
  mode: params.mode,
4651
+ denyMutations: params.denyMutations,
4496
4652
  truncateExisting: false,
4497
4653
  });
4498
4654
  const destinationPath = target.realPath;
@@ -4653,7 +4809,7 @@ async function pathExistsWithinRoot(targetDir, relativePath) {
4653
4809
  * FsSafeError as their `cause` and should be re-thrown rather than
4654
4810
  * silently swallowed by per-file error handlers.
4655
4811
  */ function isFsSafeViolation(error) {
4656
- return error instanceof Error && error.cause instanceof FsSafeError;
4812
+ return error instanceof Error && error.cause instanceof errors_FsSafeError;
4657
4813
  }
4658
4814
  async function statWithinRoot(targetDir, relativePath) {
4659
4815
  try {
@@ -19097,7 +19253,7 @@ function formatHeadingAsSetext(node, state) {
19097
19253
  node.type === 'break'
19098
19254
  ) {
19099
19255
  literalWithBreak = true
19100
- return EXIT
19256
+ return (/* inlined export .EXIT */false)
19101
19257
  }
19102
19258
  })
19103
19259
 
@@ -33420,6 +33576,7 @@ const PackageJsonSchema = schemas_object({
33420
33576
  */
33421
33577
 
33422
33578
 
33579
+
33423
33580
  /** Maximum skill file size: 1 MB */ const MAX_SKILL_FILE_BYTES = 1_048_576;
33424
33581
  /**
33425
33582
  * Skill directory locations to search for SKILL.md files.
@@ -33428,6 +33585,33 @@ const PackageJsonSchema = schemas_object({
33428
33585
  (0,external_node_path_.join)(".claude", "skills"),
33429
33586
  (0,external_node_path_.join)(".agents", "skills")
33430
33587
  ];
33588
+ /** Maximum lock file size: 256 KB */ const MAX_LOCK_FILE_BYTES = 262_144;
33589
+ /** Relative path to the skills lock file. */ const SKILLS_LOCK_PATH = "skills-lock.json";
33590
+ /** Zod schema for skills-lock.json structure */ const SkillsLockSchema = schemas_object({
33591
+ skills: record(schemas_string(), schemas_unknown()).optional()
33592
+ });
33593
+ /**
33594
+ * Reads the skills-lock.json file and returns the set of locked skill names.
33595
+ * Returns an empty set if the file does not exist or cannot be parsed.
33596
+ */ async function readLockedSkillNames(targetDir) {
33597
+ try {
33598
+ const exists = await pathExistsWithinRoot(targetDir, SKILLS_LOCK_PATH);
33599
+ if (!exists) {
33600
+ return new Set();
33601
+ }
33602
+ const content = await readTextWithinRoot(targetDir, SKILLS_LOCK_PATH, MAX_LOCK_FILE_BYTES);
33603
+ const result = SkillsLockSchema.safeParse(JSON.parse(content));
33604
+ if (result.success && Object.hasOwn(result.data, "skills") && result.data.skills != null) {
33605
+ return new Set(Object.keys(result.data.skills));
33606
+ }
33607
+ return new Set();
33608
+ } catch (error) {
33609
+ if (isFsSafeViolation(error)) {
33610
+ throw error;
33611
+ }
33612
+ return new Set();
33613
+ }
33614
+ }
33431
33615
  /**
33432
33616
  * File system implementation of the skill lint gateway.
33433
33617
  */ class FileSystemSkillLintGateway {
@@ -33437,7 +33621,11 @@ const PackageJsonSchema = schemas_object({
33437
33621
  const discovered = await this.discoverSkillsInDir(targetDir, relativeDir);
33438
33622
  skills.push(...discovered);
33439
33623
  }
33440
- return skills;
33624
+ const lockedNames = await readLockedSkillNames(targetDir);
33625
+ if (lockedNames.size === 0) {
33626
+ return skills;
33627
+ }
33628
+ return skills.filter((skill)=>!lockedNames.has(skill.skillName));
33441
33629
  }
33442
33630
  async discoverSkillsInDir(targetDir, skillsDir) {
33443
33631
  try {
@@ -45942,10 +46130,11 @@ exports.visitAsync = visitAsync;
45942
46130
 
45943
46131
  },
45944
46132
  5492(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
46133
+ const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
45945
46134
  __webpack_require__.d(__webpack_exports__, {
45946
46135
  n: () => (a)
45947
46136
  });
45948
- const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
46137
+
45949
46138
 
45950
46139
  },
45951
46140
  5975(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -46030,12 +46219,16 @@ __webpack_require__.t = function(value, mode) {
46030
46219
  })();
46031
46220
  // webpack/runtime/define_property_getters
46032
46221
  (() => {
46033
- __webpack_require__.d = (exports, definition) => {
46034
- for(var key in definition) {
46035
- if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
46036
- Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
46037
- }
46038
- }
46222
+ __webpack_require__.d = (exports, getters, values) => {
46223
+ var define = (defs, kind) => {
46224
+ for(var key in defs) {
46225
+ if(__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) {
46226
+ Object.defineProperty(exports, key, { enumerable: true, [kind]: defs[key] });
46227
+ }
46228
+ }
46229
+ };
46230
+ define(getters, "get");
46231
+ define(values, "value");
46039
46232
  };
46040
46233
  })();
46041
46234
  // webpack/runtime/ensure_chunk
@@ -46137,7 +46330,7 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
46137
46330
  // module factories are used so entry inlining is disabled
46138
46331
  // startup
46139
46332
  // Load entry module and return exports
46140
- var __webpack_exports__ = __webpack_require__(4403);
46333
+ var __webpack_exports__ = __webpack_require__(9884);
46141
46334
  var __webpack_exports__DEFAULT_LINT_RULES = __webpack_exports__.Kd;
46142
46335
  var __webpack_exports__LintValidationError = __webpack_exports__.F5;
46143
46336
  var __webpack_exports__createFormatter = __webpack_exports__.xi;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/lint",
3
- "version": "5.14.10",
3
+ "version": "5.15.0",
4
4
  "description": "Programmatic lint API for validating AI coding assistant configurations — skills, agents, hooks, and instructions",
5
5
  "type": "module",
6
6
  "repository": {