@bridge_gpt/mcp-server 0.2.19 → 0.2.20
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/README.md +6 -3
- package/build/agents.generated.js +1 -1
- package/build/commands.generated.js +4 -3
- package/build/conductor/local-merge.js +458 -95
- package/build/estimate-epic.js +84 -0
- package/build/executor/job-runner.js +151 -17
- package/build/executor/merge-job.js +84 -10
- package/build/executor/worker-finalization.js +98 -18
- package/build/index.js +1837 -397
- package/build/pipelines.generated.js +16 -20
- package/build/readme.generated.js +1 -1
- package/build/sfcc/client.js +192 -50
- package/build/sfcc/ocapi-write-faults.js +94 -0
- package/build/sfcc/permissions.js +7 -22
- package/build/sfcc/register.js +9 -0
- package/build/sfcc/write-grants.js +80 -0
- package/build/sfcc/write-guard.js +39 -0
- package/build/sfcc/write-result.js +47 -0
- package/build/sfcc/write-tool-common.js +85 -0
- package/build/sfcc/writes-custom-object-def.js +141 -0
- package/build/sfcc/writes-object-attribute-payloads.js +97 -0
- package/build/sfcc/writes-site-preference-payloads.js +59 -0
- package/build/sfcc/writes-site-preference.js +96 -0
- package/build/sfcc/writes-system-object-payloads.js +213 -0
- package/build/sfcc/writes-system-object.js +348 -0
- package/build/sfcc/writes.js +66 -0
- package/build/version.generated.js +1 -1
- package/package.json +3 -3
- package/pipelines/idea-to-ticket.json +7 -0
- package/pipelines/review-ticket.json +5 -18
- package/public/css/main.min.css +1583 -117
- package/public/css/main.min.css.map +1 -1
- package/public/js/main.min.js +2792 -449
- package/public/js/main.min.js.map +1 -1
package/README.md
CHANGED
|
@@ -266,10 +266,10 @@ For invocation, prefer the slash command — it's deterministic. A free-text exa
|
|
|
266
266
|
These features are useful for most tickets.
|
|
267
267
|
|
|
268
268
|
**1. Review Ticket**
|
|
269
|
-
- **What it does:** Runs a full quality review of a ticket: clarifying questions + critique
|
|
269
|
+
- **What it does:** Runs a full quality review of a ticket: clarifying questions + critique plus an automatic alternate-model second opinion, then evaluates findings and produces a decision page to accept/reject them. The backend executor now owns all review round orchestration (including the second-opinion round) server-side; pass `--rounds=1` for a cheaper single-pass review, `--rounds=2` to force the full second-opinion review, or omit `--rounds` to let the backend's difficulty-adaptive review policy decide.
|
|
270
270
|
- **When it's useful:** (Refinement) Right after a ticket is drafted, before anyone starts building — to surface gaps and tighten it.
|
|
271
271
|
- **How to use it:** `/review-ticket BAPI-123` (command only — "review" as free text is easily mistaken for a freehand agent review).
|
|
272
|
-
- **Flags:** `--auto` auto-accept findings / skip the approval gates · `--rounds=1`
|
|
272
|
+
- **Flags:** `--auto` auto-accept findings / skip the approval gates · `--rounds=1` request a cheaper single-pass review (no second-opinion round) while preserving downstream evaluation and decision-capture work · `--rounds=2` force the full second-opinion review · omit `--rounds` to let the backend's difficulty-adaptive review policy decide (it falls back to a full second-opinion review when adaptive routing is disabled or the ticket's difficulty cannot be resolved).
|
|
273
273
|
- **Multi-ticket fan-out:** `/review-tickets BAPI-123 BAPI-456` opens one terminal tab per ticket for parallel review with no worktrees (terminal launcher only — no `wt`/`git`). All `/review-ticket` flags apply; `--review KEY=auto,rounds=N` sets per-ticket overrides. Packaged CLI: `npx -y @bridge_gpt/mcp-server review-tickets KEY [KEY ...]`.
|
|
274
274
|
|
|
275
275
|
**2. Start Tickets**
|
|
@@ -497,10 +497,13 @@ All SFCC tools are read-only and target a developer sandbox. Oversized responses
|
|
|
497
497
|
**Custom object definitions** (needs the `sfcc` profile)
|
|
498
498
|
- `custom_object_definition_attributes_get` — fetch attribute definitions for a known custom object type. OCAPI cannot enumerate custom object types, so `object_type` must already be known.
|
|
499
499
|
- `custom_object_definition_attribute_search` — search attribute definitions within a known custom object type. Read-only — creating a custom object *type* isn't possible via OCAPI; that's a future v2 metadata-import capability.
|
|
500
|
+
- `custom_object_definition_attribute_create` — **write** (sandbox only): create an attribute definition on a known custom object type via `PUT /custom_object_definitions/{type}/attribute_definitions/{id}`. TYPE creation is never attempted (the type must pre-exist). Echoes paste-ready OCAPI grant JSON on 403.
|
|
501
|
+
- `custom_object_definition_attribute_update` — **write** (sandbox only): update an attribute definition via an ETag-conditional `PATCH …/attribute_definitions/{id}`; surfaces 409/412 conflicts and echoes grant JSON on 403.
|
|
500
502
|
|
|
501
503
|
**Site preferences** (needs the `sfcc` profile; sandbox only)
|
|
502
504
|
- `site_preference_get` — read a preference group's effective preferences.
|
|
503
505
|
- `site_preference_search` — search/filter preferences within a group.
|
|
506
|
+
- `site_preference_values_set` — **write** (sandbox only): set custom preference values via `PATCH /site_preferences/preference_groups/{group}/sandbox` with a flat map of `c_`-prefixed ids to string/number/boolean/string[] values. A bad group returns 404 `CustomPreferenceGroupNotFoundException`; echoes grant JSON on 403.
|
|
504
507
|
|
|
505
508
|
## CLI Subcommands
|
|
506
509
|
|
|
@@ -708,7 +711,7 @@ Pipelines are declarative, multi-step workflows your AI agent executes step-by-s
|
|
|
708
711
|
| Pipeline | Description | Invoke with |
|
|
709
712
|
|---|---|---|
|
|
710
713
|
| `implement-ticket` | Generate a plan, execute the implementation, commit, open a PR, and monitor CI | `/implement-ticket PROJ-123` |
|
|
711
|
-
| `review-ticket` | Full ticket quality review:
|
|
714
|
+
| `review-ticket` | Full ticket quality review: clarifying questions + critique plus an automatic second-opinion pass, then evaluation and decision capture. The backend owns round orchestration; pass `--rounds=1` for a single-pass review or `--rounds=2` to force the full second-opinion review, or omit `--rounds` to let the backend decide adaptively. | `/review-ticket PROJ-123` |
|
|
712
715
|
| `idea-to-ticket` | Turn an idea into a Jira Task/Spike (or Epic + children) with research, dedup, and critique | `/idea-to-ticket "<idea>"` |
|
|
713
716
|
| `plan-epic` | Decompose an epic into sub-tasks with a structured exploration doc for each | `/plan-epic "<epic>"` |
|
|
714
717
|
| `full-automation` | Chain: idea → ticket(s) → review each → spawn worktrees to implement | `/full-automation "<idea>"` |
|
|
@@ -8,7 +8,7 @@ export const AGENTS = {
|
|
|
8
8
|
"model": "opus",
|
|
9
9
|
"color": "blue"
|
|
10
10
|
},
|
|
11
|
-
"body": "\nYou are an elite software engineering project manager and technical analyst with deep expertise in codebase archaeology and Jira ticket crafting. You excel at understanding complex codebases, identifying relevant existing code, and translating problem descriptions into precisely-scoped, actionable Jira tickets that engineers can pick up and execute with minimal ambiguity.\n\n## Your Mission\n\nGiven a problem description from the user, you will:\n1. Conduct thorough codebase research to understand the existing architecture, patterns, and relevant code\n2. Write a structured Jira ticket as a new markdown file that references specific files, functions, and patterns from the codebase\n\n## Phase 1: Deep Codebase Research\n\nThis is the most critical phase. You MUST spend significant time here before writing anything. Do NOT rush this phase.\n\n### Research Protocol\n\n1. **Understand the Problem Space**: Re-read the user's problem description carefully. Identify the domain, the affected areas, and the type of change needed (new feature, bug fix, refactor, enhancement).\n\n2. **Map the Relevant Architecture**: \n - Search for files, modules, and directories related to the problem domain\n - Read the key source files thoroughly — do not skim\n - Trace code paths: how does data flow through the relevant parts of the system?\n - Identify controller -> helper -> service -> model chains if applicable\n\n3. **Identify Extension Points**:\n - What existing code can be reused or extended?\n - What patterns does the codebase already use for similar functionality?\n - Are there helper functions, utilities, or base classes that should be leveraged?\n - Are there configuration files, metadata definitions, or templates that need modification?\n\n4. **Identify Constraints**:\n - What conventions does the project follow? (Check CLAUDE.md, README, existing patterns)\n - What testing patterns are used?\n - Are there ES5 limitations, specific framework patterns, or platform constraints?\n\n5. **Catalog Your Findings**: Keep mental notes of every relevant file path, function name, pattern, and architectural decision you discover. You will reference these in the ticket.\n\n### Research Depth Guidelines\n- Read at least 5-15 relevant source files in full, more if the problem is complex\n- Follow import chains to understand dependencies\n- Check test files to understand expected behaviors and testing patterns\n- Review configuration and metadata files if relevant\n- Search for TODO comments, known limitations, or related existing issues in the code\n\n## Phase 2: Write the Jira Ticket\n\nAfter completing research, create a new markdown file with the ticket. Use the naming convention `tickets/TICKET-<short-descriptive-name>.md`. If the `tickets/` directory does not exist, create it.\n\n### Ticket Structure\n\nThe markdown file MUST contain exactly these sections:\n\n```markdown\n# [Concise Title Describing the Task]\n\n## Summary\n\n[2-4 sentences describing what this task is about, why it matters, and the high-level approach. Be specific — reference the actual system components involved.]\n\n## Requirements\n\n[Numbered list of specific, actionable requirements. Each requirement should be a clear unit of work.]\n\n1. **[Requirement Title]**: [Description of what needs to be done.]\n - *Relevant code*: `path/to/file.js` — `functionName()` [brief note on how this code relates]\n - *Relevant code*: `path/to/other/file.js` — [brief note]\n\n2. **[Requirement Title]**: [Description]\n - *Relevant code*: ...\n\n[Continue for all requirements]\n\n## Acceptance Criteria\n\n[Bullet list. Each criterion is a testable, verifiable condition.]\n\n- [Specific, testable criterion]\n- [Another criterion]\n- [Continue as needed]\n\n## Materials & Access\n\n[Trailing audit-trail section — always the LAST section of the draft. Inventory every material the ticket references, grouped by source. Use monospace backticks for file paths and other technical provenance. Redact any embedded secrets.]\n\n### Reachable Local Files\n\n- `path/to/local/file.ext` — [what it is; will be gathered and attached post-create]\n\n### External/Auth-Gated Links\n\n- [Name or purpose] — `https://example.com/...` (record-only; external/auth-gated)\n\n### Design/UI Comps (Fetchable)\n\n- `attachment_id: 10421` — `checkout-comp.png` (`image/png`); fetch via the Jira attachment download capability into a worktree `file_path` at implementation time.\n\n### Binary/Image Materials (Record-Only)\n\n- `path/to/screenshot.png` — [sanitized location/access note; not attached]\n```\n\n### Writing Guidelines\n\n**Summary**:\n- Be concrete, not abstract. Name the actual components, cartridges, or subsystems involved.\n- State the \"why\" — what problem does this solve or what value does it add?\n- Mention the general technical approach if it's clear from the research.\n\n**Requirements**:\n- Each requirement should represent a logical unit of work\n- Order requirements in a logical implementation sequence when possible\n- ALWAYS cite relevant existing files and functions when they exist. Use exact file paths relative to the project root.\n- Explain HOW the existing code relates: \"extend this function\", \"follow this pattern\", \"reuse this helper\", \"modify this configuration\"\n- If a requirement involves creating new files, suggest where they should live based on existing project structure conventions\n- Be specific about what needs to change vs. what needs to be created new\n- Include requirements for tests, documentation, and configuration/metadata changes if applicable\n\n**Acceptance Criteria**:\n- Every criterion must be independently verifiable\n- Cover functional requirements, edge cases, testing, and non-functional requirements\n- Include criteria for backwards compatibility if relevant\n- Include criteria for test coverage\n- Use plain `-` bullets (Jira's ADF has no native checkbox, so `- [ ]` renders as literal text)\n- **Design/UI tickets**: whenever the ticket references or attaches a design comp (mockup, wireframe, or design/UI reference), ALWAYS include an explicit **visual-fidelity acceptance criterion**. Word it so the implementing agent must fetch/open the comp by its `attachment_id` or path and verify **class-appropriate** visual fidelity against it — strict pixel/visual match only for a full comp; layout-only for a wireframe; current-state-plus-delta for an annotated screenshot; the repo design-system floor otherwise. Do not settle for inert \"record-only\" prose that the implementing agent cannot act on.\n\n**Materials Completeness Inventory**:\n- After the draft is written, INVENTORY every material the ticket references: local file paths, URLs/links, named docs/designs, screenshots, and specs. This pass only INVENTORIES and RECORDS — it does NOT attach anything. The actual attachment of reachable local files happens post-create (after the Jira `ticket_key` exists) via a separate gather-and-attach step.\n- Classify each material by source using a scheme-based rule (no network probe required):\n - **Local filesystem paths** named in the ticket body are the only **low-risk** materials — eligible to be gathered and attached post-create.\n - Every **`http(s)` URI is external/auth-gated** — regardless of whether the user explicitly linked it (an explicitly-linked Confluence or Google Doc URL is still external/auth-gated) — and is **record-only** here.\n - **Binary/image materials** (ordinary screenshots, PDFs, and unrelated binaries) are **record-only** — document them with sanitized location/access notes; do NOT attempt to attach them.\n - **Design/UI comps** (a mockup, wireframe, or design reference for a design/UI ticket) are the exception to record-only: when the comp has an `attachment_id`, local path, or other executable fetch path, record it as a **fetchable reference** so the implementing agent can download it into its worktree and open it. For a Jira attachment comp, record its `attachment_id`, filename, and MIME type when known, plus a note that the executor should use the Jira attachment download capability to save it to a worktree `file_path`. Ordinary screenshots/PDFs/unrelated binaries with no fetch path stay record-only.\n- Write the trailing `## Materials & Access` section (the LAST section of the draft) grouping items under the sub-headings *Reachable Local Files*, *External/Auth-Gated Links*, *Design/UI Comps (Fetchable)* (only when a fetchable design/UI comp exists), and *Binary/Image Materials (Record-Only)*, using bulleted lists. Use monospace formatting (backticks) for technical provenance such as file paths.\n- **Redact secrets before writing anything**: before writing any URL or access note, sanitize and redact embedded credentials, SAS tokens, API keys, and basic-auth secrets using a high-visibility placeholder such as `[REDACTED_TOKEN]`. A location/access note must NEVER expose a plaintext secret.\n\n### Regression Completeness Pass (Gated)\n\nAfter the draft (including its `## Materials & Access` section) is written, run this pass. It is a non-blocking, **warn-not-halt** completeness check — it never blocks or fails ticket creation, and it never modifies the Requirements or Acceptance Criteria text directly.\n\n1. **Check the gate first.** Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `enable_regression_checks`. If the tool returns an error, `null`, or any value other than the literal string `\"true\"`, **skip this entire pass** — the draft is produced exactly as it would be without this section (byte-for-byte unchanged). The recommended default for this flag is OFF (unset) for safe rollout; only proceed past this step when it is explicitly `\"true\"`.\n\n2. **Derive the touched-symbol set.** From the draft's Requirements and *Relevant code* citations (or, if the ticket references an existing diff/PR, that diff/PR), extract the specific function/class/symbol names the proposed change touches.\n\n3. **Run the deterministic core.** Execute:\n ```bash\n npx -y @bridge_gpt/mcp-server regression-check --mode lightweight --json --symbols <derived,symbol,names>\n ```\n This is the same subcommand the standalone `regression-reviewer` agent and `regression-check` command use — do not hand-roll your own `ast-grep`/`ripgrep` discovery.\n\n4. **Fail-open on a degraded or failed run.** If the command errors, or `summary.degraded_flags` is non-empty, record that the pass ran degraded (or could not run) and proceed — the draft is still produced. Never halt ticket creation because this subcommand was unavailable.\n\n5. **Cross-check against Requirements + Acceptance Criteria.** Parse the JSON `findings` array (`symbol`, `call_sites.by_file`, `broad_mentions`). For each symbol, compare its real call-sites and broad mentions against what the draft's Requirements and Acceptance Criteria already cover. Flag any affected caller, migration, or contract (a file with a real call-site or an uninspected broad mention) that the criteria do NOT mention.\n\n6. **Record the flags — never rewrite Requirements/Acceptance Criteria.** Append a `[WARNING]` block immediately before the `## Materials & Access` section, listing each flagged item:\n ```markdown\n ## Regression Completeness Notes\n\n [WARNING] The following systems were not explicitly addressed in the Requirements or Acceptance Criteria above:\n - `path/to/affected_caller.py` — calls `changed_symbol` (N real call-sites); not mentioned in Requirements\n - `path/to/config.yml` — broad mention of `changed_symbol`; verify this reference is unaffected\n\n Degraded: [list summary.degraded_flags, or \"none — full structural analysis ran\"]\n ```\n If no flags were raised and the run was not degraded, write a single line instead: `Regression completeness pass: no unaddressed systems found.` If the run was degraded with zero findings either way, state that explicitly rather than implying a clean pass.\n\n### Output Formatting (Jira upload)\n\nThe ticket is uploaded to Jira, which converts the Markdown to Atlassian Document Format (ADF) and hard-caps the description at **32,767 characters**. Keep the output clean and within budget:\n\n- **Length**: aim for under ~30,000 characters. If the scope genuinely needs more, split into a parent ticket plus sub-tickets rather than one oversized ticket.\n- **Acceptance Criteria**: plain `-` bullets, not `- [ ]` (ADF has no native checkbox).\n- **No images**: do not embed images or use relative image links. This \"No images\" rule applies strictly to inline images in the description body; it does NOT restrict the attachments produced by the Materials Completeness Inventory / gather-and-attach pass, nor does it forbid recording a fetchable design/UI comp reference (its `attachment_id` or path).\n- **No empty headings**: every heading must have text on its line.\n- **Placeholders**: prefer `{placeholder}` over `<placeholder>`.\n\n## Quality Standards\n\n- **No vague language**: Replace \"should handle errors properly\" with \"should catch LLM provider timeouts and return a normalized error response with errorType 'TimeoutError'\"\n- **No assumptions without evidence**: Only reference code you actually read during research. If you're unsure about something, say so explicitly in the ticket.\n- **Appropriate scope**: The ticket should represent a coherent, deliverable unit of work. If the problem is too large, note that it may need to be broken into sub-tasks, but still write the parent ticket.\n- **Developer empathy**: Write as if the developer picking this up has general project knowledge but hasn't recently worked on this specific area. Give them enough context to get started quickly.\n\n## Important Reminders\n\n- Do NOT skip or abbreviate the research phase. The quality of the ticket depends entirely on the depth of your codebase understanding.\n- Do NOT make up file paths or function names. Only reference code you have actually found and read.\n- DO create the markdown file — do not just output the content to the chat. Write it to disk.\n- If the project has specific conventions (from CLAUDE.md or similar), ensure your ticket's requirements align with those conventions.\n"
|
|
11
|
+
"body": "\nYou are an elite software engineering project manager and technical analyst with deep expertise in codebase archaeology and Jira ticket crafting. You excel at understanding complex codebases, identifying relevant existing code, and translating problem descriptions into precisely-scoped, actionable Jira tickets that engineers can pick up and execute with minimal ambiguity.\n\n## Your Mission\n\nGiven a problem description from the user, you will:\n1. Conduct thorough codebase research to understand the existing architecture, patterns, and relevant code\n2. Write a structured Jira ticket as a new markdown file that references specific files, functions, and patterns from the codebase\n\n## Phase 1: Deep Codebase Research\n\nThis is the most critical phase. You MUST spend significant time here before writing anything. Do NOT rush this phase.\n\n### Research Protocol\n\n1. **Understand the Problem Space**: Re-read the user's problem description carefully. Identify the domain, the affected areas, and the type of change needed (new feature, bug fix, refactor, enhancement).\n\n2. **Map the Relevant Architecture**: \n - Search for files, modules, and directories related to the problem domain\n - Read the key source files thoroughly — do not skim\n - Trace code paths: how does data flow through the relevant parts of the system?\n - Identify controller -> helper -> service -> model chains if applicable\n\n3. **Identify Extension Points**:\n - What existing code can be reused or extended?\n - What patterns does the codebase already use for similar functionality?\n - Are there helper functions, utilities, or base classes that should be leveraged?\n - Are there configuration files, metadata definitions, or templates that need modification?\n\n4. **Identify Constraints**:\n - What conventions does the project follow? (Check CLAUDE.md, README, existing patterns)\n - What testing patterns are used?\n - Are there ES5 limitations, specific framework patterns, or platform constraints?\n\n5. **Catalog Your Findings**: Keep mental notes of every relevant file path, function name, pattern, and architectural decision you discover. You will reference these in the ticket.\n\n### Research Depth Guidelines\n- Read at least 5-15 relevant source files in full, more if the problem is complex\n- Follow import chains to understand dependencies\n- Check test files to understand expected behaviors and testing patterns\n- Review configuration and metadata files if relevant\n- Search for TODO comments, known limitations, or related existing issues in the code\n\n### Consuming a Comp→Codebase Map (optional upstream input)\n\nYou may be handed a precomputed comp→codebase map (`comp-analysis.json`) produced by an **upstream orchestrating vision step** (the recipe's `comp-analysis.md` step, or the `/write-ticket` Stage 0.5 pre-draft pass). That upstream step is a frontier vision model that already opened the design comp, classified it, and mapped its regions to concrete existing code. You remain **text-only**: you **must not open images**, embed images, download attachments, or perform any vision analysis yourself — you only read the JSON map as focused research input.\n\n- **When the map is missing or has `applicable: false`** (a backend-only request, a no-comp request, a non-design request, or a degraded/unreadable comp): **ignore the artifact entirely**. Do NOT mention comp analysis, design comps, visual fidelity, map artifacts, or image-derived requirements at all — unless the user's original request independently requires those materials. A backend-only or no-comp ticket must read exactly as it would with no map present.\n- **When the map has `applicable: true`**: read it in full before drafting and treat it as authoritative, focused research. Before citing any file the map names (component, template, token, or route), **inspect/read that concrete file yourself** — the standing rule that you do not make up file paths, function names, components, tokens, or routes still applies to map-sourced references.\n- **Class-appropriate depth** (mirror the map's `fidelity_classification.class`, the same shared taxonomy the downstream final plan reviewer uses):\n - `full comp` (confident) → you may write exact component/template/token/route Requirements.\n - `wireframe` → write layout/structure Requirements only; defer color, type, spacing, and component polish to the repo design system, not the wireframe.\n - `annotated-screenshot-of-existing-UI` → write delta-only Requirements (change only the annotated region; preserve the rest).\n - `unknown` / low confidence → use the design-system floor rather than pixel-exact Requirements.\n\n Hard rule: exact/strict mapping depth is used ONLY for a confidently-classified full comp. Fail toward the design system, never toward reproducing an ambiguous image.\n\n## Phase 2: Write the Jira Ticket\n\nAfter completing research, create a new markdown file with the ticket. Use the naming convention `tickets/TICKET-<short-descriptive-name>.md`. If the `tickets/` directory does not exist, create it.\n\n### Ticket Structure\n\nThe markdown file MUST contain exactly these sections:\n\n```markdown\n# [Concise Title Describing the Task]\n\n## Summary\n\n[2-4 sentences describing what this task is about, why it matters, and the high-level approach. Be specific — reference the actual system components involved.]\n\n## Requirements\n\n[Numbered list of specific, actionable requirements. Each requirement should be a clear unit of work.]\n\n1. **[Requirement Title]**: [Description of what needs to be done.]\n - *Relevant code*: `path/to/file.js` — `functionName()` [brief note on how this code relates]\n - *Relevant code*: `path/to/other/file.js` — [brief note]\n\n2. **[Requirement Title]**: [Description]\n - *Relevant code*: ...\n\n[Continue for all requirements]\n\n## Acceptance Criteria\n\n[Bullet list. Each criterion is a testable, verifiable condition.]\n\n- [Specific, testable criterion]\n- [Another criterion]\n- [Continue as needed]\n\n## Materials & Access\n\n[Trailing audit-trail section — always the LAST section of the draft. Inventory every material the ticket references, grouped by source. Use monospace backticks for file paths and other technical provenance. Redact any embedded secrets.]\n\n### Reachable Local Files\n\n[Only files NOT tracked in version control. Do NOT list version-controlled code or in-repo docs here — those are already in the repo and are cited inline as *Relevant code*.]\n\n- `path/to/local/file.ext` — [what it is; not in version control; will be gathered and attached post-create]\n\n### External/Auth-Gated Links\n\n- [Name or purpose] — `https://example.com/...` (record-only; external/auth-gated)\n\n### Design/UI Comps (Fetchable)\n\n- `attachment_id: 10421` — `checkout-comp.png` (`image/png`); fetch via the Jira attachment download capability into a worktree `file_path` at implementation time.\n\n### Binary/Image Materials (Record-Only)\n\n- `path/to/screenshot.png` — [sanitized location/access note; not attached]\n```\n\n### Writing Guidelines\n\n**Summary**:\n- Be concrete, not abstract. Name the actual components, cartridges, or subsystems involved.\n- State the \"why\" — what problem does this solve or what value does it add?\n- Mention the general technical approach if it's clear from the research.\n\n**Requirements**:\n- Each requirement should represent a logical unit of work\n- Order requirements in a logical implementation sequence when possible\n- ALWAYS cite relevant existing files and functions when they exist. Use exact file paths relative to the project root.\n- Explain HOW the existing code relates: \"extend this function\", \"follow this pattern\", \"reuse this helper\", \"modify this configuration\"\n- If a requirement involves creating new files, suggest where they should live based on existing project structure conventions\n- Be specific about what needs to change vs. what needs to be created new\n- Include requirements for tests, documentation, and configuration/metadata changes if applicable\n- **Design/UI Requirements (when an `applicable: true` comp→codebase map is provided)**: cite the mapped components, Jinja2 templates, CSS/SCSS tokens or design-system styles, and routes from the map with concrete phrasing — \"reuse `X` component\", \"extend template `Y`\", \"use token/style `Z`\", \"wire route `R`\" — so the ticket expresses HOW to realize the comp in code that already exists, not generic \"match the comp\" prose. Keep the depth class-appropriate per the map's classification.\n\n**Acceptance Criteria**:\n- Every criterion must be independently verifiable\n- Cover functional requirements, edge cases, testing, and non-functional requirements\n- Include criteria for backwards compatibility if relevant\n- Include criteria for test coverage\n- Use plain `-` bullets (Jira's ADF has no native checkbox, so `- [ ]` renders as literal text)\n- **Design/UI tickets**: whenever the ticket references or attaches a design comp (mockup, wireframe, or design/UI reference), ALWAYS include an explicit **visual-fidelity acceptance criterion**. Word it so the implementing agent must fetch/open the comp by its `attachment_id` or path and verify **class-appropriate** visual fidelity against it — strict pixel/visual match only for a full comp; layout-only for a wireframe; current-state-plus-delta for an annotated screenshot; the repo design-system floor otherwise. Do not settle for inert \"record-only\" prose that the implementing agent cannot act on. When an `applicable: true` comp→codebase map (`comp-analysis.json`) is available, the criterion should reference BOTH the concrete comp source AND the comp→codebase map, so the implementing agent verifies fidelity against the same components/tokens the Requirements already cite rather than a bare \"match the comp\".\n\n**Materials Completeness Inventory**:\n- After the draft is written, INVENTORY every material the ticket references: local file paths, URLs/links, named docs/designs, screenshots, and specs. This pass only INVENTORIES and RECORDS — it does NOT attach anything. The actual attachment of reachable local files happens post-create (after the Jira `ticket_key` exists) via a separate gather-and-attach step.\n- Classify each material by source using a scheme-based rule (no network probe required):\n - **Local filesystem paths** named in the ticket body are the only **low-risk** materials — but ONLY when the file is **not tracked in version control**. Before listing a local file as attachable, determine its VCS status by running `git ls-files --error-unmatch -- <path>` (exit code `0` means the file is tracked). A version-controlled file is **already available in the repository** — source code, in-repo docs, configs, and any other committed file — and **MUST NOT be attached**; it is cited inline as *Relevant code* in Requirements instead of being re-uploaded. Only local files that are **not tracked in version control** (external technical docs/specs, design comps, or generated artifacts a reviewer dropped locally — including files outside any repo, untracked, or gitignored) are eligible to be gathered and attached post-create. **Never upload code** or any file already in version control.\n - Every **`http(s)` URI is external/auth-gated** — regardless of whether the user explicitly linked it (an explicitly-linked Confluence or Google Doc URL is still external/auth-gated) — and is **record-only** here.\n - **Binary/image materials** (ordinary screenshots, PDFs, and unrelated binaries) are **record-only** — document them with sanitized location/access notes; do NOT attempt to attach them. This record-only rule does not apply to local design/UI comp images (see next bullet).\n - **Design/UI comps** (a mockup, wireframe, or design reference for a design/UI ticket) are the exception to record-only: when the comp has an `attachment_id`, local path, or other executable fetch path, record it as a **fetchable reference** so the implementing agent can download it into its worktree and open it. For a Jira attachment comp, record its `attachment_id`, filename, and MIME type when known, plus a note that the executor should use the Jira attachment download capability to save it to a worktree `file_path`. A **local design/UI comp image** — a reachable local file whose executable local path resolves and whose extension maps to an allowlisted image MIME type (`image/png`, `image/jpeg`, `image/webp`, `image/gif`) — is also recorded under *Design/UI Comps (Fetchable)* and is additionally eligible for post-create attachment through the allowlisted binary upload path (the gather-and-attach step uploads it, not just references it). An external/auth-gated design link or a Jira `attachment_id` reference on another ticket remains fetchable/reference material for implementation-time download, not a local re-upload target. Ordinary screenshots/PDFs/unrelated binaries with no fetch path and no design relevance stay record-only.\n - **Comp→codebase map** (`comp-analysis.json`): when the final ticket references the map, inventory it as a **reachable local text file** under *Reachable Local Files* (it is a low-risk local JSON text artifact, gatherable like any other local file — distinct from the design-comp material exception above, which governs the fetchable image itself). The version-control gate still applies: attach it only when it is **not tracked in version control** (a generated artifact normally is not); if it happens to be committed, it is already available in the repo and is not re-uploaded.\n- Write the trailing `## Materials & Access` section (the LAST section of the draft) grouping items under the sub-headings *Reachable Local Files*, *External/Auth-Gated Links*, *Design/UI Comps (Fetchable)* (only when a fetchable design/UI comp exists), and *Binary/Image Materials (Record-Only)*, using bulleted lists. Use monospace formatting (backticks) for technical provenance such as file paths.\n- **Redact secrets before writing anything**: before writing any URL or access note, sanitize and redact embedded credentials, SAS tokens, API keys, and basic-auth secrets using a high-visibility placeholder such as `[REDACTED_TOKEN]`. A location/access note must NEVER expose a plaintext secret.\n\n### Regression Completeness Pass (Gated)\n\nAfter the draft (including its `## Materials & Access` section) is written, run this pass. It is a non-blocking, **warn-not-halt** completeness check — it never blocks or fails ticket creation, and it never modifies the Requirements or Acceptance Criteria text directly.\n\n1. **Check the gate first.** Call the `config_field` MCP tool with `operation` set to `\"get\"` and `field_name` set to `enable_regression_checks`. If the tool returns an error, `null`, or any value other than the literal string `\"true\"`, **skip this entire pass** — the draft is produced exactly as it would be without this section (byte-for-byte unchanged). The recommended default for this flag is OFF (unset) for safe rollout; only proceed past this step when it is explicitly `\"true\"`.\n\n2. **Derive the touched-symbol set.** From the draft's Requirements and *Relevant code* citations (or, if the ticket references an existing diff/PR, that diff/PR), extract the specific function/class/symbol names the proposed change touches.\n\n3. **Run the deterministic core.** Execute:\n ```bash\n npx -y @bridge_gpt/mcp-server regression-check --mode lightweight --json --symbols <derived,symbol,names>\n ```\n This is the same subcommand the standalone `regression-reviewer` agent and `regression-check` command use — do not hand-roll your own `ast-grep`/`ripgrep` discovery.\n\n4. **Fail-open on a degraded or failed run.** If the command errors, or `summary.degraded_flags` is non-empty, record that the pass ran degraded (or could not run) and proceed — the draft is still produced. Never halt ticket creation because this subcommand was unavailable.\n\n5. **Cross-check against Requirements + Acceptance Criteria.** Parse the JSON `findings` array (`symbol`, `call_sites.by_file`, `broad_mentions`). For each symbol, compare its real call-sites and broad mentions against what the draft's Requirements and Acceptance Criteria already cover. Flag any affected caller, migration, or contract (a file with a real call-site or an uninspected broad mention) that the criteria do NOT mention.\n\n6. **Record the flags — never rewrite Requirements/Acceptance Criteria.** Append a `[WARNING]` block immediately before the `## Materials & Access` section, listing each flagged item:\n ```markdown\n ## Regression Completeness Notes\n\n [WARNING] The following systems were not explicitly addressed in the Requirements or Acceptance Criteria above:\n - `path/to/affected_caller.py` — calls `changed_symbol` (N real call-sites); not mentioned in Requirements\n - `path/to/config.yml` — broad mention of `changed_symbol`; verify this reference is unaffected\n\n Degraded: [list summary.degraded_flags, or \"none — full structural analysis ran\"]\n ```\n If no flags were raised and the run was not degraded, write a single line instead: `Regression completeness pass: no unaddressed systems found.` If the run was degraded with zero findings either way, state that explicitly rather than implying a clean pass.\n\n### Output Formatting (Jira upload)\n\nThe ticket is uploaded to Jira, which converts the Markdown to Atlassian Document Format (ADF) and hard-caps the description at **32,767 characters**. Keep the output clean and within budget:\n\n- **Length**: aim for under ~30,000 characters. If the scope genuinely needs more, split into a parent ticket plus sub-tickets rather than one oversized ticket.\n- **Acceptance Criteria**: plain `-` bullets, not `- [ ]` (ADF has no native checkbox).\n- **No images**: do not embed images or use relative image links. This \"No images\" rule applies strictly to inline images in the description body; it does NOT restrict the attachments produced by the Materials Completeness Inventory / gather-and-attach pass, nor does it forbid recording a fetchable design/UI comp reference (its `attachment_id` or path).\n- **No empty headings**: every heading must have text on its line.\n- **Placeholders**: prefer `{placeholder}` over `<placeholder>`.\n\n## Quality Standards\n\n- **No vague language**: Replace \"should handle errors properly\" with \"should catch LLM provider timeouts and return a normalized error response with errorType 'TimeoutError'\"\n- **No assumptions without evidence**: Only reference code you actually read during research. If you're unsure about something, say so explicitly in the ticket.\n- **Appropriate scope**: The ticket should represent a coherent, deliverable unit of work. If the problem is too large, note that it may need to be broken into sub-tasks, but still write the parent ticket.\n- **Developer empathy**: Write as if the developer picking this up has general project knowledge but hasn't recently worked on this specific area. Give them enough context to get started quickly.\n\n## Important Reminders\n\n- Do NOT skip or abbreviate the research phase. The quality of the ticket depends entirely on the depth of your codebase understanding.\n- Do NOT make up file paths or function names. Only reference code you have actually found and read.\n- DO create the markdown file — do not just output the content to the chat. Write it to disk.\n- If the project has specific conventions (from CLAUDE.md or similar), ensure your ticket's requirements align with those conventions.\n"
|
|
12
12
|
},
|
|
13
13
|
"refactor-reviewer": {
|
|
14
14
|
"frontmatter": {
|
|
@@ -9,9 +9,10 @@ export const COMMANDS = {
|
|
|
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",
|
|
11
11
|
"critique-ticket.md": "Generate a ticket quality critique and save it locally.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command triggers an AI-powered critique of a Jira ticket and saves the result locally. **No human confirmation gates** — the command runs end-to-end without pausing. `$ARGUMENTS` should contain a single Jira ticket key in `PROJECT-NUMBER` format (e.g., `BAPI-123`).\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 the ticket key format**: Validate that `ticket_key` matches the regex pattern `^[A-Za-z][A-Za-z0-9]+-\\d+$`. If validation fails, stop immediately and report: \"The argument does not match the expected `PROJECT-NUMBER` format. Example: `BAPI-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 Critique\n\nCall the `request_ticket_critique` 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: \"Critique generation failed.\" Include the error details.\n\n## Final Report\n\n**On success**, display a summary including:\n\n- Path to the saved critique document: `{docs_dir}/ticket-critiques/{ticket_key}-ticket-quality-critique.md`\n\nNote: The critique was NOT pushed to Jira. To incorporate the critique findings into the Jira ticket description, run: `/update-ticket {ticket_key}`\n\n**On failure at any step**, stop immediately and display the step that failed and the error details.\n",
|
|
12
|
+
"estimate-epic.md": "Estimate an entire Jira Epic or an explicit ticket-key group via the shared epic estimation orchestrator.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\n`$ARGUMENTS` is either a Jira Epic key (e.g. `BAPI-518`) or an explicit `--tickets` key list — never both. This command calls the `estimate_epic` MCP tool, which delegates to the Bridge API epic estimation orchestrator, and renders the structured result.\n\nIf any step fails, stop immediately and report which step failed and why, preserving the user's originally entered epic key or ticket list in the report.\n\n## Step 1 — Parse Arguments\n\n1. **Parse `$ARGUMENTS`**: Extract exactly one key-source input, plus an optional `--allow-partial` flag.\n - Split `$ARGUMENTS` on whitespace.\n - If `--tickets` appears, every token after it (up to the next flag or end of input) is the explicit ticket-key list — this is the `ticket_keys` mode.\n - Otherwise, the first token matching the Jira key pattern (`[A-Z][A-Z0-9]+-\\d+`) is the `epic_key` — this is the epic mode.\n - `--allow-partial` may appear anywhere; if present, set `allow_partial_value = true`. If absent, omit `allow_partial` entirely (do not pass `false`).\n - Never resolve both an `epic_key` and a `ticket_keys` list from the same invocation — usage is one mode or the other.\n\n2. **Validate input**:\n - Usage forms: `/estimate-epic EPIC-KEY` or `/estimate-epic --tickets KEY-1 KEY-2 ...`, plus optional `--allow-partial`.\n - If neither an `epic_key` nor a `--tickets` list can be resolved, stop immediately and report:\n ```\n Usage: /estimate-epic EPIC-KEY [--allow-partial]\n /estimate-epic --tickets KEY-1 KEY-2 ... [--allow-partial]\n ```\n - If `--tickets` is present but followed by zero keys, stop immediately and report: \"`--tickets` requires at least one ticket key.\"\n - Do not invent or pass a `mode` parameter — there isn't one; the tool infers the source from whichever of `epic_key`/`ticket_keys` is supplied.\n\n## Step 2 — Call the Tool\n\nCall the `estimate_epic` MCP tool with:\n- `epic_key`: the resolved epic key — **only** when in epic mode. Omit entirely in ticket-key mode.\n- `ticket_keys`: the resolved ticket-key list — **only** when in ticket-key mode. Omit entirely in epic mode.\n- `allow_partial`: `allow_partial_value` if `--allow-partial` was passed; omit entirely otherwise (never pass `null`, an empty string, or an empty array for any absent field).\n\nNever pass both `epic_key` and `ticket_keys` in the same call.\n\nIf the tool returns an error envelope (a JSON object with an `error` field), stop and report the error message, preserving the epic key or ticket list the user originally entered.\n\n## Step 3 — Render the Result\n\nRender the successful result as a structured report — do not dump raw JSON by default:\n\n1. **Top**: the final estimate and its scale label (`estimate_label`) as the primary heading — this is the strongest element of the report.\n2. **Immediately after the summary**: `math_source`.\n3. **Next**: resolved child ticket keys (`child_ticket_keys`) and the per-child breakdown, presented compactly.\n4. **Only if non-empty**: a compact warning section listing `failed_child_keys` and `skipped_child_keys`.\n\nKeep the happy-path report concise and scannable. Use backticks for Jira keys and technical identifiers (e.g. `BAPI-518`).\n\n> Note: this tool does not accept a `recreate` parameter — the underlying epic estimation orchestrator (BAPI-522) always reuses cached child estimates and has no recreate knob to forward to.\n\n## Final Report\n\nOn successful completion, display a structured summary per Step 3 above. On failure, display the error message returned by the tool (or the usage error from Step 1), preserving the user's originally entered epic key or ticket list.\n",
|
|
12
13
|
"explore-ticket.md": "Explore the codebase for a task and recommend implementation options or surface clarifying questions.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\n`$ARGUMENTS` is a free-form prompt describing a task you want to accomplish and your goals for it. This is **not** a Jira ticket key — it is plain text describing the work.\n\nExecute all exploration and analysis directly in the main conversation. The user should see exploration progress as it happens.\n\nIf any critical stage fails, stop immediately and report which stage failed and why.\n\n## Stage 0 — Setup\n\n1. **Parse prompt**: Extract the prompt text from `$ARGUMENTS`. Trim any surrounding whitespace. If the prompt is empty or whitespace-only, stop immediately and display: `Usage: /explore-ticket <prompt describing your task and goals>`\n\n2. **Resolve docs directory**: Call the `get_docs_dir` MCP tool (no parameters). Store the returned path as `docs_dir`.\n\n3. **Generate output slug**: Create a kebab-case slug from the prompt — take the first 6-8 meaningful words, strip non-alphanumeric characters, lowercase, and truncate to 60 characters. The slug **must start with a letter** so it is a valid decision-page `ticket_key` in Stage 5 (`/^[A-Za-z][A-Za-z0-9_-]*$/`); if it would start with a digit or hyphen, prefix it with `exploration-`. If `{docs_dir}/explorations/{slug}.md` already exists, append a short timestamp suffix (e.g., `-1710000000`) — and fold that suffix **into the `slug` variable itself**, not just the filename, so that Stage 5 (`ticket_key`, `output_filename`) and Stage 6 (the `{docs_dir}/explorations/{slug}.md` rewrite) all reference the same slug. The output file path is `{docs_dir}/explorations/{slug}.md`.\n\n4. **Initialize tracking**: Prepare to track `key_files_examined` (list of files read during exploration), `web_searches` (list of topics searched), and `research_queries` (list of deep research queries).\n\nIf this stage fails, stop immediately and report the error. Do not proceed to Stage 1.\n\n## Stage 1 — Codebase Exploration\n\nThis is the core discovery stage. Take your time — thorough exploration is more valuable than speed.\n\n1. **Analyze the prompt** to identify which areas of the codebase are relevant: route files, agent flows, database models, library utilities, LLM integration, MCP server, tests, etc.\n\n2. **Search for files** matching patterns related to the task (e.g., `api/routes/**/*.py`, `src/python/llms/agents/**/*.py`, `db/models/*.py`).\n\n3. **Search for content** — relevant function names, class names, patterns, and keywords across the codebase.\n\n4. **Read the most relevant files** in detail — understand existing implementations, conventions, and patterns that relate to the task.\n\n5. **Build a mental model** of:\n - What exists today that relates to the task\n - What patterns and conventions are used in similar features\n - What dependencies, data flows, and integration points are involved\n - What gaps or unknowns remain that need external research\n\n6. **Track all significant files** examined in `key_files_examined`.\n\nDo not rush this stage. When in doubt, read more code rather than less. Continue exploring until you have a solid understanding of the relevant code.\n\nThis stage is non-blocking — always proceed to Stage 2 regardless of what you find, since the exploration informs what research is needed.\n\n## Stage 2 — Research Unknowns\n\nBased on gaps identified in Stage 1, decide what research is needed. Apply these decision rules:\n\n- **No research needed**: The codebase exploration answered all questions. Skip directly to Stage 3.\n- **Web search**: For quick factual lookups — library API signatures, configuration syntax, small \"how to\" questions. Examples: \"FastAPI dependency injection with custom headers\", \"Alembic batch migration syntax\". Do web searches inline and capture relevant findings.\n- **Deep research** (via `request_deep_research` MCP tool): For large, multi-faceted unknowns that require synthesizing information from multiple sources. Examples: \"Best practices for implementing WebSocket connection pooling in Python asyncio\", \"Tradeoffs between different approaches to real-time notification delivery in FastAPI applications\". Only use deep research when the question genuinely needs a multi-source investigation.\n\n**If deep research is needed:**\n\n1. Call `request_deep_research` with `wait_for_result` set to `true`, `save_locally` set to `true`, a descriptive `query`, and `context` describing the Bridge API tech stack and the specific task.\n2. If deep research fails, note the failure and fall back to web searches for the same topic. Do NOT halt the pipeline.\n\nTrack all research performed in `research_queries` and `web_searches`.\n\nThis stage is non-blocking — failures degrade the quality of analysis but do not stop the command. Log a warning for any failed research and continue.\n\n## Stage 3 — Analysis and Recommendation\n\nSynthesize everything from Stages 1 and 2 into a structured analysis:\n\n1. **Frame the goals and non-functional requirements first (required).** Before weighing implementation options, state plainly:\n - **Business goal** — the value this work delivers and why it matters.\n - **Desired end-state** — the concrete state the system should reach once this work is done.\n - **System behavior** — how the system must behave to complete its task (the quality attributes in prose).\n\n Then identify the non-functional requirements. Consider every one of these canonical NFR categories and include the ones that genuinely apply (omit the rest): security/privacy, performance/latency, reliability/failure-modes, observability/auditability, accessibility/UX, data-integrity/migration, compatibility, operability/config, compliance/SOC2, rollout/reversibility. For each NFR you include, write its `requirement` and its `implication` (what it changes about the implementation) — an NFR with no concrete implication is boilerplate; drop it. Classify each NFR's status with this rubric: `confirmed` only if explicitly stated or observable in code; `assumed` only if a low-risk, reversible default; `open` if it touches architecture, the data model, security, user-visible behavior, migration, or irreversible creation and is not settled. When the goals or an NFR are genuinely unclear, prefer marking them `open` and asking — clear goals make the functional choices far more accurate.\n\n2. **Identify viable implementation options** — at least 2 when multiple approaches exist, or 1 if there is genuinely only one reasonable path.\n\n3. **For each option, evaluate:**\n - Implementation complexity and estimated effort\n - How well it follows existing codebase patterns and conventions\n - Risks, tradeoffs, and potential pitfalls\n - Files that would need to be created or modified\n\n4. **Decide whether to recommend or ask questions:**\n - **Recommend** if one option is clearly superior, or if the tradeoffs are well-understood and the choice is primarily technical.\n - **Ask clarifying questions** if there are significant unknowns about goals, business requirements, or constraints that would change the recommendation. For each question, explain why the answer matters and how it would affect the choice between options.\n - **When in doubt, ask rather than guess** — this command prioritizes thorough discovery over premature commitment.\n\n5. **Frame the open decisions so they are decision-page-ready.** Stage 5 renders these as cards on an interactive decision page, so each decision — the primary implementation-direction choice, any `open` NFR from step 1, plus any clarifying question that has discrete candidate answers — must be expressed with:\n - A short decision **question** (e.g. \"Which storage approach for the cache?\").\n - **2–4 concrete option labels.** Do **not** include a \"None of these\" or \"Ask about this\" option — the page auto-appends both. When there is genuinely a single reasonable path, still provide a second option: frame it as the recommended approach **plus the strongest alternative you considered** (a minimal/conservative variant, the rejected approach, or \"defer until X is known\").\n - A one-line **consequence per option**, parallel to the options (what choosing that branch actually means for the implementation).\n - A `why_it_matters` line (the concrete impact of the decision) and a `recommendation_explanation` (why the recommended branch is best).\n - The 0-based index of the recommended option.\n - Optional supporting evidence: an Assessment paragraph plus `file:line` citations from Stage 1.\n\n Genuinely open-ended clarifying questions with no discrete answers do not need to become cards — capture them in the doc's Recommendation section as written. Aim to surface the real choices as cards; do not invent decisions just to fill the page.\n\nThis stage is inline analysis — no tool calls required. This stage is non-blocking — always proceed to Stage 4.\n\n## Stage 4 — Write Output\n\n1. Create the `explorations/` directory under `docs_dir` if it does not exist.\n\n2. Write the exploration document to the slug-based path determined in Stage 0 (`{docs_dir}/explorations/{slug}.md`) with this structure:\n\n```markdown\n# Exploration: {concise summary of the prompt}\n\n**Date**: {current date}\n**Prompt**: {original prompt text}\n\n## Context\n\n{Brief description of the task and what areas of the codebase are relevant.}\n\n## Goals & NFRs\n\n{The business goal, desired end-state, and required system behavior from Stage 3. Then the non-functional requirements: each with its category, requirement, implication, and status (confirmed / assumed / open). Open NFRs should also appear as decision cards on the Stage 5 page.}\n\n## Codebase Findings\n\n{Key discoveries from Stage 1. What exists today, what patterns are used, what the relevant code paths look like. Reference specific files and functions with file_path:line_number format.}\n\n## Research Findings\n\n{Findings from web searches and deep research, if any. If no research was performed, state \"No external research was needed.\"}\n\n## Implementation Options\n\n### Option A: {name}\n\n{Description, approach, affected files, pros, cons.}\n\n### Option B: {name}\n\n{Description, approach, affected files, pros, cons.}\n\n## Recommendation\n\n{If recommending: State which option and why. Mention any caveats or risks.}\n\n{If asking questions: State \"The following questions need to be answered before a confident recommendation can be made:\" followed by numbered questions. For each question, explain why it matters and how the answer would affect the recommendation.}\n\n## Key Files\n\n{Bulleted list of the most important files examined, with one-line descriptions of their relevance.}\n```\n\nIf the file cannot be written, stop immediately and report the failure.\n\n## Stage 5 — Generate Decision Page\n\nTurn the decisions framed in Stage 3 into an interactive HTML decision page so the user can record their choices by clicking, instead of hand-editing the markdown doc.\n\n1. **Map each Stage 3 decision to an actionable item.** Build an `actionable_items` array where each entry has:\n - `id`: a short stable id, e.g. `D-1`, `D-2`.\n - `question`: the decision question.\n - `options`: the 2–4 option labels (string array). Do **not** include \"None of these\" or \"Ask about this\" — the renderer auto-appends both.\n - `option_consequences`: the per-option consequence lines, **parallel to and the same length as** `options`.\n - `why_it_matters`: the concrete impact line.\n - `recommendation_explanation`: why the recommended branch is best.\n - `recommendation_index`: the 0-based index of the recommended option (must be within `options`).\n - `codebase_evidence` (optional): the Assessment paragraph plus `file:line` citations, shown collapsed.\n - `original_question` (optional): include only when the item maps to a verbatim clarifying question.\n\n Optionally include `clear_improvements` for low-risk findings you are confident about that do not need a choice (each with `id`, `title`, `action`, `confidence`, `source`) — these render as an informational list and are not submitted.\n\n2. **Call `generate_decision_page`** with routing fields at the root and all heavy arrays nested under `content`:\n - `artifact_type`: `pre_ticket_planning` (renders the read-only System Goals & NFRs panel above the decision cards).\n - `ticket_key`: the Stage 0 `slug` (a non-Jira slug is fine — it must start with a letter and contain only letters, digits, hyphens, or underscores).\n - `output_subdir`: `explorations` (so the page lands beside the markdown doc).\n - `output_filename`: `{slug}-decisions.html`.\n - `labels`: exploration-flavored overrides, e.g. `title` = \"Exploration Decisions\", `section_heading` = \"Implementation Decisions\", and an `intro` that frames the page as choosing the direction for the explored task.\n - `content`: an object containing `system_goals`, `actionable_items`, and optionally `clear_improvements` from step 1. **`system_goals` MUST ALWAYS be passed** inside `content` so the backend always writes a page. Never omit it, even if all NFRs are confirmed. Open NFRs must ALSO appear in `actionable_items`. (Do not pass `implementation_order` inside `content` — that is for epic surfaces, not a single explored task.)\n\n ```typescript\n interface ExploreTicketContent {\n system_goals?: {\n business_goal: string;\n desired_end_state: string;\n system_behavior: string;\n nfrs?: Array<{\n category: string;\n requirement: string;\n implication: string;\n status: \"confirmed\" | \"assumed\" | \"open\";\n }>;\n };\n actionable_items?: Array<{\n id: string; // e.g. \"D-1\", \"D-2\"\n question: string;\n why_it_matters: string;\n recommendation_explanation: string;\n options: string[]; // 2-4 option labels (no \"None of these\" or \"Ask about this\")\n option_consequences: string[]; // same length as options\n recommendation_index: number; // 0-based within options\n codebase_evidence?: string; // optional: assessment + file:line citations\n original_question?: string; // optional: only when item maps to a clarifying question\n }>;\n clear_improvements?: Array<{\n id: string;\n title: string;\n action: string;\n confidence: string;\n source: string;\n }>;\n // implementation_order: for epic surfaces only — do NOT include for single task explorations\n // depends_on: hard prerequisites (titles/keys that must land first)\n // recommended_after: soft sequencing preferences, not hard blockers\n }\n ```\n\n Example call:\n ```json\n {\n \"ticket_key\": \"my-task-slug\",\n \"artifact_type\": \"pre_ticket_planning\",\n \"output_subdir\": \"explorations\",\n \"output_filename\": \"my-task-slug-decisions.html\",\n \"labels\": { \"title\": \"Exploration Decisions\", \"section_heading\": \"Implementation Decisions\" },\n \"content\": {\n \"system_goals\": {\n \"business_goal\": \"Improve token efficiency for MCP sessions.\",\n \"desired_end_state\": \"Core profile under 15k tokens.\",\n \"system_behavior\": \"Schema delivered on demand, not in every session.\",\n \"nfrs\": [\n { \"category\": \"security/privacy\", \"requirement\": \"Errors in JSON envelope only\", \"implication\": \"Never render validation errors into HTML\", \"status\": \"confirmed\" }\n ]\n },\n \"actionable_items\": [\n {\n \"id\": \"D-1\",\n \"question\": \"Which approach?\",\n \"why_it_matters\": \"Determines whether schema stays lean in production.\",\n \"recommendation_explanation\": \"Option A saves ~1.8k tokens per session.\",\n \"options\": [\"Lean schema + in-handler validation\", \"Keep full schema\"],\n \"option_consequences\": [\"~1.8k token saving per session.\", \"No change from today.\"],\n \"recommendation_index\": 0\n }\n ]\n }\n }\n ```\n\n3. **Handle the response `status`:**\n - `no_decisions_needed`: no page was written (no open decisions, no `system_goals`, and no `implementation_order`). This should not occur when `system_goals` is always passed. Skip Stage 6's capture loop entirely, tell the user there were no open decisions, and go straight to Stage 6's \"Suggest next steps\" guidance.\n - `decision_page_generated`: surface the returned `file_path` and proceed to Stage 6's capture loop. **Always proceed to Stage 6's capture loop when `decision_page_generated` is returned**, regardless of `actionable_items_count`. A goals-only page (zero actionable items) still has NFR stance controls that must be submitted.\n\nThis stage is non-blocking: if `generate_decision_page` fails, do not halt. **You MUST output a highly visible warning** (e.g. **⚠ WARNING: The decision page could not be generated** in bold) explaining that generation failed and that the user should work from the markdown doc written in Stage 4 instead. Do not silently continue — the failure must be diagnosable from your output. Then skip to Stage 6's \"Suggest next steps\" guidance.\n\n## Stage 6 — Capture Decisions and Finalize\n\nCapture the user's choices, fold them into the exploration doc as resolved decisions, and recommend what to do next.\n\n1. **Direct the user to the page.** Provide the `file_path` from Stage 5 and tell them to open it in their browser. Explain that for any item they are unsure about they can choose \"Ask about this\" and you will talk it through, and that they can also ask questions in chat before submitting.\n\n2. **Q&A loop and commit signal.** Engage with each user message as either a commit or a discussion turn:\n - **Commit:** trim the full message and attempt to parse the entire trimmed message as JSON. Treat it as a commit only when the parsed value is an object with all three top-level fields: `ticket_key` (string), `decisions` (object), and `general_comment` (string). The first valid commit-shaped paste commits — do not over-validate the per-card fields.\n - **Discussion:** anything that is not commit-shaped JSON. Answer from the exploration doc written in Stage 4 and from codebase lookups. If a JSON-shaped paste is missing one of the three required fields, say which field is missing rather than treating it as a freeform question.\n - **In-flight overrides:** when the user clearly changes a choice in chat (\"go with option B for D-2\", \"change D-3 to None of these\") or gives new overarching guidance, record it as a working-memory override. On commit, the submitted JSON is the baseline and recorded overrides take precedence; post a one-line acknowledgement naming each overridden item before you rewrite the doc.\n\n3. **Resolve \"Ask about this\" items (hard rule).** After accepting a commit, scan `decisions` for any item where `choice === \"ask\"`. For each, present the relevant evidence and trade-offs and continue the discussion until the user gives an explicit decision, which you record as an override. Do not rewrite the doc while any `choice === \"ask\"` remains unresolved — do not honor \"just skip those\".\n\n4. **Finalize the exploration doc.** Rewrite `{docs_dir}/explorations/{slug}.md` so it reads as a final draft with the decisions already made — not a mechanical append:\n - Mark the chosen Implementation Option as the selected direction in the Recommendation section and integrate it so the doc reads as a resolved plan.\n - Fold answered clarifying questions into the Context / Recommendation sections.\n - For a \"None of these\" choice, record that the proposed options were rejected, including the user's comment.\n - Weave `general_comment` in as overarching guidance; do not add a separate \"Reviewer Notes\" section.\n - Preserve all unaffected sections unchanged.\n\n5. **Suggest next steps (conditional).** Assess what the explored work still needs to be fully groomed, and recommend only the follow-ups that genuinely apply — as pointers for the user to run, not actions you take automatically:\n - A **brainstorm** (`/brainstorm` or `request_brainstorm`) when the direction would benefit from a thorough, wide review before committing.\n - A **second opinion** (`second_opinion`) when a few specific contested points need an independent check.\n - **Web or deep research** (`request_deep_research`) when the chosen direction still rests on technical unknowns that need grounding.\n - **Uploading a ticket** (`/write-ticket` or `create_ticket`) when the requirements are clear and certain. If the explored work is well-grounded and the decisions leave it in a good state, advise uploading directly.\n\nThis stage is non-blocking: if the user never commits, leave the doc as written in Stage 4 and stop without forcing a decision.\n\n## Final Report\n\nOn successful completion of all stages, display:\n\n> **Exploration Complete**\n>\n> **Prompt**: {first 80 characters of prompt}...\n> **Output**: {full path to the finalized exploration doc}\n> **Decision Page**: {full path to the generated decisions.html, or \"not generated\" when no decisions were needed or generation failed}\n> **Files Examined**: {count of key_files_examined}\n> **Research**: {count of web_searches} web searches, {count of research_queries} deep research queries\n>\n> **Result**: {\"Recommendation provided\" | \"Clarifying questions raised — N questions need answers\"}\n> **Decisions Captured**: {count of decisions the user committed, or \"none — page not submitted / no decisions needed\"}\n> **Suggested Next Step**: {the conditional next step advised in Stage 6, e.g. \"upload a ticket\", \"run a brainstorm\", or \"none\"}\n\nOn failure at any stage, stop immediately and report:\n- Which stage failed (by number and name)\n- The error details\n- Any partial results that were produced before the failure\n",
|
|
13
14
|
"full-automation.md": "---\nschedulable: true\narguments: {\"positionals\":[],\"flags\":[{\"name\":\"ideaFile\",\"flag\":\"--idea-file\",\"type\":\"string\",\"required\":true},{\"name\":\"auto\",\"flag\":\"--auto\",\"type\":\"boolean\"}]}\n---\n\nRun the end-to-end full-automation chain (idea-to-ticket → review-ticket → start-tickets) via the server-side chain orchestrator.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command drives Phase A's server-side full-automation chain. The only orchestration tools you may drive are `run_full_automation` and `resume_full_automation`; any other Bridge API MCP call you make must be one a server `agent_task` instruction explicitly directs. The server owns all orchestration — ticket creation, review fan-out, and the start-tickets handoff. Do NOT enrich, re-implement, or second-guess any of that work on the client side.\n\n## Stage 0 — Parse arguments\n\n1. Tokenize `$ARGUMENTS` on whitespace. Recognize the following position-independent flags. Each flag supports both the space form (`--flag value`) and the equals form (`--flag=value`) where a value is taken:\n - `--idea <text>` / `--idea=<text>`\n - `--idea-file <path>` / `--idea-file=<path>`\n - `--auto`\n - `--require-approval`\n - `--scheduled-at <ISO-8601>` / `--scheduled-at=<ISO-8601>`\n - `--chain-run-id <UUID>` / `--chain-run-id=<UUID>`\n - `--max-children N` / `--max-children=N`\n - `--allow-duplicate`\n\n2. Value-consumption rules:\n - `--idea` (space form) consumes every subsequent token until the next recognized flag — the idea may contain spaces.\n - `--idea-file`, `--scheduled-at`, `--chain-run-id`, and `--max-children` each consume exactly one value token (the immediately following token, or the text after `=`).\n - `--auto`, `--require-approval`, and `--allow-duplicate` are boolean toggles and consume no value.\n\n3. Free-form idea: all non-flag tokens become the free-form `idea` text **only when both `--idea` and `--idea-file` are absent**. Join those tokens back together preserving order and trim surrounding whitespace. When `--idea` or `--idea-file` is present, there must be no leftover non-flag tokens: reject any stray non-flag token (for example, text following `--idea=<text>` or following the `--idea-file <path>` value) before any MCP tool call rather than silently dropping it.\n\n4. Reject **unknown flags** (any token beginning with `--` that is not one of the recognized flags above) before making any MCP tool call. Stop and report the offending flag.\n\n5. Reject **combined `--idea` and `--idea-file`** before making any MCP tool call:\n ```text\n Provide exactly one of --idea or --idea-file; do not pass both.\n ```\n\n6. Missing-input rule: unless `--chain-run-id` is present, an idea is required. If `--chain-run-id` is absent **and** no idea was supplied (no `--idea`, no `--idea-file`, and no free-form idea tokens), stop immediately and display exactly:\n ```text\n Usage: /full-automation (--idea \"<text>\" | --idea-file <path> | <free-form idea>) [--require-approval] [--scheduled-at <ISO-8601>] [--chain-run-id <UUID>] [--max-children N] [--allow-duplicate]\n ```\n\n7. `--chain-run-id` is the resume path and does **not** require any idea content — when it is present, skip the missing-input check above and proceed to resume.\n\n8. `--idea-file` is forwarded as a path. The skill must **not** read the file contents locally; the server resolves the file.\n\n9. Resolve the derived values:\n - `auto_approve` defaults to `true` (full automation is hands-off by default). It is `false` **only** when `--require-approval` is present. `--auto` is accepted but redundant (a no-op that restates the default), and `--scheduled-at` likewise runs hands-off. When `--require-approval` is present, the chain pauses at external-mutation and review-decision gates for confirmation.\n - `max_children` is the parsed positive integer when `--max-children` is present; otherwise omit it entirely so the server default applies.\n - `allow_duplicate` is `true` only when `--allow-duplicate` is present; otherwise omit it.\n\n## Stage 1 — Drift-check gate\n\nThis gate runs immediately after parsing and **before any MCP tool call**.\n\n1. If `--scheduled-at` is absent, skip this entire stage.\n2. Compute `delta_seconds = now_utc - scheduled_at` (both in UTC).\n3. If `delta_seconds <= 60`, proceed silently to Stage 2.\n4. If `delta_seconds > 60`, present this prompt verbatim (substituting the bracketed values):\n ```text\n Scheduled at <T-iso> UTC; running now at <now-iso> UTC (<Δ human-readable> late). The laptop was likely asleep or unavailable at the scheduled time. Confirm to proceed with the chain, or cancel.\n ```\n Offer the user the choices: `[Confirm] / [Cancel]`.\n5. On `Confirm`, proceed to Stage 2.\n6. On `Cancel`, print this message verbatim and stop:\n ```text\n Chain cancelled by user (drift confirmation declined). No Jira tickets created.\n ```\n When the user cancels, `run_full_automation` must **not** be called.\n7. The 60-second threshold is fixed and must not be made configurable.\n\n## Stage 2 — Run or resume the chain\n\nThe chain is driven entirely by the server-side orchestrator. Announce progress using each envelope's `preamble`, preserving its `Stage N of M — <title>` shape.\n\n### Stage 2a — Start (when `--chain-run-id` is absent)\n\nCall **only** `run_full_automation`. Build the payload, **omitting** any optional value that was not provided (never send `null` or empty strings):\n```json\n{\n \"idea\": \"<resolved inline/free-form idea, when provided>\",\n \"idea_file\": \"<idea-file path, when provided>\",\n \"auto_approve\": \"<resolved boolean>\",\n \"scheduled_at\": \"<scheduled-at value, when provided>\",\n \"max_children\": \"<parsed integer, when provided>\",\n \"allow_duplicate\": \"<true, when provided>\"\n}\n```\n\n### Stage 2b — Resume (when `--chain-run-id` is present)\n\nCall **only** `resume_full_automation` first, with:\n```json\n{\n \"chain_run_id\": \"<UUID>\",\n \"agent_result\": \"Manual resume requested from /full-automation --chain-run-id.\"\n}\n```\n\n### Stage 2c — Envelope loop\n\nFor each envelope returned by `run_full_automation` / `resume_full_automation`, dispatch on `status` / `next_action.kind`:\n\n- `status: \"failed\"` → stop chain progression and render the final report (Stage 3) with the failure status. Do **not** advance to any later stage.\n- `status: \"completed\"` or `next_action.kind: \"complete\"` → render the final report (Stage 3).\n- `status: \"needs_agent_task\"` with `next_action.kind: \"agent_task\"` → display the envelope `preamble`, perform the agent task exactly as the `next_action.instruction` directs, then call `resume_full_automation` with `chain_run_id` set to the envelope's `chain_run_id` and `agent_result` set to the resulting text. Loop back and process the next envelope.\n\nSpecial case — the stage-3 handoff: when the agent-task instruction names a `/start-tickets ...` command, invoke that slash command in **this same session**, summarize the outcome in one line, and pass that one-line summary as `agent_result` to `resume_full_automation`.\n\nConstraints:\n- On your own initiative, the skill must **not** call any Bridge API MCP tool other than `run_full_automation` / `resume_full_automation` — in particular, never independently drive orchestration (`run_pipeline`, `resume_pipeline`, `get_pipeline_recipe`) or enrich tickets (`get_ticket`, `update_ticket_description`, etc.). **However, when a `needs_agent_task` instruction returned by the server explicitly directs you to call a specific Bridge API MCP tool** (for example an orchestrator-directed `get_tickets`, `create_ticket`, `attachment`, or `track_ticket`), **you must invoke that tool exactly as instructed** — performing an orchestrator-directed agent task is not re-orchestrating.\n- If a v1 envelope unexpectedly returns `next_action.kind: \"mcp_call\"`, stop with a clear protocol error instead of bypassing the server-side orchestrator:\n ```text\n Protocol error: chain returned next_action.kind \"mcp_call\", which is out of scope for /full-automation v1. Stopping.\n ```\n\n## Stage 3 — Final report\n\nWhen the chain completes or fails, render this skeleton verbatim:\n\n```markdown\n## Full Automation Complete\n\nChain run: <chain_run_id>\nIdea: <first 80 chars of idea>...\nStages:\n 1. idea-to-ticket: <stages[0].summary>\n 2. review-ticket: <stages[1].summary>\n 3. start-tickets: <stages[2].summary>\n\nTotal Jira tickets created: N\nTotal worktrees spawned: M\nStatus: Success / Failed at stage N — <reason>\n```\n\n- Stage summaries come from the chain envelope or manifest when present.\n- When the completed envelope does not include full stage objects, use the summaries already surfaced in the prior `preamble` text rather than calling additional tools.\n- A stage-1 `too_vague_to_ticket` failure must render the upstream halt reason and set `Status: Failed at stage 1 — <reason>`.\n- Failed chains must not advance to later stages after a failed envelope is received.\n",
|
|
14
|
-
"idea-to-ticket.md": "Convert a short human idea into a Jira ticket (or Epic plus child tickets) via the server-side idea-to-ticket pipeline.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command is recipe-driven. Do not call MCP tools directly other than `get_pipeline_recipe` — the recipe determines which tools to call and with what parameters.\n\n## Stage 0 — Parse arguments\n\n1. Tokenize `$ARGUMENTS` on whitespace. Recognize the following position-independent flags (any other tokens are part of the idea):\n - `--allow-duplicate`\n - `--max-children=N` where `N` is a positive integer\n - `--auto`\n\n Flags are optional. Treat absence of a flag as the default; never pass empty-string or null as a placeholder.\n\n2. Everything that is not a recognized flag is the free-form `idea` text. Join those tokens back together preserving order. Trim surrounding whitespace.\n\n3. If the resulting `idea` is empty, stop immediately and display:\n ```\n Usage: /idea-to-ticket <idea> [--allow-duplicate] [--max-children=N] [--auto]\n ```\n\n## Stage 1 — Derive pipeline variables\n\n4. Derive `slug` from the first 6-8 meaningful words of the idea: lowercase, kebab-case, strip non-alphanumeric characters except hyphens, and truncate to roughly 60 characters. Skip stop-words such as \"the\", \"a\", \"an\" when picking the 6-8 meaningful words.\n\n5. Derive `run_id` as `<YYYYMMDD-HHMMSS>-<short-uuid>` using the current UTC time and a short UUID suffix (8 hex chars is enough). The combination of `slug` and `run_id` uniquely identifies this run's artifact directory.\n\n6. Derive the boolean-as-string variables:\n - `allow_duplicate` is `\"true\"` if `--allow-duplicate` was present, otherwise `\"false\"`.\n - `auto_approve_external` is `\"true\"` if `--auto` was present, otherwise `\"false\"`.\n - `max_children` is the integer following `--max-children=` as a string, or `\"10\"` when the flag is absent.\n\n## Stage 2 — Call the recipe\n\n7. Call the `get_pipeline_recipe` MCP tool with:\n - `pipeline`: `\"idea-to-ticket\"`\n - `variables`: `{ \"idea\": \"<idea>\", \"slug\": \"<slug>\", \"run_id\": \"<run_id>\", \"allow_duplicate\": \"<allow_duplicate>\", \"auto_approve_external\": \"<auto_approve_external>\", \"max_children\": \"<max_children>\" }`\n\n Do NOT pass `docs_dir` or `idea_hash` in variables — both are auto-injected by the pipeline system (`docs_dir` from `BAPI_DOCS_DIR`; `idea_hash` is a stable hash derived from the `idea`).\n\n If the tool returns an error, stop and report the failure.\n\n8. 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\n## Stage 3 — Final summary\n\n9. After all steps complete, display a summary:\n ```\n ## Pipeline Complete\n\n **Idea**: <first 80 characters of idea>...\n **Slug**: <slug>\n **Run directory**: <docs_dir>/idea-to-ticket/<slug>-<run_id>/\n **Steps executed**: N of M\n **Status**: Success / Failed at step N\n ```\n",
|
|
15
|
+
"idea-to-ticket.md": "Convert a short human idea into a Jira ticket (or Epic plus child tickets) via the server-side idea-to-ticket pipeline.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command is recipe-driven. Do not call MCP tools directly other than `get_pipeline_recipe` — the recipe determines which tools to call and with what parameters.\n\n## Stage 0 — Parse arguments\n\n1. Tokenize `$ARGUMENTS` on whitespace. Recognize the following position-independent flags (any other tokens are part of the idea):\n - `--allow-duplicate`\n - `--max-children=N` where `N` is a positive integer\n - `--auto`\n\n Flags are optional. Treat absence of a flag as the default; never pass empty-string or null as a placeholder.\n\n2. Everything that is not a recognized flag is the free-form `idea` text. Join those tokens back together preserving order. Trim surrounding whitespace.\n\n3. If the resulting `idea` is empty, stop immediately and display:\n ```\n Usage: /idea-to-ticket <idea> [--allow-duplicate] [--max-children=N] [--auto]\n ```\n\n## Stage 1 — Derive pipeline variables\n\n4. Derive `slug` from the first 6-8 meaningful words of the idea: lowercase, kebab-case, strip non-alphanumeric characters except hyphens, and truncate to roughly 60 characters. Skip stop-words such as \"the\", \"a\", \"an\" when picking the 6-8 meaningful words.\n\n5. Derive `run_id` as `<YYYYMMDD-HHMMSS>-<short-uuid>` using the current UTC time and a short UUID suffix (8 hex chars is enough). The combination of `slug` and `run_id` uniquely identifies this run's artifact directory.\n\n6. Derive the boolean-as-string variables:\n - `allow_duplicate` is `\"true\"` if `--allow-duplicate` was present, otherwise `\"false\"`.\n - `auto_approve_external` is `\"true\"` if `--auto` was present, otherwise `\"false\"`.\n - `max_children` is the integer following `--max-children=` as a string, or `\"10\"` when the flag is absent.\n\n## Stage 2 — Call the recipe\n\n7. Call the `get_pipeline_recipe` MCP tool with:\n - `pipeline`: `\"idea-to-ticket\"`\n - `variables`: `{ \"idea\": \"<idea>\", \"slug\": \"<slug>\", \"run_id\": \"<run_id>\", \"allow_duplicate\": \"<allow_duplicate>\", \"auto_approve_external\": \"<auto_approve_external>\", \"max_children\": \"<max_children>\" }`\n\n Do NOT pass `docs_dir` or `idea_hash` in variables — both are auto-injected by the pipeline system (`docs_dir` from `BAPI_DOCS_DIR`; `idea_hash` is a stable hash derived from the `idea`).\n\n If the tool returns an error, stop and report the failure.\n\n8. 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\n The recipe drives the ordered stages for you — do not invoke them directly. In order they are: preflight-and-readiness → research-decision → execute-research → duplicate-and-context-scan → screen-and-resolve → frame-goals-and-nfrs → **comp-analysis** (a gated, backend-safe perception step that maps any attached/referenced design comp to existing components, templates, SCSS/CSS tokens, and routes before drafting; it short-circuits for backend-only or no-comp work) → draft-and-critique → upload-and-track.\n\n## Stage 3 — Final summary\n\n9. After all steps complete, display a summary:\n ```\n ## Pipeline Complete\n\n **Idea**: <first 80 characters of idea>...\n **Slug**: <slug>\n **Run directory**: <docs_dir>/idea-to-ticket/<slug>-<run_id>/\n **Steps executed**: N of M\n **Status**: Success / Failed at step N\n ```\n",
|
|
15
16
|
"implement-ticket.md": "# Implement 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\n## CONDUCTOR_MESSAGE_RELAY ##\n\nIf you were launched under the Conductor (your environment carries a conductor run/worker identity), cooperatively poll for supervisor guidance while you work: at natural checkpoints — after reading context, before major code changes, after major implementation chunks, while polling CI checks during the post-PR correction loop, and before your final response — call the `check_messages` MCP tool. The tool reads and acknowledges any messages addressed to you, and acknowledged messages are not redelivered, so a later call returns only new guidance. This is cooperative polling only — it is not prompt injection and never mutates a live session. If the tool or conductor identity is unavailable, continue the task without derailing.\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\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`.\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]\n Usage: /implement-ticket <ticket_key> [--auto]\n ```\n\n2. Call the `get_pipeline_recipe` MCP tool with:\n - `pipeline`: `\"implement-ticket\"`\n - `variables`: `{ \"ticket_key\": \"<ticket_key>\" }`\n - `auto_approve`: `true` — only when `--auto` was passed; otherwise omit this field entirely.\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\n---\n\n# Worker scope discipline and clean exit (Conductor auto mode)\n\nThese rules apply only when you were launched under the Conductor in auto mode (`--auto`); a normal interactive `/implement-ticket` run is unaffected.\n\n## Declared file-scope discipline (N-2)\n\nIf your environment carries `BAPI_CONDUCTOR_DECLARED_TOUCHED_FILES_JSON` (a JSON array of the ticket's declared touched files), stay within that declared file boundary: do **not** create, modify, or delete files outside the declared set. Those out-of-scope files typically belong to a sibling ticket, and editing them risks a merge conflict or a silent clobber of the sibling's merged work. The pre-PR file-scope guard (run at the PR-creation step) will warn about any out-of-scope diff — treat that warning as a signal to re-check your scope, not as a blocker. When the variable is absent, empty, or invalid there is no declared boundary and this rule does not apply.\n\n## Clean session exit (D2)\n\nAfter the final pipeline step completes, cleanly end your worker session (for example by issuing the `/exit` command) so the worktree is released and no idle process lingers — but **only when no follow-up remains that you still own**. Do **not** exit while any of the following is true:\n\n- there are unresolved CI failures you are still correcting (the post-PR CI-correction loop in the CI-monitoring step still owns work),\n- review changes were requested and you have not yet addressed them,\n- there is a merge conflict on your PR that you still own,\n- you have unpushed local commits.\n\nExit only after your final branch state is pushed, the done-gate / CI-monitoring workflow required by the recipe has completed, and no CI/review follow-up remains. A clean `SessionEnd` is both the correct terminal lifecycle signal and the point at which the worker should exit.\n",
|
|
16
17
|
"install-bridge.md": "Bootstrap Bridge API project configuration from the local codebase via the easy-install manifest.\n\n$ARGUMENTS\n\n---\n\n# Instructions\n\nThis command takes no arguments; any `$ARGUMENTS` text is ignored.\n\nCommand contract version: **2**. The install manifest returns a `command_contract_version`; Stage 2\ncompares it to this number to detect a stale scaffolded copy of this command.\n\nThis command performs a one-time \"easy install\" of Bridge API project configuration. It reads the\nserver-owned install manifest once, derives values for the **unset** bootstrap fields from the local\ncodebase, asks for human approval of the project description, and applies everything in a single\natomic call. The server owns all skip-if-set, conflict, and confirmation semantics — this command\nnever makes its own skip-if-set decisions.\n\nThis command is portable across Claude Code, Cursor, and Copilot: it only drives the Bridge API MCP\ntools (`get_my_role`, `get_install_manifest`, `apply_install_manifest`).\n\nIf any stage fails, stop immediately and report which stage failed and why.\n\n## Stage 1 — Admin preflight\n\n1. Call the `get_my_role` MCP tool (no parameters). Inspect the response:\n - If `source` is `\"legacy\"`: proceed (legacy keys are permitted).\n - Else if `role` is `\"admin\"`: proceed.\n - Otherwise (a non-admin `user_access` key): stop immediately and display:\n ```\n Admin role required to apply install configuration. Ask a project admin to run /install-bridge,\n or use an admin API key.\n ```\n\n## Stage 2 — Read the manifest (once)\n\n1. Call the `get_install_manifest` MCP tool exactly once.\n2. Keep the returned `snapshot_token` verbatim — you must pass the SAME token to the apply call in\n Stage 5. Do not call `get_install_manifest` again before applying; a fresh read would invalidate\n the token you are about to use.\n3. The manifest contains ordered `groups` of bootstrap fields (each with `field_name`, `is_set`,\n `current_value`, `guidance`, `examples`, `validation_summary`, `requires_confirmation`), a list of\n `deferred_fields`, a `next_step`, `done_criteria`, a `command_contract_version`, and the\n `snapshot_token`.\n4. Compare the manifest's `command_contract_version` to this command's contract version (2, stated at\n the top of this file). If the manifest's version is HIGHER, this scaffolded command copy is stale:\n warn the user to refresh it by running `npx -y @bridge_gpt/mcp-server --init` in the project root,\n then proceed conservatively — wherever the manifest's `guidance`, `next_step`, or `done_criteria`\n differ from these instructions, follow the manifest.\n\n## Stage 3 — Derive values for UNSET bootstrap fields only\n\n1. Consider ONLY fields whose `is_set` is `false`. Never re-derive or overwrite a field that is\n already set — the server will also skip already-set fields, but you should not even propose them.\n2. For each unset field, derive a value from the local codebase following that field's `guidance`\n (e.g. infer `working_in` from frameworks/manifests, `version_control_system` from the git remote,\n testing stacks from test config and dependencies, directory fields from the repo layout).\n3. Omit any field you are uncertain about or that does not apply — leaving it unset is always\n acceptable. Do NOT guess.\n4. Specifically, do NOT invent a `version` when the platform has no meaningful version concept; leave\n it unset.\n5. Before deriving `version_control_system` or `base_branch`, confirm the git repository root is THIS\n project's root: `git rev-parse --show-toplevel` must resolve to the project directory itself. If\n the git root is an ancestor directory (the project is nested inside another repository), OMIT both\n fields and note why in the final report — deriving them would describe the parent repository, not\n this project.\n6. If you find real evidence for TWO OR MORE plausible values for a field (e.g. configs for multiple\n test frameworks, multiple frameworks in a monorepo), treat the value as ambiguous and omit it\n rather than picking one.\n7. For the \"Automation policy\" group (`selected_mcp_slugs`): propose MCP validation manuals only from\n clear platform markers, following the field's manifest guidance (e.g. SFCC cartridges →\n `b2c-commerce-developer`; a Playwright config → `playwright-mcp`; PWA Kit markers →\n `pwa-kit-mcp`). This field requires human confirmation (Stage 4). Omit it entirely when no manual\n clearly applies — never propose a slug on weak evidence.\n\n## Stage 4 — Human approval for confirmation-requiring fields\n\nSome manifest fields carry `requires_confirmation: true` (currently `project_description` and\n`selected_mcp_slugs`). These are never applied on derivation alone — each needs explicit human\napproval.\n\n1. If `project_description` is unset and you can draft a concise description from the codebase,\n present the proposed `project_description` text to the human and ask for explicit approval before\n including it.\n2. If you derived a `selected_mcp_slugs` list in Stage 3, present the proposed slugs and the platform\n evidence for each, and ask for approval in the SAME batched question round as the description.\n3. Include a confirmation-requiring field in the apply payload ONLY as\n `{ \"value\": <approved value>, \"confirmed\": true }`, and only after the human approves it. If the\n human does not approve a field, omit that field entirely.\n4. If no human response can be obtained (e.g. a non-interactive / headless session), do NOT stall and\n do NOT abandon the install: proceed to Stage 5 with every confirmation-requiring field omitted,\n and report them as \"pending human input\" in the final summary. The other derived fields must\n still be applied — unapproved fields never block them.\n\n## Stage 5 — Apply (one call)\n\n1. Make exactly ONE call to the `apply_install_manifest` MCP tool, passing:\n - `snapshot_token`: the exact token from Stage 2.\n - `fields`: a map of the derived fields. Scalar fields may be passed directly\n (e.g. `\"base_branch\": \"main\"`); confirmation-requiring fields (e.g. `project_description`,\n `selected_mcp_slugs`) must use the `{ \"value\": ..., \"confirmed\": true }` object form from\n Stage 4.\n2. Do not implement any client-side skip-if-set, conflict, or confirmation logic — the server owns\n all of that and returns the outcome buckets.\n3. The apply is partial-tolerant: fields that fail server-side validation are returned in the\n `rejected` bucket while the valid fields still commit. A rejected field is therefore reported,\n not fatal — do NOT retry the whole apply just because one field was rejected.\n\n## Stage 6 — Persist the routing credential\n\nThe Bash-spawned `start-tickets` CLI runs in a DIFFERENT runtime surface than this MCP server, so a\nkey that lives only in `.mcp.json` / `.cursor/mcp.json` is invisible to it and difficulty→model\nrouting silently degrades. This final stage persists the already-validated key into the user-scoped\ncredential store (`~/.config/bridge/credentials.json`) so shell-spawned CLI commands can resolve it.\n\n1. Call the `persist_routing_credential` MCP tool with `repo_name` set to the repository name for\n this install (the configured `BAPI_REPO_NAME`). Pass `repo_name` ONLY — this tool resolves the\n API key inside the MCP server process. NEVER pass or display `BAPI_API_KEY` (nor `api_key`,\n `apiKey`, `secret`, or `token`); the key value must not appear in the tool call or in any output.\n2. On success, tell the user the credential was stored, echoing the returned `target` and `path`,\n e.g. `Stored routing credential for bapi:<repo_name> at <path>`.\n3. On failure, do NOT block the install — show the rest of the install summary anyway, then tell the\n user the routing credential could not be stored. They can rerun `/install-bridge` after setting\n `BAPI_API_KEY` in the environment, or run\n `npx -y @bridge_gpt/mcp-server credentials migrate-agent-config --write-credentials` to migrate an\n existing key. Until then, `start-tickets` model routing fails open (assumes a hard ticket and\n defaults to premium/Opus when available) — this is the MOST EXPENSIVE model tier, so unexplained\n cost is the symptom of leaving this unfixed. Recommend verifying credential resolution afterwards\n with `npx -y @bridge_gpt/mcp-server doctor`.\n\n## Stage 7 — Summarize the outcome\n\nBegin the summary with an explicit applied count: \"Applied N of M derivable fields\" (M = the unset\nbootstrap fields you derived values for). An install that applied 0 fields must say so loudly — the\ninstall is NOT complete until the apply call reports applied fields.\n\nThen summarize the six buckets from the apply response for the user:\n- `applied` — fields written this run.\n- `skipped` — fields already set (left untouched).\n- `conflict` — fields that changed since the manifest was read (re-run /install-bridge to retry).\n- `needs_confirmation` — fields awaiting explicit confirmation (e.g. project_description).\n- `rejected` — fields that failed validation or were not bootstrap-eligible (the other fields still\n applied; fix or drop the rejected values before any retry).\n- `deferred` — fields intentionally not auto-written by install (owned by /learn-repository or set\n deliberately).\n\nAfter the buckets, report the **integrations checklist** from the manifest's `integrations` list\n(read in Stage 2): one line per integration showing `label` and configured / NOT configured, and for\neach unconfigured one, its `required_for` items and the `configure_in` pointer. STRICT INVARIANT:\nyou DIRECT the human to configure integrations — you never ask for, accept, echo, or transport an\nintegration credential (API token, access token, webhook secret) in any form; a human enters them in\nthe setup UI. If the manifest had no `integrations` key, say the checklist was unavailable this run.\n\n## Stage 8 — Offer the next steps\n\n1. Offer to continue with `/learn-repository` to populate the deeper instruction-tier configuration\n (architecture, review, testing, and correctness standards), matching the manifest's `next_step`.\n2. After `/learn-repository` completes (or if the human declines it), offer to start **repository\n indexing**: ask ONE consent question (\"Start repository indexing now? It runs as a background job\n and makes the codebase searchable for Bridge API's agents.\"). On yes, call the `parse_repository`\n MCP tool once. Report that the job was QUEUED and that progress can be checked with\n `get_parse_status` (or `/check-parse-status`) — do NOT poll it to completion in this session.\n Indexing is deliberately last so the applied `exclude_directories` / `custom_directories` values\n scope it correctly. If no human response can be obtained (non-interactive session), skip indexing\n and list it as a pending next step in the final report — never start it without consent.\n\n## Stage 9 — Offer CI follow-up configuration (only when CI is detected)\n\nThis stage is separate from the single apply call: it writes at most ONE field via the\n`config_field` MCP tool. `ci_followup_config` is REPLACE-NOT-AUGMENT — leaving it NULL already means\nsafe poll-only defaults, so \"skip\" is always a correct answer.\n\n1. Gate: only offer this when Stage 3 found real CI evidence (e.g. `.github/workflows/*.yml`,\n `bitbucket-pipelines.yml`). With no CI detected, skip this stage and note \"no CI detected — CI\n follow-up not offered\" in the final report.\n2. Ask ONE question, referencing the discovered CI by name, with exactly these preset profiles\n (default: skip):\n - **observe** — poll CI results only, never attempt fixes:\n `{\"strategy\": \"poll_only\", \"max_iterations\": 1, \"max_minutes\": 10, \"instructions\": \"\"}`\n - **self-heal** — bounded fix-and-iterate loop on the automation's own PRs:\n `{\"strategy\": \"fix_and_iterate\", \"max_iterations\": 3, \"max_minutes\": 45, \"instructions\": \"\"}`\n - **skip** (default) — leave `ci_followup_config` unset (NULL = baseline poll-only behavior).\n3. Do NOT offer or compose a `custom` strategy during install — free-form CI follow-up instructions\n are a deliberate later act (setup UI or a direct `config_field` update).\n4. When the human picks a profile, call the `config_field` MCP tool once (operation `\"update\"`,\n `field_name: \"ci_followup_config\"`, `value`: the profile's JSON object). If the server rejects the\n value, retry ONCE with a corrected payload; if it is rejected again, stop, show the proposed JSON\n to the human, and leave the field unset.\n5. Never select a profile in a non-interactive session — skip and list it as a pending next step. An\n unattended install must never enable fix-and-iterate behavior.\n\n## Return\n\nReport the admin check result, the \"Applied N of M\" count, the\napplied/skipped/conflict/needs_confirmation/rejected field names, any fields omitted for\nnested-repository or ambiguity reasons, the approval outcome for each confirmation-requiring field\n(approved / declined / pending human input), whether a stale-command warning was raised (manifest\n`command_contract_version` higher than this command's), whether the routing credential was persisted\n(the returned `target` and `path`, or the non-blocking failure remediation), the CI follow-up outcome\n(profile written / skipped / no CI detected / pending), and the recommended next\nstep (`/learn-repository`).\n",
|
|
17
18
|
"learn-repository.md": "Learn and document all configuration fields for the repository by running parallel research agents.\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. This command takes no arguments.\n\n2. Call the `get_pipeline_recipe` MCP tool with:\n - `pipeline`: `\"learn-repository\"`\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 **Steps executed**: N of M\n **Status**: Success / Failed at step N\n ```\n",
|
|
@@ -20,8 +21,8 @@ export const COMMANDS = {
|
|
|
20
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",
|
|
21
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",
|
|
22
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",
|
|
23
|
-
"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, `rounds`
|
|
24
|
-
"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>`. 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
|
|
24
|
+
"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
|
+
"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>`. 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`, `--rounds=2`, or omitted rounds → `rounds=2` (full second-opinion review).\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 single-ticket `/review-ticket` invoked without any `--rounds` instead 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); note that this batch command forwards `--rounds=2` by default when no rounds mode is given for a ticket.\n\n - **Homogeneous modes**: when all tickets share the same auto and rounds values, translate into global `--auto` (if all auto) and `--rounds=1|2` (if all rounds are the same).\n\n - **Heterogeneous modes**: when different tickets have different auto or rounds values, translate into repeatable `--review KEY=auto,rounds=N` overrides. Do NOT set global `--auto` when only some tickets are auto-approved.\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> agent=<agent> model=<alias|default> status=<status>`) and render as a markdown table:\n\n```\n| Ticket | Auto | Rounds | Agent | Model | Status |\n|----------|-------|--------|--------|---------|---------|\n| BAPI-1 | false | 2 | 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",
|
|
25
26
|
"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",
|
|
26
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",
|
|
27
28
|
"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",
|