@rallycry/conveyor-agent 7.3.0 → 7.3.2

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.
@@ -416,7 +416,14 @@ ${q.question}${q.options.length ? "\n" + q.options.map((o) => `- ${o.label}: ${o
416
416
  const apiUrl = this.config.apiUrl;
417
417
  if (!codespaceName || !apiUrl) return false;
418
418
  try {
419
- const response = await fetch(`${apiUrl}/api/codespace/bootstrap/${codespaceName}`);
419
+ const bootstrapToken = process.env.CONVEYOR_BOOTSTRAP_TOKEN;
420
+ const headers = {};
421
+ if (bootstrapToken) {
422
+ headers["x-codespace-token"] = bootstrapToken;
423
+ }
424
+ const response = await fetch(`${apiUrl}/api/codespace/bootstrap/${codespaceName}`, {
425
+ headers
426
+ });
420
427
  if (!response.ok) return false;
421
428
  const config = await response.json();
422
429
  if (config.envVars?.CLAUDE_CODE_OAUTH_TOKEN) {
@@ -1522,6 +1529,13 @@ function buildDiscoveryPrompt(context, runnerMode) {
1522
1529
  `- Include testing requirements and acceptance criteria`,
1523
1530
  `- Set \`storyPointValue\` based on estimated complexity`,
1524
1531
  ``,
1532
+ `### Plan Verification Requirements`,
1533
+ `Every plan MUST include a **Testing / Verification** section enumerating:`,
1534
+ `- The quality gates: \`bun run lint\`, \`bun run typecheck\`, \`bun run test\` (or scoped equivalents)`,
1535
+ `- Any task-specific end-to-end checks (manual UI walk-through, API smoke test, migration dry-run, etc.)`,
1536
+ `- For refactors: line-count / file-size expectations and a public-API-surface diff check`,
1537
+ `This ensures executing agents and reviewers have a clear definition of "done" and prevents silent regressions.`,
1538
+ ``,
1525
1539
  `### Completing Planning`,
1526
1540
  `Once ALL checklist items above are done, call the **ExitPlanMode** tool.`,
1527
1541
  `- Required before ExitPlanMode will succeed: **plan** (via update_task), **story points** (via update_task_properties), **title** (via update_task_properties)`,
@@ -1595,7 +1609,15 @@ function buildModePrompt(agentMode, context, runnerMode) {
1595
1609
  `- Goal: coordinate child task execution and ensure all children complete successfully`
1596
1610
  ] : [
1597
1611
  `- If this is a leaf task (no children): execute the plan directly`,
1598
- `- Goal: implement the plan, run tests, open a PR when done`
1612
+ `- Goal: implement the plan, verify quality gates, open a PR when done`,
1613
+ ``,
1614
+ `### Pre-PR Verification Checklist`,
1615
+ `Before calling \`mcp__conveyor__create_pull_request\`, verify ALL of the following pass:`,
1616
+ `1. \`bun run lint\` \u2014 no new lint errors`,
1617
+ `2. \`bun run typecheck\` \u2014 no new type errors`,
1618
+ `3. \`bun run test\` \u2014 relevant suites pass (scope to the affected package if the full run is prohibitively slow, and state the scope in the PR description)`,
1619
+ `If a gate fails, fix it before opening the PR. Do NOT open PRs with known failing gates.`,
1620
+ `For refactors: also run \`git diff ${context?.baseBranch ?? "dev"}..HEAD\` and confirm the public API surface (exports, function signatures) has no unintended breaking changes.`
1599
1621
  ]
1600
1622
  ];
1601
1623
  return parts.join("\n");
@@ -2087,6 +2109,7 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
2087
2109
  `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.`,
2088
2110
  `Work on the git branch "${context.githubBranch}". Stay on this branch for the entire task. Do not checkout or create other branches.`,
2089
2111
  `Your replies are visible to the team in chat \u2014 briefly describe what you're doing when you begin meaningful implementation, and again when the PR is ready.`,
2112
+ `Before opening the PR, run the quality gates: \`bun run lint && bun run typecheck && bun run test\`. Fix any failures. Do NOT open a PR with known failing gates \u2014 scope the test run to affected packages if the full suite is prohibitively slow, and state the scope in the PR body.`,
2090
2113
  `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.`
2091
2114
  ];
2092
2115
  if (isAutoMode) {
@@ -2143,6 +2166,7 @@ New messages since your last run:`,
2143
2166
  ...newMessages.map((m) => `[${m.userName ?? "user"}]: ${m.content}`),
2144
2167
  `
2145
2168
  Address the requested changes directly. Do NOT re-investigate the codebase from scratch or write a new plan \u2014 go straight to implementing the feedback.`,
2169
+ `Before pushing or opening a PR, re-run the quality gates: \`bun run lint && bun run typecheck && bun run test\`. Fix any failures \u2014 relaunches are the most common place verification gets skipped.`,
2146
2170
  `Implement your updates and open a PR when finished.`
2147
2171
  ];
2148
2172
  if (context.githubPRUrl) {
@@ -2236,7 +2260,7 @@ import { z } from "zod";
2236
2260
  function buildReadTaskChatTool(connection) {
2237
2261
  return defineTool(
2238
2262
  "read_task_chat",
2239
- "Read recent messages from a task chat. Omit task_id to read the current task's chat, or provide a child task ID to read a child's chat.",
2263
+ "Read recent human/user chat messages for a task. When to use: you need to see user instructions, questions, or feedback posted to the task chat. Omit task_id for the current task, or pass a child task ID to read a child's chat. When NOT to use: for agent reasoning, tool calls, or setup/dev-server output \u2014 use get_task_cli instead. Returns: JSON array of recent chat messages (default 20).",
2240
2264
  {
2241
2265
  limit: z.number().optional().describe("Number of recent messages to fetch (default 20)"),
2242
2266
  task_id: z.string().optional().describe("Child task ID to read chat from. Omit to read the current task's chat.")
@@ -2263,7 +2287,7 @@ function buildReadTaskChatTool(connection) {
2263
2287
  function buildGetTaskPlanTool(connection) {
2264
2288
  return defineTool(
2265
2289
  "get_task_plan",
2266
- "Re-read the latest task plan in case it was updated",
2290
+ "Re-read the current task's plan. When to use: the user just said they updated the plan mid-session or explicitly asked you to re-read it. When NOT to use: to fetch general task info (title, status, description) \u2014 use get_task. The plan was already included in your initial context, so do not call this speculatively. Returns: the plan markdown string.",
2267
2291
  {},
2268
2292
  async () => {
2269
2293
  try {
@@ -2281,7 +2305,7 @@ function buildGetTaskPlanTool(connection) {
2281
2305
  function buildGetTaskTool(connection) {
2282
2306
  return defineTool(
2283
2307
  "get_task",
2284
- "Look up a task by slug or ID to get its title, description, plan, and status",
2308
+ "Look up any task by slug or ID. When to use: you need the current title, description, plan, status, branch, PR info, or story points for this or a related task. When NOT to use: to list child tasks (use list_subtasks), or to re-read only the current plan (use get_task_plan). Returns: JSON task object including id, slug, title, description, plan, status, branch, githubPRNumber, githubPRUrl, storyPointValue.",
2285
2309
  {
2286
2310
  slug_or_id: z.string().describe("The task slug (e.g. 'my-task') or CUID")
2287
2311
  },
@@ -2304,7 +2328,7 @@ function buildGetTaskTool(connection) {
2304
2328
  function buildGetTaskCliTool(connection) {
2305
2329
  return defineTool(
2306
2330
  "get_task_cli",
2307
- "Read CLI execution logs from a task. Returns agent reasoning, tool calls, setup output, and other execution events. Use 'source' to filter: 'agent' for agent reasoning/tool calls only, 'application' for setup/dev-server output only.",
2331
+ "Read CLI execution logs from a task \u2014 agent reasoning, tool calls, and setup/dev-server output. When to use: inspecting what another agent did, debugging build/setup output, or reviewing prior tool calls. Filter with source='agent' for reasoning and tool calls only, source='application' for setup/dev-server output only. When NOT to use: for human/user chat \u2014 use read_task_chat. Returns: newline-joined event log lines each prefixed with `[timestamp] [type]` and formatted content.",
2308
2332
  {
2309
2333
  task_id: z.string().optional().describe("Task ID or slug. Omit to read logs from the current task."),
2310
2334
  source: z.enum(["agent", "application"]).optional().describe("Filter by log source. Omit for all logs."),
@@ -2337,7 +2361,7 @@ function buildGetTaskCliTool(connection) {
2337
2361
  function buildListTaskFilesTool(connection) {
2338
2362
  return defineTool(
2339
2363
  "list_task_files",
2340
- "List all files attached to this task with metadata (name, type, size) and download URLs",
2364
+ "List all files attached to this task with metadata. When to use: before fetching a specific file, to see what is available and how large each is. When NOT to use: to read a file's contents \u2014 use get_task_file. Returns: JSON array of file metadata (id, name, mimeType, size, downloadUrl), plus inline image blocks for any attached images.",
2341
2365
  {},
2342
2366
  async () => {
2343
2367
  try {
@@ -2367,7 +2391,7 @@ function buildListTaskFilesTool(connection) {
2367
2391
  function buildGetTaskFileTool(connection) {
2368
2392
  return defineTool(
2369
2393
  "get_task_file",
2370
- "Get a specific task file's content and download URL by file ID",
2394
+ "Fetch one task file's content plus metadata by file ID. When to use: you have a file ID from list_task_files and need its content or download URL. Call list_task_files first to discover IDs and check sizes \u2014 large binaries may be truncated by the service's size limit. When NOT to use: to enumerate attachments \u2014 use list_task_files. Returns: JSON metadata; for images an inline image block is also returned, and text content is embedded inline when available.",
2371
2395
  { fileId: z.string().describe("The file ID to retrieve") },
2372
2396
  async ({ fileId }) => {
2373
2397
  try {
@@ -2410,7 +2434,7 @@ import { z as z2 } from "zod";
2410
2434
  function buildGetDependenciesTool(connection) {
2411
2435
  return defineTool(
2412
2436
  "get_dependencies",
2413
- "Get this task's dependencies and their current status (met = merged to dev)",
2437
+ "Get this task's dependencies and their current met/unmet status. When to use: confirming that blockers have been merged before starting work, or investigating why a task cannot start. When NOT to use: to look up a specific task's state \u2014 use get_task. Returns: JSON array of dependency objects (slug, title, status, and whether the dependency is met \u2014 met means merged to dev).",
2414
2438
  {},
2415
2439
  async () => {
2416
2440
  try {
@@ -2430,15 +2454,19 @@ function buildGetDependenciesTool(connection) {
2430
2454
  function buildGetSuggestionsTool(connection) {
2431
2455
  return defineTool(
2432
2456
  "get_suggestions",
2433
- "List project suggestions sorted by vote score. Use this to see what the team thinks is important.",
2457
+ "List project suggestions sorted by vote score. When to use: seeing what the team thinks is important, finding a suggestion to vote on, or checking for duplicates before create_suggestion. Filter by status (Planning, Open, InProgress, ReviewPR, ReviewDev, ReviewLive, Complete, Cancelled) or cap results with limit (default 20). When NOT to use: for task lists \u2014 suggestions are project-level idea records, not tasks. Returns: JSON array of suggestions with id, title, description, status, score.",
2434
2458
  {
2435
- status: z2.string().optional().describe("Filter by status: Open, Accepted, Rejected, Implemented"),
2436
- limit: z2.number().optional().describe("Max results (default 20)")
2459
+ status: z2.string().optional().describe(
2460
+ "Filter by status: Planning, Open, InProgress, ReviewPR, ReviewDev, ReviewLive, Complete, Cancelled"
2461
+ ),
2462
+ limit: z2.number().int().min(1).max(100).optional().describe("Max results (default 20)")
2437
2463
  },
2438
- async ({ status: _status, limit: _limit }) => {
2464
+ async ({ status, limit }) => {
2439
2465
  try {
2440
2466
  const suggestions = await connection.call("getSuggestions", {
2441
- sessionId: connection.sessionId
2467
+ sessionId: connection.sessionId,
2468
+ status,
2469
+ limit
2442
2470
  });
2443
2471
  if (suggestions.length === 0) {
2444
2472
  return textResult("No suggestions found.");
@@ -2459,7 +2487,7 @@ import { z as z3 } from "zod";
2459
2487
  function buildPostToChatTool(connection) {
2460
2488
  return defineTool(
2461
2489
  "post_to_chat",
2462
- "Post a message to a task chat. Your normal replies already appear in chat \u2014 only use this for explicit out-of-band updates or posting to a child task's chat.",
2490
+ "Post an out-of-band message to a task chat. When to use: the user explicitly asked for a status update that must appear in chat, or you need to message a child task's chat (pass its ID as task_id). When NOT to use: for normal responses \u2014 your regular replies already appear in the current task's chat automatically. Returns: confirmation string.",
2463
2491
  {
2464
2492
  message: z3.string().describe("The message to post to the team"),
2465
2493
  task_id: z3.string().optional().describe("Child task ID to post to. Omit to post to the current task's chat.")
@@ -2487,7 +2515,7 @@ function buildPostToChatTool(connection) {
2487
2515
  function buildForceUpdateTaskStatusTool(connection) {
2488
2516
  return defineTool(
2489
2517
  "force_update_task_status",
2490
- "EMERGENCY ONLY: Force-override a task's Kanban status. Status transitions happen automatically (building sets InProgress, PR creation sets ReviewPR, merge sets ReviewDev). Only use this if an automatic transition failed or a task is stuck in the wrong status. Omit task_id to update the current task, or provide a child task ID.",
2518
+ "EMERGENCY ONLY: force-override a task's Kanban status. When to use: an automatic transition failed and the task is wedged \u2014 e.g. a PR was merged but status did not advance to ReviewDev, a build completed but status is still InProgress with no session running, or a child is stuck in ReviewPR after its PR was closed. When NOT to use: in normal flow \u2014 building, PR creation, and merge each transition status automatically. Omit task_id for the current task; pass a child task ID to update a child. Returns: confirmation string.",
2491
2519
  {
2492
2520
  status: z3.enum(["InProgress", "ReviewPR", "ReviewDev", "Complete"]).describe("The new status for the task"),
2493
2521
  task_id: z3.string().optional().describe("Child task ID to update. Omit to update the current task.")
@@ -2519,7 +2547,7 @@ function buildForceUpdateTaskStatusTool(connection) {
2519
2547
  function buildCreatePullRequestTool(connection, config) {
2520
2548
  return defineTool(
2521
2549
  "create_pull_request",
2522
- "Create a GitHub pull request for this task. Automatically stages uncommitted changes, commits them, and pushes before creating the PR. Use this instead of gh CLI or git commands to create PRs.",
2550
+ "Create a GitHub pull request for this task. Runs in order: 1) stage any uncommitted changes, 2) commit them (using commitMessage, or a default derived from title), 3) push to origin, 4) create the PR via GitHub API. When to use: opening the PR for this task \u2014 always use this instead of the gh CLI or raw git. Common failures: missing remote branch, a PR already open for this branch, or an expired git token (retry after the refresh). Returns: confirmation string with the new PR number and URL.",
2523
2551
  {
2524
2552
  title: z3.string().describe("The PR title"),
2525
2553
  body: z3.string().describe("The PR description/body in markdown"),
@@ -2605,7 +2633,7 @@ Troubleshooting:
2605
2633
  function buildAddDependencyTool(connection) {
2606
2634
  return defineTool(
2607
2635
  "add_dependency",
2608
- "Add a dependency \u2014 this task cannot start until the specified task is merged to dev",
2636
+ "Add a blocking dependency \u2014 this task cannot start until the named task is merged to dev. When to use: you discovered work that must land before this task can proceed. When NOT to use: to track work that should happen after this task \u2014 use create_follow_up_task instead. Returns: confirmation string.",
2609
2637
  {
2610
2638
  depends_on_slug_or_id: z3.string().describe("Slug or ID of the task this task depends on")
2611
2639
  },
@@ -2627,7 +2655,7 @@ function buildAddDependencyTool(connection) {
2627
2655
  function buildRemoveDependencyTool(connection) {
2628
2656
  return defineTool(
2629
2657
  "remove_dependency",
2630
- "Remove a dependency from this task",
2658
+ "Remove a previously added dependency from this task. When to use: the dependency was added in error or is no longer relevant. Returns: confirmation string.",
2631
2659
  {
2632
2660
  depends_on_slug_or_id: z3.string().describe("Slug or ID of the task to remove as dependency")
2633
2661
  },
@@ -2649,7 +2677,7 @@ function buildRemoveDependencyTool(connection) {
2649
2677
  function buildCreateFollowUpTaskTool(connection) {
2650
2678
  return defineTool(
2651
2679
  "create_follow_up_task",
2652
- "Create a follow-up task in this project that depends on the current task. Use for out-of-scope work, v1.1 features, or cleanup that should happen after this task merges.",
2680
+ "Create a follow-up task that depends on the current task. When to use: out-of-scope work, v1.1 features, or cleanup that should happen after this task merges. The new task will be unblocked once the current task is merged. When NOT to use: to add a blocker to this task \u2014 use add_dependency instead. Returns: confirmation string with the new task's slug.",
2653
2681
  {
2654
2682
  title: z3.string().describe("Follow-up task title"),
2655
2683
  description: z3.string().optional().describe("Brief description of the follow-up work"),
@@ -2679,7 +2707,7 @@ function buildCreateFollowUpTaskTool(connection) {
2679
2707
  function buildCreateSuggestionTool(connection) {
2680
2708
  return defineTool(
2681
2709
  "create_suggestion",
2682
- "Suggest a feature, improvement, or idea for the project. If you want to recommend something \u2014 a document, a rule, a feature, a task, an optimization \u2014 use this tool. If a similar suggestion already exists, your vote will be added to it instead of creating a duplicate.",
2710
+ "Suggest a feature, improvement, rule, or idea for the project. When to use: recommending anything project-scoped \u2014 a document, a rule, a feature, a task, an optimization. If a similar suggestion already exists the service will dedupe and record your upvote instead. When NOT to use: for actionable work scoped to the current task \u2014 open a follow-up task. Returns: confirmation string with the suggestion id (and mergedIntoId if deduped).",
2683
2711
  {
2684
2712
  title: z3.string().describe("Short title for the suggestion"),
2685
2713
  description: z3.string().optional().describe(
@@ -2712,7 +2740,7 @@ function buildCreateSuggestionTool(connection) {
2712
2740
  function buildVoteSuggestionTool(connection) {
2713
2741
  return defineTool(
2714
2742
  "vote_suggestion",
2715
- "Vote on a project suggestion. Use +1 to upvote or -1 to downvote.",
2743
+ "Vote +1 or -1 on a project suggestion. When to use: expressing support or disagreement with a specific suggestion returned from get_suggestions. Returns: confirmation string with the suggestion's updated score.",
2716
2744
  {
2717
2745
  suggestion_id: z3.string().describe("The suggestion ID to vote on"),
2718
2746
  value: z3.number().refine((v) => v === 1 || v === -1, { message: "Value must be 1 or -1" }).describe("+1 to upvote, -1 to downvote")
@@ -2761,7 +2789,7 @@ var SP_DESCRIPTION = "Story point value (1=Common, 2=Magic, 3=Rare, 5=Unique)";
2761
2789
  function buildUpdateTaskTool(connection) {
2762
2790
  return defineTool(
2763
2791
  "update_task",
2764
- "Save the finalized task plan and/or description",
2792
+ "Save the finalized plan and/or description to the current task. When to use: in Plan mode, after reaching alignment with the user on the approach. When NOT to use: for child/subtasks \u2014 use update_subtask. This tool does not change status or other properties. Returns: confirmation string.",
2765
2793
  {
2766
2794
  plan: z4.string().optional().describe("The task plan in markdown"),
2767
2795
  description: z4.string().optional().describe("Updated task description")
@@ -2783,7 +2811,7 @@ function buildUpdateTaskTool(connection) {
2783
2811
  function buildCreateSubtaskTool(connection) {
2784
2812
  return defineTool(
2785
2813
  "create_subtask",
2786
- "Create a subtask under the current parent task. Use for breaking complex tasks into smaller pieces.",
2814
+ "Create a subtask under the current parent task. When to use: breaking a complex parent task into smaller pieces during planning. When NOT to use: for follow-ups that depend on this task but are not children \u2014 use create_follow_up_task. Returns: confirmation string with the new subtask id.",
2787
2815
  {
2788
2816
  title: z4.string().describe("Subtask title"),
2789
2817
  description: z4.string().optional().describe("Brief description"),
@@ -2813,7 +2841,7 @@ function buildCreateSubtaskTool(connection) {
2813
2841
  function buildUpdateSubtaskTool(connection) {
2814
2842
  return defineTool(
2815
2843
  "update_subtask",
2816
- "Update an existing subtask's fields",
2844
+ "Update an existing subtask's fields (title, description, plan, ordinal, storyPointValue). When to use: refining a child's plan or reordering the subtask queue. When NOT to use: to change status (pack tools do that automatically) or to update the current task itself (use update_task). Returns: confirmation string.",
2817
2845
  {
2818
2846
  subtaskId: z4.string().describe("The subtask ID to update"),
2819
2847
  title: z4.string().optional(),
@@ -2842,7 +2870,7 @@ function buildUpdateSubtaskTool(connection) {
2842
2870
  function buildDeleteSubtaskTool(connection) {
2843
2871
  return defineTool(
2844
2872
  "delete_subtask",
2845
- "Delete a subtask",
2873
+ "Delete a subtask by id. When to use: a subtask was created in error or is no longer needed. Returns: confirmation string.",
2846
2874
  { subtaskId: z4.string().describe("The subtask ID to delete") },
2847
2875
  async ({ subtaskId }) => {
2848
2876
  try {
@@ -2860,7 +2888,7 @@ function buildDeleteSubtaskTool(connection) {
2860
2888
  function buildListSubtasksTool(connection) {
2861
2889
  return defineTool(
2862
2890
  "list_subtasks",
2863
- "List all subtasks under the current parent task. Returns status, PR info (githubPRNumber, githubPRUrl), agent assignment (agentId), and plan for each child.",
2891
+ "List all subtasks under the current parent task. When to use: coordinating child work \u2014 check who is running, which children are ready for review, or which are blocked. When NOT to use: for non-child related tasks \u2014 use get_task. Returns: JSON array with id, slug, title, status, storyPointValue, githubPRNumber, githubPRUrl, agentId, and plan for each child.",
2864
2892
  {},
2865
2893
  async () => {
2866
2894
  try {
@@ -2879,7 +2907,7 @@ function buildPackTools(connection) {
2879
2907
  return [
2880
2908
  defineTool(
2881
2909
  "start_child_cloud_build",
2882
- "Start a cloud build for a child task. The child must be in Open status with story points and an agent assigned.",
2910
+ "Start a cloud build (codespace) for a child task. Preconditions: the child must be in Open status, have a story point value, and have an agent assigned. When NOT to use: if the child is already InProgress or past Open \u2014 it is already building or done. Returns: confirmation string including the child task id that the build was started for.",
2883
2911
  {
2884
2912
  childTaskId: z4.string().describe("The child task ID to start a cloud build for")
2885
2913
  },
@@ -2899,7 +2927,7 @@ function buildPackTools(connection) {
2899
2927
  ),
2900
2928
  defineTool(
2901
2929
  "stop_child_build",
2902
- "Stop a running cloud build for a child task. Sends a stop signal to the child agent.",
2930
+ "Send a graceful stop signal to a running child build's agent. When to use: you decided the child should halt (plan changed, deadlock, scope pivot) and want the agent to exit cleanly. This is not a force-kill \u2014 the agent may take a moment to wind down. Returns: confirmation string.",
2903
2931
  {
2904
2932
  childTaskId: z4.string().describe("The child task ID whose build should be stopped")
2905
2933
  },
@@ -2919,7 +2947,7 @@ function buildPackTools(connection) {
2919
2947
  ),
2920
2948
  defineTool(
2921
2949
  "approve_and_merge_pr",
2922
- "Approve and merge a child task's pull request. Only succeeds if all CI/CD checks are passing. Returns an error if checks are pending (retry after waiting) or failed (investigate). The child task must be in ReviewPR status.",
2950
+ "Approve and merge a child task's PR. Preconditions: child is in ReviewPR and you have reviewed the diff. When NOT to use: if review surfaced issues \u2014 post to the child's chat or escalate instead. Returns: { childTaskId, prNumber, merged }. merged=true means the merge happened and status is now ReviewDev. merged=false means the merge is queued for GitHub automerge (CI still running) \u2014 do NOT proceed as if merged; wait for the child's status to transition to ReviewDev. If checks have failed, this call errors \u2014 investigate the failure.",
2923
2951
  {
2924
2952
  childTaskId: z4.string().describe("The child task ID whose PR should be approved and merged")
2925
2953
  },
@@ -3007,7 +3035,7 @@ function buildCodeReviewTools(connection) {
3007
3035
  return [
3008
3036
  defineTool(
3009
3037
  "approve_code_review",
3010
- "Approve the code review. Use this when the code passes all review criteria and is ready to merge.",
3038
+ "Approve the code review and exit. When to use: the diff passes all review criteria and is ready to merge. When NOT to use: if any substantive issue remains \u2014 call request_code_changes with a structured issues[] list. This tool takes only a summary; it does not accept an issues array (by design \u2014 an approval should have no blocking issues). Returns: confirmation string.",
3011
3039
  {
3012
3040
  summary: z6.string().describe("Brief summary of what was reviewed and why it looks good")
3013
3041
  },
@@ -3030,7 +3058,7 @@ ${summary}`;
3030
3058
  ),
3031
3059
  defineTool(
3032
3060
  "request_code_changes",
3033
- "Request changes during code review. Use this when substantive issues are found that need to be fixed before merge.",
3061
+ "Request changes during code review and exit. When to use: substantive issues were found that must be fixed before merge. Each entry in issues[] is { file: string, line?: number, severity: 'critical' | 'major' | 'minor', description: string }. When NOT to use: for an approval \u2014 use approve_code_review. Returns: confirmation string.",
3034
3062
  {
3035
3063
  issues: z6.array(
3036
3064
  z6.object({
@@ -3624,7 +3652,7 @@ function buildClientInspectionTools(manager) {
3624
3652
  return [
3625
3653
  defineTool(
3626
3654
  "debug_inspect_client_paused",
3627
- "When the client-side debugger is paused at a breakpoint, returns the call stack and local variables. Includes React component state, props, and hooks when paused inside a component.",
3655
+ "When the client-side (browser) debugger is paused at a breakpoint, returns the call stack and local variables from the paused frame. When to use: after a client breakpoint hits, to see what is in scope in the browser. When NOT to use: for server pauses \u2014 use debug_inspect_paused. Returns: JSON with side='client', reason, hitBreakpoints, callStack, and localVariables. If the debugger paused between turns and has since resumed, queued breakpoint hits are returned instead.",
3628
3656
  {},
3629
3657
  async () => {
3630
3658
  const clientOrErr = requirePlaywrightClient(manager);
@@ -3667,7 +3695,7 @@ ${JSON.stringify(queuedHits, null, 2)}`
3667
3695
  ),
3668
3696
  defineTool(
3669
3697
  "debug_evaluate_client",
3670
- "Evaluate a JavaScript expression in the client-side browser context. When paused at a client breakpoint, evaluates in the paused scope. Can access DOM, window, React internals, etc.",
3698
+ "Evaluate a JavaScript expression in the browser context. When paused at a client breakpoint, runs in the paused scope (use frameIndex to pick a frame); otherwise runs in the page's global scope with access to DOM, window, and React internals. Side effects are real \u2014 navigations, DOM mutations, and function calls execute. Prefer read-only expressions unless you specifically want to mutate page state. Returns: `(type) value`.",
3671
3699
  {
3672
3700
  expression: z8.string().describe("JavaScript expression to evaluate in the browser context"),
3673
3701
  frameIndex: z8.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
@@ -3741,7 +3769,7 @@ function buildClientInteractionTools(manager) {
3741
3769
  ),
3742
3770
  defineTool(
3743
3771
  "debug_navigate_client",
3744
- "Navigate the headless browser to a specific URL. Use this to reproduce specific flows or visit different pages.",
3772
+ "Navigate the headless browser to a URL. When to use: reproducing a specific flow or visiting a different page. Waits for `domcontentloaded` before returning (Playwright's default ~30s navigation timeout applies). Returns: confirmation string with the resolved current URL.",
3745
3773
  {
3746
3774
  url: z8.string().describe("URL to navigate to (e.g., http://localhost:3000/dashboard)")
3747
3775
  },
@@ -3758,7 +3786,7 @@ function buildClientInteractionTools(manager) {
3758
3786
  ),
3759
3787
  defineTool(
3760
3788
  "debug_click_client",
3761
- "Click an element on the page in the headless browser. Use CSS selectors to target elements. Useful for reproducing bugs by interacting with the UI programmatically.",
3789
+ "Click an element in the headless browser by CSS selector. When to use: reproducing bugs by interacting with the UI programmatically. Playwright auto-waits for the element to be visible, stable, and enabled before clicking, up to a 10s timeout \u2014 a miss throws and is reported in the failure message. Returns: confirmation string.",
3762
3790
  {
3763
3791
  selector: z8.string().describe(
3764
3792
  "CSS selector of the element to click (e.g., 'button.submit', '#login-form input[type=submit]')"
@@ -3931,7 +3959,7 @@ function buildDebugLifecycleTools(manager) {
3931
3959
  return [
3932
3960
  defineTool(
3933
3961
  "debug_enter_mode",
3934
- "Activate debug mode: restarts the dev server with Node.js --inspect flag and connects the CDP debugger. Optionally launch a headless Chromium browser for client-side debugging. Use serverSide for backend breakpoints, clientSide for frontend breakpoints, or both for full-stack.",
3962
+ "Activate debug mode. When to use: at the start of a debug session before setting breakpoints or probes. Restarts the dev server with Node.js --inspect for server-side CDP, and/or launches a headless Chromium via Playwright for client-side. Default: if neither serverSide nor clientSide is passed, server-side only is activated. Pass clientSide=true for frontend debugging (previewUrl required), or set both for full-stack. Returns: activation status string listing active modes, an echoed hypothesis if given, and a warning if source maps are missing.",
3935
3963
  {
3936
3964
  hypothesis: z9.string().optional().describe("Your hypothesis about the bug \u2014 helps track debugging intent"),
3937
3965
  serverSide: z9.boolean().optional().describe(
@@ -4077,7 +4105,7 @@ ${JSON.stringify(queuedHits, null, 2)}`
4077
4105
  ),
4078
4106
  defineTool(
4079
4107
  "debug_evaluate",
4080
- "Evaluate a JavaScript expression in the current paused scope (or globally if not paused). When paused, use frameIndex to evaluate in a specific call frame.",
4108
+ "Evaluate a JavaScript expression server-side in the Node process. When paused at a breakpoint the expression runs in that frame's scope (use frameIndex to pick a different frame); otherwise it runs in the global scope. Side effects are real \u2014 assignments, function calls, and I/O all execute. Prefer read-only expressions unless you specifically want to mutate state. Returns: `(type) value`.",
4081
4109
  {
4082
4110
  expression: z9.string().describe("The JavaScript expression to evaluate"),
4083
4111
  frameIndex: z9.number().optional().describe("Call stack frame index (0 = top frame). Defaults to the top frame.")
@@ -4176,7 +4204,7 @@ function buildProbeResultTools(manager) {
4176
4204
  return [
4177
4205
  defineTool(
4178
4206
  "debug_get_probe_results",
4179
- "Fetch captured probe hit data. Returns expression values from each time a probed line executed.",
4207
+ "Fetch captured probe hit data. When to use: after triggering the code path for a probe set by debug_add_probe. Filtering: pass label to filter directly, or probeId to look up and filter by that probe's label; if both are passed, label wins and probeId is ignored. Returns: grouped text with per-probe hit count, timestamps, and captured expression values.",
4180
4208
  {
4181
4209
  probeId: z9.string().optional().describe("Filter results by probe ID (resolves to its label)"),
4182
4210
  label: z9.string().optional().describe("Filter results by probe label"),
@@ -5586,6 +5614,7 @@ var QueryBridge = class {
5586
5614
  }
5587
5615
  } finally {
5588
5616
  this.mode.pendingModeRestart = false;
5617
+ this._abortController = null;
5589
5618
  }
5590
5619
  }
5591
5620
  // ── QueryHost construction ──────────────────────────────────────────
@@ -6691,8 +6720,8 @@ function buildTaskListTools(connection) {
6691
6720
  { annotations: { readOnlyHint: true } }
6692
6721
  ),
6693
6722
  defineTool(
6694
- "get_task",
6695
- "Get detailed information about a task including chat messages, child tasks, and session.",
6723
+ "get_project_task",
6724
+ "Get detailed information about a task in this project (chat messages, child tasks, session). Project-runner scope.",
6696
6725
  { task_id: z10.string().describe("The task ID to look up") },
6697
6726
  async ({ task_id }) => {
6698
6727
  try {
@@ -6790,8 +6819,8 @@ function buildMutationTools2(connection) {
6790
6819
  }
6791
6820
  ),
6792
6821
  defineTool(
6793
- "update_task",
6794
- "Update an existing task's title, description, plan, status, or assignee.",
6822
+ "update_project_task",
6823
+ "Update an existing task's title, description, plan, status, or assignee. Project-runner scope.",
6795
6824
  {
6796
6825
  task_id: z10.string().describe("The task ID to update"),
6797
6826
  title: z10.string().optional().describe("New title"),
@@ -7341,7 +7370,7 @@ function spawnChildAgent(assignment, workDir) {
7341
7370
  CONVEYOR_TASK_TOKEN: taskToken,
7342
7371
  CONVEYOR_TASK_ID: taskId,
7343
7372
  ...sessionId ? { CONVEYOR_SESSION_ID: sessionId } : {},
7344
- CONVEYOR_MODE: agentMode === "code-review" ? "code-review" : mode,
7373
+ CONVEYOR_MODE: mode,
7345
7374
  CONVEYOR_WORKSPACE: workDir,
7346
7375
  CONVEYOR_USE_WORKTREE: "false",
7347
7376
  CONVEYOR_AGENT_MODE: effectiveAgentMode,
@@ -7395,7 +7424,7 @@ async function killAgent(agent, taskId) {
7395
7424
  async function handleAssignment(assignment, activeAgents, projectDir, connection) {
7396
7425
  const { taskId, mode } = assignment;
7397
7426
  const shortId = taskId.slice(0, 8);
7398
- const agentKey = assignment.agentMode === "code-review" ? `${taskId}:code-review` : taskId;
7427
+ const agentKey = mode === "code-review" ? `${taskId}:code-review` : taskId;
7399
7428
  const existing = activeAgents.get(agentKey);
7400
7429
  if (existing) {
7401
7430
  if (existing.process.exitCode === null) {
@@ -7796,4 +7825,4 @@ export {
7796
7825
  loadForwardPorts,
7797
7826
  loadConveyorConfig
7798
7827
  };
7799
- //# sourceMappingURL=chunk-5MTPAVNZ.js.map
7828
+ //# sourceMappingURL=chunk-WDGSLU5S.js.map