@bugzy-ai/bugzy 1.2.0 → 1.3.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.
- package/README.md +49 -27
- package/dist/cli/index.cjs +492 -144
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +495 -147
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +85 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +85 -30
- package/dist/index.js.map +1 -1
- package/dist/tasks/index.cjs +28 -29
- package/dist/tasks/index.cjs.map +1 -1
- package/dist/tasks/index.js +28 -29
- package/dist/tasks/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/init/AGENTS.md +155 -0
package/dist/cli/index.cjs
CHANGED
|
@@ -568,7 +568,9 @@ Document all findings including:
|
|
|
568
568
|
\`\`\`
|
|
569
569
|
|
|
570
570
|
#### 3.2 Launch Test Runner Agent
|
|
571
|
-
|
|
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
|
-
|
|
1044
|
+
{{INVOKE_TEST_CODE_GENERATOR}} for the current area with the following context:
|
|
1043
1045
|
|
|
1044
1046
|
**Agent Invocation:**
|
|
1045
|
-
"
|
|
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
|
-
|
|
1187
|
+
{{INVOKE_DOCUMENTATION_RESEARCHER}} to gather comprehensive product documentation:
|
|
1186
1188
|
|
|
1187
1189
|
\`\`\`
|
|
1188
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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. **
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
-
|
|
3205
|
+
{{INVOKE_TEAM_COMMUNICATOR}} to post concise results to Slack thread:
|
|
3205
3206
|
|
|
3206
3207
|
\`\`\`
|
|
3207
|
-
|
|
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
|
-
|
|
3389
|
+
{{INVOKE_DOCUMENTATION_RESEARCHER}} to gather comprehensive context about the changed features:
|
|
3389
3390
|
|
|
3390
3391
|
\`\`\`
|
|
3391
|
-
|
|
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]**,
|
|
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
|
-
|
|
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
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
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,10 +3851,10 @@ function validateProjectStructure() {
|
|
|
3747
3851
|
}
|
|
3748
3852
|
return true;
|
|
3749
3853
|
}
|
|
3750
|
-
async function
|
|
3854
|
+
async function checkToolAvailable(command) {
|
|
3751
3855
|
const { spawn: spawn2 } = await import("child_process");
|
|
3752
3856
|
return new Promise((resolve) => {
|
|
3753
|
-
const proc = spawn2("which", [
|
|
3857
|
+
const proc = spawn2("which", [command]);
|
|
3754
3858
|
proc.on("close", (code) => {
|
|
3755
3859
|
resolve(code === 0);
|
|
3756
3860
|
});
|
|
@@ -3795,9 +3899,11 @@ async function startSession(prompt) {
|
|
|
3795
3899
|
process.exit(1);
|
|
3796
3900
|
}
|
|
3797
3901
|
spinner.succeed(import_chalk.default.green("Configuration loaded"));
|
|
3902
|
+
const tool = getToolFromConfig(config);
|
|
3903
|
+
const toolProfile = getToolProfile(tool);
|
|
3798
3904
|
spinner = (0, import_ora.default)("Validating project structure").start();
|
|
3799
3905
|
try {
|
|
3800
|
-
validateProjectStructure();
|
|
3906
|
+
await validateProjectStructure();
|
|
3801
3907
|
spinner.succeed(import_chalk.default.green("Project structure validated"));
|
|
3802
3908
|
} catch (error) {
|
|
3803
3909
|
spinner.fail(import_chalk.default.red("Invalid project structure"));
|
|
@@ -3805,15 +3911,22 @@ async function startSession(prompt) {
|
|
|
3805
3911
|
console.log(import_chalk.default.yellow("\nRun"), import_chalk.default.cyan("bugzy setup"), import_chalk.default.yellow("to fix the project structure"));
|
|
3806
3912
|
process.exit(1);
|
|
3807
3913
|
}
|
|
3808
|
-
spinner = (0, import_ora.default)(
|
|
3809
|
-
const
|
|
3810
|
-
if (!
|
|
3811
|
-
spinner.fail(import_chalk.default.red(
|
|
3812
|
-
console.log(import_chalk.default.yellow(
|
|
3813
|
-
|
|
3914
|
+
spinner = (0, import_ora.default)(`Checking ${toolProfile.name} availability`).start();
|
|
3915
|
+
const toolAvailable = await checkToolAvailable(toolProfile.cliCommand);
|
|
3916
|
+
if (!toolAvailable) {
|
|
3917
|
+
spinner.fail(import_chalk.default.red(`${toolProfile.name} CLI not found`));
|
|
3918
|
+
console.log(import_chalk.default.yellow(`
|
|
3919
|
+
Please install ${toolProfile.name}:`));
|
|
3920
|
+
if (tool === "claude-code") {
|
|
3921
|
+
console.log(import_chalk.default.cyan(" https://claude.com/claude-code"));
|
|
3922
|
+
} else if (tool === "cursor") {
|
|
3923
|
+
console.log(import_chalk.default.cyan(" https://www.cursor.com/"));
|
|
3924
|
+
} else if (tool === "codex") {
|
|
3925
|
+
console.log(import_chalk.default.cyan(" npm install -g @openai/codex"));
|
|
3926
|
+
}
|
|
3814
3927
|
process.exit(1);
|
|
3815
3928
|
}
|
|
3816
|
-
spinner.succeed(import_chalk.default.green(
|
|
3929
|
+
spinner.succeed(import_chalk.default.green(`${toolProfile.name} CLI found`));
|
|
3817
3930
|
spinner = (0, import_ora.default)("Loading environment variables").start();
|
|
3818
3931
|
const envVars = loadEnvFiles();
|
|
3819
3932
|
const envCount = Object.keys(envVars).length;
|
|
@@ -3831,14 +3944,20 @@ async function startSession(prompt) {
|
|
|
3831
3944
|
process.exit(1);
|
|
3832
3945
|
}
|
|
3833
3946
|
spinner.succeed(import_chalk.default.green("All required MCP secrets present"));
|
|
3834
|
-
console.log(import_chalk.default.green.bold(
|
|
3947
|
+
console.log(import_chalk.default.green.bold(`
|
|
3948
|
+
\u{1F680} Launching ${toolProfile.name}...
|
|
3949
|
+
`));
|
|
3835
3950
|
const args = prompt ? [prompt] : [];
|
|
3836
|
-
const
|
|
3951
|
+
const spawnEnv = { ...process.env, ...envVars };
|
|
3952
|
+
if (toolProfile.homeEnvVar) {
|
|
3953
|
+
spawnEnv[toolProfile.homeEnvVar] = path4.join(process.cwd(), ".codex");
|
|
3954
|
+
}
|
|
3955
|
+
const child = (0, import_child_process.spawn)(toolProfile.cliCommand, args, {
|
|
3837
3956
|
cwd: process.cwd(),
|
|
3838
|
-
env:
|
|
3957
|
+
env: spawnEnv,
|
|
3839
3958
|
stdio: "inherit"
|
|
3840
3959
|
});
|
|
3841
|
-
|
|
3960
|
+
child.on("close", (code) => {
|
|
3842
3961
|
if (code === 0) {
|
|
3843
3962
|
console.log(import_chalk.default.green("\n\u2713 Session ended successfully"));
|
|
3844
3963
|
} else {
|
|
@@ -3846,15 +3965,16 @@ async function startSession(prompt) {
|
|
|
3846
3965
|
\u2713 Session ended (exit code: ${code})`));
|
|
3847
3966
|
}
|
|
3848
3967
|
});
|
|
3849
|
-
|
|
3850
|
-
console.error(import_chalk.default.red(
|
|
3968
|
+
child.on("error", (error) => {
|
|
3969
|
+
console.error(import_chalk.default.red(`
|
|
3970
|
+
\u2717 Error launching ${toolProfile.name}:`), error);
|
|
3851
3971
|
process.exit(1);
|
|
3852
3972
|
});
|
|
3853
3973
|
}
|
|
3854
3974
|
|
|
3855
3975
|
// src/cli/commands/setup.ts
|
|
3856
3976
|
init_cjs_shims();
|
|
3857
|
-
var
|
|
3977
|
+
var path11 = __toESM(require("path"), 1);
|
|
3858
3978
|
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
3859
3979
|
var import_inquirer = __toESM(require("inquirer"), 1);
|
|
3860
3980
|
var import_ora2 = __toESM(require("ora"), 1);
|
|
@@ -6489,27 +6609,31 @@ function buildSubagentConfig(role, integration) {
|
|
|
6489
6609
|
// src/cli/generators/structure.ts
|
|
6490
6610
|
init_cjs_shims();
|
|
6491
6611
|
var fs4 = __toESM(require("fs"), 1);
|
|
6492
|
-
var
|
|
6493
|
-
async function createProjectStructure() {
|
|
6612
|
+
var path5 = __toESM(require("path"), 1);
|
|
6613
|
+
async function createProjectStructure(tool = DEFAULT_TOOL) {
|
|
6494
6614
|
const cwd = process.cwd();
|
|
6615
|
+
const toolProfile = getToolProfile(tool);
|
|
6495
6616
|
const bugzyDirs = [
|
|
6496
6617
|
".bugzy",
|
|
6497
6618
|
".bugzy/runtime",
|
|
6498
6619
|
".bugzy/runtime/templates"
|
|
6499
6620
|
];
|
|
6500
6621
|
for (const dir of bugzyDirs) {
|
|
6501
|
-
const dirPath =
|
|
6622
|
+
const dirPath = path5.join(cwd, dir);
|
|
6502
6623
|
if (!fs4.existsSync(dirPath)) {
|
|
6503
6624
|
fs4.mkdirSync(dirPath, { recursive: true });
|
|
6504
6625
|
}
|
|
6505
6626
|
}
|
|
6506
|
-
const
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6627
|
+
const toolDirs = [
|
|
6628
|
+
path5.dirname(toolProfile.commandsDir),
|
|
6629
|
+
// .claude, .cursor, or .codex
|
|
6630
|
+
toolProfile.commandsDir,
|
|
6631
|
+
// .claude/commands, .cursor/commands, .codex/prompts
|
|
6632
|
+
toolProfile.agentsDir
|
|
6633
|
+
// .claude/agents, .cursor/agents, .codex/agents
|
|
6510
6634
|
];
|
|
6511
|
-
for (const dir of
|
|
6512
|
-
const dirPath =
|
|
6635
|
+
for (const dir of toolDirs) {
|
|
6636
|
+
const dirPath = path5.join(cwd, dir);
|
|
6513
6637
|
if (!fs4.existsSync(dirPath)) {
|
|
6514
6638
|
fs4.mkdirSync(dirPath, { recursive: true });
|
|
6515
6639
|
}
|
|
@@ -6517,69 +6641,69 @@ async function createProjectStructure() {
|
|
|
6517
6641
|
await createRuntimeFiles();
|
|
6518
6642
|
}
|
|
6519
6643
|
function getTemplatesDir() {
|
|
6520
|
-
return
|
|
6644
|
+
return path5.join(__dirname, "../../templates/init");
|
|
6521
6645
|
}
|
|
6522
6646
|
async function createRuntimeFiles() {
|
|
6523
6647
|
const cwd = process.cwd();
|
|
6524
6648
|
const templatesDir = getTemplatesDir();
|
|
6525
|
-
const projectContextPath =
|
|
6649
|
+
const projectContextPath = path5.join(cwd, ".bugzy/runtime/project-context.md");
|
|
6526
6650
|
if (!fs4.existsSync(projectContextPath)) {
|
|
6527
|
-
const templatePath =
|
|
6651
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/project-context.md");
|
|
6528
6652
|
let content = fs4.readFileSync(templatePath, "utf-8");
|
|
6529
|
-
const projectName =
|
|
6653
|
+
const projectName = path5.basename(cwd);
|
|
6530
6654
|
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
6531
6655
|
content = content.replace(/\{\{CUSTOMER_NAME\}\}/g, "[To be filled]");
|
|
6532
6656
|
content = content.replace(/\{\{BUG_TRACKING_SYSTEM\}\}/g, "[To be filled]");
|
|
6533
6657
|
content = content.replace(/\{\{DOCUMENTATION_SYSTEM\}\}/g, "[To be filled]");
|
|
6534
6658
|
fs4.writeFileSync(projectContextPath, content, "utf-8");
|
|
6535
6659
|
}
|
|
6536
|
-
const testPlanTemplatePath =
|
|
6660
|
+
const testPlanTemplatePath = path5.join(cwd, ".bugzy/runtime/templates/test-plan-template.md");
|
|
6537
6661
|
if (!fs4.existsSync(testPlanTemplatePath)) {
|
|
6538
|
-
const templatePath =
|
|
6662
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/templates/test-plan-template.md");
|
|
6539
6663
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6540
6664
|
fs4.writeFileSync(testPlanTemplatePath, content, "utf-8");
|
|
6541
6665
|
}
|
|
6542
|
-
const bestPracticesPath =
|
|
6666
|
+
const bestPracticesPath = path5.join(cwd, ".bugzy/runtime/testing-best-practices.md");
|
|
6543
6667
|
if (!fs4.existsSync(bestPracticesPath)) {
|
|
6544
|
-
const templatePath =
|
|
6668
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/testing-best-practices.md");
|
|
6545
6669
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6546
6670
|
fs4.writeFileSync(bestPracticesPath, content, "utf-8");
|
|
6547
6671
|
}
|
|
6548
|
-
const testResultSchemaPath =
|
|
6672
|
+
const testResultSchemaPath = path5.join(cwd, ".bugzy/runtime/templates/test-result-schema.md");
|
|
6549
6673
|
if (!fs4.existsSync(testResultSchemaPath)) {
|
|
6550
|
-
const templatePath =
|
|
6674
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/templates/test-result-schema.md");
|
|
6551
6675
|
if (fs4.existsSync(templatePath)) {
|
|
6552
6676
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6553
6677
|
fs4.writeFileSync(testResultSchemaPath, content, "utf-8");
|
|
6554
6678
|
}
|
|
6555
6679
|
}
|
|
6556
|
-
const knowledgeBasePath =
|
|
6680
|
+
const knowledgeBasePath = path5.join(cwd, ".bugzy/runtime/knowledge-base.md");
|
|
6557
6681
|
if (!fs4.existsSync(knowledgeBasePath)) {
|
|
6558
|
-
const templatePath =
|
|
6682
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/knowledge-base.md");
|
|
6559
6683
|
if (fs4.existsSync(templatePath)) {
|
|
6560
6684
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6561
6685
|
fs4.writeFileSync(knowledgeBasePath, content, "utf-8");
|
|
6562
6686
|
}
|
|
6563
6687
|
}
|
|
6564
|
-
const knowledgeMaintenancePath =
|
|
6688
|
+
const knowledgeMaintenancePath = path5.join(cwd, ".bugzy/runtime/knowledge-maintenance-guide.md");
|
|
6565
6689
|
if (!fs4.existsSync(knowledgeMaintenancePath)) {
|
|
6566
|
-
const templatePath =
|
|
6690
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/knowledge-maintenance-guide.md");
|
|
6567
6691
|
if (fs4.existsSync(templatePath)) {
|
|
6568
6692
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6569
6693
|
fs4.writeFileSync(knowledgeMaintenancePath, content, "utf-8");
|
|
6570
6694
|
}
|
|
6571
6695
|
}
|
|
6572
|
-
const subagentMemoryPath =
|
|
6696
|
+
const subagentMemoryPath = path5.join(cwd, ".bugzy/runtime/subagent-memory-guide.md");
|
|
6573
6697
|
if (!fs4.existsSync(subagentMemoryPath)) {
|
|
6574
|
-
const templatePath =
|
|
6698
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/subagent-memory-guide.md");
|
|
6575
6699
|
if (fs4.existsSync(templatePath)) {
|
|
6576
6700
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6577
6701
|
fs4.writeFileSync(subagentMemoryPath, content, "utf-8");
|
|
6578
6702
|
}
|
|
6579
6703
|
}
|
|
6580
|
-
const testExecutionStrategyPath =
|
|
6704
|
+
const testExecutionStrategyPath = path5.join(cwd, ".bugzy/runtime/test-execution-strategy.md");
|
|
6581
6705
|
if (!fs4.existsSync(testExecutionStrategyPath)) {
|
|
6582
|
-
const templatePath =
|
|
6706
|
+
const templatePath = path5.join(templatesDir, ".bugzy/runtime/test-execution-strategy.md");
|
|
6583
6707
|
if (fs4.existsSync(templatePath)) {
|
|
6584
6708
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6585
6709
|
fs4.writeFileSync(testExecutionStrategyPath, content, "utf-8");
|
|
@@ -6589,18 +6713,28 @@ async function createRuntimeFiles() {
|
|
|
6589
6713
|
async function generateClaudeMd() {
|
|
6590
6714
|
const cwd = process.cwd();
|
|
6591
6715
|
const templatesDir = getTemplatesDir();
|
|
6592
|
-
const claudeMdPath =
|
|
6716
|
+
const claudeMdPath = path5.join(cwd, "CLAUDE.md");
|
|
6593
6717
|
if (!fs4.existsSync(claudeMdPath)) {
|
|
6594
|
-
const templatePath =
|
|
6718
|
+
const templatePath = path5.join(templatesDir, "CLAUDE.md");
|
|
6595
6719
|
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6596
6720
|
fs4.writeFileSync(claudeMdPath, content, "utf-8");
|
|
6597
6721
|
}
|
|
6598
6722
|
}
|
|
6723
|
+
async function generateAgentsMd() {
|
|
6724
|
+
const cwd = process.cwd();
|
|
6725
|
+
const templatesDir = getTemplatesDir();
|
|
6726
|
+
const agentsMdPath = path5.join(cwd, "AGENTS.md");
|
|
6727
|
+
if (!fs4.existsSync(agentsMdPath)) {
|
|
6728
|
+
const templatePath = path5.join(templatesDir, "AGENTS.md");
|
|
6729
|
+
const content = fs4.readFileSync(templatePath, "utf-8");
|
|
6730
|
+
fs4.writeFileSync(agentsMdPath, content, "utf-8");
|
|
6731
|
+
}
|
|
6732
|
+
}
|
|
6599
6733
|
async function updateGitignore() {
|
|
6600
6734
|
const cwd = process.cwd();
|
|
6601
|
-
const gitignorePath =
|
|
6735
|
+
const gitignorePath = path5.join(cwd, ".gitignore");
|
|
6602
6736
|
const templatesDir = getTemplatesDir();
|
|
6603
|
-
const templatePath =
|
|
6737
|
+
const templatePath = path5.join(templatesDir, ".gitignore-template");
|
|
6604
6738
|
const bugzyEntries = fs4.readFileSync(templatePath, "utf-8");
|
|
6605
6739
|
if (fs4.existsSync(gitignorePath)) {
|
|
6606
6740
|
const content = fs4.readFileSync(gitignorePath, "utf-8");
|
|
@@ -6615,7 +6749,7 @@ async function updateGitignore() {
|
|
|
6615
6749
|
// src/cli/generators/commands.ts
|
|
6616
6750
|
init_cjs_shims();
|
|
6617
6751
|
var fs5 = __toESM(require("fs"), 1);
|
|
6618
|
-
var
|
|
6752
|
+
var path6 = __toESM(require("path"), 1);
|
|
6619
6753
|
init_tasks();
|
|
6620
6754
|
|
|
6621
6755
|
// src/core/task-builder.ts
|
|
@@ -6665,22 +6799,80 @@ function buildTaskDefinition(taskSlug, projectSubAgents) {
|
|
|
6665
6799
|
};
|
|
6666
6800
|
}
|
|
6667
6801
|
|
|
6802
|
+
// src/core/tool-strings.ts
|
|
6803
|
+
init_cjs_shims();
|
|
6804
|
+
var TOOL_STRINGS = {
|
|
6805
|
+
"claude-code": {
|
|
6806
|
+
INVOKE_TEST_RUNNER: "Use the test-runner subagent to execute the tests",
|
|
6807
|
+
INVOKE_TEST_DEBUGGER_FIXER: "Use the test-debugger-fixer subagent to debug and fix the failing test",
|
|
6808
|
+
INVOKE_TEST_CODE_GENERATOR: "Use the test-code-generator subagent to generate automated test code",
|
|
6809
|
+
INVOKE_TEAM_COMMUNICATOR: "Use the team-communicator subagent to notify the team",
|
|
6810
|
+
INVOKE_ISSUE_TRACKER: "Use the issue-tracker subagent to create or update issues",
|
|
6811
|
+
INVOKE_DOCUMENTATION_RESEARCHER: "Use the documentation-researcher subagent to search and gather documentation"
|
|
6812
|
+
},
|
|
6813
|
+
"cursor": {
|
|
6814
|
+
INVOKE_TEST_RUNNER: 'Run the test-runner agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/test-runner.md)" --output-format text\n```',
|
|
6815
|
+
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```',
|
|
6816
|
+
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```',
|
|
6817
|
+
INVOKE_TEAM_COMMUNICATOR: 'Run the team-communicator agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/team-communicator.md)" --output-format text\n```',
|
|
6818
|
+
INVOKE_ISSUE_TRACKER: 'Run the issue-tracker agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/issue-tracker.md)" --output-format text\n```',
|
|
6819
|
+
INVOKE_DOCUMENTATION_RESEARCHER: 'Run the documentation-researcher agent:\n```bash\ncursor-agent -p "$(cat .cursor/agents/documentation-researcher.md)" --output-format text\n```'
|
|
6820
|
+
},
|
|
6821
|
+
"codex": {
|
|
6822
|
+
INVOKE_TEST_RUNNER: 'Run the test-runner agent:\n```bash\ncodex -p "$(cat .codex/agents/test-runner.md)"\n```',
|
|
6823
|
+
INVOKE_TEST_DEBUGGER_FIXER: 'Run the test-debugger-fixer agent:\n```bash\ncodex -p "$(cat .codex/agents/test-debugger-fixer.md)"\n```',
|
|
6824
|
+
INVOKE_TEST_CODE_GENERATOR: 'Run the test-code-generator agent:\n```bash\ncodex -p "$(cat .codex/agents/test-code-generator.md)"\n```',
|
|
6825
|
+
INVOKE_TEAM_COMMUNICATOR: 'Run the team-communicator agent:\n```bash\ncodex -p "$(cat .codex/agents/team-communicator.md)"\n```',
|
|
6826
|
+
INVOKE_ISSUE_TRACKER: 'Run the issue-tracker agent:\n```bash\ncodex -p "$(cat .codex/agents/issue-tracker.md)"\n```',
|
|
6827
|
+
INVOKE_DOCUMENTATION_RESEARCHER: 'Run the documentation-researcher agent:\n```bash\ncodex -p "$(cat .codex/agents/documentation-researcher.md)"\n```'
|
|
6828
|
+
}
|
|
6829
|
+
};
|
|
6830
|
+
function getToolString(toolId, key) {
|
|
6831
|
+
const toolStrings = TOOL_STRINGS[toolId];
|
|
6832
|
+
if (!toolStrings) {
|
|
6833
|
+
throw new Error(`Unknown tool: ${toolId}`);
|
|
6834
|
+
}
|
|
6835
|
+
const value = toolStrings[key];
|
|
6836
|
+
if (!value) {
|
|
6837
|
+
throw new Error(`Unknown string key: ${key} for tool: ${toolId}`);
|
|
6838
|
+
}
|
|
6839
|
+
return value;
|
|
6840
|
+
}
|
|
6841
|
+
function replaceInvocationPlaceholders(content, toolId) {
|
|
6842
|
+
let result = content;
|
|
6843
|
+
const keys = [
|
|
6844
|
+
"INVOKE_TEST_RUNNER",
|
|
6845
|
+
"INVOKE_TEST_DEBUGGER_FIXER",
|
|
6846
|
+
"INVOKE_TEST_CODE_GENERATOR",
|
|
6847
|
+
"INVOKE_TEAM_COMMUNICATOR",
|
|
6848
|
+
"INVOKE_ISSUE_TRACKER",
|
|
6849
|
+
"INVOKE_DOCUMENTATION_RESEARCHER"
|
|
6850
|
+
];
|
|
6851
|
+
for (const key of keys) {
|
|
6852
|
+
const placeholder = `{{${key}}}`;
|
|
6853
|
+
const replacement = getToolString(toolId, key);
|
|
6854
|
+
result = result.replace(new RegExp(placeholder, "g"), replacement);
|
|
6855
|
+
}
|
|
6856
|
+
return result;
|
|
6857
|
+
}
|
|
6858
|
+
|
|
6668
6859
|
// src/cli/generators/commands.ts
|
|
6669
6860
|
var COMMAND_FILTER = {
|
|
6670
6861
|
// Cloud-only commands (skip in local environment)
|
|
6671
6862
|
"handle-message": false,
|
|
6672
6863
|
"process-event": false
|
|
6673
6864
|
};
|
|
6674
|
-
async function generateCommands(subagents) {
|
|
6865
|
+
async function generateCommands(subagents, tool = DEFAULT_TOOL) {
|
|
6675
6866
|
const cwd = process.cwd();
|
|
6676
|
-
const
|
|
6867
|
+
const toolProfile = getToolProfile(tool);
|
|
6868
|
+
const commandsDir = path6.join(cwd, toolProfile.commandsDir);
|
|
6677
6869
|
if (!fs5.existsSync(commandsDir)) {
|
|
6678
6870
|
fs5.mkdirSync(commandsDir, { recursive: true });
|
|
6679
6871
|
}
|
|
6680
6872
|
const existingFiles = fs5.readdirSync(commandsDir);
|
|
6681
6873
|
for (const file of existingFiles) {
|
|
6682
6874
|
if (file.endsWith(".md")) {
|
|
6683
|
-
fs5.unlinkSync(
|
|
6875
|
+
fs5.unlinkSync(path6.join(commandsDir, file));
|
|
6684
6876
|
}
|
|
6685
6877
|
}
|
|
6686
6878
|
const projectSubAgents = Object.entries(subagents).map(
|
|
@@ -6694,18 +6886,35 @@ async function generateCommands(subagents) {
|
|
|
6694
6886
|
const outputSlug = typeof filterValue === "string" ? filterValue : slug;
|
|
6695
6887
|
try {
|
|
6696
6888
|
const taskDef = buildTaskDefinition(slug, projectSubAgents);
|
|
6697
|
-
const
|
|
6698
|
-
const
|
|
6889
|
+
const processedContent = replaceInvocationPlaceholders(taskDef.content, tool);
|
|
6890
|
+
const content = formatCommandMarkdown(taskDef.frontmatter, processedContent, toolProfile.commandFrontmatter);
|
|
6891
|
+
const fileName = `${outputSlug}${toolProfile.commandExtension}`;
|
|
6892
|
+
const filePath = path6.join(commandsDir, fileName);
|
|
6699
6893
|
fs5.writeFileSync(filePath, content, "utf-8");
|
|
6700
6894
|
} catch (error) {
|
|
6701
|
-
const
|
|
6702
|
-
const
|
|
6895
|
+
const processedContent = replaceInvocationPlaceholders(template.baseContent, tool);
|
|
6896
|
+
const content = formatCommandMarkdown(template.frontmatter, processedContent, toolProfile.commandFrontmatter);
|
|
6897
|
+
const fileName = `${outputSlug}${toolProfile.commandExtension}`;
|
|
6898
|
+
const filePath = path6.join(commandsDir, fileName);
|
|
6703
6899
|
fs5.writeFileSync(filePath, content, "utf-8");
|
|
6704
6900
|
console.warn(`Warning: Generated ${outputSlug} without required subagents: ${error.message}`);
|
|
6705
6901
|
}
|
|
6706
6902
|
}
|
|
6707
6903
|
}
|
|
6708
|
-
function formatCommandMarkdown(frontmatter, content) {
|
|
6904
|
+
function formatCommandMarkdown(frontmatter, content, includeFrontmatter) {
|
|
6905
|
+
if (!includeFrontmatter) {
|
|
6906
|
+
const lines2 = [];
|
|
6907
|
+
if (frontmatter.description) {
|
|
6908
|
+
lines2.push(`# ${frontmatter.description}`);
|
|
6909
|
+
lines2.push("");
|
|
6910
|
+
}
|
|
6911
|
+
if (frontmatter["argument-hint"]) {
|
|
6912
|
+
lines2.push(`**Arguments**: ${frontmatter["argument-hint"]}`);
|
|
6913
|
+
lines2.push("");
|
|
6914
|
+
}
|
|
6915
|
+
lines2.push(content);
|
|
6916
|
+
return lines2.join("\n");
|
|
6917
|
+
}
|
|
6709
6918
|
const lines = ["---"];
|
|
6710
6919
|
for (const [key, value] of Object.entries(frontmatter)) {
|
|
6711
6920
|
if (value !== void 0 && value !== null) {
|
|
@@ -6722,17 +6931,18 @@ function formatCommandMarkdown(frontmatter, content) {
|
|
|
6722
6931
|
// src/cli/generators/agents.ts
|
|
6723
6932
|
init_cjs_shims();
|
|
6724
6933
|
var fs6 = __toESM(require("fs"), 1);
|
|
6725
|
-
var
|
|
6726
|
-
async function generateAgents(subagents) {
|
|
6934
|
+
var path7 = __toESM(require("path"), 1);
|
|
6935
|
+
async function generateAgents(subagents, tool = DEFAULT_TOOL) {
|
|
6727
6936
|
const cwd = process.cwd();
|
|
6728
|
-
const
|
|
6937
|
+
const toolProfile = getToolProfile(tool);
|
|
6938
|
+
const agentsDir = path7.join(cwd, toolProfile.agentsDir);
|
|
6729
6939
|
if (!fs6.existsSync(agentsDir)) {
|
|
6730
6940
|
fs6.mkdirSync(agentsDir, { recursive: true });
|
|
6731
6941
|
}
|
|
6732
6942
|
const existingFiles = fs6.readdirSync(agentsDir);
|
|
6733
6943
|
for (const file of existingFiles) {
|
|
6734
6944
|
if (file.endsWith(".md")) {
|
|
6735
|
-
fs6.unlinkSync(
|
|
6945
|
+
fs6.unlinkSync(path7.join(agentsDir, file));
|
|
6736
6946
|
}
|
|
6737
6947
|
}
|
|
6738
6948
|
for (const [role, integration] of Object.entries(subagents)) {
|
|
@@ -6741,12 +6951,16 @@ async function generateAgents(subagents) {
|
|
|
6741
6951
|
console.warn(`Warning: Could not load template for ${role} with ${integration}`);
|
|
6742
6952
|
continue;
|
|
6743
6953
|
}
|
|
6744
|
-
const content = formatAgentMarkdown(config.frontmatter, config.content);
|
|
6745
|
-
const
|
|
6954
|
+
const content = formatAgentMarkdown(config.frontmatter, config.content, toolProfile.agentFrontmatter);
|
|
6955
|
+
const fileName = `${role}${toolProfile.agentExtension}`;
|
|
6956
|
+
const filePath = path7.join(agentsDir, fileName);
|
|
6746
6957
|
fs6.writeFileSync(filePath, content, "utf-8");
|
|
6747
6958
|
}
|
|
6748
6959
|
}
|
|
6749
|
-
function formatAgentMarkdown(frontmatter, content) {
|
|
6960
|
+
function formatAgentMarkdown(frontmatter, content, includeFrontmatter) {
|
|
6961
|
+
if (!includeFrontmatter) {
|
|
6962
|
+
return content;
|
|
6963
|
+
}
|
|
6750
6964
|
const lines = ["---"];
|
|
6751
6965
|
for (const [key, value] of Object.entries(frontmatter)) {
|
|
6752
6966
|
if (value !== void 0 && value !== null) {
|
|
@@ -6767,7 +6981,8 @@ function formatAgentMarkdown(frontmatter, content) {
|
|
|
6767
6981
|
// src/cli/generators/mcp.ts
|
|
6768
6982
|
init_cjs_shims();
|
|
6769
6983
|
var fs7 = __toESM(require("fs"), 1);
|
|
6770
|
-
var
|
|
6984
|
+
var path8 = __toESM(require("path"), 1);
|
|
6985
|
+
var import_child_process2 = require("child_process");
|
|
6771
6986
|
|
|
6772
6987
|
// src/mcp/index.ts
|
|
6773
6988
|
init_cjs_shims();
|
|
@@ -6936,12 +7151,59 @@ function buildMCPConfig(requiredServers, target = "container") {
|
|
|
6936
7151
|
}
|
|
6937
7152
|
|
|
6938
7153
|
// src/cli/generators/mcp.ts
|
|
6939
|
-
async function generateMCPConfig(mcpServers) {
|
|
7154
|
+
async function generateMCPConfig(mcpServers, tool = DEFAULT_TOOL) {
|
|
6940
7155
|
const cwd = process.cwd();
|
|
6941
|
-
const
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
7156
|
+
const toolProfile = getToolProfile(tool);
|
|
7157
|
+
if (toolProfile.mcpFormat === "json") {
|
|
7158
|
+
const mcpConfigPath = path8.join(cwd, toolProfile.mcpConfigPath);
|
|
7159
|
+
const mcpDir = path8.dirname(mcpConfigPath);
|
|
7160
|
+
if (!fs7.existsSync(mcpDir)) {
|
|
7161
|
+
fs7.mkdirSync(mcpDir, { recursive: true });
|
|
7162
|
+
}
|
|
7163
|
+
const mcpConfig = buildMCPConfig(mcpServers, "local");
|
|
7164
|
+
const content = JSON.stringify(mcpConfig, null, 2);
|
|
7165
|
+
fs7.writeFileSync(mcpConfigPath, content, "utf-8");
|
|
7166
|
+
} else if (toolProfile.mcpFormat === "toml") {
|
|
7167
|
+
return;
|
|
7168
|
+
}
|
|
7169
|
+
}
|
|
7170
|
+
function buildCodexMCPCommand(serverName) {
|
|
7171
|
+
const serverTemplate = MCP_SERVERS[serverName];
|
|
7172
|
+
if (!serverTemplate) {
|
|
7173
|
+
throw new Error(`Unknown MCP server: ${serverName}`);
|
|
7174
|
+
}
|
|
7175
|
+
const args = ["mcp", "add", `bugzy-${serverName}`];
|
|
7176
|
+
const envVars = [];
|
|
7177
|
+
if (serverTemplate.config.env) {
|
|
7178
|
+
for (const [key, value] of Object.entries(serverTemplate.config.env)) {
|
|
7179
|
+
const match = value.match(/\$\{([A-Z_]+)\}/);
|
|
7180
|
+
if (match) {
|
|
7181
|
+
args.push("--env", `${key}=$${match[1]}`);
|
|
7182
|
+
envVars.push(match[1]);
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
}
|
|
7186
|
+
args.push("--", serverTemplate.config.command);
|
|
7187
|
+
if (serverTemplate.config.args?.length) {
|
|
7188
|
+
args.push(...serverTemplate.config.args);
|
|
7189
|
+
}
|
|
7190
|
+
return { args, envVars };
|
|
7191
|
+
}
|
|
7192
|
+
async function getConfiguredCodexMCPServers() {
|
|
7193
|
+
try {
|
|
7194
|
+
const output = (0, import_child_process2.execSync)("codex mcp list", {
|
|
7195
|
+
encoding: "utf-8",
|
|
7196
|
+
env: { ...process.env, CODEX_HOME: path8.join(process.cwd(), ".codex") },
|
|
7197
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
7198
|
+
});
|
|
7199
|
+
const lines = output.split("\n");
|
|
7200
|
+
return lines.filter((line) => line.includes("bugzy-")).map((line) => {
|
|
7201
|
+
const match = line.match(/bugzy-([a-z-]+)/);
|
|
7202
|
+
return match ? match[1] : null;
|
|
7203
|
+
}).filter((name) => name !== null);
|
|
7204
|
+
} catch {
|
|
7205
|
+
return [];
|
|
7206
|
+
}
|
|
6945
7207
|
}
|
|
6946
7208
|
function getMCPServersFromSubagents(subagents) {
|
|
6947
7209
|
const mcps = /* @__PURE__ */ new Set();
|
|
@@ -6951,13 +7213,16 @@ function getMCPServersFromSubagents(subagents) {
|
|
|
6951
7213
|
return Array.from(mcps);
|
|
6952
7214
|
}
|
|
6953
7215
|
|
|
7216
|
+
// src/cli/commands/setup.ts
|
|
7217
|
+
var import_child_process4 = require("child_process");
|
|
7218
|
+
|
|
6954
7219
|
// src/cli/generators/env.ts
|
|
6955
7220
|
init_cjs_shims();
|
|
6956
7221
|
var fs8 = __toESM(require("fs"), 1);
|
|
6957
|
-
var
|
|
7222
|
+
var path9 = __toESM(require("path"), 1);
|
|
6958
7223
|
async function generateEnvExample(mcpServers) {
|
|
6959
7224
|
const cwd = process.cwd();
|
|
6960
|
-
const envExamplePath =
|
|
7225
|
+
const envExamplePath = path9.join(cwd, ".env.example");
|
|
6961
7226
|
const header = `# ============================================
|
|
6962
7227
|
# Bugzy OSS - Environment Variables
|
|
6963
7228
|
# ============================================
|
|
@@ -7017,8 +7282,8 @@ GITHUB_TOKEN=`
|
|
|
7017
7282
|
// src/cli/generators/scaffold-playwright.ts
|
|
7018
7283
|
init_cjs_shims();
|
|
7019
7284
|
var fs9 = __toESM(require("fs"), 1);
|
|
7020
|
-
var
|
|
7021
|
-
var
|
|
7285
|
+
var path10 = __toESM(require("path"), 1);
|
|
7286
|
+
var import_child_process3 = require("child_process");
|
|
7022
7287
|
async function scaffoldPlaywrightProject(options) {
|
|
7023
7288
|
const { projectName, targetDir, skipInstall = false } = options;
|
|
7024
7289
|
console.log("\n\u{1F3AD} Scaffolding Playwright test automation project...\n");
|
|
@@ -7051,7 +7316,7 @@ async function createDirectoryStructure(targetDir) {
|
|
|
7051
7316
|
"test-runs"
|
|
7052
7317
|
];
|
|
7053
7318
|
for (const dir of directories) {
|
|
7054
|
-
const fullPath =
|
|
7319
|
+
const fullPath = path10.join(targetDir, dir);
|
|
7055
7320
|
if (!fs9.existsSync(fullPath)) {
|
|
7056
7321
|
fs9.mkdirSync(fullPath, { recursive: true });
|
|
7057
7322
|
console.log(` \u2713 Created ${dir}/`);
|
|
@@ -7060,11 +7325,11 @@ async function createDirectoryStructure(targetDir) {
|
|
|
7060
7325
|
}
|
|
7061
7326
|
async function copyTemplateFiles(targetDir, projectName) {
|
|
7062
7327
|
const possiblePaths = [
|
|
7063
|
-
|
|
7328
|
+
path10.join(__dirname, "../../templates/playwright"),
|
|
7064
7329
|
// When running from dist
|
|
7065
|
-
|
|
7330
|
+
path10.join(process.cwd(), "templates/playwright"),
|
|
7066
7331
|
// When running from project root
|
|
7067
|
-
|
|
7332
|
+
path10.join(__dirname, "../../../templates/playwright")
|
|
7068
7333
|
// When running tests
|
|
7069
7334
|
];
|
|
7070
7335
|
let templatesDir = "";
|
|
@@ -7077,9 +7342,9 @@ async function copyTemplateFiles(targetDir, projectName) {
|
|
|
7077
7342
|
if (!templatesDir) {
|
|
7078
7343
|
throw new Error("Templates directory not found. Searched paths: " + possiblePaths.join(", "));
|
|
7079
7344
|
}
|
|
7080
|
-
const initTemplatesDir =
|
|
7081
|
-
const testRunsReadmeSrc =
|
|
7082
|
-
const testRunsReadmeDest =
|
|
7345
|
+
const initTemplatesDir = path10.join(__dirname, "../../templates/init");
|
|
7346
|
+
const testRunsReadmeSrc = path10.join(initTemplatesDir, "test-runs/README.md");
|
|
7347
|
+
const testRunsReadmeDest = path10.join(targetDir, "test-runs/README.md");
|
|
7083
7348
|
if (fs9.existsSync(testRunsReadmeSrc)) {
|
|
7084
7349
|
const content = fs9.readFileSync(testRunsReadmeSrc, "utf-8");
|
|
7085
7350
|
fs9.writeFileSync(testRunsReadmeDest, content, "utf-8");
|
|
@@ -7123,8 +7388,8 @@ async function copyTemplateFiles(targetDir, projectName) {
|
|
|
7123
7388
|
}
|
|
7124
7389
|
];
|
|
7125
7390
|
for (const template of templates) {
|
|
7126
|
-
const srcPath =
|
|
7127
|
-
const destPath =
|
|
7391
|
+
const srcPath = path10.join(templatesDir, template.src);
|
|
7392
|
+
const destPath = path10.join(targetDir, template.dest);
|
|
7128
7393
|
if (fs9.existsSync(srcPath)) {
|
|
7129
7394
|
let content = fs9.readFileSync(srcPath, "utf-8");
|
|
7130
7395
|
if (template.process) {
|
|
@@ -7134,7 +7399,7 @@ async function copyTemplateFiles(targetDir, projectName) {
|
|
|
7134
7399
|
DATE: (/* @__PURE__ */ new Date()).toISOString().split("T")[0]
|
|
7135
7400
|
});
|
|
7136
7401
|
}
|
|
7137
|
-
const destDir =
|
|
7402
|
+
const destDir = path10.dirname(destPath);
|
|
7138
7403
|
if (!fs9.existsSync(destDir)) {
|
|
7139
7404
|
fs9.mkdirSync(destDir, { recursive: true });
|
|
7140
7405
|
}
|
|
@@ -7154,7 +7419,7 @@ function processTemplate(content, values) {
|
|
|
7154
7419
|
return processed;
|
|
7155
7420
|
}
|
|
7156
7421
|
async function updateGitignore2(targetDir) {
|
|
7157
|
-
const gitignorePath =
|
|
7422
|
+
const gitignorePath = path10.join(targetDir, ".gitignore");
|
|
7158
7423
|
const playwrightEntries = `
|
|
7159
7424
|
# Playwright
|
|
7160
7425
|
test-results/
|
|
@@ -7174,7 +7439,7 @@ tests/.auth/
|
|
|
7174
7439
|
}
|
|
7175
7440
|
}
|
|
7176
7441
|
async function createPackageJson(targetDir, projectName) {
|
|
7177
|
-
const packageJsonPath =
|
|
7442
|
+
const packageJsonPath = path10.join(targetDir, "package.json");
|
|
7178
7443
|
const recommendedDeps = {
|
|
7179
7444
|
"@playwright/test": "^1.48.0",
|
|
7180
7445
|
"@types/node": "^20.0.0",
|
|
@@ -7230,7 +7495,7 @@ async function installDependencies(targetDir) {
|
|
|
7230
7495
|
console.log(`
|
|
7231
7496
|
\u{1F4E6} Installing dependencies using ${packageManager}...`);
|
|
7232
7497
|
const installCommand = packageManager === "pnpm" ? "pnpm install" : packageManager === "yarn" ? "yarn install" : "npm install";
|
|
7233
|
-
(0,
|
|
7498
|
+
(0, import_child_process3.execSync)(installCommand, {
|
|
7234
7499
|
cwd: targetDir,
|
|
7235
7500
|
stdio: "inherit"
|
|
7236
7501
|
});
|
|
@@ -7241,17 +7506,17 @@ async function installDependencies(targetDir) {
|
|
|
7241
7506
|
}
|
|
7242
7507
|
}
|
|
7243
7508
|
function detectPackageManager(targetDir) {
|
|
7244
|
-
if (fs9.existsSync(
|
|
7509
|
+
if (fs9.existsSync(path10.join(targetDir, "pnpm-lock.yaml"))) {
|
|
7245
7510
|
return "pnpm";
|
|
7246
7511
|
}
|
|
7247
|
-
if (fs9.existsSync(
|
|
7512
|
+
if (fs9.existsSync(path10.join(targetDir, "yarn.lock"))) {
|
|
7248
7513
|
return "yarn";
|
|
7249
7514
|
}
|
|
7250
7515
|
return "npm";
|
|
7251
7516
|
}
|
|
7252
7517
|
function isPlaywrightScaffolded(targetDir) {
|
|
7253
|
-
const playwrightConfig =
|
|
7254
|
-
const testsDir =
|
|
7518
|
+
const playwrightConfig = path10.join(targetDir, "playwright.config.ts");
|
|
7519
|
+
const testsDir = path10.join(targetDir, "tests");
|
|
7255
7520
|
return fs9.existsSync(playwrightConfig) && fs9.existsSync(testsDir);
|
|
7256
7521
|
}
|
|
7257
7522
|
|
|
@@ -7295,9 +7560,26 @@ async function setupProject(cliArgs = []) {
|
|
|
7295
7560
|
async function firstTimeSetup(cliSubagents) {
|
|
7296
7561
|
console.log(getBanner());
|
|
7297
7562
|
console.log(import_chalk2.default.cyan(" Project Setup\n"));
|
|
7563
|
+
const toolOptions = getToolOptions();
|
|
7564
|
+
const { selectedTool } = await import_inquirer.default.prompt([{
|
|
7565
|
+
type: "list",
|
|
7566
|
+
name: "selectedTool",
|
|
7567
|
+
message: "Which AI coding assistant do you use?",
|
|
7568
|
+
choices: toolOptions.map((opt) => ({
|
|
7569
|
+
name: opt.hint ? `${opt.label} - ${import_chalk2.default.gray(opt.hint)}` : opt.label,
|
|
7570
|
+
value: opt.value
|
|
7571
|
+
})),
|
|
7572
|
+
default: DEFAULT_TOOL
|
|
7573
|
+
}]);
|
|
7574
|
+
const tool = selectedTool;
|
|
7575
|
+
const toolProfile = getToolProfile(tool);
|
|
7576
|
+
console.log(import_chalk2.default.gray(`
|
|
7577
|
+
\u2713 Using ${toolProfile.name}
|
|
7578
|
+
`));
|
|
7298
7579
|
let spinner = (0, import_ora2.default)("Creating project structure").start();
|
|
7299
|
-
await createProjectStructure();
|
|
7300
|
-
|
|
7580
|
+
await createProjectStructure(tool);
|
|
7581
|
+
const toolDirName = path11.dirname(toolProfile.commandsDir);
|
|
7582
|
+
spinner.succeed(import_chalk2.default.green(`Created .bugzy/ and ${toolDirName}/ directories`));
|
|
7301
7583
|
const subagents = {};
|
|
7302
7584
|
if (cliSubagents) {
|
|
7303
7585
|
console.log(import_chalk2.default.cyan("\nConfiguring subagents from CLI arguments:\n"));
|
|
@@ -7355,15 +7637,19 @@ async function firstTimeSetup(cliSubagents) {
|
|
|
7355
7637
|
}
|
|
7356
7638
|
}
|
|
7357
7639
|
spinner = (0, import_ora2.default)("Saving configuration").start();
|
|
7358
|
-
const projectName =
|
|
7359
|
-
const config = createDefaultConfig(projectName);
|
|
7640
|
+
const projectName = path11.basename(process.cwd());
|
|
7641
|
+
const config = createDefaultConfig(projectName, tool);
|
|
7360
7642
|
config.subagents = subagents;
|
|
7361
7643
|
saveConfig(config);
|
|
7362
7644
|
spinner.succeed(import_chalk2.default.green("Saved to .bugzy/config.json"));
|
|
7363
|
-
await regenerateAll(subagents);
|
|
7364
|
-
spinner = (0, import_ora2.default)(
|
|
7365
|
-
|
|
7366
|
-
|
|
7645
|
+
await regenerateAll(subagents, tool);
|
|
7646
|
+
spinner = (0, import_ora2.default)(`Creating ${toolProfile.memoryFile}`).start();
|
|
7647
|
+
if (tool === "claude-code") {
|
|
7648
|
+
await generateClaudeMd();
|
|
7649
|
+
} else {
|
|
7650
|
+
await generateAgentsMd();
|
|
7651
|
+
}
|
|
7652
|
+
spinner.succeed(import_chalk2.default.green(`Created ${toolProfile.memoryFile}`));
|
|
7367
7653
|
spinner = (0, import_ora2.default)("Updating .gitignore").start();
|
|
7368
7654
|
await updateGitignore();
|
|
7369
7655
|
spinner.succeed(import_chalk2.default.green("Updated .gitignore"));
|
|
@@ -7390,11 +7676,38 @@ async function reconfigureProject() {
|
|
|
7390
7676
|
console.error(import_chalk2.default.red("Error: Could not load existing configuration"));
|
|
7391
7677
|
process.exit(1);
|
|
7392
7678
|
}
|
|
7679
|
+
const currentTool = getToolFromConfig(existingConfig);
|
|
7680
|
+
const currentToolProfile = getToolProfile(currentTool);
|
|
7393
7681
|
console.log(import_chalk2.default.gray("Current configuration:"));
|
|
7682
|
+
console.log(import_chalk2.default.gray(` Tool: ${currentToolProfile.name}`));
|
|
7394
7683
|
for (const [role, integration] of Object.entries(existingConfig.subagents)) {
|
|
7395
7684
|
console.log(import_chalk2.default.gray(` \u2022 ${role}: ${integration}`));
|
|
7396
7685
|
}
|
|
7397
7686
|
console.log();
|
|
7687
|
+
const toolOptions = getToolOptions();
|
|
7688
|
+
const { changeTool } = await import_inquirer.default.prompt([{
|
|
7689
|
+
type: "confirm",
|
|
7690
|
+
name: "changeTool",
|
|
7691
|
+
message: `Keep using ${currentToolProfile.name}?`,
|
|
7692
|
+
default: true
|
|
7693
|
+
}]);
|
|
7694
|
+
let tool = currentTool;
|
|
7695
|
+
if (!changeTool) {
|
|
7696
|
+
const { selectedTool } = await import_inquirer.default.prompt([{
|
|
7697
|
+
type: "list",
|
|
7698
|
+
name: "selectedTool",
|
|
7699
|
+
message: "Which AI coding assistant do you want to use?",
|
|
7700
|
+
choices: toolOptions.map((opt) => ({
|
|
7701
|
+
name: opt.hint ? `${opt.label} - ${import_chalk2.default.gray(opt.hint)}` : opt.label,
|
|
7702
|
+
value: opt.value
|
|
7703
|
+
})),
|
|
7704
|
+
default: currentTool
|
|
7705
|
+
}]);
|
|
7706
|
+
tool = selectedTool;
|
|
7707
|
+
console.log(import_chalk2.default.gray(`
|
|
7708
|
+
\u2713 Switching to ${getToolProfile(tool).name}
|
|
7709
|
+
`));
|
|
7710
|
+
}
|
|
7398
7711
|
const allSubAgents = getAllSubAgents();
|
|
7399
7712
|
const newSubagents = {};
|
|
7400
7713
|
for (const subagent of allSubAgents) {
|
|
@@ -7470,13 +7783,19 @@ async function reconfigureProject() {
|
|
|
7470
7783
|
}
|
|
7471
7784
|
}
|
|
7472
7785
|
let spinner = (0, import_ora2.default)("Updating configuration").start();
|
|
7786
|
+
existingConfig.tool = tool;
|
|
7473
7787
|
existingConfig.subagents = newSubagents;
|
|
7474
7788
|
await saveConfig(existingConfig);
|
|
7475
7789
|
spinner.succeed(import_chalk2.default.green("Updated .bugzy/config.json"));
|
|
7476
|
-
await regenerateAll(newSubagents);
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
|
|
7790
|
+
await regenerateAll(newSubagents, tool);
|
|
7791
|
+
const toolProfile = getToolProfile(tool);
|
|
7792
|
+
spinner = (0, import_ora2.default)(`Creating ${toolProfile.memoryFile}`).start();
|
|
7793
|
+
if (tool === "claude-code") {
|
|
7794
|
+
await generateClaudeMd();
|
|
7795
|
+
} else {
|
|
7796
|
+
await generateAgentsMd();
|
|
7797
|
+
}
|
|
7798
|
+
spinner.succeed(import_chalk2.default.green(`Created ${toolProfile.memoryFile}`));
|
|
7480
7799
|
console.log(import_chalk2.default.green.bold("\n\u2705 Reconfiguration complete!\n"));
|
|
7481
7800
|
console.log(import_chalk2.default.yellow("Next steps:"));
|
|
7482
7801
|
console.log(import_chalk2.default.white("1. Check .env.example for new required secrets"));
|
|
@@ -7484,23 +7803,52 @@ async function reconfigureProject() {
|
|
|
7484
7803
|
console.log(import_chalk2.default.white("3. Run:"), import_chalk2.default.cyan("bugzy"));
|
|
7485
7804
|
console.log();
|
|
7486
7805
|
}
|
|
7487
|
-
async function regenerateAll(subagents) {
|
|
7806
|
+
async function regenerateAll(subagents, tool = DEFAULT_TOOL) {
|
|
7807
|
+
const toolProfile = getToolProfile(tool);
|
|
7488
7808
|
let spinner = (0, import_ora2.default)("Generating task commands").start();
|
|
7489
|
-
await generateCommands(subagents);
|
|
7809
|
+
await generateCommands(subagents, tool);
|
|
7490
7810
|
const taskCount = Object.keys((init_tasks(), __toCommonJS(tasks_exports)).TASK_TEMPLATES).length;
|
|
7491
|
-
spinner.succeed(import_chalk2.default.green(`Generated ${taskCount} task commands in .
|
|
7811
|
+
spinner.succeed(import_chalk2.default.green(`Generated ${taskCount} task commands in ${toolProfile.commandsDir}/`));
|
|
7492
7812
|
spinner = (0, import_ora2.default)("Generating subagent configurations").start();
|
|
7493
|
-
await generateAgents(subagents);
|
|
7813
|
+
await generateAgents(subagents, tool);
|
|
7494
7814
|
const subagentCount = Object.keys(subagents).length;
|
|
7495
|
-
spinner.succeed(import_chalk2.default.green(`Generated ${subagentCount} subagent configurations in .
|
|
7815
|
+
spinner.succeed(import_chalk2.default.green(`Generated ${subagentCount} subagent configurations in ${toolProfile.agentsDir}/`));
|
|
7496
7816
|
spinner = (0, import_ora2.default)("Generating MCP configuration").start();
|
|
7497
7817
|
const mcpServers = getMCPServersFromSubagents(subagents);
|
|
7498
|
-
await generateMCPConfig(mcpServers);
|
|
7499
|
-
|
|
7818
|
+
await generateMCPConfig(mcpServers, tool);
|
|
7819
|
+
if (toolProfile.mcpFormat === "json") {
|
|
7820
|
+
spinner.succeed(import_chalk2.default.green(`Generated ${toolProfile.mcpConfigPath} (${mcpServers.length} servers)`));
|
|
7821
|
+
} else if (toolProfile.mcpFormat === "toml") {
|
|
7822
|
+
spinner.succeed(import_chalk2.default.green("MCP configuration ready"));
|
|
7823
|
+
await setupCodexMCP(mcpServers);
|
|
7824
|
+
}
|
|
7500
7825
|
spinner = (0, import_ora2.default)("Creating environment template").start();
|
|
7501
7826
|
await generateEnvExample(mcpServers);
|
|
7502
7827
|
spinner.succeed(import_chalk2.default.green("Created .env.example"));
|
|
7503
7828
|
}
|
|
7829
|
+
async function setupCodexMCP(mcpServers) {
|
|
7830
|
+
const existingServers = await getConfiguredCodexMCPServers();
|
|
7831
|
+
const newServers = mcpServers.filter((s) => !existingServers.includes(s));
|
|
7832
|
+
if (newServers.length === 0) {
|
|
7833
|
+
console.log(import_chalk2.default.gray("\n\u2713 All MCP servers already configured"));
|
|
7834
|
+
return;
|
|
7835
|
+
}
|
|
7836
|
+
console.log();
|
|
7837
|
+
for (const serverName of newServers) {
|
|
7838
|
+
const spinner = (0, import_ora2.default)(`Configuring ${serverName}`).start();
|
|
7839
|
+
try {
|
|
7840
|
+
const { args } = buildCodexMCPCommand(serverName);
|
|
7841
|
+
(0, import_child_process4.execSync)(["codex", ...args].join(" "), {
|
|
7842
|
+
stdio: "pipe",
|
|
7843
|
+
env: { ...process.env, CODEX_HOME: path11.join(process.cwd(), ".codex") }
|
|
7844
|
+
});
|
|
7845
|
+
spinner.succeed(import_chalk2.default.green(`Configured ${serverName}`));
|
|
7846
|
+
} catch (error) {
|
|
7847
|
+
spinner.fail(import_chalk2.default.red(`Failed to configure ${serverName}`));
|
|
7848
|
+
console.error(import_chalk2.default.gray(error.message));
|
|
7849
|
+
}
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7504
7852
|
|
|
7505
7853
|
// src/cli/index.ts
|
|
7506
7854
|
process.on("uncaughtException", (error) => {
|