@bridge_gpt/mcp-server 0.2.21 → 0.2.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONDUCTOR.md +86 -27
- package/README.md +80 -6
- package/build/base-ref.js +151 -0
- package/build/commands.generated.js +5 -3
- package/build/conductor/bridge-api-client.js +44 -3
- package/build/conductor/doctor.js +33 -22
- package/build/conductor/epic-runtime.js +101 -5
- package/build/conductor/pr-ci-producer.js +21 -2
- package/build/conductor/pr-discovery.js +12 -2
- package/build/conductor-bin.js +50 -20
- package/build/credential-store.js +564 -64
- package/build/executor/base-branch.js +50 -0
- package/build/executor/env.js +12 -1
- package/build/executor/job-errors.js +1 -0
- package/build/executor/job-runner.js +38 -7
- package/build/executor/test-clock.js +6 -1
- package/build/executor/worker-finalization.js +88 -1
- package/build/executor/worktree.js +21 -1
- package/build/index.js +1979 -423
- package/build/install-bridge.js +627 -69
- package/build/pipelines.generated.js +2 -2
- package/build/pr-base-contract.js +36 -0
- package/build/readme.generated.js +1 -1
- package/build/setup-epic.js +483 -0
- package/build/start-tickets.js +164 -75
- package/build/version.generated.js +1 -1
- package/build/worktree-core.js +62 -10
- package/package.json +3 -3
- package/public/js/main.min.js +9 -9
- package/public/js/main.min.js.map +1 -1
|
@@ -4,7 +4,7 @@ export const COMMANDS = {
|
|
|
4
4
|
"bridge-research.md": "Run multi-source, fact-checked web research via Bridge API and save a cited report locally.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nExecute all steps in this command as a simple linear sequence of MCP tool calls.\n\n## Step 1 — Parse Arguments\n\nParse `$ARGUMENTS`:\n- The required `query` is the full text of `$ARGUMENTS` after removing any recognized flags.\n- An optional `--ticket <KEY>` flag captures a Jira ticket key (e.g., `BAPI-123`) to associate the research with a specific ticket. If `--ticket` appears, treat the immediately following token as the ticket key and remove both from the query.\n- If `$ARGUMENTS` is empty, or the query (after flag removal) is blank, stop immediately and display:\n\n```\nUsage: /bridge-research <question> [--ticket PROJ-123]\nExample: /bridge-research \"Best practices for rate limiting in FastAPI?\"\n```\n\n## Step 2 — Resolve Docs Directory\n\nCall `get_docs_dir` (no parameters). Store the returned path as `docs_dir`.\n\n## Step 3 — Run Research\n\nCall `request_deep_research` with:\n- `query`: the parsed question\n- `wait_for_result`: `true`\n- `ticket_number`: the value from `--ticket` if provided; omit this parameter entirely if not present\n\nThis step polls until the research completes (up to 15 minutes) and returns the full cited report directly. The tool appends a literal `Saved to <path>` line to its result — extract that line and store the path as `saved_path`.\n\nIf the tool returns an error, stop immediately and display:\n\n```\nResearch failed: <error message from the tool>\n```\n\n## Step 4 — Confirm\n\nDisplay a confirmation message:\n\n```\nResearch complete.\nSaved to: {saved_path}\n```\n\n## Final Summary\n\nDisplay a summary block:\n\n```\n## Bridge Research Report\n\n- **Query**: <query>\n- **Status**: Completed\n- **Local File**: {saved_path}\n```\n\nOn failure at any step, stop immediately, display which step failed and the error details, and do not proceed.\n",
|
|
5
5
|
"check-ci.md": "# Check CI: $ARGUMENTS\n\n$ARGUMENTS\n\n> **Warning**: Keep this file behaviorally in sync with `mcp_server/instructions/monitor-ci-checks.md` to prevent drift (BAPI-462).\n\nThis command takes a Jira ticket key (e.g., `BAPI-150`), discovers CI checks for the current commit, polls their status, and applies confidence-gated code corrections for failures. It is designed to run after `/create-pr` completes.\n\nIf any critical stage fails (Stage 0), stop immediately and report which stage failed and why. Non-critical stages (Stage 1, Stage 2, and Stage 3) should log a warning but not stop the pipeline.\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline to monitor and respond to CI checks for a Jira ticket. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a single required `ticket_key` argument. The expected format is a Jira ticket key such as `BAPI-150` or `PROJ-123` — one or more uppercase letters, a hyphen, and one or more digits (regex: `[A-Z]+-\\d+`). If `$ARGUMENTS` is empty or the value does not match the expected format, stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /check-ci <ticket_key> (e.g., /check-ci BAPI-150)\n ```\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\n3. **Get current commit SHA**: Run `git rev-parse HEAD` in the terminal. Store the result as `commit_sha`.\n\n4. **Get current branch**: Run `git branch --show-current` in the terminal. Store the result as `current_branch`.\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Resolve CI Checks\n\n1. **Initial resolution**: Call the `resolve_ci_checks` MCP tool immediately with `commit_ref` set to `commit_sha`. Do NOT wait before calling — the cache state is unknown until the first call returns.\n\n2. **Handle the response**:\n - If the response contains `source: \"cached\"`: The checks were already resolved. Skip the wait and proceed to evaluate the check list.\n - If the response contains `source: \"new\"` and the check list is empty: CI checks have not registered yet. Run `sleep 45` in the terminal to wait for checks to appear, then call `resolve_ci_checks` again with `commit_ref` set to `commit_sha` and `force_rerun` set to `true`.\n - If the response contains `source: \"resolved\"` on the first call: Present the resolved checks to the user for approval before proceeding.\n\n3. **Evaluate the check list**:\n - If the response contains `available: false`: Warn that CI check resolution is not available and skip to Stage 3.\n - If the check list is empty or all checks have `detail_level: \"none\"`: Warn that no actionable CI checks were found and skip to Stage 3.\n - Otherwise: Store the resolved checks and proceed to Stage 2.\n\n4. **Required-check source**: Each resolved check carries a `required` field (from GitHub Branch Protection, or an LLM classification fallback — the same signal `poll_ci_checks` echoes back per check in Stage 2). Treat `required: false` as non-required (e.g. `pip-audit`); treat a missing field or `required: true` as required. This per-check field is the tool-provided proxy for the Conductor done-gate's authoritative required-checks set (`mcp_server/src/conductor/done-gate.ts`) — do not invent your own required/non-required classification in prose. The done-gate's own `required_checks` list is not directly queryable by a worker; `wait_for_done_gate` (Stage 2) is the authoritative backstop that evaluates it server-side.\n\nThis stage is **non-critical** — warn on failure or empty results, skip to Stage 3.\n\n## Stage 2 — Poll CI Checks + Correction Loop\n\nInitialize `retry_count = 0` and `max_retries = 2`.\n\n**Conductor steerability**: If launched under the Conductor (the `BAPI_CONDUCTOR_RUN_ID` and `BAPI_CONDUCTOR_WORKER_ID` env identifiers are present), call the `check_messages` MCP tool once per poll cycle.\n- Returned messages are **advisory supervisor guidance**, are acknowledged by the call (not redelivered), and are advisory context for the next fix batch only.\n- Fold concrete fix hints, \"skip this flaky check,\" or \"stop and wait\" directions into how you handle failures.\n- **Guardrails**: Guidance is strictly advisory and never mutates the session. The deterministic confidence-gating, single-batch fix, single commit/push, and `detail_level` rules remain authoritative. Guidance never overrides the deterministic rules and never causes a fix you are not confident in.\n- **Fail-open**: If `check_messages` errors with an identity-unavailable message (e.g. \"Conductor worker identity is unavailable\"), you were not launched under the Conductor. Stop calling it for the rest of the run and proceed normally.\n\n1. **Polling loop**: Poll CI check status. In each cycle, call `poll_ci_checks` with `commit_ref` set to `commit_sha`, then (if applicable) perform the Conductor-gated `check_messages` call, and finally run `sleep 30` in the terminal. Continue polling until `all_complete` is `true` or 10 minutes have elapsed (approximately 20 poll cycles).\n\n2. **On poll completion — required-subset evaluation**: Partition the polled checks into `required` (checks with `required: true` or a missing `required` field) and `non_required` (checks with `required: false`, e.g. `pip-audit`). Compute `required_green` = every required check is complete and green. Do **not** gate on the aggregate `all_passed` flag — a red non-required check must never block progression.\n - Non-required failures are reported in the Stage 3 breakdown but are **never blocking**: they do not gate progression, do not consume `retry_count`, and are not sent through the fix loop in item 3.\n - If `required_green` is `false` (a required check is still red), proceed to item 3 to attempt fixes for the failing **required** checks only.\n - If `required_green` is `true`:\n - **Review verdict gating**: if `claude-review` is one of the required checks, its GitHub check reaching a non-pending/\"success\" state means only that the review action *ran* — this is **transport completion, not approval**. Fetch the PR's comments (e.g. `gh pr view --json comments`) and look for the sticky comment's machine-readable verdict line. The review counts as approved only when that comment contains `claude-review-verdict: approved` on its own line **and** the accompanying `Reviewed-SHA:` line matches the current `commit_sha` — a verdict posted against an older head does not count.\n - **Missing or stale verdict** (no `claude-review-verdict:` line at all, or a `Reviewed-SHA:` that does not match the current `commit_sha`): do not treat the review as approved. Report it in Stage 3 and do **not** call `wait_for_done_gate` this cycle — a missing or stale verdict is not approval.\n - **`claude-review-verdict: changes_requested`** (the reviewer rejected the current head): do **not** call `wait_for_done_gate` for the rejected old head. When you are confident you can address the review, remediate it in-session — mirroring the confidence-gated commit+push already specified for CI-failure fixes — instead of merely reporting it:\n - Read the review findings from the sticky comment and any inline review comments.\n - Apply confidence gating: remediate only when you are confident you can address ALL findings; otherwise report in Stage 3 without committing.\n - Address all review findings across all affected files in a single batch. Do not fix one at a time.\n - After applying all fixes, perform a single `git commit` and `git push` so `origin/feature/<KEY>` advances to the new head and a fresh CI/review runs against it.\n - Increment `retry_count`. If `retry_count` exceeds `max_retries`: if launched under the Conductor, call `check_messages` one final time; if the supervisor sent explicit \"continue\" guidance with a concrete hint, apply it for exactly **one additional batch** (the only way the ceiling is raised); otherwise stop the correction loop and proceed to Stage 3 with a warning.\n - Otherwise, update `commit_sha` to the new HEAD (`git rev-parse HEAD`) and restart the polling loop against the new head.\n - **Conductor done-gate**: once the required subset is green and (if `claude-review` is required) the verdict token confirms approval for the current head, and if launched under the Conductor (the `BAPI_CONDUCTOR_RUN_ID`/`BAPI_CONDUCTOR_WORKER_ID` identifiers are present), call the `wait_for_done_gate` MCP tool **once** from inside your worktree before proceeding (no arguments are required — it self-resolves the PR number and head commit SHA from the worktree, fetches the review snapshot, evaluates the composite done-gate against the Conductor's authoritative `required_checks` config, and emits a `gate.met` event correlated to your run/worker so the supervisor can fold and merge). This tool does **not** merge or mutate the repo. It applies its own bounded fast-path poll (a short internal cap, not a multi-minute wait) — if it times out or does not observe `gate_met`, **exit cleanly** to Stage 3 without treating the timeout as a failure: the Conductor's own reconciliation pass is the correctness backstop for reaching `gate.met`, not this call. Fail-open: if the tool errors with an identity-unavailable message, you were not launched under the Conductor — skip it. Then proceed to Stage 3.\n\n3. **On required-subset failures detected**: Examine each failed **required** check's `detail_level` (non-required failures such as `pip-audit` are never processed here — they were already reported and skipped in item 2, and never consume a retry):\n\n - **`detail_level: \"full\"`** — Apply confidence gating:\n - Read the full `failure_details` payload for all failed checks.\n - If you are confident you can fix the errors, address ALL failures across all affected files in a single batch. Do not fix one at a time.\n - After applying all fixes, perform a single `git commit` and `git push`.\n - Increment `retry_count`.\n - If `retry_count` exceeds `max_retries`: if launched under the Conductor, call `check_messages` one final time. If the supervisor sent explicit \"continue\" guidance with a concrete hint, apply it for exactly **one additional batch** (this is the only way the ceiling is raised). Otherwise, stop the correction loop and proceed to Stage 3 with a warning.\n - Otherwise, update `commit_sha` to the new HEAD (`git rev-parse HEAD`) and restart the polling loop.\n - **`detail_level: \"url_only\"`** — Report the check name and URL to the user. Do not attempt fixes. Do not consume a retry.\n - **`detail_level: \"none\"`** — Report the check name only. Do not attempt fixes. Do not consume a retry.\n\n4. **Handle `unknown_checks`**: If the poll response contains `unknown_checks`, call `resolve_ci_checks` with `commit_ref` set to `commit_sha` and `force_rerun` set to `true` at most ONCE. If `unknown_checks` persist on the next poll, warn the user that the CI check configuration is unresolvable and skip to Stage 3.\n\n5. **Timeout**: If 10 minutes elapse without `all_complete` becoming `true`, warn that polling timed out and proceed to Stage 3.\n\nThis stage is **non-critical** — warn on failure or timeout, continue to Stage 3 regardless.\n\n## Stage 3 — Summary Report\n\nDisplay a structured completion report. The report **must** be presented as markdown, using exactly the structure below:\n\n```\n## CI Check Report\n\n**Ticket**: <ticket_key>\n**Branch**: <current_branch>\n**Commit SHA**: <commit_sha>\n**Status**: <Passed / Failed / Timed Out / Not Available>\n\n**Per-check breakdown**:\n| Check Name | Status | Required | Detail Level |\n|------------|--------|----------|--------------|\n| <name> | <pass/fail> | <yes/no> | <full/url_only/none> |\n\n**Review verdict**: <approved / changes_requested / not yet posted / N/A — claude-review not required>\n**Fixes attempted**: <retry_count> of <max_retries>\n**Supervisor guidance applied**: <yes/no>\n\n**Warnings**:\n<If any non-critical stages had warnings (Stage 1: resolution unavailable,\nStage 2: timeout, unfixable required-check failures, unknown_checks,\nnon-required check failures reported for visibility),\nlist them here. If no warnings, omit this section.>\n```\n\nThis stage is **non-critical** — display the report regardless.\n\n## Final Report\n\nOn success, display the structured report from Stage 3 confirming the CI check status, including per-check breakdown, fixes attempted, and any warnings from earlier stages.\n\nOn failure at any critical stage (Stage 0), display which stage failed and the error details.\n",
|
|
6
6
|
"clarify-ticket.md": "Generate clarifying questions for a Jira ticket and save them locally.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\n`$ARGUMENTS` is a required Jira ticket key (e.g., `PROJ-123`). This command generates clarifying questions for the ticket and saves them locally.\n\nIf any step fails, stop immediately and report which step failed and why.\n\n## Step 1 — Parse Arguments\n\n1. **Parse `$ARGUMENTS`**: Extract a required `ticket_key`, an optional `--second-opinion` flag, and an optional `--provider` flag.\n - Split `$ARGUMENTS` on whitespace.\n - If `--second-opinion` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `second_opinion_value`.\n - If `--second-opinion` appears without a provider name following it (or is the last token), set `second_opinion_value = \"auto\"`.\n - If `--second-opinion` is absent, set `second_opinion_value = null`.\n - If `--provider` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `provider_value`.\n - If `--provider` appears without a valid provider name following it (or is the last token), stop immediately and report: \"Usage error: --provider requires a provider name (openai, anthropic, or gemini).\"\n - If `--provider` is absent, set `provider_value = null`.\n - If both `--second-opinion` and `--provider` are present, `--second-opinion` takes precedence (set `provider_value = null`).\n - The remaining token (after removing flags and their arguments) is the `ticket_key`.\n\n2. **Validate ticket key format**: Confirm the ticket key matches the Jira key pattern `[A-Z][A-Z0-9]+-\\d+`. If it does not match, stop immediately and report: \"Invalid ticket key format. Expected a Jira key like PROJ-123.\"\n\n## Step 2 — Resolve Docs Directory\n\nCall the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n## Step 3 — Generate Clarifying Questions\n\nCall the `request_clarifying_questions` MCP tool with:\n- `ticket_number`: the validated `ticket_key`\n- `wait_for_result`: `true`\n- `save_locally`: `true`\n- `second_opinion`: set to `second_opinion_value` if non-null; omit entirely if null\n- `provider`: set to `provider_value` if non-null; omit entirely if null\n\nIf the tool returns an error, stop immediately and report: \"Clarifying questions generation failed.\" Include the error details.\n\n## Final Report\n\nOn successful completion, display:\n\n> **Ticket Key**: {ticket_key}\n>\n> **Local File Path**: {docs_dir}/clarifying-questions/{ticket_key}-clarifying-questions.md\n>\n> **Status**: The clarifying questions document has been saved locally. No changes were pushed to Jira.\n>\n> To incorporate these findings into the Jira ticket description, run: `/update-ticket {ticket_key}`\n",
|
|
7
|
-
"code-ticket.md": "# Code Ticket: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes a Jira ticket key (e.g., `BAPI-150`), downloads the AI-generated implementation plan and clarifying questions via MCP tools, then executes the plan step by step directly in the main conversation so all progress is visible.\n\nIf any critical stage fails (Stage 0, Stage 1, or Stage 3), stop immediately and report which stage failed and why. Non-critical stages (Stage 2) should log a warning but not stop the pipeline.\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline to implement a Jira ticket using an AI-generated plan. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a single required `ticket_key` argument. The expected format is a Jira ticket key such as `BAPI-150` or `PROJ-123` — one or more uppercase letters, a hyphen, and one or more digits (regex: `[A-Z]+-\\d+`). If `$ARGUMENTS` is empty or the value does not match the expected format, stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /code-ticket <ticket_key> (e.g., /code-ticket BAPI-150)\n ```\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Download Implementation Plan\n\nCall the `get_plan` MCP tool with:\n- `ticket_number`: the parsed `ticket_key` from Stage 0\n- `save_locally`: `true`\n\nInspect the response for errors. If the response text contains `NOT_FOUND` or `404` or indicates the plan was not found, stop immediately and display:\n\n```\nNo implementation plan found for <ticket_key>. Run `/plan-ticket <ticket_key>` first to generate one,\nor use the `request_plan_generation` MCP tool with `wait_for_result: true`.\n```\n\nOn success, read and internalize the full plan content. This is the plan you will execute in Stage 3.\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 2.\n\n## Stage 2 — Download Clarifying Questions\n\nCall the `get_clarifying_questions` MCP tool with:\n- `ticket_number`: the parsed `ticket_key` from Stage 0\n- `save_locally`: `false`\n\nIf the response contains `NOT_FOUND` or `404` or indicates no clarifying questions were found, log a warning note:\n\n```\nWarning: No clarifying questions found for <ticket_key>. Proceeding without supplementary context.\n```\n\nDo **NOT** stop the pipeline. Clarifying questions are supplementary context, not a hard prerequisite for implementation.\n\nOn success, internalize the clarifying questions content. Reference these for additional context where relevant to implementation steps — the answers provide supplementary guidance on requirements and technical decisions.\n\nThis stage is **non-critical** — warn on failure, continue to Stage 3 regardless.\n\n## Stage 3 — Execute Implementation Plan\n\nExecute the implementation plan step by step, directly in this conversation. Work inline so the user can see all progress and approve tool calls.\n\nFollow these rules:\n\n1. **Execute the plan in order.** Do not skip any steps, especially review steps involving test execution, lint checks, and architectural verification.\n2. **Make code changes** as directed by each step in the plan.\n3. **Run tests and checks** as specified in the plan's review steps.\n4. **Do NOT run `git commit` or `git push`.** Leave all changes uncommitted for developer review.\n5. **If a step is ambiguous or blocked**, note the issue clearly and continue with the next step rather than halting entirely.\n6. **Reference clarifying questions** (if retrieved in Stage 2) when they provide relevant context for a given step.\n\nThis stage is **critical** — if a blocking error prevents further progress, stop and report the failure.\n\n## Stage 4 — Final Summary Report\n\nDisplay a structured report after all stages complete:\n\n```\n## Implementation Complete\n\n**Ticket**: <ticket_key>\n\n**Developer Action Items**:\n- All changes are uncommitted. Review the changes with `git diff` before committing.\n- Run the project's test suite to verify nothing is broken before committing.\n\n**Warnings**:\n<If any non-critical stages had warnings (Stage 2: no clarifying questions),\nlist them here so the developer has full visibility. If no warnings, omit this section.>\n```\n\n## Final Report\n\nOn success, display the structured report from Stage 4 confirming that implementation of the ticket is complete.\n\nOn failure at any critical stage (Stage 0, Stage 1, or Stage 3), display which stage failed and the error details.\n",
|
|
7
|
+
"code-ticket.md": "# Code Ticket: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes a Jira ticket key (e.g., `BAPI-150`), downloads the AI-generated implementation plan and clarifying questions via MCP tools, then executes the plan step by step directly in the main conversation so all progress is visible.\n\nIf any critical stage fails (Stage 0, Stage 1, or Stage 3), stop immediately and report which stage failed and why. Non-critical stages (Stage 2) should log a warning but not stop the pipeline.\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline to implement a Jira ticket using an AI-generated plan. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a single required `ticket_key` argument. The expected format is a Jira ticket key such as `BAPI-150` or `PROJ-123` — one or more uppercase letters, a hyphen, and one or more digits (regex: `[A-Z]+-\\d+`). If `$ARGUMENTS` is empty or the value does not match the expected format, stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /code-ticket <ticket_key> (e.g., /code-ticket BAPI-150)\n ```\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Download Implementation Plan\n\nCall the `get_plan` MCP tool with:\n- `ticket_number`: the parsed `ticket_key` from Stage 0\n- `save_locally`: `true`\n\nInspect the response for errors. If the response text contains `NOT_FOUND` or `404` or indicates the plan was not found, stop immediately and display:\n\n```\nNo implementation plan found for <ticket_key>. Run `/plan-ticket <ticket_key>` first to generate one,\nor use the `request_plan_generation` MCP tool with `wait_for_result: true`.\n```\n\nOn success, read and internalize the full plan content. This is the plan you will execute in Stage 3.\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 2.\n\n## Stage 2 — Download Clarifying Questions\n\nCall the `get_clarifying_questions` MCP tool with:\n- `ticket_number`: the parsed `ticket_key` from Stage 0\n- `save_locally`: `false`\n\nIf the response contains `NOT_FOUND` or `404` or indicates no clarifying questions were found, log a warning note:\n\n```\nWarning: No clarifying questions found for <ticket_key>. Proceeding without supplementary context.\n```\n\nDo **NOT** stop the pipeline. Clarifying questions are supplementary context, not a hard prerequisite for implementation.\n\nOn success, internalize the clarifying questions content. Reference these for additional context where relevant to implementation steps — the answers provide supplementary guidance on requirements and technical decisions.\n\nThis stage is **non-critical** — warn on failure, continue to Stage 3 regardless.\n\n## Stage 3 — Execute Implementation Plan\n\nExecute the implementation plan step by step, directly in this conversation. Work inline so the user can see all progress and approve tool calls.\n\nFollow these rules:\n\n1. **Execute the plan in order.** Do not skip any steps, especially review steps involving test execution, lint checks, and architectural verification.\n2. **Make code changes** as directed by each step in the plan.\n3. **Run tests and checks** as specified in the plan's review steps.\n4. **Do NOT run `git commit` or `git push`.** Leave all changes uncommitted for developer review.\n5. **If a step is ambiguous or blocked**, note the issue clearly and continue with the next step rather than halting entirely.\n6. **Reference clarifying questions** (if retrieved in Stage 2) when they provide relevant context for a given step.\n7. **If a specific plan step or requirement remains ambiguous** after consulting the plan and any retrieved clarifying questions, call the `get_ticket` MCP tool with `ticket_number` set to the parsed `ticket_key` from Stage 0 to fetch the live Jira ticket details. Use only the fields relevant to resolving that ambiguity, then continue with the affected step. Do not call `get_ticket` unconditionally or as a prerequisite — only when a step's requirement is genuinely unclear.\n\nThis stage is **critical** — if a blocking error prevents further progress, stop and report the failure.\n\n## Stage 4 — Final Summary Report\n\nDisplay a structured report after all stages complete:\n\n```\n## Implementation Complete\n\n**Ticket**: <ticket_key>\n\n**Developer Action Items**:\n- All changes are uncommitted. Review the changes with `git diff` before committing.\n- Run the project's test suite to verify nothing is broken before committing.\n\n**Warnings**:\n<If any non-critical stages had warnings (Stage 2: no clarifying questions),\nlist them here so the developer has full visibility. If no warnings, omit this section.>\n```\n\n## Final Report\n\nOn success, display the structured report from Stage 4 confirming that implementation of the ticket is complete.\n\nOn failure at any critical stage (Stage 0, Stage 1, or Stage 3), display which stage failed and the error details.\n",
|
|
8
8
|
"commit-ticket.md": "# Commit Ticket: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes a Jira ticket key (e.g., `BAPI-150`), verifies the current git branch matches the ticket, identifies implementation files by cross-referencing git changes against the saved implementation plan, and commits and pushes the work. It is designed to run after `/code-ticket` completes.\n\nIf any critical stage fails (Stage 0, Stage 1, or Stage 3), stop immediately and report which stage failed and why. Non-critical stages (Stage 2, Stage 4, Stage 5, and Stage 6) should log a warning but not stop the pipeline.\n\n---\n\n# Instructions\n\nYou are executing a 7-stage pipeline to commit and push implementation work for a Jira ticket. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a single required `ticket_key` argument. The expected format is a Jira ticket key such as `BAPI-150` or `PROJ-123` — one or more uppercase letters, a hyphen, and one or more digits (regex: `[A-Z]+-\\d+`). If `$ARGUMENTS` is empty or the value does not match the expected format, stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /commit-ticket <ticket_key> (e.g., /commit-ticket BAPI-150)\n ```\n\n2. **Resolve docs directory**: Call the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n3. **Verify uncommitted changes exist**: Run `git status --porcelain` in the terminal. If the output is empty (no modified, added, or untracked files), stop immediately and display:\n\n ```\n No uncommitted changes found. Nothing to commit for <ticket_key>.\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Branch Verification and Creation\n\n1. **Get current branch**: Run `git branch --show-current` in the terminal. Store the result as `current_branch`.\n\n2. **Check branch match**: Determine if `current_branch` contains the `ticket_key` (case-insensitive comparison). For example, if the ticket key is `BAPI-150`, branch `feature/BAPI-150-add-caching` matches, as does `feature/BAPI-150` or `bugfix/bapi-150-fix`.\n\n3. **If the branch matches**: Log a confirmation message and proceed:\n\n ```\n Branch '<current_branch>' matches ticket <ticket_key>. Proceeding.\n ```\n\n4. **If the branch does NOT match**: Create a new branch from the current HEAD in the format `feature/<ticket_key>` (e.g., `feature/BAPI-150`). Run `git checkout -b feature/<ticket_key>` in the terminal. If the branch creation fails (e.g., branch already exists), try `git checkout feature/<ticket_key>` instead. If both fail, stop immediately and display:\n\n ```\n Failed to create or switch to branch 'feature/<ticket_key>'.\n Please resolve the branch situation manually and re-run.\n ```\n\n On success, log:\n\n ```\n Created and switched to new branch 'feature/<ticket_key>'.\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 2.\n\n## Stage 2 — Identify and Stage Implementation Files\n\n1. **Collect git changes**: Run `git status --porcelain` in the terminal. Parse the output to build two lists:\n - `modified_files`: files with status `M`, `MM`, `AM`, or `A` (modified or staged)\n - `untracked_files`: files with status `??` (new untracked files)\n\n Combine into a single list `all_changed_files`.\n\n2. **Load the implementation plan**: Look for the implementation plan file at `{docs_dir}/plans/{ticket_key}-plan.md`. Read the file.\n\n - **If the plan file exists**: Extract file paths mentioned in the plan. Look for patterns like backtick-quoted paths (e.g., `src/python/foo.py`), file references in step descriptions, and any explicit file listings. Build a list `plan_files` of all file paths referenced in the plan.\n\n - **If the plan file does NOT exist**: Log a warning:\n\n ```\n Warning: No implementation plan found at {docs_dir}/plans/{ticket_key}-plan.md.\n Cannot cross-reference changes against plan. Will present all changed files for review.\n ```\n\n Set `plan_files` to an empty list.\n\n3. **Classify changed files**: For each file in `all_changed_files`, classify it into one of three categories:\n\n - **Plan-matched**: The file path appears in `plan_files` (exact match or the plan references a parent directory). These are high-confidence implementation files.\n - **Likely related**: The file is not explicitly in the plan but is a test file for a plan-matched file, a migration file, an `__init__.py` in a directory with plan-matched files, or otherwise clearly related to the implementation (e.g., `requirements.txt` if the plan mentions adding a dependency).\n - **Ambiguous**: The file does not appear related to the plan. These may be pre-existing uncommitted changes.\n\n4. **Present file list for user confirmation**: Display the classified file list to the user:\n\n ```\n ## Files to Commit for <ticket_key>\n\n ### Plan-matched files (high confidence):\n - path/to/file1.py\n - path/to/file2.py\n\n ### Likely related files:\n - tests/pytest/routes/test_file1.py\n - db/alembic/versions/xxxx_migration.py\n\n ### Ambiguous files (not referenced in plan):\n - some/other/file.py\n\n Shall I proceed with committing all listed files?\n If you want to exclude any files, please specify which ones to remove.\n ```\n\n If `plan_files` is empty (plan not found), display all files under a single \"All changed files\" heading instead.\n\n5. **Wait for user confirmation**: The user may:\n - Approve all files (proceed)\n - Specify files to exclude (remove those from the commit list)\n - Cancel entirely (stop the pipeline)\n\n If the user cancels, stop immediately and display:\n\n ```\n Commit cancelled by user. No files were staged or committed.\n ```\n\n6. **Stage the approved files**: Run `git add <file1> <file2> ...` in the terminal, listing only the approved files explicitly. Do NOT use `git add -A` or `git add .`.\n\nThis stage is **non-critical** if the plan file is not found (warn and continue with all files). It is **critical** if the user cancels or if `git add` fails — stop immediately on those failures.\n\n## Stage 3 — Commit and Push\n\n1. **Generate commit message**: Based on the staged files and the implementation plan (if available), generate a concise commit message. The message must:\n - Start with a brief summary line (under 72 characters) that references the ticket key\n - Format: `<ticket_key>: <brief description of changes>`\n - Example: `BAPI-150: Add rate limiting to LLM client`\n - If the plan was available, derive the description from the plan's title or objective\n - If the plan was not available, summarize based on the file names and `git diff --staged` output\n\n2. **Commit**: Run `git commit -m \"<message>\"` in the terminal. If the commit fails due to a pre-commit hook, report the hook output and stop:\n\n ```\n Commit failed due to pre-commit hook. Hook output:\n <hook output>\n\n Please fix the issues and re-run /commit-ticket <ticket_key>.\n ```\n\n3. **Push to remote**: Run `git push -u origin <current_branch>` in the terminal. The `-u` flag sets up upstream tracking. If the push fails, stop immediately and display:\n\n ```\n Push failed. Error:\n <error output>\n\n The commit was created locally. You can push manually with:\n git push -u origin <current_branch>\n ```\n\nThis stage is **critical** — stop immediately on failure.\n\n## Stage 4 — Final Summary Report\n\nDisplay a structured report after all stages complete:\n\n```\n## Commit Complete\n\n**Ticket**: <ticket_key>\n**Branch**: <current_branch>\n**Commit**: <commit_hash> (from `git rev-parse --short HEAD`)\n**Files committed**: <count> files\n**Remote**: Pushed to origin/<current_branch>\n\n**Committed files**:\n- path/to/file1.py\n- path/to/file2.py\n- ...\n\n**Warnings**:\n<If any non-critical warnings occurred (Stage 2: plan not found),\nlist them here. If no warnings, omit this section.>\n```\n\nThis stage is **non-critical** — display the report regardless.\n\n## Stage 5 — Jira Status Transition\n\nThis stage attempts to transition the Jira ticket to the appropriate post-PR status.\n\n1. **Resolve target status**: Call the `resolve_target_status` MCP tool with `ticket_number` set to the `ticket_key`. This returns the cached or LLM-resolved target status for the project.\n\n2. **Attempt transition**: If `resolve_target_status` returned a non-null `target_status`, call the `update_jira_status` MCP tool with `ticket_number` set to the `ticket_key` and `target_status` set to the resolved value. If the ticket is already in the target status, this is a no-op.\n\n3. **On success**: Display `\"Ticket status updated: <from_status> -> <to_status>\"`.\n\n4. **On failure or not applicable**: Display a warning but do not stop the pipeline:\n - If `resolve_target_status` returned null: `\"Ticket status transition skipped: no target status configured for this project\"`\n - If `update_jira_status` failed: `\"Ticket status transition skipped: <error message>\"`\n\nThis stage is **non-critical** — log a warning on failure but do not stop the pipeline.\n\n## Stage 6 — Smoke Test Validation Comment\n\nThis stage reviews the implementation against the ticket requirements and posts a comment if manual validation is needed.\n\n1. **Fetch ticket description**: Call the `get_ticket` MCP tool with `ticket_number` set to the `ticket_key` to retrieve the current ticket requirements.\n\n2. **Review implementation**: Compare the implementation (from the plan loaded in Stage 2 and the files committed in Stage 3) against the ticket requirements. Identify any behavior or requirements that could NOT be validated through the automated tests written during implementation or through code review alone. Consider the limitations of any tests that were written: what functionality or behavior could not be validated by those tests? Examples include: requirements involving visual UI rendering or layout checks, third-party system integrations where mock tests are insufficient, or non-deterministic behaviors.\n\n3. **If untestable requirements exist**: Compose a structured comment describing specific manual validation steps stakeholders should perform. Then call the `add_comment` MCP tool with `ticket_number` set to the `ticket_key` and the comment text. Display: `\"Smoke test validation comment posted to <ticket_key>\"`.\n\n4. **If no untestable requirements exist**: Skip silently. Display: `\"No untestable requirements identified — skipping smoke test comment\"`.\n\nThis stage is **non-critical** — log a warning on failure but do not stop the pipeline.\n\n## Final Report\n\nOn success, display the structured report from Stage 4 confirming that the commit and push are complete, including the branch name, commit hash, file list, and any warnings from earlier stages.\n\nOn failure at any critical stage (Stage 0, Stage 1, or Stage 3), display which stage failed and the error details.\n",
|
|
9
9
|
"create-doc.md": "Generate a design document (TDD, FSD, or PRD) for a Jira ticket, wait for the result, and save it locally.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nExecute all steps in this command as a simple linear sequence of MCP tool calls.\n\n## Step 1 — Parse Arguments\n\n1. **Parse `$ARGUMENTS`**: Extract a required `ticket_key`, a required `--doc-type` flag, an optional `--second-opinion` flag, and an optional `--provider` flag.\n - Split `$ARGUMENTS` on whitespace.\n - If `--doc-type` appears followed by one of `tdd`, `fsd`, or `prd`, capture that as `doc_type`.\n - If `--doc-type` is absent, or is followed by anything other than `tdd`/`fsd`/`prd` (or is the last token), stop immediately and report: \"Usage error: --doc-type requires a document type (tdd, fsd, or prd).\"\n - If `--second-opinion` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `second_opinion_value`.\n - If `--second-opinion` appears without a provider name following it (or is the last token), set `second_opinion_value = \"auto\"`.\n - If `--second-opinion` is absent, set `second_opinion_value = null`.\n - If `--provider` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `provider_value`.\n - If `--provider` appears without a valid provider name following it (or is the last token), stop immediately and report: \"Usage error: --provider requires a provider name (openai, anthropic, or gemini).\"\n - If `--provider` is absent, set `provider_value = null`.\n - If both `--second-opinion` and `--provider` are present, `--second-opinion` takes precedence (set `provider_value = null`).\n - The remaining token (after removing flags and their arguments) is the `ticket_key`.\n\n2. **Validate ticket key format**: Confirm the ticket key matches the Jira key pattern `[A-Za-z][A-Za-z0-9]+-\\d+`. If it does not match (or `ticket_key` is empty or missing), stop immediately and display:\n\n ```\n Usage: /create-doc <ticket_key> --doc-type <tdd|fsd|prd> [--second-opinion [provider]] [--provider <name>] (e.g., /create-doc BAPI-150 --doc-type fsd)\n ```\n\n## Step 2 — Resolve Docs Directory\n\nCall the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n## Step 3 — Generate Design Document\n\nCall the `create_doc` MCP tool with:\n- `ticket_number`: the validated `ticket_key`\n- `doc_type`: the parsed `doc_type` (`tdd`, `fsd`, or `prd`)\n- `wait_for_result`: `true`\n- `save_locally`: `true`\n- `second_opinion`: set to `second_opinion_value` if non-null; omit entirely if null\n- `provider`: set to `provider_value` if non-null; omit entirely if null\n\nThis step may take 2-4 minutes while the backend processes the document.\n\nIf the tool returns an error, stop immediately and display:\n\n```\nDesign document generation failed: <error message from the tool>\n```\n\nIf generation did not finish, the document can be retrieved later with the `get_doc` MCP tool using the same `ticket_number` and `doc_type`.\n\n## Step 4 — Confirm Success\n\nResolve the local file path from `doc_type`:\n- `tdd` → `{docs_dir}/architecture/<ticket_key>-architecture-plan.md`\n- `fsd` → `{docs_dir}/fsd/<ticket_key>-fsd-plan.md`\n- `prd` → `{docs_dir}/prd/<ticket_key>-prd-plan.md`\n\nDisplay a confirmation message:\n\n```\nDesign document generated successfully for <ticket_key>\nSaved to: <local file path>\n```\n\n## Final Summary\n\nDisplay a summary block:\n\n```\n## Design Document Report\n\n- **Ticket**: <ticket_key>\n- **Doc Type**: <doc_type>\n- **Status**: Generated successfully\n- **Local File**: <local file path>\n```\n\nOn failure at any step, stop immediately, display which step failed and the error details, and do not proceed.\n",
|
|
10
10
|
"create-pr.md": "# Create PR: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes a Jira ticket key (e.g., `BAPI-150`), fetches the ticket summary, determines the base branch, and creates a pull request on the configured VCS provider. It is designed to run after `/commit-ticket` completes.\n\nIf any critical stage fails (Stage 0), stop immediately and report which stage failed and why. Non-critical stages (Stage 1 and Stage 2) should log a warning but not stop the pipeline.\n\n---\n\n# Instructions\n\nYou are executing a 3-stage pipeline to create a pull request for a Jira ticket. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a single required `ticket_key` argument. The expected format is a Jira ticket key such as `BAPI-150` or `PROJ-123` — one or more uppercase letters, a hyphen, and one or more digits (regex: `[A-Z]+-\\d+`). If `$ARGUMENTS` is empty or the value does not match the expected format, stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /create-pr <ticket_key> (e.g., /create-pr BAPI-150)\n ```\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\n3. **Get current branch**: Run `git branch --show-current` in the terminal. Store the result as `head_branch`. Verify that `head_branch` contains the `ticket_key` (case-insensitive comparison). If the branch does not contain the ticket key, stop immediately and display:\n\n ```\n Current branch '<head_branch>' does not contain ticket key <ticket_key>.\n Please switch to the correct feature branch before running /create-pr.\n ```\n\n4. **Resolve base branch**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `base_branch`. If the tool returns null, or an HTTP 400 Validation Error / Invalid field name, treat it as not set and fallback to `main`. Store the resolved value as `base_branch`.\n\n5. **Fetch ticket summary**: Call the `get_ticket` MCP tool with `ticket_number` set to the parsed `ticket_key`. Extract the ticket summary from the response. If the tool returns an error, log a warning and use a generic summary based on the ticket key.\n\n6. **Resolve docs directory**: Call the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Create Pull Request\n\n1. **Compose PR title**: Format the title as `<ticket_key>: <ticket_summary>`. Truncate to 72 characters if needed.\n\n2. **Compose PR body**: Build a PR body that includes:\n - A brief description derived from the ticket summary\n - A plain text reference to the local implementation plan: `Implementation Plan available locally at {docs_dir}/plans/{ticket_key}-plan.md` (do not use markdown hyperlink syntax — the local path is sufficient for team members pulling the branch)\n\n3. **Create the pull request**: Call the `create_pull_request` MCP tool with:\n - `head_branch`: the current branch from Stage 0\n - `base_branch`: the resolved base branch from Stage 0\n - `title`: the composed PR title\n - `body`: the composed PR body\n\n4. **Handle the response with graceful degradation**:\n - If the response contains `available: false`: Report the reason to the user and skip to Stage 2. Do not halt the pipeline.\n - If the response contains `created: false`: Log \"PR already exists\" and store the returned PR URL. Continue to Stage 2.\n - If the response contains `created: true`: Store the PR URL. Continue to Stage 2.\n - If an HTTP error occurs: Warn the user with the error details and continue to Stage 2. Do not halt the pipeline.\n\nThis stage is **non-critical** — warn on failure, continue to Stage 2 regardless.\n\n## Stage 2 — Summary Report\n\nDisplay a structured report after all stages complete:\n\n```\n## Pull Request Report\n\n**Ticket**: <ticket_key>\n**Branch**: <head_branch>\n**Base Branch**: <base_branch>\n**PR URL**: <pr_url or \"N/A — see warnings\">\n\n**Warnings**:\n<If any non-critical stages had warnings (Stage 1: PR creation failed or unavailable),\nlist them here. If no warnings, omit this section.>\n```\n\nThis stage is **non-critical** — display the report regardless.\n\n## Final Report\n\nOn success, display the structured report from Stage 2 confirming that the pull request was created (or already existed), including the branch name, base branch, PR URL, and any warnings from earlier stages.\n\nOn failure at any critical stage (Stage 0), display which stage failed and the error details.\n",
|
|
@@ -21,12 +21,14 @@ export const COMMANDS = {
|
|
|
21
21
|
"plan-ticket.md": "Generate an implementation plan for a Jira ticket, wait for the result, and save it locally.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nExecute all steps in this command as a simple linear sequence of MCP tool calls.\n\n## Step 1 — Parse Arguments\n\n1. **Parse `$ARGUMENTS`**: Extract a required `ticket_key`, an optional `--second-opinion` flag, and an optional `--provider` flag.\n - Split `$ARGUMENTS` on whitespace.\n - If `--second-opinion` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `second_opinion_value`.\n - If `--second-opinion` appears without a provider name following it (or is the last token), set `second_opinion_value = \"auto\"`.\n - If `--second-opinion` is absent, set `second_opinion_value = null`.\n - If `--provider` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `provider_value`.\n - If `--provider` appears without a valid provider name following it (or is the last token), stop immediately and report: \"Usage error: --provider requires a provider name (openai, anthropic, or gemini).\"\n - If `--provider` is absent, set `provider_value = null`.\n - If both `--second-opinion` and `--provider` are present, `--second-opinion` takes precedence (set `provider_value = null`).\n - The remaining token (after removing flags and their arguments) is the `ticket_key`.\n - If `ticket_key` is empty or missing, stop immediately and display:\n\n ```\n Usage: /plan-ticket <ticket_key> [--second-opinion [provider]] [--provider <name>] (e.g., /plan-ticket BAPI-150)\n ```\n\n## Step 2 — Resolve Docs Directory\n\nCall the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n## Step 3 — Generate Plan\n\nCall the `request_plan_generation` MCP tool with:\n- `ticket_number`: the parsed `ticket_key`\n- `wait_for_result`: `true`\n- `save_locally`: `true`\n- `second_opinion`: set to `second_opinion_value` if non-null; omit entirely if null\n- `provider`: set to `provider_value` if non-null; omit entirely if null\n\nThis step may take 1-5 minutes while the backend processes the plan.\n\nIf the tool returns an error, stop immediately and display:\n\n```\nPlan generation failed: <error message from the tool>\n```\n\n## Step 4 — Confirm Success\n\nDisplay a confirmation message:\n\n```\nPlan generated successfully for <ticket_key>\nSaved to: {docs_dir}/plans/<ticket_key>-plan.md\n```\n\n## Final Summary\n\nDisplay a summary block:\n\n```\n## Plan Generation Report\n\n- **Ticket**: <ticket_key>\n- **Plan Status**: Generated successfully\n- **Local File**: {docs_dir}/plans/<ticket_key>-plan.md\n```\n\nOn failure at any step, stop immediately, display which step failed and the error details, and do not proceed.\n",
|
|
22
22
|
"regression-check.md": "Run the deterministic regression-reviewer (lightweight mode) against a proposed code change and report its blast radius — which real call-sites, tests, mocks, or config the change does and doesn't account for.\n\n$ARGUMENTS\n\n---\n\n<!-- Platform coverage: this command reaches Cursor + Claude Code (the commands\n bundle is scaffolded to .claude/commands/ and .cursor/commands/ by --init).\n The companion `regression-reviewer` agent (agents/src/regression-reviewer.md)\n reaches Claude Code + GitHub Copilot. Union: Cursor, Copilot, and Claude\n Code all get this review, either via the command or the agent. -->\n\n# Instructions\n\nThis is the standalone diff/PR (or ticket-description) review entry point for the regression-reviewer (BAPI-460). It mirrors the `regression-reviewer` agent's orchestration exactly — same subcommand, same parsing, same report — so the same logical review behaves identically whether invoked as a Cursor command or a Claude Code agent.\n\n## Step 1 — Determine the Input Shape\n\nParse `$ARGUMENTS`:\n\n- If it looks like a git diff range, a ref, a PR number, or is empty (defaulting to the working tree vs. `HEAD`), treat this as a **diff/PR invocation**. Resolve a `--diff <range>` value when one is given (e.g. `main...HEAD`, a commit SHA range); omit `--diff` to use the default working-tree-vs-HEAD diff.\n- If it names specific function/class/symbol names (e.g. `--symbols resolve_db_params,SomeClass`, or prose describing a not-yet-diffed planned change), treat this as a **ticket-description invocation**. Extract the symbol names and pass them via `--symbols a,b,c`.\n\nIf neither a diff nor any extractable symbol names are available, stop and ask the user to provide one.\n\n## Step 2 — Run the Deterministic Core\n\nExecute exactly:\n\n```bash\nnpx -y @bridge_gpt/mcp-server regression-check --mode lightweight --json [--diff <range> | --symbols a,b,c]\n```\n\nDo NOT hand-roll your own `ast-grep`/`ripgrep` invocations or re-discover call-sites yourself — the subcommand owns that structural analysis.\n\n## Step 3 — Parse the Findings (Fail-Open)\n\nParse the JSON: `summary.symbols_analyzed`, `summary.truncated`, `summary.tools_used`, `summary.degraded_flags`, and the `findings` array (`symbol`, `file`, `definition_location`, `call_sites` (`count`, `by_file`), `broad_mentions`).\n\nIf `summary.degraded_flags` is non-empty (e.g. `ast-grep` or `ripgrep` was unavailable), do NOT treat the run as a failure. Proceed with whatever data IS present and call out each degraded section explicitly — never silently drop a gap. If `summary.truncated` is `true`, state that the symbol set was capped.\n\n**Ripgrep degradation formatting**: if any entry in `summary.degraded_flags` mentions ripgrep, render it with an action-first visual hierarchy of three scannable segments rather than as a plain sentence:\n1. **Status/Problem** — a warning header with a semantic warning indicator (e.g. ⚠️).\n2. **Root Cause** — a brief note that `rg` must be a real binary on `PATH`; a shell function/alias is invisible to the spawned subcommand.\n3. **Remediation** — a standalone, copy-pasteable install command (e.g. `brew install ripgrep`) on its own line.\n\nApply monospace typography (backticks) to every reference to a system command, CLI tool (`rg`), environment term (`PATH`), or installation package, in this warning and throughout the report.\n\n## Step 4 — Synthesize Risk\n\nFor each symbol, compare `call_sites.count` against `broad_mentions.length`:\n- **Accounted for**: every real call-site and broad mention is either already touched by the change or clearly unaffected (e.g. a doc/comment mention).\n- **Not accounted for**: a real call-site, or an uninspected broad mention, sits in a file the proposed change does not touch. Name the specific file.\n\nRank \"not accounted for\" items by how directly they call the changed symbol (a real call-site outranks a textual mention).\n\n## Step 5 — Propose De-Risking (Diagnostic Synthesis, Not a Patch)\n\nFor each \"not accounted for\" item, name ONE of:\n- **Update the affected caller**: point to the exact `file:line` and describe what needs to change there.\n- **Add a compatibility/guard seam**: when updating every caller isn't right (e.g. a public API, a config key read elsewhere), describe the seam needed — not its full implementation.\n\nDo NOT implement the fix. State what needs to happen and where.\n\n## Final Output\n\nPrint this report to chat (no file write required):\n\n```markdown\n# Regression Review: [Symbol(s) / Change Description]\n\n**Mode**: lightweight\n**Input**: [--diff <range> | --symbols a,b,c]\n**Tools used**: [summary.tools_used, joined]\n**Degraded**: [list summary.degraded_flags, or \"none\"]\n**Symbols analyzed**: [summary.symbols_analyzed.length][ — TRUNCATED, capped at N if summary.truncated]\n\n## Summary\n\n[2-3 sentences: overall risk level, how many symbols are fully accounted for vs. not, and any degraded-tool caveats.]\n\n## Systems Accounted For / Not Accounted For\n\nRender as a `.data-table`-style markdown table (bold header row; left-aligned `Symbol` / `File` columns; tight ✅/⚠️ status indicators):\n\n| Symbol | File | Real Call-Sites | Broad Mentions | Status |\n|---|---|---|---|---|\n| `helper` | `src/foo.py` | 3 | 4 | ⚠️ Not accounted for |\n| `caller` | `src/foo.py` | 1 | 1 | ✅ Accounted for |\n\nIf `definition_location` is `null` for a symbol, degrade gracefully — do not leave the `File` column blank. Render a muted `—` placeholder there instead.\n\n## De-Risking Guidance\n\n### 1. [Symbol / File]\n- **Issue**: [what's not accounted for, with file:line]\n- **Recommendation**: Update the affected caller at `file:line` | Add a compatibility/guard seam — [describe]\n\n[Continue for each not-accounted-for item]\n\n---\n\n*Generated by regression-check (lightweight mode). Structural findings via ast-grep + ripgrep; Pinecone semantic search not available.*\n```\n",
|
|
23
23
|
"reimplement-ticket.md": "# Reimplement Ticket: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command retrieves the reimplement context for a previously-implemented Jira ticket via MCP, then implements follow-up changes inline. Use this for small follow-up requests on tickets that have already been through the plan+implement cycle.\n\nIf any critical stage fails (Stage 0 or Stage 1), stop immediately and report which stage failed and why.\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline to implement follow-up changes on a Jira ticket using assembled reimplement context. Execute all stages in sequence.\n\n## Stage 0 — Setup and Argument Parsing\n\n1. **Parse `$ARGUMENTS`**: Extract a required `ticket_key`, an optional `--second-opinion` flag, and an optional `--provider` flag.\n - Split `$ARGUMENTS` on whitespace.\n - If `--second-opinion` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `second_opinion_value`.\n - If `--second-opinion` appears without a provider name following it (or is the last token), set `second_opinion_value = \"auto\"`.\n - If `--second-opinion` is absent, set `second_opinion_value = null`.\n - If `--provider` appears followed by a provider name (one of `openai`, `anthropic`, `gemini`), capture that provider as `provider_value`.\n - If `--provider` appears without a valid provider name following it (or is the last token), stop immediately and report: \"Usage error: --provider requires a provider name (openai, anthropic, or gemini).\"\n - If `--provider` is absent, set `provider_value = null`.\n - If both `--second-opinion` and `--provider` are present, `--second-opinion` takes precedence (set `provider_value = null`).\n - The remaining token (after removing flags and their arguments) is the `ticket_key`.\n - If `ticket_key` is empty or does not match the expected format (one or more uppercase letters, a hyphen, and one or more digits), stop immediately and display:\n\n ```\n Invalid ticket key format: '<value>'. Expected format: PROJ-123 (uppercase letters, hyphen, digits).\n Usage: /reimplement-ticket <ticket_key> [--second-opinion [provider]] [--provider <name>] (e.g., /reimplement-ticket BAPI-150)\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Request and Retrieve Reimplement Context\n\nCall the `request_reimplement_context` MCP tool with:\n- `ticket_number`: the parsed `ticket_key` from Stage 0\n- `wait_for_result`: `true`\n- `save_locally`: `true`\n- `second_opinion`: set to `second_opinion_value` if it is non-null; omit the parameter entirely if `second_opinion_value` is null\n- `provider`: set to `provider_value` if it is non-null; omit the parameter entirely if `provider_value` is null\n\nIf the tool returns an error or 404 persists after polling, stop immediately and display:\n\n```\nFailed to retrieve reimplement context for <ticket_key>.\nThis may mean:\n- The ticket has not been previously processed by Bridge API\n- Background processing failed — check server logs\n- The ticket does not exist in Jira\n\nTry running /plan-ticket <ticket_key> first if this is a new ticket.\n```\n\nOn success, read and internalize the returned context markdown. This document contains:\n- A summary of changes (if applicable)\n- New/changed information since last processing (comments, description changes, attachments)\n- The original ticket description\n- The existing implementation plan (at the bottom, for reference only)\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 2.\n\n## Stage 2 — Implement Follow-Up Changes\n\nExecute changes inline in this conversation. Work directly so the user can see all progress and approve tool calls.\n\nFollow these rules:\n\n1. **Focus on the new information.** The context document identifies what has changed since the last implementation. Focus your changes on addressing the new/changed requirements.\n2. **Reference the existing plan as supplementary guidance only.** The plan at the bottom of the context describes the original implementation, not the follow-up. Use it to understand the existing code structure, not as a step-by-step guide.\n3. **Make code changes** as directed by the new information.\n4. **Run tests and checks** to verify your changes don't break existing functionality.\n5. **Do NOT run `git commit` or `git push`.** Leave all changes uncommitted for developer review.\n6. **Scope guard**: If the follow-up changes are too large in scope (e.g., fundamentally restructuring the original implementation, touching more than 5-6 files, or requiring new infrastructure), stop and ask the user for guidance rather than attempting everything. Follow-up reimplementations should be small and targeted.\n7. **If a change is ambiguous or blocked**, note the issue clearly and continue with the next change rather than halting entirely.\n\nThis stage is **critical** — if a blocking error prevents further progress, stop and report the failure.\n\n## Stage 3 — Final Summary Report\n\nDisplay a structured report after all stages complete:\n\n```\n## Reimplement Complete\n\n**Ticket**: <ticket_key>\n\n**Changes Made**:\n- <brief summary of each change>\n\n**Developer Action Items**:\n- All changes are uncommitted. Review the changes with `git diff` before committing.\n- Run the project's test suite to verify nothing is broken before committing.\n\n**Warnings**:\n<If any issues arose during implementation (scope concerns, ambiguous requirements,\nfiles that couldn't be modified), list them here. If no warnings, omit this section.>\n```\n\n## Final Report\n\nOn success, display the structured report from Stage 3 confirming that the follow-up changes are complete.\n\nOn failure at any critical stage (Stage 0 or Stage 1), display which stage failed and the error details.\n",
|
|
24
|
+
"review-and-implement.md": "---\nschedulable: true\ninteractive: true\narguments: {\"positionals\":[{\"name\":\"ticketKey\",\"type\":\"string\",\"required\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"rounds\",\"flag\":\"--rounds\",\"type\":\"string\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"}]}\n---\n\n# Review and Implement: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command runs inside a single already-created worktree (typically spawned by `/start-tickets --workflow review-and-implement`, or its front door `/review-and-start`): it reviews the ticket via `/review-ticket`, pauses at a per-ticket human proceed/halt gate, and only then implements it via `/implement-ticket`. It creates no worktrees, refreshes no base branch, and does not monitor sibling sessions — those responsibilities stay in the launcher (`start-tickets`) and the parent front-door command.\n\n---\n\n# Instructions\n\n## Argument Parsing\n\nParse `$ARGUMENTS`:\n\n1. **Ticket key**: exactly one required token matching the Jira key pattern (`[A-Z][A-Z0-9]+-\\d+`). If zero tokens match, or more than one token matches, stop immediately and display:\n ```\n Invalid ticket key. Expected exactly one key, e.g. PROJ-123.\n Usage: /review-and-implement <ticket_key> [--auto] [--rounds=1|2] [--base-branch=BRANCH]\n ```\n2. **`--auto`**: an optional position-independent flag. When present, sets chain-level `auto_approve` to `true`. This single flag applies to BOTH the review phase and the implementation phase below — there is no separate review-auto or implementation-auto state.\n3. **`--rounds`**: an optional position-independent `--rounds <n>` / `--rounds=<n>` argument, `1` or `2`. Normalize either form to `--rounds=<n>`. Reject any other value:\n ```\n Invalid --rounds value. Expected: --rounds=1 or --rounds=2.\n Usage: /review-and-implement <ticket_key> [--auto] [--rounds=1|2] [--base-branch=BRANCH]\n ```\n When omitted, forward no `--rounds` to `/review-ticket` (the backend's difficulty-adaptive review policy decides the shape).\n4. **`--base-branch`**: an optional position-independent `--base-branch <branch>` / `--base-branch=<branch>` argument. Validate it using the same rules `/start-tickets` Stage 0 uses: after trimming, non-empty, at most 255 characters, must not start with `-`, and must not contain ASCII control characters (`0x00`–`0x1F` or `0x7F`). Reject a malformed value:\n ```\n Invalid --base-branch value: <reason>\n Usage: /review-and-implement <ticket_key> [--auto] [--rounds=1|2] [--base-branch=BRANCH]\n ```\n\n## Phase 1 — Review (inline)\n\nInvoke `/review-ticket <ticket_key>` **inline, in this same session**, forwarding:\n- `--auto` when chain-level `auto_approve` is `true`.\n- The normalized `--rounds=<n>` when `--rounds` was supplied.\n- `--base-branch=<branch>` when it was supplied.\n\n`/review-ticket` grounds its codebase evaluation against a **fresh `git archive` of `origin/<base>`**, materialized into an isolated temp directory via `materialize_fresh_base` (see `docs/BAPI-474-ground-review-against-fresh-base.md`) — NOT against this worktree's own working tree. Review therefore behaves identically whether run standalone or, as here, inside a worktree that `start-tickets` already created; the worktree's isolation exists for the implementation phase below, not for review's codebase grounding.\n\nIf the review pipeline itself fails (any step reports `Status: Failed at step N`), halt this ticket immediately — in **both** auto and non-auto mode — before Phase 2 or Phase 3 run. Report:\n```\nReview failed for <ticket_key> at step N. Implementation was not started.\n```\nDo not attempt any cleanup; the worktree/branch remains available for manual inspection or cleanup.\n\n## Phase 2 — Halt Gate\n\n`/review-ticket` produces **decisions that rewrite the ticket** — it does NOT emit a binary approve/decline verdict token. Do not parse, infer, or synthesize an approve/decline signal from its output; no such token exists to parse.\n\n- **When chain-level `auto_approve` is `true`** and Phase 1 completed successfully: skip this gate entirely and proceed straight to Phase 3.\n- **Otherwise** (non-auto, and Phase 1 completed successfully): after the ticket has been rewritten, ask the user exactly:\n ```\n Proceed to implementation for <ticket_key>? (y/N)\n ```\n Treat an empty response, any negative response (`n`, `no`, or similar), or any ambiguous/unrecognized response as **halt** — do not guess intent. On halt, report:\n ```\n Halted before implementation for <ticket_key> (declined). The worktree/branch remains available for manual cleanup.\n ```\n and stop. Do not perform Phase 3 or any cleanup.\n- On an explicit affirmative response (`y` or `yes`), proceed to Phase 3.\n\n## Phase 3 — Implement (inline)\n\nInvoke `/implement-ticket <ticket_key>` **inline, in this same session**, appending `--auto` when chain-level `auto_approve` is `true` (and omitting it on the manual-confirmation path). This is the same single chain-level `--auto` from Phase 1 — there is no separate implementation-only auto flag.\n\n## Scope\n\nThis command composes `/review-ticket` and `/implement-ticket`; it owns none of their internals and must not:\n- create, re-cut, or switch a Worktrunk worktree,\n- refresh or fetch the launcher's base branch,\n- monitor or coordinate with sibling `/review-and-implement` sessions spawned for other tickets,\n- orchestrate the parent `start-tickets` / `/review-and-start` session.\n\nA halt (review failure or a declined gate) affects **this ticket only** — sibling worktrees spawned for other keys are unaffected. Review and implementation share the single difficulty-derived model tier selected when this session was spawned by `start-tickets`; this command does not re-resolve or override model routing.\n",
|
|
25
|
+
"review-and-start.md": "---\nschedulable: true\narguments: {\"positionals\":[{\"name\":\"ticketKeys\",\"type\":\"string\",\"required\":true,\"variadic\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"rounds\",\"flag\":\"--rounds\",\"type\":\"string\"},{\"name\":\"agent\",\"flag\":\"--agent\",\"type\":\"string\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"},{\"name\":\"maxParallel\",\"flag\":\"--max-parallel\",\"type\":\"string\"},{\"name\":\"dryRun\",\"flag\":\"--dry-run\",\"type\":\"boolean\"}]}\n---\n\n# Review and Start: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes one or more Jira ticket keys (e.g., `BAPI-248` or `BAPI-248 BAPI-250` — both flow through the identical ordered `keys: string[]` path) and spawns one refreshed, self-contained Worktrunk worktree per ticket, each running `/review-and-implement <KEY>` — review, then a per-ticket human proceed/halt gate, then implementation. It is the **recommended front door** for chaining \"review these tickets, then implement the ones that pass\" starting from *existing ticket keys* (the entry point `/full-automation` lacks, since its server orchestrator only accepts an idea).\n\nIt is a thin shim over the packaged `start-tickets` CLI, invoked with `--workflow review-and-implement`: this command performs the same connectivity check and branch enrichment as `/start-tickets`, then hands off to the identical worktree/base-refresh/model-routing/credential/cross-platform-spawn/`doctor` engine — reused verbatim. The review→implement halt-gate decision logic lives entirely in the spawned `/review-and-implement` session, never here or in the CLI. Using `start-tickets --workflow review-and-implement` directly (documented in `commands/src/start-tickets.md`) remains available as the lower-level launcher seam this command drives.\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline that resolves connectivity and per-ticket branch names, then spawns N parallel Worktrunk worktrees via the packaged CLI's `--workflow review-and-implement` seam. Execute all stages in sequence directly in the main thread.\n\n## Stage 0 — Argument Parsing and Connectivity Check\n\n1. **Parse `$ARGUMENTS`** into ticket keys and pass-through flags:\n - **Ticket keys**: every whitespace-separated token matching `[A-Z]+-[0-9]+` (e.g., `BAPI-248`). A single key and multiple keys flow through the identical ordered `keys: string[]` path — there is no separate single-ticket code path. If zero keys are found, stop immediately and display:\n ```\n No ticket keys found in arguments. Expected one or more keys like BAPI-248.\n Usage: /review-and-start [flags] <KEY> [KEY ...] (e.g., /review-and-start BAPI-248 BAPI-250)\n ```\n - **`--auto`**: a single chain-level flag. When present, it is forwarded to `start-tickets --auto`, which threads it into BOTH the review and implementation phases of every spawned `/review-and-implement <KEY>` session.\n - **`--rounds`**: normalize `--rounds 1`/`--rounds=1` and `--rounds 2`/`--rounds=2` to `--rounds=<n>`; reject any other value. This value is forwarded to the review phase of every spawned session.\n - **Selected agent**: validate `--agent <name>` / `--agent=<name>` against `claude`/`cursor-agent` using the same rule as `/start-tickets`; default `claude`.\n - **User-supplied base branch**: validate `--base-branch <branch>` / `--base-branch=<branch>` using the same non-empty/≤255-character/no-leading-dash/no-control-character rules as `/start-tickets` Stage 0. A user-supplied value takes precedence over Stage 2a's `config_field` resolution below.\n - **`--max-parallel N`**: a positive integer; the CLI's own default (3) applies when omitted.\n - **`--dry-run`**: a boolean toggle.\n - Reject malformed input before proceeding: an unsupported flag, a ticket key not matching `[A-Z]+-[0-9]+`, an unsupported `--agent`/`--rounds`/`--base-branch` value — stop and report the malformed argument.\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Acknowledge CLI Pre-flight\n\nThe packaged `start-tickets` CLI (driven with `--workflow review-and-implement` in Stage 3) owns all platform pre-flight checks, refreshed worktree creation, secret-free credential provisioning, difficulty→model-tier routing, and cross-platform terminal spawning — identical to `/start-tickets`. This command does not duplicate or re-verify any of that; see `commands/src/start-tickets.md` Stage 1 for the full prerequisite/provisioning description it drives. This command does not expose `--conductor`, `--terminal`, or `--no-refresh-main`/`--no-refresh-base` — it stays scoped to the front-door flags listed above. Proceed to Stage 2.\n\n## Stage 2 — Resolve Base Branch + Enrich Branch Names (best-effort)\n\n### Stage 2a — Resolve Base Branch\n\nIdentical to `/start-tickets` Stage 2a: if the user supplied `--base-branch`, use it and skip the `config_field` lookup entirely. Otherwise call `config_field` (`operation: \"get\"`, `field_name: \"base_branch\"`) and treat a non-empty string `value` as the configured base branch; treat `null`, an empty/whitespace-only string, an HTTP `400` response, or any other lookup failure as \"unset\" and omit `--base-branch` from Stage 3 (the CLI then defaults to `main`). When forwarding a resolved value into the Stage 3 Bash invocation, apply the same mandatory single-quote escaping rule as `/start-tickets` (`'` → `'\\''`, then wrap the whole value in single quotes) before interpolating it into the command string — never expand it unquoted.\n\n### Stage 2b — Enrich Branch Names\n\nIdentical to `/start-tickets` Stage 2b: for each ticket key without a user-provided `--branch` override, call `get_ticket` (`ticket_number` set to the key, `save_locally: false`), slugify its `summary` (lowercase, collapse runs of `[^a-z0-9]+` to a single `-`, trim leading/trailing dashes, truncate to at most 40 characters preferring a dash boundary), and build `feature/<KEY>-<slug>`. On any per-key failure (404, network error, empty slug), emit a warning and let the CLI apply its default `feature/<KEY>` for that key only; never stop the pipeline. Credentials never reach the Bash-spawned CLI — this enrichment stays in the command, exactly as in `/start-tickets`.\n\nThis stage is **non-critical** — warnings are acceptable; the pipeline continues with the fallback branch for any key that fails enrichment.\n\n## Stage 3 — Invoke the Packaged CLI\n\nUse the **Bash tool** to invoke exactly **one** CLI invocation covering every requested key — never a per-key loop:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --workflow review-and-implement <pass-through-flags> <base-branch-flag> <branch-overrides> <ticket-keys>\n```\n\nWhere:\n- `<pass-through-flags>` forwards `--auto` (only if supplied), the normalized `--rounds=<n>` (only if supplied), `--agent <name>` (only if supplied), `--max-parallel N` (only if supplied), and `--dry-run` (only if supplied) verbatim.\n- `<base-branch-flag>` is `--base-branch '<escaped-value>'` only when a value was resolved in Stage 2a; otherwise omitted entirely.\n- `<branch-overrides>` is the list of `--branch KEY=BRANCH` flags assembled in Stage 2b.\n- `<ticket-keys>` is the original ordered list of keys parsed in Stage 0.\n\nCredentials are never placed in this shell command — the same secret-free provisioning path `/start-tickets` uses applies here unchanged.\n\nExample, single key, hands-off:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --workflow review-and-implement --auto --rounds=1 --branch BAPI-248=feature/BAPI-248-add-pr-rating-pre-evaluation-step BAPI-248\n```\n\nExample, multiple keys, manual per-ticket gate (no `--auto`):\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --workflow review-and-implement --branch BAPI-248=feature/BAPI-248-add-pr-rating-pre-evaluation-step --branch BAPI-250=feature/BAPI-250-deep-research-durability BAPI-248 BAPI-250\n```\n\nPass through the CLI's stdout and stderr to the user verbatim. If the CLI exits non-zero, treat that as a critical failure: report the exit code and the CLI's error output, and stop.\n\nThis stage is **critical** — propagate any non-zero exit from the packaged CLI.\n\n## Stage 4 — Final Report\n\nOnce the CLI exits 0, parse its `Summary` section (one stable line per ticket: `KEY branch=BRANCH status=STATUS`, optional trailing `path=PATH`) and reformat it as a markdown table, identical in shape to `/start-tickets` Stage 4 (`Ticket | Branch | Status`; statuses `dry-run`, `spawned`, `create-failed`, `spawn-failed`).\n\nThis report describes **worktree/spawn status only**. State explicitly in the report:\n- Each successfully spawned session independently continues through `/review-ticket`, its own per-ticket halt gate, and `/implement-ticket` — this parent session does not observe or report that later outcome. Never claim or imply that review or implementation has completed.\n- When `--dry-run` was passed, state explicitly that no worktrees were created and no tabs/sessions were opened.\n- As a fixed trade-off of this design: the difficulty-derived model tier selected at spawn time serves the **entire** chained review-and-implement session (both phases share one model), and a non-auto (including a non-auto scheduled) run pauses at each ticket's own gate rather than proceeding hands-off.\n\nIf the CLI reported any `create-failed`/`spawn-failed` statuses, or Stage 2b emitted enrichment warnings, list them under a `Warnings:` heading. If there were none, omit that section.\n\nSee `docs/claude/parallel-worktrees.md` for the underlying runbook this command builds on, and `commands/src/review-and-implement.md` for the per-ticket review→gate→implement composition each spawned session runs.\n",
|
|
24
26
|
"review-ticket.md": "---\nschedulable: true\ninteractive: true\narguments: {\"positionals\":[{\"name\":\"ticketKey\",\"type\":\"string\",\"required\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"rounds\",\"flag\":\"--rounds\",\"type\":\"string\"},{\"name\":\"noRefreshBase\",\"flag\":\"--no-refresh-base\",\"type\":\"boolean\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"},{\"name\":\"baseSha\",\"flag\":\"--base-sha\",\"type\":\"string\"}]}\n---\n\n# Review Ticket\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command is recipe-driven. Do not call MCP tools directly -- the recipe determines which tools to call and with what parameters.\n\n1. Parse `$ARGUMENTS` to extract:\n - A required `ticket_key` matching the Jira key pattern (`[A-Z][A-Z0-9]+-\\d+`).\n - An optional position-independent `--auto` flag.\n - An optional position-independent `--rounds=<n>` argument, where `<n>` is `1` or `2`.\n - An optional position-independent `--no-refresh-base` flag.\n - An optional position-independent `--base-branch=<branch>` argument.\n - An optional position-independent `--base-sha=<sha>` argument.\n\n Tokenize `$ARGUMENTS` on whitespace. The first token matching the Jira key pattern is the `ticket_key`; ignore any additional ticket-key tokens. The presence of a `--auto` token (anywhere in `$ARGUMENTS`) sets `auto_approve` to `true`. A token matching `--rounds=1` sets `rounds` to `1`; a token matching `--rounds=2` sets `rounds` to `2`. If no `--rounds` token is present, leave `rounds` unset (omitted) so the backend's difficulty-adaptive review policy can decide the review shape when enabled for this repo; when adaptive routing is disabled, unavailable, or the ticket's difficulty cannot be resolved, the backend falls back to a full premium second-opinion review. The presence of a `--no-refresh-base` token sets `no_refresh_base` to `true`. A token matching `--base-branch=<branch>` sets `base_branch` to `<branch>`. A token matching `--base-sha=<sha>` sets `base_sha` to `<sha>`.\n\n `--auto`, `--rounds`, `--no-refresh-base`, `--base-branch`, and `--base-sha` are all independent and may be supplied in any combination.\n\n If `$ARGUMENTS` is empty or contains no token matching the Jira key pattern, stop immediately and display:\n ```\n Invalid ticket key format. Expected: PROJ-123 [--auto] [--rounds=1|2] [--no-refresh-base] [--base-branch=BRANCH] [--base-sha=SHA]\n Usage: /review-ticket <ticket_key> [--auto] [--rounds=1|2] [--no-refresh-base] [--base-branch=BRANCH] [--base-sha=SHA]\n ```\n\n If a `--rounds` token is present but its value is not `1` or `2`, stop and display:\n ```\n Invalid --rounds value. Expected: --rounds=1 or --rounds=2 (omit to let the backend decide adaptively; default falls back to a full review)\n Usage: /review-ticket <ticket_key> [--auto] [--rounds=1|2] [--no-refresh-base] [--base-branch=BRANCH] [--base-sha=SHA]\n ```\n\n2. Call the `get_pipeline_recipe` MCP tool with:\n - `pipeline`: `\"review-ticket\"`\n - `variables`: `{ \"ticket_key\": \"<ticket_key>\", \"base_branch\": \"<base_branch or \"\">\", \"base_sha\": \"<base_sha or \"\">\", \"no_refresh_base\": \"<\"true\" if --no-refresh-base was passed, else \"\">\" }`\n - `auto_approve`: `true` — only when `--auto` was passed; otherwise omit this field entirely.\n - `rounds`: `1` — only when `--rounds=1` was explicitly passed on the command; `2` — only when `--rounds=2` was explicitly passed. When `--rounds` was NOT supplied, omit `rounds` entirely (do not pass `rounds: null`) so the backend's difficulty-adaptive review policy can choose the review shape when enabled for this repo. An explicit `rounds` value is forwarded to the backend and forces the review shape: `--rounds=1` requests a single-pass review, and `--rounds=2` forces the full second-opinion review even when adaptive routing is enabled. Do NOT translate `rounds` into `skip_steps` — the backend executor now owns all round orchestration (including any second-opinion rounds), so the recipe carries a single `request_ticket_review` step and you never pass `skip_steps` for round control.\n\n Example combined-mode payload (`--rounds=1 --auto --base-branch=develop`):\n ```json\n {\n \"pipeline\": \"review-ticket\",\n \"variables\": { \"ticket_key\": \"PROJ-123\", \"base_branch\": \"develop\", \"base_sha\": \"\", \"no_refresh_base\": \"\" },\n \"auto_approve\": true,\n \"rounds\": 1\n }\n ```\n\n Example explicit full-review payload (`--rounds=2`), which forces the full second-opinion review even if adaptive routing is enabled for this repo:\n ```json\n {\n \"pipeline\": \"review-ticket\",\n \"variables\": { \"ticket_key\": \"PROJ-123\", \"base_branch\": \"\", \"base_sha\": \"\", \"no_refresh_base\": \"\" },\n \"rounds\": 2\n }\n ```\n\n Example adaptive payload (no `--rounds`), which lets the backend policy executor decide the review shape (falling back to a full premium review when adaptive routing is disabled or the ticket's difficulty cannot be resolved):\n ```json\n {\n \"pipeline\": \"review-ticket\",\n \"variables\": { \"ticket_key\": \"PROJ-123\", \"base_branch\": \"\", \"base_sha\": \"\", \"no_refresh_base\": \"\" }\n }\n ```\n\n If the tool returns an error, stop and report the failure.\n\n3. Read and strictly obey the `agent_instructions` field in the response. Execute each step in order, announcing each as **Step N of M: <description>**.\n\n4. After all steps complete, display a summary:\n ```\n ## Pipeline Complete\n\n **Ticket**: <ticket_key>\n **Steps executed**: N of M\n **Status**: Success / Failed at step N\n ```\n",
|
|
25
27
|
"review-tickets.md": "---\nschedulable: true\ninteractive: true\narguments: {\"positionals\":[{\"name\":\"ticketKeys\",\"type\":\"string\",\"required\":true,\"variadic\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"rounds\",\"flag\":\"--rounds\",\"type\":\"string\"},{\"name\":\"review\",\"flag\":\"--review\",\"type\":\"string\",\"repeatable\":true},{\"name\":\"agent\",\"flag\":\"--agent\",\"type\":\"string\"},{\"name\":\"model\",\"flag\":\"--model\",\"type\":\"string\"},{\"name\":\"maxParallel\",\"flag\":\"--max-parallel\",\"type\":\"string\"},{\"name\":\"dryRun\",\"flag\":\"--dry-run\",\"type\":\"boolean\"},{\"name\":\"noRefreshBase\",\"flag\":\"--no-refresh-base\",\"type\":\"boolean\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"}]}\n---\n\n# Review Tickets: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes one or more Jira ticket keys and invokes the packaged `@bridge_gpt/mcp-server` CLI subcommand `review-tickets`, which opens one terminal tab per ticket running the selected agent with `/review-ticket <KEY> [--auto] [--rounds=<1|2>]`. By default `--rounds` is omitted so the backend routes each review by difficulty (difficulty-adaptive review); pass an explicit `--rounds=1|2` (globally or per ticket) to force the review shape. Unlike `/start-tickets`, it creates no Worktrunk worktrees — but it now requires `git` on PATH: the parent process fetches `origin/<base_branch>` once and pins a single `base_sha` for the whole batch before spawning tabs (BAPI-474), so every spawned review grounds its codebase evaluation against the same freshly-fetched base tree. Pass `--no-refresh-base` to skip this and restore the prior git-free, in-place-grounded behavior.\n\n---\n\n# Instructions\n\n## Stage 0 — Parse Arguments and Connectivity Check\n\n1. **Parse `$ARGUMENTS`** to extract ticket keys, review modes, and pass-through flags:\n\n - **Ticket keys**: every whitespace-separated token matching `[A-Z]+-[0-9]+` (e.g., `BAPI-1`). If zero keys are found, stop immediately and display:\n ```\n No ticket keys found. Expected one or more keys like BAPI-1.\n Usage: /review-tickets [flags] KEY [KEY ...]\n ```\n\n - **Review mode interpretation** (per ticket or global):\n - `auto` or `--auto` → per-ticket or global auto-approve flag.\n - `single-pass`, `one-pass`, `rounds=1`, or `--rounds=1` → `rounds=1` (single-pass review).\n - `full`, `two-pass`, `rounds=2`, or `--rounds=2` → `rounds=2` (full second-opinion review).\n - **omitted rounds → `adaptive`**: when no rounds mode is given for a ticket, do NOT choose a round count — leave it adaptive so the backend's difficulty-adaptive review policy decides the shape. `adaptive` is a distinct mode from `1` and `2`.\n - `--auto` and `--rounds` are independent: both may apply to the same ticket.\n\n The backend executor now owns all review round orchestration (including any second-opinion rounds) server-side — there is no client-side step to skip, so this command never sends `skip_steps` and never translates `--rounds=1` into skipping a second-opinion step. An explicit `--rounds` value forwarded to each spawned `/review-ticket` forces the review shape (`1` = single pass, `2` = full second-opinion review). A spawned `/review-ticket` invoked without any `--rounds` (the default) lets the backend's difficulty-adaptive review policy decide the shape (falling back to a full premium second-opinion review when adaptive routing is disabled, unavailable, or the ticket's difficulty cannot be resolved). This batch command therefore forwards **no** `--rounds` by default; it only forwards `--rounds` when the caller explicitly supplies a rounds mode (globally via `--rounds`, or per ticket via `--review`).\n\n - **Homogeneous modes**: when all tickets share the same auto and rounds mode, translate into global `--auto` (if all auto) and, only when all tickets share the same *explicit* rounds value, global `--rounds=1|2`. When all tickets are adaptive (no rounds given), omit `--rounds` entirely — do not synthesize a default.\n\n - **Heterogeneous modes**: when tickets differ in auto or rounds mode, translate into repeatable `--review KEY=auto,rounds=N` overrides. Only emit a `rounds=N` subtoken for tickets given an explicit `1`/`2`; adaptive tickets carry no `rounds` subtoken (a bare `--review KEY=auto` if they are auto, or no override at all). Do NOT set global `--auto` when only some tickets are auto-approved, and do NOT set global `--rounds` when only some tickets have an explicit rounds value.\n\n - **Pass-through flags**: collect `--dry-run`, `--max-parallel N`, `--agent claude|cursor-agent`, `--model VALUE`, `--no-refresh-base`, and `--base-branch VALUE` if supplied, and forward verbatim to the CLI.\n\n2. **Connectivity check**: Call the `ping` MCP tool. If it fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\n## Stage 1 — Invoke the Packaged CLI\n\nUse the **Bash tool** to invoke exactly one CLI invocation:\n\n```\nnpx -y @bridge_gpt/mcp-server review-tickets [--auto] [--rounds=1|2] [--review KEY=auto,rounds=N ...] [--agent <name>] [--model <alias>] [--max-parallel N] [--dry-run] [--no-refresh-base] [--base-branch BRANCH] KEY [KEY ...]\n```\n\n- `review-tickets` runs all tabs from the current repository cwd — it creates no worktrees.\n- The command never runs `wt` or `git-wt` — but it now requires `git` on PATH (BAPI-474): before spawning any tabs, the parent process fetches `origin/<base_branch>` once and pins a single `base_sha` for the whole batch, so a mid-batch `origin` advance can never mix bases within one run. Pass `--no-refresh-base` to skip the fetch and restore the prior git-free, in-place-grounded behavior.\n- Prerequisites: macOS `osascript` + `git`, Windows `wt.exe` or PowerShell + `git`, Linux `tmux` + `git` (git is not required when `--no-refresh-base` is passed).\n\nPass through the CLI's stdout and stderr verbatim. If the CLI exits non-zero, treat it as a critical failure and report the exit code and error output.\n\n## Stage 2 — Final Report\n\nOnce the CLI exits 0, parse its `Summary:` lines (each shaped like `KEY auto=<true|false> rounds=<1|2|adaptive> agent=<agent> model=<alias|default> status=<status>`) and render as a markdown table (`rounds=adaptive` means the backend chose the shape by difficulty):\n\n```\n| Ticket | Auto | Rounds | Agent | Model | Status |\n|----------|-------|----------|--------|---------|---------|\n| BAPI-1 | false | adaptive | claude | default | spawned |\n| BAPI-2 | true | 1 | claude | default | spawned |\n```\n\nRender any CLI `Warnings:` lines below the table. If there were none, omit the warnings section.\n",
|
|
26
28
|
"run-tests.md": "Run the project's full test suite (unit and E2E) using the project-configured test stacks, triage failures, fix test-code issues, and produce a structured health-check report.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command discovers how to run tests by reading per-project configuration from the Bridge API, not from hardcoded paths. Stages run only when the project has the corresponding stack configured.\n\n## Stage 0 — Argument Parsing and Setup\n\n1. **Parse `$ARGUMENTS`** for optional flags. Supported flags:\n - `--skip-e2e` — skip the E2E test stage even if an E2E stack is configured (e.g., when no local server is running)\n - `--unit-only` — shorthand that implies `--skip-e2e`\n\n Resolve flags to boolean variables:\n - Start with: `run_unit = true`, `run_e2e = true`\n - If `--unit-only` is present: set `run_e2e = false`\n - If `--skip-e2e` is present: set `run_e2e = false`\n - Unknown flags: note them in the final report as \"Unrecognized flag ignored\" but do not fail\n\n2. **Generate a run timestamp** using the current date and time in `YYYY-MM-DD-HH-MM` format (e.g., `2026-03-10-14-35`). Store this as `run_timestamp`. Both output documents will use this value.\n\nThis stage has no failure conditions — proceed to Stage 1.\n\n## Stage 1 — Resolve Project Config via MCP\n\nRead the per-project test setup from the Bridge database. Every subsequent stage is driven by what these calls return.\n\n1. **Resolve docs directory**: Call the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n2. **Read unit-test stack**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `unit_testing_stack`. Store the returned value as `unit_stack` (may be null/empty).\n\n3. **Read unit-test instructions**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `unit_testing_instructions`. Store the returned value as `unit_instructions` (may be null/empty).\n\n4. **Read E2E stack**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `e2e_testing_stack`. Store as `e2e_stack`.\n\n5. **Read E2E instructions**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `e2e_testing_instructions`. Store as `e2e_instructions`.\n\n6. **Compute configuration booleans**:\n - `unit_configured` = `true` if either `unit_stack` or `unit_instructions` is a non-empty string; otherwise `false`\n - `e2e_configured` = `true` if either `e2e_stack` or `e2e_instructions` is a non-empty string; otherwise `false`\n\n7. **Create the output directory**:\n ```\n mkdir -p {docs_dir}/testing/\n ```\n If this fails, stop immediately and report: `Cannot create output directory {docs_dir}/testing/ — check permissions.`\n\nIf any MCP call fails (e.g., the API is unreachable or returns 4xx/5xx), stop immediately and report which call failed. Do not fall back to hardcoded commands — the whole point of this command is that test setup lives in config.\n\n## Stage 2 — Unit / Standard Tests\n\nIf `run_unit` is `false`, skip this stage and record: `Unit tests: SKIPPED — run_unit was set to false (this should not happen in normal use; report as a bug).`\n\nIf `unit_configured` is `false`, skip and record:\n```\nUnit tests: SKIPPED — no unit_testing_stack or unit_testing_instructions configured for this repo. Configure via /learn-unit-testing or the project setup UI before running /run-tests.\n```\n\nOtherwise:\n\n1. Read `unit_instructions` carefully. It is the source of truth for **how to run unit tests in this repo** — runner binary, paths, environment activation, sub-suites (if the project distinguishes \"unit\" from \"integration\", both belong in this stage), and any flags. Pair it with `unit_stack` (a short label, e.g., `Pytest`, `Jest + React Testing Library`) for context.\n\n2. **Derive the test command(s)**: Extract the literal shell commands the instructions describe. If the instructions describe multiple sub-suites (e.g., a fast unit batch and a slower integration batch), plan to run each as a **separate batch** in the order described. Do not invent runners or paths that the instructions do not mention.\n\n3. **If the instructions do not specify any runnable command**, skip and record:\n ```\n Unit tests: SKIPPED — unit_testing_instructions does not describe how to invoke tests; please update via /learn-unit-testing.\n ```\n\n4. **Run each batch sequentially** in the terminal. **Continue to the next batch even if the current one has failures.** Capture the full output of each batch, including the runner's summary line (e.g., `47 passed, 3 failed in 12.4s` or `Tests: 5 failed, 22 passed`).\n\n5. For each failing test, apply the **Triage Logic** (below), then record the result.\n\n## Stage 3 — E2E Tests\n\nIf `run_e2e` is `false`, skip this stage and record: `E2E tests: SKIPPED — --skip-e2e or --unit-only flag was set.`\n\nIf `e2e_configured` is `false`, skip and record:\n```\nE2E tests: SKIPPED — no e2e_testing_stack or e2e_testing_instructions configured (the project may not have an E2E suite).\n```\n\nOtherwise:\n\n1. Read `e2e_instructions`. It is the source of truth for the E2E runner, spec paths, browser config, and any prerequisites. Pair with `e2e_stack` for context.\n\n2. **Detect server prerequisites**: If `e2e_instructions` indicates that a local server must be running (look for explicit cues such as \"server\", \"running\", \"localhost\", \"started\", \"dev server\", a URL, or a port number) and describes a readiness check, perform that check exactly as described. If the instructions describe a server prerequisite but do not describe a check, attempt the check the instructions imply (e.g., curl the URL the instructions mention) and skip the stage if it fails:\n ```\n E2E tests: SKIPPED — e2e_testing_instructions describe a server prerequisite that wasn't met. Start the server per the instructions and re-run.\n ```\n\n3. **Derive the test command(s)** from the instructions, including any spec-directory batching the instructions specify.\n\n4. **If the instructions do not specify any runnable command**, skip and record:\n ```\n E2E tests: SKIPPED — e2e_testing_instructions does not describe how to invoke tests; please update via /learn-e2e-testing.\n ```\n\n5. **Run each batch sequentially** in the terminal. **Continue to the next batch even if the current one has failures.** Capture the full output and summary line of each batch.\n\n6. For each failing test, apply the **Triage Logic** (below), then record the result.\n\n## Triage Logic\n\nFor every failing test, examine the test file and the code it tests. Classify as ONE of the following:\n\n### TEST-CODE ISSUE — fix it directly\n\nClassify as a test-code issue if ANY of the following applies:\n- The test asserts against a hardcoded value that no longer matches current behavior (outdated mock data)\n- The test imports or calls a function that was renamed, moved, or removed\n- The test asserts on a response field that was restructured\n- The test expects a specific error message string that has since changed\n- A fixture references a removed table column, model field, or schema member\n\n**Action**: Apply a minimal, targeted fix to the test file only. Then re-run just that failing test, using the runner described in the relevant instructions field (`unit_instructions` for unit-test failures, `e2e_instructions` for E2E failures). Adapt the runner invocation that the instructions provide to target a single test, following whatever convention the instructions or stack idiomatically use.\n\nIf the re-run **still fails** after your fix, do not make further edits — escalate to implementation-code issue instead and revert your change.\n\n### IMPLEMENTATION-CODE ISSUE (or UNCERTAIN) — document, do not fix\n\nClassify as an implementation issue if ANY of the following applies:\n- The production function raises an unexpected exception\n- A handler returns the wrong status code or response shape for a documented behavior\n- Business logic produces incorrect output that the test correctly asserts against\n- You are not confident the test is wrong\n\n**Action**: Do NOT modify any file outside the test directories described in `unit_testing_instructions` / `e2e_testing_instructions`. When in doubt about whether a path is test-only, treat it as production code and escalate. Record the failure in the implementation-issues document for the user to triage.\n\n## Stage 4 — Write Output Documents\n\n### Document 1: Test Run Report (always write this)\n\nWrite to: `{docs_dir}/testing/test-run-{run_timestamp}.md`\n\n```markdown\n# Test Run: {run_timestamp}\n\n## Configuration\n- Unit stack: {unit_stack or \"not configured\"}\n- E2E stack: {e2e_stack or \"not configured\"}\n- Unit tests: RUN | SKIPPED — (reason)\n- E2E tests: RUN | SKIPPED — (reason)\n\n## Unit Tests\n**Stack**: {unit_stack or \"not configured\"}\n**Result**: X passed, Y failed (sum across batches)\n\n### Batch 1: `<command>`\n**Result**: X passed, Y failed\n**Fixes applied**:\n- `path/to/test_file`: brief description of what was fixed\n- (or \"none\" if no fixes were needed)\n\n### Batch 2: `<command>`\n...\n\n**Failures escalated as implementation issues**: N\n\n## E2E Tests\n**Stack**: {e2e_stack or \"not configured\"}\n**Result**: X passed, Y failed (sum across batches)\n\n### Batch 1: `<command>`\n**Result**: X passed, Y failed\n**Fixes applied**: ...\n\n### Batch 2: `<command>`\n...\n\n**Failures escalated as implementation issues**: N\n\n## Overall Summary\n- Total test fixes applied: N\n- Suspected implementation issues found: N\n- Implementation issues document: {docs_dir}/testing/implementation-issues-{run_timestamp}.md\n (or \"not created — no issues found\")\n```\n\n### Document 2: Implementation Issues (only write if issues were found)\n\nIf at least one failure was escalated as an implementation-code issue, write to:\n`{docs_dir}/testing/implementation-issues-{run_timestamp}.md`\n\n```markdown\n# Suspected Implementation Issues: {run_timestamp}\n\nThese test failures were NOT fixed. They may indicate bugs in production code.\nA developer should investigate each item before merging.\n\n## Issue 1\n- **Test**: `path/to/test_file::test_function_name`\n- **Tier**: unit | e2e\n- **Failure message**: (paste the key assertion or exception line)\n- **Why not fixed**: (brief reasoning, e.g., \"production function raises KeyError on valid input\")\n\n## Issue 2\n...\n```\n\nIf no implementation issues were found, do NOT create this file.\n\n## Final Output\n\nAfter writing all documents, print this summary:\n\n```\nTest run complete: {run_timestamp}\nReport saved to: {docs_dir}/testing/test-run-{run_timestamp}.md\nImplementation issues: {docs_dir}/testing/implementation-issues-{run_timestamp}.md (if applicable)\nNo suspected implementation issues found. (if none)\n```\n",
|
|
27
|
-
"scan-test-coverage.md": "Scan recently shipped tickets from git history and report which features have or could gain integration tests, and which can only be smoke tested.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nScan the git history for recently shipped tickets and, for each shipped feature, determine whether it already has an integration test, whether it *could* gain one (per this repo's conventions — a test that genuinely executes the system end-to-end via real database operations, real LLM calls, or real FastAPI routing), and — where integration testing is not possible — how it could be smoke tested so it still genuinely executes the system.\n\nThis is an **investigation and discovery** command. Describe features (citing code) and *how* they would be tested at a high level. Do **not** design tests in detail, build or edit any tests, or modify feature code. Orchestrate this run in the main thread, and **fan out one subagent per shipped feature** for the per-feature investigation.\n\nThe report is written to a **durable, committed** directory (`docs/test-coverage/`), and a marker file records when the analysis last ran so subsequent runs only inspect git history since the last run.\n\n## Stage 0 — Parse Arguments and Resolve Analysis Window\n\n1. Read `$ARGUMENTS`. All flags are optional and default-safe. If a flag is malformed, ignore it and add a warning:\n - `--since=YYYY-MM-DD` — override the window start date.\n - `--full` — ignore the marker and use a default lookback of 6 months.\n - `--limit=N` — cap the number of features investigated (parse `N` as an integer; ignore if not a valid integer).\n With no arguments, run **incrementally** from the marker.\n\n2. Set the durable directory to `docs/test-coverage/` (relative to the repo root) and the marker file to `docs/test-coverage/STATE.md`. This command deliberately does **not** use `get_docs_dir` — its default (`docs/tmp`) is ephemeral, and this report must be durable.\n\n3. Read `docs/test-coverage/STATE.md` if it exists. It records two values: `last_run_utc` (an ISO-8601 UTC timestamp) and `last_analyzed_commit` (a git commit SHA).\n\n4. Resolve the analysis window with this precedence:\n - If `--since=YYYY-MM-DD` was given, use `git log --since=<date>`.\n - Else if `STATE.md` provides `last_analyzed_commit`, use the commit range `<last_analyzed_commit>..HEAD`.\n - Else (first run, no marker), default to `git log --since=<3 months ago>` (mirrors the `/scan-tickets` default of 3 months). Format the date as `YYYY-MM-DD`. Example: if today is 2026-07-07, the default `--since` is `2026-04-07`.\n - `--full` overrides the above and uses a 6-month lookback (`--since=<6 months ago>`).\n\n5. Robustness of the marker: capture `head_sha` by running `git rev-parse HEAD`, and capture the current UTC timestamp now. These become the **new** marker values, but only write them after the report is successfully produced (Stage 4). If a stored `last_analyzed_commit` is not present in history (e.g. a rebase/rewrite), fall back to `git log --since=<the date part of last_run_utc>` and add a warning noting the fallback.\n\n6. Initialize tracking variables:\n - `features` = [] (one entry per shipped feature)\n - `warnings` = [] (per-item failures and fallbacks; the run never aborts on these)\n\n7. Display the resolved window, e.g. \"Analyzing shipped features in `<range or --since date>` (HEAD = {head_sha})\".\n\n## Stage 1 — Collect Shipped Features from Git History\n\n1. List merged commits in the resolved window with:\n ```bash\n git log <range> --first-parent --pretty=format:\"%H|%h|%ad|%s\" --date=short\n ```\n `--first-parent` yields roughly one entry per squashed PR merge.\n\n2. For each commit, extract the ticket key by matching `^BAPI-[0-9]+` against the subject. Group commits by ticket key. Commits with no ticket prefix (e.g. `Fix 500 on ...`) each become a standalone feature labeled as an \"untracked change\".\n\n3. For each group, collect the changed-file footprint across its commit(s) using `git show --stat <sha>` or `git diff --name-only`. This file footprint is the primary input to the per-feature investigation.\n\n4. Best-effort enrichment: for each ticket key, call the `get_ticket` MCP tool to fetch the ticket summary. This is **fail-open** — Jira tokens can be expired — so on any error, add a warning and continue without the summary. Do not abort.\n\n5. Build a `features` entry per group: `{ticket_key, subject, commit_shas, changed_files, jira_summary?}`. If `--limit=N` was given, keep only the first `N` features (most recent first).\n\n6. Display: \"Found {count} shipped features to investigate.\"\n\n7. If `git log` returns no commits, skip to Stage 4 and write a report noting an empty window (and still refresh the marker).\n\n## Stage 2 — Investigate Each Feature (fan out subagents)\n\nFor each feature in `features`, launch an **Explore** subagent (batch several in parallel). Give each subagent the feature's `ticket_key`, `subject`, `changed_files`, and `jira_summary`, and instruct it to do read-only investigation only — no edits, no test design, no solutioning — and to return a structured finding.\n\nEach subagent must:\n\n1. Read the changed files and describe what the feature does in 2–4 sentences, with concrete `file:line` citations.\n\n2. Identify the feature's runtime surface — one or more of: real database operations (`postgres_client` / a DAL in `api/library/db/`), real LLM calls (`src/python/llms/ai_client.py`, `async_send_message_to_ai`), real FastAPI routing (a route handler under `api/routes/`), an MCP tool (`mcp_server/`), a shell-spawned / CLI flow, a frontend / Playwright surface, or pure logic / config / docs / tests.\n\n3. Check whether an **integration test already exists**: search `tests/integration/` for a mirror path or for references to the changed modules/functions. The reliable classifier is a path under `tests/integration/` plus `@pytest.mark.integration` or reliance on the `--run-integration` flag (conventions in `docs/claude/testing-integration.md`). Cite any test found.\n\n4. Classify the feature into exactly one `bucket`:\n - **`has_integration_test`** — already covered end-to-end; cite the existing integration test file.\n - **`integration_testable`** — no test yet, but the feature exercises real DB / LLM / routing and fits an existing `tests/integration/<area>/` pattern. Give a **high-level** approach only: which real entrypoint to call, which backend it would exercise, and the relevant cost/guard note (the gpt-5-nano override via `INTEGRATION_TEST_MODEL`; the local-DB `skipif` guard; `save_to_db=False`). Cite the entrypoint in code.\n - **`smoke_only`** — genuine end-to-end execution is possible but not as an automated integration test (e.g. MCP tool behavior inside a host, cross-platform terminal spawning, a headless agent session, or browser E2E). Describe how to smoke test it so it **genuinely executes the system**, citing the relevant runbook: `mcp_server/smoke-test/SMOKE-TEST.md`, `tests/mcp/`, `docs/claude/self-install-smoke-test.md`, `docs/claude/start-tickets-smoke-test.md`, or Playwright (`tests/playwright/`, which needs a running server plus `npm run build`).\n - **`not_testable`** — nothing to execute end-to-end (docs-only, a wording/comment change, pure config, or a test-only change); state why.\n\n5. Return a structured finding with these fields: `ticket_key`, `subject`, `description_with_cites`, `surface`, `bucket`, `existing_test`, `approach`, `why_not`.\n\nCollect all findings. If a per-feature subagent fails, add a warning and continue — never abort the whole run.\n\n## Stage 3 — Classify and Synthesize\n\n1. Deduplicate features that span multiple commits (merge by `ticket_key`).\n\n2. Sort each finding into the two required report sections:\n - **Section 1 — Integration Testing (covered or addable):** findings with `bucket` `has_integration_test` (sub-group \"Already covered\") or `integration_testable` (sub-group \"Could be added\").\n - **Section 2 — Not Integration-Testable:** findings with `bucket` `smoke_only` (sub-group \"Smoke-testable — how\") or `not_testable` (sub-group \"Not testable — why\").\n\n## Stage 4 — Write the Report and Update the Marker\n\n1. Create the `docs/test-coverage/` directory if it does not exist. Choose the report path `docs/test-coverage/REPORT-<YYYYMMDD>.md`; if a same-day file already exists, append `-<HHMMSS>` to avoid clobbering it.\n\n2. Write the report with this layout:\n - A title and a metadata block: generated-at UTC timestamp; the analysis window (`<from sha or since-date>` → `HEAD <head_sha>`); the feature count; and per-bucket tallies.\n - **Section 1 — Integration Testing: Covered or Addable.** One `### BAPI-NNN — <subject>` heading per feature, each with **What shipped** (with `file:line` citations), **Current coverage** (cite the existing integration test, or state \"none\"), and **How it could be integration tested (high level)**.\n - **Section 2 — Not Integration-Testable.** One heading per feature with the same feature description, plus **Why not integration-testable**, and — for `smoke_only` features — **How to smoke test (genuinely execute the system)** with the runbook citation.\n - A **Warnings** section listing each warning as a bullet — only if `warnings` is non-empty.\n\n3. **Only after** the report file is written successfully, update the marker `docs/test-coverage/STATE.md` with the new `last_run_utc` (the UTC timestamp captured in Stage 0) and `last_analyzed_commit` set to `head_sha`. This date/commit marker is what makes the next run incremental. If the report write fails, do not touch `STATE.md`.\n\n## Final Report\n\nPrint a short summary to chat:\n\n```\n**Test-coverage scan complete**\n\n* Features analyzed: {count}\n* Already covered by integration tests: {n_has}\n* Integration-testable (could be added): {n_addable}\n* Smoke-only: {n_smoke}\n* Not testable: {n_none}\n\nReport: docs/test-coverage/REPORT-<YYYYMMDD>.md\nMarker updated: last_analyzed_commit = {head_sha}\n```\n\nIf `warnings` is non-empty, add a \"Warnings:\" section listing each warning as a bullet. If there are no warnings, omit that section.\n",
|
|
29
|
+
"scan-test-coverage.md": "Scan recently shipped tickets from git history and report which features have or could gain integration tests, and which can only be smoke tested.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nScan the git history for recently shipped tickets and, for each shipped feature, determine whether it already has an integration test, whether it *could* gain one (per this repo's conventions — a test that genuinely executes the system end-to-end via real database operations, real LLM calls, or real FastAPI routing), and — where integration testing is not possible — how it could be smoke tested so it still genuinely executes the system.\n\nThis is an **investigation and discovery** command. Describe features (citing code) and *how* they would be tested at a high level. Do **not** design tests in detail, build or edit any tests, or modify feature code. Orchestrate this run in the main thread, and **fan out one subagent per shipped feature** for the per-feature investigation.\n\nThe report is written to a **durable, committed** directory (`docs/test-coverage/`), and a marker file records when the analysis last ran so subsequent runs only inspect git history since the last run.\n\n## Stage 0 — Parse Arguments and Resolve Analysis Window\n\n1. Read `$ARGUMENTS`. All flags are optional and default-safe. If a flag is malformed, ignore it and add a warning:\n - `--since=YYYY-MM-DD` — override the window start date.\n - `--full` — ignore the marker and use a default lookback of 6 months.\n - `--limit=N` — cap the number of features investigated (parse `N` as an integer; ignore if not a valid integer).\n With no arguments, run **incrementally** from the marker.\n\n2. Set the durable directory to `docs/test-coverage/` (relative to the repo root) and the marker file to `docs/test-coverage/STATE.md`. This command deliberately does **not** use `get_docs_dir` — its default (`docs/tmp`) is ephemeral, and this report must be durable.\n\n3. Read `docs/test-coverage/STATE.md` if it exists. It records two values: `last_run_utc` (an ISO-8601 UTC timestamp) and `last_analyzed_commit` (a git commit SHA).\n\n4. Resolve the analysis window with this precedence:\n - If `--since=YYYY-MM-DD` was given, use `git log --since=<date>`.\n - Else if `STATE.md` provides `last_analyzed_commit`, use the commit range `<last_analyzed_commit>..HEAD`.\n - Else (first run, no marker), default to `git log --since=<3 months ago>` (mirrors the `/scan-tickets` default of 3 months). Format the date as `YYYY-MM-DD`. Example: if today is 2026-07-07, the default `--since` is `2026-04-07`.\n - `--full` overrides the above and uses a 6-month lookback (`--since=<6 months ago>`).\n\n5. Robustness of the marker: capture `head_sha` by running `git rev-parse HEAD`, and capture the current UTC timestamp now. These become the **new** marker values, but only write them after the report is successfully produced (Stage 4). If a stored `last_analyzed_commit` is not present in history (e.g. a rebase/rewrite), fall back to `git log --since=<the date part of last_run_utc>` and add a warning noting the fallback.\n\n6. Initialize tracking variables:\n - `features` = [] (one entry per shipped feature)\n - `warnings` = [] (per-item failures and fallbacks; the run never aborts on these)\n\n7. Display the resolved window, e.g. \"Analyzing shipped features in `<range or --since date>` (HEAD = {head_sha})\".\n\n## Stage 1 — Collect Shipped Features from Git History\n\n1. List merged commits in the resolved window with:\n ```bash\n git log <range> --first-parent --pretty=format:\"%H|%h|%ad|%s\" --date=short\n ```\n `--first-parent` yields roughly one entry per squashed PR merge.\n\n2. For each commit, extract the ticket key by matching `^BAPI-[0-9]+` against the subject. Group commits by ticket key. Commits with no ticket prefix (e.g. `Fix 500 on ...`) each become a standalone feature labeled as an \"untracked change\".\n\n3. For each group, collect the changed-file footprint across its commit(s) using `git show --stat <sha>` or `git diff --name-only`. This file footprint is the primary input to the per-feature investigation.\n\n4. Best-effort enrichment: for each ticket key, call the `get_ticket` MCP tool to fetch the ticket summary. This is **fail-open** — Jira tokens can be expired — so on any error, add a warning and continue without the summary. Do not abort.\n\n5. Build a `features` entry per group: `{ticket_key, subject, commit_shas, changed_files, jira_summary?}`. If `--limit=N` was given, keep only the first `N` features (most recent first).\n\n6. Display: \"Found {count} shipped features to investigate.\"\n\n7. If `git log` returns no commits, skip to Stage 4 and write a report noting an empty window (and still refresh the marker).\n\n## Stage 2 — Investigate Each Feature (fan out subagents)\n\nFor each feature in `features`, launch an **Explore** subagent (batch several in parallel). Give each subagent the feature's `ticket_key`, `subject`, `changed_files`, and `jira_summary`, and instruct it to do read-only investigation only — no edits, no test design, no solutioning — and to return a structured finding.\n\nEach subagent must:\n\n1. Read the changed files and describe what the feature does in 2–4 sentences, with concrete `file:line` citations.\n\n2. Identify the feature's runtime surface — one or more of: real database operations (`postgres_client` / a DAL in `api/library/db/`), real LLM calls (`src/python/llms/ai_client.py`, `async_send_message_to_ai`), real FastAPI routing (a route handler under `api/routes/`), an MCP tool (`mcp_server/`), a shell-spawned / CLI flow, a frontend / Playwright surface, or pure logic / config / docs / tests.\n\n3. Check whether an **integration test already exists**: search `tests/integration/` for a mirror path or for references to the changed modules/functions. The reliable classifier is a path under `tests/integration/` plus `@pytest.mark.integration` or reliance on the `--run-integration` flag (conventions in `docs/claude/testing-integration.md`). Cite any test found.\n\n4. Classify the feature into exactly one `bucket`:\n - **`has_integration_test`** — already covered end-to-end; cite the existing integration test file.\n - **`integration_testable`** — no test yet, but the feature exercises real DB / LLM / routing and fits an existing `tests/integration/<area>/` pattern. Give a **high-level** approach only: which real entrypoint to call, which backend it would exercise, and the relevant cost/guard note (the gpt-5-nano override via `INTEGRATION_TEST_MODEL`; the local-DB `skipif` guard; `save_to_db=False`). Cite the entrypoint in code.\n - **`smoke_only`** — genuine end-to-end execution is possible but not as an automated integration test (e.g. MCP tool behavior inside a host, cross-platform terminal spawning, a headless agent session, or browser E2E). Describe how to smoke test it so it **genuinely executes the system**, citing the relevant runbook: `mcp_server/smoke-test/SMOKE-TEST.md`, `tests/mcp/`, `docs/claude/runbooks/self-install-smoke-test.md`, `docs/claude/runbooks/start-tickets-smoke-test.md`, or Playwright (`tests/playwright/`, which needs a running server plus `npm run build`).\n - **`not_testable`** — nothing to execute end-to-end (docs-only, a wording/comment change, pure config, or a test-only change); state why.\n\n5. Return a structured finding with these fields: `ticket_key`, `subject`, `description_with_cites`, `surface`, `bucket`, `existing_test`, `approach`, `why_not`.\n\nCollect all findings. If a per-feature subagent fails, add a warning and continue — never abort the whole run.\n\n## Stage 3 — Classify and Synthesize\n\n1. Deduplicate features that span multiple commits (merge by `ticket_key`).\n\n2. Sort each finding into the two required report sections:\n - **Section 1 — Integration Testing (covered or addable):** findings with `bucket` `has_integration_test` (sub-group \"Already covered\") or `integration_testable` (sub-group \"Could be added\").\n - **Section 2 — Not Integration-Testable:** findings with `bucket` `smoke_only` (sub-group \"Smoke-testable — how\") or `not_testable` (sub-group \"Not testable — why\").\n\n## Stage 4 — Write the Report and Update the Marker\n\n1. Create the `docs/test-coverage/` directory if it does not exist. Choose the report path `docs/test-coverage/REPORT-<YYYYMMDD>.md`; if a same-day file already exists, append `-<HHMMSS>` to avoid clobbering it.\n\n2. Write the report with this layout:\n - A title and a metadata block: generated-at UTC timestamp; the analysis window (`<from sha or since-date>` → `HEAD <head_sha>`); the feature count; and per-bucket tallies.\n - **Section 1 — Integration Testing: Covered or Addable.** One `### BAPI-NNN — <subject>` heading per feature, each with **What shipped** (with `file:line` citations), **Current coverage** (cite the existing integration test, or state \"none\"), and **How it could be integration tested (high level)**.\n - **Section 2 — Not Integration-Testable.** One heading per feature with the same feature description, plus **Why not integration-testable**, and — for `smoke_only` features — **How to smoke test (genuinely execute the system)** with the runbook citation.\n - A **Warnings** section listing each warning as a bullet — only if `warnings` is non-empty.\n\n3. **Only after** the report file is written successfully, update the marker `docs/test-coverage/STATE.md` with the new `last_run_utc` (the UTC timestamp captured in Stage 0) and `last_analyzed_commit` set to `head_sha`. This date/commit marker is what makes the next run incremental. If the report write fails, do not touch `STATE.md`.\n\n## Final Report\n\nPrint a short summary to chat:\n\n```\n**Test-coverage scan complete**\n\n* Features analyzed: {count}\n* Already covered by integration tests: {n_has}\n* Integration-testable (could be added): {n_addable}\n* Smoke-only: {n_smoke}\n* Not testable: {n_none}\n\nReport: docs/test-coverage/REPORT-<YYYYMMDD>.md\nMarker updated: last_analyzed_commit = {head_sha}\n```\n\nIf `warnings` is non-empty, add a \"Warnings:\" section listing each warning as a bullet. If there are no warnings, omit that section.\n",
|
|
28
30
|
"scan-tickets.md": "$ARGUMENTS\n\n---\n\n# Instructions\n\nSynchronize recently-updated Jira tickets with the local `tickets` database table and backfill missing workflow state timestamps. Perform all work directly in the main thread.\n\n## Stage 0 — Parse Arguments and Calculate Date\n\n1. Read the value of `$ARGUMENTS`. If it is empty, whitespace-only, or not a valid integer, default `months_back` to `3`. If it contains multiple tokens, extract only the first token and attempt to parse it as an integer. If parsing fails, default to `3`.\n\n2. Calculate `updated_since` by subtracting `months_back` months from today's date. Format the result as `YYYY-MM-DD`. Example: if today is 2026-03-07 and `months_back` is 3, then `updated_since` is 2025-12-07.\n\n3. Display the parsed values: \"Scanning tickets updated since {updated_since} (months_back = {months_back})\"\n\n4. Initialize the following tracking variables:\n - `tickets_scanned` = 0 (total tickets fetched from Jira)\n - `newly_tracked` = 0 (tickets inserted into database for the first time)\n - `state_updated_list` = [] (list of objects with ticket key and fields updated)\n - `warnings` = [] (list of warning strings for any per-ticket failures)\n\n## Stage 1 — Fetch All Tickets from Jira\n\n1. Initialize an empty list `all_tickets` and set `offset` to `0`.\n\n2. Enter a pagination loop:\n - Call the `get_tickets` MCP tool with: `updated_since` set to the calculated date, `limit` set to `100`, and `offset` set to the current offset value.\n - Parse the JSON response. The response contains a `tickets` array of ticket objects. Each ticket object has a `ticket_number` field (the Jira key, e.g., `BAPI-42`), along with `summary`, `status`, `issue_type`, `assignee`, and `updated_at`.\n - Append all tickets from the response's `tickets` array to `all_tickets`.\n - If the number of tickets returned in this page equals `100`, increment `offset` by `100` and repeat the loop.\n - If fewer than `100` tickets are returned, exit the loop.\n\n3. Set `tickets_scanned` to the length of `all_tickets`.\n\n4. Display: \"Fetched {tickets_scanned} tickets from Jira. Processing...\"\n\n5. If the `get_tickets` call fails at any point during pagination, **stop** and report the error. Do not proceed to Stage 2.\n\n## Stage 2 — Track Each Ticket\n\n1. Iterate over each ticket in `all_tickets`. For each ticket:\n - Call the `track_ticket` MCP tool with `ticket_number` set to the ticket's `ticket_number` field. If the ticket object includes a `summary` field, pass it as the `description` parameter.\n - Inspect the response message. If the response indicates the ticket was newly created/inserted (look for words like \"created\" or \"inserted\" in the message, as opposed to \"already exists\" or \"updated\"), increment `newly_tracked` by 1.\n - If the `track_ticket` call fails for this ticket, add a warning to the `warnings` list (e.g., \"Warning: Failed to track ticket {ticket_number}: {error}\") and **continue** to the next ticket. Do not abort the scan.\n\n2. Display a brief progress indicator every 25 tickets, e.g., \"Tracked {N} of {tickets_scanned} tickets...\"\n\n## Stage 3 — Detect and Backfill Workflow State\n\nDisplay: \"Checking workflow state for {tickets_scanned} tickets...\"\n\nIterate over each ticket in `all_tickets`. For each ticket (referenced by its `ticket_number` field), perform the following sub-steps. Wrap the entire per-ticket block in error handling: if the `get_ticket_state` call or the subsequent `update_ticket_state` call fails for a ticket, add a warning to `warnings` and continue to the next ticket.\n\n**Sub-step 4a — Retrieve current state**: Call the `get_ticket_state` MCP tool with `ticket_number` set to the ticket's key. The response contains:\n\n- Five timestamp fields (each is a timestamp string or null): `clarify_called`, `clarify_answered`, `critique_called`, `critique_answered`, `plan_generated`\n- Three boolean artifact flags: `has_clarifying_questions`, `has_critique`, `has_plan`\n\nIf the call returns a 404 or any error, add a warning to `warnings` and continue to the next ticket.\n\n**Sub-step 4b — Build fields_to_update list**: Initialize an empty `fields_to_update` list, then apply the following rules:\n\n- If `has_clarifying_questions` is `true` AND `clarify_called` is null -> add `\"clarify_called\"` to `fields_to_update`\n- If `has_clarifying_questions` is `true` AND `clarify_answered` is null -> add `\"clarify_answered\"` to `fields_to_update`\n- If `has_critique` is `true` AND `critique_called` is null -> add `\"critique_called\"` to `fields_to_update`\n- If `has_critique` is `true` AND `critique_answered` is null -> add `\"critique_answered\"` to `fields_to_update`\n- If `has_plan` is `true` AND `plan_generated` is null -> add `\"plan_generated\"` to `fields_to_update`\n\n**Sub-step 4c — Call update_ticket_state if needed**: If `fields_to_update` is non-empty, call the `update_ticket_state` MCP tool with `ticket_number` set to the ticket's key and `fields` set to the `fields_to_update` array. If this succeeds, add an entry to `state_updated_list` recording the ticket key and the list of fields that were set. If `update_ticket_state` fails, add a warning to `warnings` and continue.\n\nDisplay a progress indicator every 25 tickets that includes the current ticket key, e.g., \"Checked state for {TICKET-KEY} ({N} of {tickets_scanned} tickets)\"\n\n## Stage 4 — Report Summary\n\n1. Calculate `state_updated_count` as the length of `state_updated_list`.\n\n2. Display the summary:\n\n ```\n **Scan complete**\n\n * Tickets scanned: {tickets_scanned}\n * Newly tracked: {newly_tracked}\n * State updated: {state_updated_count}\n ```\n\n3. If `state_updated_list` is non-empty, display a section titled \"Updated tickets:\" with one bullet per ticket showing the ticket key and the comma-separated list of fields that were set. Example:\n\n ```\n Updated tickets:\n * BAPI-101: clarify_called, clarify_answered\n * BAPI-105: critique_called, critique_answered, plan_generated\n ```\n\n4. If the `warnings` list is non-empty, display a section titled \"Warnings:\" listing each warning string as a bullet. Example:\n\n ```\n Warnings:\n * Warning: Failed to track ticket BAPI-99: Connection timeout\n * Warning: State query failed for BAPI-112: SQL error\n ```\n\n5. If there are no warnings, do not display the \"Warnings:\" section.\n",
|
|
29
|
-
"start-tickets.md": "---\nschedulable: true\narguments: {\"positionals\":[{\"name\":\"ticketKeys\",\"type\":\"string\",\"required\":true,\"variadic\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"agent\",\"flag\":\"--agent\",\"type\":\"string\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"},{\"name\":\"maxParallel\",\"flag\":\"--max-parallel\",\"type\":\"string\"},{\"name\":\"dryRun\",\"flag\":\"--dry-run\",\"type\":\"boolean\"}]}\n---\n\n# Start Tickets: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes one or more Jira ticket keys (e.g., `BAPI-248 BAPI-250`) and invokes the packaged `@bridge_gpt/mcp-server` CLI subcommand `start-tickets`, which creates a Worktrunk worktree for each key and opens one tab/session per worktree running the **selected agent** — Claude Code (`claude`) by default, or Cursor Agent (`cursor-agent`) via `--agent` — in a macOS Terminal/iTerm tab, a Windows Terminal tab (or PowerShell fallback window), or a detached Linux tmux session, chosen automatically by platform. It replaces Parts 2–5 of `docs/claude/parallel-worktrees.md` with a single command.\n\nBecause the orchestration ships inside the `@bridge_gpt/mcp-server` npm package (not a repo-local script), this command works for every consumer — including projects that installed the package via `--init`.\n\nStage 0 and Stage 1 are critical (stop on failure). Stage 2 is non-critical (per-ticket enrichment failures fall back to the default branch and continue). Stage 3 is critical (propagate the packaged CLI's exit code).\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline that spawns N parallel Worktrunk worktrees and selected-agent sessions (Claude Code by default) via the packaged CLI. Execute all stages in sequence directly in the main thread.\n\n## Stage 0 — Argument Parsing and Connectivity Check\n\n1. **Parse `$ARGUMENTS`** into ticket keys, pass-through flags, and branch overrides:\n - **Ticket keys**: every whitespace-separated token matching `[A-Z]+-[0-9]+` (e.g., `BAPI-248`). If zero keys are found, stop immediately and display:\n\n ```\n No ticket keys found in arguments. Expected one or more keys like BAPI-248.\n Usage: /start-tickets [flags] <KEY> [KEY ...] (e.g., /start-tickets BAPI-248 BAPI-250)\n ```\n\n - **Pass-through flags**: collect any of `--agent <name>` (and the equals form `--agent=<name>`), `--terminal terminal|iterm`, `--dry-run`, `--auto`, `--no-refresh-main`, `--base-branch <branch>` (and the equals form `--base-branch=<branch>`), and `--max-parallel N` that the user supplied. These are forwarded verbatim to the CLI in Stage 3. `--auto` makes each spawned agent run `/implement-ticket <KEY> --auto` (hands-off implementation); omit it to keep the implementation agents interactive.\n - **Selected agent**: track a `selected_agent` variable that defaults to `claude`. If the user passed `--agent <name>` / `--agent=<name>`, validate the value against the supported agents `claude` and `cursor-agent`, set `selected_agent` to it, and reject any other (malformed/unsupported) `--agent` value before proceeding. The agent is not auto-detected from the host editor — the user selects it explicitly (default `claude`).\n - **User-supplied base branch**: track a `user_supplied_base_branch` boolean that defaults to `false`. If the user passed `--base-branch <branch>` or `--base-branch=<branch>`, set the boolean to `true` and capture the value. A user-supplied `--base-branch` value **takes precedence** over any value resolved from Bridge API config in Stage 2. Validate the user-supplied value before proceeding: after trimming surrounding whitespace it must be non-empty, at most 255 characters, must not start with `-`, and must not contain ASCII control characters (`0x00`–`0x1F` or `0x7F`); reject any malformed value with a clear error.\n - **User branch overrides**: collect any user-supplied repeatable `--branch KEY=BRANCH` flags. A user-provided override always takes precedence over Stage 2 enrichment for that key.\n - Reject malformed input before proceeding: if a token looks like a flag but is not one of the supported flags, or a ticket key does not match `[A-Z]+-[0-9]+`, or a `--branch` value is not `KEY=BRANCH`, or `--agent` names an agent other than `claude`/`cursor-agent`, or `--base-branch` fails the validation rules above, stop and report the malformed argument.\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Acknowledge CLI Pre-flight\n\nThe packaged CLI runs its own per-platform pre-flight checks and then fetches `origin` and fast-forwards the local **configured base branch** (the value resolved in Stage 2 below, or `main` when none is configured) from `origin/<base>` so the new worktrees are based on an up-to-date base. The historical flag `--no-refresh-main` still controls this behavior — the flag name is preserved for backward compatibility, but it now skips refresh of whatever base branch resolves (default `main`). The required commands depend on the OS:\n\n- **macOS**: `wt`, `git`, `osascript`.\n- **Windows**: `git-wt`, `git`, Git for Windows / Git Bash (Worktrunk runs its `pre-start` / `post-start` hooks via Git Bash), and Windows Terminal **or** PowerShell.\n- **Linux**: `wt`, `git`, `tmux`.\n\nOn **Windows** the Worktrunk binary is `git-wt` (its winget alias), which is a different tool from Windows Terminal's `wt.exe`: the CLI uses `git-wt` to **create worktrees** and `wt.exe` to **open a tab**, and never conflates the two. On **Linux** the CLI opens one detached `tmux` session per ticket (a window is added if that ticket's session already exists); attach later with `tmux attach -t <session>`. An unsupported OS (not macOS/Windows/Linux) fails fast with a clear \"unsupported platform\" message.\n\nThis stage simply notes that the CLI will fail fast if any prerequisite is missing or if local `main` has diverged from `origin/main` — you do not need to verify anything separately here, and you must not run any pre-flight commands yourself. When the CLI's pre-flight fails it now hints the user to run the read-only diagnostics command `npx -y @bridge_gpt/mcp-server doctor`, which reports found/missing for every prerequisite on the current OS — the pre-flight set plus `uv` plus the selected agent's command — and prints the manual install command for each missing one. `doctor` is strictly read-only and never installs anything; never run install commands automatically on the user's behalf. The CLI does not call any Bridge API tools; all credential-bearing work (branch enrichment in Stage 2) stays in this command. Proceed to Stage 2.\n\nThe packaged CLI also performs **secret-free Bridge API MCP provisioning** inside each created worktree: synchronously after the worktree is created and **before the agent tab/session is opened**, it writes both `.mcp.json` (Claude Code) and `.cursor/mcp.json` (Cursor) pointing at the `mcp-invoke` shim. These registrations are **secret-free** — they contain no `env` block and no API key, because the shim resolves credentials at runtime. If a spawned agent (or difficulty→model routing) reports missing Bridge API credentials, fix it by rerunning `/install-bridge` (its final stage persists the routing credential), by running `npx -y @bridge_gpt/mcp-server credentials migrate-agent-config --write-credentials` to migrate a key that lives only in `.mcp.json` / `.cursor/mcp.json`, or by adding a `bapi:<repo>` entry to the user-scoped credentials file (`~/.config/bridge/credentials.json`) — never by putting `BAPI_API_KEY` into the worktree `.mcp.json` or `.cursor/mcp.json` (that env is invisible to the Bash-spawned CLI).\n\nThis stage is **critical** in the sense that the CLI will abort if its pre-flight fails; you will see the error in Stage 3's output and must surface it.\n\n## Stage 2 — Resolve Base Branch + Enrich Branch Names (best-effort)\n\n### Stage 2a — Resolve configured `base_branch`\n\nThe CLI must be told which branch to cut new worktrees from. Resolution order:\n\n1. If `user_supplied_base_branch` from Stage 0 is `true`, **skip the config-field lookup entirely** and use the user-supplied value. The user's explicit `--base-branch` always wins; never call `config_field` for `base_branch` in that case.\n2. Otherwise, call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `base_branch` (do not pass any other parameters; the tool resolves the repository from the MCP server's configured `BAPI_REPO_NAME`).\n3. Parse the response. Treat the result as the **configured base branch** only when the response is a JSON object whose `value` field is a non-empty string after trimming surrounding whitespace.\n4. Treat **all** of the following as \"unset\" — emit a single-line warning like `Warning: base_branch is unset; CLI will default to main` and **omit** the `--base-branch` flag entirely from the Stage 3 command (the CLI's own default is `main`):\n - `value` is `null`.\n - `value` is an empty string or a whitespace-only string.\n - The endpoint returns HTTP `400` (invalid field — happens before the registry includes `base_branch`).\n - The tool returns a network error, timeout, or non-JSON parse failure.\n - Any other lookup failure.\n5. When the configured value is usable, capture it in a `resolved_base_branch` variable. **Do not** stop the pipeline on a lookup failure; fall through to the CLI default.\n\nWhen forwarding `resolved_base_branch` into the Bash invocation in Stage 3, **shell-escape it safely**: replace every literal single quote `'` in the value with the four-character sequence `'\\''`, then wrap the entire resulting string in single quotes (so the final argument looks like `'<escaped-value>'`). This is the standard POSIX single-quote escaping rule and is **mandatory** because `base_branch` is admin-configurable data that gets interpolated into a Bash command string; any unescaped single quote would otherwise break out of the surrounding quotes. Pass `--base-branch '<escaped-value>'` to the CLI as a single argv element — never expand the value unquoted into the command line.\n\n### Stage 2b — Enrich Branch Names\n\nBranch enrichment happens here, in the command, **before** invoking the CLI — the `get_ticket` MCP tool runs inside the MCP server process, which holds the Bridge API credentials the shell-spawned CLI does not have. For each parsed ticket key that does **not** already have a user-provided `--branch` override:\n\n1. Call the `get_ticket` MCP tool with `ticket_number` set to the key and `save_locally` set to `false`.\n2. From the response, extract the `summary` field. Slugify it: lowercase the string, replace every run of non-alphanumeric characters (`[^a-z0-9]+`) with a single dash `-`, trim leading and trailing dashes, and truncate to at most `40` characters (cutting at a dash boundary if possible).\n3. The enriched branch name is `feature/<KEY>-<slug>`. Example: `BAPI-248` with summary `\"Add PR rating pre-evaluation step\"` becomes `feature/BAPI-248-add-pr-rating-pre-evaluation-step` (trimmed at 40 chars).\n4. If the `get_ticket` call fails for a particular key (404, network error, missing summary) or produces an empty slug, emit a single-line warning like `Warning: could not enrich BAPI-248, falling back to feature/BAPI-248` and let the CLI apply its default `feature/<KEY>` for that key only. Do NOT stop the pipeline.\n5. Build a list of `--branch <KEY>=<BRANCH>` arguments — one entry per key whose enrichment succeeded — and merge it with any user-provided overrides from Stage 0. **Do not** call `get_ticket` for keys that already have a user-provided override; those overrides win.\n\nThis stage is **non-critical** — warnings are acceptable, the pipeline continues with the fallback default for any key that fails. Do not call the Bridge API from the CLI itself; the CLI never has credentials.\n\n## Stage 3 — Invoke the Packaged CLI\n\nUse the **Bash tool** to invoke the packaged CLI. Build the command line as:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets <pass-through-flags> <base-branch-flag> <branch-overrides> <ticket-keys>\n```\n\nWhere:\n- `<pass-through-flags>` are the supported flags collected in Stage 0 (`--agent`, `--terminal`, `--dry-run`, `--auto`, `--no-refresh-main`, `--max-parallel`), forwarded verbatim. Forward `--agent <name>` only if the user supplied it; otherwise omit it and the CLI defaults to `claude`. Forward `--auto` only if the user supplied it.\n- `<base-branch-flag>` is `--base-branch '<escaped-value>'` (single-quoted using the Stage 2a escaping rule) **only when** the user supplied `--base-branch` in Stage 0 **or** Stage 2a's `config_field` lookup returned a non-empty configured value. When the configured value is unset / lookup fails / user did not supply one, **omit this flag entirely** so the CLI's own default (`main`) takes effect.\n- `<branch-overrides>` is the list of `--branch KEY=BRANCH` flags assembled in Stage 2 (enrichment results merged with user overrides; omit any key whose enrichment failed and had no user override).\n- `<ticket-keys>` is the original list of ticket keys parsed in Stage 0, space-separated and in the original order.\n\nExample for two tickets after successful enrichment, throttled to 2 concurrent worktrees:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets \\\n --max-parallel 2 \\\n --branch BAPI-248=feature/BAPI-248-add-pr-rating-pre-evaluation-step \\\n --branch BAPI-250=feature/BAPI-250-deep-research-durability \\\n BAPI-248 BAPI-250\n```\n\nExample launching Cursor Agent instead of the default Claude Code:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --agent cursor-agent BAPI-248\n```\n\nExample cutting worktrees from a non-`main` base (either user-supplied via `--base-branch develop` in Stage 0 or resolved from Bridge API config in Stage 2a):\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --base-branch develop BAPI-248\n```\n\nPass through the CLI's stdout and stderr to the user verbatim. If the CLI exits non-zero, treat that as a critical failure: report the exit code and the CLI's error output, and stop.\n\nThis stage is **critical** — propagate any non-zero exit from the packaged CLI.\n\n## Stage 4 — Final Report\n\nOnce the CLI exits 0, parse its `Summary` section (one stable line per ticket in the form `KEY branch=BRANCH status=STATUS`, with an optional trailing `path=PATH`) and reformat it as a markdown table:\n\n```\n| Ticket | Branch | Status |\n|----------|-----------------------------------------------------|----------|\n| BAPI-248 | feature/BAPI-248-add-pr-rating-pre-evaluation-step | spawned |\n| BAPI-250 | feature/BAPI-250-deep-research-durability | spawned |\n```\n\nStatus values are `dry-run`, `spawned`, `create-failed`, and `spawn-failed`. End the report with the worktree-first explanation, rendered for the tracked `selected_agent`. When `selected_agent` is `claude` (the default):\n\n```\nThe CLI created/switched each Worktrunk worktree first (throttled by --max-parallel),\nthen opened one tab/session per successful worktree (macOS Terminal/iTerm tab, Windows\nTerminal tab or PowerShell window, or Linux tmux session). Each one runs\n`claude '/implement-ticket <KEY>'` inside its already-created worktree, which launches\nClaude Code with the starter prompt as its first message. Switch to each tab — or on\nLinux run `tmux attach -t <session>` — to monitor.\n```\n\nWhen `selected_agent` is `cursor-agent`, render the same explanation but with the Cursor handoff — do **not** claim it launches Claude Code:\n\n```\nThe CLI created/switched each Worktrunk worktree first (throttled by --max-parallel),\nthen opened one tab/session per successful worktree (macOS Terminal/iTerm tab, Windows\nTerminal tab or PowerShell window, or Linux tmux session). Each one runs\n`cursor-agent '/implement-ticket <KEY>'` inside its already-created worktree, which\nlaunches Cursor Agent with the starter prompt as its first message. Switch to each\ntab — or on Linux run `tmux attach -t <session>` — to monitor.\n```\n\nThe `/implement-ticket <KEY>` prompt is identical for both agents; only the launched command differs. When start-tickets was invoked with `--auto`, the spawned prompt is `/implement-ticket <KEY> --auto` (the implementation pipeline runs hands-off, without approval gates).\n\nIf the CLI reported any `create-failed` or `spawn-failed` statuses, or Stage 2 emitted any enrichment warnings, list them under a `Warnings:` heading at the bottom of the report. If there were none, omit that section.\n\nSee `docs/claude/parallel-worktrees.md` for the deep-dive runbook and the Worktrunk verification result behind this worktree-first model.\n\n## Difficulty-Based Implementation-Model Routing\n\nBefore launching the interactive agent for each ticket, the packaged CLI selects an\nimplementation **model tier** from the ticket's `difficulty` rating (1-10) and injects\nit as a `--model` flag at the agent spawn boundary. This happens entirely inside the\nCLI — it is **not** part of the server-side `/implement-ticket` recipe, because the\nmodel an interactive agent session uses is fixed at the moment the process is launched.\n\n- **Tier ladder (fixed):** `difficulty 1-2 → cheap`, `3-5 → basic`, `6+ → premium`.\n- **Separation of concerns:** the Python backend returns only the coarse tier\n (`cheap`/`basic`/`premium`) via `GET /jira/tickets/{KEY}/model-tier`; difficulty is\n computed on demand and cached when absent. The TypeScript CLI alone maps a tier to\n the agent-specific model alias (`claude`: `haiku`/`sonnet`/`opus`; `cursor-agent`:\n version-suffixed strings validated against `cursor-agent --list-models`).\n- **Per-repo config:**\n - `difficulty_model_routing_enabled` — boolean, **default ON**. Set to `false` to\n disable routing for a repo (the CLI then omits `--model`).\n - `difficulty_model_tier_overrides` — a JSON object mapping a tier name to a model\n alias (e.g. `{\"premium\": \"opus\"}`), **not** raw CLI arguments. Only `cheap`,\n `basic`, and `premium` keys are accepted; aliases must match `^[A-Za-z0-9._:-]+$`.\n- **Fail-open:** routing never aborts a spawn. Credential, network, config, or\n no-tier routing failures **assume a hard ticket and default to the premium/Opus\n tier** when the selected agent supports a valid premium alias; routing being\n disabled (`difficulty_model_routing_enabled = false`) or an agent that does not\n support `--model` instead omit `--model` so the agent runs on its own default\n model. Each degraded case is surfaced as exactly one secret-free, per-ticket\n routing-diagnostic line, never a hard failure.\n\n### Model routing credential\n\nDifficulty→model routing needs Bridge API credentials, and the shell-spawned\n`start-tickets` CLI is a **different runtime surface** from the MCP server: a\n`BAPI_API_KEY` that lives only in `.mcp.json` / `.cursor/mcp.json` is visible to\nthe MCP server but **not** to the Bash-spawned CLI, so routing silently degrades.\nThe durable source of truth both runtimes can resolve is the user-scoped store\n`~/.config/bridge/credentials.json`, keyed `bapi:<repo>`. If a routing-diagnostic\nline reports the credential is missing (e.g. difficulty resolves as `?`), fix it\nby any one of:\n\n1. Rerun `/install-bridge` — its final stage now persists the validated routing\n credential into `~/.config/bridge/credentials.json` via the\n `persist_routing_credential` tool.\n2. Migrate a key that lives **only** in `.mcp.json` / `.cursor/mcp.json` into the\n user-scoped store with the consent-gated, one-shot command:\n\n ```\n npx -y @bridge_gpt/mcp-server credentials migrate-agent-config --write-credentials\n ```\n\n3. Manually add `BAPI_API_KEY` under the `bapi:<repo>` target in the user-scoped\n store `~/.config/bridge/credentials.json`.\n\nNever put `BAPI_API_KEY` into a worktree `.mcp.json` / `.cursor/mcp.json` as a fix —\nthat env is invisible to the spawned CLI.\n\n## Conductor observability (opt-in via `--conductor`, BAPI-394)\n\nConductor is **opt-in**. By default `start-tickets` spawns the plain\n`cd <worktree> && <agent> '/implement-ticket <KEY> [--auto]'` — no\n`BAPI_CONDUCTOR_*` env, no supervisor window, and no message-relay instruction.\nPass `--conductor` (e.g. `/start-tickets --conductor BAPI-123`) to enable the\nConductor system below.\n\nWith `--conductor`, a run mints a single conductor `run_id` and attributes each\nworker's lifecycle events by `worker_id`, ticket key, and worktree path, and a\nsupervisor peer tab is opened. When the selected agent is **Claude Code**, the CLI\ninjects a conductor lifecycle hook into each created worktree's\n`.claude/settings.local.json` so the spawned session emits local `run.started` /\n`run.stopped` / `agent.notification` (and, when\n`BAPI_CONDUCTOR_ENABLE_PRE_TOOL_USE=1`, `tool.intent`) events into the local\nconductor ledger. These hooks apply **only** when the selected agent is Claude\nCode; other agents (e.g. `cursor-agent`) still participate in the run-level\n`run.started` event but receive no per-worktree Claude hook. Inspect the ledger\nwith the `conductor` CLI (e.g. `conductor doctor`). Conductor observability is\nbest-effort and never blocks or aborts a spawn.\n\nAlso under `--conductor`, each worker is launched with an explicit instruction to\ncall the `check_messages` MCP tool at checkpoints, so the supervisor can pass it\ntyped guidance mid-run (BAPI-397). Delivery is **cooperative** — the worker polls\nand acknowledges messages and they are never injected into a running session.\n(Epic-tick dispatch always runs with conductor enabled, independent of this\nuser-facing flag.)\n",
|
|
31
|
+
"start-tickets.md": "---\nschedulable: true\narguments: {\"positionals\":[{\"name\":\"ticketKeys\",\"type\":\"string\",\"required\":true,\"variadic\":true}],\"flags\":[{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"},{\"name\":\"agent\",\"flag\":\"--agent\",\"type\":\"string\"},{\"name\":\"workflow\",\"flag\":\"--workflow\",\"type\":\"string\"},{\"name\":\"rounds\",\"flag\":\"--rounds\",\"type\":\"string\"},{\"name\":\"baseBranch\",\"flag\":\"--base-branch\",\"type\":\"string\"},{\"name\":\"maxParallel\",\"flag\":\"--max-parallel\",\"type\":\"string\"},{\"name\":\"dryRun\",\"flag\":\"--dry-run\",\"type\":\"boolean\"}]}\n---\n\n# Start Tickets: $ARGUMENTS\n\n$ARGUMENTS\n\nThis command takes one or more Jira ticket keys (e.g., `BAPI-248 BAPI-250`) and invokes the packaged `@bridge_gpt/mcp-server` CLI subcommand `start-tickets`, which creates a Worktrunk worktree for each key and opens one tab/session per worktree running the **selected agent** — Claude Code (`claude`) by default, or Cursor Agent (`cursor-agent`) via `--agent` — in a macOS Terminal/iTerm tab, a Windows Terminal tab (or PowerShell fallback window), or a detached Linux tmux session, chosen automatically by platform. It replaces Parts 2–5 of `docs/claude/parallel-worktrees.md` with a single command.\n\nBecause the orchestration ships inside the `@bridge_gpt/mcp-server` npm package (not a repo-local script), this command works for every consumer — including projects that installed the package via `--init`.\n\nFor existing ticket keys, `/review-and-start <KEYS>` is the **recommended front door**: it supplies the same connectivity check and branch enrichment as this command, then drives this same packaged CLI with `--workflow review-and-implement` so each worktree reviews the ticket before implementing it. Using `start-tickets --workflow review-and-implement` directly (documented below) remains available as the lower-level launcher seam.\n\nStage 0 and Stage 1 are critical (stop on failure). Stage 2 is non-critical (per-ticket enrichment failures fall back to the default branch and continue). Stage 3 is critical (propagate the packaged CLI's exit code).\n\n---\n\n# Instructions\n\nYou are executing a 4-stage pipeline that spawns N parallel Worktrunk worktrees and selected-agent sessions (Claude Code by default) via the packaged CLI. Execute all stages in sequence directly in the main thread.\n\n## Stage 0 — Argument Parsing and Connectivity Check\n\n1. **Parse `$ARGUMENTS`** into ticket keys, pass-through flags, and branch overrides:\n - **Ticket keys**: every whitespace-separated token matching `[A-Z]+-[0-9]+` (e.g., `BAPI-248`). If zero keys are found, stop immediately and display:\n\n ```\n No ticket keys found in arguments. Expected one or more keys like BAPI-248.\n Usage: /start-tickets [flags] <KEY> [KEY ...] (e.g., /start-tickets BAPI-248 BAPI-250)\n ```\n\n - **Pass-through flags**: collect any of `--agent <name>` (and the equals form `--agent=<name>`), `--terminal terminal|iterm`, `--dry-run`, `--auto`, `--no-refresh-main`, `--base-branch <branch>` (and the equals form `--base-branch=<branch>`), and `--max-parallel N` that the user supplied. These are forwarded verbatim to the CLI in Stage 3. `--auto` makes each spawned agent run the selected workflow's slash command with `--auto` (hands-off); omit it to keep the spawned agents interactive.\n - **Selected agent**: track a `selected_agent` variable that defaults to `claude`. If the user passed `--agent <name>` / `--agent=<name>`, validate the value against the supported agents `claude` and `cursor-agent`, set `selected_agent` to it, and reject any other (malformed/unsupported) `--agent` value before proceeding. The agent is not auto-detected from the host editor — the user selects it explicitly (default `claude`).\n - **Selected workflow**: track a `selected_workflow` variable that defaults to `implement`. If the user passed `--workflow <value>` or `--workflow=<value>`, validate it against the two allowed values `implement` and `review-and-implement`, set `selected_workflow`, and reject any other value with the allowlist in the error. `implement` (the default) preserves today's behavior byte-for-byte — each spawned worktree runs `/implement-ticket <KEY> [--auto]`. `review-and-implement` spawns `/review-and-implement <KEY> [--auto] [--rounds=<n>]` instead, which runs `/review-ticket` then, after a per-ticket halt gate, `/implement-ticket` inside the same session. A single chain-level `--auto` applies to the selected workflow as a whole — under `review-and-implement` it auto-approves both the review and the implementation phase.\n - **Review rounds**: track a `review_rounds` value that defaults to unset. If the user passed `--rounds <n>` or `--rounds=<n>`, normalize it to `--rounds=1` or `--rounds=2` (reject any other value). `--rounds` is **review-only**: reject it (after parsing all flags, so flag order does not matter) if the final `selected_workflow` is not `review-and-implement`.\n - **User-supplied base branch**: track a `user_supplied_base_branch` boolean that defaults to `false`. If the user passed `--base-branch <branch>` or `--base-branch=<branch>`, set the boolean to `true` and capture the value. A user-supplied `--base-branch` value **takes precedence** over any value resolved from Bridge API config in Stage 2. Validate the user-supplied value before proceeding: after trimming surrounding whitespace it must be non-empty, at most 255 characters, must not start with `-`, and must not contain ASCII control characters (`0x00`–`0x1F` or `0x7F`); reject any malformed value with a clear error.\n - **User branch overrides**: collect any user-supplied repeatable `--branch KEY=BRANCH` flags. A user-provided override always takes precedence over Stage 2 enrichment for that key.\n - Reject malformed input before proceeding: if a token looks like a flag but is not one of the supported flags, or a ticket key does not match `[A-Z]+-[0-9]+`, or a `--branch` value is not `KEY=BRANCH`, or `--agent` names an agent other than `claude`/`cursor-agent`, or `--workflow` names anything other than `implement`/`review-and-implement`, or `--rounds` is used outside `review-and-implement` or names anything other than `1`/`2`, or `--base-branch` fails the validation rules above, stop and report the malformed argument.\n\n2. **Connectivity check**: Call the `ping` MCP tool (no parameters). If the ping fails or does not return `\"status\": \"ok\"`, stop immediately and display:\n\n ```\n Connectivity check failed. Please verify:\n - Check that the Bridge API MCP server is configured in your editor's MCP settings\n - Check that BAPI_BASE_URL is set and the server is reachable\n - Check that BAPI_API_KEY is valid\n - Check that BAPI_REPO_NAME matches a configured repository\n ```\n\nThis stage is **critical** — stop immediately on failure. Do not proceed to Stage 1.\n\n## Stage 1 — Acknowledge CLI Pre-flight\n\nThe packaged CLI runs its own per-platform pre-flight checks and then fetches `origin` and fast-forwards the local **configured base branch** (the value resolved in Stage 2 below, or `main` when none is configured) from `origin/<base>` so the new worktrees are based on an up-to-date base. The historical flag `--no-refresh-main` still controls this behavior — the flag name is preserved for backward compatibility, but it now skips refresh of whatever base branch resolves (default `main`). The required commands depend on the OS:\n\n- **macOS**: `wt`, `git`, `osascript`.\n- **Windows**: `git-wt`, `git`, Git for Windows / Git Bash (Worktrunk runs its `pre-start` / `post-start` hooks via Git Bash), and Windows Terminal **or** PowerShell.\n- **Linux**: `wt`, `git`, `tmux`.\n\nOn **Windows** the Worktrunk binary is `git-wt` (its winget alias), which is a different tool from Windows Terminal's `wt.exe`: the CLI uses `git-wt` to **create worktrees** and `wt.exe` to **open a tab**, and never conflates the two. On **Linux** the CLI opens one detached `tmux` session per ticket (a window is added if that ticket's session already exists); attach later with `tmux attach -t <session>`. An unsupported OS (not macOS/Windows/Linux) fails fast with a clear \"unsupported platform\" message.\n\nThis stage simply notes that the CLI will fail fast if any prerequisite is missing or if local `main` has diverged from `origin/main` — you do not need to verify anything separately here, and you must not run any pre-flight commands yourself. When the CLI's pre-flight fails it now hints the user to run the read-only diagnostics command `npx -y @bridge_gpt/mcp-server doctor`, which reports found/missing for every prerequisite on the current OS — the pre-flight set plus `uv` plus the selected agent's command — and prints the manual install command for each missing one. `doctor` is strictly read-only and never installs anything; never run install commands automatically on the user's behalf. The CLI does not call any Bridge API tools; all credential-bearing work (branch enrichment in Stage 2) stays in this command. Proceed to Stage 2.\n\nThe packaged CLI also performs **secret-free Bridge API MCP provisioning** inside each created worktree: synchronously after the worktree is created and **before the agent tab/session is opened**, it writes both `.mcp.json` (Claude Code) and `.cursor/mcp.json` (Cursor) pointing at the `mcp-invoke` shim. These registrations are **secret-free** — they contain no `env` block and no API key, because the shim resolves credentials at runtime. If a spawned agent (or difficulty→model routing) reports missing Bridge API credentials, fix it by rerunning `/install-bridge` (its final stage persists the routing credential), by running `npx -y @bridge_gpt/mcp-server credentials migrate-agent-config --write-credentials` to migrate a key that lives only in `.mcp.json` / `.cursor/mcp.json`, or by adding a `bapi:<repo>` entry to the user-scoped credentials file (`~/.config/bridge/credentials.json`) — never by putting `BAPI_API_KEY` into the worktree `.mcp.json` or `.cursor/mcp.json` (that env is invisible to the Bash-spawned CLI).\n\nThis stage is **critical** in the sense that the CLI will abort if its pre-flight fails; you will see the error in Stage 3's output and must surface it.\n\n## Stage 2 — Resolve Base Branch + Enrich Branch Names (best-effort)\n\n### Stage 2a — Resolve configured `base_branch`\n\nThe CLI must be told which branch to cut new worktrees from. Resolution order:\n\n1. If `user_supplied_base_branch` from Stage 0 is `true`, **skip the config-field lookup entirely** and use the user-supplied value. The user's explicit `--base-branch` always wins; never call `config_field` for `base_branch` in that case.\n2. Otherwise, call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `base_branch` (do not pass any other parameters; the tool resolves the repository from the MCP server's configured `BAPI_REPO_NAME`).\n3. Parse the response. Treat the result as the **configured base branch** only when the response is a JSON object whose `value` field is a non-empty string after trimming surrounding whitespace.\n4. Treat **all** of the following as \"unset\" — emit a single-line warning like `Warning: base_branch is unset; CLI will default to main` and **omit** the `--base-branch` flag entirely from the Stage 3 command (the CLI's own default is `main`):\n - `value` is `null`.\n - `value` is an empty string or a whitespace-only string.\n - The endpoint returns HTTP `400` (invalid field — happens before the registry includes `base_branch`).\n - The tool returns a network error, timeout, or non-JSON parse failure.\n - Any other lookup failure.\n5. When the configured value is usable, capture it in a `resolved_base_branch` variable. **Do not** stop the pipeline on a lookup failure; fall through to the CLI default.\n\nWhen forwarding `resolved_base_branch` into the Bash invocation in Stage 3, **shell-escape it safely**: replace every literal single quote `'` in the value with the four-character sequence `'\\''`, then wrap the entire resulting string in single quotes (so the final argument looks like `'<escaped-value>'`). This is the standard POSIX single-quote escaping rule and is **mandatory** because `base_branch` is admin-configurable data that gets interpolated into a Bash command string; any unescaped single quote would otherwise break out of the surrounding quotes. Pass `--base-branch '<escaped-value>'` to the CLI as a single argv element — never expand the value unquoted into the command line.\n\n### Stage 2b — Enrich Branch Names\n\nBranch enrichment happens here, in the command, **before** invoking the CLI — the `get_ticket` MCP tool runs inside the MCP server process, which holds the Bridge API credentials the shell-spawned CLI does not have. For each parsed ticket key that does **not** already have a user-provided `--branch` override:\n\n1. Call the `get_ticket` MCP tool with `ticket_number` set to the key and `save_locally` set to `false`.\n2. From the response, extract the `summary` field. Slugify it: lowercase the string, replace every run of non-alphanumeric characters (`[^a-z0-9]+`) with a single dash `-`, trim leading and trailing dashes, and truncate to at most `40` characters (cutting at a dash boundary if possible).\n3. The enriched branch name is `feature/<KEY>-<slug>`. Example: `BAPI-248` with summary `\"Add PR rating pre-evaluation step\"` becomes `feature/BAPI-248-add-pr-rating-pre-evaluation-step` (trimmed at 40 chars).\n4. If the `get_ticket` call fails for a particular key (404, network error, missing summary) or produces an empty slug, emit a single-line warning like `Warning: could not enrich BAPI-248, falling back to feature/BAPI-248` and let the CLI apply its default `feature/<KEY>` for that key only. Do NOT stop the pipeline.\n5. Build a list of `--branch <KEY>=<BRANCH>` arguments — one entry per key whose enrichment succeeded — and merge it with any user-provided overrides from Stage 0. **Do not** call `get_ticket` for keys that already have a user-provided override; those overrides win.\n\nThis stage is **non-critical** — warnings are acceptable, the pipeline continues with the fallback default for any key that fails. Do not call the Bridge API from the CLI itself; the CLI never has credentials.\n\n## Stage 3 — Invoke the Packaged CLI\n\nUse the **Bash tool** to invoke the packaged CLI. Build the command line as:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets <pass-through-flags> <base-branch-flag> <branch-overrides> <ticket-keys>\n```\n\nWhere:\n- `<pass-through-flags>` are the supported flags collected in Stage 0 (`--agent`, `--terminal`, `--dry-run`, `--auto`, `--no-refresh-main`, `--max-parallel`), forwarded verbatim. Forward `--agent <name>` only if the user supplied it; otherwise omit it and the CLI defaults to `claude`. Forward `--auto` only if the user supplied it.\n- Forward `--workflow <selected_workflow>` only when the user explicitly passed `--workflow`; otherwise omit it and the CLI defaults to `implement`. Forward the normalized `--rounds=<n>` from Stage 0 only when the user supplied it (which Stage 0 already guarantees is only possible under `review-and-implement`).\n- `<base-branch-flag>` is `--base-branch '<escaped-value>'` (single-quoted using the Stage 2a escaping rule) **only when** the user supplied `--base-branch` in Stage 0 **or** Stage 2a's `config_field` lookup returned a non-empty configured value. When the configured value is unset / lookup fails / user did not supply one, **omit this flag entirely** so the CLI's own default (`main`) takes effect.\n- `<branch-overrides>` is the list of `--branch KEY=BRANCH` flags assembled in Stage 2 (enrichment results merged with user overrides; omit any key whose enrichment failed and had no user override).\n- `<ticket-keys>` is the original list of ticket keys parsed in Stage 0, space-separated and in the original order.\n\nExample for two tickets after successful enrichment, throttled to 2 concurrent worktrees:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets \\\n --max-parallel 2 \\\n --branch BAPI-248=feature/BAPI-248-add-pr-rating-pre-evaluation-step \\\n --branch BAPI-250=feature/BAPI-250-deep-research-durability \\\n BAPI-248 BAPI-250\n```\n\nExample launching Cursor Agent instead of the default Claude Code:\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --agent cursor-agent BAPI-248\n```\n\nExample cutting worktrees from a non-`main` base (either user-supplied via `--base-branch develop` in Stage 0 or resolved from Bridge API config in Stage 2a):\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --base-branch develop BAPI-248\n```\n\nExample using the lower-level review-and-implement workflow directly (the `/review-and-start` command is the recommended front door for this; this form is documented here as the advanced launcher seam it drives):\n\n```\nnpx -y @bridge_gpt/mcp-server start-tickets --workflow review-and-implement --auto --rounds=2 BAPI-248\n```\n\nPass through the CLI's stdout and stderr to the user verbatim. If the CLI exits non-zero, treat that as a critical failure: report the exit code and the CLI's error output, and stop.\n\nThis stage is **critical** — propagate any non-zero exit from the packaged CLI.\n\n## Stage 4 — Final Report\n\nOnce the CLI exits 0, parse its `Summary` section (one stable line per ticket in the form `KEY branch=BRANCH status=STATUS`, with an optional trailing `path=PATH`) and reformat it as a markdown table:\n\n```\n| Ticket | Branch | Status |\n|----------|-----------------------------------------------------|----------|\n| BAPI-248 | feature/BAPI-248-add-pr-rating-pre-evaluation-step | spawned |\n| BAPI-250 | feature/BAPI-250-deep-research-durability | spawned |\n```\n\nStatus values are `dry-run`, `spawned`, `create-failed`, and `spawn-failed`. This table (and the report as a whole) describes **worktree/spawn status only** — it must never claim that review or implementation itself has completed; that work happens later, independently, inside each spawned session.\n\nCompute `spawned_command` from `selected_workflow`: `/implement-ticket <KEY>` when `implement` (the default), or `/review-and-implement <KEY>` when `review-and-implement`. Append `--auto` when the user passed it, and (workflow `review-and-implement` only) append the normalized `--rounds=<n>` when the user supplied `--rounds`. End the report with the worktree-first explanation, rendered for the tracked `selected_agent` and `spawned_command`. When `selected_agent` is `claude` (the default):\n\n```\nThe CLI created/switched each Worktrunk worktree first (throttled by --max-parallel),\nthen opened one tab/session per successful worktree (macOS Terminal/iTerm tab, Windows\nTerminal tab or PowerShell window, or Linux tmux session). Each one runs\n`claude '<spawned_command>'` inside its already-created worktree, which launches\nClaude Code with the starter prompt as its first message. Switch to each tab — or on\nLinux run `tmux attach -t <session>` — to monitor.\n```\n\nWhen `selected_agent` is `cursor-agent`, render the same explanation but with the Cursor handoff — do **not** claim it launches Claude Code:\n\n```\nThe CLI created/switched each Worktrunk worktree first (throttled by --max-parallel),\nthen opened one tab/session per successful worktree (macOS Terminal/iTerm tab, Windows\nTerminal tab or PowerShell window, or Linux tmux session). Each one runs\n`cursor-agent '<spawned_command>'` inside its already-created worktree, which\nlaunches Cursor Agent with the starter prompt as its first message. Switch to each\ntab — or on Linux run `tmux attach -t <session>` — to monitor.\n```\n\nThe spawned command is identical for both agents; only the launched agent binary differs. Under `review-and-implement`, each spawned session independently runs `/review-ticket`, pauses at its own per-ticket halt gate (unless chain-level `--auto` was passed), and only then runs `/implement-ticket` — do not report that review or implementation succeeded from this parent session.\n\nIf the CLI reported any `create-failed` or `spawn-failed` statuses, or Stage 2 emitted any enrichment warnings, list them under a `Warnings:` heading at the bottom of the report. If there were none, omit that section.\n\nSee `docs/claude/parallel-worktrees.md` for the deep-dive runbook and the Worktrunk verification result behind this worktree-first model.\n\n## Difficulty-Based Implementation-Model Routing\n\nBefore launching the interactive agent for each ticket, the packaged CLI selects an\nimplementation **model tier** from the ticket's `difficulty` rating (1-10) and injects\nit as a `--model` flag at the agent spawn boundary. This happens entirely inside the\nCLI — it is **not** part of the server-side `/implement-ticket` recipe, because the\nmodel an interactive agent session uses is fixed at the moment the process is launched.\n\n- **Tier ladder (fixed):** `difficulty 1-2 → cheap`, `3-5 → basic`, `6+ → premium`.\n- **Separation of concerns:** the Python backend returns only the coarse tier\n (`cheap`/`basic`/`premium`) via `GET /jira/tickets/{KEY}/model-tier`; difficulty is\n computed on demand and cached when absent. The TypeScript CLI alone maps a tier to\n the agent-specific model alias (`claude`: `haiku`/`sonnet`/`opus`; `cursor-agent`:\n version-suffixed strings validated against `cursor-agent --list-models`).\n- **Per-repo config:**\n - `difficulty_model_routing_enabled` — boolean, **default ON**. Set to `false` to\n disable routing for a repo (the CLI then omits `--model`).\n - `difficulty_model_tier_overrides` — a JSON object mapping a tier name to a model\n alias (e.g. `{\"premium\": \"opus\"}`), **not** raw CLI arguments. Only `cheap`,\n `basic`, and `premium` keys are accepted; aliases must match `^[A-Za-z0-9._:-]+$`.\n- **Fail-open:** routing never aborts a spawn. Credential, network, config, or\n no-tier routing failures **assume a hard ticket and default to the premium/Opus\n tier** when the selected agent supports a valid premium alias; routing being\n disabled (`difficulty_model_routing_enabled = false`) or an agent that does not\n support `--model` instead omit `--model` so the agent runs on its own default\n model. Each degraded case is surfaced as exactly one secret-free, per-ticket\n routing-diagnostic line, never a hard failure.\n\n### Model routing credential\n\nDifficulty→model routing needs Bridge API credentials, and the shell-spawned\n`start-tickets` CLI is a **different runtime surface** from the MCP server: a\n`BAPI_API_KEY` that lives only in `.mcp.json` / `.cursor/mcp.json` is visible to\nthe MCP server but **not** to the Bash-spawned CLI, so routing silently degrades.\nThe durable source of truth both runtimes can resolve is the user-scoped store\n`~/.config/bridge/credentials.json`, keyed `bapi:<repo>`. If a routing-diagnostic\nline reports the credential is missing (e.g. difficulty resolves as `?`), fix it\nby any one of:\n\n1. Rerun `/install-bridge` — its final stage now persists the validated routing\n credential into `~/.config/bridge/credentials.json` via the\n `persist_routing_credential` tool.\n2. Migrate a key that lives **only** in `.mcp.json` / `.cursor/mcp.json` into the\n user-scoped store with the consent-gated, one-shot command:\n\n ```\n npx -y @bridge_gpt/mcp-server credentials migrate-agent-config --write-credentials\n ```\n\n3. Manually add `BAPI_API_KEY` under the `bapi:<repo>` target in the user-scoped\n store `~/.config/bridge/credentials.json`.\n\nNever put `BAPI_API_KEY` into a worktree `.mcp.json` / `.cursor/mcp.json` as a fix —\nthat env is invisible to the spawned CLI.\n\n## Conductor observability (opt-in via `--conductor`, BAPI-394)\n\nConductor is **opt-in**. By default `start-tickets` spawns the plain\n`cd <worktree> && <agent> '/implement-ticket <KEY> [--auto]'` — no\n`BAPI_CONDUCTOR_*` env, no supervisor window, and no message-relay instruction.\nPass `--conductor` (e.g. `/start-tickets --conductor BAPI-123`) to enable the\nConductor system below.\n\nWith `--conductor`, a run mints a single conductor `run_id` and attributes each\nworker's lifecycle events by `worker_id`, ticket key, and worktree path, and a\nsupervisor peer tab is opened. When the selected agent is **Claude Code**, the CLI\ninjects a conductor lifecycle hook into each created worktree's\n`.claude/settings.local.json` so the spawned session emits local `run.started` /\n`run.stopped` / `agent.notification` (and, when\n`BAPI_CONDUCTOR_ENABLE_PRE_TOOL_USE=1`, `tool.intent`) events into the local\nconductor ledger. These hooks apply **only** when the selected agent is Claude\nCode; other agents (e.g. `cursor-agent`) still participate in the run-level\n`run.started` event but receive no per-worktree Claude hook. Inspect the ledger\nwith the `conductor` CLI (e.g. `conductor doctor`). Conductor observability is\nbest-effort and never blocks or aborts a spawn.\n\nAlso under `--conductor`, each worker is launched with an explicit instruction to\ncall the `check_messages` MCP tool at checkpoints, so the supervisor can pass it\ntyped guidance mid-run (BAPI-397). Delivery is **cooperative** — the worker polls\nand acknowledges messages and they are never injected into a running session.\n(Epic-tick dispatch always runs with conductor enabled, independent of this\nuser-facing flag.)\n",
|
|
30
32
|
"teach-bridge.md": "Update a Bridge API configuration field via a natural-language teaching.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command takes a natural-language teaching (e.g., \"use data-testid selectors in Playwright tests\") and updates the appropriate Bridge API configuration field. The teaching is auto-classified to the correct field, merged with existing content as actionable AI instructions, and uploaded after user confirmation.\n\n`$ARGUMENTS` is required — it is the teaching text. If `$ARGUMENTS` is empty, show:\n\n```\nUsage: /teach-bridge <teaching>\n\nExamples:\n /teach-bridge use data-testid selectors in Playwright tests\n /teach-bridge always validate input DTOs with Pydantic before passing to service layer\n /teach-bridge prefer composition over inheritance for service classes\n```\n\nIf any stage fails, stop immediately and report which stage failed and why.\n\n## Stage 0 — Preflight\n\n1. **Validate arguments**: If `$ARGUMENTS` is empty or contains only whitespace, display the usage instructions above and stop.\n\n2. **Admin check**: Call the `get_my_role` MCP tool (no parameters). Inspect the response:\n - If `role` is `\"admin\"` OR `source` is `\"legacy\"`: proceed normally.\n - Otherwise: stop immediately and display:\n ```\n Admin access required. Your API key has role \"<role>\" (source: <source>).\n Only admin keys and legacy shared keys can update configuration fields.\n Contact your project administrator to request admin access.\n ```\n\nIf this stage fails, stop immediately and report the error. Do not proceed to Stage 1.\n\n## Stage 1 — Classify\n\n1. **List available fields**: Call the `config_field` MCP tool with `operation` set to `\"list\"` (no other parameters). This returns all available configuration field names with descriptions.\n\n2. **Evaluate the teaching**: Compare the user's teaching (`$ARGUMENTS`) against each field's description to determine which field it applies to.\n\n3. **Handle classification outcomes**:\n - **Clear single match**: If one field is clearly the best target, proceed to Stage 2 with that field.\n - **Multiple plausible matches**: If 2-3 fields are equally plausible, present them to the user with their descriptions and ask which one to update. Wait for user input before proceeding.\n - **No confident match**: If you cannot confidently map the teaching to any field, ask the user to elaborate or specify which field they intend. Wait for user input before proceeding.\n\n## Stage 2 — Merge\n\n1. **Read current value**: Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to the selected field from Stage 1. Capture the current value, description, and examples from the response.\n\n2. **Draft the update**:\n - **If the field is currently null or empty**: Compose initial content from the teaching. Rephrase the user's input as imperative, agent-facing instructions (e.g., convert \"I want you to use data-testid\" to \"Always use `data-testid` attributes for Playwright element locators\"). Do not use the user's exact conversational text.\n - **If the field has existing content**: Merge the teaching into the existing value at the most appropriate location. Rephrase as imperative, agent-facing instructions. Preserve the existing structure and formatting.\n\n3. **Handle contradictions**: If the teaching contradicts existing instructions in the field, present both the existing instruction and the new teaching side-by-side and ask the user which should take precedence. Wait for user input before proceeding.\n\n## Stage 3 — Confirm and Upload\n\n1. **Show the proposed update**: Display to the user:\n - **Field**: The name of the field being updated\n - **Change summary**: A brief description of what was added or changed\n - **Full proposed value**: The complete new value for the field (not just the diff)\n\n2. **Wait for confirmation**: Ask the user to confirm, request edits, or abort.\n\n3. **On confirmation**: Call the `config_field` MCP tool with:\n - `operation`: `\"update\"`\n - `field_name`: the selected field name\n - `value`: the full merged value (pass inline, do not use `file_path`)\n\n Display a success message confirming the update.\n\n4. **On rejection**: Ask the user what they'd like to change. If they provide edits, revise the proposed value and show it again. If they abort, stop without making any changes.\n",
|
|
31
33
|
"upgrade-bridge.md": "# Upgrade Bridge\n\n$ARGUMENTS\n\nUse this command to upgrade (or update) the Bridge API MCP — the\n`@bridge_gpt/mcp-server` package, also called the bridge-api MCP — to the latest\npublished version. This is the action behind the ping tool's advice to \"tell\nyour local agent 'upgrade bridge'\".\n\n---\n\n# Instructions\n\nRun the existing packaged upgrade flow. Do not edit files, install anything by\nhand, or invent a new subcommand — just drive the upgrade CLI and report what it\ndid.\n\n## Step 1 — Run the upgrade command\n\nFrom the **project root**, run exactly:\n\n```\nnpx -y @bridge_gpt/mcp-server --upgrade\n```\n\nThis upgrades/updates the installed `@bridge_gpt/mcp-server` (the bridge-api MCP)\nand re-scaffolds the slash commands.\n\n## Step 2 — Report the result\n\n- If the CLI reports a version change, report it in the CLI's\n `oldVersion -> newVersion` form (e.g. `0.1.17 -> 0.1.19`), mirroring the\n `runUpgradeCli` output.\n- If the CLI reports that no upgrade was needed (the installed version is already\n the latest), report `Already up-to-date.` exactly.\n\n## Step 3 — Handle failures\n\nIf the command fails (non-zero exit or an error in its output), **stop** and\nreport the CLI error verbatim. Do not retry blindly or attempt manual edits to\nwork around it.\n\n## Final Report\n\nReport whether the bridge-api MCP was upgraded (with the\n`oldVersion -> newVersion` transition), was already current (`Already up-to-date.`),\nor failed (with the CLI error).\n"
|
|
32
34
|
};
|
|
@@ -31,7 +31,8 @@ export async function resolveConductorBridgeApiAccess(deps = {}) {
|
|
|
31
31
|
const platform = deps.platform ?? process.platform;
|
|
32
32
|
const readFileImpl = deps.readFile ?? ((p) => readFile(p, "utf-8"));
|
|
33
33
|
const statImpl = deps.stat ?? ((p) => stat(p));
|
|
34
|
-
const repoName =
|
|
34
|
+
const repoName = deps.repoName?.trim() ||
|
|
35
|
+
(await resolveStartTicketsRepoName({ env, cwd, readFile: readFileImpl }));
|
|
35
36
|
if (!repoName) {
|
|
36
37
|
return {
|
|
37
38
|
ok: false,
|
|
@@ -670,6 +671,38 @@ export async function fetchActiveEpicRuns(access, fetchImpl = globalThis.fetch)
|
|
|
670
671
|
}
|
|
671
672
|
return [];
|
|
672
673
|
}
|
|
674
|
+
/**
|
|
675
|
+
* POST `/jira/epic-runs/runs` to create the durable epic run row.
|
|
676
|
+
*
|
|
677
|
+
* The server is idempotent: if a non-terminal run already exists for this
|
|
678
|
+
* `(repo_name, epic_key)` it returns that run (HTTP 200) instead of minting a
|
|
679
|
+
* second one, and does not re-charge the automation-start debit. A second active
|
|
680
|
+
* run would wedge the epic permanently — every later store-plan / approve-plan
|
|
681
|
+
* call would 409 on "Multiple active runs" — so callers must NOT implement their
|
|
682
|
+
* own "POST and tolerate a conflict" retry.
|
|
683
|
+
*
|
|
684
|
+
* The API key travels ONLY in the `X-API-Key` header, never in the URL.
|
|
685
|
+
*/
|
|
686
|
+
export async function createEpicRun(access, request, fetchImpl = globalThis.fetch) {
|
|
687
|
+
requireNonEmptyString(request.epicKey);
|
|
688
|
+
const body = {
|
|
689
|
+
repo_name: access.repoName,
|
|
690
|
+
epic_key: request.epicKey,
|
|
691
|
+
status: request.status ?? "planning",
|
|
692
|
+
current_plan_version: request.currentPlanVersion ?? 0,
|
|
693
|
+
};
|
|
694
|
+
if (request.policyJson !== undefined)
|
|
695
|
+
body.policy_json = request.policyJson;
|
|
696
|
+
if (request.budgetWallClockSeconds !== undefined) {
|
|
697
|
+
body.budget_wall_clock_seconds = request.budgetWallClockSeconds;
|
|
698
|
+
}
|
|
699
|
+
if (request.budgetCostCents !== undefined) {
|
|
700
|
+
body.budget_cost_cents = request.budgetCostCents;
|
|
701
|
+
}
|
|
702
|
+
const url = buildConductorJiraUrl(access.baseUrl, `${EPIC_RUNS_API_PREFIX}/runs`);
|
|
703
|
+
const parsed = await fetchConductorJsonPostWithTimeout(url, conductorPostHeaders(access), JSON.stringify(body), CONDUCTOR_FETCH_TIMEOUT_MS, fetchImpl);
|
|
704
|
+
return parsed;
|
|
705
|
+
}
|
|
673
706
|
/**
|
|
674
707
|
* PATCH `/jira/epic-runs/runs/{identifier}` to transition an epic run's
|
|
675
708
|
* lifecycle status. Drives the same backend `update_epic_run` CAS path the
|
|
@@ -909,8 +942,16 @@ export async function approveEpicPlan(access, request, fetchImpl = globalThis.fe
|
|
|
909
942
|
}
|
|
910
943
|
catch (error) {
|
|
911
944
|
if (error instanceof ConductorBridgeApiError && error.status === 409) {
|
|
912
|
-
//
|
|
913
|
-
//
|
|
945
|
+
// The server overloads 409: "a later version is already approved"
|
|
946
|
+
// (benign — the caller is simply behind) and "multiple active runs"
|
|
947
|
+
// (the epic is WEDGED and every later plan call will 409 forever).
|
|
948
|
+
// Collapsing both to "superseded" reports success on a broken epic, so
|
|
949
|
+
// discriminate on the body. `bodyPreview` carries the server's bare-string
|
|
950
|
+
// FastAPI `detail`, which is exactly where that distinction lives.
|
|
951
|
+
const preview = error.bodyPreview ?? "";
|
|
952
|
+
if (/multiple active runs/i.test(preview)) {
|
|
953
|
+
return { ok: false, kind: "conflict", reason: "multiple_active_runs" };
|
|
954
|
+
}
|
|
914
955
|
return { ok: false, kind: "conflict", reason: "superseded" };
|
|
915
956
|
}
|
|
916
957
|
throw error;
|