@rallycry/conveyor-agent 4.10.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -272,6 +272,10 @@ var ConveyorConnection = class _ConveyorConnection {
272
272
  if (!this.socket) return;
273
273
  this.socket.emit("agentRunner:statusUpdate", { status });
274
274
  }
275
+ emitAuthToken(token) {
276
+ if (!this.socket) return;
277
+ this.socket.emit("agentRunner:authToken", { token });
278
+ }
275
279
  emitRateLimitPause(resetsAt) {
276
280
  if (!this.socket) return;
277
281
  this.socket.emit("agentRunner:rateLimitPause", { resetsAt });
@@ -560,6 +564,18 @@ async function loadForwardPorts(workspaceDir) {
560
564
  }
561
565
  }
562
566
  async function loadConveyorConfig(workspaceDir) {
567
+ const envSetup = process.env.CONVEYOR_SETUP_COMMAND;
568
+ const envStart = process.env.CONVEYOR_START_COMMAND;
569
+ const envPort = process.env.CONVEYOR_PREVIEW_PORT;
570
+ const envAuth = process.env.CONVEYOR_AUTH_TOKEN_COMMAND;
571
+ if (envSetup || envStart || envAuth) {
572
+ return {
573
+ setupCommand: envSetup,
574
+ startCommand: envStart,
575
+ previewPort: envPort ? Number(envPort) : void 0,
576
+ authTokenCommand: envAuth
577
+ };
578
+ }
563
579
  try {
564
580
  const raw = await readFile(join2(workspaceDir, CONVEYOR_CONFIG_PATH), "utf-8");
565
581
  const parsed = JSON.parse(raw);
@@ -570,7 +586,7 @@ async function loadConveyorConfig(workspaceDir) {
570
586
  }
571
587
 
572
588
  // src/setup/commands.ts
573
- import { spawn } from "child_process";
589
+ import { spawn, execSync as execSync2 } from "child_process";
574
590
  function runSetupCommand(cmd, cwd, onOutput) {
575
591
  return new Promise((resolve2, reject) => {
576
592
  const child = spawn("sh", ["-c", cmd], {
@@ -596,6 +612,21 @@ function runSetupCommand(cmd, cwd, onOutput) {
596
612
  });
597
613
  });
598
614
  }
615
+ var AUTH_TOKEN_TIMEOUT_MS = 3e4;
616
+ function runAuthTokenCommand(cmd, userEmail, cwd) {
617
+ try {
618
+ const output = execSync2(`${cmd} ${JSON.stringify(userEmail)}`, {
619
+ cwd,
620
+ timeout: AUTH_TOKEN_TIMEOUT_MS,
621
+ stdio: ["ignore", "pipe", "ignore"],
622
+ env: { ...process.env }
623
+ });
624
+ const token = output.toString().trim();
625
+ return token || null;
626
+ } catch {
627
+ return null;
628
+ }
629
+ }
599
630
  function runStartCommand(cmd, cwd, onOutput) {
600
631
  const child = spawn("sh", ["-c", cmd], {
601
632
  cwd,
@@ -614,17 +645,17 @@ function runStartCommand(cmd, cwd, onOutput) {
614
645
  }
615
646
 
616
647
  // src/setup/codespace.ts
617
- import { execSync as execSync2 } from "child_process";
648
+ import { execSync as execSync3 } from "child_process";
618
649
  function initRtk() {
619
650
  try {
620
- execSync2("rtk --version", { stdio: "ignore" });
621
- execSync2("rtk init --global --auto-patch", { stdio: "ignore" });
651
+ execSync3("rtk --version", { stdio: "ignore" });
652
+ execSync3("rtk init --global --auto-patch", { stdio: "ignore" });
622
653
  } catch {
623
654
  }
624
655
  }
625
656
  function unshallowRepo(workspaceDir) {
626
657
  try {
627
- execSync2("git fetch --unshallow", {
658
+ execSync3("git fetch --unshallow", {
628
659
  cwd: workspaceDir,
629
660
  stdio: "ignore",
630
661
  timeout: 6e4
@@ -633,9 +664,36 @@ function unshallowRepo(workspaceDir) {
633
664
  }
634
665
  }
635
666
 
667
+ // src/utils/logger.ts
668
+ import winston from "winston";
669
+ var { combine, timestamp, printf, colorize } = winston.format;
670
+ var customFormat = printf(({ level, message, timestamp: ts, service, ...meta }) => {
671
+ const svc = service ? `[${service}] ` : "";
672
+ const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : "";
673
+ return `${ts} [${level}]: ${svc}${message}${metaStr}`;
674
+ });
675
+ var logger = winston.createLogger({
676
+ level: process.env.LOG_LEVEL ?? "info",
677
+ format: combine(timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), combine(colorize(), customFormat)),
678
+ transports: [new winston.transports.Console()]
679
+ });
680
+ function createServiceLogger(serviceName) {
681
+ return logger.child({ service: serviceName });
682
+ }
683
+ function errorMeta(error) {
684
+ if (error instanceof Error) {
685
+ return {
686
+ message: error.message,
687
+ stack: error.stack,
688
+ ..."code" in error && typeof error.code === "string" ? { code: error.code } : {}
689
+ };
690
+ }
691
+ return { message: String(error) };
692
+ }
693
+
636
694
  // src/runner/agent-runner.ts
637
695
  import { randomUUID as randomUUID2 } from "crypto";
638
- import { execSync as execSync3 } from "child_process";
696
+ import { execSync as execSync4 } from "child_process";
639
697
 
640
698
  // src/execution/event-processor.ts
641
699
  function epochSecondsToISO(value) {
@@ -2820,6 +2878,74 @@ async function executeSetupConfig(config, runnerConfig, connection, setupLog, ef
2820
2878
  }
2821
2879
  return deferredStartConfig;
2822
2880
  }
2881
+ async function checkoutTaskBranch(runnerConfig, connection, callbacks, setupLog) {
2882
+ const taskBranch = process.env.CONVEYOR_TASK_BRANCH;
2883
+ if (!taskBranch) return true;
2884
+ pushSetupLog(setupLog, `[conveyor] Switching to task branch ${taskBranch}...`);
2885
+ connection.sendEvent({
2886
+ type: "setup_output",
2887
+ stream: "stdout",
2888
+ data: `Switching to task branch ${taskBranch}...
2889
+ `
2890
+ });
2891
+ try {
2892
+ await runSetupCommand(
2893
+ `git fetch origin ${taskBranch} && git checkout ${taskBranch}`,
2894
+ runnerConfig.workspaceDir,
2895
+ (stream, data) => {
2896
+ connection.sendEvent({ type: "setup_output", stream, data });
2897
+ for (const line of data.split("\n").filter(Boolean)) {
2898
+ pushSetupLog(setupLog, `[${stream}] ${line}`);
2899
+ }
2900
+ }
2901
+ );
2902
+ pushSetupLog(setupLog, `[conveyor] Switched to ${taskBranch}`);
2903
+ return true;
2904
+ } catch (error) {
2905
+ const message = `Failed to checkout ${taskBranch}: ${error instanceof Error ? error.message : "unknown error"}`;
2906
+ connection.sendEvent({ type: "setup_error", message });
2907
+ await callbacks.onEvent({ type: "setup_error", message });
2908
+ connection.postChatMessage(`Failed to switch to task branch \`${taskBranch}\`.
2909
+
2910
+ ${message}`);
2911
+ return false;
2912
+ }
2913
+ }
2914
+ async function rebasePullBranch(runnerConfig, connection, callbacks, setupLog) {
2915
+ const pullBranch = process.env.CONVEYOR_PULL_BRANCH;
2916
+ if (!pullBranch) return true;
2917
+ pushSetupLog(setupLog, `[conveyor] Rebasing onto latest ${pullBranch}...`);
2918
+ connection.sendEvent({
2919
+ type: "setup_output",
2920
+ stream: "stdout",
2921
+ data: `Rebasing onto latest ${pullBranch}...
2922
+ `
2923
+ });
2924
+ try {
2925
+ await runSetupCommand(
2926
+ `git fetch origin ${pullBranch} && git rebase origin/${pullBranch}`,
2927
+ runnerConfig.workspaceDir,
2928
+ (stream, data) => {
2929
+ connection.sendEvent({ type: "setup_output", stream, data });
2930
+ for (const line of data.split("\n").filter(Boolean)) {
2931
+ pushSetupLog(setupLog, `[${stream}] ${line}`);
2932
+ }
2933
+ }
2934
+ );
2935
+ pushSetupLog(setupLog, `[conveyor] Rebase complete`);
2936
+ return true;
2937
+ } catch (error) {
2938
+ const message = `Failed to rebase onto ${pullBranch}: ${error instanceof Error ? error.message : "unknown error"}`;
2939
+ connection.sendEvent({ type: "setup_error", message });
2940
+ await callbacks.onEvent({ type: "setup_error", message });
2941
+ connection.postChatMessage(
2942
+ `Failed to rebase onto latest \`${pullBranch}\`. There may be conflicts between the task branch and dev.
2943
+
2944
+ ${message}`
2945
+ );
2946
+ return false;
2947
+ }
2948
+ }
2823
2949
  async function runSetupSafe(runnerConfig, connection, callbacks, setupLog, effectiveAgentMode, setState) {
2824
2950
  await setState("setup");
2825
2951
  const ports = await loadForwardPorts(runnerConfig.workspaceDir);
@@ -2831,18 +2957,24 @@ async function runSetupSafe(runnerConfig, connection, callbacks, setupLog, effec
2831
2957
  () => void 0
2832
2958
  );
2833
2959
  }
2834
- const pullBranch = process.env.CONVEYOR_PULL_BRANCH;
2835
- if (pullBranch) {
2836
- pushSetupLog(setupLog, `[conveyor] Merging latest from ${pullBranch}...`);
2960
+ if (!await checkoutTaskBranch(runnerConfig, connection, callbacks, setupLog)) {
2961
+ return { ok: false, deferredStartConfig: null };
2962
+ }
2963
+ if (!await rebasePullBranch(runnerConfig, connection, callbacks, setupLog)) {
2964
+ return { ok: false, deferredStartConfig: null };
2965
+ }
2966
+ const taskBranch = process.env.CONVEYOR_TASK_BRANCH;
2967
+ if (taskBranch) {
2968
+ pushSetupLog(setupLog, `[conveyor] Switching to task branch ${taskBranch}...`);
2837
2969
  connection.sendEvent({
2838
2970
  type: "setup_output",
2839
2971
  stream: "stdout",
2840
- data: `Merging latest from ${pullBranch}...
2972
+ data: `Switching to task branch ${taskBranch}...
2841
2973
  `
2842
2974
  });
2843
2975
  try {
2844
2976
  await runSetupCommand(
2845
- `git fetch origin ${pullBranch} && git merge origin/${pullBranch} --no-edit`,
2977
+ `git fetch origin ${taskBranch} && git checkout ${taskBranch}`,
2846
2978
  runnerConfig.workspaceDir,
2847
2979
  (stream, data) => {
2848
2980
  connection.sendEvent({ type: "setup_output", stream, data });
@@ -2851,13 +2983,13 @@ async function runSetupSafe(runnerConfig, connection, callbacks, setupLog, effec
2851
2983
  }
2852
2984
  }
2853
2985
  );
2854
- pushSetupLog(setupLog, `[conveyor] Merge complete`);
2986
+ pushSetupLog(setupLog, `[conveyor] Switched to ${taskBranch}`);
2855
2987
  } catch (error) {
2856
- const message = `Failed to merge ${pullBranch}: ${error instanceof Error ? error.message : "unknown error"}`;
2988
+ const message = `Failed to checkout ${taskBranch}: ${error instanceof Error ? error.message : "unknown error"}`;
2857
2989
  connection.sendEvent({ type: "setup_error", message });
2858
2990
  await callbacks.onEvent({ type: "setup_error", message });
2859
2991
  connection.postChatMessage(
2860
- `Failed to merge latest code from \`${pullBranch}\`. There may be conflicts between the prebuild branch and dev.
2992
+ `Failed to switch to task branch \`${taskBranch}\`.
2861
2993
 
2862
2994
  ${message}`
2863
2995
  );
@@ -2897,6 +3029,17 @@ The agent cannot start until this is resolved.`
2897
3029
  return { ok: false, deferredStartConfig: null };
2898
3030
  }
2899
3031
  }
3032
+ function runAuthTokenSafe(config, connection, taskContext) {
3033
+ const authCmd = process.env.CONVEYOR_AUTH_TOKEN_COMMAND;
3034
+ if (!authCmd || !taskContext.userEmail) return;
3035
+ try {
3036
+ const token = runAuthTokenCommand(authCmd, taskContext.userEmail, config.workspaceDir);
3037
+ if (token) {
3038
+ connection.emitAuthToken(token);
3039
+ }
3040
+ } catch {
3041
+ }
3042
+ }
2900
3043
  function runDeferredStartCommand(deferredStartConfig, runnerConfig, connection, setupLog) {
2901
3044
  if (!deferredStartConfig?.startCommand) return;
2902
3045
  pushSetupLog(setupLog, `$ ${deferredStartConfig.startCommand} & (background, deferred)`);
@@ -3022,6 +3165,7 @@ function buildQueryHost(deps) {
3022
3165
  }
3023
3166
 
3024
3167
  // src/runner/agent-runner.ts
3168
+ var logger2 = createServiceLogger("AgentRunner");
3025
3169
  var HEARTBEAT_INTERVAL_MS = 3e4;
3026
3170
  var IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
3027
3171
  var AgentRunner = class {
@@ -3125,6 +3269,9 @@ var AgentRunner = class {
3125
3269
  initRtk();
3126
3270
  this.tryInitWorktree();
3127
3271
  if (!await this.fetchAndInitContext()) return;
3272
+ if (process.env.CODESPACES === "true" && this.taskContext) {
3273
+ runAuthTokenSafe(this.config, this.connection, this.taskContext);
3274
+ }
3128
3275
  this.tryPostContextWorktree();
3129
3276
  this.checkoutWorktreeBranch();
3130
3277
  await this.executeInitialMode();
@@ -3181,7 +3328,7 @@ var AgentRunner = class {
3181
3328
  if (!this.worktreeActive || !this.taskContext?.githubBranch) return;
3182
3329
  try {
3183
3330
  const branch = this.taskContext.githubBranch;
3184
- execSync3(`git fetch origin ${branch} && git checkout ${branch}`, {
3331
+ execSync4(`git fetch origin ${branch} && git checkout ${branch}`, {
3185
3332
  cwd: this.config.workspaceDir,
3186
3333
  stdio: "ignore"
3187
3334
  });
@@ -3200,8 +3347,10 @@ var AgentRunner = class {
3200
3347
  "Auto-nudge: Task is still In Progress with no PR. Prompting agent to continue..."
3201
3348
  );
3202
3349
  await this.setState("running");
3350
+ const ctx = this.taskContext ?? fresh;
3351
+ if (!ctx) return false;
3203
3352
  await this.runQuerySafe(
3204
- this.taskContext,
3353
+ ctx,
3205
3354
  "You are in Auto mode and your task is still In Progress with no pull request. You MUST create a pull request before finishing. Use the create_pull_request tool now to open a PR for your changes. If you are blocked, explain what is preventing you from creating a PR."
3206
3355
  );
3207
3356
  return true;
@@ -3291,7 +3440,12 @@ var AgentRunner = class {
3291
3440
  handleRunStartCommand() {
3292
3441
  if (!this.deferredStartConfig?.startCommand || this.startCommandStarted) return;
3293
3442
  this.startCommandStarted = true;
3294
- runDeferredStartCommand(this.deferredStartConfig, this.config, this.connection, this.setupLog);
3443
+ runDeferredStartCommand(
3444
+ this.deferredStartConfig,
3445
+ this.config,
3446
+ this.connection,
3447
+ this.setupLog
3448
+ );
3295
3449
  this.deferredStartConfig = null;
3296
3450
  }
3297
3451
  logEffectiveSettings() {
@@ -3299,18 +3453,17 @@ var AgentRunner = class {
3299
3453
  const s = this.taskContext.agentSettings ?? this.config.agentSettings ?? {};
3300
3454
  const model = this.taskContext.model || this.config.model;
3301
3455
  const thinking = formatThinkingSetting(s.thinking);
3302
- const parts = [
3303
- `model=${model}`,
3304
- `mode=${this.config.mode ?? "task"}`,
3305
- `effort=${s.effort ?? "default"}`,
3306
- `thinking=${thinking}`,
3307
- `maxBudget=$${s.maxBudgetUsd ?? 50}`,
3308
- `maxTurns=${s.maxTurns ?? "unlimited"}`
3309
- ];
3310
- if (s.betas?.length) parts.push(`betas=${s.betas.join(",")}`);
3311
- if (s.disallowedTools?.length) parts.push(`disallowed=[${s.disallowedTools.join(",")}]`);
3312
- if (s.enableFileCheckpointing) parts.push(`checkpointing=on`);
3313
- console.log(`[conveyor-agent] ${parts.join(", ")}`);
3456
+ logger2.info("Effective agent settings", {
3457
+ model,
3458
+ mode: this.config.mode ?? "task",
3459
+ effort: s.effort ?? "default",
3460
+ thinking,
3461
+ maxBudget: s.maxBudgetUsd ?? 50,
3462
+ maxTurns: s.maxTurns ?? "unlimited",
3463
+ ...s.betas?.length ? { betas: s.betas } : {},
3464
+ ...s.disallowedTools?.length ? { disallowedTools: s.disallowedTools } : {},
3465
+ ...s.enableFileCheckpointing ? { checkpointing: "on" } : {}
3466
+ });
3314
3467
  }
3315
3468
  injectHumanMessage(content, files) {
3316
3469
  const messageContent = buildMessageContent(content, files);
@@ -3341,9 +3494,9 @@ var AgentRunner = class {
3341
3494
  this.idleTimer = setTimeout(() => {
3342
3495
  this.clearIdleTimers();
3343
3496
  this.inputResolver = null;
3344
- console.log(
3345
- `[conveyor-agent] Idle for ${IDLE_TIMEOUT_MS / 6e4} minutes \u2014 shutting down.`
3346
- );
3497
+ logger2.info("Idle timeout reached, shutting down", {
3498
+ idleMinutes: IDLE_TIMEOUT_MS / 6e4
3499
+ });
3347
3500
  this.connection.postChatMessage(
3348
3501
  `Agent idle for ${IDLE_TIMEOUT_MS / 6e4} minutes with no new messages \u2014 shutting down.`
3349
3502
  );
@@ -3458,12 +3611,13 @@ var AgentRunner = class {
3458
3611
 
3459
3612
  // src/runner/project-runner.ts
3460
3613
  import { fork } from "child_process";
3461
- import { execSync as execSync4 } from "child_process";
3614
+ import { execSync as execSync5 } from "child_process";
3462
3615
  import * as path from "path";
3463
3616
  import { fileURLToPath } from "url";
3464
3617
 
3465
3618
  // src/runner/project-chat-handler.ts
3466
3619
  import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
3620
+ var logger3 = createServiceLogger("ProjectChat");
3467
3621
  var FALLBACK_MODEL = "claude-sonnet-4-20250514";
3468
3622
  function buildSystemPrompt2(projectDir, agentCtx) {
3469
3623
  const parts = [];
@@ -3516,7 +3670,7 @@ function processContentBlock(block, responseParts, turnToolCalls) {
3516
3670
  input: inputStr.slice(0, 1e4),
3517
3671
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
3518
3672
  });
3519
- console.log(`[project-chat] [tool_use] ${block.name}`);
3673
+ logger3.debug("Tool use", { tool: block.name });
3520
3674
  }
3521
3675
  }
3522
3676
  async function fetchContext(connection) {
@@ -3524,13 +3678,13 @@ async function fetchContext(connection) {
3524
3678
  try {
3525
3679
  agentCtx = await connection.fetchAgentContext();
3526
3680
  } catch {
3527
- console.log("[project-chat] Could not fetch agent context, using defaults");
3681
+ logger3.warn("Could not fetch agent context, using defaults");
3528
3682
  }
3529
3683
  let chatHistory = [];
3530
3684
  try {
3531
3685
  chatHistory = await connection.fetchChatHistory(30);
3532
3686
  } catch {
3533
- console.log("[project-chat] Could not fetch chat history, proceeding without it");
3687
+ logger3.warn("Could not fetch chat history, proceeding without it");
3534
3688
  }
3535
3689
  return { agentCtx, chatHistory };
3536
3690
  }
@@ -3604,10 +3758,7 @@ async function handleProjectChatMessage(message, connection, projectDir) {
3604
3758
  try {
3605
3759
  await runChatQuery(message, connection, projectDir);
3606
3760
  } catch (error) {
3607
- console.error(
3608
- "[project-chat] Failed to handle message:",
3609
- error instanceof Error ? error.message : error
3610
- );
3761
+ logger3.error("Failed to handle message", errorMeta(error));
3611
3762
  try {
3612
3763
  await connection.emitChatMessage(
3613
3764
  "I encountered an error processing your message. Please try again."
@@ -3620,6 +3771,7 @@ async function handleProjectChatMessage(message, connection, projectDir) {
3620
3771
  }
3621
3772
 
3622
3773
  // src/runner/project-runner.ts
3774
+ var logger4 = createServiceLogger("ProjectRunner");
3623
3775
  var __filename = fileURLToPath(import.meta.url);
3624
3776
  var __dirname = path.dirname(__filename);
3625
3777
  var HEARTBEAT_INTERVAL_MS2 = 3e4;
@@ -3637,12 +3789,12 @@ function setupWorkDir(projectDir, assignment) {
3637
3789
  }
3638
3790
  if (branch && branch !== devBranch) {
3639
3791
  try {
3640
- execSync4(`git checkout ${branch}`, { cwd: workDir, stdio: "ignore" });
3792
+ execSync5(`git checkout ${branch}`, { cwd: workDir, stdio: "ignore" });
3641
3793
  } catch {
3642
3794
  try {
3643
- execSync4(`git checkout -b ${branch}`, { cwd: workDir, stdio: "ignore" });
3795
+ execSync5(`git checkout -b ${branch}`, { cwd: workDir, stdio: "ignore" });
3644
3796
  } catch {
3645
- console.log(`[task:${shortId}] Warning: could not checkout branch ${branch}`);
3797
+ logger4.warn("Could not checkout branch", { taskId: shortId, branch });
3646
3798
  }
3647
3799
  }
3648
3800
  }
@@ -3680,13 +3832,13 @@ function spawnChildAgent(assignment, workDir) {
3680
3832
  child.stdout?.on("data", (data) => {
3681
3833
  const lines = data.toString().trimEnd().split("\n");
3682
3834
  for (const line of lines) {
3683
- console.log(`[task:${shortId}] ${line}`);
3835
+ logger4.info(line, { taskId: shortId });
3684
3836
  }
3685
3837
  });
3686
3838
  child.stderr?.on("data", (data) => {
3687
3839
  const lines = data.toString().trimEnd().split("\n");
3688
3840
  for (const line of lines) {
3689
- console.error(`[task:${shortId}] ${line}`);
3841
+ logger4.error(line, { taskId: shortId });
3690
3842
  }
3691
3843
  });
3692
3844
  return child;
@@ -3715,17 +3867,17 @@ var ProjectRunner = class {
3715
3867
  this.handleStopTask(data.taskId);
3716
3868
  });
3717
3869
  this.connection.onShutdown(() => {
3718
- console.log("[project-runner] Received shutdown signal from server");
3870
+ logger4.info("Received shutdown signal from server");
3719
3871
  void this.stop();
3720
3872
  });
3721
3873
  this.connection.onChatMessage((msg) => {
3722
- console.log("[project-runner] Received project chat message");
3874
+ logger4.debug("Received project chat message");
3723
3875
  void handleProjectChatMessage(msg, this.connection, this.projectDir);
3724
3876
  });
3725
3877
  this.heartbeatTimer = setInterval(() => {
3726
3878
  this.connection.sendHeartbeat();
3727
3879
  }, HEARTBEAT_INTERVAL_MS2);
3728
- console.log("[project-runner] Connected, waiting for task assignments...");
3880
+ logger4.info("Connected, waiting for task assignments");
3729
3881
  await new Promise((resolve2) => {
3730
3882
  this.resolveLifecycle = resolve2;
3731
3883
  process.on("SIGTERM", () => void this.stop());
@@ -3736,21 +3888,22 @@ var ProjectRunner = class {
3736
3888
  const { taskId, mode } = assignment;
3737
3889
  const shortId = taskId.slice(0, 8);
3738
3890
  if (this.activeAgents.has(taskId)) {
3739
- console.log(`[project-runner] Task ${shortId} already running, skipping`);
3891
+ logger4.info("Task already running, skipping", { taskId: shortId });
3740
3892
  return;
3741
3893
  }
3742
3894
  if (this.activeAgents.size >= MAX_CONCURRENT) {
3743
- console.log(
3744
- `[project-runner] Max concurrent agents (${MAX_CONCURRENT}) reached, rejecting task ${shortId}`
3745
- );
3895
+ logger4.warn("Max concurrent agents reached, rejecting task", {
3896
+ maxConcurrent: MAX_CONCURRENT,
3897
+ taskId: shortId
3898
+ });
3746
3899
  this.connection.emitTaskStopped(taskId, "max_concurrent_reached");
3747
3900
  return;
3748
3901
  }
3749
3902
  try {
3750
3903
  try {
3751
- execSync4("git fetch origin", { cwd: this.projectDir, stdio: "ignore" });
3904
+ execSync5("git fetch origin", { cwd: this.projectDir, stdio: "ignore" });
3752
3905
  } catch {
3753
- console.log(`[task:${shortId}] Warning: git fetch failed`);
3906
+ logger4.warn("Git fetch failed", { taskId: shortId });
3754
3907
  }
3755
3908
  const { workDir, usesWorktree } = setupWorkDir(this.projectDir, assignment);
3756
3909
  const child = spawnChildAgent(assignment, workDir);
@@ -3761,12 +3914,12 @@ var ProjectRunner = class {
3761
3914
  usesWorktree
3762
3915
  });
3763
3916
  this.connection.emitTaskStarted(taskId);
3764
- console.log(`[project-runner] Started task ${shortId} in ${mode} mode at ${workDir}`);
3917
+ logger4.info("Started task", { taskId: shortId, mode, workDir });
3765
3918
  child.on("exit", (code) => {
3766
3919
  this.activeAgents.delete(taskId);
3767
3920
  const reason = code === 0 ? "completed" : `exited with code ${code}`;
3768
3921
  this.connection.emitTaskStopped(taskId, reason);
3769
- console.log(`[project-runner] Task ${shortId} ${reason}`);
3922
+ logger4.info("Task exited", { taskId: shortId, reason });
3770
3923
  if (code === 0 && usesWorktree) {
3771
3924
  try {
3772
3925
  removeWorktree(this.projectDir, taskId);
@@ -3775,10 +3928,10 @@ var ProjectRunner = class {
3775
3928
  }
3776
3929
  });
3777
3930
  } catch (error) {
3778
- console.error(
3779
- `[project-runner] Failed to start task ${shortId}:`,
3780
- error instanceof Error ? error.message : error
3781
- );
3931
+ logger4.error("Failed to start task", {
3932
+ taskId: shortId,
3933
+ ...errorMeta(error)
3934
+ });
3782
3935
  this.connection.emitTaskStopped(
3783
3936
  taskId,
3784
3937
  `start_failed: ${error instanceof Error ? error.message : "Unknown"}`
@@ -3789,7 +3942,7 @@ var ProjectRunner = class {
3789
3942
  const agent = this.activeAgents.get(taskId);
3790
3943
  if (!agent) return;
3791
3944
  const shortId = taskId.slice(0, 8);
3792
- console.log(`[project-runner] Stopping task ${shortId}`);
3945
+ logger4.info("Stopping task", { taskId: shortId });
3793
3946
  agent.process.kill("SIGTERM");
3794
3947
  const timer = setTimeout(() => {
3795
3948
  if (this.activeAgents.has(taskId)) {
@@ -3809,7 +3962,7 @@ var ProjectRunner = class {
3809
3962
  async stop() {
3810
3963
  if (this.stopping) return;
3811
3964
  this.stopping = true;
3812
- console.log("[project-runner] Shutting down...");
3965
+ logger4.info("Shutting down");
3813
3966
  if (this.heartbeatTimer) {
3814
3967
  clearInterval(this.heartbeatTimer);
3815
3968
  this.heartbeatTimer = null;
@@ -3834,7 +3987,7 @@ var ProjectRunner = class {
3834
3987
  })
3835
3988
  ]);
3836
3989
  this.connection.disconnect();
3837
- console.log("[project-runner] Shutdown complete");
3990
+ logger4.info("Shutdown complete");
3838
3991
  if (this.resolveLifecycle) {
3839
3992
  this.resolveLifecycle();
3840
3993
  this.resolveLifecycle = null;
@@ -3914,8 +4067,10 @@ export {
3914
4067
  loadConveyorConfig,
3915
4068
  runSetupCommand,
3916
4069
  runStartCommand,
4070
+ createServiceLogger,
4071
+ errorMeta,
3917
4072
  AgentRunner,
3918
4073
  ProjectRunner,
3919
4074
  FileCache
3920
4075
  };
3921
- //# sourceMappingURL=chunk-XRB3VPXH.js.map
4076
+ //# sourceMappingURL=chunk-DODEEME6.js.map