chatroom-cli 1.65.1 → 1.65.2
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/index.js +2583 -650
- package/dist/index.js.map +15 -11
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -88419,6 +88419,379 @@ function gunzipBase64Payload(base64, maxBytes) {
|
|
|
88419
88419
|
}
|
|
88420
88420
|
var init_workspace_path_security = () => {};
|
|
88421
88421
|
|
|
88422
|
+
// src/infrastructure/services/workspace/workspace-visibility-policy.ts
|
|
88423
|
+
function isAlwaysExcludedDirName(name) {
|
|
88424
|
+
return ALWAYS_EXCLUDE_DIR_NAMES.has(name);
|
|
88425
|
+
}
|
|
88426
|
+
function isSecretPath(relativePath) {
|
|
88427
|
+
const normalized = relativePath.replace(/\\/g, "/");
|
|
88428
|
+
return SECRET_PATH_PATTERNS.some((pattern2) => pattern2.test(normalized));
|
|
88429
|
+
}
|
|
88430
|
+
function hasExcludedDirSegment(relativePath) {
|
|
88431
|
+
const segments = relativePath.split("/");
|
|
88432
|
+
return segments.some((segment) => isAlwaysExcludedDirName(segment));
|
|
88433
|
+
}
|
|
88434
|
+
function isPathVisible(relativePath) {
|
|
88435
|
+
if (!relativePath)
|
|
88436
|
+
return true;
|
|
88437
|
+
return !isSecretPath(relativePath) && !hasExcludedDirSegment(relativePath);
|
|
88438
|
+
}
|
|
88439
|
+
function isPathContentReadable(relativePath) {
|
|
88440
|
+
return isPathVisible(relativePath);
|
|
88441
|
+
}
|
|
88442
|
+
var ALWAYS_EXCLUDE_DIR_NAMES, SECRET_PATH_PATTERNS;
|
|
88443
|
+
var init_workspace_visibility_policy = __esm(() => {
|
|
88444
|
+
ALWAYS_EXCLUDE_DIR_NAMES = new Set([
|
|
88445
|
+
"node_modules",
|
|
88446
|
+
".git",
|
|
88447
|
+
"dist",
|
|
88448
|
+
"build",
|
|
88449
|
+
".next",
|
|
88450
|
+
"coverage",
|
|
88451
|
+
"__pycache__",
|
|
88452
|
+
".turbo",
|
|
88453
|
+
".cache",
|
|
88454
|
+
".tmp",
|
|
88455
|
+
"tmp",
|
|
88456
|
+
"_generated",
|
|
88457
|
+
".vercel"
|
|
88458
|
+
]);
|
|
88459
|
+
SECRET_PATH_PATTERNS = [
|
|
88460
|
+
/^\.env$/,
|
|
88461
|
+
/^\.env\./,
|
|
88462
|
+
/\.pem$/,
|
|
88463
|
+
/\.key$/,
|
|
88464
|
+
/id_rsa$/,
|
|
88465
|
+
/credentials\.json$/,
|
|
88466
|
+
/^secrets(\/|$)/,
|
|
88467
|
+
/^\.aws(\/|$)/
|
|
88468
|
+
];
|
|
88469
|
+
});
|
|
88470
|
+
|
|
88471
|
+
// src/commands/machine/daemon-start/file-content-fulfillment.ts
|
|
88472
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
88473
|
+
import { gzipSync as gzipSync2 } from "node:zlib";
|
|
88474
|
+
function getErrorCause(error) {
|
|
88475
|
+
if (typeof error === "object" && error !== null && "cause" in error && error.cause !== undefined) {
|
|
88476
|
+
return error.cause;
|
|
88477
|
+
}
|
|
88478
|
+
return error;
|
|
88479
|
+
}
|
|
88480
|
+
function isENOENT(error) {
|
|
88481
|
+
const cause3 = getErrorCause(error);
|
|
88482
|
+
return typeof cause3 === "object" && cause3 !== null && "code" in cause3 && cause3.code === "ENOENT";
|
|
88483
|
+
}
|
|
88484
|
+
function isBinaryFile(path3) {
|
|
88485
|
+
const lastDot = path3.lastIndexOf(".");
|
|
88486
|
+
if (lastDot === -1)
|
|
88487
|
+
return false;
|
|
88488
|
+
return BINARY_EXTENSIONS.has(path3.slice(lastDot).toLowerCase());
|
|
88489
|
+
}
|
|
88490
|
+
function gzipPlainText(text) {
|
|
88491
|
+
return gzipSync2(Buffer.from(text)).toString("base64");
|
|
88492
|
+
}
|
|
88493
|
+
function fulfillGzippedContentEffect(session2, workingDir, filePath, plainText, truncated) {
|
|
88494
|
+
return exports_Effect.catchAll(exports_Effect.tryPromise(() => session2.backend.mutation(api.workspaceFiles.fulfillFileContentV2, {
|
|
88495
|
+
sessionId: session2.sessionId,
|
|
88496
|
+
machineId: session2.machineId,
|
|
88497
|
+
workingDir,
|
|
88498
|
+
filePath,
|
|
88499
|
+
data: { compression: "gzip", content: gzipPlainText(plainText) },
|
|
88500
|
+
encoding: "utf8",
|
|
88501
|
+
truncated
|
|
88502
|
+
})), () => exports_Effect.void);
|
|
88503
|
+
}
|
|
88504
|
+
var MAX_CONTENT_BYTES, BINARY_EXTENSIONS, fulfillFileContentRequestsEffect;
|
|
88505
|
+
var init_file_content_fulfillment = __esm(() => {
|
|
88506
|
+
init_esm();
|
|
88507
|
+
init_daemon_services();
|
|
88508
|
+
init_api3();
|
|
88509
|
+
init_assert_registered_working_dir();
|
|
88510
|
+
init_workspace_path_security();
|
|
88511
|
+
init_workspace_visibility_policy();
|
|
88512
|
+
MAX_CONTENT_BYTES = 500 * 1024;
|
|
88513
|
+
BINARY_EXTENSIONS = new Set([
|
|
88514
|
+
".png",
|
|
88515
|
+
".jpg",
|
|
88516
|
+
".jpeg",
|
|
88517
|
+
".gif",
|
|
88518
|
+
".webp",
|
|
88519
|
+
".ico",
|
|
88520
|
+
".svg",
|
|
88521
|
+
".mp3",
|
|
88522
|
+
".mp4",
|
|
88523
|
+
".wav",
|
|
88524
|
+
".ogg",
|
|
88525
|
+
".webm",
|
|
88526
|
+
".zip",
|
|
88527
|
+
".tar",
|
|
88528
|
+
".gz",
|
|
88529
|
+
".bz2",
|
|
88530
|
+
".7z",
|
|
88531
|
+
".rar",
|
|
88532
|
+
".pdf",
|
|
88533
|
+
".doc",
|
|
88534
|
+
".docx",
|
|
88535
|
+
".xls",
|
|
88536
|
+
".xlsx",
|
|
88537
|
+
".ppt",
|
|
88538
|
+
".pptx",
|
|
88539
|
+
".woff",
|
|
88540
|
+
".woff2",
|
|
88541
|
+
".ttf",
|
|
88542
|
+
".otf",
|
|
88543
|
+
".eot",
|
|
88544
|
+
".exe",
|
|
88545
|
+
".dll",
|
|
88546
|
+
".so",
|
|
88547
|
+
".dylib",
|
|
88548
|
+
".bin",
|
|
88549
|
+
".dat",
|
|
88550
|
+
".db",
|
|
88551
|
+
".sqlite"
|
|
88552
|
+
]);
|
|
88553
|
+
fulfillFileContentRequestsEffect = exports_Effect.gen(function* () {
|
|
88554
|
+
const session2 = yield* DaemonSessionService;
|
|
88555
|
+
const requests = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => session2.backend.query(api.workspaceFiles.getPendingFileContentRequests, {
|
|
88556
|
+
sessionId: session2.sessionId,
|
|
88557
|
+
machineId: session2.machineId
|
|
88558
|
+
})), () => exports_Effect.succeed([]));
|
|
88559
|
+
if (requests.length === 0)
|
|
88560
|
+
return;
|
|
88561
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCE5 Received ${requests.length} pending file content request(s): ${requests.map((r) => r.filePath).join(", ")}`);
|
|
88562
|
+
for (const request2 of requests) {
|
|
88563
|
+
const startTime = Date.now();
|
|
88564
|
+
const { workingDir, filePath } = request2;
|
|
88565
|
+
const registered = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => assertRegisteredWorkingDir(session2, workingDir)), () => exports_Effect.succeed({ ok: false, error: "Workspace check failed" }));
|
|
88566
|
+
if (!registered.ok) {
|
|
88567
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Rejected unregistered workspace: ${workingDir} (${registered.error})`);
|
|
88568
|
+
yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[Error: workspace not registered]", false);
|
|
88569
|
+
continue;
|
|
88570
|
+
}
|
|
88571
|
+
const resolved = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => resolvePathWithinWorkspace(workingDir, filePath)), () => exports_Effect.succeed({ ok: false, error: "Invalid file path" }));
|
|
88572
|
+
if (!resolved.ok) {
|
|
88573
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Rejected file path: ${filePath} (${resolved.error})`);
|
|
88574
|
+
yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[Error reading file]", false);
|
|
88575
|
+
continue;
|
|
88576
|
+
}
|
|
88577
|
+
const absolutePath = resolved.absolutePath;
|
|
88578
|
+
if (isBinaryFile(filePath)) {
|
|
88579
|
+
yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[Binary file]", false);
|
|
88580
|
+
const elapsed4 = Date.now() - startTime;
|
|
88581
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content synced to Convex: ${filePath} [binary] (${elapsed4}ms)`);
|
|
88582
|
+
continue;
|
|
88583
|
+
}
|
|
88584
|
+
if (!isPathContentReadable(filePath)) {
|
|
88585
|
+
yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[File blocked: cannot open sensitive path in remote explorer]", false);
|
|
88586
|
+
const elapsed4 = Date.now() - startTime;
|
|
88587
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content blocked: ${filePath} [secret] (${elapsed4}ms)`);
|
|
88588
|
+
continue;
|
|
88589
|
+
}
|
|
88590
|
+
const readOutcome = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => readFile7(absolutePath)).pipe(exports_Effect.map((buffer) => {
|
|
88591
|
+
if (buffer.length > MAX_CONTENT_BYTES) {
|
|
88592
|
+
return {
|
|
88593
|
+
kind: "ok",
|
|
88594
|
+
content: buffer.subarray(0, MAX_CONTENT_BYTES).toString("utf8"),
|
|
88595
|
+
truncated: true
|
|
88596
|
+
};
|
|
88597
|
+
}
|
|
88598
|
+
return {
|
|
88599
|
+
kind: "ok",
|
|
88600
|
+
content: buffer.toString("utf8"),
|
|
88601
|
+
truncated: false
|
|
88602
|
+
};
|
|
88603
|
+
})), (error) => isENOENT(error) ? exports_Effect.succeed({ kind: "missing" }) : exports_Effect.succeed({
|
|
88604
|
+
kind: "error",
|
|
88605
|
+
content: "[Error reading file]",
|
|
88606
|
+
truncated: false
|
|
88607
|
+
}));
|
|
88608
|
+
if (readOutcome.kind === "missing") {
|
|
88609
|
+
console.log(`[${formatTimestamp()}] ⏳ File not on disk yet, deferring content sync: ${filePath}`);
|
|
88610
|
+
continue;
|
|
88611
|
+
}
|
|
88612
|
+
const { content, truncated } = readOutcome.kind === "ok" ? readOutcome : { content: readOutcome.content, truncated: readOutcome.truncated };
|
|
88613
|
+
const compressed = gzipSync2(Buffer.from(content));
|
|
88614
|
+
const contentCompressed = compressed.toString("base64");
|
|
88615
|
+
yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => session2.backend.mutation(api.workspaceFiles.fulfillFileContentV2, {
|
|
88616
|
+
sessionId: session2.sessionId,
|
|
88617
|
+
machineId: session2.machineId,
|
|
88618
|
+
workingDir,
|
|
88619
|
+
filePath,
|
|
88620
|
+
data: { compression: "gzip", content: contentCompressed },
|
|
88621
|
+
encoding: "utf8",
|
|
88622
|
+
truncated
|
|
88623
|
+
})), () => exports_Effect.void);
|
|
88624
|
+
const elapsed3 = Date.now() - startTime;
|
|
88625
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC4 File content synced to Convex: ${filePath} (${(Buffer.byteLength(content) / 1024).toFixed(1)}KB → ${(compressed.length / 1024).toFixed(1)}KB gzip, ${elapsed3}ms)`);
|
|
88626
|
+
}
|
|
88627
|
+
});
|
|
88628
|
+
});
|
|
88629
|
+
|
|
88630
|
+
// src/commands/machine/daemon-start/file-content-subscription.ts
|
|
88631
|
+
var startFileContentSubscriptionEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
88632
|
+
const session2 = yield* DaemonSessionService;
|
|
88633
|
+
let processing = false;
|
|
88634
|
+
const unsubscribe = wsClient2.onUpdate(api.workspaceFiles.getPendingFileContentRequests, {
|
|
88635
|
+
sessionId: session2.sessionId,
|
|
88636
|
+
machineId: session2.machineId
|
|
88637
|
+
}, (requests) => {
|
|
88638
|
+
if (!requests || requests.length === 0)
|
|
88639
|
+
return;
|
|
88640
|
+
if (processing)
|
|
88641
|
+
return;
|
|
88642
|
+
processing = true;
|
|
88643
|
+
exports_Effect.runPromise(fulfillFileContentRequestsEffect.pipe(exports_Effect.provideService(DaemonSessionService, session2))).catch((err) => {
|
|
88644
|
+
console.warn(`[${formatTimestamp()}] ⚠️ File content subscription processing failed: ${getErrorMessage2(err)}`);
|
|
88645
|
+
}).finally(() => {
|
|
88646
|
+
processing = false;
|
|
88647
|
+
});
|
|
88648
|
+
}, (err) => {
|
|
88649
|
+
console.warn(`[${formatTimestamp()}] ⚠️ File content subscription error: ${getErrorMessage2(err)}`);
|
|
88650
|
+
});
|
|
88651
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC2 File content subscription started (reactive)`);
|
|
88652
|
+
return {
|
|
88653
|
+
stop: () => {
|
|
88654
|
+
unsubscribe();
|
|
88655
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC2 File content subscription stopped`);
|
|
88656
|
+
}
|
|
88657
|
+
};
|
|
88658
|
+
});
|
|
88659
|
+
var init_file_content_subscription = __esm(() => {
|
|
88660
|
+
init_esm();
|
|
88661
|
+
init_daemon_services();
|
|
88662
|
+
init_file_content_fulfillment();
|
|
88663
|
+
init_api3();
|
|
88664
|
+
init_convex_error();
|
|
88665
|
+
});
|
|
88666
|
+
|
|
88667
|
+
// src/infrastructure/services/workspace/file-tree-data-hash.ts
|
|
88668
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
88669
|
+
function computeFileTreeDataHash(tree) {
|
|
88670
|
+
return createHash4("md5").update(JSON.stringify(tree)).digest("hex");
|
|
88671
|
+
}
|
|
88672
|
+
var init_file_tree_data_hash = () => {};
|
|
88673
|
+
|
|
88674
|
+
// src/infrastructure/services/workspace/file-tree-partition.ts
|
|
88675
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
88676
|
+
import { gzipSync as gzipSync3 } from "node:zlib";
|
|
88677
|
+
function computeShardDataHash(payload) {
|
|
88678
|
+
return createHash5("md5").update(JSON.stringify(payload)).digest("hex");
|
|
88679
|
+
}
|
|
88680
|
+
function shardIdForPath(path3) {
|
|
88681
|
+
const slash = path3.indexOf("/");
|
|
88682
|
+
return slash === -1 ? "__root__" : path3.slice(0, slash);
|
|
88683
|
+
}
|
|
88684
|
+
function shouldUseV3Upload(tree) {
|
|
88685
|
+
return Buffer.byteLength(JSON.stringify(tree), "utf8") > MAX_TREE_JSON_BYTES;
|
|
88686
|
+
}
|
|
88687
|
+
function childShardId(path3, parentShardId) {
|
|
88688
|
+
if (parentShardId === "__root__") {
|
|
88689
|
+
return shardIdForPath(path3);
|
|
88690
|
+
}
|
|
88691
|
+
if (path3 === parentShardId) {
|
|
88692
|
+
return parentShardId;
|
|
88693
|
+
}
|
|
88694
|
+
const prefix = `${parentShardId}/`;
|
|
88695
|
+
if (!path3.startsWith(prefix)) {
|
|
88696
|
+
return parentShardId;
|
|
88697
|
+
}
|
|
88698
|
+
const remainder = path3.slice(prefix.length);
|
|
88699
|
+
const slash = remainder.indexOf("/");
|
|
88700
|
+
return slash === -1 ? parentShardId : `${parentShardId}/${remainder.slice(0, slash)}`;
|
|
88701
|
+
}
|
|
88702
|
+
function groupEntriesByShardId(entries2, parentShardId) {
|
|
88703
|
+
const groups = new Map;
|
|
88704
|
+
for (const entry of entries2) {
|
|
88705
|
+
const shardId = parentShardId === "__root__" ? shardIdForPath(entry.path) : childShardId(entry.path, parentShardId);
|
|
88706
|
+
const group = groups.get(shardId) ?? [];
|
|
88707
|
+
group.push(entry);
|
|
88708
|
+
groups.set(shardId, group);
|
|
88709
|
+
}
|
|
88710
|
+
return groups;
|
|
88711
|
+
}
|
|
88712
|
+
function buildPreparedShard(shardId, payload) {
|
|
88713
|
+
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
88714
|
+
return {
|
|
88715
|
+
shardId,
|
|
88716
|
+
payload,
|
|
88717
|
+
dataHash: computeShardDataHash(payload),
|
|
88718
|
+
entryCount: payload.entries.length,
|
|
88719
|
+
data: { compression: "gzip", content: compressed }
|
|
88720
|
+
};
|
|
88721
|
+
}
|
|
88722
|
+
function prepareShardGroup(entries2, shardId, tree) {
|
|
88723
|
+
const payload = {
|
|
88724
|
+
entries: entries2,
|
|
88725
|
+
scannedAt: tree.scannedAt,
|
|
88726
|
+
rootDir: tree.rootDir
|
|
88727
|
+
};
|
|
88728
|
+
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
88729
|
+
if (Buffer.byteLength(compressed, "utf8") <= MAX_SHARD_JSON_BYTES) {
|
|
88730
|
+
return [buildPreparedShard(shardId, payload)];
|
|
88731
|
+
}
|
|
88732
|
+
const subgroups = groupEntriesByShardId(entries2, shardId);
|
|
88733
|
+
if (subgroups.size <= 1) {
|
|
88734
|
+
return [buildPreparedShard(shardId, payload)];
|
|
88735
|
+
}
|
|
88736
|
+
const shards = [];
|
|
88737
|
+
for (const [subId, subEntries] of subgroups) {
|
|
88738
|
+
shards.push(...prepareShardGroup(subEntries, subId, tree));
|
|
88739
|
+
}
|
|
88740
|
+
return shards;
|
|
88741
|
+
}
|
|
88742
|
+
function partitionFileTree(tree) {
|
|
88743
|
+
const topGroups = groupEntriesByShardId(tree.entries, "__root__");
|
|
88744
|
+
const shards = [];
|
|
88745
|
+
for (const [shardId, entries2] of topGroups) {
|
|
88746
|
+
shards.push(...prepareShardGroup(entries2, shardId, tree));
|
|
88747
|
+
}
|
|
88748
|
+
return shards;
|
|
88749
|
+
}
|
|
88750
|
+
var MAX_TREE_JSON_BYTES, MAX_SHARD_JSON_BYTES, MAX_SHARD_BATCH_SIZE = 8;
|
|
88751
|
+
var init_file_tree_partition = __esm(() => {
|
|
88752
|
+
MAX_TREE_JSON_BYTES = 900 * 1024;
|
|
88753
|
+
MAX_SHARD_JSON_BYTES = 800 * 1024;
|
|
88754
|
+
});
|
|
88755
|
+
|
|
88756
|
+
// src/infrastructure/services/workspace/file-tree-v3-upload.ts
|
|
88757
|
+
async function uploadFileTreeV3(session2, workingDir, tree, syncGeneration) {
|
|
88758
|
+
const shards = partitionFileTree(tree);
|
|
88759
|
+
const shardIds = [];
|
|
88760
|
+
for (let i2 = 0;i2 < shards.length; i2 += MAX_SHARD_BATCH_SIZE) {
|
|
88761
|
+
const batch = shards.slice(i2, i2 + MAX_SHARD_BATCH_SIZE);
|
|
88762
|
+
await session2.backend.mutation(api.workspaceFiles.syncFileTreeShardV3Batch, {
|
|
88763
|
+
sessionId: session2.sessionId,
|
|
88764
|
+
machineId: session2.machineId,
|
|
88765
|
+
workingDir,
|
|
88766
|
+
syncGeneration,
|
|
88767
|
+
items: batch.map((s) => ({
|
|
88768
|
+
shardId: s.shardId,
|
|
88769
|
+
data: s.data,
|
|
88770
|
+
dataHash: s.dataHash,
|
|
88771
|
+
scannedAt: tree.scannedAt,
|
|
88772
|
+
entryCount: s.entryCount
|
|
88773
|
+
}))
|
|
88774
|
+
});
|
|
88775
|
+
for (const s of batch)
|
|
88776
|
+
shardIds.push(s.shardId);
|
|
88777
|
+
}
|
|
88778
|
+
await session2.backend.mutation(api.workspaceFiles.syncFileTreeManifestV3, {
|
|
88779
|
+
sessionId: session2.sessionId,
|
|
88780
|
+
machineId: session2.machineId,
|
|
88781
|
+
workingDir,
|
|
88782
|
+
syncGeneration,
|
|
88783
|
+
shardIds,
|
|
88784
|
+
totalEntryCount: tree.entries.length,
|
|
88785
|
+
complete: true,
|
|
88786
|
+
scannedAt: tree.scannedAt
|
|
88787
|
+
});
|
|
88788
|
+
return { shardIds, totalEntryCount: tree.entries.length };
|
|
88789
|
+
}
|
|
88790
|
+
var init_file_tree_v3_upload = __esm(() => {
|
|
88791
|
+
init_file_tree_partition();
|
|
88792
|
+
init_api3();
|
|
88793
|
+
});
|
|
88794
|
+
|
|
88422
88795
|
// ../../node_modules/.pnpm/ignore@7.0.5/node_modules/ignore/index.js
|
|
88423
88796
|
var require_ignore = __commonJS((exports, module) => {
|
|
88424
88797
|
function makeArray(subject) {
|
|
@@ -88747,574 +89120,1839 @@ var require_ignore = __commonJS((exports, module) => {
|
|
|
88747
89120
|
});
|
|
88748
89121
|
|
|
88749
89122
|
// src/infrastructure/services/workspace/workspace-ignore.ts
|
|
88750
|
-
import { readFile as
|
|
89123
|
+
import { readFile as readFile8 } from "node:fs/promises";
|
|
88751
89124
|
import path3 from "node:path";
|
|
88752
|
-
|
|
88753
|
-
|
|
88754
|
-
for (const name of IGNORE_FILES) {
|
|
88755
|
-
try {
|
|
88756
|
-
const content = await readFile7(path3.join(rootDir, name), "utf-8");
|
|
88757
|
-
ig.add(content);
|
|
88758
|
-
} catch {}
|
|
88759
|
-
}
|
|
88760
|
-
return ig;
|
|
88761
|
-
}
|
|
88762
|
-
function isPathIgnoredByRules(ig, relativePath) {
|
|
88763
|
-
const normalized = relativePath.replace(/\\/g, "/");
|
|
88764
|
-
return ig.ignores(normalized);
|
|
88765
|
-
}
|
|
88766
|
-
var import_ignore, IGNORE_FILES;
|
|
88767
|
-
var init_workspace_ignore = __esm(() => {
|
|
88768
|
-
import_ignore = __toESM(require_ignore(), 1);
|
|
88769
|
-
IGNORE_FILES = [".gitignore", ".cursorignore"];
|
|
88770
|
-
});
|
|
88771
|
-
|
|
88772
|
-
// src/infrastructure/services/workspace/workspace-visibility-policy.ts
|
|
88773
|
-
import { spawn as spawn6 } from "node:child_process";
|
|
88774
|
-
function isAlwaysExcludedDirName(name) {
|
|
88775
|
-
return ALWAYS_EXCLUDE_DIR_NAMES.has(name);
|
|
89125
|
+
function normalizeRelativePath(relativePath) {
|
|
89126
|
+
return relativePath.replace(/\\/g, "/").replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
88776
89127
|
}
|
|
88777
|
-
function
|
|
88778
|
-
|
|
88779
|
-
|
|
88780
|
-
}
|
|
88781
|
-
|
|
88782
|
-
|
|
88783
|
-
return segments.some((segment) => isAlwaysExcludedDirName(segment));
|
|
88784
|
-
}
|
|
88785
|
-
function isPathVisible(relativePath) {
|
|
88786
|
-
if (!relativePath)
|
|
88787
|
-
return true;
|
|
88788
|
-
return !isSecretPath(relativePath) && !hasExcludedDirSegment(relativePath);
|
|
89128
|
+
async function readIgnoreFile(filePath) {
|
|
89129
|
+
try {
|
|
89130
|
+
return await readFile8(filePath, "utf-8");
|
|
89131
|
+
} catch {
|
|
89132
|
+
return null;
|
|
89133
|
+
}
|
|
88789
89134
|
}
|
|
88790
|
-
function
|
|
88791
|
-
|
|
89135
|
+
async function loadDirectoryIgnoreRuleSets(rootDir, relativeDir) {
|
|
89136
|
+
const normalizedDir = normalizeRelativePath(relativeDir);
|
|
89137
|
+
const absoluteDir = normalizedDir ? path3.join(rootDir, normalizedDir) : rootDir;
|
|
89138
|
+
const names = normalizedDir ? [".gitignore"] : IGNORE_FILES;
|
|
89139
|
+
const result = [];
|
|
89140
|
+
for (const name of names) {
|
|
89141
|
+
const content = await readIgnoreFile(path3.join(absoluteDir, name));
|
|
89142
|
+
if (content === null)
|
|
89143
|
+
continue;
|
|
89144
|
+
result.push({ baseDir: normalizedDir, matcher: import_ignore.default().add(content) });
|
|
89145
|
+
}
|
|
89146
|
+
return result;
|
|
88792
89147
|
}
|
|
88793
|
-
|
|
88794
|
-
|
|
88795
|
-
|
|
88796
|
-
const
|
|
88797
|
-
|
|
88798
|
-
|
|
88799
|
-
|
|
88800
|
-
|
|
88801
|
-
|
|
88802
|
-
|
|
88803
|
-
|
|
89148
|
+
function isPathIgnoredByRuleSets(ruleSets, relativePath) {
|
|
89149
|
+
const normalized = normalizeRelativePath(relativePath);
|
|
89150
|
+
let ignored = false;
|
|
89151
|
+
for (const ruleSet of ruleSets) {
|
|
89152
|
+
if (ruleSet.baseDir && normalized !== ruleSet.baseDir && !normalized.startsWith(`${ruleSet.baseDir}/`)) {
|
|
89153
|
+
continue;
|
|
89154
|
+
}
|
|
89155
|
+
const localPath = ruleSet.baseDir ? normalized.slice(ruleSet.baseDir.length).replace(/^\/+/, "") : normalized;
|
|
89156
|
+
if (!localPath)
|
|
89157
|
+
continue;
|
|
89158
|
+
const result = ruleSet.matcher.test(localPath);
|
|
89159
|
+
if (result.ignored)
|
|
89160
|
+
ignored = true;
|
|
89161
|
+
else if (result.unignored)
|
|
89162
|
+
ignored = false;
|
|
88804
89163
|
}
|
|
88805
89164
|
return ignored;
|
|
88806
89165
|
}
|
|
88807
|
-
async function
|
|
88808
|
-
|
|
88809
|
-
|
|
88810
|
-
const
|
|
88811
|
-
|
|
88812
|
-
|
|
88813
|
-
|
|
88814
|
-
|
|
88815
|
-
|
|
88816
|
-
cwd: rootDir,
|
|
88817
|
-
env: { ...process.env, GIT_TERMINAL_PROMPT: "0", GIT_PAGER: "cat", NO_COLOR: "1" }
|
|
88818
|
-
});
|
|
88819
|
-
let output = "";
|
|
88820
|
-
child.stdout.on("data", (chunk2) => {
|
|
88821
|
-
output += chunk2.toString();
|
|
88822
|
-
});
|
|
88823
|
-
child.on("error", reject);
|
|
88824
|
-
child.on("close", () => resolve5(output));
|
|
88825
|
-
child.stdin.write(relativePaths.join(`
|
|
88826
|
-
`));
|
|
88827
|
-
child.stdin.end();
|
|
88828
|
-
});
|
|
88829
|
-
const ignored = new Set;
|
|
88830
|
-
if (!stdout)
|
|
88831
|
-
return ignored;
|
|
88832
|
-
for (const entry of stdout.split("\x00")) {
|
|
88833
|
-
const trimmed = entry.trim();
|
|
88834
|
-
if (trimmed)
|
|
88835
|
-
ignored.add(trimmed);
|
|
88836
|
-
}
|
|
88837
|
-
return ignored;
|
|
88838
|
-
} catch {
|
|
88839
|
-
return new Set;
|
|
89166
|
+
async function loadApplicableIgnoreRuleSets(rootDir, relativePath) {
|
|
89167
|
+
const normalized = normalizeRelativePath(relativePath);
|
|
89168
|
+
const parentParts = normalized.split("/").slice(0, -1);
|
|
89169
|
+
const ruleSets = [];
|
|
89170
|
+
ruleSets.push(...await loadDirectoryIgnoreRuleSets(rootDir, ""));
|
|
89171
|
+
let currentDir = "";
|
|
89172
|
+
for (const part of parentParts) {
|
|
89173
|
+
currentDir = currentDir ? `${currentDir}/${part}` : part;
|
|
89174
|
+
ruleSets.push(...await loadDirectoryIgnoreRuleSets(rootDir, currentDir));
|
|
88840
89175
|
}
|
|
89176
|
+
return ruleSets;
|
|
88841
89177
|
}
|
|
88842
|
-
|
|
88843
|
-
|
|
88844
|
-
|
|
88845
|
-
|
|
88846
|
-
|
|
88847
|
-
|
|
88848
|
-
|
|
88849
|
-
|
|
88850
|
-
"build",
|
|
88851
|
-
".next",
|
|
88852
|
-
"coverage",
|
|
88853
|
-
"__pycache__",
|
|
88854
|
-
".turbo",
|
|
88855
|
-
".cache",
|
|
88856
|
-
".tmp",
|
|
88857
|
-
"tmp",
|
|
88858
|
-
"_generated",
|
|
88859
|
-
".vercel"
|
|
88860
|
-
]);
|
|
88861
|
-
SECRET_PATH_PATTERNS = [
|
|
88862
|
-
/^\.env$/,
|
|
88863
|
-
/^\.env\./,
|
|
88864
|
-
/\.pem$/,
|
|
88865
|
-
/\.key$/,
|
|
88866
|
-
/id_rsa$/,
|
|
88867
|
-
/credentials\.json$/,
|
|
88868
|
-
/^secrets(\/|$)/,
|
|
88869
|
-
/^\.aws(\/|$)/
|
|
88870
|
-
];
|
|
89178
|
+
async function isWorkspacePathIgnored(rootDir, relativePath) {
|
|
89179
|
+
const ruleSets = await loadApplicableIgnoreRuleSets(rootDir, relativePath);
|
|
89180
|
+
return isPathIgnoredByRuleSets(ruleSets, relativePath);
|
|
89181
|
+
}
|
|
89182
|
+
var import_ignore, IGNORE_FILES;
|
|
89183
|
+
var init_workspace_ignore = __esm(() => {
|
|
89184
|
+
import_ignore = __toESM(require_ignore(), 1);
|
|
89185
|
+
IGNORE_FILES = [".gitignore", ".cursorignore"];
|
|
88871
89186
|
});
|
|
88872
89187
|
|
|
88873
|
-
// src/
|
|
88874
|
-
import {
|
|
88875
|
-
import
|
|
88876
|
-
function
|
|
88877
|
-
|
|
88878
|
-
|
|
89188
|
+
// src/infrastructure/services/workspace/workspace-file-walk.ts
|
|
89189
|
+
import { promises as fsPromises } from "node:fs";
|
|
89190
|
+
import path4 from "node:path";
|
|
89191
|
+
async function walkWorkspaceFiles(rootDir, options) {
|
|
89192
|
+
const maxFilePaths = options?.maxFilePaths ?? 1e4;
|
|
89193
|
+
const filePaths = [];
|
|
89194
|
+
let truncated = false;
|
|
89195
|
+
async function visitDir(relDir, inheritedRuleSets) {
|
|
89196
|
+
if (truncated || filePaths.length >= maxFilePaths) {
|
|
89197
|
+
truncated = true;
|
|
89198
|
+
return;
|
|
89199
|
+
}
|
|
89200
|
+
const localRuleSets = await loadDirectoryIgnoreRuleSets(rootDir, relDir);
|
|
89201
|
+
const ruleSets = localRuleSets.length === 0 ? inheritedRuleSets : [...inheritedRuleSets, ...localRuleSets];
|
|
89202
|
+
const absDir = relDir ? path4.join(rootDir, relDir) : rootDir;
|
|
89203
|
+
let dirents;
|
|
89204
|
+
try {
|
|
89205
|
+
dirents = await fsPromises.readdir(absDir, { withFileTypes: true });
|
|
89206
|
+
} catch {
|
|
89207
|
+
return;
|
|
89208
|
+
}
|
|
89209
|
+
for (const ent of dirents) {
|
|
89210
|
+
if (truncated || filePaths.length >= maxFilePaths) {
|
|
89211
|
+
truncated = true;
|
|
89212
|
+
return;
|
|
89213
|
+
}
|
|
89214
|
+
if (isAlwaysExcludedDirName(ent.name))
|
|
89215
|
+
continue;
|
|
89216
|
+
const relativePath = relDir ? `${relDir}/${ent.name}` : ent.name;
|
|
89217
|
+
if (!isPathVisible(relativePath))
|
|
89218
|
+
continue;
|
|
89219
|
+
if (ent.isDirectory()) {
|
|
89220
|
+
if (isPathIgnoredByRuleSets(ruleSets, relativePath))
|
|
89221
|
+
continue;
|
|
89222
|
+
await visitDir(relativePath, ruleSets);
|
|
89223
|
+
} else if (ent.isFile()) {
|
|
89224
|
+
if (isPathIgnoredByRuleSets(ruleSets, relativePath))
|
|
89225
|
+
continue;
|
|
89226
|
+
filePaths.push(relativePath);
|
|
89227
|
+
if (filePaths.length >= maxFilePaths)
|
|
89228
|
+
truncated = true;
|
|
89229
|
+
}
|
|
89230
|
+
}
|
|
88879
89231
|
}
|
|
88880
|
-
|
|
88881
|
-
}
|
|
88882
|
-
function isENOENT(error) {
|
|
88883
|
-
const cause3 = getErrorCause(error);
|
|
88884
|
-
return typeof cause3 === "object" && cause3 !== null && "code" in cause3 && cause3.code === "ENOENT";
|
|
89232
|
+
await visitDir("", []);
|
|
89233
|
+
return { filePaths, truncated };
|
|
88885
89234
|
}
|
|
88886
|
-
|
|
88887
|
-
|
|
88888
|
-
|
|
88889
|
-
|
|
88890
|
-
|
|
89235
|
+
var init_workspace_file_walk = __esm(() => {
|
|
89236
|
+
init_workspace_ignore();
|
|
89237
|
+
init_workspace_visibility_policy();
|
|
89238
|
+
});
|
|
89239
|
+
|
|
89240
|
+
// src/infrastructure/services/workspace/file-tree-scanner.ts
|
|
89241
|
+
async function scanFileTree(rootDir, options) {
|
|
89242
|
+
const maxEntries = options?.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
89243
|
+
const scannedAt = Date.now();
|
|
89244
|
+
const walk = await walkWorkspaceFiles(rootDir, { maxFilePaths: maxEntries });
|
|
89245
|
+
const filteredPaths = walk.filePaths.filter((p) => !isExcluded(p));
|
|
89246
|
+
const entries2 = buildEntries(filteredPaths, maxEntries);
|
|
89247
|
+
return {
|
|
89248
|
+
entries: entries2,
|
|
89249
|
+
scannedAt,
|
|
89250
|
+
rootDir
|
|
89251
|
+
};
|
|
88891
89252
|
}
|
|
88892
|
-
function
|
|
88893
|
-
return
|
|
89253
|
+
function isExcluded(filePath) {
|
|
89254
|
+
return hasExcludedDirSegment(filePath);
|
|
88894
89255
|
}
|
|
88895
|
-
function
|
|
88896
|
-
|
|
88897
|
-
|
|
88898
|
-
|
|
88899
|
-
|
|
88900
|
-
|
|
88901
|
-
|
|
88902
|
-
|
|
88903
|
-
|
|
88904
|
-
|
|
89256
|
+
function buildEntries(filePaths, maxEntries) {
|
|
89257
|
+
const directories = new Set;
|
|
89258
|
+
for (const filePath of filePaths) {
|
|
89259
|
+
const parts2 = filePath.split("/");
|
|
89260
|
+
for (let i2 = 1;i2 < parts2.length; i2++) {
|
|
89261
|
+
directories.add(parts2.slice(0, i2).join("/"));
|
|
89262
|
+
}
|
|
89263
|
+
}
|
|
89264
|
+
const entries2 = [];
|
|
89265
|
+
const sortedDirs = Array.from(directories).sort();
|
|
89266
|
+
for (const dir of sortedDirs) {
|
|
89267
|
+
if (entries2.length >= maxEntries)
|
|
89268
|
+
break;
|
|
89269
|
+
entries2.push({ path: dir, type: "directory" });
|
|
89270
|
+
}
|
|
89271
|
+
const sortedFiles = filePaths.slice().sort();
|
|
89272
|
+
for (const file of sortedFiles) {
|
|
89273
|
+
if (entries2.length >= maxEntries)
|
|
89274
|
+
break;
|
|
89275
|
+
entries2.push({ path: file, type: "file" });
|
|
89276
|
+
}
|
|
89277
|
+
return entries2;
|
|
88905
89278
|
}
|
|
88906
|
-
var
|
|
88907
|
-
var
|
|
88908
|
-
|
|
88909
|
-
init_daemon_services();
|
|
88910
|
-
init_api3();
|
|
88911
|
-
init_assert_registered_working_dir();
|
|
88912
|
-
init_workspace_path_security();
|
|
89279
|
+
var DEFAULT_MAX_ENTRIES = 1e4;
|
|
89280
|
+
var init_file_tree_scanner = __esm(() => {
|
|
89281
|
+
init_workspace_file_walk();
|
|
88913
89282
|
init_workspace_visibility_policy();
|
|
88914
|
-
|
|
88915
|
-
|
|
88916
|
-
|
|
88917
|
-
|
|
88918
|
-
|
|
88919
|
-
|
|
88920
|
-
|
|
88921
|
-
|
|
88922
|
-
|
|
88923
|
-
|
|
88924
|
-
|
|
88925
|
-
|
|
88926
|
-
|
|
88927
|
-
".
|
|
88928
|
-
|
|
88929
|
-
".
|
|
88930
|
-
|
|
88931
|
-
|
|
88932
|
-
|
|
88933
|
-
|
|
88934
|
-
|
|
88935
|
-
|
|
88936
|
-
|
|
88937
|
-
|
|
88938
|
-
|
|
88939
|
-
|
|
88940
|
-
|
|
88941
|
-
|
|
88942
|
-
|
|
88943
|
-
|
|
88944
|
-
|
|
88945
|
-
|
|
88946
|
-
|
|
88947
|
-
|
|
88948
|
-
|
|
88949
|
-
|
|
88950
|
-
|
|
88951
|
-
|
|
88952
|
-
|
|
88953
|
-
"
|
|
89283
|
+
});
|
|
89284
|
+
|
|
89285
|
+
// ../../node_modules/.pnpm/readdirp@5.0.0/node_modules/readdirp/index.js
|
|
89286
|
+
import { lstat, readdir, realpath as realpath3, stat as stat2 } from "node:fs/promises";
|
|
89287
|
+
import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
|
|
89288
|
+
import { Readable as Readable3 } from "node:stream";
|
|
89289
|
+
function readdirp(root, options = {}) {
|
|
89290
|
+
let type = options.entryType || options.type;
|
|
89291
|
+
if (type === "both")
|
|
89292
|
+
type = EntryTypes.FILE_DIR_TYPE;
|
|
89293
|
+
if (type)
|
|
89294
|
+
options.type = type;
|
|
89295
|
+
if (!root) {
|
|
89296
|
+
throw new Error("readdirp: root argument is required. Usage: readdirp(root, options)");
|
|
89297
|
+
} else if (typeof root !== "string") {
|
|
89298
|
+
throw new TypeError("readdirp: root argument must be a string. Usage: readdirp(root, options)");
|
|
89299
|
+
} else if (type && !ALL_TYPES.includes(type)) {
|
|
89300
|
+
throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(", ")}`);
|
|
89301
|
+
}
|
|
89302
|
+
options.root = root;
|
|
89303
|
+
return new ReaddirpStream(options);
|
|
89304
|
+
}
|
|
89305
|
+
var EntryTypes, defaultOptions, RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR", NORMAL_FLOW_ERRORS, ALL_TYPES, DIR_TYPES, FILE_TYPES, isNormalFlowError = (error) => NORMAL_FLOW_ERRORS.has(error.code), wantBigintFsStats, emptyFn = (_entryInfo) => true, normalizeFilter = (filter11) => {
|
|
89306
|
+
if (filter11 === undefined)
|
|
89307
|
+
return emptyFn;
|
|
89308
|
+
if (typeof filter11 === "function")
|
|
89309
|
+
return filter11;
|
|
89310
|
+
if (typeof filter11 === "string") {
|
|
89311
|
+
const fl = filter11.trim();
|
|
89312
|
+
return (entry) => entry.basename === fl;
|
|
89313
|
+
}
|
|
89314
|
+
if (Array.isArray(filter11)) {
|
|
89315
|
+
const trItems = filter11.map((item) => item.trim());
|
|
89316
|
+
return (entry) => trItems.some((f) => entry.basename === f);
|
|
89317
|
+
}
|
|
89318
|
+
return emptyFn;
|
|
89319
|
+
}, ReaddirpStream;
|
|
89320
|
+
var init_readdirp = __esm(() => {
|
|
89321
|
+
EntryTypes = {
|
|
89322
|
+
FILE_TYPE: "files",
|
|
89323
|
+
DIR_TYPE: "directories",
|
|
89324
|
+
FILE_DIR_TYPE: "files_directories",
|
|
89325
|
+
EVERYTHING_TYPE: "all"
|
|
89326
|
+
};
|
|
89327
|
+
defaultOptions = {
|
|
89328
|
+
root: ".",
|
|
89329
|
+
fileFilter: (_entryInfo) => true,
|
|
89330
|
+
directoryFilter: (_entryInfo) => true,
|
|
89331
|
+
type: EntryTypes.FILE_TYPE,
|
|
89332
|
+
lstat: false,
|
|
89333
|
+
depth: 2147483648,
|
|
89334
|
+
alwaysStat: false,
|
|
89335
|
+
highWaterMark: 4096
|
|
89336
|
+
};
|
|
89337
|
+
Object.freeze(defaultOptions);
|
|
89338
|
+
NORMAL_FLOW_ERRORS = new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
|
|
89339
|
+
ALL_TYPES = [
|
|
89340
|
+
EntryTypes.DIR_TYPE,
|
|
89341
|
+
EntryTypes.EVERYTHING_TYPE,
|
|
89342
|
+
EntryTypes.FILE_DIR_TYPE,
|
|
89343
|
+
EntryTypes.FILE_TYPE
|
|
89344
|
+
];
|
|
89345
|
+
DIR_TYPES = new Set([
|
|
89346
|
+
EntryTypes.DIR_TYPE,
|
|
89347
|
+
EntryTypes.EVERYTHING_TYPE,
|
|
89348
|
+
EntryTypes.FILE_DIR_TYPE
|
|
88954
89349
|
]);
|
|
88955
|
-
|
|
88956
|
-
|
|
88957
|
-
|
|
88958
|
-
|
|
88959
|
-
|
|
88960
|
-
|
|
88961
|
-
|
|
89350
|
+
FILE_TYPES = new Set([
|
|
89351
|
+
EntryTypes.EVERYTHING_TYPE,
|
|
89352
|
+
EntryTypes.FILE_DIR_TYPE,
|
|
89353
|
+
EntryTypes.FILE_TYPE
|
|
89354
|
+
]);
|
|
89355
|
+
wantBigintFsStats = process.platform === "win32";
|
|
89356
|
+
ReaddirpStream = class ReaddirpStream extends Readable3 {
|
|
89357
|
+
parents;
|
|
89358
|
+
reading;
|
|
89359
|
+
parent;
|
|
89360
|
+
_stat;
|
|
89361
|
+
_maxDepth;
|
|
89362
|
+
_wantsDir;
|
|
89363
|
+
_wantsFile;
|
|
89364
|
+
_wantsEverything;
|
|
89365
|
+
_root;
|
|
89366
|
+
_isDirent;
|
|
89367
|
+
_statsProp;
|
|
89368
|
+
_rdOptions;
|
|
89369
|
+
_fileFilter;
|
|
89370
|
+
_directoryFilter;
|
|
89371
|
+
constructor(options = {}) {
|
|
89372
|
+
super({
|
|
89373
|
+
objectMode: true,
|
|
89374
|
+
autoDestroy: true,
|
|
89375
|
+
highWaterMark: options.highWaterMark
|
|
89376
|
+
});
|
|
89377
|
+
const opts = { ...defaultOptions, ...options };
|
|
89378
|
+
const { root, type } = opts;
|
|
89379
|
+
this._fileFilter = normalizeFilter(opts.fileFilter);
|
|
89380
|
+
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
89381
|
+
const statMethod = opts.lstat ? lstat : stat2;
|
|
89382
|
+
if (wantBigintFsStats) {
|
|
89383
|
+
this._stat = (path5) => statMethod(path5, { bigint: true });
|
|
89384
|
+
} else {
|
|
89385
|
+
this._stat = statMethod;
|
|
89386
|
+
}
|
|
89387
|
+
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions.depth;
|
|
89388
|
+
this._wantsDir = type ? DIR_TYPES.has(type) : false;
|
|
89389
|
+
this._wantsFile = type ? FILE_TYPES.has(type) : false;
|
|
89390
|
+
this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
|
|
89391
|
+
this._root = presolve(root);
|
|
89392
|
+
this._isDirent = !opts.alwaysStat;
|
|
89393
|
+
this._statsProp = this._isDirent ? "dirent" : "stats";
|
|
89394
|
+
this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
|
|
89395
|
+
this.parents = [this._exploreDir(root, 1)];
|
|
89396
|
+
this.reading = false;
|
|
89397
|
+
this.parent = undefined;
|
|
89398
|
+
}
|
|
89399
|
+
async _read(batch) {
|
|
89400
|
+
if (this.reading)
|
|
89401
|
+
return;
|
|
89402
|
+
this.reading = true;
|
|
89403
|
+
try {
|
|
89404
|
+
while (!this.destroyed && batch > 0) {
|
|
89405
|
+
const par2 = this.parent;
|
|
89406
|
+
const fil = par2 && par2.files;
|
|
89407
|
+
if (fil && fil.length > 0) {
|
|
89408
|
+
const { path: path5, depth } = par2;
|
|
89409
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path5));
|
|
89410
|
+
const awaited = await Promise.all(slice);
|
|
89411
|
+
for (const entry of awaited) {
|
|
89412
|
+
if (!entry)
|
|
89413
|
+
continue;
|
|
89414
|
+
if (this.destroyed)
|
|
89415
|
+
return;
|
|
89416
|
+
const entryType = await this._getEntryType(entry);
|
|
89417
|
+
if (entryType === "directory" && this._directoryFilter(entry)) {
|
|
89418
|
+
if (depth <= this._maxDepth) {
|
|
89419
|
+
this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
|
|
89420
|
+
}
|
|
89421
|
+
if (this._wantsDir) {
|
|
89422
|
+
this.push(entry);
|
|
89423
|
+
batch--;
|
|
89424
|
+
}
|
|
89425
|
+
} else if ((entryType === "file" || this._includeAsFile(entry)) && this._fileFilter(entry)) {
|
|
89426
|
+
if (this._wantsFile) {
|
|
89427
|
+
this.push(entry);
|
|
89428
|
+
batch--;
|
|
89429
|
+
}
|
|
89430
|
+
}
|
|
89431
|
+
}
|
|
89432
|
+
} else {
|
|
89433
|
+
const parent = this.parents.pop();
|
|
89434
|
+
if (!parent) {
|
|
89435
|
+
this.push(null);
|
|
89436
|
+
break;
|
|
89437
|
+
}
|
|
89438
|
+
this.parent = await parent;
|
|
89439
|
+
if (this.destroyed)
|
|
89440
|
+
return;
|
|
89441
|
+
}
|
|
89442
|
+
}
|
|
89443
|
+
} catch (error) {
|
|
89444
|
+
this.destroy(error);
|
|
89445
|
+
} finally {
|
|
89446
|
+
this.reading = false;
|
|
89447
|
+
}
|
|
89448
|
+
}
|
|
89449
|
+
async _exploreDir(path5, depth) {
|
|
89450
|
+
let files;
|
|
89451
|
+
try {
|
|
89452
|
+
files = await readdir(path5, this._rdOptions);
|
|
89453
|
+
} catch (error) {
|
|
89454
|
+
this._onError(error);
|
|
89455
|
+
}
|
|
89456
|
+
return { files, depth, path: path5 };
|
|
89457
|
+
}
|
|
89458
|
+
async _formatEntry(dirent, path5) {
|
|
89459
|
+
let entry;
|
|
89460
|
+
const basename2 = this._isDirent ? dirent.name : dirent;
|
|
89461
|
+
try {
|
|
89462
|
+
const fullPath = presolve(pjoin(path5, basename2));
|
|
89463
|
+
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename2 };
|
|
89464
|
+
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
89465
|
+
} catch (err) {
|
|
89466
|
+
this._onError(err);
|
|
89467
|
+
return;
|
|
89468
|
+
}
|
|
89469
|
+
return entry;
|
|
89470
|
+
}
|
|
89471
|
+
_onError(err) {
|
|
89472
|
+
if (isNormalFlowError(err) && !this.destroyed) {
|
|
89473
|
+
this.emit("warn", err);
|
|
89474
|
+
} else {
|
|
89475
|
+
this.destroy(err);
|
|
89476
|
+
}
|
|
89477
|
+
}
|
|
89478
|
+
async _getEntryType(entry) {
|
|
89479
|
+
if (!entry && this._statsProp in entry) {
|
|
89480
|
+
return "";
|
|
89481
|
+
}
|
|
89482
|
+
const stats = entry[this._statsProp];
|
|
89483
|
+
if (stats.isFile())
|
|
89484
|
+
return "file";
|
|
89485
|
+
if (stats.isDirectory())
|
|
89486
|
+
return "directory";
|
|
89487
|
+
if (stats && stats.isSymbolicLink()) {
|
|
89488
|
+
const full = entry.fullPath;
|
|
89489
|
+
try {
|
|
89490
|
+
const entryRealPath = await realpath3(full);
|
|
89491
|
+
const entryRealPathStats = await lstat(entryRealPath);
|
|
89492
|
+
if (entryRealPathStats.isFile()) {
|
|
89493
|
+
return "file";
|
|
89494
|
+
}
|
|
89495
|
+
if (entryRealPathStats.isDirectory()) {
|
|
89496
|
+
const len2 = entryRealPath.length;
|
|
89497
|
+
if (full.startsWith(entryRealPath) && full.substr(len2, 1) === psep) {
|
|
89498
|
+
const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
|
|
89499
|
+
recursiveError.code = RECURSIVE_ERROR_CODE;
|
|
89500
|
+
return this._onError(recursiveError);
|
|
89501
|
+
}
|
|
89502
|
+
return "directory";
|
|
89503
|
+
}
|
|
89504
|
+
} catch (error) {
|
|
89505
|
+
this._onError(error);
|
|
89506
|
+
return "";
|
|
89507
|
+
}
|
|
89508
|
+
}
|
|
89509
|
+
}
|
|
89510
|
+
_includeAsFile(entry) {
|
|
89511
|
+
const stats = entry && entry[this._statsProp];
|
|
89512
|
+
return stats && this._wantsEverything && !stats.isDirectory();
|
|
89513
|
+
}
|
|
89514
|
+
};
|
|
89515
|
+
});
|
|
89516
|
+
|
|
89517
|
+
// ../../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/handler.js
|
|
89518
|
+
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
89519
|
+
import { realpath as fsrealpath, lstat as lstat2, open, stat as stat3 } from "node:fs/promises";
|
|
89520
|
+
import { type as osType } from "node:os";
|
|
89521
|
+
import * as sp from "node:path";
|
|
89522
|
+
function createFsWatchInstance(path5, options, listener, errHandler, emitRaw) {
|
|
89523
|
+
const handleEvent = (rawEvent, evPath) => {
|
|
89524
|
+
listener(path5);
|
|
89525
|
+
emitRaw(rawEvent, evPath, { watchedPath: path5 });
|
|
89526
|
+
if (evPath && path5 !== evPath) {
|
|
89527
|
+
fsWatchBroadcast(sp.resolve(path5, evPath), KEY_LISTENERS, sp.join(path5, evPath));
|
|
89528
|
+
}
|
|
89529
|
+
};
|
|
89530
|
+
try {
|
|
89531
|
+
return fs_watch(path5, {
|
|
89532
|
+
persistent: options.persistent
|
|
89533
|
+
}, handleEvent);
|
|
89534
|
+
} catch (error) {
|
|
89535
|
+
errHandler(error);
|
|
89536
|
+
return;
|
|
89537
|
+
}
|
|
89538
|
+
}
|
|
89539
|
+
|
|
89540
|
+
class NodeFsHandler {
|
|
89541
|
+
fsw;
|
|
89542
|
+
_boundHandleError;
|
|
89543
|
+
constructor(fsW) {
|
|
89544
|
+
this.fsw = fsW;
|
|
89545
|
+
this._boundHandleError = (error) => fsW._handleError(error);
|
|
89546
|
+
}
|
|
89547
|
+
_watchWithNodeFs(path5, listener) {
|
|
89548
|
+
const opts = this.fsw.options;
|
|
89549
|
+
const directory = sp.dirname(path5);
|
|
89550
|
+
const basename3 = sp.basename(path5);
|
|
89551
|
+
const parent = this.fsw._getWatchedDir(directory);
|
|
89552
|
+
parent.add(basename3);
|
|
89553
|
+
const absolutePath = sp.resolve(path5);
|
|
89554
|
+
const options = {
|
|
89555
|
+
persistent: opts.persistent
|
|
89556
|
+
};
|
|
89557
|
+
if (!listener)
|
|
89558
|
+
listener = EMPTY_FN;
|
|
89559
|
+
let closer;
|
|
89560
|
+
if (opts.usePolling) {
|
|
89561
|
+
const enableBin = opts.interval !== opts.binaryInterval;
|
|
89562
|
+
options.interval = enableBin && isBinaryPath(basename3) ? opts.binaryInterval : opts.interval;
|
|
89563
|
+
closer = setFsWatchFileListener(path5, absolutePath, options, {
|
|
89564
|
+
listener,
|
|
89565
|
+
rawEmitter: this.fsw._emitRaw
|
|
89566
|
+
});
|
|
89567
|
+
} else {
|
|
89568
|
+
closer = setFsWatchListener(path5, absolutePath, options, {
|
|
89569
|
+
listener,
|
|
89570
|
+
errHandler: this._boundHandleError,
|
|
89571
|
+
rawEmitter: this.fsw._emitRaw
|
|
89572
|
+
});
|
|
89573
|
+
}
|
|
89574
|
+
return closer;
|
|
89575
|
+
}
|
|
89576
|
+
_handleFile(file, stats, initialAdd) {
|
|
89577
|
+
if (this.fsw.closed) {
|
|
88962
89578
|
return;
|
|
88963
|
-
|
|
88964
|
-
|
|
88965
|
-
|
|
88966
|
-
|
|
88967
|
-
|
|
88968
|
-
|
|
88969
|
-
|
|
88970
|
-
|
|
88971
|
-
|
|
89579
|
+
}
|
|
89580
|
+
const dirname10 = sp.dirname(file);
|
|
89581
|
+
const basename3 = sp.basename(file);
|
|
89582
|
+
const parent = this.fsw._getWatchedDir(dirname10);
|
|
89583
|
+
let prevStats = stats;
|
|
89584
|
+
if (parent.has(basename3))
|
|
89585
|
+
return;
|
|
89586
|
+
const listener = async (path5, newStats) => {
|
|
89587
|
+
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
89588
|
+
return;
|
|
89589
|
+
if (!newStats || newStats.mtimeMs === 0) {
|
|
89590
|
+
try {
|
|
89591
|
+
const newStats2 = await stat3(file);
|
|
89592
|
+
if (this.fsw.closed)
|
|
89593
|
+
return;
|
|
89594
|
+
const at = newStats2.atimeMs;
|
|
89595
|
+
const mt = newStats2.mtimeMs;
|
|
89596
|
+
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
89597
|
+
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
89598
|
+
}
|
|
89599
|
+
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
89600
|
+
this.fsw._closeFile(path5);
|
|
89601
|
+
prevStats = newStats2;
|
|
89602
|
+
const closer2 = this._watchWithNodeFs(file, listener);
|
|
89603
|
+
if (closer2)
|
|
89604
|
+
this.fsw._addPathCloser(path5, closer2);
|
|
89605
|
+
} else {
|
|
89606
|
+
prevStats = newStats2;
|
|
89607
|
+
}
|
|
89608
|
+
} catch (error) {
|
|
89609
|
+
this.fsw._remove(dirname10, basename3);
|
|
89610
|
+
}
|
|
89611
|
+
} else if (parent.has(basename3)) {
|
|
89612
|
+
const at = newStats.atimeMs;
|
|
89613
|
+
const mt = newStats.mtimeMs;
|
|
89614
|
+
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
89615
|
+
this.fsw._emit(EV.CHANGE, file, newStats);
|
|
89616
|
+
}
|
|
89617
|
+
prevStats = newStats;
|
|
88972
89618
|
}
|
|
88973
|
-
|
|
88974
|
-
|
|
88975
|
-
|
|
88976
|
-
|
|
88977
|
-
|
|
89619
|
+
};
|
|
89620
|
+
const closer = this._watchWithNodeFs(file, listener);
|
|
89621
|
+
if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
|
|
89622
|
+
if (!this.fsw._throttle(EV.ADD, file, 0))
|
|
89623
|
+
return;
|
|
89624
|
+
this.fsw._emit(EV.ADD, file, stats);
|
|
89625
|
+
}
|
|
89626
|
+
return closer;
|
|
89627
|
+
}
|
|
89628
|
+
async _handleSymlink(entry, directory, path5, item) {
|
|
89629
|
+
if (this.fsw.closed) {
|
|
89630
|
+
return;
|
|
89631
|
+
}
|
|
89632
|
+
const full = entry.fullPath;
|
|
89633
|
+
const dir = this.fsw._getWatchedDir(directory);
|
|
89634
|
+
if (!this.fsw.options.followSymlinks) {
|
|
89635
|
+
this.fsw._incrReadyCount();
|
|
89636
|
+
let linkPath;
|
|
89637
|
+
try {
|
|
89638
|
+
linkPath = await fsrealpath(path5);
|
|
89639
|
+
} catch (e) {
|
|
89640
|
+
this.fsw._emitReady();
|
|
89641
|
+
return true;
|
|
88978
89642
|
}
|
|
88979
|
-
|
|
88980
|
-
|
|
88981
|
-
|
|
88982
|
-
|
|
88983
|
-
|
|
88984
|
-
|
|
89643
|
+
if (this.fsw.closed)
|
|
89644
|
+
return;
|
|
89645
|
+
if (dir.has(item)) {
|
|
89646
|
+
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
89647
|
+
this.fsw._symlinkPaths.set(full, linkPath);
|
|
89648
|
+
this.fsw._emit(EV.CHANGE, path5, entry.stats);
|
|
89649
|
+
}
|
|
89650
|
+
} else {
|
|
89651
|
+
dir.add(item);
|
|
89652
|
+
this.fsw._symlinkPaths.set(full, linkPath);
|
|
89653
|
+
this.fsw._emit(EV.ADD, path5, entry.stats);
|
|
88985
89654
|
}
|
|
88986
|
-
|
|
88987
|
-
|
|
88988
|
-
|
|
88989
|
-
|
|
88990
|
-
|
|
89655
|
+
this.fsw._emitReady();
|
|
89656
|
+
return true;
|
|
89657
|
+
}
|
|
89658
|
+
if (this.fsw._symlinkPaths.has(full)) {
|
|
89659
|
+
return true;
|
|
89660
|
+
}
|
|
89661
|
+
this.fsw._symlinkPaths.set(full, true);
|
|
89662
|
+
}
|
|
89663
|
+
_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
|
|
89664
|
+
directory = sp.join(directory, "");
|
|
89665
|
+
const throttleKey = target ? `${directory}:${target}` : directory;
|
|
89666
|
+
throttler = this.fsw._throttle("readdir", throttleKey, 1000);
|
|
89667
|
+
if (!throttler)
|
|
89668
|
+
return;
|
|
89669
|
+
const previous = this.fsw._getWatchedDir(wh.path);
|
|
89670
|
+
const current = new Set;
|
|
89671
|
+
let stream4 = this.fsw._readdirp(directory, {
|
|
89672
|
+
fileFilter: (entry) => wh.filterPath(entry),
|
|
89673
|
+
directoryFilter: (entry) => wh.filterDir(entry)
|
|
89674
|
+
});
|
|
89675
|
+
if (!stream4)
|
|
89676
|
+
return;
|
|
89677
|
+
stream4.on(STR_DATA, async (entry) => {
|
|
89678
|
+
if (this.fsw.closed) {
|
|
89679
|
+
stream4 = undefined;
|
|
89680
|
+
return;
|
|
88991
89681
|
}
|
|
88992
|
-
const
|
|
88993
|
-
|
|
88994
|
-
|
|
88995
|
-
|
|
88996
|
-
|
|
88997
|
-
|
|
88998
|
-
|
|
89682
|
+
const item = entry.path;
|
|
89683
|
+
let path5 = sp.join(directory, item);
|
|
89684
|
+
current.add(item);
|
|
89685
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path5, item)) {
|
|
89686
|
+
return;
|
|
89687
|
+
}
|
|
89688
|
+
if (this.fsw.closed) {
|
|
89689
|
+
stream4 = undefined;
|
|
89690
|
+
return;
|
|
89691
|
+
}
|
|
89692
|
+
if (item === target || !target && !previous.has(item)) {
|
|
89693
|
+
this.fsw._incrReadyCount();
|
|
89694
|
+
path5 = sp.join(dir, sp.relative(dir, path5));
|
|
89695
|
+
this._addToNodeFs(path5, initialAdd, wh, depth + 1);
|
|
89696
|
+
}
|
|
89697
|
+
}).on(EV.ERROR, this._boundHandleError);
|
|
89698
|
+
return new Promise((resolve6, reject) => {
|
|
89699
|
+
if (!stream4)
|
|
89700
|
+
return reject();
|
|
89701
|
+
stream4.once(STR_END, () => {
|
|
89702
|
+
if (this.fsw.closed) {
|
|
89703
|
+
stream4 = undefined;
|
|
89704
|
+
return;
|
|
88999
89705
|
}
|
|
89000
|
-
|
|
89001
|
-
|
|
89002
|
-
|
|
89003
|
-
|
|
89004
|
-
}
|
|
89005
|
-
|
|
89006
|
-
|
|
89007
|
-
|
|
89008
|
-
|
|
89009
|
-
|
|
89010
|
-
|
|
89011
|
-
|
|
89012
|
-
|
|
89706
|
+
const wasThrottled = throttler ? throttler.clear() : false;
|
|
89707
|
+
resolve6(undefined);
|
|
89708
|
+
previous.getChildren().filter((item) => {
|
|
89709
|
+
return item !== directory && !current.has(item);
|
|
89710
|
+
}).forEach((item) => {
|
|
89711
|
+
this.fsw._remove(directory, item);
|
|
89712
|
+
});
|
|
89713
|
+
stream4 = undefined;
|
|
89714
|
+
if (wasThrottled)
|
|
89715
|
+
this._handleRead(directory, false, wh, target, dir, depth, throttler);
|
|
89716
|
+
});
|
|
89717
|
+
});
|
|
89718
|
+
}
|
|
89719
|
+
async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath4) {
|
|
89720
|
+
const parentDir = this.fsw._getWatchedDir(sp.dirname(dir));
|
|
89721
|
+
const tracked = parentDir.has(sp.basename(dir));
|
|
89722
|
+
if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
|
|
89723
|
+
this.fsw._emit(EV.ADD_DIR, dir, stats);
|
|
89724
|
+
}
|
|
89725
|
+
parentDir.add(sp.basename(dir));
|
|
89726
|
+
this.fsw._getWatchedDir(dir);
|
|
89727
|
+
let throttler;
|
|
89728
|
+
let closer;
|
|
89729
|
+
const oDepth = this.fsw.options.depth;
|
|
89730
|
+
if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath4)) {
|
|
89731
|
+
if (!target) {
|
|
89732
|
+
await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
|
|
89733
|
+
if (this.fsw.closed)
|
|
89734
|
+
return;
|
|
89735
|
+
}
|
|
89736
|
+
closer = this._watchWithNodeFs(dir, (dirPath, stats2) => {
|
|
89737
|
+
if (stats2 && stats2.mtimeMs === 0)
|
|
89738
|
+
return;
|
|
89739
|
+
this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
|
|
89740
|
+
});
|
|
89741
|
+
}
|
|
89742
|
+
return closer;
|
|
89743
|
+
}
|
|
89744
|
+
async _addToNodeFs(path5, initialAdd, priorWh, depth, target) {
|
|
89745
|
+
const ready = this.fsw._emitReady;
|
|
89746
|
+
if (this.fsw._isIgnored(path5) || this.fsw.closed) {
|
|
89747
|
+
ready();
|
|
89748
|
+
return false;
|
|
89749
|
+
}
|
|
89750
|
+
const wh = this.fsw._getWatchHelpers(path5);
|
|
89751
|
+
if (priorWh) {
|
|
89752
|
+
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
89753
|
+
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
89754
|
+
}
|
|
89755
|
+
try {
|
|
89756
|
+
const stats = await statMethods[wh.statMethod](wh.watchPath);
|
|
89757
|
+
if (this.fsw.closed)
|
|
89758
|
+
return;
|
|
89759
|
+
if (this.fsw._isIgnored(wh.watchPath, stats)) {
|
|
89760
|
+
ready();
|
|
89761
|
+
return false;
|
|
89762
|
+
}
|
|
89763
|
+
const follow = this.fsw.options.followSymlinks;
|
|
89764
|
+
let closer;
|
|
89765
|
+
if (stats.isDirectory()) {
|
|
89766
|
+
const absPath = sp.resolve(path5);
|
|
89767
|
+
const targetPath = follow ? await fsrealpath(path5) : path5;
|
|
89768
|
+
if (this.fsw.closed)
|
|
89769
|
+
return;
|
|
89770
|
+
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
89771
|
+
if (this.fsw.closed)
|
|
89772
|
+
return;
|
|
89773
|
+
if (absPath !== targetPath && targetPath !== undefined) {
|
|
89774
|
+
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
89775
|
+
}
|
|
89776
|
+
} else if (stats.isSymbolicLink()) {
|
|
89777
|
+
const targetPath = follow ? await fsrealpath(path5) : path5;
|
|
89778
|
+
if (this.fsw.closed)
|
|
89779
|
+
return;
|
|
89780
|
+
const parent = sp.dirname(wh.watchPath);
|
|
89781
|
+
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
89782
|
+
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
89783
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path5, wh, targetPath);
|
|
89784
|
+
if (this.fsw.closed)
|
|
89785
|
+
return;
|
|
89786
|
+
if (targetPath !== undefined) {
|
|
89787
|
+
this.fsw._symlinkPaths.set(sp.resolve(path5), targetPath);
|
|
89788
|
+
}
|
|
89789
|
+
} else {
|
|
89790
|
+
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
89791
|
+
}
|
|
89792
|
+
ready();
|
|
89793
|
+
if (closer)
|
|
89794
|
+
this.fsw._addPathCloser(path5, closer);
|
|
89795
|
+
return false;
|
|
89796
|
+
} catch (error) {
|
|
89797
|
+
if (this.fsw._handleError(error)) {
|
|
89798
|
+
ready();
|
|
89799
|
+
return path5;
|
|
89800
|
+
}
|
|
89801
|
+
}
|
|
89802
|
+
}
|
|
89803
|
+
}
|
|
89804
|
+
var STR_DATA = "data", STR_END = "end", STR_CLOSE = "close", EMPTY_FN = () => {}, pl, isWindows, isMacos, isLinux, isFreeBSD, isIBMi, EVENTS, EV, THROTTLE_MODE_WATCH = "watch", statMethods, KEY_LISTENERS = "listeners", KEY_ERR = "errHandlers", KEY_RAW = "rawEmitters", HANDLER_KEYS, binaryExtensions, isBinaryPath = (filePath) => binaryExtensions.has(sp.extname(filePath).slice(1).toLowerCase()), foreach = (val, fn2) => {
|
|
89805
|
+
if (val instanceof Set) {
|
|
89806
|
+
val.forEach(fn2);
|
|
89807
|
+
} else {
|
|
89808
|
+
fn2(val);
|
|
89809
|
+
}
|
|
89810
|
+
}, addAndConvert = (main, prop, item) => {
|
|
89811
|
+
let container = main[prop];
|
|
89812
|
+
if (!(container instanceof Set)) {
|
|
89813
|
+
main[prop] = container = new Set([container]);
|
|
89814
|
+
}
|
|
89815
|
+
container.add(item);
|
|
89816
|
+
}, clearItem = (cont) => (key) => {
|
|
89817
|
+
const set7 = cont[key];
|
|
89818
|
+
if (set7 instanceof Set) {
|
|
89819
|
+
set7.clear();
|
|
89820
|
+
} else {
|
|
89821
|
+
delete cont[key];
|
|
89822
|
+
}
|
|
89823
|
+
}, delFromSet = (main, prop, item) => {
|
|
89824
|
+
const container = main[prop];
|
|
89825
|
+
if (container instanceof Set) {
|
|
89826
|
+
container.delete(item);
|
|
89827
|
+
} else if (container === item) {
|
|
89828
|
+
delete main[prop];
|
|
89829
|
+
}
|
|
89830
|
+
}, isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val, FsWatchInstances, fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
89831
|
+
const cont = FsWatchInstances.get(fullPath);
|
|
89832
|
+
if (!cont)
|
|
89833
|
+
return;
|
|
89834
|
+
foreach(cont[listenerType], (listener) => {
|
|
89835
|
+
listener(val1, val2, val3);
|
|
89836
|
+
});
|
|
89837
|
+
}, setFsWatchListener = (path5, fullPath, options, handlers) => {
|
|
89838
|
+
const { listener, errHandler, rawEmitter } = handlers;
|
|
89839
|
+
let cont = FsWatchInstances.get(fullPath);
|
|
89840
|
+
let watcher;
|
|
89841
|
+
if (!options.persistent) {
|
|
89842
|
+
watcher = createFsWatchInstance(path5, options, listener, errHandler, rawEmitter);
|
|
89843
|
+
if (!watcher)
|
|
89844
|
+
return;
|
|
89845
|
+
return watcher.close.bind(watcher);
|
|
89846
|
+
}
|
|
89847
|
+
if (cont) {
|
|
89848
|
+
addAndConvert(cont, KEY_LISTENERS, listener);
|
|
89849
|
+
addAndConvert(cont, KEY_ERR, errHandler);
|
|
89850
|
+
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
89851
|
+
} else {
|
|
89852
|
+
watcher = createFsWatchInstance(path5, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
89853
|
+
if (!watcher)
|
|
89854
|
+
return;
|
|
89855
|
+
watcher.on(EV.ERROR, async (error) => {
|
|
89856
|
+
const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
|
|
89857
|
+
if (cont)
|
|
89858
|
+
cont.watcherUnusable = true;
|
|
89859
|
+
if (isWindows && error.code === "EPERM") {
|
|
89860
|
+
try {
|
|
89861
|
+
const fd = await open(path5, "r");
|
|
89862
|
+
await fd.close();
|
|
89863
|
+
broadcastErr(error);
|
|
89864
|
+
} catch (err) {}
|
|
89865
|
+
} else {
|
|
89866
|
+
broadcastErr(error);
|
|
89867
|
+
}
|
|
89868
|
+
});
|
|
89869
|
+
cont = {
|
|
89870
|
+
listeners: listener,
|
|
89871
|
+
errHandlers: errHandler,
|
|
89872
|
+
rawEmitters: rawEmitter,
|
|
89873
|
+
watcher
|
|
89874
|
+
};
|
|
89875
|
+
FsWatchInstances.set(fullPath, cont);
|
|
89876
|
+
}
|
|
89877
|
+
return () => {
|
|
89878
|
+
delFromSet(cont, KEY_LISTENERS, listener);
|
|
89879
|
+
delFromSet(cont, KEY_ERR, errHandler);
|
|
89880
|
+
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
89881
|
+
if (isEmptySet(cont.listeners)) {
|
|
89882
|
+
cont.watcher.close();
|
|
89883
|
+
FsWatchInstances.delete(fullPath);
|
|
89884
|
+
HANDLER_KEYS.forEach(clearItem(cont));
|
|
89885
|
+
cont.watcher = undefined;
|
|
89886
|
+
Object.freeze(cont);
|
|
89887
|
+
}
|
|
89888
|
+
};
|
|
89889
|
+
}, FsWatchFileInstances, setFsWatchFileListener = (path5, fullPath, options, handlers) => {
|
|
89890
|
+
const { listener, rawEmitter } = handlers;
|
|
89891
|
+
let cont = FsWatchFileInstances.get(fullPath);
|
|
89892
|
+
const copts = cont && cont.options;
|
|
89893
|
+
if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
|
|
89894
|
+
unwatchFile(fullPath);
|
|
89895
|
+
cont = undefined;
|
|
89896
|
+
}
|
|
89897
|
+
if (cont) {
|
|
89898
|
+
addAndConvert(cont, KEY_LISTENERS, listener);
|
|
89899
|
+
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
89900
|
+
} else {
|
|
89901
|
+
cont = {
|
|
89902
|
+
listeners: listener,
|
|
89903
|
+
rawEmitters: rawEmitter,
|
|
89904
|
+
options,
|
|
89905
|
+
watcher: watchFile(fullPath, options, (curr, prev) => {
|
|
89906
|
+
foreach(cont.rawEmitters, (rawEmitter2) => {
|
|
89907
|
+
rawEmitter2(EV.CHANGE, fullPath, { curr, prev });
|
|
89908
|
+
});
|
|
89909
|
+
const currmtime = curr.mtimeMs;
|
|
89910
|
+
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
89911
|
+
foreach(cont.listeners, (listener2) => listener2(path5, curr));
|
|
89912
|
+
}
|
|
89913
|
+
})
|
|
89914
|
+
};
|
|
89915
|
+
FsWatchFileInstances.set(fullPath, cont);
|
|
89916
|
+
}
|
|
89917
|
+
return () => {
|
|
89918
|
+
delFromSet(cont, KEY_LISTENERS, listener);
|
|
89919
|
+
delFromSet(cont, KEY_RAW, rawEmitter);
|
|
89920
|
+
if (isEmptySet(cont.listeners)) {
|
|
89921
|
+
FsWatchFileInstances.delete(fullPath);
|
|
89922
|
+
unwatchFile(fullPath);
|
|
89923
|
+
cont.options = cont.watcher = undefined;
|
|
89924
|
+
Object.freeze(cont);
|
|
89925
|
+
}
|
|
89926
|
+
};
|
|
89927
|
+
};
|
|
89928
|
+
var init_handler = __esm(() => {
|
|
89929
|
+
pl = process.platform;
|
|
89930
|
+
isWindows = pl === "win32";
|
|
89931
|
+
isMacos = pl === "darwin";
|
|
89932
|
+
isLinux = pl === "linux";
|
|
89933
|
+
isFreeBSD = pl === "freebsd";
|
|
89934
|
+
isIBMi = osType() === "OS400";
|
|
89935
|
+
EVENTS = {
|
|
89936
|
+
ALL: "all",
|
|
89937
|
+
READY: "ready",
|
|
89938
|
+
ADD: "add",
|
|
89939
|
+
CHANGE: "change",
|
|
89940
|
+
ADD_DIR: "addDir",
|
|
89941
|
+
UNLINK: "unlink",
|
|
89942
|
+
UNLINK_DIR: "unlinkDir",
|
|
89943
|
+
RAW: "raw",
|
|
89944
|
+
ERROR: "error"
|
|
89945
|
+
};
|
|
89946
|
+
EV = EVENTS;
|
|
89947
|
+
statMethods = { lstat: lstat2, stat: stat3 };
|
|
89948
|
+
HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
|
|
89949
|
+
binaryExtensions = new Set([
|
|
89950
|
+
"3dm",
|
|
89951
|
+
"3ds",
|
|
89952
|
+
"3g2",
|
|
89953
|
+
"3gp",
|
|
89954
|
+
"7z",
|
|
89955
|
+
"a",
|
|
89956
|
+
"aac",
|
|
89957
|
+
"adp",
|
|
89958
|
+
"afdesign",
|
|
89959
|
+
"afphoto",
|
|
89960
|
+
"afpub",
|
|
89961
|
+
"ai",
|
|
89962
|
+
"aif",
|
|
89963
|
+
"aiff",
|
|
89964
|
+
"alz",
|
|
89965
|
+
"ape",
|
|
89966
|
+
"apk",
|
|
89967
|
+
"appimage",
|
|
89968
|
+
"ar",
|
|
89969
|
+
"arj",
|
|
89970
|
+
"asf",
|
|
89971
|
+
"au",
|
|
89972
|
+
"avi",
|
|
89973
|
+
"bak",
|
|
89974
|
+
"baml",
|
|
89975
|
+
"bh",
|
|
89976
|
+
"bin",
|
|
89977
|
+
"bk",
|
|
89978
|
+
"bmp",
|
|
89979
|
+
"btif",
|
|
89980
|
+
"bz2",
|
|
89981
|
+
"bzip2",
|
|
89982
|
+
"cab",
|
|
89983
|
+
"caf",
|
|
89984
|
+
"cgm",
|
|
89985
|
+
"class",
|
|
89986
|
+
"cmx",
|
|
89987
|
+
"cpio",
|
|
89988
|
+
"cr2",
|
|
89989
|
+
"cur",
|
|
89990
|
+
"dat",
|
|
89991
|
+
"dcm",
|
|
89992
|
+
"deb",
|
|
89993
|
+
"dex",
|
|
89994
|
+
"djvu",
|
|
89995
|
+
"dll",
|
|
89996
|
+
"dmg",
|
|
89997
|
+
"dng",
|
|
89998
|
+
"doc",
|
|
89999
|
+
"docm",
|
|
90000
|
+
"docx",
|
|
90001
|
+
"dot",
|
|
90002
|
+
"dotm",
|
|
90003
|
+
"dra",
|
|
90004
|
+
"DS_Store",
|
|
90005
|
+
"dsk",
|
|
90006
|
+
"dts",
|
|
90007
|
+
"dtshd",
|
|
90008
|
+
"dvb",
|
|
90009
|
+
"dwg",
|
|
90010
|
+
"dxf",
|
|
90011
|
+
"ecelp4800",
|
|
90012
|
+
"ecelp7470",
|
|
90013
|
+
"ecelp9600",
|
|
90014
|
+
"egg",
|
|
90015
|
+
"eol",
|
|
90016
|
+
"eot",
|
|
90017
|
+
"epub",
|
|
90018
|
+
"exe",
|
|
90019
|
+
"f4v",
|
|
90020
|
+
"fbs",
|
|
90021
|
+
"fh",
|
|
90022
|
+
"fla",
|
|
90023
|
+
"flac",
|
|
90024
|
+
"flatpak",
|
|
90025
|
+
"fli",
|
|
90026
|
+
"flv",
|
|
90027
|
+
"fpx",
|
|
90028
|
+
"fst",
|
|
90029
|
+
"fvt",
|
|
90030
|
+
"g3",
|
|
90031
|
+
"gh",
|
|
90032
|
+
"gif",
|
|
90033
|
+
"graffle",
|
|
90034
|
+
"gz",
|
|
90035
|
+
"gzip",
|
|
90036
|
+
"h261",
|
|
90037
|
+
"h263",
|
|
90038
|
+
"h264",
|
|
90039
|
+
"icns",
|
|
90040
|
+
"ico",
|
|
90041
|
+
"ief",
|
|
90042
|
+
"img",
|
|
90043
|
+
"ipa",
|
|
90044
|
+
"iso",
|
|
90045
|
+
"jar",
|
|
90046
|
+
"jpeg",
|
|
90047
|
+
"jpg",
|
|
90048
|
+
"jpgv",
|
|
90049
|
+
"jpm",
|
|
90050
|
+
"jxr",
|
|
90051
|
+
"key",
|
|
90052
|
+
"ktx",
|
|
90053
|
+
"lha",
|
|
90054
|
+
"lib",
|
|
90055
|
+
"lvp",
|
|
90056
|
+
"lz",
|
|
90057
|
+
"lzh",
|
|
90058
|
+
"lzma",
|
|
90059
|
+
"lzo",
|
|
90060
|
+
"m3u",
|
|
90061
|
+
"m4a",
|
|
90062
|
+
"m4v",
|
|
90063
|
+
"mar",
|
|
90064
|
+
"mdi",
|
|
90065
|
+
"mht",
|
|
90066
|
+
"mid",
|
|
90067
|
+
"midi",
|
|
90068
|
+
"mj2",
|
|
90069
|
+
"mka",
|
|
90070
|
+
"mkv",
|
|
90071
|
+
"mmr",
|
|
90072
|
+
"mng",
|
|
90073
|
+
"mobi",
|
|
90074
|
+
"mov",
|
|
90075
|
+
"movie",
|
|
90076
|
+
"mp3",
|
|
90077
|
+
"mp4",
|
|
90078
|
+
"mp4a",
|
|
90079
|
+
"mpeg",
|
|
90080
|
+
"mpg",
|
|
90081
|
+
"mpga",
|
|
90082
|
+
"mxu",
|
|
90083
|
+
"nef",
|
|
90084
|
+
"npx",
|
|
90085
|
+
"numbers",
|
|
90086
|
+
"nupkg",
|
|
90087
|
+
"o",
|
|
90088
|
+
"odp",
|
|
90089
|
+
"ods",
|
|
90090
|
+
"odt",
|
|
90091
|
+
"oga",
|
|
90092
|
+
"ogg",
|
|
90093
|
+
"ogv",
|
|
90094
|
+
"otf",
|
|
90095
|
+
"ott",
|
|
90096
|
+
"pages",
|
|
90097
|
+
"pbm",
|
|
90098
|
+
"pcx",
|
|
90099
|
+
"pdb",
|
|
90100
|
+
"pdf",
|
|
90101
|
+
"pea",
|
|
90102
|
+
"pgm",
|
|
90103
|
+
"pic",
|
|
90104
|
+
"png",
|
|
90105
|
+
"pnm",
|
|
90106
|
+
"pot",
|
|
90107
|
+
"potm",
|
|
90108
|
+
"potx",
|
|
90109
|
+
"ppa",
|
|
90110
|
+
"ppam",
|
|
90111
|
+
"ppm",
|
|
90112
|
+
"pps",
|
|
90113
|
+
"ppsm",
|
|
90114
|
+
"ppsx",
|
|
90115
|
+
"ppt",
|
|
90116
|
+
"pptm",
|
|
90117
|
+
"pptx",
|
|
90118
|
+
"psd",
|
|
90119
|
+
"pya",
|
|
90120
|
+
"pyc",
|
|
90121
|
+
"pyo",
|
|
90122
|
+
"pyv",
|
|
90123
|
+
"qt",
|
|
90124
|
+
"rar",
|
|
90125
|
+
"ras",
|
|
90126
|
+
"raw",
|
|
90127
|
+
"resources",
|
|
90128
|
+
"rgb",
|
|
90129
|
+
"rip",
|
|
90130
|
+
"rlc",
|
|
90131
|
+
"rmf",
|
|
90132
|
+
"rmvb",
|
|
90133
|
+
"rpm",
|
|
90134
|
+
"rtf",
|
|
90135
|
+
"rz",
|
|
90136
|
+
"s3m",
|
|
90137
|
+
"s7z",
|
|
90138
|
+
"scpt",
|
|
90139
|
+
"sgi",
|
|
90140
|
+
"shar",
|
|
90141
|
+
"snap",
|
|
90142
|
+
"sil",
|
|
90143
|
+
"sketch",
|
|
90144
|
+
"slk",
|
|
90145
|
+
"smv",
|
|
90146
|
+
"snk",
|
|
90147
|
+
"so",
|
|
90148
|
+
"stl",
|
|
90149
|
+
"suo",
|
|
90150
|
+
"sub",
|
|
90151
|
+
"swf",
|
|
90152
|
+
"tar",
|
|
90153
|
+
"tbz",
|
|
90154
|
+
"tbz2",
|
|
90155
|
+
"tga",
|
|
90156
|
+
"tgz",
|
|
90157
|
+
"thmx",
|
|
90158
|
+
"tif",
|
|
90159
|
+
"tiff",
|
|
90160
|
+
"tlz",
|
|
90161
|
+
"ttc",
|
|
90162
|
+
"ttf",
|
|
90163
|
+
"txz",
|
|
90164
|
+
"udf",
|
|
90165
|
+
"uvh",
|
|
90166
|
+
"uvi",
|
|
90167
|
+
"uvm",
|
|
90168
|
+
"uvp",
|
|
90169
|
+
"uvs",
|
|
90170
|
+
"uvu",
|
|
90171
|
+
"viv",
|
|
90172
|
+
"vob",
|
|
90173
|
+
"war",
|
|
90174
|
+
"wav",
|
|
90175
|
+
"wax",
|
|
90176
|
+
"wbmp",
|
|
90177
|
+
"wdp",
|
|
90178
|
+
"weba",
|
|
90179
|
+
"webm",
|
|
90180
|
+
"webp",
|
|
90181
|
+
"whl",
|
|
90182
|
+
"wim",
|
|
90183
|
+
"wm",
|
|
90184
|
+
"wma",
|
|
90185
|
+
"wmv",
|
|
90186
|
+
"wmx",
|
|
90187
|
+
"woff",
|
|
90188
|
+
"woff2",
|
|
90189
|
+
"wrm",
|
|
90190
|
+
"wvx",
|
|
90191
|
+
"xbm",
|
|
90192
|
+
"xif",
|
|
90193
|
+
"xla",
|
|
90194
|
+
"xlam",
|
|
90195
|
+
"xls",
|
|
90196
|
+
"xlsb",
|
|
90197
|
+
"xlsm",
|
|
90198
|
+
"xlsx",
|
|
90199
|
+
"xlt",
|
|
90200
|
+
"xltm",
|
|
90201
|
+
"xltx",
|
|
90202
|
+
"xm",
|
|
90203
|
+
"xmind",
|
|
90204
|
+
"xpi",
|
|
90205
|
+
"xpm",
|
|
90206
|
+
"xwd",
|
|
90207
|
+
"xz",
|
|
90208
|
+
"z",
|
|
90209
|
+
"zip",
|
|
90210
|
+
"zipx"
|
|
90211
|
+
]);
|
|
90212
|
+
FsWatchInstances = new Map;
|
|
90213
|
+
FsWatchFileInstances = new Map;
|
|
90214
|
+
});
|
|
90215
|
+
|
|
90216
|
+
// ../../node_modules/.pnpm/chokidar@5.0.0/node_modules/chokidar/index.js
|
|
90217
|
+
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
90218
|
+
import { stat as statcb, Stats } from "node:fs";
|
|
90219
|
+
import { readdir as readdir2, stat as stat4 } from "node:fs/promises";
|
|
90220
|
+
import * as sp2 from "node:path";
|
|
90221
|
+
function arrify(item) {
|
|
90222
|
+
return Array.isArray(item) ? item : [item];
|
|
90223
|
+
}
|
|
90224
|
+
function createPattern(matcher) {
|
|
90225
|
+
if (typeof matcher === "function")
|
|
90226
|
+
return matcher;
|
|
90227
|
+
if (typeof matcher === "string")
|
|
90228
|
+
return (string2) => matcher === string2;
|
|
90229
|
+
if (matcher instanceof RegExp)
|
|
90230
|
+
return (string2) => matcher.test(string2);
|
|
90231
|
+
if (typeof matcher === "object" && matcher !== null) {
|
|
90232
|
+
return (string2) => {
|
|
90233
|
+
if (matcher.path === string2)
|
|
90234
|
+
return true;
|
|
90235
|
+
if (matcher.recursive) {
|
|
90236
|
+
const relative4 = sp2.relative(matcher.path, string2);
|
|
90237
|
+
if (!relative4) {
|
|
90238
|
+
return false;
|
|
90239
|
+
}
|
|
90240
|
+
return !relative4.startsWith("..") && !sp2.isAbsolute(relative4);
|
|
89013
90241
|
}
|
|
89014
|
-
|
|
89015
|
-
|
|
89016
|
-
|
|
89017
|
-
|
|
89018
|
-
|
|
89019
|
-
|
|
89020
|
-
|
|
89021
|
-
|
|
89022
|
-
|
|
89023
|
-
|
|
89024
|
-
|
|
89025
|
-
|
|
89026
|
-
|
|
89027
|
-
|
|
90242
|
+
return false;
|
|
90243
|
+
};
|
|
90244
|
+
}
|
|
90245
|
+
return () => false;
|
|
90246
|
+
}
|
|
90247
|
+
function normalizePath(path5) {
|
|
90248
|
+
if (typeof path5 !== "string")
|
|
90249
|
+
throw new Error("string expected");
|
|
90250
|
+
path5 = sp2.normalize(path5);
|
|
90251
|
+
path5 = path5.replace(/\\/g, "/");
|
|
90252
|
+
let prepend4 = false;
|
|
90253
|
+
if (path5.startsWith("//"))
|
|
90254
|
+
prepend4 = true;
|
|
90255
|
+
path5 = path5.replace(DOUBLE_SLASH_RE, "/");
|
|
90256
|
+
if (prepend4)
|
|
90257
|
+
path5 = "/" + path5;
|
|
90258
|
+
return path5;
|
|
90259
|
+
}
|
|
90260
|
+
function matchPatterns(patterns, testString, stats) {
|
|
90261
|
+
const path5 = normalizePath(testString);
|
|
90262
|
+
for (let index = 0;index < patterns.length; index++) {
|
|
90263
|
+
const pattern2 = patterns[index];
|
|
90264
|
+
if (pattern2(path5, stats)) {
|
|
90265
|
+
return true;
|
|
89028
90266
|
}
|
|
89029
|
-
}
|
|
89030
|
-
|
|
90267
|
+
}
|
|
90268
|
+
return false;
|
|
90269
|
+
}
|
|
90270
|
+
function anymatch(matchers, testString) {
|
|
90271
|
+
if (matchers == null) {
|
|
90272
|
+
throw new TypeError("anymatch: specify first argument");
|
|
90273
|
+
}
|
|
90274
|
+
const matchersArray = arrify(matchers);
|
|
90275
|
+
const patterns = matchersArray.map((matcher) => createPattern(matcher));
|
|
90276
|
+
if (testString == null) {
|
|
90277
|
+
return (testString2, stats) => {
|
|
90278
|
+
return matchPatterns(patterns, testString2, stats);
|
|
90279
|
+
};
|
|
90280
|
+
}
|
|
90281
|
+
return matchPatterns(patterns, testString);
|
|
90282
|
+
}
|
|
89031
90283
|
|
|
89032
|
-
|
|
89033
|
-
|
|
89034
|
-
|
|
89035
|
-
|
|
89036
|
-
|
|
89037
|
-
|
|
89038
|
-
|
|
89039
|
-
|
|
89040
|
-
|
|
90284
|
+
class DirEntry {
|
|
90285
|
+
path;
|
|
90286
|
+
_removeWatcher;
|
|
90287
|
+
items;
|
|
90288
|
+
constructor(dir, removeWatcher) {
|
|
90289
|
+
this.path = dir;
|
|
90290
|
+
this._removeWatcher = removeWatcher;
|
|
90291
|
+
this.items = new Set;
|
|
90292
|
+
}
|
|
90293
|
+
add(item) {
|
|
90294
|
+
const { items } = this;
|
|
90295
|
+
if (!items)
|
|
89041
90296
|
return;
|
|
89042
|
-
if (
|
|
90297
|
+
if (item !== ONE_DOT && item !== TWO_DOTS)
|
|
90298
|
+
items.add(item);
|
|
90299
|
+
}
|
|
90300
|
+
async remove(item) {
|
|
90301
|
+
const { items } = this;
|
|
90302
|
+
if (!items)
|
|
89043
90303
|
return;
|
|
89044
|
-
|
|
89045
|
-
|
|
89046
|
-
|
|
89047
|
-
|
|
89048
|
-
|
|
89049
|
-
|
|
89050
|
-
|
|
89051
|
-
|
|
89052
|
-
|
|
89053
|
-
|
|
89054
|
-
return {
|
|
89055
|
-
stop: () => {
|
|
89056
|
-
unsubscribe();
|
|
89057
|
-
console.log(`[${formatTimestamp()}] \uD83D\uDCC2 File content subscription stopped`);
|
|
90304
|
+
items.delete(item);
|
|
90305
|
+
if (items.size > 0)
|
|
90306
|
+
return;
|
|
90307
|
+
const dir = this.path;
|
|
90308
|
+
try {
|
|
90309
|
+
await readdir2(dir);
|
|
90310
|
+
} catch (err) {
|
|
90311
|
+
if (this._removeWatcher) {
|
|
90312
|
+
this._removeWatcher(sp2.dirname(dir), sp2.basename(dir));
|
|
90313
|
+
}
|
|
89058
90314
|
}
|
|
89059
|
-
}
|
|
89060
|
-
|
|
89061
|
-
|
|
89062
|
-
|
|
89063
|
-
|
|
89064
|
-
|
|
89065
|
-
|
|
89066
|
-
|
|
89067
|
-
}
|
|
89068
|
-
|
|
89069
|
-
|
|
89070
|
-
|
|
89071
|
-
|
|
89072
|
-
|
|
90315
|
+
}
|
|
90316
|
+
has(item) {
|
|
90317
|
+
const { items } = this;
|
|
90318
|
+
if (!items)
|
|
90319
|
+
return;
|
|
90320
|
+
return items.has(item);
|
|
90321
|
+
}
|
|
90322
|
+
getChildren() {
|
|
90323
|
+
const { items } = this;
|
|
90324
|
+
if (!items)
|
|
90325
|
+
return [];
|
|
90326
|
+
return [...items.values()];
|
|
90327
|
+
}
|
|
90328
|
+
dispose() {
|
|
90329
|
+
this.items.clear();
|
|
90330
|
+
this.path = "";
|
|
90331
|
+
this._removeWatcher = EMPTY_FN;
|
|
90332
|
+
this.items = EMPTY_SET;
|
|
90333
|
+
Object.freeze(this);
|
|
90334
|
+
}
|
|
89073
90335
|
}
|
|
89074
|
-
var init_file_tree_data_hash = () => {};
|
|
89075
90336
|
|
|
89076
|
-
|
|
89077
|
-
|
|
89078
|
-
|
|
89079
|
-
|
|
89080
|
-
|
|
89081
|
-
|
|
89082
|
-
|
|
89083
|
-
|
|
89084
|
-
|
|
89085
|
-
|
|
89086
|
-
|
|
89087
|
-
|
|
89088
|
-
|
|
89089
|
-
|
|
89090
|
-
|
|
89091
|
-
|
|
90337
|
+
class WatchHelper {
|
|
90338
|
+
fsw;
|
|
90339
|
+
path;
|
|
90340
|
+
watchPath;
|
|
90341
|
+
fullWatchPath;
|
|
90342
|
+
dirParts;
|
|
90343
|
+
followSymlinks;
|
|
90344
|
+
statMethod;
|
|
90345
|
+
constructor(path5, follow, fsw) {
|
|
90346
|
+
this.fsw = fsw;
|
|
90347
|
+
const watchPath = path5;
|
|
90348
|
+
this.path = path5 = path5.replace(REPLACER_RE, "");
|
|
90349
|
+
this.watchPath = watchPath;
|
|
90350
|
+
this.fullWatchPath = sp2.resolve(watchPath);
|
|
90351
|
+
this.dirParts = [];
|
|
90352
|
+
this.dirParts.forEach((parts2) => {
|
|
90353
|
+
if (parts2.length > 1)
|
|
90354
|
+
parts2.pop();
|
|
90355
|
+
});
|
|
90356
|
+
this.followSymlinks = follow;
|
|
90357
|
+
this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
|
|
89092
90358
|
}
|
|
89093
|
-
|
|
89094
|
-
return
|
|
90359
|
+
entryPath(entry) {
|
|
90360
|
+
return sp2.join(this.watchPath, sp2.relative(this.watchPath, entry.fullPath));
|
|
89095
90361
|
}
|
|
89096
|
-
|
|
89097
|
-
|
|
89098
|
-
|
|
90362
|
+
filterPath(entry) {
|
|
90363
|
+
const { stats } = entry;
|
|
90364
|
+
if (stats && stats.isSymbolicLink())
|
|
90365
|
+
return this.filterDir(entry);
|
|
90366
|
+
const resolvedPath = this.entryPath(entry);
|
|
90367
|
+
return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats);
|
|
89099
90368
|
}
|
|
89100
|
-
|
|
89101
|
-
|
|
89102
|
-
return slash === -1 ? parentShardId : `${parentShardId}/${remainder.slice(0, slash)}`;
|
|
89103
|
-
}
|
|
89104
|
-
function groupEntriesByShardId(entries2, parentShardId) {
|
|
89105
|
-
const groups = new Map;
|
|
89106
|
-
for (const entry of entries2) {
|
|
89107
|
-
const shardId = parentShardId === "__root__" ? shardIdForPath(entry.path) : childShardId(entry.path, parentShardId);
|
|
89108
|
-
const group = groups.get(shardId) ?? [];
|
|
89109
|
-
group.push(entry);
|
|
89110
|
-
groups.set(shardId, group);
|
|
90369
|
+
filterDir(entry) {
|
|
90370
|
+
return this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
|
|
89111
90371
|
}
|
|
89112
|
-
return groups;
|
|
89113
90372
|
}
|
|
89114
|
-
function
|
|
89115
|
-
const
|
|
89116
|
-
|
|
89117
|
-
|
|
89118
|
-
payload,
|
|
89119
|
-
dataHash: computeShardDataHash(payload),
|
|
89120
|
-
entryCount: payload.entries.length,
|
|
89121
|
-
data: { compression: "gzip", content: compressed }
|
|
89122
|
-
};
|
|
90373
|
+
function watch(paths, options = {}) {
|
|
90374
|
+
const watcher = new FSWatcher(options);
|
|
90375
|
+
watcher.add(paths);
|
|
90376
|
+
return watcher;
|
|
89123
90377
|
}
|
|
89124
|
-
|
|
89125
|
-
const
|
|
89126
|
-
|
|
89127
|
-
|
|
89128
|
-
rootDir: tree.rootDir
|
|
89129
|
-
};
|
|
89130
|
-
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
89131
|
-
if (Buffer.byteLength(compressed, "utf8") <= MAX_SHARD_JSON_BYTES) {
|
|
89132
|
-
return [buildPreparedShard(shardId, payload)];
|
|
89133
|
-
}
|
|
89134
|
-
const subgroups = groupEntriesByShardId(entries2, shardId);
|
|
89135
|
-
if (subgroups.size <= 1) {
|
|
89136
|
-
return [buildPreparedShard(shardId, payload)];
|
|
90378
|
+
var SLASH = "/", SLASH_SLASH = "//", ONE_DOT = ".", TWO_DOTS = "..", STRING_TYPE = "string", BACK_SLASH_RE, DOUBLE_SLASH_RE, DOT_RE, REPLACER_RE, isMatcherObject = (matcher) => typeof matcher === "object" && matcher !== null && !(matcher instanceof RegExp), unifyPaths = (paths_) => {
|
|
90379
|
+
const paths = arrify(paths_).flat();
|
|
90380
|
+
if (!paths.every((p) => typeof p === STRING_TYPE)) {
|
|
90381
|
+
throw new TypeError(`Non-string provided as watch path: ${paths}`);
|
|
89137
90382
|
}
|
|
89138
|
-
|
|
89139
|
-
|
|
89140
|
-
|
|
90383
|
+
return paths.map(normalizePathToUnix);
|
|
90384
|
+
}, toUnix = (string2) => {
|
|
90385
|
+
let str = string2.replace(BACK_SLASH_RE, SLASH);
|
|
90386
|
+
let prepend4 = false;
|
|
90387
|
+
if (str.startsWith(SLASH_SLASH)) {
|
|
90388
|
+
prepend4 = true;
|
|
89141
90389
|
}
|
|
89142
|
-
|
|
89143
|
-
|
|
89144
|
-
|
|
89145
|
-
const topGroups = groupEntriesByShardId(tree.entries, "__root__");
|
|
89146
|
-
const shards = [];
|
|
89147
|
-
for (const [shardId, entries2] of topGroups) {
|
|
89148
|
-
shards.push(...prepareShardGroup(entries2, shardId, tree));
|
|
90390
|
+
str = str.replace(DOUBLE_SLASH_RE, SLASH);
|
|
90391
|
+
if (prepend4) {
|
|
90392
|
+
str = SLASH + str;
|
|
89149
90393
|
}
|
|
89150
|
-
return
|
|
89151
|
-
}
|
|
89152
|
-
|
|
89153
|
-
|
|
89154
|
-
|
|
89155
|
-
|
|
89156
|
-
}
|
|
89157
|
-
|
|
89158
|
-
|
|
89159
|
-
|
|
89160
|
-
|
|
89161
|
-
|
|
89162
|
-
|
|
89163
|
-
|
|
89164
|
-
|
|
89165
|
-
|
|
89166
|
-
|
|
89167
|
-
|
|
89168
|
-
|
|
89169
|
-
|
|
89170
|
-
|
|
90394
|
+
return str;
|
|
90395
|
+
}, normalizePathToUnix = (path5) => toUnix(sp2.normalize(toUnix(path5))), normalizeIgnored = (cwd = "") => (path5) => {
|
|
90396
|
+
if (typeof path5 === "string") {
|
|
90397
|
+
return normalizePathToUnix(sp2.isAbsolute(path5) ? path5 : sp2.join(cwd, path5));
|
|
90398
|
+
} else {
|
|
90399
|
+
return path5;
|
|
90400
|
+
}
|
|
90401
|
+
}, getAbsolutePath = (path5, cwd) => {
|
|
90402
|
+
if (sp2.isAbsolute(path5)) {
|
|
90403
|
+
return path5;
|
|
90404
|
+
}
|
|
90405
|
+
return sp2.join(cwd, path5);
|
|
90406
|
+
}, EMPTY_SET, STAT_METHOD_F = "stat", STAT_METHOD_L = "lstat", FSWatcher;
|
|
90407
|
+
var init_chokidar = __esm(() => {
|
|
90408
|
+
init_readdirp();
|
|
90409
|
+
init_handler();
|
|
90410
|
+
/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */
|
|
90411
|
+
BACK_SLASH_RE = /\\/g;
|
|
90412
|
+
DOUBLE_SLASH_RE = /\/\//g;
|
|
90413
|
+
DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
|
|
90414
|
+
REPLACER_RE = /^\.[/\\]/;
|
|
90415
|
+
EMPTY_SET = Object.freeze(new Set);
|
|
90416
|
+
FSWatcher = class FSWatcher extends EventEmitter2 {
|
|
90417
|
+
closed;
|
|
90418
|
+
options;
|
|
90419
|
+
_closers;
|
|
90420
|
+
_ignoredPaths;
|
|
90421
|
+
_throttled;
|
|
90422
|
+
_streams;
|
|
90423
|
+
_symlinkPaths;
|
|
90424
|
+
_watched;
|
|
90425
|
+
_pendingWrites;
|
|
90426
|
+
_pendingUnlinks;
|
|
90427
|
+
_readyCount;
|
|
90428
|
+
_emitReady;
|
|
90429
|
+
_closePromise;
|
|
90430
|
+
_userIgnored;
|
|
90431
|
+
_readyEmitted;
|
|
90432
|
+
_emitRaw;
|
|
90433
|
+
_boundRemove;
|
|
90434
|
+
_nodeFsHandler;
|
|
90435
|
+
constructor(_opts = {}) {
|
|
90436
|
+
super();
|
|
90437
|
+
this.closed = false;
|
|
90438
|
+
this._closers = new Map;
|
|
90439
|
+
this._ignoredPaths = new Set;
|
|
90440
|
+
this._throttled = new Map;
|
|
90441
|
+
this._streams = new Set;
|
|
90442
|
+
this._symlinkPaths = new Map;
|
|
90443
|
+
this._watched = new Map;
|
|
90444
|
+
this._pendingWrites = new Map;
|
|
90445
|
+
this._pendingUnlinks = new Map;
|
|
90446
|
+
this._readyCount = 0;
|
|
90447
|
+
this._readyEmitted = false;
|
|
90448
|
+
const awf = _opts.awaitWriteFinish;
|
|
90449
|
+
const DEF_AWF = { stabilityThreshold: 2000, pollInterval: 100 };
|
|
90450
|
+
const opts = {
|
|
90451
|
+
persistent: true,
|
|
90452
|
+
ignoreInitial: false,
|
|
90453
|
+
ignorePermissionErrors: false,
|
|
90454
|
+
interval: 100,
|
|
90455
|
+
binaryInterval: 300,
|
|
90456
|
+
followSymlinks: true,
|
|
90457
|
+
usePolling: false,
|
|
90458
|
+
atomic: true,
|
|
90459
|
+
..._opts,
|
|
90460
|
+
ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]),
|
|
90461
|
+
awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === "object" ? { ...DEF_AWF, ...awf } : false
|
|
90462
|
+
};
|
|
90463
|
+
if (isIBMi)
|
|
90464
|
+
opts.usePolling = true;
|
|
90465
|
+
if (opts.atomic === undefined)
|
|
90466
|
+
opts.atomic = !opts.usePolling;
|
|
90467
|
+
const envPoll = process.env.CHOKIDAR_USEPOLLING;
|
|
90468
|
+
if (envPoll !== undefined) {
|
|
90469
|
+
const envLower = envPoll.toLowerCase();
|
|
90470
|
+
if (envLower === "false" || envLower === "0")
|
|
90471
|
+
opts.usePolling = false;
|
|
90472
|
+
else if (envLower === "true" || envLower === "1")
|
|
90473
|
+
opts.usePolling = true;
|
|
90474
|
+
else
|
|
90475
|
+
opts.usePolling = !!envLower;
|
|
90476
|
+
}
|
|
90477
|
+
const envInterval = process.env.CHOKIDAR_INTERVAL;
|
|
90478
|
+
if (envInterval)
|
|
90479
|
+
opts.interval = Number.parseInt(envInterval, 10);
|
|
90480
|
+
let readyCalls = 0;
|
|
90481
|
+
this._emitReady = () => {
|
|
90482
|
+
readyCalls++;
|
|
90483
|
+
if (readyCalls >= this._readyCount) {
|
|
90484
|
+
this._emitReady = EMPTY_FN;
|
|
90485
|
+
this._readyEmitted = true;
|
|
90486
|
+
process.nextTick(() => this.emit(EVENTS.READY));
|
|
90487
|
+
}
|
|
90488
|
+
};
|
|
90489
|
+
this._emitRaw = (...args2) => this.emit(EVENTS.RAW, ...args2);
|
|
90490
|
+
this._boundRemove = this._remove.bind(this);
|
|
90491
|
+
this.options = opts;
|
|
90492
|
+
this._nodeFsHandler = new NodeFsHandler(this);
|
|
90493
|
+
Object.freeze(opts);
|
|
90494
|
+
}
|
|
90495
|
+
_addIgnoredPath(matcher) {
|
|
90496
|
+
if (isMatcherObject(matcher)) {
|
|
90497
|
+
for (const ignored of this._ignoredPaths) {
|
|
90498
|
+
if (isMatcherObject(ignored) && ignored.path === matcher.path && ignored.recursive === matcher.recursive) {
|
|
90499
|
+
return;
|
|
90500
|
+
}
|
|
90501
|
+
}
|
|
90502
|
+
}
|
|
90503
|
+
this._ignoredPaths.add(matcher);
|
|
89171
90504
|
}
|
|
89172
|
-
|
|
89173
|
-
|
|
89174
|
-
|
|
89175
|
-
|
|
89176
|
-
|
|
89177
|
-
|
|
90505
|
+
_removeIgnoredPath(matcher) {
|
|
90506
|
+
this._ignoredPaths.delete(matcher);
|
|
90507
|
+
if (typeof matcher === "string") {
|
|
90508
|
+
for (const ignored of this._ignoredPaths) {
|
|
90509
|
+
if (isMatcherObject(ignored) && ignored.path === matcher) {
|
|
90510
|
+
this._ignoredPaths.delete(ignored);
|
|
90511
|
+
}
|
|
90512
|
+
}
|
|
90513
|
+
}
|
|
89178
90514
|
}
|
|
89179
|
-
|
|
89180
|
-
|
|
89181
|
-
|
|
89182
|
-
|
|
89183
|
-
|
|
89184
|
-
|
|
90515
|
+
add(paths_, _origAdd, _internal) {
|
|
90516
|
+
const { cwd } = this.options;
|
|
90517
|
+
this.closed = false;
|
|
90518
|
+
this._closePromise = undefined;
|
|
90519
|
+
let paths = unifyPaths(paths_);
|
|
90520
|
+
if (cwd) {
|
|
90521
|
+
paths = paths.map((path5) => {
|
|
90522
|
+
const absPath = getAbsolutePath(path5, cwd);
|
|
90523
|
+
return absPath;
|
|
90524
|
+
});
|
|
90525
|
+
}
|
|
90526
|
+
paths.forEach((path5) => {
|
|
90527
|
+
this._removeIgnoredPath(path5);
|
|
90528
|
+
});
|
|
90529
|
+
this._userIgnored = undefined;
|
|
90530
|
+
if (!this._readyCount)
|
|
90531
|
+
this._readyCount = 0;
|
|
90532
|
+
this._readyCount += paths.length;
|
|
90533
|
+
Promise.all(paths.map(async (path5) => {
|
|
90534
|
+
const res = await this._nodeFsHandler._addToNodeFs(path5, !_internal, undefined, 0, _origAdd);
|
|
90535
|
+
if (res)
|
|
90536
|
+
this._emitReady();
|
|
90537
|
+
return res;
|
|
90538
|
+
})).then((results) => {
|
|
90539
|
+
if (this.closed)
|
|
90540
|
+
return;
|
|
90541
|
+
results.forEach((item) => {
|
|
90542
|
+
if (item)
|
|
90543
|
+
this.add(sp2.dirname(item), sp2.basename(_origAdd || item));
|
|
90544
|
+
});
|
|
90545
|
+
});
|
|
90546
|
+
return this;
|
|
89185
90547
|
}
|
|
89186
|
-
|
|
89187
|
-
if (
|
|
89188
|
-
|
|
90548
|
+
unwatch(paths_) {
|
|
90549
|
+
if (this.closed)
|
|
90550
|
+
return this;
|
|
90551
|
+
const paths = unifyPaths(paths_);
|
|
90552
|
+
const { cwd } = this.options;
|
|
90553
|
+
paths.forEach((path5) => {
|
|
90554
|
+
if (!sp2.isAbsolute(path5) && !this._closers.has(path5)) {
|
|
90555
|
+
if (cwd)
|
|
90556
|
+
path5 = sp2.join(cwd, path5);
|
|
90557
|
+
path5 = sp2.resolve(path5);
|
|
90558
|
+
}
|
|
90559
|
+
this._closePath(path5);
|
|
90560
|
+
this._addIgnoredPath(path5);
|
|
90561
|
+
if (this._watched.has(path5)) {
|
|
90562
|
+
this._addIgnoredPath({
|
|
90563
|
+
path: path5,
|
|
90564
|
+
recursive: true
|
|
90565
|
+
});
|
|
90566
|
+
}
|
|
90567
|
+
this._userIgnored = undefined;
|
|
90568
|
+
});
|
|
90569
|
+
return this;
|
|
90570
|
+
}
|
|
90571
|
+
close() {
|
|
90572
|
+
if (this._closePromise) {
|
|
90573
|
+
return this._closePromise;
|
|
90574
|
+
}
|
|
90575
|
+
this.closed = true;
|
|
90576
|
+
this.removeAllListeners();
|
|
90577
|
+
const closers = [];
|
|
90578
|
+
this._closers.forEach((closerList) => closerList.forEach((closer) => {
|
|
90579
|
+
const promise3 = closer();
|
|
90580
|
+
if (promise3 instanceof Promise)
|
|
90581
|
+
closers.push(promise3);
|
|
90582
|
+
}));
|
|
90583
|
+
this._streams.forEach((stream4) => stream4.destroy());
|
|
90584
|
+
this._userIgnored = undefined;
|
|
90585
|
+
this._readyCount = 0;
|
|
90586
|
+
this._readyEmitted = false;
|
|
90587
|
+
this._watched.forEach((dirent) => dirent.dispose());
|
|
90588
|
+
this._closers.clear();
|
|
90589
|
+
this._watched.clear();
|
|
90590
|
+
this._streams.clear();
|
|
90591
|
+
this._symlinkPaths.clear();
|
|
90592
|
+
this._throttled.clear();
|
|
90593
|
+
this._closePromise = closers.length ? Promise.all(closers).then(() => {
|
|
90594
|
+
return;
|
|
90595
|
+
}) : Promise.resolve();
|
|
90596
|
+
return this._closePromise;
|
|
90597
|
+
}
|
|
90598
|
+
getWatched() {
|
|
90599
|
+
const watchList = {};
|
|
90600
|
+
this._watched.forEach((entry, dir) => {
|
|
90601
|
+
const key = this.options.cwd ? sp2.relative(this.options.cwd, dir) : dir;
|
|
90602
|
+
const index = key || ONE_DOT;
|
|
90603
|
+
watchList[index] = entry.getChildren().sort();
|
|
90604
|
+
});
|
|
90605
|
+
return watchList;
|
|
90606
|
+
}
|
|
90607
|
+
emitWithAll(event, args2) {
|
|
90608
|
+
this.emit(event, ...args2);
|
|
90609
|
+
if (event !== EVENTS.ERROR)
|
|
90610
|
+
this.emit(EVENTS.ALL, event, ...args2);
|
|
90611
|
+
}
|
|
90612
|
+
async _emit(event, path5, stats) {
|
|
90613
|
+
if (this.closed)
|
|
89189
90614
|
return;
|
|
90615
|
+
const opts = this.options;
|
|
90616
|
+
if (isWindows)
|
|
90617
|
+
path5 = sp2.normalize(path5);
|
|
90618
|
+
if (opts.cwd)
|
|
90619
|
+
path5 = sp2.relative(opts.cwd, path5);
|
|
90620
|
+
const args2 = [path5];
|
|
90621
|
+
if (stats != null)
|
|
90622
|
+
args2.push(stats);
|
|
90623
|
+
const awf = opts.awaitWriteFinish;
|
|
90624
|
+
let pw;
|
|
90625
|
+
if (awf && (pw = this._pendingWrites.get(path5))) {
|
|
90626
|
+
pw.lastChange = new Date;
|
|
90627
|
+
return this;
|
|
89190
90628
|
}
|
|
89191
|
-
if (
|
|
89192
|
-
|
|
89193
|
-
|
|
89194
|
-
|
|
89195
|
-
|
|
89196
|
-
|
|
89197
|
-
|
|
89198
|
-
|
|
89199
|
-
|
|
89200
|
-
|
|
89201
|
-
|
|
89202
|
-
|
|
89203
|
-
|
|
89204
|
-
|
|
89205
|
-
|
|
90629
|
+
if (opts.atomic) {
|
|
90630
|
+
if (event === EVENTS.UNLINK) {
|
|
90631
|
+
this._pendingUnlinks.set(path5, [event, ...args2]);
|
|
90632
|
+
setTimeout(() => {
|
|
90633
|
+
this._pendingUnlinks.forEach((entry, path6) => {
|
|
90634
|
+
this.emit(...entry);
|
|
90635
|
+
this.emit(EVENTS.ALL, ...entry);
|
|
90636
|
+
this._pendingUnlinks.delete(path6);
|
|
90637
|
+
});
|
|
90638
|
+
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
90639
|
+
return this;
|
|
90640
|
+
}
|
|
90641
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path5)) {
|
|
90642
|
+
event = EVENTS.CHANGE;
|
|
90643
|
+
this._pendingUnlinks.delete(path5);
|
|
90644
|
+
}
|
|
90645
|
+
}
|
|
90646
|
+
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
90647
|
+
const awfEmit = (err, stats2) => {
|
|
90648
|
+
if (err) {
|
|
90649
|
+
event = EVENTS.ERROR;
|
|
90650
|
+
args2[0] = err;
|
|
90651
|
+
this.emitWithAll(event, args2);
|
|
90652
|
+
} else if (stats2) {
|
|
90653
|
+
if (args2.length > 1) {
|
|
90654
|
+
args2[1] = stats2;
|
|
90655
|
+
} else {
|
|
90656
|
+
args2.push(stats2);
|
|
90657
|
+
}
|
|
90658
|
+
this.emitWithAll(event, args2);
|
|
90659
|
+
}
|
|
90660
|
+
};
|
|
90661
|
+
this._awaitWriteFinish(path5, awf.stabilityThreshold, event, awfEmit);
|
|
90662
|
+
return this;
|
|
90663
|
+
}
|
|
90664
|
+
if (event === EVENTS.CHANGE) {
|
|
90665
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path5, 50);
|
|
90666
|
+
if (isThrottled)
|
|
90667
|
+
return this;
|
|
90668
|
+
}
|
|
90669
|
+
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
90670
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path5) : path5;
|
|
90671
|
+
let stats2;
|
|
90672
|
+
try {
|
|
90673
|
+
stats2 = await stat4(fullPath);
|
|
90674
|
+
} catch (err) {}
|
|
90675
|
+
if (!stats2 || this.closed)
|
|
90676
|
+
return;
|
|
90677
|
+
args2.push(stats2);
|
|
90678
|
+
}
|
|
90679
|
+
this.emitWithAll(event, args2);
|
|
90680
|
+
return this;
|
|
90681
|
+
}
|
|
90682
|
+
_handleError(error) {
|
|
90683
|
+
const code2 = error && error.code;
|
|
90684
|
+
if (error && code2 !== "ENOENT" && code2 !== "ENOTDIR" && (!this.options.ignorePermissionErrors || code2 !== "EPERM" && code2 !== "EACCES")) {
|
|
90685
|
+
this.emit(EVENTS.ERROR, error);
|
|
90686
|
+
}
|
|
90687
|
+
return error || this.closed;
|
|
90688
|
+
}
|
|
90689
|
+
_throttle(actionType, path5, timeout3) {
|
|
90690
|
+
if (!this._throttled.has(actionType)) {
|
|
90691
|
+
this._throttled.set(actionType, new Map);
|
|
90692
|
+
}
|
|
90693
|
+
const action = this._throttled.get(actionType);
|
|
90694
|
+
if (!action)
|
|
90695
|
+
throw new Error("invalid throttle");
|
|
90696
|
+
const actionPath = action.get(path5);
|
|
90697
|
+
if (actionPath) {
|
|
90698
|
+
actionPath.count++;
|
|
90699
|
+
return false;
|
|
90700
|
+
}
|
|
90701
|
+
let timeoutObject;
|
|
90702
|
+
const clear = () => {
|
|
90703
|
+
const item = action.get(path5);
|
|
90704
|
+
const count3 = item ? item.count : 0;
|
|
90705
|
+
action.delete(path5);
|
|
90706
|
+
clearTimeout(timeoutObject);
|
|
90707
|
+
if (item)
|
|
90708
|
+
clearTimeout(item.timeoutObject);
|
|
90709
|
+
return count3;
|
|
90710
|
+
};
|
|
90711
|
+
timeoutObject = setTimeout(clear, timeout3);
|
|
90712
|
+
const thr = { timeoutObject, clear, count: 0 };
|
|
90713
|
+
action.set(path5, thr);
|
|
90714
|
+
return thr;
|
|
90715
|
+
}
|
|
90716
|
+
_incrReadyCount() {
|
|
90717
|
+
return this._readyCount++;
|
|
90718
|
+
}
|
|
90719
|
+
_awaitWriteFinish(path5, threshold, event, awfEmit) {
|
|
90720
|
+
const awf = this.options.awaitWriteFinish;
|
|
90721
|
+
if (typeof awf !== "object")
|
|
90722
|
+
return;
|
|
90723
|
+
const pollInterval = awf.pollInterval;
|
|
90724
|
+
let timeoutHandler;
|
|
90725
|
+
let fullPath = path5;
|
|
90726
|
+
if (this.options.cwd && !sp2.isAbsolute(path5)) {
|
|
90727
|
+
fullPath = sp2.join(this.options.cwd, path5);
|
|
90728
|
+
}
|
|
90729
|
+
const now = new Date;
|
|
90730
|
+
const writes = this._pendingWrites;
|
|
90731
|
+
function awaitWriteFinishFn(prevStat) {
|
|
90732
|
+
statcb(fullPath, (err, curStat) => {
|
|
90733
|
+
if (err || !writes.has(path5)) {
|
|
90734
|
+
if (err && err.code !== "ENOENT")
|
|
90735
|
+
awfEmit(err);
|
|
90736
|
+
return;
|
|
90737
|
+
}
|
|
90738
|
+
const now2 = Number(new Date);
|
|
90739
|
+
if (prevStat && curStat.size !== prevStat.size) {
|
|
90740
|
+
writes.get(path5).lastChange = now2;
|
|
90741
|
+
}
|
|
90742
|
+
const pw = writes.get(path5);
|
|
90743
|
+
const df = now2 - pw.lastChange;
|
|
90744
|
+
if (df >= threshold) {
|
|
90745
|
+
writes.delete(path5);
|
|
90746
|
+
awfEmit(undefined, curStat);
|
|
90747
|
+
} else {
|
|
90748
|
+
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
90749
|
+
}
|
|
90750
|
+
});
|
|
90751
|
+
}
|
|
90752
|
+
if (!writes.has(path5)) {
|
|
90753
|
+
writes.set(path5, {
|
|
90754
|
+
lastChange: now,
|
|
90755
|
+
cancelWait: () => {
|
|
90756
|
+
writes.delete(path5);
|
|
90757
|
+
clearTimeout(timeoutHandler);
|
|
90758
|
+
return event;
|
|
90759
|
+
}
|
|
90760
|
+
});
|
|
90761
|
+
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
90762
|
+
}
|
|
90763
|
+
}
|
|
90764
|
+
_isIgnored(path5, stats) {
|
|
90765
|
+
if (this.options.atomic && DOT_RE.test(path5))
|
|
90766
|
+
return true;
|
|
90767
|
+
if (!this._userIgnored) {
|
|
90768
|
+
const { cwd } = this.options;
|
|
90769
|
+
const ign = this.options.ignored;
|
|
90770
|
+
const ignored = (ign || []).map(normalizeIgnored(cwd));
|
|
90771
|
+
const ignoredPaths = [...this._ignoredPaths];
|
|
90772
|
+
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
90773
|
+
this._userIgnored = anymatch(list, undefined);
|
|
90774
|
+
}
|
|
90775
|
+
return this._userIgnored(path5, stats);
|
|
90776
|
+
}
|
|
90777
|
+
_isntIgnored(path5, stat5) {
|
|
90778
|
+
return !this._isIgnored(path5, stat5);
|
|
90779
|
+
}
|
|
90780
|
+
_getWatchHelpers(path5) {
|
|
90781
|
+
return new WatchHelper(path5, this.options.followSymlinks, this);
|
|
90782
|
+
}
|
|
90783
|
+
_getWatchedDir(directory) {
|
|
90784
|
+
const dir = sp2.resolve(directory);
|
|
90785
|
+
if (!this._watched.has(dir))
|
|
90786
|
+
this._watched.set(dir, new DirEntry(dir, this._boundRemove));
|
|
90787
|
+
return this._watched.get(dir);
|
|
90788
|
+
}
|
|
90789
|
+
_hasReadPermissions(stats) {
|
|
90790
|
+
if (this.options.ignorePermissionErrors)
|
|
90791
|
+
return true;
|
|
90792
|
+
return Boolean(Number(stats.mode) & 256);
|
|
90793
|
+
}
|
|
90794
|
+
_remove(directory, item, isDirectory) {
|
|
90795
|
+
const path5 = sp2.join(directory, item);
|
|
90796
|
+
const fullPath = sp2.resolve(path5);
|
|
90797
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path5) || this._watched.has(fullPath);
|
|
90798
|
+
if (!this._throttle("remove", path5, 100))
|
|
90799
|
+
return;
|
|
90800
|
+
if (!isDirectory && this._watched.size === 1) {
|
|
90801
|
+
this.add(directory, item, true);
|
|
90802
|
+
}
|
|
90803
|
+
const wp = this._getWatchedDir(path5);
|
|
90804
|
+
const nestedDirectoryChildren = wp.getChildren();
|
|
90805
|
+
nestedDirectoryChildren.forEach((nested2) => this._remove(path5, nested2));
|
|
90806
|
+
const parent = this._getWatchedDir(directory);
|
|
90807
|
+
const wasTracked = parent.has(item);
|
|
90808
|
+
parent.remove(item);
|
|
90809
|
+
if (this._symlinkPaths.has(fullPath)) {
|
|
90810
|
+
this._symlinkPaths.delete(fullPath);
|
|
90811
|
+
}
|
|
90812
|
+
let relPath = path5;
|
|
90813
|
+
if (this.options.cwd)
|
|
90814
|
+
relPath = sp2.relative(this.options.cwd, path5);
|
|
90815
|
+
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
90816
|
+
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
90817
|
+
if (event === EVENTS.ADD)
|
|
90818
|
+
return;
|
|
89206
90819
|
}
|
|
90820
|
+
this._watched.delete(path5);
|
|
90821
|
+
this._watched.delete(fullPath);
|
|
90822
|
+
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
90823
|
+
if (wasTracked && !this._isIgnored(path5))
|
|
90824
|
+
this._emit(eventName, path5);
|
|
90825
|
+
this._closePath(path5);
|
|
90826
|
+
}
|
|
90827
|
+
_closePath(path5) {
|
|
90828
|
+
this._closeFile(path5);
|
|
90829
|
+
const dir = sp2.dirname(path5);
|
|
90830
|
+
this._getWatchedDir(dir).remove(sp2.basename(path5));
|
|
90831
|
+
}
|
|
90832
|
+
_closeFile(path5) {
|
|
90833
|
+
const closers = this._closers.get(path5);
|
|
90834
|
+
if (!closers)
|
|
90835
|
+
return;
|
|
90836
|
+
closers.forEach((closer) => closer());
|
|
90837
|
+
this._closers.delete(path5);
|
|
89207
90838
|
}
|
|
89208
|
-
|
|
89209
|
-
|
|
89210
|
-
|
|
89211
|
-
|
|
89212
|
-
|
|
89213
|
-
|
|
89214
|
-
|
|
89215
|
-
|
|
90839
|
+
_addPathCloser(path5, closer) {
|
|
90840
|
+
if (!closer)
|
|
90841
|
+
return;
|
|
90842
|
+
let list = this._closers.get(path5);
|
|
90843
|
+
if (!list) {
|
|
90844
|
+
list = [];
|
|
90845
|
+
this._closers.set(path5, list);
|
|
90846
|
+
}
|
|
90847
|
+
list.push(closer);
|
|
90848
|
+
}
|
|
90849
|
+
_readdirp(root, opts) {
|
|
90850
|
+
if (this.closed)
|
|
90851
|
+
return;
|
|
90852
|
+
const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
|
|
90853
|
+
let stream4 = readdirp(root, options);
|
|
90854
|
+
this._streams.add(stream4);
|
|
90855
|
+
stream4.once(STR_CLOSE, () => {
|
|
90856
|
+
stream4 = undefined;
|
|
90857
|
+
});
|
|
90858
|
+
stream4.once(STR_END, () => {
|
|
90859
|
+
if (stream4) {
|
|
90860
|
+
this._streams.delete(stream4);
|
|
90861
|
+
stream4 = undefined;
|
|
90862
|
+
}
|
|
90863
|
+
});
|
|
90864
|
+
return stream4;
|
|
90865
|
+
}
|
|
90866
|
+
};
|
|
89216
90867
|
});
|
|
89217
90868
|
|
|
89218
|
-
// src/infrastructure/services/workspace/
|
|
89219
|
-
|
|
89220
|
-
|
|
89221
|
-
|
|
89222
|
-
const walk = await walkWorkspaceFiles(rootDir, { maxFilePaths: maxEntries });
|
|
89223
|
-
const filteredPaths = walk.filePaths.filter((p) => !isExcluded(p));
|
|
89224
|
-
const entries2 = buildEntries(filteredPaths, maxEntries);
|
|
89225
|
-
return {
|
|
89226
|
-
entries: entries2,
|
|
89227
|
-
scannedAt,
|
|
89228
|
-
rootDir
|
|
89229
|
-
};
|
|
89230
|
-
}
|
|
89231
|
-
function isExcluded(filePath) {
|
|
89232
|
-
return hasExcludedDirSegment(filePath);
|
|
90869
|
+
// src/infrastructure/services/workspace/workspace-fs-watcher.ts
|
|
90870
|
+
import path5 from "node:path";
|
|
90871
|
+
function toRelativePath(rootDir, absolutePath) {
|
|
90872
|
+
return path5.relative(rootDir, absolutePath).replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
89233
90873
|
}
|
|
89234
|
-
function
|
|
89235
|
-
const
|
|
89236
|
-
|
|
89237
|
-
|
|
89238
|
-
|
|
89239
|
-
|
|
90874
|
+
function createWorkspaceFsWatcher(options) {
|
|
90875
|
+
const absWorkingDir = path5.resolve(options.workingDir);
|
|
90876
|
+
const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
90877
|
+
let stopped = false;
|
|
90878
|
+
let debounceTimer = null;
|
|
90879
|
+
const pendingEvents = new Map;
|
|
90880
|
+
const scheduleFlush = () => {
|
|
90881
|
+
if (debounceTimer)
|
|
90882
|
+
clearTimeout(debounceTimer);
|
|
90883
|
+
debounceTimer = setTimeout(() => {
|
|
90884
|
+
debounceTimer = null;
|
|
90885
|
+
if (pendingEvents.size === 0 || stopped)
|
|
90886
|
+
return;
|
|
90887
|
+
const events = [...pendingEvents.values()].sort((a, b) => a.path.localeCompare(b.path));
|
|
90888
|
+
pendingEvents.clear();
|
|
90889
|
+
Promise.resolve(options.onEvents(events)).catch((error) => {
|
|
90890
|
+
options.onError?.(error);
|
|
90891
|
+
});
|
|
90892
|
+
}, debounceMs);
|
|
90893
|
+
debounceTimer.unref?.();
|
|
90894
|
+
};
|
|
90895
|
+
const enqueue = (kind, absolutePath) => {
|
|
90896
|
+
if (stopped)
|
|
90897
|
+
return;
|
|
90898
|
+
const relativePath = toRelativePath(absWorkingDir, absolutePath);
|
|
90899
|
+
if (!relativePath || !isPathVisible(relativePath) || hasExcludedDirSegment(relativePath))
|
|
90900
|
+
return;
|
|
90901
|
+
if (options.shouldIgnore?.(relativePath))
|
|
90902
|
+
return;
|
|
90903
|
+
pendingEvents.set(relativePath, { kind, path: relativePath });
|
|
90904
|
+
scheduleFlush();
|
|
90905
|
+
};
|
|
90906
|
+
const watcher = watch(absWorkingDir, {
|
|
90907
|
+
ignored: (watchPath) => {
|
|
90908
|
+
const relativePath = toRelativePath(absWorkingDir, watchPath);
|
|
90909
|
+
if (!relativePath)
|
|
90910
|
+
return false;
|
|
90911
|
+
return !isPathVisible(relativePath) || hasExcludedDirSegment(relativePath) || options.shouldIgnore?.(relativePath) === true;
|
|
90912
|
+
},
|
|
90913
|
+
ignoreInitial: true,
|
|
90914
|
+
persistent: true,
|
|
90915
|
+
awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 25 }
|
|
90916
|
+
});
|
|
90917
|
+
watcher.on("add", (filePath) => enqueue("add", filePath)).on("addDir", (filePath) => enqueue("addDir", filePath)).on("change", (filePath) => enqueue("change", filePath)).on("unlink", (filePath) => enqueue("unlink", filePath)).on("unlinkDir", (filePath) => enqueue("unlinkDir", filePath)).on("error", (error) => options.onError?.(error));
|
|
90918
|
+
const ready = new Promise((resolve7) => {
|
|
90919
|
+
watcher.once("ready", resolve7);
|
|
90920
|
+
});
|
|
90921
|
+
return {
|
|
90922
|
+
ready,
|
|
90923
|
+
stop: async () => {
|
|
90924
|
+
stopped = true;
|
|
90925
|
+
if (debounceTimer) {
|
|
90926
|
+
clearTimeout(debounceTimer);
|
|
90927
|
+
debounceTimer = null;
|
|
90928
|
+
}
|
|
90929
|
+
pendingEvents.clear();
|
|
90930
|
+
await watcher.close();
|
|
89240
90931
|
}
|
|
89241
|
-
}
|
|
89242
|
-
const entries2 = [];
|
|
89243
|
-
const sortedDirs = Array.from(directories).sort();
|
|
89244
|
-
for (const dir of sortedDirs) {
|
|
89245
|
-
if (entries2.length >= maxEntries)
|
|
89246
|
-
break;
|
|
89247
|
-
entries2.push({ path: dir, type: "directory" });
|
|
89248
|
-
}
|
|
89249
|
-
const sortedFiles = filePaths.slice().sort();
|
|
89250
|
-
for (const file of sortedFiles) {
|
|
89251
|
-
if (entries2.length >= maxEntries)
|
|
89252
|
-
break;
|
|
89253
|
-
entries2.push({ path: file, type: "file" });
|
|
89254
|
-
}
|
|
89255
|
-
return entries2;
|
|
90932
|
+
};
|
|
89256
90933
|
}
|
|
89257
|
-
var
|
|
89258
|
-
var
|
|
89259
|
-
|
|
90934
|
+
var DEFAULT_DEBOUNCE_MS = 250;
|
|
90935
|
+
var init_workspace_fs_watcher = __esm(() => {
|
|
90936
|
+
init_chokidar();
|
|
89260
90937
|
init_workspace_visibility_policy();
|
|
89261
90938
|
});
|
|
89262
90939
|
|
|
89263
|
-
// src/infrastructure/services/workspace/file-tree-v3-upload.ts
|
|
89264
|
-
async function uploadFileTreeV3(session2, workingDir, tree, syncGeneration) {
|
|
89265
|
-
const shards = partitionFileTree(tree);
|
|
89266
|
-
const shardIds = [];
|
|
89267
|
-
for (let i2 = 0;i2 < shards.length; i2 += MAX_SHARD_BATCH_SIZE) {
|
|
89268
|
-
const batch = shards.slice(i2, i2 + MAX_SHARD_BATCH_SIZE);
|
|
89269
|
-
await session2.backend.mutation(api.workspaceFiles.syncFileTreeShardV3Batch, {
|
|
89270
|
-
sessionId: session2.sessionId,
|
|
89271
|
-
machineId: session2.machineId,
|
|
89272
|
-
workingDir,
|
|
89273
|
-
syncGeneration,
|
|
89274
|
-
items: batch.map((s) => ({
|
|
89275
|
-
shardId: s.shardId,
|
|
89276
|
-
data: s.data,
|
|
89277
|
-
dataHash: s.dataHash,
|
|
89278
|
-
scannedAt: tree.scannedAt,
|
|
89279
|
-
entryCount: s.entryCount
|
|
89280
|
-
}))
|
|
89281
|
-
});
|
|
89282
|
-
for (const s of batch)
|
|
89283
|
-
shardIds.push(s.shardId);
|
|
89284
|
-
}
|
|
89285
|
-
await session2.backend.mutation(api.workspaceFiles.syncFileTreeManifestV3, {
|
|
89286
|
-
sessionId: session2.sessionId,
|
|
89287
|
-
machineId: session2.machineId,
|
|
89288
|
-
workingDir,
|
|
89289
|
-
syncGeneration,
|
|
89290
|
-
shardIds,
|
|
89291
|
-
totalEntryCount: tree.entries.length,
|
|
89292
|
-
complete: true,
|
|
89293
|
-
scannedAt: tree.scannedAt
|
|
89294
|
-
});
|
|
89295
|
-
return { shardIds, totalEntryCount: tree.entries.length };
|
|
89296
|
-
}
|
|
89297
|
-
var init_file_tree_v3_upload = __esm(() => {
|
|
89298
|
-
init_file_tree_partition();
|
|
89299
|
-
init_api3();
|
|
89300
|
-
});
|
|
89301
|
-
|
|
89302
90940
|
// src/infrastructure/services/workspace/workspace-sync-diff.ts
|
|
89303
90941
|
function diffPathIndexes(previous, next4) {
|
|
89304
90942
|
const added = [];
|
|
89305
90943
|
const removed = [];
|
|
89306
90944
|
const typeChanged = [];
|
|
89307
90945
|
const prev = previous ?? {};
|
|
89308
|
-
for (const [
|
|
89309
|
-
if (!(
|
|
89310
|
-
added.push(
|
|
89311
|
-
} else if (prev[
|
|
89312
|
-
typeChanged.push(
|
|
90946
|
+
for (const [path6, type] of Object.entries(next4)) {
|
|
90947
|
+
if (!(path6 in prev)) {
|
|
90948
|
+
added.push(path6);
|
|
90949
|
+
} else if (prev[path6] !== type) {
|
|
90950
|
+
typeChanged.push(path6);
|
|
89313
90951
|
}
|
|
89314
90952
|
}
|
|
89315
|
-
for (const
|
|
89316
|
-
if (!(
|
|
89317
|
-
removed.push(
|
|
90953
|
+
for (const path6 of Object.keys(prev)) {
|
|
90954
|
+
if (!(path6 in next4)) {
|
|
90955
|
+
removed.push(path6);
|
|
89318
90956
|
}
|
|
89319
90957
|
}
|
|
89320
90958
|
added.sort();
|
|
@@ -89322,57 +90960,12 @@ function diffPathIndexes(previous, next4) {
|
|
|
89322
90960
|
typeChanged.sort();
|
|
89323
90961
|
return { added, removed, typeChanged };
|
|
89324
90962
|
}
|
|
89325
|
-
function formatPathDiffSummary(diff8) {
|
|
89326
|
-
return `+${diff8.added.length} added, -${diff8.removed.length} removed${diff8.typeChanged.length > 0 ? `, ~${diff8.typeChanged.length} type-changed` : ""}`;
|
|
89327
|
-
}
|
|
89328
|
-
|
|
89329
|
-
// src/infrastructure/services/workspace/workspace-sync-queue.ts
|
|
89330
|
-
function queueKey(machineId, workingDir) {
|
|
89331
|
-
return `${machineId}\x00${workingDir}`;
|
|
89332
|
-
}
|
|
89333
|
-
function getOrCreateState(key) {
|
|
89334
|
-
let state = queues.get(key);
|
|
89335
|
-
if (!state) {
|
|
89336
|
-
state = { running: false, trailing: false, drainPromise: null };
|
|
89337
|
-
queues.set(key, state);
|
|
89338
|
-
}
|
|
89339
|
-
return state;
|
|
89340
|
-
}
|
|
89341
|
-
async function enqueueFileTreeSync(machineId, workingDir, task) {
|
|
89342
|
-
const key = queueKey(machineId, workingDir);
|
|
89343
|
-
const state = getOrCreateState(key);
|
|
89344
|
-
if (state.running) {
|
|
89345
|
-
state.trailing = true;
|
|
89346
|
-
return state.drainPromise ?? Promise.resolve();
|
|
89347
|
-
}
|
|
89348
|
-
const run3 = async () => {
|
|
89349
|
-
state.running = true;
|
|
89350
|
-
try {
|
|
89351
|
-
do {
|
|
89352
|
-
state.trailing = false;
|
|
89353
|
-
await task();
|
|
89354
|
-
} while (state.trailing);
|
|
89355
|
-
} finally {
|
|
89356
|
-
state.running = false;
|
|
89357
|
-
state.trailing = false;
|
|
89358
|
-
if (!state.trailing) {
|
|
89359
|
-
queues.delete(key);
|
|
89360
|
-
}
|
|
89361
|
-
}
|
|
89362
|
-
};
|
|
89363
|
-
state.drainPromise = run3();
|
|
89364
|
-
return state.drainPromise;
|
|
89365
|
-
}
|
|
89366
|
-
var queues;
|
|
89367
|
-
var init_workspace_sync_queue = __esm(() => {
|
|
89368
|
-
queues = new Map;
|
|
89369
|
-
});
|
|
89370
90963
|
|
|
89371
90964
|
// src/infrastructure/services/workspace/workspace-sync-state.ts
|
|
89372
90965
|
import { createHash as createHash6, randomUUID as randomUUID6 } from "node:crypto";
|
|
89373
90966
|
import * as fs11 from "node:fs/promises";
|
|
89374
90967
|
import { homedir as homedir7 } from "node:os";
|
|
89375
|
-
import { join as
|
|
90968
|
+
import { join as join20 } from "node:path";
|
|
89376
90969
|
function workspaceKeyFor(workingDir) {
|
|
89377
90970
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
89378
90971
|
return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
@@ -89386,15 +90979,32 @@ function buildPathIndex(entries2) {
|
|
|
89386
90979
|
}
|
|
89387
90980
|
function manifestPath(machineId, workingDir) {
|
|
89388
90981
|
const key = workspaceKeyFor(workingDir);
|
|
89389
|
-
return
|
|
90982
|
+
return join20(SYNC_STATE_DIR, machineId, key, "manifest.json");
|
|
89390
90983
|
}
|
|
89391
90984
|
async function ensureDir(filePath) {
|
|
89392
|
-
await fs11.mkdir(
|
|
90985
|
+
await fs11.mkdir(join20(filePath, ".."), { recursive: true, mode: 448 });
|
|
89393
90986
|
}
|
|
89394
90987
|
async function loadWorkspaceSyncManifest(machineId, workingDir) {
|
|
89395
90988
|
try {
|
|
89396
90989
|
const content = await fs11.readFile(manifestPath(machineId, workingDir), "utf-8");
|
|
89397
|
-
|
|
90990
|
+
const parsed = JSON.parse(content);
|
|
90991
|
+
if (!parsed || typeof parsed !== "object" || !parsed.paths)
|
|
90992
|
+
return null;
|
|
90993
|
+
if (parsed.version === "1") {
|
|
90994
|
+
return {
|
|
90995
|
+
...parsed,
|
|
90996
|
+
version: SYNC_STATE_VERSION,
|
|
90997
|
+
scanner: "filesystem",
|
|
90998
|
+
localRevision: 0,
|
|
90999
|
+
backendRevision: 0,
|
|
91000
|
+
checkpointRevision: 0,
|
|
91001
|
+
lastReconciledAt: parsed.completedAt,
|
|
91002
|
+
pendingDeltas: []
|
|
91003
|
+
};
|
|
91004
|
+
}
|
|
91005
|
+
if (parsed.version !== SYNC_STATE_VERSION)
|
|
91006
|
+
return null;
|
|
91007
|
+
return parsed;
|
|
89398
91008
|
} catch (error) {
|
|
89399
91009
|
if (error.code === "ENOENT")
|
|
89400
91010
|
return null;
|
|
@@ -89419,15 +91029,275 @@ function createManifestFromTree(args2) {
|
|
|
89419
91029
|
scanner: args2.scanner,
|
|
89420
91030
|
dataHash: args2.dataHash,
|
|
89421
91031
|
totalEntryCount: args2.tree.entries.length,
|
|
89422
|
-
paths: buildPathIndex(args2.tree.entries)
|
|
91032
|
+
paths: buildPathIndex(args2.tree.entries),
|
|
91033
|
+
localRevision: 0,
|
|
91034
|
+
backendRevision: 0,
|
|
91035
|
+
checkpointRevision: 0,
|
|
91036
|
+
lastReconciledAt: args2.tree.scannedAt,
|
|
91037
|
+
pendingDeltas: []
|
|
89423
91038
|
};
|
|
89424
91039
|
}
|
|
89425
|
-
|
|
91040
|
+
function entriesFromPathIndex(paths) {
|
|
91041
|
+
return Object.entries(paths).map(([path6, type]) => ({ path: path6, type })).sort((a, b) => a.path.localeCompare(b.path));
|
|
91042
|
+
}
|
|
91043
|
+
var SYNC_STATE_VERSION = "2", SYNC_STATE_DIR;
|
|
89426
91044
|
var init_workspace_sync_state = __esm(() => {
|
|
89427
|
-
SYNC_STATE_DIR =
|
|
91045
|
+
SYNC_STATE_DIR = join20(homedir7(), ".chatroom", "sync-state");
|
|
91046
|
+
});
|
|
91047
|
+
|
|
91048
|
+
// src/infrastructure/services/workspace/workspace-file-tree-coordinator.ts
|
|
91049
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
91050
|
+
import path6 from "node:path";
|
|
91051
|
+
function deltaEntry(paths, pathValue) {
|
|
91052
|
+
const type = paths[pathValue];
|
|
91053
|
+
if (type === undefined)
|
|
91054
|
+
throw new Error(`Missing path type for delta: ${pathValue}`);
|
|
91055
|
+
return { path: pathValue, type };
|
|
91056
|
+
}
|
|
91057
|
+
function buildPendingDeltas(previous, next4) {
|
|
91058
|
+
const diff8 = diffPathIndexes(previous, next4);
|
|
91059
|
+
if (diff8.added.length === 0 && diff8.removed.length === 0 && diff8.typeChanged.length === 0) {
|
|
91060
|
+
return [];
|
|
91061
|
+
}
|
|
91062
|
+
const operations = [
|
|
91063
|
+
...diff8.added.map((entryPath) => ({
|
|
91064
|
+
kind: "added",
|
|
91065
|
+
entry: deltaEntry(next4, entryPath)
|
|
91066
|
+
})),
|
|
91067
|
+
...diff8.removed.map((entryPath) => ({ kind: "removed", path: entryPath })),
|
|
91068
|
+
...diff8.typeChanged.map((entryPath) => ({
|
|
91069
|
+
kind: "typeChanged",
|
|
91070
|
+
entry: deltaEntry(next4, entryPath)
|
|
91071
|
+
}))
|
|
91072
|
+
];
|
|
91073
|
+
const result = [];
|
|
91074
|
+
for (let offset = 0;offset < operations.length; offset += MAX_DELTA_OPERATIONS) {
|
|
91075
|
+
const delta = {
|
|
91076
|
+
operationId: randomUUID7(),
|
|
91077
|
+
added: [],
|
|
91078
|
+
removed: [],
|
|
91079
|
+
typeChanged: [],
|
|
91080
|
+
createdAt: Date.now()
|
|
91081
|
+
};
|
|
91082
|
+
for (const operation of operations.slice(offset, offset + MAX_DELTA_OPERATIONS)) {
|
|
91083
|
+
if (operation.kind === "added")
|
|
91084
|
+
delta.added.push(operation.entry);
|
|
91085
|
+
else if (operation.kind === "removed")
|
|
91086
|
+
delta.removed.push(operation.path);
|
|
91087
|
+
else
|
|
91088
|
+
delta.typeChanged.push(operation.entry);
|
|
91089
|
+
}
|
|
91090
|
+
result.push(delta);
|
|
91091
|
+
}
|
|
91092
|
+
return result;
|
|
91093
|
+
}
|
|
91094
|
+
function isIgnoreFile(relativePath) {
|
|
91095
|
+
return relativePath === ".gitignore" || relativePath === ".cursorignore" || relativePath.endsWith("/.gitignore");
|
|
91096
|
+
}
|
|
91097
|
+
function removePathAndDescendants(paths, relativePath) {
|
|
91098
|
+
delete paths[relativePath];
|
|
91099
|
+
const prefix = `${relativePath}/`;
|
|
91100
|
+
for (const candidate of Object.keys(paths)) {
|
|
91101
|
+
if (candidate.startsWith(prefix))
|
|
91102
|
+
delete paths[candidate];
|
|
91103
|
+
}
|
|
91104
|
+
}
|
|
91105
|
+
function ensureParentDirectories(paths, relativePath) {
|
|
91106
|
+
const parts2 = relativePath.split("/");
|
|
91107
|
+
for (let index = 1;index < parts2.length; index++) {
|
|
91108
|
+
paths[parts2.slice(0, index).join("/")] = "directory";
|
|
91109
|
+
}
|
|
91110
|
+
}
|
|
91111
|
+
async function addDirectorySubtree(rootDir, relativeDir, paths) {
|
|
91112
|
+
if (await isWorkspacePathIgnored(rootDir, relativeDir))
|
|
91113
|
+
return;
|
|
91114
|
+
ensureParentDirectories(paths, relativeDir);
|
|
91115
|
+
paths[relativeDir] = "directory";
|
|
91116
|
+
const subtree = await scanFileTree(path6.join(rootDir, relativeDir));
|
|
91117
|
+
for (const entry of subtree.entries) {
|
|
91118
|
+
const prefixedPath = `${relativeDir}/${entry.path}`;
|
|
91119
|
+
if (await isWorkspacePathIgnored(rootDir, prefixedPath))
|
|
91120
|
+
continue;
|
|
91121
|
+
paths[prefixedPath] = entry.type;
|
|
91122
|
+
}
|
|
91123
|
+
}
|
|
91124
|
+
async function applyFsEvents(rootDir, previous, events) {
|
|
91125
|
+
if (events.some((event) => isIgnoreFile(event.path)))
|
|
91126
|
+
return null;
|
|
91127
|
+
const next4 = { ...previous };
|
|
91128
|
+
for (const event of events) {
|
|
91129
|
+
if (event.kind === "unlink" || event.kind === "unlinkDir") {
|
|
91130
|
+
removePathAndDescendants(next4, event.path);
|
|
91131
|
+
continue;
|
|
91132
|
+
}
|
|
91133
|
+
if (event.kind === "change" && next4[event.path] !== undefined)
|
|
91134
|
+
continue;
|
|
91135
|
+
if (await isWorkspacePathIgnored(rootDir, event.path)) {
|
|
91136
|
+
removePathAndDescendants(next4, event.path);
|
|
91137
|
+
continue;
|
|
91138
|
+
}
|
|
91139
|
+
if (event.kind === "addDir") {
|
|
91140
|
+
await addDirectorySubtree(rootDir, event.path, next4);
|
|
91141
|
+
} else {
|
|
91142
|
+
ensureParentDirectories(next4, event.path);
|
|
91143
|
+
next4[event.path] = "file";
|
|
91144
|
+
}
|
|
91145
|
+
}
|
|
91146
|
+
return next4;
|
|
91147
|
+
}
|
|
91148
|
+
function treeFromManifest(manifest) {
|
|
91149
|
+
return {
|
|
91150
|
+
entries: entriesFromPathIndex(manifest.paths),
|
|
91151
|
+
rootDir: manifest.workingDir,
|
|
91152
|
+
scannedAt: manifest.completedAt
|
|
91153
|
+
};
|
|
91154
|
+
}
|
|
91155
|
+
function nextReconcileDelay(baseMs) {
|
|
91156
|
+
const jitter = baseMs * RECONCILE_JITTER_RATIO;
|
|
91157
|
+
return Math.max(1000, Math.round(baseMs - jitter + Math.random() * jitter * 2));
|
|
91158
|
+
}
|
|
91159
|
+
async function startWorkspaceFileTreeCoordinator(options) {
|
|
91160
|
+
const workingDir = normalizeWorkingDirForLookup(options.workingDir);
|
|
91161
|
+
let stopped = false;
|
|
91162
|
+
let serial = Promise.resolve();
|
|
91163
|
+
let reconcileTimer = null;
|
|
91164
|
+
const loadedManifest = await loadWorkspaceSyncManifest(options.machineId, workingDir);
|
|
91165
|
+
const isColdStart = loadedManifest === null;
|
|
91166
|
+
let manifest;
|
|
91167
|
+
if (loadedManifest) {
|
|
91168
|
+
manifest = loadedManifest;
|
|
91169
|
+
} else {
|
|
91170
|
+
const tree = await scanFileTree(workingDir);
|
|
91171
|
+
manifest = createManifestFromTree({
|
|
91172
|
+
machineId: options.machineId,
|
|
91173
|
+
workingDir,
|
|
91174
|
+
scanner: "filesystem",
|
|
91175
|
+
dataHash: computeFileTreeDataHash(tree),
|
|
91176
|
+
tree
|
|
91177
|
+
});
|
|
91178
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91179
|
+
}
|
|
91180
|
+
const publishCheckpoint = async () => {
|
|
91181
|
+
const result = await options.onCheckpoint(treeFromManifest(manifest), manifest.backendRevision);
|
|
91182
|
+
manifest.backendRevision = result.revision;
|
|
91183
|
+
manifest.checkpointRevision = result.revision;
|
|
91184
|
+
manifest.pendingDeltas = [];
|
|
91185
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91186
|
+
};
|
|
91187
|
+
if (isColdStart)
|
|
91188
|
+
await publishCheckpoint();
|
|
91189
|
+
const flushPending = async () => {
|
|
91190
|
+
while (!stopped && manifest.pendingDeltas.length > 0) {
|
|
91191
|
+
const delta = manifest.pendingDeltas[0];
|
|
91192
|
+
if (!delta)
|
|
91193
|
+
break;
|
|
91194
|
+
const result = await options.onDelta(delta, manifest.backendRevision);
|
|
91195
|
+
if (result.status === "conflict") {
|
|
91196
|
+
manifest.backendRevision = result.revision;
|
|
91197
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91198
|
+
continue;
|
|
91199
|
+
}
|
|
91200
|
+
manifest.backendRevision = result.revision;
|
|
91201
|
+
manifest.pendingDeltas.shift();
|
|
91202
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91203
|
+
const checkpointEvery = options.checkpointEveryRevisions ?? DEFAULT_CHECKPOINT_EVERY_REVISIONS;
|
|
91204
|
+
if (manifest.pendingDeltas.length === 0 && manifest.backendRevision - manifest.checkpointRevision >= checkpointEvery) {
|
|
91205
|
+
await publishCheckpoint();
|
|
91206
|
+
}
|
|
91207
|
+
}
|
|
91208
|
+
};
|
|
91209
|
+
const commitPaths = async (nextPaths, reconciledAt) => {
|
|
91210
|
+
const deltas = buildPendingDeltas(manifest.paths, nextPaths);
|
|
91211
|
+
if (reconciledAt !== undefined)
|
|
91212
|
+
manifest.lastReconciledAt = reconciledAt;
|
|
91213
|
+
if (deltas.length === 0) {
|
|
91214
|
+
if (reconciledAt !== undefined)
|
|
91215
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91216
|
+
await flushPending();
|
|
91217
|
+
return 0;
|
|
91218
|
+
}
|
|
91219
|
+
manifest.paths = nextPaths;
|
|
91220
|
+
manifest.totalEntryCount = Object.keys(nextPaths).length;
|
|
91221
|
+
manifest.completedAt = Date.now();
|
|
91222
|
+
manifest.localRevision += 1;
|
|
91223
|
+
manifest.pendingDeltas.push(...deltas);
|
|
91224
|
+
manifest.dataHash = computeFileTreeDataHash(treeFromManifest(manifest));
|
|
91225
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91226
|
+
await flushPending();
|
|
91227
|
+
return deltas.reduce((total, delta) => total + delta.added.length + delta.removed.length + delta.typeChanged.length, 0);
|
|
91228
|
+
};
|
|
91229
|
+
const reconcileNow = async () => {
|
|
91230
|
+
const tree = await scanFileTree(workingDir);
|
|
91231
|
+
const corrected = await commitPaths(buildPathIndex(tree.entries), tree.scannedAt);
|
|
91232
|
+
options.onReconciled?.(corrected);
|
|
91233
|
+
};
|
|
91234
|
+
const enqueueSerial = (task) => {
|
|
91235
|
+
serial = serial.then(task, task).catch((error) => {
|
|
91236
|
+
options.onError?.(error);
|
|
91237
|
+
});
|
|
91238
|
+
return serial;
|
|
91239
|
+
};
|
|
91240
|
+
const scheduleReconcile = (delay3) => {
|
|
91241
|
+
if (stopped)
|
|
91242
|
+
return;
|
|
91243
|
+
if (reconcileTimer)
|
|
91244
|
+
clearTimeout(reconcileTimer);
|
|
91245
|
+
const interval = options.reconcileIntervalMs ?? DEFAULT_RECONCILE_INTERVAL_MS;
|
|
91246
|
+
reconcileTimer = setTimeout(() => {
|
|
91247
|
+
reconcileTimer = null;
|
|
91248
|
+
enqueueSerial(reconcileNow).finally(() => scheduleReconcile());
|
|
91249
|
+
}, delay3 ?? nextReconcileDelay(interval));
|
|
91250
|
+
reconcileTimer.unref?.();
|
|
91251
|
+
};
|
|
91252
|
+
await flushPending();
|
|
91253
|
+
const watcher = createWorkspaceFsWatcher({
|
|
91254
|
+
workingDir,
|
|
91255
|
+
onEvents: async (events) => {
|
|
91256
|
+
await enqueueSerial(async () => {
|
|
91257
|
+
const nextPaths = await applyFsEvents(workingDir, manifest.paths, events);
|
|
91258
|
+
if (nextPaths === null) {
|
|
91259
|
+
await reconcileNow();
|
|
91260
|
+
return;
|
|
91261
|
+
}
|
|
91262
|
+
await commitPaths(nextPaths);
|
|
91263
|
+
});
|
|
91264
|
+
},
|
|
91265
|
+
onError: (error) => {
|
|
91266
|
+
options.onError?.(error);
|
|
91267
|
+
scheduleReconcile(1000);
|
|
91268
|
+
}
|
|
91269
|
+
});
|
|
91270
|
+
await watcher.ready;
|
|
91271
|
+
scheduleReconcile();
|
|
91272
|
+
return {
|
|
91273
|
+
workingDir,
|
|
91274
|
+
getManifest: () => manifest,
|
|
91275
|
+
getTree: () => treeFromManifest(manifest),
|
|
91276
|
+
checkpoint: () => enqueueSerial(publishCheckpoint),
|
|
91277
|
+
reconcile: () => enqueueSerial(reconcileNow),
|
|
91278
|
+
stop: async () => {
|
|
91279
|
+
stopped = true;
|
|
91280
|
+
if (reconcileTimer)
|
|
91281
|
+
clearTimeout(reconcileTimer);
|
|
91282
|
+
reconcileTimer = null;
|
|
91283
|
+
await watcher.stop();
|
|
91284
|
+
await serial;
|
|
91285
|
+
await saveWorkspaceSyncManifest(manifest);
|
|
91286
|
+
}
|
|
91287
|
+
};
|
|
91288
|
+
}
|
|
91289
|
+
var DEFAULT_RECONCILE_INTERVAL_MS, DEFAULT_CHECKPOINT_EVERY_REVISIONS = 100, RECONCILE_JITTER_RATIO = 0.2, MAX_DELTA_OPERATIONS = 100;
|
|
91290
|
+
var init_workspace_file_tree_coordinator = __esm(() => {
|
|
91291
|
+
init_file_tree_data_hash();
|
|
91292
|
+
init_file_tree_scanner();
|
|
91293
|
+
init_workspace_fs_watcher();
|
|
91294
|
+
init_workspace_ignore();
|
|
91295
|
+
init_workspace_sync_state();
|
|
91296
|
+
DEFAULT_RECONCILE_INTERVAL_MS = 10 * 60 * 1000;
|
|
89428
91297
|
});
|
|
89429
91298
|
|
|
89430
91299
|
// src/commands/machine/daemon-start/file-tree-subscription.ts
|
|
91300
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
89431
91301
|
import { gzipSync as gzipSync4 } from "node:zlib";
|
|
89432
91302
|
function logSubscriptionWarn(label, err) {
|
|
89433
91303
|
console.warn(`[${formatTimestamp()}] ⚠️ ${label}: ${getErrorMessage2(err)}`);
|
|
@@ -89435,7 +91305,7 @@ function logSubscriptionWarn(label, err) {
|
|
|
89435
91305
|
async function syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration) {
|
|
89436
91306
|
if (shouldUseV3Upload(tree)) {
|
|
89437
91307
|
await uploadFileTreeV3(session2, normalizedWorkingDir, tree, syncGeneration);
|
|
89438
|
-
return;
|
|
91308
|
+
return { snapshotKind: "v3", snapshotId: syncGeneration };
|
|
89439
91309
|
}
|
|
89440
91310
|
const treeJson = JSON.stringify(tree);
|
|
89441
91311
|
const compressed = gzipSync4(Buffer.from(treeJson)).toString("base64");
|
|
@@ -89447,60 +91317,122 @@ async function syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHas
|
|
|
89447
91317
|
dataHash,
|
|
89448
91318
|
scannedAt: tree.scannedAt
|
|
89449
91319
|
});
|
|
91320
|
+
return { snapshotKind: "v2", snapshotId: dataHash };
|
|
89450
91321
|
}
|
|
89451
|
-
|
|
89452
|
-
|
|
89453
|
-
|
|
89454
|
-
|
|
91322
|
+
function toDeltaOperations(delta) {
|
|
91323
|
+
return [
|
|
91324
|
+
...delta.added.map((entry) => ({
|
|
91325
|
+
operation: "add",
|
|
91326
|
+
path: entry.path,
|
|
91327
|
+
entryType: entry.type
|
|
91328
|
+
})),
|
|
91329
|
+
...delta.removed.map((entryPath) => ({
|
|
91330
|
+
operation: "remove",
|
|
91331
|
+
path: entryPath
|
|
91332
|
+
})),
|
|
91333
|
+
...delta.typeChanged.map((entry) => ({
|
|
91334
|
+
operation: "type-change",
|
|
91335
|
+
path: entry.path,
|
|
91336
|
+
entryType: entry.type
|
|
91337
|
+
}))
|
|
91338
|
+
];
|
|
91339
|
+
}
|
|
91340
|
+
async function publishCheckpoint(session2, normalizedWorkingDir, tree, revision) {
|
|
89455
91341
|
const dataHash = computeFileTreeDataHash(tree);
|
|
89456
|
-
|
|
89457
|
-
|
|
91342
|
+
const syncGeneration = randomUUID8();
|
|
91343
|
+
const snapshot = await syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration);
|
|
91344
|
+
let checkpointRevision = revision;
|
|
91345
|
+
let result = await session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
|
|
91346
|
+
sessionId: session2.sessionId,
|
|
91347
|
+
machineId: session2.machineId,
|
|
91348
|
+
workingDir: normalizedWorkingDir,
|
|
91349
|
+
revision: checkpointRevision,
|
|
91350
|
+
...snapshot
|
|
91351
|
+
});
|
|
91352
|
+
if (result.status === "resync-required") {
|
|
91353
|
+
checkpointRevision = result.expectedRevision + 1;
|
|
91354
|
+
result = await session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
|
|
89458
91355
|
sessionId: session2.sessionId,
|
|
89459
91356
|
machineId: session2.machineId,
|
|
89460
|
-
workingDir: normalizedWorkingDir
|
|
91357
|
+
workingDir: normalizedWorkingDir,
|
|
91358
|
+
revision: checkpointRevision,
|
|
91359
|
+
...snapshot
|
|
89461
91360
|
});
|
|
89462
|
-
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree unchanged, skipped upload: ${normalizedWorkingDir}`);
|
|
89463
|
-
return;
|
|
89464
91361
|
}
|
|
89465
|
-
|
|
89466
|
-
|
|
89467
|
-
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree diff: ${formatPathDiffSummary(pathDiff)} (${normalizedWorkingDir})`);
|
|
91362
|
+
if (result.status === "snapshot-missing") {
|
|
91363
|
+
throw new Error(`File tree checkpoint rejected: ${result.status}`);
|
|
89468
91364
|
}
|
|
89469
|
-
|
|
89470
|
-
|
|
89471
|
-
machineId: session2.machineId,
|
|
89472
|
-
workingDir: normalizedWorkingDir,
|
|
89473
|
-
scanner,
|
|
89474
|
-
dataHash,
|
|
89475
|
-
tree
|
|
89476
|
-
});
|
|
89477
|
-
await syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, manifest.syncGeneration);
|
|
89478
|
-
await session2.backend.mutation(api.workspaceFiles.fulfillFileTreeRequest, {
|
|
89479
|
-
sessionId: session2.sessionId,
|
|
89480
|
-
machineId: session2.machineId,
|
|
89481
|
-
workingDir: normalizedWorkingDir
|
|
89482
|
-
});
|
|
89483
|
-
await saveWorkspaceSyncManifest(manifest);
|
|
91365
|
+
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree checkpoint: ${normalizedWorkingDir} (${tree.entries.length} entries, revision ${checkpointRevision})`);
|
|
91366
|
+
return { revision: checkpointRevision };
|
|
89484
91367
|
}
|
|
89485
91368
|
var startFileTreeSubscriptionEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
89486
91369
|
const session2 = yield* DaemonSessionService;
|
|
91370
|
+
const coordinators = new Map;
|
|
91371
|
+
const ensureCoordinator = (workingDir, forceReconcile) => {
|
|
91372
|
+
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
91373
|
+
let coordinatorPromise = coordinators.get(normalized);
|
|
91374
|
+
if (!coordinatorPromise) {
|
|
91375
|
+
coordinatorPromise = startWorkspaceFileTreeCoordinator({
|
|
91376
|
+
machineId: session2.machineId,
|
|
91377
|
+
workingDir: normalized,
|
|
91378
|
+
onDelta: async (delta, baseRevision) => {
|
|
91379
|
+
const operations = toDeltaOperations(delta);
|
|
91380
|
+
const result = await session2.backend.mutation(api.workspaceFiles.applyFileTreeDeltaBatch, {
|
|
91381
|
+
sessionId: session2.sessionId,
|
|
91382
|
+
machineId: session2.machineId,
|
|
91383
|
+
workingDir: normalized,
|
|
91384
|
+
operationId: delta.operationId,
|
|
91385
|
+
baseRevision,
|
|
91386
|
+
operations
|
|
91387
|
+
});
|
|
91388
|
+
if (result.status === "resync-required") {
|
|
91389
|
+
return { status: "conflict", revision: result.expectedRevision };
|
|
91390
|
+
}
|
|
91391
|
+
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree delta: ${normalized} (${operations.length} operations, ${Buffer.byteLength(JSON.stringify(operations))} bytes, revision ${result.revision})`);
|
|
91392
|
+
return result;
|
|
91393
|
+
},
|
|
91394
|
+
onCheckpoint: (tree, revision) => publishCheckpoint(session2, normalized, tree, revision),
|
|
91395
|
+
onError: (error) => logSubscriptionWarn(`File tree coordinator failed for ${normalized}`, error),
|
|
91396
|
+
onReconciled: (correctedPathCount) => {
|
|
91397
|
+
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree reconciled: ${normalized} (${correctedPathCount} corrected paths)`);
|
|
91398
|
+
}
|
|
91399
|
+
}).catch((error) => {
|
|
91400
|
+
coordinators.delete(normalized);
|
|
91401
|
+
throw error;
|
|
91402
|
+
});
|
|
91403
|
+
coordinators.set(normalized, coordinatorPromise);
|
|
91404
|
+
}
|
|
91405
|
+
return coordinatorPromise.then(async (coordinator) => {
|
|
91406
|
+
const checkpoint = await session2.backend.query(api.workspaceFiles.getFileTreeCheckpoint, {
|
|
91407
|
+
sessionId: session2.sessionId,
|
|
91408
|
+
machineId: session2.machineId,
|
|
91409
|
+
workingDir: normalized
|
|
91410
|
+
});
|
|
91411
|
+
if (checkpoint === null)
|
|
91412
|
+
await coordinator.checkpoint();
|
|
91413
|
+
if (forceReconcile)
|
|
91414
|
+
await coordinator.reconcile();
|
|
91415
|
+
return coordinator;
|
|
91416
|
+
});
|
|
91417
|
+
};
|
|
89487
91418
|
const unsubscribe = wsClient2.onUpdate(api.workspaceFiles.getPendingFileTreeRequests, { sessionId: session2.sessionId, machineId: session2.machineId }, (requests) => {
|
|
89488
91419
|
if (!requests?.length)
|
|
89489
91420
|
return;
|
|
89490
|
-
const
|
|
89491
|
-
|
|
89492
|
-
|
|
89493
|
-
|
|
89494
|
-
|
|
89495
|
-
|
|
89496
|
-
|
|
89497
|
-
|
|
89498
|
-
|
|
89499
|
-
|
|
89500
|
-
|
|
89501
|
-
|
|
91421
|
+
const requestsByDir = new Map;
|
|
91422
|
+
for (const request2 of requests) {
|
|
91423
|
+
const normalized = normalizeWorkingDirForLookup(request2.workingDir);
|
|
91424
|
+
requestsByDir.set(normalized, requestsByDir.get(normalized) === true || request2.force === true);
|
|
91425
|
+
}
|
|
91426
|
+
for (const [normalized, force] of requestsByDir) {
|
|
91427
|
+
const start3 = Date.now();
|
|
91428
|
+
ensureCoordinator(normalized, force).then(() => session2.backend.mutation(api.workspaceFiles.fulfillFileTreeRequest, {
|
|
91429
|
+
sessionId: session2.sessionId,
|
|
91430
|
+
machineId: session2.machineId,
|
|
91431
|
+
workingDir: normalized
|
|
91432
|
+
})).then(() => {
|
|
91433
|
+
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree ready: ${normalized} (${Date.now() - start3}ms${force ? ", reconciled" : ", cached"})`);
|
|
89502
91434
|
}).catch((err) => {
|
|
89503
|
-
logSubscriptionWarn(
|
|
91435
|
+
logSubscriptionWarn(`File tree failed for ${normalized}`, err);
|
|
89504
91436
|
});
|
|
89505
91437
|
}
|
|
89506
91438
|
}, (err) => {
|
|
@@ -89510,6 +91442,10 @@ var startFileTreeSubscriptionEffect = (wsClient2) => exports_Effect.gen(function
|
|
|
89510
91442
|
return {
|
|
89511
91443
|
stop: () => {
|
|
89512
91444
|
unsubscribe();
|
|
91445
|
+
Promise.all([...coordinators.values()].map((coordinator) => coordinator.then((handle) => handle.stop()).catch(() => {
|
|
91446
|
+
return;
|
|
91447
|
+
})));
|
|
91448
|
+
coordinators.clear();
|
|
89513
91449
|
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree subscription stopped`);
|
|
89514
91450
|
}
|
|
89515
91451
|
};
|
|
@@ -89518,13 +91454,10 @@ var init_file_tree_subscription = __esm(() => {
|
|
|
89518
91454
|
init_esm();
|
|
89519
91455
|
init_daemon_services();
|
|
89520
91456
|
init_api3();
|
|
89521
|
-
init_git_reader();
|
|
89522
91457
|
init_file_tree_data_hash();
|
|
89523
91458
|
init_file_tree_partition();
|
|
89524
|
-
init_file_tree_scanner();
|
|
89525
91459
|
init_file_tree_v3_upload();
|
|
89526
|
-
|
|
89527
|
-
init_workspace_sync_state();
|
|
91460
|
+
init_workspace_file_tree_coordinator();
|
|
89528
91461
|
init_convex_error();
|
|
89529
91462
|
});
|
|
89530
91463
|
|
|
@@ -89535,7 +91468,7 @@ function unsupportedFileWriteOperationMessage(operation) {
|
|
|
89535
91468
|
|
|
89536
91469
|
// src/commands/machine/daemon-start/file-write-fulfillment.ts
|
|
89537
91470
|
import { access as access4, mkdir as mkdir9, rename as rename5, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
|
|
89538
|
-
import { dirname as
|
|
91471
|
+
import { dirname as dirname11 } from "node:path";
|
|
89539
91472
|
function isTerminalFileWriteError(errorMessage) {
|
|
89540
91473
|
const terminalMessages = new Set([
|
|
89541
91474
|
"Invalid file path",
|
|
@@ -89587,7 +91520,7 @@ async function validateWriteOperation(operation, absolutePath) {
|
|
|
89587
91520
|
}
|
|
89588
91521
|
async function writePayloadToDisk(absolutePath, operation, content) {
|
|
89589
91522
|
if (operation === "create") {
|
|
89590
|
-
await mkdir9(
|
|
91523
|
+
await mkdir9(dirname11(absolutePath), { recursive: true });
|
|
89591
91524
|
}
|
|
89592
91525
|
await writeFile8(absolutePath, content);
|
|
89593
91526
|
}
|
|
@@ -89650,7 +91583,7 @@ async function fulfillOneFileWriteRequest(session2, request2) {
|
|
|
89650
91583
|
});
|
|
89651
91584
|
return;
|
|
89652
91585
|
}
|
|
89653
|
-
await mkdir9(
|
|
91586
|
+
await mkdir9(dirname11(targetResolved.absolutePath), { recursive: true });
|
|
89654
91587
|
await rename5(resolved.absolutePath, targetResolved.absolutePath);
|
|
89655
91588
|
await completeWriteRequest(session2, request2._id, { status: "done" });
|
|
89656
91589
|
const elapsed4 = Date.now() - startTime;
|
|
@@ -92997,11 +94930,11 @@ class AgentProcessManager {
|
|
|
92997
94930
|
const initPrompt = await this.fetchInitPromptResult(opts, slot);
|
|
92998
94931
|
if (!initPrompt.ok)
|
|
92999
94932
|
return initPrompt.result;
|
|
93000
|
-
const
|
|
93001
|
-
if (!
|
|
93002
|
-
return
|
|
93003
|
-
await this.finalizeRunningSlot(key, slot, opts,
|
|
93004
|
-
return { success: true, pid:
|
|
94933
|
+
const spawn6 = await this.spawnAgentForEnsureRunning(key, slot, opts, initPrompt, wantResume);
|
|
94934
|
+
if (!spawn6.ok)
|
|
94935
|
+
return spawn6.result;
|
|
94936
|
+
await this.finalizeRunningSlot(key, slot, opts, spawn6.spawnResult, wantResume);
|
|
94937
|
+
return { success: true, pid: spawn6.spawnResult.pid };
|
|
93005
94938
|
} catch (e) {
|
|
93006
94939
|
this.resetSlotIdle(slot);
|
|
93007
94940
|
return { success: false, error: `Unexpected error: ${e.message}` };
|
|
@@ -93248,7 +95181,7 @@ var init_daemon_startup_log = __esm(() => {
|
|
|
93248
95181
|
});
|
|
93249
95182
|
|
|
93250
95183
|
// src/commands/machine/daemon-start/init.ts
|
|
93251
|
-
import { stat as
|
|
95184
|
+
import { stat as stat5 } from "node:fs/promises";
|
|
93252
95185
|
async function discoverModelsForHarness(harness, service3) {
|
|
93253
95186
|
const installed2 = await service3.isInstalled();
|
|
93254
95187
|
if (!installed2) {
|
|
@@ -93283,7 +95216,7 @@ function createDefaultDeps17() {
|
|
|
93283
95216
|
kill: (pid, signal) => process.kill(pid, signal)
|
|
93284
95217
|
},
|
|
93285
95218
|
fs: {
|
|
93286
|
-
stat:
|
|
95219
|
+
stat: stat5
|
|
93287
95220
|
},
|
|
93288
95221
|
machine: {
|
|
93289
95222
|
clearAgentPid,
|
|
@@ -93294,7 +95227,7 @@ function createDefaultDeps17() {
|
|
|
93294
95227
|
},
|
|
93295
95228
|
clock: {
|
|
93296
95229
|
now: () => Date.now(),
|
|
93297
|
-
delay: (ms) => new Promise((
|
|
95230
|
+
delay: (ms) => new Promise((resolve7) => setTimeout(resolve7, ms))
|
|
93298
95231
|
},
|
|
93299
95232
|
spawning: new HarnessSpawningService({ rateLimiter: new SpawnRateLimiter }),
|
|
93300
95233
|
agentProcessManager: null
|
|
@@ -94655,18 +96588,18 @@ var init_jsonc = __esm(() => {
|
|
|
94655
96588
|
});
|
|
94656
96589
|
|
|
94657
96590
|
// src/infrastructure/services/workspace/workspace-resolver.ts
|
|
94658
|
-
import { readFile as readFile10, readdir, stat as
|
|
94659
|
-
import { join as
|
|
96591
|
+
import { readFile as readFile10, readdir as readdir3, stat as stat6 } from "node:fs/promises";
|
|
96592
|
+
import { join as join21, basename as basename4, resolve as resolve7 } from "node:path";
|
|
94660
96593
|
async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
94661
|
-
const parentDir =
|
|
96594
|
+
const parentDir = join21(rootDir, cleaned.slice(0, -2));
|
|
94662
96595
|
try {
|
|
94663
|
-
const entries2 = await
|
|
96596
|
+
const entries2 = await readdir3(parentDir, { withFileTypes: true });
|
|
94664
96597
|
const dirs = [];
|
|
94665
96598
|
for (const entry of entries2) {
|
|
94666
96599
|
if (!entry.isDirectory())
|
|
94667
96600
|
continue;
|
|
94668
|
-
const dirPath =
|
|
94669
|
-
if (
|
|
96601
|
+
const dirPath = join21(parentDir, entry.name);
|
|
96602
|
+
if (resolve7(dirPath).startsWith(resolve7(rootDir))) {
|
|
94670
96603
|
dirs.push(dirPath);
|
|
94671
96604
|
}
|
|
94672
96605
|
}
|
|
@@ -94676,11 +96609,11 @@ async function resolveGlobPatternStar(rootDir, cleaned) {
|
|
|
94676
96609
|
}
|
|
94677
96610
|
}
|
|
94678
96611
|
async function resolveLiteralPath(rootDir, cleaned) {
|
|
94679
|
-
const dir =
|
|
96612
|
+
const dir = join21(rootDir, cleaned);
|
|
94680
96613
|
try {
|
|
94681
|
-
if (!
|
|
96614
|
+
if (!resolve7(dir).startsWith(resolve7(rootDir)))
|
|
94682
96615
|
return [];
|
|
94683
|
-
const s = await
|
|
96616
|
+
const s = await stat6(dir);
|
|
94684
96617
|
if (s.isDirectory())
|
|
94685
96618
|
return [dir];
|
|
94686
96619
|
} catch {}
|
|
@@ -94696,10 +96629,10 @@ async function resolveGlobPattern(rootDir, pattern2) {
|
|
|
94696
96629
|
}
|
|
94697
96630
|
async function readPackageJson(dir) {
|
|
94698
96631
|
try {
|
|
94699
|
-
const content = await readFile10(
|
|
96632
|
+
const content = await readFile10(join21(dir, "package.json"), "utf-8");
|
|
94700
96633
|
const pkg = JSON.parse(content);
|
|
94701
96634
|
return {
|
|
94702
|
-
name: pkg.name ||
|
|
96635
|
+
name: pkg.name || basename4(dir),
|
|
94703
96636
|
scripts: pkg.scripts && typeof pkg.scripts === "object" ? pkg.scripts : {}
|
|
94704
96637
|
};
|
|
94705
96638
|
} catch {
|
|
@@ -94708,7 +96641,7 @@ async function readPackageJson(dir) {
|
|
|
94708
96641
|
}
|
|
94709
96642
|
async function readPnpmWorkspacePatterns(rootDir) {
|
|
94710
96643
|
try {
|
|
94711
|
-
const content = await readFile10(
|
|
96644
|
+
const content = await readFile10(join21(rootDir, "pnpm-workspace.yaml"), "utf-8");
|
|
94712
96645
|
const patterns = [];
|
|
94713
96646
|
let inPackages = false;
|
|
94714
96647
|
for (const line of content.split(`
|
|
@@ -94735,7 +96668,7 @@ async function readPnpmWorkspacePatterns(rootDir) {
|
|
|
94735
96668
|
}
|
|
94736
96669
|
async function readPackageJsonWorkspacePatterns(rootDir) {
|
|
94737
96670
|
try {
|
|
94738
|
-
const content = await readFile10(
|
|
96671
|
+
const content = await readFile10(join21(rootDir, "package.json"), "utf-8");
|
|
94739
96672
|
const pkg = JSON.parse(content);
|
|
94740
96673
|
if (!pkg.workspaces)
|
|
94741
96674
|
return [];
|
|
@@ -94784,11 +96717,11 @@ var init_workspace_resolver = () => {};
|
|
|
94784
96717
|
|
|
94785
96718
|
// src/infrastructure/services/workspace/command-discovery.ts
|
|
94786
96719
|
import { access as access5, readFile as readFile11 } from "node:fs/promises";
|
|
94787
|
-
import { join as
|
|
96720
|
+
import { join as join22, relative as relative4, basename as basename5 } from "node:path";
|
|
94788
96721
|
async function detectPackageManager(workingDir) {
|
|
94789
96722
|
for (const { file, manager } of LOCKFILE_MAP) {
|
|
94790
96723
|
try {
|
|
94791
|
-
await access5(
|
|
96724
|
+
await access5(join22(workingDir, file));
|
|
94792
96725
|
return manager;
|
|
94793
96726
|
} catch {}
|
|
94794
96727
|
}
|
|
@@ -94856,8 +96789,8 @@ function collectRootScriptCommands(scripts, pm, scriptPrefix, rootSw) {
|
|
|
94856
96789
|
return commands;
|
|
94857
96790
|
}
|
|
94858
96791
|
async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
94859
|
-
let rootPackageName =
|
|
94860
|
-
const pkg = await readJsonFile(
|
|
96792
|
+
let rootPackageName = basename5(workingDir);
|
|
96793
|
+
const pkg = await readJsonFile(join22(workingDir, "package.json"), "root package.json");
|
|
94861
96794
|
if (!pkg)
|
|
94862
96795
|
return { commands: [], rootPackageName };
|
|
94863
96796
|
if (pkg.name)
|
|
@@ -94873,7 +96806,7 @@ async function readRootPackageJson(workingDir, pm, scriptPrefix) {
|
|
|
94873
96806
|
}
|
|
94874
96807
|
async function readTurboJson(workingDir, _turboPrefix, _rootSubWorkspace) {
|
|
94875
96808
|
const turboTaskNames = [];
|
|
94876
|
-
const turbo = await readJsonFile(
|
|
96809
|
+
const turbo = await readJsonFile(join22(workingDir, "turbo.json"), "turbo.json");
|
|
94877
96810
|
if (!turbo?.tasks || typeof turbo.tasks !== "object")
|
|
94878
96811
|
return turboTaskNames;
|
|
94879
96812
|
for (const taskName of Object.keys(turbo.tasks)) {
|
|
@@ -94902,7 +96835,7 @@ async function discoverCommands(workingDir) {
|
|
|
94902
96835
|
}
|
|
94903
96836
|
const subWorkspaces = await resolveSubWorkspaces(workingDir, pm);
|
|
94904
96837
|
for (const pkg of subWorkspaces) {
|
|
94905
|
-
const wsPath =
|
|
96838
|
+
const wsPath = relative4(workingDir, pkg.dir) || ".";
|
|
94906
96839
|
const pkgSubWorkspace = { type: "npm", path: wsPath, name: pkg.name };
|
|
94907
96840
|
await addSubWorkspaceCommands(commands, pm, pkg, wsPath, pkgSubWorkspace, turboTaskNames);
|
|
94908
96841
|
}
|
|
@@ -95380,10 +97313,10 @@ function assignProp(target, prop, value) {
|
|
|
95380
97313
|
configurable: true
|
|
95381
97314
|
});
|
|
95382
97315
|
}
|
|
95383
|
-
function getElementAtPath(obj,
|
|
95384
|
-
if (!
|
|
97316
|
+
function getElementAtPath(obj, path7) {
|
|
97317
|
+
if (!path7)
|
|
95385
97318
|
return obj;
|
|
95386
|
-
return
|
|
97319
|
+
return path7.reduce((acc, key) => acc?.[key], obj);
|
|
95387
97320
|
}
|
|
95388
97321
|
function promiseAllObject(promisesObj) {
|
|
95389
97322
|
const keys5 = Object.keys(promisesObj);
|
|
@@ -95629,11 +97562,11 @@ function aborted(x, startIndex = 0) {
|
|
|
95629
97562
|
}
|
|
95630
97563
|
return false;
|
|
95631
97564
|
}
|
|
95632
|
-
function prefixIssues(
|
|
97565
|
+
function prefixIssues(path7, issues) {
|
|
95633
97566
|
return issues.map((iss) => {
|
|
95634
97567
|
var _a2;
|
|
95635
97568
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
95636
|
-
iss.path.unshift(
|
|
97569
|
+
iss.path.unshift(path7);
|
|
95637
97570
|
return iss;
|
|
95638
97571
|
});
|
|
95639
97572
|
}
|
|
@@ -95818,7 +97751,7 @@ function treeifyError(error, _mapper) {
|
|
|
95818
97751
|
return issue2.message;
|
|
95819
97752
|
};
|
|
95820
97753
|
const result = { errors: [] };
|
|
95821
|
-
const processError = (error2,
|
|
97754
|
+
const processError = (error2, path7 = []) => {
|
|
95822
97755
|
var _a2, _b2;
|
|
95823
97756
|
for (const issue2 of error2.issues) {
|
|
95824
97757
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -95828,7 +97761,7 @@ function treeifyError(error, _mapper) {
|
|
|
95828
97761
|
} else if (issue2.code === "invalid_element") {
|
|
95829
97762
|
processError({ issues: issue2.issues }, issue2.path);
|
|
95830
97763
|
} else {
|
|
95831
|
-
const fullpath = [...
|
|
97764
|
+
const fullpath = [...path7, ...issue2.path];
|
|
95832
97765
|
if (fullpath.length === 0) {
|
|
95833
97766
|
result.errors.push(mapper(issue2));
|
|
95834
97767
|
continue;
|
|
@@ -95858,9 +97791,9 @@ function treeifyError(error, _mapper) {
|
|
|
95858
97791
|
processError(error);
|
|
95859
97792
|
return result;
|
|
95860
97793
|
}
|
|
95861
|
-
function toDotPath(
|
|
97794
|
+
function toDotPath(path7) {
|
|
95862
97795
|
const segs = [];
|
|
95863
|
-
for (const seg of
|
|
97796
|
+
for (const seg of path7) {
|
|
95864
97797
|
if (typeof seg === "number")
|
|
95865
97798
|
segs.push(`[${seg}]`);
|
|
95866
97799
|
else if (typeof seg === "symbol")
|
|
@@ -106873,7 +108806,7 @@ var init_layers = __esm(() => {
|
|
|
106873
108806
|
IntervalClock = class IntervalClock extends exports_Context.Tag("IntervalClock")() {
|
|
106874
108807
|
};
|
|
106875
108808
|
IntervalClockLive = exports_Layer.succeed(IntervalClock, {
|
|
106876
|
-
sleep: (ms) => exports_Effect.promise(() => new Promise((
|
|
108809
|
+
sleep: (ms) => exports_Effect.promise(() => new Promise((resolve8) => setTimeout(resolve8, ms)))
|
|
106877
108810
|
});
|
|
106878
108811
|
});
|
|
106879
108812
|
|
|
@@ -107849,8 +109782,8 @@ var init_command_loop = __esm(() => {
|
|
|
107849
109782
|
const withTimeout2 = async (p, ms) => {
|
|
107850
109783
|
await Promise.race([
|
|
107851
109784
|
Promise.resolve(p).catch(() => {}),
|
|
107852
|
-
new Promise((
|
|
107853
|
-
const t = setTimeout(
|
|
109785
|
+
new Promise((resolve8) => {
|
|
109786
|
+
const t = setTimeout(resolve8, ms);
|
|
107854
109787
|
t.unref?.();
|
|
107855
109788
|
})
|
|
107856
109789
|
]);
|
|
@@ -108004,7 +109937,7 @@ async function daemonStop() {
|
|
|
108004
109937
|
console.log(`Stopping daemon (PID: ${pid})...`);
|
|
108005
109938
|
try {
|
|
108006
109939
|
process.kill(pid, "SIGTERM");
|
|
108007
|
-
await new Promise((
|
|
109940
|
+
await new Promise((resolve8) => setTimeout(resolve8, 8000));
|
|
108008
109941
|
try {
|
|
108009
109942
|
process.kill(pid, 0);
|
|
108010
109943
|
console.log(`Process did not exit gracefully, forcing...`);
|
|
@@ -108128,7 +110061,7 @@ __export(exports_opencode_install, {
|
|
|
108128
110061
|
installTool: () => installTool
|
|
108129
110062
|
});
|
|
108130
110063
|
import * as os2 from "os";
|
|
108131
|
-
import * as
|
|
110064
|
+
import * as path7 from "path";
|
|
108132
110065
|
async function isChatroomInstalledDefault() {
|
|
108133
110066
|
try {
|
|
108134
110067
|
const { execSync: execSync3 } = await import("child_process");
|
|
@@ -108498,9 +110431,9 @@ After logging in, try this command again.\`;
|
|
|
108498
110431
|
const fsService = yield* OpenCodeInstallFsService;
|
|
108499
110432
|
const { checkExisting = true } = options;
|
|
108500
110433
|
const homeDir = os2.homedir();
|
|
108501
|
-
const toolDir =
|
|
108502
|
-
const toolPath =
|
|
108503
|
-
const handoffToolPath =
|
|
110434
|
+
const toolDir = path7.join(homeDir, ".config", "opencode", "tool");
|
|
110435
|
+
const toolPath = path7.join(toolDir, "chatroom.ts");
|
|
110436
|
+
const handoffToolPath = path7.join(toolDir, "chatroom-handoff.ts");
|
|
108504
110437
|
if (checkExisting) {
|
|
108505
110438
|
const existingFiles = [];
|
|
108506
110439
|
const toolExists = yield* fsService.access(toolPath);
|
|
@@ -108573,7 +110506,7 @@ async function withRetry(fn2, opts) {
|
|
|
108573
110506
|
return;
|
|
108574
110507
|
}
|
|
108575
110508
|
const delay3 = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);
|
|
108576
|
-
await new Promise((
|
|
110509
|
+
await new Promise((resolve8) => setTimeout(resolve8, delay3));
|
|
108577
110510
|
}
|
|
108578
110511
|
}
|
|
108579
110512
|
return;
|
|
@@ -109055,4 +110988,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
109055
110988
|
});
|
|
109056
110989
|
program2.parse();
|
|
109057
110990
|
|
|
109058
|
-
//# debugId=
|
|
110991
|
+
//# debugId=D9A06559C6AC810C64756E2164756E21
|