@bugzy-ai/bugzy 1.18.2 → 1.18.4

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.
Files changed (61) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +273 -273
  3. package/dist/cli/index.cjs +295 -210
  4. package/dist/cli/index.cjs.map +1 -1
  5. package/dist/cli/index.js +294 -209
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/index.cjs +291 -206
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.js +291 -206
  10. package/dist/index.js.map +1 -1
  11. package/dist/subagents/index.cjs +115 -137
  12. package/dist/subagents/index.cjs.map +1 -1
  13. package/dist/subagents/index.js +115 -137
  14. package/dist/subagents/index.js.map +1 -1
  15. package/dist/subagents/metadata.cjs +12 -18
  16. package/dist/subagents/metadata.cjs.map +1 -1
  17. package/dist/subagents/metadata.js +12 -18
  18. package/dist/subagents/metadata.js.map +1 -1
  19. package/dist/tasks/index.cjs +142 -54
  20. package/dist/tasks/index.cjs.map +1 -1
  21. package/dist/tasks/index.js +142 -54
  22. package/dist/tasks/index.js.map +1 -1
  23. package/dist/templates/init/.bugzy/runtime/knowledge-base.md +61 -0
  24. package/dist/templates/init/.bugzy/runtime/knowledge-maintenance-guide.md +97 -0
  25. package/dist/templates/init/.bugzy/runtime/project-context.md +35 -0
  26. package/dist/templates/init/.bugzy/runtime/subagent-memory-guide.md +87 -0
  27. package/dist/templates/init/.bugzy/runtime/templates/test-plan-template.md +50 -0
  28. package/dist/templates/init/.bugzy/runtime/templates/test-result-schema.md +498 -0
  29. package/dist/templates/init/.bugzy/runtime/test-execution-strategy.md +535 -0
  30. package/dist/templates/init/.bugzy/runtime/testing-best-practices.md +632 -0
  31. package/dist/templates/init/.gitignore-template +25 -0
  32. package/package.json +95 -95
  33. package/templates/init/.bugzy/runtime/knowledge-base.md +61 -61
  34. package/templates/init/.bugzy/runtime/knowledge-maintenance-guide.md +97 -97
  35. package/templates/init/.bugzy/runtime/project-context.md +35 -35
  36. package/templates/init/.bugzy/runtime/subagent-memory-guide.md +87 -87
  37. package/templates/init/.bugzy/runtime/templates/event-examples.md +194 -194
  38. package/templates/init/.bugzy/runtime/templates/test-plan-template.md +50 -50
  39. package/templates/init/.bugzy/runtime/templates/test-result-schema.md +498 -498
  40. package/templates/init/.claude/settings.json +28 -28
  41. package/templates/init/.env.testdata +18 -18
  42. package/templates/init/.gitignore-template +24 -24
  43. package/templates/init/AGENTS.md +155 -155
  44. package/templates/init/CLAUDE.md +157 -157
  45. package/templates/init/test-runs/README.md +45 -45
  46. package/templates/init/tests/CLAUDE.md +193 -193
  47. package/templates/init/tests/docs/test-execution-strategy.md +535 -535
  48. package/templates/init/tests/docs/testing-best-practices.md +724 -724
  49. package/templates/playwright/BasePage.template.ts +190 -190
  50. package/templates/playwright/auth.setup.template.ts +89 -89
  51. package/templates/playwright/dataGenerators.helper.template.ts +148 -148
  52. package/templates/playwright/dateUtils.helper.template.ts +96 -96
  53. package/templates/playwright/pages.fixture.template.ts +50 -50
  54. package/templates/playwright/playwright.config.template.ts +97 -97
  55. package/templates/playwright/reporters/__tests__/bugzy-reporter-failure-classification.test.ts +299 -299
  56. package/templates/playwright/reporters/__tests__/bugzy-reporter-manifest-merge.test.ts +329 -329
  57. package/templates/playwright/reporters/__tests__/playwright.config.ts +5 -5
  58. package/templates/playwright/reporters/bugzy-reporter.ts +784 -784
  59. package/templates/init/.bugzy/runtime/handlers/messages/feedback.md +0 -178
  60. package/templates/init/.bugzy/runtime/handlers/messages/question.md +0 -122
  61. package/templates/init/.bugzy/runtime/handlers/messages/status.md +0 -146
@@ -120,6 +120,13 @@ var INTEGRATIONS = {
120
120
  // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)
121
121
  isLocal: true,
122
122
  integrationType: "local"
123
+ },
124
+ default: {
125
+ id: "default",
126
+ name: "Default",
127
+ provider: "default",
128
+ isLocal: true,
129
+ integrationType: "local"
123
130
  }
124
131
  };
125
132
  var SUBAGENTS = {
@@ -179,28 +186,15 @@ var SUBAGENTS = {
179
186
  color: "cyan",
180
187
  version: "1.0.0"
181
188
  },
182
- "test-code-generator": {
183
- role: "test-code-generator",
184
- name: "Test Code Generator",
185
- description: "Generate automated test scripts and page objects",
189
+ "test-engineer": {
190
+ role: "test-engineer",
191
+ name: "Test Engineer",
192
+ description: "Create, update, debug, and fix automated tests",
186
193
  icon: "code",
187
- integrations: [INTEGRATIONS.playwright],
194
+ integrations: [INTEGRATIONS.default],
188
195
  model: "sonnet",
189
196
  color: "purple",
190
197
  isRequired: true,
191
- // Required for automated test generation
192
- version: "1.0.0"
193
- },
194
- "test-debugger-fixer": {
195
- role: "test-debugger-fixer",
196
- name: "Test Debugger & Fixer",
197
- description: "Debug and fix failing automated tests automatically",
198
- icon: "wrench",
199
- integrations: [INTEGRATIONS.playwright],
200
- model: "sonnet",
201
- color: "yellow",
202
- isRequired: true,
203
- // Required for automated test execution and fixing
204
198
  version: "1.0.0"
205
199
  },
206
200
  "changelog-historian": {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/subagents/metadata.ts"],"sourcesContent":["/**\r\n * Sub-Agents Metadata\r\n * Client-safe metadata without file system access\r\n */\r\n\r\n/**\r\n * Integration type determines how credentials are obtained\r\n * - 'oauth': Uses Nango OAuth flow (Slack, Notion, Jira Cloud, etc.)\r\n * - 'local': No configuration needed (Playwright)\r\n * - 'custom': Custom configuration flow (Jira Server via MCP tunnel)\r\n */\r\nexport type IntegrationType = 'oauth' | 'local' | 'custom';\r\n\r\n/**\r\n * Integration configuration for sub-agents\r\n */\r\nexport interface SubAgentIntegration {\r\n id: string;\r\n name: string;\r\n provider: string;\r\n requiredMCP?: string;\r\n /** @deprecated Use integrationType instead */\r\n isLocal?: boolean; // True if integration doesn't require external connector (e.g., playwright)\r\n integrationType: IntegrationType;\r\n}\r\n\r\n/**\r\n * Sub-Agent Metadata\r\n */\r\nexport interface SubAgentMetadata {\r\n role: string;\r\n name: string;\r\n description: string;\r\n icon: string; // Icon name (e.g., 'play', 'message-square', 'bot', 'file-search')\r\n integrations: SubAgentIntegration[];\r\n model?: string;\r\n color?: string;\r\n isRequired?: boolean;\r\n defaultIntegration?: string; // Fallback integration ID when others aren't configured\r\n version: string;\r\n}\r\n\r\n/**\r\n * Available integrations by provider\r\n */\r\nexport const INTEGRATIONS: Record<string, SubAgentIntegration> = {\r\n linear: {\r\n id: 'linear',\r\n name: 'Linear',\r\n provider: 'linear',\r\n requiredMCP: 'mcp__linear__*',\r\n integrationType: 'oauth'\r\n },\r\n jira: {\r\n id: 'jira',\r\n name: 'Jira',\r\n provider: 'jira',\r\n requiredMCP: 'mcp__jira__*',\r\n integrationType: 'oauth'\r\n },\r\n 'jira-server': {\r\n id: 'jira-server',\r\n name: 'Jira Server',\r\n provider: 'jira-server',\r\n requiredMCP: 'mcp__jira-server__*',\r\n integrationType: 'custom'\r\n },\r\n 'azure-devops': {\r\n id: 'azure-devops',\r\n name: 'Azure DevOps',\r\n provider: 'azure-devops',\r\n requiredMCP: 'mcp__azure-devops__*',\r\n integrationType: 'oauth' // Uses Nango with API key auth for PAT\r\n },\r\n notion: {\r\n id: 'notion',\r\n name: 'Notion',\r\n provider: 'notion',\r\n requiredMCP: 'mcp__notion__*',\r\n integrationType: 'oauth'\r\n },\r\n confluence: {\r\n id: 'confluence',\r\n name: 'Confluence',\r\n provider: 'confluence',\r\n requiredMCP: 'mcp__confluence__*',\r\n integrationType: 'oauth'\r\n },\r\n slack: {\r\n id: 'slack',\r\n name: 'Slack',\r\n provider: 'slack',\r\n requiredMCP: 'mcp__slack__*',\r\n integrationType: 'oauth'\r\n },\r\n playwright: {\r\n id: 'playwright',\r\n name: 'Playwright',\r\n provider: 'playwright',\r\n // No requiredMCP — uses playwright-cli (CLI tool), not MCP server\r\n isLocal: true, // Playwright runs locally, no external connector needed\r\n integrationType: 'local'\r\n },\r\n teams: {\r\n id: 'teams',\r\n name: 'Microsoft Teams',\r\n provider: 'teams',\r\n requiredMCP: 'mcp__teams__*',\r\n integrationType: 'oauth'\r\n },\r\n email: {\r\n id: 'email',\r\n name: 'Email',\r\n provider: 'resend',\r\n requiredMCP: 'mcp__resend__*',\r\n integrationType: 'local' // Uses platform API key, no OAuth needed\r\n },\r\n github: {\r\n id: 'github',\r\n name: 'GitHub',\r\n provider: 'github',\r\n requiredMCP: 'mcp__github__*',\r\n integrationType: 'oauth'\r\n },\r\n local: {\r\n id: 'local',\r\n name: 'Local (Terminal)',\r\n provider: 'local',\r\n // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)\r\n isLocal: true,\r\n integrationType: 'local'\r\n }\r\n};\r\n\r\n/**\r\n * Sub-Agents Registry - metadata only (templates loaded from files)\r\n */\r\nexport const SUBAGENTS: Record<string, SubAgentMetadata> = {\r\n 'browser-automation': {\r\n role: 'browser-automation',\r\n name: 'Browser Automation',\r\n description: 'Execute automated browser tests (always included)',\r\n icon: 'play',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'green',\r\n isRequired: true,\r\n version: '1.0.0'\r\n },\r\n 'team-communicator': {\r\n role: 'team-communicator',\r\n name: 'Team Communicator',\r\n description: 'Send notifications and updates to your team',\r\n icon: 'message-square',\r\n integrations: [INTEGRATIONS.slack, INTEGRATIONS.teams, INTEGRATIONS.email],\r\n model: 'sonnet',\r\n color: 'blue',\r\n isRequired: true, // Required - CLI uses 'local' (auto-configured), cloud uses email fallback\r\n defaultIntegration: 'email', // Email fallback for cloud (CLI auto-configures 'local' separately)\r\n version: '1.0.0'\r\n },\r\n 'issue-tracker': {\r\n role: 'issue-tracker',\r\n name: 'Issue Tracker',\r\n description: 'Automatically create and track bugs and issues',\r\n icon: 'bot',\r\n integrations: [\r\n // INTEGRATIONS.linear,\r\n INTEGRATIONS.jira,\r\n INTEGRATIONS['jira-server'],\r\n INTEGRATIONS['azure-devops'],\r\n INTEGRATIONS.notion,\r\n INTEGRATIONS.slack\r\n ],\r\n model: 'sonnet',\r\n color: 'red',\r\n version: '1.0.0'\r\n },\r\n 'documentation-researcher': {\r\n role: 'documentation-researcher',\r\n name: 'Documentation Researcher',\r\n description: 'Search and retrieve information from your documentation',\r\n icon: 'file-search',\r\n integrations: [\r\n INTEGRATIONS.notion,\r\n INTEGRATIONS.jira,\r\n // INTEGRATIONS.confluence\r\n ],\r\n model: 'sonnet',\r\n color: 'cyan',\r\n version: '1.0.0'\r\n },\r\n 'test-code-generator': {\r\n role: 'test-code-generator',\r\n name: 'Test Code Generator',\r\n description: 'Generate automated test scripts and page objects',\r\n icon: 'code',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'purple',\r\n isRequired: true, // Required for automated test generation\r\n version: '1.0.0'\r\n },\r\n 'test-debugger-fixer': {\r\n role: 'test-debugger-fixer',\r\n name: 'Test Debugger & Fixer',\r\n description: 'Debug and fix failing automated tests automatically',\r\n icon: 'wrench',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'yellow',\r\n isRequired: true, // Required for automated test execution and fixing\r\n version: '1.0.0'\r\n },\r\n 'changelog-historian': {\r\n role: 'changelog-historian',\r\n name: 'Changelog Historian',\r\n description: 'Retrieves and analyzes code changes from GitHub PRs and commits',\r\n icon: 'git-pull-request',\r\n integrations: [INTEGRATIONS.github],\r\n model: 'haiku',\r\n color: 'gray',\r\n isRequired: false,\r\n version: '1.0.0'\r\n }\r\n};\r\n\r\n/**\r\n * Get all available sub-agents\r\n */\r\nexport function getAllSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS);\r\n}\r\n\r\n/**\r\n * Get sub-agent by role\r\n */\r\nexport function getSubAgent(role: string): SubAgentMetadata | undefined {\r\n return SUBAGENTS[role];\r\n}\r\n\r\n/**\r\n * Get integration by ID\r\n */\r\nexport function getIntegration(integrationId: string): SubAgentIntegration | undefined {\r\n return INTEGRATIONS[integrationId];\r\n}\r\n\r\n/**\r\n * Get required sub-agents (always included)\r\n */\r\nexport function getRequiredSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS).filter(agent => agent.isRequired);\r\n}\r\n\r\n/**\r\n * Get optional sub-agents (user can choose)\r\n */\r\nexport function getOptionalSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS).filter(agent => !agent.isRequired);\r\n}\r\n\r\n/**\r\n * Map integration ID to display name\r\n */\r\nexport function getIntegrationDisplayName(integrationId: string): string {\r\n return INTEGRATIONS[integrationId]?.name || integrationId;\r\n}\r\n\r\n/**\r\n * Get required integrations from a list of subagent roles\r\n */\r\nexport function getRequiredIntegrationsFromSubagents(roles: string[]): string[] {\r\n const integrations = new Set<string>();\r\n\r\n for (const role of roles) {\r\n const agent = SUBAGENTS[role];\r\n if (agent?.integrations) {\r\n agent.integrations.forEach(int => integrations.add(int.id));\r\n }\r\n }\r\n\r\n return Array.from(integrations);\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/subagents/metadata.ts"],"sourcesContent":["/**\n * Sub-Agents Metadata\n * Client-safe metadata without file system access\n */\n\n/**\n * Integration type determines how credentials are obtained\n * - 'oauth': Uses Nango OAuth flow (Slack, Notion, Jira Cloud, etc.)\n * - 'local': No configuration needed (Playwright)\n * - 'custom': Custom configuration flow (Jira Server via MCP tunnel)\n */\nexport type IntegrationType = 'oauth' | 'local' | 'custom';\n\n/**\n * Integration configuration for sub-agents\n */\nexport interface SubAgentIntegration {\n id: string;\n name: string;\n provider: string;\n requiredMCP?: string;\n /** @deprecated Use integrationType instead */\n isLocal?: boolean; // True if integration doesn't require external connector (e.g., playwright)\n integrationType: IntegrationType;\n}\n\n/**\n * Sub-Agent Metadata\n */\nexport interface SubAgentMetadata {\n role: string;\n name: string;\n description: string;\n icon: string; // Icon name (e.g., 'play', 'message-square', 'bot', 'file-search')\n integrations: SubAgentIntegration[];\n model?: string;\n color?: string;\n isRequired?: boolean;\n defaultIntegration?: string; // Fallback integration ID when others aren't configured\n version: string;\n}\n\n/**\n * Available integrations by provider\n */\nexport const INTEGRATIONS: Record<string, SubAgentIntegration> = {\n linear: {\n id: 'linear',\n name: 'Linear',\n provider: 'linear',\n requiredMCP: 'mcp__linear__*',\n integrationType: 'oauth'\n },\n jira: {\n id: 'jira',\n name: 'Jira',\n provider: 'jira',\n requiredMCP: 'mcp__jira__*',\n integrationType: 'oauth'\n },\n 'jira-server': {\n id: 'jira-server',\n name: 'Jira Server',\n provider: 'jira-server',\n requiredMCP: 'mcp__jira-server__*',\n integrationType: 'custom'\n },\n 'azure-devops': {\n id: 'azure-devops',\n name: 'Azure DevOps',\n provider: 'azure-devops',\n requiredMCP: 'mcp__azure-devops__*',\n integrationType: 'oauth' // Uses Nango with API key auth for PAT\n },\n notion: {\n id: 'notion',\n name: 'Notion',\n provider: 'notion',\n requiredMCP: 'mcp__notion__*',\n integrationType: 'oauth'\n },\n confluence: {\n id: 'confluence',\n name: 'Confluence',\n provider: 'confluence',\n requiredMCP: 'mcp__confluence__*',\n integrationType: 'oauth'\n },\n slack: {\n id: 'slack',\n name: 'Slack',\n provider: 'slack',\n requiredMCP: 'mcp__slack__*',\n integrationType: 'oauth'\n },\n playwright: {\n id: 'playwright',\n name: 'Playwright',\n provider: 'playwright',\n // No requiredMCP — uses playwright-cli (CLI tool), not MCP server\n isLocal: true, // Playwright runs locally, no external connector needed\n integrationType: 'local'\n },\n teams: {\n id: 'teams',\n name: 'Microsoft Teams',\n provider: 'teams',\n requiredMCP: 'mcp__teams__*',\n integrationType: 'oauth'\n },\n email: {\n id: 'email',\n name: 'Email',\n provider: 'resend',\n requiredMCP: 'mcp__resend__*',\n integrationType: 'local' // Uses platform API key, no OAuth needed\n },\n github: {\n id: 'github',\n name: 'GitHub',\n provider: 'github',\n requiredMCP: 'mcp__github__*',\n integrationType: 'oauth'\n },\n local: {\n id: 'local',\n name: 'Local (Terminal)',\n provider: 'local',\n // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)\n isLocal: true,\n integrationType: 'local'\n },\n default: {\n id: 'default',\n name: 'Default',\n provider: 'default',\n isLocal: true,\n integrationType: 'local'\n }\n};\n\n/**\n * Sub-Agents Registry - metadata only (templates loaded from files)\n */\nexport const SUBAGENTS: Record<string, SubAgentMetadata> = {\n 'browser-automation': {\n role: 'browser-automation',\n name: 'Browser Automation',\n description: 'Execute automated browser tests (always included)',\n icon: 'play',\n integrations: [INTEGRATIONS.playwright],\n model: 'sonnet',\n color: 'green',\n isRequired: true,\n version: '1.0.0'\n },\n 'team-communicator': {\n role: 'team-communicator',\n name: 'Team Communicator',\n description: 'Send notifications and updates to your team',\n icon: 'message-square',\n integrations: [INTEGRATIONS.slack, INTEGRATIONS.teams, INTEGRATIONS.email],\n model: 'sonnet',\n color: 'blue',\n isRequired: true, // Required - CLI uses 'local' (auto-configured), cloud uses email fallback\n defaultIntegration: 'email', // Email fallback for cloud (CLI auto-configures 'local' separately)\n version: '1.0.0'\n },\n 'issue-tracker': {\n role: 'issue-tracker',\n name: 'Issue Tracker',\n description: 'Automatically create and track bugs and issues',\n icon: 'bot',\n integrations: [\n // INTEGRATIONS.linear,\n INTEGRATIONS.jira,\n INTEGRATIONS['jira-server'],\n INTEGRATIONS['azure-devops'],\n INTEGRATIONS.notion,\n INTEGRATIONS.slack\n ],\n model: 'sonnet',\n color: 'red',\n version: '1.0.0'\n },\n 'documentation-researcher': {\n role: 'documentation-researcher',\n name: 'Documentation Researcher',\n description: 'Search and retrieve information from your documentation',\n icon: 'file-search',\n integrations: [\n INTEGRATIONS.notion,\n INTEGRATIONS.jira,\n // INTEGRATIONS.confluence\n ],\n model: 'sonnet',\n color: 'cyan',\n version: '1.0.0'\n },\n 'test-engineer': {\n role: 'test-engineer',\n name: 'Test Engineer',\n description: 'Create, update, debug, and fix automated tests',\n icon: 'code',\n integrations: [INTEGRATIONS.default],\n model: 'sonnet',\n color: 'purple',\n isRequired: true,\n version: '1.0.0'\n },\n 'changelog-historian': {\n role: 'changelog-historian',\n name: 'Changelog Historian',\n description: 'Retrieves and analyzes code changes from GitHub PRs and commits',\n icon: 'git-pull-request',\n integrations: [INTEGRATIONS.github],\n model: 'haiku',\n color: 'gray',\n isRequired: false,\n version: '1.0.0'\n }\n};\n\n/**\n * Get all available sub-agents\n */\nexport function getAllSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS);\n}\n\n/**\n * Get sub-agent by role\n */\nexport function getSubAgent(role: string): SubAgentMetadata | undefined {\n return SUBAGENTS[role];\n}\n\n/**\n * Get integration by ID\n */\nexport function getIntegration(integrationId: string): SubAgentIntegration | undefined {\n return INTEGRATIONS[integrationId];\n}\n\n/**\n * Get required sub-agents (always included)\n */\nexport function getRequiredSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS).filter(agent => agent.isRequired);\n}\n\n/**\n * Get optional sub-agents (user can choose)\n */\nexport function getOptionalSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS).filter(agent => !agent.isRequired);\n}\n\n/**\n * Map integration ID to display name\n */\nexport function getIntegrationDisplayName(integrationId: string): string {\n return INTEGRATIONS[integrationId]?.name || integrationId;\n}\n\n/**\n * Get required integrations from a list of subagent roles\n */\nexport function getRequiredIntegrationsFromSubagents(roles: string[]): string[] {\n const integrations = new Set<string>();\n\n for (const role of roles) {\n const agent = SUBAGENTS[role];\n if (agent?.integrations) {\n agent.integrations.forEach(int => integrations.add(int.id));\n }\n }\n\n return Array.from(integrations);\n}\n"],"mappings":"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","names":[]}
@@ -88,6 +88,13 @@ var INTEGRATIONS = {
88
88
  // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)
89
89
  isLocal: true,
90
90
  integrationType: "local"
91
+ },
92
+ default: {
93
+ id: "default",
94
+ name: "Default",
95
+ provider: "default",
96
+ isLocal: true,
97
+ integrationType: "local"
91
98
  }
92
99
  };
93
100
  var SUBAGENTS = {
@@ -147,28 +154,15 @@ var SUBAGENTS = {
147
154
  color: "cyan",
148
155
  version: "1.0.0"
149
156
  },
150
- "test-code-generator": {
151
- role: "test-code-generator",
152
- name: "Test Code Generator",
153
- description: "Generate automated test scripts and page objects",
157
+ "test-engineer": {
158
+ role: "test-engineer",
159
+ name: "Test Engineer",
160
+ description: "Create, update, debug, and fix automated tests",
154
161
  icon: "code",
155
- integrations: [INTEGRATIONS.playwright],
162
+ integrations: [INTEGRATIONS.default],
156
163
  model: "sonnet",
157
164
  color: "purple",
158
165
  isRequired: true,
159
- // Required for automated test generation
160
- version: "1.0.0"
161
- },
162
- "test-debugger-fixer": {
163
- role: "test-debugger-fixer",
164
- name: "Test Debugger & Fixer",
165
- description: "Debug and fix failing automated tests automatically",
166
- icon: "wrench",
167
- integrations: [INTEGRATIONS.playwright],
168
- model: "sonnet",
169
- color: "yellow",
170
- isRequired: true,
171
- // Required for automated test execution and fixing
172
166
  version: "1.0.0"
173
167
  },
174
168
  "changelog-historian": {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/subagents/metadata.ts"],"sourcesContent":["/**\r\n * Sub-Agents Metadata\r\n * Client-safe metadata without file system access\r\n */\r\n\r\n/**\r\n * Integration type determines how credentials are obtained\r\n * - 'oauth': Uses Nango OAuth flow (Slack, Notion, Jira Cloud, etc.)\r\n * - 'local': No configuration needed (Playwright)\r\n * - 'custom': Custom configuration flow (Jira Server via MCP tunnel)\r\n */\r\nexport type IntegrationType = 'oauth' | 'local' | 'custom';\r\n\r\n/**\r\n * Integration configuration for sub-agents\r\n */\r\nexport interface SubAgentIntegration {\r\n id: string;\r\n name: string;\r\n provider: string;\r\n requiredMCP?: string;\r\n /** @deprecated Use integrationType instead */\r\n isLocal?: boolean; // True if integration doesn't require external connector (e.g., playwright)\r\n integrationType: IntegrationType;\r\n}\r\n\r\n/**\r\n * Sub-Agent Metadata\r\n */\r\nexport interface SubAgentMetadata {\r\n role: string;\r\n name: string;\r\n description: string;\r\n icon: string; // Icon name (e.g., 'play', 'message-square', 'bot', 'file-search')\r\n integrations: SubAgentIntegration[];\r\n model?: string;\r\n color?: string;\r\n isRequired?: boolean;\r\n defaultIntegration?: string; // Fallback integration ID when others aren't configured\r\n version: string;\r\n}\r\n\r\n/**\r\n * Available integrations by provider\r\n */\r\nexport const INTEGRATIONS: Record<string, SubAgentIntegration> = {\r\n linear: {\r\n id: 'linear',\r\n name: 'Linear',\r\n provider: 'linear',\r\n requiredMCP: 'mcp__linear__*',\r\n integrationType: 'oauth'\r\n },\r\n jira: {\r\n id: 'jira',\r\n name: 'Jira',\r\n provider: 'jira',\r\n requiredMCP: 'mcp__jira__*',\r\n integrationType: 'oauth'\r\n },\r\n 'jira-server': {\r\n id: 'jira-server',\r\n name: 'Jira Server',\r\n provider: 'jira-server',\r\n requiredMCP: 'mcp__jira-server__*',\r\n integrationType: 'custom'\r\n },\r\n 'azure-devops': {\r\n id: 'azure-devops',\r\n name: 'Azure DevOps',\r\n provider: 'azure-devops',\r\n requiredMCP: 'mcp__azure-devops__*',\r\n integrationType: 'oauth' // Uses Nango with API key auth for PAT\r\n },\r\n notion: {\r\n id: 'notion',\r\n name: 'Notion',\r\n provider: 'notion',\r\n requiredMCP: 'mcp__notion__*',\r\n integrationType: 'oauth'\r\n },\r\n confluence: {\r\n id: 'confluence',\r\n name: 'Confluence',\r\n provider: 'confluence',\r\n requiredMCP: 'mcp__confluence__*',\r\n integrationType: 'oauth'\r\n },\r\n slack: {\r\n id: 'slack',\r\n name: 'Slack',\r\n provider: 'slack',\r\n requiredMCP: 'mcp__slack__*',\r\n integrationType: 'oauth'\r\n },\r\n playwright: {\r\n id: 'playwright',\r\n name: 'Playwright',\r\n provider: 'playwright',\r\n // No requiredMCP — uses playwright-cli (CLI tool), not MCP server\r\n isLocal: true, // Playwright runs locally, no external connector needed\r\n integrationType: 'local'\r\n },\r\n teams: {\r\n id: 'teams',\r\n name: 'Microsoft Teams',\r\n provider: 'teams',\r\n requiredMCP: 'mcp__teams__*',\r\n integrationType: 'oauth'\r\n },\r\n email: {\r\n id: 'email',\r\n name: 'Email',\r\n provider: 'resend',\r\n requiredMCP: 'mcp__resend__*',\r\n integrationType: 'local' // Uses platform API key, no OAuth needed\r\n },\r\n github: {\r\n id: 'github',\r\n name: 'GitHub',\r\n provider: 'github',\r\n requiredMCP: 'mcp__github__*',\r\n integrationType: 'oauth'\r\n },\r\n local: {\r\n id: 'local',\r\n name: 'Local (Terminal)',\r\n provider: 'local',\r\n // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)\r\n isLocal: true,\r\n integrationType: 'local'\r\n }\r\n};\r\n\r\n/**\r\n * Sub-Agents Registry - metadata only (templates loaded from files)\r\n */\r\nexport const SUBAGENTS: Record<string, SubAgentMetadata> = {\r\n 'browser-automation': {\r\n role: 'browser-automation',\r\n name: 'Browser Automation',\r\n description: 'Execute automated browser tests (always included)',\r\n icon: 'play',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'green',\r\n isRequired: true,\r\n version: '1.0.0'\r\n },\r\n 'team-communicator': {\r\n role: 'team-communicator',\r\n name: 'Team Communicator',\r\n description: 'Send notifications and updates to your team',\r\n icon: 'message-square',\r\n integrations: [INTEGRATIONS.slack, INTEGRATIONS.teams, INTEGRATIONS.email],\r\n model: 'sonnet',\r\n color: 'blue',\r\n isRequired: true, // Required - CLI uses 'local' (auto-configured), cloud uses email fallback\r\n defaultIntegration: 'email', // Email fallback for cloud (CLI auto-configures 'local' separately)\r\n version: '1.0.0'\r\n },\r\n 'issue-tracker': {\r\n role: 'issue-tracker',\r\n name: 'Issue Tracker',\r\n description: 'Automatically create and track bugs and issues',\r\n icon: 'bot',\r\n integrations: [\r\n // INTEGRATIONS.linear,\r\n INTEGRATIONS.jira,\r\n INTEGRATIONS['jira-server'],\r\n INTEGRATIONS['azure-devops'],\r\n INTEGRATIONS.notion,\r\n INTEGRATIONS.slack\r\n ],\r\n model: 'sonnet',\r\n color: 'red',\r\n version: '1.0.0'\r\n },\r\n 'documentation-researcher': {\r\n role: 'documentation-researcher',\r\n name: 'Documentation Researcher',\r\n description: 'Search and retrieve information from your documentation',\r\n icon: 'file-search',\r\n integrations: [\r\n INTEGRATIONS.notion,\r\n INTEGRATIONS.jira,\r\n // INTEGRATIONS.confluence\r\n ],\r\n model: 'sonnet',\r\n color: 'cyan',\r\n version: '1.0.0'\r\n },\r\n 'test-code-generator': {\r\n role: 'test-code-generator',\r\n name: 'Test Code Generator',\r\n description: 'Generate automated test scripts and page objects',\r\n icon: 'code',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'purple',\r\n isRequired: true, // Required for automated test generation\r\n version: '1.0.0'\r\n },\r\n 'test-debugger-fixer': {\r\n role: 'test-debugger-fixer',\r\n name: 'Test Debugger & Fixer',\r\n description: 'Debug and fix failing automated tests automatically',\r\n icon: 'wrench',\r\n integrations: [INTEGRATIONS.playwright],\r\n model: 'sonnet',\r\n color: 'yellow',\r\n isRequired: true, // Required for automated test execution and fixing\r\n version: '1.0.0'\r\n },\r\n 'changelog-historian': {\r\n role: 'changelog-historian',\r\n name: 'Changelog Historian',\r\n description: 'Retrieves and analyzes code changes from GitHub PRs and commits',\r\n icon: 'git-pull-request',\r\n integrations: [INTEGRATIONS.github],\r\n model: 'haiku',\r\n color: 'gray',\r\n isRequired: false,\r\n version: '1.0.0'\r\n }\r\n};\r\n\r\n/**\r\n * Get all available sub-agents\r\n */\r\nexport function getAllSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS);\r\n}\r\n\r\n/**\r\n * Get sub-agent by role\r\n */\r\nexport function getSubAgent(role: string): SubAgentMetadata | undefined {\r\n return SUBAGENTS[role];\r\n}\r\n\r\n/**\r\n * Get integration by ID\r\n */\r\nexport function getIntegration(integrationId: string): SubAgentIntegration | undefined {\r\n return INTEGRATIONS[integrationId];\r\n}\r\n\r\n/**\r\n * Get required sub-agents (always included)\r\n */\r\nexport function getRequiredSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS).filter(agent => agent.isRequired);\r\n}\r\n\r\n/**\r\n * Get optional sub-agents (user can choose)\r\n */\r\nexport function getOptionalSubAgents(): SubAgentMetadata[] {\r\n return Object.values(SUBAGENTS).filter(agent => !agent.isRequired);\r\n}\r\n\r\n/**\r\n * Map integration ID to display name\r\n */\r\nexport function getIntegrationDisplayName(integrationId: string): string {\r\n return INTEGRATIONS[integrationId]?.name || integrationId;\r\n}\r\n\r\n/**\r\n * Get required integrations from a list of subagent roles\r\n */\r\nexport function getRequiredIntegrationsFromSubagents(roles: string[]): string[] {\r\n const integrations = new Set<string>();\r\n\r\n for (const role of roles) {\r\n const agent = SUBAGENTS[role];\r\n if (agent?.integrations) {\r\n agent.integrations.forEach(int => integrations.add(int.id));\r\n }\r\n }\r\n\r\n return Array.from(integrations);\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/subagents/metadata.ts"],"sourcesContent":["/**\n * Sub-Agents Metadata\n * Client-safe metadata without file system access\n */\n\n/**\n * Integration type determines how credentials are obtained\n * - 'oauth': Uses Nango OAuth flow (Slack, Notion, Jira Cloud, etc.)\n * - 'local': No configuration needed (Playwright)\n * - 'custom': Custom configuration flow (Jira Server via MCP tunnel)\n */\nexport type IntegrationType = 'oauth' | 'local' | 'custom';\n\n/**\n * Integration configuration for sub-agents\n */\nexport interface SubAgentIntegration {\n id: string;\n name: string;\n provider: string;\n requiredMCP?: string;\n /** @deprecated Use integrationType instead */\n isLocal?: boolean; // True if integration doesn't require external connector (e.g., playwright)\n integrationType: IntegrationType;\n}\n\n/**\n * Sub-Agent Metadata\n */\nexport interface SubAgentMetadata {\n role: string;\n name: string;\n description: string;\n icon: string; // Icon name (e.g., 'play', 'message-square', 'bot', 'file-search')\n integrations: SubAgentIntegration[];\n model?: string;\n color?: string;\n isRequired?: boolean;\n defaultIntegration?: string; // Fallback integration ID when others aren't configured\n version: string;\n}\n\n/**\n * Available integrations by provider\n */\nexport const INTEGRATIONS: Record<string, SubAgentIntegration> = {\n linear: {\n id: 'linear',\n name: 'Linear',\n provider: 'linear',\n requiredMCP: 'mcp__linear__*',\n integrationType: 'oauth'\n },\n jira: {\n id: 'jira',\n name: 'Jira',\n provider: 'jira',\n requiredMCP: 'mcp__jira__*',\n integrationType: 'oauth'\n },\n 'jira-server': {\n id: 'jira-server',\n name: 'Jira Server',\n provider: 'jira-server',\n requiredMCP: 'mcp__jira-server__*',\n integrationType: 'custom'\n },\n 'azure-devops': {\n id: 'azure-devops',\n name: 'Azure DevOps',\n provider: 'azure-devops',\n requiredMCP: 'mcp__azure-devops__*',\n integrationType: 'oauth' // Uses Nango with API key auth for PAT\n },\n notion: {\n id: 'notion',\n name: 'Notion',\n provider: 'notion',\n requiredMCP: 'mcp__notion__*',\n integrationType: 'oauth'\n },\n confluence: {\n id: 'confluence',\n name: 'Confluence',\n provider: 'confluence',\n requiredMCP: 'mcp__confluence__*',\n integrationType: 'oauth'\n },\n slack: {\n id: 'slack',\n name: 'Slack',\n provider: 'slack',\n requiredMCP: 'mcp__slack__*',\n integrationType: 'oauth'\n },\n playwright: {\n id: 'playwright',\n name: 'Playwright',\n provider: 'playwright',\n // No requiredMCP — uses playwright-cli (CLI tool), not MCP server\n isLocal: true, // Playwright runs locally, no external connector needed\n integrationType: 'local'\n },\n teams: {\n id: 'teams',\n name: 'Microsoft Teams',\n provider: 'teams',\n requiredMCP: 'mcp__teams__*',\n integrationType: 'oauth'\n },\n email: {\n id: 'email',\n name: 'Email',\n provider: 'resend',\n requiredMCP: 'mcp__resend__*',\n integrationType: 'local' // Uses platform API key, no OAuth needed\n },\n github: {\n id: 'github',\n name: 'GitHub',\n provider: 'github',\n requiredMCP: 'mcp__github__*',\n integrationType: 'oauth'\n },\n local: {\n id: 'local',\n name: 'Local (Terminal)',\n provider: 'local',\n // No requiredMCP - uses built-in Claude Code tools (AskUserQuestion, text output)\n isLocal: true,\n integrationType: 'local'\n },\n default: {\n id: 'default',\n name: 'Default',\n provider: 'default',\n isLocal: true,\n integrationType: 'local'\n }\n};\n\n/**\n * Sub-Agents Registry - metadata only (templates loaded from files)\n */\nexport const SUBAGENTS: Record<string, SubAgentMetadata> = {\n 'browser-automation': {\n role: 'browser-automation',\n name: 'Browser Automation',\n description: 'Execute automated browser tests (always included)',\n icon: 'play',\n integrations: [INTEGRATIONS.playwright],\n model: 'sonnet',\n color: 'green',\n isRequired: true,\n version: '1.0.0'\n },\n 'team-communicator': {\n role: 'team-communicator',\n name: 'Team Communicator',\n description: 'Send notifications and updates to your team',\n icon: 'message-square',\n integrations: [INTEGRATIONS.slack, INTEGRATIONS.teams, INTEGRATIONS.email],\n model: 'sonnet',\n color: 'blue',\n isRequired: true, // Required - CLI uses 'local' (auto-configured), cloud uses email fallback\n defaultIntegration: 'email', // Email fallback for cloud (CLI auto-configures 'local' separately)\n version: '1.0.0'\n },\n 'issue-tracker': {\n role: 'issue-tracker',\n name: 'Issue Tracker',\n description: 'Automatically create and track bugs and issues',\n icon: 'bot',\n integrations: [\n // INTEGRATIONS.linear,\n INTEGRATIONS.jira,\n INTEGRATIONS['jira-server'],\n INTEGRATIONS['azure-devops'],\n INTEGRATIONS.notion,\n INTEGRATIONS.slack\n ],\n model: 'sonnet',\n color: 'red',\n version: '1.0.0'\n },\n 'documentation-researcher': {\n role: 'documentation-researcher',\n name: 'Documentation Researcher',\n description: 'Search and retrieve information from your documentation',\n icon: 'file-search',\n integrations: [\n INTEGRATIONS.notion,\n INTEGRATIONS.jira,\n // INTEGRATIONS.confluence\n ],\n model: 'sonnet',\n color: 'cyan',\n version: '1.0.0'\n },\n 'test-engineer': {\n role: 'test-engineer',\n name: 'Test Engineer',\n description: 'Create, update, debug, and fix automated tests',\n icon: 'code',\n integrations: [INTEGRATIONS.default],\n model: 'sonnet',\n color: 'purple',\n isRequired: true,\n version: '1.0.0'\n },\n 'changelog-historian': {\n role: 'changelog-historian',\n name: 'Changelog Historian',\n description: 'Retrieves and analyzes code changes from GitHub PRs and commits',\n icon: 'git-pull-request',\n integrations: [INTEGRATIONS.github],\n model: 'haiku',\n color: 'gray',\n isRequired: false,\n version: '1.0.0'\n }\n};\n\n/**\n * Get all available sub-agents\n */\nexport function getAllSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS);\n}\n\n/**\n * Get sub-agent by role\n */\nexport function getSubAgent(role: string): SubAgentMetadata | undefined {\n return SUBAGENTS[role];\n}\n\n/**\n * Get integration by ID\n */\nexport function getIntegration(integrationId: string): SubAgentIntegration | undefined {\n return INTEGRATIONS[integrationId];\n}\n\n/**\n * Get required sub-agents (always included)\n */\nexport function getRequiredSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS).filter(agent => agent.isRequired);\n}\n\n/**\n * Get optional sub-agents (user can choose)\n */\nexport function getOptionalSubAgents(): SubAgentMetadata[] {\n return Object.values(SUBAGENTS).filter(agent => !agent.isRequired);\n}\n\n/**\n * Map integration ID to display name\n */\nexport function getIntegrationDisplayName(integrationId: string): string {\n return INTEGRATIONS[integrationId]?.name || integrationId;\n}\n\n/**\n * Get required integrations from a list of subagent roles\n */\nexport function getRequiredIntegrationsFromSubagents(roles: string[]): string[] {\n const integrations = new Set<string>();\n\n for (const role of roles) {\n const agent = SUBAGENTS[role];\n if (agent?.integrations) {\n agent.integrations.forEach(int => integrations.add(int.id));\n }\n }\n\n return Array.from(integrations);\n}\n"],"mappings":"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","names":[]}
@@ -167,20 +167,20 @@ Example structure:
167
167
  {
168
168
  inline: true,
169
169
  title: "Generate All Manual Test Case Files",
170
- content: `Generate ALL manual test case markdown files in \`./test-cases/\` BEFORE invoking the test-code-generator agent.
170
+ content: `Generate ALL manual test case markdown files in \`./test-cases/\` BEFORE invoking the test-engineer agent.
171
171
 
172
172
  Create files using \`TC-XXX-feature-description.md\` format. Follow the format of existing test cases in the directory. If no existing cases exist, include:
173
173
  - Frontmatter with test case metadata (id, title, type, area, \`automated: true/false\`, \`automated_test:\` empty)
174
174
  - Clear test steps with expected results
175
175
  - Required test data references (use env var names, not values)`
176
176
  },
177
- // Step 11: Automate Test Cases (inline - detailed instructions for test-code-generator)
177
+ // Step 11: Automate Test Cases (inline - detailed instructions for test-engineer)
178
178
  {
179
179
  inline: true,
180
180
  title: "Automate Test Cases Area by Area",
181
181
  content: `**IMPORTANT**: Process each feature area separately to enable incremental, focused test creation.
182
182
 
183
- **For each area**, invoke the test-code-generator agent:
183
+ **For each area**, invoke the test-engineer agent:
184
184
 
185
185
  **Prepare Area Context:**
186
186
  Before invoking the agent, identify the test cases for the current area:
@@ -192,9 +192,9 @@ Before invoking the agent, identify the test cases for the current area:
192
192
  - Existing automated tests in ./tests/specs/
193
193
  - Existing Page Objects in ./tests/pages/
194
194
 
195
- **Invoke test-code-generator Agent:**
195
+ **Invoke test-engineer Agent:**
196
196
 
197
- {{INVOKE_TEST_CODE_GENERATOR}} for the current area with the following context:
197
+ {{INVOKE_TEST_ENGINEER}} for the current area with the following context:
198
198
 
199
199
  "Automate test cases for the [AREA_NAME] area.
200
200
 
@@ -208,7 +208,7 @@ Before invoking the agent, identify the test cases for the current area:
208
208
  - Existing page objects: [directory from ./tests/CLAUDE.md]
209
209
 
210
210
  **Knowledge Base Patterns (MUST APPLY):**
211
- Include ALL relevant testing patterns from the knowledge base that apply to this area. For example, if the KB documents timing behaviors (animation delays, loading states), selector gotchas, or recommended assertion approaches \u2014 list them here explicitly and instruct the agent to use the specific patterns described (e.g., specific assertion methods with specific timeouts). The test-code-generator does not have access to the knowledge base, so you MUST relay the exact patterns and recommended code approaches.
211
+ Include ALL relevant testing patterns from the knowledge base that apply to this area. For example, if the KB documents timing behaviors (animation delays, loading states), selector gotchas, or recommended assertion approaches \u2014 list them here explicitly and instruct the agent to use the specific patterns described (e.g., specific assertion methods with specific timeouts). The test-engineer does not have access to the knowledge base, so you MUST relay the exact patterns and recommended code approaches.
212
212
 
213
213
  **The agent should:**
214
214
  1. Read the manual test case files for this area
@@ -267,7 +267,7 @@ Move to the next area and repeat until all areas are complete.
267
267
  content: `Provide a summary of created artifacts: manual test cases (count, IDs), automated tests (count, spec files), page objects and supporting files, coverage by area, and command to run tests (from \`./tests/CLAUDE.md\`).`
268
268
  }
269
269
  ],
270
- requiredSubagents: ["browser-automation", "test-code-generator"],
270
+ requiredSubagents: ["browser-automation", "test-engineer"],
271
271
  optionalSubagents: ["documentation-researcher", "team-communicator"],
272
272
  dependentTasks: []
273
273
  };
@@ -454,10 +454,10 @@ After saving the test plan:
454
454
  var handleMessageTask = {
455
455
  slug: TASK_SLUGS.HANDLE_MESSAGE,
456
456
  name: "Handle Message",
457
- description: "Handle team responses and Slack communications, maintaining context for ongoing conversations (LLM-routed)",
457
+ description: "Handle team messages, maintaining context for ongoing conversations",
458
458
  frontmatter: {
459
- description: "Handle team responses and Slack communications, maintaining context for ongoing conversations",
460
- "argument-hint": "[slack thread context or team message]"
459
+ description: "Handle team messages, maintaining context for ongoing conversations",
460
+ "argument-hint": "[team thread context or message]"
461
461
  },
462
462
  steps: [
463
463
  // Step 1: Overview (inline)
@@ -466,7 +466,7 @@ var handleMessageTask = {
466
466
  title: "Handle Message Overview",
467
467
  content: `# Handle Message Command
468
468
 
469
- Process team responses from Slack threads and handle multi-turn conversations with the product team about testing clarifications, ambiguities, and questions.`
469
+ Process team messages and handle multi-turn conversations with the product team about testing clarifications, ambiguities, and questions.`
470
470
  },
471
471
  // Step 2: Security Notice (library)
472
472
  "security-notice",
@@ -480,19 +480,19 @@ Process team responses from Slack threads and handle multi-turn conversations wi
480
480
  "load-project-context",
481
481
  // Step 5: Knowledge Base Read (library)
482
482
  "read-knowledge-base",
483
- // Step 5: Detect Intent (inline - task-specific)
483
+ // Step 6: Detect Intent (inline - simplified, no handler file loading)
484
484
  {
485
485
  inline: true,
486
- title: "Detect Message Intent and Load Handler",
487
- content: `Before processing the message, identify the intent type to load the appropriate handler.
486
+ title: "Detect Message Intent",
487
+ content: `Identify the intent type from the event payload or message patterns:
488
488
 
489
- #### 0.1 Extract Intent from Event Payload
489
+ #### Extract Intent from Event Payload
490
490
 
491
491
  Check the event payload for the \`intent\` field provided by the LLM layer:
492
492
  - If \`intent\` is present, use it directly
493
493
  - Valid intent values: \`question\`, \`feedback\`, \`status\`
494
494
 
495
- #### 0.2 Fallback Intent Detection (if no intent provided)
495
+ #### Fallback Intent Detection (if no intent provided)
496
496
 
497
497
  If intent is not in the payload, detect from message patterns:
498
498
 
@@ -503,39 +503,125 @@ If intent is not in the payload, detect from message patterns:
503
503
  | Question words: "what", "which", "do we have", "is there" about tests/project | \`question\` |
504
504
  | Default (none of above) | \`feedback\` |
505
505
 
506
- #### 0.3 Load Handler File
506
+ Then follow the matching handler section below.`
507
+ },
508
+ // Step 7: Process by Intent (all three handlers consolidated)
509
+ {
510
+ inline: true,
511
+ title: "Process Message by Intent",
512
+ content: `Based on the detected intent, follow the appropriate section:
513
+
514
+ ---
515
+
516
+ ## If intent = "feedback"
517
+
518
+ ### Step 1: Parse Feedback
519
+
520
+ Extract the following from the message:
521
+
522
+ | Field | Description |
523
+ |-------|-------------|
524
+ | **Type** | \`bug_report\`, \`test_result\`, \`observation\`, \`suggestion\`, \`general\` |
525
+ | **Severity** | \`critical\`, \`high\`, \`medium\`, \`low\` |
526
+ | **Component** | Affected area (e.g., "login", "checkout") |
527
+ | **Description** | Core issue description |
528
+ | **Expected** | What should happen (if stated) |
529
+ | **Steps** | How to reproduce (if provided) |
530
+
531
+ **Type Detection**:
532
+ - \`bug_report\`: "bug", "broken", "doesn't work", "error", "crash"
533
+ - \`test_result\`: "test passed", "test failed", "ran tests", "testing showed"
534
+ - \`observation\`: "noticed", "observed", "found that", "saw that"
535
+ - \`suggestion\`: "should", "could we", "what if", "idea"
536
+ - \`general\`: Default for unclassified feedback
537
+
538
+ ### Step 2: Update Test Case Specifications
539
+
540
+ **CRITICAL**: When feedback requests changes to test behavior (e.g., "change the expected result", "update the test to check for X", "the test should verify Y instead"), you MUST update the test case markdown files to reflect the requested changes.
541
+
542
+ For each actionable feedback item:
543
+ 1. Identify which test case(s) are affected
544
+ 2. Read the test case markdown file
545
+ 3. Update the test steps, expected results, or assertions as requested
546
+ 4. Save the modified test case file
547
+
548
+ This step updates the **specification** (markdown test case files) only. The \`sync-automation-from-feedback\` step that follows handles syncing the **implementation** (automation code) to match.
549
+
550
+ ### Step 3: Acknowledge and Confirm
551
+
552
+ Respond confirming: feedback received, summary of what was captured, actions taken (including any test case updates), and follow-up questions if needed.
553
+
554
+ ---
555
+
556
+ ## If intent = "question"
557
+
558
+ ### Step 1: Classify Question Type
559
+
560
+ | Type | Indicators | Primary Context Sources |
561
+ |------|------------|------------------------|
562
+ | **Coverage** | "what tests", "do we have", "is there a test for" | test-cases/, test-plan.md |
563
+ | **Results** | "did tests pass", "what failed", "test results" | test-runs/ |
564
+ | **Knowledge** | "how does", "what is", "explain" | knowledge-base.md |
565
+ | **Plan** | "what's in scope", "test plan", "testing strategy" | test-plan.md |
566
+ | **Process** | "how do I", "when should", "what's the workflow" | project-context.md |
567
+
568
+ ### Step 2: Load Relevant Context
507
569
 
508
- Based on detected intent, load the handler from:
509
- \`.bugzy/runtime/handlers/messages/{intent}.md\`
570
+ Based on question type, load the appropriate files:
571
+ - **Coverage**: Read test-plan.md, list ./test-cases/, search for relevant keywords
572
+ - **Results**: List ./test-runs/ (newest first), read summary.json from relevant runs
573
+ - **Knowledge**: Read .bugzy/runtime/knowledge-base.md, search for relevant entries
574
+ - **Plan**: Read test-plan.md, extract relevant sections
575
+ - **Process**: Read .bugzy/runtime/project-context.md
510
576
 
511
- **Handler files:**
512
- - \`question.md\` - Questions about tests, coverage, project details
513
- - \`feedback.md\` - Bug reports, test observations, general information
514
- - \`status.md\` - Status checks on test runs, task progress
577
+ ### Step 3: Formulate Answer
515
578
 
516
- #### 0.4 Follow Handler Instructions
579
+ - Be specific: quote relevant sections from source files
580
+ - Cite sources: mention which files contain the information
581
+ - Quantify when possible: "We have 12 test cases covering login..."
582
+ - Acknowledge gaps if information is incomplete
583
+
584
+ ### Step 4: Offer Follow-up
585
+
586
+ End response with offer to provide more detail and suggest related information.
587
+
588
+ ---
517
589
 
518
- **IMPORTANT**: The handler file is authoritative for this intent type.
590
+ ## If intent = "status"
519
591
 
520
- 1. Read the handler file completely
521
- 2. Follow its processing steps in order
522
- 3. Apply its context loading requirements
523
- 4. Use its response guidelines
524
- 5. Perform any memory updates it specifies
592
+ ### Step 1: Identify Status Scope
525
593
 
526
- The handler file contains all necessary processing logic for the detected intent type. Each handler includes:
527
- - Specific processing steps for that intent
528
- - Context loading requirements
529
- - Response guidelines
530
- - Memory update instructions`
594
+ | Scope | Indicators | Data Sources |
595
+ |-------|------------|--------------|
596
+ | **Latest test run** | "last run", "recent tests", "how did tests go" | Most recent test-runs/ directory |
597
+ | **Specific test** | Test ID mentioned (TC-XXX) | test-runs/*/TC-XXX/, test-cases/TC-XXX.md |
598
+ | **Overall** | "overall", "all tests", "pass rate" | All test-runs/ summaries |
599
+ | **Task progress** | "is the task done", "what's happening with" | team-communicator memory |
600
+
601
+ ### Step 2: Gather Status Data
602
+
603
+ Based on scope, read the appropriate test-runs/ directories and summary files. Calculate aggregate statistics for overall status requests.
604
+
605
+ ### Step 3: Format Status Report
606
+
607
+ Present status clearly: lead with pass/fail summary, use bullet points, include timestamps, offer to drill down into specifics.
608
+
609
+ ### Step 4: Provide Context and Recommendations
610
+
611
+ For failing tests: suggest review, note if new or recurring. For declining trends: highlight causes. For good results: acknowledge healthy state.`
612
+ },
613
+ // Step 8: Sync automation from feedback (conditional on test-engineer)
614
+ {
615
+ stepId: "sync-automation-from-feedback",
616
+ conditionalOnSubagent: "test-engineer"
531
617
  },
532
- // Step 6: Post Response via Team Communicator
618
+ // Step 9: Post Response via Team Communicator
533
619
  {
534
620
  inline: true,
535
621
  title: "Post Response to Team",
536
622
  content: `## Post Response to the Team
537
623
 
538
- After processing the message through the handler and composing your response:
624
+ After processing the message and composing your response:
539
625
 
540
626
  {{INVOKE_TEAM_COMMUNICATOR}} to post the response back to the team.
541
627
 
@@ -550,13 +636,13 @@ After processing the message through the handler and composing your response:
550
636
  - Ask the user whether to post \u2014 the message came from the team, the response goes back to the team
551
637
  - Compose a draft without sending it`
552
638
  },
553
- // Step 7: Clarification Protocol (for ambiguous intents)
639
+ // Step 10: Clarification Protocol (for ambiguous intents)
554
640
  "clarification-protocol",
555
- // Step 8: Knowledge Base Update (library)
641
+ // Step 11: Knowledge Base Update (library)
556
642
  "update-knowledge-base"
557
643
  ],
558
644
  requiredSubagents: ["team-communicator"],
559
- optionalSubagents: [],
645
+ optionalSubagents: ["test-engineer"],
560
646
  dependentTasks: ["verify-changes"]
561
647
  };
562
648
 
@@ -1156,7 +1242,7 @@ If selected test cases have formatting issues:
1156
1242
 
1157
1243
  **Failure Handling**:
1158
1244
  - Test failures are automatically triaged (product bugs vs test issues)
1159
- - Test issues are automatically fixed by the test-debugger-fixer subagent
1245
+ - Test issues are automatically fixed by the test-engineer subagent
1160
1246
  - Product bugs are logged via issue tracker after triage
1161
1247
  - All results are analyzed for learning opportunities and team communication
1162
1248
  - Critical failures trigger immediate team notification
@@ -1173,7 +1259,7 @@ If selected test cases have formatting issues:
1173
1259
  conditionalOnSubagent: "team-communicator"
1174
1260
  }
1175
1261
  ],
1176
- requiredSubagents: ["browser-automation", "test-debugger-fixer"],
1262
+ requiredSubagents: ["browser-automation", "test-engineer"],
1177
1263
  optionalSubagents: ["issue-tracker", "team-communicator"],
1178
1264
  dependentTasks: []
1179
1265
  };
@@ -1453,7 +1539,7 @@ Generate summary of test selection based on description analysis:
1453
1539
  - **Execution strategy**: [smart selection | full suite | smoke tests | user-specified]
1454
1540
  \`\`\``
1455
1541
  },
1456
- // Step 7b: Create Tests for Coverage Gaps (conditional - test-code-generator)
1542
+ // Step 7b: Create Tests for Coverage Gaps (conditional - test-engineer)
1457
1543
  {
1458
1544
  inline: true,
1459
1545
  title: "Create Tests for Coverage Gaps",
@@ -1489,7 +1575,7 @@ If the Jira issue or PR references test accounts/data (e.g., TEST_PREMIUM_USER,
1489
1575
 
1490
1576
  ### Generate Automated Test Specs
1491
1577
 
1492
- {{INVOKE_TEST_CODE_GENERATOR}} to create automated test specs:
1578
+ {{INVOKE_TEST_ENGINEER}} to create automated test specs:
1493
1579
  - Read the manual test cases you just created
1494
1580
  - Explore the feature in the browser to discover selectors and flows
1495
1581
  - Create page objects in the directory specified by \`./tests/CLAUDE.md\`
@@ -1500,7 +1586,7 @@ If the Jira issue or PR references test accounts/data (e.g., TEST_PREMIUM_USER,
1500
1586
  ### If Tests Already Cover the Feature
1501
1587
 
1502
1588
  Skip this step \u2014 proceed directly to running existing tests.`,
1503
- conditionalOnSubagent: "test-code-generator"
1589
+ conditionalOnSubagent: "test-engineer"
1504
1590
  },
1505
1591
  // Step 8-11: Test Execution (library steps)
1506
1592
  "run-tests",
@@ -1689,8 +1775,8 @@ Post PR comment if GitHub context available.`,
1689
1775
  **If test execution fails:** report specific error, suggest troubleshooting, don't proceed with triage.`
1690
1776
  }
1691
1777
  ],
1692
- requiredSubagents: ["browser-automation", "test-debugger-fixer"],
1693
- optionalSubagents: ["documentation-researcher", "issue-tracker", "team-communicator", "changelog-historian", "test-code-generator"],
1778
+ requiredSubagents: ["browser-automation", "test-engineer"],
1779
+ optionalSubagents: ["documentation-researcher", "issue-tracker", "team-communicator", "changelog-historian"],
1694
1780
  dependentTasks: []
1695
1781
  };
1696
1782
 
@@ -1766,7 +1852,7 @@ This command orchestrates the complete test coverage workflow in a single execut
1766
1852
  },
1767
1853
  "generate-final-report"
1768
1854
  ],
1769
- requiredSubagents: ["browser-automation", "test-code-generator", "test-debugger-fixer"],
1855
+ requiredSubagents: ["browser-automation", "test-engineer"],
1770
1856
  optionalSubagents: ["documentation-researcher", "team-communicator", "issue-tracker"],
1771
1857
  dependentTasks: ["run-tests", "generate-test-cases"]
1772
1858
  };
@@ -1875,7 +1961,7 @@ This task is triggered automatically when test results are submitted to the Bugz
1875
1961
  "normalize-test-results",
1876
1962
  // Step 7: Triage Failures (existing library step)
1877
1963
  "triage-failures",
1878
- // Step 8: Fix Test Issues (library — uses test-debugger-fixer)
1964
+ // Step 8: Fix Test Issues (library — uses test-engineer)
1879
1965
  "fix-test-issues",
1880
1966
  // Step 9: Log Product Bugs (conditional — requires issue-tracker)
1881
1967
  {
@@ -1934,7 +2020,7 @@ Create a structured triage report as the task output. This report is stored in \
1934
2020
  Output this JSON as the final result of the task.`
1935
2021
  }
1936
2022
  ],
1937
- requiredSubagents: ["browser-automation", "test-debugger-fixer"],
2023
+ requiredSubagents: ["browser-automation", "test-engineer"],
1938
2024
  optionalSubagents: ["issue-tracker", "team-communicator"],
1939
2025
  dependentTasks: []
1940
2026
  };
@@ -1991,12 +2077,14 @@ This step helps correlate what the tests cover with what the application actuall
1991
2077
  {
1992
2078
  inline: true,
1993
2079
  title: "Commit Analysis Results",
1994
- content: `Commit all analysis artifacts to the project repository:
2080
+ content: `Commit analysis artifacts to the **parent project repository** (the workspace root).
1995
2081
 
1996
- 1. The test codebase analysis report (\`.bugzy/runtime/test-codebase-analysis.md\`)
1997
- 2. Any generated CLAUDE.md draft (if the external repo was missing one)
2082
+ **IMPORTANT \u2014 Do NOT stage the \`tests\` submodule.** The \`tests/\` directory is an external git submodule. Any changes made inside it (e.g., \`reporters/parse-results.ts\`, \`tests/CLAUDE.md\`) will be committed and pushed to the external repo automatically by the post-execution handler. Staging the submodule in the parent would record a local-only commit SHA that doesn't exist on the remote, causing a broken reference.
1998
2083
 
1999
- Use a clear commit message: "chore: analyze external test codebase"
2084
+ **What to commit in the parent repo:**
2085
+ 1. \`git add .bugzy/\` \u2014 the test codebase analysis report and runtime files
2086
+ 2. Do NOT run \`git add .\` or \`git add tests\` \u2014 this would stage the submodule pointer
2087
+ 3. \`git commit -m "chore: analyze external test codebase"\`
2000
2088
 
2001
2089
  These artifacts will be available to all future task executions for this project.`
2002
2090
  },