lody 0.96.1 → 0.97.1

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$1 = "0123456789abcdef";
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$1.charAt(this.bytes[i2] >>> 4);
572
- text += DIGITS$1.charAt(15 & this.bytes[i2]);
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$1.charAt(this.bytes[i2] >>> 4);
581
- text += DIGITS$1.charAt(15 & this.bytes[i2]);
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.96.1";
4329
+ const version$a = "0.97.1";
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$2 = (url) => {
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$2(apiBaseUrl)}${apiPath}`;
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) => {
@@ -16316,12 +16190,15 @@ Requirements:
16316
16190
  type: "idle"
16317
16191
  };
16318
16192
  },
16319
- running(activity) {
16320
- return activity ? {
16193
+ running(activity, detail) {
16194
+ return {
16321
16195
  type: "running",
16322
- activity
16323
- } : {
16324
- type: "running"
16196
+ ...activity !== void 0 ? {
16197
+ activity
16198
+ } : {},
16199
+ ...detail !== void 0 ? {
16200
+ detail
16201
+ } : {}
16325
16202
  };
16326
16203
  },
16327
16204
  requestPermission() {
@@ -16931,14 +16808,49 @@ Requirements:
16931
16808
  description: "Devin CLI coding agent by Cognition",
16932
16809
  icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/devin.svg",
16933
16810
  distribution: {
16934
- local: {
16935
- command: "devin",
16936
- args: [
16937
- "acp"
16938
- ],
16939
- versionArgs: [
16940
- "--version"
16941
- ]
16811
+ binary: {
16812
+ "darwin-aarch64": {
16813
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-aarch64-apple-darwin.tar.gz",
16814
+ cmd: "./bin/devin",
16815
+ args: [
16816
+ "acp"
16817
+ ]
16818
+ },
16819
+ "darwin-x86_64": {
16820
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-x86_64-apple-darwin.tar.gz",
16821
+ cmd: "./bin/devin",
16822
+ args: [
16823
+ "acp"
16824
+ ]
16825
+ },
16826
+ "linux-aarch64": {
16827
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-aarch64-unknown-linux.tar.gz",
16828
+ cmd: "./bin/devin",
16829
+ args: [
16830
+ "acp"
16831
+ ]
16832
+ },
16833
+ "linux-x86_64": {
16834
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-x86_64-unknown-linux.tar.gz",
16835
+ cmd: "./bin/devin",
16836
+ args: [
16837
+ "acp"
16838
+ ]
16839
+ },
16840
+ "windows-aarch64": {
16841
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-aarch64-pc-windows.zip",
16842
+ cmd: "./bin\\devin.exe",
16843
+ args: [
16844
+ "acp"
16845
+ ]
16846
+ },
16847
+ "windows-x86_64": {
16848
+ archive: "https://static.devin.ai/cli/3000.10.21/devin-3000.10.21-x86_64-pc-windows.zip",
16849
+ cmd: "./bin\\devin.exe",
16850
+ args: [
16851
+ "acp"
16852
+ ]
16853
+ }
16942
16854
  }
16943
16855
  }
16944
16856
  },
@@ -22606,7 +22518,8 @@ ${tailedOutput}` : null;
22606
22518
  type: literal$1("running"),
22607
22519
  activity: _enum$1([
22608
22520
  "image_generation"
22609
- ]).optional()
22521
+ ]).optional(),
22522
+ detail: string$1().min(1).max(280).optional()
22610
22523
  }),
22611
22524
  object$1({
22612
22525
  type: literal$1("requestPermission")
@@ -22869,9 +22782,6 @@ ${tailedOutput}` : null;
22869
22782
  ...inputConfig.mcpServerIds ? {
22870
22783
  mcpServerIds: inputConfig.mcpServerIds
22871
22784
  } : {},
22872
- ...typeof inputConfig.taskToolsEnabled === "boolean" ? {
22873
- taskToolsEnabled: inputConfig.taskToolsEnabled
22874
- } : {},
22875
22785
  ...inputConfig.agentRoleId !== void 0 ? {
22876
22786
  agentRoleId: inputConfig.agentRoleId
22877
22787
  } : {},
@@ -22899,7 +22809,6 @@ ${tailedOutput}` : null;
22899
22809
  return resolved;
22900
22810
  };
22901
22811
  const resolveSessionMcpSelection = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).mcpServerIds ?? [];
22902
- const resolveSessionTaskToolsEnabled = (history, messageQueue = []) => resolveSessionConversationConfig(history, messageQueue).taskToolsEnabled === true;
22903
22812
  const normalizeTextInputBlock = (block) => {
22904
22813
  const trimmed2 = block.text.trim();
22905
22814
  if (!trimmed2) return null;
@@ -23141,9 +23050,6 @@ ${tailedOutput}` : null;
23141
23050
  mcpServerIds: args2.mcpServerIds ? [
23142
23051
  ...args2.mcpServerIds
23143
23052
  ] : void 0,
23144
- ...args2.taskToolsEnabled !== void 0 ? {
23145
- taskToolsEnabled: args2.taskToolsEnabled === true
23146
- } : {},
23147
23053
  ...args2.agentRoleId !== void 0 ? {
23148
23054
  agentRoleId: args2.agentRoleId
23149
23055
  } : {},
@@ -23175,326 +23081,6 @@ ${tailedOutput}` : null;
23175
23081
  finished: true
23176
23082
  };
23177
23083
  };
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
23084
  const REVIEW_POLICY_FLOCK_STREAM_SEGMENT = "rp";
23499
23085
  const getReviewPolicyFlockDocId = (workspaceId) => `${workspaceId}:${REVIEW_POLICY_FLOCK_STREAM_SEGMENT}`;
23500
23086
  const REVIEW_POLICY_ROW_FAMILY = "policy";
@@ -66068,8 +65654,7 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
66068
65654
  "cliType",
66069
65655
  "agentType",
66070
65656
  "mcpServerIds",
66071
- "configOptionValues",
66072
- "taskToolsEnabled"
65657
+ "configOptionValues"
66073
65658
  ];
66074
65659
  const parseCursor = (cursor, total) => {
66075
65660
  if (cursor === void 0) return total;
@@ -66351,95 +65936,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
66351
65936
  })
66352
65937
  });
66353
65938
  }
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
65939
  const sanitizeToolCallContentForHistory = (content, kind) => {
66444
65940
  if (!content) return void 0;
66445
65941
  const filtered = stripToolCallContentForHistory(kind ?? null, content);
@@ -66519,8 +66015,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
66519
66015
  matched: turns !== history
66520
66016
  };
66521
66017
  }
66522
- case "task-proposal":
66523
- return planTaskProposal(history, action.turnId, action.meta, action.timestamp);
66524
66018
  case "upsert-goal": {
66525
66019
  let replaced = false;
66526
66020
  for (const entry of history) entry.items = entry.items?.flatMap((item) => {
@@ -67075,7 +66569,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
67075
66569
  const normalized = normalizeSessionTurnInputConfig({
67076
66570
  mcpServerIds: picked.mcpServerIds,
67077
66571
  configOptionValues: picked.configOptionValues,
67078
- taskToolsEnabled: picked.taskToolsEnabled,
67079
66572
  cliType: picked.cliType,
67080
66573
  agentType: picked.agentType
67081
66574
  });
@@ -67378,18 +66871,15 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
67378
66871
  const commands = {
67379
66872
  async applyHistoryAction(action) {
67380
66873
  let matched = action.kind === "user-status" && action.requeueUndelivered === true;
67381
- let proposal;
67382
66874
  const apply = (entries) => {
67383
66875
  const result = applyHistoryAction(entries, action);
67384
66876
  matched = result.matched;
67385
- proposal = result.proposal;
67386
66877
  return result.turns;
67387
66878
  };
67388
- if (action.kind === "operation-progress" || action.kind === "task-proposal") {
66879
+ if (action.kind === "operation-progress") {
67389
66880
  const preview = applyHistoryAction(writer.readStored(), action);
67390
66881
  if (!preview.matched) return {
67391
- matched: false,
67392
- proposal: preview.proposal
66882
+ matched: false
67393
66883
  };
67394
66884
  }
67395
66885
  const target = historyActionTarget(action);
@@ -67398,8 +66888,7 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
67398
66888
  ])[0] ?? entry);
67399
66889
  else writer.update(apply);
67400
66890
  return {
67401
- matched,
67402
- proposal
66891
+ matched
67403
66892
  };
67404
66893
  },
67405
66894
  async appendTurn(turn) {
@@ -67425,17 +66914,6 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
67425
66914
  ]);
67426
66915
  commit();
67427
66916
  },
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
66917
  async respondPermission(requestId, outcome, respondOptions) {
67440
66918
  parseHistoryWrite(PermissionOutcomeSchema, outcome);
67441
66919
  return writer.respondPermission(requestId, outcome, respondOptions);
@@ -124140,7 +123618,6 @@ ${incoming}`).output;
124140
123618
  const MCP_HTTP_SESSION_ID_HEADER = "x-lody-mcp-session-id";
124141
123619
  const MCP_HTTP_WORKSPACE_ID_HEADER = "x-lody-mcp-workspace-id";
124142
123620
  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
123621
  const MCP_HTTP_WORKDIR_B64_HEADER = "x-lody-mcp-workdir-b64";
124145
123622
  const MCP_HTTP_TOKEN_ENV = "LODY_MCP_HTTP_TOKEN";
124146
123623
  const MCP_HTTP_PREFERRED_PORT_ENV = "LODY_MCP_HTTP_PREFERRED_PORT";
@@ -124165,10 +123642,6 @@ ${incoming}`).output;
124165
123642
  name: MCP_HTTP_MACHINE_ID_HEADER,
124166
123643
  value: context2.machineId
124167
123644
  },
124168
- {
124169
- name: MCP_HTTP_TASK_TOOLS_ENABLED_HEADER,
124170
- value: context2.taskToolsEnabled ? "1" : "0"
124171
- },
124172
123645
  {
124173
123646
  name: MCP_HTTP_WORKDIR_B64_HEADER,
124174
123647
  value: Buffer.from(context2.workdir, "utf8").toString("base64url")
@@ -129945,6 +129418,21 @@ ${incoming}`).output;
129945
129418
  ])
129946
129419
  });
129947
129420
  const IMAGE_GENERATION_REVISED_PROMPT_PREFIX = "Revised prompt: ";
129421
+ const MAX_LIVE_REASONING_LABEL_LENGTH = 280;
129422
+ const latestCodexReasoningSummaryLine = (text) => {
129423
+ for (const rawLine of text.split(/\r?\n/u).reverse()) {
129424
+ let line3 = rawLine.trim();
129425
+ if (!line3 || line3.startsWith("<!--")) continue;
129426
+ line3 = line3.replace(/^#+\s*/u, "").trim();
129427
+ if (line3.startsWith("**")) {
129428
+ const closing = line3.indexOf("**", 2);
129429
+ if (closing < 0) continue;
129430
+ line3 = `${line3.slice(2, closing)}${line3.slice(closing + 2)}`.trim();
129431
+ }
129432
+ if (line3) return line3.slice(0, MAX_LIVE_REASONING_LABEL_LENGTH);
129433
+ }
129434
+ return null;
129435
+ };
129948
129436
  function isRecord$2(value) {
129949
129437
  return typeof value === "object" && value !== null;
129950
129438
  }
@@ -130058,6 +129546,8 @@ ${incoming}`).output;
130058
129546
  agentMcpCapabilities;
130059
129547
  configOptions = [];
130060
129548
  configOptionsListeners = /* @__PURE__ */ new Set();
129549
+ codexReasoningMessageId = null;
129550
+ codexReasoningText = "";
130061
129551
  configOptionValues;
130062
129552
  legacySessionModelState = null;
130063
129553
  currentModel;
@@ -130083,8 +129573,7 @@ ${incoming}`).output;
130083
129573
  sessionId: this.options.sessionId,
130084
129574
  workspaceId: this.options.workspaceId,
130085
129575
  machineId: this.options.machineId,
130086
- workdir,
130087
- taskToolsEnabled: this.options.taskToolsEnabled === true
129576
+ workdir
130088
129577
  })
130089
129578
  }
130090
129579
  ];
@@ -130114,10 +129603,6 @@ ${incoming}`).output;
130114
129603
  {
130115
129604
  name: "LODY_MCP_WORKDIR",
130116
129605
  value: workdir
130117
- },
130118
- {
130119
- name: "LODY_MCP_TASK_TOOLS_ENABLED",
130120
- value: this.options.taskToolsEnabled === true ? "1" : "0"
130121
129606
  }
130122
129607
  ];
130123
129608
  for (const [name2, value] of [
@@ -130317,9 +129802,40 @@ ${incoming}`).output;
130317
129802
  if (this.handleImageGenerationNotification(notification)) {
130318
129803
  return;
130319
129804
  }
129805
+ if (this.handleCodexLiveReasoning(notification)) {
129806
+ return;
129807
+ }
130320
129808
  this.options.onUpdateMessage(notification);
130321
129809
  return;
130322
129810
  }
129811
+ handleCodexLiveReasoning(notification) {
129812
+ if (!this.isCodexAgent()) return false;
129813
+ const { update: update2 } = notification;
129814
+ if (update2.sessionUpdate === "agent_thought_chunk") {
129815
+ if (update2.content.type !== "text") return true;
129816
+ const messageId = update2.messageId ?? "__current__";
129817
+ if (this.codexReasoningMessageId !== messageId) {
129818
+ this.codexReasoningMessageId = messageId;
129819
+ this.codexReasoningText = "";
129820
+ }
129821
+ this.codexReasoningText += update2.content.text;
129822
+ this.options.onLiveReasoningStatus?.(latestCodexReasoningSummaryLine(this.codexReasoningText));
129823
+ return true;
129824
+ }
129825
+ switch (update2.sessionUpdate) {
129826
+ case "agent_message_chunk":
129827
+ case "tool_call":
129828
+ case "tool_call_update":
129829
+ case "plan":
129830
+ if (this.codexReasoningMessageId !== null) {
129831
+ this.codexReasoningMessageId = null;
129832
+ this.codexReasoningText = "";
129833
+ this.options.onLiveReasoningStatus?.(null);
129834
+ }
129835
+ break;
129836
+ }
129837
+ return false;
129838
+ }
130323
129839
  handleGoalSessionInfoUpdate(notification) {
130324
129840
  if (notification.update.sessionUpdate !== "session_info_update") {
130325
129841
  return;
@@ -137047,11 +136563,11 @@ ${fallbackStderrTail}` : errorMessage2;
137047
136563
  agentConfig: options.agentConfig,
137048
136564
  configOptionValues: options.configOptionValues,
137049
136565
  resolveWorktreeProject: options.resolveWorktreeProject,
137050
- taskToolsEnabled: options.taskToolsEnabled,
137051
136566
  launcher: options.launcher,
137052
136567
  terminalEnabled: options.terminalEnabled,
137053
136568
  onStartupStage: options.onStartupStage,
137054
136569
  onUpdateMessage: options.onUpdateMessage,
136570
+ onLiveReasoningStatus: options.onLiveReasoningStatus,
137055
136571
  onRequestPermission: options.onRequestPermission,
137056
136572
  onUsageUpdate: options.onUsageUpdate,
137057
136573
  onContextWindowUsageUpdate: options.onContextWindowUsageUpdate,
@@ -138839,7 +138355,7 @@ ${fallbackStderrTail}` : errorMessage2;
138839
138355
  const phaseToStatus = (phase, detail) => {
138840
138356
  switch (phase ?? "thinking") {
138841
138357
  case "thinking":
138842
- return SessionStatusFactory.running();
138358
+ return SessionStatusFactory.running(void 0, detail);
138843
138359
  case "initializing":
138844
138360
  return SessionStatusFactory.initializing(void 0, detail);
138845
138361
  case "git-clone":
@@ -143082,7 +142598,10 @@ ${withCauses}`;
143082
142598
  type: "successor"
143083
142599
  }))
143084
142600
  ]);
143085
- if (settled.type === "prompt" && !run2.successor) runtime.steerWaitController?.abort();
142601
+ const handoffVerdictPending = !!runtime.pendingHandoffSteerOutcome && !runtime.cancelRequested;
142602
+ if (settled.type === "prompt" && !run2.successor && !handoffVerdictPending) {
142603
+ runtime.steerWaitController?.abort();
142604
+ }
143086
142605
  const decision = await this.steerMutationQueue.enqueue(runtime.sessionId, async () => {
143087
142606
  if (this.turnRuntimeBySession.get(runtime.sessionId) !== runtime || !runtime.promptInFlight) {
143088
142607
  return {
@@ -143639,6 +143158,16 @@ ${withCauses}`;
143639
143158
  const previousUserTurnId = runtime.userTurnId;
143640
143159
  const steerRun = agentClient.steerPrompt(acpSessionId, promptBlocks);
143641
143160
  providerSubmissionStarted = true;
143161
+ if (steerCapability.upstreamTurn === "handoff") {
143162
+ const pendingOutcome = steerRun.outcome;
143163
+ runtime.pendingHandoffSteerOutcome = pendingOutcome;
143164
+ const clear = () => {
143165
+ if (runtime.pendingHandoffSteerOutcome === pendingOutcome) {
143166
+ runtime.pendingHandoffSteerOutcome = void 0;
143167
+ }
143168
+ };
143169
+ void pendingOutcome.then(clear, clear);
143170
+ }
143642
143171
  let steerOutcome;
143643
143172
  try {
143644
143173
  steerOutcome = await wait(steerRun.outcome);
@@ -145234,7 +144763,6 @@ ${withCauses}`;
145234
144763
  agentType: acpSessionConfig.agentType,
145235
144764
  configOptionValues: acpSessionConfig.configOptionValues,
145236
144765
  mcpServerIds: acpSessionConfig.mcpServerIds ?? [],
145237
- taskToolsEnabled: acpSessionConfig.taskToolsEnabled === true,
145238
144766
  customAcp: resumeCustomAcp,
145239
144767
  runtimeOverrides: resumeRuntimeOverrides,
145240
144768
  requesterUserId: userId,
@@ -145749,7 +145277,6 @@ ${withCauses}`;
145749
145277
  agentType: acpSessionConfig.agentType,
145750
145278
  configOptionValues: acpSessionConfig.configOptionValues,
145751
145279
  mcpServerIds: acpSessionConfig.mcpServerIds ?? [],
145752
- taskToolsEnabled: acpSessionConfig.taskToolsEnabled === true,
145753
145280
  agentConfigId: existingMeta?.agentConfigId,
145754
145281
  customAcp: acpSessionConfig.customAcp,
145755
145282
  runtimeOverrides: acpSessionConfig.runtimeOverrides,
@@ -148260,7 +147787,6 @@ ${withCauses}`;
148260
147787
  modelId: entry.inputConfig?.modelId,
148261
147788
  configOptionValues: entry.inputConfig?.configOptionValues,
148262
147789
  mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
148263
- taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
148264
147790
  agentRoleId: entry.inputConfig?.agentRoleId,
148265
147791
  agentRoleRevision: entry.inputConfig?.agentRoleRevision,
148266
147792
  issuePRMentions: entry.inputConfig?.issuePRMentions,
@@ -148295,7 +147821,6 @@ ${withCauses}`;
148295
147821
  modelId: entry.inputConfig?.modelId,
148296
147822
  configOptionValues: entry.inputConfig?.configOptionValues,
148297
147823
  mcpServerIds: entry.inputConfig?.mcpServerIds ?? [],
148298
- taskToolsEnabled: entry.inputConfig?.taskToolsEnabled === true,
148299
147824
  agentRoleId: entry.inputConfig?.agentRoleId,
148300
147825
  agentRoleRevision: entry.inputConfig?.agentRoleRevision,
148301
147826
  issuePRMentions: entry.inputConfig?.issuePRMentions,
@@ -148369,7 +147894,6 @@ ${withCauses}`;
148369
147894
  modelId: queuedItem.acpSessionConfig?.modelId,
148370
147895
  configOptionValues: isConfigOptionValueRecord(queuedItem.acpSessionConfig?.configOptionValues) ? queuedItem.acpSessionConfig.configOptionValues : void 0,
148371
147896
  mcpServerIds: normalizeMcpServerIdSelection(queuedItem.acpSessionConfig?.mcpServerIds) ?? [],
148372
- taskToolsEnabled: queuedItem.acpSessionConfig?.taskToolsEnabled === true,
148373
147897
  agentRoleId: queuedItem.acpSessionConfig?.agentRoleId,
148374
147898
  agentRoleRevision: queuedItem.acpSessionConfig?.agentRoleRevision,
148375
147899
  issuePRMentions: queuedItem.acpSessionConfig?.issuePRMentions,
@@ -149211,7 +148735,6 @@ ${withCauses}`;
149211
148735
  agentCliType: marker.cleanup.cliType,
149212
148736
  agentType: marker.cleanup.agentType,
149213
148737
  mcpServerIds: resolveSessionMcpSelection(history),
149214
- taskToolsEnabled: false,
149215
148738
  project: marker.cleanup.project,
149216
148739
  sessionId: targetSessionId,
149217
148740
  githubRepo: marker.cleanup.repoFullName,
@@ -149563,7 +149086,6 @@ ${withCauses}`;
149563
149086
  agentCliType: source.cliType,
149564
149087
  agentType: source.agentType,
149565
149088
  mcpServerIds: resolveSessionMcpSelection(historyResult.history),
149566
- taskToolsEnabled: resolveSessionTaskToolsEnabled(historyResult.history),
149567
149089
  customAcp: agentConfig.customAcp,
149568
149090
  runtimeOverrides: agentConfig.runtimeOverrides,
149569
149091
  env: agentConfig.env,
@@ -149657,7 +149179,6 @@ ${withCauses}`;
149657
149179
  agentCliType: source.cliType,
149658
149180
  agentType: source.agentType,
149659
149181
  mcpServerIds: resolveSessionMcpSelection(historyResult.history),
149660
- taskToolsEnabled: resolveSessionTaskToolsEnabled(historyResult.history),
149661
149182
  customAcp: agentConfig.customAcp,
149662
149183
  runtimeOverrides: agentConfig.runtimeOverrides,
149663
149184
  env: agentConfig.env,
@@ -149815,7 +149336,7 @@ ${withCauses}`;
149815
149336
  let commitEditable = editable;
149816
149337
  let commitMeta = meta;
149817
149338
  try {
149818
- runtime = await this.getOrRestoreRuntime(meta, spec.requestedByUserId, resolveSessionMcpSelection(history), spec.inputConfig.taskToolsEnabled === true);
149339
+ runtime = await this.getOrRestoreRuntime(meta, spec.requestedByUserId, resolveSessionMcpSelection(history));
149819
149340
  const agentClient = runtime.agentClient;
149820
149341
  oldAcpSessionId = runtime.acpSessionId;
149821
149342
  if (!agentClient || !oldAcpSessionId) {
@@ -150006,7 +149527,7 @@ ${withCauses}`;
150006
149527
  resume: preparedSessionId
150007
149528
  };
150008
149529
  }
150009
- async getOrRestoreRuntime(meta, requestedByUserId, mcpServerIds, taskToolsEnabled) {
149530
+ async getOrRestoreRuntime(meta, requestedByUserId, mcpServerIds) {
150010
149531
  const existing = this.deps.sessionManager.getSession(meta.id);
150011
149532
  if (existing) return existing;
150012
149533
  if (!meta.acpSessionId || !meta.agentConfigId) {
@@ -150027,7 +149548,6 @@ ${withCauses}`;
150027
149548
  agentCliType: meta.cliType,
150028
149549
  agentType: meta.agentType,
150029
149550
  mcpServerIds,
150030
- taskToolsEnabled,
150031
149551
  customAcp: agentConfig.customAcp,
150032
149552
  runtimeOverrides: agentConfig.runtimeOverrides,
150033
149553
  env: agentConfig.env,
@@ -150080,9 +149600,8 @@ ${withCauses}`;
150080
149600
  string$1(),
150081
149601
  boolean()
150082
149602
  ])).optional(),
150083
- taskToolsEnabled: boolean().optional(),
150084
149603
  inheritSessionDefaults: literal$1(false).optional()
150085
- }).strict().nullable()).optional()
149604
+ }).strip().nullable()).optional()
150086
149605
  }).strict();
150087
149606
  const OperationRowSchema = object$1({
150088
149607
  workspace_id: string$1(),
@@ -162757,510 +162276,6 @@ ${part.truncated ? TRUNCATION_MARKER : ""}${part.content}`).join("\n\n");
162757
162276
  }
162758
162277
  return table2.toString();
162759
162278
  }
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
162279
  function sortAgentConfigs(configs) {
163265
162280
  return [
163266
162281
  ...configs
@@ -164727,7 +163742,6 @@ ${entry.text}`).join("\n\n");
164727
163742
  modeId: args2.modeId,
164728
163743
  modelId: args2.modelId,
164729
163744
  configOptionValues: args2.configOptionValues && Object.keys(args2.configOptionValues).length > 0 ? args2.configOptionValues : void 0,
164730
- taskToolsEnabled: args2.taskToolsEnabled === true,
164731
163745
  resume: args2.resume,
164732
163746
  chainDepth: args2.chainDepth
164733
163747
  };
@@ -164748,9 +163762,6 @@ ${entry.text}`).join("\n\n");
164748
163762
  };
164749
163763
  return {
164750
163764
  config: {
164751
- ...rest.taskToolsEnabled !== void 0 ? {
164752
- taskToolsEnabled: rest.taskToolsEnabled
164753
- } : {},
164754
163765
  ...resolved.modeId ?? rest.modeId ? {
164755
163766
  modeId: resolved.modeId ?? rest.modeId
164756
163767
  } : {},
@@ -164827,8 +163838,7 @@ ${entry.text}`).join("\n\n");
164827
163838
  return {
164828
163839
  modeId: explicitConfig.modeId ?? fallbackConfig?.modeId,
164829
163840
  modelId: explicitConfig.modelId ?? fallbackConfig?.modelId,
164830
- configOptionValues: explicitConfig.configOptionValues ?? fallbackConfig?.configOptionValues,
164831
- taskToolsEnabled: explicitConfig.taskToolsEnabled ?? fallbackConfig?.taskToolsEnabled
163841
+ configOptionValues: explicitConfig.configOptionValues ?? fallbackConfig?.configOptionValues
164832
163842
  };
164833
163843
  }
164834
163844
  function validateConfigOptionValue(option2, value) {
@@ -164963,9 +163973,6 @@ ${entry.text}`).join("\n\n");
164963
163973
  } : {},
164964
163974
  ...configOptionValues ? {
164965
163975
  configOptionValues
164966
- } : {},
164967
- ...config2.taskToolsEnabled !== void 0 ? {
164968
- taskToolsEnabled: config2.taskToolsEnabled
164969
163976
  } : {}
164970
163977
  };
164971
163978
  }
@@ -164997,9 +164004,6 @@ ${entry.text}`).join("\n\n");
164997
164004
  } : {},
164998
164005
  ...inputConfig.configOptionValues ? {
164999
164006
  configOptionValues: inputConfig.configOptionValues
165000
- } : {},
165001
- ...inputConfig.taskToolsEnabled !== void 0 ? {
165002
- taskToolsEnabled: inputConfig.taskToolsEnabled
165003
164007
  } : {}
165004
164008
  };
165005
164009
  }
@@ -165703,7 +164707,6 @@ ${entry.text}`).join("\n\n");
165703
164707
  const currentSession = currentSessionId ? await resolveSessionMetaOrThrow(args2.manager, currentSessionId) : void 0;
165704
164708
  const parentSession = parentSessionId ? await resolveSessionMetaOrThrow(args2.manager, parentSessionId) : void 0;
165705
164709
  assertSupportedParentDepth(parentSession);
165706
- const taskId = normalizeCliValue(args2.options.taskId) ?? currentSession?.taskId;
165707
164710
  const targetMachine = await resolveTargetMachineForCreate({
165708
164711
  manager: args2.manager,
165709
164712
  workspaceId,
@@ -165789,10 +164792,7 @@ ${entry.text}`).join("\n\n");
165789
164792
  ...parentSessionId ? {
165790
164793
  parentSessionId
165791
164794
  } : {},
165792
- ...resolveOpenedBySessionRelation(currentSession),
165793
- ...taskId ? {
165794
- taskId
165795
- } : {}
164795
+ ...resolveOpenedBySessionRelation(currentSession)
165796
164796
  };
165797
164797
  }
165798
164798
  async function validateSessionCreateOptions(args2) {
@@ -165866,7 +164866,7 @@ ${entry.text}`).join("\n\n");
165866
164866
  options,
165867
164867
  requester
165868
164868
  });
165869
- const { targetMachine, agentConfig, project, parentSessionId, openedBySessionId, openedByRootSessionId, taskId } = resolved;
164869
+ const { targetMachine, agentConfig, project, parentSessionId, openedBySessionId, openedByRootSessionId } = resolved;
165870
164870
  const effectiveDispatchConfig = await resolveEffectiveSessionCreateDispatchConfig({
165871
164871
  manager,
165872
164872
  workspaceId: workspace.id,
@@ -165918,9 +164918,6 @@ ${entry.text}`).join("\n\n");
165918
164918
  } : {},
165919
164919
  ...options.agentRoleRevision !== void 0 ? {
165920
164920
  agentRoleRevision: options.agentRoleRevision
165921
- } : {},
165922
- ...taskId ? {
165923
- taskId
165924
164921
  } : {}
165925
164922
  });
165926
164923
  let completionAbortController;
@@ -165941,7 +164938,6 @@ ${entry.text}`).join("\n\n");
165941
164938
  modeId: modeId ?? void 0,
165942
164939
  modelId: modelId ?? void 0,
165943
164940
  configOptionValues: effectiveDispatchConfig.configOptionValues,
165944
- taskToolsEnabled: taskId ? true : effectiveDispatchConfig.taskToolsEnabled,
165945
164941
  chainDepth: options.chainDepth
165946
164942
  }),
165947
164943
  preallocatedId: options.userTurnId
@@ -165981,17 +164977,6 @@ ${entry.text}`).join("\n\n");
165981
164977
  timestamp: userTurn.timestamp,
165982
164978
  inputConfig: userTurn.inputConfig
165983
164979
  });
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
164980
  return {
165996
164981
  sessionId,
165997
164982
  machineId: targetMachine.id,
@@ -166010,9 +164995,6 @@ ${entry.text}`).join("\n\n");
166010
164995
  ...openedByRootSessionId ? {
166011
164996
  openedByRootSessionId
166012
164997
  } : {},
166013
- ...taskId ? {
166014
- taskId
166015
- } : {},
166016
164998
  completionPromise
166017
164999
  };
166018
165000
  } catch (error2) {
@@ -166098,7 +165080,6 @@ ${entry.text}`).join("\n\n");
166098
165080
  modeId: effectiveDispatchConfig.modeId,
166099
165081
  modelId: effectiveDispatchConfig.modelId,
166100
165082
  configOptionValues: effectiveDispatchConfig.configOptionValues,
166101
- taskToolsEnabled: effectiveDispatchConfig.taskToolsEnabled,
166102
165083
  resume: session2.acpSessionId ?? void 0,
166103
165084
  chainDepth: orchestration?.chainDepth
166104
165085
  }),
@@ -173701,7 +172682,7 @@ ${entry.text}`).join("\n\n");
173701
172682
  const shouldIgnoreTunnelSendError = (error2) => options.interrupted() || error2 instanceof Error && error2.message === "Tunnel connection is unavailable";
173702
172683
  const handleBackgroundTunnelSendError = (error2) => {
173703
172684
  if (!shouldIgnoreTunnelSendError(error2)) {
173704
- console.warn(`Failed to send preview tunnel message: ${formatError$1(error2)}`);
172685
+ console.warn(`Failed to send preview tunnel message: ${formatError(error2)}`);
173705
172686
  }
173706
172687
  };
173707
172688
  return new Promise((resolve2, reject2) => {
@@ -173745,7 +172726,7 @@ ${entry.text}`).join("\n\n");
173745
172726
  });
173746
172727
  return;
173747
172728
  }
173748
- const message = event.message || formatError$1(event.error) || "Unknown WebSocket error";
172729
+ const message = event.message || formatError(event.error) || "Unknown WebSocket error";
173749
172730
  resolve2({
173750
172731
  kind: "disconnected",
173751
172732
  message: `Preview tunnel connection error: ${message}`
@@ -173809,7 +172790,7 @@ ${entry.text}`).join("\n\n");
173809
172790
  void sendMessage({
173810
172791
  type: "response-error",
173811
172792
  requestId: message.requestId,
173812
- message: formatError$1(error2)
172793
+ message: formatError(error2)
173813
172794
  }).catch(handleBackgroundTunnelSendError);
173814
172795
  });
173815
172796
  return;
@@ -173836,7 +172817,7 @@ ${entry.text}`).join("\n\n");
173836
172817
  void sendMessage({
173837
172818
  type: "websocket-reject",
173838
172819
  requestId: message.requestId,
173839
- message: formatError$1(error2)
172820
+ message: formatError(error2)
173840
172821
  }).catch(handleBackgroundTunnelSendError);
173841
172822
  }
173842
172823
  return;
@@ -174021,7 +173002,7 @@ ${entry.text}`).join("\n\n");
174021
173002
  await sendMessage({
174022
173003
  type: "response-error",
174023
173004
  requestId: message.requestId,
174024
- message: formatError$1(error2)
173005
+ message: formatError(error2)
174025
173006
  }).catch((sendError) => {
174026
173007
  if (!shouldIgnoreTunnelSendError(sendError)) throw sendError;
174027
173008
  });
@@ -174094,7 +173075,7 @@ ${entry.text}`).join("\n\n");
174094
173075
  localSocket.terminate();
174095
173076
  });
174096
173077
  localSocket.on("error", (error2) => {
174097
- if (!socketContext.handshakeSettled) rejectHandshake(formatError$1(error2));
173078
+ if (!socketContext.handshakeSettled) rejectHandshake(formatError(error2));
174098
173079
  });
174099
173080
  localSocket.on("close", (code2, reasonBuffer) => {
174100
173081
  const reason = Buffer$2.from(reasonBuffer).toString("utf8");
@@ -174185,7 +173166,7 @@ ${entry.text}`).join("\n\n");
174185
173166
  queueBackgroundMessage({
174186
173167
  type: "response-error",
174187
173168
  requestId,
174188
- message: formatError$1(error2)
173169
+ message: formatError(error2)
174189
173170
  });
174190
173171
  }
174191
173172
  });
@@ -174515,12 +173496,12 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
174515
173496
  function formatLocalWebSocketClose(code2, reason) {
174516
173497
  return reason ? `Local WebSocket connection closed during handshake (${code2}: ${reason})` : `Local WebSocket connection closed during handshake (${code2})`;
174517
173498
  }
174518
- function formatError$1(error2) {
173499
+ function formatError(error2) {
174519
173500
  if (error2 instanceof Error) return error2.message;
174520
173501
  return typeof error2 === "string" ? error2 : "Unknown error";
174521
173502
  }
174522
173503
  function asError(error2) {
174523
- return error2 instanceof Error ? error2 : new Error(formatError$1(error2));
173504
+ return error2 instanceof Error ? error2 : new Error(formatError(error2));
174524
173505
  }
174525
173506
  async function withTimeout$1(promise2, timeoutMs, message) {
174526
173507
  let timeoutHandle;
@@ -179544,10 +178525,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
179544
178525
  await createSessionResult(auth, workspace, this.workspaceDocument, prompt2, options, dispatchConfig);
179545
178526
  return;
179546
178527
  }
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, {
178528
+ await sendSessionChatResult(auth, workspace, this.workspaceDocument, item.target.sessionId, prompt2, resolveTurnDispatchConfig({}), void 0, delegatedRequester ? void 0 : operation.requesterUserId, {
179551
178529
  userTurnId: item.target.userTurnId,
179552
178530
  chainDepth: operation.initiatorChainDepth + 1,
179553
178531
  bypassSessionQuota: shouldBypassSessionQuota(operation.kind)
@@ -179618,6 +178596,9 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
179618
178596
  this.sessionManager.on("onACPUpdateMessage", (sessionId, update2) => {
179619
178597
  this.enqueueACPUpdate(sessionId, update2);
179620
178598
  });
178599
+ this.sessionManager.on("onCodexLiveReasoningStatus", (sessionId, label2) => {
178600
+ this.setSessionActivePresencePhase(sessionId, "thinking", label2 ?? void 0);
178601
+ });
179621
178602
  this.sessionManager.on("onWriteTextFile", (sessionId, event) => {
179622
178603
  this.trackCodeCollabEvidenceWrite(sessionId, this.collectCodeCollabWriteTextFileEvidence(sessionId, event));
179623
178604
  });
@@ -188416,7 +187397,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
188416
187397
  agentType: callbacks.agentType
188417
187398
  },
188418
187399
  configOptionValues: this.config.configOptionValues,
188419
- taskToolsEnabled: this.config.taskToolsEnabled,
188420
187400
  launcher,
188421
187401
  workspaceId: this.config.workspaceId,
188422
187402
  machineId: this.config.machineId,
@@ -188425,6 +187405,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
188425
187405
  forkSessionTurnId: callbacks.forkSessionTurnId,
188426
187406
  onStartupStage: callbacks.onStartupStage,
188427
187407
  onUpdateMessage: callbacks.onUpdateMessage,
187408
+ onLiveReasoningStatus: callbacks.onLiveReasoningStatus,
188428
187409
  onRequestPermission: callbacks.onRequestPermission,
188429
187410
  onUsageUpdate: callbacks.onUsageUpdate,
188430
187411
  onContextWindowUsageUpdate: callbacks.onContextWindowUsageUpdate,
@@ -189154,7 +188135,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189154
188135
  }
189155
188136
  };
189156
188137
  }
189157
- function buildSessionPreparationCompatibility(launchSource, mcpServerIds, configOptionValues, taskToolsEnabled) {
188138
+ function buildSessionPreparationCompatibility(launchSource, mcpServerIds, configOptionValues) {
189158
188139
  return {
189159
188140
  launch: buildSessionLaunchConfig({
189160
188141
  customAcp: launchSource?.customAcp,
@@ -189165,8 +188146,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189165
188146
  mcpServerIds: mcpServerIds ? [
189166
188147
  ...mcpServerIds
189167
188148
  ] : void 0,
189168
- configOptionValues,
189169
- taskToolsEnabled
188149
+ configOptionValues
189170
188150
  })
189171
188151
  };
189172
188152
  }
@@ -189283,7 +188263,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189283
188263
  return null;
189284
188264
  }
189285
188265
  const current2 = resource.readCurrentLaunchConfig(sessionMeta);
189286
- if (!current2 || !isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, resource.config.mcpServerIds, resource.config.configOptionValues, resource.config.taskToolsEnabled))) {
188266
+ if (!current2 || !isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, resource.config.mcpServerIds, resource.config.configOptionValues))) {
189287
188267
  return null;
189288
188268
  }
189289
188269
  return {
@@ -189324,7 +188304,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189324
188304
  await this.preparationService.discard(sessionId);
189325
188305
  return await this.createSessionInnerWithAgent(config2, agentStart);
189326
188306
  }
189327
- const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues, config2.taskToolsEnabled);
188307
+ const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues);
189328
188308
  const claim = this.preparationService.claim({
189329
188309
  sessionId,
189330
188310
  requesterUserId: config2.requesterUserId,
@@ -189343,7 +188323,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189343
188323
  cliType: config2.agentCliType,
189344
188324
  agentType: config2.agentType
189345
188325
  });
189346
- return current2 !== null && isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, config2.mcpServerIds, config2.configOptionValues, config2.taskToolsEnabled));
188326
+ return current2 !== null && isDeepStrictEqual(resource.compatibility, buildSessionPreparationCompatibility(current2.config, config2.mcpServerIds, config2.configOptionValues));
189347
188327
  }
189348
188328
  });
189349
188329
  if (claim.status === "miss") {
@@ -189501,7 +188481,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189501
188481
  agentType: spec.agentType,
189502
188482
  configOptionValues: spec.runConfig?.configOptionValues,
189503
188483
  mcpServerIds: spec.runConfig?.mcpServerIds ?? [],
189504
- taskToolsEnabled: spec.runConfig?.taskToolsEnabled === true,
189505
188484
  customAcp: agentConfig.customAcp,
189506
188485
  runtimeOverrides: agentConfig.runtimeOverrides,
189507
188486
  project: spec.project,
@@ -189515,7 +188494,7 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189515
188494
  userName: user.name,
189516
188495
  userEmail: user.email
189517
188496
  };
189518
- const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues, config2.taskToolsEnabled);
188497
+ const compatibility = buildSessionPreparationCompatibility(config2, config2.mcpServerIds, config2.configOptionValues);
189519
188498
  const ghTokenInjected = await this.prepareGitHubRepoSessionConfig(config2);
189520
188499
  signal.throwIfAborted();
189521
188500
  const launch = await resolveACPProcessLaunchAsync({
@@ -189773,6 +188752,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
189773
188752
  onUpdateMessage: (update2) => {
189774
188753
  dispatchEvent(() => this.emit("onACPUpdateMessage", sessionId, update2));
189775
188754
  },
188755
+ onLiveReasoningStatus: (label2) => {
188756
+ dispatchEvent(() => this.emit("onCodexLiveReasoningStatus", sessionId, label2));
188757
+ },
189776
188758
  onRequestPermission: (requestId, request2) => {
189777
188759
  if (options?.allowInteractiveRequest && !options.allowInteractiveRequest()) {
189778
188760
  return Promise.resolve({
@@ -194426,344 +193408,6 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
194426
193408
  counters: () => scheduler.counters
194427
193409
  };
194428
193410
  };
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
193411
  const openReviewFlock = async (repo, workspaceId) => await repo.openFlockDoc(getReviewPolicyFlockDocId(workspaceId));
194768
193412
  const readReviewPolicy = async (repo, workspaceId) => {
194769
193413
  const handle = await openReviewFlock(repo, workspaceId);
@@ -197008,7 +195652,6 @@ ${trimmed2}${closing}`;
197008
195652
  await runtime.lody.cleanup();
197009
195653
  runtime.unsubscribeTerminalCleanup();
197010
195654
  await runtime.prPollerWorkspace?.dispose();
197011
- await runtime.taskAutomation?.dispose();
197012
195655
  await runtime.reviewAutomation?.dispose();
197013
195656
  } catch (error2) {
197014
195657
  runtime.unsubscribeTerminalCleanup();
@@ -197193,30 +195836,6 @@ ${trimmed2}${closing}`;
197193
195836
  prAssociation: this.cloudPort.prAssociation,
197194
195837
  logger: workspaceLogger
197195
195838
  }) : 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
195839
  const reviewAutomation = this.cloudPort.githubTokens ? createReviewAutomation({
197221
195840
  documentManager: startedLody.documentManager,
197222
195841
  workspaceId: workspace.id,
@@ -197267,7 +195886,6 @@ ${trimmed2}${closing}`;
197267
195886
  lody: startedLody,
197268
195887
  unsubscribeTerminalCleanup,
197269
195888
  prPollerWorkspace,
197270
- taskAutomation,
197271
195889
  reviewAutomation
197272
195890
  });
197273
195891
  if (prPollerWorkspace) {
@@ -199343,7 +197961,7 @@ Shutting down gracefully${reason}...`);
199343
197961
  authBaseUrl: LODY_AUTH_URL,
199344
197962
  authSiteUrl: LODY_AUTH_SITE_URL,
199345
197963
  serverBaseUrl: LODY_SERVER_URL,
199346
- previewGatewayUrl: process.env.LODY_PREVIEW_GATEWAY_URL,
197964
+ previewGatewayUrl: "",
199347
197965
  runtimeArtifactsBaseUrl: process.env.LODY_RUNTIME_BASE_URL,
199348
197966
  logger: logger2
199349
197967
  });
@@ -225823,17 +224441,11 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
225823
224441
  }
225824
224442
  async function listSyncableFlockDocIds(manager, workspaceId) {
225825
224443
  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));
224444
+ return machines.map((entry) => getMachineFlockDocId(workspaceId, entry.meta.id)).sort((left2, right2) => left2.localeCompare(right2));
225830
224445
  }
225831
- function buildSyncDocIds(aliveRoomIds, taskIds) {
224446
+ function buildSyncDocIds(aliveRoomIds) {
225832
224447
  return [
225833
- .../* @__PURE__ */ new Set([
225834
- ...aliveRoomIds,
225835
- ...taskIds.map((taskId) => getTaskRoomId(taskId))
225836
- ])
224448
+ ...aliveRoomIds
225837
224449
  ].sort((left2, right2) => left2.localeCompare(right2));
225838
224450
  }
225839
224451
  async function syncWorkspace(input2) {
@@ -225863,8 +224475,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
225863
224475
  });
225864
224476
  return;
225865
224477
  }
225866
- const taskIds = await listWorkspaceTaskIds(manager, workspaceId).catch(() => []);
225867
- const docIds = buildSyncDocIds(await listAliveRoomIds(manager, () => true), taskIds);
224478
+ const docIds = buildSyncDocIds(await listAliveRoomIds(manager, () => true));
225868
224479
  const flockDocIds = await listSyncableFlockDocIds(manager, workspaceId);
225869
224480
  await syncItems({
225870
224481
  summary: summary2,
@@ -226638,58 +225249,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
226638
225249
  }
226639
225250
  };
226640
225251
  }
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
225252
  const SESSION_EXPORT_CONCURRENCY = 4;
226694
225253
  const ATTACHMENT_EXPORT_CONCURRENCY = 4;
226695
225254
  function sortSessionsByCreatedAt(sessions) {
@@ -226796,27 +225355,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
226796
225355
  relativePath: path__default.posix.join("sessions", sessionDirName)
226797
225356
  };
226798
225357
  }
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
225358
  async function exportWorkspaceData(options) {
226821
225359
  const downloadImages = options.downloadImages !== false;
226822
225360
  const warnings = [];
@@ -226834,13 +225372,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
226834
225372
  warnings
226835
225373
  }));
226836
225374
  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
225375
  let usageExported = false;
226845
225376
  try {
226846
225377
  const usageBundle = await fetchWorkspaceUsageBundle({
@@ -226863,7 +225394,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
226863
225394
  },
226864
225395
  outputDir: options.outputDir,
226865
225396
  sessionCount: sessionIndex.length,
226866
- taskCount: taskIndex.length,
225397
+ taskCount: 0,
226867
225398
  usageExported
226868
225399
  };
226869
225400
  await writeJson(path__default.join(options.outputDir, "manifest.json"), manifest);
@@ -226888,11 +225419,6 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
226888
225419
  await mapWithConcurrency$1(sessions, EXPORT_SYNC_CONCURRENCY, async (entry) => {
226889
225420
  await syncDocForRead(manager, getSessionRoomId(entry.meta.id), `export:${workspace.id}:${entry.meta.id}`);
226890
225421
  });
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
225422
  }
226897
225423
  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
225424
  await runOneShotCommand("export", options, async () => {
@@ -227035,7 +225561,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
227035
225561
  data = createReviewBundleSnapshot(bundle);
227036
225562
  }
227037
225563
  const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
227038
- const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-D_i2QTRo.js").then(async (m) => {
225564
+ const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-Bf0L8T_A.js").then(async (m) => {
227039
225565
  await m.__tla;
227040
225566
  return m;
227041
225567
  });
@@ -245237,62 +243763,6 @@ ${result.stdout ?? ""}`;
245237
243763
  });
245238
243764
  return FeedbackSubmissionResultSchema.parse(raw2);
245239
243765
  }
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
243766
  const jsonBytes = (value) => Buffer.byteLength(JSON.stringify(value), "utf8");
245297
243767
  const encodeSessionHistoryCursor = (cursor) => Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
245298
243768
  const parseSessionHistoryCursor = (cursor, sessionId, newestBeforeIndex) => {
@@ -245420,83 +243890,6 @@ ${result.stdout ?? ""}`;
245420
243890
  maxBytes: params.maxBytes
245421
243891
  });
245422
243892
  }
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
243893
  async function syncMcpCatalog(syncer, workspaceId) {
245501
243894
  await syncer.syncFlockDocOrThrow(getWorkspaceFlockDocId(workspaceId), {
245502
243895
  timeoutMs: 1e4,
@@ -245741,19 +244134,10 @@ ${result.stdout ?? ""}`;
245741
244134
  const SESSION_RENAME_MANY_TOOL_NAME = "lody_session_rename_many";
245742
244135
  const OPERATION_GET_TOOL_NAME = "lody_operation_get";
245743
244136
  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
244137
  const REVIEW_SUBMIT_TOOL_NAME = "lody_review_submit";
245753
244138
  const SESSION_FILE_MAX_SIZE_MB = Math.floor(SESSION_FILE_MAX_SIZE_BYTES / (1024 * 1024));
245754
244139
  const SESSION_CONTROL_TIMEOUT_MS = 3e4;
245755
244140
  const LODY_CLI_DEFAULT_TIMEOUT_MS = 10 * 6e4;
245756
- const escapeMarkdownImageAlt = (value) => value.replaceAll(/[\\\]]/gu, "\\$&");
245757
244141
  const MAX_MCP_SESSION_WAIT_TIMEOUT_SECONDS = 3600;
245758
244142
  const MAX_MCP_COMMAND_BATCH_SIZE = 20;
245759
244143
  const MAX_MCP_STATUS_BATCH_SIZE = 50;
@@ -245764,11 +244148,6 @@ ${result.stdout ?? ""}`;
245764
244148
  const MAX_MCP_SESSION_HISTORY_LIMIT = 50;
245765
244149
  const MAX_MCP_SESSION_HISTORY_BYTES = 128 * 1024;
245766
244150
  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
244151
  const FILE_UPLOAD_TIMEOUT_MS = 10 * 6e4;
245773
244152
  const PreviewToolInputSchema = object$1({
245774
244153
  protocol: literal$1("http").default("http"),
@@ -245783,9 +244162,6 @@ ${result.stdout ?? ""}`;
245783
244162
  const ImageUploadToolInputSchema = object$1({
245784
244163
  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
244164
  }).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
244165
  const FileUploadToolInputSchema = object$1({
245790
244166
  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
244167
  }).strict();
@@ -246113,7 +244489,7 @@ ${result.stdout ?? ""}`;
246113
244489
  cursor: string$1().trim().min(1).optional()
246114
244490
  }).strict();
246115
244491
  const SessionHistoryToolInputSchema = object$1({
246116
- sessionId: string$1().trim().min(1).optional().describe("Target session id, or current. Defaults to current."),
244492
+ 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
244493
  cursor: string$1().trim().min(1).optional(),
246118
244494
  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
244495
  }).strict();
@@ -246140,8 +244516,7 @@ ${result.stdout ?? ""}`;
246140
244516
  workspaceId: readRequiredEnv("LODY_MCP_WORKSPACE_ID", "LODY_PREVIEW_MCP_WORKSPACE_ID"),
246141
244517
  sessionId: SessionIdSchema$1.parse(readRequiredEnv("LODY_MCP_SESSION_ID", "LODY_PREVIEW_MCP_SESSION_ID")),
246142
244518
  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"
244519
+ workdir: readOptionalEnv("LODY_MCP_WORKDIR", "LODY_PREVIEW_MCP_WORKDIR") ?? process.cwd()
246145
244520
  };
246146
244521
  const sharedOperationStores = /* @__PURE__ */ new Map();
246147
244522
  const resolveOperationStorePathForContext = () => getLodyOperationStorePath(getSessionContext().machineId);
@@ -246300,9 +244675,14 @@ ${result.stdout ?? ""}`;
246300
244675
  return JSON.parse(line3);
246301
244676
  };
246302
244677
  const runLodyCliJson = async (args2, timeoutMs) => parseJsonCliOutput((await runLodyCli(args2, timeoutMs)).stdout);
244678
+ const SESSION_URI_PREFIX = "session://";
244679
+ const stripSessionUriPrefix = (value) => value.startsWith(SESSION_URI_PREFIX) ? value.slice(SESSION_URI_PREFIX.length) : value;
246303
244680
  const resolveMcpSessionId = (sessionId, ctx) => {
246304
244681
  const normalized = normalizeCliValue(sessionId);
246305
- return normalized && normalized !== "current" ? normalized : ctx.sessionId;
244682
+ if (!normalized || normalized === "current") {
244683
+ return ctx.sessionId;
244684
+ }
244685
+ return stripSessionUriPrefix(normalized);
246306
244686
  };
246307
244687
  const getMcpWorkspaceId = (ctx) => ctx.workspaceId;
246308
244688
  const buildStructuredOutputOptions = (args2, outputMode = "json", onEvent) => {
@@ -246374,10 +244754,7 @@ ${prompt2}` : prompt2;
246374
244754
  return {
246375
244755
  input: input2,
246376
244756
  prompt: input2.prompt,
246377
- dispatchConfig: {
246378
- ...buildMcpTurnDispatchConfig(input2),
246379
- taskToolsEnabled: invoking?.frozenInputConfig.taskToolsEnabled === true
246380
- }
244757
+ dispatchConfig: buildMcpTurnDispatchConfig(input2)
246381
244758
  };
246382
244759
  }
246383
244760
  if (!role || role.id !== input2.agentRoleId) {
@@ -246416,7 +244793,6 @@ ${prompt2}` : prompt2;
246416
244793
  prompt: composeAgentRolePrompt(role.promptPrefix, input2.prompt),
246417
244794
  dispatchConfig: {
246418
244795
  ...role.runConfig,
246419
- taskToolsEnabled: invoking?.frozenInputConfig.taskToolsEnabled === true,
246420
244796
  inheritSessionDefaults: false
246421
244797
  },
246422
244798
  role
@@ -246985,16 +245361,6 @@ ${prompt2}` : prompt2;
246985
245361
  inputConfig
246986
245362
  };
246987
245363
  };
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
245364
  const resolveInvokingTurnContext = async (session2) => {
246999
245365
  const source = await resolveInvokingTurnSource();
247000
245366
  const chainDepth = source.inputConfig.chainDepth ?? 0;
@@ -247447,10 +245813,7 @@ ${prompt2}` : prompt2;
247447
245813
  throw new Error("Single chat Operation is missing its active target item.");
247448
245814
  }
247449
245815
  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, {
245816
+ const result = await sendSessionChatResult(auth, workspace, manager, pendingItem.target.sessionId, args2.prompt, resolveTurnDispatchConfig({}), void 0, void 0, {
247454
245817
  userTurnId: pendingItem.target.userTurnId,
247455
245818
  chainDepth: invoking.chainDepth + 1
247456
245819
  }, toDelegatedSessionRequester(invoking.identity));
@@ -247873,10 +246236,7 @@ ${prompt2}` : prompt2;
247873
246236
  return batchFailure("INVALID_ITEM", "Chat item requires sessionId and prompt.", false, storedItem.label, storedItem.target);
247874
246237
  }
247875
246238
  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, {
246239
+ await sendSessionChatResult(auth, workspace, manager, storedItem.target.sessionId, expandedItem.prompt, resolveTurnDispatchConfig({}), void 0, void 0, {
247880
246240
  userTurnId: storedItem.target.userTurnId,
247881
246241
  chainDepth: invoking.chainDepth + 1,
247882
246242
  bypassSessionQuota: shouldBypassSessionQuota("session_chat_many")
@@ -247891,103 +246251,6 @@ ${prompt2}` : prompt2;
247891
246251
  return snapshotOperation(ctx.sessionId, args2.operationId);
247892
246252
  });
247893
246253
  };
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
246254
  const ReviewSubmitToolInputSchema = object$1({
247992
246255
  verdict: _enum$1(REVIEW_VERDICT_VALUES).describe("`approve` only when nothing blocking remains."),
247993
246256
  findings: array$2(object$1({
@@ -248009,145 +246272,17 @@ ${prompt2}` : prompt2;
248009
246272
  })).max(100).optional().describe("Verdict on each previously raised finding. Use `disputed` to escalate to a human."),
248010
246273
  summary: string$1().trim().max(2e3).optional()
248011
246274
  }).strict();
248012
- const resolveTaskPrProvider = (url) => url.includes("gitlab") ? "gitlab" : "github";
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 = {}) {
246275
+ function buildLodyMcpServer() {
248147
246276
  initCliAnalytics();
248148
246277
  const server = new McpServer({
248149
246278
  name: "lody",
248150
246279
  version: "0.1.0"
246280
+ }, {
246281
+ instructions: [
246282
+ "Session mentions in user messages may appear as markdown links of the form [@Title](session://<sessionId>).",
246283
+ "To read that conversation, call lody_session_history with sessionId set to the <sessionId> (the part after session://), or pass the full session:// URI.",
246284
+ "Paginate with nextCursor when you need older turns."
246285
+ ].join(" ")
248151
246286
  });
248152
246287
  server.registerTool(FEEDBACK_TOOL_NAME, {
248153
246288
  title: "Send feedback about Lody",
@@ -248303,37 +246438,6 @@ ${prompt2}` : prompt2;
248303
246438
  return textResult(`Failed to upload images: ${String(error2)}`, true);
248304
246439
  }
248305
246440
  });
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: `![${escapeMarkdownImageAlt(image.fileName ?? "image")}](${image.markdownUrl})`
248331
- }))
248332
- });
248333
- } catch (error2) {
248334
- return mcpErrorResult(error2);
248335
- }
248336
- });
248337
246441
  server.registerTool(FILE_UPLOAD_TOOL_NAME, {
248338
246442
  title: "Upload files to Lody conversation",
248339
246443
  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 +246756,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
248652
246756
  });
248653
246757
  server.registerTool(SESSION_HISTORY_TOOL_NAME, {
248654
246758
  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.`,
246759
+ 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
246760
  inputSchema: SessionHistoryToolInputSchema
248657
246761
  }, async (args2) => {
248658
246762
  try {
@@ -248661,241 +246765,6 @@ ${lines2.join("\n")}` : ""}${suffix}`);
248661
246765
  return mcpErrorResult(error2);
248662
246766
  }
248663
246767
  });
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
246768
  server.registerTool(REVIEW_SUBMIT_TOOL_NAME, {
248900
246769
  title: "Submit a code review",
248901
246770
  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 +246839,10 @@ ${lines2.join("\n")}` : ""}${suffix}`);
248970
246839
  return mcpErrorResult(error2);
248971
246840
  }
248972
246841
  });
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
246842
  return server;
248988
246843
  }
248989
246844
  async function runLodyMcpServer() {
248990
- const context2 = getSessionContext();
248991
- await buildLodyMcpServer({
248992
- taskToolsEnabled: context2.taskToolsEnabled
248993
- }).connect(new StdioServerTransport());
246845
+ await buildLodyMcpServer().connect(new StdioServerTransport());
248994
246846
  }
248995
246847
  var RequestError = class extends Error {
248996
246848
  constructor(message, options) {
@@ -250537,9 +248389,8 @@ data:
250537
248389
  const rawSessionId = singleHeader(req, MCP_HTTP_SESSION_ID_HEADER);
250538
248390
  const workspaceId = singleHeader(req, MCP_HTTP_WORKSPACE_ID_HEADER);
250539
248391
  const machineId = singleHeader(req, MCP_HTTP_MACHINE_ID_HEADER);
250540
- const taskToolsEnabled = singleHeader(req, MCP_HTTP_TASK_TOOLS_ENABLED_HEADER);
250541
248392
  const workdirB64 = singleHeader(req, MCP_HTTP_WORKDIR_B64_HEADER);
250542
- if (!rawSessionId || !workspaceId || !machineId || taskToolsEnabled !== "0" && taskToolsEnabled !== "1" || !workdirB64) {
248393
+ if (!rawSessionId || !workspaceId || !machineId || !workdirB64) {
250543
248394
  return null;
250544
248395
  }
250545
248396
  const sessionId = SessionIdSchema$1.safeParse(rawSessionId);
@@ -250559,7 +248410,6 @@ data:
250559
248410
  sessionId: sessionId.data,
250560
248411
  workspaceId,
250561
248412
  machineId,
250562
- taskToolsEnabled: taskToolsEnabled === "1",
250563
248413
  workdir,
250564
248414
  localControlSocketPath: getLocalControlSocketPath()
250565
248415
  };
@@ -250617,9 +248467,7 @@ data:
250617
248467
  reject(res, 400, "Missing or invalid Lody MCP session context headers");
250618
248468
  return;
250619
248469
  }
250620
- const server = buildLodyMcpServer({
250621
- taskToolsEnabled: context2.taskToolsEnabled
250622
- });
248470
+ const server = buildLodyMcpServer();
250623
248471
  const transport = new StreamableHTTPServerTransport({
250624
248472
  sessionIdGenerator: void 0,
250625
248473
  enableJsonResponse: true