chatroom-cli 1.98.3 → 1.98.5
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 +402 -335
- package/dist/index.js.map +26 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -108647,12 +108647,17 @@ function handleRefreshCapabilitiesEffect(event, tracker) {
|
|
|
108647
108647
|
})));
|
|
108648
108648
|
});
|
|
108649
108649
|
}
|
|
108650
|
-
async function handleInboundCommandEvent(commandId, tracker, effectContext2, session2) {
|
|
108651
|
-
|
|
108652
|
-
|
|
108653
|
-
|
|
108654
|
-
}
|
|
108655
|
-
|
|
108650
|
+
async function handleInboundCommandEvent(commandId, tracker, effectContext2, session2, commandEvent) {
|
|
108651
|
+
let event;
|
|
108652
|
+
if (commandEvent?._id.toString() === commandId) {
|
|
108653
|
+
event = commandEvent;
|
|
108654
|
+
} else {
|
|
108655
|
+
const result = await session2.backend.query(api.machines.getCommandEvents, {
|
|
108656
|
+
sessionId: session2.sessionId,
|
|
108657
|
+
machineId: session2.machineId
|
|
108658
|
+
});
|
|
108659
|
+
event = result?.events?.find((e) => e._id.toString() === commandId);
|
|
108660
|
+
}
|
|
108656
108661
|
if (!event)
|
|
108657
108662
|
return;
|
|
108658
108663
|
await exports_Effect.runPromise(dispatchCommandEventEffect(event, tracker).pipe(exports_Effect.provide(effectContext2)));
|
|
@@ -110259,49 +110264,6 @@ var init_file_content_subscription = __esm(() => {
|
|
|
110259
110264
|
init_daemon_services();
|
|
110260
110265
|
});
|
|
110261
110266
|
|
|
110262
|
-
// ../../services/backend/src/domain/workspace-file-tree/types.ts
|
|
110263
|
-
var MAX_TREE_JSON_BYTES;
|
|
110264
|
-
var init_types2 = __esm(() => {
|
|
110265
|
-
MAX_TREE_JSON_BYTES = 900 * 1024;
|
|
110266
|
-
});
|
|
110267
|
-
// ../../services/backend/src/domain/workspace-file-tree/select-strategy.ts
|
|
110268
|
-
function treeJsonByteLength(tree) {
|
|
110269
|
-
return Buffer.byteLength(JSON.stringify(tree), "utf8");
|
|
110270
|
-
}
|
|
110271
|
-
function selectFileTreeSnapshotStrategyId(tree) {
|
|
110272
|
-
return treeJsonByteLength(tree) > MAX_TREE_JSON_BYTES ? "sharded" : "blob";
|
|
110273
|
-
}
|
|
110274
|
-
var init_select_strategy = __esm(() => {
|
|
110275
|
-
init_types2();
|
|
110276
|
-
});
|
|
110277
|
-
|
|
110278
|
-
// ../../services/backend/src/domain/workspace-file-tree/registry.ts
|
|
110279
|
-
var init_registry5 = __esm(() => {
|
|
110280
|
-
init_select_strategy();
|
|
110281
|
-
});
|
|
110282
|
-
// ../../services/backend/src/domain/workspace-file-tree/transport/blob-snapshot.ts
|
|
110283
|
-
function toLegacyBlobSyncArgs(payload) {
|
|
110284
|
-
return { data: payload.data, dataHash: payload.dataHash, scannedAt: payload.scannedAt };
|
|
110285
|
-
}
|
|
110286
|
-
|
|
110287
|
-
// ../../services/backend/src/domain/workspace-file-tree/transport/sharded-snapshot.ts
|
|
110288
|
-
function toLegacyShardBatchItem(shard) {
|
|
110289
|
-
return { ...shard };
|
|
110290
|
-
}
|
|
110291
|
-
function toLegacyManifestSyncArgs(manifest) {
|
|
110292
|
-
return { ...manifest };
|
|
110293
|
-
}
|
|
110294
|
-
// ../../services/backend/src/domain/workspace-file-tree/transport/index.ts
|
|
110295
|
-
var init_transport = () => {};
|
|
110296
|
-
|
|
110297
|
-
// ../../services/backend/src/domain/workspace-file-tree/index.ts
|
|
110298
|
-
var init_workspace_file_tree = __esm(() => {
|
|
110299
|
-
init_types2();
|
|
110300
|
-
init_select_strategy();
|
|
110301
|
-
init_registry5();
|
|
110302
|
-
init_transport();
|
|
110303
|
-
});
|
|
110304
|
-
|
|
110305
110267
|
// src/infrastructure/services/workspace/file-tree-data-hash.ts
|
|
110306
110268
|
import { createHash as createHash6 } from "node:crypto";
|
|
110307
110269
|
function computeFileTreeDataHash(tree) {
|
|
@@ -110309,168 +110271,6 @@ function computeFileTreeDataHash(tree) {
|
|
|
110309
110271
|
}
|
|
110310
110272
|
var init_file_tree_data_hash = () => {};
|
|
110311
110273
|
|
|
110312
|
-
// src/infrastructure/services/workspace/transport/blob-snapshot-publish.ts
|
|
110313
|
-
import { gzipSync as gzipSync2 } from "node:zlib";
|
|
110314
|
-
function buildBlobSnapshotPayload(tree, dataHash) {
|
|
110315
|
-
const compressed = gzipSync2(Buffer.from(JSON.stringify(tree))).toString("base64");
|
|
110316
|
-
return {
|
|
110317
|
-
data: { compression: "gzip", content: compressed },
|
|
110318
|
-
dataHash,
|
|
110319
|
-
scannedAt: tree.scannedAt
|
|
110320
|
-
};
|
|
110321
|
-
}
|
|
110322
|
-
async function publishBlobSnapshot(session2, workingDir, payload) {
|
|
110323
|
-
await session2.backend.mutation(api.workspaceFiles.syncFileTreeV2, {
|
|
110324
|
-
sessionId: session2.sessionId,
|
|
110325
|
-
machineId: session2.machineId,
|
|
110326
|
-
workingDir,
|
|
110327
|
-
...toLegacyBlobSyncArgs(payload)
|
|
110328
|
-
});
|
|
110329
|
-
return {
|
|
110330
|
-
strategyId: "blob",
|
|
110331
|
-
snapshotId: payload.dataHash,
|
|
110332
|
-
scannedAt: payload.scannedAt,
|
|
110333
|
-
entryCount: 0
|
|
110334
|
-
};
|
|
110335
|
-
}
|
|
110336
|
-
var init_blob_snapshot_publish = __esm(() => {
|
|
110337
|
-
init_api3();
|
|
110338
|
-
});
|
|
110339
|
-
|
|
110340
|
-
// src/infrastructure/services/workspace/file-tree-partition.ts
|
|
110341
|
-
import { createHash as createHash7 } from "node:crypto";
|
|
110342
|
-
import { gzipSync as gzipSync3 } from "node:zlib";
|
|
110343
|
-
function computeShardDataHash(payload) {
|
|
110344
|
-
return createHash7("md5").update(JSON.stringify(payload)).digest("hex");
|
|
110345
|
-
}
|
|
110346
|
-
function shardIdForPath(path3) {
|
|
110347
|
-
const slash = path3.indexOf("/");
|
|
110348
|
-
return slash === -1 ? "__root__" : path3.slice(0, slash);
|
|
110349
|
-
}
|
|
110350
|
-
function childShardId(path3, parentShardId) {
|
|
110351
|
-
if (parentShardId === "__root__") {
|
|
110352
|
-
return shardIdForPath(path3);
|
|
110353
|
-
}
|
|
110354
|
-
if (path3 === parentShardId) {
|
|
110355
|
-
return parentShardId;
|
|
110356
|
-
}
|
|
110357
|
-
const prefix = `${parentShardId}/`;
|
|
110358
|
-
if (!path3.startsWith(prefix)) {
|
|
110359
|
-
return parentShardId;
|
|
110360
|
-
}
|
|
110361
|
-
const remainder = path3.slice(prefix.length);
|
|
110362
|
-
const slash = remainder.indexOf("/");
|
|
110363
|
-
return slash === -1 ? parentShardId : `${parentShardId}/${remainder.slice(0, slash)}`;
|
|
110364
|
-
}
|
|
110365
|
-
function groupEntriesByShardId(entries2, parentShardId) {
|
|
110366
|
-
const groups = new Map;
|
|
110367
|
-
for (const entry of entries2) {
|
|
110368
|
-
const shardId = parentShardId === "__root__" ? shardIdForPath(entry.path) : childShardId(entry.path, parentShardId);
|
|
110369
|
-
const group = groups.get(shardId) ?? [];
|
|
110370
|
-
group.push(entry);
|
|
110371
|
-
groups.set(shardId, group);
|
|
110372
|
-
}
|
|
110373
|
-
return groups;
|
|
110374
|
-
}
|
|
110375
|
-
function buildPreparedShard(shardId, payload) {
|
|
110376
|
-
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
110377
|
-
return {
|
|
110378
|
-
shardId,
|
|
110379
|
-
payload,
|
|
110380
|
-
dataHash: computeShardDataHash(payload),
|
|
110381
|
-
entryCount: payload.entries.length,
|
|
110382
|
-
data: { compression: "gzip", content: compressed }
|
|
110383
|
-
};
|
|
110384
|
-
}
|
|
110385
|
-
function subdivideShardGroup(subgroups, tree) {
|
|
110386
|
-
const shards = [];
|
|
110387
|
-
for (const [subId, subEntries] of subgroups) {
|
|
110388
|
-
shards.push(...prepareShardGroup(subEntries, subId, tree));
|
|
110389
|
-
}
|
|
110390
|
-
return shards;
|
|
110391
|
-
}
|
|
110392
|
-
function shouldSkipParentCompression(subgroups, entryCount) {
|
|
110393
|
-
return subgroups.size > 1 && entryCount > LARGE_SHARD_ENTRY_THRESHOLD;
|
|
110394
|
-
}
|
|
110395
|
-
function prepareShardGroup(entries2, shardId, tree) {
|
|
110396
|
-
const subgroups = groupEntriesByShardId(entries2, shardId);
|
|
110397
|
-
if (shouldSkipParentCompression(subgroups, entries2.length)) {
|
|
110398
|
-
return subdivideShardGroup(subgroups, tree);
|
|
110399
|
-
}
|
|
110400
|
-
const payload = {
|
|
110401
|
-
entries: entries2,
|
|
110402
|
-
scannedAt: tree.scannedAt,
|
|
110403
|
-
rootDir: tree.rootDir
|
|
110404
|
-
};
|
|
110405
|
-
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
110406
|
-
if (Buffer.byteLength(compressed, "utf8") <= MAX_SHARD_JSON_BYTES || subgroups.size <= 1) {
|
|
110407
|
-
return [buildPreparedShard(shardId, payload)];
|
|
110408
|
-
}
|
|
110409
|
-
return subdivideShardGroup(subgroups, tree);
|
|
110410
|
-
}
|
|
110411
|
-
function partitionFileTree(tree) {
|
|
110412
|
-
const topGroups = groupEntriesByShardId(tree.entries, "__root__");
|
|
110413
|
-
const shards = [];
|
|
110414
|
-
for (const [shardId, entries2] of topGroups) {
|
|
110415
|
-
shards.push(...prepareShardGroup(entries2, shardId, tree));
|
|
110416
|
-
}
|
|
110417
|
-
return shards;
|
|
110418
|
-
}
|
|
110419
|
-
var MAX_TREE_JSON_BYTES2, MAX_SHARD_JSON_BYTES, MAX_SHARD_BATCH_SIZE = 8, LARGE_SHARD_ENTRY_THRESHOLD = 50000;
|
|
110420
|
-
var init_file_tree_partition = __esm(() => {
|
|
110421
|
-
init_workspace_file_tree();
|
|
110422
|
-
MAX_TREE_JSON_BYTES2 = 900 * 1024;
|
|
110423
|
-
MAX_SHARD_JSON_BYTES = 800 * 1024;
|
|
110424
|
-
});
|
|
110425
|
-
|
|
110426
|
-
// src/infrastructure/services/workspace/transport/sharded-snapshot-publish.ts
|
|
110427
|
-
async function publishShardedSnapshot(session2, workingDir, tree, syncGeneration) {
|
|
110428
|
-
const shards = partitionFileTree(tree);
|
|
110429
|
-
const shardIds = [];
|
|
110430
|
-
for (let i2 = 0;i2 < shards.length; i2 += MAX_SHARD_BATCH_SIZE) {
|
|
110431
|
-
const batch = shards.slice(i2, i2 + MAX_SHARD_BATCH_SIZE);
|
|
110432
|
-
const items = batch.map((s) => ({
|
|
110433
|
-
shardId: s.shardId,
|
|
110434
|
-
data: s.data,
|
|
110435
|
-
dataHash: s.dataHash,
|
|
110436
|
-
scannedAt: tree.scannedAt,
|
|
110437
|
-
entryCount: s.entryCount
|
|
110438
|
-
}));
|
|
110439
|
-
await session2.backend.mutation(api.workspaceFiles.syncFileTreeShardV3Batch, {
|
|
110440
|
-
sessionId: session2.sessionId,
|
|
110441
|
-
machineId: session2.machineId,
|
|
110442
|
-
workingDir,
|
|
110443
|
-
syncGeneration,
|
|
110444
|
-
items: items.map(toLegacyShardBatchItem)
|
|
110445
|
-
});
|
|
110446
|
-
for (const s of batch)
|
|
110447
|
-
shardIds.push(s.shardId);
|
|
110448
|
-
}
|
|
110449
|
-
const manifest = {
|
|
110450
|
-
syncGeneration,
|
|
110451
|
-
shardIds,
|
|
110452
|
-
totalEntryCount: tree.entries.length,
|
|
110453
|
-
complete: true,
|
|
110454
|
-
scannedAt: tree.scannedAt
|
|
110455
|
-
};
|
|
110456
|
-
await session2.backend.mutation(api.workspaceFiles.syncFileTreeManifestV3, {
|
|
110457
|
-
sessionId: session2.sessionId,
|
|
110458
|
-
machineId: session2.machineId,
|
|
110459
|
-
workingDir,
|
|
110460
|
-
...toLegacyManifestSyncArgs(manifest)
|
|
110461
|
-
});
|
|
110462
|
-
return {
|
|
110463
|
-
strategyId: "sharded",
|
|
110464
|
-
snapshotId: syncGeneration,
|
|
110465
|
-
scannedAt: tree.scannedAt,
|
|
110466
|
-
entryCount: tree.entries.length
|
|
110467
|
-
};
|
|
110468
|
-
}
|
|
110469
|
-
var init_sharded_snapshot_publish = __esm(() => {
|
|
110470
|
-
init_api3();
|
|
110471
|
-
init_file_tree_partition();
|
|
110472
|
-
});
|
|
110473
|
-
|
|
110474
110274
|
// src/infrastructure/services/workspace/file-tree-sync-ranker.ts
|
|
110475
110275
|
function fileExtension(p) {
|
|
110476
110276
|
const b = (p.split("/").pop() ?? p).toLowerCase();
|
|
@@ -113598,13 +113398,13 @@ function diffPathIndexes(previous, next4) {
|
|
|
113598
113398
|
}
|
|
113599
113399
|
|
|
113600
113400
|
// src/infrastructure/services/workspace/workspace-sync-state.ts
|
|
113601
|
-
import { createHash as
|
|
113401
|
+
import { createHash as createHash7, randomUUID as randomUUID9 } from "node:crypto";
|
|
113602
113402
|
import * as fs11 from "node:fs/promises";
|
|
113603
113403
|
import { homedir as homedir8 } from "node:os";
|
|
113604
113404
|
import { join as join24 } from "node:path";
|
|
113605
113405
|
function workspaceKeyFor(workingDir) {
|
|
113606
113406
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
113607
|
-
return
|
|
113407
|
+
return createHash7("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
113608
113408
|
}
|
|
113609
113409
|
function buildPathIndex(entries2) {
|
|
113610
113410
|
const paths = {};
|
|
@@ -114045,6 +113845,45 @@ var init_workspace_sync_queue = __esm(() => {
|
|
|
114045
113845
|
lastCompletedAtByKey = new Map;
|
|
114046
113846
|
});
|
|
114047
113847
|
|
|
113848
|
+
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-schema.ts
|
|
113849
|
+
var DURABLE_COALESCING_STATE_MIGRATIONS;
|
|
113850
|
+
var init_durable_coalescing_state_schema = __esm(() => {
|
|
113851
|
+
DURABLE_COALESCING_STATE_MIGRATIONS = [
|
|
113852
|
+
`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
|
|
113853
|
+
`CREATE TABLE IF NOT EXISTS coalescing_outbox_entries (delivery_key TEXT PRIMARY KEY, payload_json TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', attempts INTEGER NOT NULL DEFAULT 0, last_error TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`
|
|
113854
|
+
];
|
|
113855
|
+
});
|
|
113856
|
+
|
|
113857
|
+
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
113858
|
+
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
113859
|
+
import { dirname as dirname12 } from "node:path";
|
|
113860
|
+
import { DatabaseSync } from "node:sqlite";
|
|
113861
|
+
function openDurableCoalescingStateStore(path8) {
|
|
113862
|
+
mkdirSync6(dirname12(path8), { recursive: true });
|
|
113863
|
+
const db = new DatabaseSync(path8);
|
|
113864
|
+
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
113865
|
+
db.exec(sql);
|
|
113866
|
+
db.prepare("UPDATE coalescing_outbox_entries SET status='pending' WHERE status='in_flight'").run();
|
|
113867
|
+
return { upsertPending: (key, payload) => {
|
|
113868
|
+
const now = Date.now();
|
|
113869
|
+
db.prepare("INSERT INTO coalescing_outbox_entries(delivery_key,payload_json,status,created_at,updated_at) VALUES(?,?,'pending',?,?) ON CONFLICT(delivery_key) DO UPDATE SET payload_json=excluded.payload_json,status='pending',updated_at=excluded.updated_at").run(key, payload, now, now);
|
|
113870
|
+
}, getPending: (key) => db.prepare("SELECT payload_json as payloadJson, attempts FROM coalescing_outbox_entries WHERE delivery_key=? AND status IN ('pending','in_flight')").get(key) ?? null, markDone: (key) => {
|
|
113871
|
+
db.prepare("DELETE FROM coalescing_outbox_entries WHERE delivery_key=?").run(key);
|
|
113872
|
+
}, markPendingRetry: (key, error51) => {
|
|
113873
|
+
db.prepare("UPDATE coalescing_outbox_entries SET status='pending',last_error=?,attempts=attempts+1,updated_at=? WHERE delivery_key=?").run(String(error51), Date.now(), key);
|
|
113874
|
+
}, listPendingKeys: () => db.prepare("SELECT delivery_key as key FROM coalescing_outbox_entries WHERE status IN ('pending','in_flight')").all().map((r) => String(r.key)), close: () => db.close() };
|
|
113875
|
+
}
|
|
113876
|
+
var init_durable_coalescing_state_store = __esm(() => {
|
|
113877
|
+
init_durable_coalescing_state_schema();
|
|
113878
|
+
});
|
|
113879
|
+
|
|
113880
|
+
// src/daemon/infrastructure/outbox/lib/outbox-retry-backoff.ts
|
|
113881
|
+
function computeExponentialRetryDelayMs(attempt, retryDelayMs, maxRetryDelayMs) {
|
|
113882
|
+
const exponent = Math.min(Math.max(0, attempt), MAX_RETRY_EXPONENT);
|
|
113883
|
+
return Math.min(retryDelayMs * 2 ** exponent, maxRetryDelayMs);
|
|
113884
|
+
}
|
|
113885
|
+
var MAX_RETRY_EXPONENT = 20;
|
|
113886
|
+
|
|
114048
113887
|
// src/daemon/infrastructure/outbox/lib/coalescing-state-outbox.ts
|
|
114049
113888
|
function createCoalescingStateOutbox(options) {
|
|
114050
113889
|
const durable = [options.store, options.deliveryKey, options.serialize, options.deserialize];
|
|
@@ -114061,8 +113900,10 @@ function createCoalescingStateOutbox(options) {
|
|
|
114061
113900
|
let stopped = false;
|
|
114062
113901
|
if (options.store && options.deliveryKey && options.deserialize) {
|
|
114063
113902
|
const recovered = options.store.getPending(options.deliveryKey);
|
|
114064
|
-
if (recovered)
|
|
113903
|
+
if (recovered) {
|
|
114065
113904
|
pending3 = { state: options.deserialize(recovered.payloadJson), waiters: [] };
|
|
113905
|
+
retryAttempt = recovered.attempts;
|
|
113906
|
+
}
|
|
114066
113907
|
}
|
|
114067
113908
|
const rejectWaiters = (waiters, error51) => {
|
|
114068
113909
|
for (const waiter of waiters)
|
|
@@ -114088,8 +113929,9 @@ function createCoalescingStateOutbox(options) {
|
|
|
114088
113929
|
}, Math.max(0, delayMs));
|
|
114089
113930
|
timer.unref?.();
|
|
114090
113931
|
};
|
|
114091
|
-
if (pending3)
|
|
114092
|
-
schedule2(0);
|
|
113932
|
+
if (pending3) {
|
|
113933
|
+
schedule2(retryAttempt > 0 ? computeExponentialRetryDelayMs(retryAttempt - 1, retryDelayMs, maxRetryDelayMs) : 0);
|
|
113934
|
+
}
|
|
114093
113935
|
async function drain2() {
|
|
114094
113936
|
if (stopped || !pending3 || inFlight2)
|
|
114095
113937
|
return;
|
|
@@ -114098,18 +113940,22 @@ function createCoalescingStateOutbox(options) {
|
|
|
114098
113940
|
const sendPromise = Promise.resolve().then(() => options.send(batch.state));
|
|
114099
113941
|
inFlight2 = { ...batch, promise: sendPromise };
|
|
114100
113942
|
let retryDelay = null;
|
|
113943
|
+
const store = options.store;
|
|
113944
|
+
const deliveryKey = options.deliveryKey;
|
|
114101
113945
|
try {
|
|
114102
113946
|
const result = await sendPromise;
|
|
114103
113947
|
lastSentAt = Date.now();
|
|
114104
113948
|
retryAttempt = 0;
|
|
114105
|
-
|
|
113949
|
+
if (store && deliveryKey)
|
|
113950
|
+
store.markDone(deliveryKey);
|
|
114106
113951
|
for (const waiter of batch.waiters)
|
|
114107
113952
|
waiter.resolve(result);
|
|
114108
113953
|
} catch (error51) {
|
|
114109
113954
|
options.onError?.(error51);
|
|
114110
|
-
|
|
113955
|
+
if (store && deliveryKey)
|
|
113956
|
+
store.markPendingRetry(deliveryKey, error51);
|
|
114111
113957
|
pending3 = mergePending(batch, pending3);
|
|
114112
|
-
retryDelay =
|
|
113958
|
+
retryDelay = computeExponentialRetryDelayMs(retryAttempt, retryDelayMs, maxRetryDelayMs);
|
|
114113
113959
|
retryAttempt++;
|
|
114114
113960
|
throw error51;
|
|
114115
113961
|
} finally {
|
|
@@ -114130,7 +113976,9 @@ function createCoalescingStateOutbox(options) {
|
|
|
114130
113976
|
} else {
|
|
114131
113977
|
pending3 = { state, waiters: [waiter] };
|
|
114132
113978
|
}
|
|
114133
|
-
options.store
|
|
113979
|
+
if (options.store && options.deliveryKey && options.serialize) {
|
|
113980
|
+
options.store.upsertPending(options.deliveryKey, options.serialize(state));
|
|
113981
|
+
}
|
|
114134
113982
|
});
|
|
114135
113983
|
if (!inFlight2 && !timer) {
|
|
114136
113984
|
const delay3 = lastSentAt === 0 ? 0 : Math.max(0, minIntervalMs - (Date.now() - lastSentAt));
|
|
@@ -114168,6 +114016,7 @@ function createCoalescingStateOutbox(options) {
|
|
|
114168
114016
|
return { enqueue, flushNow, stop: stop4 };
|
|
114169
114017
|
}
|
|
114170
114018
|
var DEFAULT_MIN_INTERVAL_MS = 5000, DEFAULT_RETRY_DELAY_MS = 500, DEFAULT_MAX_RETRY_DELAY_MS = 5000;
|
|
114019
|
+
var init_coalescing_state_outbox = () => {};
|
|
114171
114020
|
|
|
114172
114021
|
// src/daemon/infrastructure/outbox/lib/keyed-coalescing-state-outbox-registry.ts
|
|
114173
114022
|
function createKeyedCoalescingStateOutboxRegistry(options) {
|
|
@@ -114207,7 +114056,9 @@ function createKeyedCoalescingStateOutboxRegistry(options) {
|
|
|
114207
114056
|
}
|
|
114208
114057
|
};
|
|
114209
114058
|
}
|
|
114210
|
-
var init_keyed_coalescing_state_outbox_registry = () => {
|
|
114059
|
+
var init_keyed_coalescing_state_outbox_registry = __esm(() => {
|
|
114060
|
+
init_coalescing_state_outbox();
|
|
114061
|
+
});
|
|
114211
114062
|
|
|
114212
114063
|
// src/daemon/infrastructure/outbox/outbox-db-path.ts
|
|
114213
114064
|
import { homedir as homedir9 } from "node:os";
|
|
@@ -114217,38 +114068,6 @@ function resolveOutboxDbPath(machineId, kind) {
|
|
|
114217
114068
|
}
|
|
114218
114069
|
var init_outbox_db_path = () => {};
|
|
114219
114070
|
|
|
114220
|
-
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-schema.ts
|
|
114221
|
-
var DURABLE_COALESCING_STATE_MIGRATIONS;
|
|
114222
|
-
var init_durable_coalescing_state_schema = __esm(() => {
|
|
114223
|
-
DURABLE_COALESCING_STATE_MIGRATIONS = [
|
|
114224
|
-
`CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
|
|
114225
|
-
`CREATE TABLE IF NOT EXISTS coalescing_outbox_entries (delivery_key TEXT PRIMARY KEY, payload_json TEXT NOT NULL, status TEXT NOT NULL DEFAULT 'pending', attempts INTEGER NOT NULL DEFAULT 0, last_error TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`
|
|
114226
|
-
];
|
|
114227
|
-
});
|
|
114228
|
-
|
|
114229
|
-
// src/daemon/infrastructure/outbox/lib/durable-coalescing-state-store.ts
|
|
114230
|
-
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
114231
|
-
import { dirname as dirname12 } from "node:path";
|
|
114232
|
-
import { DatabaseSync } from "node:sqlite";
|
|
114233
|
-
function openDurableCoalescingStateStore(path8) {
|
|
114234
|
-
mkdirSync6(dirname12(path8), { recursive: true });
|
|
114235
|
-
const db = new DatabaseSync(path8);
|
|
114236
|
-
for (const sql of DURABLE_COALESCING_STATE_MIGRATIONS)
|
|
114237
|
-
db.exec(sql);
|
|
114238
|
-
db.prepare("UPDATE coalescing_outbox_entries SET status='pending' WHERE status='in_flight'").run();
|
|
114239
|
-
return { upsertPending: (key, payload) => {
|
|
114240
|
-
const now = Date.now();
|
|
114241
|
-
db.prepare("INSERT INTO coalescing_outbox_entries(delivery_key,payload_json,status,created_at,updated_at) VALUES(?,?,'pending',?,?) ON CONFLICT(delivery_key) DO UPDATE SET payload_json=excluded.payload_json,status='pending',updated_at=excluded.updated_at").run(key, payload, now, now);
|
|
114242
|
-
}, getPending: (key) => db.prepare("SELECT payload_json as payloadJson, attempts FROM coalescing_outbox_entries WHERE delivery_key=? AND status IN ('pending','in_flight')").get(key) ?? null, markDone: (key) => {
|
|
114243
|
-
db.prepare("DELETE FROM coalescing_outbox_entries WHERE delivery_key=?").run(key);
|
|
114244
|
-
}, markPendingRetry: (key, error51) => {
|
|
114245
|
-
db.prepare("UPDATE coalescing_outbox_entries SET status='pending',last_error=?,attempts=attempts+1,updated_at=? WHERE delivery_key=?").run(String(error51), Date.now(), key);
|
|
114246
|
-
}, listPendingKeys: () => db.prepare("SELECT delivery_key as key FROM coalescing_outbox_entries WHERE status IN ('pending','in_flight')").all().map((r) => String(r.key)), close: () => db.close() };
|
|
114247
|
-
}
|
|
114248
|
-
var init_durable_coalescing_state_store = __esm(() => {
|
|
114249
|
-
init_durable_coalescing_state_schema();
|
|
114250
|
-
});
|
|
114251
|
-
|
|
114252
114071
|
// src/daemon/infrastructure/outbox/workspace-file-tree-checkpoint-outbox.ts
|
|
114253
114072
|
function createWorkspaceFileTreeCheckpointOutboxRegistry(machineId, createSend, options) {
|
|
114254
114073
|
return createKeyedCoalescingStateOutboxRegistry({
|
|
@@ -114257,14 +114076,17 @@ function createWorkspaceFileTreeCheckpointOutboxRegistry(machineId, createSend,
|
|
|
114257
114076
|
deserialize: JSON.parse,
|
|
114258
114077
|
createSend,
|
|
114259
114078
|
minIntervalMs: WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MIN_INTERVAL_MS,
|
|
114079
|
+
retryDelayMs: WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_RETRY_DELAY_MS,
|
|
114080
|
+
maxRetryDelayMs: WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MAX_RETRY_DELAY_MS,
|
|
114260
114081
|
onError: options?.onError
|
|
114261
114082
|
});
|
|
114262
114083
|
}
|
|
114263
|
-
var WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MIN_INTERVAL_MS = 5000;
|
|
114084
|
+
var WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MIN_INTERVAL_MS = 5000, WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_RETRY_DELAY_MS = 5000, WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MAX_RETRY_DELAY_MS;
|
|
114264
114085
|
var init_workspace_file_tree_checkpoint_outbox = __esm(() => {
|
|
114086
|
+
init_durable_coalescing_state_store();
|
|
114265
114087
|
init_keyed_coalescing_state_outbox_registry();
|
|
114266
114088
|
init_outbox_db_path();
|
|
114267
|
-
|
|
114089
|
+
WORKSPACE_FILE_TREE_CHECKPOINT_OUTBOX_MAX_RETRY_DELAY_MS = 5 * 60000;
|
|
114268
114090
|
});
|
|
114269
114091
|
|
|
114270
114092
|
// src/daemon/infrastructure/outbox/lib/durable-fifo-queue-schema.ts
|
|
@@ -114320,7 +114142,7 @@ function createFifoBatchedOutbox(o) {
|
|
|
114320
114142
|
let stopped = false;
|
|
114321
114143
|
let retryTimer;
|
|
114322
114144
|
let retryAttempt = 0;
|
|
114323
|
-
const retryDelay = () =>
|
|
114145
|
+
const retryDelay = () => computeExponentialRetryDelayMs(retryAttempt++, o.retryDelayMs ?? 500, o.maxRetryDelayMs ?? 5000);
|
|
114324
114146
|
const scheduleRetry = () => {
|
|
114325
114147
|
if (!stopped && !retryTimer) {
|
|
114326
114148
|
retryTimer = setTimeout(() => {
|
|
@@ -114362,6 +114184,7 @@ function createFifoBatchedOutbox(o) {
|
|
|
114362
114184
|
scheduleRetry();
|
|
114363
114185
|
break;
|
|
114364
114186
|
}
|
|
114187
|
+
retryAttempt = 0;
|
|
114365
114188
|
} catch (e) {
|
|
114366
114189
|
o.onError?.(e);
|
|
114367
114190
|
for (const r of rows2)
|
|
@@ -114401,6 +114224,7 @@ function createFifoBatchedOutbox(o) {
|
|
|
114401
114224
|
};
|
|
114402
114225
|
return { enqueue, flushNow, stop: stop4 };
|
|
114403
114226
|
}
|
|
114227
|
+
var init_fifo_batched_outbox = () => {};
|
|
114404
114228
|
|
|
114405
114229
|
// src/daemon/infrastructure/outbox/lib/keyed-fifo-batched-outbox-registry.ts
|
|
114406
114230
|
function createKeyedFifoBatchedOutboxRegistry(o) {
|
|
@@ -114415,6 +114239,8 @@ function createKeyedFifoBatchedOutboxRegistry(o) {
|
|
|
114415
114239
|
deliveryKey: key,
|
|
114416
114240
|
serialize: o.serialize,
|
|
114417
114241
|
deserialize: o.deserialize,
|
|
114242
|
+
retryDelayMs: o.retryDelayMs,
|
|
114243
|
+
maxRetryDelayMs: o.maxRetryDelayMs,
|
|
114418
114244
|
onError: (e) => o.onError?.(key, e),
|
|
114419
114245
|
classifyOutcome: o.classifyOutcome
|
|
114420
114246
|
});
|
|
@@ -114447,7 +114273,7 @@ function createKeyedFifoBatchedOutboxRegistry(o) {
|
|
|
114447
114273
|
};
|
|
114448
114274
|
}
|
|
114449
114275
|
var init_keyed_fifo_batched_outbox_registry = __esm(() => {
|
|
114450
|
-
|
|
114276
|
+
init_fifo_batched_outbox();
|
|
114451
114277
|
});
|
|
114452
114278
|
|
|
114453
114279
|
// src/daemon/infrastructure/outbox/workspace-file-tree-delta-outbox.ts
|
|
@@ -114466,15 +114292,18 @@ function createWorkspaceFileTreeDeltaOutboxRegistry(machineId, createSend, optio
|
|
|
114466
114292
|
},
|
|
114467
114293
|
serialize: JSON.stringify,
|
|
114468
114294
|
deserialize: JSON.parse,
|
|
114295
|
+
retryDelayMs: WORKSPACE_FILE_TREE_DELTA_OUTBOX_RETRY_DELAY_MS,
|
|
114296
|
+
maxRetryDelayMs: WORKSPACE_FILE_TREE_DELTA_OUTBOX_MAX_RETRY_DELAY_MS,
|
|
114469
114297
|
onError: options?.onError,
|
|
114470
114298
|
classifyOutcome: (result, unit) => result.status === "conflict" ? { kind: "retry", item: { ...unit, baseRevision: result.revision } } : { kind: "success" }
|
|
114471
114299
|
});
|
|
114472
114300
|
}
|
|
114473
|
-
var WORKSPACE_FILE_TREE_DELTA_OUTBOX_BATCH_SIZE = 5;
|
|
114301
|
+
var WORKSPACE_FILE_TREE_DELTA_OUTBOX_BATCH_SIZE = 5, WORKSPACE_FILE_TREE_DELTA_OUTBOX_RETRY_DELAY_MS = 5000, WORKSPACE_FILE_TREE_DELTA_OUTBOX_MAX_RETRY_DELAY_MS;
|
|
114474
114302
|
var init_workspace_file_tree_delta_outbox = __esm(() => {
|
|
114475
|
-
init_outbox_db_path();
|
|
114476
114303
|
init_durable_fifo_queue_store();
|
|
114477
114304
|
init_keyed_fifo_batched_outbox_registry();
|
|
114305
|
+
init_outbox_db_path();
|
|
114306
|
+
WORKSPACE_FILE_TREE_DELTA_OUTBOX_MAX_RETRY_DELAY_MS = 5 * 60000;
|
|
114478
114307
|
});
|
|
114479
114308
|
|
|
114480
114309
|
// src/daemon/infrastructure/outbox/index.ts
|
|
@@ -114483,8 +114312,303 @@ var init_outbox = __esm(() => {
|
|
|
114483
114312
|
init_workspace_file_tree_delta_outbox();
|
|
114484
114313
|
});
|
|
114485
114314
|
|
|
114486
|
-
//
|
|
114315
|
+
// ../../services/backend/src/domain/workspace-file-tree/types.ts
|
|
114316
|
+
var MAX_TREE_JSON_BYTES;
|
|
114317
|
+
var init_types2 = __esm(() => {
|
|
114318
|
+
MAX_TREE_JSON_BYTES = 900 * 1024;
|
|
114319
|
+
});
|
|
114320
|
+
// ../../services/backend/src/domain/workspace-file-tree/select-strategy.ts
|
|
114321
|
+
function treeJsonByteLength(tree) {
|
|
114322
|
+
return Buffer.byteLength(JSON.stringify(tree), "utf8");
|
|
114323
|
+
}
|
|
114324
|
+
function selectFileTreeSnapshotStrategyId(tree) {
|
|
114325
|
+
return treeJsonByteLength(tree) > MAX_TREE_JSON_BYTES ? "sharded" : "blob";
|
|
114326
|
+
}
|
|
114327
|
+
var init_select_strategy = __esm(() => {
|
|
114328
|
+
init_types2();
|
|
114329
|
+
});
|
|
114330
|
+
|
|
114331
|
+
// ../../services/backend/src/domain/workspace-file-tree/registry.ts
|
|
114332
|
+
var init_registry5 = __esm(() => {
|
|
114333
|
+
init_select_strategy();
|
|
114334
|
+
});
|
|
114335
|
+
// ../../services/backend/src/domain/workspace-file-tree/transport/blob-snapshot.ts
|
|
114336
|
+
function toLegacyBlobSyncArgs(payload) {
|
|
114337
|
+
return { data: payload.data, dataHash: payload.dataHash, scannedAt: payload.scannedAt };
|
|
114338
|
+
}
|
|
114339
|
+
|
|
114340
|
+
// ../../services/backend/src/domain/workspace-file-tree/transport/sharded-snapshot.ts
|
|
114341
|
+
function toLegacyShardBatchItem(shard) {
|
|
114342
|
+
return { ...shard };
|
|
114343
|
+
}
|
|
114344
|
+
function toLegacyManifestSyncArgs(manifest) {
|
|
114345
|
+
return { ...manifest };
|
|
114346
|
+
}
|
|
114347
|
+
// ../../services/backend/src/domain/workspace-file-tree/transport/index.ts
|
|
114348
|
+
var init_transport = () => {};
|
|
114349
|
+
|
|
114350
|
+
// ../../services/backend/src/domain/workspace-file-tree/index.ts
|
|
114351
|
+
var init_workspace_file_tree = __esm(() => {
|
|
114352
|
+
init_types2();
|
|
114353
|
+
init_select_strategy();
|
|
114354
|
+
init_registry5();
|
|
114355
|
+
init_transport();
|
|
114356
|
+
});
|
|
114357
|
+
|
|
114358
|
+
// src/infrastructure/services/workspace/transport/blob-snapshot-publish.ts
|
|
114359
|
+
import { gzipSync as gzipSync2 } from "node:zlib";
|
|
114360
|
+
function buildBlobSnapshotPayload(tree, dataHash) {
|
|
114361
|
+
const compressed = gzipSync2(Buffer.from(JSON.stringify(tree))).toString("base64");
|
|
114362
|
+
return {
|
|
114363
|
+
data: { compression: "gzip", content: compressed },
|
|
114364
|
+
dataHash,
|
|
114365
|
+
scannedAt: tree.scannedAt
|
|
114366
|
+
};
|
|
114367
|
+
}
|
|
114368
|
+
async function publishBlobSnapshot(session2, workingDir, payload) {
|
|
114369
|
+
await session2.backend.mutation(api.workspaceFiles.syncFileTreeV2, {
|
|
114370
|
+
sessionId: session2.sessionId,
|
|
114371
|
+
machineId: session2.machineId,
|
|
114372
|
+
workingDir,
|
|
114373
|
+
...toLegacyBlobSyncArgs(payload)
|
|
114374
|
+
});
|
|
114375
|
+
return {
|
|
114376
|
+
strategyId: "blob",
|
|
114377
|
+
snapshotId: payload.dataHash,
|
|
114378
|
+
scannedAt: payload.scannedAt,
|
|
114379
|
+
entryCount: 0
|
|
114380
|
+
};
|
|
114381
|
+
}
|
|
114382
|
+
var init_blob_snapshot_publish = __esm(() => {
|
|
114383
|
+
init_api3();
|
|
114384
|
+
});
|
|
114385
|
+
|
|
114386
|
+
// src/infrastructure/services/workspace/file-tree-partition.ts
|
|
114387
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
114388
|
+
import { gzipSync as gzipSync3 } from "node:zlib";
|
|
114389
|
+
function computeShardDataHash(payload) {
|
|
114390
|
+
return createHash8("md5").update(JSON.stringify(payload)).digest("hex");
|
|
114391
|
+
}
|
|
114392
|
+
function shardIdForPath(path8) {
|
|
114393
|
+
const slash = path8.indexOf("/");
|
|
114394
|
+
return slash === -1 ? "__root__" : path8.slice(0, slash);
|
|
114395
|
+
}
|
|
114396
|
+
function childShardId(path8, parentShardId) {
|
|
114397
|
+
if (parentShardId === "__root__") {
|
|
114398
|
+
return shardIdForPath(path8);
|
|
114399
|
+
}
|
|
114400
|
+
if (path8 === parentShardId) {
|
|
114401
|
+
return parentShardId;
|
|
114402
|
+
}
|
|
114403
|
+
const prefix = `${parentShardId}/`;
|
|
114404
|
+
if (!path8.startsWith(prefix)) {
|
|
114405
|
+
return parentShardId;
|
|
114406
|
+
}
|
|
114407
|
+
const remainder = path8.slice(prefix.length);
|
|
114408
|
+
const slash = remainder.indexOf("/");
|
|
114409
|
+
return slash === -1 ? parentShardId : `${parentShardId}/${remainder.slice(0, slash)}`;
|
|
114410
|
+
}
|
|
114411
|
+
function groupEntriesByShardId(entries2, parentShardId) {
|
|
114412
|
+
const groups = new Map;
|
|
114413
|
+
for (const entry of entries2) {
|
|
114414
|
+
const shardId = parentShardId === "__root__" ? shardIdForPath(entry.path) : childShardId(entry.path, parentShardId);
|
|
114415
|
+
const group = groups.get(shardId) ?? [];
|
|
114416
|
+
group.push(entry);
|
|
114417
|
+
groups.set(shardId, group);
|
|
114418
|
+
}
|
|
114419
|
+
return groups;
|
|
114420
|
+
}
|
|
114421
|
+
function buildPreparedShard(shardId, payload) {
|
|
114422
|
+
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
114423
|
+
return {
|
|
114424
|
+
shardId,
|
|
114425
|
+
payload,
|
|
114426
|
+
dataHash: computeShardDataHash(payload),
|
|
114427
|
+
entryCount: payload.entries.length,
|
|
114428
|
+
data: { compression: "gzip", content: compressed }
|
|
114429
|
+
};
|
|
114430
|
+
}
|
|
114431
|
+
function subdivideShardGroup(subgroups, tree) {
|
|
114432
|
+
const shards = [];
|
|
114433
|
+
for (const [subId, subEntries] of subgroups) {
|
|
114434
|
+
shards.push(...prepareShardGroup(subEntries, subId, tree));
|
|
114435
|
+
}
|
|
114436
|
+
return shards;
|
|
114437
|
+
}
|
|
114438
|
+
function shouldSkipParentCompression(subgroups, entryCount) {
|
|
114439
|
+
return subgroups.size > 1 && entryCount > LARGE_SHARD_ENTRY_THRESHOLD;
|
|
114440
|
+
}
|
|
114441
|
+
function prepareShardGroup(entries2, shardId, tree) {
|
|
114442
|
+
const subgroups = groupEntriesByShardId(entries2, shardId);
|
|
114443
|
+
if (shouldSkipParentCompression(subgroups, entries2.length)) {
|
|
114444
|
+
return subdivideShardGroup(subgroups, tree);
|
|
114445
|
+
}
|
|
114446
|
+
const payload = {
|
|
114447
|
+
entries: entries2,
|
|
114448
|
+
scannedAt: tree.scannedAt,
|
|
114449
|
+
rootDir: tree.rootDir
|
|
114450
|
+
};
|
|
114451
|
+
const compressed = gzipSync3(Buffer.from(JSON.stringify(payload))).toString("base64");
|
|
114452
|
+
if (Buffer.byteLength(compressed, "utf8") <= MAX_SHARD_JSON_BYTES || subgroups.size <= 1) {
|
|
114453
|
+
return [buildPreparedShard(shardId, payload)];
|
|
114454
|
+
}
|
|
114455
|
+
return subdivideShardGroup(subgroups, tree);
|
|
114456
|
+
}
|
|
114457
|
+
function partitionFileTree(tree) {
|
|
114458
|
+
const topGroups = groupEntriesByShardId(tree.entries, "__root__");
|
|
114459
|
+
const shards = [];
|
|
114460
|
+
for (const [shardId, entries2] of topGroups) {
|
|
114461
|
+
shards.push(...prepareShardGroup(entries2, shardId, tree));
|
|
114462
|
+
}
|
|
114463
|
+
return shards;
|
|
114464
|
+
}
|
|
114465
|
+
var MAX_TREE_JSON_BYTES2, MAX_SHARD_JSON_BYTES, MAX_SHARD_BATCH_SIZE = 8, LARGE_SHARD_ENTRY_THRESHOLD = 50000;
|
|
114466
|
+
var init_file_tree_partition = __esm(() => {
|
|
114467
|
+
init_workspace_file_tree();
|
|
114468
|
+
MAX_TREE_JSON_BYTES2 = 900 * 1024;
|
|
114469
|
+
MAX_SHARD_JSON_BYTES = 800 * 1024;
|
|
114470
|
+
});
|
|
114471
|
+
|
|
114472
|
+
// src/infrastructure/services/workspace/transport/sharded-snapshot-publish.ts
|
|
114473
|
+
async function publishShardedSnapshot(session2, workingDir, tree, syncGeneration) {
|
|
114474
|
+
const shards = partitionFileTree(tree);
|
|
114475
|
+
const shardIds = [];
|
|
114476
|
+
for (let i2 = 0;i2 < shards.length; i2 += MAX_SHARD_BATCH_SIZE) {
|
|
114477
|
+
const batch = shards.slice(i2, i2 + MAX_SHARD_BATCH_SIZE);
|
|
114478
|
+
const items = batch.map((s) => ({
|
|
114479
|
+
shardId: s.shardId,
|
|
114480
|
+
data: s.data,
|
|
114481
|
+
dataHash: s.dataHash,
|
|
114482
|
+
scannedAt: tree.scannedAt,
|
|
114483
|
+
entryCount: s.entryCount
|
|
114484
|
+
}));
|
|
114485
|
+
await session2.backend.mutation(api.workspaceFiles.syncFileTreeShardV3Batch, {
|
|
114486
|
+
sessionId: session2.sessionId,
|
|
114487
|
+
machineId: session2.machineId,
|
|
114488
|
+
workingDir,
|
|
114489
|
+
syncGeneration,
|
|
114490
|
+
items: items.map(toLegacyShardBatchItem)
|
|
114491
|
+
});
|
|
114492
|
+
for (const s of batch)
|
|
114493
|
+
shardIds.push(s.shardId);
|
|
114494
|
+
}
|
|
114495
|
+
const manifest = {
|
|
114496
|
+
syncGeneration,
|
|
114497
|
+
shardIds,
|
|
114498
|
+
totalEntryCount: tree.entries.length,
|
|
114499
|
+
complete: true,
|
|
114500
|
+
scannedAt: tree.scannedAt
|
|
114501
|
+
};
|
|
114502
|
+
await session2.backend.mutation(api.workspaceFiles.syncFileTreeManifestV3, {
|
|
114503
|
+
sessionId: session2.sessionId,
|
|
114504
|
+
machineId: session2.machineId,
|
|
114505
|
+
workingDir,
|
|
114506
|
+
...toLegacyManifestSyncArgs(manifest)
|
|
114507
|
+
});
|
|
114508
|
+
return {
|
|
114509
|
+
strategyId: "sharded",
|
|
114510
|
+
snapshotId: syncGeneration,
|
|
114511
|
+
scannedAt: tree.scannedAt,
|
|
114512
|
+
entryCount: tree.entries.length
|
|
114513
|
+
};
|
|
114514
|
+
}
|
|
114515
|
+
var init_sharded_snapshot_publish = __esm(() => {
|
|
114516
|
+
init_api3();
|
|
114517
|
+
init_file_tree_partition();
|
|
114518
|
+
});
|
|
114519
|
+
|
|
114520
|
+
// src/daemon/infrastructure/outbox/workspace-file-tree-checkpoint-send.ts
|
|
114487
114521
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
114522
|
+
function needsMoreCheckpointPrune(result) {
|
|
114523
|
+
return (result.status === "published" || result.status === "unchanged") && result.pruneComplete === false;
|
|
114524
|
+
}
|
|
114525
|
+
function assertCheckpointAccepted(result) {
|
|
114526
|
+
if (result.status === "snapshot-missing" || result.status === "resync-required") {
|
|
114527
|
+
throw new Error(`File tree checkpoint rejected: ${result.status}`);
|
|
114528
|
+
}
|
|
114529
|
+
}
|
|
114530
|
+
async function syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration) {
|
|
114531
|
+
if (selectFileTreeSnapshotStrategyId(tree) === "sharded") {
|
|
114532
|
+
const ref2 = await publishShardedSnapshot(session2, normalizedWorkingDir, tree, syncGeneration);
|
|
114533
|
+
return { strategyId: ref2.strategyId, snapshotId: ref2.snapshotId };
|
|
114534
|
+
}
|
|
114535
|
+
const ref = await publishBlobSnapshot(session2, normalizedWorkingDir, buildBlobSnapshotPayload(tree, dataHash));
|
|
114536
|
+
return { strategyId: ref.strategyId, snapshotId: ref.snapshotId };
|
|
114537
|
+
}
|
|
114538
|
+
async function publishCheckpointUntilPruned(session2, normalizedWorkingDir, snapshot, revision) {
|
|
114539
|
+
let checkpointRevision = revision;
|
|
114540
|
+
const publish = () => session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
|
|
114541
|
+
sessionId: session2.sessionId,
|
|
114542
|
+
machineId: session2.machineId,
|
|
114543
|
+
workingDir: normalizedWorkingDir,
|
|
114544
|
+
revision: checkpointRevision,
|
|
114545
|
+
...snapshot
|
|
114546
|
+
});
|
|
114547
|
+
let result = await publish();
|
|
114548
|
+
if (result.status === "resync-required") {
|
|
114549
|
+
checkpointRevision = result.expectedRevision + 1;
|
|
114550
|
+
result = await publish();
|
|
114551
|
+
}
|
|
114552
|
+
while (needsMoreCheckpointPrune(result))
|
|
114553
|
+
result = await publish();
|
|
114554
|
+
assertCheckpointAccepted(result);
|
|
114555
|
+
return checkpointRevision;
|
|
114556
|
+
}
|
|
114557
|
+
function createWorkspaceFileTreeCheckpointSend(session2, normalizedWorkingDir) {
|
|
114558
|
+
return async (state) => {
|
|
114559
|
+
const snapshot = await syncScannedFileTree(session2, normalizedWorkingDir, state.tree, computeFileTreeDataHash(state.tree), randomUUID11());
|
|
114560
|
+
const revision = await publishCheckpointUntilPruned(session2, normalizedWorkingDir, snapshot, state.revision);
|
|
114561
|
+
return { revision };
|
|
114562
|
+
};
|
|
114563
|
+
}
|
|
114564
|
+
var init_workspace_file_tree_checkpoint_send = __esm(() => {
|
|
114565
|
+
init_workspace_file_tree();
|
|
114566
|
+
init_api3();
|
|
114567
|
+
init_file_tree_data_hash();
|
|
114568
|
+
init_blob_snapshot_publish();
|
|
114569
|
+
init_sharded_snapshot_publish();
|
|
114570
|
+
});
|
|
114571
|
+
|
|
114572
|
+
// src/daemon/infrastructure/outbox/workspace-file-tree-delta-send.ts
|
|
114573
|
+
function toDeltaOperations(delta) {
|
|
114574
|
+
return [
|
|
114575
|
+
...delta.added.map((entry) => ({
|
|
114576
|
+
o: "a",
|
|
114577
|
+
p: entry.path,
|
|
114578
|
+
e: entry.type === "directory" ? "d" : "f"
|
|
114579
|
+
})),
|
|
114580
|
+
...delta.removed.map((entryPath) => ({
|
|
114581
|
+
o: "r",
|
|
114582
|
+
p: entryPath
|
|
114583
|
+
})),
|
|
114584
|
+
...delta.typeChanged.map((entry) => ({
|
|
114585
|
+
o: "t",
|
|
114586
|
+
p: entry.path,
|
|
114587
|
+
e: entry.type === "directory" ? "d" : "f"
|
|
114588
|
+
}))
|
|
114589
|
+
];
|
|
114590
|
+
}
|
|
114591
|
+
function createWorkspaceFileTreeDeltaSend(session2, normalizedWorkingDir) {
|
|
114592
|
+
return async (unit) => {
|
|
114593
|
+
const result = await session2.backend.mutation(api.workspaceFiles.applyFileTreeDeltaBatch, {
|
|
114594
|
+
sessionId: session2.sessionId,
|
|
114595
|
+
machineId: session2.machineId,
|
|
114596
|
+
workingDir: normalizedWorkingDir,
|
|
114597
|
+
operationId: unit.delta.operationId,
|
|
114598
|
+
baseRevision: unit.baseRevision,
|
|
114599
|
+
operations: toDeltaOperations(unit.delta)
|
|
114600
|
+
});
|
|
114601
|
+
if (result.status === "resync-required") {
|
|
114602
|
+
return { status: "conflict", revision: result.expectedRevision };
|
|
114603
|
+
}
|
|
114604
|
+
return result;
|
|
114605
|
+
};
|
|
114606
|
+
}
|
|
114607
|
+
var init_workspace_file_tree_delta_send = __esm(() => {
|
|
114608
|
+
init_api3();
|
|
114609
|
+
});
|
|
114610
|
+
|
|
114611
|
+
// src/daemon/entry/files/file-tree-subscription.ts
|
|
114488
114612
|
function logSubscriptionWarn(label, err) {
|
|
114489
114613
|
console.warn(`[${formatTimestamp()}] ⚠️ ${label}: ${getErrorMessage(err)}`);
|
|
114490
114614
|
}
|
|
@@ -114552,79 +114676,20 @@ async function drainPendingFileTreeRequests(session2, coordinators, ensureCoordi
|
|
|
114552
114676
|
});
|
|
114553
114677
|
await processPendingFileTreeRequests(session2, coordinators, ensureCoordinator, requests);
|
|
114554
114678
|
}
|
|
114555
|
-
async function syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration) {
|
|
114556
|
-
if (selectFileTreeSnapshotStrategyId(tree) === "sharded") {
|
|
114557
|
-
const ref2 = await publishShardedSnapshot(session2, normalizedWorkingDir, tree, syncGeneration);
|
|
114558
|
-
return { strategyId: ref2.strategyId, snapshotId: ref2.snapshotId };
|
|
114559
|
-
}
|
|
114560
|
-
const ref = await publishBlobSnapshot(session2, normalizedWorkingDir, buildBlobSnapshotPayload(tree, dataHash));
|
|
114561
|
-
return { strategyId: ref.strategyId, snapshotId: ref.snapshotId };
|
|
114562
|
-
}
|
|
114563
|
-
function toDeltaOperations(delta) {
|
|
114564
|
-
return [
|
|
114565
|
-
...delta.added.map((entry) => ({
|
|
114566
|
-
o: "a",
|
|
114567
|
-
p: entry.path,
|
|
114568
|
-
e: entry.type === "directory" ? "d" : "f"
|
|
114569
|
-
})),
|
|
114570
|
-
...delta.removed.map((entryPath) => ({
|
|
114571
|
-
o: "r",
|
|
114572
|
-
p: entryPath
|
|
114573
|
-
})),
|
|
114574
|
-
...delta.typeChanged.map((entry) => ({
|
|
114575
|
-
o: "t",
|
|
114576
|
-
p: entry.path,
|
|
114577
|
-
e: entry.type === "directory" ? "d" : "f"
|
|
114578
|
-
}))
|
|
114579
|
-
];
|
|
114580
|
-
}
|
|
114581
|
-
async function publishCheckpoint(session2, normalizedWorkingDir, tree, revision) {
|
|
114582
|
-
const dataHash = computeFileTreeDataHash(tree);
|
|
114583
|
-
const syncGeneration = randomUUID11();
|
|
114584
|
-
const snapshot = await syncScannedFileTree(session2, normalizedWorkingDir, tree, dataHash, syncGeneration);
|
|
114585
|
-
let checkpointRevision = revision;
|
|
114586
|
-
let result = await session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
|
|
114587
|
-
sessionId: session2.sessionId,
|
|
114588
|
-
machineId: session2.machineId,
|
|
114589
|
-
workingDir: normalizedWorkingDir,
|
|
114590
|
-
revision: checkpointRevision,
|
|
114591
|
-
...snapshot
|
|
114592
|
-
});
|
|
114593
|
-
if (result.status === "resync-required") {
|
|
114594
|
-
checkpointRevision = result.expectedRevision + 1;
|
|
114595
|
-
result = await session2.backend.mutation(api.workspaceFiles.publishFileTreeCheckpoint, {
|
|
114596
|
-
sessionId: session2.sessionId,
|
|
114597
|
-
machineId: session2.machineId,
|
|
114598
|
-
workingDir: normalizedWorkingDir,
|
|
114599
|
-
revision: checkpointRevision,
|
|
114600
|
-
...snapshot
|
|
114601
|
-
});
|
|
114602
|
-
}
|
|
114603
|
-
if (result.status === "snapshot-missing") {
|
|
114604
|
-
throw new Error(`File tree checkpoint rejected: ${result.status}`);
|
|
114605
|
-
}
|
|
114606
|
-
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree checkpoint: ${normalizedWorkingDir} (${tree.entries.length} entries, revision ${checkpointRevision})`);
|
|
114607
|
-
return { revision: checkpointRevision };
|
|
114608
|
-
}
|
|
114609
114679
|
var startFileTreeSubscriptionEffect = () => exports_Effect.gen(function* () {
|
|
114610
114680
|
const session2 = yield* DaemonSessionService;
|
|
114611
114681
|
const coordinators = new Map;
|
|
114612
|
-
const checkpointOutboxRegistry = createWorkspaceFileTreeCheckpointOutboxRegistry(session2.machineId, (normalized) =>
|
|
114682
|
+
const checkpointOutboxRegistry = createWorkspaceFileTreeCheckpointOutboxRegistry(session2.machineId, (normalized) => {
|
|
114683
|
+
const send = createWorkspaceFileTreeCheckpointSend(session2, normalized);
|
|
114684
|
+
return async (state) => {
|
|
114685
|
+
const result = await send(state);
|
|
114686
|
+
console.log(`[${formatTimestamp()}] \uD83C\uDF33 File tree checkpoint: ${normalized} (${state.tree.entries.length} entries, revision ${result.revision})`);
|
|
114687
|
+
return result;
|
|
114688
|
+
};
|
|
114689
|
+
}, {
|
|
114613
114690
|
onError: (normalized, error51) => logSubscriptionWarn(`File tree checkpoint outbox failed for ${normalized}`, error51)
|
|
114614
114691
|
});
|
|
114615
|
-
const deltaOutboxRegistry = createWorkspaceFileTreeDeltaOutboxRegistry(session2.machineId, (normalized) =>
|
|
114616
|
-
const result = await session2.backend.mutation(api.workspaceFiles.applyFileTreeDeltaBatch, {
|
|
114617
|
-
sessionId: session2.sessionId,
|
|
114618
|
-
machineId: session2.machineId,
|
|
114619
|
-
workingDir: normalized,
|
|
114620
|
-
operationId: unit.delta.operationId,
|
|
114621
|
-
baseRevision: unit.baseRevision,
|
|
114622
|
-
operations: toDeltaOperations(unit.delta)
|
|
114623
|
-
});
|
|
114624
|
-
if (result.status === "resync-required")
|
|
114625
|
-
return { status: "conflict", revision: result.expectedRevision };
|
|
114626
|
-
return result;
|
|
114627
|
-
});
|
|
114692
|
+
const deltaOutboxRegistry = createWorkspaceFileTreeDeltaOutboxRegistry(session2.machineId, (normalized) => createWorkspaceFileTreeDeltaSend(session2, normalized));
|
|
114628
114693
|
const ensureCoordinator = (workingDir, forceReconcile) => {
|
|
114629
114694
|
const normalized = normalizeWorkingDirForLookup(workingDir);
|
|
114630
114695
|
let coordinatorPromise = coordinators.get(normalized);
|
|
@@ -114672,16 +114737,14 @@ var startFileTreeSubscriptionEffect = () => exports_Effect.gen(function* () {
|
|
|
114672
114737
|
};
|
|
114673
114738
|
});
|
|
114674
114739
|
var init_file_tree_subscription = __esm(() => {
|
|
114675
|
-
init_workspace_file_tree();
|
|
114676
114740
|
init_esm();
|
|
114677
114741
|
init_api3();
|
|
114678
|
-
init_file_tree_data_hash();
|
|
114679
|
-
init_blob_snapshot_publish();
|
|
114680
|
-
init_sharded_snapshot_publish();
|
|
114681
114742
|
init_workspace_file_tree_coordinator();
|
|
114682
114743
|
init_workspace_sync_queue();
|
|
114683
114744
|
init_convex_error();
|
|
114684
114745
|
init_outbox();
|
|
114746
|
+
init_workspace_file_tree_checkpoint_send();
|
|
114747
|
+
init_workspace_file_tree_delta_send();
|
|
114685
114748
|
init_daemon_services();
|
|
114686
114749
|
});
|
|
114687
114750
|
|
|
@@ -116683,7 +116746,7 @@ Listening for commands...`);
|
|
|
116683
116746
|
registerCommandInboundHandler(async (event) => {
|
|
116684
116747
|
evictStaleDedupEntries(dedupTracker);
|
|
116685
116748
|
if (event.type === "command.received") {
|
|
116686
|
-
await handleInboundCommandEvent(event.commandId, dedupTracker, effectContext2, session2);
|
|
116749
|
+
await handleInboundCommandEvent(event.commandId, dedupTracker, effectContext2, session2, event.commandEvent);
|
|
116687
116750
|
} else {
|
|
116688
116751
|
await drainActionableCommandRuns(session2, commandRunRuntime);
|
|
116689
116752
|
}
|
|
@@ -117840,7 +117903,11 @@ function startCommandEventsSubscriber(deps, onEvent) {
|
|
|
117840
117903
|
if (seen.has(event._id))
|
|
117841
117904
|
continue;
|
|
117842
117905
|
seen.add(event._id);
|
|
117843
|
-
onEvent({
|
|
117906
|
+
onEvent({
|
|
117907
|
+
type: "command.received",
|
|
117908
|
+
commandId: event._id,
|
|
117909
|
+
commandEvent: event
|
|
117910
|
+
});
|
|
117844
117911
|
}
|
|
117845
117912
|
}, (err) => {
|
|
117846
117913
|
console.warn(`[daemon] command-events subscriber error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -134066,4 +134133,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
134066
134133
|
});
|
|
134067
134134
|
program2.parse();
|
|
134068
134135
|
|
|
134069
|
-
//# debugId=
|
|
134136
|
+
//# debugId=D41963016C23E20F64756E2164756E21
|