@bugzy-ai/bugzy 1.2.1 → 1.4.0

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.
@@ -568,7 +568,9 @@ Document all findings including:
568
568
  \`\`\`
569
569
 
570
570
  #### 3.2 Launch Test Runner Agent
571
- Invoke the test-runner agent with special exploration instructions:
571
+ {{INVOKE_TEST_RUNNER}}
572
+
573
+ Execute the exploration test case with special exploration instructions:
572
574
 
573
575
  \`\`\`
574
576
  Execute the exploration test case at ./test-cases/EXPLORATION-TEMP.md with focus on discovery and documentation.
@@ -1039,10 +1041,10 @@ Before invoking the agent, identify the test cases for the current area:
1039
1041
 
1040
1042
  #### Step 2.2: Invoke test-code-generator Agent
1041
1043
 
1042
- Use the test-code-generator agent for the current area with the following context:
1044
+ {{INVOKE_TEST_CODE_GENERATOR}} for the current area with the following context:
1043
1045
 
1044
1046
  **Agent Invocation:**
1045
- "Use the test-code-generator agent to automate test cases for the [AREA_NAME] area.
1047
+ "Automate test cases for the [AREA_NAME] area.
1046
1048
 
1047
1049
  **Context:**
1048
1050
  - Area: [AREA_NAME]
@@ -1182,10 +1184,10 @@ Provide a comprehensive summary showing:
1182
1184
  role: "documentation-researcher",
1183
1185
  contentBlock: `#### 1.4 Gather Product Documentation
1184
1186
 
1185
- Use the documentation-researcher agent to gather comprehensive product documentation:
1187
+ {{INVOKE_DOCUMENTATION_RESEARCHER}} to gather comprehensive product documentation:
1186
1188
 
1187
1189
  \`\`\`
1188
- Use the documentation-researcher agent to explore all available product documentation, specifically focusing on:
1190
+ Explore all available product documentation, specifically focusing on:
1189
1191
  - UI elements and workflows
1190
1192
  - User interactions and navigation paths
1191
1193
  - Form fields and validation rules
@@ -1199,10 +1201,9 @@ Use the documentation-researcher agent to explore all available product document
1199
1201
  role: "team-communicator",
1200
1202
  contentBlock: `### Step 4.5: Team Communication
1201
1203
 
1202
- Use the team-communicator agent to notify the product team about the new test cases and automated tests:
1204
+ {{INVOKE_TEAM_COMMUNICATOR}} to notify the product team about the new test cases and automated tests:
1203
1205
 
1204
1206
  \`\`\`
1205
- Use the team-communicator agent to:
1206
1207
  1. Post an update about test case and automation creation
1207
1208
  2. Provide summary of coverage:
1208
1209
  - Number of manual test cases created
@@ -1471,10 +1472,10 @@ Provide a summary of:
1471
1472
  role: "documentation-researcher",
1472
1473
  contentBlock: `### Step 2: Gather comprehensive project documentation
1473
1474
 
1474
- Use the documentation-researcher agent to explore and gather all available project information and other documentation sources. This ensures the test plan is based on complete and current information.
1475
+ {{INVOKE_DOCUMENTATION_RESEARCHER}} to explore and gather all available project information and other documentation sources. This ensures the test plan is based on complete and current information.
1475
1476
 
1476
1477
  \`\`\`
1477
- Use the documentation-researcher agent to explore all available project documentation related to: $ARGUMENTS
1478
+ Explore all available project documentation related to: $ARGUMENTS
1478
1479
 
1479
1480
  Specifically gather:
1480
1481
  - Product specifications and requirements
@@ -1499,10 +1500,9 @@ The agent will:
1499
1500
  role: "team-communicator",
1500
1501
  contentBlock: `### Step 7.5: Team Communication
1501
1502
 
1502
- Use the team-communicator agent to notify the product team about the new test plan:
1503
+ {{INVOKE_TEAM_COMMUNICATOR}} to notify the product team about the new test plan:
1503
1504
 
1504
1505
  \`\`\`
1505
- Use the team-communicator agent to:
1506
1506
  1. Post an update about the test plan creation
1507
1507
  2. Provide a brief summary of coverage areas and key features
1508
1508
  3. Mention any areas that need exploration or clarification
@@ -1755,7 +1755,7 @@ Classify the ambiguity level to determine appropriate response:
1755
1755
  #### Clarification Approach by Severity
1756
1756
 
1757
1757
  **For CRITICAL/HIGH ambiguity:**
1758
- 1. **Use team-communicator to ask specific questions**
1758
+ 1. **{{INVOKE_TEAM_COMMUNICATOR}} to ask specific questions**
1759
1759
  2. **WAIT for response before proceeding**
1760
1760
  3. **Document the clarification request in event history**
1761
1761
 
@@ -2028,7 +2028,7 @@ ${KNOWLEDGE_BASE_UPDATE_INSTRUCTIONS}`,
2028
2028
  contentBlock: `#### 3.3 Use Documentation Researcher if Needed
2029
2029
  For events mentioning unknown features or components:
2030
2030
  \`\`\`
2031
- Use documentation-researcher agent to find information about: [component/feature]
2031
+ {{INVOKE_DOCUMENTATION_RESEARCHER}} to find information about: [component/feature]
2032
2032
  \`\`\``
2033
2033
  },
2034
2034
  {
@@ -2037,7 +2037,7 @@ Use documentation-researcher agent to find information about: [component/feature
2037
2037
 
2038
2038
  When an issue needs to be tracked (task type: report_bug or update_story):
2039
2039
  \`\`\`
2040
- Use issue-tracker agent to:
2040
+ {{INVOKE_ISSUE_TRACKER}}
2041
2041
  1. Check for duplicate issues in the tracking system
2042
2042
  2. For bugs: Create detailed bug report with:
2043
2043
  - Clear, descriptive title
@@ -2315,7 +2315,7 @@ For each failed test:
2315
2315
  For each test classified as **[TEST ISSUE]**, use the test-debugger-fixer agent to automatically fix the test:
2316
2316
 
2317
2317
  \`\`\`
2318
- Use the test-debugger-fixer agent to fix test issues:
2318
+ {{INVOKE_TEST_DEBUGGER_FIXER}}
2319
2319
 
2320
2320
  For each failed test classified as a test issue (not a product bug), provide:
2321
2321
  - Test run timestamp: [from manifest.timestamp]
@@ -2410,7 +2410,7 @@ After triage in Step 5.1, for tests classified as **[PRODUCT BUG]**, use the iss
2410
2410
  For each bug to report, use the issue-tracker agent:
2411
2411
 
2412
2412
  \`\`\`
2413
- Use issue-tracker agent to:
2413
+ {{INVOKE_ISSUE_TRACKER}}
2414
2414
  1. Check for duplicate bugs in the tracking system
2415
2415
  - The agent will automatically search for similar existing issues
2416
2416
  - It maintains memory of recently reported issues
@@ -2481,10 +2481,11 @@ After issue tracker agent completes, create a summary:
2481
2481
  role: "team-communicator",
2482
2482
  contentBlock: `### Step 6: Team Communication
2483
2483
 
2484
- Use the team-communicator agent to notify the product team about test execution:
2484
+ {{INVOKE_TEAM_COMMUNICATOR}}
2485
+
2486
+ Notify the product team about test execution:
2485
2487
 
2486
2488
  \`\`\`
2487
- Use the team-communicator agent to:
2488
2489
  1. Post test execution summary with key statistics
2489
2490
  2. Highlight critical failures that need immediate attention
2490
2491
  3. Share important learnings about product behavior
@@ -2828,7 +2829,7 @@ Read and analyze the JSON report:
2828
2829
  For each test classified as **[TEST ISSUE]**, use the test-debugger-fixer agent to automatically fix the test:
2829
2830
 
2830
2831
  \`\`\`
2831
- Use the test-debugger-fixer agent to fix test issues:
2832
+ {{INVOKE_TEST_DEBUGGER_FIXER}}
2832
2833
 
2833
2834
  For each failed test classified as a test issue (not a product bug), provide:
2834
2835
  - Test file path: [from JSON report]
@@ -2869,7 +2870,7 @@ Classification guidelines:
2869
2870
  #### 4A.4 Fix Test Issues Automatically
2870
2871
 
2871
2872
  For tests classified as [TEST ISSUE]:
2872
- - Use test-debugger-fixer agent to analyze and fix
2873
+ - {{INVOKE_TEST_DEBUGGER_FIXER}} to analyze and fix
2873
2874
  - Agent debugs with browser if needed
2874
2875
  - Applies fix (selector update, wait condition, assertion correction)
2875
2876
  - Reruns test to verify fix (10x for flaky tests)
@@ -2885,7 +2886,7 @@ Track fixed tests with:
2885
2886
  {{ISSUE_TRACKER_INSTRUCTIONS}}
2886
2887
 
2887
2888
  For tests classified as [PRODUCT BUG]:
2888
- - Use issue-tracker agent to create bug reports
2889
+ - {{INVOKE_ISSUE_TRACKER}} to create bug reports
2889
2890
  - Agent checks for duplicates automatically
2890
2891
  - Creates detailed report with:
2891
2892
  - Title, description, reproduction steps
@@ -3201,10 +3202,10 @@ Format as comprehensive markdown report for terminal display:
3201
3202
 
3202
3203
  {{TEAM_COMMUNICATOR_INSTRUCTIONS}}
3203
3204
 
3204
- Use team-communicator agent to post concise results to Slack thread:
3205
+ {{INVOKE_TEAM_COMMUNICATOR}} to post concise results to Slack thread:
3205
3206
 
3206
3207
  \`\`\`
3207
- Use the team-communicator agent to post verification results.
3208
+ Post verification results.
3208
3209
 
3209
3210
  **Channel**: [from CHANGE_CONTEXT.slackChannel]
3210
3211
  **Thread**: [from CHANGE_CONTEXT.slackThread]
@@ -3385,10 +3386,10 @@ A successful verification includes:
3385
3386
  role: "documentation-researcher",
3386
3387
  contentBlock: `#### Research Project Documentation
3387
3388
 
3388
- Use the documentation-researcher agent to gather comprehensive context about the changed features:
3389
+ {{INVOKE_DOCUMENTATION_RESEARCHER}} to gather comprehensive context about the changed features:
3389
3390
 
3390
3391
  \`\`\`
3391
- Use the documentation-researcher agent to explore project documentation related to the changes.
3392
+ Explore project documentation related to the changes.
3392
3393
 
3393
3394
  Specifically gather:
3394
3395
  - Product specifications for affected features
@@ -3420,10 +3421,9 @@ Use this information to:
3420
3421
  role: "issue-tracker",
3421
3422
  contentBlock: `#### Log Product Bugs
3422
3423
 
3423
- For tests classified as **[PRODUCT BUG]**, use the issue-tracker agent to log bugs:
3424
+ For tests classified as **[PRODUCT BUG]**, {{INVOKE_ISSUE_TRACKER}} to log bugs:
3424
3425
 
3425
3426
  \`\`\`
3426
- Use issue-tracker agent to:
3427
3427
  1. Check for duplicate bugs in the tracking system
3428
3428
  - The agent will automatically search for similar existing issues
3429
3429
  - It maintains memory of recently reported issues
@@ -3472,10 +3472,9 @@ Use issue-tracker agent to:
3472
3472
  role: "team-communicator",
3473
3473
  contentBlock: `#### Team Communication
3474
3474
 
3475
- Use the team-communicator agent to share verification results (primarily for Slack trigger, but can be used for other triggers):
3475
+ {{INVOKE_TEAM_COMMUNICATOR}} to share verification results (primarily for Slack trigger, but can be used for other triggers):
3476
3476
 
3477
3477
  \`\`\`
3478
- Use the team-communicator agent to:
3479
3478
  1. Post verification results summary
3480
3479
  2. Highlight critical failures that need immediate attention
3481
3480
  3. Share bugs logged with issue tracker links
@@ -3605,6 +3604,7 @@ var import_chalk3 = __toESM(require("chalk"), 1);
3605
3604
  // src/cli/commands/start.ts
3606
3605
  init_cjs_shims();
3607
3606
  var import_child_process = require("child_process");
3607
+ var path4 = __toESM(require("path"), 1);
3608
3608
  var import_chalk = __toESM(require("chalk"), 1);
3609
3609
  var import_ora = __toESM(require("ora"), 1);
3610
3610
 
@@ -3612,6 +3612,97 @@ var import_ora = __toESM(require("ora"), 1);
3612
3612
  init_cjs_shims();
3613
3613
  var fs = __toESM(require("fs"), 1);
3614
3614
  var path = __toESM(require("path"), 1);
3615
+
3616
+ // src/core/tool-profile.ts
3617
+ init_cjs_shims();
3618
+ var DEFAULT_TOOL = "claude-code";
3619
+ var CLAUDE_CODE_PROFILE = {
3620
+ id: "claude-code",
3621
+ name: "Claude Code",
3622
+ cliCommand: "claude",
3623
+ commandsDir: ".claude/commands",
3624
+ agentsDir: ".claude/agents",
3625
+ mcpConfigPath: ".mcp.json",
3626
+ mcpFormat: "json",
3627
+ memoryFile: "CLAUDE.md",
3628
+ commandFrontmatter: true,
3629
+ agentFrontmatter: true,
3630
+ commandInvocationPrefix: "/",
3631
+ commandExtension: ".md",
3632
+ agentExtension: ".md"
3633
+ };
3634
+ var CURSOR_PROFILE = {
3635
+ id: "cursor",
3636
+ name: "Cursor",
3637
+ cliCommand: "cursor-agent",
3638
+ commandsDir: ".cursor/commands",
3639
+ agentsDir: ".cursor/agents",
3640
+ mcpConfigPath: ".cursor/mcp.json",
3641
+ mcpFormat: "json",
3642
+ memoryFile: "AGENTS.md",
3643
+ // Cursor now uses AGENTS.md (.cursorrules deprecated as of v0.45+)
3644
+ commandFrontmatter: false,
3645
+ // Cursor uses plain markdown
3646
+ agentFrontmatter: false,
3647
+ // Agent files are plain markdown for CLI invocation
3648
+ commandInvocationPrefix: "/",
3649
+ commandExtension: ".md",
3650
+ agentExtension: ".md"
3651
+ };
3652
+ var CODEX_PROFILE = {
3653
+ id: "codex",
3654
+ name: "Codex CLI",
3655
+ cliCommand: "codex",
3656
+ commandsDir: ".codex/prompts",
3657
+ // Codex uses prompts directory
3658
+ agentsDir: ".codex/agents",
3659
+ mcpConfigPath: ".codex/config.toml",
3660
+ // Project-local via CODEX_HOME
3661
+ mcpFormat: "toml",
3662
+ homeEnvVar: "CODEX_HOME",
3663
+ // Set to project root for project-local config
3664
+ memoryFile: "AGENTS.md",
3665
+ commandFrontmatter: true,
3666
+ // Codex prompts support frontmatter
3667
+ agentFrontmatter: false,
3668
+ // Agent files are plain markdown for CLI invocation
3669
+ commandInvocationPrefix: "/prompts:",
3670
+ commandExtension: ".md",
3671
+ agentExtension: ".md"
3672
+ };
3673
+ var TOOL_PROFILES = {
3674
+ "claude-code": CLAUDE_CODE_PROFILE,
3675
+ "cursor": CURSOR_PROFILE,
3676
+ "codex": CODEX_PROFILE
3677
+ };
3678
+ function getToolProfile(toolId) {
3679
+ const profile = TOOL_PROFILES[toolId];
3680
+ if (!profile) {
3681
+ throw new Error(`Unknown tool: ${toolId}`);
3682
+ }
3683
+ return profile;
3684
+ }
3685
+ function getToolOptions() {
3686
+ return [
3687
+ {
3688
+ value: "claude-code",
3689
+ label: "Claude Code (CLI or Cloud)",
3690
+ hint: "Anthropic's official CLI - recommended"
3691
+ },
3692
+ {
3693
+ value: "cursor",
3694
+ label: "Cursor (Experimental)",
3695
+ hint: "VS Code-based AI editor - experimental support"
3696
+ },
3697
+ {
3698
+ value: "codex",
3699
+ label: "Codex CLI (Experimental)",
3700
+ hint: "OpenAI's terminal-based agent - experimental support"
3701
+ }
3702
+ ];
3703
+ }
3704
+
3705
+ // src/cli/utils/config.ts
3615
3706
  async function loadConfig(configPath = ".bugzy/config.json") {
3616
3707
  const fullPath = path.join(process.cwd(), configPath);
3617
3708
  if (!fs.existsSync(fullPath)) {
@@ -3620,6 +3711,9 @@ async function loadConfig(configPath = ".bugzy/config.json") {
3620
3711
  try {
3621
3712
  const content = fs.readFileSync(fullPath, "utf-8");
3622
3713
  const config = JSON.parse(content);
3714
+ if (!config.tool) {
3715
+ config.tool = DEFAULT_TOOL;
3716
+ }
3623
3717
  return config;
3624
3718
  } catch (error) {
3625
3719
  console.error(`Error loading config from ${fullPath}:`, error);
@@ -3644,15 +3738,19 @@ function configExists(configPath = ".bugzy/config.json") {
3644
3738
  const fullPath = path.join(process.cwd(), configPath);
3645
3739
  return fs.existsSync(fullPath);
3646
3740
  }
3647
- function createDefaultConfig(projectName) {
3741
+ function createDefaultConfig(projectName, tool = DEFAULT_TOOL) {
3648
3742
  return {
3649
3743
  version: "1.0.0",
3744
+ tool,
3650
3745
  project: {
3651
3746
  name: projectName
3652
3747
  },
3653
3748
  subagents: {}
3654
3749
  };
3655
3750
  }
3751
+ function getToolFromConfig(config) {
3752
+ return config.tool || DEFAULT_TOOL;
3753
+ }
3656
3754
 
3657
3755
  // src/cli/utils/env.ts
3658
3756
  init_cjs_shims();
@@ -3715,13 +3813,19 @@ function validateEnvVars(mcpServers, envVars) {
3715
3813
  init_cjs_shims();
3716
3814
  var fs3 = __toESM(require("fs"), 1);
3717
3815
  var path3 = __toESM(require("path"), 1);
3718
- function validateProjectStructure() {
3816
+ async function validateProjectStructure() {
3817
+ const config = await loadConfig();
3818
+ const tool = config ? getToolFromConfig(config) : DEFAULT_TOOL;
3819
+ const toolProfile = getToolProfile(tool);
3719
3820
  const requiredDirs = [
3720
3821
  ".bugzy",
3721
3822
  ".bugzy/runtime",
3722
- ".claude",
3723
- ".claude/commands",
3724
- ".claude/agents"
3823
+ path3.dirname(toolProfile.commandsDir),
3824
+ // .claude, .cursor, or .codex
3825
+ toolProfile.commandsDir,
3826
+ // .claude/commands, .cursor/commands, .codex/prompts
3827
+ toolProfile.agentsDir
3828
+ // .claude/agents, .cursor/agents, .codex/agents
3725
3829
  ];
3726
3830
  const requiredFiles = [
3727
3831
  ".bugzy/config.json",
@@ -3747,15 +3851,24 @@ function validateProjectStructure() {
3747
3851
  }
3748
3852
  return true;
3749
3853
  }
3750
- async function checkClaudeAvailable() {
3854
+ async function checkToolAvailable(command) {
3751
3855
  const { spawn: spawn2 } = await import("child_process");
3856
+ const isWindows = process.platform === "win32";
3857
+ const checkCommand = isWindows ? "where" : "which";
3752
3858
  return new Promise((resolve) => {
3753
- const proc = spawn2("which", ["claude"]);
3859
+ const proc = spawn2(checkCommand, [command], {
3860
+ shell: isWindows
3861
+ // Windows needs shell for 'where'
3862
+ });
3754
3863
  proc.on("close", (code) => {
3755
- resolve(code === 0);
3864
+ if (code !== 0) {
3865
+ console.warn(`Warning: Could not verify '${command}' is installed (${checkCommand} check failed). Continuing anyway...`);
3866
+ }
3867
+ resolve(true);
3756
3868
  });
3757
3869
  proc.on("error", () => {
3758
- resolve(false);
3870
+ console.warn(`Warning: Could not verify '${command}' is installed (${checkCommand} not available). Continuing anyway...`);
3871
+ resolve(true);
3759
3872
  });
3760
3873
  });
3761
3874
  }
@@ -3795,9 +3908,11 @@ async function startSession(prompt) {
3795
3908
  process.exit(1);
3796
3909
  }
3797
3910
  spinner.succeed(import_chalk.default.green("Configuration loaded"));
3911
+ const tool = getToolFromConfig(config);
3912
+ const toolProfile = getToolProfile(tool);
3798
3913
  spinner = (0, import_ora.default)("Validating project structure").start();
3799
3914
  try {
3800
- validateProjectStructure();
3915
+ await validateProjectStructure();
3801
3916
  spinner.succeed(import_chalk.default.green("Project structure validated"));
3802
3917
  } catch (error) {
3803
3918
  spinner.fail(import_chalk.default.red("Invalid project structure"));
@@ -3805,15 +3920,9 @@ async function startSession(prompt) {
3805
3920
  console.log(import_chalk.default.yellow("\nRun"), import_chalk.default.cyan("bugzy setup"), import_chalk.default.yellow("to fix the project structure"));
3806
3921
  process.exit(1);
3807
3922
  }
3808
- spinner = (0, import_ora.default)("Checking Claude Code availability").start();
3809
- const claudeAvailable = await checkClaudeAvailable();
3810
- if (!claudeAvailable) {
3811
- spinner.fail(import_chalk.default.red("Claude Code CLI not found"));
3812
- console.log(import_chalk.default.yellow("\nPlease install Claude Code:"));
3813
- console.log(import_chalk.default.cyan(" https://claude.com/claude-code"));
3814
- process.exit(1);
3815
- }
3816
- spinner.succeed(import_chalk.default.green("Claude Code CLI found"));
3923
+ spinner = (0, import_ora.default)(`Checking ${toolProfile.name} availability`).start();
3924
+ await checkToolAvailable(toolProfile.cliCommand);
3925
+ spinner.succeed(import_chalk.default.green(`${toolProfile.name} CLI check complete`));
3817
3926
  spinner = (0, import_ora.default)("Loading environment variables").start();
3818
3927
  const envVars = loadEnvFiles();
3819
3928
  const envCount = Object.keys(envVars).length;
@@ -3831,14 +3940,20 @@ async function startSession(prompt) {
3831
3940
  process.exit(1);
3832
3941
  }
3833
3942
  spinner.succeed(import_chalk.default.green("All required MCP secrets present"));
3834
- console.log(import_chalk.default.green.bold("\n\u{1F680} Launching Claude Code...\n"));
3943
+ console.log(import_chalk.default.green.bold(`
3944
+ \u{1F680} Launching ${toolProfile.name}...
3945
+ `));
3835
3946
  const args = prompt ? [prompt] : [];
3836
- const claude = (0, import_child_process.spawn)("claude", args, {
3947
+ const spawnEnv = { ...process.env, ...envVars };
3948
+ if (toolProfile.homeEnvVar) {
3949
+ spawnEnv[toolProfile.homeEnvVar] = path4.join(process.cwd(), ".codex");
3950
+ }
3951
+ const child = (0, import_child_process.spawn)(toolProfile.cliCommand, args, {
3837
3952
  cwd: process.cwd(),
3838
- env: { ...process.env, ...envVars },
3953
+ env: spawnEnv,
3839
3954
  stdio: "inherit"
3840
3955
  });
3841
- claude.on("close", (code) => {
3956
+ child.on("close", (code) => {
3842
3957
  if (code === 0) {
3843
3958
  console.log(import_chalk.default.green("\n\u2713 Session ended successfully"));
3844
3959
  } else {
@@ -3846,15 +3961,16 @@ async function startSession(prompt) {
3846
3961
  \u2713 Session ended (exit code: ${code})`));
3847
3962
  }
3848
3963
  });
3849
- claude.on("error", (error) => {
3850
- console.error(import_chalk.default.red("\n\u2717 Error launching Claude Code:"), error);
3964
+ child.on("error", (error) => {
3965
+ console.error(import_chalk.default.red(`
3966
+ \u2717 Error launching ${toolProfile.name}:`), error);
3851
3967
  process.exit(1);
3852
3968
  });
3853
3969
  }
3854
3970
 
3855
3971
  // src/cli/commands/setup.ts
3856
3972
  init_cjs_shims();
3857
- var path10 = __toESM(require("path"), 1);
3973
+ var path11 = __toESM(require("path"), 1);
3858
3974
  var import_chalk2 = __toESM(require("chalk"), 1);
3859
3975
  var import_inquirer = __toESM(require("inquirer"), 1);
3860
3976
  var import_ora2 = __toESM(require("ora"), 1);
@@ -6421,8 +6537,8 @@ var SUBAGENTS = {
6421
6537
  description: "Automatically create and track bugs and issues",
6422
6538
  icon: "bot",
6423
6539
  integrations: [
6424
- INTEGRATIONS.linear,
6425
- INTEGRATIONS.jira,
6540
+ // INTEGRATIONS.linear,
6541
+ // INTEGRATIONS.jira,
6426
6542
  INTEGRATIONS["jira-server"],
6427
6543
  INTEGRATIONS.notion,
6428
6544
  INTEGRATIONS.slack
@@ -6436,7 +6552,10 @@ var SUBAGENTS = {
6436
6552
  name: "Documentation Researcher",
6437
6553
  description: "Search and retrieve information from your documentation",
6438
6554
  icon: "file-search",
6439
- integrations: [INTEGRATIONS.notion, INTEGRATIONS.confluence],
6555
+ integrations: [
6556
+ INTEGRATIONS.notion
6557
+ // INTEGRATIONS.confluence
6558
+ ],
6440
6559
  model: "sonnet",
6441
6560
  color: "cyan",
6442
6561
  version: "1.0.0"
@@ -6489,27 +6608,31 @@ function buildSubagentConfig(role, integration) {
6489
6608
  // src/cli/generators/structure.ts
6490
6609
  init_cjs_shims();
6491
6610
  var fs4 = __toESM(require("fs"), 1);
6492
- var path4 = __toESM(require("path"), 1);
6493
- async function createProjectStructure() {
6611
+ var path5 = __toESM(require("path"), 1);
6612
+ async function createProjectStructure(tool = DEFAULT_TOOL) {
6494
6613
  const cwd = process.cwd();
6614
+ const toolProfile = getToolProfile(tool);
6495
6615
  const bugzyDirs = [
6496
6616
  ".bugzy",
6497
6617
  ".bugzy/runtime",
6498
6618
  ".bugzy/runtime/templates"
6499
6619
  ];
6500
6620
  for (const dir of bugzyDirs) {
6501
- const dirPath = path4.join(cwd, dir);
6621
+ const dirPath = path5.join(cwd, dir);
6502
6622
  if (!fs4.existsSync(dirPath)) {
6503
6623
  fs4.mkdirSync(dirPath, { recursive: true });
6504
6624
  }
6505
6625
  }
6506
- const claudeDirs = [
6507
- ".claude",
6508
- ".claude/commands",
6509
- ".claude/agents"
6626
+ const toolDirs = [
6627
+ path5.dirname(toolProfile.commandsDir),
6628
+ // .claude, .cursor, or .codex
6629
+ toolProfile.commandsDir,
6630
+ // .claude/commands, .cursor/commands, .codex/prompts
6631
+ toolProfile.agentsDir
6632
+ // .claude/agents, .cursor/agents, .codex/agents
6510
6633
  ];
6511
- for (const dir of claudeDirs) {
6512
- const dirPath = path4.join(cwd, dir);
6634
+ for (const dir of toolDirs) {
6635
+ const dirPath = path5.join(cwd, dir);
6513
6636
  if (!fs4.existsSync(dirPath)) {
6514
6637
  fs4.mkdirSync(dirPath, { recursive: true });
6515
6638
  }
@@ -6517,69 +6640,69 @@ async function createProjectStructure() {
6517
6640
  await createRuntimeFiles();
6518
6641
  }
6519
6642
  function getTemplatesDir() {
6520
- return path4.join(__dirname, "../../templates/init");
6643
+ return path5.join(__dirname, "../../templates/init");
6521
6644
  }
6522
6645
  async function createRuntimeFiles() {
6523
6646
  const cwd = process.cwd();
6524
6647
  const templatesDir = getTemplatesDir();
6525
- const projectContextPath = path4.join(cwd, ".bugzy/runtime/project-context.md");
6648
+ const projectContextPath = path5.join(cwd, ".bugzy/runtime/project-context.md");
6526
6649
  if (!fs4.existsSync(projectContextPath)) {
6527
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/project-context.md");
6650
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/project-context.md");
6528
6651
  let content = fs4.readFileSync(templatePath, "utf-8");
6529
- const projectName = path4.basename(cwd);
6652
+ const projectName = path5.basename(cwd);
6530
6653
  content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
6531
6654
  content = content.replace(/\{\{CUSTOMER_NAME\}\}/g, "[To be filled]");
6532
6655
  content = content.replace(/\{\{BUG_TRACKING_SYSTEM\}\}/g, "[To be filled]");
6533
6656
  content = content.replace(/\{\{DOCUMENTATION_SYSTEM\}\}/g, "[To be filled]");
6534
6657
  fs4.writeFileSync(projectContextPath, content, "utf-8");
6535
6658
  }
6536
- const testPlanTemplatePath = path4.join(cwd, ".bugzy/runtime/templates/test-plan-template.md");
6659
+ const testPlanTemplatePath = path5.join(cwd, ".bugzy/runtime/templates/test-plan-template.md");
6537
6660
  if (!fs4.existsSync(testPlanTemplatePath)) {
6538
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/templates/test-plan-template.md");
6661
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/templates/test-plan-template.md");
6539
6662
  const content = fs4.readFileSync(templatePath, "utf-8");
6540
6663
  fs4.writeFileSync(testPlanTemplatePath, content, "utf-8");
6541
6664
  }
6542
- const bestPracticesPath = path4.join(cwd, ".bugzy/runtime/testing-best-practices.md");
6665
+ const bestPracticesPath = path5.join(cwd, ".bugzy/runtime/testing-best-practices.md");
6543
6666
  if (!fs4.existsSync(bestPracticesPath)) {
6544
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/testing-best-practices.md");
6667
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/testing-best-practices.md");
6545
6668
  const content = fs4.readFileSync(templatePath, "utf-8");
6546
6669
  fs4.writeFileSync(bestPracticesPath, content, "utf-8");
6547
6670
  }
6548
- const testResultSchemaPath = path4.join(cwd, ".bugzy/runtime/templates/test-result-schema.md");
6671
+ const testResultSchemaPath = path5.join(cwd, ".bugzy/runtime/templates/test-result-schema.md");
6549
6672
  if (!fs4.existsSync(testResultSchemaPath)) {
6550
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/templates/test-result-schema.md");
6673
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/templates/test-result-schema.md");
6551
6674
  if (fs4.existsSync(templatePath)) {
6552
6675
  const content = fs4.readFileSync(templatePath, "utf-8");
6553
6676
  fs4.writeFileSync(testResultSchemaPath, content, "utf-8");
6554
6677
  }
6555
6678
  }
6556
- const knowledgeBasePath = path4.join(cwd, ".bugzy/runtime/knowledge-base.md");
6679
+ const knowledgeBasePath = path5.join(cwd, ".bugzy/runtime/knowledge-base.md");
6557
6680
  if (!fs4.existsSync(knowledgeBasePath)) {
6558
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/knowledge-base.md");
6681
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/knowledge-base.md");
6559
6682
  if (fs4.existsSync(templatePath)) {
6560
6683
  const content = fs4.readFileSync(templatePath, "utf-8");
6561
6684
  fs4.writeFileSync(knowledgeBasePath, content, "utf-8");
6562
6685
  }
6563
6686
  }
6564
- const knowledgeMaintenancePath = path4.join(cwd, ".bugzy/runtime/knowledge-maintenance-guide.md");
6687
+ const knowledgeMaintenancePath = path5.join(cwd, ".bugzy/runtime/knowledge-maintenance-guide.md");
6565
6688
  if (!fs4.existsSync(knowledgeMaintenancePath)) {
6566
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/knowledge-maintenance-guide.md");
6689
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/knowledge-maintenance-guide.md");
6567
6690
  if (fs4.existsSync(templatePath)) {
6568
6691
  const content = fs4.readFileSync(templatePath, "utf-8");
6569
6692
  fs4.writeFileSync(knowledgeMaintenancePath, content, "utf-8");
6570
6693
  }
6571
6694
  }
6572
- const subagentMemoryPath = path4.join(cwd, ".bugzy/runtime/subagent-memory-guide.md");
6695
+ const subagentMemoryPath = path5.join(cwd, ".bugzy/runtime/subagent-memory-guide.md");
6573
6696
  if (!fs4.existsSync(subagentMemoryPath)) {
6574
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/subagent-memory-guide.md");
6697
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/subagent-memory-guide.md");
6575
6698
  if (fs4.existsSync(templatePath)) {
6576
6699
  const content = fs4.readFileSync(templatePath, "utf-8");
6577
6700
  fs4.writeFileSync(subagentMemoryPath, content, "utf-8");
6578
6701
  }
6579
6702
  }
6580
- const testExecutionStrategyPath = path4.join(cwd, ".bugzy/runtime/test-execution-strategy.md");
6703
+ const testExecutionStrategyPath = path5.join(cwd, ".bugzy/runtime/test-execution-strategy.md");
6581
6704
  if (!fs4.existsSync(testExecutionStrategyPath)) {
6582
- const templatePath = path4.join(templatesDir, ".bugzy/runtime/test-execution-strategy.md");
6705
+ const templatePath = path5.join(templatesDir, ".bugzy/runtime/test-execution-strategy.md");
6583
6706
  if (fs4.existsSync(templatePath)) {
6584
6707
  const content = fs4.readFileSync(templatePath, "utf-8");
6585
6708
  fs4.writeFileSync(testExecutionStrategyPath, content, "utf-8");
@@ -6589,18 +6712,28 @@ async function createRuntimeFiles() {
6589
6712
  async function generateClaudeMd() {
6590
6713
  const cwd = process.cwd();
6591
6714
  const templatesDir = getTemplatesDir();
6592
- const claudeMdPath = path4.join(cwd, "CLAUDE.md");
6715
+ const claudeMdPath = path5.join(cwd, "CLAUDE.md");
6593
6716
  if (!fs4.existsSync(claudeMdPath)) {
6594
- const templatePath = path4.join(templatesDir, "CLAUDE.md");
6717
+ const templatePath = path5.join(templatesDir, "CLAUDE.md");
6595
6718
  const content = fs4.readFileSync(templatePath, "utf-8");
6596
6719
  fs4.writeFileSync(claudeMdPath, content, "utf-8");
6597
6720
  }
6598
6721
  }
6722
+ async function generateAgentsMd() {
6723
+ const cwd = process.cwd();
6724
+ const templatesDir = getTemplatesDir();
6725
+ const agentsMdPath = path5.join(cwd, "AGENTS.md");
6726
+ if (!fs4.existsSync(agentsMdPath)) {
6727
+ const templatePath = path5.join(templatesDir, "AGENTS.md");
6728
+ const content = fs4.readFileSync(templatePath, "utf-8");
6729
+ fs4.writeFileSync(agentsMdPath, content, "utf-8");
6730
+ }
6731
+ }
6599
6732
  async function updateGitignore() {
6600
6733
  const cwd = process.cwd();
6601
- const gitignorePath = path4.join(cwd, ".gitignore");
6734
+ const gitignorePath = path5.join(cwd, ".gitignore");
6602
6735
  const templatesDir = getTemplatesDir();
6603
- const templatePath = path4.join(templatesDir, ".gitignore-template");
6736
+ const templatePath = path5.join(templatesDir, ".gitignore-template");
6604
6737
  const bugzyEntries = fs4.readFileSync(templatePath, "utf-8");
6605
6738
  if (fs4.existsSync(gitignorePath)) {
6606
6739
  const content = fs4.readFileSync(gitignorePath, "utf-8");
@@ -6615,7 +6748,7 @@ async function updateGitignore() {
6615
6748
  // src/cli/generators/commands.ts
6616
6749
  init_cjs_shims();
6617
6750
  var fs5 = __toESM(require("fs"), 1);
6618
- var path5 = __toESM(require("path"), 1);
6751
+ var path6 = __toESM(require("path"), 1);
6619
6752
  init_tasks();
6620
6753
 
6621
6754
  // src/core/task-builder.ts
@@ -6665,22 +6798,80 @@ function buildTaskDefinition(taskSlug, projectSubAgents) {
6665
6798
  };
6666
6799
  }
6667
6800
 
6801
+ // src/core/tool-strings.ts
6802
+ init_cjs_shims();
6803
+ var TOOL_STRINGS = {
6804
+ "claude-code": {
6805
+ INVOKE_TEST_RUNNER: "Use the test-runner subagent to execute the tests",
6806
+ INVOKE_TEST_DEBUGGER_FIXER: "Use the test-debugger-fixer subagent to debug and fix the failing test",
6807
+ INVOKE_TEST_CODE_GENERATOR: "Use the test-code-generator subagent to generate automated test code",
6808
+ INVOKE_TEAM_COMMUNICATOR: "Use the team-communicator subagent to notify the team",
6809
+ INVOKE_ISSUE_TRACKER: "Use the issue-tracker subagent to create or update issues",
6810
+ INVOKE_DOCUMENTATION_RESEARCHER: "Use the documentation-researcher subagent to search and gather documentation"
6811
+ },
6812
+ "cursor": {
6813
+ INVOKE_TEST_RUNNER: 'Run the test-runner agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/test-runner.md)" --output-format text\n```',
6814
+ INVOKE_TEST_DEBUGGER_FIXER: 'Run the test-debugger-fixer agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/test-debugger-fixer.md)" --output-format text\n```',
6815
+ INVOKE_TEST_CODE_GENERATOR: 'Run the test-code-generator agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/test-code-generator.md)" --output-format text\n```',
6816
+ INVOKE_TEAM_COMMUNICATOR: 'Run the team-communicator agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/team-communicator.md)" --output-format text\n```',
6817
+ INVOKE_ISSUE_TRACKER: 'Run the issue-tracker agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/issue-tracker.md)" --output-format text\n```',
6818
+ INVOKE_DOCUMENTATION_RESEARCHER: 'Run the documentation-researcher agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/documentation-researcher.md)" --output-format text\n```'
6819
+ },
6820
+ "codex": {
6821
+ INVOKE_TEST_RUNNER: 'Run the test-runner agent:\n```bash\ncodex -p "$(cat .codex/agents/test-runner.md)"\n```',
6822
+ INVOKE_TEST_DEBUGGER_FIXER: 'Run the test-debugger-fixer agent:\n```bash\ncodex -p "$(cat .codex/agents/test-debugger-fixer.md)"\n```',
6823
+ INVOKE_TEST_CODE_GENERATOR: 'Run the test-code-generator agent:\n```bash\ncodex -p "$(cat .codex/agents/test-code-generator.md)"\n```',
6824
+ INVOKE_TEAM_COMMUNICATOR: 'Run the team-communicator agent:\n```bash\ncodex -p "$(cat .codex/agents/team-communicator.md)"\n```',
6825
+ INVOKE_ISSUE_TRACKER: 'Run the issue-tracker agent:\n```bash\ncodex -p "$(cat .codex/agents/issue-tracker.md)"\n```',
6826
+ INVOKE_DOCUMENTATION_RESEARCHER: 'Run the documentation-researcher agent:\n```bash\ncodex -p "$(cat .codex/agents/documentation-researcher.md)"\n```'
6827
+ }
6828
+ };
6829
+ function getToolString(toolId, key) {
6830
+ const toolStrings = TOOL_STRINGS[toolId];
6831
+ if (!toolStrings) {
6832
+ throw new Error(`Unknown tool: ${toolId}`);
6833
+ }
6834
+ const value = toolStrings[key];
6835
+ if (!value) {
6836
+ throw new Error(`Unknown string key: ${key} for tool: ${toolId}`);
6837
+ }
6838
+ return value;
6839
+ }
6840
+ function replaceInvocationPlaceholders(content, toolId) {
6841
+ let result = content;
6842
+ const keys = [
6843
+ "INVOKE_TEST_RUNNER",
6844
+ "INVOKE_TEST_DEBUGGER_FIXER",
6845
+ "INVOKE_TEST_CODE_GENERATOR",
6846
+ "INVOKE_TEAM_COMMUNICATOR",
6847
+ "INVOKE_ISSUE_TRACKER",
6848
+ "INVOKE_DOCUMENTATION_RESEARCHER"
6849
+ ];
6850
+ for (const key of keys) {
6851
+ const placeholder = `{{${key}}}`;
6852
+ const replacement = getToolString(toolId, key);
6853
+ result = result.replace(new RegExp(placeholder, "g"), replacement);
6854
+ }
6855
+ return result;
6856
+ }
6857
+
6668
6858
  // src/cli/generators/commands.ts
6669
6859
  var COMMAND_FILTER = {
6670
6860
  // Cloud-only commands (skip in local environment)
6671
6861
  "handle-message": false,
6672
6862
  "process-event": false
6673
6863
  };
6674
- async function generateCommands(subagents) {
6864
+ async function generateCommands(subagents, tool = DEFAULT_TOOL) {
6675
6865
  const cwd = process.cwd();
6676
- const commandsDir = path5.join(cwd, ".claude", "commands");
6866
+ const toolProfile = getToolProfile(tool);
6867
+ const commandsDir = path6.join(cwd, toolProfile.commandsDir);
6677
6868
  if (!fs5.existsSync(commandsDir)) {
6678
6869
  fs5.mkdirSync(commandsDir, { recursive: true });
6679
6870
  }
6680
6871
  const existingFiles = fs5.readdirSync(commandsDir);
6681
6872
  for (const file of existingFiles) {
6682
6873
  if (file.endsWith(".md")) {
6683
- fs5.unlinkSync(path5.join(commandsDir, file));
6874
+ fs5.unlinkSync(path6.join(commandsDir, file));
6684
6875
  }
6685
6876
  }
6686
6877
  const projectSubAgents = Object.entries(subagents).map(
@@ -6694,18 +6885,35 @@ async function generateCommands(subagents) {
6694
6885
  const outputSlug = typeof filterValue === "string" ? filterValue : slug;
6695
6886
  try {
6696
6887
  const taskDef = buildTaskDefinition(slug, projectSubAgents);
6697
- const content = formatCommandMarkdown(taskDef.frontmatter, taskDef.content);
6698
- const filePath = path5.join(commandsDir, `${outputSlug}.md`);
6888
+ const processedContent = replaceInvocationPlaceholders(taskDef.content, tool);
6889
+ const content = formatCommandMarkdown(taskDef.frontmatter, processedContent, toolProfile.commandFrontmatter);
6890
+ const fileName = `${outputSlug}${toolProfile.commandExtension}`;
6891
+ const filePath = path6.join(commandsDir, fileName);
6699
6892
  fs5.writeFileSync(filePath, content, "utf-8");
6700
6893
  } catch (error) {
6701
- const content = formatCommandMarkdown(template.frontmatter, template.baseContent);
6702
- const filePath = path5.join(commandsDir, `${outputSlug}.md`);
6894
+ const processedContent = replaceInvocationPlaceholders(template.baseContent, tool);
6895
+ const content = formatCommandMarkdown(template.frontmatter, processedContent, toolProfile.commandFrontmatter);
6896
+ const fileName = `${outputSlug}${toolProfile.commandExtension}`;
6897
+ const filePath = path6.join(commandsDir, fileName);
6703
6898
  fs5.writeFileSync(filePath, content, "utf-8");
6704
6899
  console.warn(`Warning: Generated ${outputSlug} without required subagents: ${error.message}`);
6705
6900
  }
6706
6901
  }
6707
6902
  }
6708
- function formatCommandMarkdown(frontmatter, content) {
6903
+ function formatCommandMarkdown(frontmatter, content, includeFrontmatter) {
6904
+ if (!includeFrontmatter) {
6905
+ const lines2 = [];
6906
+ if (frontmatter.description) {
6907
+ lines2.push(`# ${frontmatter.description}`);
6908
+ lines2.push("");
6909
+ }
6910
+ if (frontmatter["argument-hint"]) {
6911
+ lines2.push(`**Arguments**: ${frontmatter["argument-hint"]}`);
6912
+ lines2.push("");
6913
+ }
6914
+ lines2.push(content);
6915
+ return lines2.join("\n");
6916
+ }
6709
6917
  const lines = ["---"];
6710
6918
  for (const [key, value] of Object.entries(frontmatter)) {
6711
6919
  if (value !== void 0 && value !== null) {
@@ -6722,17 +6930,18 @@ function formatCommandMarkdown(frontmatter, content) {
6722
6930
  // src/cli/generators/agents.ts
6723
6931
  init_cjs_shims();
6724
6932
  var fs6 = __toESM(require("fs"), 1);
6725
- var path6 = __toESM(require("path"), 1);
6726
- async function generateAgents(subagents) {
6933
+ var path7 = __toESM(require("path"), 1);
6934
+ async function generateAgents(subagents, tool = DEFAULT_TOOL) {
6727
6935
  const cwd = process.cwd();
6728
- const agentsDir = path6.join(cwd, ".claude", "agents");
6936
+ const toolProfile = getToolProfile(tool);
6937
+ const agentsDir = path7.join(cwd, toolProfile.agentsDir);
6729
6938
  if (!fs6.existsSync(agentsDir)) {
6730
6939
  fs6.mkdirSync(agentsDir, { recursive: true });
6731
6940
  }
6732
6941
  const existingFiles = fs6.readdirSync(agentsDir);
6733
6942
  for (const file of existingFiles) {
6734
6943
  if (file.endsWith(".md")) {
6735
- fs6.unlinkSync(path6.join(agentsDir, file));
6944
+ fs6.unlinkSync(path7.join(agentsDir, file));
6736
6945
  }
6737
6946
  }
6738
6947
  for (const [role, integration] of Object.entries(subagents)) {
@@ -6741,12 +6950,16 @@ async function generateAgents(subagents) {
6741
6950
  console.warn(`Warning: Could not load template for ${role} with ${integration}`);
6742
6951
  continue;
6743
6952
  }
6744
- const content = formatAgentMarkdown(config.frontmatter, config.content);
6745
- const filePath = path6.join(agentsDir, `${role}.md`);
6953
+ const content = formatAgentMarkdown(config.frontmatter, config.content, toolProfile.agentFrontmatter);
6954
+ const fileName = `${role}${toolProfile.agentExtension}`;
6955
+ const filePath = path7.join(agentsDir, fileName);
6746
6956
  fs6.writeFileSync(filePath, content, "utf-8");
6747
6957
  }
6748
6958
  }
6749
- function formatAgentMarkdown(frontmatter, content) {
6959
+ function formatAgentMarkdown(frontmatter, content, includeFrontmatter) {
6960
+ if (!includeFrontmatter) {
6961
+ return content;
6962
+ }
6750
6963
  const lines = ["---"];
6751
6964
  for (const [key, value] of Object.entries(frontmatter)) {
6752
6965
  if (value !== void 0 && value !== null) {
@@ -6767,7 +6980,8 @@ function formatAgentMarkdown(frontmatter, content) {
6767
6980
  // src/cli/generators/mcp.ts
6768
6981
  init_cjs_shims();
6769
6982
  var fs7 = __toESM(require("fs"), 1);
6770
- var path7 = __toESM(require("path"), 1);
6983
+ var path8 = __toESM(require("path"), 1);
6984
+ var import_child_process2 = require("child_process");
6771
6985
 
6772
6986
  // src/mcp/index.ts
6773
6987
  init_cjs_shims();
@@ -6777,6 +6991,7 @@ var MCP_SERVERS = {
6777
6991
  name: "Slack",
6778
6992
  description: "Slack MCP server for messaging and channel operations",
6779
6993
  requiresCredentials: true,
6994
+ npmPackages: ["simple-slack-mcp-server"],
6780
6995
  config: {
6781
6996
  command: "slack-mcp-server",
6782
6997
  args: [],
@@ -6790,6 +7005,7 @@ var MCP_SERVERS = {
6790
7005
  name: "Microsoft Teams",
6791
7006
  description: "Microsoft Teams MCP server for messaging and channel operations",
6792
7007
  requiresCredentials: true,
7008
+ npmPackages: ["@bugzy-ai/teams-mcp-server"],
6793
7009
  config: {
6794
7010
  command: "teams-mcp-server",
6795
7011
  args: [],
@@ -6803,6 +7019,7 @@ var MCP_SERVERS = {
6803
7019
  name: "Playwright",
6804
7020
  description: "Playwright MCP server for browser automation",
6805
7021
  requiresCredentials: false,
7022
+ npmPackages: ["@playwright/mcp"],
6806
7023
  config: {
6807
7024
  command: "mcp-server-playwright",
6808
7025
  args: [
@@ -6827,6 +7044,7 @@ var MCP_SERVERS = {
6827
7044
  name: "Notion",
6828
7045
  description: "Notion MCP server for documentation",
6829
7046
  requiresCredentials: true,
7047
+ npmPackages: ["@notionhq/notion-mcp-server"],
6830
7048
  config: {
6831
7049
  command: "notion-mcp-server",
6832
7050
  args: [],
@@ -6840,6 +7058,7 @@ var MCP_SERVERS = {
6840
7058
  name: "Jira Server (On-Prem)",
6841
7059
  description: "Jira Server MCP via tunnel for on-premise instances",
6842
7060
  requiresCredentials: true,
7061
+ npmPackages: ["@mcp-tunnel/wrapper", "@bugzy-ai/jira-mcp-server"],
6843
7062
  config: {
6844
7063
  command: "mcp-tunnel",
6845
7064
  args: ["--server", "jira-mcp-server"],
@@ -6936,12 +7155,59 @@ function buildMCPConfig(requiredServers, target = "container") {
6936
7155
  }
6937
7156
 
6938
7157
  // src/cli/generators/mcp.ts
6939
- async function generateMCPConfig(mcpServers) {
7158
+ async function generateMCPConfig(mcpServers, tool = DEFAULT_TOOL) {
6940
7159
  const cwd = process.cwd();
6941
- const mcpConfigPath = path7.join(cwd, ".mcp.json");
6942
- const mcpConfig = buildMCPConfig(mcpServers, "local");
6943
- const content = JSON.stringify(mcpConfig, null, 2);
6944
- fs7.writeFileSync(mcpConfigPath, content, "utf-8");
7160
+ const toolProfile = getToolProfile(tool);
7161
+ if (toolProfile.mcpFormat === "json") {
7162
+ const mcpConfigPath = path8.join(cwd, toolProfile.mcpConfigPath);
7163
+ const mcpDir = path8.dirname(mcpConfigPath);
7164
+ if (!fs7.existsSync(mcpDir)) {
7165
+ fs7.mkdirSync(mcpDir, { recursive: true });
7166
+ }
7167
+ const mcpConfig = buildMCPConfig(mcpServers, "local");
7168
+ const content = JSON.stringify(mcpConfig, null, 2);
7169
+ fs7.writeFileSync(mcpConfigPath, content, "utf-8");
7170
+ } else if (toolProfile.mcpFormat === "toml") {
7171
+ return;
7172
+ }
7173
+ }
7174
+ function buildCodexMCPCommand(serverName) {
7175
+ const serverTemplate = MCP_SERVERS[serverName];
7176
+ if (!serverTemplate) {
7177
+ throw new Error(`Unknown MCP server: ${serverName}`);
7178
+ }
7179
+ const args = ["mcp", "add", `bugzy-${serverName}`];
7180
+ const envVars = [];
7181
+ if (serverTemplate.config.env) {
7182
+ for (const [key, value] of Object.entries(serverTemplate.config.env)) {
7183
+ const match = value.match(/\$\{([A-Z_]+)\}/);
7184
+ if (match) {
7185
+ args.push("--env", `${key}=$${match[1]}`);
7186
+ envVars.push(match[1]);
7187
+ }
7188
+ }
7189
+ }
7190
+ args.push("--", serverTemplate.config.command);
7191
+ if (serverTemplate.config.args?.length) {
7192
+ args.push(...serverTemplate.config.args);
7193
+ }
7194
+ return { args, envVars };
7195
+ }
7196
+ async function getConfiguredCodexMCPServers() {
7197
+ try {
7198
+ const output = (0, import_child_process2.execSync)("codex mcp list", {
7199
+ encoding: "utf-8",
7200
+ env: { ...process.env, CODEX_HOME: path8.join(process.cwd(), ".codex") },
7201
+ stdio: ["pipe", "pipe", "pipe"]
7202
+ });
7203
+ const lines = output.split("\n");
7204
+ return lines.filter((line) => line.includes("bugzy-")).map((line) => {
7205
+ const match = line.match(/bugzy-([a-z-]+)/);
7206
+ return match ? match[1] : null;
7207
+ }).filter((name) => name !== null);
7208
+ } catch {
7209
+ return [];
7210
+ }
6945
7211
  }
6946
7212
  function getMCPServersFromSubagents(subagents) {
6947
7213
  const mcps = /* @__PURE__ */ new Set();
@@ -6951,13 +7217,16 @@ function getMCPServersFromSubagents(subagents) {
6951
7217
  return Array.from(mcps);
6952
7218
  }
6953
7219
 
7220
+ // src/cli/commands/setup.ts
7221
+ var import_child_process4 = require("child_process");
7222
+
6954
7223
  // src/cli/generators/env.ts
6955
7224
  init_cjs_shims();
6956
7225
  var fs8 = __toESM(require("fs"), 1);
6957
- var path8 = __toESM(require("path"), 1);
7226
+ var path9 = __toESM(require("path"), 1);
6958
7227
  async function generateEnvExample(mcpServers) {
6959
7228
  const cwd = process.cwd();
6960
- const envExamplePath = path8.join(cwd, ".env.example");
7229
+ const envExamplePath = path9.join(cwd, ".env.example");
6961
7230
  const header = `# ============================================
6962
7231
  # Bugzy OSS - Environment Variables
6963
7232
  # ============================================
@@ -6983,11 +7252,13 @@ function getMCPEnvConfig(serverName) {
6983
7252
  const configs = {
6984
7253
  slack: `
6985
7254
  # Slack MCP Server
6986
- # Get your token from: https://api.slack.com/apps
7255
+ # Setup guide: https://github.com/bugzy-ai/bugzy/blob/main/docs/slack-setup.md
7256
+ # Required scopes: channels:read, chat:write, chat:write.public, reactions:write
6987
7257
  SLACK_ACCESS_TOKEN=`,
6988
7258
  notion: `
6989
7259
  # Notion MCP Server
6990
- # Get your token from: https://www.notion.so/my-integrations
7260
+ # Setup guide: https://github.com/bugzy-ai/bugzy/blob/main/docs/notion-setup.md
7261
+ # Requires: Internal Integration Token (ntn_* or secret_*)
6991
7262
  NOTION_TOKEN=`,
6992
7263
  linear: `
6993
7264
  # Linear MCP Server
@@ -7017,8 +7288,8 @@ GITHUB_TOKEN=`
7017
7288
  // src/cli/generators/scaffold-playwright.ts
7018
7289
  init_cjs_shims();
7019
7290
  var fs9 = __toESM(require("fs"), 1);
7020
- var path9 = __toESM(require("path"), 1);
7021
- var import_child_process2 = require("child_process");
7291
+ var path10 = __toESM(require("path"), 1);
7292
+ var import_child_process3 = require("child_process");
7022
7293
  async function scaffoldPlaywrightProject(options) {
7023
7294
  const { projectName, targetDir, skipInstall = false } = options;
7024
7295
  console.log("\n\u{1F3AD} Scaffolding Playwright test automation project...\n");
@@ -7051,7 +7322,7 @@ async function createDirectoryStructure(targetDir) {
7051
7322
  "test-runs"
7052
7323
  ];
7053
7324
  for (const dir of directories) {
7054
- const fullPath = path9.join(targetDir, dir);
7325
+ const fullPath = path10.join(targetDir, dir);
7055
7326
  if (!fs9.existsSync(fullPath)) {
7056
7327
  fs9.mkdirSync(fullPath, { recursive: true });
7057
7328
  console.log(` \u2713 Created ${dir}/`);
@@ -7060,11 +7331,11 @@ async function createDirectoryStructure(targetDir) {
7060
7331
  }
7061
7332
  async function copyTemplateFiles(targetDir, projectName) {
7062
7333
  const possiblePaths = [
7063
- path9.join(__dirname, "../../templates/playwright"),
7334
+ path10.join(__dirname, "../../templates/playwright"),
7064
7335
  // When running from dist
7065
- path9.join(process.cwd(), "templates/playwright"),
7336
+ path10.join(process.cwd(), "templates/playwright"),
7066
7337
  // When running from project root
7067
- path9.join(__dirname, "../../../templates/playwright")
7338
+ path10.join(__dirname, "../../../templates/playwright")
7068
7339
  // When running tests
7069
7340
  ];
7070
7341
  let templatesDir = "";
@@ -7077,9 +7348,9 @@ async function copyTemplateFiles(targetDir, projectName) {
7077
7348
  if (!templatesDir) {
7078
7349
  throw new Error("Templates directory not found. Searched paths: " + possiblePaths.join(", "));
7079
7350
  }
7080
- const initTemplatesDir = path9.join(__dirname, "../../templates/init");
7081
- const testRunsReadmeSrc = path9.join(initTemplatesDir, "test-runs/README.md");
7082
- const testRunsReadmeDest = path9.join(targetDir, "test-runs/README.md");
7351
+ const initTemplatesDir = path10.join(__dirname, "../../templates/init");
7352
+ const testRunsReadmeSrc = path10.join(initTemplatesDir, "test-runs/README.md");
7353
+ const testRunsReadmeDest = path10.join(targetDir, "test-runs/README.md");
7083
7354
  if (fs9.existsSync(testRunsReadmeSrc)) {
7084
7355
  const content = fs9.readFileSync(testRunsReadmeSrc, "utf-8");
7085
7356
  fs9.writeFileSync(testRunsReadmeDest, content, "utf-8");
@@ -7123,8 +7394,8 @@ async function copyTemplateFiles(targetDir, projectName) {
7123
7394
  }
7124
7395
  ];
7125
7396
  for (const template of templates) {
7126
- const srcPath = path9.join(templatesDir, template.src);
7127
- const destPath = path9.join(targetDir, template.dest);
7397
+ const srcPath = path10.join(templatesDir, template.src);
7398
+ const destPath = path10.join(targetDir, template.dest);
7128
7399
  if (fs9.existsSync(srcPath)) {
7129
7400
  let content = fs9.readFileSync(srcPath, "utf-8");
7130
7401
  if (template.process) {
@@ -7134,7 +7405,7 @@ async function copyTemplateFiles(targetDir, projectName) {
7134
7405
  DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
7135
7406
  });
7136
7407
  }
7137
- const destDir = path9.dirname(destPath);
7408
+ const destDir = path10.dirname(destPath);
7138
7409
  if (!fs9.existsSync(destDir)) {
7139
7410
  fs9.mkdirSync(destDir, { recursive: true });
7140
7411
  }
@@ -7154,7 +7425,7 @@ function processTemplate(content, values) {
7154
7425
  return processed;
7155
7426
  }
7156
7427
  async function updateGitignore2(targetDir) {
7157
- const gitignorePath = path9.join(targetDir, ".gitignore");
7428
+ const gitignorePath = path10.join(targetDir, ".gitignore");
7158
7429
  const playwrightEntries = `
7159
7430
  # Playwright
7160
7431
  test-results/
@@ -7174,7 +7445,7 @@ tests/.auth/
7174
7445
  }
7175
7446
  }
7176
7447
  async function createPackageJson(targetDir, projectName) {
7177
- const packageJsonPath = path9.join(targetDir, "package.json");
7448
+ const packageJsonPath = path10.join(targetDir, "package.json");
7178
7449
  const recommendedDeps = {
7179
7450
  "@playwright/test": "^1.48.0",
7180
7451
  "@types/node": "^20.0.0",
@@ -7230,7 +7501,7 @@ async function installDependencies(targetDir) {
7230
7501
  console.log(`
7231
7502
  \u{1F4E6} Installing dependencies using ${packageManager}...`);
7232
7503
  const installCommand = packageManager === "pnpm" ? "pnpm install" : packageManager === "yarn" ? "yarn install" : "npm install";
7233
- (0, import_child_process2.execSync)(installCommand, {
7504
+ (0, import_child_process3.execSync)(installCommand, {
7234
7505
  cwd: targetDir,
7235
7506
  stdio: "inherit"
7236
7507
  });
@@ -7241,17 +7512,17 @@ async function installDependencies(targetDir) {
7241
7512
  }
7242
7513
  }
7243
7514
  function detectPackageManager(targetDir) {
7244
- if (fs9.existsSync(path9.join(targetDir, "pnpm-lock.yaml"))) {
7515
+ if (fs9.existsSync(path10.join(targetDir, "pnpm-lock.yaml"))) {
7245
7516
  return "pnpm";
7246
7517
  }
7247
- if (fs9.existsSync(path9.join(targetDir, "yarn.lock"))) {
7518
+ if (fs9.existsSync(path10.join(targetDir, "yarn.lock"))) {
7248
7519
  return "yarn";
7249
7520
  }
7250
7521
  return "npm";
7251
7522
  }
7252
7523
  function isPlaywrightScaffolded(targetDir) {
7253
- const playwrightConfig = path9.join(targetDir, "playwright.config.ts");
7254
- const testsDir = path9.join(targetDir, "tests");
7524
+ const playwrightConfig = path10.join(targetDir, "playwright.config.ts");
7525
+ const testsDir = path10.join(targetDir, "tests");
7255
7526
  return fs9.existsSync(playwrightConfig) && fs9.existsSync(testsDir);
7256
7527
  }
7257
7528
 
@@ -7295,9 +7566,26 @@ async function setupProject(cliArgs = []) {
7295
7566
  async function firstTimeSetup(cliSubagents) {
7296
7567
  console.log(getBanner());
7297
7568
  console.log(import_chalk2.default.cyan(" Project Setup\n"));
7569
+ const toolOptions = getToolOptions();
7570
+ const { selectedTool } = await import_inquirer.default.prompt([{
7571
+ type: "list",
7572
+ name: "selectedTool",
7573
+ message: "Which AI coding assistant do you use?",
7574
+ choices: toolOptions.map((opt) => ({
7575
+ name: opt.hint ? `${opt.label} - ${import_chalk2.default.gray(opt.hint)}` : opt.label,
7576
+ value: opt.value
7577
+ })),
7578
+ default: DEFAULT_TOOL
7579
+ }]);
7580
+ const tool = selectedTool;
7581
+ const toolProfile = getToolProfile(tool);
7582
+ console.log(import_chalk2.default.gray(`
7583
+ \u2713 Using ${toolProfile.name}
7584
+ `));
7298
7585
  let spinner = (0, import_ora2.default)("Creating project structure").start();
7299
- await createProjectStructure();
7300
- spinner.succeed(import_chalk2.default.green("Created .bugzy/ and .claude/ directories"));
7586
+ await createProjectStructure(tool);
7587
+ const toolDirName = path11.dirname(toolProfile.commandsDir);
7588
+ spinner.succeed(import_chalk2.default.green(`Created .bugzy/ and ${toolDirName}/ directories`));
7301
7589
  const subagents = {};
7302
7590
  if (cliSubagents) {
7303
7591
  console.log(import_chalk2.default.cyan("\nConfiguring subagents from CLI arguments:\n"));
@@ -7354,16 +7642,48 @@ async function firstTimeSetup(cliSubagents) {
7354
7642
  }
7355
7643
  }
7356
7644
  }
7645
+ const mcpServers = getMCPServersFromSubagents(subagents);
7646
+ const packagesToInstall = [...new Set(
7647
+ mcpServers.flatMap((s) => MCP_SERVERS[s]?.npmPackages ?? [])
7648
+ )];
7649
+ if (packagesToInstall.length > 0) {
7650
+ console.log(import_chalk2.default.cyan("\nMCP Server Packages Required:\n"));
7651
+ packagesToInstall.forEach((pkg) => console.log(import_chalk2.default.white(` \u2022 ${pkg}`)));
7652
+ const { installMCP } = await import_inquirer.default.prompt([{
7653
+ type: "confirm",
7654
+ name: "installMCP",
7655
+ message: "Install MCP packages globally now?",
7656
+ default: true
7657
+ }]);
7658
+ if (installMCP) {
7659
+ const spinner2 = (0, import_ora2.default)("Installing MCP packages").start();
7660
+ try {
7661
+ (0, import_child_process4.execSync)(`npm install -g ${packagesToInstall.join(" ")}`, { stdio: "pipe" });
7662
+ spinner2.succeed(import_chalk2.default.green("MCP packages installed"));
7663
+ } catch (e) {
7664
+ spinner2.fail(import_chalk2.default.red("Some packages failed to install"));
7665
+ console.log(import_chalk2.default.yellow("\nInstall manually: npm install -g " + packagesToInstall.join(" ")));
7666
+ }
7667
+ } else {
7668
+ console.log(import_chalk2.default.yellow("\n\u26A0\uFE0F MCP servers will not work until packages are installed:"));
7669
+ console.log(import_chalk2.default.white(` npm install -g ${packagesToInstall.join(" ")}
7670
+ `));
7671
+ }
7672
+ }
7357
7673
  spinner = (0, import_ora2.default)("Saving configuration").start();
7358
- const projectName = path10.basename(process.cwd());
7359
- const config = createDefaultConfig(projectName);
7674
+ const projectName = path11.basename(process.cwd());
7675
+ const config = createDefaultConfig(projectName, tool);
7360
7676
  config.subagents = subagents;
7361
7677
  saveConfig(config);
7362
7678
  spinner.succeed(import_chalk2.default.green("Saved to .bugzy/config.json"));
7363
- await regenerateAll(subagents);
7364
- spinner = (0, import_ora2.default)("Creating CLAUDE.md").start();
7365
- await generateClaudeMd();
7366
- spinner.succeed(import_chalk2.default.green("Created CLAUDE.md"));
7679
+ await regenerateAll(subagents, tool);
7680
+ spinner = (0, import_ora2.default)(`Creating ${toolProfile.memoryFile}`).start();
7681
+ if (tool === "claude-code") {
7682
+ await generateClaudeMd();
7683
+ } else {
7684
+ await generateAgentsMd();
7685
+ }
7686
+ spinner.succeed(import_chalk2.default.green(`Created ${toolProfile.memoryFile}`));
7367
7687
  spinner = (0, import_ora2.default)("Updating .gitignore").start();
7368
7688
  await updateGitignore();
7369
7689
  spinner.succeed(import_chalk2.default.green("Updated .gitignore"));
@@ -7375,11 +7695,23 @@ async function firstTimeSetup(cliSubagents) {
7375
7695
  });
7376
7696
  }
7377
7697
  console.log(import_chalk2.default.green.bold("\n\u2705 Setup complete!\n"));
7698
+ console.log(import_chalk2.default.cyan("\u{1F4CB} Project Context:"));
7699
+ console.log(import_chalk2.default.white(" Edit .bugzy/runtime/project-context.md to help the AI understand your project:"));
7700
+ console.log(import_chalk2.default.gray(" \u2022 Project description and tech stack"));
7701
+ console.log(import_chalk2.default.gray(" \u2022 Team communication channels"));
7702
+ console.log(import_chalk2.default.gray(" \u2022 Bug tracking workflow"));
7703
+ console.log(import_chalk2.default.gray(" \u2022 Testing conventions\n"));
7378
7704
  console.log(import_chalk2.default.yellow("Next steps:"));
7379
7705
  console.log(import_chalk2.default.white("1. cp .env.example .env"));
7380
7706
  console.log(import_chalk2.default.white("2. Edit .env and add your API tokens"));
7381
- console.log(import_chalk2.default.white("3. npx playwright install (install browser binaries)"));
7382
- console.log(import_chalk2.default.white("4. Run:"), import_chalk2.default.cyan("bugzy"));
7707
+ if (subagents["test-runner"]) {
7708
+ console.log(import_chalk2.default.white("3. npx playwright install (install browser binaries)"));
7709
+ console.log(import_chalk2.default.white("4. Edit .bugzy/runtime/project-context.md"));
7710
+ console.log(import_chalk2.default.white("5. Run:"), import_chalk2.default.cyan("bugzy"));
7711
+ } else {
7712
+ console.log(import_chalk2.default.white("3. Edit .bugzy/runtime/project-context.md"));
7713
+ console.log(import_chalk2.default.white("4. Run:"), import_chalk2.default.cyan("bugzy"));
7714
+ }
7383
7715
  console.log();
7384
7716
  }
7385
7717
  async function reconfigureProject() {
@@ -7390,11 +7722,38 @@ async function reconfigureProject() {
7390
7722
  console.error(import_chalk2.default.red("Error: Could not load existing configuration"));
7391
7723
  process.exit(1);
7392
7724
  }
7725
+ const currentTool = getToolFromConfig(existingConfig);
7726
+ const currentToolProfile = getToolProfile(currentTool);
7393
7727
  console.log(import_chalk2.default.gray("Current configuration:"));
7728
+ console.log(import_chalk2.default.gray(` Tool: ${currentToolProfile.name}`));
7394
7729
  for (const [role, integration] of Object.entries(existingConfig.subagents)) {
7395
7730
  console.log(import_chalk2.default.gray(` \u2022 ${role}: ${integration}`));
7396
7731
  }
7397
7732
  console.log();
7733
+ const toolOptions = getToolOptions();
7734
+ const { changeTool } = await import_inquirer.default.prompt([{
7735
+ type: "confirm",
7736
+ name: "changeTool",
7737
+ message: `Keep using ${currentToolProfile.name}?`,
7738
+ default: true
7739
+ }]);
7740
+ let tool = currentTool;
7741
+ if (!changeTool) {
7742
+ const { selectedTool } = await import_inquirer.default.prompt([{
7743
+ type: "list",
7744
+ name: "selectedTool",
7745
+ message: "Which AI coding assistant do you want to use?",
7746
+ choices: toolOptions.map((opt) => ({
7747
+ name: opt.hint ? `${opt.label} - ${import_chalk2.default.gray(opt.hint)}` : opt.label,
7748
+ value: opt.value
7749
+ })),
7750
+ default: currentTool
7751
+ }]);
7752
+ tool = selectedTool;
7753
+ console.log(import_chalk2.default.gray(`
7754
+ \u2713 Switching to ${getToolProfile(tool).name}
7755
+ `));
7756
+ }
7398
7757
  const allSubAgents = getAllSubAgents();
7399
7758
  const newSubagents = {};
7400
7759
  for (const subagent of allSubAgents) {
@@ -7470,13 +7829,19 @@ async function reconfigureProject() {
7470
7829
  }
7471
7830
  }
7472
7831
  let spinner = (0, import_ora2.default)("Updating configuration").start();
7832
+ existingConfig.tool = tool;
7473
7833
  existingConfig.subagents = newSubagents;
7474
7834
  await saveConfig(existingConfig);
7475
7835
  spinner.succeed(import_chalk2.default.green("Updated .bugzy/config.json"));
7476
- await regenerateAll(newSubagents);
7477
- spinner = (0, import_ora2.default)("Creating CLAUDE.md").start();
7478
- await generateClaudeMd();
7479
- spinner.succeed(import_chalk2.default.green("Created CLAUDE.md"));
7836
+ await regenerateAll(newSubagents, tool);
7837
+ const toolProfile = getToolProfile(tool);
7838
+ spinner = (0, import_ora2.default)(`Creating ${toolProfile.memoryFile}`).start();
7839
+ if (tool === "claude-code") {
7840
+ await generateClaudeMd();
7841
+ } else {
7842
+ await generateAgentsMd();
7843
+ }
7844
+ spinner.succeed(import_chalk2.default.green(`Created ${toolProfile.memoryFile}`));
7480
7845
  console.log(import_chalk2.default.green.bold("\n\u2705 Reconfiguration complete!\n"));
7481
7846
  console.log(import_chalk2.default.yellow("Next steps:"));
7482
7847
  console.log(import_chalk2.default.white("1. Check .env.example for new required secrets"));
@@ -7484,23 +7849,52 @@ async function reconfigureProject() {
7484
7849
  console.log(import_chalk2.default.white("3. Run:"), import_chalk2.default.cyan("bugzy"));
7485
7850
  console.log();
7486
7851
  }
7487
- async function regenerateAll(subagents) {
7852
+ async function regenerateAll(subagents, tool = DEFAULT_TOOL) {
7853
+ const toolProfile = getToolProfile(tool);
7488
7854
  let spinner = (0, import_ora2.default)("Generating task commands").start();
7489
- await generateCommands(subagents);
7855
+ await generateCommands(subagents, tool);
7490
7856
  const taskCount = Object.keys((init_tasks(), __toCommonJS(tasks_exports)).TASK_TEMPLATES).length;
7491
- spinner.succeed(import_chalk2.default.green(`Generated ${taskCount} task commands in .claude/commands/`));
7857
+ spinner.succeed(import_chalk2.default.green(`Generated ${taskCount} task commands in ${toolProfile.commandsDir}/`));
7492
7858
  spinner = (0, import_ora2.default)("Generating subagent configurations").start();
7493
- await generateAgents(subagents);
7859
+ await generateAgents(subagents, tool);
7494
7860
  const subagentCount = Object.keys(subagents).length;
7495
- spinner.succeed(import_chalk2.default.green(`Generated ${subagentCount} subagent configurations in .claude/agents/`));
7861
+ spinner.succeed(import_chalk2.default.green(`Generated ${subagentCount} subagent configurations in ${toolProfile.agentsDir}/`));
7496
7862
  spinner = (0, import_ora2.default)("Generating MCP configuration").start();
7497
7863
  const mcpServers = getMCPServersFromSubagents(subagents);
7498
- await generateMCPConfig(mcpServers);
7499
- spinner.succeed(import_chalk2.default.green(`Generated .mcp.json (${mcpServers.length} servers)`));
7864
+ await generateMCPConfig(mcpServers, tool);
7865
+ if (toolProfile.mcpFormat === "json") {
7866
+ spinner.succeed(import_chalk2.default.green(`Generated ${toolProfile.mcpConfigPath} (${mcpServers.length} servers)`));
7867
+ } else if (toolProfile.mcpFormat === "toml") {
7868
+ spinner.succeed(import_chalk2.default.green("MCP configuration ready"));
7869
+ await setupCodexMCP(mcpServers);
7870
+ }
7500
7871
  spinner = (0, import_ora2.default)("Creating environment template").start();
7501
7872
  await generateEnvExample(mcpServers);
7502
7873
  spinner.succeed(import_chalk2.default.green("Created .env.example"));
7503
7874
  }
7875
+ async function setupCodexMCP(mcpServers) {
7876
+ const existingServers = await getConfiguredCodexMCPServers();
7877
+ const newServers = mcpServers.filter((s) => !existingServers.includes(s));
7878
+ if (newServers.length === 0) {
7879
+ console.log(import_chalk2.default.gray("\n\u2713 All MCP servers already configured"));
7880
+ return;
7881
+ }
7882
+ console.log();
7883
+ for (const serverName of newServers) {
7884
+ const spinner = (0, import_ora2.default)(`Configuring ${serverName}`).start();
7885
+ try {
7886
+ const { args } = buildCodexMCPCommand(serverName);
7887
+ (0, import_child_process4.execSync)(["codex", ...args].join(" "), {
7888
+ stdio: "pipe",
7889
+ env: { ...process.env, CODEX_HOME: path11.join(process.cwd(), ".codex") }
7890
+ });
7891
+ spinner.succeed(import_chalk2.default.green(`Configured ${serverName}`));
7892
+ } catch (error) {
7893
+ spinner.fail(import_chalk2.default.red(`Failed to configure ${serverName}`));
7894
+ console.error(import_chalk2.default.gray(error.message));
7895
+ }
7896
+ }
7897
+ }
7504
7898
 
7505
7899
  // src/cli/index.ts
7506
7900
  process.on("uncaughtException", (error) => {