@lousy-agents/cli 5.17.11 → 5.17.12

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.
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "ghcr.io/devcontainers/features/copilot-cli:1.0.0": {},
12
12
  "ghcr.io/anthropics/devcontainer-features/claude-code:1": {
13
- "version": "v2.1.218"
13
+ "version": "v2.1.219"
14
14
  },
15
15
  "ghcr.io/rocker-org/devcontainer-features/apt-packages:1.0.2": {
16
16
  "packages": "yamllint, shellcheck",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "devDependencies": {
20
20
  "@biomejs/biome": "2.5.3",
21
- "@lousy-agents/mcp": "5.17.10",
21
+ "@lousy-agents/mcp": "5.17.11",
22
22
  "@modelcontextprotocol/server-sequential-thinking": "2026.7.4",
23
23
  "@testcontainers/postgresql": "12.0.4",
24
24
  "@types/node": "24.13.3",
@@ -972,9 +972,9 @@
972
972
  }
973
973
  },
974
974
  "node_modules/@lousy-agents/mcp": {
975
- "version": "5.17.10",
976
- "resolved": "https://registry.npmjs.org/@lousy-agents/mcp/-/mcp-5.17.10.tgz",
977
- "integrity": "sha512-kyuOOgHi46onNnI510/L5y8REr+7Rnk4ane5z/ehtTM+7KnfHSqzWfbgxAbiOagx1tmIlISqFsZgwyFQ/g+EOQ==",
975
+ "version": "5.17.11",
976
+ "resolved": "https://registry.npmjs.org/@lousy-agents/mcp/-/mcp-5.17.11.tgz",
977
+ "integrity": "sha512-g88nSiJDaQ8q8rGBDMdBZmbqp1rZaqkzPT+E/zOiHy+vhupn49+MxNogBoFeEJADWJYN8zpTgDlMXQ8MGFNwgg==",
978
978
  "dev": true,
979
979
  "license": "BSD-2-Clause-Patent",
980
980
  "dependencies": {
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@biomejs/biome": "2.5.3",
32
- "@lousy-agents/mcp": "5.17.10",
32
+ "@lousy-agents/mcp": "5.17.11",
33
33
  "@modelcontextprotocol/server-sequential-thinking": "2026.7.4",
34
34
  "@testcontainers/postgresql": "12.0.4",
35
35
  "@types/node": "24.13.3",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "ghcr.io/devcontainers/features/copilot-cli:1.0.0": {},
12
12
  "ghcr.io/anthropics/devcontainer-features/claude-code:1": {
13
- "version": "v2.1.218"
13
+ "version": "v2.1.219"
14
14
  },
15
15
  "ghcr.io/rocker-org/devcontainer-features/apt-packages:1.0.2": {
16
16
  "packages": "yamllint, shellcheck",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "devDependencies": {
22
22
  "@biomejs/biome": "2.5.3",
23
- "@lousy-agents/mcp": "5.17.10",
23
+ "@lousy-agents/mcp": "5.17.11",
24
24
  "@modelcontextprotocol/server-sequential-thinking": "2026.7.4",
25
25
  "@types/node": "24.13.3",
26
26
  "@upstash/context7-mcp": "3.2.4",
package/dist/index.js CHANGED
@@ -3032,7 +3032,7 @@ exports.basename = (path, { windows } = {}) => {
3032
3032
 
3033
3033
 
3034
3034
  },
3035
- 580(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
3035
+ 9646(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
3036
3036
  // NAMESPACE OBJECT: ../../node_modules/micromark/lib/constructs.js
3037
3037
  var constructs_namespaceObject = {};
3038
3038
  __webpack_require__.r(constructs_namespaceObject);
@@ -3407,26 +3407,304 @@ function directory_guard_createNearestExistingSyncDirectoryGuard(rootReal, targe
3407
3407
  return directory_guard_createSyncDirectoryGuard(root);
3408
3408
  }
3409
3409
 
3410
- ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/fsync.js
3410
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/directory-durability.js
3411
3411
 
3412
3412
 
3413
- async function syncDirectoryBestEffort(dirPath) {
3413
+
3414
+
3415
+
3416
+
3417
+ function directoryOpenFlags() {
3414
3418
  if (process.platform === "win32") {
3415
- return;
3419
+ return "r";
3416
3420
  }
3417
- let handle;
3421
+ return (external_node_fs_.constants.O_RDONLY |
3422
+ external_node_fs_.constants.O_DIRECTORY |
3423
+ external_node_fs_.constants.O_NOFOLLOW |
3424
+ external_node_fs_.constants.O_NONBLOCK);
3425
+ }
3426
+ function isWindowsDirectorySyncUnsupported(error) {
3427
+ if (process.platform !== "win32") {
3428
+ return false;
3429
+ }
3430
+ const code = error.code;
3431
+ return (code === "EACCES" ||
3432
+ code === "EINVAL" ||
3433
+ code === "EISDIR" ||
3434
+ code === "ENOSYS" ||
3435
+ code === "ENOTSUP" ||
3436
+ code === "EPERM");
3437
+ }
3438
+ function isWindowsDirectoryOpenUnsupported(error) {
3439
+ if (process.platform !== "win32") {
3440
+ return false;
3441
+ }
3442
+ const code = error.code;
3443
+ return code === "EINVAL" || code === "EISDIR" || code === "ENOSYS" || code === "ENOTSUP";
3444
+ }
3445
+ function unsupportedOutcome(error) {
3446
+ const code = error.code;
3447
+ return code ? { status: "unsupported", code } : { status: "unsupported" };
3448
+ }
3449
+ function assertDirectory(identity, pathname, label) {
3450
+ if (identity.isSymbolicLink() || !identity.isDirectory()) {
3451
+ throw new errors_FsSafeError("not-file", `${label} must be a real directory: ${pathname}`);
3452
+ }
3453
+ }
3454
+ async function createDirectoryReceipt(directoryPath, label) {
3455
+ const resolvedPath = external_node_path_.resolve(directoryPath);
3456
+ const identity = await promises_.lstat(resolvedPath);
3457
+ assertDirectory(identity, resolvedPath, label);
3458
+ return {
3459
+ path: resolvedPath,
3460
+ realPath: await promises_.realpath(resolvedPath),
3461
+ identity,
3462
+ };
3463
+ }
3464
+ function createDirectoryReceiptSync(directoryPath, label) {
3465
+ const resolvedPath = path.resolve(directoryPath);
3466
+ const identity = fsSync.lstatSync(resolvedPath);
3467
+ assertDirectory(identity, resolvedPath, label);
3468
+ return {
3469
+ path: resolvedPath,
3470
+ realPath: fsSync.realpathSync(resolvedPath),
3471
+ identity,
3472
+ };
3473
+ }
3474
+ async function assertDirectoryReceiptCurrent(receipt, label) {
3475
+ const currentIdentity = await promises_.lstat(receipt.path);
3476
+ assertDirectory(currentIdentity, receipt.path, label);
3477
+ if (!file_identity_sameFileIdentity(receipt.identity, currentIdentity) ||
3478
+ (await promises_.realpath(receipt.path)) !== receipt.realPath) {
3479
+ throw new errors_FsSafeError("path-mismatch", `${label} changed during durable directory operation: ${receipt.path}`);
3480
+ }
3481
+ }
3482
+ function assertDirectoryReceiptCurrentSync(receipt, label) {
3483
+ const currentIdentity = fsSync.lstatSync(receipt.path);
3484
+ assertDirectory(currentIdentity, receipt.path, label);
3485
+ if (!sameFileIdentity(receipt.identity, currentIdentity) ||
3486
+ fsSync.realpathSync(receipt.path) !== receipt.realPath) {
3487
+ throw new FsSafeError("path-mismatch", `${label} changed during durable directory operation: ${receipt.path}`);
3488
+ }
3489
+ }
3490
+ async function assertOpenDirectoryCurrent(handle, receipt, label) {
3491
+ const openedIdentity = await handle.stat();
3492
+ assertDirectory(openedIdentity, receipt.path, label);
3493
+ if (!file_identity_sameFileIdentity(receipt.identity, openedIdentity)) {
3494
+ throw new errors_FsSafeError("path-mismatch", `${label} handle changed during directory sync: ${receipt.path}`);
3495
+ }
3496
+ await assertDirectoryReceiptCurrent(receipt, label);
3497
+ }
3498
+ class PinnedDirectoryImpl {
3499
+ receipt;
3500
+ #handle;
3501
+ #label;
3502
+ #closed = false;
3503
+ constructor(handle, receipt, label) {
3504
+ this.#handle = handle;
3505
+ this.receipt = receipt;
3506
+ this.#label = label;
3507
+ }
3508
+ async assertCurrent() {
3509
+ if (this.#closed) {
3510
+ throw new errors_FsSafeError("helper-failed", `${this.#label} pin is already closed`);
3511
+ }
3512
+ await assertOpenDirectoryCurrent(this.#handle, this.receipt, this.#label);
3513
+ }
3514
+ async sync() {
3515
+ await this.assertCurrent();
3516
+ try {
3517
+ await this.#handle.sync();
3518
+ }
3519
+ catch (error) {
3520
+ if (!isWindowsDirectorySyncUnsupported(error)) {
3521
+ throw error;
3522
+ }
3523
+ await this.assertCurrent();
3524
+ return unsupportedOutcome(error);
3525
+ }
3526
+ await this.assertCurrent();
3527
+ return { status: "synced" };
3528
+ }
3529
+ async close() {
3530
+ if (this.#closed) {
3531
+ return;
3532
+ }
3533
+ this.#closed = true;
3534
+ await this.#handle.close();
3535
+ }
3536
+ }
3537
+ async function pinDirectory(directory, options = {}) {
3538
+ const label = options.label ?? "directory";
3539
+ const receipt = typeof directory === "string" ? await createDirectoryReceipt(directory, label) : directory;
3540
+ await assertDirectoryReceiptCurrent(receipt, label);
3541
+ const handle = await promises_.open(receipt.path, directoryOpenFlags());
3418
3542
  try {
3419
- const flags = external_node_fs_.constants.O_RDONLY |
3420
- ("O_DIRECTORY" in external_node_fs_.constants ? external_node_fs_.constants.O_DIRECTORY : 0) |
3421
- ("O_NOFOLLOW" in external_node_fs_.constants ? external_node_fs_.constants.O_NOFOLLOW : 0);
3422
- handle = await promises_.open(dirPath, flags);
3423
- await handle.sync();
3543
+ await assertOpenDirectoryCurrent(handle, receipt, label);
3544
+ return new PinnedDirectoryImpl(handle, receipt, label);
3545
+ }
3546
+ catch (error) {
3547
+ await handle.close().catch(() => undefined);
3548
+ throw error;
3549
+ }
3550
+ }
3551
+ async function syncDirectory(directory, options = {}) {
3552
+ const label = options.label ?? "directory";
3553
+ const receipt = typeof directory === "string" ? await createDirectoryReceipt(directory, label) : directory;
3554
+ let pinned;
3555
+ try {
3556
+ pinned = await pinDirectory(receipt, { label });
3557
+ }
3558
+ catch (error) {
3559
+ if (!isWindowsDirectoryOpenUnsupported(error)) {
3560
+ throw error;
3561
+ }
3562
+ await assertDirectoryReceiptCurrent(receipt, label);
3563
+ return unsupportedOutcome(error);
3564
+ }
3565
+ try {
3566
+ return await pinned.sync();
3567
+ }
3568
+ finally {
3569
+ await pinned.close();
3570
+ }
3571
+ }
3572
+ function syncDirectorySync(directory, options = {}) {
3573
+ const label = options.label ?? "directory";
3574
+ const receipt = typeof directory === "string" ? createDirectoryReceiptSync(directory, label) : directory;
3575
+ assertDirectoryReceiptCurrentSync(receipt, label);
3576
+ let descriptor;
3577
+ try {
3578
+ descriptor = fsSync.openSync(receipt.path, directoryOpenFlags());
3579
+ }
3580
+ catch (error) {
3581
+ if (!isWindowsDirectoryOpenUnsupported(error)) {
3582
+ throw error;
3583
+ }
3584
+ assertDirectoryReceiptCurrentSync(receipt, label);
3585
+ return unsupportedOutcome(error);
3586
+ }
3587
+ try {
3588
+ const openedIdentity = fsSync.fstatSync(descriptor);
3589
+ assertDirectory(openedIdentity, receipt.path, label);
3590
+ if (!sameFileIdentity(receipt.identity, openedIdentity)) {
3591
+ throw new FsSafeError("path-mismatch", `${label} handle changed during directory sync: ${receipt.path}`);
3592
+ }
3593
+ assertDirectoryReceiptCurrentSync(receipt, label);
3594
+ try {
3595
+ fsSync.fsyncSync(descriptor);
3596
+ }
3597
+ catch (error) {
3598
+ if (!isWindowsDirectorySyncUnsupported(error)) {
3599
+ throw error;
3600
+ }
3601
+ assertDirectoryReceiptCurrentSync(receipt, label);
3602
+ return unsupportedOutcome(error);
3603
+ }
3604
+ assertDirectoryReceiptCurrentSync(receipt, label);
3605
+ return { status: "synced" };
3606
+ }
3607
+ finally {
3608
+ fsSync.closeSync(descriptor);
3609
+ }
3610
+ }
3611
+ async function syncDirectoryBestEffort(directoryPath) {
3612
+ await syncDirectory(directoryPath).catch(() => undefined);
3613
+ }
3614
+ function syncDirectoryBestEffortSync(directoryPath) {
3615
+ try {
3616
+ syncDirectorySync(directoryPath);
3424
3617
  }
3425
3618
  catch {
3426
- // Some filesystems reject directory handles; keep the write usable there.
3619
+ // Compatibility helper for operations whose primary write may remain usable.
3620
+ }
3621
+ }
3622
+ async function findExistingAncestorReceipt(targetPath, label) {
3623
+ let currentPath = path.resolve(targetPath);
3624
+ while (true) {
3625
+ try {
3626
+ return await createDirectoryReceipt(currentPath, label);
3627
+ }
3628
+ catch (error) {
3629
+ if (error.code !== "ENOENT") {
3630
+ throw error;
3631
+ }
3632
+ }
3633
+ const parentPath = path.dirname(currentPath);
3634
+ if (parentPath === currentPath) {
3635
+ throw new FsSafeError("not-found", `${label} has no existing directory ancestor`);
3636
+ }
3637
+ currentPath = parentPath;
3638
+ }
3639
+ }
3640
+ async function ensureDurableDirectory(options) {
3641
+ const directoryPath = path.resolve(options.directoryPath);
3642
+ const label = options.label ?? "directory";
3643
+ const ancestorReceipt = await findExistingAncestorReceipt(directoryPath, label);
3644
+ const targetExists = ancestorReceipt.path === directoryPath;
3645
+ if (options.expectedExistingIdentity &&
3646
+ (!targetExists || !sameFileIdentity(options.expectedExistingIdentity, ancestorReceipt.identity))) {
3647
+ throw new FsSafeError("path-mismatch", `${label} changed before durable directory pinning: ${directoryPath}`);
3648
+ }
3649
+ const ancestor = await pinDirectory(ancestorReceipt, { label });
3650
+ const pinnedDirectories = [ancestor];
3651
+ try {
3652
+ await ancestor.assertCurrent();
3653
+ if (!targetExists) {
3654
+ if (options.create) {
3655
+ await options.create(directoryPath);
3656
+ }
3657
+ else {
3658
+ const created = await ensureAbsoluteDirectory(directoryPath, {
3659
+ mode: options.mode,
3660
+ scopeLabel: label,
3661
+ });
3662
+ if (!created.ok) {
3663
+ throw created.error;
3664
+ }
3665
+ }
3666
+ }
3667
+ await ancestor.assertCurrent();
3668
+ let currentPath = ancestor.receipt.path;
3669
+ for (const segment of path
3670
+ .relative(ancestor.receipt.path, directoryPath)
3671
+ .split(path.sep)
3672
+ .filter(Boolean)) {
3673
+ currentPath = path.join(currentPath, segment);
3674
+ pinnedDirectories.push(await pinDirectory(currentPath, { label }));
3675
+ }
3676
+ let parentSync = { status: "not-needed" };
3677
+ for (let index = pinnedDirectories.length - 1; index > 0; index -= 1) {
3678
+ const parent = pinnedDirectories[index - 1];
3679
+ const child = pinnedDirectories[index];
3680
+ if (!parent || !child) {
3681
+ throw new FsSafeError("helper-failed", `${label} directory pin chain is incomplete`);
3682
+ }
3683
+ await child.assertCurrent();
3684
+ try {
3685
+ const outcome = await parent.sync();
3686
+ if (outcome.status === "unsupported") {
3687
+ parentSync = outcome;
3688
+ }
3689
+ else if (parentSync.status === "not-needed") {
3690
+ parentSync = outcome;
3691
+ }
3692
+ }
3693
+ catch (error) {
3694
+ throw new FsSafeError("helper-failed", `${label} could not sync created directory edge ${child.receipt.path} through ${parent.receipt.path}`, { cause: error });
3695
+ }
3696
+ await child.assertCurrent();
3697
+ }
3698
+ const finalReceipt = pinnedDirectories.at(-1)?.receipt;
3699
+ if (!finalReceipt) {
3700
+ throw new FsSafeError("helper-failed", `${label} directory receipt is missing`);
3701
+ }
3702
+ await ancestor.assertCurrent();
3703
+ await assertDirectoryReceiptCurrent(finalReceipt, label);
3704
+ return { ...finalReceipt, parentSync };
3427
3705
  }
3428
3706
  finally {
3429
- await handle?.close().catch(() => undefined);
3707
+ await Promise.all(pinnedDirectories.toReversed().map(async (directory) => directory.close()));
3430
3708
  }
3431
3709
  }
3432
3710
 
@@ -62334,4 +62612,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
62334
62612
  // module factories are used so entry inlining is disabled
62335
62613
  // startup
62336
62614
  // Load entry module and return exports
62337
- var __webpack_exports__ = __webpack_require__(580);
62615
+ var __webpack_exports__ = __webpack_require__(9646);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/cli",
3
- "version": "5.17.11",
3
+ "version": "5.17.12",
4
4
  "description": "CLI scaffolding tool that sets up projects with structure, instructions, and feedback loops for AI coding assistants",
5
5
  "type": "module",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "ghcr.io/devcontainers/features/copilot-cli:1.0.0": {},
12
12
  "ghcr.io/anthropics/devcontainer-features/claude-code:1": {
13
- "version": "v2.1.218"
13
+ "version": "v2.1.219"
14
14
  },
15
15
  "ghcr.io/rocker-org/devcontainer-features/apt-packages:1.0.2": {
16
16
  "packages": "libnss3, libnspr4, libatk1.0-0t64, libatk-bridge2.0-0t64, libcups2t64, libdrm2, libdbus-1-3, libatspi2.0-0t64, libxcomposite1, libxdamage1, libxfixes3, libxrandr2, libgbm1, libxkbcommon0, libasound2t64, yamllint, shellcheck",
@@ -23,7 +23,7 @@
23
23
  "devDependencies": {
24
24
  "@biomejs/biome": "2.5.3",
25
25
  "@eslint/eslintrc": "3.3.6",
26
- "@lousy-agents/mcp": "5.17.10",
26
+ "@lousy-agents/mcp": "5.17.11",
27
27
  "@modelcontextprotocol/server-sequential-thinking": "2026.7.4",
28
28
  "@testing-library/jest-dom": "7.0.0",
29
29
  "@testing-library/react": "16.3.2",
@@ -33,7 +33,7 @@
33
33
  "@upstash/context7-mcp": "3.2.4",
34
34
  "@vitejs/plugin-react": "6.0.4",
35
35
  "@vitest/ui": "4.1.10",
36
- "eslint": "10.7.0",
36
+ "eslint": "10.8.0",
37
37
  "eslint-config-next": "16.2.11",
38
38
  "happy-dom": "20.11.1",
39
39
  "jsdom": "29.1.1",