lody 0.65.0 → 0.66.0
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.
|
|
6
|
+
const reviewViewerVersion = "0.66.0";
|
|
7
7
|
const reviewViewerSha256 = "50ab599b652bdf4b959b539ea948454dd588703039bd4c5c037c7877ce10696f";
|
|
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
|
@@ -36839,7 +36839,7 @@ Mongoose Error Code: ${error2.code}` : ""}`
|
|
|
36839
36839
|
return client;
|
|
36840
36840
|
}
|
|
36841
36841
|
const name$1 = "lody";
|
|
36842
|
-
const version$3 = "0.
|
|
36842
|
+
const version$3 = "0.66.0";
|
|
36843
36843
|
const description$1 = "Lody Agent CLI tool for managing remote command execution";
|
|
36844
36844
|
const type$2 = "module";
|
|
36845
36845
|
const main$4 = "dist/index.js";
|
|
@@ -36849,7 +36849,7 @@ Mongoose Error Code: ${error2.code}` : ""}`
|
|
|
36849
36849
|
const scripts = {
|
|
36850
36850
|
"dev": "node dev.mjs",
|
|
36851
36851
|
"dev:staging": "LODY_AUTH_URL=https://impressive-guineapig-165.convex.cloud LODY_AUTH_SITE_URL=https://impressive-guineapig-165.convex.site LODY_SERVER_URL=https://lody-server.zx-073.workers.dev SITE_URL=https://main.lody.pages.dev/ pnpm run dev",
|
|
36852
|
-
"dev:prod": "LODY_AUTH_URL=https://
|
|
36852
|
+
"dev:prod": "LODY_AUTH_URL=https://convex.lody.ai LODY_SERVER_URL=https://api.lody.ai pnpm run dev",
|
|
36853
36853
|
"build": "pnpm run clean && pnpm run typecheck && pnpm run build:bundle && pnpm run check:published-bundle-imports && pnpm run copy:wasm",
|
|
36854
36854
|
"build:watch": "pnpm run prepare:review-assets && vite build --watch",
|
|
36855
36855
|
"build:bundle": "pnpm run prepare:review-assets && vite build",
|
|
@@ -36884,7 +36884,7 @@ Mongoose Error Code: ${error2.code}` : ""}`
|
|
|
36884
36884
|
"node": ">=18.0.0"
|
|
36885
36885
|
};
|
|
36886
36886
|
const optionalDependencies = {
|
|
36887
|
-
"acp-extension-claude": "0.
|
|
36887
|
+
"acp-extension-claude": "0.54.1",
|
|
36888
36888
|
"acp-extension-codex": "0.15.0"
|
|
36889
36889
|
};
|
|
36890
36890
|
const devDependencies = {
|
|
@@ -42112,8 +42112,8 @@ Task description:
|
|
|
42112
42112
|
const historyItemAnySchema = schema.Any({
|
|
42113
42113
|
defaultLoroText: true
|
|
42114
42114
|
});
|
|
42115
|
-
const isRecord$
|
|
42116
|
-
const isWorktreeScriptHistoryStep = (value) => isRecord$
|
|
42115
|
+
const isRecord$a = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
42116
|
+
const isWorktreeScriptHistoryStep = (value) => isRecord$a(value) && typeof value.command === "string" && (value.status === "in_progress" || value.status === "completed" || value.status === "failed") && typeof value.output === "string";
|
|
42117
42117
|
const historyMessageItemSchema = schema.LoroMap({
|
|
42118
42118
|
type: schema.String(),
|
|
42119
42119
|
text: schema.LoroText({
|
|
@@ -44276,7 +44276,7 @@ Task description:
|
|
|
44276
44276
|
"claude",
|
|
44277
44277
|
"codex"
|
|
44278
44278
|
]);
|
|
44279
|
-
function isRecord$
|
|
44279
|
+
function isRecord$9(value) {
|
|
44280
44280
|
return typeof value === "object" && value !== null;
|
|
44281
44281
|
}
|
|
44282
44282
|
function getTrimmedString(value) {
|
|
@@ -44293,7 +44293,7 @@ Task description:
|
|
|
44293
44293
|
return value === "builtin" || value === "registry" || value === "custom";
|
|
44294
44294
|
}
|
|
44295
44295
|
function normalizeLegacyProjectRef(value) {
|
|
44296
|
-
if (!isRecord$
|
|
44296
|
+
if (!isRecord$9(value)) {
|
|
44297
44297
|
return value;
|
|
44298
44298
|
}
|
|
44299
44299
|
const kind = value.kind;
|
|
@@ -44309,13 +44309,13 @@ Task description:
|
|
|
44309
44309
|
normalized.branch = existingBranch;
|
|
44310
44310
|
} else {
|
|
44311
44311
|
const legacyBranchFromString = getTrimmedString(legacyProject);
|
|
44312
|
-
const legacyBranchFromObject = isRecord$
|
|
44312
|
+
const legacyBranchFromObject = isRecord$9(legacyProject) ? getTrimmedString(legacyProject.branch) ?? getTrimmedString(legacyProject.project) : void 0;
|
|
44313
44313
|
const resolvedBranch = legacyBranchFromString ?? legacyBranchFromObject;
|
|
44314
44314
|
if (resolvedBranch) {
|
|
44315
44315
|
normalized.branch = resolvedBranch;
|
|
44316
44316
|
}
|
|
44317
44317
|
}
|
|
44318
|
-
if (isRecord$
|
|
44318
|
+
if (isRecord$9(legacyProject)) {
|
|
44319
44319
|
if (kind === "github" && !getTrimmedString(normalized.repoFullName)) {
|
|
44320
44320
|
const repoFullName = getTrimmedString(legacyProject.repoFullName);
|
|
44321
44321
|
if (repoFullName) {
|
|
@@ -44352,7 +44352,7 @@ Task description:
|
|
|
44352
44352
|
};
|
|
44353
44353
|
normalized.project = normalizeLegacyProjectRef(normalized.project);
|
|
44354
44354
|
const currentProject = normalized.project;
|
|
44355
|
-
const projectRecord = isRecord$
|
|
44355
|
+
const projectRecord = isRecord$9(currentProject) ? currentProject : void 0;
|
|
44356
44356
|
const explicitBranch = getTrimmedString(normalized.branch) ?? getTrimmedString(currentProject) ?? (projectRecord ? getTrimmedString(projectRecord.branch) ?? getTrimmedString(projectRecord.project) : void 0);
|
|
44357
44357
|
const repoFullName = (projectRecord ? getTrimmedString(projectRecord.repoFullName) : void 0) ?? getTrimmedString(normalized.repoFullName) ?? getTrimmedString(normalized.githubRepo);
|
|
44358
44358
|
const localProjectId = (projectRecord ? getTrimmedString(projectRecord.localProjectId) : void 0) ?? getTrimmedString(normalized.localProjectId);
|
|
@@ -44395,7 +44395,7 @@ Task description:
|
|
|
44395
44395
|
return normalized;
|
|
44396
44396
|
}
|
|
44397
44397
|
function normalizeLegacyAcpSessionConfig(value) {
|
|
44398
|
-
if (!isRecord$
|
|
44398
|
+
if (!isRecord$9(value)) {
|
|
44399
44399
|
return value;
|
|
44400
44400
|
}
|
|
44401
44401
|
const normalized = {
|
|
@@ -44430,13 +44430,13 @@ Task description:
|
|
|
44430
44430
|
return normalized;
|
|
44431
44431
|
}
|
|
44432
44432
|
function normalizeLegacySessionMessage(parsed) {
|
|
44433
|
-
if (!isRecord$
|
|
44433
|
+
if (!isRecord$9(parsed)) {
|
|
44434
44434
|
return parsed;
|
|
44435
44435
|
}
|
|
44436
44436
|
const messageType = parsed.type;
|
|
44437
44437
|
if (messageType === "session/create" || messageType === "session/chat") {
|
|
44438
44438
|
const normalized = normalizeLegacySessionProject(parsed);
|
|
44439
|
-
if (!isRecord$
|
|
44439
|
+
if (!isRecord$9(normalized)) {
|
|
44440
44440
|
return normalized;
|
|
44441
44441
|
}
|
|
44442
44442
|
normalized.acpSessionConfig = normalizeLegacyAcpSessionConfig(normalized.acpSessionConfig);
|
|
@@ -48632,17 +48632,17 @@ Task description:
|
|
|
48632
48632
|
droppedNotifications
|
|
48633
48633
|
};
|
|
48634
48634
|
}
|
|
48635
|
-
const isRecord$
|
|
48635
|
+
const isRecord$8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48636
48636
|
const getBooleanField = (value, camelCaseKey, snakeCaseKey) => value[camelCaseKey] === true || value[snakeCaseKey] === true;
|
|
48637
48637
|
const getClaudeCodeMeta = (meta) => {
|
|
48638
|
-
if (!isRecord$
|
|
48638
|
+
if (!isRecord$8(meta)) return null;
|
|
48639
48639
|
const claudeCode = meta.claudeCode;
|
|
48640
|
-
return isRecord$
|
|
48640
|
+
return isRecord$8(claudeCode) ? claudeCode : null;
|
|
48641
48641
|
};
|
|
48642
48642
|
const getCodexMeta = (meta) => {
|
|
48643
|
-
if (!isRecord$
|
|
48643
|
+
if (!isRecord$8(meta)) return null;
|
|
48644
48644
|
const codex = meta.codex;
|
|
48645
|
-
return isRecord$
|
|
48645
|
+
return isRecord$8(codex) ? codex : null;
|
|
48646
48646
|
};
|
|
48647
48647
|
function parseAskUserQuestionPermissionMeta(meta) {
|
|
48648
48648
|
const claudeCode = getClaudeCodeMeta(meta);
|
|
@@ -48657,18 +48657,18 @@ Task description:
|
|
|
48657
48657
|
}
|
|
48658
48658
|
function parseClaudeAskUserQuestionPermissionMeta(claudeCode) {
|
|
48659
48659
|
const raw2 = claudeCode.askUserQuestion;
|
|
48660
|
-
if (!isRecord$
|
|
48660
|
+
if (!isRecord$8(raw2)) return null;
|
|
48661
48661
|
const rawQuestions = raw2.questions;
|
|
48662
48662
|
if (!Array.isArray(rawQuestions) || rawQuestions.length === 0) return null;
|
|
48663
48663
|
const questions = [];
|
|
48664
48664
|
for (const rawQuestion of rawQuestions) {
|
|
48665
|
-
if (!isRecord$
|
|
48665
|
+
if (!isRecord$8(rawQuestion)) return null;
|
|
48666
48666
|
if (typeof rawQuestion.question !== "string") return null;
|
|
48667
48667
|
if (typeof rawQuestion.header !== "string") return null;
|
|
48668
48668
|
if (!Array.isArray(rawQuestion.options)) return null;
|
|
48669
48669
|
const options = [];
|
|
48670
48670
|
for (const rawOption of rawQuestion.options) {
|
|
48671
|
-
if (!isRecord$
|
|
48671
|
+
if (!isRecord$8(rawOption)) return null;
|
|
48672
48672
|
if (typeof rawOption.label !== "string") return null;
|
|
48673
48673
|
options.push({
|
|
48674
48674
|
label: rawOption.label,
|
|
@@ -48696,12 +48696,12 @@ Task description:
|
|
|
48696
48696
|
}
|
|
48697
48697
|
function parseCodexRequestUserInputPermissionMeta(codex) {
|
|
48698
48698
|
const raw2 = codex.requestUserInput;
|
|
48699
|
-
if (!isRecord$
|
|
48699
|
+
if (!isRecord$8(raw2)) return null;
|
|
48700
48700
|
const rawQuestions = raw2.questions;
|
|
48701
48701
|
if (!Array.isArray(rawQuestions) || rawQuestions.length === 0) return null;
|
|
48702
48702
|
const questions = [];
|
|
48703
48703
|
for (const rawQuestion of rawQuestions) {
|
|
48704
|
-
if (!isRecord$
|
|
48704
|
+
if (!isRecord$8(rawQuestion)) return null;
|
|
48705
48705
|
if (typeof rawQuestion.id !== "string") return null;
|
|
48706
48706
|
if (typeof rawQuestion.question !== "string") return null;
|
|
48707
48707
|
if (typeof rawQuestion.header !== "string") return null;
|
|
@@ -48710,7 +48710,7 @@ Task description:
|
|
|
48710
48710
|
if (rawOptions !== void 0) {
|
|
48711
48711
|
if (!Array.isArray(rawOptions)) return null;
|
|
48712
48712
|
for (const rawOption of rawOptions) {
|
|
48713
|
-
if (!isRecord$
|
|
48713
|
+
if (!isRecord$8(rawOption)) return null;
|
|
48714
48714
|
if (typeof rawOption.label !== "string") return null;
|
|
48715
48715
|
options.push({
|
|
48716
48716
|
label: rawOption.label,
|
|
@@ -48772,16 +48772,16 @@ Task description:
|
|
|
48772
48772
|
}
|
|
48773
48773
|
const getCodexOutcomeAnswers = (outcomeMeta) => {
|
|
48774
48774
|
const codex = getCodexMeta(outcomeMeta);
|
|
48775
|
-
const requestUserInput = codex && isRecord$
|
|
48776
|
-
return requestUserInput && isRecord$
|
|
48775
|
+
const requestUserInput = codex && isRecord$8(codex.requestUserInput) ? codex.requestUserInput : null;
|
|
48776
|
+
return requestUserInput && isRecord$8(requestUserInput.answers) ? requestUserInput.answers : null;
|
|
48777
48777
|
};
|
|
48778
48778
|
const getClaudeOutcomeAnswers = (outcomeMeta) => {
|
|
48779
48779
|
const claudeCode = getClaudeCodeMeta(outcomeMeta);
|
|
48780
|
-
const askUserQuestion = claudeCode && isRecord$
|
|
48781
|
-
return askUserQuestion && isRecord$
|
|
48780
|
+
const askUserQuestion = claudeCode && isRecord$8(claudeCode.askUserQuestion) ? claudeCode.askUserQuestion : null;
|
|
48781
|
+
return askUserQuestion && isRecord$8(askUserQuestion.answers) ? askUserQuestion.answers : null;
|
|
48782
48782
|
};
|
|
48783
48783
|
function extractAskUserQuestionAnswersFromOutcome(meta, outcome) {
|
|
48784
|
-
if (!outcome || !isRecord$
|
|
48784
|
+
if (!outcome || !isRecord$8(outcome._meta)) return null;
|
|
48785
48785
|
const rawAnswers = meta.source === "codex" ? getCodexOutcomeAnswers(outcome._meta) : getClaudeOutcomeAnswers(outcome._meta);
|
|
48786
48786
|
if (!rawAnswers) return null;
|
|
48787
48787
|
const result = {};
|
|
@@ -48790,7 +48790,7 @@ Task description:
|
|
|
48790
48790
|
const raw2 = rawAnswers[key2];
|
|
48791
48791
|
if (raw2 === void 0) continue;
|
|
48792
48792
|
if (meta.source === "codex") {
|
|
48793
|
-
if (!isRecord$
|
|
48793
|
+
if (!isRecord$8(raw2)) continue;
|
|
48794
48794
|
const inner = raw2.answers;
|
|
48795
48795
|
if (!Array.isArray(inner)) continue;
|
|
48796
48796
|
const values = inner.filter((value) => typeof value === "string");
|
|
@@ -48806,20 +48806,20 @@ Task description:
|
|
|
48806
48806
|
}
|
|
48807
48807
|
return Object.keys(result).length > 0 ? result : null;
|
|
48808
48808
|
}
|
|
48809
|
-
const isEnumOption = (value) => isRecord$
|
|
48809
|
+
const isEnumOption = (value) => isRecord$8(value) && typeof value.const === "string";
|
|
48810
48810
|
const getEnumOptionSource = (prop) => {
|
|
48811
48811
|
if (Array.isArray(prop.oneOf)) return prop.oneOf;
|
|
48812
48812
|
if (Array.isArray(prop.enum)) return prop.enum;
|
|
48813
48813
|
const items2 = prop.items;
|
|
48814
|
-
if (isRecord$
|
|
48814
|
+
if (isRecord$8(items2)) {
|
|
48815
48815
|
if (Array.isArray(items2.anyOf)) return items2.anyOf;
|
|
48816
48816
|
if (Array.isArray(items2.enum)) return items2.enum;
|
|
48817
48817
|
}
|
|
48818
48818
|
return null;
|
|
48819
48819
|
};
|
|
48820
|
-
const isQuestionProperty = (prop) => isRecord$
|
|
48821
|
-
const isFreeTextProperty = (prop) => isRecord$
|
|
48822
|
-
const isMultiSelectProperty = (prop) => prop.type === "array" || isRecord$
|
|
48820
|
+
const isQuestionProperty = (prop) => isRecord$8(prop) && getEnumOptionSource(prop) !== null;
|
|
48821
|
+
const isFreeTextProperty = (prop) => isRecord$8(prop) && prop.type === "string" && !Array.isArray(prop.oneOf) && !Array.isArray(prop.enum);
|
|
48822
|
+
const isMultiSelectProperty = (prop) => prop.type === "array" || isRecord$8(prop.items);
|
|
48823
48823
|
const parseElicitationOptions = (source) => {
|
|
48824
48824
|
const options = [];
|
|
48825
48825
|
for (const entry of source) {
|
|
@@ -48844,9 +48844,9 @@ Task description:
|
|
|
48844
48844
|
return options;
|
|
48845
48845
|
};
|
|
48846
48846
|
function parseAskUserQuestionElicitationRequest(request) {
|
|
48847
|
-
if (!isRecord$
|
|
48847
|
+
if (!isRecord$8(request) || request.mode !== "form") return null;
|
|
48848
48848
|
const schema2 = request.requestedSchema;
|
|
48849
|
-
if (!isRecord$
|
|
48849
|
+
if (!isRecord$8(schema2) || !isRecord$8(schema2.properties)) return null;
|
|
48850
48850
|
const entries = Object.entries(schema2.properties);
|
|
48851
48851
|
const questionEntries = entries.filter(([, prop]) => isQuestionProperty(prop));
|
|
48852
48852
|
if (questionEntries.length === 0) return null;
|
|
@@ -48856,7 +48856,7 @@ Task description:
|
|
|
48856
48856
|
const questions = [];
|
|
48857
48857
|
const fieldKeys = [];
|
|
48858
48858
|
for (const [key2, prop] of questionEntries) {
|
|
48859
|
-
if (!isRecord$
|
|
48859
|
+
if (!isRecord$8(prop)) continue;
|
|
48860
48860
|
const source = getEnumOptionSource(prop);
|
|
48861
48861
|
if (!source) continue;
|
|
48862
48862
|
const header = typeof prop.title === "string" ? prop.title : "";
|
|
@@ -48889,7 +48889,7 @@ Task description:
|
|
|
48889
48889
|
};
|
|
48890
48890
|
}
|
|
48891
48891
|
const answers = extractAskUserQuestionAnswersFromOutcome(elicitation.meta, {
|
|
48892
|
-
_meta: isRecord$
|
|
48892
|
+
_meta: isRecord$8(outcome._meta) ? outcome._meta : null
|
|
48893
48893
|
});
|
|
48894
48894
|
if (!answers) {
|
|
48895
48895
|
return {
|
|
@@ -52309,7 +52309,7 @@ ${tailedOutput}` : null;
|
|
|
52309
52309
|
];
|
|
52310
52310
|
const buildPreviewTunnelRefreshPath = (tunnelId) => `${PREVIEW_TUNNELS_API_PATH}/${encodeURIComponent(tunnelId)}/refresh`;
|
|
52311
52311
|
const buildPreviewTunnelRevokePath = (tunnelId) => `${PREVIEW_TUNNELS_API_PATH}/${encodeURIComponent(tunnelId)}/revoke`;
|
|
52312
|
-
const isRecord$
|
|
52312
|
+
const isRecord$7 = (value) => typeof value === "object" && value !== null;
|
|
52313
52313
|
const isString$2 = (value) => typeof value === "string";
|
|
52314
52314
|
const isOptionalNumber = (value) => value === void 0 || typeof value === "number";
|
|
52315
52315
|
const isOptionalBoolean = (value) => value === void 0 || typeof value === "boolean";
|
|
@@ -52317,11 +52317,11 @@ ${tailedOutput}` : null;
|
|
|
52317
52317
|
const isStringArray$1 = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
52318
52318
|
const isHeaderEntries = (value) => Array.isArray(value) && value.every((entry) => Array.isArray(entry) && entry.length === 2 && typeof entry[0] === "string" && typeof entry[1] === "string");
|
|
52319
52319
|
const isPreviewTunnelBinaryPayloadStream = (value) => value === "request-body" || value === "response-body" || value === "websocket-frame";
|
|
52320
|
-
const isPreviewResourceLimits = (value) => isRecord$
|
|
52320
|
+
const isPreviewResourceLimits = (value) => isRecord$7(value) && isPositiveInteger(value.maxRequestBodyBytes) && isPositiveInteger(value.maxResponseBodyBytes) && isPositiveInteger(value.maxRequestDurationMs);
|
|
52321
52321
|
const parseJsonRecord = (raw2) => {
|
|
52322
52322
|
try {
|
|
52323
52323
|
const parsed = JSON.parse(raw2);
|
|
52324
|
-
return isRecord$
|
|
52324
|
+
return isRecord$7(parsed) ? parsed : null;
|
|
52325
52325
|
} catch {
|
|
52326
52326
|
return null;
|
|
52327
52327
|
}
|
|
@@ -52360,8 +52360,209 @@ ${tailedOutput}` : null;
|
|
|
52360
52360
|
const parsed = parseJsonRecord(raw2);
|
|
52361
52361
|
return parsed && isPreviewTunnelServerMessage(parsed) ? parsed : null;
|
|
52362
52362
|
};
|
|
52363
|
-
const isPreviewTunnelCreateResponse = (value) => isRecord$
|
|
52364
|
-
const isPreviewTunnelRefreshResponse = (value) => isRecord$
|
|
52363
|
+
const isPreviewTunnelCreateResponse = (value) => isRecord$7(value) && isString$2(value.tunnelId) && isString$2(value.publicUrl) && isString$2(value.websocketUrl) && isString$2(value.sessionToken) && typeof value.expiresAt === "number" && (value.resourceLimits === void 0 || isPreviewResourceLimits(value.resourceLimits));
|
|
52364
|
+
const isPreviewTunnelRefreshResponse = (value) => isRecord$7(value) && isString$2(value.websocketUrl) && isString$2(value.sessionToken) && typeof value.expiresAt === "number";
|
|
52365
|
+
const MACHINE_FLOCK_DOC_STREAM_SEGMENT = "mf";
|
|
52366
|
+
const getMachineFlockDocId = (workspaceId, machineId) => `${workspaceId}:${MACHINE_FLOCK_DOC_STREAM_SEGMENT}:${machineId}`;
|
|
52367
|
+
const machineFlockKeys = {
|
|
52368
|
+
dotlodyPath: () => [
|
|
52369
|
+
"dotlodyPath"
|
|
52370
|
+
],
|
|
52371
|
+
archiveSessionCommand: (sessionId) => [
|
|
52372
|
+
"cmd",
|
|
52373
|
+
"archiveSession",
|
|
52374
|
+
sessionId
|
|
52375
|
+
],
|
|
52376
|
+
deleteSessionCommand: (sessionId) => [
|
|
52377
|
+
"cmd",
|
|
52378
|
+
"deleteSession",
|
|
52379
|
+
sessionId
|
|
52380
|
+
],
|
|
52381
|
+
localProject: (localProjectId) => [
|
|
52382
|
+
"localProject",
|
|
52383
|
+
localProjectId
|
|
52384
|
+
],
|
|
52385
|
+
agentConfig: (agentConfigId) => [
|
|
52386
|
+
"agentConfig",
|
|
52387
|
+
agentConfigId
|
|
52388
|
+
],
|
|
52389
|
+
agentConfigIndex: (agentConfigId) => [
|
|
52390
|
+
"agentConfigIndex",
|
|
52391
|
+
agentConfigId
|
|
52392
|
+
],
|
|
52393
|
+
acpCapability: (cliType, agentType) => [
|
|
52394
|
+
"acpCapability",
|
|
52395
|
+
cliType,
|
|
52396
|
+
agentType
|
|
52397
|
+
],
|
|
52398
|
+
rateLimit: (cliType, limitId) => [
|
|
52399
|
+
"rateLimit",
|
|
52400
|
+
cliType,
|
|
52401
|
+
limitId
|
|
52402
|
+
]
|
|
52403
|
+
};
|
|
52404
|
+
const parseMachineFlockKey = (key2) => {
|
|
52405
|
+
if (key2.length === 1 && key2[0] === "dotlodyPath") {
|
|
52406
|
+
return {
|
|
52407
|
+
kind: "dotlodyPath",
|
|
52408
|
+
key: machineFlockKeys.dotlodyPath()
|
|
52409
|
+
};
|
|
52410
|
+
}
|
|
52411
|
+
if (key2.length === 3 && key2[0] === "cmd" && key2[1] === "archiveSession" && isNonEmptyString(key2[2])) {
|
|
52412
|
+
const sessionId = key2[2];
|
|
52413
|
+
return {
|
|
52414
|
+
kind: "archiveSessionCommand",
|
|
52415
|
+
key: machineFlockKeys.archiveSessionCommand(sessionId),
|
|
52416
|
+
sessionId
|
|
52417
|
+
};
|
|
52418
|
+
}
|
|
52419
|
+
if (key2.length === 3 && key2[0] === "cmd" && key2[1] === "deleteSession" && isNonEmptyString(key2[2])) {
|
|
52420
|
+
const sessionId = key2[2];
|
|
52421
|
+
return {
|
|
52422
|
+
kind: "deleteSessionCommand",
|
|
52423
|
+
key: machineFlockKeys.deleteSessionCommand(sessionId),
|
|
52424
|
+
sessionId
|
|
52425
|
+
};
|
|
52426
|
+
}
|
|
52427
|
+
if (key2.length === 2 && key2[0] === "localProject" && isNonEmptyString(key2[1])) {
|
|
52428
|
+
const localProjectId = key2[1];
|
|
52429
|
+
return {
|
|
52430
|
+
kind: "localProject",
|
|
52431
|
+
key: machineFlockKeys.localProject(localProjectId),
|
|
52432
|
+
localProjectId
|
|
52433
|
+
};
|
|
52434
|
+
}
|
|
52435
|
+
if (key2.length === 2 && key2[0] === "agentConfig" && isNonEmptyString(key2[1])) {
|
|
52436
|
+
const agentConfigId = key2[1];
|
|
52437
|
+
return {
|
|
52438
|
+
kind: "agentConfig",
|
|
52439
|
+
key: machineFlockKeys.agentConfig(agentConfigId),
|
|
52440
|
+
agentConfigId
|
|
52441
|
+
};
|
|
52442
|
+
}
|
|
52443
|
+
if (key2.length === 2 && key2[0] === "agentConfigIndex" && isNonEmptyString(key2[1])) {
|
|
52444
|
+
const agentConfigId = key2[1];
|
|
52445
|
+
return {
|
|
52446
|
+
kind: "agentConfigIndex",
|
|
52447
|
+
key: machineFlockKeys.agentConfigIndex(agentConfigId),
|
|
52448
|
+
agentConfigId
|
|
52449
|
+
};
|
|
52450
|
+
}
|
|
52451
|
+
if (key2.length === 3 && key2[0] === "acpCapability" && isAgentConfigCliType(key2[1]) && isNonEmptyString(key2[2])) {
|
|
52452
|
+
return {
|
|
52453
|
+
kind: "acpCapability",
|
|
52454
|
+
key: machineFlockKeys.acpCapability(key2[1], key2[2]),
|
|
52455
|
+
cliType: key2[1],
|
|
52456
|
+
agentType: key2[2]
|
|
52457
|
+
};
|
|
52458
|
+
}
|
|
52459
|
+
if (key2.length === 3 && key2[0] === "rateLimit" && isCliType(key2[1]) && isNonEmptyString(key2[2])) {
|
|
52460
|
+
return {
|
|
52461
|
+
kind: "rateLimit",
|
|
52462
|
+
key: machineFlockKeys.rateLimit(key2[1], key2[2]),
|
|
52463
|
+
cliType: key2[1],
|
|
52464
|
+
limitId: key2[2]
|
|
52465
|
+
};
|
|
52466
|
+
}
|
|
52467
|
+
return void 0;
|
|
52468
|
+
};
|
|
52469
|
+
const serializeMachineFlockKey = (key2) => JSON.stringify(key2);
|
|
52470
|
+
function readMachineFlockRowsFromFlock(flock) {
|
|
52471
|
+
const rows = {};
|
|
52472
|
+
for (const row of flock.scan()) {
|
|
52473
|
+
const parsed = parseMachineFlockRow(row.key, row.value);
|
|
52474
|
+
if (!parsed) {
|
|
52475
|
+
continue;
|
|
52476
|
+
}
|
|
52477
|
+
rows[serializeMachineFlockKey(parsed.key)] = parsed;
|
|
52478
|
+
}
|
|
52479
|
+
return rows;
|
|
52480
|
+
}
|
|
52481
|
+
function writeMachineFlockRowToFlock(flock, row, nowMs2) {
|
|
52482
|
+
const previous = readMachineFlockRowsFromFlock(flock)[serializeMachineFlockKey(row.key)];
|
|
52483
|
+
if (machineFlockRowsEqual(previous, row)) {
|
|
52484
|
+
return false;
|
|
52485
|
+
}
|
|
52486
|
+
flock.set(row.key, row.value, nowMs2);
|
|
52487
|
+
flock.commit();
|
|
52488
|
+
return true;
|
|
52489
|
+
}
|
|
52490
|
+
function deleteMachineFlockRowFromFlock(flock, key2, nowMs2) {
|
|
52491
|
+
const rowId = serializeMachineFlockKey(key2);
|
|
52492
|
+
const previous = readMachineFlockRowsFromFlock(flock)[rowId];
|
|
52493
|
+
if (!previous) {
|
|
52494
|
+
return false;
|
|
52495
|
+
}
|
|
52496
|
+
flock.delete(key2, nowMs2);
|
|
52497
|
+
flock.commit();
|
|
52498
|
+
return true;
|
|
52499
|
+
}
|
|
52500
|
+
function parseMachineFlockRow(key2, value) {
|
|
52501
|
+
const parsedKey = parseMachineFlockKey(key2);
|
|
52502
|
+
if (!parsedKey || value === void 0) {
|
|
52503
|
+
return void 0;
|
|
52504
|
+
}
|
|
52505
|
+
switch (parsedKey.kind) {
|
|
52506
|
+
case "dotlodyPath":
|
|
52507
|
+
return typeof value === "string" && value.trim() ? {
|
|
52508
|
+
key: parsedKey.key,
|
|
52509
|
+
value
|
|
52510
|
+
} : void 0;
|
|
52511
|
+
case "archiveSessionCommand":
|
|
52512
|
+
return isMachineArchiveSessionCommand(value) ? {
|
|
52513
|
+
key: parsedKey.key,
|
|
52514
|
+
value
|
|
52515
|
+
} : void 0;
|
|
52516
|
+
case "deleteSessionCommand":
|
|
52517
|
+
return isMachineDeleteSessionCommand(value) ? {
|
|
52518
|
+
key: parsedKey.key,
|
|
52519
|
+
value
|
|
52520
|
+
} : void 0;
|
|
52521
|
+
case "localProject":
|
|
52522
|
+
return isLocalProjectMeta(value) ? {
|
|
52523
|
+
key: parsedKey.key,
|
|
52524
|
+
value
|
|
52525
|
+
} : void 0;
|
|
52526
|
+
case "agentConfig":
|
|
52527
|
+
return isAgentConfigMeta(value) ? {
|
|
52528
|
+
key: parsedKey.key,
|
|
52529
|
+
value
|
|
52530
|
+
} : void 0;
|
|
52531
|
+
case "agentConfigIndex":
|
|
52532
|
+
return isAgentConfigListSummary(value) ? {
|
|
52533
|
+
key: parsedKey.key,
|
|
52534
|
+
value
|
|
52535
|
+
} : void 0;
|
|
52536
|
+
case "acpCapability":
|
|
52537
|
+
return isAcpCapabilityCacheEntry(value) ? {
|
|
52538
|
+
key: parsedKey.key,
|
|
52539
|
+
value
|
|
52540
|
+
} : void 0;
|
|
52541
|
+
case "rateLimit":
|
|
52542
|
+
return isRecord$6(value) ? {
|
|
52543
|
+
key: parsedKey.key,
|
|
52544
|
+
value
|
|
52545
|
+
} : void 0;
|
|
52546
|
+
}
|
|
52547
|
+
return void 0;
|
|
52548
|
+
}
|
|
52549
|
+
function machineFlockRowsEqual(left2, right2) {
|
|
52550
|
+
if (left2 === right2) return true;
|
|
52551
|
+
if (!left2 || !right2) return false;
|
|
52552
|
+
return serializeMachineFlockKey(left2.key) === serializeMachineFlockKey(right2.key) && JSON.stringify(left2.value) === JSON.stringify(right2.value);
|
|
52553
|
+
}
|
|
52554
|
+
const isRecord$6 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52555
|
+
const isNonEmptyString = (value) => typeof value === "string" && value.length > 0;
|
|
52556
|
+
const isOptionalString = (value) => value === void 0 || typeof value === "string";
|
|
52557
|
+
const isStringRecord = (value) => isRecord$6(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
52558
|
+
const isCliType = (value) => value === "claude" || value === "codex";
|
|
52559
|
+
const isAgentConfigCliType = (value) => value === "builtin" || value === "registry" || value === "custom";
|
|
52560
|
+
const isMachineArchiveSessionCommand = (value) => isRecord$6(value) && value.v === 1 && typeof value.requestedAt === "number" && isOptionalString(value.requestedBy);
|
|
52561
|
+
const isMachineDeleteSessionCommand = (value) => isRecord$6(value) && value.v === 1 && typeof value.requestedAt === "number" && isOptionalString(value.repoFullName) && isOptionalString(value.branchName) && isOptionalString(value.baseBranchName) && isOptionalString(value.localProjectId) && isOptionalString(value.originalRootPath) && (value.isWorktree === void 0 || value.isWorktree === true) && isOptionalString(value.keptWorktreePath);
|
|
52562
|
+
const isLocalProjectMeta = (value) => isRecord$6(value) && isNonEmptyString(value.id) && isNonEmptyString(value.name) && isNonEmptyString(value.rootPath) && typeof value.createdAtMs === "number" && (value.lastOpenedAtMs === void 0 || typeof value.lastOpenedAtMs === "number");
|
|
52563
|
+
const isAgentConfigMeta = (value) => isRecord$6(value) && isNonEmptyString(value.id) && isNonEmptyString(value.machineId) && isNonEmptyString(value.name) && isOptionalString(value.description) && isAgentConfigCliType(value.cliType) && isNonEmptyString(value.agentType) && isStringRecord(value.env);
|
|
52564
|
+
const isAgentConfigListSummary = (value) => isRecord$6(value) && isNonEmptyString(value.id) && isNonEmptyString(value.machineId) && isNonEmptyString(value.name) && isOptionalString(value.description) && isAgentConfigCliType(value.cliType) && isNonEmptyString(value.agentType) && isOptionalString(value.brandId);
|
|
52565
|
+
const isAcpCapabilityCacheEntry = (value) => isRecord$6(value) && isAgentConfigCliType(value.cliType) && isNonEmptyString(value.agentType) && Array.isArray(value.modes) && Array.isArray(value.models) && typeof value.fetchedAt === "number";
|
|
52365
52566
|
const LOCAL_MACHINE_RPC_PATH = "/machine-rpc";
|
|
52366
52567
|
const BaseLocalMachineRpcRequestSchema = object$1({
|
|
52367
52568
|
machineId: string$1().trim().min(1),
|
|
@@ -126956,7 +127157,7 @@ ${error2.message}` : execaMessage;
|
|
|
126956
127157
|
const BuiltinACPSetting = {
|
|
126957
127158
|
claude: {
|
|
126958
127159
|
packageName: "acp-extension-claude",
|
|
126959
|
-
version: "0.
|
|
127160
|
+
version: "0.54.1",
|
|
126960
127161
|
binName: "acp-extension-claude"
|
|
126961
127162
|
},
|
|
126962
127163
|
codex: {
|
|
@@ -134538,16 +134739,13 @@ $mem | ConvertTo-Json -Compress
|
|
|
134538
134739
|
userResolver;
|
|
134539
134740
|
detachMetaRoomSyncedListener = null;
|
|
134540
134741
|
bootstrapChain = Promise.resolve();
|
|
134742
|
+
startupBootstrapTimer = null;
|
|
134541
134743
|
started = false;
|
|
134542
134744
|
async start() {
|
|
134543
134745
|
if (this.started) {
|
|
134544
134746
|
return;
|
|
134545
134747
|
}
|
|
134546
134748
|
this.started = true;
|
|
134547
|
-
await this.bootstrapOwnedSessions("startup");
|
|
134548
|
-
if (!this.started) {
|
|
134549
|
-
return;
|
|
134550
|
-
}
|
|
134551
134749
|
this.detachMetaRoomSyncedListener = this.deps.workspaceDocument.onMetaRoomSynced((reason) => {
|
|
134552
134750
|
if (!this.started) {
|
|
134553
134751
|
return;
|
|
@@ -134559,16 +134757,25 @@ $mem | ConvertTo-Json -Compress
|
|
|
134559
134757
|
return;
|
|
134560
134758
|
}
|
|
134561
134759
|
const sessionId = event.docId.slice(SESSION_DOC_PREFIX.length);
|
|
134562
|
-
this.reconcileSessionWatch(sessionId).catch((
|
|
134563
|
-
this.deps.logger.error(`[dispatch] Failed to reconcile session watch for ${sessionId}: ${formatErrorMessage(error2)}`);
|
|
134564
|
-
});
|
|
134760
|
+
this.reconcileSessionWatch(sessionId, "metadata-watch").catch(() => void 0);
|
|
134565
134761
|
}, {
|
|
134566
134762
|
kinds: [
|
|
134567
134763
|
"doc-metadata"
|
|
134568
134764
|
]
|
|
134569
134765
|
});
|
|
134766
|
+
this.startupBootstrapTimer = setTimeout(() => {
|
|
134767
|
+
this.startupBootstrapTimer = null;
|
|
134768
|
+
if (this.started) {
|
|
134769
|
+
this.enqueueBootstrap("startup");
|
|
134770
|
+
}
|
|
134771
|
+
}, 0);
|
|
134772
|
+
this.startupBootstrapTimer.unref?.();
|
|
134570
134773
|
}
|
|
134571
134774
|
stop() {
|
|
134775
|
+
if (this.startupBootstrapTimer) {
|
|
134776
|
+
clearTimeout(this.startupBootstrapTimer);
|
|
134777
|
+
this.startupBootstrapTimer = null;
|
|
134778
|
+
}
|
|
134572
134779
|
this.metadataWatchHandle?.unsubscribe();
|
|
134573
134780
|
this.metadataWatchHandle = null;
|
|
134574
134781
|
this.detachMetaRoomSyncedListener?.();
|
|
@@ -134633,6 +134840,13 @@ $mem | ConvertTo-Json -Compress
|
|
|
134633
134840
|
return;
|
|
134634
134841
|
}
|
|
134635
134842
|
await this.bootstrapOwnedSessions(reason);
|
|
134843
|
+
if (reason === "startup" && this.started) {
|
|
134844
|
+
this.deps.onStartupBootstrapComplete?.();
|
|
134845
|
+
}
|
|
134846
|
+
}).catch((error2) => {
|
|
134847
|
+
this.deps.logger.error(`[dispatch] Owned-session bootstrap failed (reason=${reason}): ${formatErrorMessage(error2, {
|
|
134848
|
+
includeStack: true
|
|
134849
|
+
})}`);
|
|
134636
134850
|
});
|
|
134637
134851
|
this.bootstrapChain = next2;
|
|
134638
134852
|
}
|
|
@@ -134647,11 +134861,20 @@ $mem | ConvertTo-Json -Compress
|
|
|
134647
134861
|
this.deps.logger.debug(`[dispatch] Scanning owned sessions (reason=${reason})`);
|
|
134648
134862
|
const flock = getMeta();
|
|
134649
134863
|
const sessionRoomIds = /* @__PURE__ */ new Set();
|
|
134650
|
-
|
|
134651
|
-
|
|
134652
|
-
|
|
134653
|
-
|
|
134654
|
-
|
|
134864
|
+
let rows;
|
|
134865
|
+
try {
|
|
134866
|
+
rows = await flock.scan({
|
|
134867
|
+
prefix: [
|
|
134868
|
+
"m"
|
|
134869
|
+
]
|
|
134870
|
+
});
|
|
134871
|
+
} catch (error2) {
|
|
134872
|
+
this.deps.logger.error(`[dispatch] Failed to scan owned sessions (reason=${reason}): ${formatErrorMessage(error2, {
|
|
134873
|
+
includeStack: true
|
|
134874
|
+
})}`);
|
|
134875
|
+
return;
|
|
134876
|
+
}
|
|
134877
|
+
for (const row of rows) {
|
|
134655
134878
|
const key2 = row.key;
|
|
134656
134879
|
if (!Array.isArray(key2) || key2.length < 2) {
|
|
134657
134880
|
continue;
|
|
@@ -134661,58 +134884,83 @@ $mem | ConvertTo-Json -Compress
|
|
|
134661
134884
|
sessionRoomIds.add(roomId);
|
|
134662
134885
|
}
|
|
134663
134886
|
}
|
|
134887
|
+
this.deps.logger.debug(`[dispatch] Found ${sessionRoomIds.size} session room(s) during owned-session scan (reason=${reason})`);
|
|
134664
134888
|
if (!this.started) {
|
|
134665
134889
|
return;
|
|
134666
134890
|
}
|
|
134667
|
-
await Promise.all(
|
|
134891
|
+
const reconcileFailures = await Promise.all([
|
|
134892
|
+
...sessionRoomIds
|
|
134893
|
+
].map(async (roomId) => {
|
|
134668
134894
|
if (!this.started) {
|
|
134669
|
-
return;
|
|
134895
|
+
return false;
|
|
134670
134896
|
}
|
|
134671
134897
|
const sessionId = roomId.slice(SESSION_DOC_PREFIX.length);
|
|
134672
|
-
|
|
134898
|
+
try {
|
|
134899
|
+
await this.reconcileSessionWatch(sessionId, `bootstrap:${reason}`);
|
|
134900
|
+
return false;
|
|
134901
|
+
} catch {
|
|
134902
|
+
return true;
|
|
134903
|
+
}
|
|
134673
134904
|
}));
|
|
134905
|
+
const failedCount = reconcileFailures.filter(Boolean).length;
|
|
134906
|
+
if (failedCount > 0) {
|
|
134907
|
+
this.deps.logger.warn(`[dispatch] Owned-session bootstrap completed with ${failedCount}/${sessionRoomIds.size} session reconcile failure(s) (reason=${reason})`);
|
|
134908
|
+
}
|
|
134674
134909
|
}
|
|
134675
|
-
async reconcileSessionWatch(sessionId) {
|
|
134910
|
+
async reconcileSessionWatch(sessionId, trigger) {
|
|
134676
134911
|
const roomId = getSessionRoomId(sessionId);
|
|
134677
|
-
|
|
134678
|
-
|
|
134679
|
-
|
|
134680
|
-
|
|
134681
|
-
|
|
134682
|
-
|
|
134683
|
-
|
|
134684
|
-
|
|
134685
|
-
|
|
134686
|
-
this.cancelSeenTurn.delete(sessionId);
|
|
134687
|
-
this.goalCommandSeenId.delete(sessionId);
|
|
134688
|
-
this.interruptAccessRetry(sessionId);
|
|
134689
|
-
return;
|
|
134690
|
-
}
|
|
134691
|
-
if (!this.sessionNeedsActiveWatch(meta)) {
|
|
134692
|
-
const watched = this.watchedSessions.get(sessionId);
|
|
134693
|
-
if (watched) {
|
|
134694
|
-
watched.unsubscribe();
|
|
134912
|
+
let phase = "read-doc-meta";
|
|
134913
|
+
try {
|
|
134914
|
+
const record2 = await this.deps.workspaceDocument.repo.getDocMeta(roomId);
|
|
134915
|
+
const meta = isLoroRepoDocDeleted(record2) ? void 0 : record2?.meta;
|
|
134916
|
+
phase = "evaluate-ownership";
|
|
134917
|
+
const isOwned = meta?.machineId === this.deps.machineId && !meta?.isArchived;
|
|
134918
|
+
if (!isOwned) {
|
|
134919
|
+
const watched = this.watchedSessions.get(sessionId);
|
|
134920
|
+
watched?.unsubscribe();
|
|
134695
134921
|
this.watchedSessions.delete(sessionId);
|
|
134696
|
-
this.
|
|
134922
|
+
this.cancelCheckChains.delete(sessionId);
|
|
134923
|
+
this.goalCommandCheckChains.delete(sessionId);
|
|
134924
|
+
this.cancelSeenTurn.delete(sessionId);
|
|
134925
|
+
this.goalCommandSeenId.delete(sessionId);
|
|
134926
|
+
this.interruptAccessRetry(sessionId);
|
|
134927
|
+
return;
|
|
134697
134928
|
}
|
|
134698
|
-
|
|
134699
|
-
|
|
134700
|
-
|
|
134701
|
-
|
|
134702
|
-
|
|
134703
|
-
|
|
134704
|
-
|
|
134705
|
-
|
|
134706
|
-
|
|
134707
|
-
|
|
134708
|
-
|
|
134709
|
-
|
|
134929
|
+
phase = "evaluate-active-watch";
|
|
134930
|
+
if (!this.sessionNeedsActiveWatch(meta)) {
|
|
134931
|
+
const watched = this.watchedSessions.get(sessionId);
|
|
134932
|
+
if (watched) {
|
|
134933
|
+
watched.unsubscribe();
|
|
134934
|
+
this.watchedSessions.delete(sessionId);
|
|
134935
|
+
this.deps.logger.debug(`[${sessionId}] Unwatching idle session (no pending work)`);
|
|
134936
|
+
}
|
|
134937
|
+
this.interruptAccessRetry(sessionId);
|
|
134938
|
+
return;
|
|
134939
|
+
}
|
|
134940
|
+
if (!this.watchedSessions.has(sessionId)) {
|
|
134941
|
+
phase = "open-session-doc";
|
|
134942
|
+
const sessionDoc = await this.deps.workspaceDocument.getOrCreateSessionDoc(sessionId);
|
|
134943
|
+
phase = "subscribe-session-doc";
|
|
134944
|
+
const unsubscribe2 = sessionDoc.mirror?.subscribe(() => {
|
|
134945
|
+
this.enqueueGoalCommandCheck(sessionId);
|
|
134946
|
+
this.enqueueSessionCheck(sessionId);
|
|
134710
134947
|
});
|
|
134948
|
+
if (unsubscribe2) {
|
|
134949
|
+
this.watchedSessions.set(sessionId, {
|
|
134950
|
+
unsubscribe: unsubscribe2
|
|
134951
|
+
});
|
|
134952
|
+
}
|
|
134711
134953
|
}
|
|
134954
|
+
phase = "enqueue-session-checks";
|
|
134955
|
+
this.enqueueCancelCheck(sessionId);
|
|
134956
|
+
this.enqueueGoalCommandCheck(sessionId);
|
|
134957
|
+
this.enqueueSessionCheck(sessionId);
|
|
134958
|
+
} catch (error2) {
|
|
134959
|
+
this.deps.logger.error(`[dispatch] Failed to reconcile session watch (sessionId=${sessionId}, roomId=${roomId}, trigger=${trigger}, phase=${phase}): ${formatErrorMessage(error2, {
|
|
134960
|
+
includeStack: true
|
|
134961
|
+
})}`);
|
|
134962
|
+
throw error2;
|
|
134712
134963
|
}
|
|
134713
|
-
this.enqueueCancelCheck(sessionId);
|
|
134714
|
-
this.enqueueGoalCommandCheck(sessionId);
|
|
134715
|
-
this.enqueueSessionCheck(sessionId);
|
|
134716
134964
|
}
|
|
134717
134965
|
sessionNeedsActiveWatch(meta) {
|
|
134718
134966
|
const statusType = meta.status?.type;
|
|
@@ -143563,6 +143811,71 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
143563
143811
|
function delay$1(ms2) {
|
|
143564
143812
|
return new Promise((resolve2) => setTimeout(resolve2, ms2));
|
|
143565
143813
|
}
|
|
143814
|
+
function getMachineCommandEventImpact(events) {
|
|
143815
|
+
let archive = false;
|
|
143816
|
+
let deleteCommand = false;
|
|
143817
|
+
for (const event of events) {
|
|
143818
|
+
const parsed = parseMachineFlockKey(event.key);
|
|
143819
|
+
if (parsed?.kind === "archiveSessionCommand") {
|
|
143820
|
+
archive = true;
|
|
143821
|
+
}
|
|
143822
|
+
if (parsed?.kind === "deleteSessionCommand") {
|
|
143823
|
+
archive = true;
|
|
143824
|
+
deleteCommand = true;
|
|
143825
|
+
}
|
|
143826
|
+
}
|
|
143827
|
+
return {
|
|
143828
|
+
archive,
|
|
143829
|
+
delete: deleteCommand
|
|
143830
|
+
};
|
|
143831
|
+
}
|
|
143832
|
+
function getMachineFlockArchiveSessionIds(rows) {
|
|
143833
|
+
const sessionIds = [];
|
|
143834
|
+
for (const row of Object.values(rows)) {
|
|
143835
|
+
const parsed = parseMachineFlockKey(row.key);
|
|
143836
|
+
if (parsed?.kind === "archiveSessionCommand") {
|
|
143837
|
+
sessionIds.push(parsed.sessionId);
|
|
143838
|
+
}
|
|
143839
|
+
}
|
|
143840
|
+
return sessionIds;
|
|
143841
|
+
}
|
|
143842
|
+
function getMachineFlockDeleteEntries(rows) {
|
|
143843
|
+
const entries = [];
|
|
143844
|
+
for (const row of Object.values(rows)) {
|
|
143845
|
+
const parsed = parseMachineFlockKey(row.key);
|
|
143846
|
+
if (parsed?.kind === "deleteSessionCommand") {
|
|
143847
|
+
entries.push([
|
|
143848
|
+
parsed.sessionId,
|
|
143849
|
+
row.value
|
|
143850
|
+
]);
|
|
143851
|
+
}
|
|
143852
|
+
}
|
|
143853
|
+
return entries;
|
|
143854
|
+
}
|
|
143855
|
+
function buildMachineCommandSnapshot(machineMeta, machineFlockRows) {
|
|
143856
|
+
const needToArchiveSessions = machineMeta?.needToArchiveSessions ?? {};
|
|
143857
|
+
const archiveSessionIds = Array.from(/* @__PURE__ */ new Set([
|
|
143858
|
+
...Object.keys(needToArchiveSessions),
|
|
143859
|
+
...getMachineFlockArchiveSessionIds(machineFlockRows)
|
|
143860
|
+
]));
|
|
143861
|
+
const entriesBySessionId = /* @__PURE__ */ new Map();
|
|
143862
|
+
for (const [sessionId, request] of getMachineFlockDeleteEntries(machineFlockRows)) {
|
|
143863
|
+
entriesBySessionId.set(sessionId, request);
|
|
143864
|
+
}
|
|
143865
|
+
for (const [sessionId, request] of Object.entries(machineMeta?.needToDeleteSessions ?? {})) {
|
|
143866
|
+
if (!entriesBySessionId.has(sessionId)) {
|
|
143867
|
+
entriesBySessionId.set(sessionId, request);
|
|
143868
|
+
}
|
|
143869
|
+
}
|
|
143870
|
+
const deleteEntries = Array.from(entriesBySessionId.entries());
|
|
143871
|
+
return {
|
|
143872
|
+
machineMeta,
|
|
143873
|
+
machineFlockRows,
|
|
143874
|
+
archiveSessionIds,
|
|
143875
|
+
deleteEntries,
|
|
143876
|
+
deleteSessionIds: new Set(deleteEntries.map(([sessionId]) => sessionId))
|
|
143877
|
+
};
|
|
143878
|
+
}
|
|
143566
143879
|
function formatLiveActivityUpdatedAt(value, nowMs2) {
|
|
143567
143880
|
if (!Number.isFinite(value) || value <= 0) return "";
|
|
143568
143881
|
const elapsedMs = Math.max(0, nowMs2 - value);
|
|
@@ -143893,6 +144206,13 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
143893
144206
|
}
|
|
143894
144207
|
},
|
|
143895
144208
|
recordChatFailure: async (sessionDoc, reason, message) => await this.recordChatFailure(sessionDoc, reason, message),
|
|
144209
|
+
onStartupBootstrapComplete: () => {
|
|
144210
|
+
void this.resetMachineDisconnectedSessionsToIdle().catch((error2) => {
|
|
144211
|
+
this.logger.debug(`[dispatch] Failed to reset stale sessions after startup bootstrap: ${formatErrorMessage(error2, {
|
|
144212
|
+
includeStack: true
|
|
144213
|
+
})}`);
|
|
144214
|
+
});
|
|
144215
|
+
},
|
|
143896
144216
|
onFatalAuthFailure: (error2) => this.onFatalAuthFailure?.(error2)
|
|
143897
144217
|
});
|
|
143898
144218
|
this.setupSessionEventHandlers();
|
|
@@ -143917,6 +144237,9 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
143917
144237
|
archiveInFlight = /* @__PURE__ */ new Set();
|
|
143918
144238
|
deleteWatchHandle = null;
|
|
143919
144239
|
deleteInFlight = /* @__PURE__ */ new Set();
|
|
144240
|
+
machineFlockCommandWatcherPromise = null;
|
|
144241
|
+
machineFlockCommandUnsubscribe = null;
|
|
144242
|
+
machineFlockCommandRoomSub = null;
|
|
143920
144243
|
sessionFileBackfillInFlight = /* @__PURE__ */ new Set();
|
|
143921
144244
|
sessionFileBackfillStopped = false;
|
|
143922
144245
|
detachCodeCollabMetaRoomSyncedListener = null;
|
|
@@ -145392,6 +145715,104 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
145392
145715
|
})();
|
|
145393
145716
|
});
|
|
145394
145717
|
}
|
|
145718
|
+
getMachineFlockDocIdForMachine() {
|
|
145719
|
+
return getMachineFlockDocId(this.workspaceId, this.machineId);
|
|
145720
|
+
}
|
|
145721
|
+
getMachineFlockLogContext() {
|
|
145722
|
+
const docId = this.getMachineFlockDocIdForMachine();
|
|
145723
|
+
return `workspaceId=${this.workspaceId}, machineId=${this.machineId}, docId=${docId}`;
|
|
145724
|
+
}
|
|
145725
|
+
setupMachineFlockCommandWatcher() {
|
|
145726
|
+
if (this.machineFlockCommandWatcherPromise) {
|
|
145727
|
+
return;
|
|
145728
|
+
}
|
|
145729
|
+
const flockDocId = this.getMachineFlockDocIdForMachine();
|
|
145730
|
+
const flockContext = this.getMachineFlockLogContext();
|
|
145731
|
+
this.machineFlockCommandWatcherPromise = (async () => {
|
|
145732
|
+
const handle = await this.workspaceDocument.repo.openFlockDoc(flockDocId);
|
|
145733
|
+
this.machineFlockCommandUnsubscribe = handle.flock.subscribe((batch) => {
|
|
145734
|
+
const events = batch.events ?? [];
|
|
145735
|
+
const impact = getMachineCommandEventImpact(events);
|
|
145736
|
+
if (impact.archive) {
|
|
145737
|
+
void this.processArchiveRequests();
|
|
145738
|
+
}
|
|
145739
|
+
if (impact.delete) {
|
|
145740
|
+
void this.processDeleteRequests();
|
|
145741
|
+
}
|
|
145742
|
+
});
|
|
145743
|
+
this.machineFlockCommandRoomSub = await handle.joinRoom();
|
|
145744
|
+
void this.machineFlockCommandRoomSub.firstSyncedWithRemote.then(() => {
|
|
145745
|
+
void this.processArchiveRequests();
|
|
145746
|
+
void this.processDeleteRequests();
|
|
145747
|
+
}, (error2) => {
|
|
145748
|
+
this.logger.debug(`[machine-flock] Command room initial sync failed (${flockContext}): ${formatErrorMessage(error2, {
|
|
145749
|
+
includeStack: true
|
|
145750
|
+
})}`);
|
|
145751
|
+
});
|
|
145752
|
+
this.logger.debug(`[machine-flock] Command watcher registered (${flockContext})`);
|
|
145753
|
+
void this.processArchiveRequests();
|
|
145754
|
+
void this.processDeleteRequests();
|
|
145755
|
+
})().catch((error2) => {
|
|
145756
|
+
this.machineFlockCommandWatcherPromise = null;
|
|
145757
|
+
this.logger.error(`[machine-flock] Failed to start command watcher (${flockContext}): ${formatErrorMessage(error2, {
|
|
145758
|
+
includeStack: true
|
|
145759
|
+
})}`);
|
|
145760
|
+
});
|
|
145761
|
+
}
|
|
145762
|
+
async readMachineFlockCommandRows() {
|
|
145763
|
+
const handle = await this.workspaceDocument.repo.openFlockDoc(this.getMachineFlockDocIdForMachine());
|
|
145764
|
+
return readMachineFlockRowsFromFlock(handle.flock);
|
|
145765
|
+
}
|
|
145766
|
+
async tryReadMachineFlockCommandRows() {
|
|
145767
|
+
try {
|
|
145768
|
+
return await this.readMachineFlockCommandRows();
|
|
145769
|
+
} catch (error2) {
|
|
145770
|
+
this.logger.debug(`[machine-flock] Failed to read command rows; falling back to machine meta queues (${this.getMachineFlockLogContext()}): ${formatErrorMessage(error2, {
|
|
145771
|
+
includeStack: true
|
|
145772
|
+
})}`);
|
|
145773
|
+
return {};
|
|
145774
|
+
}
|
|
145775
|
+
}
|
|
145776
|
+
async readMachineCommandSnapshot() {
|
|
145777
|
+
const machineRoomId = getMachineRoomId(this.machineId);
|
|
145778
|
+
const [machineMetaDoc, machineFlockRows] = await Promise.all([
|
|
145779
|
+
this.workspaceDocument.repo.getDocMeta(machineRoomId),
|
|
145780
|
+
this.tryReadMachineFlockCommandRows()
|
|
145781
|
+
]);
|
|
145782
|
+
return buildMachineCommandSnapshot(machineMetaDoc?.meta, machineFlockRows);
|
|
145783
|
+
}
|
|
145784
|
+
async deleteMachineFlockCommandRow(key2, nowMs2 = getServerNow()) {
|
|
145785
|
+
const handle = await this.workspaceDocument.repo.openFlockDoc(this.getMachineFlockDocIdForMachine());
|
|
145786
|
+
const changed = deleteMachineFlockRowFromFlock(handle.flock, key2, nowMs2);
|
|
145787
|
+
if (!changed) {
|
|
145788
|
+
return false;
|
|
145789
|
+
}
|
|
145790
|
+
await this.workspaceDocument.repo.flush();
|
|
145791
|
+
await handle.syncOnce();
|
|
145792
|
+
return true;
|
|
145793
|
+
}
|
|
145794
|
+
async writeMachineFlockRow(row, nowMs2 = getServerNow()) {
|
|
145795
|
+
const handle = await this.workspaceDocument.repo.openFlockDoc(this.getMachineFlockDocIdForMachine());
|
|
145796
|
+
const changed = writeMachineFlockRowToFlock(handle.flock, row, nowMs2);
|
|
145797
|
+
if (!changed) {
|
|
145798
|
+
return false;
|
|
145799
|
+
}
|
|
145800
|
+
await this.workspaceDocument.repo.flush();
|
|
145801
|
+
await handle.syncOnce();
|
|
145802
|
+
return true;
|
|
145803
|
+
}
|
|
145804
|
+
async publishMachineDotlodyPath() {
|
|
145805
|
+
try {
|
|
145806
|
+
await this.writeMachineFlockRow({
|
|
145807
|
+
key: machineFlockKeys.dotlodyPath(),
|
|
145808
|
+
value: path__default.join(os__default.homedir(), ".lody")
|
|
145809
|
+
});
|
|
145810
|
+
} catch (error2) {
|
|
145811
|
+
this.logger.debug(`[machine-flock] Failed to publish dotlodyPath (${this.getMachineFlockLogContext()}): ${formatErrorMessage(error2, {
|
|
145812
|
+
includeStack: true
|
|
145813
|
+
})}`);
|
|
145814
|
+
}
|
|
145815
|
+
}
|
|
145395
145816
|
setupArchiveWatcher() {
|
|
145396
145817
|
if (this.archiveWatchHandle) {
|
|
145397
145818
|
return;
|
|
@@ -149242,7 +149663,6 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
149242
149663
|
await this.handler.registerMachine();
|
|
149243
149664
|
void this.handler.ensureMachineRegistered();
|
|
149244
149665
|
await this.handler.startSessionDispatchWatcher();
|
|
149245
|
-
void this.handler.resetMachineDisconnectedSessionsToIdle();
|
|
149246
149666
|
void this.handler.scanAndBackfillLocalSessionFiles();
|
|
149247
149667
|
this.options.logger.debug("Machine runtime initialized");
|
|
149248
149668
|
return {
|
|
@@ -158992,7 +159412,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
158992
159412
|
throw error2;
|
|
158993
159413
|
}
|
|
158994
159414
|
})().catch((error2) => {
|
|
158995
|
-
const message = `[fleet] Failed to start workspace runtime ${workspace.id}: ${formatErrorMessage(error2
|
|
159415
|
+
const message = `[fleet] Failed to start workspace runtime ${workspace.id}: ${formatErrorMessage(error2, {
|
|
159416
|
+
includeStack: true
|
|
159417
|
+
})}`;
|
|
158996
159418
|
this.logger.warn(message);
|
|
158997
159419
|
this.runtimeStateReporter.upsertIssue({
|
|
158998
159420
|
code: `workspace_start_failed:${workspace.id}`,
|
|
@@ -191902,7 +192324,7 @@ ${entry.text}`).join("\n\n");
|
|
|
191902
192324
|
data = createReviewBundleSnapshot(bundle);
|
|
191903
192325
|
}
|
|
191904
192326
|
const { injectReviewSnapshot } = await import("./chunks/index-v46gaGAl.js");
|
|
191905
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-
|
|
192327
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-DzrxfC5z.js");
|
|
191906
192328
|
const template = await resolveReviewViewerTemplate();
|
|
191907
192329
|
const html = injectReviewSnapshot(template, data);
|
|
191908
192330
|
const outputPath = options.output ? path__default$1.resolve(options.output) : defaultHtmlOutputPath(inputPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lody",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.66.0",
|
|
4
4
|
"description": "Lody Agent CLI tool for managing remote command execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=18.0.0"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"acp-extension-claude": "0.
|
|
23
|
+
"acp-extension-claude": "0.54.1",
|
|
24
24
|
"acp-extension-codex": "0.15.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"zod": "^4.1.5",
|
|
79
79
|
"@lody/cli-supervisor": "0.0.1",
|
|
80
80
|
"@lody/code-review-helper": "0.0.0",
|
|
81
|
-
"lody-code-review-viewer": "0.
|
|
81
|
+
"lody-code-review-viewer": "0.66.0",
|
|
82
82
|
"@lody/convex": "0.0.1",
|
|
83
83
|
"@lody/loro-streams-rpc": "0.0.1",
|
|
84
84
|
"@lody/shared": "0.0.1"
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"scripts": {
|
|
101
101
|
"dev": "node dev.mjs",
|
|
102
102
|
"dev:staging": "LODY_AUTH_URL=https://impressive-guineapig-165.convex.cloud LODY_AUTH_SITE_URL=https://impressive-guineapig-165.convex.site LODY_SERVER_URL=https://lody-server.zx-073.workers.dev SITE_URL=https://main.lody.pages.dev/ pnpm run dev",
|
|
103
|
-
"dev:prod": "LODY_AUTH_URL=https://
|
|
103
|
+
"dev:prod": "LODY_AUTH_URL=https://convex.lody.ai LODY_SERVER_URL=https://api.lody.ai pnpm run dev",
|
|
104
104
|
"build": "pnpm run clean && pnpm run typecheck && pnpm run build:bundle && pnpm run check:published-bundle-imports && pnpm run copy:wasm",
|
|
105
105
|
"build:watch": "pnpm run prepare:review-assets && vite build --watch",
|
|
106
106
|
"build:bundle": "pnpm run prepare:review-assets && vite build",
|