Logocob

cob sync

템플릿 프로젝트 → Mason 브릭 동기화 + 인벤토리 역생성

cob sync#

.envrc 설정을 기반으로 템플릿 프로젝트를 Mason 브릭으로 동기화합니다. --emit-manifest 모드에서는 반대로 기존 feature 패키지를 스캔해 매니페스트 v1(feature.yaml) 인벤토리를 역생성합니다.

cob sync --type <type> --project-dir template/my_project [options]

옵션#

옵션축약설명기본값
--type -t 동기화 타입 ( app , monorepo , feature , all-features , all-console-features ). --emit-manifest 사용 시 생략 가능 -
--name -n --type feature 또는 --emit-manifest의 feature 이름 (예: home, group, task) -
--project-dir-d템플릿 프로젝트 경로현재 디렉토리
--bricks-dir -b bricks/ 디렉토리 경로 프로젝트 경로에서 자동 탐지
--sync-icons템플릿의 앱 아이콘도 동기화 (기본은 기존 브릭 아이콘 보존)false
--commitsync 완료 후 bricks 레포에 자동 커밋false
--push 자동 커밋 + origin 푸시 (--commit 자동 활성화) false
--force-shared 비정본 프로젝트도 공유 brick(app/monorepo) sync 허용 (canonical donor 정책 우회) false
--strict-residual sync 후 미변환 raw 프로젝트명이 brick에 남으면 실패 (CI 게이트, monorepo) false
--emit-manifest 기존 feature의 부품 구성을 매니페스트 v1(feature.yaml)로 역생성 (읽기전용, --name 필수) false
--output -o emit-manifest 결과를 저장할 파일 경로 stdout 출력만

동기화 모드#

동기화 타입#

타입설명대상
app 앱 브릭 동기화 bricks/{app,console,widgetbook}/__brick__/
monorepo모노레포 전체 동기화bricks/monorepo/__brick__//
feature 개별 feature 브릭 동기화 (--name 필수) bricks/feature_{name}/
all-features모든 feature 브릭 일괄 동기화feature 브릭 전체
all-console-features console feature 브릭 일괄 동기화 console feature 브릭 전체

템플릿 변수 변환#

sync는 템플릿 프로젝트의 하드코딩된 값을 .envrc 설정 기반의 Mason 템플릿 변수로 변환합니다. 패턴은 우선순위 순서로 적용됩니다 (GitHub URL → GitHub 조직 → Apple Developer ID → Firebase/도메인 → 프로젝트명 → 조직명). 케이스 변환은 문맥 인식형입니다:

문맥변환 예시
GitHub URLgithub.com/org/
패키지명_service
Firestore 컬렉션_users

Canonical donor 정책#

공유 brick(app, monorepo)은 정본(canonical) 프로젝트만 sync할 수 있습니다. bricks 레포 루트의 .cob-donor.yaml 마커로 정본을 지정하며, 마커가 없으면 정책이 적용되지 않습니다. 비정본 프로젝트가 공유 brick을 sync하려면 --force-shared가 필요합니다. feature/all-features/all-console-features는 프로젝트별 분리 경로이므로 정책 없이 통과합니다.

--emit-manifest 모드 (읽기전용 인벤토리)#

기존 feature 패키지(feature/{application,console}/<name>)를 스캔해 부품 구성을 매니페스트 v1(feature.yaml) 형태로 역생성합니다. 파일을 변경하지 않는 읽기전용 모드이며, --name <feature>가 필수입니다.

감지 항목#

항목감지 위치비고
network lib/src/data/repository/mixins/{feature}_{network}_mixin.dart serverpod/openapi/graphql — v1 compose는 serverpod만 지원 (그 외 경고)
usecases lib/src/domain/usecase/*_usecase.dart 스켈레톤({feature}.dart)은 compose가 항상 생성하므로 제외
blocs lib/src/presentation/bloc/blocs/*/ bloc 파일의 final XUsecase x; 필드로 usecase 의존성 추출, 스켈레톤({feature}/) 제외
widgets lib/src/presentation/widget/*.dart widget.dart barrel 제외
entities frontend lib/src/domain/entity/ + backend *.spy.yaml 필드는 백엔드 spy.yaml(계약 소스)에서 읽음, 빈 placeholder spy 제외
backend 토글 backend/*_server/lib/src/feature/{feature}/ endpoint, console_endpoint, service, constant, exception, validation, helper, test, cache, dto, entity, enum, readme — "비어있지 않은 파일 존재" 기준

출력#

  • 매니페스트 YAML을 stdout에 출력하고, --output <path> 지정 시 파일로도 저장합니다.
  • project_namebackend/*_server 디렉토리명에서 추정하며, 미발견 시 myproject로 출력하고 경고합니다.
  • 함께 출력되는 이름 규약 리포트는 usecase ↔ repository 인터페이스(i_{feature}_repository.dart) 메서드의 1:1 매칭 성립률을 측정합니다.

한계#

역분석은 usecase ↔ repository 메서드 이름 규약 1:1 성립을 전제합니다 (성립률은 리포트로 확인). call-site AST 분석과 백엔드 3단 매칭은 의도적으로 제외됩니다 — v1 매니페스트에 wiring 표현이 없으므로 round-trip은 스키마 표현력과 일치해야 성립합니다.

--strict-residual (CI 게이트)#

monorepo sync 완료 후 ResidualTokenScanner가 brick에 남은 미변환 raw 프로젝트명 토큰을 검출합니다. 1건이라도 발견되면 sync를 실패 처리하고 software 에러 코드로 종료하므로, CI에서 변환 누락을 게이트로 차단할 수 있습니다.

🚫 --strict-residual: 미변환 raw 토큰 N건으로 sync를 실패 처리합니다.

예시#

# 모노레포 동기화
cob sync --type monorepo --project-dir template/good_teacher

# 개별 feature 브릭 동기화
cob sync --type feature --name home --project-dir template/good_teacher

# console feature 전체 동기화
cob sync --type all-console-features --project-dir template/kobic

# 동기화 후 자동 커밋 + 푸시
cob sync --type monorepo --project-dir template/good_teacher --push

# emit-manifest: home feature 인벤토리 역생성 (stdout)
cob sync --emit-manifest --name home --project-dir template/good_teacher

# emit-manifest: 파일로 저장
cob sync --emit-manifest --name home --project-dir template/good_teacher \
  --output claudedocs/home-feature.yaml
# CI에서 strict-residual 게이트 사용 (GitHub Actions)
- name: Sync monorepo (residual gate)
  run: |
    dart run bin/cob.dart sync --type monorepo \
      --project-dir template/good_teacher \
      --strict-residual