@bridge_gpt/mcp-server 0.1.7 → 0.1.9

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/build/index.js CHANGED
@@ -16,7 +16,10 @@ import { writeFile, mkdir, readFile, stat } from "fs/promises";
16
16
  import path from "path";
17
17
  import { PIPELINES as BUNDLED_PIPELINES, INSTRUCTIONS as BUNDLED_INSTRUCTIONS } from "./pipelines.generated.js";
18
18
  import { COMMANDS } from "./commands.generated.js";
19
+ import { AGENTS } from "./agents.generated.js";
20
+ import { reconstructAgentMarkdown, translateAgentToCopilot } from "./agent-utils.js";
19
21
  import { resolveRecipe, loadCustomPipelines } from "./pipeline-utils.js";
22
+ import { generateDecisionPageHtml } from "./decision-page-template.js";
20
23
  // Mutable pipeline/instruction state — starts with bundled, merged with user at startup
21
24
  const PIPELINES = { ...BUNDLED_PIPELINES };
22
25
  const INSTRUCTIONS = { ...BUNDLED_INSTRUCTIONS };
@@ -393,7 +396,63 @@ if (process.argv.includes("--init")) {
393
396
  if (skippedFiles.size > 0)
394
397
  console.log(` Skipped (unchanged): ${skippedFiles.size}`);
395
398
  console.log(` ${dirNames}`);
396
- // ---- Phase 5: Scaffold custom pipeline directories ----
399
+ // ---- Phase 5: Scaffold agent directories ----
400
+ const agentWritten = new Set();
401
+ const agentSkipped = new Set();
402
+ const agentOverwritten = new Set();
403
+ // Always scaffold to .claude/agents/
404
+ const claudeAgentsDir = path.join(cwd, ".claude", "agents");
405
+ await mkdir(claudeAgentsDir, { recursive: true });
406
+ for (const [key, agent] of Object.entries(AGENTS)) {
407
+ const filename = `${key}.md`;
408
+ const content = reconstructAgentMarkdown(agent.frontmatter, agent.body);
409
+ const target = path.join(claudeAgentsDir, filename);
410
+ try {
411
+ const existing = await readFile(target, "utf-8");
412
+ if (existing === content) {
413
+ agentSkipped.add(filename);
414
+ continue;
415
+ }
416
+ agentOverwritten.add(filename);
417
+ }
418
+ catch { /* file doesn't exist */ }
419
+ await writeFile(target, content, "utf-8");
420
+ agentWritten.add(filename);
421
+ }
422
+ // Scaffold to .github/agents/ for VS Code / Copilot
423
+ if (ideDetection.vscode) {
424
+ const copilotAgentsDir = path.join(cwd, ".github", "agents");
425
+ await mkdir(copilotAgentsDir, { recursive: true });
426
+ for (const [key, agent] of Object.entries(AGENTS)) {
427
+ const filename = `${key}.agent.md`;
428
+ const content = translateAgentToCopilot(agent.frontmatter, agent.body);
429
+ const target = path.join(copilotAgentsDir, filename);
430
+ try {
431
+ const existing = await readFile(target, "utf-8");
432
+ if (existing === content) {
433
+ agentSkipped.add(filename);
434
+ continue;
435
+ }
436
+ agentOverwritten.add(filename);
437
+ }
438
+ catch { /* file doesn't exist */ }
439
+ await writeFile(target, content, "utf-8");
440
+ agentWritten.add(filename);
441
+ }
442
+ }
443
+ // TODO: Add Cursor agent scaffolding when Cursor publishes a formal agent spec
444
+ // A file written in any directory takes priority over skipped
445
+ for (const f of agentWritten)
446
+ agentSkipped.delete(f);
447
+ const agentTotal = Object.keys(AGENTS).length;
448
+ console.log(`\nAgents: scaffolded ${agentTotal} agent${agentTotal === 1 ? "" : "s"}`);
449
+ if (agentWritten.size > 0)
450
+ console.log(` Written: ${agentWritten.size}`);
451
+ if (agentOverwritten.size > 0)
452
+ console.log(` Overwritten (content changed): ${agentOverwritten.size}`);
453
+ if (agentSkipped.size > 0)
454
+ console.log(` Skipped (unchanged): ${agentSkipped.size}`);
455
+ // ---- Phase 6: Scaffold custom pipeline directories ----
397
456
  const pipelinesDir = path.resolve(cwd, process.env.BAPI_PIPELINES_DIR ?? ".bridge/pipelines");
398
457
  const instrDir = path.join(path.dirname(pipelinesDir), "instructions");
399
458
  await mkdir(pipelinesDir, { recursive: true });
@@ -516,7 +575,7 @@ automatically provided by the server.
516
575
  console.log(` ${path.relative(cwd, examplePath)} (written)`);
517
576
  }
518
577
  console.log(` ${path.relative(cwd, instrDir)}/ (ensured)`);
519
- // ---- Phase 6: Final summary ----
578
+ // ---- Phase 7: Final summary ----
520
579
  if (anyCreatedOrAdded) {
521
580
  console.log("\nUpdate BAPI_API_KEY and BAPI_REPO_NAME in your config files — " +
522
581
  "get these values from the Bridge API setup UI at https://bridgegpt-api.com");
@@ -1955,6 +2014,117 @@ server.registerTool("get_pipeline_recipe", {
1955
2014
  }
1956
2015
  });
1957
2016
  // ---------------------------------------------------------------------------
2017
+ // generate_decision_page
2018
+ // ---------------------------------------------------------------------------
2019
+ server.registerTool("generate_decision_page", {
2020
+ description: "Generate a local HTML decision page for capturing user decisions on ticket review findings. " +
2021
+ "Renders recommendation-driven review decisions with custom options from resolution guide " +
2022
+ "decision trees, plus confirmed improvements. The user opens the HTML file " +
2023
+ "in a browser, makes selections, and copies the resulting JSON output back to the agent.",
2024
+ inputSchema: {
2025
+ ticket_key: z.string().describe("Jira ticket key, e.g. BAPI-123"),
2026
+ actionable_items: z
2027
+ .array(z.object({
2028
+ id: z.string().min(1),
2029
+ question: z.string().min(1),
2030
+ context: z.string().min(1),
2031
+ source: z.string().min(1).describe("Source reference from the evaluation, e.g. 'Clarifying Q3 (initial round)'"),
2032
+ recommendation_index: z.number().int().min(0).describe("0-based index of the recommended option in the options array"),
2033
+ options: z.array(z.string().min(1)).min(1).describe("Option labels from resolution guide decision tree branches. Values are auto-generated."),
2034
+ }))
2035
+ .optional()
2036
+ .default([])
2037
+ .describe("Actionable review decisions with option labels from resolution guide decision trees. 'None of these' auto-appended."),
2038
+ clear_improvements: z
2039
+ .array(z.object({
2040
+ id: z.string().min(1),
2041
+ title: z.string().min(1),
2042
+ action: z.string().min(1),
2043
+ confidence: z.string().min(1),
2044
+ source: z.string().min(1).describe("Source reference from the evaluation"),
2045
+ }))
2046
+ .optional()
2047
+ .default([])
2048
+ .describe("Confirmed improvements displayed as informational list, not submitted."),
2049
+ },
2050
+ }, async (input) => {
2051
+ const validationError = (message) => ({
2052
+ content: [{
2053
+ type: "text",
2054
+ text: JSON.stringify({ error: "VALIDATION_ERROR", status: 400, message }),
2055
+ }],
2056
+ });
2057
+ // Validate ticket_key format (reject instead of silently sanitizing)
2058
+ if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(input.ticket_key)) {
2059
+ return validationError(`Invalid ticket_key "${input.ticket_key}": must start with a letter and contain only letters, digits, hyphens, or underscores.`);
2060
+ }
2061
+ // No-decisions fast path: return structured response without writing a file
2062
+ if (input.actionable_items.length === 0) {
2063
+ return {
2064
+ content: [{
2065
+ type: "text",
2066
+ text: JSON.stringify({
2067
+ status: "no_decisions_needed",
2068
+ ticket_key: input.ticket_key,
2069
+ clear_improvements_count: input.clear_improvements.length,
2070
+ }),
2071
+ }],
2072
+ };
2073
+ }
2074
+ // Validate actionable_items
2075
+ const seenIds = new Set();
2076
+ for (const item of input.actionable_items) {
2077
+ if (seenIds.has(item.id)) {
2078
+ return validationError(`Duplicate actionable_items id: "${item.id}"`);
2079
+ }
2080
+ seenIds.add(item.id);
2081
+ if (item.recommendation_index >= item.options.length) {
2082
+ return validationError(`Item "${item.id}": recommendation_index ${item.recommendation_index} is out of bounds (${item.options.length} options).`);
2083
+ }
2084
+ const noneLabel = item.options.find((label) => label.toLowerCase() === "none of these");
2085
+ if (noneLabel) {
2086
+ return validationError(`Item "${item.id}": option label "${noneLabel}" is reserved and auto-appended by the tool.`);
2087
+ }
2088
+ }
2089
+ // Read design assets and base64-encode for embedding
2090
+ const assetsDir = path.join(PROJECT_ROOT, "design-assets");
2091
+ const fontsDir = path.join(PROJECT_ROOT, "public", "fonts");
2092
+ let faviconBase64 = "";
2093
+ let logoBase64 = "";
2094
+ try {
2095
+ const faviconBuf = await readFile(path.join(assetsDir, "favicon", "favicon-32x32.png"));
2096
+ faviconBase64 = faviconBuf.toString("base64");
2097
+ }
2098
+ catch { /* favicon optional */ }
2099
+ try {
2100
+ const logoBuf = await readFile(path.join(assetsDir, "just-logo-rough-draft.png"));
2101
+ logoBase64 = logoBuf.toString("base64");
2102
+ }
2103
+ catch { /* logo optional */ }
2104
+ // Compute relative path from output dir to fonts dir
2105
+ const docsPath = getDocsPath("review");
2106
+ const fontsRelPath = path.relative(docsPath, fontsDir);
2107
+ const html = generateDecisionPageHtml(input, {
2108
+ faviconBase64,
2109
+ logoBase64,
2110
+ fontsRelPath,
2111
+ });
2112
+ const filePath = path.join(docsPath, `${input.ticket_key}-decisions.html`);
2113
+ await mkdir(docsPath, { recursive: true });
2114
+ await writeFile(filePath, html, "utf-8");
2115
+ return {
2116
+ content: [{
2117
+ type: "text",
2118
+ text: JSON.stringify({
2119
+ status: "decision_page_generated",
2120
+ file_path: filePath,
2121
+ actionable_items_count: input.actionable_items.length,
2122
+ clear_improvements_count: input.clear_improvements.length,
2123
+ }),
2124
+ }],
2125
+ };
2126
+ });
2127
+ // ---------------------------------------------------------------------------
1958
2128
  // Entry point
1959
2129
  // ---------------------------------------------------------------------------
1960
2130
  // Load custom user pipelines before accepting connections
@@ -85,6 +85,16 @@ export const PIPELINES = {
85
85
  "description": "Create a pull request",
86
86
  "requires_approval": true
87
87
  },
88
+ {
89
+ "type": "mcp_call",
90
+ "tool": "update_jira_status",
91
+ "params": {
92
+ "ticket_number": "{ticket_key}",
93
+ "target_status": "In Review"
94
+ },
95
+ "description": "Transition ticket to In Review",
96
+ "on_error": "warn_and_continue"
97
+ },
88
98
  {
89
99
  "type": "agent_task",
90
100
  "instruction_file": "monitor-ci-checks.md",
@@ -328,6 +338,54 @@ export const PIPELINES = {
328
338
  }
329
339
  ]
330
340
  },
341
+ "plan-epic": {
342
+ "name": "plan-epic",
343
+ "description": "Decompose a feature epic into sub-tasks with structured exploration documents for each.",
344
+ "variables": [
345
+ "epic_description",
346
+ "epic_slug",
347
+ "docs_dir"
348
+ ],
349
+ "steps": [
350
+ {
351
+ "type": "mcp_call",
352
+ "tool": "ping",
353
+ "params": {},
354
+ "description": "Verify Bridge API connectivity"
355
+ },
356
+ {
357
+ "type": "agent_task",
358
+ "instruction_file": "assess-epic-research-needs.md",
359
+ "description": "Assess research needs for the epic"
360
+ },
361
+ {
362
+ "type": "agent_task",
363
+ "instruction_file": "execute-epic-research.md",
364
+ "description": "Execute research plan",
365
+ "on_error": "warn_and_continue"
366
+ },
367
+ {
368
+ "type": "agent_task",
369
+ "instruction_file": "explore-epic-codebase.md",
370
+ "description": "Perform holistic codebase exploration for the epic"
371
+ },
372
+ {
373
+ "type": "agent_task",
374
+ "instruction_file": "decompose-epic.md",
375
+ "description": "Decompose epic into sub-tasks and get user approval"
376
+ },
377
+ {
378
+ "type": "agent_task",
379
+ "instruction_file": "explore-epic-subtasks.md",
380
+ "description": "Perform focused exploration for each sub-task"
381
+ },
382
+ {
383
+ "type": "agent_task",
384
+ "instruction_file": "write-epic-summary.md",
385
+ "description": "Write epic overview and summary document"
386
+ }
387
+ ]
388
+ },
331
389
  "pr-ticket": {
332
390
  "name": "pr-ticket",
333
391
  "description": "Commit changes and create a pull request.",
@@ -362,7 +420,7 @@ export const PIPELINES = {
362
420
  },
363
421
  "review-ticket": {
364
422
  "name": "review-ticket",
365
- "description": "Review a ticket with two rounds of analysis (initial + second opinion) and evaluate suggestions for accuracy and value.",
423
+ "description": "Review a ticket with two rounds of analysis (initial + second opinion), evaluate suggestions for accuracy, and produce a resolution guide with decision trees.",
366
424
  "variables": [
367
425
  "ticket_key",
368
426
  "docs_dir"
@@ -428,14 +486,30 @@ export const PIPELINES = {
428
486
  "type": "agent_task",
429
487
  "instruction_file": "evaluate-ticket-review.md",
430
488
  "description": "Evaluate review suggestions against the codebase for groundedness and value"
489
+ },
490
+ {
491
+ "type": "agent_task",
492
+ "instruction_file": "recommend-ticket-resolutions.md",
493
+ "description": "Produce a resolution guide with decision trees and confidence-tagged recommendations"
494
+ },
495
+ {
496
+ "type": "agent_task",
497
+ "instruction_file": "capture-review-decisions.md",
498
+ "description": "Generate HTML decision page, capture user decisions, and interpretively rewrite clarifying questions and critique docs"
431
499
  }
432
500
  ]
433
501
  }
434
502
  };
435
503
  export const INSTRUCTIONS = {
504
+ "assess-epic-research-needs.md": "Analyze the epic description and build a structured research plan.\n\n## Epic Description\n\n{epic_description}\n\n## Instructions\n\n1. Create the directory structure for this epic's artifacts:\n ```\n mkdir -p {docs_dir}/epic-plans/{epic_slug}\n ```\n\n2. Analyze the epic description above. Determine what external knowledge is required to plan this epic effectively. Consider:\n - Unfamiliar technologies, libraries, or frameworks mentioned\n - API documentation or integration specs that need to be consulted\n - Best practices or architectural patterns that require research\n - Domain-specific knowledge gaps\n\n3. Decide on a **Research Mode**:\n - **deep**: Use when the epic involves large, multi-faceted unknowns requiring synthesis from multiple sources (e.g., \"best practices for implementing WebSocket connection pooling in Python asyncio\").\n - **web**: Use for quick factual lookups — library API signatures, configuration syntax, small \"how to\" questions.\n - **none**: Use when the codebase exploration alone will provide sufficient context and no external knowledge is needed.\n\n4. Write a structured research plan to `{docs_dir}/epic-plans/{epic_slug}/research-plan.md` with these sections:\n\n```markdown\n# Research Plan\n\n## Research Mode\n{deep | web | none}\n\n## Deep Research Query\n{If mode is \"deep\": a single, well-crafted query for the deep research tool. Otherwise: \"N/A\"}\n\n## Web Search Topics\n{If mode is \"web\" or as fallback topics for \"deep\": a numbered list of specific search topics. Otherwise: \"N/A\"}\n\n## Rationale\n{Brief explanation of why this research mode was chosen and what knowledge gaps it addresses.}\n```\n",
505
+ "capture-review-decisions.md": "Capture user decisions on review findings for {ticket_key} using the HTML decision page, then interpretively rewrite the clarifying questions and critique docs and upload both to Jira.\n\n## Step 1: Read source documents\n\nRead both files:\n- Evaluation: `{docs_dir}/review/{ticket_key}-review-evaluation.md`\n- Resolution guide: `{docs_dir}/review/{ticket_key}-resolution-guide.md`\n\nIf either file does not exist or is empty, stop and report: \"Review evaluation or resolution guide not found. Run the earlier pipeline steps first.\"\n\n## Step 2: Map evaluation items to decision page input\n\nTransform the evaluation into `generate_decision_page` JSON input using these mapping rules:\n\n| Evaluation Section | JSON Field | Mapping Rule |\n|---|---|---|\n| Open Questions | `actionable_items` | E-item title → `question`, assessment + codebase evidence → `context`, `**Source**` from the evaluation → `source`, decision tree branch texts from the resolution guide → `options` (string array, labels only), `**Recommendation Index**` from the resolution guide → `recommendation_index` |\n| Needs Scrutiny | `actionable_items` | E-item title → `question`, assessment + evidence → `context`, `**Source**` from the evaluation → `source`, decision tree branch texts from the resolution guide → `options` (string array, labels only), `**Recommendation Index**` from the resolution guide → `recommendation_index` |\n| Confirmed Improvements | `clear_improvements` | E-item title → `title`, confidence tag → `confidence`, recommended action → `action`, `**Source**` from the evaluation → `source` |\n\nFor each actionable item, the `options` array is a list of plain label strings extracted from the resolution guide's decision tree branches. The tool auto-generates value keys (`opt-0`, `opt-1`, etc.) and auto-appends a \"None of these\" option. Do not generate value keys yourself.\n\n## Step 3: Call the MCP tool\n\nCall `generate_decision_page` with:\n- `ticket_key`: `{ticket_key}`\n- `actionable_items`: combined mapped array from Step 2 (each item has `id`, `question`, `context`, `source`, `recommendation_index`, `options`)\n- `clear_improvements`: mapped array from Step 2 (each item has `id`, `title`, `action`, `confidence`, `source`)\n\n## Step 4: Check tool response\n\nThe tool returns a JSON response with a `status` field:\n- If `status` is `\"no_decisions_needed\"`: skip Steps 5, 6, 7, and 8 entirely. Output a success message: \"All suggestions were confirmed as improvements. No decisions needed — skipping doc rewrite and upload.\"\n- If `status` is `\"decision_page_generated\"`: continue to Step 5. The response includes `file_path`.\n\n## Step 5: Direct user to the decision page\n\nTell the user to open the generated HTML file in their browser. Provide the `file_path` from the tool response.\n\n## Step 6: Wait for user input\n\nStop and wait for the user to paste the JSON output from the decision page. Do NOT assume responses. Do NOT proceed until the user provides the JSON.\n\n## Step 7: Interpretively rewrite source documents\n\nThe pasted JSON contains a `decisions` object keyed by item ID. Each decision includes `source`, `choice`, `chosen_label`, and `comment`. Use these fields to locate and rewrite the corresponding sections in:\n- `{docs_dir}/clarifying-questions/{ticket_key}-clarifying-questions.md`\n- `{docs_dir}/ticket-critiques/{ticket_key}-ticket-quality-critique.md`\n\nFor each decision, use the `source` field (e.g., \"Clarifying Q3 (initial round)\") to find the original section in the appropriate document. Then apply the decision:\n\n### Actionable item decisions\n\n- **Selected option** (`choice` is `opt-N`): Add `**Review Decision**: Accepted. <chosen_label>.` to the corresponding section. Integrate the selected direction into the section text so it reads as a final recommendation or resolved answer.\n- **None of these** (`choice` is `none`): Add `**Review Decision**: Rejected — none of the proposed options accepted.` Include the user's `comment` explaining why. Rewrite the section to reflect this decision.\n\nFor actionable items sourced from clarifying questions, rewrite the question's best-guess answer so it reads as the final resolved direction chosen by the reviewer. Do not leave the item framed as an unresolved accept/reject/modify prompt.\n\n### General comment handling\n\nTreat `general_comment` as overarching guidance that informs the tone and direction of both document rewrites. If it contains specific actionable feedback, weave it into the relevant sections. If it is broad or general, use it as context for how the rewrites should read. Do not create a separate \"General Comment\" or \"Reviewer Notes\" section — the goal is \"final draft\" form.\n\n### Rewrite principles\n\nThe goal is a **final draft** — the documents should read as if they were written with the decisions already made. Do not mechanically append decisions. Instead, lightly rewrite affected sections so they reflect the decisions naturally. Preserve all non-affected sections unchanged.\n\n## Step 8: Upload to Jira\n\nUpload both updated documents to Jira using `upload_attachment`:\n\n1. Upload clarifying questions:\n - `ticket_number`: `{ticket_key}`\n - `file_path`: `{docs_dir}/clarifying-questions/{ticket_key}-clarifying-questions.md`\n - `link_type`: `clarifying-questions.md`\n\n2. Upload ticket quality critique:\n - `ticket_number`: `{ticket_key}`\n - `file_path`: `{docs_dir}/ticket-critiques/{ticket_key}-ticket-quality-critique.md`\n - `link_type`: `ticket-quality-critique.md`\n\n## Step 9: Complete\n\nConfirm: \"Review decisions captured and uploaded to {ticket_key}.\"\n\nThis is a single-round process. Do not iterate or ask for additional feedback rounds.\n",
436
506
  "commit-and-push.md": "Stage all changed files and create a commit for ticket {ticket_key}.\n\n1. Run `git add` on all files modified or created during implementation. Do not stage unrelated files.\n2. Create a commit with the message: `{ticket_key}: Implementation`\n3. Push the current branch to the remote.\n",
437
- "evaluate-ticket-review.md": "Evaluate the clarifying questions and ticket critiques generated for {ticket_key}, assessing their accuracy and value against the actual codebase.\n\n1. Fetch the current ticket description using the `get_ticket` tool with ticket_number `{ticket_key}`.\n2. Gather all clarifying questions and critiques from the preceding pipeline steps. Both initial and second-opinion rounds may be present — use the MCP call results from the conversation context, since the files on disk at `{docs_dir}/clarifying-questions/{ticket_key}-clarifying-questions.md` and `{docs_dir}/ticket-critiques/{ticket_key}-ticket-quality-critique.md` only reflect the most recent round.\n3. For each clarifying question and its best-guess answer, verify groundedness against the codebase using file search and code grep:\n - If the question/answer accurately reflects the codebase, confirm it as grounded with evidence.\n - If the question/answer misunderstands the codebase (wrong assumptions about architecture, incorrect file references, etc.), call it out with evidence of what the code actually does.\n - If the question raises a genuine gap that cannot be resolved from the codebase alone, note it as a legitimate open question.\n4. For each critique point (Requested Changes and Points to Consider), assess:\n - Does it identify a genuine gap or design issue in the ticket? Confirm with codebase evidence.\n - Is it based on an inaccurate understanding of the existing code? Flag with corrections.\n - Is it a stylistic preference rather than a substantive improvement? Note as low-priority.\n5. Produce a structured evaluation with three sections:\n - **Confirmed Improvements**: Suggestions that are grounded and would genuinely improve the ticket by closing significant gaps or correcting design issues.\n - **Needs Scrutiny**: Suggestions based on inaccurate codebase assumptions, with evidence of the actual code behavior.\n - **Open Questions**: Legitimate ambiguities that require human input to resolve.\n6. Save the evaluation to `{docs_dir}/explorations/{ticket_key}-review-evaluation.md`. Output only the structured evaluation no meta-commentary.\n",
507
+ "decompose-epic.md": "Decompose the epic into manageable sub-tasks and get user approval.\n\n## Epic Description\n\n{epic_description}\n\n## Instructions\n\n1. Read the following artifacts to establish full context. If a file does not exist or is empty, proceed without it:\n - `{docs_dir}/epic-plans/{epic_slug}/research-findings.md`\n - `{docs_dir}/epic-plans/{epic_slug}/codebase-exploration.md`\n\n2. Reason about the epic and produce a decomposition. Consider:\n - Logical groupings of work that can be implemented and tested independently\n - Dependencies between sub-tasks (what must be built first)\n - A reasonable scope for each sub-task (each should be achievable in a single implementation session)\n\n3. Write the decomposition to `{docs_dir}/epic-plans/{epic_slug}/decomposition.md` with this format:\n\n```markdown\n# Epic Decomposition\n\n## Sub-tasks\n\n### 1. {Sub-task title}\n- **Scope**: {What this sub-task covers}\n- **Key files/areas**: {Files and code areas involved}\n- **Dependencies**: {Other sub-task numbers this depends on, or \"None\"}\n\n### 2. {Sub-task title}\n...\n```\n\n4. **Soft limit check**: If the decomposition results in more than 8 sub-tasks, you must verbally warn the user: \"This decomposition has N sub-tasks, which exceeds the recommended limit of 8. Consider splitting this feature into multiple epics.\" Then proceed with the approval flow.\n\n5. Present the decomposition to the user and ask for their feedback. Explain the reasoning behind the breakdown and the dependency ordering.\n\n6. You MUST stop and wait for the user to respond. Do NOT assume approval. Do NOT proceed to the next step.\n\n7. If the user provides feedback or rejects the decomposition:\n - Incorporate their feedback\n - Rewrite `{docs_dir}/epic-plans/{epic_slug}/decomposition.md` with the revised version\n - Present the revised decomposition and ask for approval again\n - Repeat until the user explicitly approves\n\n8. Only after explicit user approval, confirm: \"Decomposition approved. Proceeding to sub-task exploration.\"\n",
508
+ "evaluate-ticket-review.md": "Evaluate the clarifying questions and ticket critiques generated for {ticket_key}, assessing their accuracy and value against the actual codebase.\n\n1. Fetch the current ticket description using the `get_ticket` tool with ticket_number `{ticket_key}`.\n2. Gather all clarifying questions and critiques from the preceding pipeline steps. Both initial and second-opinion rounds may be present — use the MCP call results from the conversation context, since the files on disk at `{docs_dir}/clarifying-questions/{ticket_key}-clarifying-questions.md` and `{docs_dir}/ticket-critiques/{ticket_key}-ticket-quality-critique.md` only reflect the most recent round.\n3. For each clarifying question and its best-guess answer, verify groundedness against the codebase using file search and code grep. Apply the following depth rules based on round agreement:\n - **Both rounds agree** (same question raised, similar answer): Briefly confirm or refute with a single codebase citation. Keep the assessment to 1 sentence.\n - **Rounds disagree** (one round flags it and the other doesn't, or they reach opposite conclusions): Perform deeper analysis — cite 2+ codebase locations, explain the discrepancy, and state which round's position the evidence supports.\n - **Single round only** (no second opinion for this item): Treat as a disagreement — give full analytical depth.\n Then categorize:\n - If the question/answer accurately reflects the codebase, confirm it as grounded with evidence.\n - If the question/answer misunderstands the codebase (wrong assumptions about architecture, incorrect file references, etc.), call it out with evidence of what the code actually does.\n - If the question raises a genuine gap that cannot be resolved from the codebase alone, note it as a legitimate open question.\n4. For each critique point (Requested Changes and Points to Consider), apply the same depth rules from step 3 based on round agreement, then assess:\n - Does it identify a genuine gap or design issue in the ticket? Confirm with codebase evidence.\n - Is it based on an inaccurate understanding of the existing code? Flag with corrections.\n - Is it a stylistic preference rather than a substantive improvement? Note as low-priority.\n5. Produce a structured evaluation with three sections, following the formatting rules below. Number each item sequentially across all sections (E-1, E-2, E-3, ...).\n\n## Formatting Rules\n\nEach item must follow this template:\n\n```\n### E-<sequential number>: <concise title>\n\n**Source**: <which clarifying question or critique point this originated from, e.g. \"Clarifying Q3 (initial round)\" or \"Critique: Requested Change 2 (second opinion)\">\n\n**Round Agreement**: <\"both rounds agree\" | \"rounds disagree\" | \"single round only\"> — <if disagreeing, 1 sentence on what the disagreement is>\n\n**Assessment**: <1-2 sentence summary of what was found>\n\n**Codebase Evidence**:\n- `path/to/file.ts:42` — <what this line/block demonstrates>\n- `path/to/other.ts:110-125` — <what this range demonstrates>\n\n<If no direct codebase evidence exists, state: \"No direct codebase evidence found.\">\n```\n\n**Depth calibration**: When Round Agreement is \"both rounds agree\", keep Assessment to 1 sentence and Codebase Evidence to 1 citation. When Round Agreement is \"rounds disagree\" or \"single round only\", Assessment should be 2 sentences and Codebase Evidence should cite 2+ files explaining the discrepancy.\n\n## Output Sections\n\n- **Confirmed Improvements**: Suggestions that are grounded and would genuinely improve the ticket by closing significant gaps or correcting design issues.\n- **Needs Scrutiny**: Suggestions based on inaccurate codebase assumptions, with evidence of the actual code behavior.\n- **Open Questions**: Legitimate ambiguities that require human input to resolve.\n\n6. Save the evaluation to `{docs_dir}/review/{ticket_key}-review-evaluation.md`. Output only the structured evaluation — no meta-commentary.\n",
509
+ "execute-epic-research.md": "Execute the research plan and write findings.\n\n## Instructions\n\n1. Read the research plan from `{docs_dir}/epic-plans/{epic_slug}/research-plan.md`.\n\n2. Execute the plan based on the Research Mode:\n\n **If mode is `deep`**:\n - Call the `request_deep_research` MCP tool with:\n - `query`: the Deep Research Query from the plan\n - `context`: \"Bridge API is a Python/FastAPI application with PostgreSQL, LiteLLM, and Pinecone. This research supports epic planning for: {epic_description}\"\n - `wait_for_result`: true\n - `save_locally`: true\n - If deep research fails, log a warning and fall back to web searches using the Web Search Topics from the plan. Do NOT halt.\n\n **If mode is `web`**:\n - Perform web searches for each topic listed in the plan.\n - Capture relevant findings from each search.\n\n **If mode is `none`**:\n - Write a brief note: \"No external research needed. Proceeding with codebase exploration.\"\n\n3. Write all findings to `{docs_dir}/epic-plans/{epic_slug}/research-findings.md` with this structure:\n\n```markdown\n# Research Findings\n\n## Mode\n{deep | web | none}\n\n## Findings\n{Synthesized research results organized by topic. Include source references where applicable.}\n\n## Key Takeaways\n{Bullet points summarizing the most important findings that will inform the codebase exploration and epic decomposition.}\n```\n",
438
510
  "execute-plan.md": "Execute the AI-generated implementation plan for ticket {ticket_key}.\n\n1. Read the plan from `{docs_dir}/plans/{ticket_key}-plan.md`.\n2. Execute each step in the plan sequentially, making code changes as directed.\n3. Run any tests or checks specified in the plan's review steps.\n4. Do NOT run `git commit` or `git push` — leave all changes uncommitted for developer review.\n5. If a step is ambiguous or blocked, note the issue clearly and continue with the next step.\n",
511
+ "explore-epic-codebase.md": "Perform a holistic, epic-level codebase exploration.\n\n## Epic Description\n\n{epic_description}\n\n## Instructions\n\n1. Read the research findings from `{docs_dir}/epic-plans/{epic_slug}/research-findings.md` to establish context. If the file does not exist or is empty, proceed without it.\n\n2. Explore the codebase with a focus on breadth rather than depth. The goal is to build a \"lay of the land\" understanding for the entire epic, not to deeply analyze any single sub-task. Use `Glob`, `Grep`, and `Read` tools to search for:\n - Files, modules, and directories relevant to the epic\n - Architectural patterns used in similar features\n - Integration points and dependencies between modules\n - Existing conventions for the type of work this epic involves\n - Database models, API routes, agent flows, and utilities that may be affected\n\n3. Build a mental model of:\n - What exists today that relates to the epic\n - What patterns and conventions are used in similar features\n - What dependencies, data flows, and integration points are involved\n - What areas of the codebase will likely need changes\n\n4. Write the exploration findings to `{docs_dir}/epic-plans/{epic_slug}/codebase-exploration.md` with this structure:\n\n```markdown\n# Codebase Exploration\n\n## Architecture Overview\n{High-level description of how the relevant parts of the codebase are structured.}\n\n## Relevant Code Areas\n{List of key files, modules, and directories with brief descriptions of their relevance to the epic.}\n\n## Existing Patterns\n{Patterns and conventions discovered that should be followed when implementing the epic.}\n\n## Integration Points\n{Dependencies, data flows, and integration points that the epic will need to account for.}\n\n## Potential Challenges\n{Any architectural constraints, technical debt, or complexity that could affect implementation.}\n```\n",
512
+ "explore-epic-subtasks.md": "Perform focused code explorations for each approved sub-task.\n\n## Instructions\n\n1. Read the approved decomposition from `{docs_dir}/epic-plans/{epic_slug}/decomposition.md`.\n\n2. Create the explorations directory:\n ```\n mkdir -p {docs_dir}/epic-plans/{epic_slug}/explorations/\n ```\n\n3. For each sub-task in the decomposition, perform a focused exploration:\n - Search for specific files and patterns relevant to the sub-task\n - Identify implementation options and tradeoffs\n - Reference the holistic codebase exploration (`{docs_dir}/epic-plans/{epic_slug}/codebase-exploration.md`) and research findings (`{docs_dir}/epic-plans/{epic_slug}/research-findings.md`) for context\n - Default to lightweight exploration — only go deeper when the holistic exploration left significant gaps for a specific sub-task\n\n4. Write an exploration document for each sub-task to `{docs_dir}/epic-plans/{epic_slug}/explorations/NN-{subtask-slug}.md` (using zero-padded numbering, e.g., `01-add-pipeline-json.md`, `02-create-instruction-files.md`).\n\n5. Each exploration document MUST include these exactly named sections:\n\n```markdown\n# {Sub-task title}\n\n## Context\n{Brief description of the sub-task scope and its role within the epic.}\n\n## Relevant Code\n{Specific files, functions, and patterns relevant to this sub-task. Reference with file_path:line_number format.}\n\n## Implementation Options\n{Viable approaches for implementing the sub-task. For each option: description, pros, cons.}\n\n## Recommendation\n{Which option to pursue and why. Include any caveats or risks.}\n```\n\n6. **Word count guidance**: Target 300-500 words per document. Keep the exploration lightweight. Only exceed this limit if the holistic codebase exploration left significant gaps for a specific sub-task.\n",
439
513
  "learn-architecture.md": "## Objective\n\nExplore the codebase to identify architectural principles, directory conventions, design patterns, and data flow, then draft `architecture_instructions` for the project config.\n\n## Instructions\n\n### Phase 1 — Principles Research\n\nResearch the codebase to identify architectural principles and conventions. For each area below, examine at least 5 representative files. Cite file paths for every pattern. Include code examples (5-15 lines) showing correct usage. Where relevant, include a WRONG example showing the common mistake.\n\nFor each pattern, classify its evidence level:\n- `ENFORCED` — consistently followed across the codebase, violations would be bugs\n- `CONVENTION` — commonly observed, occasional deviations exist\n- `ASPIRATIONAL` — intended direction, not yet consistently applied\n\nResearch areas:\n1. **Architectural coding patterns**: Search `api/routes/` and `api/library/` for separation of concerns, layer boundaries, function-vs-class decisions. Read files matching `*_lib.py`, `*_utils.py`, `*_helpers.py` to document module naming suffix conventions.\n2. **Design patterns**: Search for factory functions, strategy patterns, middleware chains, registry patterns, and dependency injection in `api/` and `src/python/`. Cite concrete usage with file path and function name.\n3. **Dependency management**: Read `requirements.in`, `requirements-dev.in`, and `package.json` files to document how dependencies are declared and organized.\n4. **Error handling architecture**: Search for `log_exception_to_sentry` and `HTTPException` usage patterns across `api/routes/` to document the system-wide error propagation strategy.\n5. **Configuration management**: Search for `os.environ` and `get_config_field` usage to document the two-tier system (env vars vs. database config).\n6. **Tech stack detection**: Read `requirements.in`, `package.json`, and `main.py` to identify primary languages, frameworks, and key libraries.\n7. **Security architecture**: Read `api/routes/setup/auth.py` and search for `require_api_key`, `require_api_session`, and `verify_repo_access` to document authentication and authorization design.\n8. **Agent prompting conventions**: Read files in `src/python/llms/agents/` to document prompt construction, section headers, dynamic content delimiters, and role-based personas.\n\nScope exclusion: Do NOT document testing patterns. Skip the `tests/` directory entirely.\n\nWrite findings to `{docs_dir}/tmp/architecture-principles.md`.\n\n### Phase 2 — Structure & Data Flow Research\n\n1. Call the `regenerate_directory_map` MCP tool to get a fresh directory map.\n2. Read the principles document from Phase 1.\n3. Research and document:\n - **Directory conventions**: For each major directory, document purpose, file naming, internal structure, and an example file.\n - **Module boundaries and import patterns**: Which directories are distinct modules and how they interact. Document import restrictions.\n - **Data flow patterns**: Trace 2-3 complete request paths (synchronous, async background task, agent orchestration).\n - **Integration patterns**: How external services (Jira, GitHub/Bitbucket, LLMs, Pinecone, PostgreSQL) are integrated.\n - **Background task patterns**: The async task lifecycle with `asyncio.create_task`, semaphores, and error reporting.\n\nWrite findings to `{docs_dir}/tmp/architecture-structure.md`.\n\n### Phase 3 — Draft\n\n1. Read both research documents.\n2. Combine into a single `architecture_instructions` draft with these required sections:\n - **1. Core Principles** — Each principle with evidence level and explanation.\n - **2. Layered Architecture** — Layer separation, dependency rule, agent vs orchestration logic.\n - **3. Directory Conventions** — Purpose, naming, structure for each major directory.\n - **4. Data Flow Patterns** — Complete request path traces with file paths.\n - **5. Technical Standards** — Coding style, async patterns, database, schema, LLM integration, config, dependencies.\n - **6. Error Handling & Monitoring** — Error propagation strategy, Sentry integration, Langfuse tracing.\n - **7. Security & Authentication** — Auth architecture, session model, permission model.\n - **8. Agent Prompting Conventions** — Prompt construction, section headers, content delimiters.\n - **9. Integration Points** — External service clients and their calling patterns.\n - **10. AI Code Generation Guidelines** — Anti-patterns, duplication avoidance, pattern compliance checklist.\n\n3. Write the draft to `{docs_dir}/standards/architecture_instructions.md`.\n",
440
514
  "learn-backend-correctness.md": "## Objective\n\nExplore the codebase to identify correctness standards for backend code, then draft the corresponding correctness standards document.\n\n## Target Type\n\n- **Type**: `backend_correctness`\n- **Field name**: `backend_correctness_standards`\n- **Scope**: Server-side code: Python, Ruby, Go, Java, C#, Node.js server code, API routes, business logic.\n\n## Instructions\n\n### Phase 1 — Explore Correctness Patterns\n\nFocus on implementation correctness: how to write code that is correct, idiomatic, and robust within this project's conventions.\n\n1. **File Type Detection**: Use Glob to find files matching `**/*.py` in `api/` and `src/python/`. If very few or no files exist, note this and draft minimal instructions.\n\n2. **Convention Analysis**: Read 3-5 representative files in `api/routes/` and `api/library/` to identify:\n - Structure patterns (imports, exports, class structure, function ordering)\n - Naming conventions (variables, functions, classes, files)\n - Framework conventions and idioms\n - Best practices followed\n - Issues and inconsistencies\n\n Also read files to document:\n - Error handling implementation (try/except ordering, Sentry calls) with CORRECT/WRONG examples\n - Authentication implementation (auth check sequence) with code examples\n - Database call patterns (`postgres_helpers` (bool, result) tuple handling) with CORRECT/WRONG examples\n - Input validation patterns (Pydantic models, naming conventions)\n - HTTP client patterns (error handling, JiraError sanitization)\n - Async implementation patterns (`asyncio.to_thread()` for blocking code)\n\n### Phase 2 — Draft\n\nDraft correctness standards as clear, actionable instructions for an AI code generation agent. Cover:\n- Code structure and organization requirements\n- Naming conventions to follow\n- Framework-specific patterns and idioms\n- Security requirements relevant to this code type\n- Performance considerations\n- Common mistakes to avoid\n- Guards against common AI weaknesses: duplicative code, verbose implementations, security vulnerabilities\n\nAlso include:\n- Route handler boilerplate (auth -> validation -> business logic -> error handling)\n- Database interaction patterns with CORRECT/WRONG examples\n- Exception handling pattern (specific first, HTTPException re-raise, generic with Sentry)\n- Sentry reporting patterns and common mistakes\n- Input sanitization rules (JiraError headers, raw exception messages)\n\nWrite the draft to `{docs_dir}/standards/backend_correctness_standards.md`.\n",
441
515
  "learn-documentation-instructions.md": "## Objective\n\nExplore the codebase to identify implementation documentation patterns — the markdown records that document what was built, why, and when — then draft `documentation_instructions` for the project config.\n\n## Instructions\n\n### Phase 1 — Explore Implementation Record Patterns\n\nFocus on how the project records what was built, why, and when. These records serve as persistent project memory. Code-level documentation (docstrings, inline comments) is handled by correctness standards, not here.\n\n1. **Implementation Record Discovery**: Search for:\n - Ticket-numbered documents matching `BAPI-*.md` or `PROJ-*.md` in `docs/` and subdirectories\n - Feature/migration documents in `docs/`, `documentation/`, or similar directories\n - Architecture Decision Records (ADRs) in `adr/`, `decisions/`, or similar\n - Changelogs (`CHANGELOG.md`, release notes)\n\n Count how many records exist and identify the naming convention.\n\n2. **Record Structure Analysis**: Read 3-5 representative implementation records (mix of early and recent). Document:\n - Sections present (Summary, Architecture, Database Changes, API Reference, etc.)\n - Level of detail provided\n - Types of information captured (motivation, design decisions, schema changes, file paths, API contracts)\n - How code examples and diagrams are used\n\n3. **Documentation Location and Organization**: Read the directory structure of `docs/` to identify where records are stored, the file naming convention, whether there is a table of contents or index, and whether subdirectories serve different purposes.\n\n### Phase 2 — Draft\n\nDraft `documentation_instructions` as clear, actionable instructions for an AI agent writing implementation documentation after completing a feature. Cover:\n- **Purpose**: Documents serve as persistent project memory for future agents and developers.\n- **When to write**: After completing any feature, refactor, migration, or significant bug fix.\n- **File naming convention**: Based on discovered patterns or sensible defaults.\n- **File location**: Where to place implementation records.\n- **Required sections**: Standard structure from analysis or sensible defaults.\n- **Content guidelines**: Level of detail — motivations, design decisions, database changes, file references, API contracts.\n- **Scope boundary**: Implementation records only; code-level docs belong in correctness standards.\n\nWrite the draft to `{docs_dir}/standards/documentation_instructions.md`.\n",
@@ -446,5 +520,7 @@ export const INSTRUCTIONS = {
446
520
  "learn-template-correctness.md": "## Objective\n\nExplore the codebase to identify correctness standards for template files, then draft the corresponding correctness standards document.\n\n## Target Type\n\n- **Type**: `template_correctness`\n- **Field name**: `template_correctness_standards`\n- **Scope**: Template files: HTML, Jinja2, Handlebars, EJS, ERB, Blade, Pug, Twig.\n\n## Instructions\n\n### Phase 1 — Explore Correctness Patterns\n\nFocus on implementation correctness: how to write code that is correct, idiomatic, and robust within this project's conventions.\n\n1. **File Type Detection**: Use Glob to find files matching `**/*.html`, `**/*.jinja2`, `**/*.j2` in `templates/` and similar directories (excluding `node_modules/`). If very few or no files exist, note this and draft minimal instructions.\n\n2. **Convention Analysis**: Read 3-5 representative template files to identify:\n - Structure patterns (imports, exports, class structure, function ordering)\n - Naming conventions (variables, functions, classes, files)\n - Framework conventions and idioms\n - Best practices followed\n - Issues and inconsistencies\n\n### Phase 2 — Draft\n\nDraft correctness standards as clear, actionable instructions for an AI code generation agent. Cover:\n- Code structure and organization requirements\n- Naming conventions to follow\n- Framework-specific patterns and idioms\n- Security requirements relevant to this code type\n- Performance considerations\n- Common mistakes to avoid\n- Guards against common AI weaknesses: duplicative code, verbose implementations, security vulnerabilities\n\nWrite the draft to `{docs_dir}/standards/template_correctness_standards.md`.\n",
447
521
  "learn-unit-testing.md": "## Objective\n\nExplore the codebase to identify the test runner, assertion library, mocking framework, and testing patterns, then draft `unit_testing_instructions` for the project config.\n\n## Instructions\n\n### Phase 1 — Explore Testing Infrastructure\n\n1. **Test Runner and Framework Detection**: Search for test runner configs (`pytest.ini`, `pyproject.toml` `[tool.pytest]` section, `jest.config.*`) and read `package.json` test scripts. Read the `tests/` directory structure.\n\n2. **Testing Patterns**: Read 3-5 representative test files in `tests/pytest/` to identify:\n - Assertion library and style (`assert`, `expect`, custom matchers)\n - Mocking framework (`unittest.mock`, `jest.mock`, `sinon`, etc.)\n - Fixture patterns (setup/teardown)\n - Test organization (by module, feature, layer)\n - Exemplary tests vs. weak tests\n\n3. **How to Run Tests**: Read `pyproject.toml`, `package.json`, and `Makefile` (if present) to determine exact commands for: full suite, single file, by name pattern, with verbose output.\n\n4. **Mocking vs. Fidelity**: Read test helper files in `tests/pytest/helpers/` to document how external APIs are mocked, whether integration tests exist alongside unit tests, and patterns for avoiding third-party calls in tests.\n\n### Phase 2 — Draft\n\nDraft `unit_testing_instructions` as clear, actionable instructions for an AI agent writing unit tests. Cover:\n- How to run tests (exact commands)\n- Which test framework and assertion library to use\n- How to mock external dependencies without calling third parties\n- How to structure test files and test functions\n- What constitutes a thorough test (not just happy path)\n- How to avoid shallow tests that pass but don't verify meaningful behavior\n- Guards against common AI weaknesses: tests that mock the thing being tested, trivially passing assertions, overly complex setup\n\nWrite the draft to `{docs_dir}/standards/unit_testing_instructions.md`.\n",
448
522
  "monitor-ci-checks.md": "Monitor CI checks for the most recent commit.\n\n1. Run `git rev-parse HEAD` to get the current commit SHA.\n2. Call the `resolve_ci_checks` tool with the commit SHA as `commit_ref`. This discovers and classifies the CI checks for the repository.\n3. Poll CI status by calling `poll_ci_checks` with the same `commit_ref`. Check the response for `all_complete` and `all_passed`.\n4. If checks are not yet complete, wait 30 seconds and poll again. Repeat until all checks are complete or 10 minutes have elapsed.\n5. If all checks pass, report success.\n6. If any checks fail, report which checks failed and include any available annotations or log details from the poll response. Do NOT attempt to fix failures — just report them clearly.\n\n## Polling Directive\n\nDuring the polling loop, execute `sleep 30` silently. Do NOT output any inline commentary, reasoning, or partial status updates between polls. Only output a status message when:\n- All checks are complete (pass or fail), OR\n- The 10-minute timeout is reached.\n\nThis minimizes context window consumption during long-running CI waits.\n",
449
- "update-ticket-rewrite.md": "Rewrite the Jira ticket description for {ticket_key} using the generated clarifying questions and critique documents.\n\n1. Fetch the current ticket description using the `get_ticket` tool with ticket_number `{ticket_key}`.\n2. Read the clarifying questions from the local file saved by the previous step (check `{docs_dir}/clarifying-questions/` for `{ticket_key}-clarifying-questions.md`). For each best-guess answer, verify it against the codebase using file search and code grep. Accept verified answers, correct inaccurate ones with evidence, and let ambiguous ones stand.\n3. Read the critique from the local file saved by the previous step (check `{docs_dir}/ticket-critiques/` for `{ticket_key}-ticket-quality-critique.md`). Address all Requested Changes. Apply Points to Consider selectivelyaccept genuine improvements, skip stylistic preferences.\n4. Write the rewritten ticket in standard markdown format (not Jira wiki markup). Preserve the Summary, Requirements, and Acceptance Criteria structure.\n5. Save the output to `{docs_dir}/tickets/{ticket_key}.md`. Output only the clean rewritten ticket — no meta-commentary.\n"
523
+ "recommend-ticket-resolutions.md": "Read the evaluation produced by the previous pipeline step and generate a resolution guide for {ticket_key}.\n\n1. Read the evaluation from `{docs_dir}/review/{ticket_key}-review-evaluation.md`.\n2. Fetch the current ticket description using the `get_ticket` tool with ticket_number `{ticket_key}` for context.\n3. Before processing individual items, produce the following executive summary at the top of the output file:\n\n## TL;DR: Items Needing Your Decision\n\nList every item from the Needs Scrutiny and Open Questions sections of the evaluation, one bullet each:\n\n- **E-<number>: <title>** — <1-sentence summary of what decision is needed>\n\nIf both sections are empty, write: \"No decisions needed — all suggestions were confirmed as improvements.\"\n\n4. Process each item from the evaluation according to its section, following the rules below.\n\n## Needs Scrutiny\n\nFor each item in the Needs Scrutiny section, produce:\n\n```\n### E-<number>: <title from evaluation>\n\n**Confidence**: <High/Medium/Low>\n**Resolution path**: <\"resolve at your desk\" or \"needs a conversation\">\n\n**Decision tree**:\n- If <condition 1>, then <action 1>. See `file:line`. <1-2 sentence rationale.>\n- If <condition 2>, then <action 2>. See `file:line`. <1-2 sentence rationale.>\n- If <condition 3>, then <action 3>. See `file:line`. <1-2 sentence rationale.>\n\n**Recommendation Index**: <0-based index of the recommended branch in the decision tree above>\n**Recommendation**: <which branch the evidence best supports and why, 1-2 sentences>\n```\n\n## Open Questions\n\nFor each item in the Open Questions section, produce:\n\n```\n### E-<number>: <title from evaluation>\n\n**Confidence**: <High/Medium/Low>\n**Resolution path**: <\"resolve at your desk\" or \"needs a conversation\">\n\n**Decision tree**:\n- If <condition 1>, then <action 1>. See `file:line` (if available). <1-2 sentence rationale.>\n- If <condition 2>, then <action 2>. See `file:line` (if available). <1-2 sentence rationale.>\n\n**Recommendation Index**: <0-based index of the recommended branch in the decision tree above>\n**Recommendation**: <best guess at resolution path and why, or \"Insufficient evidence — escalate to <suggested stakeholder role>\", 1-2 sentences>\n```\n\n## Confirmed Improvements\n\nRender each Confirmed Improvement as a single bullet in a compact list. No headings per item, no decision trees, no rationale paragraphs.\n\n- **E-<number>: <title>** (Confidence: <High/Medium/Low>) — <recommended action, 1 sentence>\n\n## Round Agreement Summary\n\nAfter all items are processed, produce a summary section that groups items by round agreement status from the evaluation:\n\n### Points of Disagreement\nFor items where the evaluation marked \"rounds disagree\" or \"single round only\": list as bullets with the E-number, the nature of the disagreement, and a 1-sentence explanation of why this disagreement matters for the ticket (e.g., it indicates an architectural ambiguity, a scope question, or a standards gap).\n\nIf no items were marked as disagreements, write: \"All reviewed points had round consensus. No disagreement-driven risks identified.\"\n\n### Points of Agreement\nFor items where the evaluation marked \"both rounds agree\": list as bullets with the E-number and a half-sentence noting the shared conclusion. These items required minimal analysis and are lower risk.\n\n## Decision Tree Rules\n\n- Each decision tree must have 2-4 branches. Do not exceed 4.\n- Each branch must end with a concrete, actionable step (not \"investigate further\").\n- Cite relevant code in `file:line` format where possible. If no code reference exists, omit the citation rather than fabricating one.\n- Cap each branch at 2-3 sentences total (including the action and rationale).\n- `**Recommendation Index**` must be the 0-based index of the recommended branch in the decision tree above. The first branch is index 0, the second is index 1, etc.\n- **\"resolve at your desk\"**: The item can be resolved through technical investigation reading code, running tests, or checking configuration. No stakeholder input needed.\n- **\"needs a conversation\"**: The item involves a product decision, scope question, or cross-team dependency that cannot be resolved from the codebase alone.\n\n## Confidence Tags\n\nAssign confidence based on codebase evidence strength from the evaluation:\n- **High**: The evaluation cites specific `file:line` references that directly support the assessment.\n- **Medium**: The evaluation references related code patterns or architectural conventions, but not the exact code in question.\n- **Low**: No direct codebase evidence. Assessment is based on general reasoning or domain knowledge.\n\n## Edge Cases\n\n- If the evaluation contains zero items in Needs Scrutiny, write: \"No items flagged for scrutiny. All reviewed suggestions were either confirmed or remain open questions.\"\n- If the evaluation contains zero items in Open Questions, write: \"No open questions identified. All ambiguities were resolved through codebase analysis.\"\n- If both Needs Scrutiny and Open Questions are empty, include only the Confirmed Improvements section and add a summary: \"All suggestions from the review were confirmed as grounded improvements. No decision trees are needed.\"\n- If the evaluation does not contain Round Agreement fields (e.g., it was generated before this format), infer agreement status from the Source field: if both rounds are cited with the same conclusion, treat as agreement; if only one round is cited or they conflict, treat as disagreement.\n\n5. Save the resolution guide to `{docs_dir}/review/{ticket_key}-resolution-guide.md`. Output only the resolution guide — no meta-commentary.\n",
524
+ "update-ticket-rewrite.md": "Rewrite the Jira ticket description for {ticket_key} using the generated clarifying questions and critique documents.\n\n1. Fetch the current ticket description using the `get_ticket` tool with ticket_number `{ticket_key}`.\n2. Read the clarifying questions from the local file saved by the previous step (check `{docs_dir}/clarifying-questions/` for `{ticket_key}-clarifying-questions.md`). For each best-guess answer, verify it against the codebase using file search and code grep. Accept verified answers, correct inaccurate ones with evidence, and let ambiguous ones stand.\n3. Read the critique from the local file saved by the previous step (check `{docs_dir}/ticket-critiques/` for `{ticket_key}-ticket-quality-critique.md`). Address all Requested Changes. Apply Points to Consider selectively — accept genuine improvements, skip stylistic preferences.\n4. Write the rewritten ticket in standard markdown format (not Jira wiki markup). Preserve the Summary, Requirements, and Acceptance Criteria structure.\n5. Save the output to `{docs_dir}/tickets/{ticket_key}.md`. Output only the clean rewritten ticket — no meta-commentary.\n",
525
+ "write-epic-summary.md": "Synthesize all sub-task explorations into a final overview document.\n\n## Instructions\n\n1. First, use a terminal command or glob pattern to list all files in `{docs_dir}/epic-plans/{epic_slug}/explorations/`. Then read each file. Do not guess filenames — discover them dynamically.\n\n2. Also read:\n - `{docs_dir}/epic-plans/{epic_slug}/research-findings.md`\n - `{docs_dir}/epic-plans/{epic_slug}/decomposition.md`\n\n3. Synthesize the information into an overview and write it to `{docs_dir}/epic-plans/{epic_slug}/overview.md` with the following required sections:\n\n```markdown\n# Epic Overview: {epic title derived from description}\n\n## Epic Description and Goals\n{Summary of the epic's purpose, scope, and desired outcomes.}\n\n## Research Summary\n{Key external findings that informed the decomposition. If no research was performed, state \"No external research was needed.\"}\n\n## Sub-task List\n{Numbered list of all sub-tasks with relative markdown links to their exploration docs.}\n1. [Sub-task title](explorations/01-subtask-slug.md) — one-line summary\n2. [Sub-task title](explorations/02-subtask-slug.md) — one-line summary\n...\n\n## Dependency Graph\n{Textual list showing execution ordering and dependencies between sub-tasks.}\n- Sub-task 1: No dependencies (start here)\n- Sub-task 2: Depends on Sub-task 1\n- Sub-task 3: Depends on Sub-task 1\n- Sub-task 4: Depends on Sub-tasks 2, 3\n...\n\n## Next Steps\n{One-line summaries for each sub-task, specifically formatted so they can be copy-pasted directly into the `/write-ticket` command. Each line should be a self-contained ticket description.}\n```\n\n4. After writing the overview, display the file path to the user and summarize the epic plan.\n"
450
526
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bridge_gpt/mcp-server",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Bridge API MCP server — exposes Jira endpoints as MCP tools for Claude Code agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,12 +10,13 @@
10
10
  "files": [
11
11
  "build/",
12
12
  "!build/pipeline-utils.test.js",
13
+ "!build/decision-page-template.test.js",
13
14
  "pipelines/",
14
15
  "README.md",
15
16
  "LICENSE"
16
17
  ],
17
18
  "scripts": {
18
- "build": "node scripts/bundle-pipelines.js && node scripts/bundle-commands.js && tsc",
19
+ "build": "node scripts/bundle-pipelines.js && node scripts/bundle-commands.js && node scripts/bundle-agents.js && tsc",
19
20
  "postbuild": "node scripts/prepend-shebang.cjs",
20
21
  "start": "node build/index.js",
21
22
  "test": "node --test build/pipeline-utils.test.js",
@@ -42,6 +42,16 @@
42
42
  "description": "Create a pull request",
43
43
  "requires_approval": true
44
44
  },
45
+ {
46
+ "type": "mcp_call",
47
+ "tool": "update_jira_status",
48
+ "params": {
49
+ "ticket_number": "{ticket_key}",
50
+ "target_status": "In Review"
51
+ },
52
+ "description": "Transition ticket to In Review",
53
+ "on_error": "warn_and_continue"
54
+ },
45
55
  {
46
56
  "type": "agent_task",
47
57
  "instruction_file": "monitor-ci-checks.md",
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "plan-epic",
3
+ "description": "Decompose a feature epic into sub-tasks with structured exploration documents for each.",
4
+ "variables": ["epic_description", "epic_slug", "docs_dir"],
5
+ "steps": [
6
+ {
7
+ "type": "mcp_call",
8
+ "tool": "ping",
9
+ "params": {},
10
+ "description": "Verify Bridge API connectivity"
11
+ },
12
+ {
13
+ "type": "agent_task",
14
+ "instruction_file": "assess-epic-research-needs.md",
15
+ "description": "Assess research needs for the epic"
16
+ },
17
+ {
18
+ "type": "agent_task",
19
+ "instruction_file": "execute-epic-research.md",
20
+ "description": "Execute research plan",
21
+ "on_error": "warn_and_continue"
22
+ },
23
+ {
24
+ "type": "agent_task",
25
+ "instruction_file": "explore-epic-codebase.md",
26
+ "description": "Perform holistic codebase exploration for the epic"
27
+ },
28
+ {
29
+ "type": "agent_task",
30
+ "instruction_file": "decompose-epic.md",
31
+ "description": "Decompose epic into sub-tasks and get user approval"
32
+ },
33
+ {
34
+ "type": "agent_task",
35
+ "instruction_file": "explore-epic-subtasks.md",
36
+ "description": "Perform focused exploration for each sub-task"
37
+ },
38
+ {
39
+ "type": "agent_task",
40
+ "instruction_file": "write-epic-summary.md",
41
+ "description": "Write epic overview and summary document"
42
+ }
43
+ ]
44
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "review-ticket",
3
- "description": "Review a ticket with two rounds of analysis (initial + second opinion) and evaluate suggestions for accuracy and value.",
3
+ "description": "Review a ticket with two rounds of analysis (initial + second opinion), evaluate suggestions for accuracy, and produce a resolution guide with decision trees.",
4
4
  "variables": ["ticket_key", "docs_dir"],
5
5
  "steps": [
6
6
  {
@@ -63,6 +63,16 @@
63
63
  "type": "agent_task",
64
64
  "instruction_file": "evaluate-ticket-review.md",
65
65
  "description": "Evaluate review suggestions against the codebase for groundedness and value"
66
+ },
67
+ {
68
+ "type": "agent_task",
69
+ "instruction_file": "recommend-ticket-resolutions.md",
70
+ "description": "Produce a resolution guide with decision trees and confidence-tagged recommendations"
71
+ },
72
+ {
73
+ "type": "agent_task",
74
+ "instruction_file": "capture-review-decisions.md",
75
+ "description": "Generate HTML decision page, capture user decisions, and interpretively rewrite clarifying questions and critique docs"
66
76
  }
67
77
  ]
68
78
  }