lody 0.71.1 → 0.71.3
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.
|
@@ -3,7 +3,7 @@ import { readFile, mkdir, writeFile, rename } from "node:fs/promises";
|
|
|
3
3
|
import os__default from "node:os";
|
|
4
4
|
import path__default from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
-
const reviewViewerVersion = "0.71.
|
|
6
|
+
const reviewViewerVersion = "0.71.3";
|
|
7
7
|
const reviewViewerSha256 = "e395b367a7644fe83bc050d0c646810914a2844824fd2b5d11d24ae4f55b6893";
|
|
8
8
|
const reviewViewerFileName = "standalone.html";
|
|
9
9
|
const DEFAULT_CDN_BASES = ["https://cdn.jsdelivr.net/npm", "https://unpkg.com"];
|
package/dist/index.js
CHANGED
|
@@ -4190,7 +4190,7 @@ let __tla = Promise.all([
|
|
|
4190
4190
|
}
|
|
4191
4191
|
}
|
|
4192
4192
|
const name$1 = "lody";
|
|
4193
|
-
const version$7 = "0.71.
|
|
4193
|
+
const version$7 = "0.71.3";
|
|
4194
4194
|
const description$1 = "Lody Agent CLI tool for managing remote command execution";
|
|
4195
4195
|
const type$2 = "module";
|
|
4196
4196
|
const main$4 = "dist/index.js";
|
|
@@ -4204,7 +4204,7 @@ let __tla = Promise.all([
|
|
|
4204
4204
|
"build": "pnpm run clean && pnpm run prepare:acp-adapters && pnpm run typecheck && pnpm run build:bundle && pnpm run check:published-bundle-imports && pnpm run copy:wasm",
|
|
4205
4205
|
"build:watch": "pnpm run prepare:review-assets && vite build --watch",
|
|
4206
4206
|
"build:bundle": "pnpm run prepare:review-assets && vite build",
|
|
4207
|
-
"prepare:acp-adapters": "pnpm --dir ../.. --filter acp-extension-claude build && pnpm --dir ../.. --filter acp-extension-codex build",
|
|
4207
|
+
"prepare:acp-adapters": "corepack pnpm --dir ../.. --filter acp-extension-claude build && corepack pnpm --dir ../.. --filter acp-extension-codex build",
|
|
4208
4208
|
"prepare:review-assets": "pnpm --dir ../.. --filter lody-code-review-viewer build",
|
|
4209
4209
|
"check:published-bundle-imports": "node scripts/check-published-bundle-imports.js",
|
|
4210
4210
|
"copy:wasm": "node scripts/copy-loro-wasm.js",
|
|
@@ -4516,7 +4516,7 @@ let __tla = Promise.all([
|
|
|
4516
4516
|
displayName: "Codex"
|
|
4517
4517
|
}
|
|
4518
4518
|
];
|
|
4519
|
-
const usesAcpProvidedSessionTitle = (cliType, agentType) => cliType === "builtin" &&
|
|
4519
|
+
const usesAcpProvidedSessionTitle = (cliType, agentType) => cliType === "builtin" && agentType === "claude";
|
|
4520
4520
|
const isBuiltinRuntimeOverrides = (value) => {
|
|
4521
4521
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
4522
4522
|
return false;
|
|
@@ -136226,6 +136226,32 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136226
136226
|
};
|
|
136227
136227
|
}
|
|
136228
136228
|
}
|
|
136229
|
+
const isOperationStoreBusyError = (error2) => {
|
|
136230
|
+
if (!(error2 instanceof Error)) return false;
|
|
136231
|
+
const code2 = error2.code;
|
|
136232
|
+
return code2 === "SQLITE_BUSY" || code2 === "SQLITE_BUSY_SNAPSHOT";
|
|
136233
|
+
};
|
|
136234
|
+
const BUSY_RETRY_DELAYS_MS = [
|
|
136235
|
+
100,
|
|
136236
|
+
300,
|
|
136237
|
+
900
|
|
136238
|
+
];
|
|
136239
|
+
const runWithOperationStoreBusyRetry = async (run2, options = {}) => {
|
|
136240
|
+
const delays = options.delaysMs ?? BUSY_RETRY_DELAYS_MS;
|
|
136241
|
+
const sleep2 = options.sleep ?? ((ms2) => new Promise((resolve2) => setTimeout(resolve2, ms2)));
|
|
136242
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
136243
|
+
try {
|
|
136244
|
+
return run2();
|
|
136245
|
+
} catch (error2) {
|
|
136246
|
+
if (!isOperationStoreBusyError(error2)) throw error2;
|
|
136247
|
+
const delayMs = delays[attempt];
|
|
136248
|
+
if (delayMs === void 0) {
|
|
136249
|
+
throw new LodyOperationStoreError("STORE_BUSY", "The local Operation store is busy; retry the command.", true);
|
|
136250
|
+
}
|
|
136251
|
+
await sleep2(delayMs);
|
|
136252
|
+
}
|
|
136253
|
+
}
|
|
136254
|
+
};
|
|
136229
136255
|
const parseJson = (text, schema2, label2) => {
|
|
136230
136256
|
let parsed;
|
|
136231
136257
|
try {
|
|
@@ -136361,7 +136387,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136361
136387
|
const getOperationDeliveryId = (requesterSessionId, operationId) => `operation:${requesterSessionId}:${operationId}:completion`;
|
|
136362
136388
|
const getOperationCompletionTurnId = (requesterSessionId, operationId) => `operation-completion:${requesterSessionId}:${operationId}`;
|
|
136363
136389
|
class LodyOperationStore {
|
|
136364
|
-
constructor(dbPath = getLodyOperationStorePath(), now2 = Date.now) {
|
|
136390
|
+
constructor(dbPath = getLodyOperationStorePath(), now2 = Date.now, options = {}) {
|
|
136365
136391
|
this.now = now2;
|
|
136366
136392
|
mkdirSync$2(path__default$1.dirname(dbPath), {
|
|
136367
136393
|
recursive: true
|
|
@@ -136371,8 +136397,10 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136371
136397
|
this.db.pragma("journal_mode = WAL");
|
|
136372
136398
|
this.db.pragma("foreign_keys = ON");
|
|
136373
136399
|
this.migrate();
|
|
136374
|
-
|
|
136375
|
-
|
|
136400
|
+
if (options.maintenance !== false) {
|
|
136401
|
+
this.repairTerminalDeliveries();
|
|
136402
|
+
this.cleanupExpired(false);
|
|
136403
|
+
}
|
|
136376
136404
|
}
|
|
136377
136405
|
db;
|
|
136378
136406
|
close() {
|
|
@@ -136414,7 +136442,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136414
136442
|
claimedItemIndexes
|
|
136415
136443
|
};
|
|
136416
136444
|
});
|
|
136417
|
-
const accepted = transaction();
|
|
136445
|
+
const accepted = transaction.immediate();
|
|
136418
136446
|
this.cleanupExpired(false);
|
|
136419
136447
|
return accepted;
|
|
136420
136448
|
}
|
|
@@ -136471,7 +136499,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136471
136499
|
return {
|
|
136472
136500
|
claimed: true
|
|
136473
136501
|
};
|
|
136474
|
-
})();
|
|
136502
|
+
}).immediate();
|
|
136475
136503
|
}
|
|
136476
136504
|
markItemInputDurable(requesterSessionId, operationId, itemIndex, claimToken) {
|
|
136477
136505
|
return this.db.transaction(() => {
|
|
@@ -136492,7 +136520,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136492
136520
|
this.db.prepare(`DELETE FROM operation_item_materializations
|
|
136493
136521
|
WHERE requester_session_id = ? AND operation_id = ? AND item_index = ?`).run(requesterSessionId, operationId, itemIndex);
|
|
136494
136522
|
return this.get(requesterSessionId, operationId);
|
|
136495
|
-
})();
|
|
136523
|
+
}).immediate();
|
|
136496
136524
|
}
|
|
136497
136525
|
finish(requesterSessionId, operationId, completion, finishedAt = new Date(this.now()).toISOString()) {
|
|
136498
136526
|
const bounded = this.assertCompletionBound(completion);
|
|
@@ -136518,7 +136546,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136518
136546
|
}
|
|
136519
136547
|
return updated;
|
|
136520
136548
|
});
|
|
136521
|
-
return transaction();
|
|
136549
|
+
return transaction.immediate();
|
|
136522
136550
|
}
|
|
136523
136551
|
cancel(requesterSessionId, operationId) {
|
|
136524
136552
|
const transaction = this.db.transaction(() => {
|
|
@@ -136542,7 +136570,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136542
136570
|
didCancel: true
|
|
136543
136571
|
};
|
|
136544
136572
|
});
|
|
136545
|
-
return transaction();
|
|
136573
|
+
return transaction.immediate();
|
|
136546
136574
|
}
|
|
136547
136575
|
listPendingDeliveries(workspaceId, requesterSessionId) {
|
|
136548
136576
|
const rows = requesterSessionId ? this.db.prepare(`SELECT * FROM deliveries
|
|
@@ -136690,7 +136718,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136690
136718
|
)`).run(cutoff);
|
|
136691
136719
|
this.db.prepare(`INSERT INTO orchestration_meta (key, value) VALUES ('last_cleanup_at_ms', ?)
|
|
136692
136720
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(nowMs2));
|
|
136693
|
-
})();
|
|
136721
|
+
}).immediate();
|
|
136694
136722
|
}
|
|
136695
136723
|
migrate() {
|
|
136696
136724
|
this.db.exec(`
|
|
@@ -136774,7 +136802,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136774
136802
|
WHERE deliveries.requester_session_id = operations.requester_session_id
|
|
136775
136803
|
AND deliveries.operation_id = operations.operation_id
|
|
136776
136804
|
)`).run();
|
|
136777
|
-
})();
|
|
136805
|
+
}).immediate();
|
|
136778
136806
|
}
|
|
136779
136807
|
}
|
|
136780
136808
|
const terminalAssistantFor = (history, userTurnId) => history.find((entry) => entry.role === "assistant" && entry.userTurnId === userTurnId && (entry.finished === true || typeof entry.endedAt === "number"));
|
|
@@ -136800,6 +136828,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136800
136828
|
deliveryChains = /* @__PURE__ */ new Map();
|
|
136801
136829
|
operationAbortControllers = /* @__PURE__ */ new Map();
|
|
136802
136830
|
metaWatch = null;
|
|
136831
|
+
store = null;
|
|
136803
136832
|
storeWatch = null;
|
|
136804
136833
|
storeWakeTimer = null;
|
|
136805
136834
|
started = false;
|
|
@@ -136815,15 +136844,15 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136815
136844
|
"doc-metadata"
|
|
136816
136845
|
]
|
|
136817
136846
|
});
|
|
136818
|
-
this.
|
|
136847
|
+
this.store = this.storeFactory();
|
|
136819
136848
|
const storePath = this.options.storePath ?? getLodyOperationStorePath(this.options.machineId);
|
|
136820
136849
|
const storeBasename = path__default$1.basename(storePath);
|
|
136821
136850
|
this.storeWatch = watch(path__default$1.dirname(storePath), (_event, filename) => {
|
|
136822
136851
|
if (!filename || !filename.toString().startsWith(storeBasename)) return;
|
|
136823
|
-
this.
|
|
136824
|
-
if (this.storeWakeTimer) clearTimeout(this.storeWakeTimer);
|
|
136852
|
+
if (this.storeWakeTimer) return;
|
|
136825
136853
|
this.storeWakeTimer = setTimeout(() => {
|
|
136826
136854
|
this.storeWakeTimer = null;
|
|
136855
|
+
this.abortTerminalCoordinators();
|
|
136827
136856
|
this.wake("operation-store");
|
|
136828
136857
|
}, 10);
|
|
136829
136858
|
this.storeWakeTimer.unref?.();
|
|
@@ -136838,6 +136867,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136838
136867
|
this.storeWatch = null;
|
|
136839
136868
|
if (this.storeWakeTimer) clearTimeout(this.storeWakeTimer);
|
|
136840
136869
|
this.storeWakeTimer = null;
|
|
136870
|
+
this.store?.close();
|
|
136871
|
+
this.store = null;
|
|
136841
136872
|
for (const subscription of this.targetSubscriptions.values()) {
|
|
136842
136873
|
subscription.unsubscribe();
|
|
136843
136874
|
}
|
|
@@ -136877,6 +136908,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
136877
136908
|
]);
|
|
136878
136909
|
}
|
|
136879
136910
|
withStore(fn) {
|
|
136911
|
+
if (this.store) return fn(this.store);
|
|
136880
136912
|
const store = this.storeFactory();
|
|
136881
136913
|
try {
|
|
136882
136914
|
return fn(store);
|
|
@@ -140996,12 +141028,6 @@ ${entry.text}`).join("\n\n");
|
|
|
140996
141028
|
} : {}
|
|
140997
141029
|
};
|
|
140998
141030
|
}
|
|
140999
|
-
async function ensureSessionDocSynced(sessionDoc, reason) {
|
|
141000
|
-
const synced = await sessionDoc.waitUntilSynced();
|
|
141001
|
-
if (!synced) {
|
|
141002
|
-
throw new Error(`Session document changes were not confirmed by Loro Streams (${reason}). Retry the command after checking network connectivity.`);
|
|
141003
|
-
}
|
|
141004
|
-
}
|
|
141005
141031
|
function buildCliHistoryInputConfig(args2) {
|
|
141006
141032
|
return {
|
|
141007
141033
|
prompt: args2.prompt,
|
|
@@ -141416,13 +141442,24 @@ ${entry.text}`).join("\n\n");
|
|
|
141416
141442
|
} catch {
|
|
141417
141443
|
}
|
|
141418
141444
|
}
|
|
141419
|
-
async function
|
|
141445
|
+
async function writeDispatchPointer(args2) {
|
|
141420
141446
|
await args2.manager.repo.upsertDocMeta(getSessionRoomId(args2.sessionId), {
|
|
141421
141447
|
latestUserMsgId: args2.userTurnId,
|
|
141422
141448
|
lastMissingHistoryUserMsgId: void 0
|
|
141423
141449
|
});
|
|
141424
|
-
|
|
141425
|
-
|
|
141450
|
+
}
|
|
141451
|
+
async function confirmDispatchSyncedBestEffort(args2) {
|
|
141452
|
+
const logger2 = args2.logger ?? getLogger("session");
|
|
141453
|
+
try {
|
|
141454
|
+
const synced = await args2.sessionDoc.waitUntilSynced();
|
|
141455
|
+
if (!synced) {
|
|
141456
|
+
logger2.warn(`Session dispatch not yet confirmed by Loro Streams (${args2.reason}:doc); the durable dispatch pointer will converge on reconnect.`);
|
|
141457
|
+
return;
|
|
141458
|
+
}
|
|
141459
|
+
await ensureWorkspaceMetaSynced(args2.manager, `${args2.reason}:meta`);
|
|
141460
|
+
} catch (error2) {
|
|
141461
|
+
logger2.warn(`Session dispatch confirmation did not complete (${args2.reason}); the durable dispatch pointer will converge on reconnect: ${formatErrorMessage(error2)}`);
|
|
141462
|
+
}
|
|
141426
141463
|
}
|
|
141427
141464
|
async function listMachineMetasForWorkspace(manager) {
|
|
141428
141465
|
return (await listAliveDocMetas(manager, isMachineDocRoomId)).map((entry) => entry.meta);
|
|
@@ -141950,6 +141987,7 @@ ${entry.text}`).join("\n\n");
|
|
|
141950
141987
|
});
|
|
141951
141988
|
let completionAbortController;
|
|
141952
141989
|
let completionPromise;
|
|
141990
|
+
let dispatched = false;
|
|
141953
141991
|
try {
|
|
141954
141992
|
const modeId = effectiveDispatchConfig.modeId;
|
|
141955
141993
|
const modelId = effectiveDispatchConfig.modelId;
|
|
@@ -141977,11 +142015,15 @@ ${entry.text}`).join("\n\n");
|
|
|
141977
142015
|
await manager.repo.upsertDocMeta(sessionRoomId, {
|
|
141978
142016
|
status: SessionStatusFactory.idle()
|
|
141979
142017
|
});
|
|
141980
|
-
await
|
|
142018
|
+
await writeDispatchPointer({
|
|
141981
142019
|
manager,
|
|
141982
|
-
sessionDoc,
|
|
141983
142020
|
sessionId,
|
|
141984
|
-
userTurnId
|
|
142021
|
+
userTurnId
|
|
142022
|
+
});
|
|
142023
|
+
dispatched = true;
|
|
142024
|
+
await confirmDispatchSyncedBestEffort({
|
|
142025
|
+
manager,
|
|
142026
|
+
sessionDoc,
|
|
141985
142027
|
reason: `session.create:${sessionId}`
|
|
141986
142028
|
});
|
|
141987
142029
|
await dispatchTurnFastPath({
|
|
@@ -142014,7 +142056,9 @@ ${entry.text}`).join("\n\n");
|
|
|
142014
142056
|
} catch (error2) {
|
|
142015
142057
|
completionAbortController?.abort();
|
|
142016
142058
|
await completionPromise?.catch(() => void 0);
|
|
142017
|
-
|
|
142059
|
+
if (!dispatched) {
|
|
142060
|
+
await rollbackPendingSessionCreate(manager, sessionId);
|
|
142061
|
+
}
|
|
142018
142062
|
throw error2;
|
|
142019
142063
|
}
|
|
142020
142064
|
}
|
|
@@ -142081,13 +142125,18 @@ ${entry.text}`).join("\n\n");
|
|
|
142081
142125
|
signal: completionAbortController?.signal,
|
|
142082
142126
|
onEvent: structuredOutput.onEvent
|
|
142083
142127
|
}) : void 0;
|
|
142128
|
+
let dispatched = false;
|
|
142084
142129
|
try {
|
|
142085
142130
|
await updateSessionActivityTimestampsBestEffort(manager, sessionId);
|
|
142086
|
-
await
|
|
142131
|
+
await writeDispatchPointer({
|
|
142087
142132
|
manager,
|
|
142088
|
-
sessionDoc,
|
|
142089
142133
|
sessionId,
|
|
142090
|
-
userTurnId
|
|
142134
|
+
userTurnId
|
|
142135
|
+
});
|
|
142136
|
+
dispatched = true;
|
|
142137
|
+
await confirmDispatchSyncedBestEffort({
|
|
142138
|
+
manager,
|
|
142139
|
+
sessionDoc,
|
|
142091
142140
|
reason: `session.chat:${sessionId}:${userTurnId}`
|
|
142092
142141
|
});
|
|
142093
142142
|
await dispatchTurnFastPath({
|
|
@@ -142110,11 +142159,13 @@ ${entry.text}`).join("\n\n");
|
|
|
142110
142159
|
} catch (error2) {
|
|
142111
142160
|
completionAbortController?.abort();
|
|
142112
142161
|
await completionPromise?.catch(() => void 0);
|
|
142113
|
-
|
|
142114
|
-
|
|
142115
|
-
|
|
142116
|
-
|
|
142117
|
-
|
|
142162
|
+
if (!dispatched) {
|
|
142163
|
+
await removeHistoryEntryById(sessionDoc, userTurnId);
|
|
142164
|
+
await manager.repo.upsertDocMeta(getSessionRoomId(sessionId), {
|
|
142165
|
+
latestUserMsgId: void 0,
|
|
142166
|
+
lastMissingHistoryUserMsgId: void 0
|
|
142167
|
+
}).catch(() => void 0);
|
|
142168
|
+
}
|
|
142118
142169
|
throw error2;
|
|
142119
142170
|
}
|
|
142120
142171
|
}
|
|
@@ -143470,7 +143521,7 @@ ${entry.text}`).join("\n\n");
|
|
|
143470
143521
|
this.deps.logger.debug(`[${sessionId}] auto-commit-push: turn cancelled during ${stage}; skipping remaining work`);
|
|
143471
143522
|
return true;
|
|
143472
143523
|
};
|
|
143473
|
-
if (!resolveProjectGitHubRepo(project)) {
|
|
143524
|
+
if (!resolveProjectGitHubRepo(project) || project?.kind === "local" && project.useWorktree !== true) {
|
|
143474
143525
|
return;
|
|
143475
143526
|
}
|
|
143476
143527
|
const workspace = await this.resolveWorkspaceSessionContext(sessionId, sessionDoc);
|
|
@@ -144447,11 +144498,11 @@ ${entry.text}`).join("\n\n");
|
|
|
144447
144498
|
});
|
|
144448
144499
|
}
|
|
144449
144500
|
const workspaceRoot = path__default$1.resolve(resolvedWorkspace.workspaceRoot);
|
|
144450
|
-
const workspacePath = normalizeWorkspacePath(requestedPath, options);
|
|
144501
|
+
const workspacePath = normalizeWorkspacePath(resolveWorkspaceRelativeRequestPath(workspaceRoot, requestedPath), options);
|
|
144451
144502
|
const requestedAbsolutePath = path__default$1.resolve(workspaceRoot, workspacePath);
|
|
144452
144503
|
const absolutePath = await resolveExistingPathWithoutConflicts(workspaceRoot, workspacePath, requestedPath) ?? requestedAbsolutePath;
|
|
144453
144504
|
const relative2 = path__default$1.relative(workspaceRoot, absolutePath);
|
|
144454
|
-
if (
|
|
144505
|
+
if (isPathOutsideRoot(relative2)) {
|
|
144455
144506
|
throw new CodeCollabV2ServiceError("invalid_path", "Path escapes workspace root.", {
|
|
144456
144507
|
path: requestedPath
|
|
144457
144508
|
});
|
|
@@ -145136,6 +145187,21 @@ ${entry.text}`).join("\n\n");
|
|
|
145136
145187
|
}
|
|
145137
145188
|
return normalized;
|
|
145138
145189
|
}
|
|
145190
|
+
function resolveWorkspaceRelativeRequestPath(workspaceRoot, input2) {
|
|
145191
|
+
if (!path__default$1.isAbsolute(input2)) {
|
|
145192
|
+
return input2;
|
|
145193
|
+
}
|
|
145194
|
+
const relative2 = path__default$1.relative(workspaceRoot, path__default$1.resolve(input2));
|
|
145195
|
+
if (isPathOutsideRoot(relative2)) {
|
|
145196
|
+
throw new CodeCollabV2ServiceError("invalid_path", "Path escapes workspace root.", {
|
|
145197
|
+
path: input2
|
|
145198
|
+
});
|
|
145199
|
+
}
|
|
145200
|
+
return relative2.split(path__default$1.sep).join("/");
|
|
145201
|
+
}
|
|
145202
|
+
function isPathOutsideRoot(relativePath) {
|
|
145203
|
+
return relativePath === ".." || relativePath.startsWith(`..${path__default$1.sep}`) || path__default$1.isAbsolute(relativePath);
|
|
145204
|
+
}
|
|
145139
145205
|
async function stableReadFile(resolved, maxBytes) {
|
|
145140
145206
|
let lastTransientError;
|
|
145141
145207
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
@@ -145252,7 +145318,7 @@ ${entry.text}`).join("\n\n");
|
|
|
145252
145318
|
throw mapNodeReadError(error2, resolved.workspacePath);
|
|
145253
145319
|
});
|
|
145254
145320
|
const relative2 = path__default$1.relative(rootRealpath, fileRealpath);
|
|
145255
|
-
if (
|
|
145321
|
+
if (isPathOutsideRoot(relative2)) {
|
|
145256
145322
|
throw new CodeCollabV2ServiceError("invalid_path", "Resolved path escapes workspace root.", {
|
|
145257
145323
|
path: resolved.workspacePath
|
|
145258
145324
|
});
|
|
@@ -155586,7 +155652,9 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
155586
155652
|
this.logger.debug(`[${sessionId}] Failed to delete session doc (may already be deleted): ${formatErrorMessage(error2)}`);
|
|
155587
155653
|
}
|
|
155588
155654
|
try {
|
|
155589
|
-
const operationStore = new LodyOperationStore(getLodyOperationStorePath(this.machineId)
|
|
155655
|
+
const operationStore = new LodyOperationStore(getLodyOperationStorePath(this.machineId), void 0, {
|
|
155656
|
+
maintenance: false
|
|
155657
|
+
});
|
|
155590
155658
|
try {
|
|
155591
155659
|
operationStore.deleteRequesterSession(sessionId);
|
|
155592
155660
|
} finally {
|
|
@@ -203328,7 +203396,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
203328
203396
|
data = createReviewBundleSnapshot(bundle);
|
|
203329
203397
|
}
|
|
203330
203398
|
const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
|
|
203331
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-
|
|
203399
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-S-XYMgL_.js");
|
|
203332
203400
|
const template = await resolveReviewViewerTemplate();
|
|
203333
203401
|
const html = injectReviewSnapshot(template, data);
|
|
203334
203402
|
const outputPath = options.output ? path__default$1.resolve(options.output) : defaultHtmlOutputPath(inputPath);
|
|
@@ -221226,14 +221294,14 @@ ${result.stderr}`;
|
|
|
221226
221294
|
localControlSocketPath: readOptionalEnv("LODY_MCP_SOCKET_PATH", "LODY_PREVIEW_MCP_SOCKET_PATH"),
|
|
221227
221295
|
workdir: readOptionalEnv("LODY_MCP_WORKDIR", "LODY_PREVIEW_MCP_WORKDIR") ?? process.cwd()
|
|
221228
221296
|
});
|
|
221229
|
-
|
|
221230
|
-
|
|
221231
|
-
|
|
221232
|
-
|
|
221233
|
-
}
|
|
221234
|
-
|
|
221235
|
-
}
|
|
221297
|
+
let sharedOperationStore;
|
|
221298
|
+
const getSharedOperationStore = () => {
|
|
221299
|
+
sharedOperationStore ??= new LodyOperationStore(void 0, void 0, {
|
|
221300
|
+
maintenance: false
|
|
221301
|
+
});
|
|
221302
|
+
return sharedOperationStore;
|
|
221236
221303
|
};
|
|
221304
|
+
const withOperationStore = (fn) => runWithOperationStoreBusyRetry(() => fn(getSharedOperationStore()));
|
|
221237
221305
|
const assertBatchSize = (length2, maximum) => {
|
|
221238
221306
|
if (length2 < 1 || length2 > maximum) {
|
|
221239
221307
|
throw new LodyOperationStoreError("BATCH_TOO_LARGE", `Batch item count must be between 1 and ${maximum}; received ${length2}.`, false);
|
|
@@ -222070,8 +222138,8 @@ ${result.stderr}`;
|
|
|
222070
222138
|
deadlineSeconds: args2.deadlineSeconds
|
|
222071
222139
|
} : {}
|
|
222072
222140
|
};
|
|
222073
|
-
const retry2 = withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_create", canonicalCommand));
|
|
222074
|
-
if (retry2) return withOperationStore((store) => store.snapshot(retry2));
|
|
222141
|
+
const retry2 = await withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_create", canonicalCommand));
|
|
222142
|
+
if (retry2) return await withOperationStore((store) => store.snapshot(retry2));
|
|
222075
222143
|
const targetMachineId = args2.machineId ?? currentSession.machineId;
|
|
222076
222144
|
await assertMachineOnlineForSingleCommand(manager, targetMachineId, ctx);
|
|
222077
222145
|
const createOptions = buildMcpCreateOptions(args2, ctx);
|
|
@@ -222092,7 +222160,7 @@ ${result.stderr}`;
|
|
|
222092
222160
|
const preallocatedUserTurnId = randomUUID();
|
|
222093
222161
|
const materializationClaimToken = randomUUID();
|
|
222094
222162
|
const timing = operationDeadline(args2.deadlineSeconds);
|
|
222095
|
-
const accepted = withOperationStore((store) => store.accept({
|
|
222163
|
+
const accepted = await withOperationStore((store) => store.accept({
|
|
222096
222164
|
workspaceId: workspace.id,
|
|
222097
222165
|
ownerMachineId: ctx.machineId,
|
|
222098
222166
|
requesterSessionId: ctx.sessionId,
|
|
@@ -222115,7 +222183,7 @@ ${result.stderr}`;
|
|
|
222115
222183
|
materializationClaimToken
|
|
222116
222184
|
}));
|
|
222117
222185
|
if (accepted.operation.state === "finished") {
|
|
222118
|
-
return withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222186
|
+
return await withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222119
222187
|
}
|
|
222120
222188
|
const pendingItem = accepted.operation.items[0];
|
|
222121
222189
|
if (!pendingItem || pendingItem.status !== "active") {
|
|
@@ -222129,7 +222197,7 @@ ${result.stderr}`;
|
|
|
222129
222197
|
if (result.sessionId !== pendingItem.target.sessionId || result.userTurnId !== pendingItem.target.userTurnId) {
|
|
222130
222198
|
throw new Error("Create result did not preserve preallocated target ids.");
|
|
222131
222199
|
}
|
|
222132
|
-
withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, 0, materializationClaimToken));
|
|
222200
|
+
await withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, 0, materializationClaimToken));
|
|
222133
222201
|
}
|
|
222134
222202
|
return snapshotOperation(ctx.sessionId, args2.operationId);
|
|
222135
222203
|
});
|
|
@@ -222154,8 +222222,8 @@ ${result.stderr}`;
|
|
|
222154
222222
|
deadlineSeconds: args2.deadlineSeconds
|
|
222155
222223
|
} : {}
|
|
222156
222224
|
};
|
|
222157
|
-
const retry2 = withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_chat", canonicalCommand));
|
|
222158
|
-
if (retry2) return withOperationStore((store) => store.snapshot(retry2));
|
|
222225
|
+
const retry2 = await withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_chat", canonicalCommand));
|
|
222226
|
+
if (retry2) return await withOperationStore((store) => store.snapshot(retry2));
|
|
222159
222227
|
const targetSession = await readCurrentSessionMeta(manager, args2.sessionId);
|
|
222160
222228
|
if (!targetSession) {
|
|
222161
222229
|
throw new LodyOperationStoreError("SESSION_NOT_FOUND", `Target Session not found: ${args2.sessionId}`, false);
|
|
@@ -222177,7 +222245,7 @@ ${result.stderr}`;
|
|
|
222177
222245
|
const preallocatedUserTurnId = randomUUID();
|
|
222178
222246
|
const materializationClaimToken = randomUUID();
|
|
222179
222247
|
const timing = operationDeadline(args2.deadlineSeconds);
|
|
222180
|
-
const accepted = withOperationStore((store) => store.accept({
|
|
222248
|
+
const accepted = await withOperationStore((store) => store.accept({
|
|
222181
222249
|
workspaceId: workspace.id,
|
|
222182
222250
|
ownerMachineId: ctx.machineId,
|
|
222183
222251
|
requesterSessionId: ctx.sessionId,
|
|
@@ -222200,7 +222268,7 @@ ${result.stderr}`;
|
|
|
222200
222268
|
materializationClaimToken
|
|
222201
222269
|
}));
|
|
222202
222270
|
if (accepted.operation.state === "finished") {
|
|
222203
|
-
return withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222271
|
+
return await withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222204
222272
|
}
|
|
222205
222273
|
const pendingItem = accepted.operation.items[0];
|
|
222206
222274
|
if (!pendingItem || pendingItem.status !== "active") {
|
|
@@ -222214,7 +222282,7 @@ ${result.stderr}`;
|
|
|
222214
222282
|
if (result.userTurnId !== pendingItem.target.userTurnId) {
|
|
222215
222283
|
throw new Error("Chat result did not preserve the preallocated target turn id.");
|
|
222216
222284
|
}
|
|
222217
|
-
withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, 0, materializationClaimToken));
|
|
222285
|
+
await withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, 0, materializationClaimToken));
|
|
222218
222286
|
}
|
|
222219
222287
|
return snapshotOperation(ctx.sessionId, args2.operationId);
|
|
222220
222288
|
});
|
|
@@ -222257,11 +222325,11 @@ ${result.stderr}`;
|
|
|
222257
222325
|
} : {},
|
|
222258
222326
|
error: makeLodyError(code2, message, retryable)
|
|
222259
222327
|
});
|
|
222260
|
-
const finishOperationWhenEveryItemIsTerminal = (requesterSessionId, operationId, items2) => {
|
|
222328
|
+
const finishOperationWhenEveryItemIsTerminal = async (requesterSessionId, operationId, items2) => {
|
|
222261
222329
|
if (items2.some((item) => item.status === "active")) {
|
|
222262
222330
|
return;
|
|
222263
222331
|
}
|
|
222264
|
-
withOperationStore((store) => store.finish(requesterSessionId, operationId, {
|
|
222332
|
+
await withOperationStore((store) => store.finish(requesterSessionId, operationId, {
|
|
222265
222333
|
type: "result",
|
|
222266
222334
|
value: {
|
|
222267
222335
|
items: items2
|
|
@@ -222289,8 +222357,8 @@ ${result.stderr}`;
|
|
|
222289
222357
|
deadlineSeconds: args2.deadlineSeconds
|
|
222290
222358
|
} : {}
|
|
222291
222359
|
};
|
|
222292
|
-
const retry2 = withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_create_many", canonicalCommand));
|
|
222293
|
-
if (retry2) return withOperationStore((store) => store.snapshot(retry2));
|
|
222360
|
+
const retry2 = await withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_create_many", canonicalCommand));
|
|
222361
|
+
if (retry2) return await withOperationStore((store) => store.snapshot(retry2));
|
|
222294
222362
|
const invoking = await resolveInvokingTurnContext(manager, requester);
|
|
222295
222363
|
const initialItems = await mapWithConcurrency(expanded, 5, async (item) => {
|
|
222296
222364
|
const label2 = item.label;
|
|
@@ -222337,7 +222405,7 @@ ${result.stderr}`;
|
|
|
222337
222405
|
});
|
|
222338
222406
|
const materializationClaimToken = randomUUID();
|
|
222339
222407
|
const timing = operationDeadline(args2.deadlineSeconds);
|
|
222340
|
-
const accepted = withOperationStore((store) => store.accept({
|
|
222408
|
+
const accepted = await withOperationStore((store) => store.accept({
|
|
222341
222409
|
workspaceId: workspace.id,
|
|
222342
222410
|
ownerMachineId: ctx.machineId,
|
|
222343
222411
|
requesterSessionId: ctx.sessionId,
|
|
@@ -222358,7 +222426,7 @@ ${result.stderr}`;
|
|
|
222358
222426
|
materializationClaimToken
|
|
222359
222427
|
}));
|
|
222360
222428
|
if (accepted.operation.state === "finished") {
|
|
222361
|
-
return withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222429
|
+
return await withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222362
222430
|
}
|
|
222363
222431
|
const nextItems = await mapWithConcurrency(accepted.operation.items, 5, async (storedItem, index) => {
|
|
222364
222432
|
if (storedItem.status !== "active" || storedItem.inputDurable || !accepted.claimedItemIndexes.includes(index)) {
|
|
@@ -222392,13 +222460,13 @@ ${result.stderr}`;
|
|
|
222392
222460
|
options.userTurnId = storedItem.target.userTurnId;
|
|
222393
222461
|
options.chainDepth = invoking.chainDepth + 1;
|
|
222394
222462
|
await createSessionResult(auth, workspace, manager, expandedItem.prompt, options, resolveTurnDispatchConfig({}));
|
|
222395
|
-
withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, index, materializationClaimToken));
|
|
222463
|
+
await withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, index, materializationClaimToken));
|
|
222396
222464
|
return markOperationItemInputDurable(storedItem);
|
|
222397
222465
|
} catch {
|
|
222398
222466
|
return storedItem;
|
|
222399
222467
|
}
|
|
222400
222468
|
});
|
|
222401
|
-
finishOperationWhenEveryItemIsTerminal(ctx.sessionId, args2.operationId, nextItems);
|
|
222469
|
+
await finishOperationWhenEveryItemIsTerminal(ctx.sessionId, args2.operationId, nextItems);
|
|
222402
222470
|
return snapshotOperation(ctx.sessionId, args2.operationId);
|
|
222403
222471
|
});
|
|
222404
222472
|
};
|
|
@@ -222423,8 +222491,8 @@ ${result.stderr}`;
|
|
|
222423
222491
|
deadlineSeconds: args2.deadlineSeconds
|
|
222424
222492
|
} : {}
|
|
222425
222493
|
};
|
|
222426
|
-
const retry2 = withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_chat_many", canonicalCommand));
|
|
222427
|
-
if (retry2) return withOperationStore((store) => store.snapshot(retry2));
|
|
222494
|
+
const retry2 = await withOperationStore((store) => store.findMatchingRetry(ctx.sessionId, args2.operationId, "session_chat_many", canonicalCommand));
|
|
222495
|
+
if (retry2) return await withOperationStore((store) => store.snapshot(retry2));
|
|
222428
222496
|
const invoking = await resolveInvokingTurnContext(manager, requester);
|
|
222429
222497
|
const initialItems = await mapWithConcurrency(expanded, 5, async (item) => {
|
|
222430
222498
|
if (!item.sessionId || !item.prompt) {
|
|
@@ -222455,7 +222523,7 @@ ${result.stderr}`;
|
|
|
222455
222523
|
});
|
|
222456
222524
|
const materializationClaimToken = randomUUID();
|
|
222457
222525
|
const timing = operationDeadline(args2.deadlineSeconds);
|
|
222458
|
-
const accepted = withOperationStore((store) => store.accept({
|
|
222526
|
+
const accepted = await withOperationStore((store) => store.accept({
|
|
222459
222527
|
workspaceId: workspace.id,
|
|
222460
222528
|
ownerMachineId: ctx.machineId,
|
|
222461
222529
|
requesterSessionId: ctx.sessionId,
|
|
@@ -222476,7 +222544,7 @@ ${result.stderr}`;
|
|
|
222476
222544
|
materializationClaimToken
|
|
222477
222545
|
}));
|
|
222478
222546
|
if (accepted.operation.state === "finished") {
|
|
222479
|
-
return withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222547
|
+
return await withOperationStore((store) => store.snapshot(accepted.operation));
|
|
222480
222548
|
}
|
|
222481
222549
|
const nextItems = await mapWithConcurrency(accepted.operation.items, 5, async (storedItem, index) => {
|
|
222482
222550
|
if (storedItem.status !== "active" || storedItem.inputDurable || !accepted.claimedItemIndexes.includes(index)) {
|
|
@@ -222491,13 +222559,13 @@ ${result.stderr}`;
|
|
|
222491
222559
|
userTurnId: storedItem.target.userTurnId,
|
|
222492
222560
|
chainDepth: invoking.chainDepth + 1
|
|
222493
222561
|
});
|
|
222494
|
-
withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, index, materializationClaimToken));
|
|
222562
|
+
await withOperationStore((store) => store.markItemInputDurable(ctx.sessionId, args2.operationId, index, materializationClaimToken));
|
|
222495
222563
|
return markOperationItemInputDurable(storedItem);
|
|
222496
222564
|
} catch {
|
|
222497
222565
|
return storedItem;
|
|
222498
222566
|
}
|
|
222499
222567
|
});
|
|
222500
|
-
finishOperationWhenEveryItemIsTerminal(ctx.sessionId, args2.operationId, nextItems);
|
|
222568
|
+
await finishOperationWhenEveryItemIsTerminal(ctx.sessionId, args2.operationId, nextItems);
|
|
222501
222569
|
return snapshotOperation(ctx.sessionId, args2.operationId);
|
|
222502
222570
|
});
|
|
222503
222571
|
};
|
|
@@ -222779,7 +222847,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
222779
222847
|
}, async (args2) => {
|
|
222780
222848
|
try {
|
|
222781
222849
|
const ctx = getSessionContext();
|
|
222782
|
-
return jsonTextResult(snapshotOperation(ctx.sessionId, args2.operationId));
|
|
222850
|
+
return jsonTextResult(await snapshotOperation(ctx.sessionId, args2.operationId));
|
|
222783
222851
|
} catch (error2) {
|
|
222784
222852
|
return mcpErrorResult(error2);
|
|
222785
222853
|
}
|
|
@@ -222792,13 +222860,13 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
222792
222860
|
try {
|
|
222793
222861
|
const ctx = getSessionContext();
|
|
222794
222862
|
const requesterSessionId = ctx.sessionId;
|
|
222795
|
-
const before = withOperationStore((store) => store.get(requesterSessionId, args2.operationId));
|
|
222796
|
-
const cancellation = withOperationStore((store) => store.cancel(requesterSessionId, args2.operationId));
|
|
222863
|
+
const before = await withOperationStore((store) => store.get(requesterSessionId, args2.operationId));
|
|
222864
|
+
const cancellation = await withOperationStore((store) => store.cancel(requesterSessionId, args2.operationId));
|
|
222797
222865
|
if (cancellation.didCancel && before.state === "active") {
|
|
222798
222866
|
const startedTargets = before.items.filter((item) => item.status === "active" && item.inputDurable);
|
|
222799
222867
|
await Promise.allSettled(startedTargets.map((item) => item.status === "active" ? runLodyCliJson(buildOperationTargetCancelArgs(getMcpWorkspaceId(ctx), item)) : Promise.resolve()));
|
|
222800
222868
|
}
|
|
222801
|
-
return jsonTextResult(withOperationStore((store) => store.snapshot(cancellation.operation)));
|
|
222869
|
+
return jsonTextResult(await withOperationStore((store) => store.snapshot(cancellation.operation)));
|
|
222802
222870
|
} catch (error2) {
|
|
222803
222871
|
return mcpErrorResult(error2);
|
|
222804
222872
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lody",
|
|
3
|
-
"version": "0.71.
|
|
3
|
+
"version": "0.71.3",
|
|
4
4
|
"description": "Lody Agent CLI tool for managing remote command execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -75,15 +75,15 @@
|
|
|
75
75
|
"ws": "^8.18.3",
|
|
76
76
|
"zod": "^4.1.5",
|
|
77
77
|
"zstd-stream": "^1.1.0",
|
|
78
|
-
"@lody/cli-supervisor": "0.0.1",
|
|
79
|
-
"@lody/code-review-helper": "0.0.0",
|
|
80
|
-
"@lody/loro-streams-rpc": "0.0.1",
|
|
81
|
-
"@lody/shared": "0.0.1",
|
|
82
78
|
"@lody/convex": "0.0.1",
|
|
79
|
+
"@lody/loro-streams-rpc": "0.0.1",
|
|
83
80
|
"acp-extension-claude": "0.59.0",
|
|
84
|
-
"
|
|
81
|
+
"@lody/code-review-helper": "0.0.0",
|
|
82
|
+
"@lody/cli-supervisor": "0.0.1",
|
|
83
|
+
"@lody/shared": "0.0.1",
|
|
85
84
|
"acp-extension-core": "0.0.5",
|
|
86
|
-
"lody-code-review-viewer": "0.71.
|
|
85
|
+
"lody-code-review-viewer": "0.71.3",
|
|
86
|
+
"acp-extension-codex": "1.2.1"
|
|
87
87
|
},
|
|
88
88
|
"files": [
|
|
89
89
|
"dist",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"build": "pnpm run clean && pnpm run prepare:acp-adapters && pnpm run typecheck && pnpm run build:bundle && pnpm run check:published-bundle-imports && pnpm run copy:wasm",
|
|
107
107
|
"build:watch": "pnpm run prepare:review-assets && vite build --watch",
|
|
108
108
|
"build:bundle": "pnpm run prepare:review-assets && vite build",
|
|
109
|
-
"prepare:acp-adapters": "pnpm --dir ../.. --filter acp-extension-claude build && pnpm --dir ../.. --filter acp-extension-codex build",
|
|
109
|
+
"prepare:acp-adapters": "corepack pnpm --dir ../.. --filter acp-extension-claude build && corepack pnpm --dir ../.. --filter acp-extension-codex build",
|
|
110
110
|
"prepare:review-assets": "pnpm --dir ../.. --filter lody-code-review-viewer build",
|
|
111
111
|
"check:published-bundle-imports": "node scripts/check-published-bundle-imports.js",
|
|
112
112
|
"copy:wasm": "node scripts/copy-loro-wasm.js",
|