LogoSkills

dev:issue

This skill automates the entire development cycle from branch creation to merge for a single ZenHub/GitHub issue.

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/dev:issue

/dev:issue โ€” ์ด์Šˆ ํ•˜๋‚˜, ๋๊นŒ์ง€ ์ž๋™ ์ฒ˜๋ฆฌ#

ํ•œ๋งˆ๋””๋กœ#

์ด์Šˆ ๋ฒˆํ˜ธ ํ•˜๋‚˜๋งŒ ์•Œ๋ ค์ฃผ๋ฉด ๋ธŒ๋žœ์น˜ ๋งŒ๋“ค๊ธฐ โ†’ ์ฝ”๋“œ ๊ตฌํ˜„ โ†’ ํ…Œ์ŠคํŠธ โ†’ PR ์ƒ์„ฑ โ†’ ์ฝ”๋“œ ๋ฆฌ๋ทฐ โ†’ ๋จธ์ง€(์™„๋ฃŒ ์ฒ˜๋ฆฌ) ๊นŒ์ง€์˜ ๊ฐœ๋ฐœ ๊ณผ์ •์„ ์ž๋™์œผ๋กœ ์ง„ํ–‰ํ•ด ์ฃผ๋Š” ๋ช…๋ น์ž…๋‹ˆ๋‹ค. ๊ณต์žฅ์˜ ์ปจ๋ฒ ์ด์–ด ๋ฒจํŠธ์ฒ˜๋Ÿผ, ์›์žฌ๋ฃŒ(์ด์Šˆ) ํ•˜๋‚˜๋ฅผ ์˜ฌ๋ ค๋†“์œผ๋ฉด ์™„์„ฑํ’ˆ(๋จธ์ง€๋œ ์ฝ”๋“œ)์ด ๋‚˜์˜ค๋Š” ์‹์ด์—์š”. ๋‹จ, ๋งˆ์ง€๋ง‰ "์ตœ์ข… ํ•ฉ์น˜๊ธฐ"๋Š” ์‚ฌ๋žŒ์ด ์ง์ ‘ ์Šน์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์•ผ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

๋ˆ„๊ฐ€ยท์–ธ์ œ ์“ฐ๋‚˜์š”#

  • ์ •ํ•ด์ง„ ์ด์Šˆ(์ž‘์—… ํ•ญ๋ชฉ) ํ•˜๋‚˜๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฐœ๋ฐœ์ž
  • "25๋ฒˆ ์ด์Šˆ ์ž‘์—…ํ•ด์ค˜"์ฒ˜๋Ÿผ ๋‹จ์ผ ์ž‘์—… ๋‹จ์œ„๋ฅผ ๋งก๊ธฐ๊ณ  ์‹ถ์„ ๋•Œ
  • ๊ธ‰ํ•œ ํ•ซํ”ฝ์Šค๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๋•Œ (ํ…Œ์ŠคํŠธ๋‚˜ ๋ฆฌ๋ทฐ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋Š” ์˜ต์…˜ ์ œ๊ณต)

์—ฌ๋Ÿฌ ์ด์Šˆ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋Œ๋ฆฌ๊ฑฐ๋‚˜, ์ž‘์—… ๋‚ด์šฉ์„ ์ƒˆ๋กœ ์ •ํ•ด์„œ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” /dev:runยท/dev:batch ๊ฐ™์€ ๋‹ค๋ฅธ ๋ช…๋ น์„ ์”๋‹ˆ๋‹ค.

๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”#

  • ์ด์Šˆ ์ „์šฉ ์ž‘์—… ๋ธŒ๋žœ์น˜(feature/{๋ฒˆํ˜ธ}-{์„ค๋ช…})๋ฅผ ๋งŒ๋“ค๊ณ , ZenHub ์ƒํƒœ๋ฅผ "In Progress"๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.
  • ํ™”๋ฉด ๊ด€๋ จ ์ด์Šˆ๋ฉด BDD ์‹œ๋‚˜๋ฆฌ์˜ค(๋™์ž‘ ๋ช…์„ธ์„œ)๋ฅผ ์ž๋™์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ด์Šˆ ๋‚ด์šฉ์„ ๋ถ„์„ํ•ด ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , ์ž‘์—… ๋‹จ์œ„๋งˆ๋‹ค ์ปค๋ฐ‹์„ ๋‚จ๊น๋‹ˆ๋‹ค.
  • ํ™”๋ฉด ๊ธฐ๋Šฅ์ด๋ฉด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐยท์‹ค๊ธฐ๊ธฐ์— ์•ฑ์„ ๋„์›Œ Figma ์‹œ์•ˆ๊ณผ ์‚ฌ์ง„์œผ๋กœ ๋Œ€์กฐํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅด๋ฉด ๋˜‘๊ฐ™์•„์งˆ ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๊ณ ์น˜๊ณ , ๋„๊ตฌ/๊ธฐ๊ธฐ๊ฐ€ ์—†๊ฑฐ๋‚˜ ๊ทธ๋ž˜๋„ ์•ˆ ๋งž์œผ๋ฉด ์‚ฌ๋žŒ์—๊ฒŒ ํ™•์ธ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  • ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑยท์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ด€๋ฌธ์„ ํ†ต๊ณผํ•˜์ง€ ๋ชปํ•˜๋ฉด PR์„ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค(ํ’ˆ์งˆ ์•ˆ์ „์žฅ์น˜).
  • PR(๋ณ‘ํ•ฉ ์š”์ฒญ) ์„ ๋งŒ๋“ค๊ณ , ๋ณธ๋ฌธ์— Closes #์ด์Šˆ๋ฒˆํ˜ธ๋ฅผ ๋„ฃ์–ด ์ด์Šˆ์™€ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ๋ฆฌ๋ทฐ๋ฅผ ์ž๋™ ์‹คํ–‰ํ•˜๊ณ , ํฌ๋งทยท๋ฆฐํŠธ ๊ฐ™์€ ๊ธฐ๊ณ„์ ์œผ๋กœ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์„ ์ž๋™ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆ์ง€๋ง‰์— ์‚ฌ๋žŒ์˜ ์Šน์ธ์„ ๋ฐ›์•„ ๋จธ์ง€ํ•˜๊ณ , ์ด์Šˆ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค(GitHub์™€ ZenHub ์–‘์ชฝ ๋ชจ๋‘ ํ™•์ •). ๋‹จ, ๊ณ„์ธต ์ž‘์—…์ด๋ผ ๋ถ€๋ชจ ์ž‘์—… ๋ฒ ์ด์Šค ๋ธŒ๋žœ์น˜(story/ยทepic/)๋กœ ํ•ฉ์น˜๋Š” ๊ฒฝ์šฐ GitHub ์ž๋™ ๋‹ซํž˜์ด ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ง์ ‘ ๋‹ซ๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ž…๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ์“ฐ๋‚˜์š”#

# ๊ธฐ๋ณธ: 25๋ฒˆ ์ด์Šˆ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ฒ˜๋ฆฌ
/dev:issue 25

# ๋จธ์ง€๋Š” ํ•˜์ง€ ์•Š๊ณ  PR๊นŒ์ง€๋งŒ
/dev:issue 25 --no-merge

# ํ…Œ์ŠคํŠธ ๊ฑด๋„ˆ๋›ฐ๊ธฐ (๊ธ‰ํ•œ ํ•ซํ”ฝ์Šค์šฉ)
/dev:issue 25 --skip-tests

# base(๊ธฐ์ค€) ๋ธŒ๋žœ์น˜ ๋ณ€๊ฒฝ
/dev:issue 25 --base main

# BDD ์‹œ๋‚˜๋ฆฌ์˜ค ๊ฐ•์ œ ์ƒ์„ฑ
/dev:issue 25 --bdd

# BDD ์‹œ๋‚˜๋ฆฌ์˜ค ๊ฑด๋„ˆ๋›ฐ๊ธฐ
/dev:issue 25 --skip-bdd

# ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๊ฑด๋„ˆ๋›ฐ๊ธฐ (๊ธ‰ํ•œ ํ•ซํ”ฝ์Šค์šฉ)
/dev:issue 25 --skip-review

# ํ™”๋ฉด ๋””์ž์ธ ๊ฒ€์ฆ ๊ฑด๋„ˆ๋›ฐ๊ธฐ (์—ฌ์ „ํžˆ ํ™•์ธ ์ ˆ์ฐจ ํ•„์š”)
/dev:issue 25 --skip-design-verify

{issue_number}(์ด์Šˆ ๋ฒˆํ˜ธ)๋Š” ๋ฐ˜๋“œ์‹œ ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ -- ์˜ต์…˜์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์„ ํƒํ•ด์„œ ๋ถ™์ด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์•ˆ์—์„œ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋‚˜์š”#

์ด 9๋‹จ๊ณ„๋กœ, ์•ž ๋‹จ๊ณ„๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

  1. ์ด์Šˆ ์ •๋ณด ์กฐํšŒ โ€” ์ด์Šˆ์˜ ์ œ๋ชฉยท๋‚ด์šฉยทํƒ€์ž…์„ ์ฝ๊ณ , ํ™”๋ฉด ์ข…๋ฅ˜(๋ชฉ๋ก/์ƒ์„ธ/ํผ)์ธ์ง€ ์ž๋™์œผ๋กœ ํŒ๋ณ„ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ โ€” ์ด์Šˆ ์ „์šฉ ์ž‘์—… ๊ณต๊ฐ„(๋ธŒ๋žœ์น˜)์„ ๋งŒ๋“ค๊ณ  ์ƒํƒœ๋ฅผ "In Progress"๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.
  3. BDD ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ โ€” ํ™”๋ฉด ๊ธฐ๋Šฅ์ด๋ฉด ๋™์ž‘ ๋ช…์„ธ์„œ๋ฅผ ๋งŒ๋“ค์–ด ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค(์•„๋‹ˆ๋ฉด ๊ฑด๋„ˆ๋œ€).
  4. ๊ตฌํ˜„ ์ž‘์—… โ€” ์ด์Šˆ ๋‚ด์šฉ๋Œ€๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋‹จ๊ณ„๋ณ„๋กœ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.
  5. ํ™”๋ฉด ์‹ค๊ธฐ๊ธฐ ๋Œ€์กฐ ํ™•์ธ โ€” ํ™”๋ฉด ๊ธฐ๋Šฅ์ด๋ฉด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐยท์‹ค๊ธฐ๊ธฐ์— ์•ฑ์„ ๋„์›Œ Figma ์‹œ์•ˆ๊ณผ ์‚ฌ์ง„์œผ๋กœ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅด๋ฉด ๋˜‘๊ฐ™์•„์งˆ ๋•Œ๊นŒ์ง€ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๊ณ ์น˜๊ณ , ๋„๊ตฌ/๊ธฐ๊ธฐ๊ฐ€ ์—†๊ฑฐ๋‚˜ ๊ทธ๋ž˜๋„ ์•ˆ ๋งž์œผ๋ฉด ์‚ฌ๋žŒ์—๊ฒŒ ํ™•์ธ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  6. ํ…Œ์ŠคํŠธ ์ž‘์„ฑยท๊ฒ€์ฆ (ํ•„์ˆ˜ ๊ด€๋ฌธ) โ€” ๋‹จ์œ„ยทBDDยท๋ฐฑ์—”๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ฆฝ๋‹ˆ๋‹ค. ์ „๋ถ€ ํ†ต๊ณผํ•ด์•ผ๋งŒ ๋‹ค์Œ์œผ๋กœ ์ง„ํ–‰๋˜๋ฉฐ, ์‹คํŒจํ•˜๋ฉด ์ตœ๋Œ€ 3๋ฒˆ๊นŒ์ง€ ์ž๋™ ์ˆ˜์ •์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.
  7. PR ์ƒ์„ฑ โ€” ๋ณ‘ํ•ฉ ์š”์ฒญ์„ ๋งŒ๋“ค๊ณ  ์ด์Šˆ์™€ ์—ฐ๊ฒฐํ•œ ๋’ค, ์ƒํƒœ๋ฅผ "Review/QA"๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.
  8. ์ฝ”๋“œ ๋ฆฌ๋ทฐ โ€” ์ž๋™ ๋ฆฌ๋ทฐ๋ฅผ ๋Œ๋ฆฌ๊ณ  ํฌ๋งทยท๋ฆฐํŠธ ๋“ฑ ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์„ ๋ฐ˜์˜ํ•œ ๋’ค, ์™„๋ฃŒ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  9. ๋จธ์ง€ ์Šน์ธ ๋Œ€๊ธฐ โ€” ์ตœ์ข… ์š”์•ฝ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์‚ฌ๋žŒ์˜ ์Šน์ธ์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์Šน์ธํ•˜๋ฉด ํ•ฉ์ณ์ง€๊ณ  ์ด์Šˆ๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ซํž™๋‹ˆ๋‹ค.

โš™๏ธ ์ƒ์„ธ ์˜ต์…˜ยท์‹คํ–‰ ๋ช…์„ธ (๊ฐœ๋ฐœ์ž / AI ์—์ด์ „ํŠธ์šฉ)

Overview#

This skill automates the entire development cycle from branch creation to merge for a single ZenHub/GitHub issue.


Usage#

/dev:issue {issue_number}

Parameters#

ParameterRequiredDescription
issue_numberโœ…GitHub issue number

Options#

/dev:issue 25 --no-merge      # PR only, without merge
/dev:issue 25 --skip-tests    # Skip tests (for urgent hotfixes)
/dev:issue 25 --base main     # Change base branch
/dev:issue 25 --bdd           # Force BDD scenario generation
/dev:issue 25 --skip-bdd      # Skip BDD scenarios
/dev:issue 25 --skip-review   # Skip code review (for urgent hotfixes)
/dev:issue 25 --skip-design-verify   # Skip design verification (still requires AskUserQuestion confirmation)
/dev:issue 25 --design-target=android --design-tolerance pixel=1,color_delta_e=2

Execution Flow#

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    /dev:issue                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                 โ”‚
โ”‚  Step 1: ์ด์Šˆ ์ •๋ณด ์กฐํšŒ                                           โ”‚
โ”‚  โ”œโ”€โ”€ mcp__zenhub__searchLatestIssues                            โ”‚
โ”‚  โ”œโ”€โ”€ ์ด์Šˆ ํƒ€์ž…, ์ œ๋ชฉ, ๋ณธ๋ฌธ ์ถ”์ถœ                                     โ”‚
โ”‚  โ”œโ”€โ”€ ํ™”๋ฉด ํƒ€์ž… ๊ฐ์ง€ (๋ชฉ๋ก/์ƒ์„ธ/ํผ)                                  โ”‚
โ”‚  โ””โ”€โ”€ ๋ถ€๋ชจ/์ž์‹ ๊ด€๊ณ„ ํ™•์ธ                                           โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 2: ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ                                              โ”‚
โ”‚  โ”œโ”€โ”€ Task(subagent_type:  " issue-branch-agent " )                  โ”‚
โ”‚  โ”œโ”€โ”€ issue-state-agent โ†’  " In Progress "   ์ด๋™                      โ”‚
โ”‚  โ””โ”€โ”€ ๊ฒฐ๊ณผ: feature/{number}-{slug}                               โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 3: BDD ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ (ํ™”๋ฉด ๊ธฐ๋Šฅ ์‹œ) โ† NEW                     โ”‚
โ”‚  โ”œโ”€โ”€ Task(subagent_type:  " bdd-scenario-agent " )                  โ”‚
โ”‚  โ”œโ”€โ”€ Gherkin Feature ํŒŒ์ผ ์ƒ์„ฑ                                    โ”‚
โ”‚  โ”œโ”€โ”€ Step Definition ์ƒ์„ฑ                                        โ”‚
โ”‚  โ””โ”€โ”€ ์ปค๋ฐ‹:  " test({scope}): โœ… BDD ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ "                      โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 4: ๊ตฌํ˜„ ์ž‘์—…                                                โ”‚
โ”‚  โ”œโ”€โ”€ Task(subagent_type:  " implementation-agent " )                โ”‚
โ”‚  โ”œโ”€โ”€ ์ด์Šˆ ๋‚ด์šฉ ๋ถ„์„ โ†’ ๋ ˆ์ด์–ด ์—์ด์ „ํŠธ ์œ„์ž„                            โ”‚
โ”‚  โ””โ”€โ”€ ์ฆ๋ถ„ ์ปค๋ฐ‹ ์ƒ์„ฑ                                                โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 4.5: ๋””์ž์ธ ๊ฒ€์ฆ ๊ฒŒ์ดํŠธ (screen feature + Figma ์†Œ์Šค ์‹œ) โš ๏ธ      โ”‚
โ”‚  โ”œโ”€โ”€ ์ƒ์„ธ ๋กœ์ง์€ run.md Step 7.3๊ณผ ๋™์ผ โ€” ์—ฌ๊ธฐ์„œ๋Š” ์œ„์ž„๋งŒ ํ•จ           โ”‚
โ”‚  โ”œโ”€โ”€ flutter run --print-dtd โ†’ pixel-loop:loop โ†’ visual-verify   โ”‚
โ”‚  โ”œโ”€โ”€ ๋„๊ตฌ/๊ธฐ๊ธฐ ๋ถ€์žฌยท์ž”์กด ๋ถˆ์ผ์น˜ ์‹œ AskUserQuestion ํ™•์ธ (๋ฌด์Œ ์Šคํ‚ต ๊ธˆ์ง€)โ”‚
โ”‚  โ””โ”€โ”€ ๊ฒฐ๊ณผ๋ฅผ PR body์˜  " Design Verification "   ์„น์…˜์— ๊ธฐ๋ก             โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 5: ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐ ๊ฒ€์ฆ (ํ•„์ˆ˜ ๊ฒŒ์ดํŠธ) โš ๏ธ                        โ”‚
โ”‚  โ”œโ”€โ”€ [ํ”„๋ก ํŠธ์—”๋“œ ํ…Œ์ŠคํŠธ - ํ•„์ˆ˜]                                      โ”‚
โ”‚  โ”‚   โ”œโ”€โ”€ UseCase ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (unit-test-agent)                     โ”‚
โ”‚  โ”‚   โ””โ”€โ”€ BLoC ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (bloc-test-agent)                        โ”‚
โ”‚  โ”œโ”€โ”€ [๋ฐฑ์—”๋“œ ํ…Œ์ŠคํŠธ - Backend ๋ณ€๊ฒฝ ์‹œ ํ•„์ˆ˜]                           โ”‚
โ”‚  โ”‚   โ”œโ”€โ”€ ์—”๋“œํฌ์ธํŠธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (serverpod-test-agent)               โ”‚
โ”‚  โ”‚   โ”œโ”€โ”€ ์„œ๋น„์Šค ๋กœ์ง ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (serverpod-test-agent)              โ”‚
โ”‚  โ”‚   โ””โ”€โ”€ ์—”๋“œํฌ์ธํŠธ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ (serverpod-test-agent)               โ”‚
โ”‚  โ”œโ”€โ”€ BDD Widget ํ…Œ์ŠคํŠธ (ํ™”๋ฉด ๊ธฐ๋Šฅ ์‹œ)                                โ”‚
โ”‚  โ”œโ”€โ”€ test-runner-agent ํ˜ธ์ถœ (require_tests: true)                โ”‚
โ”‚  โ”œโ”€โ”€ โš ๏ธ ๋ชจ๋“  ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ•„์ˆ˜ (๊ฒŒ์ดํŠธ ์‹คํŒจ ์‹œ PR ์ƒ์„ฑ ์ฐจ๋‹จ)            โ”‚
โ”‚  โ””โ”€โ”€ ์‹คํŒจ ์‹œ ์ž๋™ ์ˆ˜์ • ์‹œ๋„ (์ตœ๋Œ€ 3ํšŒ)                               โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 6: PR ์ƒ์„ฑ                                                  โ”‚
โ”‚  โ”œโ”€โ”€ gh pr create                                                โ”‚
โ”‚  โ”œโ”€โ”€ Closes #{issue_number} ์ž๋™ ํฌํ•จ                             โ”‚
โ”‚  โ””โ”€โ”€ issue-state-agent โ†’  " Review/QA "   ์ด๋™                        โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 7: ์ฝ”๋“œ ๋ฆฌ๋ทฐ ์ง„ํ–‰ โ† NEW                                      โ”‚
โ”‚  โ”œโ”€โ”€ /code-review ์ž๋™ ์‹คํ–‰                                       โ”‚
โ”‚  โ”œโ”€โ”€ ๋ฆฌ๋ทฐ ํ”ผ๋“œ๋ฐฑ ์ž๋™ ๋ฐ˜์˜ (format, analyze --fix)                  โ”‚
โ”‚  โ”œโ”€โ”€ /checklist:feature-complete ์‹คํ–‰                            โ”‚
โ”‚  โ””โ”€โ”€ ์žฌ๊ฒ€ํ†  ํ•„์š” ์‹œ ๋ฐ˜๋ณต                                            โ”‚
โ”‚                                                                 โ”‚
โ”‚  Step 8: ๋จธ์ง€ ์Šน์ธ ๋Œ€๊ธฐ (๋จธ์ง€ = Close)                             โ”‚
โ”‚  โ”œโ”€โ”€ ์ตœ์ข… ์ƒํƒœ ์š”์•ฝ ํ‘œ์‹œ                                            โ”‚
โ”‚  โ”œโ”€โ”€ ์‚ฌ์šฉ์ž ์Šน์ธ ์š”์ฒญ (AskUserQuestion)                            โ”‚
โ”‚  โ”œโ”€โ”€ ์Šน์ธ ์‹œ ์Šค์ฟผ์‹œ ๋จธ์ง€ ์‹คํ–‰                                       โ”‚
โ”‚  โ”œโ”€โ”€ GitHub  " Closes # "   ํ‚ค์›Œ๋“œ๋กœ ์ด์Šˆ ์ž๋™ Close                    โ”‚
โ”‚  โ””โ”€โ”€ โญ Close ๊ฒ€์ฆ + ํด๋ฐฑ (GitHub closed + ZenHub Closed ํ™•์ •)     โ”‚
โ”‚                                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Auto Screen Type Detection#

Detects screen keywords from issue title/body to decide whether to write BDD scenarios:

PatternScreen TypeBDD
"๋ชฉ๋ก", "๋ฆฌ์ŠคํŠธ", "list", "์กฐํšŒ"Listโœ… Generate
"์ƒ์„ธ", "detail", "๋ณด๊ธฐ"Detailโœ… Generate
"์ถ”๊ฐ€", "์ƒ์„ฑ", "๋“ฑ๋ก", "form"Formโœ… Generate
"์ˆ˜์ •", "ํŽธ์ง‘", "edit"Formโœ… Generate
"๋ฆฌํŒฉํ† ๋ง", "๊ฐœ์„ ", "์ตœ์ ํ™”"-โŒ Skip
"์„ค์ •", "ํ™˜๊ฒฝ", "๋นŒ๋“œ"-โŒ Skip

Detailed Implementation#

Step 1: Query Issue Info#

์ด์Šˆ๊ฐ€ ์ด๋ฏธ ์กด์žฌํ•œ๋‹ค๊ณ  ์ „์ œํ•˜๋ฏ€๋กœ /dev:run์˜ Step 1.5(PM ์š”๊ตฌ์‚ฌํ•ญ ์ •์ œ, pm-spec-agent)๋Š” ์—ฌ๊ธฐ์„œ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค. ์กฐํšŒํ•œ issue.body๊ฐ€ FR/AC๋‚˜ ์Šค์ฝ”ํ”„ ์—†์ด ํ•œ ์ค„๋ฟ์ด๋ฉด, ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ(Step 2) ์ „์— pm-spec-agent๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•ด ์ด์Šˆ ๋ณธ๋ฌธ์„ ๋ณด๊ฐ•ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค โ€” ํ•„์ˆ˜ ๊ฒŒ์ดํŠธ๋Š” ์•„๋‹ˆ๋‹ค(non-blocking). ์ž์„ธํ•œ ๋‚ด์šฉ์€ SKILL.md โ†’ "PM Requirements Refinement Gate" ์ฐธ๊ณ .

// ์ด์Šˆ ์ •๋ณด ์กฐํšŒ
const issueResult = await mcp__zenhub__searchLatestIssues({
  query: issue_number.toString()
});

const issue = issueResult.find(i = >   i.number === issue_number);

// ์ถ”์ถœํ•  ์ •๋ณด
const issueInfo = {
  id: issue.id,                    // GraphQL ID
  number: issue.number,            // GitHub ๋ฒˆํ˜ธ
  title: issue.title,              // ์ด์Šˆ ์ œ๋ชฉ
  body: issue.body,                // ์ด์Šˆ ๋ณธ๋ฌธ (Acceptance Criteria ํฌํ•จ)
  type: issue.issueType?.name,     // Feature, Task, Bug, Sub-task
  pipeline: issue.pipelineIssue?.pipeline?.name,
  parentIssue: issue.parentIssue,  // ๋ถ€๋ชจ ์ด์Šˆ ์ •๋ณด
  labels: issue.labels,            // ๋ผ๋ฒจ ๋ชฉ๋ก
};

Step 2: Branch Creation#

// ๋ธŒ๋žœ์น˜ ์—์ด์ „ํŠธ ํ˜ธ์ถœ
const branchResult = await Task({
  subagent_type:  " issue-branch-agent " ,
  prompt: `
    issue_number: ${issueInfo.number}
    issue_title: ${issueInfo.title}
    issue_type: ${issueInfo.type}
    base_branch: development

    ์ด ์ด์Šˆ๋ฅผ ์œ„ํ•œ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.
  `
});

// Pipeline ์ด๋™: In Progress
await Task({
  subagent_type:  " issue-state-agent " ,
  prompt: `
    issue_number: ${issueInfo.number}
    action: move_pipeline
    target_pipeline:  " In Progress " 
   `
});

// ์Šคํ”„๋ฆฐํŠธ ๋ฐฐ์ •(ํƒ€์ž„๋ผ์ธ ๊ฐ€์‹œ์„ฑ) โ€” ๊ธฐ๋ณธ 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: [issueInfo.id], sprintIds: [sprint.id] });
}

Step 3: BDD Scenario Writing (for screen features)#

// ํ™”๋ฉด ํƒ€์ž… ๊ฐ์ง€
const screenKeywords = {
  list: [ " ๋ชฉ๋ก " ,  " ๋ฆฌ์ŠคํŠธ " ,  " list " ,  " ์กฐํšŒ " ,  " ๊ฒ€์ƒ‰ " ],
  detail: [ " ์ƒ์„ธ " ,  " detail " ,  " ๋ณด๊ธฐ " ],
  form: [ " ์ถ”๊ฐ€ " ,  " ์ƒ์„ฑ " ,  " ์ˆ˜์ • " ,  " ํŽธ์ง‘ " ,  " form " ,  " ๋“ฑ๋ก " ],
};

const screenType = detectScreenType(issueInfo.title + issueInfo.body);
const requiresBdd = screenType !== null  & &   !options.skipBdd;

if (requiresBdd || options.bdd) {
  // BDD ์‹œ๋‚˜๋ฆฌ์˜ค ์—์ด์ „ํŠธ ํ˜ธ์ถœ
  await Task({
    subagent_type:  " bdd-scenario-agent " ,
    prompt: `
      feature_name: ${extractFeatureName(issueInfo)}
      entity_name: ${extractEntityName(issueInfo)}
      screen_type: ${screenType ||  " list " }

      ํ™”๋ฉด ํƒ€์ž…์— ๋งž๋Š” BDD ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.
    `
  });

  // ์ปค๋ฐ‹
  const scope = extractScope(issueInfo);
  await Bash(`
    git add .
    git commit -m  " test(${scope}): โœ… BDD ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ

    - ${screenType} ํ™”๋ฉด ์‹œ๋‚˜๋ฆฌ์˜ค ์ถ”๊ฐ€
    - Step Definition ์ƒ์„ฑ

    Co-Authored-By: Claude Opus 4.5  < noreply@anthropic.com > " 
   `);
}

Step 4: Implementation Work#

// ๊ตฌํ˜„ ์—์ด์ „ํŠธ ํ˜ธ์ถœ
const implResult = await Task({
  subagent_type:  " implementation-agent " ,
  prompt: `
    issue_number: ${issueInfo.number}
    issue_body: ${issueInfo.body}
    issue_type: ${issueInfo.type}
    issue_title: ${issueInfo.title}

    ์ด์Šˆ ๋‚ด์šฉ์„ ๋ถ„์„ํ•˜๊ณ  ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.
    ์™„๋ฃŒ๋œ ์ž‘์—…๋งˆ๋‹ค ์ปค๋ฐ‹์„ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”.
  `
});

// ์ปค๋ฐ‹ ๊ฒฐ๊ณผ ํ™•์ธ
console.log(`์ƒ์„ฑ๋œ ์ปค๋ฐ‹: ${implResult.commits.length}๊ฐœ`);
console.log(`๋ณ€๊ฒฝ๋œ ํŒŒ์ผ: ${implResult.files_changed.length}๊ฐœ`);

Step 4.5: Design Verification Gate (screen features) โš ๏ธ#

Screen feature(issueInfo์—์„œ ํ™”๋ฉด ์ข…๋ฅ˜๊ฐ€ ๊ฐ์ง€๋จ) + Figma ์†Œ์Šค(.claude/docs/{scope}/figma_analysis.md)๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ์‹คํ–‰. ์ „์ฒด ๋กœ์ง(๋„๊ตฌ/๊ธฐ๊ธฐ preflight, flutter run --print-dtd ๊ธฐ๋™, pixel-loop:loop ์ €์ž‘, visual-verify ๊ฒŒ์ดํŠธ, ์‹คํŒจ ์‹œ ์žฌ์‹œ๋„/์‚ฌ์šฉ์ž ํ™•์ธ, prBodyExtras.designVerification ๊ธฐ๋ก)์€ run.md โ†’ Step 7.3: Design Verification Gate๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌ์‚ฌ์šฉํ•œ๋‹ค โ€” ์—ฌ๊ธฐ์„œ ์ค‘๋ณต ๊ธฐ์ˆ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

  • Figma ์†Œ์Šค๊ฐ€ ์—†์œผ๋ฉด not-applicable๋กœ ์กฐ์šฉํžˆ skip.
  • ๋„๊ตฌ/๊ธฐ๊ธฐ(figma-mcp/maestro/dart-mcp/device) ๋ถ€์žฌ ๋˜๋Š” --skip-design-verify ์‹œ์—๋„ AskUserQuestion ํ™•์ธ์€ ์ƒ๋žตํ•˜์ง€ ์•Š๋Š”๋‹ค(๋ฌด์Œ ์Šคํ‚ต ๊ธˆ์ง€).
  • ๊ฒฐ๊ณผ๋Š” Step 6 PR ๋ณธ๋ฌธ์˜ "Design Verification" ์„น์…˜์— ๋ฐ˜์˜๋œ๋‹ค.

Step 5: Test Writing and Verification (Required Gate)#

// Feature๋ช… ์ถ”์ถœ (์ด์Šˆ ์ œ๋ชฉ ๋˜๋Š” ์Šค์ฝ”ํ”„์—์„œ)
const featureName = extractFeatureName(issueInfo);

// Backend ๋ณ€๊ฒฝ ๊ฐ์ง€
const hasBackendChanges = detectBackendChanges(issueInfo);

// ํ…Œ์ŠคํŠธ ์œ ํ˜• ๊ฒฐ์ •
const testTypes = [ " unit " ,  " bloc " ];
if (requiresBdd) testTypes.push( " bdd " );
if (hasBackendChanges) testTypes.push( " backend_unit " ,  " backend_integration " );

// ํ…Œ์ŠคํŠธ ์—์ด์ „ํŠธ ํ˜ธ์ถœ (require_tests: true โ†’ ๋ˆ„๋ฝ ์‹œ ์ž๋™ ์ƒ์„ฑ)
const testResult = await Task({
  subagent_type:  " test-runner-agent " ,
  prompt: `
    feature_name: ${featureName}
    test_types: ${JSON.stringify(testTypes)}
    auto_fix: true
    require_tests: true

    ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•œ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ํ•ด์ฃผ์„ธ์š”.
    โš ๏ธ ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•ด์•ผ PR ์ƒ์„ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  `
});

// โš ๏ธ ํ…Œ์ŠคํŠธ ์‹คํŒจ ์‹œ PR ์ƒ์„ฑ ์ฐจ๋‹จ
if (!testResult.success) {
  if (testResult.failures.some(f = >   !f.fixable)) {
    throw new Error(`ํ…Œ์ŠคํŠธ ์‹คํŒจ: ${testResult.failures.length}๊ฐœ - PR ์ƒ์„ฑ ์ฐจ๋‹จ`);
  }
}

Step 6: PR Creation#

// PR ์ƒ์„ฑ
const gitmoji = getGitmoji(issueInfo.type);
const scope = extractScope(issueInfo);

await Bash(`
  gh pr create --title  " ${gitmoji} ${scope}: ${issueInfo.title} "   \
    --body  " $(cat  < < ' EOF ' 
 ## Summary
- ${issueInfo.title}

## Test Plan
- [ ] UseCase ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ
- [ ] BLoC ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ
${hasBackendChanges ?  ' - [ ] ๋ฐฑ์—”๋“œ ์—”๋“œํฌ์ธํŠธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ '   :  ' ' }
${hasBackendChanges ?  ' - [ ] ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค ๋กœ์ง ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ '   :  ' ' }
${hasBackendChanges ?  ' - [ ] ๋ฐฑ์—”๋“œ ์—”๋“œํฌ์ธํŠธ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ '   :  ' ' }
${requiresBdd ?  ' - [ ] BDD ์‹œ๋‚˜๋ฆฌ์˜ค ํ†ต๊ณผ '   :  ' ' }
${designVerification ? `
## Design Verification
${designVerification.status ===  " pass "   ? `โœ… PASS โ€” tolerance ${designVerification.tolerance}, target ${designVerification.target}` :  ' ' }
${designVerification.status ===  " skipped "   ? `โš ๏ธ ๋””์ž์ธ ๊ฒ€์ฆ ๋ฏธ์‹คํ–‰ (${designVerification.reason}) โ€” ๋””์ž์ด๋„ˆ ์ˆ˜๋™ ํ™•์ธ ํ•„์š”` :  ' ' }
${designVerification.status ===  " fail-acknowledged "   ? `โš ๏ธ ์ž”์กด ๋ถˆ์ผ์น˜ ${designVerification.diffCount}๊ฑด โ€” ์‚ฌ์šฉ์ž ํ™•์ธ ํ›„ ์ง„ํ–‰` :  ' ' }
` :  ' ' }

Closes #${issueInfo.number}

๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code)
EOF
) " 
 `);

// Pipeline ์ด๋™: Review/QA (fail-closed id ํ•ด์„ โ€” undefined silent no-op ๋ฐฉ์ง€)
const _ws = await mcp__zenhub__getWorkspacePipelinesAndRepositories();
const reviewQa = _ws.pipelines.find(p = >   p.name ===  " Review/QA " );
if (!reviewQa) throw new Error(` ' Review/QA '   ํŒŒ์ดํ”„๋ผ์ธ ์—†์Œ. ๋ผ์ด๋ธŒ: ${_ws.pipelines.map(p = >   p.name).join( " ,  " )}`);
await mcp__zenhub__moveIssueToPipeline({ issueId: issueInfo.id, pipelineId: reviewQa.id });

Step 7: Code Review#

if (!options.skipReview) {
  // /code-review ์ž๋™ ์‹คํ–‰
  await Skill({ skill:  " code-review "   });

  // ์ž๋™ ๋ฐ˜์˜ ๊ฐ€๋Šฅํ•œ ํ”ผ๋“œ๋ฐฑ ์ ์šฉ
  await Bash(`melos run format`);
  await Bash(`melos run analyze --fix`);

  // ์ˆ˜์ • ์‚ฌํ•ญ ์žˆ์œผ๋ฉด ์ปค๋ฐ‹
  const hasChanges = await Bash(`git status --porcelain`);
  if (hasChanges.stdout.trim()) {
    await Bash(`
      git add .
      git commit -m  " style(${scope}): ๐ŸŽจ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜

      - ํฌ๋งทํŒ… ์ ์šฉ
      - ๋ฆฐํŠธ ๊ฒฝ๊ณ  ์ˆ˜์ •

      Co-Authored-By: Claude Opus 4.5  < noreply@anthropic.com > " 
     `);

    // โš ๏ธ Per-Push Verification Gate: PR์ด ์ด๋ฏธ ์กด์žฌํ•ด๋„ push ์ง์ „์—
    //    Step 5.5 ๊ฒŒ์ดํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌ์‹คํ–‰ํ•œ๋‹ค (0๊ฑด ๋ฏธ๋‹ฌ ์‹œ push ์ฐจ๋‹จ)
    await Bash(`melos run format`);              // dcm format
    await Bash(`dart fix --apply`);
    const recheck = await Bash(`melos run analyze 2 > & 1`);
    if (countLintIssues(recheck)  >   0) {
      throw new Error( " Per-Push Gate blocked: dart analyze ์ด์Šˆ ์ž”์กด โ€” ์ˆ˜์ • ํ›„ ์žฌ์‹œ๋„ " );
    }
    const dcmRecheck = await Bash(`melos run dcm:analyze 2 > & 1`);
    if (countDcmErrors(dcmRecheck)  >   0) {
      throw new Error( " Per-Push Gate blocked: dcm analyze error ์ด์Šˆ ์ž”์กด โ€” ์ˆ˜์ • ํ›„ ์žฌ์‹œ๋„ " );
    }

    await Bash(`git push`);
  }

  // /checklist:feature-complete ์‹คํ–‰
  await Skill({ skill:  " checklist:feature-complete "   });
}

Step 8: Wait for Merge Approval#

// ์ตœ์ข… ์ƒํƒœ ์š”์•ฝ ํ‘œ์‹œ
console.log(`
โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘  Ready for Merge                                               โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ“‹ Issue: #${issueInfo.number} - ${issueInfo.title}           โ•‘
โ•‘  ๐Ÿ”€ PR: #${prNumber}                                           โ•‘
โ•‘  ๐ŸŒฟ Branch: ${branchResult.branch_name}                        โ•‘
โ•‘                                                                โ•‘
โ•‘  โœ… Tests: ${testResult.summary.passed}/${testResult.summary.total} passed
โ•‘  โœ… Review: All issues resolved                                โ•‘
โ•‘  โœ… Checklist: Passed                                          โ•‘
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ”’ Merge blocked until user approval                         โ•‘
โ•‘                                                                โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
`);

// ์‚ฌ์šฉ์ž ์Šน์ธ ์š”์ฒญ
const approval = await AskUserQuestion({
  questions: [{
    header:  " ๋จธ์ง€ " ,
    question:  " PR์„ ๋จธ์ง€ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? " ,
    options: [
      { label:  " ๋จธ์ง€ ์Šน์ธ " , description:  " ์Šค์ฟผ์‹œ ๋จธ์ง€ ํ›„ ์ด์Šˆ ํด๋กœ์ฆˆ "   },
      { label:  " ์ˆ˜์ • ํ•„์š” " , description:  " Step 4๋กœ ๋Œ์•„๊ฐ€์„œ ์ˆ˜์ • "   },
      { label:  " ์ทจ์†Œ " , description:  " ํ˜„์žฌ ์ƒํƒœ ์œ ์ง€ "   },
    ],
    multiSelect: false,
  }],
});

if (approval ===  " ๋จธ์ง€ ์Šน์ธ " ) {
  // ์Šค์ฟผ์‹œ ๋จธ์ง€ โ†’ GitHub  " Closes # "   ํ‚ค์›Œ๋“œ๋กœ ์ด์Šˆ ์ž๋™ Close (์ •์ฑ…: ๋จธ์ง€ = Close)
  // Done ํŒŒ์ดํ”„๋ผ์ธ ๋ฏธ์‚ฌ์šฉ (Done โ‰  closed)
  await Bash(`gh pr merge --squash --delete-branch`);

  // โญ Close ๊ฒ€์ฆ + ํด๋ฐฑ (ZenHub 2-์ƒํƒœ ๋ชจ๋ธ: Pipeline โ‰  GitHub state)
  //   `Closes #N` ์ž๋™ close๊ฐ€ ๋ˆ„๋ฝ/์ง€์—ฐ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ GitHub state๋กœ ๊ฒ€์ฆํ•œ๋‹ค.
  const ghState = (await Bash(`gh issue view ${issueInfo.number} --json state -q .state`)).trim();
  if (ghState !==  " CLOSED " ) {
    await Bash(`gh issue close ${issueInfo.number} --reason completed`);
  }
  const closedOnZh = await mcp__zenhub__searchClosedIssues({ query: `#${issueInfo.number}` });
  if (!closedOnZh.find(i = >   i.number === issueInfo.number)) {
    await mcp__zenhub__updateIssue({ issueId: issueInfo.id, state:  " CLOSED "   });
  }

  // โญ Post-merge: base ๋ธŒ๋žœ์น˜๋กœ ์ด๋™ + ์ตœ์‹ ํ™” + ์„œ๋ธŒ๋ชจ๋“ˆ ๋™๊ธฐํ™” (ํ•„์ˆ˜)
  //   - gh pr merge --delete-branch ๋Š” base๋ฅผ ์ฒดํฌ์•„์›ƒํ•˜์ง€๋งŒ pull ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  //   - git pull ์€ superproject์˜ ์„œ๋ธŒ๋ชจ๋“ˆ ํฌ์ธํ„ฐ๋งŒ ๊ฐฑ์‹ ํ•  ๋ฟ ์„œ๋ธŒ๋ชจ๋“ˆ ์›Œํ‚นํŠธ๋ฆฌ๋Š”
  //     ์ฒดํฌ์•„์›ƒํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ git submodule update ๋กœ base๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ปค๋ฐ‹์— ์ •๋ ฌํ•œ๋‹ค
  //     (Serverpod/Melos ๋ชจ๋…ธ๋ ˆํฌ ๋นŒ๋“œ/์ฝ”๋“œ์   drift ๋ฐฉ์ง€). ์„œ๋ธŒ๋ชจ๋“ˆ์ด ์—†์œผ๋ฉด no-op.
  //   - baseBranch = PR base (๊ณ„์ธต: ๋ถ€๋ชจ ๋ธŒ๋žœ์น˜, ๋…๋ฆฝ: development).
  const baseBranch = branchResult.base_branch ??  " development " ;
  await Bash(`
    git checkout ${baseBranch}
    git pull --ff-only origin ${baseBranch}
    git submodule sync --recursive
    git submodule update --init --recursive
  `);
}

Output Format#

On Success#

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘  Issue Cycle Complete: #25                                     โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ“‹ Issue: feat(community): โœจ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํ™”๋ฉด ๊ตฌํ˜„              โ•‘
โ•‘  ๐ŸŒฟ Branch: feature/25-community-list                          โ•‘
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ“ Commits:                                                   โ•‘
โ•‘    1. feat(community): โœจ domain layer ๊ตฌํ˜„                     โ•‘
โ•‘    2. feat(community): โœจ data layer ๊ตฌํ˜„                       โ•‘
โ•‘    3. feat(community): โœจ presentation layer ๊ตฌํ˜„               โ•‘
โ•‘                                                                โ•‘
โ•‘  โœ… Tests:                                                     โ•‘
โ•‘    - UseCase Unit: 12/12 passed                                โ•‘
โ•‘    - BLoC Unit: 8/8 passed                                     โ•‘
โ•‘    - Backend Unit: 6/6 (endpoint: 3, service: 3)               โ•‘
โ•‘    - Backend Integration: 4/4 passed                           โ•‘
โ•‘    - BDD: 5/5 scenarios passed                                 โ•‘
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ”€ PR: #42                                                    โ•‘
โ•‘    - URL: https://github.com/owner/repo/pull/42                โ•‘
โ•‘    - Reviews: 2 comments (auto-resolved)                       โ•‘
โ•‘    - Status: Merged โœ…                                         โ•‘
โ•‘                                                                โ•‘
โ•‘  ๐Ÿ“Š Duration: 15m 32s                                          โ•‘
โ•‘  ๐Ÿ Final State: CLOSED (by merge)                             โ•‘
โ•‘                                                                โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

On Failure#

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘  Issue Cycle Failed: #25                                       โ•‘
โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
โ•‘                                                                โ•‘
โ•‘  โŒ Failed at: Step 4 (ํ…Œ์ŠคํŠธ ์‹คํ–‰)                              โ•‘
โ•‘                                                                โ•‘
โ•‘  Error Details:                                                โ•‘
โ•‘    - Test: post_list_bloc_test.dart                            โ•‘
โ•‘    - Reason: Expected PostLoaded but got PostError             โ•‘
โ•‘    - Fixable: No (logic error)                                 โ•‘
โ•‘                                                                โ•‘
โ•‘  Current State:                                                โ•‘
โ•‘    - Branch: feature/25-community-list (exists)                โ•‘
โ•‘    - Commits: 3 committed                                      โ•‘
โ•‘    - Pipeline: In Progress                                     โ•‘
โ•‘    - PR: Not created                                           โ•‘
โ•‘                                                                โ•‘
โ•‘  Recovery Options:                                             โ•‘
โ•‘    1. Fix the test manually and re-run                         โ•‘
โ•‘    2. /dev:issue 25 --skip-tests                    โ•‘
โ•‘                                                                โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Error Handling#

Step-by-Step Recovery Strategy#

Failed StepStateRecovery Method
Branch creationNo changesRetry
ImplementationBranch exists, some commitsContinue work
Design verification (Step 4.5)Code complete๋„๊ตฌ/๊ธฐ๊ธฐ ํ™•์ธ ํ›„ ์žฌ์‹คํ–‰, ๋˜๋Š” --skip-design-verify(ํ™•์ธ ํ•„์š”) โ€” ์ž์„ธํ•œ ๋‚ด์šฉ์€ run.md Step 7.3 ์ฐธ๊ณ 
TestsCode complete, tests failedManual fix then retry
PR creationCode completeCreate PR manually or retry
MergePR exists, CI pendingWait for CI pass then retry
Issue closePR mergedManual close

Auto Recovery Attempt#

// ์ตœ๋Œ€ ์žฌ์‹œ๋„ ํšŸ์ˆ˜
const MAX_RETRIES = 3;

async function executeWithRetry(step, retries = MAX_RETRIES) {
  for (let i = 0; i  <   retries; i++) {
    try {
      return await step();
    } catch (error) {
      if (i === retries - 1) throw error;
      console.log(`์žฌ์‹œ๋„ ${i + 1}/${retries}...`);
      await sleep(5000); // 5์ดˆ ๋Œ€๊ธฐ
    }
  }
}

TodoWrite Integration#

Progress Tracking#

// ์‹œ์ž‘ ์‹œ
TodoWrite([
  { content:  " ์ด์Šˆ ์ •๋ณด ์กฐํšŒ " , status:  " in_progress " , activeForm:  " ์ด์Šˆ ์ •๋ณด ์กฐํšŒ ์ค‘ "   },
  { content:  " ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ " , status:  " pending " , activeForm:  " ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋Œ€๊ธฐ "   },
  { content:  " ๊ตฌํ˜„ ์ž‘์—… " , status:  " pending " , activeForm:  " ๊ตฌํ˜„ ์ž‘์—… ๋Œ€๊ธฐ "   },
  { content:  " ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐ ๊ฒ€์ฆ (ํ•„์ˆ˜ ๊ฒŒ์ดํŠธ) " , status:  " pending " , activeForm:  " ํ…Œ์ŠคํŠธ ์ž‘์„ฑ/๊ฒ€์ฆ ๋Œ€๊ธฐ "   },
  { content:  " PR ์ƒ์„ฑ ๋ฐ ๋จธ์ง€ " , status:  " pending " , activeForm:  " PR ์ƒ์„ฑ ๋Œ€๊ธฐ "   },
  { content:  " ์ด์Šˆ ํด๋กœ์ฆˆ " , status:  " pending " , activeForm:  " ์ด์Šˆ ํด๋กœ์ฆˆ ๋Œ€๊ธฐ "   },
]);

// ๊ฐ ๋‹จ๊ณ„ ์™„๋ฃŒ ์‹œ ์ฆ‰์‹œ ์—…๋ฐ์ดํŠธ
//  " completed " ๋กœ ๋งˆํ‚นํ•˜๊ณ  ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ  " in_progress " ๋กœ ๋ณ€๊ฒฝ

Key Rules#

  1. Sequential execution: Each step proceeds only after previous step succeeds
  2. State tracking: Record current state at every step
  3. Failure tolerance: Preserve current state on failure and provide clear recovery guide
  4. Issue linking: Reference issue number in all commits and PRs
  5. Auto cleanup: Auto-delete branch on success (after merge)
  6. Parent check: Auto-verify parent issue on issue close

Verification Gates (Required)#

Branch Verification (Before Step 2 Start)#

# ํ˜„์žฌ ๋ธŒ๋žœ์น˜ ํ™•์ธ
BRANCH=$(git rev-parse --abbrev-ref HEAD)

# development/main์—์„œ ์ง์ ‘ ์ž‘์—… ์‹œ์ž‘ ๊ธˆ์ง€
if [[ $BRANCH ==  " development "   || $BRANCH ==  " main "   ]]; then
  echo  " โŒ development/main์—์„œ ์ง์ ‘ ์ž‘์—…ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค " 
   echo  " " 
   echo  "     /dev:issue์€ Step 2์—์„œ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. " 
   echo  "     ํ˜„์žฌ development ๋ธŒ๋žœ์น˜์— ์žˆ๋‹ค๋ฉด ์ •์ƒ์ž…๋‹ˆ๋‹ค. " 
   echo  " " 
   # Step 2๊ฐ€ ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๊ณ„์† ์ง„ํ–‰
fi

Pre-PR Verification (Before Step 6)#

# 1. ๋ธŒ๋žœ์น˜ ํ˜•์‹ ๊ฒ€์ฆ
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ ! $BRANCH =~ ^(feature|fix|refactor|chore)/[0-9]+ ]]; then
  echo  " โŒ ๋ธŒ๋žœ์น˜ ํ˜•์‹ ์˜ค๋ฅ˜: $BRANCH " 
   echo  "     ์˜ฌ๋ฐ”๋ฅธ ํ˜•์‹: feature/{issue_number}-description " 
   echo  " " 
   echo  "     Step 2์—์„œ ๋ธŒ๋žœ์น˜๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. " 
   echo  "     /dev:issue์„ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์ฃผ์„ธ์š”. " 
   exit 1
fi

# 2. development/main ์ง์ ‘ ์ปค๋ฐ‹ ๋ฐฉ์ง€
if [[ $BRANCH ==  " development "   || $BRANCH ==  " main "   ]]; then
  echo  " โŒ development/main์— ์ง์ ‘ PR์„ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค " 
   exit 1
fi

# 3. ์ปค๋ฐ‹ ์กด์žฌ ํ™•์ธ
COMMITS=$(git rev-list --count origin/development..HEAD)
if [[ $COMMITS -eq 0 ]]; then
  echo  " โŒ ์ปค๋ฐ‹์ด ์—†์Šต๋‹ˆ๋‹ค. " 
   echo  "     Step 4 (๊ตฌํ˜„ ์ž‘์—…)์„ ๋จผ์ € ์™„๋ฃŒํ•ด์ฃผ์„ธ์š”. " 
   exit 1
fi

# 3.5. ๋””์ž์ธ ๊ฒ€์ฆ ๊ฒฐ๊ณผ ๊ธฐ๋ก ํ™•์ธ (screen feature + Figma ์†Œ์Šค ์‹œ โ€” Step 4.5 ๊ฒŒ์ดํŠธ)
#      ๋ฏธ๊ฒ€์ฆ ์ƒํƒœ๋ฅผ pass ๋กœ ๊ฐ„์ฃผํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ๋น„์–ด ์žˆ์œผ๋ฉด ์ฐจ๋‹จ
if [[  " $REQUIRES_BDD "   ==  " true "   & &   -f  " .claude/docs/${SCOPE}/figma_analysis.md "   & &   -z  " $DESIGN_VERIFICATION_STATUS "   ]]; then
  echo  " โŒ Step 4.5 ๋””์ž์ธ ๊ฒ€์ฆ ๊ฒฐ๊ณผ๊ฐ€ ๊ธฐ๋ก๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค โ€” PR ์ƒ์„ฑ ์ฐจ๋‹จ " 
   exit 1
fi

# 4. Pre-push ๊ฒ€์ฆ + ๋ฆฐํŠธ 0๊ฑด ๊ฒŒ์ดํŠธ
#    (Per-Push Gate: ์ตœ์ดˆ push๋ฟ ์•„๋‹ˆ๋ผ ๋ฆฌ๋ทฐ ํ”ผ๋“œ๋ฐฑ ๋“ฑ ์ดํ›„ ๋ชจ๋“  push ์ง์ „์— ์žฌ์‹คํ–‰)
echo  " ๐Ÿ” Pre-push ๊ฒ€์ฆ ์ค‘... " 
 melos run format || { echo  " โŒ ํฌ๋งท ์˜ค๋ฅ˜ " ; exit 1; }
dart fix --apply  # ์ž๋™ ์ˆ˜์ • ๊ฐ€๋Šฅํ•œ ๋ฆฐํŠธ ์ด์Šˆ ์ผ๊ด„ ์ˆ˜์ •
melos run analyze 2 > & 1 | tee /tmp/analyze_output.txt
LINT_ISSUES=$(grep -c -E  ' \s+(info|warning|error)\s+[โ€ขยท-] '   /tmp/analyze_output.txt || true)
if [[ $LINT_ISSUES -gt 0 ]]; then
  echo  " โš ๏ธ flutter analyze ์ด์Šˆ ${LINT_ISSUES}๊ฑด โ€” ์ˆ˜๋™ ์ˆ˜์ • ํ›„ ์žฌ๊ฒ€์ฆ ํ•„์š” " 
   # ์ˆ˜๋™ ์ˆ˜์ • ์‹œ๋„ (์ตœ๋Œ€ 2ํšŒ ๋ฐ˜๋ณต) โ†’ 0๊ฑด ๋‹ฌ์„ฑ ํ•„์ˆ˜
  exit 1
fi
echo  " โœ… Pre-push ๊ฒ€์ฆ ํ†ต๊ณผ (๋ฆฐํŠธ 0๊ฑด) "

TodoWrite Integration (Required)#

Initialization (On Step 1 Start)#

TodoWrite([
  { content:  " Step 1: ์ด์Šˆ ์ •๋ณด ์กฐํšŒ " , status:  " in_progress " , activeForm:  " ์ด์Šˆ ์กฐํšŒ ์ค‘ "   },
  { content:  " Step 2: ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ " , status:  " pending " , activeForm:  " ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ๋Œ€๊ธฐ "   },
  { content:  " Step 3: BDD ์‹œ๋‚˜๋ฆฌ์˜ค " , status:  " pending " , activeForm:  " BDD ์ž‘์„ฑ ๋Œ€๊ธฐ "   },
  { content:  " Step 4: ๊ตฌํ˜„ ์ž‘์—… " , status:  " pending " , activeForm:  " ๊ตฌํ˜„ ๋Œ€๊ธฐ "   },
  { content:  " Step 4.5: ๋””์ž์ธ ๊ฒ€์ฆ ๊ฒŒ์ดํŠธ (screen feature ์‹œ) " , status:  " pending " , activeForm:  " ๋””์ž์ธ ๊ฒ€์ฆ ๋Œ€๊ธฐ "   },
  { content:  " Step 5: ํ…Œ์ŠคํŠธ ์‹คํ–‰ " , status:  " pending " , activeForm:  " ํ…Œ์ŠคํŠธ ๋Œ€๊ธฐ "   },
  { content:  " Step 5.5: Pre-push ๊ฒ€์ฆ + ๋ฆฐํŠธ 0๊ฑด ๊ฒŒ์ดํŠธ (์ดํ›„ ๋ชจ๋“  push๋งˆ๋‹ค ์žฌ์‹คํ–‰) " , status:  " pending " , activeForm:  " ๊ฒ€์ฆ ๋Œ€๊ธฐ "   },
  { content:  " Step 6: PR ์ƒ์„ฑ " , status:  " pending " , activeForm:  " PR ์ƒ์„ฑ ๋Œ€๊ธฐ "   },
  { content:  " Step 7: ์ฝ”๋“œ ๋ฆฌ๋ทฐ " , status:  " pending " , activeForm:  " ๋ฆฌ๋ทฐ ๋Œ€๊ธฐ "   },
  { content:  " Step 8: ๋จธ์ง€ ์Šน์ธ " , status:  " pending " , activeForm:  " ๋จธ์ง€ ๋Œ€๊ธฐ "   },
]);

Update Immediately on Step Completion#

// ๊ฐ ๋‹จ๊ณ„ ์™„๋ฃŒ ์ฆ‰์‹œ TodoWrite ํ˜ธ์ถœ
// ์˜ˆ: Step 2 ์™„๋ฃŒ ํ›„
TodoWrite([
  { content:  " Step 1: ์ด์Šˆ ์ •๋ณด ์กฐํšŒ " , status:  " completed " , activeForm:  " ์ด์Šˆ ์กฐํšŒ ์™„๋ฃŒ "   },
  { content:  " Step 2: ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ " , status:  " completed " , activeForm:  " ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ ์™„๋ฃŒ "   },
  { content:  " Step 3: BDD ์‹œ๋‚˜๋ฆฌ์˜ค " , status:  " in_progress " , activeForm:  " BDD ์ž‘์„ฑ ์ค‘ "   },
  // ... ๋‚˜๋จธ์ง€ pending ์œ ์ง€
]);

State Tracking Rules#

RuleDescription
Only 1 in_progressOnly 1 in_progress state allowed at a time
Immediate updateChange to completed immediately on step completion
Skip markingAdd "(skip)" to content for N/A steps (BDD, etc.)
Keep on failureKeep failed step as in_progress, output error message

  • issue-branch-agent: Branch creation
  • bdd-scenario-agent: BDD scenario generation (for screen features)
  • implementation-agent: Code implementation
  • test-runner-agent: Test execution (including BDD)
  • pr-lifecycle-agent: PR management
  • issue-state-agent: Issue state management
  • /dev:run: Start full cycle with work content
  • /dev:bugfix: Bug fix dedicated cycle
  • /dev:parallel: Parallel processing of multiple issues
  • /dev:sprint: Full Epic orchestration
  • /code-review: Run code review
  • /checklist:feature-complete: Completion checklist
  • /bdd:generate: BDD scenario generation