@rallycry/conveyor-agent 7.0.11 → 7.0.13

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.
@@ -484,7 +484,7 @@ var ModeController = class {
484
484
  }
485
485
  get isReadOnly() {
486
486
  const m = this.effectiveMode;
487
- if (["discovery", "code-review", "help"].includes(m)) return true;
487
+ if (["discovery", "help"].includes(m)) return true;
488
488
  return m === "auto" && !this._hasExitedPlanMode;
489
489
  }
490
490
  get isAutoPlanning() {
@@ -492,13 +492,13 @@ var ModeController = class {
492
492
  }
493
493
  get isBuildCapable() {
494
494
  const m = this.effectiveMode;
495
- return m === "building" || m === "auto" && this._hasExitedPlanMode;
495
+ return m === "building" || m === "review" || m === "auto" && this._hasExitedPlanMode;
496
496
  }
497
497
  // ── Mode resolution ────────────────────────────────────────────────
498
498
  /** Resolve the initial mode based on task context */
499
499
  resolveInitialMode(context) {
500
500
  if (this._runnerMode === "code-review") {
501
- this._mode = "code-review";
501
+ this._mode = "review";
502
502
  return this._mode;
503
503
  }
504
504
  if (this._mode === "auto" && this.canBypassPlanning(context)) {
@@ -517,8 +517,12 @@ var ModeController = class {
517
517
  // ── Mode transitions ───────────────────────────────────────────────
518
518
  /** Handle mode change from server */
519
519
  handleModeChange(newMode) {
520
- if (this._runnerMode !== "pm") return { type: "noop" };
521
520
  if (newMode === this._mode) return { type: "noop" };
521
+ if (this._runnerMode === "task" && newMode === "review") {
522
+ this._mode = newMode;
523
+ return { type: "restart_query", newMode: "review" };
524
+ }
525
+ if (this._runnerMode !== "pm") return { type: "noop" };
522
526
  this._mode = newMode;
523
527
  this.updateExitedPlanModeFlag(newMode);
524
528
  if (this.isBuildCapable) {
@@ -1367,7 +1371,7 @@ var RegisterProjectAgentResponseSchema = z.object({
1367
1371
  agentSettings: z.record(z.string(), z.unknown()).nullable(),
1368
1372
  branchSwitchCommand: z.string().nullable()
1369
1373
  });
1370
- var CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set(["ci_failure"]);
1374
+ var CRITICAL_AUTOMATED_SOURCES = /* @__PURE__ */ new Set(["ci_failure", "review_trigger"]);
1371
1375
 
1372
1376
  // src/execution/pack-runner-prompt.ts
1373
1377
  function findLastAgentMessageIndex(history) {
@@ -1794,8 +1798,8 @@ function buildAutoPrompt(context) {
1794
1798
  `### Transitioning to Building:`,
1795
1799
  `When your plan is complete and all required properties are set, call the **ExitPlanMode** tool.`,
1796
1800
  `- If any required properties are missing, ExitPlanMode will be denied with details on what's missing`,
1797
- `- Once ExitPlanMode succeeds, the system will automatically restart your session in Building mode with the appropriate model`,
1798
- `- You do NOT need to do anything after calling ExitPlanMode \u2014 the transition is handled for you`,
1801
+ `- Once ExitPlanMode succeeds, you will seamlessly transition to full build access within the same session`,
1802
+ `- Continue directly with implementation \u2014 no restart or waiting is needed`,
1799
1803
  ``,
1800
1804
  `### Subtask Plan Requirements`,
1801
1805
  `When creating subtasks, each MUST include a detailed \`plan\` field:`,
@@ -1859,8 +1863,6 @@ function buildModePrompt(agentMode, context) {
1859
1863
  return buildReviewPrompt(context);
1860
1864
  case "auto":
1861
1865
  return buildAutoPrompt(context);
1862
- case "code-review":
1863
- return buildCodeReviewPrompt();
1864
1866
  default:
1865
1867
  return null;
1866
1868
  }
@@ -1869,8 +1871,9 @@ function buildReviewPrompt(context) {
1869
1871
  const parts = [
1870
1872
  `
1871
1873
  ## Mode: Review`,
1872
- `You are in Review mode \u2014 reviewing and coordinating.`,
1873
- `- You have read-only access plus light edit capability (can suggest fixes, run tests, check linting)`,
1874
+ `You are in Review mode \u2014 performing code review with fix capability.`,
1875
+ `- You have full write access \u2014 you can audit code, make fixes, push changes, and run tests`,
1876
+ `- Safety rules: no destructive operations, use --force-with-lease instead of --force`,
1874
1877
  ``
1875
1878
  ];
1876
1879
  if (context?.isParentTask) {
@@ -1892,80 +1895,62 @@ function buildReviewPrompt(context) {
1892
1895
  );
1893
1896
  } else {
1894
1897
  parts.push(
1895
- `### Leaf Task Review`,
1896
- `You are reviewing your own work before completion.`,
1897
- `- Run tests and check linting to verify the PR is ready.`,
1898
- `- If the PR is already open, review the diff for correctness.`,
1899
- `- You can get hands dirty \u2014 if a fix is small, make it directly.`,
1900
- `- If follow-up work is needed, use \`create_follow_up_task\`.`
1898
+ `### Code Review Process`,
1899
+ `1. Run \`git diff <baseBranch>..HEAD\` to see all changes in this PR`,
1900
+ `2. Read the task plan to understand the intended changes`,
1901
+ `3. Explore the surrounding codebase to verify pattern consistency`,
1902
+ `4. Review against the criteria below`,
1903
+ ``,
1904
+ `### Review Criteria`,
1905
+ `- **Correctness**: Does the code do what the plan says? Logic errors, off-by-one, race conditions?`,
1906
+ `- **Pattern Consistency**: Does the code follow existing patterns in the codebase? Check nearby files.`,
1907
+ `- **Security**: No hardcoded secrets, no injection vulnerabilities, proper input validation at boundaries.`,
1908
+ `- **Performance**: No unnecessary loops, no N+1 queries, no blocking in async contexts.`,
1909
+ `- **Error Handling**: Appropriate error handling at system boundaries. No swallowed errors.`,
1910
+ `- **Test Coverage**: Are new code paths tested? Edge cases covered?`,
1911
+ `- **TypeScript Best Practices**: Proper typing (no unnecessary \`any\`), correct React patterns, proper async/await.`,
1912
+ `- **Naming & Readability**: Clear names, no misleading comments, self-documenting code.`,
1913
+ ``,
1914
+ `### Fix Capability`,
1915
+ `You have full write access. If you find issues:`,
1916
+ `- **Small fixes**: Make the fix directly, commit, and push. Then re-review.`,
1917
+ `- **Larger issues**: Use \`request_code_changes\` to flag them for the team.`,
1918
+ `- After pushing fixes, wait for CI to pass before approving.`,
1919
+ ``,
1920
+ `### Output \u2014 You MUST do exactly ONE of:`,
1921
+ ``,
1922
+ `#### If code passes review (or after you've fixed all issues):`,
1923
+ `Use the \`approve_code_review\` tool with a brief summary of what looks good.`,
1924
+ ``,
1925
+ `#### If changes are needed that you cannot fix:`,
1926
+ `Use the \`request_code_changes\` tool with specific issues:`,
1927
+ `- Reference specific files and line numbers`,
1928
+ `- Explain what's wrong and suggest fixes`,
1929
+ `- Focus on substantive issues, not style nitpicks (linting handles that)`,
1930
+ ``,
1931
+ `### Previous Review Feedback`,
1932
+ `If previous review feedback is present in the chat history, verify those specific issues were addressed before raising new concerns.`,
1933
+ ``,
1934
+ `### Rules`,
1935
+ `- Do NOT re-review things CI already validates (formatting, lint rules).`,
1936
+ `- Be concise \u2014 actionable specifics over general observations.`,
1937
+ `- Max 5-7 issues per review. Prioritize the most important ones.`
1901
1938
  );
1902
1939
  }
1903
- parts.push(
1904
- ``,
1905
- `### General Review Guidelines`,
1906
- `- For larger issues, create a follow-up task rather than fixing directly.`,
1907
- `- Focus on correctness, pattern consistency, and test coverage.`,
1908
- `- Be concise in feedback \u2014 actionable specifics over general observations.`,
1909
- `- Goal: ensure quality, provide feedback, coordinate progression.`
1910
- );
1911
1940
  if (process.env.CLAUDESPACE_NAME) {
1912
1941
  parts.push(
1913
1942
  ``,
1914
1943
  `### Resource Management`,
1915
- `Your pod starts with minimal resources (0.25 CPU / 1 Gi). You MUST call \`scale_up_resources\``,
1916
- `BEFORE running any of these operations \u2014 they WILL fail or OOM at baseline resources:`,
1917
- `- **light** (1 CPU / 4 Gi) \u2014 bun/npm/yarn install, pip install, basic dev servers, light builds`,
1918
- `- **standard** (2 CPU / 8 Gi) \u2014 full dev servers, test suites, typecheck, lint`,
1919
- `- **heavy** (4 CPU / 16 Gi) \u2014 E2E/browser automation, large parallel builds`,
1944
+ `Your pod starts with minimal resources. You MUST call \`scale_up_resources\``,
1945
+ `BEFORE running any resource-intensive operations \u2014 they WILL fail or OOM at baseline resources:`,
1946
+ `- **setup** \u2014 package installs, basic dev servers, light builds`,
1947
+ `- **build** \u2014 full dev servers, test suites, typecheck, lint, E2E tests`,
1920
1948
  `Scaling is one-way (up only) and capped by project limits.`,
1921
- `CRITICAL: Always scale to at least "light" before running any package install command.`
1949
+ `CRITICAL: Always scale to at least "setup" before running any package install command.`
1922
1950
  );
1923
1951
  }
1924
1952
  return parts.join("\n");
1925
1953
  }
1926
- function buildCodeReviewPrompt() {
1927
- return [
1928
- `
1929
- ## Mode: Code Review`,
1930
- `You are an automated code reviewer. A PR has passed all CI checks and you are performing a final code quality review before merge.`,
1931
- ``,
1932
- `## Review Process`,
1933
- `1. Run \`git diff <devBranch>..HEAD\` to see all changes in this PR`,
1934
- `2. Read the task plan to understand the intended changes`,
1935
- `3. Explore the surrounding codebase to verify pattern consistency`,
1936
- `4. Review against the criteria below`,
1937
- ``,
1938
- `### Review Criteria`,
1939
- `- **Correctness**: Does the code do what the plan says? Logic errors, off-by-one, race conditions?`,
1940
- `- **Pattern Consistency**: Does the code follow existing patterns in the codebase? Check nearby files.`,
1941
- `- **Security**: No hardcoded secrets, no injection vulnerabilities, proper input validation at boundaries.`,
1942
- `- **Performance**: No unnecessary loops, no N+1 queries, no blocking in async contexts.`,
1943
- `- **Error Handling**: Appropriate error handling at system boundaries. No swallowed errors.`,
1944
- `- **Test Coverage**: Are new code paths tested? Edge cases covered?`,
1945
- `- **TypeScript Best Practices**: Proper typing (no unnecessary \`any\`), correct React patterns, proper async/await.`,
1946
- `- **Naming & Readability**: Clear names, no misleading comments, self-documenting code.`,
1947
- ``,
1948
- `## Output \u2014 You MUST do exactly ONE of:`,
1949
- ``,
1950
- `### If code passes review:`,
1951
- `Use the \`approve_code_review\` tool with a brief summary of what looks good.`,
1952
- ``,
1953
- `### If changes are needed:`,
1954
- `Use the \`request_code_changes\` tool with specific issues:`,
1955
- `- Reference specific files and line numbers`,
1956
- `- Explain what's wrong and suggest fixes`,
1957
- `- Focus on substantive issues, not style nitpicks (linting handles that)`,
1958
- ``,
1959
- `## Previous Review Feedback`,
1960
- `If previous review feedback is present in the chat history, verify those specific issues were addressed before raising new concerns. Focus on whether the requested changes were implemented correctly.`,
1961
- ``,
1962
- `## Rules`,
1963
- `- You are READ-ONLY. Do NOT modify any files.`,
1964
- `- Do NOT re-review things CI already validates (formatting, lint rules).`,
1965
- `- Be concise \u2014 the task agent needs actionable feedback, not essays.`,
1966
- `- Max 5-7 issues per review. Prioritize the most important ones.`
1967
- ].join("\n");
1968
- }
1969
1954
 
1970
1955
  // src/execution/system-prompt.ts
1971
1956
  function formatProjectAgentLine(pa) {
@@ -2392,18 +2377,6 @@ ${context.plan}`);
2392
2377
  }
2393
2378
  return parts;
2394
2379
  }
2395
- function buildCodeReviewInstructions(context) {
2396
- const parts = [
2397
- `You are performing an automated code review for this task.`,
2398
- `The PR branch is "${context.githubBranch}"${context.baseBranch ? ` based on "${context.baseBranch}"` : ""}.`,
2399
- `Begin your code review by running \`git diff ${context.baseBranch ?? "dev"}..HEAD\` to see all changes.`,
2400
- ``,
2401
- `CRITICAL: You are in Code Review mode. You are READ-ONLY \u2014 do NOT modify any files.`,
2402
- `After reviewing, you MUST call exactly one of: \`approve_code_review\` or \`request_code_changes\`.`,
2403
- `Do NOT go idle, ask for confirmation, or wait for instructions \u2014 complete the review and exit.`
2404
- ];
2405
- return parts;
2406
- }
2407
2380
  function buildFreshInstructions(isPm, isAutoMode, context, agentMode) {
2408
2381
  if (isPm && agentMode === "building") {
2409
2382
  return [
@@ -2554,10 +2527,6 @@ function buildIdleRelaunchInstructions(context, isPm, agentMode, isAuto) {
2554
2527
  function buildInstructions(mode, context, scenario, agentMode, isAuto) {
2555
2528
  const parts = [`
2556
2529
  ## Instructions`];
2557
- if (agentMode === "code-review") {
2558
- parts.push(...buildCodeReviewInstructions(context));
2559
- return parts;
2560
- }
2561
2530
  const isPm = mode === "pm";
2562
2531
  if (scenario === "fresh") {
2563
2532
  parts.push(...buildFreshInstructions(isPm, agentMode === "auto", context, agentMode));
@@ -2572,7 +2541,7 @@ function buildInstructions(mode, context, scenario, agentMode, isAuto) {
2572
2541
  }
2573
2542
  async function buildInitialPrompt(mode, context, isAuto, agentMode) {
2574
2543
  const isPackRunner = mode === "pm" && !!isAuto && !!context.isParentTask;
2575
- if (!isPackRunner && agentMode !== "code-review") {
2544
+ if (!isPackRunner) {
2576
2545
  const sessionRelaunch = buildRelaunchWithSession(mode, context, agentMode, isAuto);
2577
2546
  if (sessionRelaunch) return sessionRelaunch;
2578
2547
  }
@@ -4839,23 +4808,20 @@ function getModeTools(agentMode, connection, config, context) {
4839
4808
  }
4840
4809
  function buildConveyorTools(connection, config, context, agentMode, debugManager) {
4841
4810
  const effectiveMode = agentMode ?? context?.agentMode ?? void 0;
4842
- if (effectiveMode === "code-review") {
4843
- return [
4844
- buildReadTaskChatTool(connection),
4845
- buildGetTaskPlanTool(connection),
4846
- buildGetTaskTool(connection),
4847
- buildGetTaskCliTool(connection),
4848
- buildListTaskFilesTool(connection),
4849
- buildGetTaskFileTool(connection),
4850
- ...buildCodeReviewTools(connection)
4851
- ];
4852
- }
4853
4811
  const commonTools = buildCommonTools(connection, config);
4854
4812
  const modeTools = getModeTools(effectiveMode, connection, config, context);
4855
4813
  const discoveryTools = effectiveMode === "discovery" || effectiveMode === "auto" ? buildDiscoveryTools(connection) : [];
4814
+ const codeReviewTools = effectiveMode === "review" ? buildCodeReviewTools(connection) : [];
4856
4815
  const emergencyTools = [buildForceUpdateTaskStatusTool(connection)];
4857
4816
  const debugTools = debugManager && effectiveMode === "building" ? buildDebugTools(debugManager) : [];
4858
- return [...commonTools, ...modeTools, ...discoveryTools, ...emergencyTools, ...debugTools];
4817
+ return [
4818
+ ...commonTools,
4819
+ ...modeTools,
4820
+ ...discoveryTools,
4821
+ ...codeReviewTools,
4822
+ ...emergencyTools,
4823
+ ...debugTools
4824
+ ];
4859
4825
  }
4860
4826
  function createConveyorMcpServer(harness, connection, config, context, agentMode, debugManager) {
4861
4827
  return harness.createMcpServer({
@@ -5274,7 +5240,6 @@ function collectMissingProps(taskProps) {
5274
5240
  // src/execution/tool-access.ts
5275
5241
  var PM_PLAN_FILE_TOOLS = /* @__PURE__ */ new Set(["Write", "Edit", "MultiEdit"]);
5276
5242
  var DESTRUCTIVE_CMD_PATTERN = /git\s+push\s+--force(?!\s*-with-lease)|git\s+reset\s+--hard|rm\s+-rf\s+\//;
5277
- var CODE_REVIEW_WRITE_CMD_PATTERN = /git\s+push|git\s+commit|git\s+add|rm\s+|mv\s+|cp\s+|mkdir\s+|touch\s+|chmod\s+|chown\s+/;
5278
5243
  var RESOURCE_HEAVY_PATTERNS = [
5279
5244
  /\bbun\s+(install|i|add)\b/,
5280
5245
  /\bnpm\s+(install|ci|i)\b/,
@@ -5311,48 +5276,12 @@ function handleBuildingToolAccess(toolName, input) {
5311
5276
  }
5312
5277
  return { behavior: "allow", updatedInput: input };
5313
5278
  }
5314
- function handleReviewToolAccess(toolName, input, isParentTask) {
5315
- if (isParentTask) {
5316
- return handleBuildingToolAccess(toolName, input);
5317
- }
5318
- if (PM_PLAN_FILE_TOOLS.has(toolName)) {
5319
- if (isPlanFile(input)) {
5320
- return { behavior: "allow", updatedInput: input };
5321
- }
5322
- return {
5323
- behavior: "deny",
5324
- message: "Review mode restricts file writes. Use bash to run tests and linting instead."
5325
- };
5326
- }
5327
- if (toolName === "Bash") {
5328
- const cmd = String(input.command ?? "");
5329
- if (DESTRUCTIVE_CMD_PATTERN.test(cmd)) {
5330
- return { behavior: "deny", message: "Destructive operation blocked in review mode." };
5331
- }
5332
- }
5333
- return { behavior: "allow", updatedInput: input };
5334
- }
5335
- function handleCodeReviewToolAccess(toolName, input) {
5336
- if (PM_PLAN_FILE_TOOLS.has(toolName)) {
5337
- return {
5338
- behavior: "deny",
5339
- message: "Code review mode is fully read-only. File writes are not permitted."
5340
- };
5341
- }
5342
- if (toolName === "Bash") {
5343
- const cmd = String(input.command ?? "");
5344
- if (DESTRUCTIVE_CMD_PATTERN.test(cmd) || CODE_REVIEW_WRITE_CMD_PATTERN.test(cmd)) {
5345
- return {
5346
- behavior: "deny",
5347
- message: "Code review mode is read-only. Write operations and destructive commands are blocked."
5348
- };
5349
- }
5350
- }
5351
- return { behavior: "allow", updatedInput: input };
5279
+ function handleReviewToolAccess(toolName, input) {
5280
+ return handleBuildingToolAccess(toolName, input);
5352
5281
  }
5353
5282
  function handleAutoToolAccess(toolName, input, hasExitedPlanMode, isParentTask) {
5354
5283
  if (hasExitedPlanMode) {
5355
- return isParentTask ? handleReviewToolAccess(toolName, input, true) : handleBuildingToolAccess(toolName, input);
5284
+ return isParentTask ? handleReviewToolAccess(toolName, input) : handleBuildingToolAccess(toolName, input);
5356
5285
  }
5357
5286
  return { behavior: "allow", updatedInput: input };
5358
5287
  }
@@ -5404,16 +5333,13 @@ async function handleExitPlanMode(host, input) {
5404
5333
  host.connection.postChatMessage(
5405
5334
  "Plan complete. Running identification \u2014 icon and agent assignment will be set automatically."
5406
5335
  );
5407
- host.requestSoftStop();
5408
5336
  return { behavior: "allow", updatedInput: input };
5409
5337
  }
5410
5338
  await host.connection.triggerIdentification();
5411
5339
  host.hasExitedPlanMode = true;
5412
5340
  const newMode = host.isParentTask ? "review" : "building";
5413
- host.pendingModeRestart = true;
5414
- if (host.onModeTransition) {
5415
- host.onModeTransition(newMode);
5416
- }
5341
+ host.connection.sendEvent({ type: "mode_transition", from: "auto", to: newMode });
5342
+ host.connection.emitModeChanged(newMode);
5417
5343
  return { behavior: "allow", updatedInput: input };
5418
5344
  } catch (err) {
5419
5345
  return {
@@ -5468,11 +5394,9 @@ function resolveToolAccess(host, toolName, input) {
5468
5394
  case "building":
5469
5395
  return handleBuildingToolAccess(toolName, input);
5470
5396
  case "review":
5471
- return handleReviewToolAccess(toolName, input, host.isParentTask);
5397
+ return handleReviewToolAccess(toolName, input);
5472
5398
  case "auto":
5473
5399
  return handleAutoToolAccess(toolName, input, host.hasExitedPlanMode, host.isParentTask);
5474
- case "code-review":
5475
- return handleCodeReviewToolAccess(toolName, input);
5476
5400
  default:
5477
5401
  return { behavior: "allow", updatedInput: input };
5478
5402
  }
@@ -5551,13 +5475,10 @@ function buildHooks(host) {
5551
5475
  };
5552
5476
  }
5553
5477
  function isReadOnlyMode(mode, hasExitedPlanMode) {
5554
- return mode === "discovery" || mode === "help" || mode === "code-review" || mode === "auto" && !hasExitedPlanMode;
5478
+ return mode === "discovery" || mode === "help" || mode === "auto" && !hasExitedPlanMode;
5555
5479
  }
5556
5480
  function buildDisallowedTools(settings, mode, hasExitedPlanMode) {
5557
5481
  const modeDisallowed = isReadOnlyMode(mode, hasExitedPlanMode) ? ["TodoWrite", "TodoRead", "NotebookEdit"] : [];
5558
- if (mode === "code-review") {
5559
- modeDisallowed.push("ExitPlanMode", "EnterPlanMode");
5560
- }
5561
5482
  const configured = settings.disallowedTools ?? [];
5562
5483
  const combined = [...configured, ...modeDisallowed];
5563
5484
  return combined.length > 0 ? combined : void 0;
@@ -5593,11 +5514,11 @@ function buildQueryOptions(host, context) {
5593
5514
  },
5594
5515
  sandbox: context.useSandbox ? { enabled: true } : { enabled: false },
5595
5516
  hooks: buildHooks(host),
5596
- maxTurns: mode === "code-review" ? Math.min(settings.maxTurns ?? 15, 15) : settings.maxTurns,
5517
+ maxTurns: settings.maxTurns,
5597
5518
  effort: settings.effort,
5598
5519
  thinking: settings.thinking,
5599
5520
  betas: settings.betas,
5600
- maxBudgetUsd: mode === "code-review" ? Math.min(settings.maxBudgetUsd ?? 10, 10) : settings.maxBudgetUsd ?? 50,
5521
+ maxBudgetUsd: settings.maxBudgetUsd ?? 50,
5601
5522
  abortController: host.abortController ?? void 0,
5602
5523
  disallowedTools: buildDisallowedTools(settings, mode, host.hasExitedPlanMode),
5603
5524
  enableFileCheckpointing: settings.enableFileCheckpointing,
@@ -6087,6 +6008,7 @@ var SessionRunner = class _SessionRunner {
6087
6008
  stopped = false;
6088
6009
  hasCompleted = false;
6089
6010
  interrupted = false;
6011
+ _isReviewing = false;
6090
6012
  taskContext = null;
6091
6013
  fullContext = null;
6092
6014
  queryBridge = null;
@@ -6193,8 +6115,8 @@ var SessionRunner = class _SessionRunner {
6193
6115
  this.queryBridge = this.createQueryBridge();
6194
6116
  this.logInitialization();
6195
6117
  const staleMessageCount = this.pendingMessages.length;
6196
- await this.executeInitialMode();
6197
- if (staleMessageCount > 0) {
6118
+ const didExecuteInitialQuery = await this.executeInitialMode();
6119
+ if (staleMessageCount > 0 && didExecuteInitialQuery) {
6198
6120
  this.pendingMessages.splice(0, staleMessageCount);
6199
6121
  }
6200
6122
  if (!this.stopped && this._state !== "error") {
@@ -6203,6 +6125,9 @@ var SessionRunner = class _SessionRunner {
6203
6125
  if (!this.stopped && this.pendingMessages.length === 0) {
6204
6126
  await this.maybeSendPRNudge();
6205
6127
  }
6128
+ if (!this.stopped && this.pendingMessages.length === 0) {
6129
+ await this.maybeTransitionToReview();
6130
+ }
6206
6131
  if (!this.stopped) {
6207
6132
  process.stderr.write(
6208
6133
  `[conveyor-agent] Listening for messages (mode: ${this.mode.effectiveMode})
@@ -6289,25 +6214,20 @@ var SessionRunner = class _SessionRunner {
6289
6214
  }
6290
6215
  }
6291
6216
  // ── Initial mode execution ─────────────────────────────────────────
6217
+ /** Returns true if an initial query was executed, false otherwise. */
6292
6218
  async executeInitialMode() {
6293
- if (!this.taskContext || !this.fullContext) return;
6219
+ if (!this.taskContext || !this.fullContext) return false;
6294
6220
  const effectiveMode = this.mode.effectiveMode;
6295
- if (effectiveMode === "code-review") {
6296
- await this.setState("running");
6297
- await this.callbacks.onEvent({ type: "execute_mode", mode: effectiveMode });
6298
- await this.executeQuery();
6299
- this.stopped = true;
6300
- return;
6301
- }
6302
- const shouldRun = effectiveMode === "building" || effectiveMode === "auto" || effectiveMode === "review" && this.mode.isPackRunner(this.taskContext);
6221
+ const shouldRun = effectiveMode === "building" || effectiveMode === "auto" || effectiveMode === "review";
6303
6222
  if (shouldRun) {
6304
6223
  await this.setState("running");
6305
6224
  await this.callbacks.onEvent({ type: "execute_mode", mode: effectiveMode });
6306
6225
  await this.executeQuery();
6307
6226
  if (!this.stopped) await this.setState("idle");
6308
- } else {
6309
- await this.setState("idle");
6227
+ return true;
6310
6228
  }
6229
+ await this.setState("idle");
6230
+ return false;
6311
6231
  }
6312
6232
  // ── Message waiting ────────────────────────────────────────────────
6313
6233
  waitForMessage() {
@@ -6422,6 +6342,37 @@ var SessionRunner = class _SessionRunner {
6422
6342
  await this.refreshTaskContext();
6423
6343
  }
6424
6344
  }
6345
+ // ── Same-box review transition ─────────────────────────────────
6346
+ async maybeTransitionToReview() {
6347
+ if (!this.config.isAuto || this._isReviewing) return;
6348
+ await this.refreshTaskContext();
6349
+ if (!this.taskContext?.githubPRUrl || this.taskContext.status !== "ReviewPR") return;
6350
+ this._isReviewing = true;
6351
+ try {
6352
+ this.mode.handleModeChange("review");
6353
+ process.stderr.write(
6354
+ `[conveyor-agent] Auto-transitioning to review mode (same-box code review)
6355
+ `
6356
+ );
6357
+ this.connection.sendEvent({
6358
+ type: "mode_transition",
6359
+ from: "building",
6360
+ to: "review"
6361
+ });
6362
+ this.connection.emitModeChanged("review");
6363
+ const reviewPrompt = [
6364
+ `You have just created a PR for this task. Now perform a self-review of your changes.`,
6365
+ `Run \`git diff ${this.fullContext?.baseBranch ?? "dev"}..HEAD\` to see all changes.`,
6366
+ `Review the changes according to the review criteria in your instructions.`,
6367
+ `If you find issues, fix them directly, commit, and push. Then approve the review.`,
6368
+ `If everything looks good, approve the review using \`approve_code_review\`.`
6369
+ ].join("\n");
6370
+ await this.setState("running");
6371
+ await this.executeQuery(reviewPrompt);
6372
+ } finally {
6373
+ this._isReviewing = false;
6374
+ }
6375
+ }
6425
6376
  // ── Context & bridge construction ────────────────────────────────
6426
6377
  buildFullContext(ctx) {
6427
6378
  const chatHistory = mapChatHistory(ctx.chatHistory);
@@ -6499,6 +6450,9 @@ var SessionRunner = class _SessionRunner {
6499
6450
  if (action.type === "start_auto") {
6500
6451
  this.connection.emitModeChanged(this.mode.effectiveMode);
6501
6452
  this.softStop();
6453
+ } else if (action.type === "restart_query") {
6454
+ this.connection.emitModeChanged(action.newMode);
6455
+ this.softStop();
6502
6456
  }
6503
6457
  });
6504
6458
  this.connection.onWake(() => this.lifecycle.wake());
@@ -7536,7 +7490,7 @@ var ProjectRunner = class {
7536
7490
  async handleAuditTags(request) {
7537
7491
  this.connection.emitStatus("busy");
7538
7492
  try {
7539
- const { handleTagAudit } = await import("./tag-audit-handler-L7YPDXTA.js");
7493
+ const { handleTagAudit } = await import("./tag-audit-handler-PACJJEDB.js");
7540
7494
  await handleTagAudit(request, this.connection, this.projectDir);
7541
7495
  } catch (error) {
7542
7496
  const msg = error instanceof Error ? error.message : String(error);
@@ -7957,4 +7911,4 @@ export {
7957
7911
  loadForwardPorts,
7958
7912
  loadConveyorConfig
7959
7913
  };
7960
- //# sourceMappingURL=chunk-OUARAX27.js.map
7914
+ //# sourceMappingURL=chunk-3O4P2KST.js.map