| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Invoke | /dev:bugfix |
/dev:bugfix โ ๋ฒ๊ทธ ํ๋๋ฅผ ๋๊น์ง ์ฑ ์์ง๋ "์๋ฆฌ ์๋ํ"#
๋ฒ๊ทธ ์ ๊ณ ๋ถํฐ ์ฝ๋ ์์ , ํ ์คํธ, PR ๋ณํฉ๊น์ง ํ ๋ฒ์ ์ฒ๋ฆฌํ๋ ์ํฌํ๋ก
ํ๋ง๋๋ก#
๋ฒ๊ทธ ํ๋๋ฅผ ๋ฐ๊ฒฌํ์ ๋, ์ ์ โ ์์ธ ๋ถ์ โ ์์ โ ๊ฒ์ฆ(ํ ์คํธ) โ ๋ณํฉ๊น์ง ์ ๊ณผ์ ์ ํ ๋ช ๋ น์ผ๋ก ์ฒ๋ฆฌํด ์ฃผ๋ "์๋ฆฌ ๊ธฐ์ฌ"์ ๋๋ค. ๊ฐ์ ์ ํ์ด ๊ณ ์ฅ ๋ฌ์ ๋, ์ ์๋ง ํ๋ฉด ๊ธฐ์ฌ๋์ด ์์ ๊ณ ์น๊ณ ์ ์๋ํ๋์ง ํ์ธ๊น์ง ํ ๋ค ๋ง๋ฌด๋ฆฌํด ์ฃผ๋ ๊ฒ๊ณผ ๊ฐ์์.
๋๊ฐยท์ธ์ ์ฐ๋์#
- ์ด๋ฏธ ๋ฑ๋ก๋ ๋ฒ๊ทธ ์ด์ ๋ฒํธ๊ฐ ์๊ณ , ๊ทธ ๋ฒ๊ทธ๋ฅผ ๊ณ ์ณ์ ๋ง๋ฌด๋ฆฌํ๊ณ ์ถ์ ๋
- ์์ง ์ด์๊ฐ ์๊ณ , ์คํฌ๋ฆฐ์ท์ด๋ ์ค๋ช
๋ง ์๋ ์ ๋ฒ๊ทธ๋ฅผ ์ฒ์๋ถํฐ ์ ์ํด์ ๊ณ ์น๊ณ ์ถ์ ๋ (
--new) - ๊ธํ ํซํฝ์ค๋ผ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํด์ผ ํ ๋ (
--skip-tests๊ฐ์ ์ต์ ์ ๊ณต)
๐ ๋จ, ๋ฒ๊ทธ(Bug) ์ ํ ์ด์๋ง ์ฒ๋ฆฌํฉ๋๋ค. ์ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ๋ค๋ฅธ ๋ช
๋ น(/dev:issue)์ ์๋๋ค.
๋ฌด์์ ํด์ฃผ๋์#
- ์์ ์ฉ ๋ธ๋์น๊ฐ
fix/{๋ฒํธ}-{์ค๋ช }ํ์์ผ๋ก ์๋ ์์ฑ๋ฉ๋๋ค - ๋ฒ๊ทธ ์์ธ์ ์ฐพ์ ์ฝ๋๋ฅผ ๊ณ ์น๊ณ , ์์ ๋ด์ญ์ ์ปค๋ฐ์ผ๋ก ์ฐจ๊ณก์ฐจ๊ณก ๊ธฐ๋กํฉ๋๋ค
- ๊ฐ์ ๋ฒ๊ทธ๊ฐ ๋ค์ ์ ์๊ธฐ๋๋ก ํ ์คํธ(ํ๋ก ํธ์๋ + ๋ฐฑ์๋) ๋ฅผ ์์ฑํ๊ณ ๋ชจ๋ ํต๊ณผ์ํต๋๋ค
- PR(์ฝ๋ ๋ฆฌ๋ทฐ ์์ฒญ) ์ ๋ง๋ค์ด ์ด์์ ์๋ ์ฐ๊ฒฐํ๊ณ , ๋ฆฌ๋ทฐ ํ ๋ณํฉ๊น์ง ์งํํฉ๋๋ค
- ์งํ ์ํฉ์ ๋ง์ถฐ ZenHub ์ด์ ์ํ๊ฐ "์งํ ์ค โ ๋ฆฌ๋ทฐ โ ์๋ฃ(Closed)"๋ก ์๋ ์ด๋ํฉ๋๋ค
์ด๋ป๊ฒ ์ฐ๋์#
# ๊ธฐ์กด ๋ฒ๊ทธ ์ด์๋ก ์์
/dev:bugfix 123
# ์ ๋ฒ๊ทธ ๋ฆฌํฌํธ๋ถํฐ ์์ (์คํฌ๋ฆฐ์ท + ์ค๋ช
)
/dev:bugfix --new /tmp/screenshot.png " ์ฑ ํฌ๋์ "
# PR๋ง ๋ง๋ค๊ณ ๋ณํฉ์ ์ง์ (์๋ ๋ณํฉ ๋๊ธฐ)
/dev:bugfix 123 --no-merge
# ํ
์คํธ ๊ฑด๋๋ฐ๊ธฐ (๊ธํ ํซํฝ์ค์ฉ)
/dev:bugfix 123 --skip-tests
# ๊ธฐ์ค ๋ธ๋์น ๋ณ๊ฒฝ (๊ธฐ๋ณธ๊ฐ: development)
/dev:bugfix 123 --base main
issue_number(์ด์ ๋ฒํธ) ๋๋--new์ค ํ๋๋ ๋ฐ๋์ ํ์ํฉ๋๋ค--no-merge: PR๊น์ง๋ง ๋ง๋ค๊ณ ๋ณํฉ์ ์ฌ๋์ด ์ง์ ํฉ๋๋ค--skip-tests: ํ ์คํธ ์์ฑ/์คํ์ ์๋ตํฉ๋๋ค (๊ธํ ๋๋ง)--base: ์ด๋ ๋ธ๋์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ ํ ์ง ์ง์ ํฉ๋๋ค (๊ธฐ๋ณธdevelopment)
์์์ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์#
๋๋ต ๋ค์ ์์๋ก ์งํ๋ฉ๋๋ค.
-
์ํฅ ๋ฒ์ ์ ๊ฒ โ ๊ณ ์น๊ธฐ ์ ์ "์ด ๋ฒ๊ทธ๋ฅผ ๊ฑด๋๋ฆฌ๋ฉด ์ด๋๊น์ง ์ํฅ์ด ๊ฐ๋์ง"๋ฅผ ๋จผ์ ์ดํ๋๋ค. ์ํ๋๊ฐ ๋ฎ์ผ๋ฉด(LOW) ๋ฐ๋ก ์งํ, ์ค๊ฐ(MEDIUM)์ด๋ฉด ์ฌ์ฉ์์๊ฒ ํ์ธ, ๋์ผ๋ฉด(HIGH) ๋ ์ ์คํ ๋ค๋ฅธ ์ํฌํ๋ก(
/plan โ /build)๋ฅผ ๊ถํฉ๋๋ค. - ๋ฒ๊ทธ ์ ์ (
--new์ผ ๋) โ ์คํฌ๋ฆฐ์ทยท์ค๋ช ์ ๋ถ์ํด ZenHub ์ด์๋ฅผ ์๋ก ๋ง๋ญ๋๋ค. - ์ด์ ์ ๋ณด ์กฐํ โ ์ด์์ ์ ๋ชฉยท๋ด์ฉยท์ฌํ ๋ฐฉ๋ฒ์ ์ฝ์ด ์์ธ์ ๋ถ์ํฉ๋๋ค.
- ๋ธ๋์น ์์ฑ โ ์์ ์ฉ ๋ธ๋์น๋ฅผ ๋ง๋ค๊ณ ์ด์๋ฅผ "์งํ ์ค"์ผ๋ก ์ฎ๊น๋๋ค.
- ๋ฒ๊ทธ ์์ โ ๊ด๋ จ ์ฝ๋๋ฅผ ์ฐพ์ ๊ณ ์น๊ณ , ๋ณ๊ฒฝ ์ฌํญ์ ์ปค๋ฐํฉ๋๋ค.
- ๊ธฐ์กด ํ ์คํธ ํ์ธ โ ์๋๊ธฐ ์ ๊ธฐ์กด ํ ์คํธ๊ฐ ์ ๋๋์ง ๊ธฐ์ค์ ์ ์ก์ต๋๋ค.
- ํ ์คํธ ์์ฑ โ ๊ฐ์ ๋ฒ๊ทธ๊ฐ ์ฌ๋ฐํ์ง ์๋๋ก ํ๋ก ํธยท๋ฐฑ์๋ ํ ์คํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
- ํ ์คํธ ์คํยท๊ฒ์ฆ โ ๋ชจ๋ ํ ์คํธ๋ฅผ ๋๋ฆฌ๊ณ , ์คํจํ๋ฉด ์ต๋ 3๋ฒ๊น์ง ์๋ ์์ ์ ์๋ํฉ๋๋ค.
- PR ์์ฑ โ ์ฝ๋ ๋ฆฌ๋ทฐ ์์ฒญ์ ๋ง๋ค๊ณ ์ด์์ ์๋์ผ๋ก ์ฐ๊ฒฐํฉ๋๋ค(
Closes #๋ฒํธ). - ๋ณํฉยท๋ง๋ฌด๋ฆฌ โ ๋ฆฌ๋ทฐ ํ ๋ณํฉํ๋ฉด ์ด์๊ฐ ์๋์ผ๋ก "์๋ฃ(Closed)" ์ฒ๋ฆฌ๋๊ณ , ๊ธฐ์ค ๋ธ๋์น๋ฅผ ์ต์ ์ํ๋ก ์ ๋ฆฌํฉ๋๋ค.
โ๏ธ ์์ธ ์ต์ ยท์คํ ๋ช ์ธ (๊ฐ๋ฐ์ / AI ์์ด์ ํธ์ฉ)
Overview#
This workflow automates the entire bug issue fix cycle:
- Bug report creation (optional)
- Branch creation
- Bug fix work
- Unit test writing (frontend + backend)
- Test execution and verification
- PR creation and merge
Usage#
# ๊ธฐ์กด ๋ฒ๊ทธ ์ด์๋ก ์์
/dev:bugfix {issue_number}
# ์ ๋ฒ๊ทธ ๋ฆฌํฌํธ๋ถํฐ ์์
/dev:bugfix --new [์ด๋ฏธ์ง_๊ฒฝ๋ก] " ๋ฒ๊ทธ ์ค๋ช
"Parameters#
| Parameter | Required | Description |
|---|---|---|
issue_number | โ * | Existing bug issue number |
--new | โ * | New bug report creation mode |
--no-merge | โ | PR creation only (no merge) |
--skip-tests | โ | Skip tests (for urgent hotfixes) |
--base | โ | Base branch (default: development) |
*Either issue_number or --new is required
Option Examples#
# PR only (no merge)
/dev:bugfix 123 --no-merge
# Skip tests (urgent)
/dev:bugfix 123 --skip-tests
# Change base branch
/dev:bugfix 123 --base main
# New bug + image analysis
/dev:bugfix --new /tmp/screenshot.png " App crash "Execution Flow#
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ /dev:bugfix โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Step 0: Blast Radius Analysis (before fix) โ
โ โโโ Identify all callers/dependents of affected code (Grep) โ
โ โโโ Map test coverage of affected areas โ
โ โโโ Flag untested areas that could regress โ
โ โโโ Risk assessment: โ
โ LOW (โค5 files) โ proceed โ
โ MED (5-15 files or multi-layer) โ confirm with user โ
โ HIGH ( > 15 files or core module) โ suggest /plan โ /build โ
โ โ
โ Step 1: Bug Report Creation (with --new option) โ
โ โโโ Call /bug-report (image analysis) โ
โ โโโ Create ZenHub issue โ
โ โโโ Result: obtain issue_number โ
โ โ
โ Step 2: Query Issue Info โ
โ โโโ mcp__zenhub__searchLatestIssues โ
โ โโโ Extract issue type, title, body โ
โ โโโ Analyze bug cause โ
โ โ
โ Step 3: Branch Creation โ
โ โโโ fix/{number}-{slug} format โ
โ โโโ issue-state-agent โ " In Progress " โ
โ โโโ Based on development branch โ
โ โ
โ Step 4: Bug Fix Work โ
โ โโโ Analyze issue body โ identify cause โ
โ โโโ Search related code โ
โ โโโ Fix code โ
โ โโโ Create incremental commits โ
โ โ
โ Step 4.5: Existing Test Verification (Baseline) โ
โ โโโ Run existing tests for related packages โ
โ โโโ On failure โ fix code or existing tests first โ
โ โโโ Record baseline pass rate โ
โ โ
โ Step 5: Test Writing (required, delegated to cc-flutter-dev) โ
โ โโโ Frontend tests โ
โ โ โโโ unit-test-agent โ UseCase parameter passing tests โ
โ โ โโโ bloc-test-agent โ BLoC state transition verification โ
โ โ โโโ widget-test-agent โ State copyWith rendering tests โ
โ โโโ Backend tests โ
โ โ โโโ Endpoint auth/permission tests โ
โ โ โโโ Filter parameter passing integration tests โ
โ โ โโโ Service logic unit tests (if applicable) โ
โ โโโ Create test commits โ
โ โ
โ Step 6: Test Execution and Regression Verification โ
โ โโโ Run all tests (existing + new) โ
โ โโโ Attempt auto-fix on failure (up to 3 times) โ
โ โโโ Verify baseline pass rate maintained โ
โ โ
โ Step 7: PR Creation โ
โ โโโ gh pr create โ
โ โโโ issue-state-agent โ " Review " โ
โ โโโ Auto-link issue (Closes #{number}) โ
โ โ
โ Step 8: Merge (merge = Close, unless --no-merge) โ
โ โโโ Wait for review โ
โ โโโ Squash merge โ
โ โโโ Issue auto-Close via GitHub " Closes # " keyword โ
โ โโโ โญ Verify closed (GitHub + ZenHub) + fallback โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโDetailed Implementation#
Step 0: Blast Radius Analysis#
Run before creating a branch to assess fix complexity and risk:
// 1. Identify affected code area from issue description
const affectedFiles = await Grep({ pattern: bugPattern, output_mode: " files_with_matches " });
// 2. Find all callers/dependents
const dependents = [];
for (const file of affectedFiles) {
const exports = extractExports(file); // classes, functions, mixins
for (const symbol of exports) {
const callers = await Grep({ pattern: symbol, output_mode: " files_with_matches " });
dependents.push(...callers);
}
}
const uniqueDependents = [...new Set(dependents)];
// 3. Map test coverage
const testFiles = await Glob({ pattern: " test/**/*_test.dart " });
const coveredFiles = matchSourceToTest(uniqueDependents, testFiles);
const uncoveredFiles = uniqueDependents.filter(f = > !coveredFiles.includes(f));
// 4. Risk assessment
const fileCount = uniqueDependents.length;
const layerCount = countLayers(uniqueDependents); // presentation, domain, data, backend
let riskLevel;
if (fileCount < = 5 & & layerCount < = 1) {
riskLevel = " LOW " ; // โ proceed directly
} else if (fileCount < = 15 || layerCount < = 2) {
riskLevel = " MEDIUM " ; // โ confirm with user
} else {
riskLevel = " HIGH " ; // โ suggest /plan โ /build workflow
}Output:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Blast Radius Analysis โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ Affected files: {fileCount} โ
โ Layers touched: {layers} โ
โ Test coverage: {coveredCount}/{totalCount} files covered โ
โ Uncovered areas: โ
โ - {uncoveredFile1} โ
โ - {uncoveredFile2} โ
โ Risk Level: {LOW|MEDIUM|HIGH} โ
โ โ
โ {recommendation} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ- LOW: ์๋ ์งํ
- MEDIUM: ์ฌ์ฉ์์๊ฒ ํ์ธ ์์ฒญ ("Proceed with bugfix?" / "Switch to /plan โ /build?")
- HIGH:
/plan โ /build์ํฌํ๋ก์ฐ ๊ถ์ฅ (๊ตฌ์กฐ์ ๋ณ๊ฒฝ์ด ํ์ํ ๊ฐ๋ฅ์ฑ ๋์)
Step 1: Bug Report Creation (Optional)#
โ ๏ธ ์ด์(๋ฒ๊ทธ ๋ฆฌํฌํธ) ์์ฑ์ ZenHub(GitHub)์๋ง ํฉ๋๋ค. Jira์๋ ์ด์๋ฅผ ๋ง๋ค์ง ์์ผ๋ฉฐ, Jira๋ ์์ฑ๋ ์ด์๋ฅผ ์กฐํยทํ์ธํ๋ ์ฝ๊ธฐ ์ ์ฉ ์ฉ๋๋ก๋ง ์๋๋ค. ์ ์ฑ : SKILL.md โ "Issue Tracker Policy".
When --new option is provided:
// /bug-report ์คํฌ ํธ์ถ
const bugReport = await Skill({
skill: " bug-report " ,
args: `${imagePath} " ${description} " `
});
// Extract created issue number
const issueNumber = bugReport.issue_number;Step 2: Query Issue Info#
// Query issue info
const issueResult = await mcp__zenhub__searchLatestIssues({
query: issue_number.toString()
});
const issue = issueResult.find(i = > i.number === issue_number);
// Extract bug info
const bugInfo = {
id: issue.id,
number: issue.number,
title: issue.title,
body: issue.body, // Includes reproduction steps, expected/actual results
severity: extractSeverity(issue.labels),
area: extractArea(issue.labels),
};Step 3: Branch Creation#
// Generate branch name: fix/{number}-{slug}
// createSlug romanizes non-ASCII and never returns ' ' (see issue-branch-agent.md)
const slug = createSlug(bugInfo.title, " fix " );
const branchName = `fix/${bugInfo.number}-${slug}`;
// Defense-in-depth (LANG-05): a Korean-only title must not yield " fix/30- " .
if (!slug || branchName.endsWith( " - " )) throw new Error(`๋น slug โ ๋ธ๋์น๋ช
๋น์ ์(${branchName})`);
// Create branch
await Bash(`git checkout -b ${branchName} origin/development`);
// Pipeline move: In Progress (fail-closed id ํด์ โ undefined silent no-op ๋ฐฉ์ง)
const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const inProgress = workspace.pipelines.find(p = > p.name === " In Progress " );
if (!inProgress) throw new Error(` ' In Progress ' ํ์ดํ๋ผ์ธ ์์. ๋ผ์ด๋ธ: ${workspace.pipelines.map(p = > p.name).join( " , " )}`);
await mcp__zenhub__moveIssueToPipeline({ issueId: bugInfo.id, pipelineId: inProgress.id });
// ์คํ๋ฆฐํธ ๋ฐฐ์ (ํ์๋ผ์ธ ๊ฐ์์ฑ) โ ๋ฒ๊ทธ ์ด์๋ฅผ ํ์ฑ ์คํ๋ฆฐํธ์ ์ฌ๋ ค ๋ก๋๋งต/๋ฒ๋ค์ด์ ๋
ธ์ถ.
// ๊ธฐ๋ณธ on, --no-sprint ๋ก opt-out. ์
๋ ํฐ: rules/zenhub-conventions.md โ " Sprint Selector Resolution " .
if (!options.noSprint) {
const sprint = options.sprint === " next "
? await mcp__zenhub__getUpcomingSprint()
: await mcp__zenhub__getSprint(); // id ์์ = ํ์ฑ
if (sprint?.id) await mcp__zenhub__addIssuesToSprints({ issueIds: [bugInfo.id], sprintIds: [sprint.id] });
}Step 4: Bug Fix Work#
// Bug cause analysis
// 1. Identify reproduction steps from issue body
// 2. Search related code (Grep, Glob)
// 3. Infer cause
// Code fix
// - Modify related files
// - Create incremental commits
await Bash(`git commit -m " fix(${scope}): ๐ ${bugInfo.title} " `);Step 5: Unit Test Writing (Required)#
Frontend + backend unit tests must be written before PR creation.
5-1. Frontend Tests
Write the following tests depending on the changed code area:
// State tests: copyWith, nullable field clearing, Equatable, etc.
// File: test/presentation/bloc/{feature}_state_test.dart
// - Verify initial state default values
// - Verify copyWith updates
// - Verify nullable field clearing (clearXxx flags)
// - Verify value preservation (existing values maintained on copyWith() call)
// BLoC tests: event handlers โ state transitions
// File: test/presentation/bloc/{feature}_bloc_test.dart
// - Verify per-event state transitions with blocTest()
// - Mock Repository setUp
// - Set initial state with seed()
// - Verify sequential state changes with expect()
// UseCase tests: parameter passing and error handling
// File: test/domain/usecase/{usecase}_test.dart
// - Verify correct parameter passing on Repository calls (verify)
// - Separate success/failure cases
// - Verify Params Equatable5-2. Backend Tests
// Integration tests: using withServerpod()
// File: backend/kobic_server/test/integration/{feature}_test.dart
// - Auth test: reject unauthenticated access to requireLogin endpoints
// - Filter parameter passing test: verify correct calls per filter
// - Combined filter test: apply all filters simultaneously
// - Pagination test: pass limit/offset parameters
// Service unit tests (on business logic changes)
// File: backend/kobic_server/test/unit/{feature}/{service}_test.dart5-3. Test Fixture Writing Rules
// Serverpod generated DTO classes have many required fields
// โ Create test fixtures via helper functions
// e.g.: _createTestBook(), _createCategory()
// Mock generation: @GenerateNiceMocks + build_runner
// โ Must regenerate mocks after writing test files
await Bash(`melos exec --scope=${package} -- dart run build_runner build -d`);5-4. Test Commit
await Bash(`git commit -m " test(${scope}): โ
${bugInfo.title} ํ
์คํธ ์ถ๊ฐ " `);Step 6: Test Execution and Verification#
// Run all tests
await Bash(`melos exec --scope=${package} -- flutter test`);
// Attempt auto-fix on failure
if (testFailed) {
// Fix fixtures (generated class signature mismatches, etc.)
// Build transitive dependencies (missing .g.dart, .module.dart)
// Regenerate mocks
// Re-run
}
// Verify all tests pass (required)
// Do not proceed with PR creation if tests failStep 7: PR Creation#
// Create PR
const prTitle = `fix(${scope}): ๐ ${bugInfo.title}`;
const prBody = `
## Summary
- ${bugInfo.title} bug fix
## Changes
- ${changesSummary}
## Test Plan
- [ ] Reproduction steps verified
- [ ] Tests passed
Closes #${bugInfo.number}
๐ค Generated with [Claude Code](https://claude.com/claude-code)
`;
await Bash(`gh pr create --title " ${prTitle} " --body " ${prBody} " `);
// Pipeline move: Review
await mcp__zenhub__moveIssueToPipeline({
issueId: bugInfo.id,
pipelineId: reviewPipelineId
});Step 8: Merge (merge = Close)#
// Squash merge โ issue auto-Close via GitHub " Closes # " keyword โ ZenHub syncs to Closed
// Never move to Done (Done โ closed)
await Bash(`gh pr merge --squash --delete-branch`);
// โญ Closure verification + fallback (ZenHub two-state model)
const ghState = (await Bash(`gh issue view ${bugInfo.number} --json state -q .state`)).trim();
if (ghState !== " CLOSED " ) {
await Bash(`gh issue close ${bugInfo.number} --reason completed`);
}
const closed = await mcp__zenhub__searchClosedIssues({ query: `#${bugInfo.number}` });
if (!closed.find(i = > i.number === bugInfo.number)) {
await mcp__zenhub__updateIssue({ issueId: bugInfo.id, state: " CLOSED " });
}
// โญ Post-merge: base ๋ธ๋์น๋ก ์ด๋ + ์ต์ ํ + ์๋ธ๋ชจ๋ ๋๊ธฐํ (ํ์)
// gh pr merge --delete-branch ๋ base๋ฅผ pull ํ์ง ์๊ณ , git pull ์ ์๋ธ๋ชจ๋ ํฌ์ธํฐ๋ง
// ๊ฐฑ์ ํ ๋ฟ ์ํนํธ๋ฆฌ๋ ์ฒดํฌ์์ํ์ง ์๋๋ค. git submodule update ๋ก base๊ฐ ๊ฐ๋ฆฌํค๋
// ์ปค๋ฐ์ ์ ๋ ฌํ๋ค (Serverpod/Melos ๋ชจ๋
ธ๋ ํฌ ๋น๋/์ฝ๋์ drift ๋ฐฉ์ง). ์๋ธ๋ชจ๋ ์์ผ๋ฉด no-op.
await Bash(`
git checkout development
git pull --ff-only origin development
git submodule sync --recursive
git submodule update --init --recursive
`);Output Format#
On Success#
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Bug Cycle Complete: #123 โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ โ
โ ๐ Bug: [Bug] ๋ก๊ทธ์ธ: ์์
๋ก๊ทธ์ธ ๋ฒํผ ๋ฏธ๋์ โ
โ ๐ฟ Branch: fix/123-social-login-button โ
โ โ
โ ๐ Commits: โ
โ 1. fix(auth): ๐ ์์
๋ก๊ทธ์ธ ๋ฒํผ ํด๋ฆญ ํธ๋ค๋ฌ ์์ โ
โ 2. test(auth): โ
์์
๋ก๊ทธ์ธ ๋ฒํผ ํ
์คํธ ์ถ๊ฐ โ
โ โ
โ โ
Tests: โ
โ - FE State: 16/16 passed โ
โ - FE BLoC: 10/10 passed โ
โ - FE UseCase: 10/10 passed โ
โ - BE Integration: 10/10 passed โ
โ โ
โ ๐ PR: #456 โ
โ - URL: https://github.com/coco-de/kobic/pull/456 โ
โ - Status: Merged โ
โ
โ โ
โ ๐ Duration: 8m 15s โ
โ ๐ Final State: CLOSED (by merge) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโOn Failure#
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Bug Cycle Failed: #123 โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฃ
โ โ
โ โ Failed at: Step 4 (Bug fix work) โ
โ โ
โ Error Details: โ
โ - Cause identification failed: additional info needed โ
โ - Related code not found โ
โ โ
โ Current State: โ
โ - Branch: fix/123-social-login (exists) โ
โ - Commits: 0 โ
โ - Pipeline: In Progress โ
โ - PR: Not created โ
โ โ
โ Recovery Options: โ
โ 1. Request additional info on the issue โ
โ 2. Manually analyze cause then retry โ
โ 3. /dev:bugfix 123 --skip-tests โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโTodoWrite Integration#
Progress Tracking#
TodoWrite([
{ content: " Bug report creation " , status: " completed " , activeForm: " Bug report creation complete " },
{ content: " Issue info query " , status: " in_progress " , activeForm: " Querying issue info " },
{ content: " Branch creation " , status: " pending " , activeForm: " Branch creation pending " },
{ content: " Bug fix work " , status: " pending " , activeForm: " Bug fix pending " },
{ content: " Unit test writing (FE+BE) " , status: " pending " , activeForm: " Test writing pending " },
{ content: " Test execution and verification " , status: " pending " , activeForm: " Test execution pending " },
{ content: " PR creation " , status: " pending " , activeForm: " PR creation pending " },
{ content: " Merge and close " , status: " pending " , activeForm: " Merge pending " },
]);Error Handling#
Step-by-Step Recovery Strategy#
| Failed Step | State | Recovery Method |
|---|---|---|
| Blast radius | No changes | Retry or switch to /plan โ /build |
| Bug report | No changes | Retry /bug-report |
| Branch creation | Issue exists | Retry |
| Bug fix | Branch exists | Manual fix then retry |
| Test writing | Code modified | Fix fixtures, regenerate mocks, build transitive deps |
| Test execution | Tests written | Manual test fix or --skip-tests |
| PR creation | Tests passed | Run gh pr create manually |
| Merge | PR exists | Wait for CI pass then retry |
Key Rules#
- Verify Bug Issue Type: Only process Bug type issues
- Branch Naming: Follow
fix/{number}-{slug}format - Commit Message:
fix({scope}): ๐ {description}format - Tests Required (before PR): Frontend (State/BLoC/UseCase) + Backend (integration/unit) tests must be written and passed before PR creation
- Separate Test Commits: Separate fix commits from test commits for easier review
- Issue Link: Include
Closes #{number}in PR - State Tracking: Update Pipeline state at every step
Related Commands#
/bug-report: Bug report creation/dev:issue: General issue cycle/zenhub:manage: ZenHub pipeline management
Related Agents#
issue-state-agent: Issue state managementimplementation-agent: Code implementationtest-runner-agent: Test executionpr-lifecycle-agent: PR management