@vemdev/cli 0.1.53 → 0.1.55

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
@@ -23,7 +23,7 @@ import {
23
23
  isVemInitialized,
24
24
  listAllAgentSessions,
25
25
  parseVemUpdateBlock
26
- } from "./chunk-PPAFJ3LP.js";
26
+ } from "./chunk-SOAUDPRS.js";
27
27
  import {
28
28
  readCopilotSessionDetail
29
29
  } from "./chunk-PO3WNPAJ.js";
@@ -891,7 +891,13 @@ function truncateForDisplay(value, maxChars) {
891
891
  return `${trimmed.slice(0, Math.max(0, maxChars - 15)).trimEnd()}
892
892
  ...[truncated]`;
893
893
  }
894
- var AGENT_TASK_STATUSES = /* @__PURE__ */ new Set(["todo", "in-review", "in-progress", "blocked", "done"]);
894
+ var AGENT_TASK_STATUSES = /* @__PURE__ */ new Set([
895
+ "todo",
896
+ "in-review",
897
+ "in-progress",
898
+ "blocked",
899
+ "done"
900
+ ]);
895
901
  var MAX_CHILD_TASKS_IN_PROMPT = 12;
896
902
  var TASK_STATUS_ORDER = {
897
903
  "in-review": 0,
@@ -967,32 +973,20 @@ var fetchRemoteAgentTasks = async (configService) => {
967
973
  return null;
968
974
  }
969
975
  };
970
- var fetchRemoteAgentTaskById = async (configService, taskId) => {
976
+ var fetchRemoteAgentTaskById = async (configService, _taskId, dbId) => {
971
977
  try {
972
- const [apiKey, projectId] = await Promise.all([
973
- resolveApiKey(configService),
974
- configService.getProjectId()
975
- ]);
976
- if (!apiKey || !projectId) return null;
977
- const query = new URLSearchParams({
978
- id: taskId,
979
- include_deleted: "true"
980
- });
981
- const response = await fetch(
982
- `${API_URL}/projects/${projectId}/tasks?${query.toString()}`,
983
- {
984
- headers: {
985
- Authorization: `Bearer ${apiKey}`,
986
- ...await buildDeviceHeaders(configService)
987
- }
978
+ const apiKey = await resolveApiKey(configService);
979
+ if (!apiKey) return null;
980
+ const response = await fetch(`${API_URL}/tasks/${encodeURIComponent(dbId)}`, {
981
+ headers: {
982
+ Authorization: `Bearer ${apiKey}`,
983
+ ...await buildDeviceHeaders(configService)
988
984
  }
989
- );
985
+ });
990
986
  if (!response.ok) return null;
991
987
  const body = await response.json();
992
- if (!Array.isArray(body.tasks)) return null;
993
- const normalized = body.tasks.map((task) => normalizeAgentTask(task)).filter((task) => Boolean(task));
994
- if (normalized.length === 0) return null;
995
- return normalized.find((task) => task.id === taskId) ?? normalized[0];
988
+ if (!body.task) return null;
989
+ return normalizeAgentTask(body.task);
996
990
  } catch {
997
991
  return null;
998
992
  }
@@ -1012,44 +1006,12 @@ var mergeAgentTasks = (localTasks, remote) => {
1012
1006
  };
1013
1007
  var updateTaskMetaRemote = async (configService, task, patch) => {
1014
1008
  try {
1015
- const [apiKey, projectId] = await Promise.all([
1016
- resolveApiKey(configService),
1017
- configService.getProjectId()
1018
- ]);
1019
- if (!apiKey || !projectId) {
1020
- debugAgentSync(
1021
- "updateTaskMetaRemote skipped:",
1022
- `apiKey=${Boolean(apiKey)}`,
1023
- `projectId=${Boolean(projectId)}`
1024
- );
1025
- return false;
1026
- }
1027
- const query = new URLSearchParams({
1028
- id: task.id,
1029
- include_deleted: "true"
1030
- });
1031
- const lookupResponse = await fetch(
1032
- `${API_URL}/projects/${projectId}/tasks?${query.toString()}`,
1033
- {
1034
- headers: {
1035
- Authorization: `Bearer ${apiKey}`,
1036
- ...await buildDeviceHeaders(configService)
1037
- }
1038
- }
1039
- );
1040
- if (!lookupResponse.ok) {
1041
- debugAgentSync(
1042
- "task lookup failed:",
1043
- String(lookupResponse.status),
1044
- lookupResponse.statusText
1045
- );
1009
+ const apiKey = await resolveApiKey(configService);
1010
+ if (!apiKey) {
1011
+ debugAgentSync("updateTaskMetaRemote skipped: no apiKey");
1046
1012
  return false;
1047
1013
  }
1048
- const lookupBody = await lookupResponse.json();
1049
- const remoteTask = Array.isArray(lookupBody.tasks) ? lookupBody.tasks.find(
1050
- (entry) => asTrimmedString(entry.id) === task.id
1051
- ) ?? lookupBody.tasks[0] : null;
1052
- const dbId = asTrimmedString(remoteTask?.db_id) ?? asTrimmedString(task.db_id);
1014
+ const dbId = asTrimmedString(task.db_id);
1053
1015
  if (!dbId) {
1054
1016
  debugAgentSync("task lookup missing db_id", `task=${task.id}`);
1055
1017
  return false;
@@ -1069,25 +1031,24 @@ var updateTaskMetaRemote = async (configService, task, patch) => {
1069
1031
  ) : void 0;
1070
1032
  const normalizedSessions = Array.isArray(patch.sessions) && patch.sessions.length > 0 ? patch.sessions : void 0;
1071
1033
  const payload = {
1072
- title: asTrimmedString(remoteTask?.title) ?? task.title,
1073
- description: asTrimmedString(remoteTask?.description) ?? task.description ?? null,
1074
- status: asTrimmedString(remoteTask?.status) ?? task.status,
1075
- priority: asTrimmedString(remoteTask?.priority) ?? "medium",
1076
- tags: normalizeStringArray(remoteTask?.tags),
1077
- type: asTrimmedString(remoteTask?.type) ?? null,
1078
- estimate_hours: normalizeNumber(remoteTask?.estimate_hours),
1079
- depends_on: normalizeStringArray(remoteTask?.depends_on),
1080
- blocked_by: normalizeStringArray(remoteTask?.blocked_by),
1081
- recurrence_rule: asTrimmedString(remoteTask?.recurrence_rule) ?? null,
1082
- owner_id: asTrimmedString(remoteTask?.owner_id) ?? null,
1083
- reviewer_id: asTrimmedString(remoteTask?.reviewer_id) ?? null,
1084
- parent_id: asTrimmedString(remoteTask?.parent_id) ?? null,
1085
- subtask_order: typeof remoteTask?.subtask_order === "number" ? remoteTask.subtask_order : null,
1086
- due_at: asTrimmedString(remoteTask?.due_at) ?? null,
1087
- validation_steps: normalizeStringArray(remoteTask?.validation_steps),
1088
- evidence: normalizeStringArray(remoteTask?.evidence),
1089
- related_decisions: Array.isArray(remoteTask?.related_decisions) ? remoteTask.related_decisions : [],
1090
- deleted_at: asTrimmedString(remoteTask?.deleted_at) ?? null
1034
+ title: asTrimmedString(task.title) ?? task.title,
1035
+ description: asTrimmedString(task.description) ?? null,
1036
+ priority: asTrimmedString(task.priority) ?? "medium",
1037
+ tags: normalizeStringArray(task.tags),
1038
+ type: asTrimmedString(task.type) ?? null,
1039
+ estimate_hours: normalizeNumber(task.estimate_hours),
1040
+ depends_on: normalizeStringArray(task.depends_on),
1041
+ blocked_by: normalizeStringArray(task.blocked_by),
1042
+ recurrence_rule: asTrimmedString(task.recurrence_rule) ?? null,
1043
+ owner_id: asTrimmedString(task.owner_id) ?? null,
1044
+ reviewer_id: asTrimmedString(task.reviewer_id) ?? null,
1045
+ parent_id: asTrimmedString(task.parent_id) ?? null,
1046
+ subtask_order: typeof task.subtask_order === "number" ? task.subtask_order : null,
1047
+ due_at: asTrimmedString(task.due_at) ?? null,
1048
+ validation_steps: normalizeStringArray(task.validation_steps),
1049
+ evidence: normalizeStringArray(task.evidence),
1050
+ related_decisions: Array.isArray(task.related_decisions) ? task.related_decisions : [],
1051
+ deleted_at: asTrimmedString(task.deleted_at) ?? null
1091
1052
  };
1092
1053
  if (patch.status !== void 0) payload.status = patch.status;
1093
1054
  if (normalizedEvidence !== void 0) payload.evidence = normalizedEvidence;
@@ -1102,24 +1063,39 @@ var updateTaskMetaRemote = async (configService, task, patch) => {
1102
1063
  payload.actor = patch.actor.trim().length > 0 ? patch.actor.trim() : void 0;
1103
1064
  }
1104
1065
  if (patch.title !== void 0) payload.title = patch.title;
1105
- if (patch.description !== void 0) payload.description = patch.description;
1066
+ if (patch.description !== void 0)
1067
+ payload.description = patch.description;
1106
1068
  if (patch.priority !== void 0) payload.priority = patch.priority;
1107
1069
  if (patch.tags !== void 0) payload.tags = patch.tags;
1108
1070
  if (patch.type !== void 0) payload.type = patch.type;
1109
- if (patch.estimate_hours !== void 0) payload.estimate_hours = patch.estimate_hours;
1071
+ if (patch.estimate_hours !== void 0)
1072
+ payload.estimate_hours = patch.estimate_hours;
1110
1073
  if (patch.depends_on !== void 0) payload.depends_on = patch.depends_on;
1111
1074
  if (patch.blocked_by !== void 0) payload.blocked_by = patch.blocked_by;
1112
- if (patch.recurrence_rule !== void 0) payload.recurrence_rule = patch.recurrence_rule;
1075
+ if (patch.recurrence_rule !== void 0)
1076
+ payload.recurrence_rule = patch.recurrence_rule;
1113
1077
  if (patch.owner_id !== void 0) payload.owner_id = patch.owner_id;
1114
- if (patch.reviewer_id !== void 0) payload.reviewer_id = patch.reviewer_id;
1115
- if (patch.validation_steps !== void 0) payload.validation_steps = patch.validation_steps;
1078
+ if (patch.reviewer_id !== void 0)
1079
+ payload.reviewer_id = patch.reviewer_id;
1080
+ if (patch.validation_steps !== void 0)
1081
+ payload.validation_steps = patch.validation_steps;
1116
1082
  if (patch.user_notes !== void 0) payload.user_notes = patch.user_notes;
1117
- if (patch.github_issue_number !== void 0) payload.github_issue_number = patch.github_issue_number;
1083
+ if (patch.github_issue_number !== void 0)
1084
+ payload.github_issue_number = patch.github_issue_number;
1118
1085
  if (patch.parent_id !== void 0) payload.parent_id = patch.parent_id;
1119
- if (patch.subtask_order !== void 0) payload.subtask_order = patch.subtask_order;
1086
+ if (patch.subtask_order !== void 0)
1087
+ payload.subtask_order = patch.subtask_order;
1120
1088
  if (patch.due_at !== void 0) payload.due_at = patch.due_at;
1121
- if (patch.raw_vem_update !== void 0) payload.raw_vem_update = patch.raw_vem_update;
1122
- if (patch.cli_version !== void 0) payload.cli_version = patch.cli_version;
1089
+ if (patch.raw_vem_update !== void 0)
1090
+ payload.raw_vem_update = patch.raw_vem_update;
1091
+ if (patch.cli_version !== void 0)
1092
+ payload.cli_version = patch.cli_version;
1093
+ if (patch.task_context !== void 0)
1094
+ payload.task_context = patch.task_context;
1095
+ if (patch.task_context_summary !== void 0)
1096
+ payload.task_context_summary = patch.task_context_summary;
1097
+ if (patch.changelog_entry !== void 0)
1098
+ payload.changelog_entry = patch.changelog_entry;
1123
1099
  const response = await fetch(
1124
1100
  `${API_URL}/tasks/${encodeURIComponent(dbId)}/meta`,
1125
1101
  {
@@ -1150,30 +1126,6 @@ var updateTaskMetaRemote = async (configService, task, patch) => {
1150
1126
  return false;
1151
1127
  }
1152
1128
  };
1153
- var updateTaskContextRemote = async (configService, task, payload) => {
1154
- try {
1155
- const [apiKey, projectId] = await Promise.all([
1156
- resolveApiKey(configService),
1157
- configService.getProjectId()
1158
- ]);
1159
- if (!apiKey || !projectId) return false;
1160
- const response = await fetch(
1161
- `${API_URL}/projects/${projectId}/tasks/${encodeURIComponent(task.id)}/context`,
1162
- {
1163
- method: "PUT",
1164
- headers: {
1165
- Authorization: `Bearer ${apiKey}`,
1166
- "Content-Type": "application/json",
1167
- ...await buildDeviceHeaders(configService)
1168
- },
1169
- body: JSON.stringify(payload)
1170
- }
1171
- );
1172
- return response.ok;
1173
- } catch {
1174
- return false;
1175
- }
1176
- };
1177
1129
  var markTaskInProgressRemote = async (configService, task, actor) => {
1178
1130
  return updateTaskMetaRemote(configService, task, {
1179
1131
  status: "in-progress",
@@ -1203,10 +1155,41 @@ var buildRemoteTaskContextPatch = (patch, updatedTask) => {
1203
1155
  }
1204
1156
  return Object.keys(payload).length > 0 ? payload : null;
1205
1157
  };
1206
- var syncParsedTaskUpdatesToRemote = async (configService, update, result) => {
1207
- if (!result || !update.tasks || update.tasks.length === 0) return;
1158
+ var syncParsedTaskUpdatesToRemote = async (configService, update, result, activeTask) => {
1159
+ const hasTasks = Array.isArray(update.tasks) && update.tasks.length > 0;
1160
+ if (!hasTasks) {
1161
+ const hasContent = typeof update.context === "string" && update.context.trim().length > 0 || Array.isArray(update.changelog_append) && update.changelog_append.length > 0 || typeof update.changelog_append === "string" && update.changelog_append.trim().length > 0;
1162
+ if (activeTask && hasContent) {
1163
+ const changelogEntry = Array.isArray(update.changelog_append) ? update.changelog_append.join("\n").trim() || null : update.changelog_append?.trim() ?? null;
1164
+ await updateTaskMetaRemote(configService, activeTask, {
1165
+ raw_vem_update: JSON.parse(JSON.stringify(update)),
1166
+ cli_version: "0.1.55",
1167
+ ...changelogEntry ? { changelog_entry: changelogEntry } : {}
1168
+ });
1169
+ }
1170
+ return;
1171
+ }
1172
+ if (!result) return;
1208
1173
  const changelogReasoning = Array.isArray(update.changelog_append) ? update.changelog_append.join("\n").trim() : update.changelog_append?.trim() ?? void 0;
1209
- const patchById = new Map(update.tasks.map((entry) => [entry.id, entry]));
1174
+ const tasksMissingDbId = result.updatedTasks.filter(
1175
+ (t) => !asTrimmedString(t.db_id)
1176
+ );
1177
+ if (tasksMissingDbId.length > 0) {
1178
+ const remoteTasks = await fetchRemoteAgentTasks(configService);
1179
+ if (remoteTasks) {
1180
+ const remoteById = new Map(
1181
+ remoteTasks.visible.map((t) => [t.id, t])
1182
+ );
1183
+ for (const task of tasksMissingDbId) {
1184
+ const remote = remoteById.get(task.id);
1185
+ if (remote?.db_id) {
1186
+ task.db_id = remote.db_id;
1187
+ await taskService.updateTask(task.id, { db_id: remote.db_id });
1188
+ }
1189
+ }
1190
+ }
1191
+ }
1192
+ const patchById = new Map((update.tasks ?? []).map((entry) => [entry.id, entry]));
1210
1193
  for (const updatedTask of result.updatedTasks) {
1211
1194
  const patch = patchById.get(updatedTask.id);
1212
1195
  if (!patch) continue;
@@ -1237,16 +1220,11 @@ var syncParsedTaskUpdatesToRemote = async (configService, update, result) => {
1237
1220
  ...patch.subtask_order !== void 0 ? { subtask_order: patch.subtask_order } : {},
1238
1221
  ...patch.due_at !== void 0 ? { due_at: patch.due_at } : {},
1239
1222
  raw_vem_update: JSON.parse(JSON.stringify(update)),
1240
- cli_version: "0.1.53"
1223
+ cli_version: "0.1.55",
1224
+ // Task memory fields — stored in task_memory_entries on the API side.
1225
+ ...buildRemoteTaskContextPatch(patch, updatedTask) ?? {},
1226
+ changelog_entry: changelogReasoning ?? null
1241
1227
  });
1242
- const taskContextPatch = buildRemoteTaskContextPatch(patch, updatedTask);
1243
- if (taskContextPatch) {
1244
- await updateTaskContextRemote(
1245
- configService,
1246
- remoteTaskRef,
1247
- taskContextPatch
1248
- );
1249
- }
1250
1228
  }
1251
1229
  };
1252
1230
  var mergeTaskContextWithNote = (existing, note) => {
@@ -1843,7 +1821,11 @@ Your task is ${activeTask?.id}: ${activeTask?.title}${childScopeText}.
1843
1821
 
1844
1822
  Start by reading .vem/task_context.md and .vem/current_context.md for task and project context. Then explore the repository structure (list directories, read key files like package.json, README, and relevant source files) to understand the codebase before writing any code. Implement all required changes, run any existing tests or builds to verify, then provide the vem_update block.`;
1845
1823
  if (options.autoExit) {
1846
- console.log(chalk7.cyan("Auto-injecting context via -p flag (autonomous mode)..."));
1824
+ console.log(
1825
+ chalk7.cyan(
1826
+ "Auto-injecting context via -p flag (autonomous mode)..."
1827
+ )
1828
+ );
1847
1829
  launchArgs = [...launchArgs, "-p", autonomousPrompt, "--yolo"];
1848
1830
  } else {
1849
1831
  console.log(chalk7.cyan("Auto-injecting context via -i flag..."));
@@ -2081,7 +2063,8 @@ Agent exited with code ${exitCode}
2081
2063
  await syncParsedTaskUpdatesToRemote(
2082
2064
  configService,
2083
2065
  parsedAgentUpdate,
2084
- appliedUpdateResult
2066
+ appliedUpdateResult,
2067
+ activeTask
2085
2068
  );
2086
2069
  const syncedMemory = await syncProjectMemoryToRemote();
2087
2070
  if (syncedMemory) {
@@ -2156,7 +2139,11 @@ Agent exited with code ${exitCode}
2156
2139
  }
2157
2140
  const freshTasks = await taskService.getTasks();
2158
2141
  let localActiveTask = activeTask ? freshTasks.find((t) => t.id === activeTask.id) : void 0;
2159
- const remoteActiveTask = activeTask ? await fetchRemoteAgentTaskById(configService, activeTask.id) : null;
2142
+ const remoteActiveTask = activeTask?.db_id ? await fetchRemoteAgentTaskById(
2143
+ configService,
2144
+ activeTask.id,
2145
+ activeTask.db_id
2146
+ ) : null;
2160
2147
  if (localActiveTask && remoteActiveTask && localActiveTask.status !== remoteActiveTask.status) {
2161
2148
  await taskService.updateTask(localActiveTask.id, {
2162
2149
  status: remoteActiveTask.status
@@ -2273,18 +2260,16 @@ ${entry}`;
2273
2260
  });
2274
2261
  }
2275
2262
  const remoteTaskRef = freshActiveTask ?? activeTask;
2276
- const [remoteMetaUpdated, remoteContextUpdated] = await Promise.all(
2277
- [
2278
- updateTaskMetaRemote(configService, remoteTaskRef, {
2279
- status: "done",
2280
- evidence: [evidence.desc],
2281
- reasoning: reasoningText,
2282
- actor: agentName
2283
- }),
2284
- contextSummary !== void 0 ? updateTaskContextRemote(configService, remoteTaskRef, {
2285
- task_context_summary: contextSummary || null
2286
- }) : Promise.resolve(false)
2287
- ]
2263
+ const remoteMetaUpdated = await updateTaskMetaRemote(
2264
+ configService,
2265
+ remoteTaskRef,
2266
+ {
2267
+ status: "done",
2268
+ evidence: [evidence.desc],
2269
+ reasoning: reasoningText,
2270
+ actor: agentName,
2271
+ ...contextSummary !== void 0 ? { task_context_summary: contextSummary || null } : {}
2272
+ }
2288
2273
  );
2289
2274
  activeTask.status = "done";
2290
2275
  if (!remoteMetaUpdated) {
@@ -2297,7 +2282,7 @@ ${entry}`;
2297
2282
  console.log(
2298
2283
  chalk7.green(
2299
2284
  `
2300
- \u2714 Task ${freshActiveTask.id} marked as done${remoteMetaUpdated || remoteContextUpdated ? " (cloud + local cache)" : " (local cache)"}.`
2285
+ \u2714 Task ${freshActiveTask.id} marked as done${remoteMetaUpdated ? " (cloud + local cache)" : " (local cache)"}.`
2301
2286
  )
2302
2287
  );
2303
2288
  } else {
@@ -2510,7 +2495,11 @@ function registerCycleCommands(program2) {
2510
2495
  try {
2511
2496
  const cycles = await cycleService.getCycles();
2512
2497
  if (cycles.length === 0) {
2513
- console.log(chalk9.gray("\n No cycles yet. Create one with: vem cycle create\n"));
2498
+ console.log(
2499
+ chalk9.gray(
2500
+ "\n No cycles yet. Create one with: vem cycle create\n"
2501
+ )
2502
+ );
2514
2503
  return;
2515
2504
  }
2516
2505
  const table = new Table({
@@ -2634,7 +2623,9 @@ function registerCycleCommands(program2) {
2634
2623
  process.exitCode = 1;
2635
2624
  return;
2636
2625
  }
2637
- const updated = await cycleService.updateCycle(id, { status: "active" });
2626
+ const updated = await cycleService.updateCycle(id, {
2627
+ status: "active"
2628
+ });
2638
2629
  console.log(chalk9.cyan(`
2639
2630
  \u2714 Cycle ${id} is now active
2640
2631
  `));
@@ -2662,7 +2653,9 @@ function registerCycleCommands(program2) {
2662
2653
  `));
2663
2654
  return;
2664
2655
  }
2665
- const updated = await cycleService.updateCycle(id, { status: "closed" });
2656
+ const updated = await cycleService.updateCycle(id, {
2657
+ status: "closed"
2658
+ });
2666
2659
  console.log(chalk9.green(`
2667
2660
  \u2714 Cycle ${id} closed
2668
2661
  `));
@@ -2678,8 +2671,10 @@ function registerCycleCommands(program2) {
2678
2671
  );
2679
2672
  }
2680
2673
  console.log(
2681
- chalk9.gray(` Closed: ${new Date(updated.closed_at).toLocaleDateString()}
2682
- `)
2674
+ chalk9.gray(
2675
+ ` Closed: ${new Date(updated.closed_at).toLocaleDateString()}
2676
+ `
2677
+ )
2683
2678
  );
2684
2679
  } catch (error) {
2685
2680
  console.error(chalk9.red(`Failed to close cycle: ${error.message}`));
@@ -2787,13 +2782,17 @@ function registerCycleCommands(program2) {
2787
2782
  ]);
2788
2783
  }
2789
2784
  const done = cycleTasks.filter((t) => t.status === "done").length;
2790
- console.log(`
2785
+ console.log(
2786
+ `
2791
2787
  ${chalk9.white(String(done))}/${chalk9.white(String(cycleTasks.length))} tasks done
2792
- `);
2788
+ `
2789
+ );
2793
2790
  console.log(table.toString());
2794
2791
  console.log();
2795
2792
  } catch (error) {
2796
- console.error(chalk9.red(`Failed to show cycle focus: ${error.message}`));
2793
+ console.error(
2794
+ chalk9.red(`Failed to show cycle focus: ${error.message}`)
2795
+ );
2797
2796
  }
2798
2797
  });
2799
2798
  }
@@ -2806,7 +2805,9 @@ import prompts5 from "prompts";
2806
2805
  async function getRepoRoot2() {
2807
2806
  const { execSync: execSync4 } = await import("child_process");
2808
2807
  try {
2809
- return execSync4("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
2808
+ return execSync4("git rev-parse --show-toplevel", {
2809
+ encoding: "utf-8"
2810
+ }).trim();
2810
2811
  } catch {
2811
2812
  return process.cwd();
2812
2813
  }
@@ -2877,9 +2878,7 @@ function registerInstructionCommands(program2) {
2877
2878
  const dest = path.resolve(repoRoot, entry.path);
2878
2879
  const resolvedRoot = path.resolve(repoRoot);
2879
2880
  if (!dest.startsWith(`${resolvedRoot}${path.sep}`) && dest !== resolvedRoot) {
2880
- console.warn(
2881
- chalk10.yellow(`Skipping unsafe path: ${entry.path}`)
2882
- );
2881
+ console.warn(chalk10.yellow(`Skipping unsafe path: ${entry.path}`));
2883
2882
  continue;
2884
2883
  }
2885
2884
  if (!options.force) {
@@ -2905,9 +2904,11 @@ function registerInstructionCommands(program2) {
2905
2904
  }
2906
2905
  const skippedMsg = skipped > 0 ? `, ${skipped} skipped` : "";
2907
2906
  console.log(
2908
- chalk10.green(`
2907
+ chalk10.green(
2908
+ `
2909
2909
  \u2714 Pulled ${written} instruction file(s)${skippedMsg}.
2910
- `)
2910
+ `
2911
+ )
2911
2912
  );
2912
2913
  } catch (error) {
2913
2914
  console.error(
@@ -2935,9 +2936,7 @@ function registerInstructionCommands(program2) {
2935
2936
  const localInstructions = await readLocalInstructions();
2936
2937
  if (localInstructions.length === 0) {
2937
2938
  console.log(
2938
- chalk10.yellow(
2939
- "No instruction files found locally. Looked for:"
2940
- )
2939
+ chalk10.yellow("No instruction files found locally. Looked for:")
2941
2940
  );
2942
2941
  for (const f of KNOWN_AGENT_INSTRUCTION_FILES) {
2943
2942
  console.log(chalk10.gray(` ${f}`));
@@ -2975,11 +2974,9 @@ function registerInstructionCommands(program2) {
2975
2974
  console.log(chalk10.green(` \u2714 ${entry.path}`));
2976
2975
  }
2977
2976
  const versionNote = data.version_number ? ` (saved as v${data.version_number})` : "";
2978
- console.log(
2979
- chalk10.green(`
2977
+ console.log(chalk10.green(`
2980
2978
  \u2714 Instructions pushed${versionNote}.
2981
- `)
2982
- );
2979
+ `));
2983
2980
  } catch (error) {
2984
2981
  console.error(
2985
2982
  chalk10.red("\n\u2716 Instructions push failed:"),
@@ -2988,9 +2985,7 @@ function registerInstructionCommands(program2) {
2988
2985
  process.exitCode = 1;
2989
2986
  }
2990
2987
  });
2991
- instructionsCmd.command("status").description(
2992
- "Check if local instruction files are in sync with the cloud"
2993
- ).action(async () => {
2988
+ instructionsCmd.command("status").description("Check if local instruction files are in sync with the cloud").action(async () => {
2994
2989
  await trackCommandUsage("instructions.status");
2995
2990
  try {
2996
2991
  const configService = new ConfigService();
@@ -3022,8 +3017,12 @@ function registerInstructionCommands(program2) {
3022
3017
  }
3023
3018
  const cloudData = await cloudRes.json();
3024
3019
  const cloudInstructions = cloudData.instructions ?? [];
3025
- const localMap = new Map(localInstructions.map((e) => [e.path, e.content]));
3026
- const cloudMap = new Map(cloudInstructions.map((e) => [e.path, e.content]));
3020
+ const localMap = new Map(
3021
+ localInstructions.map((e) => [e.path, e.content])
3022
+ );
3023
+ const cloudMap = new Map(
3024
+ cloudInstructions.map((e) => [e.path, e.content])
3025
+ );
3027
3026
  const allPaths = /* @__PURE__ */ new Set([...localMap.keys(), ...cloudMap.keys()]);
3028
3027
  let inSync = true;
3029
3028
  console.log(chalk10.bold("\nInstruction file sync status:\n"));
@@ -3046,7 +3045,9 @@ function registerInstructionCommands(program2) {
3046
3045
  );
3047
3046
  inSync = false;
3048
3047
  } else {
3049
- console.log(chalk10.green(` \u2714 ${filePath}`) + chalk10.gray(" (in sync)"));
3048
+ console.log(
3049
+ chalk10.green(` \u2714 ${filePath}`) + chalk10.gray(" (in sync)")
3050
+ );
3050
3051
  }
3051
3052
  }
3052
3053
  if (allPaths.size === 0) {
@@ -3165,9 +3166,7 @@ function registerInstructionCommands(program2) {
3165
3166
  )
3166
3167
  );
3167
3168
  console.log(
3168
- chalk10.gray(
3169
- " Run `vem instructions pull` to update local files."
3170
- )
3169
+ chalk10.gray(" Run `vem instructions pull` to update local files.")
3171
3170
  );
3172
3171
  } catch (error) {
3173
3172
  console.error(
@@ -3402,7 +3401,7 @@ function registerMaintenanceCommands(program2) {
3402
3401
  });
3403
3402
  program2.command("diff").description("Show differences between local and cloud state").option("--detailed", "Show detailed content diffs").option("--json", "Output as JSON").action(async (options) => {
3404
3403
  try {
3405
- const { DiffService } = await import("./dist-2IBAWS6G.js");
3404
+ const { DiffService } = await import("./dist-27CAVU4D.js");
3406
3405
  const diffService = new DiffService();
3407
3406
  const result = await diffService.compareWithLastPush();
3408
3407
  if (options.json) {
@@ -3460,7 +3459,7 @@ ${"\u2500".repeat(50)}`));
3460
3459
  });
3461
3460
  program2.command("doctor").description("Run health checks on VEM setup").option("--json", "Output as JSON").action(async (options) => {
3462
3461
  try {
3463
- const { DoctorService } = await import("./dist-2IBAWS6G.js");
3462
+ const { DoctorService } = await import("./dist-27CAVU4D.js");
3464
3463
  const doctorService = new DoctorService();
3465
3464
  const results = await doctorService.runAllChecks();
3466
3465
  if (options.json) {
@@ -4109,7 +4108,13 @@ function commandExists(command) {
4109
4108
  return false;
4110
4109
  }
4111
4110
  }
4112
- var KNOWN_RUNNER_AGENTS = ["copilot", "gh", "claude", "gemini", "codex"];
4111
+ var KNOWN_RUNNER_AGENTS = [
4112
+ "copilot",
4113
+ "gh",
4114
+ "claude",
4115
+ "gemini",
4116
+ "codex"
4117
+ ];
4113
4118
  function hasSandboxCredentials(agent) {
4114
4119
  if (agent === "claude") {
4115
4120
  return typeof process.env.ANTHROPIC_API_KEY === "string" && process.env.ANTHROPIC_API_KEY.trim().length > 0;
@@ -4118,7 +4123,9 @@ function hasSandboxCredentials(agent) {
4118
4123
  const envToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
4119
4124
  if (envToken && envToken.trim().length > 0) return true;
4120
4125
  try {
4121
- const token = execFileSync("gh", ["auth", "token"], { encoding: "utf-8" }).trim();
4126
+ const token = execFileSync("gh", ["auth", "token"], {
4127
+ encoding: "utf-8"
4128
+ }).trim();
4122
4129
  return token.length > 0;
4123
4130
  } catch {
4124
4131
  return false;
@@ -4134,9 +4141,13 @@ function hasSandboxCredentials(agent) {
4134
4141
  }
4135
4142
  function getAvailableAgentCommands(selectedAgent, sandbox) {
4136
4143
  const isAvailable = (command) => commandExists(command) && (!sandbox || hasSandboxCredentials(command));
4137
- const knownAvailable = KNOWN_RUNNER_AGENTS.filter((command) => isAvailable(command));
4144
+ const knownAvailable = KNOWN_RUNNER_AGENTS.filter(
4145
+ (command) => isAvailable(command)
4146
+ );
4138
4147
  const selectedAvailable = isAvailable(selectedAgent);
4139
- if (selectedAvailable && !knownAvailable.includes(selectedAgent)) {
4148
+ if (selectedAvailable && !knownAvailable.includes(
4149
+ selectedAgent
4150
+ )) {
4140
4151
  return [selectedAgent, ...knownAvailable];
4141
4152
  }
4142
4153
  return knownAvailable;
@@ -4171,9 +4182,7 @@ function checkDockerAvailable() {
4171
4182
  try {
4172
4183
  execFileSync("docker", ["info"], { stdio: "ignore" });
4173
4184
  } catch {
4174
- console.error(
4175
- chalk13.red("\u2717 Docker is not running or not installed.")
4176
- );
4185
+ console.error(chalk13.red("\u2717 Docker is not running or not installed."));
4177
4186
  console.error(
4178
4187
  chalk13.yellow(
4179
4188
  " The vem runner requires Docker to run agents in a secure sandbox."
@@ -4206,7 +4215,9 @@ function getSandboxImageDir() {
4206
4215
  return dirname2(candidate);
4207
4216
  }
4208
4217
  }
4209
- throw new Error("Dockerfile.sandbox not found. Ensure the vem CLI is installed correctly.");
4218
+ throw new Error(
4219
+ "Dockerfile.sandbox not found. Ensure the vem CLI is installed correctly."
4220
+ );
4210
4221
  }
4211
4222
  function buildSandboxImage() {
4212
4223
  console.log(chalk13.cyan(" Building sandbox Docker image (first use)..."));
@@ -4220,7 +4231,9 @@ function buildSandboxImage() {
4220
4231
  }
4221
4232
  function ensureSandboxImage() {
4222
4233
  try {
4223
- execFileSync("docker", ["image", "inspect", SANDBOX_IMAGE_NAME], { stdio: "ignore" });
4234
+ execFileSync("docker", ["image", "inspect", SANDBOX_IMAGE_NAME], {
4235
+ stdio: "ignore"
4236
+ });
4224
4237
  } catch {
4225
4238
  buildSandboxImage();
4226
4239
  }
@@ -4235,7 +4248,11 @@ function collectSandboxCredentials(agent) {
4235
4248
  if (agent === "claude") {
4236
4249
  addFromEnv("ANTHROPIC_API_KEY");
4237
4250
  if (!creds.ANTHROPIC_API_KEY) {
4238
- console.error(chalk13.red(`\u2717 ANTHROPIC_API_KEY is not set. Required for --agent claude.`));
4251
+ console.error(
4252
+ chalk13.red(
4253
+ `\u2717 ANTHROPIC_API_KEY is not set. Required for --agent claude.`
4254
+ )
4255
+ );
4239
4256
  process.exit(1);
4240
4257
  }
4241
4258
  } else if (agent === "copilot" || agent === "gh") {
@@ -4244,31 +4261,43 @@ function collectSandboxCredentials(agent) {
4244
4261
  creds.GITHUB_TOKEN = envToken;
4245
4262
  } else {
4246
4263
  try {
4247
- const token = execFileSync("gh", ["auth", "token"], { encoding: "utf-8" }).trim();
4264
+ const token = execFileSync("gh", ["auth", "token"], {
4265
+ encoding: "utf-8"
4266
+ }).trim();
4248
4267
  if (token) creds.GITHUB_TOKEN = token;
4249
4268
  } catch {
4250
4269
  }
4251
4270
  }
4252
4271
  if (!creds.GITHUB_TOKEN) {
4253
- console.error(chalk13.red(`\u2717 GitHub token not found. Required for --agent copilot.`));
4254
- console.error(chalk13.gray(" Set GITHUB_TOKEN env var or run: gh auth login"));
4272
+ console.error(
4273
+ chalk13.red(`\u2717 GitHub token not found. Required for --agent copilot.`)
4274
+ );
4275
+ console.error(
4276
+ chalk13.gray(" Set GITHUB_TOKEN env var or run: gh auth login")
4277
+ );
4255
4278
  process.exit(1);
4256
4279
  }
4257
4280
  } else if (agent === "gemini") {
4258
4281
  addFromEnv("GEMINI_API_KEY");
4259
4282
  if (!creds.GEMINI_API_KEY) {
4260
- console.error(chalk13.red(`\u2717 GEMINI_API_KEY is not set. Required for --agent gemini.`));
4283
+ console.error(
4284
+ chalk13.red(`\u2717 GEMINI_API_KEY is not set. Required for --agent gemini.`)
4285
+ );
4261
4286
  process.exit(1);
4262
4287
  }
4263
4288
  } else if (agent === "codex") {
4264
4289
  addFromEnv("OPENAI_API_KEY");
4265
4290
  if (!creds.OPENAI_API_KEY) {
4266
- console.error(chalk13.red(`\u2717 OPENAI_API_KEY is not set. Required for --agent codex.`));
4291
+ console.error(
4292
+ chalk13.red(`\u2717 OPENAI_API_KEY is not set. Required for --agent codex.`)
4293
+ );
4267
4294
  process.exit(1);
4268
4295
  }
4269
4296
  }
4270
- if (process.env.GIT_AUTHOR_NAME) creds.GIT_AUTHOR_NAME = process.env.GIT_AUTHOR_NAME;
4271
- if (process.env.GIT_AUTHOR_EMAIL) creds.GIT_AUTHOR_EMAIL = process.env.GIT_AUTHOR_EMAIL;
4297
+ if (process.env.GIT_AUTHOR_NAME)
4298
+ creds.GIT_AUTHOR_NAME = process.env.GIT_AUTHOR_NAME;
4299
+ if (process.env.GIT_AUTHOR_EMAIL)
4300
+ creds.GIT_AUTHOR_EMAIL = process.env.GIT_AUTHOR_EMAIL;
4272
4301
  return creds;
4273
4302
  }
4274
4303
  function sanitizeBranchSegment(value) {
@@ -4282,7 +4311,10 @@ async function resolveGitRemote(configService) {
4282
4311
  const linkedRemote = (await configService.getLinkedRemoteName())?.trim();
4283
4312
  const preferredRemote = linkedRemote || "origin";
4284
4313
  try {
4285
- return { name: preferredRemote, url: runGit(["remote", "get-url", preferredRemote]) };
4314
+ return {
4315
+ name: preferredRemote,
4316
+ url: runGit(["remote", "get-url", preferredRemote])
4317
+ };
4286
4318
  } catch {
4287
4319
  if (preferredRemote !== "origin") {
4288
4320
  try {
@@ -4316,14 +4348,26 @@ function getCommitHashesSince(baseHash) {
4316
4348
  const output = runGit(["rev-list", `${baseHash}..HEAD`]);
4317
4349
  return output.split("\n").map((entry) => entry.trim()).filter(Boolean);
4318
4350
  }
4351
+ var _deviceHeadersCache = null;
4352
+ function getCachedDeviceHeaders(configService) {
4353
+ if (!_deviceHeadersCache) {
4354
+ _deviceHeadersCache = buildDeviceHeaders(configService);
4355
+ }
4356
+ return _deviceHeadersCache;
4357
+ }
4358
+ var FETCH_TIMEOUT_MS = 3e4;
4319
4359
  async function apiRequest(configService, apiKey, path4, init) {
4320
4360
  const headers = {
4321
4361
  Authorization: `Bearer ${apiKey}`,
4322
4362
  "Content-Type": "application/json",
4323
- ...await buildDeviceHeaders(configService),
4363
+ ...await getCachedDeviceHeaders(configService),
4324
4364
  ...init?.headers ?? {}
4325
4365
  };
4326
- return fetch(`${API_URL}${path4}`, { ...init, headers });
4366
+ return fetch(`${API_URL}${path4}`, {
4367
+ ...init,
4368
+ headers,
4369
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
4370
+ });
4327
4371
  }
4328
4372
  async function appendRunLogs(configService, apiKey, runId, entries) {
4329
4373
  if (entries.length === 0) return;
@@ -4333,23 +4377,33 @@ async function appendRunLogs(configService, apiKey, runId, entries) {
4333
4377
  });
4334
4378
  }
4335
4379
  async function sendRunnerHeartbeat(configService, apiKey, projectId, status, currentTaskRunId, capabilities) {
4336
- await apiRequest(configService, apiKey, `/projects/${projectId}/runners/heartbeat`, {
4337
- method: "POST",
4338
- body: JSON.stringify({
4339
- status,
4340
- current_task_run_id: currentTaskRunId,
4341
- capabilities
4342
- })
4343
- });
4380
+ await apiRequest(
4381
+ configService,
4382
+ apiKey,
4383
+ `/projects/${projectId}/runners/heartbeat`,
4384
+ {
4385
+ method: "POST",
4386
+ body: JSON.stringify({
4387
+ status,
4388
+ current_task_run_id: currentTaskRunId,
4389
+ capabilities
4390
+ })
4391
+ }
4392
+ );
4344
4393
  }
4345
4394
  async function completeTaskRunWithRetry(configService, apiKey, runId, payload, attempts = 5) {
4346
4395
  let lastError = "unknown error";
4347
4396
  for (let attempt = 1; attempt <= attempts; attempt++) {
4348
4397
  try {
4349
- const response = await apiRequest(configService, apiKey, `/task-runs/${runId}/complete`, {
4350
- method: "POST",
4351
- body: JSON.stringify(payload)
4352
- });
4398
+ const response = await apiRequest(
4399
+ configService,
4400
+ apiKey,
4401
+ `/task-runs/${runId}/complete`,
4402
+ {
4403
+ method: "POST",
4404
+ body: JSON.stringify(payload)
4405
+ }
4406
+ );
4353
4407
  if (response.ok) return;
4354
4408
  const bodyText = await response.text().catch(() => "");
4355
4409
  lastError = `HTTP ${response.status}${bodyText ? `: ${bodyText}` : ""}`;
@@ -4363,7 +4417,15 @@ async function completeTaskRunWithRetry(configService, apiKey, runId, payload, a
4363
4417
  throw new Error(`Failed to complete run ${runId}: ${lastError}`);
4364
4418
  }
4365
4419
  async function executeClaimedRun(input) {
4366
- const { configService, apiKey, projectId, agent, useSandbox, agentPinned, run } = input;
4420
+ const {
4421
+ configService,
4422
+ apiKey,
4423
+ projectId,
4424
+ agent,
4425
+ useSandbox,
4426
+ agentPinned,
4427
+ run
4428
+ } = input;
4367
4429
  const repoRoot = getRepoRoot3();
4368
4430
  let sequence = 1;
4369
4431
  let heartbeatTimer = null;
@@ -4390,7 +4452,11 @@ async function executeClaimedRun(input) {
4390
4452
  } catch {
4391
4453
  originalBranch = null;
4392
4454
  }
4393
- const preparedBranch = prepareTaskBranch(run.task_external_id, baseBranch, remote.name);
4455
+ const preparedBranch = prepareTaskBranch(
4456
+ run.task_external_id,
4457
+ baseBranch,
4458
+ remote.name
4459
+ );
4394
4460
  baseHash = preparedBranch.baseHash;
4395
4461
  branchName = preparedBranch.branchName;
4396
4462
  await appendRunLogs(configService, apiKey, run.id, [
@@ -4403,7 +4469,14 @@ async function executeClaimedRun(input) {
4403
4469
  ]);
4404
4470
  const child = spawn3(
4405
4471
  process.execPath,
4406
- [getCliEntrypoint(), "agent", agent, "--task", run.task_external_id, "--auto-exit"],
4472
+ [
4473
+ getCliEntrypoint(),
4474
+ "agent",
4475
+ agent,
4476
+ "--task",
4477
+ run.task_external_id,
4478
+ "--auto-exit"
4479
+ ],
4407
4480
  {
4408
4481
  env: {
4409
4482
  ...process.env,
@@ -4473,15 +4546,13 @@ async function executeClaimedRun(input) {
4473
4546
  { sequence: sequence++, stream: "stderr", chunk: text }
4474
4547
  ]);
4475
4548
  });
4476
- const result = await new Promise(
4477
- (resolve3) => {
4478
- child.on("exit", (code, signal) => resolve3({ code, signal }));
4479
- child.on("error", (error) => {
4480
- completionError = error.message;
4481
- resolve3({ code: null, signal: null });
4482
- });
4483
- }
4484
- );
4549
+ const result = await new Promise((resolve3) => {
4550
+ child.on("exit", (code, signal) => resolve3({ code, signal }));
4551
+ child.on("error", (error) => {
4552
+ completionError = error.message;
4553
+ resolve3({ code: null, signal: null });
4554
+ });
4555
+ });
4485
4556
  exitCode = result.code;
4486
4557
  if (completionError) {
4487
4558
  completionStatus = cancellationRequested ? "cancelled" : "failed";
@@ -4503,7 +4574,11 @@ async function executeClaimedRun(input) {
4503
4574
  if (completionStatus === "completed" && hasDirtyWorktree()) {
4504
4575
  runGit(["add", "-A"], { stdio: "inherit" });
4505
4576
  runGit(
4506
- ["commit", "-m", `chore(${run.task_external_id}): apply agent changes`],
4577
+ [
4578
+ "commit",
4579
+ "-m",
4580
+ `chore(${run.task_external_id}): apply agent changes`
4581
+ ],
4507
4582
  { stdio: "inherit" }
4508
4583
  );
4509
4584
  }
@@ -4599,15 +4674,19 @@ async function executeClaimedRunInSandbox(input) {
4599
4674
  execFileSync("rm", ["-rf", worktreePath], { stdio: "ignore" });
4600
4675
  }
4601
4676
  console.log(chalk13.gray(` Cloning ${baseBranch} \u2192 ${worktreePath}`));
4602
- execFileSync("git", [
4603
- "clone",
4604
- "--quiet",
4605
- `file://${repoRoot}`,
4606
- "--branch",
4607
- baseBranch,
4608
- "--single-branch",
4609
- worktreePath
4610
- ], { stdio: "pipe" });
4677
+ execFileSync(
4678
+ "git",
4679
+ [
4680
+ "clone",
4681
+ "--quiet",
4682
+ `file://${repoRoot}`,
4683
+ "--branch",
4684
+ baseBranch,
4685
+ "--single-branch",
4686
+ worktreePath
4687
+ ],
4688
+ { stdio: "pipe" }
4689
+ );
4611
4690
  runGitIn(worktreePath, ["checkout", "-b", branchName]);
4612
4691
  if (remoteUrl) {
4613
4692
  runGitIn(worktreePath, ["remote", "set-url", "origin", remoteUrl]);
@@ -4674,7 +4753,9 @@ async function executeClaimedRunInSandbox(input) {
4674
4753
  if (dockerProcess?.pid) {
4675
4754
  try {
4676
4755
  if (containerName) {
4677
- execFileSync("docker", ["stop", containerName], { stdio: "ignore" });
4756
+ execFileSync("docker", ["stop", containerName], {
4757
+ stdio: "ignore"
4758
+ });
4678
4759
  } else {
4679
4760
  dockerProcess.kill("SIGTERM");
4680
4761
  }
@@ -4682,7 +4763,11 @@ async function executeClaimedRunInSandbox(input) {
4682
4763
  }
4683
4764
  }
4684
4765
  await appendRunLogs(configService, apiKey, run.id, [
4685
- { sequence: sequence++, stream: "system", chunk: "Cancellation requested from web UI. Stopping sandbox container.\n" }
4766
+ {
4767
+ sequence: sequence++,
4768
+ stream: "system",
4769
+ chunk: "Cancellation requested from web UI. Stopping sandbox container.\n"
4770
+ }
4686
4771
  ]);
4687
4772
  }
4688
4773
  if (maxRuntimeAt && !timedOut) {
@@ -4694,21 +4779,29 @@ async function executeClaimedRunInSandbox(input) {
4694
4779
  if (dockerProcess?.pid) {
4695
4780
  try {
4696
4781
  if (containerName) {
4697
- execFileSync("docker", ["stop", containerName], { stdio: "ignore" });
4782
+ execFileSync("docker", ["stop", containerName], {
4783
+ stdio: "ignore"
4784
+ });
4698
4785
  }
4699
4786
  } catch {
4700
4787
  }
4701
4788
  }
4702
4789
  await appendRunLogs(configService, apiKey, run.id, [
4703
- { sequence: sequence++, stream: "system", chunk: "Run exceeded the maximum runtime. Stopping sandbox container.\n" }
4790
+ {
4791
+ sequence: sequence++,
4792
+ stream: "system",
4793
+ chunk: "Run exceeded the maximum runtime. Stopping sandbox container.\n"
4794
+ }
4704
4795
  ]);
4705
4796
  }
4706
4797
  }
4707
4798
  } catch {
4708
4799
  }
4709
4800
  }, 3e4);
4801
+ const stdoutChunks = [];
4710
4802
  const streamLogs = (stream, data) => {
4711
4803
  const chunk = data.toString("utf-8");
4804
+ if (stream === "stdout") stdoutChunks.push(chunk);
4712
4805
  appendRunLogs(configService, apiKey, run.id, [
4713
4806
  { sequence: sequence++, stream, chunk }
4714
4807
  ]).catch(() => {
@@ -4728,7 +4821,10 @@ async function executeClaimedRunInSandbox(input) {
4728
4821
  if (exitCode === 0 && !cancellationRequested && !timedOut) {
4729
4822
  completionStatus = "completed";
4730
4823
  try {
4731
- const output = runGitIn(worktreePath, ["rev-list", `${baseHash}..HEAD`]);
4824
+ const output = runGitIn(worktreePath, [
4825
+ "rev-list",
4826
+ `${baseHash}..HEAD`
4827
+ ]);
4732
4828
  commitHashes = output.split("\n").map((h) => h.trim()).filter(Boolean);
4733
4829
  } catch {
4734
4830
  }
@@ -4736,18 +4832,29 @@ async function executeClaimedRunInSandbox(input) {
4736
4832
  } else if (!cancellationRequested && !timedOut) {
4737
4833
  completionStatus = "failed";
4738
4834
  }
4835
+ const fullDockerLogLines2 = stdoutChunks.join("").split("\n").filter(Boolean).slice(-1e3);
4739
4836
  if (completionStatus === "completed" && commitHashes.length > 0) {
4740
4837
  try {
4741
- runGitIn(worktreePath, ["push", "-u", "origin", branchName], { stdio: "inherit" });
4838
+ runGitIn(worktreePath, ["push", "-u", "origin", branchName], {
4839
+ stdio: "inherit"
4840
+ });
4742
4841
  await appendRunLogs(configService, apiKey, run.id, [
4743
- { sequence: sequence++, stream: "system", chunk: `Pushed branch ${branchName} to ${remote.name}.
4744
- ` }
4842
+ {
4843
+ sequence: sequence++,
4844
+ stream: "system",
4845
+ chunk: `Pushed branch ${branchName} to ${remote.name}.
4846
+ `
4847
+ }
4745
4848
  ]);
4746
4849
  } catch (pushErr) {
4747
4850
  const msg = pushErr instanceof Error ? pushErr.message : String(pushErr);
4748
4851
  await appendRunLogs(configService, apiKey, run.id, [
4749
- { sequence: sequence++, stream: "system", chunk: `Warning: failed to push branch: ${msg}
4750
- ` }
4852
+ {
4853
+ sequence: sequence++,
4854
+ stream: "system",
4855
+ chunk: `Warning: failed to push branch: ${msg}
4856
+ `
4857
+ }
4751
4858
  ]);
4752
4859
  createPr = false;
4753
4860
  }
@@ -4761,8 +4868,12 @@ async function executeClaimedRunInSandbox(input) {
4761
4868
  heartbeatTimer = null;
4762
4869
  }
4763
4870
  await appendRunLogs(configService, apiKey, run.id, [
4764
- { sequence: sequence++, stream: "system", chunk: `Sandbox run error: ${msg}
4765
- ` }
4871
+ {
4872
+ sequence: sequence++,
4873
+ stream: "system",
4874
+ chunk: `Sandbox run error: ${msg}
4875
+ `
4876
+ }
4766
4877
  ]).catch(() => {
4767
4878
  });
4768
4879
  } finally {
@@ -4797,19 +4908,35 @@ async function executeClaimedRunInSandbox(input) {
4797
4908
  pr_body: run.user_prompt?.trim() ? `Triggered from VEM web.
4798
4909
 
4799
4910
  Instructions:
4800
- ${run.user_prompt.trim()}` : "Triggered from VEM web."
4911
+ ${run.user_prompt.trim()}` : "Triggered from VEM web.",
4912
+ // Pass the full Docker log so the API can parse the vem_update block
4913
+ // reliably even when some live-streamed chunks were dropped.
4914
+ full_log_lines: fullDockerLogLines.length > 0 ? fullDockerLogLines : void 0
4801
4915
  });
4802
4916
  }
4803
4917
  }
4804
4918
  async function appendTerminalLogs(configService, apiKey, sessionId, entries) {
4805
4919
  if (entries.length === 0) return;
4806
- await apiRequest(configService, apiKey, `/terminal-sessions/${sessionId}/logs`, {
4807
- method: "POST",
4808
- body: JSON.stringify({ entries })
4809
- });
4920
+ await apiRequest(
4921
+ configService,
4922
+ apiKey,
4923
+ `/terminal-sessions/${sessionId}/logs`,
4924
+ {
4925
+ method: "POST",
4926
+ body: JSON.stringify({ entries })
4927
+ }
4928
+ );
4810
4929
  }
4811
4930
  async function executeClaimedTerminalSession(input) {
4812
- const { configService, apiKey, projectId, agent, useSandbox, agentPinned, session } = input;
4931
+ const {
4932
+ configService,
4933
+ apiKey,
4934
+ projectId,
4935
+ agent,
4936
+ useSandbox,
4937
+ agentPinned,
4938
+ session
4939
+ } = input;
4813
4940
  const repoRoot = getRepoRoot3();
4814
4941
  let sequence = 2;
4815
4942
  let heartbeatTimer = null;
@@ -4869,15 +4996,13 @@ $ ${session.command}
4869
4996
  { sequence: sequence++, stream: "stderr", chunk: text }
4870
4997
  ]);
4871
4998
  });
4872
- const result = await new Promise(
4873
- (resolve3) => {
4874
- child.on("exit", (code, signal) => resolve3({ code, signal }));
4875
- child.on("error", (error) => {
4876
- completionError = error.message;
4877
- resolve3({ code: null, signal: null });
4878
- });
4879
- }
4880
- );
4999
+ const result = await new Promise((resolve3) => {
5000
+ child.on("exit", (code, signal) => resolve3({ code, signal }));
5001
+ child.on("error", (error) => {
5002
+ completionError = error.message;
5003
+ resolve3({ code: null, signal: null });
5004
+ });
5005
+ });
4881
5006
  exitCode = result.code;
4882
5007
  if (completionError) {
4883
5008
  completionStatus = cancellationRequested ? "cancelled" : "failed";
@@ -4907,15 +5032,20 @@ $ ${session.command}
4907
5032
  if (heartbeatTimer) {
4908
5033
  clearInterval(heartbeatTimer);
4909
5034
  }
4910
- await apiRequest(configService, apiKey, `/terminal-sessions/${session.id}/complete`, {
4911
- method: "POST",
4912
- body: JSON.stringify({
4913
- status: completionStatus,
4914
- exit_code: exitCode,
4915
- error_message: completionError,
4916
- terminal_reason: completionStatus === "cancelled" ? "Command cancelled from workspace UI." : null
4917
- })
4918
- });
5035
+ await apiRequest(
5036
+ configService,
5037
+ apiKey,
5038
+ `/terminal-sessions/${session.id}/complete`,
5039
+ {
5040
+ method: "POST",
5041
+ body: JSON.stringify({
5042
+ status: completionStatus,
5043
+ exit_code: exitCode,
5044
+ error_message: completionError,
5045
+ terminal_reason: completionStatus === "cancelled" ? "Command cancelled from workspace UI." : null
5046
+ })
5047
+ }
5048
+ );
4919
5049
  await sendRunnerHeartbeat(
4920
5050
  configService,
4921
5051
  apiKey,
@@ -4927,7 +5057,14 @@ $ ${session.command}
4927
5057
  }
4928
5058
  }
4929
5059
  function registerRunnerCommands(program2) {
4930
- program2.command("runner").description("Run a paired worker that executes queued web task runs").option("--agent <command>", "Agent command to launch for claimed tasks", "copilot").option("--poll-interval <seconds>", "Polling interval in seconds", "10").option("--once", "Claim at most one run and then exit").option("--unsafe", "Disable Docker sandbox (run agent directly on host \u2014 no isolation)").action(async (options, command) => {
5060
+ program2.command("runner").description("Run a paired worker that executes queued web task runs").option(
5061
+ "--agent <command>",
5062
+ "Agent command to launch for claimed tasks",
5063
+ "copilot"
5064
+ ).option("--poll-interval <seconds>", "Polling interval in seconds", "10").option("--once", "Claim at most one run and then exit").option(
5065
+ "--unsafe",
5066
+ "Disable Docker sandbox (run agent directly on host \u2014 no isolation)"
5067
+ ).action(async (options, command) => {
4931
5068
  const configService = new ConfigService();
4932
5069
  const apiKey = await ensureAuthenticated(configService);
4933
5070
  const projectId = await configService.getProjectId();
@@ -4953,7 +5090,11 @@ function registerRunnerCommands(program2) {
4953
5090
  )
4954
5091
  );
4955
5092
  if (!useSandbox) {
4956
- console.log(chalk13.yellow(" \u26A0 Running in unsafe mode \u2014 agent has full host access."));
5093
+ console.log(
5094
+ chalk13.yellow(
5095
+ " \u26A0 Running in unsafe mode \u2014 agent has full host access."
5096
+ )
5097
+ );
4957
5098
  }
4958
5099
  let shouldStop = false;
4959
5100
  let consecutiveErrors = 0;
@@ -4966,7 +5107,11 @@ function registerRunnerCommands(program2) {
4966
5107
  const claimBackend = useSandbox ? "local_sandbox" : "local_runner";
4967
5108
  while (!shouldStop) {
4968
5109
  try {
4969
- const capabilities = getRunnerCapabilities(agent, useSandbox, agentPinned);
5110
+ const capabilities = getRunnerCapabilities(
5111
+ agent,
5112
+ useSandbox,
5113
+ agentPinned
5114
+ );
4970
5115
  await sendRunnerHeartbeat(
4971
5116
  configService,
4972
5117
  apiKey,
@@ -4990,7 +5135,9 @@ function registerRunnerCommands(program2) {
4990
5135
  );
4991
5136
  if (!claimResponse.ok) {
4992
5137
  const data = await claimResponse.json().catch(() => ({}));
4993
- throw new Error(data.error || "Failed to claim task run");
5138
+ throw new Error(
5139
+ data.error || "Failed to claim task run"
5140
+ );
4994
5141
  }
4995
5142
  const payload = await claimResponse.json();
4996
5143
  if (payload.run) {
@@ -5028,7 +5175,9 @@ function registerRunnerCommands(program2) {
5028
5175
  );
5029
5176
  if (!terminalClaimResponse.ok) {
5030
5177
  const data = await terminalClaimResponse.json().catch(() => ({}));
5031
- throw new Error(data.error || "Failed to claim terminal session");
5178
+ throw new Error(
5179
+ data.error || "Failed to claim terminal session"
5180
+ );
5032
5181
  }
5033
5182
  const terminalPayload = await terminalClaimResponse.json();
5034
5183
  if (terminalPayload.session) {
@@ -6423,6 +6572,34 @@ Snapshot Contents:`));
6423
6572
  return;
6424
6573
  }
6425
6574
  const update = parseVemUpdateBlock(input);
6575
+ const sandboxRunId = process.env.VEM_TASK_RUN_ID;
6576
+ const sandboxApiKey = process.env.VEM_API_KEY;
6577
+ const sandboxApiUrl = "https://api.vem.dev";
6578
+ if (sandboxRunId && sandboxApiKey) {
6579
+ const res = await fetch(
6580
+ `${sandboxApiUrl}/task-runs/${sandboxRunId}/vem-update-structured`,
6581
+ {
6582
+ method: "POST",
6583
+ headers: {
6584
+ Authorization: `Bearer ${sandboxApiKey}`,
6585
+ "Content-Type": "application/json"
6586
+ },
6587
+ body: JSON.stringify({ update })
6588
+ }
6589
+ );
6590
+ if (!res.ok) {
6591
+ const errText = await res.text().catch(() => "");
6592
+ console.error(
6593
+ chalk17.red("[vem finalize] API submission failed:"),
6594
+ res.status,
6595
+ errText
6596
+ );
6597
+ process.exitCode = 1;
6598
+ } else {
6599
+ console.log(chalk17.green("\n\u2714 vem update submitted to API\n"));
6600
+ }
6601
+ return;
6602
+ }
6426
6603
  const result = await applyVemUpdate(update);
6427
6604
  console.log(chalk17.green("\n\u2714 vem update applied\n"));
6428
6605
  if (result.updatedTasks.length > 0) {
@@ -6467,14 +6644,16 @@ Snapshot Contents:`));
6467
6644
  console.log(chalk17.gray("Context updated."));
6468
6645
  }
6469
6646
  const configService = new ConfigService();
6470
- await syncParsedTaskUpdatesToRemote(configService, update, result).catch(
6471
- (err) => {
6472
- console.error(
6473
- chalk17.yellow("[vem finalize] syncParsed failed:"),
6474
- err instanceof Error ? err.message : String(err)
6475
- );
6476
- }
6477
- );
6647
+ await syncParsedTaskUpdatesToRemote(
6648
+ configService,
6649
+ update,
6650
+ result
6651
+ ).catch((err) => {
6652
+ console.error(
6653
+ chalk17.yellow("[vem finalize] syncParsed failed:"),
6654
+ err instanceof Error ? err.message : String(err)
6655
+ );
6656
+ });
6478
6657
  const synced = await syncProjectMemoryToRemote().catch(() => false);
6479
6658
  if (synced) {
6480
6659
  console.log(chalk17.gray("\u2714 Synced to cloud."));
@@ -7084,7 +7263,14 @@ function registerTaskCommands(program2) {
7084
7263
  const tasks = await getDisplayTasks({ includeDeleted: true });
7085
7264
  const status = typeof options.status === "string" ? options.status : void 0;
7086
7265
  const cycleFilter = typeof options.cycle === "string" ? options.cycle.trim() : void 0;
7087
- const validStatuses = /* @__PURE__ */ new Set(["todo", "ready", "in-review", "in-progress", "blocked", "done"]);
7266
+ const validStatuses = /* @__PURE__ */ new Set([
7267
+ "todo",
7268
+ "ready",
7269
+ "in-review",
7270
+ "in-progress",
7271
+ "blocked",
7272
+ "done"
7273
+ ]);
7088
7274
  if (status && !validStatuses.has(status)) {
7089
7275
  console.error(
7090
7276
  chalk18.red(
@@ -7450,7 +7636,10 @@ ${currentSummary}
7450
7636
  ).option("-d, --description <description>", "Task description").option("--tags <tags>", "Comma-separated tags").option("--type <type>", "Task type (feature, bug, chore, spike, enabler)").option("--estimate-hours <hours>", "Estimated hours (e.g. 2.5)").option("--depends-on <ids>", "Comma-separated task IDs").option("--blocked-by <ids>", "Comma-separated task IDs").option("--recurrence <rule>", "Recurrence rule (weekly, monthly, cron)").option("--owner <id>", "Owner ID").option("--reviewer <id>", "Reviewer ID").option("--parent <id>", "Parent task ID").option("--order <number>", "Subtask order").option("--due-at <iso>", "Due date ISO string (YYYY-MM-DD)").option(
7451
7637
  "--validation <steps>",
7452
7638
  'Comma-separated validation steps (e.g. "pnpm build, pnpm test")'
7453
- ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option("--impact-score <score>", "Impact score 0-100 (RICE-based priority)").option("--actor <name>", "Actor name for task creation").option("-r, --reasoning <reasoning>", "Reasoning for creation").action(async (title, options) => {
7639
+ ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option(
7640
+ "--impact-score <score>",
7641
+ "Impact score 0-100 (RICE-based priority)"
7642
+ ).option("--actor <name>", "Actor name for task creation").option("-r, --reasoning <reasoning>", "Reasoning for creation").action(async (title, options) => {
7454
7643
  await trackCommandUsage("task add");
7455
7644
  try {
7456
7645
  let taskTitle = typeof title === "string" && title.trim().length > 0 ? title.trim() : void 0;
@@ -7797,7 +7986,9 @@ ${currentSummary}
7797
7986
  const dueAt = parseDueAtIso(dueAtInput);
7798
7987
  const normalizedType = typeInput?.trim().toLowerCase();
7799
7988
  if (normalizedType && normalizedType !== "feature" && normalizedType !== "bug" && normalizedType !== "chore" && normalizedType !== "spike" && normalizedType !== "enabler") {
7800
- throw new Error("type must be feature, bug, chore, spike, or enabler.");
7989
+ throw new Error(
7990
+ "type must be feature, bug, chore, spike, or enabler."
7991
+ );
7801
7992
  }
7802
7993
  const taskType = normalizedType === "feature" || normalizedType === "bug" || normalizedType === "chore" || normalizedType === "spike" || normalizedType === "enabler" ? normalizedType : void 0;
7803
7994
  let validationSteps = parseCommaList(validationInput);
@@ -7924,7 +8115,10 @@ ${currentSummary}
7924
8115
  taskCmd.command("update <id>").description("Update task metadata").option("--tags <tags>", "Comma-separated tags").option("--type <type>", "Task type (feature, bug, chore, spike, enabler)").option("--estimate-hours <hours>", "Estimated hours (e.g. 2.5)").option("--depends-on <ids>", "Comma-separated task IDs").option("--blocked-by <ids>", "Comma-separated task IDs").option("--recurrence <rule>", "Recurrence rule (weekly, monthly, cron)").option("--owner <id>", "Owner ID").option("--reviewer <id>", "Reviewer ID").option("--parent <id>", "Parent task ID").option("--order <number>", "Subtask order").option("--due-at <iso>", "Due date ISO string (YYYY-MM-DD)").option(
7925
8116
  "--validation <steps>",
7926
8117
  "Set validation steps (comma-separated). Use empty string to clear."
7927
- ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option("--impact-score <score>", "Impact score 0-100 (RICE-based priority)").option("--actor <name>", "Actor name for task update").option("-r, --reasoning <reasoning>", "Reasoning for update").action(async (id, options) => {
8118
+ ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option(
8119
+ "--impact-score <score>",
8120
+ "Impact score 0-100 (RICE-based priority)"
8121
+ ).option("--actor <name>", "Actor name for task update").option("-r, --reasoning <reasoning>", "Reasoning for update").action(async (id, options) => {
7928
8122
  try {
7929
8123
  const estimate = options.estimateHours !== void 0 ? Number.parseFloat(options.estimateHours) : void 0;
7930
8124
  if (estimate !== void 0 && Number.isNaN(estimate)) {
@@ -8565,8 +8759,12 @@ No agent sessions attached to ${id} yet.`)
8565
8759
  console.log(chalk18.bold(`
8566
8760
  \u23F1 Flow Metrics: ${id} \u2014 ${task.title}
8567
8761
  `));
8568
- console.log(` ${chalk18.gray("Lead time (created \u2192 done):")} ${fmtMs(metrics.lead_time_ms)}`);
8569
- console.log(` ${chalk18.gray("Cycle time (started \u2192 done):")} ${fmtMs(metrics.cycle_time_ms)}`);
8762
+ console.log(
8763
+ ` ${chalk18.gray("Lead time (created \u2192 done):")} ${fmtMs(metrics.lead_time_ms)}`
8764
+ );
8765
+ console.log(
8766
+ ` ${chalk18.gray("Cycle time (started \u2192 done):")} ${fmtMs(metrics.cycle_time_ms)}`
8767
+ );
8570
8768
  if (Object.keys(metrics.time_in_status).length > 0) {
8571
8769
  console.log(chalk18.gray("\n Time in each status:"));
8572
8770
  for (const [status, ms] of Object.entries(metrics.time_in_status)) {
@@ -8584,15 +8782,27 @@ No agent sessions attached to ${id} yet.`)
8584
8782
  return chalk18.white(`${hrs}h`);
8585
8783
  };
8586
8784
  console.log(chalk18.bold("\n\u{1F4CA} Project Flow Summary\n"));
8587
- console.log(` ${chalk18.gray("WIP (active tasks):")} ${chalk18.yellow(String(summary.wip_count))}`);
8588
- console.log(` ${chalk18.gray("Throughput (last 7d):")} ${chalk18.white(String(summary.throughput_last_7d))} tasks`);
8589
- console.log(` ${chalk18.gray("Throughput (last 30d):")} ${chalk18.white(String(summary.throughput_last_30d))} tasks`);
8590
- console.log(` ${chalk18.gray("Avg cycle time:")} ${fmtMs(summary.avg_cycle_time_ms)}`);
8591
- console.log(` ${chalk18.gray("Avg lead time:")} ${fmtMs(summary.avg_lead_time_ms)}`);
8785
+ console.log(
8786
+ ` ${chalk18.gray("WIP (active tasks):")} ${chalk18.yellow(String(summary.wip_count))}`
8787
+ );
8788
+ console.log(
8789
+ ` ${chalk18.gray("Throughput (last 7d):")} ${chalk18.white(String(summary.throughput_last_7d))} tasks`
8790
+ );
8791
+ console.log(
8792
+ ` ${chalk18.gray("Throughput (last 30d):")} ${chalk18.white(String(summary.throughput_last_30d))} tasks`
8793
+ );
8794
+ console.log(
8795
+ ` ${chalk18.gray("Avg cycle time:")} ${fmtMs(summary.avg_cycle_time_ms)}`
8796
+ );
8797
+ console.log(
8798
+ ` ${chalk18.gray("Avg lead time:")} ${fmtMs(summary.avg_lead_time_ms)}`
8799
+ );
8592
8800
  console.log();
8593
8801
  }
8594
8802
  } catch (error) {
8595
- console.error(chalk18.red(`Failed to get flow metrics: ${error.message}`));
8803
+ console.error(
8804
+ chalk18.red(`Failed to get flow metrics: ${error.message}`)
8805
+ );
8596
8806
  }
8597
8807
  });
8598
8808
  taskCmd.command("score [id]").description("Show or set the impact score (0-100) for a task").option("--set <score>", "Set impact score manually (0-100)").option("-r, --reasoning <reasoning>", "Reasoning for score change").action(async (id, options) => {
@@ -8604,7 +8814,9 @@ No agent sessions attached to ${id} yet.`)
8604
8814
  (t) => t.impact_score === void 0 && t.status !== "done" && !t.deleted_at
8605
8815
  );
8606
8816
  if (unscored.length === 0) {
8607
- console.log(chalk18.green("\n\u2714 All active tasks have impact scores.\n"));
8817
+ console.log(
8818
+ chalk18.green("\n\u2714 All active tasks have impact scores.\n")
8819
+ );
8608
8820
  return;
8609
8821
  }
8610
8822
  const table = new Table4({
@@ -8622,9 +8834,13 @@ No agent sessions attached to ${id} yet.`)
8622
8834
  }
8623
8835
  console.log(chalk18.bold("\n\u{1F3AF} Impact Scores\n"));
8624
8836
  console.log(table.toString());
8625
- console.log(chalk18.gray(`
8837
+ console.log(
8838
+ chalk18.gray(
8839
+ `
8626
8840
  Unscored: ${unscored.length} task(s). Use: vem task score <id> --set <0-100>
8627
- `));
8841
+ `
8842
+ )
8843
+ );
8628
8844
  return;
8629
8845
  }
8630
8846
  const task = await taskService.getTask(id);
@@ -8635,7 +8851,9 @@ No agent sessions attached to ${id} yet.`)
8635
8851
  if (options.set !== void 0) {
8636
8852
  const score = Number.parseFloat(options.set);
8637
8853
  if (Number.isNaN(score) || score < 0 || score > 100) {
8638
- console.error(chalk18.red("Score must be a number between 0 and 100."));
8854
+ console.error(
8855
+ chalk18.red("Score must be a number between 0 and 100.")
8856
+ );
8639
8857
  process.exitCode = 1;
8640
8858
  return;
8641
8859
  }
@@ -8643,15 +8861,21 @@ No agent sessions attached to ${id} yet.`)
8643
8861
  impact_score: score,
8644
8862
  reasoning: options.reasoning
8645
8863
  });
8646
- console.log(chalk18.green(`
8864
+ console.log(
8865
+ chalk18.green(`
8647
8866
  \u2714 Impact score for ${id} set to ${score}
8648
- `));
8867
+ `)
8868
+ );
8649
8869
  } else {
8650
8870
  console.log(chalk18.bold(`
8651
8871
  \u{1F3AF} ${id}: ${task.title}`));
8652
- console.log(` Impact score: ${task.impact_score !== void 0 ? chalk18.yellow(String(Math.round(task.impact_score))) : chalk18.gray("not set")}`);
8653
- console.log(chalk18.gray(` Set with: vem task score ${id} --set <0-100>
8654
- `));
8872
+ console.log(
8873
+ ` Impact score: ${task.impact_score !== void 0 ? chalk18.yellow(String(Math.round(task.impact_score))) : chalk18.gray("not set")}`
8874
+ );
8875
+ console.log(
8876
+ chalk18.gray(` Set with: vem task score ${id} --set <0-100>
8877
+ `)
8878
+ );
8655
8879
  }
8656
8880
  } catch (error) {
8657
8881
  console.error(chalk18.red(`Failed to manage score: ${error.message}`));
@@ -8744,11 +8968,11 @@ async function initServerMonitoring(config) {
8744
8968
  await initServerMonitoring({
8745
8969
  dsn: "https://ed007f2c213d0aa07c1be256ca51750c@o4510863861612544.ingest.de.sentry.io/4510863921774672",
8746
8970
  environment: process.env.NODE_ENV || "production",
8747
- release: "0.1.53",
8971
+ release: "0.1.55",
8748
8972
  serviceName: "cli"
8749
8973
  });
8750
8974
  var program = new Command();
8751
- program.name("vem").description("vem Project Memory CLI").version("0.1.53").addHelpText(
8975
+ program.name("vem").description("vem Project Memory CLI").version("0.1.55").addHelpText(
8752
8976
  "after",
8753
8977
  `
8754
8978
  ${chalk19.bold("\n\u26A1 Power Workflows:")}