lody 0.96.1 → 0.97.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.
package/dist/index.js
CHANGED
|
@@ -506,7 +506,7 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
506
506
|
this._buckets = {};
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
|
-
const DIGITS
|
|
509
|
+
const DIGITS = "0123456789abcdef";
|
|
510
510
|
class UUID {
|
|
511
511
|
constructor(bytes2) {
|
|
512
512
|
this.bytes = bytes2;
|
|
@@ -568,8 +568,8 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
568
568
|
toString() {
|
|
569
569
|
let text = "";
|
|
570
570
|
for (let i2 = 0; i2 < this.bytes.length; i2++) {
|
|
571
|
-
text += DIGITS
|
|
572
|
-
text += DIGITS
|
|
571
|
+
text += DIGITS.charAt(this.bytes[i2] >>> 4);
|
|
572
|
+
text += DIGITS.charAt(15 & this.bytes[i2]);
|
|
573
573
|
if (3 === i2 || 5 === i2 || 7 === i2 || 9 === i2) text += "-";
|
|
574
574
|
}
|
|
575
575
|
return text;
|
|
@@ -577,8 +577,8 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
577
577
|
toHex() {
|
|
578
578
|
let text = "";
|
|
579
579
|
for (let i2 = 0; i2 < this.bytes.length; i2++) {
|
|
580
|
-
text += DIGITS
|
|
581
|
-
text += DIGITS
|
|
580
|
+
text += DIGITS.charAt(this.bytes[i2] >>> 4);
|
|
581
|
+
text += DIGITS.charAt(15 & this.bytes[i2]);
|
|
582
582
|
}
|
|
583
583
|
return text;
|
|
584
584
|
}
|
|
@@ -4326,7 +4326,7 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
4326
4326
|
}
|
|
4327
4327
|
const name$2 = "lody";
|
|
4328
4328
|
const name$1 = "@lody/cli-cloud";
|
|
4329
|
-
const version$a = "0.
|
|
4329
|
+
const version$a = "0.97.0";
|
|
4330
4330
|
const type$2 = "module";
|
|
4331
4331
|
const scripts = {
|
|
4332
4332
|
"dev": "node dev.mjs",
|
|
@@ -9701,9 +9701,6 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
9701
9701
|
mcpServerIds: schema.Any({
|
|
9702
9702
|
required: false
|
|
9703
9703
|
}),
|
|
9704
|
-
taskToolsEnabled: schema.Boolean({
|
|
9705
|
-
required: false
|
|
9706
|
-
}),
|
|
9707
9704
|
agentRoleId: agentRoleIdSchema,
|
|
9708
9705
|
agentRoleRevision: schema.Number({
|
|
9709
9706
|
required: false
|
|
@@ -11213,10 +11210,7 @@ Requirements:
|
|
|
11213
11210
|
config2.configOptionValues ? Object.entries(config2.configOptionValues).sort(([left2], [right2]) => left2.localeCompare(right2)) : null,
|
|
11214
11211
|
...config2.mcpServerIds === void 0 ? [] : [
|
|
11215
11212
|
normalizeMcpServerIdsForDedup(config2.mcpServerIds)
|
|
11216
|
-
]
|
|
11217
|
-
...config2.taskToolsEnabled === true ? [
|
|
11218
|
-
true
|
|
11219
|
-
] : []
|
|
11213
|
+
]
|
|
11220
11214
|
];
|
|
11221
11215
|
}
|
|
11222
11216
|
function normalizeSessionPreparationClaimIdentity(input2) {
|
|
@@ -11503,7 +11497,6 @@ Requirements:
|
|
|
11503
11497
|
modelId: string$1().optional(),
|
|
11504
11498
|
configOptionValues: AcpConfigOptionValuesSchema.optional(),
|
|
11505
11499
|
mcpServerIds: array$2(string$1()).optional(),
|
|
11506
|
-
taskToolsEnabled: boolean().optional(),
|
|
11507
11500
|
agentRoleId: string$1().trim().min(1).nullable().optional(),
|
|
11508
11501
|
agentRoleRevision: number$4().int().nonnegative().optional(),
|
|
11509
11502
|
issuePRMentions: array$2(IssuePRMentionSchema).optional(),
|
|
@@ -11578,10 +11571,6 @@ Requirements:
|
|
|
11578
11571
|
if (mcpServerIds) {
|
|
11579
11572
|
normalized.mcpServerIds = mcpServerIds;
|
|
11580
11573
|
}
|
|
11581
|
-
const taskToolsEnabled = maybeParseField(boolean(), record2.taskToolsEnabled);
|
|
11582
|
-
if (taskToolsEnabled !== void 0) {
|
|
11583
|
-
normalized.taskToolsEnabled = taskToolsEnabled;
|
|
11584
|
-
}
|
|
11585
11574
|
if (record2.agentRoleId === null) {
|
|
11586
11575
|
normalized.agentRoleId = null;
|
|
11587
11576
|
} else {
|
|
@@ -11926,8 +11915,7 @@ Requirements:
|
|
|
11926
11915
|
modeId: string$1().trim().min(1).optional(),
|
|
11927
11916
|
modelId: string$1().trim().min(1).optional(),
|
|
11928
11917
|
configOptionValues: AcpConfigOptionValuesSchema.transform((values) => Object.fromEntries(Object.entries(values).filter(([configId]) => !isSensitiveAcpConfigOptionId(configId)))).optional(),
|
|
11929
|
-
mcpServerIds: array$2(string$1()).transform((ids2) => normalizeMcpServerIdSelection(ids2) ?? []).optional()
|
|
11930
|
-
taskToolsEnabled: boolean().optional()
|
|
11918
|
+
mcpServerIds: array$2(string$1()).transform((ids2) => normalizeMcpServerIdSelection(ids2) ?? []).optional()
|
|
11931
11919
|
}).strict();
|
|
11932
11920
|
const SessionPreparationSpecSchema = object$1({
|
|
11933
11921
|
preparationId: SessionPreparationIdSchema,
|
|
@@ -14735,36 +14723,6 @@ Requirements:
|
|
|
14735
14723
|
}
|
|
14736
14724
|
return false;
|
|
14737
14725
|
}
|
|
14738
|
-
function resolveTaskProposalOnEntry(entry, proposalId, resolution) {
|
|
14739
|
-
const items2 = Array.isArray(entry.items) ? entry.items : [];
|
|
14740
|
-
for (const item of items2) {
|
|
14741
|
-
const notice = asRecord$3(item);
|
|
14742
|
-
if (notice?.type === "system_notice" && notice.name === "task_proposal" && asRecord$3(notice.meta)?.proposalId === proposalId) {
|
|
14743
|
-
const meta = asRecord$3(notice.meta);
|
|
14744
|
-
meta.outcome = resolution.outcome;
|
|
14745
|
-
if (resolution.taskId !== void 0) meta.taskId = resolution.taskId;
|
|
14746
|
-
return true;
|
|
14747
|
-
}
|
|
14748
|
-
}
|
|
14749
|
-
return false;
|
|
14750
|
-
}
|
|
14751
|
-
function hasTaskProposal(entry, proposalId) {
|
|
14752
|
-
const items2 = Array.isArray(entry.items) ? entry.items : [];
|
|
14753
|
-
return items2.some((item) => {
|
|
14754
|
-
const notice = asRecord$3(item);
|
|
14755
|
-
return notice?.type === "system_notice" && notice.name === "task_proposal" && asRecord$3(notice.meta)?.proposalId === proposalId;
|
|
14756
|
-
});
|
|
14757
|
-
}
|
|
14758
|
-
const TaskProposalResolutionSchema = object$1({
|
|
14759
|
-
outcome: _enum$1([
|
|
14760
|
-
"created",
|
|
14761
|
-
"dismissed"
|
|
14762
|
-
]),
|
|
14763
|
-
taskId: string$1().optional()
|
|
14764
|
-
}).strict();
|
|
14765
|
-
function parseTaskProposalResolution(value) {
|
|
14766
|
-
return parseHistoryWrite(TaskProposalResolutionSchema, value);
|
|
14767
|
-
}
|
|
14768
14726
|
function resolveEditableTail(turns, expectedUserTurnId) {
|
|
14769
14727
|
let userIndex = -1;
|
|
14770
14728
|
for (let index = turns.length - 1; index >= 0; index -= 1) {
|
|
@@ -15397,85 +15355,7 @@ Requirements:
|
|
|
15397
15355
|
const getLoroPreviewCommentStreamId = (workspaceId, sessionId) => `${workspaceId}:${LORO_PREVIEW_COMMENT_STREAM_SEGMENT}:${sessionId}`;
|
|
15398
15356
|
const TASK_DOC_PREFIX = "task-";
|
|
15399
15357
|
const LORO_TASK_STREAM_SEGMENT = "tk";
|
|
15400
|
-
const getTaskRoomId = (taskId) => `${TASK_DOC_PREFIX}${taskId}`;
|
|
15401
|
-
const isTaskDocRoomId = (roomId) => roomId.startsWith(TASK_DOC_PREFIX);
|
|
15402
|
-
const getTaskIdFromRoomId = (roomId) => isTaskDocRoomId(roomId) ? roomId.slice(TASK_DOC_PREFIX.length) : null;
|
|
15403
15358
|
const getLoroTaskStreamId = (workspaceId, taskId) => `${workspaceId}:${LORO_TASK_STREAM_SEGMENT}:${taskId}`;
|
|
15404
|
-
const TASK_STATUS_VALUES = [
|
|
15405
|
-
"backlog",
|
|
15406
|
-
"todo",
|
|
15407
|
-
"in_progress",
|
|
15408
|
-
"needs_review",
|
|
15409
|
-
"done",
|
|
15410
|
-
"canceled"
|
|
15411
|
-
];
|
|
15412
|
-
const TASK_PRIORITY_VALUES = [
|
|
15413
|
-
"urgent",
|
|
15414
|
-
"high",
|
|
15415
|
-
"medium",
|
|
15416
|
-
"low"
|
|
15417
|
-
];
|
|
15418
|
-
const TASK_LABEL_MAX_LENGTH = 32;
|
|
15419
|
-
const TASK_LABEL_MAX_COUNT = 10;
|
|
15420
|
-
const normalizeTaskLabel = (raw2) => raw2.trim().toLowerCase().slice(0, TASK_LABEL_MAX_LENGTH);
|
|
15421
|
-
const normalizeTaskLabels = (raw2) => {
|
|
15422
|
-
if (!raw2) return [];
|
|
15423
|
-
const seen = /* @__PURE__ */ new Set();
|
|
15424
|
-
for (const value of raw2) {
|
|
15425
|
-
const label2 = normalizeTaskLabel(value);
|
|
15426
|
-
if (label2) seen.add(label2);
|
|
15427
|
-
if (seen.size >= TASK_LABEL_MAX_COUNT) break;
|
|
15428
|
-
}
|
|
15429
|
-
return [
|
|
15430
|
-
...seen
|
|
15431
|
-
];
|
|
15432
|
-
};
|
|
15433
|
-
const TASK_TITLE_FALLBACK_MAX_LENGTH = 80;
|
|
15434
|
-
const deriveTaskTitle = (input2) => {
|
|
15435
|
-
const explicit = (input2.title ?? "").replace(/[\r\n]+/g, " ").trim();
|
|
15436
|
-
if (explicit) {
|
|
15437
|
-
return explicit;
|
|
15438
|
-
}
|
|
15439
|
-
const firstLine = (input2.body ?? "").split("\n").map((line3) => line3.trim()).find((line3) => line3.length > 0);
|
|
15440
|
-
if (!firstLine) {
|
|
15441
|
-
return "";
|
|
15442
|
-
}
|
|
15443
|
-
if (firstLine.length <= TASK_TITLE_FALLBACK_MAX_LENGTH) {
|
|
15444
|
-
return firstLine;
|
|
15445
|
-
}
|
|
15446
|
-
return `${firstLine.slice(0, TASK_TITLE_FALLBACK_MAX_LENGTH).trimEnd()}\u2026`;
|
|
15447
|
-
};
|
|
15448
|
-
const isEmptyTaskDraft = (input2) => (input2.title ?? "").trim().length === 0 && (input2.body ?? "").trim().length === 0;
|
|
15449
|
-
const getActiveTaskLinks = (links) => links.filter((link2) => link2.removedAt === void 0);
|
|
15450
|
-
const getActiveTaskSessionLinks = (links) => getActiveTaskLinks(links).filter((link2) => link2.kind === "session" && Boolean(link2.sessionId));
|
|
15451
|
-
const getActiveTaskPrLinks = (links) => getActiveTaskLinks(links).filter((link2) => link2.kind === "pr" && Boolean(link2.url));
|
|
15452
|
-
const summarizeTaskMentions = (timeline) => {
|
|
15453
|
-
let lastCommentAt;
|
|
15454
|
-
const mentioned = /* @__PURE__ */ new Set();
|
|
15455
|
-
for (const entry of timeline) {
|
|
15456
|
-
if (entry.kind !== "comment") {
|
|
15457
|
-
continue;
|
|
15458
|
-
}
|
|
15459
|
-
if (lastCommentAt === void 0 || entry.createdAt > lastCommentAt) {
|
|
15460
|
-
lastCommentAt = entry.createdAt;
|
|
15461
|
-
}
|
|
15462
|
-
for (const userId of entry.mentions ?? []) {
|
|
15463
|
-
if (userId) {
|
|
15464
|
-
mentioned.add(userId);
|
|
15465
|
-
}
|
|
15466
|
-
}
|
|
15467
|
-
}
|
|
15468
|
-
return {
|
|
15469
|
-
...lastCommentAt !== void 0 ? {
|
|
15470
|
-
lastCommentAt
|
|
15471
|
-
} : {},
|
|
15472
|
-
...mentioned.size > 0 ? {
|
|
15473
|
-
mentionedUserIds: [
|
|
15474
|
-
...mentioned
|
|
15475
|
-
]
|
|
15476
|
-
} : {}
|
|
15477
|
-
};
|
|
15478
|
-
};
|
|
15479
15359
|
const ACP_FAST_MODE_CONFIG_IDS = [
|
|
15480
15360
|
"fast-mode",
|
|
15481
15361
|
"fast"
|
|
@@ -15672,7 +15552,7 @@ Requirements:
|
|
|
15672
15552
|
}
|
|
15673
15553
|
const WORKSPACE_API_PATH_PREFIX = "/api/workspaces";
|
|
15674
15554
|
const SESSION_IMAGE_UPLOAD_API_PATH = "/session-images/upload";
|
|
15675
|
-
const trimTrailingSlash$
|
|
15555
|
+
const trimTrailingSlash$1 = (url) => {
|
|
15676
15556
|
if (!url.endsWith("/")) {
|
|
15677
15557
|
return url;
|
|
15678
15558
|
}
|
|
@@ -15685,14 +15565,8 @@ Requirements:
|
|
|
15685
15565
|
return `${WORKSPACE_API_PATH_PREFIX}/${encodeURIComponent(workspaceId)}/session-images/${encodeURIComponent(sessionId)}/${encodeURIComponent(imageId)}`;
|
|
15686
15566
|
};
|
|
15687
15567
|
const buildSessionImageApiUrl = (apiBaseUrl, apiPath) => {
|
|
15688
|
-
return `${trimTrailingSlash$
|
|
15689
|
-
};
|
|
15690
|
-
const TASK_IMAGE_UPLOAD_API_PATH = "/task-images/upload";
|
|
15691
|
-
const TASK_IMAGE_MARKDOWN_PROTOCOL = "lody-image://";
|
|
15692
|
-
const trimTrailingSlash$1 = (url) => url.endsWith("/") ? url.slice(0, -1) : url;
|
|
15693
|
-
const getTaskImageUploadApiPath = (workspaceId) => `/api/workspaces/${encodeURIComponent(workspaceId)}${TASK_IMAGE_UPLOAD_API_PATH}`;
|
|
15694
|
-
const buildTaskImageApiUrl = (apiBaseUrl, apiPath) => `${trimTrailingSlash$1(apiBaseUrl)}${apiPath}`;
|
|
15695
|
-
const buildTaskImageMarkdownUrl = (imageId) => `${TASK_IMAGE_MARKDOWN_PROTOCOL}${imageId}`;
|
|
15568
|
+
return `${trimTrailingSlash$1(apiBaseUrl)}${apiPath}`;
|
|
15569
|
+
};
|
|
15696
15570
|
const SESSION_FILE_OBJECT_PREFIX = "session-files";
|
|
15697
15571
|
const SESSION_FILE_PART_SIZE_BYTES = 16 * 1024 * 1024;
|
|
15698
15572
|
const trimTrailingSlash = (url) => {
|
|
@@ -22869,9 +22743,6 @@ ${tailedOutput}` : null;
|
|
|
22869
22743
|
...inputConfig.mcpServerIds ? {
|
|
22870
22744
|
mcpServerIds: inputConfig.mcpServerIds
|
|
22871
22745
|
} : {},
|
|
22872
|
-
...typeof inputConfig.taskToolsEnabled === "boolean" ? {
|
|
22873
|
-
taskToolsEnabled: inputConfig.taskToolsEnabled
|
|
22874
|
-
} : {},
|
|
22875
22746
|
...inputConfig.agentRoleId !== void 0 ? {
|
|
22876
22747
|
agentRoleId: inputConfig.agentRoleId
|
|
22877
22748
|
} : {},
|
|
@@ -22899,7 +22770,6 @@ ${tailedOutput}` : null;
|
|
|
22899
22770
|
return resolved;
|
|
22900
22771
|
};
|
|
22901
22772
|
const resolveSessionMcpSelection = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).mcpServerIds ?? [];
|
|
22902
|
-
const resolveSessionTaskToolsEnabled = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).taskToolsEnabled === true;
|
|
22903
22773
|
const normalizeTextInputBlock = (block) => {
|
|
22904
22774
|
const trimmed2 = block.text.trim();
|
|
22905
22775
|
if (!trimmed2) return null;
|
|
@@ -23141,9 +23011,6 @@ ${tailedOutput}` : null;
|
|
|
23141
23011
|
mcpServerIds: args2.mcpServerIds ? [
|
|
23142
23012
|
...args2.mcpServerIds
|
|
23143
23013
|
] : void 0,
|
|
23144
|
-
...args2.taskToolsEnabled !== void 0 ? {
|
|
23145
|
-
taskToolsEnabled: args2.taskToolsEnabled === true
|
|
23146
|
-
} : {},
|
|
23147
23014
|
...args2.agentRoleId !== void 0 ? {
|
|
23148
23015
|
agentRoleId: args2.agentRoleId
|
|
23149
23016
|
} : {},
|
|
@@ -23175,326 +23042,6 @@ ${tailedOutput}` : null;
|
|
|
23175
23042
|
finished: true
|
|
23176
23043
|
};
|
|
23177
23044
|
};
|
|
23178
|
-
const taskMetaSchema = schema.LoroMap({
|
|
23179
|
-
taskId: schema.String(),
|
|
23180
|
-
title: schema.String(),
|
|
23181
|
-
status: schema.String(),
|
|
23182
|
-
ownerId: schema.String(),
|
|
23183
|
-
order: schema.String(),
|
|
23184
|
-
priority: schema.String({
|
|
23185
|
-
required: false
|
|
23186
|
-
}),
|
|
23187
|
-
labels: schema.Any({
|
|
23188
|
-
required: false
|
|
23189
|
-
}),
|
|
23190
|
-
agent: schema.Any({
|
|
23191
|
-
required: false
|
|
23192
|
-
}),
|
|
23193
|
-
projects: schema.Any({
|
|
23194
|
-
required: false
|
|
23195
|
-
}),
|
|
23196
|
-
lastRunConfig: schema.Any({
|
|
23197
|
-
required: false
|
|
23198
|
-
}),
|
|
23199
|
-
createdAt: schema.Number(),
|
|
23200
|
-
updatedAt: schema.Number(),
|
|
23201
|
-
createdBy: schema.String({
|
|
23202
|
-
required: false
|
|
23203
|
-
})
|
|
23204
|
-
});
|
|
23205
|
-
const taskLinkSchema = schema.LoroMap({
|
|
23206
|
-
id: schema.String(),
|
|
23207
|
-
kind: schema.String(),
|
|
23208
|
-
actorKind: schema.String(),
|
|
23209
|
-
actorId: schema.String({
|
|
23210
|
-
required: false
|
|
23211
|
-
}),
|
|
23212
|
-
actorName: schema.String({
|
|
23213
|
-
required: false
|
|
23214
|
-
}),
|
|
23215
|
-
linkedAt: schema.Number(),
|
|
23216
|
-
removedAt: schema.Number({
|
|
23217
|
-
required: false
|
|
23218
|
-
}),
|
|
23219
|
-
sessionId: schema.String({
|
|
23220
|
-
required: false
|
|
23221
|
-
}),
|
|
23222
|
-
origin: schema.String({
|
|
23223
|
-
required: false
|
|
23224
|
-
}),
|
|
23225
|
-
parentSessionId: schema.String({
|
|
23226
|
-
required: false
|
|
23227
|
-
}),
|
|
23228
|
-
provider: schema.String({
|
|
23229
|
-
required: false
|
|
23230
|
-
}),
|
|
23231
|
-
url: schema.String({
|
|
23232
|
-
required: false
|
|
23233
|
-
}),
|
|
23234
|
-
originSessionId: schema.String({
|
|
23235
|
-
required: false
|
|
23236
|
-
})
|
|
23237
|
-
});
|
|
23238
|
-
const taskTimelineEntrySchema = schema.LoroMap({
|
|
23239
|
-
id: schema.String(),
|
|
23240
|
-
kind: schema.String(),
|
|
23241
|
-
actorKind: schema.String(),
|
|
23242
|
-
actorId: schema.String({
|
|
23243
|
-
required: false
|
|
23244
|
-
}),
|
|
23245
|
-
actorName: schema.String({
|
|
23246
|
-
required: false
|
|
23247
|
-
}),
|
|
23248
|
-
createdAt: schema.Number(),
|
|
23249
|
-
body: schema.String({
|
|
23250
|
-
required: false
|
|
23251
|
-
}),
|
|
23252
|
-
mentions: schema.LoroList(schema.String(), void 0, {
|
|
23253
|
-
required: false
|
|
23254
|
-
}),
|
|
23255
|
-
agentMentions: schema.LoroList(schema.String(), void 0, {
|
|
23256
|
-
required: false
|
|
23257
|
-
}),
|
|
23258
|
-
dispatchedSessionId: schema.String({
|
|
23259
|
-
required: false
|
|
23260
|
-
}),
|
|
23261
|
-
originSessionId: schema.String({
|
|
23262
|
-
required: false
|
|
23263
|
-
}),
|
|
23264
|
-
quote: schema.String({
|
|
23265
|
-
required: false
|
|
23266
|
-
}),
|
|
23267
|
-
anchor: schema.String({
|
|
23268
|
-
required: false
|
|
23269
|
-
}),
|
|
23270
|
-
activityType: schema.String({
|
|
23271
|
-
required: false
|
|
23272
|
-
}),
|
|
23273
|
-
activityData: schema.Any({
|
|
23274
|
-
required: false
|
|
23275
|
-
})
|
|
23276
|
-
});
|
|
23277
|
-
const taskDocSchema = schema({
|
|
23278
|
-
meta: taskMetaSchema,
|
|
23279
|
-
body: schema.LoroText(),
|
|
23280
|
-
links: schema.LoroList(taskLinkSchema, (item) => item.id),
|
|
23281
|
-
timeline: schema.LoroList(taskTimelineEntrySchema, (item) => item.id)
|
|
23282
|
-
});
|
|
23283
|
-
const TASK_INDEX_FLOCK_STREAM_SEGMENT = "ti";
|
|
23284
|
-
const getTaskIndexFlockDocId = (workspaceId) => `${workspaceId}:${TASK_INDEX_FLOCK_STREAM_SEGMENT}`;
|
|
23285
|
-
const TASK_INDEX_ROW_FAMILY = "task";
|
|
23286
|
-
const taskIndexKeys = {
|
|
23287
|
-
task: (taskId) => [
|
|
23288
|
-
TASK_INDEX_ROW_FAMILY,
|
|
23289
|
-
taskId
|
|
23290
|
-
]
|
|
23291
|
-
};
|
|
23292
|
-
const getTaskIndexScanPrefix = () => [
|
|
23293
|
-
TASK_INDEX_ROW_FAMILY
|
|
23294
|
-
];
|
|
23295
|
-
const TaskIndexRowSchema = object$1({
|
|
23296
|
-
taskId: string$1().trim().min(1),
|
|
23297
|
-
title: string$1(),
|
|
23298
|
-
status: _enum$1(TASK_STATUS_VALUES),
|
|
23299
|
-
ownerId: string$1(),
|
|
23300
|
-
order: string$1().min(1),
|
|
23301
|
-
priority: _enum$1(TASK_PRIORITY_VALUES).optional(),
|
|
23302
|
-
labels: array$2(string$1()).optional(),
|
|
23303
|
-
hasAgent: boolean().optional(),
|
|
23304
|
-
agentConfigId: string$1().optional(),
|
|
23305
|
-
projectKind: _enum$1([
|
|
23306
|
-
"local",
|
|
23307
|
-
"github"
|
|
23308
|
-
]).optional(),
|
|
23309
|
-
projectKey: string$1().optional(),
|
|
23310
|
-
ready: boolean().optional(),
|
|
23311
|
-
sessionCount: number$4().int().nonnegative().optional(),
|
|
23312
|
-
prCount: number$4().int().nonnegative().optional(),
|
|
23313
|
-
lastCommentAt: number$4().optional(),
|
|
23314
|
-
mentionedUserIds: array$2(string$1()).optional(),
|
|
23315
|
-
createdAt: number$4(),
|
|
23316
|
-
updatedAt: number$4(),
|
|
23317
|
-
deletedAt: number$4().optional()
|
|
23318
|
-
}).strip();
|
|
23319
|
-
const parseTaskIndexRow = (value) => {
|
|
23320
|
-
const parsed = TaskIndexRowSchema.safeParse(value);
|
|
23321
|
-
return parsed.success ? parsed.data : void 0;
|
|
23322
|
-
};
|
|
23323
|
-
const parseTaskIndexKey = (key2) => {
|
|
23324
|
-
if (key2.length !== 2) {
|
|
23325
|
-
return void 0;
|
|
23326
|
-
}
|
|
23327
|
-
if (key2[0] !== TASK_INDEX_ROW_FAMILY) {
|
|
23328
|
-
return void 0;
|
|
23329
|
-
}
|
|
23330
|
-
const taskId = key2[1];
|
|
23331
|
-
return typeof taskId === "string" && taskId.length > 0 ? taskId : void 0;
|
|
23332
|
-
};
|
|
23333
|
-
const readTaskIndexRows = (scanned) => {
|
|
23334
|
-
const rows = {};
|
|
23335
|
-
for (const row of scanned) {
|
|
23336
|
-
const taskId = parseTaskIndexKey(row.key);
|
|
23337
|
-
if (!taskId) {
|
|
23338
|
-
continue;
|
|
23339
|
-
}
|
|
23340
|
-
const parsed = parseTaskIndexRow(row.value);
|
|
23341
|
-
if (!parsed || parsed.taskId !== taskId) {
|
|
23342
|
-
continue;
|
|
23343
|
-
}
|
|
23344
|
-
rows[taskId] = parsed;
|
|
23345
|
-
}
|
|
23346
|
-
return rows;
|
|
23347
|
-
};
|
|
23348
|
-
const listVisibleTaskIndexRows = (rows) => Object.values(rows).filter((row) => row.deletedAt === void 0);
|
|
23349
|
-
const countTaskLinks = (links) => {
|
|
23350
|
-
let sessionCount = 0;
|
|
23351
|
-
let prCount = 0;
|
|
23352
|
-
for (const link2 of links) {
|
|
23353
|
-
if (link2.removedAt !== void 0) {
|
|
23354
|
-
continue;
|
|
23355
|
-
}
|
|
23356
|
-
if (link2.kind === "session") {
|
|
23357
|
-
sessionCount += 1;
|
|
23358
|
-
} else if (link2.kind === "pr") {
|
|
23359
|
-
prCount += 1;
|
|
23360
|
-
}
|
|
23361
|
-
}
|
|
23362
|
-
return {
|
|
23363
|
-
sessionCount,
|
|
23364
|
-
prCount
|
|
23365
|
-
};
|
|
23366
|
-
};
|
|
23367
|
-
const summarizeTaskProject = (projects) => {
|
|
23368
|
-
const first2 = projects?.[0];
|
|
23369
|
-
if (!first2) return {};
|
|
23370
|
-
if (first2.kind === "github" && first2.repoFullName) {
|
|
23371
|
-
return {
|
|
23372
|
-
projectKind: "github",
|
|
23373
|
-
projectKey: first2.repoFullName
|
|
23374
|
-
};
|
|
23375
|
-
}
|
|
23376
|
-
if (first2.kind === "local" && first2.localProjectId) {
|
|
23377
|
-
return {
|
|
23378
|
-
projectKind: "local",
|
|
23379
|
-
projectKey: first2.localProjectId
|
|
23380
|
-
};
|
|
23381
|
-
}
|
|
23382
|
-
return {};
|
|
23383
|
-
};
|
|
23384
|
-
const buildTaskIndexRow = (source, counts, mentions = {}) => ({
|
|
23385
|
-
taskId: source.taskId,
|
|
23386
|
-
title: source.title,
|
|
23387
|
-
status: source.status,
|
|
23388
|
-
ownerId: source.ownerId,
|
|
23389
|
-
order: source.order,
|
|
23390
|
-
...source.priority ? {
|
|
23391
|
-
priority: source.priority
|
|
23392
|
-
} : {},
|
|
23393
|
-
...source.labels && source.labels.length > 0 ? {
|
|
23394
|
-
labels: normalizeTaskLabels(source.labels)
|
|
23395
|
-
} : {},
|
|
23396
|
-
hasAgent: Boolean(source.agent),
|
|
23397
|
-
...source.agent ? {
|
|
23398
|
-
agentConfigId: source.agent.agentConfigId
|
|
23399
|
-
} : {},
|
|
23400
|
-
...summarizeTaskProject(source.projects),
|
|
23401
|
-
ready: source.agent ? (source.projects?.length ?? 0) > 0 : true,
|
|
23402
|
-
sessionCount: counts.sessionCount,
|
|
23403
|
-
prCount: counts.prCount,
|
|
23404
|
-
...mentions.lastCommentAt !== void 0 ? {
|
|
23405
|
-
lastCommentAt: mentions.lastCommentAt
|
|
23406
|
-
} : {},
|
|
23407
|
-
...mentions.mentionedUserIds && mentions.mentionedUserIds.length > 0 ? {
|
|
23408
|
-
mentionedUserIds: mentions.mentionedUserIds
|
|
23409
|
-
} : {},
|
|
23410
|
-
createdAt: source.createdAt,
|
|
23411
|
-
updatedAt: source.updatedAt
|
|
23412
|
-
});
|
|
23413
|
-
const DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
23414
|
-
const FIRST_DIGIT = DIGITS.charAt(0);
|
|
23415
|
-
const LAST_DIGIT = DIGITS.charAt(DIGITS.length - 1);
|
|
23416
|
-
const TASK_ORDER_MIN_KEY = DIGITS.charAt(1);
|
|
23417
|
-
const digitIndex = (digit) => {
|
|
23418
|
-
const index = digit === void 0 ? -1 : DIGITS.indexOf(digit);
|
|
23419
|
-
if (index < 0) {
|
|
23420
|
-
throw new Error(`invalid order key digit: ${digit}`);
|
|
23421
|
-
}
|
|
23422
|
-
return index;
|
|
23423
|
-
};
|
|
23424
|
-
const digitAt = (value, index) => {
|
|
23425
|
-
const digit = value[index];
|
|
23426
|
-
if (digit === void 0) {
|
|
23427
|
-
throw new Error(`order key index out of range: ${value}[${index}]`);
|
|
23428
|
-
}
|
|
23429
|
-
return digit;
|
|
23430
|
-
};
|
|
23431
|
-
const assertValidKey = (key2, label2) => {
|
|
23432
|
-
if (key2.length === 0) {
|
|
23433
|
-
throw new Error(`${label2} order key must not be empty`);
|
|
23434
|
-
}
|
|
23435
|
-
if (key2.endsWith(FIRST_DIGIT)) {
|
|
23436
|
-
throw new Error(`${label2} order key must not end with '${FIRST_DIGIT}': ${key2}`);
|
|
23437
|
-
}
|
|
23438
|
-
for (const digit of key2) {
|
|
23439
|
-
digitIndex(digit);
|
|
23440
|
-
}
|
|
23441
|
-
};
|
|
23442
|
-
const midpoint = (before, after2) => {
|
|
23443
|
-
const beforeDigit = before.length > 0 ? digitIndex(before[0]) : 0;
|
|
23444
|
-
const afterDigit = DIGITS.length;
|
|
23445
|
-
if (afterDigit - beforeDigit > 1) {
|
|
23446
|
-
return digitAt(DIGITS, Math.round((beforeDigit + afterDigit) / 2));
|
|
23447
|
-
}
|
|
23448
|
-
return digitAt(DIGITS, beforeDigit) + midpoint(before.slice(1));
|
|
23449
|
-
};
|
|
23450
|
-
const appendJitter = (key2, after2, random2) => {
|
|
23451
|
-
if (!random2) {
|
|
23452
|
-
return key2;
|
|
23453
|
-
}
|
|
23454
|
-
const value = random2();
|
|
23455
|
-
if (!Number.isFinite(value)) {
|
|
23456
|
-
return key2;
|
|
23457
|
-
}
|
|
23458
|
-
let highest = DIGITS.length - 1;
|
|
23459
|
-
if (highest < 1) {
|
|
23460
|
-
return key2;
|
|
23461
|
-
}
|
|
23462
|
-
const clamped = Math.min(Math.max(value, 0), 0.999999);
|
|
23463
|
-
const index = 1 + Math.floor(clamped * highest);
|
|
23464
|
-
return key2 + digitAt(DIGITS, Math.min(index, highest));
|
|
23465
|
-
};
|
|
23466
|
-
const generateTaskOrderKeyBetween = (before, after2, random2) => {
|
|
23467
|
-
if (before !== null) {
|
|
23468
|
-
assertValidKey(before, "before");
|
|
23469
|
-
}
|
|
23470
|
-
if (before === null && after2 === null) {
|
|
23471
|
-
return appendJitter(TASK_ORDER_MIN_KEY, null, random2);
|
|
23472
|
-
}
|
|
23473
|
-
if (before !== null && after2 === null) {
|
|
23474
|
-
const head2 = before.slice(0, -1);
|
|
23475
|
-
const tail2 = digitAt(before, before.length - 1);
|
|
23476
|
-
if (tail2 !== LAST_DIGIT) {
|
|
23477
|
-
return appendJitter(head2 + digitAt(DIGITS, digitIndex(tail2) + 1), null, random2);
|
|
23478
|
-
}
|
|
23479
|
-
return appendJitter(`${before}${digitAt(DIGITS, 1)}`, null, random2);
|
|
23480
|
-
}
|
|
23481
|
-
return appendJitter(midpoint(before), after2, random2);
|
|
23482
|
-
};
|
|
23483
|
-
const generateTaskOrderKeyAtEnd = (existingKeys, random2) => {
|
|
23484
|
-
let max2 = null;
|
|
23485
|
-
for (const key2 of existingKeys) {
|
|
23486
|
-
if (key2.length > 0 && (max2 === null || key2 > max2)) {
|
|
23487
|
-
max2 = key2;
|
|
23488
|
-
}
|
|
23489
|
-
}
|
|
23490
|
-
return generateTaskOrderKeyBetween(max2, null, random2);
|
|
23491
|
-
};
|
|
23492
|
-
const compareTaskOrder = (a, b) => {
|
|
23493
|
-
if (a.order !== b.order) {
|
|
23494
|
-
return a.order < b.order ? -1 : 1;
|
|
23495
|
-
}
|
|
23496
|
-
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
23497
|
-
};
|
|
23498
23045
|
const REVIEW_POLICY_FLOCK_STREAM_SEGMENT = "rp";
|
|
23499
23046
|
const getReviewPolicyFlockDocId = (workspaceId) => `${workspaceId}:${REVIEW_POLICY_FLOCK_STREAM_SEGMENT}`;
|
|
23500
23047
|
const REVIEW_POLICY_ROW_FAMILY = "policy";
|
|
@@ -66068,8 +65615,7 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
66068
65615
|
"cliType",
|
|
66069
65616
|
"agentType",
|
|
66070
65617
|
"mcpServerIds",
|
|
66071
|
-
"configOptionValues"
|
|
66072
|
-
"taskToolsEnabled"
|
|
65618
|
+
"configOptionValues"
|
|
66073
65619
|
];
|
|
66074
65620
|
const parseCursor = (cursor, total) => {
|
|
66075
65621
|
if (cursor === void 0) return total;
|
|
@@ -66351,95 +65897,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
66351
65897
|
})
|
|
66352
65898
|
});
|
|
66353
65899
|
}
|
|
66354
|
-
class HistoryActionRefused extends Error {
|
|
66355
|
-
constructor(code2, message) {
|
|
66356
|
-
super(message);
|
|
66357
|
-
this.code = code2;
|
|
66358
|
-
}
|
|
66359
|
-
}
|
|
66360
|
-
const sameActor = (current2, desired) => current2?.kind === desired?.kind && current2?.agentConfigId === desired?.agentConfigId && current2?.name === desired?.name;
|
|
66361
|
-
const samePendingProposal = (current2, desired) => current2.proposalId === desired.proposalId && current2.title === desired.title && current2.body === desired.body && current2.outcome === void 0 && current2.taskId === void 0 && sameActor(current2.proposedBy, desired.proposedBy);
|
|
66362
|
-
function planTaskProposal(history, turnId, desiredMeta, timestamp2) {
|
|
66363
|
-
const desiredItem = {
|
|
66364
|
-
type: "system_notice",
|
|
66365
|
-
name: "task_proposal",
|
|
66366
|
-
meta: desiredMeta
|
|
66367
|
-
};
|
|
66368
|
-
let changed = false;
|
|
66369
|
-
let result = {
|
|
66370
|
-
pending: true
|
|
66371
|
-
};
|
|
66372
|
-
const apply = () => {
|
|
66373
|
-
const existingIndex = history.findIndex((entry) => entry.id === turnId);
|
|
66374
|
-
if (existingIndex < 0) {
|
|
66375
|
-
changed = true;
|
|
66376
|
-
return [
|
|
66377
|
-
...history,
|
|
66378
|
-
{
|
|
66379
|
-
id: turnId,
|
|
66380
|
-
role: "system",
|
|
66381
|
-
timestamp: timestamp2,
|
|
66382
|
-
items: [
|
|
66383
|
-
desiredItem
|
|
66384
|
-
],
|
|
66385
|
-
fileDiff: [],
|
|
66386
|
-
finished: true
|
|
66387
|
-
}
|
|
66388
|
-
];
|
|
66389
|
-
}
|
|
66390
|
-
const existing = history[existingIndex];
|
|
66391
|
-
const proposalItemIndex = existing?.items?.findIndex((item) => item.type === "system_notice" && item.name === "task_proposal");
|
|
66392
|
-
const proposalItem = proposalItemIndex !== void 0 && proposalItemIndex >= 0 ? existing?.items?.[proposalItemIndex] : void 0;
|
|
66393
|
-
const existingMetaValue = proposalItem?.type === "system_notice" && proposalItem.name === "task_proposal" ? proposalItem.meta : void 0;
|
|
66394
|
-
const parsedExistingMeta = TaskProposalMetaSchema.safeParse(existingMetaValue);
|
|
66395
|
-
const existingMeta = parsedExistingMeta.success ? parsedExistingMeta.data : void 0;
|
|
66396
|
-
if (!existing || proposalItemIndex === void 0 || proposalItemIndex < 0 || !existingMeta) {
|
|
66397
|
-
throw new HistoryActionRefused("TASK_PROPOSAL_ID_CONFLICT", `History entry ${turnId} exists but is not a task proposal. Use a different proposalId.`);
|
|
66398
|
-
}
|
|
66399
|
-
if (existingMeta.proposalId !== desiredMeta.proposalId) {
|
|
66400
|
-
throw new HistoryActionRefused("TASK_PROPOSAL_ID_CONFLICT", `History entry ${turnId} belongs to a different proposal. Use a different proposalId.`);
|
|
66401
|
-
}
|
|
66402
|
-
if (existingMeta.outcome === "created") {
|
|
66403
|
-
result = {
|
|
66404
|
-
pending: false,
|
|
66405
|
-
outcome: "created",
|
|
66406
|
-
...existingMeta.taskId ? {
|
|
66407
|
-
taskId: existingMeta.taskId
|
|
66408
|
-
} : {}
|
|
66409
|
-
};
|
|
66410
|
-
return history;
|
|
66411
|
-
}
|
|
66412
|
-
if (existingMeta.outcome === "dismissed") {
|
|
66413
|
-
result = {
|
|
66414
|
-
pending: false,
|
|
66415
|
-
outcome: "dismissed"
|
|
66416
|
-
};
|
|
66417
|
-
return history;
|
|
66418
|
-
}
|
|
66419
|
-
if (samePendingProposal(existingMeta, desiredMeta)) {
|
|
66420
|
-
return history;
|
|
66421
|
-
}
|
|
66422
|
-
const items2 = [
|
|
66423
|
-
...existing.items ?? []
|
|
66424
|
-
];
|
|
66425
|
-
items2[proposalItemIndex] = desiredItem;
|
|
66426
|
-
const nextHistory = [
|
|
66427
|
-
...history
|
|
66428
|
-
];
|
|
66429
|
-
nextHistory[existingIndex] = {
|
|
66430
|
-
...existing,
|
|
66431
|
-
items: items2
|
|
66432
|
-
};
|
|
66433
|
-
changed = true;
|
|
66434
|
-
return nextHistory;
|
|
66435
|
-
};
|
|
66436
|
-
const turns = apply();
|
|
66437
|
-
return {
|
|
66438
|
-
turns,
|
|
66439
|
-
matched: changed,
|
|
66440
|
-
proposal: result
|
|
66441
|
-
};
|
|
66442
|
-
}
|
|
66443
65900
|
const sanitizeToolCallContentForHistory = (content, kind) => {
|
|
66444
65901
|
if (!content) return void 0;
|
|
66445
65902
|
const filtered = stripToolCallContentForHistory(kind ?? null, content);
|
|
@@ -66519,8 +65976,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
66519
65976
|
matched: turns !== history
|
|
66520
65977
|
};
|
|
66521
65978
|
}
|
|
66522
|
-
case "task-proposal":
|
|
66523
|
-
return planTaskProposal(history, action.turnId, action.meta, action.timestamp);
|
|
66524
65979
|
case "upsert-goal": {
|
|
66525
65980
|
let replaced = false;
|
|
66526
65981
|
for (const entry of history) entry.items = entry.items?.flatMap((item) => {
|
|
@@ -67075,7 +66530,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
67075
66530
|
const normalized = normalizeSessionTurnInputConfig({
|
|
67076
66531
|
mcpServerIds: picked.mcpServerIds,
|
|
67077
66532
|
configOptionValues: picked.configOptionValues,
|
|
67078
|
-
taskToolsEnabled: picked.taskToolsEnabled,
|
|
67079
66533
|
cliType: picked.cliType,
|
|
67080
66534
|
agentType: picked.agentType
|
|
67081
66535
|
});
|
|
@@ -67378,18 +66832,15 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
67378
66832
|
const commands = {
|
|
67379
66833
|
async applyHistoryAction(action) {
|
|
67380
66834
|
let matched = action.kind === "user-status" && action.requeueUndelivered === true;
|
|
67381
|
-
let proposal;
|
|
67382
66835
|
const apply = (entries) => {
|
|
67383
66836
|
const result = applyHistoryAction(entries, action);
|
|
67384
66837
|
matched = result.matched;
|
|
67385
|
-
proposal = result.proposal;
|
|
67386
66838
|
return result.turns;
|
|
67387
66839
|
};
|
|
67388
|
-
if (action.kind === "operation-progress"
|
|
66840
|
+
if (action.kind === "operation-progress") {
|
|
67389
66841
|
const preview = applyHistoryAction(writer.readStored(), action);
|
|
67390
66842
|
if (!preview.matched) return {
|
|
67391
|
-
matched: false
|
|
67392
|
-
proposal: preview.proposal
|
|
66843
|
+
matched: false
|
|
67393
66844
|
};
|
|
67394
66845
|
}
|
|
67395
66846
|
const target = historyActionTarget(action);
|
|
@@ -67398,8 +66849,7 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
67398
66849
|
])[0] ?? entry);
|
|
67399
66850
|
else writer.update(apply);
|
|
67400
66851
|
return {
|
|
67401
|
-
matched
|
|
67402
|
-
proposal
|
|
66852
|
+
matched
|
|
67403
66853
|
};
|
|
67404
66854
|
},
|
|
67405
66855
|
async appendTurn(turn) {
|
|
@@ -67425,17 +66875,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
67425
66875
|
]);
|
|
67426
66876
|
commit();
|
|
67427
66877
|
},
|
|
67428
|
-
async resolveTaskProposal(entryId, proposalId, resolution) {
|
|
67429
|
-
parseTaskProposalResolution(resolution);
|
|
67430
|
-
let found = false;
|
|
67431
|
-
writer.updateEntry(entryId, (entry) => {
|
|
67432
|
-
if (!hasTaskProposal(entry, proposalId)) return entry;
|
|
67433
|
-
resolveTaskProposalOnEntry(entry, proposalId, resolution);
|
|
67434
|
-
found = true;
|
|
67435
|
-
return entry;
|
|
67436
|
-
});
|
|
67437
|
-
return found;
|
|
67438
|
-
},
|
|
67439
66878
|
async respondPermission(requestId, outcome, respondOptions) {
|
|
67440
66879
|
parseHistoryWrite(PermissionOutcomeSchema, outcome);
|
|
67441
66880
|
return writer.respondPermission(requestId, outcome, respondOptions);
|
|
@@ -124140,7 +123579,6 @@ ${incoming}`).output;
|
|
|
124140
123579
|
const MCP_HTTP_SESSION_ID_HEADER = "x-lody-mcp-session-id";
|
|
124141
123580
|
const MCP_HTTP_WORKSPACE_ID_HEADER = "x-lody-mcp-workspace-id";
|
|
124142
123581
|
const MCP_HTTP_MACHINE_ID_HEADER = "x-lody-mcp-machine-id";
|
|
124143
|
-
const MCP_HTTP_TASK_TOOLS_ENABLED_HEADER = "x-lody-mcp-task-tools-enabled";
|
|
124144
123582
|
const MCP_HTTP_WORKDIR_B64_HEADER = "x-lody-mcp-workdir-b64";
|
|
124145
123583
|
const MCP_HTTP_TOKEN_ENV = "LODY_MCP_HTTP_TOKEN";
|
|
124146
123584
|
const MCP_HTTP_PREFERRED_PORT_ENV = "LODY_MCP_HTTP_PREFERRED_PORT";
|
|
@@ -124165,10 +123603,6 @@ ${incoming}`).output;
|
|
|
124165
123603
|
name: MCP_HTTP_MACHINE_ID_HEADER,
|
|
124166
123604
|
value: context2.machineId
|
|
124167
123605
|
},
|
|
124168
|
-
{
|
|
124169
|
-
name: MCP_HTTP_TASK_TOOLS_ENABLED_HEADER,
|
|
124170
|
-
value: context2.taskToolsEnabled ? "1" : "0"
|
|
124171
|
-
},
|
|
124172
123606
|
{
|
|
124173
123607
|
name: MCP_HTTP_WORKDIR_B64_HEADER,
|
|
124174
123608
|
value: Buffer.from(context2.workdir, "utf8").toString("base64url")
|
|
@@ -130083,8 +129517,7 @@ ${incoming}`).output;
|
|
|
130083
129517
|
sessionId: this.options.sessionId,
|
|
130084
129518
|
workspaceId: this.options.workspaceId,
|
|
130085
129519
|
machineId: this.options.machineId,
|
|
130086
|
-
workdir
|
|
130087
|
-
taskToolsEnabled: this.options.taskToolsEnabled === true
|
|
129520
|
+
workdir
|
|
130088
129521
|
})
|
|
130089
129522
|
}
|
|
130090
129523
|
];
|
|
@@ -130114,10 +129547,6 @@ ${incoming}`).output;
|
|
|
130114
129547
|
{
|
|
130115
129548
|
name: "LODY_MCP_WORKDIR",
|
|
130116
129549
|
value: workdir
|
|
130117
|
-
},
|
|
130118
|
-
{
|
|
130119
|
-
name: "LODY_MCP_TASK_TOOLS_ENABLED",
|
|
130120
|
-
value: this.options.taskToolsEnabled === true ? "1" : "0"
|
|
130121
129550
|
}
|
|
130122
129551
|
];
|
|
130123
129552
|
for (const [name2, value] of [
|
|
@@ -137047,7 +136476,6 @@ ${fallbackStderrTail}` : errorMessage2;
|
|
|
137047
136476
|
agentConfig: options.agentConfig,
|
|
137048
136477
|
configOptionValues: options.configOptionValues,
|
|
137049
136478
|
resolveWorktreeProject: options.resolveWorktreeProject,
|
|
137050
|
-
taskToolsEnabled: options.taskToolsEnabled,
|
|
137051
136479
|
launcher: options.launcher,
|
|
137052
136480
|
terminalEnabled: options.terminalEnabled,
|
|
137053
136481
|
onStartupStage: options.onStartupStage,
|
|
@@ -145234,7 +144662,6 @@ ${withCauses}`;
|
|
|
145234
144662
|
agentType: acpSessionConfig.agentType,
|
|
145235
144663
|
configOptionValues: acpSessionConfig.configOptionValues,
|
|
145236
144664
|
mcpServerIds: acpSessionConfig.mcpServerIds ?? [],
|
|
145237
|
-
taskToolsEnabled: acpSessionConfig.taskToolsEnabled === true,
|
|
145238
144665
|
customAcp: resumeCustomAcp,
|
|
145239
144666
|
runtimeOverrides: resumeRuntimeOverrides,
|
|
145240
144667
|
requesterUserId: userId,
|
|
@@ -145749,7 +145176,6 @@ ${withCauses}`;
|
|
|
145749
145176
|
agentType: acpSessionConfig.agentType,
|
|
145750
145177
|
configOptionValues: acpSessionConfig.configOptionValues,
|
|
145751
145178
|
mcpServerIds: acpSessionConfig.mcpServerIds ?? [],
|
|
145752
|
-
taskToolsEnabled: acpSessionConfig.taskToolsEnabled === true,
|
|
145753
145179
|
agentConfigId: existingMeta?.agentConfigId,
|
|
145754
145180
|
customAcp: acpSessionConfig.customAcp,
|
|
145755
145181
|
runtimeOverrides: acpSessionConfig.runtimeOverrides,
|
|
@@ -148260,7 +147686,6 @@ ${withCauses}`;
|
|
|
148260
147686
|
modelId: entry.inputConfig?.modelId,
|
|
148261
147687
|
configOptionValues: entry.inputConfig?.configOptionValues,
|
|
148262
147688
|
mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
|
|
148263
|
-
taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
|
|
148264
147689
|
agentRoleId: entry.inputConfig?.agentRoleId,
|
|
148265
147690
|
agentRoleRevision: entry.inputConfig?.agentRoleRevision,
|
|
148266
147691
|
issuePRMentions: entry.inputConfig?.issuePRMentions,
|
|
@@ -148295,7 +147720,6 @@ ${withCauses}`;
|
|
|
148295
147720
|
modelId: entry.inputConfig?.modelId,
|
|
148296
147721
|
configOptionValues: entry.inputConfig?.configOptionValues,
|
|
148297
147722
|
mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
|
|
148298
|
-
taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
|
|
148299
147723
|
agentRoleId: entry.inputConfig?.agentRoleId,
|
|
148300
147724
|
agentRoleRevision: entry.inputConfig?.agentRoleRevision,
|
|
148301
147725
|
issuePRMentions: entry.inputConfig?.issuePRMentions,
|
|
@@ -148369,7 +147793,6 @@ ${withCauses}`;
|
|
|
148369
147793
|
modelId: queuedItem.acpSessionConfig?.modelId,
|
|
148370
147794
|
configOptionValues: isConfigOptionValueRecord(queuedItem.acpSessionConfig?.configOptionValues) ? queuedItem.acpSessionConfig.configOptionValues : void 0,
|
|
148371
147795
|
mcpServerIds: normalizeMcpServerIdSelection(queuedItem.acpSessionConfig?.mcpServerIds) ?? [],
|
|
148372
|
-
taskToolsEnabled: queuedItem.acpSessionConfig?.taskToolsEnabled === true,
|
|
148373
147796
|
agentRoleId: queuedItem.acpSessionConfig?.agentRoleId,
|
|
148374
147797
|
agentRoleRevision: queuedItem.acpSessionConfig?.agentRoleRevision,
|
|
148375
147798
|
issuePRMentions: queuedItem.acpSessionConfig?.issuePRMentions,
|
|
@@ -149211,7 +148634,6 @@ ${withCauses}`;
|
|
|
149211
148634
|
agentCliType: marker.cleanup.cliType,
|
|
149212
148635
|
agentType: marker.cleanup.agentType,
|
|
149213
148636
|
mcpServerIds: resolveSessionMcpSelection(history),
|
|
149214
|
-
taskToolsEnabled: false,
|
|
149215
148637
|
project: marker.cleanup.project,
|
|
149216
148638
|
sessionId: targetSessionId,
|
|
149217
148639
|
githubRepo: marker.cleanup.repoFullName,
|
|
@@ -149563,7 +148985,6 @@ ${withCauses}`;
|
|
|
149563
148985
|
agentCliType: source.cliType,
|
|
149564
148986
|
agentType: source.agentType,
|
|
149565
148987
|
mcpServerIds: resolveSessionMcpSelection(historyResult.history),
|
|
149566
|
-
taskToolsEnabled: resolveSessionTaskToolsEnabled(historyResult.history),
|
|
149567
148988
|
customAcp: agentConfig.customAcp,
|
|
149568
148989
|
runtimeOverrides: agentConfig.runtimeOverrides,
|
|
149569
148990
|
env: agentConfig.env,
|
|
@@ -149657,7 +149078,6 @@ ${withCauses}`;
|
|
|
149657
149078
|
agentCliType: source.cliType,
|
|
149658
149079
|
agentType: source.agentType,
|
|
149659
149080
|
mcpServerIds: resolveSessionMcpSelection(historyResult.history),
|
|
149660
|
-
taskToolsEnabled: resolveSessionTaskToolsEnabled(historyResult.history),
|
|
149661
149081
|
customAcp: agentConfig.customAcp,
|
|
149662
149082
|
runtimeOverrides: agentConfig.runtimeOverrides,
|
|
149663
149083
|
env: agentConfig.env,
|
|
@@ -149815,7 +149235,7 @@ ${withCauses}`;
|
|
|
149815
149235
|
let commitEditable = editable;
|
|
149816
149236
|
let commitMeta = meta;
|
|
149817
149237
|
try {
|
|
149818
|
-
runtime = await this.getOrRestoreRuntime(meta, spec.requestedByUserId, resolveSessionMcpSelection(history)
|
|
149238
|
+
runtime = await this.getOrRestoreRuntime(meta, spec.requestedByUserId, resolveSessionMcpSelection(history));
|
|
149819
149239
|
const agentClient = runtime.agentClient;
|
|
149820
149240
|
oldAcpSessionId = runtime.acpSessionId;
|
|
149821
149241
|
if (!agentClient || !oldAcpSessionId) {
|
|
@@ -150006,7 +149426,7 @@ ${withCauses}`;
|
|
|
150006
149426
|
resume: preparedSessionId
|
|
150007
149427
|
};
|
|
150008
149428
|
}
|
|
150009
|
-
async getOrRestoreRuntime(meta, requestedByUserId, mcpServerIds
|
|
149429
|
+
async getOrRestoreRuntime(meta, requestedByUserId, mcpServerIds) {
|
|
150010
149430
|
const existing = this.deps.sessionManager.getSession(meta.id);
|
|
150011
149431
|
if (existing) return existing;
|
|
150012
149432
|
if (!meta.acpSessionId || !meta.agentConfigId) {
|
|
@@ -150027,7 +149447,6 @@ ${withCauses}`;
|
|
|
150027
149447
|
agentCliType: meta.cliType,
|
|
150028
149448
|
agentType: meta.agentType,
|
|
150029
149449
|
mcpServerIds,
|
|
150030
|
-
taskToolsEnabled,
|
|
150031
149450
|
customAcp: agentConfig.customAcp,
|
|
150032
149451
|
runtimeOverrides: agentConfig.runtimeOverrides,
|
|
150033
149452
|
env: agentConfig.env,
|
|
@@ -150080,9 +149499,8 @@ ${withCauses}`;
|
|
|
150080
149499
|
string$1(),
|
|
150081
149500
|
boolean()
|
|
150082
149501
|
])).optional(),
|
|
150083
|
-
taskToolsEnabled: boolean().optional(),
|
|
150084
149502
|
inheritSessionDefaults: literal$1(false).optional()
|
|
150085
|
-
}).
|
|
149503
|
+
}).strip().nullable()).optional()
|
|
150086
149504
|
}).strict();
|
|
150087
149505
|
const OperationRowSchema = object$1({
|
|
150088
149506
|
workspace_id: string$1(),
|
|
@@ -162757,510 +162175,6 @@ ${part.truncated ? TRUNCATION_MARKER : ""}${part.content}`).join("\n\n");
|
|
|
162757
162175
|
}
|
|
162758
162176
|
return table2.toString();
|
|
162759
162177
|
}
|
|
162760
|
-
const randomId = () => globalThis.crypto?.randomUUID?.() ?? `t${getServerNow()}${Math.floor(Math.random() * 1e6)}`;
|
|
162761
|
-
const emptyTaskDocState = (taskId) => ({
|
|
162762
|
-
meta: {
|
|
162763
|
-
taskId,
|
|
162764
|
-
title: "",
|
|
162765
|
-
status: "backlog",
|
|
162766
|
-
ownerId: "",
|
|
162767
|
-
order: TASK_ORDER_MIN_KEY,
|
|
162768
|
-
priority: void 0,
|
|
162769
|
-
labels: void 0,
|
|
162770
|
-
agent: void 0,
|
|
162771
|
-
projects: void 0,
|
|
162772
|
-
lastRunConfig: void 0,
|
|
162773
|
-
createdAt: 0,
|
|
162774
|
-
updatedAt: 0,
|
|
162775
|
-
createdBy: void 0
|
|
162776
|
-
},
|
|
162777
|
-
body: "",
|
|
162778
|
-
links: [],
|
|
162779
|
-
timeline: []
|
|
162780
|
-
});
|
|
162781
|
-
const withTaskMirror = async (manager, taskId, fn, options) => {
|
|
162782
|
-
const roomId = getTaskRoomId(taskId);
|
|
162783
|
-
await manager.syncDocOrThrow(roomId, {
|
|
162784
|
-
reason: `task:${taskId}`
|
|
162785
|
-
}).catch(() => void 0);
|
|
162786
|
-
const handle = await manager.repo.openPersistedDoc(roomId);
|
|
162787
|
-
const mirror = new Mirror({
|
|
162788
|
-
doc: handle.doc,
|
|
162789
|
-
schema: taskDocSchema,
|
|
162790
|
-
ignoreUnknownProperties: true,
|
|
162791
|
-
...options?.seedEmptyDocument ? {
|
|
162792
|
-
initialState: emptyTaskDocState(taskId)
|
|
162793
|
-
} : {}
|
|
162794
|
-
});
|
|
162795
|
-
try {
|
|
162796
|
-
return await fn({
|
|
162797
|
-
mirror,
|
|
162798
|
-
syncOnce: async () => {
|
|
162799
|
-
await handle.syncOnce();
|
|
162800
|
-
}
|
|
162801
|
-
});
|
|
162802
|
-
} finally {
|
|
162803
|
-
mirror.dispose();
|
|
162804
|
-
}
|
|
162805
|
-
};
|
|
162806
|
-
const planWorkspaceTaskEnumeration = (indexRows, metaTaskIds) => {
|
|
162807
|
-
const visibleTaskIds = listVisibleTaskIndexRows(indexRows).map((row) => row.taskId);
|
|
162808
|
-
const missingIndexTaskIds = [
|
|
162809
|
-
...new Set(metaTaskIds)
|
|
162810
|
-
].filter((taskId) => !Object.prototype.hasOwnProperty.call(indexRows, taskId));
|
|
162811
|
-
return {
|
|
162812
|
-
visibleTaskIds,
|
|
162813
|
-
missingIndexTaskIds
|
|
162814
|
-
};
|
|
162815
|
-
};
|
|
162816
|
-
const readTaskIndexRowMap = async (manager, workspaceId, options) => {
|
|
162817
|
-
const handle = await manager.repo.openFlockDoc(getTaskIndexFlockDocId(workspaceId));
|
|
162818
|
-
if (options?.sync) {
|
|
162819
|
-
await handle.syncOnce().catch(() => void 0);
|
|
162820
|
-
}
|
|
162821
|
-
return readTaskIndexRows(handle.flock.scan({
|
|
162822
|
-
prefix: getTaskIndexScanPrefix()
|
|
162823
|
-
}));
|
|
162824
|
-
};
|
|
162825
|
-
const listWorkspaceTaskIds = async (manager, workspaceId) => {
|
|
162826
|
-
const indexRows = await readTaskIndexRowMap(manager, workspaceId);
|
|
162827
|
-
const metaTaskIds = (await listAliveRoomIds(manager, isTaskDocRoomId)).map(getTaskIdFromRoomId).filter((taskId) => taskId !== null);
|
|
162828
|
-
const plan = planWorkspaceTaskEnumeration(indexRows, metaTaskIds);
|
|
162829
|
-
const taskIds = new Set(plan.visibleTaskIds);
|
|
162830
|
-
for (const taskId of plan.missingIndexTaskIds) {
|
|
162831
|
-
const snapshot = await readTask(manager, taskId).catch(() => null);
|
|
162832
|
-
if (!snapshot || snapshot.meta.taskId !== taskId) {
|
|
162833
|
-
continue;
|
|
162834
|
-
}
|
|
162835
|
-
taskIds.add(taskId);
|
|
162836
|
-
await republishIndexRow(manager, workspaceId, snapshot).catch(() => void 0);
|
|
162837
|
-
}
|
|
162838
|
-
return [
|
|
162839
|
-
...taskIds
|
|
162840
|
-
];
|
|
162841
|
-
};
|
|
162842
|
-
const readTask = async (manager, taskId) => withTaskMirror(manager, taskId, ({ mirror }) => {
|
|
162843
|
-
const state2 = mirror.getState();
|
|
162844
|
-
if (!state2.meta?.taskId) {
|
|
162845
|
-
return null;
|
|
162846
|
-
}
|
|
162847
|
-
return {
|
|
162848
|
-
meta: state2.meta,
|
|
162849
|
-
body: state2.body ?? "",
|
|
162850
|
-
links: state2.links ?? [],
|
|
162851
|
-
timeline: state2.timeline ?? []
|
|
162852
|
-
};
|
|
162853
|
-
});
|
|
162854
|
-
const selectTaskIndexRows = (rows, filter2) => {
|
|
162855
|
-
const needle = filter2.titleContains?.trim().toLowerCase();
|
|
162856
|
-
const statuses = filter2.status && filter2.status.length > 0 ? new Set(filter2.status) : null;
|
|
162857
|
-
const matches = listVisibleTaskIndexRows(rows).filter((row) => {
|
|
162858
|
-
if (statuses && !statuses.has(row.status)) {
|
|
162859
|
-
return false;
|
|
162860
|
-
}
|
|
162861
|
-
if (filter2.ownerId !== void 0 && (row.ownerId ?? "") !== filter2.ownerId) {
|
|
162862
|
-
return false;
|
|
162863
|
-
}
|
|
162864
|
-
if (filter2.hasAgent !== void 0 && Boolean(row.hasAgent) !== filter2.hasAgent) {
|
|
162865
|
-
return false;
|
|
162866
|
-
}
|
|
162867
|
-
if (needle && !row.title.toLowerCase().includes(needle)) {
|
|
162868
|
-
return false;
|
|
162869
|
-
}
|
|
162870
|
-
return true;
|
|
162871
|
-
});
|
|
162872
|
-
matches.sort((a, b) => a.updatedAt === b.updatedAt ? a.taskId.localeCompare(b.taskId) : b.updatedAt - a.updatedAt);
|
|
162873
|
-
return {
|
|
162874
|
-
rows: matches.slice(0, filter2.limit),
|
|
162875
|
-
matched: matches.length
|
|
162876
|
-
};
|
|
162877
|
-
};
|
|
162878
|
-
const listTasksFromIndex = async (manager, workspaceId, filter2) => selectTaskIndexRows(await readTaskIndexRowMap(manager, workspaceId, {
|
|
162879
|
-
sync: true
|
|
162880
|
-
}), filter2);
|
|
162881
|
-
async function republishIndexRow(manager, workspaceId, snapshot) {
|
|
162882
|
-
const flockDocId = getTaskIndexFlockDocId(workspaceId);
|
|
162883
|
-
const handle = await manager.repo.openFlockDoc(flockDocId);
|
|
162884
|
-
const key2 = taskIndexKeys.task(snapshot.meta.taskId);
|
|
162885
|
-
const row = buildTaskIndexRow(snapshot.meta, countTaskLinks(snapshot.links), summarizeTaskMentions(snapshot.timeline));
|
|
162886
|
-
const previous = parseTaskIndexRow([
|
|
162887
|
-
...handle.flock.scan({
|
|
162888
|
-
prefix: [
|
|
162889
|
-
...key2
|
|
162890
|
-
]
|
|
162891
|
-
})
|
|
162892
|
-
].find((entry) => entry.key.length === key2.length)?.value);
|
|
162893
|
-
if (previous && JSON.stringify(previous) === JSON.stringify(row)) {
|
|
162894
|
-
return;
|
|
162895
|
-
}
|
|
162896
|
-
handle.flock.set([
|
|
162897
|
-
...key2
|
|
162898
|
-
], row);
|
|
162899
|
-
handle.flock.commit();
|
|
162900
|
-
await manager.repo.flush();
|
|
162901
|
-
await handle.syncOnce().catch(() => void 0);
|
|
162902
|
-
}
|
|
162903
|
-
const sameLabelSet = (next2, previous) => next2.length === previous.length && [
|
|
162904
|
-
...next2
|
|
162905
|
-
].sort().join("\0") === [
|
|
162906
|
-
...previous
|
|
162907
|
-
].sort().join("\0");
|
|
162908
|
-
const sameProjectList = (next2, previous) => JSON.stringify(next2.map(normalizeProjectRefForDedup)) === JSON.stringify(previous.map(normalizeProjectRefForDedup));
|
|
162909
|
-
const buildAgentActorFields = (actor) => ({
|
|
162910
|
-
actorKind: "agent",
|
|
162911
|
-
...actor.agentConfigId ? {
|
|
162912
|
-
actorId: actor.agentConfigId
|
|
162913
|
-
} : {},
|
|
162914
|
-
...actor.name ? {
|
|
162915
|
-
actorName: actor.name
|
|
162916
|
-
} : {}
|
|
162917
|
-
});
|
|
162918
|
-
const createTaskFromAgent = async (manager, workspaceId, input2, actor, creatorUserId) => {
|
|
162919
|
-
if (isEmptyTaskDraft(input2)) {
|
|
162920
|
-
return null;
|
|
162921
|
-
}
|
|
162922
|
-
const taskId = randomId();
|
|
162923
|
-
const indexRows = await readTaskIndexRowMap(manager, workspaceId, {
|
|
162924
|
-
sync: true
|
|
162925
|
-
});
|
|
162926
|
-
const order = generateTaskOrderKeyAtEnd(listVisibleTaskIndexRows(indexRows).map((row) => row.order), Math.random);
|
|
162927
|
-
const labels = normalizeTaskLabels(input2.labels ? [
|
|
162928
|
-
...input2.labels
|
|
162929
|
-
] : void 0);
|
|
162930
|
-
const snapshot = await withTaskMirror(manager, taskId, async ({ mirror, syncOnce }) => {
|
|
162931
|
-
mirror.setState((draft) => {
|
|
162932
|
-
const state2 = draft;
|
|
162933
|
-
const now2 = getServerNow();
|
|
162934
|
-
Object.assign(state2.meta, {
|
|
162935
|
-
taskId,
|
|
162936
|
-
title: deriveTaskTitle(input2),
|
|
162937
|
-
status: input2.status ?? "backlog",
|
|
162938
|
-
ownerId: input2.ownerId ?? creatorUserId,
|
|
162939
|
-
order,
|
|
162940
|
-
...input2.priority ? {
|
|
162941
|
-
priority: input2.priority
|
|
162942
|
-
} : {},
|
|
162943
|
-
...labels.length > 0 ? {
|
|
162944
|
-
labels
|
|
162945
|
-
} : {},
|
|
162946
|
-
...input2.projects && input2.projects.length > 0 ? {
|
|
162947
|
-
projects: [
|
|
162948
|
-
...input2.projects
|
|
162949
|
-
]
|
|
162950
|
-
} : {},
|
|
162951
|
-
createdAt: now2,
|
|
162952
|
-
updatedAt: now2,
|
|
162953
|
-
createdBy: creatorUserId
|
|
162954
|
-
});
|
|
162955
|
-
state2.body = input2.body ?? "";
|
|
162956
|
-
state2.timeline.push({
|
|
162957
|
-
id: randomId(),
|
|
162958
|
-
kind: "activity",
|
|
162959
|
-
...buildAgentActorFields(actor),
|
|
162960
|
-
createdAt: now2,
|
|
162961
|
-
activityType: "created"
|
|
162962
|
-
});
|
|
162963
|
-
});
|
|
162964
|
-
await manager.repo.flush();
|
|
162965
|
-
await syncOnce().catch(() => void 0);
|
|
162966
|
-
const after2 = mirror.getState();
|
|
162967
|
-
return {
|
|
162968
|
-
meta: after2.meta,
|
|
162969
|
-
body: after2.body ?? "",
|
|
162970
|
-
links: after2.links ?? [],
|
|
162971
|
-
timeline: after2.timeline ?? []
|
|
162972
|
-
};
|
|
162973
|
-
}, {
|
|
162974
|
-
seedEmptyDocument: true
|
|
162975
|
-
});
|
|
162976
|
-
await republishIndexRow(manager, workspaceId, snapshot);
|
|
162977
|
-
return snapshot;
|
|
162978
|
-
};
|
|
162979
|
-
const applyAgentTaskUpdate = async (manager, workspaceId, taskId, input2, actor) => {
|
|
162980
|
-
const result = await withTaskMirror(manager, taskId, async ({ mirror, syncOnce }) => {
|
|
162981
|
-
const before = mirror.getState();
|
|
162982
|
-
if (!before.meta?.taskId) {
|
|
162983
|
-
return null;
|
|
162984
|
-
}
|
|
162985
|
-
const previous = before.meta;
|
|
162986
|
-
const previousStatus = previous.status;
|
|
162987
|
-
const alreadyLinked = input2.pullRequest !== void 0 && (before.links ?? []).some((link2) => link2.url === input2.pullRequest?.url && link2.removedAt === void 0);
|
|
162988
|
-
mirror.setState((draft) => {
|
|
162989
|
-
const state2 = draft;
|
|
162990
|
-
const now2 = getServerNow();
|
|
162991
|
-
const activities = [];
|
|
162992
|
-
const recordActivity = (activityType, activityData) => {
|
|
162993
|
-
activities.push({
|
|
162994
|
-
id: randomId(),
|
|
162995
|
-
kind: "activity",
|
|
162996
|
-
...buildAgentActorFields(actor),
|
|
162997
|
-
createdAt: now2,
|
|
162998
|
-
activityType,
|
|
162999
|
-
...activityData ? {
|
|
163000
|
-
activityData
|
|
163001
|
-
} : {}
|
|
163002
|
-
});
|
|
163003
|
-
};
|
|
163004
|
-
if (input2.status !== void 0 && input2.status !== previousStatus) {
|
|
163005
|
-
state2.meta.status = input2.status;
|
|
163006
|
-
recordActivity("status_changed", {
|
|
163007
|
-
from: previousStatus,
|
|
163008
|
-
to: input2.status
|
|
163009
|
-
});
|
|
163010
|
-
}
|
|
163011
|
-
if (input2.title !== void 0 && input2.title !== previous.title) {
|
|
163012
|
-
state2.meta.title = input2.title;
|
|
163013
|
-
recordActivity("title_changed", {
|
|
163014
|
-
from: previous.title,
|
|
163015
|
-
to: input2.title
|
|
163016
|
-
});
|
|
163017
|
-
}
|
|
163018
|
-
if (input2.ownerId !== void 0 && input2.ownerId !== (previous.ownerId ?? "")) {
|
|
163019
|
-
state2.meta.ownerId = input2.ownerId;
|
|
163020
|
-
recordActivity("owner_changed", input2.ownerId ? {
|
|
163021
|
-
to: input2.ownerId
|
|
163022
|
-
} : {});
|
|
163023
|
-
}
|
|
163024
|
-
if (input2.priority !== void 0) {
|
|
163025
|
-
const next2 = input2.priority ?? void 0;
|
|
163026
|
-
if (next2 !== previous.priority) {
|
|
163027
|
-
if (next2 === void 0) {
|
|
163028
|
-
delete state2.meta.priority;
|
|
163029
|
-
} else {
|
|
163030
|
-
state2.meta.priority = next2;
|
|
163031
|
-
}
|
|
163032
|
-
recordActivity("priority_changed", next2 ? {
|
|
163033
|
-
to: next2
|
|
163034
|
-
} : {});
|
|
163035
|
-
}
|
|
163036
|
-
}
|
|
163037
|
-
if (input2.labels !== void 0) {
|
|
163038
|
-
const next2 = normalizeTaskLabels([
|
|
163039
|
-
...input2.labels
|
|
163040
|
-
]);
|
|
163041
|
-
if (!sameLabelSet(next2, previous.labels ?? [])) {
|
|
163042
|
-
state2.meta.labels = next2;
|
|
163043
|
-
recordActivity("labels_changed", next2.length > 0 ? {
|
|
163044
|
-
to: next2.join(", ")
|
|
163045
|
-
} : {});
|
|
163046
|
-
}
|
|
163047
|
-
}
|
|
163048
|
-
if (input2.projects !== void 0) {
|
|
163049
|
-
const next2 = [
|
|
163050
|
-
...input2.projects
|
|
163051
|
-
];
|
|
163052
|
-
if (!sameProjectList(next2, previous.projects ?? [])) {
|
|
163053
|
-
state2.meta.projects = next2;
|
|
163054
|
-
recordActivity("projects_changed", {
|
|
163055
|
-
count: String(next2.length)
|
|
163056
|
-
});
|
|
163057
|
-
}
|
|
163058
|
-
}
|
|
163059
|
-
if (input2.pullRequest && !alreadyLinked) {
|
|
163060
|
-
state2.links.push({
|
|
163061
|
-
id: randomId(),
|
|
163062
|
-
kind: "pr",
|
|
163063
|
-
provider: input2.pullRequest.provider,
|
|
163064
|
-
url: input2.pullRequest.url,
|
|
163065
|
-
originSessionId: input2.pullRequest.originSessionId,
|
|
163066
|
-
...buildAgentActorFields(actor),
|
|
163067
|
-
linkedAt: now2
|
|
163068
|
-
});
|
|
163069
|
-
recordActivity("pr_linked", {
|
|
163070
|
-
url: input2.pullRequest.url
|
|
163071
|
-
});
|
|
163072
|
-
}
|
|
163073
|
-
if (activities.length > 0) {
|
|
163074
|
-
state2.meta.updatedAt = now2;
|
|
163075
|
-
state2.timeline.push(...activities);
|
|
163076
|
-
}
|
|
163077
|
-
});
|
|
163078
|
-
await manager.repo.flush();
|
|
163079
|
-
await syncOnce().catch(() => void 0);
|
|
163080
|
-
const after2 = mirror.getState();
|
|
163081
|
-
return {
|
|
163082
|
-
meta: after2.meta,
|
|
163083
|
-
body: after2.body ?? "",
|
|
163084
|
-
links: after2.links ?? [],
|
|
163085
|
-
timeline: after2.timeline ?? []
|
|
163086
|
-
};
|
|
163087
|
-
});
|
|
163088
|
-
if (result) {
|
|
163089
|
-
await republishIndexRow(manager, workspaceId, result);
|
|
163090
|
-
}
|
|
163091
|
-
return result;
|
|
163092
|
-
};
|
|
163093
|
-
const planTaskBodyEdit = (currentBody, edit) => {
|
|
163094
|
-
let nextBody;
|
|
163095
|
-
if (edit.oldString === "") {
|
|
163096
|
-
nextBody = currentBody ? `${currentBody}
|
|
163097
|
-
|
|
163098
|
-
${edit.newString}` : edit.newString;
|
|
163099
|
-
} else {
|
|
163100
|
-
const first2 = currentBody.indexOf(edit.oldString);
|
|
163101
|
-
if (first2 < 0) {
|
|
163102
|
-
return {
|
|
163103
|
-
ok: false,
|
|
163104
|
-
code: "NO_MATCH",
|
|
163105
|
-
body: currentBody
|
|
163106
|
-
};
|
|
163107
|
-
}
|
|
163108
|
-
if (currentBody.indexOf(edit.oldString, first2 + edit.oldString.length) >= 0) {
|
|
163109
|
-
const occurrences = currentBody.split(edit.oldString).length - 1;
|
|
163110
|
-
return {
|
|
163111
|
-
ok: false,
|
|
163112
|
-
code: "AMBIGUOUS_MATCH",
|
|
163113
|
-
occurrences
|
|
163114
|
-
};
|
|
163115
|
-
}
|
|
163116
|
-
nextBody = currentBody.slice(0, first2) + edit.newString + currentBody.slice(first2 + edit.oldString.length);
|
|
163117
|
-
}
|
|
163118
|
-
const delta = nextBody.length - currentBody.length;
|
|
163119
|
-
return {
|
|
163120
|
-
ok: true,
|
|
163121
|
-
nextBody,
|
|
163122
|
-
added: delta > 0 ? delta : 0,
|
|
163123
|
-
removed: delta < 0 ? -delta : 0
|
|
163124
|
-
};
|
|
163125
|
-
};
|
|
163126
|
-
const applyAgentTaskBodyEdit = async (manager, workspaceId, taskId, edit, actor, originSessionId) => {
|
|
163127
|
-
const result = await withTaskMirror(manager, taskId, async ({ mirror, syncOnce }) => {
|
|
163128
|
-
const before = mirror.getState();
|
|
163129
|
-
if (!before.meta?.taskId) {
|
|
163130
|
-
return {
|
|
163131
|
-
ok: false,
|
|
163132
|
-
code: "TASK_NOT_FOUND"
|
|
163133
|
-
};
|
|
163134
|
-
}
|
|
163135
|
-
const currentBody = before.body ?? "";
|
|
163136
|
-
const plan = planTaskBodyEdit(currentBody, edit);
|
|
163137
|
-
if (!plan.ok) {
|
|
163138
|
-
return plan;
|
|
163139
|
-
}
|
|
163140
|
-
const { nextBody, added, removed } = plan;
|
|
163141
|
-
mirror.setState((draft) => {
|
|
163142
|
-
const state2 = draft;
|
|
163143
|
-
const now2 = getServerNow();
|
|
163144
|
-
state2.body = nextBody;
|
|
163145
|
-
state2.meta.updatedAt = now2;
|
|
163146
|
-
state2.timeline.push({
|
|
163147
|
-
id: randomId(),
|
|
163148
|
-
kind: "activity",
|
|
163149
|
-
...buildAgentActorFields(actor),
|
|
163150
|
-
createdAt: now2,
|
|
163151
|
-
activityType: "body_edited",
|
|
163152
|
-
activityData: {
|
|
163153
|
-
added: String(added),
|
|
163154
|
-
removed: String(removed)
|
|
163155
|
-
},
|
|
163156
|
-
...originSessionId ? {
|
|
163157
|
-
originSessionId
|
|
163158
|
-
} : {}
|
|
163159
|
-
});
|
|
163160
|
-
});
|
|
163161
|
-
await manager.repo.flush();
|
|
163162
|
-
await syncOnce().catch(() => void 0);
|
|
163163
|
-
const after2 = mirror.getState();
|
|
163164
|
-
return {
|
|
163165
|
-
ok: true,
|
|
163166
|
-
snapshot: {
|
|
163167
|
-
meta: after2.meta,
|
|
163168
|
-
body: after2.body ?? "",
|
|
163169
|
-
links: after2.links ?? [],
|
|
163170
|
-
timeline: after2.timeline ?? []
|
|
163171
|
-
},
|
|
163172
|
-
added,
|
|
163173
|
-
removed
|
|
163174
|
-
};
|
|
163175
|
-
});
|
|
163176
|
-
if (result.ok) {
|
|
163177
|
-
await republishIndexRow(manager, workspaceId, result.snapshot);
|
|
163178
|
-
}
|
|
163179
|
-
return result;
|
|
163180
|
-
};
|
|
163181
|
-
const appendAgentTaskComment = async (manager, workspaceId, taskId, input2, actor) => {
|
|
163182
|
-
const snapshot = await withTaskMirror(manager, taskId, async ({ mirror, syncOnce }) => {
|
|
163183
|
-
const before = mirror.getState();
|
|
163184
|
-
if (!before.meta?.taskId) {
|
|
163185
|
-
return null;
|
|
163186
|
-
}
|
|
163187
|
-
mirror.setState((draft) => {
|
|
163188
|
-
const state2 = draft;
|
|
163189
|
-
state2.timeline.push({
|
|
163190
|
-
id: randomId(),
|
|
163191
|
-
kind: "comment",
|
|
163192
|
-
...buildAgentActorFields(actor),
|
|
163193
|
-
createdAt: getServerNow(),
|
|
163194
|
-
body: input2.body,
|
|
163195
|
-
...input2.mentions && input2.mentions.length > 0 ? {
|
|
163196
|
-
mentions: input2.mentions
|
|
163197
|
-
} : {},
|
|
163198
|
-
...input2.originSessionId ? {
|
|
163199
|
-
originSessionId: input2.originSessionId
|
|
163200
|
-
} : {}
|
|
163201
|
-
});
|
|
163202
|
-
state2.meta.updatedAt = getServerNow();
|
|
163203
|
-
});
|
|
163204
|
-
await manager.repo.flush();
|
|
163205
|
-
await syncOnce().catch(() => void 0);
|
|
163206
|
-
const after2 = mirror.getState();
|
|
163207
|
-
return after2.meta?.taskId ? after2 : null;
|
|
163208
|
-
});
|
|
163209
|
-
if (!snapshot) {
|
|
163210
|
-
return false;
|
|
163211
|
-
}
|
|
163212
|
-
await republishIndexRow(manager, workspaceId, snapshot);
|
|
163213
|
-
return true;
|
|
163214
|
-
};
|
|
163215
|
-
const linkTaskSessionFromCli = async (manager, workspaceId, taskId, input2, actor) => {
|
|
163216
|
-
const result = await withTaskMirror(manager, taskId, async ({ mirror, syncOnce }) => {
|
|
163217
|
-
const before = mirror.getState();
|
|
163218
|
-
if (!before.meta?.taskId) {
|
|
163219
|
-
return null;
|
|
163220
|
-
}
|
|
163221
|
-
if ((before.links ?? []).some((link2) => link2.sessionId === input2.sessionId && link2.removedAt === void 0)) {
|
|
163222
|
-
return null;
|
|
163223
|
-
}
|
|
163224
|
-
mirror.setState((draft) => {
|
|
163225
|
-
const state2 = draft;
|
|
163226
|
-
const now2 = getServerNow();
|
|
163227
|
-
state2.links.push({
|
|
163228
|
-
id: randomId(),
|
|
163229
|
-
kind: "session",
|
|
163230
|
-
sessionId: input2.sessionId,
|
|
163231
|
-
origin: input2.origin,
|
|
163232
|
-
...input2.parentSessionId ? {
|
|
163233
|
-
parentSessionId: input2.parentSessionId
|
|
163234
|
-
} : {},
|
|
163235
|
-
...buildAgentActorFields(actor),
|
|
163236
|
-
linkedAt: now2
|
|
163237
|
-
});
|
|
163238
|
-
state2.timeline.push({
|
|
163239
|
-
id: randomId(),
|
|
163240
|
-
kind: "activity",
|
|
163241
|
-
...buildAgentActorFields(actor),
|
|
163242
|
-
createdAt: now2,
|
|
163243
|
-
activityType: "session_linked",
|
|
163244
|
-
activityData: {
|
|
163245
|
-
origin: input2.origin
|
|
163246
|
-
}
|
|
163247
|
-
});
|
|
163248
|
-
state2.meta.updatedAt = now2;
|
|
163249
|
-
});
|
|
163250
|
-
await manager.repo.flush();
|
|
163251
|
-
await syncOnce().catch(() => void 0);
|
|
163252
|
-
const after2 = mirror.getState();
|
|
163253
|
-
return {
|
|
163254
|
-
meta: after2.meta,
|
|
163255
|
-
body: after2.body ?? "",
|
|
163256
|
-
links: after2.links ?? [],
|
|
163257
|
-
timeline: after2.timeline ?? []
|
|
163258
|
-
};
|
|
163259
|
-
});
|
|
163260
|
-
if (result) {
|
|
163261
|
-
await republishIndexRow(manager, workspaceId, result);
|
|
163262
|
-
}
|
|
163263
|
-
};
|
|
163264
162178
|
function sortAgentConfigs(configs) {
|
|
163265
162179
|
return [
|
|
163266
162180
|
...configs
|
|
@@ -164727,7 +163641,6 @@ ${entry.text}`).join("\n\n");
|
|
|
164727
163641
|
modeId: args2.modeId,
|
|
164728
163642
|
modelId: args2.modelId,
|
|
164729
163643
|
configOptionValues: args2.configOptionValues && Object.keys(args2.configOptionValues).length > 0 ? args2.configOptionValues : void 0,
|
|
164730
|
-
taskToolsEnabled: args2.taskToolsEnabled === true,
|
|
164731
163644
|
resume: args2.resume,
|
|
164732
163645
|
chainDepth: args2.chainDepth
|
|
164733
163646
|
};
|
|
@@ -164748,9 +163661,6 @@ ${entry.text}`).join("\n\n");
|
|
|
164748
163661
|
};
|
|
164749
163662
|
return {
|
|
164750
163663
|
config: {
|
|
164751
|
-
...rest.taskToolsEnabled !== void 0 ? {
|
|
164752
|
-
taskToolsEnabled: rest.taskToolsEnabled
|
|
164753
|
-
} : {},
|
|
164754
163664
|
...resolved.modeId ?? rest.modeId ? {
|
|
164755
163665
|
modeId: resolved.modeId ?? rest.modeId
|
|
164756
163666
|
} : {},
|
|
@@ -164827,8 +163737,7 @@ ${entry.text}`).join("\n\n");
|
|
|
164827
163737
|
return {
|
|
164828
163738
|
modeId: explicitConfig.modeId ?? fallbackConfig?.modeId,
|
|
164829
163739
|
modelId: explicitConfig.modelId ?? fallbackConfig?.modelId,
|
|
164830
|
-
configOptionValues: explicitConfig.configOptionValues ?? fallbackConfig?.configOptionValues
|
|
164831
|
-
taskToolsEnabled: explicitConfig.taskToolsEnabled ?? fallbackConfig?.taskToolsEnabled
|
|
163740
|
+
configOptionValues: explicitConfig.configOptionValues ?? fallbackConfig?.configOptionValues
|
|
164832
163741
|
};
|
|
164833
163742
|
}
|
|
164834
163743
|
function validateConfigOptionValue(option2, value) {
|
|
@@ -164963,9 +163872,6 @@ ${entry.text}`).join("\n\n");
|
|
|
164963
163872
|
} : {},
|
|
164964
163873
|
...configOptionValues ? {
|
|
164965
163874
|
configOptionValues
|
|
164966
|
-
} : {},
|
|
164967
|
-
...config2.taskToolsEnabled !== void 0 ? {
|
|
164968
|
-
taskToolsEnabled: config2.taskToolsEnabled
|
|
164969
163875
|
} : {}
|
|
164970
163876
|
};
|
|
164971
163877
|
}
|
|
@@ -164997,9 +163903,6 @@ ${entry.text}`).join("\n\n");
|
|
|
164997
163903
|
} : {},
|
|
164998
163904
|
...inputConfig.configOptionValues ? {
|
|
164999
163905
|
configOptionValues: inputConfig.configOptionValues
|
|
165000
|
-
} : {},
|
|
165001
|
-
...inputConfig.taskToolsEnabled !== void 0 ? {
|
|
165002
|
-
taskToolsEnabled: inputConfig.taskToolsEnabled
|
|
165003
163906
|
} : {}
|
|
165004
163907
|
};
|
|
165005
163908
|
}
|
|
@@ -165703,7 +164606,6 @@ ${entry.text}`).join("\n\n");
|
|
|
165703
164606
|
const currentSession = currentSessionId ? await resolveSessionMetaOrThrow(args2.manager, currentSessionId) : void 0;
|
|
165704
164607
|
const parentSession = parentSessionId ? await resolveSessionMetaOrThrow(args2.manager, parentSessionId) : void 0;
|
|
165705
164608
|
assertSupportedParentDepth(parentSession);
|
|
165706
|
-
const taskId = normalizeCliValue(args2.options.taskId) ?? currentSession?.taskId;
|
|
165707
164609
|
const targetMachine = await resolveTargetMachineForCreate({
|
|
165708
164610
|
manager: args2.manager,
|
|
165709
164611
|
workspaceId,
|
|
@@ -165789,10 +164691,7 @@ ${entry.text}`).join("\n\n");
|
|
|
165789
164691
|
...parentSessionId ? {
|
|
165790
164692
|
parentSessionId
|
|
165791
164693
|
} : {},
|
|
165792
|
-
...resolveOpenedBySessionRelation(currentSession)
|
|
165793
|
-
...taskId ? {
|
|
165794
|
-
taskId
|
|
165795
|
-
} : {}
|
|
164694
|
+
...resolveOpenedBySessionRelation(currentSession)
|
|
165796
164695
|
};
|
|
165797
164696
|
}
|
|
165798
164697
|
async function validateSessionCreateOptions(args2) {
|
|
@@ -165866,7 +164765,7 @@ ${entry.text}`).join("\n\n");
|
|
|
165866
164765
|
options,
|
|
165867
164766
|
requester
|
|
165868
164767
|
});
|
|
165869
|
-
const { targetMachine, agentConfig, project, parentSessionId, openedBySessionId, openedByRootSessionId
|
|
164768
|
+
const { targetMachine, agentConfig, project, parentSessionId, openedBySessionId, openedByRootSessionId } = resolved;
|
|
165870
164769
|
const effectiveDispatchConfig = await resolveEffectiveSessionCreateDispatchConfig({
|
|
165871
164770
|
manager,
|
|
165872
164771
|
workspaceId: workspace.id,
|
|
@@ -165918,9 +164817,6 @@ ${entry.text}`).join("\n\n");
|
|
|
165918
164817
|
} : {},
|
|
165919
164818
|
...options.agentRoleRevision !== void 0 ? {
|
|
165920
164819
|
agentRoleRevision: options.agentRoleRevision
|
|
165921
|
-
} : {},
|
|
165922
|
-
...taskId ? {
|
|
165923
|
-
taskId
|
|
165924
164820
|
} : {}
|
|
165925
164821
|
});
|
|
165926
164822
|
let completionAbortController;
|
|
@@ -165941,7 +164837,6 @@ ${entry.text}`).join("\n\n");
|
|
|
165941
164837
|
modeId: modeId ?? void 0,
|
|
165942
164838
|
modelId: modelId ?? void 0,
|
|
165943
164839
|
configOptionValues: effectiveDispatchConfig.configOptionValues,
|
|
165944
|
-
taskToolsEnabled: taskId ? true : effectiveDispatchConfig.taskToolsEnabled,
|
|
165945
164840
|
chainDepth: options.chainDepth
|
|
165946
164841
|
}),
|
|
165947
164842
|
preallocatedId: options.userTurnId
|
|
@@ -165981,17 +164876,6 @@ ${entry.text}`).join("\n\n");
|
|
|
165981
164876
|
timestamp: userTurn.timestamp,
|
|
165982
164877
|
inputConfig: userTurn.inputConfig
|
|
165983
164878
|
});
|
|
165984
|
-
if (taskId) {
|
|
165985
|
-
await linkTaskSessionFromCli(manager, workspace.id, taskId, {
|
|
165986
|
-
sessionId,
|
|
165987
|
-
origin: options.taskLinkOrigin ?? "agent-spawn",
|
|
165988
|
-
...openedBySessionId ? {
|
|
165989
|
-
parentSessionId: openedBySessionId
|
|
165990
|
-
} : {}
|
|
165991
|
-
}, {
|
|
165992
|
-
agentConfigId: agentConfig.id
|
|
165993
|
-
}).catch(() => void 0);
|
|
165994
|
-
}
|
|
165995
164879
|
return {
|
|
165996
164880
|
sessionId,
|
|
165997
164881
|
machineId: targetMachine.id,
|
|
@@ -166010,9 +164894,6 @@ ${entry.text}`).join("\n\n");
|
|
|
166010
164894
|
...openedByRootSessionId ? {
|
|
166011
164895
|
openedByRootSessionId
|
|
166012
164896
|
} : {},
|
|
166013
|
-
...taskId ? {
|
|
166014
|
-
taskId
|
|
166015
|
-
} : {},
|
|
166016
164897
|
completionPromise
|
|
166017
164898
|
};
|
|
166018
164899
|
} catch (error2) {
|
|
@@ -166098,7 +164979,6 @@ ${entry.text}`).join("\n\n");
|
|
|
166098
164979
|
modeId: effectiveDispatchConfig.modeId,
|
|
166099
164980
|
modelId: effectiveDispatchConfig.modelId,
|
|
166100
164981
|
configOptionValues: effectiveDispatchConfig.configOptionValues,
|
|
166101
|
-
taskToolsEnabled: effectiveDispatchConfig.taskToolsEnabled,
|
|
166102
164982
|
resume: session2.acpSessionId ?? void 0,
|
|
166103
164983
|
chainDepth: orchestration?.chainDepth
|
|
166104
164984
|
}),
|
|
@@ -173701,7 +172581,7 @@ ${entry.text}`).join("\n\n");
|
|
|
173701
172581
|
const shouldIgnoreTunnelSendError = (error2) => options.interrupted() || error2 instanceof Error && error2.message === "Tunnel connection is unavailable";
|
|
173702
172582
|
const handleBackgroundTunnelSendError = (error2) => {
|
|
173703
172583
|
if (!shouldIgnoreTunnelSendError(error2)) {
|
|
173704
|
-
console.warn(`Failed to send preview tunnel message: ${formatError
|
|
172584
|
+
console.warn(`Failed to send preview tunnel message: ${formatError(error2)}`);
|
|
173705
172585
|
}
|
|
173706
172586
|
};
|
|
173707
172587
|
return new Promise((resolve2, reject2) => {
|
|
@@ -173745,7 +172625,7 @@ ${entry.text}`).join("\n\n");
|
|
|
173745
172625
|
});
|
|
173746
172626
|
return;
|
|
173747
172627
|
}
|
|
173748
|
-
const message = event.message || formatError
|
|
172628
|
+
const message = event.message || formatError(event.error) || "Unknown WebSocket error";
|
|
173749
172629
|
resolve2({
|
|
173750
172630
|
kind: "disconnected",
|
|
173751
172631
|
message: `Preview tunnel connection error: ${message}`
|
|
@@ -173809,7 +172689,7 @@ ${entry.text}`).join("\n\n");
|
|
|
173809
172689
|
void sendMessage({
|
|
173810
172690
|
type: "response-error",
|
|
173811
172691
|
requestId: message.requestId,
|
|
173812
|
-
message: formatError
|
|
172692
|
+
message: formatError(error2)
|
|
173813
172693
|
}).catch(handleBackgroundTunnelSendError);
|
|
173814
172694
|
});
|
|
173815
172695
|
return;
|
|
@@ -173836,7 +172716,7 @@ ${entry.text}`).join("\n\n");
|
|
|
173836
172716
|
void sendMessage({
|
|
173837
172717
|
type: "websocket-reject",
|
|
173838
172718
|
requestId: message.requestId,
|
|
173839
|
-
message: formatError
|
|
172719
|
+
message: formatError(error2)
|
|
173840
172720
|
}).catch(handleBackgroundTunnelSendError);
|
|
173841
172721
|
}
|
|
173842
172722
|
return;
|
|
@@ -174021,7 +172901,7 @@ ${entry.text}`).join("\n\n");
|
|
|
174021
172901
|
await sendMessage({
|
|
174022
172902
|
type: "response-error",
|
|
174023
172903
|
requestId: message.requestId,
|
|
174024
|
-
message: formatError
|
|
172904
|
+
message: formatError(error2)
|
|
174025
172905
|
}).catch((sendError) => {
|
|
174026
172906
|
if (!shouldIgnoreTunnelSendError(sendError)) throw sendError;
|
|
174027
172907
|
});
|
|
@@ -174094,7 +172974,7 @@ ${entry.text}`).join("\n\n");
|
|
|
174094
172974
|
localSocket.terminate();
|
|
174095
172975
|
});
|
|
174096
172976
|
localSocket.on("error", (error2) => {
|
|
174097
|
-
if (!socketContext.handshakeSettled) rejectHandshake(formatError
|
|
172977
|
+
if (!socketContext.handshakeSettled) rejectHandshake(formatError(error2));
|
|
174098
172978
|
});
|
|
174099
172979
|
localSocket.on("close", (code2, reasonBuffer) => {
|
|
174100
172980
|
const reason = Buffer$2.from(reasonBuffer).toString("utf8");
|
|
@@ -174185,7 +173065,7 @@ ${entry.text}`).join("\n\n");
|
|
|
174185
173065
|
queueBackgroundMessage({
|
|
174186
173066
|
type: "response-error",
|
|
174187
173067
|
requestId,
|
|
174188
|
-
message: formatError
|
|
173068
|
+
message: formatError(error2)
|
|
174189
173069
|
});
|
|
174190
173070
|
}
|
|
174191
173071
|
});
|
|
@@ -174515,12 +173395,12 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
174515
173395
|
function formatLocalWebSocketClose(code2, reason) {
|
|
174516
173396
|
return reason ? `Local WebSocket connection closed during handshake (${code2}: ${reason})` : `Local WebSocket connection closed during handshake (${code2})`;
|
|
174517
173397
|
}
|
|
174518
|
-
function formatError
|
|
173398
|
+
function formatError(error2) {
|
|
174519
173399
|
if (error2 instanceof Error) return error2.message;
|
|
174520
173400
|
return typeof error2 === "string" ? error2 : "Unknown error";
|
|
174521
173401
|
}
|
|
174522
173402
|
function asError(error2) {
|
|
174523
|
-
return error2 instanceof Error ? error2 : new Error(formatError
|
|
173403
|
+
return error2 instanceof Error ? error2 : new Error(formatError(error2));
|
|
174524
173404
|
}
|
|
174525
173405
|
async function withTimeout$1(promise2, timeoutMs, message) {
|
|
174526
173406
|
let timeoutHandle;
|
|
@@ -179544,10 +178424,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
179544
178424
|
await createSessionResult(auth, workspace, this.workspaceDocument, prompt2, options, dispatchConfig);
|
|
179545
178425
|
return;
|
|
179546
178426
|
}
|
|
179547
|
-
await sendSessionChatResult(auth, workspace, this.workspaceDocument, item.target.sessionId, prompt2, {
|
|
179548
|
-
...resolveTurnDispatchConfig({}),
|
|
179549
|
-
taskToolsEnabled: operation.frozenContinuationConfig.inputConfig.taskToolsEnabled === true
|
|
179550
|
-
}, void 0, delegatedRequester ? void 0 : operation.requesterUserId, {
|
|
178427
|
+
await sendSessionChatResult(auth, workspace, this.workspaceDocument, item.target.sessionId, prompt2, resolveTurnDispatchConfig({}), void 0, delegatedRequester ? void 0 : operation.requesterUserId, {
|
|
179551
178428
|
userTurnId: item.target.userTurnId,
|
|
179552
178429
|
chainDepth: operation.initiatorChainDepth + 1,
|
|
179553
178430
|
bypassSessionQuota: shouldBypassSessionQuota(operation.kind)
|
|
@@ -188416,7 +187293,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
188416
187293
|
agentType: callbacks.agentType
|
|
188417
187294
|
},
|
|
188418
187295
|
configOptionValues: this.config.configOptionValues,
|
|
188419
|
-
taskToolsEnabled: this.config.taskToolsEnabled,
|
|
188420
187296
|
launcher,
|
|
188421
187297
|
workspaceId: this.config.workspaceId,
|
|
188422
187298
|
machineId: this.config.machineId,
|
|
@@ -189154,7 +188030,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189154
188030
|
}
|
|
189155
188031
|
};
|
|
189156
188032
|
}
|
|
189157
|
-
function buildSessionPreparationCompatibility(launchSource, mcpServerIds, configOptionValues
|
|
188033
|
+
function buildSessionPreparationCompatibility(launchSource, mcpServerIds, configOptionValues) {
|
|
189158
188034
|
return {
|
|
189159
188035
|
launch: buildSessionLaunchConfig({
|
|
189160
188036
|
customAcp: launchSource?.customAcp,
|
|
@@ -189165,8 +188041,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189165
188041
|
mcpServerIds: mcpServerIds ? [
|
|
189166
188042
|
...mcpServerIds
|
|
189167
188043
|
] : void 0,
|
|
189168
|
-
configOptionValues
|
|
189169
|
-
taskToolsEnabled
|
|
188044
|
+
configOptionValues
|
|
189170
188045
|
})
|
|
189171
188046
|
};
|
|
189172
188047
|
}
|
|
@@ -189283,7 +188158,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189283
188158
|
return null;
|
|
189284
188159
|
}
|
|
189285
188160
|
const current2 = resource.readCurrentLaunchConfig(sessionMeta);
|
|
189286
|
-
if (!current2 || !isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, resource.config.mcpServerIds, resource.config.configOptionValues
|
|
188161
|
+
if (!current2 || !isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, resource.config.mcpServerIds, resource.config.configOptionValues))) {
|
|
189287
188162
|
return null;
|
|
189288
188163
|
}
|
|
189289
188164
|
return {
|
|
@@ -189324,7 +188199,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189324
188199
|
await this.preparationService.discard(sessionId);
|
|
189325
188200
|
return await this.createSessionInnerWithAgent(config2, agentStart);
|
|
189326
188201
|
}
|
|
189327
|
-
const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues
|
|
188202
|
+
const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues);
|
|
189328
188203
|
const claim = this.preparationService.claim({
|
|
189329
188204
|
sessionId,
|
|
189330
188205
|
requesterUserId: config2.requesterUserId,
|
|
@@ -189343,7 +188218,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189343
188218
|
cliType: config2.agentCliType,
|
|
189344
188219
|
agentType: config2.agentType
|
|
189345
188220
|
});
|
|
189346
|
-
return current2 !== null && isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, config2.mcpServerIds, config2.configOptionValues
|
|
188221
|
+
return current2 !== null && isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, config2.mcpServerIds, config2.configOptionValues));
|
|
189347
188222
|
}
|
|
189348
188223
|
});
|
|
189349
188224
|
if (claim.status === "miss") {
|
|
@@ -189501,7 +188376,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189501
188376
|
agentType: spec.agentType,
|
|
189502
188377
|
configOptionValues: spec.runConfig?.configOptionValues,
|
|
189503
188378
|
mcpServerIds: spec.runConfig?.mcpServerIds ?? [],
|
|
189504
|
-
taskToolsEnabled: spec.runConfig?.taskToolsEnabled === true,
|
|
189505
188379
|
customAcp: agentConfig.customAcp,
|
|
189506
188380
|
runtimeOverrides: agentConfig.runtimeOverrides,
|
|
189507
188381
|
project: spec.project,
|
|
@@ -189515,7 +188389,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
189515
188389
|
userName: user.name,
|
|
189516
188390
|
userEmail: user.email
|
|
189517
188391
|
};
|
|
189518
|
-
const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues
|
|
188392
|
+
const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues);
|
|
189519
188393
|
const ghTokenInjected = await this.prepareGitHubRepoSessionConfig(config2);
|
|
189520
188394
|
signal.throwIfAborted();
|
|
189521
188395
|
const launch = await resolveACPProcessLaunchAsync({
|
|
@@ -194426,344 +193300,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
194426
193300
|
counters: () => scheduler.counters
|
|
194427
193301
|
};
|
|
194428
193302
|
};
|
|
194429
|
-
const isTaskAutomationEligible = (candidate, input2) => {
|
|
194430
|
-
const agentConfigId = candidate.agentConfigId;
|
|
194431
|
-
if (!agentConfigId) {
|
|
194432
|
-
return false;
|
|
194433
|
-
}
|
|
194434
|
-
if (candidate.status !== "backlog" && candidate.status !== "todo") {
|
|
194435
|
-
return false;
|
|
194436
|
-
}
|
|
194437
|
-
if (!candidate.ready) {
|
|
194438
|
-
return false;
|
|
194439
|
-
}
|
|
194440
|
-
if (!input2.ownedAgentConfigIds.has(agentConfigId)) {
|
|
194441
|
-
return false;
|
|
194442
|
-
}
|
|
194443
|
-
return candidate.ownerId === input2.operatorUserId;
|
|
194444
|
-
};
|
|
194445
|
-
const planTaskAutomation = (input2) => {
|
|
194446
|
-
const plan = {
|
|
194447
|
-
start: [],
|
|
194448
|
-
queued: [],
|
|
194449
|
-
waitingForAgent: [],
|
|
194450
|
-
skippedAsBaseline: []
|
|
194451
|
-
};
|
|
194452
|
-
const busyAgentConfigIds = new Set(input2.inFlightByAgentConfigId.keys());
|
|
194453
|
-
for (const candidate of input2.candidates) {
|
|
194454
|
-
if (candidate.agentConfigId && candidate.status === "in_progress" && candidate.ownerId === input2.operatorUserId) {
|
|
194455
|
-
busyAgentConfigIds.add(candidate.agentConfigId);
|
|
194456
|
-
}
|
|
194457
|
-
}
|
|
194458
|
-
const byAgent = /* @__PURE__ */ new Map();
|
|
194459
|
-
for (const candidate of input2.candidates) {
|
|
194460
|
-
if (!isTaskAutomationEligible(candidate, input2)) {
|
|
194461
|
-
continue;
|
|
194462
|
-
}
|
|
194463
|
-
if (input2.startedTaskIds.has(candidate.taskId)) {
|
|
194464
|
-
continue;
|
|
194465
|
-
}
|
|
194466
|
-
if (input2.baselineTaskIds.has(candidate.taskId)) {
|
|
194467
|
-
plan.skippedAsBaseline.push(candidate.taskId);
|
|
194468
|
-
continue;
|
|
194469
|
-
}
|
|
194470
|
-
const agentConfigId = candidate.agentConfigId;
|
|
194471
|
-
const bucket = byAgent.get(agentConfigId);
|
|
194472
|
-
if (bucket) {
|
|
194473
|
-
bucket.push(candidate);
|
|
194474
|
-
} else {
|
|
194475
|
-
byAgent.set(agentConfigId, [
|
|
194476
|
-
candidate
|
|
194477
|
-
]);
|
|
194478
|
-
}
|
|
194479
|
-
}
|
|
194480
|
-
for (const [agentConfigId, bucket] of byAgent) {
|
|
194481
|
-
const ordered = [
|
|
194482
|
-
...bucket
|
|
194483
|
-
].sort((a, b) => compareTaskOrder({
|
|
194484
|
-
order: a.order,
|
|
194485
|
-
id: a.taskId
|
|
194486
|
-
}, {
|
|
194487
|
-
order: b.order,
|
|
194488
|
-
id: b.taskId
|
|
194489
|
-
}));
|
|
194490
|
-
if (!input2.onlineAgentConfigIds.has(agentConfigId)) {
|
|
194491
|
-
for (const candidate of ordered) {
|
|
194492
|
-
plan.waitingForAgent.push({
|
|
194493
|
-
taskId: candidate.taskId,
|
|
194494
|
-
agentConfigId
|
|
194495
|
-
});
|
|
194496
|
-
}
|
|
194497
|
-
continue;
|
|
194498
|
-
}
|
|
194499
|
-
const busy = busyAgentConfigIds.has(agentConfigId);
|
|
194500
|
-
let position = 0;
|
|
194501
|
-
for (const [index, candidate] of ordered.entries()) {
|
|
194502
|
-
if (!busy && index === 0) {
|
|
194503
|
-
plan.start.push({
|
|
194504
|
-
taskId: candidate.taskId,
|
|
194505
|
-
agentConfigId
|
|
194506
|
-
});
|
|
194507
|
-
continue;
|
|
194508
|
-
}
|
|
194509
|
-
position += 1;
|
|
194510
|
-
plan.queued.push({
|
|
194511
|
-
taskId: candidate.taskId,
|
|
194512
|
-
agentConfigId,
|
|
194513
|
-
position
|
|
194514
|
-
});
|
|
194515
|
-
}
|
|
194516
|
-
}
|
|
194517
|
-
return plan;
|
|
194518
|
-
};
|
|
194519
|
-
const collectTaskAutomationBaseline = (candidates, input2) => {
|
|
194520
|
-
const baseline = /* @__PURE__ */ new Set();
|
|
194521
|
-
for (const candidate of candidates) {
|
|
194522
|
-
if (isTaskAutomationEligible(candidate, input2)) {
|
|
194523
|
-
baseline.add(candidate.taskId);
|
|
194524
|
-
}
|
|
194525
|
-
}
|
|
194526
|
-
return baseline;
|
|
194527
|
-
};
|
|
194528
|
-
const toCandidate = (row) => ({
|
|
194529
|
-
taskId: row.taskId,
|
|
194530
|
-
order: row.order,
|
|
194531
|
-
ownerId: row.ownerId,
|
|
194532
|
-
...row.agentConfigId ? {
|
|
194533
|
-
agentConfigId: row.agentConfigId
|
|
194534
|
-
} : {},
|
|
194535
|
-
status: row.status,
|
|
194536
|
-
ready: row.ready !== false
|
|
194537
|
-
});
|
|
194538
|
-
class TaskAutomationScheduler {
|
|
194539
|
-
deps;
|
|
194540
|
-
baseline = null;
|
|
194541
|
-
started = /* @__PURE__ */ new Set();
|
|
194542
|
-
inFlightByAgentConfigId = /* @__PURE__ */ new Map();
|
|
194543
|
-
running = false;
|
|
194544
|
-
rerunRequested = false;
|
|
194545
|
-
stopped = false;
|
|
194546
|
-
constructor(deps) {
|
|
194547
|
-
this.deps = deps;
|
|
194548
|
-
}
|
|
194549
|
-
stop() {
|
|
194550
|
-
this.stopped = true;
|
|
194551
|
-
}
|
|
194552
|
-
async evaluate() {
|
|
194553
|
-
if (this.stopped) {
|
|
194554
|
-
return;
|
|
194555
|
-
}
|
|
194556
|
-
if (this.running) {
|
|
194557
|
-
this.rerunRequested = true;
|
|
194558
|
-
return;
|
|
194559
|
-
}
|
|
194560
|
-
this.running = true;
|
|
194561
|
-
try {
|
|
194562
|
-
do {
|
|
194563
|
-
this.rerunRequested = false;
|
|
194564
|
-
await this.runPass();
|
|
194565
|
-
} while (this.rerunRequested && !this.stopped);
|
|
194566
|
-
} finally {
|
|
194567
|
-
this.running = false;
|
|
194568
|
-
}
|
|
194569
|
-
}
|
|
194570
|
-
async runPass() {
|
|
194571
|
-
const rows = await this.deps.readTaskIndex();
|
|
194572
|
-
const candidates = rows.map(toCandidate);
|
|
194573
|
-
const ownedAgents = await this.deps.listOwnedAgentConfigs();
|
|
194574
|
-
const ownedAgentConfigIds = new Set(ownedAgents.filter((config2) => config2.machineId === this.deps.machineId).map((config2) => config2.id));
|
|
194575
|
-
if (this.baseline === null) {
|
|
194576
|
-
this.baseline = collectTaskAutomationBaseline(candidates, {
|
|
194577
|
-
ownedAgentConfigIds,
|
|
194578
|
-
operatorUserId: this.deps.operatorUserId
|
|
194579
|
-
});
|
|
194580
|
-
if (this.baseline.size > 0) {
|
|
194581
|
-
this.deps.logger.debug(`[task-automation] baseline recorded count=${this.baseline.size} (not started)`);
|
|
194582
|
-
}
|
|
194583
|
-
return;
|
|
194584
|
-
}
|
|
194585
|
-
const stillEligible = new Set(candidates.filter((entry) => (entry.status === "backlog" || entry.status === "todo") && entry.ready && entry.agentConfigId).map((entry) => entry.taskId));
|
|
194586
|
-
for (const taskId of [
|
|
194587
|
-
...this.baseline
|
|
194588
|
-
]) {
|
|
194589
|
-
if (!stillEligible.has(taskId)) {
|
|
194590
|
-
this.baseline.delete(taskId);
|
|
194591
|
-
}
|
|
194592
|
-
}
|
|
194593
|
-
const onlineAgentConfigIds = this.deps.isMachineOnline() ? ownedAgentConfigIds : /* @__PURE__ */ new Set();
|
|
194594
|
-
const plan = planTaskAutomation({
|
|
194595
|
-
candidates,
|
|
194596
|
-
ownedAgentConfigIds,
|
|
194597
|
-
onlineAgentConfigIds,
|
|
194598
|
-
operatorUserId: this.deps.operatorUserId,
|
|
194599
|
-
inFlightByAgentConfigId: this.inFlightByAgentConfigId,
|
|
194600
|
-
baselineTaskIds: this.baseline,
|
|
194601
|
-
startedTaskIds: this.started
|
|
194602
|
-
});
|
|
194603
|
-
for (const queued of plan.queued) {
|
|
194604
|
-
this.deps.onQueued?.(queued.taskId, queued.position);
|
|
194605
|
-
}
|
|
194606
|
-
for (const start2 of plan.start) {
|
|
194607
|
-
if (this.inFlightByAgentConfigId.has(start2.agentConfigId)) {
|
|
194608
|
-
continue;
|
|
194609
|
-
}
|
|
194610
|
-
this.inFlightByAgentConfigId.set(start2.agentConfigId, start2.taskId);
|
|
194611
|
-
this.started.add(start2.taskId);
|
|
194612
|
-
try {
|
|
194613
|
-
this.deps.logger.debug(`[task-automation] starting taskId=${start2.taskId} agentConfigId=${start2.agentConfigId}`);
|
|
194614
|
-
await this.deps.startTask(start2.taskId, start2.agentConfigId);
|
|
194615
|
-
} catch (error2) {
|
|
194616
|
-
this.started.delete(start2.taskId);
|
|
194617
|
-
this.deps.logger.warn(`[task-automation] failed to start taskId=${start2.taskId}: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
194618
|
-
} finally {
|
|
194619
|
-
this.inFlightByAgentConfigId.delete(start2.agentConfigId);
|
|
194620
|
-
}
|
|
194621
|
-
}
|
|
194622
|
-
}
|
|
194623
|
-
}
|
|
194624
|
-
const readTaskIndexRowsForWorkspace = async (repo, workspaceId) => {
|
|
194625
|
-
const handle = await repo.openFlockDoc(getTaskIndexFlockDocId(workspaceId));
|
|
194626
|
-
return listVisibleTaskIndexRows(readTaskIndexRows(handle.flock.scan({
|
|
194627
|
-
prefix: getTaskIndexScanPrefix()
|
|
194628
|
-
})));
|
|
194629
|
-
};
|
|
194630
|
-
function createTaskAutomationWorkspace(options) {
|
|
194631
|
-
const { documentManager, workspaceId, machineId, userId, logger: logger2, startTask } = options;
|
|
194632
|
-
const flockDocId = getTaskIndexFlockDocId(workspaceId);
|
|
194633
|
-
const readTaskIndex = () => readTaskIndexRowsForWorkspace(documentManager.repo, workspaceId);
|
|
194634
|
-
const scheduler = new TaskAutomationScheduler({
|
|
194635
|
-
workspaceId,
|
|
194636
|
-
machineId,
|
|
194637
|
-
operatorUserId: userId,
|
|
194638
|
-
logger: logger2,
|
|
194639
|
-
readTaskIndex,
|
|
194640
|
-
listOwnedAgentConfigs: () => listMergedAgentConfigs(documentManager.repo, workspaceId, [
|
|
194641
|
-
machineId
|
|
194642
|
-
]).catch(() => []),
|
|
194643
|
-
isMachineOnline: () => documentManager.isTransportConnected(),
|
|
194644
|
-
startTask,
|
|
194645
|
-
onQueued: (taskId, position) => {
|
|
194646
|
-
logger2.debug(`[task-automation] queued taskId=${taskId} position=${position}`);
|
|
194647
|
-
}
|
|
194648
|
-
});
|
|
194649
|
-
let unsubscribe = null;
|
|
194650
|
-
let disposed = false;
|
|
194651
|
-
let joined = null;
|
|
194652
|
-
const detachReconnect = documentManager.onStreamsOnline(() => {
|
|
194653
|
-
if (disposed) {
|
|
194654
|
-
return;
|
|
194655
|
-
}
|
|
194656
|
-
void scheduler.evaluate().catch(() => void 0);
|
|
194657
|
-
});
|
|
194658
|
-
void (async () => {
|
|
194659
|
-
try {
|
|
194660
|
-
const handle = await documentManager.repo.openFlockDoc(flockDocId);
|
|
194661
|
-
if (disposed) {
|
|
194662
|
-
return;
|
|
194663
|
-
}
|
|
194664
|
-
await scheduler.evaluate();
|
|
194665
|
-
unsubscribe = handle.flock.subscribe(() => {
|
|
194666
|
-
if (disposed) {
|
|
194667
|
-
return;
|
|
194668
|
-
}
|
|
194669
|
-
void scheduler.evaluate().catch(() => void 0);
|
|
194670
|
-
});
|
|
194671
|
-
const subscription = await handle.joinRoom();
|
|
194672
|
-
if (disposed) {
|
|
194673
|
-
subscription.unsubscribe();
|
|
194674
|
-
return;
|
|
194675
|
-
}
|
|
194676
|
-
joined = subscription;
|
|
194677
|
-
await streamsRoomBinding(subscription).firstSyncedWithRemote;
|
|
194678
|
-
if (!disposed) {
|
|
194679
|
-
await scheduler.evaluate();
|
|
194680
|
-
}
|
|
194681
|
-
} catch (error2) {
|
|
194682
|
-
if (!disposed) {
|
|
194683
|
-
logger2.warn(`[task-automation] failed to attach task index: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
194684
|
-
}
|
|
194685
|
-
}
|
|
194686
|
-
})();
|
|
194687
|
-
return {
|
|
194688
|
-
evaluate: () => scheduler.evaluate(),
|
|
194689
|
-
dispose: async () => {
|
|
194690
|
-
disposed = true;
|
|
194691
|
-
scheduler.stop();
|
|
194692
|
-
detachReconnect();
|
|
194693
|
-
unsubscribe?.();
|
|
194694
|
-
joined?.unsubscribe();
|
|
194695
|
-
}
|
|
194696
|
-
};
|
|
194697
|
-
}
|
|
194698
|
-
const buildAutomationBrief = (title2, body2) => {
|
|
194699
|
-
const trimmed2 = body2.trim();
|
|
194700
|
-
const header = `You are executing a Lody task that was delegated to you.
|
|
194701
|
-
|
|
194702
|
-
Task: ${title2}`;
|
|
194703
|
-
const closing = "\n\nWhen you finish, call lody_task_update to move the task to needs_review (and link the pull request if you opened one), and lody_task_comment to summarize what you did. Nobody is watching this session, so that report is how the work becomes visible.";
|
|
194704
|
-
if (!trimmed2) {
|
|
194705
|
-
return `${header}
|
|
194706
|
-
|
|
194707
|
-
(The task has no description. If the title is not enough to act on, say so in a task comment instead of guessing.)${closing}`;
|
|
194708
|
-
}
|
|
194709
|
-
return `${header}
|
|
194710
|
-
|
|
194711
|
-
---
|
|
194712
|
-
|
|
194713
|
-
${trimmed2}${closing}`;
|
|
194714
|
-
};
|
|
194715
|
-
const buildProjectOptions = (project) => {
|
|
194716
|
-
if (!project) {
|
|
194717
|
-
return {};
|
|
194718
|
-
}
|
|
194719
|
-
if (project.kind === "github") {
|
|
194720
|
-
return {
|
|
194721
|
-
repo: project.repoFullName,
|
|
194722
|
-
...project.branch ? {
|
|
194723
|
-
branch: project.branch
|
|
194724
|
-
} : {}
|
|
194725
|
-
};
|
|
194726
|
-
}
|
|
194727
|
-
return {
|
|
194728
|
-
localProject: project.localProjectId,
|
|
194729
|
-
...project.branch ? {
|
|
194730
|
-
branch: project.branch
|
|
194731
|
-
} : {},
|
|
194732
|
-
...project.useWorktree ? {
|
|
194733
|
-
worktree: true
|
|
194734
|
-
} : {}
|
|
194735
|
-
};
|
|
194736
|
-
};
|
|
194737
|
-
const startDelegatedTask = async (deps, taskId, agentConfigId) => {
|
|
194738
|
-
const snapshot = await readTask(deps.manager, taskId);
|
|
194739
|
-
if (!snapshot) {
|
|
194740
|
-
throw new Error(`Task not found: ${taskId}`);
|
|
194741
|
-
}
|
|
194742
|
-
const projects = snapshot.meta.projects ?? [];
|
|
194743
|
-
const project = projects[0];
|
|
194744
|
-
if (!project) {
|
|
194745
|
-
throw new Error(`Task has no project: ${taskId}`);
|
|
194746
|
-
}
|
|
194747
|
-
const result = await deps.createSession({
|
|
194748
|
-
auth: deps.auth,
|
|
194749
|
-
workspace: deps.workspace,
|
|
194750
|
-
manager: deps.manager,
|
|
194751
|
-
prompt: buildAutomationBrief(snapshot.meta.title, snapshot.body),
|
|
194752
|
-
options: {
|
|
194753
|
-
agentConfig: agentConfigId,
|
|
194754
|
-
taskId,
|
|
194755
|
-
taskLinkOrigin: "run",
|
|
194756
|
-
title: snapshot.meta.title.slice(0, 50),
|
|
194757
|
-
...buildProjectOptions(project)
|
|
194758
|
-
}
|
|
194759
|
-
});
|
|
194760
|
-
deps.logger.debug(`[task-automation] started sessionId=${result.sessionId} for taskId=${taskId}`);
|
|
194761
|
-
await applyAgentTaskUpdate(deps.manager, deps.workspace.id, taskId, {
|
|
194762
|
-
status: "in_progress"
|
|
194763
|
-
}, {
|
|
194764
|
-
agentConfigId
|
|
194765
|
-
});
|
|
194766
|
-
};
|
|
194767
193303
|
const openReviewFlock = async (repo, workspaceId) => await repo.openFlockDoc(getReviewPolicyFlockDocId(workspaceId));
|
|
194768
193304
|
const readReviewPolicy = async (repo, workspaceId) => {
|
|
194769
193305
|
const handle = await openReviewFlock(repo, workspaceId);
|
|
@@ -197008,7 +195544,6 @@ ${trimmed2}${closing}`;
|
|
|
197008
195544
|
await runtime.lody.cleanup();
|
|
197009
195545
|
runtime.unsubscribeTerminalCleanup();
|
|
197010
195546
|
await runtime.prPollerWorkspace?.dispose();
|
|
197011
|
-
await runtime.taskAutomation?.dispose();
|
|
197012
195547
|
await runtime.reviewAutomation?.dispose();
|
|
197013
195548
|
} catch (error2) {
|
|
197014
195549
|
runtime.unsubscribeTerminalCleanup();
|
|
@@ -197193,30 +195728,6 @@ ${trimmed2}${closing}`;
|
|
|
197193
195728
|
prAssociation: this.cloudPort.prAssociation,
|
|
197194
195729
|
logger: workspaceLogger
|
|
197195
195730
|
}) : null;
|
|
197196
|
-
const taskAutomation = createTaskAutomationWorkspace({
|
|
197197
|
-
documentManager: startedLody.documentManager,
|
|
197198
|
-
workspaceId: workspace.id,
|
|
197199
|
-
machineId: this.machineId,
|
|
197200
|
-
userId: this.userId,
|
|
197201
|
-
logger: workspaceLogger,
|
|
197202
|
-
startTask: async (taskId, agentConfigId) => {
|
|
197203
|
-
const { createSessionResult: createSessionResult2, resolveTurnDispatchConfig: resolveTurnDispatchConfig2 } = await Promise.resolve().then(() => session);
|
|
197204
|
-
await startDelegatedTask({
|
|
197205
|
-
auth: {
|
|
197206
|
-
token: this.cliToken,
|
|
197207
|
-
userId: this.userId,
|
|
197208
|
-
userName: "",
|
|
197209
|
-
userEmail: "",
|
|
197210
|
-
machineId: this.machineId,
|
|
197211
|
-
machineName: this.machineName
|
|
197212
|
-
},
|
|
197213
|
-
workspace,
|
|
197214
|
-
manager: startedLody.documentManager,
|
|
197215
|
-
logger: workspaceLogger,
|
|
197216
|
-
createSession: async (args2) => createSessionResult2(args2.auth, args2.workspace, args2.manager, args2.prompt, args2.options, resolveTurnDispatchConfig2({}))
|
|
197217
|
-
}, taskId, agentConfigId);
|
|
197218
|
-
}
|
|
197219
|
-
});
|
|
197220
195731
|
const reviewAutomation = this.cloudPort.githubTokens ? createReviewAutomation({
|
|
197221
195732
|
documentManager: startedLody.documentManager,
|
|
197222
195733
|
workspaceId: workspace.id,
|
|
@@ -197267,7 +195778,6 @@ ${trimmed2}${closing}`;
|
|
|
197267
195778
|
lody: startedLody,
|
|
197268
195779
|
unsubscribeTerminalCleanup,
|
|
197269
195780
|
prPollerWorkspace,
|
|
197270
|
-
taskAutomation,
|
|
197271
195781
|
reviewAutomation
|
|
197272
195782
|
});
|
|
197273
195783
|
if (prPollerWorkspace) {
|
|
@@ -199343,7 +197853,7 @@ Shutting down gracefully${reason}...`);
|
|
|
199343
197853
|
authBaseUrl: LODY_AUTH_URL,
|
|
199344
197854
|
authSiteUrl: LODY_AUTH_SITE_URL,
|
|
199345
197855
|
serverBaseUrl: LODY_SERVER_URL,
|
|
199346
|
-
previewGatewayUrl:
|
|
197856
|
+
previewGatewayUrl: "",
|
|
199347
197857
|
runtimeArtifactsBaseUrl: process.env.LODY_RUNTIME_BASE_URL,
|
|
199348
197858
|
logger: logger2
|
|
199349
197859
|
});
|
|
@@ -225823,17 +224333,11 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
225823
224333
|
}
|
|
225824
224334
|
async function listSyncableFlockDocIds(manager, workspaceId) {
|
|
225825
224335
|
const machines = await listAliveDocMetas(manager, isMachineDocRoomId);
|
|
225826
|
-
return
|
|
225827
|
-
...machines.map((entry) => getMachineFlockDocId(workspaceId, entry.meta.id)),
|
|
225828
|
-
getTaskIndexFlockDocId(workspaceId)
|
|
225829
|
-
].sort((left2, right2) => left2.localeCompare(right2));
|
|
224336
|
+
return machines.map((entry) => getMachineFlockDocId(workspaceId, entry.meta.id)).sort((left2, right2) => left2.localeCompare(right2));
|
|
225830
224337
|
}
|
|
225831
|
-
function buildSyncDocIds(aliveRoomIds
|
|
224338
|
+
function buildSyncDocIds(aliveRoomIds) {
|
|
225832
224339
|
return [
|
|
225833
|
-
|
|
225834
|
-
...aliveRoomIds,
|
|
225835
|
-
...taskIds.map((taskId) => getTaskRoomId(taskId))
|
|
225836
|
-
])
|
|
224340
|
+
...aliveRoomIds
|
|
225837
224341
|
].sort((left2, right2) => left2.localeCompare(right2));
|
|
225838
224342
|
}
|
|
225839
224343
|
async function syncWorkspace(input2) {
|
|
@@ -225863,8 +224367,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
225863
224367
|
});
|
|
225864
224368
|
return;
|
|
225865
224369
|
}
|
|
225866
|
-
const
|
|
225867
|
-
const docIds = buildSyncDocIds(await listAliveRoomIds(manager, () => true), taskIds);
|
|
224370
|
+
const docIds = buildSyncDocIds(await listAliveRoomIds(manager, () => true));
|
|
225868
224371
|
const flockDocIds = await listSyncableFlockDocIds(manager, workspaceId);
|
|
225869
224372
|
await syncItems({
|
|
225870
224373
|
summary: summary2,
|
|
@@ -226638,58 +225141,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
226638
225141
|
}
|
|
226639
225142
|
};
|
|
226640
225143
|
}
|
|
226641
|
-
function formatTaskMarkdown(snapshot) {
|
|
226642
|
-
const { meta } = snapshot;
|
|
226643
|
-
const lines2 = [
|
|
226644
|
-
`# ${meta.title || "Untitled task"}`,
|
|
226645
|
-
""
|
|
226646
|
-
];
|
|
226647
|
-
lines2.push(`- Status: ${meta.status}`);
|
|
226648
|
-
if (meta.ownerId) {
|
|
226649
|
-
lines2.push(`- Owner: ${meta.ownerId}`);
|
|
226650
|
-
}
|
|
226651
|
-
if (meta.agent?.agentConfigId) {
|
|
226652
|
-
lines2.push(`- Agent: ${meta.agent.agentConfigId}`);
|
|
226653
|
-
}
|
|
226654
|
-
lines2.push("");
|
|
226655
|
-
const body2 = snapshot.body.trim();
|
|
226656
|
-
lines2.push(body2.length > 0 ? body2 : "_No description._");
|
|
226657
|
-
const links = snapshot.links.filter((link2) => link2.removedAt === void 0);
|
|
226658
|
-
if (links.length > 0) {
|
|
226659
|
-
lines2.push("", "## Links", "");
|
|
226660
|
-
for (const link2 of links) {
|
|
226661
|
-
lines2.push(link2.kind === "session" ? `- Session \`${link2.sessionId}\`${link2.origin ? ` (${link2.origin})` : ""}` : `- ${link2.url ?? "Pull request"}`);
|
|
226662
|
-
}
|
|
226663
|
-
}
|
|
226664
|
-
const comments = snapshot.timeline.filter((entry) => entry.kind === "comment");
|
|
226665
|
-
if (comments.length > 0) {
|
|
226666
|
-
lines2.push("", "## Thread", "");
|
|
226667
|
-
for (const comment of comments) {
|
|
226668
|
-
const author = comment.actorName ?? comment.actorId ?? comment.actorKind;
|
|
226669
|
-
lines2.push(`### ${author}`, "", (comment.body ?? "").trim(), "");
|
|
226670
|
-
}
|
|
226671
|
-
}
|
|
226672
|
-
return `${lines2.join("\n").trimEnd()}
|
|
226673
|
-
`;
|
|
226674
|
-
}
|
|
226675
|
-
function buildTaskIndexExportEntry(snapshot) {
|
|
226676
|
-
return {
|
|
226677
|
-
taskId: snapshot.meta.taskId,
|
|
226678
|
-
title: snapshot.meta.title,
|
|
226679
|
-
status: snapshot.meta.status,
|
|
226680
|
-
createdAt: snapshot.meta.createdAt,
|
|
226681
|
-
updatedAt: snapshot.meta.updatedAt,
|
|
226682
|
-
relativePath: `tasks/${snapshot.meta.taskId}`
|
|
226683
|
-
};
|
|
226684
|
-
}
|
|
226685
|
-
function sortTasksByCreatedAt(snapshots) {
|
|
226686
|
-
return [
|
|
226687
|
-
...snapshots
|
|
226688
|
-
].sort((left2, right2) => {
|
|
226689
|
-
const delta = (left2.meta.createdAt ?? 0) - (right2.meta.createdAt ?? 0);
|
|
226690
|
-
return delta !== 0 ? delta : left2.meta.taskId.localeCompare(right2.meta.taskId);
|
|
226691
|
-
});
|
|
226692
|
-
}
|
|
226693
225144
|
const SESSION_EXPORT_CONCURRENCY = 4;
|
|
226694
225145
|
const ATTACHMENT_EXPORT_CONCURRENCY = 4;
|
|
226695
225146
|
function sortSessionsByCreatedAt(sessions) {
|
|
@@ -226796,27 +225247,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
226796
225247
|
relativePath: path__default.posix.join("sessions", sessionDirName)
|
|
226797
225248
|
};
|
|
226798
225249
|
}
|
|
226799
|
-
async function exportTasks(input2) {
|
|
226800
|
-
let taskIds;
|
|
226801
|
-
try {
|
|
226802
|
-
taskIds = await listWorkspaceTaskIds(input2.manager, input2.workspaceId);
|
|
226803
|
-
} catch (error2) {
|
|
226804
|
-
input2.warnings.push(`Task export skipped: ${formatErrorMessage(error2)}`);
|
|
226805
|
-
return [];
|
|
226806
|
-
}
|
|
226807
|
-
const snapshots = await mapWithConcurrency$1(taskIds, SESSION_EXPORT_CONCURRENCY, async (taskId) => readTask(input2.manager, taskId).catch((error2) => {
|
|
226808
|
-
input2.warnings.push(`Task ${taskId} export failed: ${formatErrorMessage(error2)}`);
|
|
226809
|
-
return null;
|
|
226810
|
-
}));
|
|
226811
|
-
const index = [];
|
|
226812
|
-
for (const snapshot of sortTasksByCreatedAt(snapshots.filter((entry) => entry !== null))) {
|
|
226813
|
-
const taskDir = path__default.join(input2.outputDir, "tasks", encodeExportPathSegment(snapshot.meta.taskId, "task"));
|
|
226814
|
-
await writeJson(path__default.join(taskDir, "task.json"), snapshot);
|
|
226815
|
-
await writeText(path__default.join(taskDir, "task.md"), formatTaskMarkdown(snapshot));
|
|
226816
|
-
index.push(buildTaskIndexExportEntry(snapshot));
|
|
226817
|
-
}
|
|
226818
|
-
return index;
|
|
226819
|
-
}
|
|
226820
225250
|
async function exportWorkspaceData(options) {
|
|
226821
225251
|
const downloadImages = options.downloadImages !== false;
|
|
226822
225252
|
const warnings = [];
|
|
@@ -226834,13 +225264,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
226834
225264
|
warnings
|
|
226835
225265
|
}));
|
|
226836
225266
|
await writeJson(path__default.join(options.outputDir, "sessions", "index.json"), sessionIndex);
|
|
226837
|
-
const taskIndex = await exportTasks({
|
|
226838
|
-
manager: options.manager,
|
|
226839
|
-
workspaceId: options.workspace.id,
|
|
226840
|
-
outputDir: options.outputDir,
|
|
226841
|
-
warnings
|
|
226842
|
-
});
|
|
226843
|
-
await writeJson(path__default.join(options.outputDir, "tasks", "index.json"), taskIndex);
|
|
226844
225267
|
let usageExported = false;
|
|
226845
225268
|
try {
|
|
226846
225269
|
const usageBundle = await fetchWorkspaceUsageBundle({
|
|
@@ -226863,7 +225286,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
226863
225286
|
},
|
|
226864
225287
|
outputDir: options.outputDir,
|
|
226865
225288
|
sessionCount: sessionIndex.length,
|
|
226866
|
-
taskCount:
|
|
225289
|
+
taskCount: 0,
|
|
226867
225290
|
usageExported
|
|
226868
225291
|
};
|
|
226869
225292
|
await writeJson(path__default.join(options.outputDir, "manifest.json"), manifest);
|
|
@@ -226888,11 +225311,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
226888
225311
|
await mapWithConcurrency$1(sessions, EXPORT_SYNC_CONCURRENCY, async (entry) => {
|
|
226889
225312
|
await syncDocForRead(manager, getSessionRoomId(entry.meta.id), `export:${workspace.id}:${entry.meta.id}`);
|
|
226890
225313
|
});
|
|
226891
|
-
const workspaceId = workspace.id;
|
|
226892
|
-
const taskIds = await listWorkspaceTaskIds(manager, workspaceId).catch(() => []);
|
|
226893
|
-
await mapWithConcurrency$1(taskIds, EXPORT_SYNC_CONCURRENCY, async (taskId) => {
|
|
226894
|
-
await syncDocForRead(manager, getTaskRoomId(taskId), `export:${workspace.id}:${taskId}`);
|
|
226895
|
-
});
|
|
226896
225314
|
}
|
|
226897
225315
|
const exportCommand = new Command("export").description("Export user-facing workspace session data").option("--workspace <selector>", "Target workspace id, slug, or name").option("--all-workspace", "Export all accessible workspaces").option("--no-images", "Skip downloading image binaries").option("--offline", "Read the local cache without syncing first").option("--debug", "Enable debug output").argument("[outputDir]", "Output directory for export files").action(async (outputDirArg, options) => {
|
|
226898
225316
|
await runOneShotCommand("export", options, async () => {
|
|
@@ -227035,7 +225453,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
227035
225453
|
data = createReviewBundleSnapshot(bundle);
|
|
227036
225454
|
}
|
|
227037
225455
|
const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
|
|
227038
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-
|
|
225456
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-B9jEGZSx.js").then(async (m) => {
|
|
227039
225457
|
await m.__tla;
|
|
227040
225458
|
return m;
|
|
227041
225459
|
});
|
|
@@ -245237,62 +243655,6 @@ ${result.stdout ?? ""}`;
|
|
|
245237
243655
|
});
|
|
245238
243656
|
return FeedbackSubmissionResultSchema.parse(raw2);
|
|
245239
243657
|
}
|
|
245240
|
-
const formatError = (error2) => error2 instanceof Error ? error2.message : String(error2);
|
|
245241
|
-
const syncProposalDoc = async (manager, roomId, phase) => {
|
|
245242
|
-
try {
|
|
245243
|
-
await manager.syncDocOrThrow(roomId, {
|
|
245244
|
-
reason: `mcp.task_propose:${phase}`
|
|
245245
|
-
});
|
|
245246
|
-
} catch (error2) {
|
|
245247
|
-
const detail = phase === "hydrate" ? "The conversation could not be synchronized before writing the task proposal." : "The task proposal was saved locally, but remote synchronization was not confirmed.";
|
|
245248
|
-
throw new LodyOperationStoreError("TASK_PROPOSAL_SYNC_FAILED", `${detail} Retry with the same proposalId; retries are idempotent. ${formatError(error2)}`, true);
|
|
245249
|
-
}
|
|
245250
|
-
};
|
|
245251
|
-
const publishTaskProposal = async (manager, sessionId, draft, actor, options = {}) => {
|
|
245252
|
-
const doc = await manager.getOrCreateSessionDoc(sessionId);
|
|
245253
|
-
await syncProposalDoc(manager, doc.roomId, "hydrate");
|
|
245254
|
-
const desiredMeta = {
|
|
245255
|
-
proposalId: draft.proposalId,
|
|
245256
|
-
title: draft.title,
|
|
245257
|
-
...draft.body !== void 0 ? {
|
|
245258
|
-
body: draft.body
|
|
245259
|
-
} : {},
|
|
245260
|
-
proposedBy: {
|
|
245261
|
-
kind: "agent",
|
|
245262
|
-
...actor.agentConfigId ? {
|
|
245263
|
-
agentConfigId: actor.agentConfigId
|
|
245264
|
-
} : {},
|
|
245265
|
-
...actor.name ? {
|
|
245266
|
-
name: actor.name
|
|
245267
|
-
} : {}
|
|
245268
|
-
}
|
|
245269
|
-
};
|
|
245270
|
-
const turnId = `task-proposal-${draft.proposalId}`;
|
|
245271
|
-
let changed = false;
|
|
245272
|
-
let result = {
|
|
245273
|
-
pending: true
|
|
245274
|
-
};
|
|
245275
|
-
const applied = await doc.sessionData.commands.applyHistoryAction({
|
|
245276
|
-
kind: "task-proposal",
|
|
245277
|
-
turnId,
|
|
245278
|
-
meta: desiredMeta,
|
|
245279
|
-
timestamp: new Date((options.now ?? getServerNow)()).toISOString()
|
|
245280
|
-
}).catch((error2) => {
|
|
245281
|
-
if (!(error2 instanceof HistoryActionRefused)) throw error2;
|
|
245282
|
-
throw new LodyOperationStoreError("TASK_PROPOSAL_ID_CONFLICT", "History turn already belongs to a different task proposal", false);
|
|
245283
|
-
});
|
|
245284
|
-
const accepted = applied;
|
|
245285
|
-
changed = accepted.matched ?? false;
|
|
245286
|
-
result = accepted.proposal ?? {
|
|
245287
|
-
pending: true
|
|
245288
|
-
};
|
|
245289
|
-
if (!changed) {
|
|
245290
|
-
return result;
|
|
245291
|
-
}
|
|
245292
|
-
await manager.repo.flush();
|
|
245293
|
-
await syncProposalDoc(manager, doc.roomId, "commit");
|
|
245294
|
-
return result;
|
|
245295
|
-
};
|
|
245296
243658
|
const jsonBytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
245297
243659
|
const encodeSessionHistoryCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
245298
243660
|
const parseSessionHistoryCursor = (cursor, sessionId, newestBeforeIndex) => {
|
|
@@ -245420,83 +243782,6 @@ ${result.stdout ?? ""}`;
|
|
|
245420
243782
|
maxBytes: params.maxBytes
|
|
245421
243783
|
});
|
|
245422
243784
|
}
|
|
245423
|
-
const MIME_TYPE_BY_EXTENSION = {
|
|
245424
|
-
png: "image/png",
|
|
245425
|
-
jpg: "image/jpeg",
|
|
245426
|
-
jpeg: "image/jpeg",
|
|
245427
|
-
webp: "image/webp",
|
|
245428
|
-
gif: "image/gif"
|
|
245429
|
-
};
|
|
245430
|
-
const readTaskImage = async (filePath) => {
|
|
245431
|
-
const absolutePath = path__default$1.resolve(filePath);
|
|
245432
|
-
let handle;
|
|
245433
|
-
try {
|
|
245434
|
-
handle = await fs__default$1.promises.open(absolutePath, fs__default$1.constants.O_RDONLY | fs__default$1.constants.O_NOFOLLOW);
|
|
245435
|
-
} catch (error2) {
|
|
245436
|
-
const code2 = error2?.code;
|
|
245437
|
-
throw new Error(code2 === "ELOOP" ? `Image path must not be a symlink: ${filePath}` : `Image file not found: ${filePath}`, {
|
|
245438
|
-
cause: error2
|
|
245439
|
-
});
|
|
245440
|
-
}
|
|
245441
|
-
try {
|
|
245442
|
-
const stat2 = await handle.stat();
|
|
245443
|
-
if (!stat2.isFile()) throw new Error(`Image path is not a file: ${filePath}`);
|
|
245444
|
-
if (stat2.size <= 0) throw new Error(`Image is empty: ${filePath}`);
|
|
245445
|
-
if (stat2.size > SESSION_IMAGE_MAX_SIZE_BYTES) {
|
|
245446
|
-
throw new Error(`Image must be <= ${Math.floor(SESSION_IMAGE_MAX_SIZE_BYTES / (1024 * 1024))}MB: ${filePath}`);
|
|
245447
|
-
}
|
|
245448
|
-
const fileName = path__default$1.basename(absolutePath);
|
|
245449
|
-
const extension2 = path__default$1.extname(fileName).slice(1).toLowerCase();
|
|
245450
|
-
const mimeType = MIME_TYPE_BY_EXTENSION[extension2];
|
|
245451
|
-
if (!mimeType) throw new Error(`Unsupported image file extension: ${fileName}`);
|
|
245452
|
-
return {
|
|
245453
|
-
fileName,
|
|
245454
|
-
mimeType,
|
|
245455
|
-
bytes: await handle.readFile()
|
|
245456
|
-
};
|
|
245457
|
-
} finally {
|
|
245458
|
-
await handle.close();
|
|
245459
|
-
}
|
|
245460
|
-
};
|
|
245461
|
-
const uploadTaskImages = async (args2) => {
|
|
245462
|
-
const serverUrl = LODY_SERVER_URL?.trim();
|
|
245463
|
-
if (!serverUrl) throw new Error("LODY_SERVER_URL is not defined");
|
|
245464
|
-
const uploadUrl = buildTaskImageApiUrl(serverUrl, getTaskImageUploadApiPath(args2.workspaceId));
|
|
245465
|
-
const results = [];
|
|
245466
|
-
for (const filePath of args2.paths) {
|
|
245467
|
-
const file2 = await readTaskImage(filePath);
|
|
245468
|
-
const bytes2 = new Uint8Array(file2.bytes.byteLength);
|
|
245469
|
-
bytes2.set(file2.bytes);
|
|
245470
|
-
const formData = new FormData();
|
|
245471
|
-
formData.set("file", new Blob([
|
|
245472
|
-
bytes2
|
|
245473
|
-
], {
|
|
245474
|
-
type: file2.mimeType
|
|
245475
|
-
}), file2.fileName);
|
|
245476
|
-
const response2 = await fetch(uploadUrl, {
|
|
245477
|
-
method: "POST",
|
|
245478
|
-
headers: {
|
|
245479
|
-
Authorization: `Bearer ${args2.token}`
|
|
245480
|
-
},
|
|
245481
|
-
body: formData
|
|
245482
|
-
});
|
|
245483
|
-
if (!response2.ok) {
|
|
245484
|
-
const detail = await response2.text().catch(() => "");
|
|
245485
|
-
throw new Error(`Failed to upload task image (${response2.status})${detail ? `: ${detail.slice(0, 200)}` : ""}`);
|
|
245486
|
-
}
|
|
245487
|
-
const body2 = await response2.json().catch(() => null);
|
|
245488
|
-
const image = body2 && typeof body2 === "object" && "image" in body2 ? body2.image : void 0;
|
|
245489
|
-
if (!image || typeof image !== "object" || typeof image.imageId !== "string" || typeof image.mimeType !== "string" || typeof image.sizeBytes !== "number") {
|
|
245490
|
-
throw new Error("Invalid task image upload payload");
|
|
245491
|
-
}
|
|
245492
|
-
const payload = image;
|
|
245493
|
-
results.push({
|
|
245494
|
-
...payload,
|
|
245495
|
-
markdownUrl: buildTaskImageMarkdownUrl(payload.imageId)
|
|
245496
|
-
});
|
|
245497
|
-
}
|
|
245498
|
-
return results;
|
|
245499
|
-
};
|
|
245500
243785
|
async function syncMcpCatalog(syncer, workspaceId) {
|
|
245501
243786
|
await syncer.syncFlockDocOrThrow(getWorkspaceFlockDocId(workspaceId), {
|
|
245502
243787
|
timeoutMs: 1e4,
|
|
@@ -245741,19 +244026,10 @@ ${result.stdout ?? ""}`;
|
|
|
245741
244026
|
const SESSION_RENAME_MANY_TOOL_NAME = "lody_session_rename_many";
|
|
245742
244027
|
const OPERATION_GET_TOOL_NAME = "lody_operation_get";
|
|
245743
244028
|
const OPERATION_CANCEL_TOOL_NAME = "lody_operation_cancel";
|
|
245744
|
-
const TASK_LIST_TOOL_NAME = "lody_task_list";
|
|
245745
|
-
const TASK_GET_TOOL_NAME = "lody_task_get";
|
|
245746
|
-
const TASK_CREATE_TOOL_NAME = "lody_task_create";
|
|
245747
|
-
const TASK_PROPOSE_TOOL_NAME = "lody_task_propose";
|
|
245748
|
-
const TASK_UPDATE_TOOL_NAME = "lody_task_update";
|
|
245749
|
-
const TASK_EDIT_BODY_TOOL_NAME = "lody_task_edit_body";
|
|
245750
|
-
const TASK_COMMENT_TOOL_NAME = "lody_task_comment";
|
|
245751
|
-
const TASK_IMAGE_UPLOAD_TOOL_NAME = "lody_task_upload_images";
|
|
245752
244029
|
const REVIEW_SUBMIT_TOOL_NAME = "lody_review_submit";
|
|
245753
244030
|
const SESSION_FILE_MAX_SIZE_MB = Math.floor(SESSION_FILE_MAX_SIZE_BYTES / (1024 * 1024));
|
|
245754
244031
|
const SESSION_CONTROL_TIMEOUT_MS = 3e4;
|
|
245755
244032
|
const LODY_CLI_DEFAULT_TIMEOUT_MS = 10 * 6e4;
|
|
245756
|
-
const escapeMarkdownImageAlt = (value) => value.replaceAll(/[\\\]]/gu, "\\$&");
|
|
245757
244033
|
const MAX_MCP_SESSION_WAIT_TIMEOUT_SECONDS = 3600;
|
|
245758
244034
|
const MAX_MCP_COMMAND_BATCH_SIZE = 20;
|
|
245759
244035
|
const MAX_MCP_STATUS_BATCH_SIZE = 50;
|
|
@@ -245764,11 +244040,6 @@ ${result.stdout ?? ""}`;
|
|
|
245764
244040
|
const MAX_MCP_SESSION_HISTORY_LIMIT = 50;
|
|
245765
244041
|
const MAX_MCP_SESSION_HISTORY_BYTES = 128 * 1024;
|
|
245766
244042
|
const MAX_MCP_SESSION_TITLE_CHARS = 200;
|
|
245767
|
-
const MAX_MCP_TASK_BODY_BYTES = 64 * 1024;
|
|
245768
|
-
const MAX_MCP_TASK_LINKS = 50;
|
|
245769
|
-
const MAX_MCP_TASK_EDIT_CHARS = 64e3;
|
|
245770
|
-
const DEFAULT_MCP_TASK_LIST_LIMIT = 20;
|
|
245771
|
-
const MAX_MCP_TASK_LIST_LIMIT = 100;
|
|
245772
244043
|
const FILE_UPLOAD_TIMEOUT_MS = 10 * 6e4;
|
|
245773
244044
|
const PreviewToolInputSchema = object$1({
|
|
245774
244045
|
protocol: literal$1("http").default("http"),
|
|
@@ -245783,9 +244054,6 @@ ${result.stdout ?? ""}`;
|
|
|
245783
244054
|
const ImageUploadToolInputSchema = object$1({
|
|
245784
244055
|
paths: array$2(string$1().trim().min(1).describe("Absolute path or session-workspace-relative path to an image file.")).min(1).max(SESSION_IMAGE_MAX_COUNT).describe("Image file paths to upload to the current Lody conversation.")
|
|
245785
244056
|
}).strict();
|
|
245786
|
-
const TaskImageUploadToolInputSchema = object$1({
|
|
245787
|
-
paths: array$2(string$1().trim().min(1).describe("Absolute path or session-workspace-relative path to an image file.")).min(1).max(SESSION_IMAGE_MAX_COUNT).describe("Images to upload for use in a task description or comment.")
|
|
245788
|
-
}).strict();
|
|
245789
244057
|
const FileUploadToolInputSchema = object$1({
|
|
245790
244058
|
paths: array$2(string$1().trim().min(1).describe("Absolute path or session-workspace-relative path to a file.")).min(1).max(SESSION_FILE_MAX_COUNT).describe("File paths to upload to the current Lody conversation.")
|
|
245791
244059
|
}).strict();
|
|
@@ -246113,7 +244381,7 @@ ${result.stdout ?? ""}`;
|
|
|
246113
244381
|
cursor: string$1().trim().min(1).optional()
|
|
246114
244382
|
}).strict();
|
|
246115
244383
|
const SessionHistoryToolInputSchema = object$1({
|
|
246116
|
-
sessionId: string$1().trim().min(1).optional().describe("Target session id, or current. Defaults to current."),
|
|
244384
|
+
sessionId: string$1().trim().min(1).optional().describe("Target session id, or current. Defaults to current. Also accepts a `session://<sessionId>` URI from a session mention link."),
|
|
246117
244385
|
cursor: string$1().trim().min(1).optional(),
|
|
246118
244386
|
limit: number$4().int().positive().max(MAX_MCP_SESSION_HISTORY_LIMIT).optional().describe(`Maximum transcript turns to return. Defaults to ${DEFAULT_MCP_SESSION_HISTORY_LIMIT}.`)
|
|
246119
244387
|
}).strict();
|
|
@@ -246140,8 +244408,7 @@ ${result.stdout ?? ""}`;
|
|
|
246140
244408
|
workspaceId: readRequiredEnv("LODY_MCP_WORKSPACE_ID", "LODY_PREVIEW_MCP_WORKSPACE_ID"),
|
|
246141
244409
|
sessionId: SessionIdSchema$1.parse(readRequiredEnv("LODY_MCP_SESSION_ID", "LODY_PREVIEW_MCP_SESSION_ID")),
|
|
246142
244410
|
localControlSocketPath: readOptionalEnv("LODY_MCP_SOCKET_PATH", "LODY_PREVIEW_MCP_SOCKET_PATH"),
|
|
246143
|
-
workdir: readOptionalEnv("LODY_MCP_WORKDIR", "LODY_PREVIEW_MCP_WORKDIR") ?? process.cwd()
|
|
246144
|
-
taskToolsEnabled: readOptionalEnv("LODY_MCP_TASK_TOOLS_ENABLED") === "1"
|
|
244411
|
+
workdir: readOptionalEnv("LODY_MCP_WORKDIR", "LODY_PREVIEW_MCP_WORKDIR") ?? process.cwd()
|
|
246145
244412
|
};
|
|
246146
244413
|
const sharedOperationStores = /* @__PURE__ */ new Map();
|
|
246147
244414
|
const resolveOperationStorePathForContext = () => getLodyOperationStorePath(getSessionContext().machineId);
|
|
@@ -246300,9 +244567,14 @@ ${result.stdout ?? ""}`;
|
|
|
246300
244567
|
return JSON.parse(line3);
|
|
246301
244568
|
};
|
|
246302
244569
|
const runLodyCliJson = async (args2, timeoutMs) => parseJsonCliOutput((await runLodyCli(args2, timeoutMs)).stdout);
|
|
244570
|
+
const SESSION_URI_PREFIX = "session://";
|
|
244571
|
+
const stripSessionUriPrefix = (value) => value.startsWith(SESSION_URI_PREFIX) ? value.slice(SESSION_URI_PREFIX.length) : value;
|
|
246303
244572
|
const resolveMcpSessionId = (sessionId, ctx) => {
|
|
246304
244573
|
const normalized = normalizeCliValue(sessionId);
|
|
246305
|
-
|
|
244574
|
+
if (!normalized || normalized === "current") {
|
|
244575
|
+
return ctx.sessionId;
|
|
244576
|
+
}
|
|
244577
|
+
return stripSessionUriPrefix(normalized);
|
|
246306
244578
|
};
|
|
246307
244579
|
const getMcpWorkspaceId = (ctx) => ctx.workspaceId;
|
|
246308
244580
|
const buildStructuredOutputOptions = (args2, outputMode = "json", onEvent) => {
|
|
@@ -246374,10 +244646,7 @@ ${prompt2}` : prompt2;
|
|
|
246374
244646
|
return {
|
|
246375
244647
|
input: input2,
|
|
246376
244648
|
prompt: input2.prompt,
|
|
246377
|
-
dispatchConfig:
|
|
246378
|
-
...buildMcpTurnDispatchConfig(input2),
|
|
246379
|
-
taskToolsEnabled: invoking?.frozenInputConfig.taskToolsEnabled === true
|
|
246380
|
-
}
|
|
244649
|
+
dispatchConfig: buildMcpTurnDispatchConfig(input2)
|
|
246381
244650
|
};
|
|
246382
244651
|
}
|
|
246383
244652
|
if (!role || role.id !== input2.agentRoleId) {
|
|
@@ -246416,7 +244685,6 @@ ${prompt2}` : prompt2;
|
|
|
246416
244685
|
prompt: composeAgentRolePrompt(role.promptPrefix, input2.prompt),
|
|
246417
244686
|
dispatchConfig: {
|
|
246418
244687
|
...role.runConfig,
|
|
246419
|
-
taskToolsEnabled: invoking?.frozenInputConfig.taskToolsEnabled === true,
|
|
246420
244688
|
inheritSessionDefaults: false
|
|
246421
244689
|
},
|
|
246422
244690
|
role
|
|
@@ -246985,16 +245253,6 @@ ${prompt2}` : prompt2;
|
|
|
246985
245253
|
inputConfig
|
|
246986
245254
|
};
|
|
246987
245255
|
};
|
|
246988
|
-
const assertInvokingTurnTaskToolsEnabled = async (manager, sessionId) => {
|
|
246989
|
-
const session2 = await readCurrentSessionMeta(manager, sessionId);
|
|
246990
|
-
if (!session2) {
|
|
246991
|
-
throw new LodyOperationStoreError("SESSION_NOT_FOUND", `Requester Session not found: ${sessionId}`, false);
|
|
246992
|
-
}
|
|
246993
|
-
const source = await resolveInvokingTurnSource();
|
|
246994
|
-
if (source.inputConfig.taskToolsEnabled !== true) {
|
|
246995
|
-
throw new LodyOperationStoreError("TASK_TOOLS_DISABLED", "Lody Task tools are disabled for the driving user turn.", false);
|
|
246996
|
-
}
|
|
246997
|
-
};
|
|
246998
245256
|
const resolveInvokingTurnContext = async (session2) => {
|
|
246999
245257
|
const source = await resolveInvokingTurnSource();
|
|
247000
245258
|
const chainDepth = source.inputConfig.chainDepth ?? 0;
|
|
@@ -247447,10 +245705,7 @@ ${prompt2}` : prompt2;
|
|
|
247447
245705
|
throw new Error("Single chat Operation is missing its active target item.");
|
|
247448
245706
|
}
|
|
247449
245707
|
if (!pendingItem.inputDurable && accepted.claimedItemIndexes.includes(0)) {
|
|
247450
|
-
const result = await sendSessionChatResult(auth, workspace, manager, pendingItem.target.sessionId, args2.prompt, {
|
|
247451
|
-
...resolveTurnDispatchConfig({}),
|
|
247452
|
-
taskToolsEnabled: invoking.frozenInputConfig.taskToolsEnabled === true
|
|
247453
|
-
}, void 0, void 0, {
|
|
245708
|
+
const result = await sendSessionChatResult(auth, workspace, manager, pendingItem.target.sessionId, args2.prompt, resolveTurnDispatchConfig({}), void 0, void 0, {
|
|
247454
245709
|
userTurnId: pendingItem.target.userTurnId,
|
|
247455
245710
|
chainDepth: invoking.chainDepth + 1
|
|
247456
245711
|
}, toDelegatedSessionRequester(invoking.identity));
|
|
@@ -247873,10 +246128,7 @@ ${prompt2}` : prompt2;
|
|
|
247873
246128
|
return batchFailure("INVALID_ITEM", "Chat item requires sessionId and prompt.", false, storedItem.label, storedItem.target);
|
|
247874
246129
|
}
|
|
247875
246130
|
try {
|
|
247876
|
-
await sendSessionChatResult(auth, workspace, manager, storedItem.target.sessionId, expandedItem.prompt, {
|
|
247877
|
-
...resolveTurnDispatchConfig({}),
|
|
247878
|
-
taskToolsEnabled: invoking.frozenInputConfig.taskToolsEnabled === true
|
|
247879
|
-
}, void 0, void 0, {
|
|
246131
|
+
await sendSessionChatResult(auth, workspace, manager, storedItem.target.sessionId, expandedItem.prompt, resolveTurnDispatchConfig({}), void 0, void 0, {
|
|
247880
246132
|
userTurnId: storedItem.target.userTurnId,
|
|
247881
246133
|
chainDepth: invoking.chainDepth + 1,
|
|
247882
246134
|
bypassSessionQuota: shouldBypassSessionQuota("session_chat_many")
|
|
@@ -247891,103 +246143,6 @@ ${prompt2}` : prompt2;
|
|
|
247891
246143
|
return snapshotOperation(ctx.sessionId, args2.operationId);
|
|
247892
246144
|
});
|
|
247893
246145
|
};
|
|
247894
|
-
const TaskGetToolInputSchema = object$1({
|
|
247895
|
-
taskId: string$1().trim().min(1).describe("Task id to read.")
|
|
247896
|
-
}).strict();
|
|
247897
|
-
const TaskStatusInputSchema = _enum$1(TASK_STATUS_VALUES);
|
|
247898
|
-
const TaskPriorityInputSchema = _enum$1(TASK_PRIORITY_VALUES);
|
|
247899
|
-
const TaskLabelsInputSchema = array$2(string$1().trim().min(1).max(TASK_LABEL_MAX_LENGTH)).max(TASK_LABEL_MAX_COUNT);
|
|
247900
|
-
const TASK_OWNER_SELF_ALIAS = "me";
|
|
247901
|
-
const TaskOwnerIdWriteSchema = string$1().trim().refine((value) => value === "", {
|
|
247902
|
-
message: 'Agents may only unassign an owner: pass "" . Assigning a person is a human act, and "me" is a lody_task_list filter rather than a user id.'
|
|
247903
|
-
});
|
|
247904
|
-
const TaskProjectInputSchema = discriminatedUnion("kind", [
|
|
247905
|
-
object$1({
|
|
247906
|
-
kind: literal$1("github"),
|
|
247907
|
-
repo: string$1().trim().min(1).describe("GitHub repo full name, such as owner/repo."),
|
|
247908
|
-
branch: string$1().trim().min(1).optional().describe("Base branch; defaults to main.")
|
|
247909
|
-
}).strict(),
|
|
247910
|
-
object$1({
|
|
247911
|
-
kind: literal$1("local"),
|
|
247912
|
-
projectId: string$1().trim().min(1).describe("Local project id returned by lody_session_create_options."),
|
|
247913
|
-
branch: string$1().trim().min(1).optional().describe("Optional Git branch."),
|
|
247914
|
-
worktree: boolean().optional().describe("Run the task in an isolated local git worktree for the project.")
|
|
247915
|
-
}).strict()
|
|
247916
|
-
]);
|
|
247917
|
-
const DEFAULT_TASK_GITHUB_BRANCH = "main";
|
|
247918
|
-
const toTaskProjectRef = (input2) => input2.kind === "github" ? {
|
|
247919
|
-
kind: "github",
|
|
247920
|
-
repoFullName: input2.repo,
|
|
247921
|
-
branch: input2.branch ?? DEFAULT_TASK_GITHUB_BRANCH
|
|
247922
|
-
} : {
|
|
247923
|
-
kind: "local",
|
|
247924
|
-
localProjectId: input2.projectId,
|
|
247925
|
-
...input2.branch ? {
|
|
247926
|
-
branch: input2.branch
|
|
247927
|
-
} : {},
|
|
247928
|
-
...input2.worktree ? {
|
|
247929
|
-
useWorktree: true
|
|
247930
|
-
} : {}
|
|
247931
|
-
};
|
|
247932
|
-
const TaskListToolInputSchema = object$1({
|
|
247933
|
-
status: array$2(TaskStatusInputSchema).min(1).max(TASK_STATUS_VALUES.length).optional().describe("Keep only these statuses."),
|
|
247934
|
-
ownerId: string$1().trim().optional().describe('Owner user id, "me" for the signed-in operator, or "" for unassigned tasks.'),
|
|
247935
|
-
hasAgent: boolean().optional().describe("true keeps only tasks entrusted to an agent; false keeps only tasks without one."),
|
|
247936
|
-
titleContains: string$1().trim().min(1).max(200).optional().describe("Case-insensitive substring of the title."),
|
|
247937
|
-
limit: number$4().int().min(1).max(MAX_MCP_TASK_LIST_LIMIT).optional().describe(`Maximum rows to return. Default ${DEFAULT_MCP_TASK_LIST_LIMIT}.`)
|
|
247938
|
-
}).strict();
|
|
247939
|
-
const TaskCreateToolInputSchema = object$1({
|
|
247940
|
-
title: string$1().trim().min(1).max(200).describe("Short title for the task."),
|
|
247941
|
-
body: string$1().max(2e4).optional().describe("Markdown description: context, acceptance criteria, links."),
|
|
247942
|
-
status: TaskStatusInputSchema.optional().describe("Defaults to backlog."),
|
|
247943
|
-
priority: TaskPriorityInputSchema.optional().describe("Omit to leave the task untriaged."),
|
|
247944
|
-
labels: TaskLabelsInputSchema.optional(),
|
|
247945
|
-
ownerId: TaskOwnerIdWriteSchema.optional().describe('Pass "" to create the task unassigned. Omit it to own the task as the signed-in operator; you cannot assign it to someone else.'),
|
|
247946
|
-
project: TaskProjectInputSchema.optional().describe("Repository or local project this work belongs to.")
|
|
247947
|
-
}).strict();
|
|
247948
|
-
const TaskProposeToolInputSchema = object$1({
|
|
247949
|
-
proposalId: string$1().trim().min(1).max(64).describe("Caller-chosen stable id so re-proposing the same work does not stack up cards."),
|
|
247950
|
-
title: string$1().trim().min(1).max(200).describe("Short title for the proposed task."),
|
|
247951
|
-
body: string$1().max(2e4).optional().describe("Markdown draft for the task description.")
|
|
247952
|
-
}).strict();
|
|
247953
|
-
const TASK_UPDATE_FIELDS = [
|
|
247954
|
-
"status",
|
|
247955
|
-
"title",
|
|
247956
|
-
"ownerId",
|
|
247957
|
-
"priority",
|
|
247958
|
-
"labels",
|
|
247959
|
-
"project",
|
|
247960
|
-
"pullRequestUrl"
|
|
247961
|
-
];
|
|
247962
|
-
const TaskUpdateToolInputSchema = object$1({
|
|
247963
|
-
taskId: string$1().trim().min(1),
|
|
247964
|
-
status: TaskStatusInputSchema.optional().describe("New task status. done and canceled are recorded in the task thread with your name; they do not notify the owner, so if a person needs to know, leave a comment."),
|
|
247965
|
-
title: string$1().trim().min(1).max(200).optional().describe("Replacement title."),
|
|
247966
|
-
ownerId: TaskOwnerIdWriteSchema.optional().describe('Pass "" to clear the owner. Assigning the task to a person is a human act and is not available here; ask the owner in a comment instead.'),
|
|
247967
|
-
priority: union$7([
|
|
247968
|
-
TaskPriorityInputSchema,
|
|
247969
|
-
literal$1("none")
|
|
247970
|
-
]).optional().describe('New priority, or "none" to clear it.'),
|
|
247971
|
-
labels: TaskLabelsInputSchema.optional().describe("Replaces the whole label set; pass [] to clear."),
|
|
247972
|
-
project: TaskProjectInputSchema.optional().describe("Repository or local project this work belongs to."),
|
|
247973
|
-
pullRequestUrl: string$1().trim().url().optional().describe("Pull request produced by this work. Linking it delegates task completion to the pull request.")
|
|
247974
|
-
}).strict().superRefine((value, ctx) => {
|
|
247975
|
-
if (TASK_UPDATE_FIELDS.every((field) => value[field] === void 0)) {
|
|
247976
|
-
ctx.addIssue({
|
|
247977
|
-
code: ZodIssueCode$1.custom,
|
|
247978
|
-
message: `Provide at least one field to change: ${TASK_UPDATE_FIELDS.join(", ")}.`
|
|
247979
|
-
});
|
|
247980
|
-
}
|
|
247981
|
-
});
|
|
247982
|
-
const TaskEditBodyToolInputSchema = object$1({
|
|
247983
|
-
taskId: string$1().trim().min(1),
|
|
247984
|
-
oldString: string$1().max(MAX_MCP_TASK_EDIT_CHARS).describe("Exact text to replace in the current body. Use an empty string to append a new section."),
|
|
247985
|
-
newString: string$1().max(MAX_MCP_TASK_EDIT_CHARS).describe("Replacement text.")
|
|
247986
|
-
}).strict();
|
|
247987
|
-
const TaskCommentToolInputSchema = object$1({
|
|
247988
|
-
taskId: string$1().trim().min(1),
|
|
247989
|
-
body: string$1().trim().min(1).max(2e4).describe("Markdown comment to add to the task.")
|
|
247990
|
-
}).strict();
|
|
247991
246146
|
const ReviewSubmitToolInputSchema = object$1({
|
|
247992
246147
|
verdict: _enum$1(REVIEW_VERDICT_VALUES).describe("`approve` only when nothing blocking remains."),
|
|
247993
246148
|
findings: array$2(object$1({
|
|
@@ -248009,145 +246164,17 @@ ${prompt2}` : prompt2;
|
|
|
248009
246164
|
})).max(100).optional().describe("Verdict on each previously raised finding. Use `disputed` to escalate to a human."),
|
|
248010
246165
|
summary: string$1().trim().max(2e3).optional()
|
|
248011
246166
|
}).strict();
|
|
248012
|
-
|
|
248013
|
-
const buildTaskListFilter = (args2, operatorUserId) => ({
|
|
248014
|
-
...args2.status ? {
|
|
248015
|
-
status: args2.status
|
|
248016
|
-
} : {},
|
|
248017
|
-
...args2.ownerId !== void 0 ? {
|
|
248018
|
-
ownerId: args2.ownerId === TASK_OWNER_SELF_ALIAS ? operatorUserId : args2.ownerId
|
|
248019
|
-
} : {},
|
|
248020
|
-
...args2.hasAgent !== void 0 ? {
|
|
248021
|
-
hasAgent: args2.hasAgent
|
|
248022
|
-
} : {},
|
|
248023
|
-
...args2.titleContains ? {
|
|
248024
|
-
titleContains: args2.titleContains
|
|
248025
|
-
} : {},
|
|
248026
|
-
limit: args2.limit ?? DEFAULT_MCP_TASK_LIST_LIMIT
|
|
248027
|
-
});
|
|
248028
|
-
const buildTaskUpdateInput = (args2, sessionId) => ({
|
|
248029
|
-
...args2.status ? {
|
|
248030
|
-
status: args2.status
|
|
248031
|
-
} : {},
|
|
248032
|
-
...args2.title !== void 0 ? {
|
|
248033
|
-
title: args2.title
|
|
248034
|
-
} : {},
|
|
248035
|
-
...args2.ownerId !== void 0 ? {
|
|
248036
|
-
ownerId: args2.ownerId
|
|
248037
|
-
} : {},
|
|
248038
|
-
...args2.priority !== void 0 ? {
|
|
248039
|
-
priority: args2.priority === "none" ? null : args2.priority
|
|
248040
|
-
} : {},
|
|
248041
|
-
...args2.labels !== void 0 ? {
|
|
248042
|
-
labels: args2.labels
|
|
248043
|
-
} : {},
|
|
248044
|
-
...args2.project ? {
|
|
248045
|
-
projects: [
|
|
248046
|
-
toTaskProjectRef(args2.project)
|
|
248047
|
-
]
|
|
248048
|
-
} : {},
|
|
248049
|
-
...args2.pullRequestUrl ? {
|
|
248050
|
-
pullRequest: {
|
|
248051
|
-
url: args2.pullRequestUrl,
|
|
248052
|
-
provider: resolveTaskPrProvider(args2.pullRequestUrl),
|
|
248053
|
-
originSessionId: sessionId
|
|
248054
|
-
}
|
|
248055
|
-
} : {}
|
|
248056
|
-
});
|
|
248057
|
-
const resolveTaskActor = async (manager, sessionId) => {
|
|
248058
|
-
const session2 = await readCurrentSessionMeta(manager, sessionId);
|
|
248059
|
-
if (!session2?.agentConfigId) {
|
|
248060
|
-
return {};
|
|
248061
|
-
}
|
|
248062
|
-
const config2 = await manager.getAgentConfigById(session2.agentConfigId).catch(() => void 0);
|
|
248063
|
-
return {
|
|
248064
|
-
agentConfigId: session2.agentConfigId,
|
|
248065
|
-
...config2?.name ? {
|
|
248066
|
-
name: config2.name
|
|
248067
|
-
} : {}
|
|
248068
|
-
};
|
|
248069
|
-
};
|
|
248070
|
-
const summarizeTaskBodyForMcp = (body2, key2) => {
|
|
248071
|
-
const bounded = truncateSessionHistoryText(body2, MAX_MCP_TASK_BODY_BYTES);
|
|
248072
|
-
return "truncated" in bounded ? {
|
|
248073
|
-
[key2]: bounded.text,
|
|
248074
|
-
bodyTruncated: true,
|
|
248075
|
-
bodyOmittedBytes: bounded.omittedBytes
|
|
248076
|
-
} : {
|
|
248077
|
-
[key2]: bounded.text
|
|
248078
|
-
};
|
|
248079
|
-
};
|
|
248080
|
-
const summarizeTaskIndexRowForMcp = (row) => ({
|
|
248081
|
-
taskId: row.taskId,
|
|
248082
|
-
title: row.title,
|
|
248083
|
-
status: row.status,
|
|
248084
|
-
ownerId: row.ownerId,
|
|
248085
|
-
...row.priority ? {
|
|
248086
|
-
priority: row.priority
|
|
248087
|
-
} : {},
|
|
248088
|
-
...row.labels && row.labels.length > 0 ? {
|
|
248089
|
-
labels: row.labels
|
|
248090
|
-
} : {},
|
|
248091
|
-
hasAgent: Boolean(row.hasAgent),
|
|
248092
|
-
...row.projectKind ? {
|
|
248093
|
-
projectKind: row.projectKind,
|
|
248094
|
-
projectKey: row.projectKey
|
|
248095
|
-
} : {},
|
|
248096
|
-
sessionCount: row.sessionCount ?? 0,
|
|
248097
|
-
prCount: row.prCount ?? 0,
|
|
248098
|
-
updatedAt: row.updatedAt
|
|
248099
|
-
});
|
|
248100
|
-
const summarizeTaskForMcp = (snapshot) => {
|
|
248101
|
-
const sessionLinks = getActiveTaskSessionLinks(snapshot.links);
|
|
248102
|
-
const prLinks = getActiveTaskPrLinks(snapshot.links);
|
|
248103
|
-
const allComments = snapshot.timeline.filter((entry) => entry.kind === "comment");
|
|
248104
|
-
const projects = snapshot.meta.projects ?? [];
|
|
248105
|
-
return {
|
|
248106
|
-
taskId: snapshot.meta.taskId,
|
|
248107
|
-
title: snapshot.meta.title,
|
|
248108
|
-
status: snapshot.meta.status,
|
|
248109
|
-
ownerId: snapshot.meta.ownerId,
|
|
248110
|
-
...snapshot.meta.priority ? {
|
|
248111
|
-
priority: snapshot.meta.priority
|
|
248112
|
-
} : {},
|
|
248113
|
-
...snapshot.meta.labels && snapshot.meta.labels.length > 0 ? {
|
|
248114
|
-
labels: snapshot.meta.labels
|
|
248115
|
-
} : {},
|
|
248116
|
-
hasAgent: Boolean(snapshot.meta.agent),
|
|
248117
|
-
...projects.length > 0 ? {
|
|
248118
|
-
projects: projects.map((project) => summarizeProjectRefForMcp(project))
|
|
248119
|
-
} : {},
|
|
248120
|
-
...summarizeTaskBodyForMcp(snapshot.body, "body"),
|
|
248121
|
-
sessions: sessionLinks.slice(-MAX_MCP_TASK_LINKS).map((link2) => ({
|
|
248122
|
-
sessionId: link2.sessionId,
|
|
248123
|
-
origin: link2.origin
|
|
248124
|
-
})),
|
|
248125
|
-
...sessionLinks.length > MAX_MCP_TASK_LINKS ? {
|
|
248126
|
-
sessionCount: sessionLinks.length
|
|
248127
|
-
} : {},
|
|
248128
|
-
pullRequests: prLinks.slice(-MAX_MCP_TASK_LINKS).map((link2) => ({
|
|
248129
|
-
url: link2.url,
|
|
248130
|
-
provider: link2.provider
|
|
248131
|
-
})),
|
|
248132
|
-
...prLinks.length > MAX_MCP_TASK_LINKS ? {
|
|
248133
|
-
pullRequestCount: prLinks.length
|
|
248134
|
-
} : {},
|
|
248135
|
-
comments: allComments.slice(-20).map((entry) => ({
|
|
248136
|
-
actor: entry.actorKind,
|
|
248137
|
-
actorName: entry.actorName,
|
|
248138
|
-
body: entry.body,
|
|
248139
|
-
createdAt: entry.createdAt
|
|
248140
|
-
})),
|
|
248141
|
-
...allComments.length > 20 ? {
|
|
248142
|
-
commentCount: allComments.length
|
|
248143
|
-
} : {}
|
|
248144
|
-
};
|
|
248145
|
-
};
|
|
248146
|
-
function buildLodyMcpServer(config2 = {}) {
|
|
246167
|
+
function buildLodyMcpServer() {
|
|
248147
246168
|
initCliAnalytics();
|
|
248148
246169
|
const server = new McpServer({
|
|
248149
246170
|
name: "lody",
|
|
248150
246171
|
version: "0.1.0"
|
|
246172
|
+
}, {
|
|
246173
|
+
instructions: [
|
|
246174
|
+
"Session mentions in user messages may appear as markdown links of the form [@Title](session://<sessionId>).",
|
|
246175
|
+
"To read that conversation, call lody_session_history with sessionId set to the <sessionId> (the part after session://), or pass the full session:// URI.",
|
|
246176
|
+
"Paginate with nextCursor when you need older turns."
|
|
246177
|
+
].join(" ")
|
|
248151
246178
|
});
|
|
248152
246179
|
server.registerTool(FEEDBACK_TOOL_NAME, {
|
|
248153
246180
|
title: "Send feedback about Lody",
|
|
@@ -248303,37 +246330,6 @@ ${prompt2}` : prompt2;
|
|
|
248303
246330
|
return textResult(`Failed to upload images: ${String(error2)}`, true);
|
|
248304
246331
|
}
|
|
248305
246332
|
});
|
|
248306
|
-
const taskImageUploadTool = server.registerTool(TASK_IMAGE_UPLOAD_TOOL_NAME, {
|
|
248307
|
-
title: "Upload images for a Lody task",
|
|
248308
|
-
description: "Upload local images to the current workspace and return stable Markdown image references. Use the returned markdown in lody_task_comment, lody_task_edit_body, or lody_task_propose. Unlike lody_upload_images, this does not add anything to the current conversation.",
|
|
248309
|
-
inputSchema: TaskImageUploadToolInputSchema
|
|
248310
|
-
}, async (args2) => {
|
|
248311
|
-
try {
|
|
248312
|
-
const ctx = getSessionContext();
|
|
248313
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248314
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248315
|
-
await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248316
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248317
|
-
});
|
|
248318
|
-
const images = await uploadTaskImages({
|
|
248319
|
-
paths: args2.paths.map((filePath) => resolveUploadPath(filePath, ctx.workdir)),
|
|
248320
|
-
workspaceId: workspace.id,
|
|
248321
|
-
token: auth.token
|
|
248322
|
-
});
|
|
248323
|
-
return jsonTextResult({
|
|
248324
|
-
ok: true,
|
|
248325
|
-
images: images.map((image) => ({
|
|
248326
|
-
imageId: image.imageId,
|
|
248327
|
-
fileName: image.fileName,
|
|
248328
|
-
mimeType: image.mimeType,
|
|
248329
|
-
sizeBytes: image.sizeBytes,
|
|
248330
|
-
markdown: ``
|
|
248331
|
-
}))
|
|
248332
|
-
});
|
|
248333
|
-
} catch (error2) {
|
|
248334
|
-
return mcpErrorResult(error2);
|
|
248335
|
-
}
|
|
248336
|
-
});
|
|
248337
246333
|
server.registerTool(FILE_UPLOAD_TOOL_NAME, {
|
|
248338
246334
|
title: "Upload files to Lody conversation",
|
|
248339
246335
|
description: `Use this when the user explicitly asks you to send, attach, share, or provide a downloadable file artifact in the current Lody chat (logs, reports, data, archives, binaries, documents, etc.). Do not use this merely because a file exists in the workspace: Lody can show ordinary workspace files through its file browser, so give a workspace-relative path when the user only needs to inspect one. Upload 1-${SESSION_FILE_MAX_COUNT} local files of any type (max ${SESSION_FILE_MAX_SIZE_MB} MB each). Each file is attached to this conversation as a downloadable attachment; the user can download it and, for plain-text files, preview it inline. No reusable URL is returned and nothing is written to the workspace file area. Paths may be absolute or relative to the current session workspace (which can differ from shell cwd) but must point inside the session workspace; files elsewhere on the host are rejected. Missing, unreadable, oversized (> ${SESSION_FILE_MAX_SIZE_MB} MB), or empty files are rejected with an error identifying which path failed and why.`,
|
|
@@ -248652,7 +246648,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
248652
246648
|
});
|
|
248653
246649
|
server.registerTool(SESSION_HISTORY_TOOL_NAME, {
|
|
248654
246650
|
title: "Read Lody session history",
|
|
248655
|
-
description: `Read one bounded visible transcript page, oldest-to-newest. Omit cursor for the newest page; nextCursor reads older entries. Defaults to ${DEFAULT_MCP_SESSION_HISTORY_LIMIT}, max ${MAX_MCP_SESSION_HISTORY_LIMIT}, with a 128 KiB response cap.`,
|
|
246651
|
+
description: `Read one bounded visible transcript page, oldest-to-newest. Use this for [@Title](session://<sessionId>) mention links: pass sessionId as the <sessionId> or the full session:// URI. Omit cursor for the newest page; nextCursor reads older entries. Defaults to ${DEFAULT_MCP_SESSION_HISTORY_LIMIT}, max ${MAX_MCP_SESSION_HISTORY_LIMIT}, with a 128 KiB response cap.`,
|
|
248656
246652
|
inputSchema: SessionHistoryToolInputSchema
|
|
248657
246653
|
}, async (args2) => {
|
|
248658
246654
|
try {
|
|
@@ -248661,241 +246657,6 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
248661
246657
|
return mcpErrorResult(error2);
|
|
248662
246658
|
}
|
|
248663
246659
|
});
|
|
248664
|
-
const taskListTool = server.registerTool(TASK_LIST_TOOL_NAME, {
|
|
248665
|
-
title: "List Lody tasks",
|
|
248666
|
-
description: "Find tasks in this workspace by status, owner, agent, or title, and get their ids so you can read or update one. Returns list summaries only \u2014 call lody_task_get for a task description, comments, or links.",
|
|
248667
|
-
inputSchema: TaskListToolInputSchema
|
|
248668
|
-
}, async (args2) => {
|
|
248669
|
-
try {
|
|
248670
|
-
const ctx = getSessionContext();
|
|
248671
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248672
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248673
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248674
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248675
|
-
const filter2 = buildTaskListFilter(args2, auth.userId);
|
|
248676
|
-
const page = await listTasksFromIndex(manager, workspace.id, filter2);
|
|
248677
|
-
return jsonTextResult({
|
|
248678
|
-
ok: true,
|
|
248679
|
-
tasks: page.rows.map(summarizeTaskIndexRowForMcp),
|
|
248680
|
-
...page.matched > page.rows.length ? {
|
|
248681
|
-
matched: page.matched
|
|
248682
|
-
} : {}
|
|
248683
|
-
});
|
|
248684
|
-
});
|
|
248685
|
-
} catch (error2) {
|
|
248686
|
-
return mcpErrorResult(error2);
|
|
248687
|
-
}
|
|
248688
|
-
});
|
|
248689
|
-
const taskGetTool = server.registerTool(TASK_GET_TOOL_NAME, {
|
|
248690
|
-
title: "Read a Lody task",
|
|
248691
|
-
description: "Read a task: title, status, owner, description body, linked sessions and pull requests, and recent comments. Read before editing the body so your edit matches the current text.",
|
|
248692
|
-
inputSchema: TaskGetToolInputSchema
|
|
248693
|
-
}, async (args2) => {
|
|
248694
|
-
try {
|
|
248695
|
-
const ctx = getSessionContext();
|
|
248696
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248697
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248698
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248699
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248700
|
-
const snapshot = await readTask(manager, args2.taskId);
|
|
248701
|
-
if (!snapshot) {
|
|
248702
|
-
return jsonTextResult({
|
|
248703
|
-
ok: false,
|
|
248704
|
-
error: makeLodyError("TASK_NOT_FOUND", `Task not found: ${args2.taskId}`, false)
|
|
248705
|
-
}, true);
|
|
248706
|
-
}
|
|
248707
|
-
return jsonTextResult({
|
|
248708
|
-
ok: true,
|
|
248709
|
-
task: summarizeTaskForMcp(snapshot)
|
|
248710
|
-
});
|
|
248711
|
-
});
|
|
248712
|
-
} catch (error2) {
|
|
248713
|
-
return mcpErrorResult(error2);
|
|
248714
|
-
}
|
|
248715
|
-
});
|
|
248716
|
-
const taskCreateTool = server.registerTool(TASK_CREATE_TOOL_NAME, {
|
|
248717
|
-
title: "Create a Lody task",
|
|
248718
|
-
description: "Create a task now, when the user asked in this conversation to record one. For follow-up work you noticed yourself, use lody_task_propose instead so the user decides. The task is created immediately and attributed to you; it is never started automatically, because only a person can entrust a task to an agent.",
|
|
248719
|
-
inputSchema: TaskCreateToolInputSchema
|
|
248720
|
-
}, async (args2) => {
|
|
248721
|
-
try {
|
|
248722
|
-
const ctx = getSessionContext();
|
|
248723
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248724
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248725
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248726
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248727
|
-
const actor = await resolveTaskActor(manager, ctx.sessionId);
|
|
248728
|
-
const snapshot = await createTaskFromAgent(manager, workspace.id, {
|
|
248729
|
-
title: args2.title,
|
|
248730
|
-
...args2.body !== void 0 ? {
|
|
248731
|
-
body: args2.body
|
|
248732
|
-
} : {},
|
|
248733
|
-
...args2.status ? {
|
|
248734
|
-
status: args2.status
|
|
248735
|
-
} : {},
|
|
248736
|
-
...args2.ownerId !== void 0 ? {
|
|
248737
|
-
ownerId: args2.ownerId
|
|
248738
|
-
} : {},
|
|
248739
|
-
...args2.priority ? {
|
|
248740
|
-
priority: args2.priority
|
|
248741
|
-
} : {},
|
|
248742
|
-
...args2.labels ? {
|
|
248743
|
-
labels: args2.labels
|
|
248744
|
-
} : {},
|
|
248745
|
-
...args2.project ? {
|
|
248746
|
-
projects: [
|
|
248747
|
-
toTaskProjectRef(args2.project)
|
|
248748
|
-
]
|
|
248749
|
-
} : {}
|
|
248750
|
-
}, actor, auth.userId);
|
|
248751
|
-
if (!snapshot) {
|
|
248752
|
-
return jsonTextResult({
|
|
248753
|
-
ok: false,
|
|
248754
|
-
error: makeLodyError("TASK_EMPTY", "A task needs a title or a description.", false)
|
|
248755
|
-
}, true);
|
|
248756
|
-
}
|
|
248757
|
-
return jsonTextResult({
|
|
248758
|
-
ok: true,
|
|
248759
|
-
task: summarizeTaskForMcp(snapshot)
|
|
248760
|
-
});
|
|
248761
|
-
});
|
|
248762
|
-
} catch (error2) {
|
|
248763
|
-
return mcpErrorResult(error2);
|
|
248764
|
-
}
|
|
248765
|
-
});
|
|
248766
|
-
const taskProposeTool = server.registerTool(TASK_PROPOSE_TOOL_NAME, {
|
|
248767
|
-
title: "Propose a Lody task",
|
|
248768
|
-
description: "Suggest that work be recorded as a task, when the user asks you to note something for later or you find follow-up work outside the current scope. This does not create the task: it puts a card in this conversation that the user can confirm now or days from now. Reuse the same proposalId to update your own pending proposal instead of adding another card.",
|
|
248769
|
-
inputSchema: TaskProposeToolInputSchema
|
|
248770
|
-
}, async (args2) => {
|
|
248771
|
-
try {
|
|
248772
|
-
const ctx = getSessionContext();
|
|
248773
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248774
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248775
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248776
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248777
|
-
const sessionId = ctx.sessionId;
|
|
248778
|
-
const actor = await resolveTaskActor(manager, sessionId);
|
|
248779
|
-
const proposal = await publishTaskProposal(manager, sessionId, args2, actor);
|
|
248780
|
-
return jsonTextResult({
|
|
248781
|
-
ok: true,
|
|
248782
|
-
proposalId: args2.proposalId,
|
|
248783
|
-
...proposal,
|
|
248784
|
-
note: proposal.pending ? "The proposal is synchronized. A Tasks-enabled client can now render the confirmation card." : "This proposal was already resolved, so it was not reopened."
|
|
248785
|
-
});
|
|
248786
|
-
});
|
|
248787
|
-
} catch (error2) {
|
|
248788
|
-
return mcpErrorResult(error2);
|
|
248789
|
-
}
|
|
248790
|
-
});
|
|
248791
|
-
const taskUpdateTool = server.registerTool(TASK_UPDATE_TOOL_NAME, {
|
|
248792
|
-
title: "Update a Lody task",
|
|
248793
|
-
description: "Change a task: status, title, priority, labels, project, and the pull request this work produced. Linking a pull request delegates completion to it: the task finishes when the pull request merges. Every change is attributed to you on the task. The description is edited separately with lody_task_edit_body. Two things stay human-only: entrusting an agent, and assigning an owner to a person (you may clear an owner).",
|
|
248794
|
-
inputSchema: TaskUpdateToolInputSchema
|
|
248795
|
-
}, async (args2) => {
|
|
248796
|
-
try {
|
|
248797
|
-
const ctx = getSessionContext();
|
|
248798
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248799
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248800
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248801
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248802
|
-
const sessionId = ctx.sessionId;
|
|
248803
|
-
const actor = await resolveTaskActor(manager, sessionId);
|
|
248804
|
-
const snapshot = await applyAgentTaskUpdate(manager, workspace.id, args2.taskId, buildTaskUpdateInput(args2, sessionId), actor);
|
|
248805
|
-
if (!snapshot) {
|
|
248806
|
-
return jsonTextResult({
|
|
248807
|
-
ok: false,
|
|
248808
|
-
error: makeLodyError("TASK_NOT_FOUND", `Task not found: ${args2.taskId}`, false)
|
|
248809
|
-
}, true);
|
|
248810
|
-
}
|
|
248811
|
-
return jsonTextResult({
|
|
248812
|
-
ok: true,
|
|
248813
|
-
task: summarizeTaskForMcp(snapshot)
|
|
248814
|
-
});
|
|
248815
|
-
});
|
|
248816
|
-
} catch (error2) {
|
|
248817
|
-
return mcpErrorResult(error2);
|
|
248818
|
-
}
|
|
248819
|
-
});
|
|
248820
|
-
const taskEditBodyTool = server.registerTool(TASK_EDIT_BODY_TOOL_NAME, {
|
|
248821
|
-
title: "Edit a Lody task description",
|
|
248822
|
-
description: "Replace an exact snippet of a task description, the same way a file edit works. oldString must match the current body exactly; an empty oldString appends. On a mismatch the current body is returned so you can retry. Every edit is attributed to you and recorded on the task, so edit directly rather than asking for permission first.",
|
|
248823
|
-
inputSchema: TaskEditBodyToolInputSchema
|
|
248824
|
-
}, async (args2) => {
|
|
248825
|
-
try {
|
|
248826
|
-
const ctx = getSessionContext();
|
|
248827
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248828
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248829
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248830
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248831
|
-
const sessionId = ctx.sessionId;
|
|
248832
|
-
const actor = await resolveTaskActor(manager, sessionId);
|
|
248833
|
-
const result = await applyAgentTaskBodyEdit(manager, workspace.id, args2.taskId, {
|
|
248834
|
-
oldString: args2.oldString,
|
|
248835
|
-
newString: args2.newString
|
|
248836
|
-
}, actor, sessionId);
|
|
248837
|
-
if (!result.ok) {
|
|
248838
|
-
if (result.code === "NO_MATCH") {
|
|
248839
|
-
return jsonTextResult({
|
|
248840
|
-
ok: false,
|
|
248841
|
-
error: makeLodyError("BODY_NO_MATCH", "oldString was not found in the current task body. Retry against currentBody.", true),
|
|
248842
|
-
...summarizeTaskBodyForMcp(result.body, "currentBody")
|
|
248843
|
-
}, true);
|
|
248844
|
-
}
|
|
248845
|
-
if (result.code === "AMBIGUOUS_MATCH") {
|
|
248846
|
-
return jsonTextResult({
|
|
248847
|
-
ok: false,
|
|
248848
|
-
error: makeLodyError("BODY_AMBIGUOUS_MATCH", `oldString matches ${result.occurrences} places; include more context to make it unique.`, true)
|
|
248849
|
-
}, true);
|
|
248850
|
-
}
|
|
248851
|
-
return jsonTextResult({
|
|
248852
|
-
ok: false,
|
|
248853
|
-
error: makeLodyError("TASK_NOT_FOUND", `Task not found: ${args2.taskId}`, false)
|
|
248854
|
-
}, true);
|
|
248855
|
-
}
|
|
248856
|
-
return jsonTextResult({
|
|
248857
|
-
ok: true,
|
|
248858
|
-
added: result.added,
|
|
248859
|
-
removed: result.removed,
|
|
248860
|
-
task: summarizeTaskForMcp(result.snapshot)
|
|
248861
|
-
});
|
|
248862
|
-
});
|
|
248863
|
-
} catch (error2) {
|
|
248864
|
-
return mcpErrorResult(error2);
|
|
248865
|
-
}
|
|
248866
|
-
});
|
|
248867
|
-
const taskCommentTool = server.registerTool(TASK_COMMENT_TOOL_NAME, {
|
|
248868
|
-
title: "Comment on a Lody task",
|
|
248869
|
-
description: "Add a comment to a task thread \u2014 a progress note, a summary of what you did, or a question for the owner. Comments are coordination, not execution: posting one never starts work.",
|
|
248870
|
-
inputSchema: TaskCommentToolInputSchema
|
|
248871
|
-
}, async (args2) => {
|
|
248872
|
-
try {
|
|
248873
|
-
const ctx = getSessionContext();
|
|
248874
|
-
const auth = getAuthContextOrThrow$1("mcp");
|
|
248875
|
-
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
248876
|
-
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
248877
|
-
await assertInvokingTurnTaskToolsEnabled(manager, ctx.sessionId);
|
|
248878
|
-
const sessionId = ctx.sessionId;
|
|
248879
|
-
const actor = await resolveTaskActor(manager, sessionId);
|
|
248880
|
-
const appended = await appendAgentTaskComment(manager, workspace.id, args2.taskId, {
|
|
248881
|
-
body: args2.body,
|
|
248882
|
-
originSessionId: sessionId
|
|
248883
|
-
}, actor);
|
|
248884
|
-
if (!appended) {
|
|
248885
|
-
return jsonTextResult({
|
|
248886
|
-
ok: false,
|
|
248887
|
-
error: makeLodyError("TASK_NOT_FOUND", `Task not found: ${args2.taskId}`, false)
|
|
248888
|
-
}, true);
|
|
248889
|
-
}
|
|
248890
|
-
return jsonTextResult({
|
|
248891
|
-
ok: true,
|
|
248892
|
-
taskId: args2.taskId
|
|
248893
|
-
});
|
|
248894
|
-
});
|
|
248895
|
-
} catch (error2) {
|
|
248896
|
-
return mcpErrorResult(error2);
|
|
248897
|
-
}
|
|
248898
|
-
});
|
|
248899
246660
|
server.registerTool(REVIEW_SUBMIT_TOOL_NAME, {
|
|
248900
246661
|
title: "Submit a code review",
|
|
248901
246662
|
description: "Report the result of reviewing a branch. Call this exactly once per review round. Only a session acting as a review agent can use it.",
|
|
@@ -248970,27 +246731,10 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
248970
246731
|
return mcpErrorResult(error2);
|
|
248971
246732
|
}
|
|
248972
246733
|
});
|
|
248973
|
-
if (config2.taskToolsEnabled !== true) {
|
|
248974
|
-
for (const tool of [
|
|
248975
|
-
taskImageUploadTool,
|
|
248976
|
-
taskListTool,
|
|
248977
|
-
taskGetTool,
|
|
248978
|
-
taskCreateTool,
|
|
248979
|
-
taskProposeTool,
|
|
248980
|
-
taskUpdateTool,
|
|
248981
|
-
taskEditBodyTool,
|
|
248982
|
-
taskCommentTool
|
|
248983
|
-
]) {
|
|
248984
|
-
tool.disable();
|
|
248985
|
-
}
|
|
248986
|
-
}
|
|
248987
246734
|
return server;
|
|
248988
246735
|
}
|
|
248989
246736
|
async function runLodyMcpServer() {
|
|
248990
|
-
|
|
248991
|
-
await buildLodyMcpServer({
|
|
248992
|
-
taskToolsEnabled: context2.taskToolsEnabled
|
|
248993
|
-
}).connect(new StdioServerTransport());
|
|
246737
|
+
await buildLodyMcpServer().connect(new StdioServerTransport());
|
|
248994
246738
|
}
|
|
248995
246739
|
var RequestError = class extends Error {
|
|
248996
246740
|
constructor(message, options) {
|
|
@@ -250537,9 +248281,8 @@ data:
|
|
|
250537
248281
|
const rawSessionId = singleHeader(req, MCP_HTTP_SESSION_ID_HEADER);
|
|
250538
248282
|
const workspaceId = singleHeader(req, MCP_HTTP_WORKSPACE_ID_HEADER);
|
|
250539
248283
|
const machineId = singleHeader(req, MCP_HTTP_MACHINE_ID_HEADER);
|
|
250540
|
-
const taskToolsEnabled = singleHeader(req, MCP_HTTP_TASK_TOOLS_ENABLED_HEADER);
|
|
250541
248284
|
const workdirB64 = singleHeader(req, MCP_HTTP_WORKDIR_B64_HEADER);
|
|
250542
|
-
if (!rawSessionId || !workspaceId || !machineId ||
|
|
248285
|
+
if (!rawSessionId || !workspaceId || !machineId || !workdirB64) {
|
|
250543
248286
|
return null;
|
|
250544
248287
|
}
|
|
250545
248288
|
const sessionId = SessionIdSchema$1.safeParse(rawSessionId);
|
|
@@ -250559,7 +248302,6 @@ data:
|
|
|
250559
248302
|
sessionId: sessionId.data,
|
|
250560
248303
|
workspaceId,
|
|
250561
248304
|
machineId,
|
|
250562
|
-
taskToolsEnabled: taskToolsEnabled === "1",
|
|
250563
248305
|
workdir,
|
|
250564
248306
|
localControlSocketPath: getLocalControlSocketPath()
|
|
250565
248307
|
};
|
|
@@ -250617,9 +248359,7 @@ data:
|
|
|
250617
248359
|
reject(res, 400, "Missing or invalid Lody MCP session context headers");
|
|
250618
248360
|
return;
|
|
250619
248361
|
}
|
|
250620
|
-
const server = buildLodyMcpServer(
|
|
250621
|
-
taskToolsEnabled: context2.taskToolsEnabled
|
|
250622
|
-
});
|
|
248362
|
+
const server = buildLodyMcpServer();
|
|
250623
248363
|
const transport = new StreamableHTTPServerTransport({
|
|
250624
248364
|
sessionIdGenerator: void 0,
|
|
250625
248365
|
enableJsonResponse: true
|