LogoSkills

zenhub-init-workspace

ZenHub 보드를 표준 6칸(New Issues→Review/QA)으로 정리하고 Done 칸을 비우며, 저장소·칸 ID 를 모은 `zenhub-conventions.yaml` 을 만듭니다 — 새 프로젝트에서 최초 1회.

/cc-dev:zenhub:init-workspace — 작업 보드 초기 세팅#

항목내용
실행 명령/cc-dev:zenhub:init-workspace
분류개발 사이클
난이도●○○ 간단
MCP 서버zenhub

한마디로#

새 프로젝트를 시작할 때 ZenHub 작업 보드(칸반)의 칸들을 표준 형태로 한 번에 정리해 주는 명령입니다. 이사 들어가기 전에 빈 방에 똑같은 규격의 정리 선반을 미리 짜 넣어 두는 것과 같아요.

누가·언제 쓰나요#

  • ZenHub 작업 공간에 새 GitHub 저장소를 막 연결한 직후
  • 팀마다 제각각인 보드 칸 구조를 표준 형태로 통일하고 싶을 때
  • /cc-dev:run 같은 개발 자동화 흐름을 본격적으로 시작하기 전 초기 세팅으로

무엇을 해주나요#

  • 작업 보드를 표준 6칸 구조로 정리합니다: New Issues → Icebox → Product Backlog → Sprint Backlog → In Progress → Review/QA
  • 더 이상 쓰지 않는 Done 칸을 비웁니다 — 그 안에 남아 있던 일감은 모두 자동으로 완료(Closed) 처리합니다. (완료는 이제 PR이 합쳐질 때 자동으로 처리되므로 Done 칸이 필요 없습니다.)
  • 저장소·조직·일감 종류·각 칸의 ID를 한곳에 모아 둔 설정 파일 .claude/config/bmad/zenhub-conventions.yaml 을 자동으로 만들어 줍니다. (다음 명령들이 매번 다시 조회하지 않고 빠르게 쓸 수 있게 해 주는 일종의 주소록입니다.)
  • 프로젝트의 .mcp.json 에 ZenHub 연결 설정이 제대로 들어 있는지 확인해 줍니다.
  • 마지막에 "무엇이 끝났고, 무엇을 손으로 더 해야 하는지" 정리한 보고서를 보여 줍니다.

참고: ZenHub의 기술적 제약 때문에 칸을 직접 지우거나 새로 추가하는 작업은 사람이 손으로 해야 합니다. 명령은 어디서 무엇을 눌러야 하는지 링크와 함께 안내만 해 줍니다.

어떻게 쓰나요#

# 기본 — 작업 공간 ID.mcp.json에서 자동으로 읽어 옵니다
/cc-dev:zenhub:init-workspace

# 작업 공간 ID를 직접 지정할 때
/cc-dev:zenhub:init-workspace --workspace-id 69c4c110fc3a90000f3387d9

--workspace-id 는 생략해도 됩니다. 생략하면 프로젝트의 .mcp.json 파일에서 ID를 알아서 찾습니다.

안에서 무슨 일이 벌어지나요#

  1. 현황 조회 — 지금 작업 보드에 어떤 칸들이 있고, 어떤 저장소가 연결돼 있는지 읽어 옵니다.
  2. 표준과 비교 — 현재 칸 목록을 표준 6칸과 견줘서 빠진 칸, 지워야 할 Done 칸, 표준에 없는 별도 칸을 가려냅니다.
  3. 분석 보고 — "현재 상태 / 추가가 필요한 작업"을 표로 보여 줍니다.
  4. Done 칸 정리 — Done 칸에 남은 일감을 모두 완료(Closed) 처리하고, Done 칸 자체를 지우는 방법(주소와 클릭 위치)을 안내합니다.
  5. 일감 종류 조회 — Epic·Feature·Task·Bug 같은 일감 유형 정보를 가져옵니다.
  6. 설정 파일 생성 — 위에서 모은 ID들을 zenhub-conventions.yaml 파일로 저장합니다.
  7. 연결 설정 확인.mcp.json 에 ZenHub 설정이 있는지 점검합니다.
  8. 완료 보고 — 끝난 일과 사람이 손으로 해야 할 다음 단계(빠진 칸 추가, Done 칸 삭제, /cc-dev:run 시작)를 정리해 보여 줍니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Triggers#

  • Right after adding a new GitHub repo to a ZenHub workspace
  • When you want to standardize workspace pipeline structure
  • Initial setup before starting development workflows like /cc-dev:run

Context Trigger Pattern#

/cc-dev:zenhub:init-workspace [--workspace-id  < id > ]

Parameters#

ParameterRequiredDescriptionExample
--workspace-idOptionalWorkspace ID (reads from .mcp.json if omitted)69c4c110fc3a90000f3387d9

Standard Pipeline Structure#

After initialization, the workspace should contain only these pipelines:

New IssuesIceboxProduct BacklogSprint BacklogIn ProgressReview/QA
PipelinePurposeNotes
New IssuesNewly created issuesAuto-placement
IceboxOn hold/low priorityOptional
Product BacklogApproved backlogAfter triage
Sprint BacklogAssigned to current sprintDuring sprint planning
In ProgressWork in progressOn branch creation
Review/QACode review/QAOn PR creation

Done pipeline is not used. Issues auto-close via GitHub Closes # keyword on PR merge.

Execution Flow#

Step 1: Query Workspace Info#

const workspace = await mcp__zenhub__getWorkspacePipelinesAndRepositories();

Extract from query results:

  • workspace.pipelines → Current pipeline list
  • workspace.githubRepositories → Connected repo list (필드명: githubRepositories, repositories 아님)
  • workspace.zenhubOrganization.id → Organization ID (setDatesForIssuezenhubOrganizationId)

Step 2: Analyze Current Pipelines#

Compare current pipeline list with the standard structure:

const STANDARD_PIPELINES = [
   " New Issues " ,
   " Icebox " ,
   " Product Backlog " ,
   " Sprint Backlog " ,
   " In Progress " ,
   " Review/QA " 
 ];

const PIPELINES_TO_REMOVE = [ " Done " ];

const currentNames = workspace.pipelines.map(p = >   p.name);
const missing = STANDARD_PIPELINES.filter(name = >   !currentNames.includes(name));
const toRemove = workspace.pipelines.filter(p = >   PIPELINES_TO_REMOVE.includes(p.name));
const extra = currentNames.filter(name = > 
   !STANDARD_PIPELINES.includes(name)  & &   !PIPELINES_TO_REMOVE.includes(name)
);

Step 3: Analysis Report#

Report current state and required actions to the user:

╔════════════════════════════════════════════════════════════════╗
║  ZenHub Workspace Pipeline Analysis                           ║
╠════════════════════════════════════════════════════════════════╣
║                                                                ║
║  Workspace: {workspace_id}                                     ║
║  Repositories: {repo_names}                                    ║
║                                                                ║
║  Current Pipelines:                                            ║
║  ✅ New Issues                                                 ║
║  ✅ Product Backlog                                            ║
║  ✅ In Progress                                                ║
║  ✅ Review/QA                                                  ║
║  ⚠️  Done (needs removal)                                      ║
║  ❌ Icebox (missing)                                           ║
║  ❌ Sprint Backlog (missing)                                   ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

Step 4: Handle Done Pipeline#

When the Done pipeline exists:

  1. Check issues in the Done pipeline:
const doneIssues = await mcp__zenhub__getIssuesInPipeline({
  pipelineId: donePipeline.id
});
  1. Close issues if any exist (대문자 "CLOSED" — 소문자 "closed" 는 enum 거부로 false-success):
for (const issue of doneIssues) {
  // GitHub 가 source of truth — 직접 닫고 ZenHub state 동기화
  await Bash(`gh issue close ${issue.number} --reason completed`);
  await mcp__zenhub__updateIssue({ issueId: issue.id, state:  " CLOSED "   });
}
// ⚠️ 파이프라인 삭제 안내(아래) 전에 전부 CLOSED 인지 재확인 — 미완 이슈가 컬럼 제거와 함께 은닉되지 않도록.
for (const issue of doneIssues) {
  const st = (await Bash(`gh issue view ${issue.number} --json state -q .state`)).trim();
  if (st !==  " CLOSED " ) throw new Error(`Done 이슈 #${issue.number} 미종료 — 파이프라인 삭제 보류`);
}
  1. Guide Done pipeline removal (모든 Done 이슈가 CLOSED 검증된 뒤에만):

The ZenHub MCP API does not support pipeline deletion. Please manually remove the Done pipeline at the following URL:

https://app.zenhub.com/workspaces/{workspace_id}/boardDone pipeline header (...)Delete pipeline

Step 5: Query and Cache Issue Types#

const issueTypes = await mcp__zenhub__getIssueTypes();

Step 6: Generate zenhub-conventions.yaml#

Generate a .claude/config/bmad/zenhub-conventions.yaml file at the project root to cache IDs:

Note: cc-product's BMAD Method workflow (/cc-product:workflow-init) generates an analogous cache at bmad/zenhub-conventions.yaml (no .claude/config/ prefix) with a different schema (see plugins/cc-product/references/templates/zenhub-conventions-template.md). The two caches are independent — this command does not read or write the cc-product path, and vice versa.

# Auto-generated by /cc-dev:zenhub:init-workspace
# Date: {current_date}

repository:
  id:  " {repo.id} " 
   owner:  " {repo_owner} " 
   name:  " {repo_name} " 

 organization:
  id:  " {workspace.organizationId} " 

 issue_types:
  epic:  " {epicType.id} " 
   feature:  " {featureType.id} " 
   task:  " {taskType.id} " 
   bug:  " {bugType.id} " 

 pipelines:
  new_issues:  " {newIssuesPipeline.id} " 
   icebox:  " {iceboxPipeline.id} " 
   product_backlog:  " {backlogPipeline.id} " 
   sprint_backlog:  " {sprintBacklogPipeline.id} " 
   in_progress:  " {inProgressPipeline.id} " 
   review_qa:  " {reviewQAPipeline.id} " 
   # Done pipeline not used — Closed on PR merge

sprints:
  active:
    id:  " " 
     name:  " " 
   upcoming:
    id:  " " 
     name:  " " 

 issue_creation:
  method:  " github " 
   # 제목/본문 접두사 규칙은 여기서 설정하지 않는다 — SoT: rules/zenhub-conventions.md
  # →  " Issue Title Conventions "   (fix:/feat:/chore:, Project/Epic/Story는 접두사 없음)

last_updated:  " {ISO_8601_timestamp} "

Step 7: Verify .mcp.json#

Verify that ZenHub MCP configuration exists in the project root's .mcp.json:

// Read .mcp.json file
const mcpConfig = readFile( " .mcp.json " );

// Check zenhub server configuration
if (!mcpConfig.mcpServers?.zenhub) {
  // Need to create .mcp.json or add zenhub configuration
}

Step 7b: Verify token actually scopes to THIS project's workspace (필수)

토큰 존재 여부만으로는 불충분하다 — ZenHub API 토큰은 단일 기본 워크스페이스에 스코프되며, 한 조직에 여러 워크스페이스(예: 프로젝트 전용 + 범용/공용)가 있으면 .mcp.json 에 값이 들어 있어도 다른 워크스페이스를 가리킬 수 있다. Step 1 에서 이미 조회한 workspace.githubRepositories 를 대상 저장소와 대조한다:

const currentRepoName = (await Bash(`gh repo view --json name -q .name`)).trim();
const scoped = workspace.githubRepositories.some(r = >   r.name === currentRepoName);
if (!scoped) {
  // ⚠️ 토큰이 다른 워크스페이스에 스코프됨. 이 상태에서는:
  //   - createGitHubIssue / getIssueTypes(repositoryId) / setIssueEstimate 는 정상 동작(노드 ID 직접 지정, 워크스페이스 무관)
  //   - getWorkspacePipelinesAndRepositories / searchLatestIssues / moveIssueToPipeline 는 이 워크스페이스 기준이라 대상 저장소와 무관하거나 실패
  // 이 경우 초기화를 계속 진행해도 파이프라인 이동(Step 3~4, 이후 /cc-dev:zenhub:breakdown 등)이 실패한다.
  // 사용자에게 올바른 워크스페이스로 스코프된 토큰 발급/교체를 안내하고 중단.
  // 상세 진단·해결: ../rules/zenhub-conventions.md  " Token / Workspace Scope Pitfall " 
 }

이 검증을 건너뛰면, 이후 이슈 생성까지는 조용히 성공하다가 파이프라인 이동(/cc-dev:zenhub:breakdown 등 후속 명령)에서 처음으로 실패가 드러나 원인 파악에 시간이 걸린다.

Step 8: Completion Report#

╔════════════════════════════════════════════════════════════════╗
║  Workspace Initialization Complete                             ║
╠════════════════════════════════════════════════════════════════╣
║                                                                ║
║  ✅ Pipeline analysis complete                                 ║
║  ✅ Done issues ({N})Closed                                 ║
║  ⚠️  Done pipeline manual removal needed (URL guided)          ║
║  ✅ zenhub-conventions.yaml generated                          ║
║  ✅ .mcp.json verification complete                            ║
║                                                                ║
║  📋 Missing Pipelines:                                         ║
║     → Manual addition needed in ZenHub Board: {missing_names}  ║
║                                                                ║
║  🏁 Next Steps:                                                ║
║     1. Manually remove Done pipeline                           ║
║     2. Manually add missing pipelines                          ║
║     3. Start development with /cc-dev:run                         ║
║                                                                ║
╚════════════════════════════════════════════════════════════════╝

Completion Rules#

  • All issues in Done pipeline are Closed (automatic)
  • Done pipeline deletion is manual (MCP API limitation)
  • Missing pipeline addition is manual (MCP API limitation)
  • zenhub-conventions.yaml is auto-generated (ID caching)
  • Re-run after pipeline changes to refresh cache
CommandDescription
/cc-dev:zenhub:managePR linking and pipeline state management
/cc-dev:zenhub:breakdownInitiative/Project/Epic/Feature/Bug/Task creation (scale auto-inferred)
/cc-dev:runFull development cycle automation