@lousy-agents/cli 5.17.7 → 5.17.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/copilot-with-fastify/.devcontainer/devcontainer.json +1 -1
- package/api/copilot-with-fastify/package-lock.json +10 -10
- package/api/copilot-with-fastify/package.json +1 -1
- package/cli/copilot-with-citty/.devcontainer/devcontainer.json +1 -1
- package/cli/copilot-with-citty/package.json +1 -1
- package/dist/index.js +404 -151
- package/package.json +1 -1
- package/ui/copilot-with-react/.devcontainer/devcontainer.json +1 -1
- package/ui/copilot-with-react/package.json +4 -4
|
@@ -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.
|
|
13
|
+
"version": "v2.1.218"
|
|
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.
|
|
21
|
+
"@lousy-agents/mcp": "5.17.8",
|
|
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.
|
|
976
|
-
"resolved": "https://registry.npmjs.org/@lousy-agents/mcp/-/mcp-5.17.
|
|
977
|
-
"integrity": "sha512-
|
|
975
|
+
"version": "5.17.8",
|
|
976
|
+
"resolved": "https://registry.npmjs.org/@lousy-agents/mcp/-/mcp-5.17.8.tgz",
|
|
977
|
+
"integrity": "sha512-4c6NkQAje237D4DzbY1cH+qvYc2uIX1uZc0KBYZtqSMSUfKrGb4crCR8TcS/HRnM8NGqRXqtnnh/mkiyZyvq+A==",
|
|
978
978
|
"dev": true,
|
|
979
979
|
"license": "BSD-2-Clause-Patent",
|
|
980
980
|
"dependencies": {
|
|
@@ -3476,9 +3476,9 @@
|
|
|
3476
3476
|
}
|
|
3477
3477
|
},
|
|
3478
3478
|
"node_modules/fast-json-stringify/node_modules/fast-uri": {
|
|
3479
|
-
"version": "4.1.
|
|
3480
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.
|
|
3481
|
-
"integrity": "sha512-
|
|
3479
|
+
"version": "4.1.1",
|
|
3480
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.1.tgz",
|
|
3481
|
+
"integrity": "sha512-YPOs1zD5TG2+EZt+r88LwF6mclA7TPkpwMP7ZN3TO2HiHS8TXvq7QA/17iJsV9dubcLo/f8eEYqMBruyQV21hQ==",
|
|
3482
3482
|
"funding": [
|
|
3483
3483
|
{
|
|
3484
3484
|
"type": "github",
|
|
@@ -3501,9 +3501,9 @@
|
|
|
3501
3501
|
}
|
|
3502
3502
|
},
|
|
3503
3503
|
"node_modules/fast-uri": {
|
|
3504
|
-
"version": "3.1.
|
|
3505
|
-
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.
|
|
3506
|
-
"integrity": "sha512-
|
|
3504
|
+
"version": "3.1.4",
|
|
3505
|
+
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
|
|
3506
|
+
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
|
|
3507
3507
|
"funding": [
|
|
3508
3508
|
{
|
|
3509
3509
|
"type": "github",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@biomejs/biome": "2.5.3",
|
|
32
|
-
"@lousy-agents/mcp": "5.17.
|
|
32
|
+
"@lousy-agents/mcp": "5.17.8",
|
|
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.
|
|
13
|
+
"version": "v2.1.218"
|
|
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.
|
|
23
|
+
"@lousy-agents/mcp": "5.17.8",
|
|
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
|
-
|
|
3035
|
+
580(__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);
|
|
@@ -3790,15 +3790,11 @@ var external_node_child_process_ = __webpack_require__(1421);
|
|
|
3790
3790
|
const PINNED_PYTHON_WORKER_SOURCE = String.raw `
|
|
3791
3791
|
import base64, errno, json, os, secrets, stat, sys
|
|
3792
3792
|
DIR_FLAGS = os.O_RDONLY
|
|
3793
|
-
if hasattr(os, "O_DIRECTORY"):
|
|
3794
|
-
|
|
3795
|
-
if hasattr(os, "O_NOFOLLOW"):
|
|
3796
|
-
DIR_FLAGS |= os.O_NOFOLLOW
|
|
3793
|
+
if hasattr(os, "O_DIRECTORY"): DIR_FLAGS |= os.O_DIRECTORY
|
|
3794
|
+
if hasattr(os, "O_NOFOLLOW"): DIR_FLAGS |= os.O_NOFOLLOW
|
|
3797
3795
|
READ_FLAGS = os.O_RDONLY
|
|
3798
|
-
if hasattr(os, "O_NONBLOCK"):
|
|
3799
|
-
|
|
3800
|
-
if hasattr(os, "O_NOFOLLOW"):
|
|
3801
|
-
READ_FLAGS |= os.O_NOFOLLOW
|
|
3796
|
+
if hasattr(os, "O_NONBLOCK"): READ_FLAGS |= os.O_NONBLOCK
|
|
3797
|
+
if hasattr(os, "O_NOFOLLOW"): READ_FLAGS |= os.O_NOFOLLOW
|
|
3802
3798
|
WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_EXCL
|
|
3803
3799
|
if hasattr(os, "O_NOFOLLOW"):
|
|
3804
3800
|
WRITE_FLAGS |= os.O_NOFOLLOW
|
|
@@ -3878,6 +3874,10 @@ def write_all(fd, data):
|
|
|
3878
3874
|
if written <= 0:
|
|
3879
3875
|
raise OSError(errno.EIO, "short write")
|
|
3880
3876
|
view = view[written:]
|
|
3877
|
+
def fsync_best_effort(fd):
|
|
3878
|
+
try: os.fsync(fd)
|
|
3879
|
+
except OSError as error:
|
|
3880
|
+
if error.errno != errno.EPERM: raise
|
|
3881
3881
|
def link_unsupported(exc):
|
|
3882
3882
|
unsupported = (errno.EPERM, errno.EOPNOTSUPP, getattr(errno, "ENOTSUP", errno.EOPNOTSUPP))
|
|
3883
3883
|
return getattr(exc, "errno", None) in unsupported
|
|
@@ -4083,13 +4083,13 @@ def write_path(root_fd, payload):
|
|
|
4083
4083
|
temp_name, temp_fd = create_temp_file(parent_fd, basename, mode)
|
|
4084
4084
|
os.fchmod(temp_fd, mode)
|
|
4085
4085
|
write_all(temp_fd, data)
|
|
4086
|
-
|
|
4086
|
+
fsync_best_effort(temp_fd)
|
|
4087
4087
|
temp_stat = os.fstat(temp_fd)
|
|
4088
4088
|
os.close(temp_fd)
|
|
4089
4089
|
temp_fd = None
|
|
4090
4090
|
result_stat = commit_temp_file(parent_fd, temp_name, basename, overwrite, mode, temp_stat)
|
|
4091
4091
|
temp_name = None
|
|
4092
|
-
|
|
4092
|
+
fsync_best_effort(parent_fd)
|
|
4093
4093
|
return {"dev": result_stat.st_dev, "ino": result_stat.st_ino}
|
|
4094
4094
|
finally:
|
|
4095
4095
|
if temp_fd is not None:
|
|
@@ -4516,29 +4516,34 @@ async function runPinnedPathHelper(params) {
|
|
|
4516
4516
|
}
|
|
4517
4517
|
}
|
|
4518
4518
|
|
|
4519
|
-
;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/sidecar-lock.js
|
|
4520
|
-
|
|
4519
|
+
;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js
|
|
4521
4520
|
|
|
4522
4521
|
|
|
4523
4522
|
|
|
4524
|
-
const
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4523
|
+
const SIDECAR_LOCK_OWNERSHIP_TOKEN_BYTES = 16;
|
|
4524
|
+
const SIDECAR_LOCK_OWNERSHIP_TOKEN_BITS = SIDECAR_LOCK_OWNERSHIP_TOKEN_BYTES * 8;
|
|
4525
|
+
const SIDECAR_LOCK_OWNERSHIP_TOKEN_PREFIX = "\t".repeat(8);
|
|
4526
|
+
const SIDECAR_LOCK_OWNERSHIP_TOKEN_PATTERN = new RegExp(`\\n(${SIDECAR_LOCK_OWNERSHIP_TOKEN_PREFIX}[ \\t]{${SIDECAR_LOCK_OWNERSHIP_TOKEN_BITS}})\\n$`);
|
|
4527
|
+
function createSidecarLockOwnershipToken() {
|
|
4528
|
+
let token = SIDECAR_LOCK_OWNERSHIP_TOKEN_PREFIX;
|
|
4529
|
+
for (const byte of (0,external_node_crypto_.randomBytes)(SIDECAR_LOCK_OWNERSHIP_TOKEN_BYTES)) {
|
|
4530
|
+
for (let bit = 7; bit >= 0; bit -= 1) {
|
|
4531
|
+
token += byte & (1 << bit) ? "\t" : " ";
|
|
4532
|
+
}
|
|
4529
4533
|
}
|
|
4530
|
-
return
|
|
4534
|
+
return token;
|
|
4531
4535
|
}
|
|
4532
|
-
function
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4536
|
+
function readSidecarLockOwnershipToken(raw) {
|
|
4537
|
+
return SIDECAR_LOCK_OWNERSHIP_TOKEN_PATTERN.exec(raw)?.[1];
|
|
4538
|
+
}
|
|
4539
|
+
function serializeSidecarLockPayload(payload) {
|
|
4540
|
+
const ownershipToken = createSidecarLockOwnershipToken();
|
|
4541
|
+
return {
|
|
4542
|
+
raw: `${JSON.stringify(payload, null, 2)}\n${ownershipToken}\n`,
|
|
4543
|
+
ownershipToken,
|
|
4544
|
+
};
|
|
4540
4545
|
}
|
|
4541
|
-
async function
|
|
4546
|
+
async function readSidecarLockSnapshot(lockPath) {
|
|
4542
4547
|
try {
|
|
4543
4548
|
const stat = await promises_.lstat(lockPath);
|
|
4544
4549
|
const raw = await promises_.readFile(lockPath, "utf8");
|
|
@@ -4560,7 +4565,15 @@ async function readLockSnapshot(lockPath) {
|
|
|
4560
4565
|
throw err;
|
|
4561
4566
|
}
|
|
4562
4567
|
}
|
|
4563
|
-
function
|
|
4568
|
+
function sidecarLockSnapshotMatches(current, observed) {
|
|
4569
|
+
if (observed.ownershipToken !== undefined) {
|
|
4570
|
+
return (current.stat?.isFile() === true &&
|
|
4571
|
+
current.raw !== undefined &&
|
|
4572
|
+
observed.raw !== undefined &&
|
|
4573
|
+
readSidecarLockOwnershipToken(current.raw) === observed.ownershipToken &&
|
|
4574
|
+
readSidecarLockOwnershipToken(observed.raw) === observed.ownershipToken &&
|
|
4575
|
+
current.raw === observed.raw);
|
|
4576
|
+
}
|
|
4564
4577
|
if (observed.stat && current.stat && !file_identity_sameFileIdentity(observed.stat, current.stat)) {
|
|
4565
4578
|
return false;
|
|
4566
4579
|
}
|
|
@@ -4569,30 +4582,54 @@ function snapshotMatches(current, observed) {
|
|
|
4569
4582
|
}
|
|
4570
4583
|
return observed.stat !== undefined && current.stat !== undefined;
|
|
4571
4584
|
}
|
|
4572
|
-
async function
|
|
4573
|
-
const current = await
|
|
4574
|
-
if (!current || !observed) {
|
|
4575
|
-
return false;
|
|
4576
|
-
}
|
|
4577
|
-
if (!snapshotMatches(current, observed)) {
|
|
4578
|
-
// The lock changed after we decided it was stale. Leave the fresh holder's
|
|
4579
|
-
// file alone; deleting by path here would break mutual exclusion.
|
|
4585
|
+
async function removeSidecarLockIfUnchanged(lockPath, observed) {
|
|
4586
|
+
const current = await readSidecarLockSnapshot(lockPath);
|
|
4587
|
+
if (!current || !observed || !sidecarLockSnapshotMatches(current, observed)) {
|
|
4580
4588
|
return false;
|
|
4581
4589
|
}
|
|
4582
4590
|
await promises_.rm(lockPath, { force: true }).catch(() => undefined);
|
|
4583
4591
|
return true;
|
|
4584
4592
|
}
|
|
4585
|
-
async function
|
|
4586
|
-
const current = await
|
|
4587
|
-
return !!current && !!observed &&
|
|
4593
|
+
async function sidecarLockSnapshotStillPresent(lockPath, observed) {
|
|
4594
|
+
const current = await readSidecarLockSnapshot(lockPath);
|
|
4595
|
+
return !!current && !!observed && sidecarLockSnapshotMatches(current, observed);
|
|
4588
4596
|
}
|
|
4589
|
-
async function
|
|
4590
|
-
|
|
4591
|
-
|
|
4597
|
+
async function sidecarReclaimGuardExists(pathname) {
|
|
4598
|
+
try {
|
|
4599
|
+
await promises_.lstat(pathname);
|
|
4600
|
+
return true;
|
|
4601
|
+
}
|
|
4602
|
+
catch (err) {
|
|
4603
|
+
if (err.code === "ENOENT") {
|
|
4604
|
+
return false;
|
|
4605
|
+
}
|
|
4606
|
+
throw err;
|
|
4592
4607
|
}
|
|
4593
|
-
|
|
4608
|
+
}
|
|
4609
|
+
async function tryAcquireSidecarReclaimGuard(reclaimGuards, reclaimGuardPath) {
|
|
4610
|
+
try {
|
|
4611
|
+
await promises_.mkdir(reclaimGuardPath);
|
|
4612
|
+
reclaimGuards.add(reclaimGuardPath);
|
|
4613
|
+
return true;
|
|
4614
|
+
}
|
|
4615
|
+
catch (err) {
|
|
4616
|
+
if (err.code === "EEXIST") {
|
|
4617
|
+
return false;
|
|
4618
|
+
}
|
|
4619
|
+
throw err;
|
|
4620
|
+
}
|
|
4621
|
+
}
|
|
4622
|
+
async function releaseSidecarReclaimGuard(reclaimGuards, reclaimGuardPath) {
|
|
4623
|
+
await promises_.rmdir(reclaimGuardPath);
|
|
4624
|
+
reclaimGuards.delete(reclaimGuardPath);
|
|
4625
|
+
}
|
|
4626
|
+
async function removeStaleSidecarLockIfAllowed(params) {
|
|
4627
|
+
if (!params.shouldRemoveStaleLock || params.snapshot.raw === undefined) {
|
|
4594
4628
|
return "not-approved";
|
|
4595
4629
|
}
|
|
4630
|
+
if (!(await sidecarLockSnapshotStillPresent(params.lockPath, params.snapshot))) {
|
|
4631
|
+
return "changed";
|
|
4632
|
+
}
|
|
4596
4633
|
if (!(await params.shouldRemoveStaleLock({
|
|
4597
4634
|
lockPath: params.lockPath,
|
|
4598
4635
|
normalizedTargetPath: params.normalizedTargetPath,
|
|
@@ -4601,32 +4638,95 @@ async function removeStaleLockIfAllowed(params) {
|
|
|
4601
4638
|
}))) {
|
|
4602
4639
|
return "not-approved";
|
|
4603
4640
|
}
|
|
4604
|
-
|
|
4605
|
-
if (!current || !snapshotMatches(current, params.snapshot)) {
|
|
4641
|
+
if (!(await sidecarLockSnapshotStillPresent(params.lockPath, params.snapshot))) {
|
|
4606
4642
|
return "changed";
|
|
4607
4643
|
}
|
|
4608
4644
|
try {
|
|
4609
|
-
await promises_.rm(params.lockPath
|
|
4645
|
+
await promises_.rm(params.lockPath);
|
|
4646
|
+
return "removed";
|
|
4610
4647
|
}
|
|
4611
4648
|
catch (err) {
|
|
4612
4649
|
if (err.code === "ENOENT") {
|
|
4613
4650
|
return "changed";
|
|
4614
4651
|
}
|
|
4615
|
-
|
|
4652
|
+
throw err;
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4656
|
+
;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/sidecar-lock.js
|
|
4657
|
+
|
|
4658
|
+
|
|
4659
|
+
|
|
4660
|
+
|
|
4661
|
+
|
|
4662
|
+
const GLOBAL_STATE_KEY = Symbol.for("fsSafe.sidecarLockManagers");
|
|
4663
|
+
function getGlobalManagers() {
|
|
4664
|
+
const globalWithState = globalThis;
|
|
4665
|
+
if (!globalWithState[GLOBAL_STATE_KEY]) {
|
|
4666
|
+
globalWithState[GLOBAL_STATE_KEY] = new Map();
|
|
4616
4667
|
}
|
|
4617
|
-
return
|
|
4668
|
+
return globalWithState[GLOBAL_STATE_KEY];
|
|
4669
|
+
}
|
|
4670
|
+
function resolveManagerState(key) {
|
|
4671
|
+
const managers = getGlobalManagers();
|
|
4672
|
+
let state = managers.get(key);
|
|
4673
|
+
if (!state) {
|
|
4674
|
+
state = {
|
|
4675
|
+
cleanupRegistered: false,
|
|
4676
|
+
held: new Map(),
|
|
4677
|
+
reclaimCleanupRegistered: false,
|
|
4678
|
+
reclaimGuards: new Set(),
|
|
4679
|
+
};
|
|
4680
|
+
managers.set(key, state);
|
|
4681
|
+
}
|
|
4682
|
+
else {
|
|
4683
|
+
// The global manager symbol is shared across package copies and hot reloads.
|
|
4684
|
+
// Backfill state created by fs-safe versions that predate reclaim guards.
|
|
4685
|
+
state.reclaimCleanupRegistered ??= false;
|
|
4686
|
+
state.reclaimGuards ??= new Set();
|
|
4687
|
+
}
|
|
4688
|
+
return state;
|
|
4618
4689
|
}
|
|
4619
4690
|
function snapshotMatchesSync(lockPath, observed) {
|
|
4691
|
+
let fd;
|
|
4620
4692
|
try {
|
|
4621
|
-
const
|
|
4622
|
-
if (
|
|
4693
|
+
const beforeStat = external_node_fs_.lstatSync(lockPath);
|
|
4694
|
+
if (!beforeStat.isFile()) {
|
|
4695
|
+
return false;
|
|
4696
|
+
}
|
|
4697
|
+
const openFlags = external_node_fs_.constants.O_RDONLY |
|
|
4698
|
+
(process.platform !== "win32" && typeof external_node_fs_.constants.O_NOFOLLOW === "number"
|
|
4699
|
+
? external_node_fs_.constants.O_NOFOLLOW
|
|
4700
|
+
: 0) |
|
|
4701
|
+
(typeof external_node_fs_.constants.O_NONBLOCK === "number" ? external_node_fs_.constants.O_NONBLOCK : 0);
|
|
4702
|
+
fd = external_node_fs_.openSync(lockPath, openFlags);
|
|
4703
|
+
const openedStat = external_node_fs_.fstatSync(fd);
|
|
4704
|
+
if (!openedStat.isFile()) {
|
|
4705
|
+
return false;
|
|
4706
|
+
}
|
|
4707
|
+
if (observed.raw !== undefined && openedStat.size !== Buffer.byteLength(observed.raw)) {
|
|
4623
4708
|
return false;
|
|
4624
4709
|
}
|
|
4625
|
-
|
|
4710
|
+
const raw = external_node_fs_.readFileSync(fd, "utf8");
|
|
4711
|
+
const afterStat = external_node_fs_.lstatSync(lockPath);
|
|
4712
|
+
if (!afterStat.isFile() || !file_identity_sameFileIdentity(beforeStat, afterStat)) {
|
|
4713
|
+
return false;
|
|
4714
|
+
}
|
|
4715
|
+
return sidecarLockSnapshotMatches({ raw, payload: null, stat: afterStat }, observed);
|
|
4626
4716
|
}
|
|
4627
4717
|
catch {
|
|
4628
4718
|
return false;
|
|
4629
4719
|
}
|
|
4720
|
+
finally {
|
|
4721
|
+
if (fd !== undefined) {
|
|
4722
|
+
try {
|
|
4723
|
+
external_node_fs_.closeSync(fd);
|
|
4724
|
+
}
|
|
4725
|
+
catch {
|
|
4726
|
+
// Best-effort process-exit cleanup.
|
|
4727
|
+
}
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4630
4730
|
}
|
|
4631
4731
|
async function resolveNormalizedTargetPath(targetPath) {
|
|
4632
4732
|
const resolved = external_node_path_.resolve(targetPath);
|
|
@@ -4661,6 +4761,17 @@ async function defaultShouldReclaim(params) {
|
|
|
4661
4761
|
return true;
|
|
4662
4762
|
}
|
|
4663
4763
|
}
|
|
4764
|
+
function releaseAllReclaimGuardsSync(state) {
|
|
4765
|
+
for (const reclaimGuardPath of state.reclaimGuards) {
|
|
4766
|
+
try {
|
|
4767
|
+
external_node_fs_.rmdirSync(reclaimGuardPath);
|
|
4768
|
+
state.reclaimGuards.delete(reclaimGuardPath);
|
|
4769
|
+
}
|
|
4770
|
+
catch {
|
|
4771
|
+
// Best-effort process-exit cleanup. A surviving guard fails closed.
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4664
4775
|
function releaseAllLocksSync(state) {
|
|
4665
4776
|
for (const [normalizedTargetPath, held] of state.held) {
|
|
4666
4777
|
void held.handle.close().catch(() => undefined);
|
|
@@ -4674,6 +4785,7 @@ function releaseAllLocksSync(state) {
|
|
|
4674
4785
|
}
|
|
4675
4786
|
state.held.delete(normalizedTargetPath);
|
|
4676
4787
|
}
|
|
4788
|
+
releaseAllReclaimGuardsSync(state);
|
|
4677
4789
|
}
|
|
4678
4790
|
async function releaseHeldLock(state, normalizedTargetPath, held, opts = {}) {
|
|
4679
4791
|
const current = state.held.get(normalizedTargetPath);
|
|
@@ -4696,7 +4808,7 @@ async function releaseHeldLock(state, normalizedTargetPath, held, opts = {}) {
|
|
|
4696
4808
|
state.held.delete(normalizedTargetPath);
|
|
4697
4809
|
held.releasePromise = (async () => {
|
|
4698
4810
|
await held.handle.close().catch(() => undefined);
|
|
4699
|
-
await
|
|
4811
|
+
await removeSidecarLockIfUnchanged(held.lockPath, held.snapshot);
|
|
4700
4812
|
})();
|
|
4701
4813
|
try {
|
|
4702
4814
|
await held.releasePromise;
|
|
@@ -4709,11 +4821,16 @@ async function releaseHeldLock(state, normalizedTargetPath, held, opts = {}) {
|
|
|
4709
4821
|
function createSidecarLockManager(key) {
|
|
4710
4822
|
const state = resolveManagerState(key);
|
|
4711
4823
|
function ensureExitCleanupRegistered() {
|
|
4712
|
-
if (state.cleanupRegistered) {
|
|
4824
|
+
if (!state.cleanupRegistered) {
|
|
4825
|
+
state.cleanupRegistered = true;
|
|
4826
|
+
state.reclaimCleanupRegistered = true;
|
|
4827
|
+
process.on("exit", () => releaseAllLocksSync(state));
|
|
4713
4828
|
return;
|
|
4714
4829
|
}
|
|
4715
|
-
state.
|
|
4716
|
-
|
|
4830
|
+
if (!state.reclaimCleanupRegistered) {
|
|
4831
|
+
state.reclaimCleanupRegistered = true;
|
|
4832
|
+
process.on("exit", () => releaseAllReclaimGuardsSync(state));
|
|
4833
|
+
}
|
|
4717
4834
|
}
|
|
4718
4835
|
async function acquire(options) {
|
|
4719
4836
|
ensureExitCleanupRegistered();
|
|
@@ -4733,108 +4850,146 @@ function createSidecarLockManager(key) {
|
|
|
4733
4850
|
const startedAt = Date.now();
|
|
4734
4851
|
const retry = options.retry ?? {};
|
|
4735
4852
|
const maxRetries = options.timeoutMs === Number.POSITIVE_INFINITY ? undefined : retry.retries;
|
|
4853
|
+
const reclaimGuardPath = `${lockPath}.reclaim`;
|
|
4854
|
+
let ownsReclaimGuard = false;
|
|
4736
4855
|
let attempt = 0;
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
const createdHeld = {
|
|
4746
|
-
count: 1,
|
|
4747
|
-
handle,
|
|
4748
|
-
lockPath,
|
|
4749
|
-
snapshot,
|
|
4750
|
-
acquiredAt: Date.now(),
|
|
4751
|
-
metadata: options.metadata ?? {},
|
|
4752
|
-
};
|
|
4753
|
-
state.held.set(normalizedTargetPath, createdHeld);
|
|
4754
|
-
const release = () => releaseHeldLock(state, normalizedTargetPath, createdHeld).then(() => undefined);
|
|
4755
|
-
return {
|
|
4856
|
+
const waitForRetry = async () => {
|
|
4857
|
+
const elapsed = Date.now() - startedAt;
|
|
4858
|
+
if ((options.timeoutMs !== undefined &&
|
|
4859
|
+
options.timeoutMs !== Number.POSITIVE_INFINITY &&
|
|
4860
|
+
elapsed >= options.timeoutMs) ||
|
|
4861
|
+
(maxRetries !== undefined && attempt >= maxRetries)) {
|
|
4862
|
+
throw Object.assign(new Error(`file lock timeout for ${normalizedTargetPath}`), {
|
|
4863
|
+
code: "file_lock_timeout",
|
|
4756
4864
|
lockPath,
|
|
4757
4865
|
normalizedTargetPath,
|
|
4758
|
-
|
|
4759
|
-
[Symbol.asyncDispose]: release,
|
|
4760
|
-
};
|
|
4866
|
+
});
|
|
4761
4867
|
}
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
state.held.delete(normalizedTargetPath);
|
|
4774
|
-
}
|
|
4775
|
-
// If payload serialization/write fails, the file may be empty or
|
|
4776
|
-
// partial JSON, so remove while our exclusive handle is still open.
|
|
4777
|
-
await promises_.rm(lockPath, { force: true }).catch(() => undefined);
|
|
4778
|
-
await handle.close().catch(() => undefined);
|
|
4779
|
-
// Windows can refuse removing an open file; retry after close but
|
|
4780
|
-
// only if the path still points at the file identity we created.
|
|
4781
|
-
await removeLockIfUnchanged(lockPath, failedSnapshot);
|
|
4782
|
-
}
|
|
4783
|
-
if (err.code !== "EEXIST") {
|
|
4784
|
-
throw err;
|
|
4785
|
-
}
|
|
4786
|
-
const nowMs = Date.now();
|
|
4787
|
-
const snapshot = await readLockSnapshot(lockPath);
|
|
4788
|
-
if (!snapshot) {
|
|
4868
|
+
const remaining = options.timeoutMs === undefined || options.timeoutMs === Number.POSITIVE_INFINITY
|
|
4869
|
+
? Number.POSITIVE_INFINITY
|
|
4870
|
+
: Math.max(0, options.timeoutMs - elapsed);
|
|
4871
|
+
const delay = Math.min(computeDelayMs(retry, attempt), remaining);
|
|
4872
|
+
attempt += 1;
|
|
4873
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4874
|
+
};
|
|
4875
|
+
try {
|
|
4876
|
+
while (true) {
|
|
4877
|
+
if (!ownsReclaimGuard && (await sidecarReclaimGuardExists(reclaimGuardPath))) {
|
|
4878
|
+
await waitForRetry();
|
|
4789
4879
|
continue;
|
|
4790
4880
|
}
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
lockPath,
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4881
|
+
let handle = null;
|
|
4882
|
+
try {
|
|
4883
|
+
handle = await promises_.open(lockPath, "wx");
|
|
4884
|
+
const payload = await options.payload();
|
|
4885
|
+
const { raw, ownershipToken } = serializeSidecarLockPayload(payload);
|
|
4886
|
+
await handle.writeFile(raw, "utf8");
|
|
4887
|
+
const snapshot = { raw, payload, stat: await handle.stat(), ownershipToken };
|
|
4888
|
+
const createdHeld = {
|
|
4889
|
+
count: 1,
|
|
4890
|
+
handle,
|
|
4891
|
+
lockPath,
|
|
4892
|
+
snapshot,
|
|
4893
|
+
acquiredAt: Date.now(),
|
|
4894
|
+
metadata: options.metadata ?? {},
|
|
4895
|
+
};
|
|
4896
|
+
state.held.set(normalizedTargetPath, createdHeld);
|
|
4897
|
+
if (ownsReclaimGuard) {
|
|
4898
|
+
try {
|
|
4899
|
+
await releaseSidecarReclaimGuard(state.reclaimGuards, reclaimGuardPath);
|
|
4900
|
+
ownsReclaimGuard = false;
|
|
4901
|
+
}
|
|
4902
|
+
catch (err) {
|
|
4903
|
+
await releaseHeldLock(state, normalizedTargetPath, createdHeld, { force: true });
|
|
4904
|
+
throw err;
|
|
4813
4905
|
}
|
|
4814
4906
|
}
|
|
4815
|
-
|
|
4816
|
-
|
|
4907
|
+
const release = () => releaseHeldLock(state, normalizedTargetPath, createdHeld).then(() => undefined);
|
|
4908
|
+
return {
|
|
4817
4909
|
lockPath,
|
|
4818
4910
|
normalizedTargetPath,
|
|
4819
|
-
|
|
4911
|
+
release,
|
|
4912
|
+
[Symbol.asyncDispose]: release,
|
|
4913
|
+
};
|
|
4820
4914
|
}
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4915
|
+
catch (err) {
|
|
4916
|
+
if (handle) {
|
|
4917
|
+
const failedSnapshot = { payload: null };
|
|
4918
|
+
try {
|
|
4919
|
+
failedSnapshot.stat = await handle.stat();
|
|
4920
|
+
}
|
|
4921
|
+
catch {
|
|
4922
|
+
// Best-effort cleanup of a failed exclusive create.
|
|
4923
|
+
}
|
|
4924
|
+
const current = state.held.get(normalizedTargetPath);
|
|
4925
|
+
if (current?.handle === handle) {
|
|
4926
|
+
state.held.delete(normalizedTargetPath);
|
|
4927
|
+
}
|
|
4928
|
+
// If payload serialization/write fails, the file may be empty or
|
|
4929
|
+
// partial JSON, so remove while our exclusive handle is still open.
|
|
4930
|
+
await promises_.rm(lockPath, { force: true }).catch(() => undefined);
|
|
4931
|
+
await handle.close().catch(() => undefined);
|
|
4932
|
+
// Windows can refuse removing an open file; retry after close but
|
|
4933
|
+
// only if the path still points at the file identity we created.
|
|
4934
|
+
await removeSidecarLockIfUnchanged(lockPath, failedSnapshot);
|
|
4935
|
+
}
|
|
4936
|
+
if (err.code !== "EEXIST") {
|
|
4937
|
+
throw err;
|
|
4938
|
+
}
|
|
4939
|
+
if (ownsReclaimGuard) {
|
|
4940
|
+
await releaseSidecarReclaimGuard(state.reclaimGuards, reclaimGuardPath);
|
|
4941
|
+
ownsReclaimGuard = false;
|
|
4942
|
+
continue;
|
|
4943
|
+
}
|
|
4944
|
+
const nowMs = Date.now();
|
|
4945
|
+
const snapshot = await readSidecarLockSnapshot(lockPath);
|
|
4946
|
+
if (!snapshot) {
|
|
4947
|
+
continue;
|
|
4948
|
+
}
|
|
4949
|
+
const shouldReclaim = options.shouldReclaim ?? defaultShouldReclaim;
|
|
4950
|
+
if (await shouldReclaim({
|
|
4828
4951
|
lockPath,
|
|
4829
4952
|
normalizedTargetPath,
|
|
4830
|
-
|
|
4953
|
+
payload: snapshot?.payload ?? null,
|
|
4954
|
+
staleMs: options.staleMs,
|
|
4955
|
+
nowMs,
|
|
4956
|
+
heldByThisProcess: state.held.has(normalizedTargetPath),
|
|
4957
|
+
})) {
|
|
4958
|
+
if (!(await sidecarLockSnapshotStillPresent(lockPath, snapshot))) {
|
|
4959
|
+
continue;
|
|
4960
|
+
}
|
|
4961
|
+
const staleRecovery = options.staleRecovery ?? "fail-closed";
|
|
4962
|
+
if (staleRecovery === "remove-if-unchanged") {
|
|
4963
|
+
if (!(await tryAcquireSidecarReclaimGuard(state.reclaimGuards, reclaimGuardPath))) {
|
|
4964
|
+
await waitForRetry();
|
|
4965
|
+
continue;
|
|
4966
|
+
}
|
|
4967
|
+
ownsReclaimGuard = true;
|
|
4968
|
+
const removal = await removeStaleSidecarLockIfAllowed({
|
|
4969
|
+
lockPath,
|
|
4970
|
+
normalizedTargetPath,
|
|
4971
|
+
snapshot,
|
|
4972
|
+
shouldRemoveStaleLock: options.shouldRemoveStaleLock,
|
|
4973
|
+
});
|
|
4974
|
+
if (removal === "removed" || removal === "changed") {
|
|
4975
|
+
continue;
|
|
4976
|
+
}
|
|
4977
|
+
await releaseSidecarReclaimGuard(state.reclaimGuards, reclaimGuardPath);
|
|
4978
|
+
ownsReclaimGuard = false;
|
|
4979
|
+
}
|
|
4980
|
+
throw Object.assign(new Error(`file lock stale for ${normalizedTargetPath}`), {
|
|
4981
|
+
code: "file_lock_stale",
|
|
4982
|
+
lockPath,
|
|
4983
|
+
normalizedTargetPath,
|
|
4984
|
+
});
|
|
4985
|
+
}
|
|
4986
|
+
await waitForRetry();
|
|
4831
4987
|
}
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
finally {
|
|
4991
|
+
if (ownsReclaimGuard) {
|
|
4992
|
+
await releaseSidecarReclaimGuard(state.reclaimGuards, reclaimGuardPath).catch(() => undefined);
|
|
4838
4993
|
}
|
|
4839
4994
|
}
|
|
4840
4995
|
}
|
|
@@ -4921,6 +5076,16 @@ function assertWithinMaxBytes(bytes, maxBytes) {
|
|
|
4921
5076
|
throw new errors_FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes (got at least ${bytes})`);
|
|
4922
5077
|
}
|
|
4923
5078
|
}
|
|
5079
|
+
async function syncFileBestEffort(handle) {
|
|
5080
|
+
try {
|
|
5081
|
+
await handle.sync();
|
|
5082
|
+
}
|
|
5083
|
+
catch (error) {
|
|
5084
|
+
if (error?.code !== "EPERM") {
|
|
5085
|
+
throw error;
|
|
5086
|
+
}
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
4924
5089
|
async function writeStreamToHandle(stream, handle, maxBytes) {
|
|
4925
5090
|
let bytes = 0;
|
|
4926
5091
|
for await (const chunk of stream) {
|
|
@@ -5082,7 +5247,7 @@ async function runPinnedWriteFallback(params) {
|
|
|
5082
5247
|
else {
|
|
5083
5248
|
await writeStreamToHandle(params.input.stream, handle, params.maxBytes);
|
|
5084
5249
|
}
|
|
5085
|
-
await handle
|
|
5250
|
+
await syncFileBestEffort(handle);
|
|
5086
5251
|
const stat = await handle.stat();
|
|
5087
5252
|
await handle.close().catch(() => undefined);
|
|
5088
5253
|
await syncDirectoryBestEffort(parentPath);
|
|
@@ -5127,7 +5292,7 @@ async function runPinnedWriteFallback(params) {
|
|
|
5127
5292
|
throw new errors_FsSafeError("path-mismatch", "fallback temp path changed during write");
|
|
5128
5293
|
}
|
|
5129
5294
|
const expectedTempStat = tempStat;
|
|
5130
|
-
await handle
|
|
5295
|
+
await syncFileBestEffort(handle);
|
|
5131
5296
|
await handle.close().catch(() => undefined);
|
|
5132
5297
|
handle = undefined;
|
|
5133
5298
|
await withAsyncDirectoryGuards([parentGuard], async () => {
|
|
@@ -6036,16 +6201,104 @@ function assertNoUnsafeDeviceReadPath(filePath, options) {
|
|
|
6036
6201
|
}
|
|
6037
6202
|
}
|
|
6038
6203
|
|
|
6204
|
+
;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/bounded-read.js
|
|
6205
|
+
|
|
6206
|
+
|
|
6207
|
+
const READ_CHUNK_BYTES = 64 * 1024;
|
|
6208
|
+
function assertMaxBytes(maxBytes) {
|
|
6209
|
+
if (maxBytes === Number.POSITIVE_INFINITY) {
|
|
6210
|
+
return;
|
|
6211
|
+
}
|
|
6212
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0) {
|
|
6213
|
+
throw new RangeError("maxBytes must be a non-negative safe integer or Infinity");
|
|
6214
|
+
}
|
|
6215
|
+
}
|
|
6216
|
+
function createScratchBuffer(maxBytes) {
|
|
6217
|
+
const initialReadBytes = Number.isFinite(maxBytes)
|
|
6218
|
+
? Math.min(READ_CHUNK_BYTES, maxBytes + 1)
|
|
6219
|
+
: READ_CHUNK_BYTES;
|
|
6220
|
+
return Buffer.allocUnsafe(Math.max(1, initialReadBytes));
|
|
6221
|
+
}
|
|
6222
|
+
function nextReadLength(total, maxBytes, capacity) {
|
|
6223
|
+
return Number.isFinite(maxBytes)
|
|
6224
|
+
? Math.min(capacity, maxBytes - total + 1)
|
|
6225
|
+
: capacity;
|
|
6226
|
+
}
|
|
6227
|
+
function appendChunk(params) {
|
|
6228
|
+
const total = params.total + params.bytesRead;
|
|
6229
|
+
if (total > params.maxBytes) {
|
|
6230
|
+
throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got at least ${total})`);
|
|
6231
|
+
}
|
|
6232
|
+
params.chunks.push(Buffer.from(params.scratch.subarray(0, params.bytesRead)));
|
|
6233
|
+
return total;
|
|
6234
|
+
}
|
|
6235
|
+
async function readBoundedAsync(maxBytes, readChunk) {
|
|
6236
|
+
assertMaxBytes(maxBytes);
|
|
6237
|
+
const chunks = [];
|
|
6238
|
+
const scratch = createScratchBuffer(maxBytes);
|
|
6239
|
+
let total = 0;
|
|
6240
|
+
while (true) {
|
|
6241
|
+
const length = nextReadLength(total, maxBytes, scratch.length);
|
|
6242
|
+
const bytesRead = await readChunk(scratch, length);
|
|
6243
|
+
if (bytesRead === 0) {
|
|
6244
|
+
return Buffer.concat(chunks, total);
|
|
6245
|
+
}
|
|
6246
|
+
total = appendChunk({ chunks, scratch, bytesRead, total, maxBytes });
|
|
6247
|
+
}
|
|
6248
|
+
}
|
|
6249
|
+
/**
|
|
6250
|
+
* Reads from the handle's current offset without closing it. A bounded read
|
|
6251
|
+
* consumes at most maxBytes + 1 bytes so growth after an earlier stat cannot
|
|
6252
|
+
* force an unbounded allocation.
|
|
6253
|
+
*/
|
|
6254
|
+
async function readFileHandleBounded(handle, maxBytes) {
|
|
6255
|
+
return await readBoundedAsync(maxBytes, async (scratch, length) => {
|
|
6256
|
+
return (await handle.read(scratch, 0, length, null)).bytesRead;
|
|
6257
|
+
});
|
|
6258
|
+
}
|
|
6259
|
+
function readDescriptorChunk(fd, scratch, length) {
|
|
6260
|
+
return new Promise((resolve, reject) => {
|
|
6261
|
+
fs.read(fd, scratch, 0, length, null, (error, bytesRead) => {
|
|
6262
|
+
if (error) {
|
|
6263
|
+
reject(error);
|
|
6264
|
+
return;
|
|
6265
|
+
}
|
|
6266
|
+
resolve(bytesRead);
|
|
6267
|
+
});
|
|
6268
|
+
});
|
|
6269
|
+
}
|
|
6270
|
+
/** Async bounded read from a numeric descriptor. The caller owns the descriptor. */
|
|
6271
|
+
async function readFileDescriptorBounded(fd, maxBytes) {
|
|
6272
|
+
return await readBoundedAsync(maxBytes, async (scratch, length) => {
|
|
6273
|
+
return await readDescriptorChunk(fd, scratch, length);
|
|
6274
|
+
});
|
|
6275
|
+
}
|
|
6276
|
+
/** Sync bounded read from a numeric descriptor. The caller owns the descriptor. */
|
|
6277
|
+
function readFileDescriptorBoundedSync(fd, maxBytes) {
|
|
6278
|
+
assertMaxBytes(maxBytes);
|
|
6279
|
+
const chunks = [];
|
|
6280
|
+
const scratch = createScratchBuffer(maxBytes);
|
|
6281
|
+
let total = 0;
|
|
6282
|
+
while (true) {
|
|
6283
|
+
const length = nextReadLength(total, maxBytes, scratch.length);
|
|
6284
|
+
const bytesRead = fs.readSync(fd, scratch, 0, length, null);
|
|
6285
|
+
if (bytesRead === 0) {
|
|
6286
|
+
return Buffer.concat(chunks, total);
|
|
6287
|
+
}
|
|
6288
|
+
total = appendChunk({ chunks, scratch, bytesRead, total, maxBytes });
|
|
6289
|
+
}
|
|
6290
|
+
}
|
|
6291
|
+
|
|
6039
6292
|
;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/read-opened-file.js
|
|
6040
6293
|
|
|
6294
|
+
|
|
6041
6295
|
async function read_opened_file_readOpenedFileSafely(params) {
|
|
6042
6296
|
if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
|
|
6043
6297
|
throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
|
|
6044
6298
|
}
|
|
6045
|
-
const buffer =
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
}
|
|
6299
|
+
const buffer = params.maxBytes === undefined
|
|
6300
|
+
? await params.opened.handle.readFile()
|
|
6301
|
+
: await readFileHandleBounded(params.opened.handle, params.maxBytes);
|
|
6049
6302
|
return {
|
|
6050
6303
|
buffer,
|
|
6051
6304
|
realPath: params.opened.realPath,
|
|
@@ -62073,4 +62326,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
|
|
|
62073
62326
|
// module factories are used so entry inlining is disabled
|
|
62074
62327
|
// startup
|
|
62075
62328
|
// Load entry module and return exports
|
|
62076
|
-
var __webpack_exports__ = __webpack_require__(
|
|
62329
|
+
var __webpack_exports__ = __webpack_require__(580);
|
package/package.json
CHANGED
|
@@ -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.
|
|
13
|
+
"version": "v2.1.218"
|
|
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",
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
"@emotion/server": "11.11.0",
|
|
17
17
|
"@mui/material": "9.2.0",
|
|
18
18
|
"@mui/material-nextjs": "9.1.1",
|
|
19
|
-
"next": "16.2.
|
|
19
|
+
"next": "16.2.11",
|
|
20
20
|
"react": "19.2.8",
|
|
21
21
|
"react-dom": "19.2.8"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@biomejs/biome": "2.5.3",
|
|
25
25
|
"@eslint/eslintrc": "3.3.6",
|
|
26
|
-
"@lousy-agents/mcp": "5.17.
|
|
26
|
+
"@lousy-agents/mcp": "5.17.8",
|
|
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",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"@vitejs/plugin-react": "6.0.4",
|
|
35
35
|
"@vitest/ui": "4.1.10",
|
|
36
36
|
"eslint": "10.7.0",
|
|
37
|
-
"eslint-config-next": "16.2.
|
|
38
|
-
"happy-dom": "20.11.
|
|
37
|
+
"eslint-config-next": "16.2.11",
|
|
38
|
+
"happy-dom": "20.11.1",
|
|
39
39
|
"jsdom": "29.1.1",
|
|
40
40
|
"typescript": "7.0.2",
|
|
41
41
|
"vitest": "4.1.10",
|