@rallycry/conveyor-agent 10.5.0 → 10.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2308,6 +2308,9 @@ var SpawnTaskSessionRequestSchema = z.object({
2308
2308
  taskId: z.string(),
2309
2309
  kind: z.enum(["tui", "shell"])
2310
2310
  });
2311
+ var SpawnTaskReviewRequestSchema = z.object({
2312
+ taskId: z.string()
2313
+ });
2311
2314
  var ReportSessionSpawnFailureRequestSchema = z.object({
2312
2315
  sessionId: z.string(),
2313
2316
  spawnedSessionId: z.string(),
@@ -2705,12 +2708,6 @@ var TASK_CHAT_HISTORY_LIMIT = 20;
2705
2708
  var PM_CHAT_HISTORY_LIMIT = 40;
2706
2709
  var AGENT_CHAT_HISTORY_FETCH_LIMIT = Math.max(TASK_CHAT_HISTORY_LIMIT, PM_CHAT_HISTORY_LIMIT) + 10;
2707
2710
  var PRE_BUILD_TASK_STATUSES = /* @__PURE__ */ new Set(["Planning", "Open"]);
2708
- function hasTaskPlan(plan) {
2709
- return !!plan?.trim();
2710
- }
2711
- function taskNeedsPlanning(task) {
2712
- return !hasTaskPlan(task.plan) && PRE_BUILD_TASK_STATUSES.has(task.status) && !task.githubPRUrl;
2713
- }
2714
2711
 
2715
2712
  // src/runner/mode-controller.ts
2716
2713
  var ModeController = class {
@@ -2797,28 +2794,19 @@ var ModeController = class {
2797
2794
  return this._mode;
2798
2795
  }
2799
2796
  /**
2800
- * An auto task that still NEEDS PLANNING (no plan saved, pre-build status, no
2801
- * PR see `taskNeedsPlanning` in @project/shared) runs the read-only plan turn
2802
- * first (`--permission-mode plan`): resolveInitialMode leaves it in `auto` with
2803
- * `_hasExitedPlanMode = false`, and once the agent finishes it calls
2804
- * ExitPlanMode building. Everything else bypasses planning and builds
2805
- * immediately with `--dangerously-skip-permissions`:
2806
- *
2807
- * - a plan already on the card (e.g. a Planning card planned by a human/PM),
2808
- * - a build already underway (status past `Planning`/`Open` — releases booted
2809
- * `InProgress`, pod restarts mid-build where DB `agentMode` stays `"auto"`),
2810
- * - a PR already open (safety net if status lags).
2811
- *
2812
- * Runtime Build-after-Discovery never reaches this gate as `auto` — the server's
2813
- * `resolveModeToSend` rewrites it to `"building"` for any task with a plan.
2797
+ * Auto mode always bypasses the plan turn: resolveInitialMode calls
2798
+ * transitionToBuilding() at boot, so the agent runs with
2799
+ * `--dangerously-skip-permissions` from turn 1 and documents its plan into
2800
+ * the card (via update_task_plan) as the approach firms up — non-blocking,
2801
+ * never a gate. Use discovery mode for a plan turn that stops for human
2802
+ * approval. Non-auto modes never bypass.
2814
2803
  */
2815
- canBypassPlanning(context) {
2816
- if (this._mode !== "auto") return false;
2817
- return !taskNeedsPlanning(context);
2804
+ canBypassPlanning(_context) {
2805
+ return this._mode === "auto";
2818
2806
  }
2819
2807
  // ── Mode transitions ───────────────────────────────────────────────
2820
2808
  /** Handle mode change from server */
2821
- handleModeChange(newMode, context) {
2809
+ handleModeChange(newMode, _context) {
2822
2810
  if (newMode === this._mode) return { type: "noop" };
2823
2811
  if (this._runnerMode === "task" && newMode === "review") {
2824
2812
  this._mode = newMode;
@@ -2833,7 +2821,7 @@ var ModeController = class {
2833
2821
  if (this._runnerMode === "task" && newMode === "auto") {
2834
2822
  this._mode = newMode;
2835
2823
  this._isAuto = true;
2836
- this._hasExitedPlanMode = !context || !taskNeedsPlanning(context);
2824
+ this._hasExitedPlanMode = true;
2837
2825
  return { type: "restart_query", newMode: "auto" };
2838
2826
  }
2839
2827
  if (this._mode === "auto" && this._hasExitedPlanMode && newMode === "building") {
@@ -4132,11 +4120,16 @@ async function readRaw(path4) {
4132
4120
  }
4133
4121
  }
4134
4122
  async function ensureClaudeCredentials(env = process.env) {
4123
+ const isCloud = isConveyorCloudEnv(env);
4124
+ const token = env.CLAUDE_CODE_OAUTH_TOKEN;
4125
+ if (isCloud && token) {
4126
+ await sanitizeApprovedApiKeys(token);
4127
+ }
4135
4128
  try {
4136
4129
  const path4 = claudeCredentialsPath();
4137
4130
  const plan = planCredentialsWrite({
4138
- isCloud: isConveyorCloudEnv(env),
4139
- token: env.CLAUDE_CODE_OAUTH_TOKEN,
4131
+ isCloud,
4132
+ token,
4140
4133
  existingRaw: await readRaw(path4),
4141
4134
  now: Date.now()
4142
4135
  });
@@ -4151,6 +4144,40 @@ async function ensureClaudeCredentials(env = process.env) {
4151
4144
  `);
4152
4145
  }
4153
4146
  }
4147
+ function apiKeyApprovalSuffix(token) {
4148
+ return token.slice(-20);
4149
+ }
4150
+ function planApprovedApiKeyCleanup(existingRaw, oauthToken) {
4151
+ if (!oauthToken) return null;
4152
+ const config = parseClaudeJson(existingRaw);
4153
+ const responses = config.customApiKeyResponses;
4154
+ if (typeof responses !== "object" || responses === null || Array.isArray(responses)) {
4155
+ return null;
4156
+ }
4157
+ const record = responses;
4158
+ const approved = record.approved;
4159
+ if (!Array.isArray(approved)) return null;
4160
+ const suffix = apiKeyApprovalSuffix(oauthToken);
4161
+ const filtered = approved.filter((entry) => entry !== suffix);
4162
+ if (filtered.length === approved.length) return null;
4163
+ record.approved = filtered;
4164
+ return JSON.stringify(config);
4165
+ }
4166
+ async function sanitizeApprovedApiKeys(oauthToken) {
4167
+ try {
4168
+ const path4 = claudeJsonPath();
4169
+ const cleaned = planApprovedApiKeyCleanup(await readRaw(path4), oauthToken);
4170
+ if (cleaned === null) return;
4171
+ await writeFile4(path4, cleaned, "utf8");
4172
+ process.stderr.write(
4173
+ "[conveyor-agent] removed poisoned customApiKeyResponses.approved entry from .claude.json\n"
4174
+ );
4175
+ } catch (err) {
4176
+ const message = err instanceof Error ? err.message : String(err);
4177
+ process.stderr.write(`[conveyor-agent] claude approved-key sanitize failed: ${message}
4178
+ `);
4179
+ }
4180
+ }
4154
4181
  function claudeJsonPath() {
4155
4182
  const configDir = process.env.CLAUDE_CONFIG_DIR;
4156
4183
  return configDir ? join3(configDir, ".claude.json") : join3(homedir2(), ".claude.json");
@@ -4270,7 +4297,10 @@ function resolvePlanDialogTiming() {
4270
4297
  return {
4271
4298
  firstPressMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_FIRST_PRESS_MS", PLAN_DIALOG_FIRST_PRESS_MS),
4272
4299
  intervalMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_INTERVAL_MS", PLAN_DIALOG_INTERVAL_MS),
4273
- slowIntervalMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_SLOW_INTERVAL_MS", PLAN_DIALOG_SLOW_INTERVAL_MS),
4300
+ slowIntervalMs: envMs(
4301
+ "CONVEYOR_PTY_PLAN_DIALOG_SLOW_INTERVAL_MS",
4302
+ PLAN_DIALOG_SLOW_INTERVAL_MS
4303
+ ),
4274
4304
  fastWindowMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_FAST_WINDOW_MS", PLAN_DIALOG_FAST_WINDOW_MS),
4275
4305
  windowMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_WINDOW_MS", PLAN_DIALOG_WINDOW_MS)
4276
4306
  };
@@ -4304,6 +4334,9 @@ function inheritedEnv(socketPath) {
4304
4334
  for (const [key, value] of Object.entries(process.env)) {
4305
4335
  if (typeof value === "string") env[key] = value;
4306
4336
  }
4337
+ if (env.CLAUDE_CODE_OAUTH_TOKEN) {
4338
+ delete env.ANTHROPIC_API_KEY;
4339
+ }
4307
4340
  if (socketPath) {
4308
4341
  env.CONVEYOR_HOOK_SOCKET = socketPath;
4309
4342
  }
@@ -5230,6 +5263,7 @@ function buildPackRunnerSystemPrompt(context, config, setupLog) {
5230
5263
  ``,
5231
5264
  `1. Call list_subtasks to see the current state of all child tasks.`,
5232
5265
  ` The response includes PR info, agent assignment, and **dependency info** (dependencies array + allDependenciesMet flag).`,
5266
+ ` If list_subtasks returns NO children, this is a fresh parent card: break the work down now \u2014 explore the codebase, save a parent-level plan with update_task_plan, then create child tasks with create_subtask, each with a detailed plan (file:line citations, verification steps) and dependsOn set for any child that blocks on another. Then fire the ready children and continue the loop.`,
5233
5267
  ``,
5234
5268
  `2. Evaluate children by status and dependency readiness:`,
5235
5269
  ` - "ReviewPR": Review and merge its PR with approve_and_merge_pr. (Highest priority)`,
@@ -5292,6 +5326,7 @@ function buildPackRunnerInstructions(context, scenario) {
5292
5326
  parts.push(
5293
5327
  `You are the Pack Runner for this task and its subtasks.`,
5294
5328
  `Begin your autonomous loop immediately: call list_subtasks to assess the current state.`,
5329
+ `If there are no children yet, create them first \u2014 save a parent-level plan with update_task_plan, then create child tasks with detailed plans and dependsOn set where one blocks on another. Then fire the ready ones.`,
5295
5330
  `If any child is in "ReviewPR" status, review and merge its PR first.`,
5296
5331
  `Then fire the next "Open" child task.`
5297
5332
  );
@@ -5726,15 +5761,15 @@ function buildPmAutoWithPlanRelaunchParts() {
5726
5761
  return [
5727
5762
  `
5728
5763
  You are in auto mode. A plan already exists for this task.`,
5729
- `Verify that story points, title, and tags are set via get_current_plan, then call ExitPlanMode immediately to transition to building.`,
5764
+ `Begin implementing it now \u2014 refine story points, title, and tags via update_task_properties if they look like placeholders.`,
5730
5765
  `Do NOT wait for team input \u2014 proceed autonomously.`
5731
5766
  ];
5732
5767
  }
5733
5768
  function buildPmAutoPlanningRelaunchParts() {
5734
5769
  return [
5735
5770
  `
5736
- You are in auto mode. Continue planning autonomously.`,
5737
- `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,
5771
+ You are in auto mode. Continue building autonomously.`,
5772
+ `Save a concise plan with update_task_plan as your approach firms up \u2014 never pause or wait for approval.`,
5738
5773
  `Do NOT wait for team input \u2014 proceed autonomously.`
5739
5774
  ];
5740
5775
  }
@@ -5810,6 +5845,20 @@ function buildPropertyInstructions(context, runnerMode) {
5810
5845
  }
5811
5846
  return parts;
5812
5847
  }
5848
+ function buildPlanDocumentationSection(context) {
5849
+ const hasPlan = !!context?.plan?.trim();
5850
+ return [
5851
+ ``,
5852
+ `### Plan & Properties (non-blocking \u2014 do NOT pause the build for these)`,
5853
+ `- The card is already In Progress and advances automatically (In Progress \u2192 Review PR when you open the PR). There is no plan-approval step.`,
5854
+ ...hasPlan ? [
5855
+ `- A plan is already saved on the card. Keep it current with update_task_plan if your approach diverges materially from it.`
5856
+ ] : [
5857
+ `- No plan is saved yet: once your approach settles, save a concise implementation plan with update_task_plan (file:line citations). Fill it in as you go \u2014 never wait on it before writing code.`
5858
+ ],
5859
+ `- Identification auto-fills title, story points, and icon with quick AI guesses. After exploring, refine the title and story points with update_task_properties if they look like placeholders. Icons are automatic \u2014 never set them.`
5860
+ ];
5861
+ }
5813
5862
  function buildExplorationMethodology() {
5814
5863
  return [
5815
5864
  ``,
@@ -5909,23 +5958,10 @@ function buildAutoPrompt(context, runnerMode) {
5909
5958
  const parts = [
5910
5959
  `
5911
5960
  ## Mode: Auto`,
5912
- `You are in Auto mode \u2014 operating autonomously through planning \u2192 building \u2192 PR.`,
5913
- ``,
5914
- `### Phase 1: Discovery & Planning (current)`,
5915
- `- You are in the SDK's plan mode \u2014 read-only access is enforced automatically`,
5916
- `- You have MCP tools for task properties: update_task_plan, update_task_properties`,
5917
- ``,
5918
- `### Required before transitioning:`,
5919
- `Before calling ExitPlanMode, you MUST fill in ALL of these:`,
5920
- `1. **Plan** \u2014 Save a clear implementation plan using update_task_plan`,
5921
- `2. **Story Points** \u2014 Assign via update_task_properties`,
5922
- `3. **Title** \u2014 Set an accurate title via update_task_properties (if the current one is vague or "Untitled")`,
5923
- ``,
5924
- `### Transitioning to Building:`,
5925
- `When your plan is complete and all required properties are set, call the **ExitPlanMode** tool.`,
5926
- `- If any required properties are missing, ExitPlanMode will be denied with details on what's missing`,
5927
- `- Once ExitPlanMode succeeds, you will seamlessly transition to full build access within the same session`,
5928
- `- Continue directly with implementation \u2014 no restart or waiting is needed`,
5961
+ `You are in Auto mode \u2014 operating autonomously through building \u2192 PR.`,
5962
+ `- You have full coding access (read, write, edit, bash, git) from the start \u2014 there is no read-only planning phase`,
5963
+ `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,
5964
+ ...buildPlanDocumentationSection(context),
5929
5965
  ``,
5930
5966
  `### Subtask Plan Requirements`,
5931
5967
  `When creating subtasks, each MUST include a detailed \`plan\` field:`,
@@ -5941,8 +5977,8 @@ function buildAutoPrompt(context, runnerMode) {
5941
5977
  ...context?.isParentTask ? [
5942
5978
  ``,
5943
5979
  `### Parent Task Guidance`,
5944
- `You are a parent task. Your plan should define child tasks with detailed plans, not direct implementation steps.`,
5945
- `After ExitPlanMode, you'll transition to Review mode to coordinate child task execution.`,
5980
+ `You are a parent task \u2014 coordinate child tasks instead of implementing directly.`,
5981
+ `If no children exist yet, break the work down now: save a parent-level plan with update_task_plan, then create child tasks with create_subtask (each with a detailed plan).`,
5946
5982
  `Child task status lifecycle: Open \u2192 InProgress \u2192 ReviewPR \u2192 ReviewDev \u2192 Complete.`,
5947
5983
  `Set child ordering with \`dependsOn\` (sibling ids/slugs) on \`create_subtask\` \u2014 explicit metadata the pack runner schedules off, not order described in plan text. Independent children get none and run in parallel.`
5948
5984
  ] : [],
@@ -5980,7 +6016,8 @@ function buildModePrompt(agentMode, context, runnerMode) {
5980
6016
  `2. \`bun run test:affected\` \u2014 runs only the tests your diff can affect (docs-only diffs run nothing; apps/api diffs run unit tests only since CI covers the int shards; shared/db diffs escalate to the full suite automatically)`,
5981
6017
  `Docs/markdown/.claude-only changes need NO local gates \u2014 open the PR and let CI validate.`,
5982
6018
  `If a gate fails, fix it before opening the PR. Do NOT open PRs with known failing gates. Never run the full \`bun run test\` for a diff confined to one package.`,
5983
- `For refactors: also run \`git diff ${context?.baseBranch ?? "dev"}..HEAD\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`
6019
+ `For refactors: also run \`git diff ${context?.baseBranch ?? "dev"}..HEAD\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`,
6020
+ ...context?.isAuto || !context?.plan?.trim() ? buildPlanDocumentationSection(context) : []
5984
6021
  ]
5985
6022
  ];
5986
6023
  return parts.join("\n");
@@ -6377,16 +6414,15 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
6377
6414
  if (context.plan?.trim()) {
6378
6415
  return [
6379
6416
  `You are operating autonomously. A plan already exists for this task.`,
6380
- `Verify that story points, title, and tags are set, then call ExitPlanMode immediately to transition to building.`,
6381
- `Do NOT re-plan or wait for team input \u2014 proceed autonomously.`
6417
+ `Begin implementing it now \u2014 do NOT re-plan or wait for team input.`,
6418
+ `Refine story points, title, and tags via update_task_properties if they look like placeholders.`
6382
6419
  ];
6383
6420
  }
6384
6421
  return [
6385
- `You are operating autonomously. Begin planning immediately.`,
6422
+ `You are operating autonomously. No plan is saved on this card yet \u2014 start building now.`,
6386
6423
  `1. Search the codebase (grep/glob) to locate relevant files, then read the critical ones`,
6387
- `2. Draft a clear implementation plan and save it with update_task_plan`,
6388
- `3. Set story points, tags, and title (update_task_properties)`,
6389
- `4. When the plan and all required properties are set, call ExitPlanMode to transition to building`,
6424
+ `2. Implement the work; as your approach firms up, save a concise plan with update_task_plan \u2014 never pause or wait for approval`,
6425
+ `3. Refine story points, tags, and title (update_task_properties) if they look like placeholders`,
6390
6426
  `Do NOT wait for team input \u2014 proceed autonomously.`
6391
6427
  ];
6392
6428
  }
@@ -6407,14 +6443,23 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
6407
6443
  `When you finish planning, save the plan with update_task_plan, post a summary of the plan for the team with post_to_chat (your turn output is NOT shown in chat), then end your turn. A separate task agent will execute the plan after review.`
6408
6444
  ];
6409
6445
  }
6410
- const parts = [
6446
+ return buildFreshLeafInstructions(context, isAutoMode);
6447
+ }
6448
+ function buildFreshLeafInstructions(context, isAutoMode) {
6449
+ const parts = context.plan?.trim() ? [
6411
6450
  `Begin executing the task plan above immediately.`,
6412
- `Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first \u2014 the environment is already set up.`,
6451
+ `Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first \u2014 the environment is already set up.`
6452
+ ] : [
6453
+ `No plan is saved on this card yet. Investigate the task briefly (search first, read only critical files), then implement.`,
6454
+ `As your approach firms up, save a concise implementation plan with update_task_plan (file:line citations) \u2014 do NOT pause or wait for approval; the card is already In Progress and advances automatically.`,
6455
+ `Do NOT run install, build, lint, test, or dev server commands first \u2014 the environment is already set up.`
6456
+ ];
6457
+ parts.push(
6413
6458
  `Work on the git branch "${context.githubBranch}". Stay on this branch for the entire task. Do not checkout or create other branches.`,
6414
6459
  `Use post_to_chat to keep the team informed (your turn output is NOT shown in chat \u2014 post_to_chat is the only way they see it): briefly post what you're doing when you begin meaningful implementation, and again when the PR is ready.`,
6415
6460
  `Before opening the PR, verify with \`bun run check\` (lint + typecheck) and \`bun run test:affected\` (tests scoped to your diff \u2014 docs-only changes need no local gates). Fix any failures. Do NOT open a PR with known failing gates. CI runs the full suite on the PR \u2014 never run the full \`bun run test\` for a diff confined to one package.`,
6416
6461
  `When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`
6417
- ];
6462
+ );
6418
6463
  if (isAutoMode) {
6419
6464
  parts.push(
6420
6465
  `
@@ -6463,8 +6508,7 @@ Your plan has been approved. Address the feedback above, then begin implementing
6463
6508
  } else if (isAuto) {
6464
6509
  parts2.push(
6465
6510
  `
6466
- You are in auto mode. Address the feedback above \u2014 update the plan accordingly using update_task_plan.`,
6467
- `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,
6511
+ You are in auto mode. Address the feedback above and continue building \u2014 update the saved plan with update_task_plan if the feedback changes your approach.`,
6468
6512
  `Do NOT wait for additional team input \u2014 the messages above ARE the team's input. Proceed autonomously.`
6469
6513
  );
6470
6514
  } else {
@@ -6503,13 +6547,13 @@ function buildIdleRelaunchInstructions(context, isPm, agentMode, isAuto) {
6503
6547
  if (context.plan?.trim()) {
6504
6548
  return [
6505
6549
  `You were relaunched in auto mode. A plan already exists for this task.`,
6506
- `Verify that story points, title, and tags are set, then call ExitPlanMode immediately to transition to building.`,
6550
+ `Begin implementing it now \u2014 refine story points, title, and tags via update_task_properties if they look like placeholders.`,
6507
6551
  `Do NOT wait for instructions or go idle \u2014 you are in auto mode.`
6508
6552
  ];
6509
6553
  }
6510
6554
  return [
6511
- `You were relaunched in auto mode. Continue planning autonomously.`,
6512
- `When the plan and all required properties are set, call ExitPlanMode to transition to building.`,
6555
+ `You were relaunched in auto mode. Continue building autonomously.`,
6556
+ `Save a concise plan with update_task_plan as your approach firms up \u2014 never pause or wait for approval.`,
6513
6557
  `Do NOT wait for instructions or go idle \u2014 you are in auto mode.`
6514
6558
  ];
6515
6559
  }
@@ -6549,7 +6593,13 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
6549
6593
  const isCodeReview = mode === "code-review" || !isPm && agentMode === "review";
6550
6594
  if (scenario === "fresh") {
6551
6595
  parts.push(
6552
- ...buildFreshInstructions(isPm, isCodeReview, agentMode === "auto", context, agentMode)
6596
+ ...buildFreshInstructions(
6597
+ isPm,
6598
+ isCodeReview,
6599
+ agentMode === "auto" || !!isAuto,
6600
+ context,
6601
+ agentMode
6602
+ )
6553
6603
  );
6554
6604
  return parts;
6555
6605
  }
@@ -7423,7 +7473,7 @@ var DEPENDS_ON_DESCRIPTION = "Sibling subtask ids or slugs this subtask blocks o
7423
7473
  function buildUpdateTaskTool(connection) {
7424
7474
  return defineTool(
7425
7475
  "update_task_plan",
7426
- "Save the finalized plan and/or description to the current task. Use in Plan mode after alignment. For children use update_subtask; for title/tags/PR use update_task_properties.",
7476
+ "Save the plan and/or description to the current task. In auto/building mode, save the plan as your approach firms up \u2014 non-blocking, never pause the build for it. For children use update_subtask; for title/tags/PR use update_task_properties.",
7427
7477
  {
7428
7478
  plan: z9.string().optional().describe("The task plan in markdown"),
7429
7479
  description: z9.string().optional().describe("Updated task description")
@@ -7778,7 +7828,7 @@ ${issueLines}`;
7778
7828
 
7779
7829
  // src/tools/index.ts
7780
7830
  function getTaskModeTools(agentMode, connection) {
7781
- if (agentMode === "discovery" || agentMode === "auto") {
7831
+ if (agentMode === "discovery" || agentMode === "auto" || agentMode === "building") {
7782
7832
  return [buildUpdateTaskTool(connection)];
7783
7833
  }
7784
7834
  return [];
@@ -7806,7 +7856,7 @@ function buildConveyorTools(connection, config, context, agentMode) {
7806
7856
  const effectiveMode = agentMode ?? context?.agentMode ?? void 0;
7807
7857
  const commonTools = buildCommonTools(connection, config);
7808
7858
  const modeTools = getModeTools(effectiveMode, connection, config, context);
7809
- const discoveryTools = effectiveMode === "discovery" || effectiveMode === "auto" ? buildDiscoveryTools(connection) : [];
7859
+ const discoveryTools = effectiveMode === "discovery" || effectiveMode === "auto" || effectiveMode === "building" ? buildDiscoveryTools(connection) : [];
7810
7860
  const codeReviewTools = effectiveMode === "review" ? buildCodeReviewTools(connection) : [];
7811
7861
  const emergencyTools = [buildForceUpdateTaskStatusTool(connection)];
7812
7862
  return [...commonTools, ...modeTools, ...discoveryTools, ...codeReviewTools, ...emergencyTools];
@@ -8756,9 +8806,10 @@ function buildQueryOptions(host, context) {
8756
8806
  // the same text via `--append-system-prompt`. PTY-only: the SDK harness
8757
8807
  // already receives it through systemPrompt.append.
8758
8808
  ...host.harnessKind === "pty" && systemPromptText ? { appendSystemPrompt: systemPromptText } : {},
8759
- // Auto mode pre-exit: after the ExitPlanMode hook allows the call, the
8760
- // CLI's plan dialog still renders press Enter so the autonomous agent
8761
- // continues building in the same session (Conveyor validated in the hook).
8809
+ // Auto mode pre-exit (residual sessions only auto now boots post-exit):
8810
+ // after the ExitPlanMode hook allows the call, the CLI's plan dialog still
8811
+ // renders press Enter so the autonomous agent continues building in the
8812
+ // same session (Conveyor validated in the hook).
8762
8813
  planDialogAutoAccept: mode === "auto" && !host.hasExitedPlanMode,
8763
8814
  tools: { type: "preset", preset: "claude_code" },
8764
8815
  mcpServers: {
@@ -10629,9 +10680,9 @@ var SessionRunner = class _SessionRunner {
10629
10680
  /** The build-phase nudge (In Progress, no PR). Offers BOTH escape routes so
10630
10681
  * the agent never just goes idle. */
10631
10682
  static STUCK_PROMPT = "You are in Auto mode, your task is still In Progress, and there is no open pull request. Do ONE of these right now: (1) open a pull request with the create_pull_request tool, OR (2) call post_to_chat to explain exactly where you are stuck and what you need from a human. Do not finish or go idle silently.";
10632
- /** The planning-phase nudge (still Planning, identification/plan unfinished).
10633
- * Same two-escape-route shape, aimed at finishing discovery instead of a PR. */
10634
- static STUCK_PROMPT_PLANNING = "You are in Auto mode and still in the Planning phase \u2014 identification and/or the plan are not finished. Do ONE of these right now: (1) finish identifying the task (set the story points) and save the plan with the update_task_plan tool, then call ExitPlanMode to begin building, OR (2) call post_to_chat to explain exactly where you are stuck and what you need from a human. Do not finish or go idle silently.";
10683
+ /** The pre-build nudge (still Planning/Open, identification/plan unfinished).
10684
+ * Same two-escape-route shape, aimed at landing the plan + continuing to build. */
10685
+ static STUCK_PROMPT_PLANNING = "You are in Auto mode and the card is still in a pre-build status \u2014 identification and/or the plan are not finished. Do ONE of these right now: (1) set the story points, save the plan with the update_task_plan tool, and continue implementing, OR (2) call post_to_chat to explain exactly where you are stuck and what you need from a human. Do not finish or go idle silently.";
10635
10686
  /**
10636
10687
  * Classify how an auto task is "stuck" after its turn ended (call sites run
10637
10688
  * post-turn, so the TUI is no longer working), or null if it isn't. Shared
@@ -10641,11 +10692,12 @@ var SessionRunner = class _SessionRunner {
10641
10692
  *
10642
10693
  * - "pr": In Progress with no open PR (build finished without shipping).
10643
10694
  * - "planning": still in a pre-build status (Planning/Open) without
10644
- * (identified + saved plan). A fresh auto agent that finishes its plan turn
10645
- * WITHOUT ExitPlanMode would otherwise idle clean-exit its session Ends
10646
- * the workspace is reaped "agent_gone" before a plan ever landed. Nudging
10647
- * (and, on exhaustion, going dormant) keeps the session Active so the pod
10648
- * is never prematurely slept.
10695
+ * (identified + saved plan) e.g. the server-side InProgress bump failed
10696
+ * and the agent idled before documenting its plan. An agent that idles
10697
+ * here would otherwise clean-exit its session Ends the workspace is
10698
+ * reaped "agent_gone" before a plan ever landed. Nudging (and, on
10699
+ * exhaustion, going dormant) keeps the session Active so the pod is never
10700
+ * prematurely slept.
10649
10701
  */
10650
10702
  autoStuckKind() {
10651
10703
  if (!this.mode.isAuto || this.stopped) return null;
@@ -11145,4 +11197,4 @@ export {
11145
11197
  runStartCommand,
11146
11198
  unshallowRepo
11147
11199
  };
11148
- //# sourceMappingURL=chunk-MSDYMAG3.js.map
11200
+ //# sourceMappingURL=chunk-5ELLQUP4.js.map