@vemdev/cli 0.1.53 → 0.1.54

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
@@ -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,
@@ -1102,24 +1108,33 @@ var updateTaskMetaRemote = async (configService, task, patch) => {
1102
1108
  payload.actor = patch.actor.trim().length > 0 ? patch.actor.trim() : void 0;
1103
1109
  }
1104
1110
  if (patch.title !== void 0) payload.title = patch.title;
1105
- if (patch.description !== void 0) payload.description = patch.description;
1111
+ if (patch.description !== void 0)
1112
+ payload.description = patch.description;
1106
1113
  if (patch.priority !== void 0) payload.priority = patch.priority;
1107
1114
  if (patch.tags !== void 0) payload.tags = patch.tags;
1108
1115
  if (patch.type !== void 0) payload.type = patch.type;
1109
- if (patch.estimate_hours !== void 0) payload.estimate_hours = patch.estimate_hours;
1116
+ if (patch.estimate_hours !== void 0)
1117
+ payload.estimate_hours = patch.estimate_hours;
1110
1118
  if (patch.depends_on !== void 0) payload.depends_on = patch.depends_on;
1111
1119
  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;
1120
+ if (patch.recurrence_rule !== void 0)
1121
+ payload.recurrence_rule = patch.recurrence_rule;
1113
1122
  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;
1123
+ if (patch.reviewer_id !== void 0)
1124
+ payload.reviewer_id = patch.reviewer_id;
1125
+ if (patch.validation_steps !== void 0)
1126
+ payload.validation_steps = patch.validation_steps;
1116
1127
  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;
1128
+ if (patch.github_issue_number !== void 0)
1129
+ payload.github_issue_number = patch.github_issue_number;
1118
1130
  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;
1131
+ if (patch.subtask_order !== void 0)
1132
+ payload.subtask_order = patch.subtask_order;
1120
1133
  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;
1134
+ if (patch.raw_vem_update !== void 0)
1135
+ payload.raw_vem_update = patch.raw_vem_update;
1136
+ if (patch.cli_version !== void 0)
1137
+ payload.cli_version = patch.cli_version;
1123
1138
  const response = await fetch(
1124
1139
  `${API_URL}/tasks/${encodeURIComponent(dbId)}/meta`,
1125
1140
  {
@@ -1237,7 +1252,7 @@ var syncParsedTaskUpdatesToRemote = async (configService, update, result) => {
1237
1252
  ...patch.subtask_order !== void 0 ? { subtask_order: patch.subtask_order } : {},
1238
1253
  ...patch.due_at !== void 0 ? { due_at: patch.due_at } : {},
1239
1254
  raw_vem_update: JSON.parse(JSON.stringify(update)),
1240
- cli_version: "0.1.53"
1255
+ cli_version: "0.1.54"
1241
1256
  });
1242
1257
  const taskContextPatch = buildRemoteTaskContextPatch(patch, updatedTask);
1243
1258
  if (taskContextPatch) {
@@ -1843,7 +1858,11 @@ Your task is ${activeTask?.id}: ${activeTask?.title}${childScopeText}.
1843
1858
 
1844
1859
  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
1860
  if (options.autoExit) {
1846
- console.log(chalk7.cyan("Auto-injecting context via -p flag (autonomous mode)..."));
1861
+ console.log(
1862
+ chalk7.cyan(
1863
+ "Auto-injecting context via -p flag (autonomous mode)..."
1864
+ )
1865
+ );
1847
1866
  launchArgs = [...launchArgs, "-p", autonomousPrompt, "--yolo"];
1848
1867
  } else {
1849
1868
  console.log(chalk7.cyan("Auto-injecting context via -i flag..."));
@@ -2510,7 +2529,11 @@ function registerCycleCommands(program2) {
2510
2529
  try {
2511
2530
  const cycles = await cycleService.getCycles();
2512
2531
  if (cycles.length === 0) {
2513
- console.log(chalk9.gray("\n No cycles yet. Create one with: vem cycle create\n"));
2532
+ console.log(
2533
+ chalk9.gray(
2534
+ "\n No cycles yet. Create one with: vem cycle create\n"
2535
+ )
2536
+ );
2514
2537
  return;
2515
2538
  }
2516
2539
  const table = new Table({
@@ -2634,7 +2657,9 @@ function registerCycleCommands(program2) {
2634
2657
  process.exitCode = 1;
2635
2658
  return;
2636
2659
  }
2637
- const updated = await cycleService.updateCycle(id, { status: "active" });
2660
+ const updated = await cycleService.updateCycle(id, {
2661
+ status: "active"
2662
+ });
2638
2663
  console.log(chalk9.cyan(`
2639
2664
  \u2714 Cycle ${id} is now active
2640
2665
  `));
@@ -2662,7 +2687,9 @@ function registerCycleCommands(program2) {
2662
2687
  `));
2663
2688
  return;
2664
2689
  }
2665
- const updated = await cycleService.updateCycle(id, { status: "closed" });
2690
+ const updated = await cycleService.updateCycle(id, {
2691
+ status: "closed"
2692
+ });
2666
2693
  console.log(chalk9.green(`
2667
2694
  \u2714 Cycle ${id} closed
2668
2695
  `));
@@ -2678,8 +2705,10 @@ function registerCycleCommands(program2) {
2678
2705
  );
2679
2706
  }
2680
2707
  console.log(
2681
- chalk9.gray(` Closed: ${new Date(updated.closed_at).toLocaleDateString()}
2682
- `)
2708
+ chalk9.gray(
2709
+ ` Closed: ${new Date(updated.closed_at).toLocaleDateString()}
2710
+ `
2711
+ )
2683
2712
  );
2684
2713
  } catch (error) {
2685
2714
  console.error(chalk9.red(`Failed to close cycle: ${error.message}`));
@@ -2787,13 +2816,17 @@ function registerCycleCommands(program2) {
2787
2816
  ]);
2788
2817
  }
2789
2818
  const done = cycleTasks.filter((t) => t.status === "done").length;
2790
- console.log(`
2819
+ console.log(
2820
+ `
2791
2821
  ${chalk9.white(String(done))}/${chalk9.white(String(cycleTasks.length))} tasks done
2792
- `);
2822
+ `
2823
+ );
2793
2824
  console.log(table.toString());
2794
2825
  console.log();
2795
2826
  } catch (error) {
2796
- console.error(chalk9.red(`Failed to show cycle focus: ${error.message}`));
2827
+ console.error(
2828
+ chalk9.red(`Failed to show cycle focus: ${error.message}`)
2829
+ );
2797
2830
  }
2798
2831
  });
2799
2832
  }
@@ -2806,7 +2839,9 @@ import prompts5 from "prompts";
2806
2839
  async function getRepoRoot2() {
2807
2840
  const { execSync: execSync4 } = await import("child_process");
2808
2841
  try {
2809
- return execSync4("git rev-parse --show-toplevel", { encoding: "utf-8" }).trim();
2842
+ return execSync4("git rev-parse --show-toplevel", {
2843
+ encoding: "utf-8"
2844
+ }).trim();
2810
2845
  } catch {
2811
2846
  return process.cwd();
2812
2847
  }
@@ -2877,9 +2912,7 @@ function registerInstructionCommands(program2) {
2877
2912
  const dest = path.resolve(repoRoot, entry.path);
2878
2913
  const resolvedRoot = path.resolve(repoRoot);
2879
2914
  if (!dest.startsWith(`${resolvedRoot}${path.sep}`) && dest !== resolvedRoot) {
2880
- console.warn(
2881
- chalk10.yellow(`Skipping unsafe path: ${entry.path}`)
2882
- );
2915
+ console.warn(chalk10.yellow(`Skipping unsafe path: ${entry.path}`));
2883
2916
  continue;
2884
2917
  }
2885
2918
  if (!options.force) {
@@ -2905,9 +2938,11 @@ function registerInstructionCommands(program2) {
2905
2938
  }
2906
2939
  const skippedMsg = skipped > 0 ? `, ${skipped} skipped` : "";
2907
2940
  console.log(
2908
- chalk10.green(`
2941
+ chalk10.green(
2942
+ `
2909
2943
  \u2714 Pulled ${written} instruction file(s)${skippedMsg}.
2910
- `)
2944
+ `
2945
+ )
2911
2946
  );
2912
2947
  } catch (error) {
2913
2948
  console.error(
@@ -2935,9 +2970,7 @@ function registerInstructionCommands(program2) {
2935
2970
  const localInstructions = await readLocalInstructions();
2936
2971
  if (localInstructions.length === 0) {
2937
2972
  console.log(
2938
- chalk10.yellow(
2939
- "No instruction files found locally. Looked for:"
2940
- )
2973
+ chalk10.yellow("No instruction files found locally. Looked for:")
2941
2974
  );
2942
2975
  for (const f of KNOWN_AGENT_INSTRUCTION_FILES) {
2943
2976
  console.log(chalk10.gray(` ${f}`));
@@ -2975,11 +3008,9 @@ function registerInstructionCommands(program2) {
2975
3008
  console.log(chalk10.green(` \u2714 ${entry.path}`));
2976
3009
  }
2977
3010
  const versionNote = data.version_number ? ` (saved as v${data.version_number})` : "";
2978
- console.log(
2979
- chalk10.green(`
3011
+ console.log(chalk10.green(`
2980
3012
  \u2714 Instructions pushed${versionNote}.
2981
- `)
2982
- );
3013
+ `));
2983
3014
  } catch (error) {
2984
3015
  console.error(
2985
3016
  chalk10.red("\n\u2716 Instructions push failed:"),
@@ -2988,9 +3019,7 @@ function registerInstructionCommands(program2) {
2988
3019
  process.exitCode = 1;
2989
3020
  }
2990
3021
  });
2991
- instructionsCmd.command("status").description(
2992
- "Check if local instruction files are in sync with the cloud"
2993
- ).action(async () => {
3022
+ instructionsCmd.command("status").description("Check if local instruction files are in sync with the cloud").action(async () => {
2994
3023
  await trackCommandUsage("instructions.status");
2995
3024
  try {
2996
3025
  const configService = new ConfigService();
@@ -3022,8 +3051,12 @@ function registerInstructionCommands(program2) {
3022
3051
  }
3023
3052
  const cloudData = await cloudRes.json();
3024
3053
  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]));
3054
+ const localMap = new Map(
3055
+ localInstructions.map((e) => [e.path, e.content])
3056
+ );
3057
+ const cloudMap = new Map(
3058
+ cloudInstructions.map((e) => [e.path, e.content])
3059
+ );
3027
3060
  const allPaths = /* @__PURE__ */ new Set([...localMap.keys(), ...cloudMap.keys()]);
3028
3061
  let inSync = true;
3029
3062
  console.log(chalk10.bold("\nInstruction file sync status:\n"));
@@ -3046,7 +3079,9 @@ function registerInstructionCommands(program2) {
3046
3079
  );
3047
3080
  inSync = false;
3048
3081
  } else {
3049
- console.log(chalk10.green(` \u2714 ${filePath}`) + chalk10.gray(" (in sync)"));
3082
+ console.log(
3083
+ chalk10.green(` \u2714 ${filePath}`) + chalk10.gray(" (in sync)")
3084
+ );
3050
3085
  }
3051
3086
  }
3052
3087
  if (allPaths.size === 0) {
@@ -3165,9 +3200,7 @@ function registerInstructionCommands(program2) {
3165
3200
  )
3166
3201
  );
3167
3202
  console.log(
3168
- chalk10.gray(
3169
- " Run `vem instructions pull` to update local files."
3170
- )
3203
+ chalk10.gray(" Run `vem instructions pull` to update local files.")
3171
3204
  );
3172
3205
  } catch (error) {
3173
3206
  console.error(
@@ -4109,7 +4142,13 @@ function commandExists(command) {
4109
4142
  return false;
4110
4143
  }
4111
4144
  }
4112
- var KNOWN_RUNNER_AGENTS = ["copilot", "gh", "claude", "gemini", "codex"];
4145
+ var KNOWN_RUNNER_AGENTS = [
4146
+ "copilot",
4147
+ "gh",
4148
+ "claude",
4149
+ "gemini",
4150
+ "codex"
4151
+ ];
4113
4152
  function hasSandboxCredentials(agent) {
4114
4153
  if (agent === "claude") {
4115
4154
  return typeof process.env.ANTHROPIC_API_KEY === "string" && process.env.ANTHROPIC_API_KEY.trim().length > 0;
@@ -4118,7 +4157,9 @@ function hasSandboxCredentials(agent) {
4118
4157
  const envToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
4119
4158
  if (envToken && envToken.trim().length > 0) return true;
4120
4159
  try {
4121
- const token = execFileSync("gh", ["auth", "token"], { encoding: "utf-8" }).trim();
4160
+ const token = execFileSync("gh", ["auth", "token"], {
4161
+ encoding: "utf-8"
4162
+ }).trim();
4122
4163
  return token.length > 0;
4123
4164
  } catch {
4124
4165
  return false;
@@ -4134,9 +4175,13 @@ function hasSandboxCredentials(agent) {
4134
4175
  }
4135
4176
  function getAvailableAgentCommands(selectedAgent, sandbox) {
4136
4177
  const isAvailable = (command) => commandExists(command) && (!sandbox || hasSandboxCredentials(command));
4137
- const knownAvailable = KNOWN_RUNNER_AGENTS.filter((command) => isAvailable(command));
4178
+ const knownAvailable = KNOWN_RUNNER_AGENTS.filter(
4179
+ (command) => isAvailable(command)
4180
+ );
4138
4181
  const selectedAvailable = isAvailable(selectedAgent);
4139
- if (selectedAvailable && !knownAvailable.includes(selectedAgent)) {
4182
+ if (selectedAvailable && !knownAvailable.includes(
4183
+ selectedAgent
4184
+ )) {
4140
4185
  return [selectedAgent, ...knownAvailable];
4141
4186
  }
4142
4187
  return knownAvailable;
@@ -4171,9 +4216,7 @@ function checkDockerAvailable() {
4171
4216
  try {
4172
4217
  execFileSync("docker", ["info"], { stdio: "ignore" });
4173
4218
  } catch {
4174
- console.error(
4175
- chalk13.red("\u2717 Docker is not running or not installed.")
4176
- );
4219
+ console.error(chalk13.red("\u2717 Docker is not running or not installed."));
4177
4220
  console.error(
4178
4221
  chalk13.yellow(
4179
4222
  " The vem runner requires Docker to run agents in a secure sandbox."
@@ -4206,7 +4249,9 @@ function getSandboxImageDir() {
4206
4249
  return dirname2(candidate);
4207
4250
  }
4208
4251
  }
4209
- throw new Error("Dockerfile.sandbox not found. Ensure the vem CLI is installed correctly.");
4252
+ throw new Error(
4253
+ "Dockerfile.sandbox not found. Ensure the vem CLI is installed correctly."
4254
+ );
4210
4255
  }
4211
4256
  function buildSandboxImage() {
4212
4257
  console.log(chalk13.cyan(" Building sandbox Docker image (first use)..."));
@@ -4220,7 +4265,9 @@ function buildSandboxImage() {
4220
4265
  }
4221
4266
  function ensureSandboxImage() {
4222
4267
  try {
4223
- execFileSync("docker", ["image", "inspect", SANDBOX_IMAGE_NAME], { stdio: "ignore" });
4268
+ execFileSync("docker", ["image", "inspect", SANDBOX_IMAGE_NAME], {
4269
+ stdio: "ignore"
4270
+ });
4224
4271
  } catch {
4225
4272
  buildSandboxImage();
4226
4273
  }
@@ -4235,7 +4282,11 @@ function collectSandboxCredentials(agent) {
4235
4282
  if (agent === "claude") {
4236
4283
  addFromEnv("ANTHROPIC_API_KEY");
4237
4284
  if (!creds.ANTHROPIC_API_KEY) {
4238
- console.error(chalk13.red(`\u2717 ANTHROPIC_API_KEY is not set. Required for --agent claude.`));
4285
+ console.error(
4286
+ chalk13.red(
4287
+ `\u2717 ANTHROPIC_API_KEY is not set. Required for --agent claude.`
4288
+ )
4289
+ );
4239
4290
  process.exit(1);
4240
4291
  }
4241
4292
  } else if (agent === "copilot" || agent === "gh") {
@@ -4244,31 +4295,43 @@ function collectSandboxCredentials(agent) {
4244
4295
  creds.GITHUB_TOKEN = envToken;
4245
4296
  } else {
4246
4297
  try {
4247
- const token = execFileSync("gh", ["auth", "token"], { encoding: "utf-8" }).trim();
4298
+ const token = execFileSync("gh", ["auth", "token"], {
4299
+ encoding: "utf-8"
4300
+ }).trim();
4248
4301
  if (token) creds.GITHUB_TOKEN = token;
4249
4302
  } catch {
4250
4303
  }
4251
4304
  }
4252
4305
  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"));
4306
+ console.error(
4307
+ chalk13.red(`\u2717 GitHub token not found. Required for --agent copilot.`)
4308
+ );
4309
+ console.error(
4310
+ chalk13.gray(" Set GITHUB_TOKEN env var or run: gh auth login")
4311
+ );
4255
4312
  process.exit(1);
4256
4313
  }
4257
4314
  } else if (agent === "gemini") {
4258
4315
  addFromEnv("GEMINI_API_KEY");
4259
4316
  if (!creds.GEMINI_API_KEY) {
4260
- console.error(chalk13.red(`\u2717 GEMINI_API_KEY is not set. Required for --agent gemini.`));
4317
+ console.error(
4318
+ chalk13.red(`\u2717 GEMINI_API_KEY is not set. Required for --agent gemini.`)
4319
+ );
4261
4320
  process.exit(1);
4262
4321
  }
4263
4322
  } else if (agent === "codex") {
4264
4323
  addFromEnv("OPENAI_API_KEY");
4265
4324
  if (!creds.OPENAI_API_KEY) {
4266
- console.error(chalk13.red(`\u2717 OPENAI_API_KEY is not set. Required for --agent codex.`));
4325
+ console.error(
4326
+ chalk13.red(`\u2717 OPENAI_API_KEY is not set. Required for --agent codex.`)
4327
+ );
4267
4328
  process.exit(1);
4268
4329
  }
4269
4330
  }
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;
4331
+ if (process.env.GIT_AUTHOR_NAME)
4332
+ creds.GIT_AUTHOR_NAME = process.env.GIT_AUTHOR_NAME;
4333
+ if (process.env.GIT_AUTHOR_EMAIL)
4334
+ creds.GIT_AUTHOR_EMAIL = process.env.GIT_AUTHOR_EMAIL;
4272
4335
  return creds;
4273
4336
  }
4274
4337
  function sanitizeBranchSegment(value) {
@@ -4282,7 +4345,10 @@ async function resolveGitRemote(configService) {
4282
4345
  const linkedRemote = (await configService.getLinkedRemoteName())?.trim();
4283
4346
  const preferredRemote = linkedRemote || "origin";
4284
4347
  try {
4285
- return { name: preferredRemote, url: runGit(["remote", "get-url", preferredRemote]) };
4348
+ return {
4349
+ name: preferredRemote,
4350
+ url: runGit(["remote", "get-url", preferredRemote])
4351
+ };
4286
4352
  } catch {
4287
4353
  if (preferredRemote !== "origin") {
4288
4354
  try {
@@ -4333,23 +4399,33 @@ async function appendRunLogs(configService, apiKey, runId, entries) {
4333
4399
  });
4334
4400
  }
4335
4401
  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
- });
4402
+ await apiRequest(
4403
+ configService,
4404
+ apiKey,
4405
+ `/projects/${projectId}/runners/heartbeat`,
4406
+ {
4407
+ method: "POST",
4408
+ body: JSON.stringify({
4409
+ status,
4410
+ current_task_run_id: currentTaskRunId,
4411
+ capabilities
4412
+ })
4413
+ }
4414
+ );
4344
4415
  }
4345
4416
  async function completeTaskRunWithRetry(configService, apiKey, runId, payload, attempts = 5) {
4346
4417
  let lastError = "unknown error";
4347
4418
  for (let attempt = 1; attempt <= attempts; attempt++) {
4348
4419
  try {
4349
- const response = await apiRequest(configService, apiKey, `/task-runs/${runId}/complete`, {
4350
- method: "POST",
4351
- body: JSON.stringify(payload)
4352
- });
4420
+ const response = await apiRequest(
4421
+ configService,
4422
+ apiKey,
4423
+ `/task-runs/${runId}/complete`,
4424
+ {
4425
+ method: "POST",
4426
+ body: JSON.stringify(payload)
4427
+ }
4428
+ );
4353
4429
  if (response.ok) return;
4354
4430
  const bodyText = await response.text().catch(() => "");
4355
4431
  lastError = `HTTP ${response.status}${bodyText ? `: ${bodyText}` : ""}`;
@@ -4363,7 +4439,15 @@ async function completeTaskRunWithRetry(configService, apiKey, runId, payload, a
4363
4439
  throw new Error(`Failed to complete run ${runId}: ${lastError}`);
4364
4440
  }
4365
4441
  async function executeClaimedRun(input) {
4366
- const { configService, apiKey, projectId, agent, useSandbox, agentPinned, run } = input;
4442
+ const {
4443
+ configService,
4444
+ apiKey,
4445
+ projectId,
4446
+ agent,
4447
+ useSandbox,
4448
+ agentPinned,
4449
+ run
4450
+ } = input;
4367
4451
  const repoRoot = getRepoRoot3();
4368
4452
  let sequence = 1;
4369
4453
  let heartbeatTimer = null;
@@ -4390,7 +4474,11 @@ async function executeClaimedRun(input) {
4390
4474
  } catch {
4391
4475
  originalBranch = null;
4392
4476
  }
4393
- const preparedBranch = prepareTaskBranch(run.task_external_id, baseBranch, remote.name);
4477
+ const preparedBranch = prepareTaskBranch(
4478
+ run.task_external_id,
4479
+ baseBranch,
4480
+ remote.name
4481
+ );
4394
4482
  baseHash = preparedBranch.baseHash;
4395
4483
  branchName = preparedBranch.branchName;
4396
4484
  await appendRunLogs(configService, apiKey, run.id, [
@@ -4403,7 +4491,14 @@ async function executeClaimedRun(input) {
4403
4491
  ]);
4404
4492
  const child = spawn3(
4405
4493
  process.execPath,
4406
- [getCliEntrypoint(), "agent", agent, "--task", run.task_external_id, "--auto-exit"],
4494
+ [
4495
+ getCliEntrypoint(),
4496
+ "agent",
4497
+ agent,
4498
+ "--task",
4499
+ run.task_external_id,
4500
+ "--auto-exit"
4501
+ ],
4407
4502
  {
4408
4503
  env: {
4409
4504
  ...process.env,
@@ -4473,15 +4568,13 @@ async function executeClaimedRun(input) {
4473
4568
  { sequence: sequence++, stream: "stderr", chunk: text }
4474
4569
  ]);
4475
4570
  });
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
- );
4571
+ const result = await new Promise((resolve3) => {
4572
+ child.on("exit", (code, signal) => resolve3({ code, signal }));
4573
+ child.on("error", (error) => {
4574
+ completionError = error.message;
4575
+ resolve3({ code: null, signal: null });
4576
+ });
4577
+ });
4485
4578
  exitCode = result.code;
4486
4579
  if (completionError) {
4487
4580
  completionStatus = cancellationRequested ? "cancelled" : "failed";
@@ -4503,7 +4596,11 @@ async function executeClaimedRun(input) {
4503
4596
  if (completionStatus === "completed" && hasDirtyWorktree()) {
4504
4597
  runGit(["add", "-A"], { stdio: "inherit" });
4505
4598
  runGit(
4506
- ["commit", "-m", `chore(${run.task_external_id}): apply agent changes`],
4599
+ [
4600
+ "commit",
4601
+ "-m",
4602
+ `chore(${run.task_external_id}): apply agent changes`
4603
+ ],
4507
4604
  { stdio: "inherit" }
4508
4605
  );
4509
4606
  }
@@ -4599,15 +4696,19 @@ async function executeClaimedRunInSandbox(input) {
4599
4696
  execFileSync("rm", ["-rf", worktreePath], { stdio: "ignore" });
4600
4697
  }
4601
4698
  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" });
4699
+ execFileSync(
4700
+ "git",
4701
+ [
4702
+ "clone",
4703
+ "--quiet",
4704
+ `file://${repoRoot}`,
4705
+ "--branch",
4706
+ baseBranch,
4707
+ "--single-branch",
4708
+ worktreePath
4709
+ ],
4710
+ { stdio: "pipe" }
4711
+ );
4611
4712
  runGitIn(worktreePath, ["checkout", "-b", branchName]);
4612
4713
  if (remoteUrl) {
4613
4714
  runGitIn(worktreePath, ["remote", "set-url", "origin", remoteUrl]);
@@ -4674,7 +4775,9 @@ async function executeClaimedRunInSandbox(input) {
4674
4775
  if (dockerProcess?.pid) {
4675
4776
  try {
4676
4777
  if (containerName) {
4677
- execFileSync("docker", ["stop", containerName], { stdio: "ignore" });
4778
+ execFileSync("docker", ["stop", containerName], {
4779
+ stdio: "ignore"
4780
+ });
4678
4781
  } else {
4679
4782
  dockerProcess.kill("SIGTERM");
4680
4783
  }
@@ -4682,7 +4785,11 @@ async function executeClaimedRunInSandbox(input) {
4682
4785
  }
4683
4786
  }
4684
4787
  await appendRunLogs(configService, apiKey, run.id, [
4685
- { sequence: sequence++, stream: "system", chunk: "Cancellation requested from web UI. Stopping sandbox container.\n" }
4788
+ {
4789
+ sequence: sequence++,
4790
+ stream: "system",
4791
+ chunk: "Cancellation requested from web UI. Stopping sandbox container.\n"
4792
+ }
4686
4793
  ]);
4687
4794
  }
4688
4795
  if (maxRuntimeAt && !timedOut) {
@@ -4694,13 +4801,19 @@ async function executeClaimedRunInSandbox(input) {
4694
4801
  if (dockerProcess?.pid) {
4695
4802
  try {
4696
4803
  if (containerName) {
4697
- execFileSync("docker", ["stop", containerName], { stdio: "ignore" });
4804
+ execFileSync("docker", ["stop", containerName], {
4805
+ stdio: "ignore"
4806
+ });
4698
4807
  }
4699
4808
  } catch {
4700
4809
  }
4701
4810
  }
4702
4811
  await appendRunLogs(configService, apiKey, run.id, [
4703
- { sequence: sequence++, stream: "system", chunk: "Run exceeded the maximum runtime. Stopping sandbox container.\n" }
4812
+ {
4813
+ sequence: sequence++,
4814
+ stream: "system",
4815
+ chunk: "Run exceeded the maximum runtime. Stopping sandbox container.\n"
4816
+ }
4704
4817
  ]);
4705
4818
  }
4706
4819
  }
@@ -4728,7 +4841,10 @@ async function executeClaimedRunInSandbox(input) {
4728
4841
  if (exitCode === 0 && !cancellationRequested && !timedOut) {
4729
4842
  completionStatus = "completed";
4730
4843
  try {
4731
- const output = runGitIn(worktreePath, ["rev-list", `${baseHash}..HEAD`]);
4844
+ const output = runGitIn(worktreePath, [
4845
+ "rev-list",
4846
+ `${baseHash}..HEAD`
4847
+ ]);
4732
4848
  commitHashes = output.split("\n").map((h) => h.trim()).filter(Boolean);
4733
4849
  } catch {
4734
4850
  }
@@ -4738,16 +4854,26 @@ async function executeClaimedRunInSandbox(input) {
4738
4854
  }
4739
4855
  if (completionStatus === "completed" && commitHashes.length > 0) {
4740
4856
  try {
4741
- runGitIn(worktreePath, ["push", "-u", "origin", branchName], { stdio: "inherit" });
4857
+ runGitIn(worktreePath, ["push", "-u", "origin", branchName], {
4858
+ stdio: "inherit"
4859
+ });
4742
4860
  await appendRunLogs(configService, apiKey, run.id, [
4743
- { sequence: sequence++, stream: "system", chunk: `Pushed branch ${branchName} to ${remote.name}.
4744
- ` }
4861
+ {
4862
+ sequence: sequence++,
4863
+ stream: "system",
4864
+ chunk: `Pushed branch ${branchName} to ${remote.name}.
4865
+ `
4866
+ }
4745
4867
  ]);
4746
4868
  } catch (pushErr) {
4747
4869
  const msg = pushErr instanceof Error ? pushErr.message : String(pushErr);
4748
4870
  await appendRunLogs(configService, apiKey, run.id, [
4749
- { sequence: sequence++, stream: "system", chunk: `Warning: failed to push branch: ${msg}
4750
- ` }
4871
+ {
4872
+ sequence: sequence++,
4873
+ stream: "system",
4874
+ chunk: `Warning: failed to push branch: ${msg}
4875
+ `
4876
+ }
4751
4877
  ]);
4752
4878
  createPr = false;
4753
4879
  }
@@ -4761,8 +4887,12 @@ async function executeClaimedRunInSandbox(input) {
4761
4887
  heartbeatTimer = null;
4762
4888
  }
4763
4889
  await appendRunLogs(configService, apiKey, run.id, [
4764
- { sequence: sequence++, stream: "system", chunk: `Sandbox run error: ${msg}
4765
- ` }
4890
+ {
4891
+ sequence: sequence++,
4892
+ stream: "system",
4893
+ chunk: `Sandbox run error: ${msg}
4894
+ `
4895
+ }
4766
4896
  ]).catch(() => {
4767
4897
  });
4768
4898
  } finally {
@@ -4803,13 +4933,26 @@ ${run.user_prompt.trim()}` : "Triggered from VEM web."
4803
4933
  }
4804
4934
  async function appendTerminalLogs(configService, apiKey, sessionId, entries) {
4805
4935
  if (entries.length === 0) return;
4806
- await apiRequest(configService, apiKey, `/terminal-sessions/${sessionId}/logs`, {
4807
- method: "POST",
4808
- body: JSON.stringify({ entries })
4809
- });
4936
+ await apiRequest(
4937
+ configService,
4938
+ apiKey,
4939
+ `/terminal-sessions/${sessionId}/logs`,
4940
+ {
4941
+ method: "POST",
4942
+ body: JSON.stringify({ entries })
4943
+ }
4944
+ );
4810
4945
  }
4811
4946
  async function executeClaimedTerminalSession(input) {
4812
- const { configService, apiKey, projectId, agent, useSandbox, agentPinned, session } = input;
4947
+ const {
4948
+ configService,
4949
+ apiKey,
4950
+ projectId,
4951
+ agent,
4952
+ useSandbox,
4953
+ agentPinned,
4954
+ session
4955
+ } = input;
4813
4956
  const repoRoot = getRepoRoot3();
4814
4957
  let sequence = 2;
4815
4958
  let heartbeatTimer = null;
@@ -4869,15 +5012,13 @@ $ ${session.command}
4869
5012
  { sequence: sequence++, stream: "stderr", chunk: text }
4870
5013
  ]);
4871
5014
  });
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
- );
5015
+ const result = await new Promise((resolve3) => {
5016
+ child.on("exit", (code, signal) => resolve3({ code, signal }));
5017
+ child.on("error", (error) => {
5018
+ completionError = error.message;
5019
+ resolve3({ code: null, signal: null });
5020
+ });
5021
+ });
4881
5022
  exitCode = result.code;
4882
5023
  if (completionError) {
4883
5024
  completionStatus = cancellationRequested ? "cancelled" : "failed";
@@ -4907,15 +5048,20 @@ $ ${session.command}
4907
5048
  if (heartbeatTimer) {
4908
5049
  clearInterval(heartbeatTimer);
4909
5050
  }
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
- });
5051
+ await apiRequest(
5052
+ configService,
5053
+ apiKey,
5054
+ `/terminal-sessions/${session.id}/complete`,
5055
+ {
5056
+ method: "POST",
5057
+ body: JSON.stringify({
5058
+ status: completionStatus,
5059
+ exit_code: exitCode,
5060
+ error_message: completionError,
5061
+ terminal_reason: completionStatus === "cancelled" ? "Command cancelled from workspace UI." : null
5062
+ })
5063
+ }
5064
+ );
4919
5065
  await sendRunnerHeartbeat(
4920
5066
  configService,
4921
5067
  apiKey,
@@ -4927,7 +5073,14 @@ $ ${session.command}
4927
5073
  }
4928
5074
  }
4929
5075
  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) => {
5076
+ program2.command("runner").description("Run a paired worker that executes queued web task runs").option(
5077
+ "--agent <command>",
5078
+ "Agent command to launch for claimed tasks",
5079
+ "copilot"
5080
+ ).option("--poll-interval <seconds>", "Polling interval in seconds", "10").option("--once", "Claim at most one run and then exit").option(
5081
+ "--unsafe",
5082
+ "Disable Docker sandbox (run agent directly on host \u2014 no isolation)"
5083
+ ).action(async (options, command) => {
4931
5084
  const configService = new ConfigService();
4932
5085
  const apiKey = await ensureAuthenticated(configService);
4933
5086
  const projectId = await configService.getProjectId();
@@ -4953,7 +5106,11 @@ function registerRunnerCommands(program2) {
4953
5106
  )
4954
5107
  );
4955
5108
  if (!useSandbox) {
4956
- console.log(chalk13.yellow(" \u26A0 Running in unsafe mode \u2014 agent has full host access."));
5109
+ console.log(
5110
+ chalk13.yellow(
5111
+ " \u26A0 Running in unsafe mode \u2014 agent has full host access."
5112
+ )
5113
+ );
4957
5114
  }
4958
5115
  let shouldStop = false;
4959
5116
  let consecutiveErrors = 0;
@@ -4966,7 +5123,11 @@ function registerRunnerCommands(program2) {
4966
5123
  const claimBackend = useSandbox ? "local_sandbox" : "local_runner";
4967
5124
  while (!shouldStop) {
4968
5125
  try {
4969
- const capabilities = getRunnerCapabilities(agent, useSandbox, agentPinned);
5126
+ const capabilities = getRunnerCapabilities(
5127
+ agent,
5128
+ useSandbox,
5129
+ agentPinned
5130
+ );
4970
5131
  await sendRunnerHeartbeat(
4971
5132
  configService,
4972
5133
  apiKey,
@@ -4990,7 +5151,9 @@ function registerRunnerCommands(program2) {
4990
5151
  );
4991
5152
  if (!claimResponse.ok) {
4992
5153
  const data = await claimResponse.json().catch(() => ({}));
4993
- throw new Error(data.error || "Failed to claim task run");
5154
+ throw new Error(
5155
+ data.error || "Failed to claim task run"
5156
+ );
4994
5157
  }
4995
5158
  const payload = await claimResponse.json();
4996
5159
  if (payload.run) {
@@ -5028,7 +5191,9 @@ function registerRunnerCommands(program2) {
5028
5191
  );
5029
5192
  if (!terminalClaimResponse.ok) {
5030
5193
  const data = await terminalClaimResponse.json().catch(() => ({}));
5031
- throw new Error(data.error || "Failed to claim terminal session");
5194
+ throw new Error(
5195
+ data.error || "Failed to claim terminal session"
5196
+ );
5032
5197
  }
5033
5198
  const terminalPayload = await terminalClaimResponse.json();
5034
5199
  if (terminalPayload.session) {
@@ -6467,14 +6632,16 @@ Snapshot Contents:`));
6467
6632
  console.log(chalk17.gray("Context updated."));
6468
6633
  }
6469
6634
  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
- );
6635
+ await syncParsedTaskUpdatesToRemote(
6636
+ configService,
6637
+ update,
6638
+ result
6639
+ ).catch((err) => {
6640
+ console.error(
6641
+ chalk17.yellow("[vem finalize] syncParsed failed:"),
6642
+ err instanceof Error ? err.message : String(err)
6643
+ );
6644
+ });
6478
6645
  const synced = await syncProjectMemoryToRemote().catch(() => false);
6479
6646
  if (synced) {
6480
6647
  console.log(chalk17.gray("\u2714 Synced to cloud."));
@@ -7084,7 +7251,14 @@ function registerTaskCommands(program2) {
7084
7251
  const tasks = await getDisplayTasks({ includeDeleted: true });
7085
7252
  const status = typeof options.status === "string" ? options.status : void 0;
7086
7253
  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"]);
7254
+ const validStatuses = /* @__PURE__ */ new Set([
7255
+ "todo",
7256
+ "ready",
7257
+ "in-review",
7258
+ "in-progress",
7259
+ "blocked",
7260
+ "done"
7261
+ ]);
7088
7262
  if (status && !validStatuses.has(status)) {
7089
7263
  console.error(
7090
7264
  chalk18.red(
@@ -7450,7 +7624,10 @@ ${currentSummary}
7450
7624
  ).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
7625
  "--validation <steps>",
7452
7626
  '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) => {
7627
+ ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option(
7628
+ "--impact-score <score>",
7629
+ "Impact score 0-100 (RICE-based priority)"
7630
+ ).option("--actor <name>", "Actor name for task creation").option("-r, --reasoning <reasoning>", "Reasoning for creation").action(async (title, options) => {
7454
7631
  await trackCommandUsage("task add");
7455
7632
  try {
7456
7633
  let taskTitle = typeof title === "string" && title.trim().length > 0 ? title.trim() : void 0;
@@ -7797,7 +7974,9 @@ ${currentSummary}
7797
7974
  const dueAt = parseDueAtIso(dueAtInput);
7798
7975
  const normalizedType = typeInput?.trim().toLowerCase();
7799
7976
  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.");
7977
+ throw new Error(
7978
+ "type must be feature, bug, chore, spike, or enabler."
7979
+ );
7801
7980
  }
7802
7981
  const taskType = normalizedType === "feature" || normalizedType === "bug" || normalizedType === "chore" || normalizedType === "spike" || normalizedType === "enabler" ? normalizedType : void 0;
7803
7982
  let validationSteps = parseCommaList(validationInput);
@@ -7924,7 +8103,10 @@ ${currentSummary}
7924
8103
  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
8104
  "--validation <steps>",
7926
8105
  "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) => {
8106
+ ).option("--cycle <id>", "Assign to a cycle (e.g. CYCLE-001)").option(
8107
+ "--impact-score <score>",
8108
+ "Impact score 0-100 (RICE-based priority)"
8109
+ ).option("--actor <name>", "Actor name for task update").option("-r, --reasoning <reasoning>", "Reasoning for update").action(async (id, options) => {
7928
8110
  try {
7929
8111
  const estimate = options.estimateHours !== void 0 ? Number.parseFloat(options.estimateHours) : void 0;
7930
8112
  if (estimate !== void 0 && Number.isNaN(estimate)) {
@@ -8565,8 +8747,12 @@ No agent sessions attached to ${id} yet.`)
8565
8747
  console.log(chalk18.bold(`
8566
8748
  \u23F1 Flow Metrics: ${id} \u2014 ${task.title}
8567
8749
  `));
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)}`);
8750
+ console.log(
8751
+ ` ${chalk18.gray("Lead time (created \u2192 done):")} ${fmtMs(metrics.lead_time_ms)}`
8752
+ );
8753
+ console.log(
8754
+ ` ${chalk18.gray("Cycle time (started \u2192 done):")} ${fmtMs(metrics.cycle_time_ms)}`
8755
+ );
8570
8756
  if (Object.keys(metrics.time_in_status).length > 0) {
8571
8757
  console.log(chalk18.gray("\n Time in each status:"));
8572
8758
  for (const [status, ms] of Object.entries(metrics.time_in_status)) {
@@ -8584,15 +8770,27 @@ No agent sessions attached to ${id} yet.`)
8584
8770
  return chalk18.white(`${hrs}h`);
8585
8771
  };
8586
8772
  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)}`);
8773
+ console.log(
8774
+ ` ${chalk18.gray("WIP (active tasks):")} ${chalk18.yellow(String(summary.wip_count))}`
8775
+ );
8776
+ console.log(
8777
+ ` ${chalk18.gray("Throughput (last 7d):")} ${chalk18.white(String(summary.throughput_last_7d))} tasks`
8778
+ );
8779
+ console.log(
8780
+ ` ${chalk18.gray("Throughput (last 30d):")} ${chalk18.white(String(summary.throughput_last_30d))} tasks`
8781
+ );
8782
+ console.log(
8783
+ ` ${chalk18.gray("Avg cycle time:")} ${fmtMs(summary.avg_cycle_time_ms)}`
8784
+ );
8785
+ console.log(
8786
+ ` ${chalk18.gray("Avg lead time:")} ${fmtMs(summary.avg_lead_time_ms)}`
8787
+ );
8592
8788
  console.log();
8593
8789
  }
8594
8790
  } catch (error) {
8595
- console.error(chalk18.red(`Failed to get flow metrics: ${error.message}`));
8791
+ console.error(
8792
+ chalk18.red(`Failed to get flow metrics: ${error.message}`)
8793
+ );
8596
8794
  }
8597
8795
  });
8598
8796
  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 +8802,9 @@ No agent sessions attached to ${id} yet.`)
8604
8802
  (t) => t.impact_score === void 0 && t.status !== "done" && !t.deleted_at
8605
8803
  );
8606
8804
  if (unscored.length === 0) {
8607
- console.log(chalk18.green("\n\u2714 All active tasks have impact scores.\n"));
8805
+ console.log(
8806
+ chalk18.green("\n\u2714 All active tasks have impact scores.\n")
8807
+ );
8608
8808
  return;
8609
8809
  }
8610
8810
  const table = new Table4({
@@ -8622,9 +8822,13 @@ No agent sessions attached to ${id} yet.`)
8622
8822
  }
8623
8823
  console.log(chalk18.bold("\n\u{1F3AF} Impact Scores\n"));
8624
8824
  console.log(table.toString());
8625
- console.log(chalk18.gray(`
8825
+ console.log(
8826
+ chalk18.gray(
8827
+ `
8626
8828
  Unscored: ${unscored.length} task(s). Use: vem task score <id> --set <0-100>
8627
- `));
8829
+ `
8830
+ )
8831
+ );
8628
8832
  return;
8629
8833
  }
8630
8834
  const task = await taskService.getTask(id);
@@ -8635,7 +8839,9 @@ No agent sessions attached to ${id} yet.`)
8635
8839
  if (options.set !== void 0) {
8636
8840
  const score = Number.parseFloat(options.set);
8637
8841
  if (Number.isNaN(score) || score < 0 || score > 100) {
8638
- console.error(chalk18.red("Score must be a number between 0 and 100."));
8842
+ console.error(
8843
+ chalk18.red("Score must be a number between 0 and 100.")
8844
+ );
8639
8845
  process.exitCode = 1;
8640
8846
  return;
8641
8847
  }
@@ -8643,15 +8849,21 @@ No agent sessions attached to ${id} yet.`)
8643
8849
  impact_score: score,
8644
8850
  reasoning: options.reasoning
8645
8851
  });
8646
- console.log(chalk18.green(`
8852
+ console.log(
8853
+ chalk18.green(`
8647
8854
  \u2714 Impact score for ${id} set to ${score}
8648
- `));
8855
+ `)
8856
+ );
8649
8857
  } else {
8650
8858
  console.log(chalk18.bold(`
8651
8859
  \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
- `));
8860
+ console.log(
8861
+ ` Impact score: ${task.impact_score !== void 0 ? chalk18.yellow(String(Math.round(task.impact_score))) : chalk18.gray("not set")}`
8862
+ );
8863
+ console.log(
8864
+ chalk18.gray(` Set with: vem task score ${id} --set <0-100>
8865
+ `)
8866
+ );
8655
8867
  }
8656
8868
  } catch (error) {
8657
8869
  console.error(chalk18.red(`Failed to manage score: ${error.message}`));
@@ -8744,11 +8956,11 @@ async function initServerMonitoring(config) {
8744
8956
  await initServerMonitoring({
8745
8957
  dsn: "https://ed007f2c213d0aa07c1be256ca51750c@o4510863861612544.ingest.de.sentry.io/4510863921774672",
8746
8958
  environment: process.env.NODE_ENV || "production",
8747
- release: "0.1.53",
8959
+ release: "0.1.54",
8748
8960
  serviceName: "cli"
8749
8961
  });
8750
8962
  var program = new Command();
8751
- program.name("vem").description("vem Project Memory CLI").version("0.1.53").addHelpText(
8963
+ program.name("vem").description("vem Project Memory CLI").version("0.1.54").addHelpText(
8752
8964
  "after",
8753
8965
  `
8754
8966
  ${chalk19.bold("\n\u26A1 Power Workflows:")}