From c890aef64d3c0b6906b7ff7dced0298778bae37a Mon Sep 17 00:00:00 2001
From: opficdev <162981733+opficdev@users.noreply.github.com>
Date: Sat, 5 Sep 2026 23:41:12 +0900
Subject: [PATCH 1/4] =?UTF-8?q?docs:=20README=20=EC=9E=AC=EA=B5=AC?=
=?UTF-8?q?=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 167 ++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 137 insertions(+), 30 deletions(-)
diff --git a/README.md b/README.md
index fde807a..07d8dc1 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,109 @@
-# Cradle
+
Cradle
-Cradle은 Swift Macro를 사용해 의존성 graph의 factory를 생성하는 라이브러리입니다.
+
+ Factory를 선언하면 Cradle이 의존성을 연결하고 graph별 수명을 관리해요.
+
-## 요구 사항
+
+ ExampleApp
+ ·
+ 사용 안내
+ ·
+ 테스트
+ ·
+ MIT License
+
-- Swift tools 6.3
-- iOS 17 이상 또는 macOS 10.15 이상
-- `CradlePlugin` 사용 시 arm64 또는 x86_64 macOS 빌드 호스트
+
-## 설치
+Cradle은 Swift Macro를 사용해 `@Provide` Factory를 반환 타입과 매개변수 타입으로 연결해요. 어떤 값을 누가 만들고 언제까지 쓸지는 graph마다 정해요.
+
+Swift tools 6.3과 iOS 17 이상 또는 macOS 10.15 이상이 필요해요.
-### Swift Package Manager
+## 첫 graph
-`Package.swift`의 dependencies에 Cradle을 추가합니다. 아래 `1.0.0`은 배포가 완료된 버전 예시이며, 최초 tag가 게시되기 전에는 실제 설치에 사용할 수 없습니다.
+이 예제에서는 `UserRepository`와 `LoadUserUseCase`를 graph가 만들고 보관해요. 화면마다 달라지는 `UserID`는 `userProfileViewModel`을 호출할 때 넘겨요.
+
+```swift
+import Cradle
+
+struct UserID {
+ let rawValue: String
+}
+
+struct User {
+ let id: UserID
+}
+
+protocol UserRepository {
+ func load(id: UserID) -> User
+}
+
+struct LiveUserRepository: UserRepository {
+ func load(id: UserID) -> User {
+ User(id: id)
+ }
+}
+
+struct LoadUserUseCase {
+ let repository: any UserRepository
+
+ func execute(id: UserID) -> User {
+ repository.load(id: id)
+ }
+}
+
+struct UserProfileViewModel {
+ let user: User
+}
+
+@DependencyGraph
+final class AppGraph {
+ @Provide
+ private func makeUserRepository() -> any UserRepository {
+ LiveUserRepository()
+ }
+
+ @Provide
+ private func makeLoadUserUseCase(
+ repository: any UserRepository
+ ) -> LoadUserUseCase {
+ LoadUserUseCase(repository: repository)
+ }
+
+ @Provide(.transient)
+ private func makeUserProfileViewModel(
+ useCase: LoadUserUseCase,
+ @External userID: UserID
+ ) -> UserProfileViewModel {
+ UserProfileViewModel(user: useCase.execute(id: userID))
+ }
+}
+
+let graph = AppGraph()
+let viewModel = graph.userProfileViewModel(
+ userID: UserID(rawValue: "user-1")
+)
+```
+
+`@Provide`는 반환 타입을 기준으로 Factory를 연결해요. 기본값은 graph마다 한 번 만들고 계속 쓰며, `.transient`는 접근할 때마다 새로 만들어요. `@External`은 graph가 만들 수 없는 호출 시점 값에 붙여요.
+
+Cradle은 graph를 만들 때 누락한 등록, 중복된 등록, 순환 의존성처럼 연결할 수 없는 구성을 컴파일 단계에서 알려줘요. Factory 본문에서 하는 임의 호출이나 실행 중 상태까지 검사하지는 않아요.
+
+## 설치
+
+아직 release tag가 없어요. 지금은 `develop` branch를 가리켜 설치해요.
```swift
dependencies: [
- .package(url: "https://github.com/opficdev/Cradle.git", from: "1.0.0")
+ .package(
+ url: "https://github.com/opficdev/Cradle.git",
+ branch: "develop"
+ )
]
```
-앱 또는 라이브러리 target에는 `Cradle` product를 연결합니다.
+Cradle을 쓸 target에는 `Cradle` product를 추가해요.
```swift
.target(
@@ -31,7 +114,23 @@ dependencies: [
)
```
-`CradleTesting`은 테스트 target에서만 선택적으로 연결합니다. graph 선언과 `.mock` 편의 API를 함께 사용하려면 `Cradle`도 같은 target에 추가합니다.
+
+첫 release tag 뒤 버전을 고정하기
+
+첫 release tag가 올라오면 의존성 버전을 고정할 수 있어요.
+
+```swift
+dependencies: [
+ .package(url: "https://github.com/opficdev/Cradle.git", from: "1.0.0")
+]
+```
+
+
+
+
+테스트와 Mermaid 산출물 추가하기
+
+테스트에서 Factory를 바꾸려면 `CradleTesting`을 test target에만 연결해요. graph 선언과 `.mock` 편의 API를 함께 쓰려면 `Cradle`도 같은 target에 추가해요.
```swift
.testTarget(
@@ -43,7 +142,7 @@ dependencies: [
)
```
-`CradlePlugin`은 import하는 라이브러리가 아니라 macOS 빌드 호스트에서 실행하는 Build Tool Plugin입니다. Mermaid 개발 산출물이 필요한 target에만 연결합니다.
+`CradlePlugin`은 Swift에서 import하지 않아요. macOS build host에서 실행되는 Build Tool Plugin이므로 Mermaid 개발 산출물이 필요할 때만 target에 연결해요.
```swift
.target(
@@ -57,31 +156,39 @@ dependencies: [
)
```
-`@DependencyGraph`, `@Provide`, `@External`의 사용 조건과 생성 멤버 계약은 [DependencyGraph 안내](Sources/Cradle/Cradle.docc/DependencyGraph.md)에서 확인할 수 있습니다. 테스트 대역 교체는 [CradleTesting 안내](Sources/CradleTesting/CradleTesting.docc/CradleTesting.md)를 참고합니다.
+`CradlePlugin`은 arm64 또는 x86_64 macOS build host에서만 쓸 수 있어요.
-## 배포
+
-관리자는 Actions의 `Deploy SPM`을 수동으로 실행하고, 접두사 없는 `version`과 선택 `release_notes`를 입력합니다. 배포 흐름은 다음 순서로 진행합니다.
+
+Xcode에서 Mermaid 파일 열기
-1. `version` 형식과 기존 tag를 확인합니다.
-2. artifact, 원격 revision 소비자, 전체 test를 검증합니다.
-3. 검증한 commit에 annotated tag를 만들고 원격 tag revision을 확인합니다.
-4. exact version 소비자를 검증한 뒤 GitHub Release를 생성하고 게시 상태를 확인합니다.
+`CradlePlugin`은 build 때 Mermaid 원본을 만들어요. Xcode에서 파일을 바로 열고 싶다면 target의 마지막 Run Script 단계에서 [CopyCradleMermaid.sh](Examples/ExampleApp/Scripts/CopyCradleMermaid.sh)를 실행하고 Based on dependency analysis를 선택 해제해요.
-tag push 뒤 exact version 소비자 검증이나 Release 생성에 실패하면 tag는 그대로 남고 GitHub Release는 생성되지 않습니다. 배포는 tag를 삭제하거나 이동하지 않으므로, 원인을 확인한 뒤 기존 tag를 기준으로 별도 Release 절차를 진행해야 합니다.
+```sh
+/bin/sh "${SRCROOT}/Scripts/CopyCradleMermaid.sh"
+```
-## Mermaid 개발 산출물
+`Cmd+B` 뒤 `Examples/ExampleApp/.cradle/DependencyGraph.mmd`가 생겨요. `.cradle/`은 Git에 올리지 않고 앱과 라이브러리 binary에도 넣지 않아요. Xcode의 build 도구 작업 경로는 공개된 고정 경로가 아니에요. 경고가 나타나면 `CopyCradleMermaid.sh`의 검색 경로를 확인해요.
-`CradlePlugin`은 build 중 Mermaid 원본을 생성합니다. Xcode에서 바로 열 파일이 필요하면 target의 마지막 Run Script 단계가 `.cradle/DependencyGraph.mmd`로 복사하게 설정할 수 있습니다.
+
-### ExampleApp 설정
+
+관리자용 SwiftPM 배포
-`Examples/ExampleApp`의 `Cradle Mermaid copy` 단계는 [CopyCradleMermaid.sh](Examples/ExampleApp/Scripts/CopyCradleMermaid.sh)를 실행합니다. 같은 설정을 추가할 때는 이 단계를 target의 마지막 Build Phase에 두고 Based on dependency analysis를 선택 해제합니다.
+관리자는 Actions에서 `Deploy SPM` workflow를 직접 실행해요. 접두사 없는 `version`과 선택 `release_notes`를 입력하면 아래 순서로 배포돼요.
-```sh
-/bin/sh "${SRCROOT}/Scripts/CopyCradleMermaid.sh"
-```
+1. `version` 형식과 같은 tag가 이미 있는지 확인해요.
+2. artifact, 원격 revision 소비자, 전체 test를 검증해요.
+3. 검증한 commit에 annotated tag를 만들고 원격 tag revision을 확인해요.
+4. exact version 소비자를 검증한 뒤 GitHub Release를 생성하고 게시 상태를 확인해요.
+
+tag를 원격에 push한 뒤 exact version 소비자 검증이 실패하면 tag는 남지만 GitHub Release는 아직 생성되지 않아요. `createRelease` 요청 뒤 응답 확인이 실패한 경우에는 GitHub에서 Release 생성 여부를 직접 확인해요. 배포 과정에서 tag를 삭제하거나 이동하지 않으므로 원인을 고친 뒤 기존 tag를 기준으로 별도 Release 절차를 진행해요.
+
+
-`Cmd+B`를 마치면 `Examples/ExampleApp/.cradle/DependencyGraph.mmd`가 생성됩니다. `.cradle/`은 Git에서 제외되며 앱이나 라이브러리 제품에 포함되지 않습니다.
+## 더 살펴보기
-Xcode의 build 도구 작업 경로는 공개된 고정 경로가 아닙니다. 이 설정은 현재 `CradlePlugin` 산출물을 쉽게 열기 위한 방법이므로, Xcode 구조가 바뀐 뒤 경고가 나오면 [CopyCradleMermaid.sh](Examples/ExampleApp/Scripts/CopyCradleMermaid.sh)의 검색 경로를 확인해야 합니다.
+- [ExampleApp](Examples/ExampleApp) — 단일 app target에서 `sources`, `@External`, SwiftUI `@Observable`과 `@State`를 쓰는 상품 상세 예제
+- [DependencyGraph 안내](Sources/Cradle/Cradle.docc/DependencyGraph.md) — `sources`, 수명, actor graph, `CradlePlugin`, 선언 조건과 compiler diagnostic
+- [CradleTesting 안내](Sources/CradleTesting/CradleTesting.docc/CradleTesting.md) — `overrides: true`, `.replace`, `.mock`, graph별 테스트 대역 구성
From 124286305970cdd755a6806b11677a5868858918 Mon Sep 17 00:00:00 2001
From: opficdev <162981733+opficdev@users.noreply.github.com>
Date: Sun, 6 Sep 2026 00:04:16 +0900
Subject: [PATCH 2/4] =?UTF-8?q?docs:=20=EB=B0=B0=ED=8F=AC=20=EB=AC=B8?=
=?UTF-8?q?=EC=84=9C=EC=99=80=20=EC=95=84=ED=82=A4=ED=85=8D=EC=B2=98=20?=
=?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 24 +++++----------
docs/Architecture.md | 70 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 17 deletions(-)
create mode 100644 docs/Architecture.md
diff --git a/README.md b/README.md
index 07d8dc1..de6d360 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,8 @@
·
사용 안내
·
+ 아키텍처
+ ·
테스트
·
MIT License
@@ -86,19 +88,19 @@ let viewModel = graph.userProfileViewModel(
)
```
-`@Provide`는 반환 타입을 기준으로 Factory를 연결해요. 기본값은 graph마다 한 번 만들고 계속 쓰며, `.transient`는 접근할 때마다 새로 만들어요. `@External`은 graph가 만들 수 없는 호출 시점 값에 붙여요.
+`@Provide`는 반환 타입을 기준으로 Factory를 연결해요. 기본값은 graph마다 한 번 만들고 계속 쓰며, `.transient`는 접근할 때마다 Factory를 다시 호출해요. `@External`은 graph가 만들 수 없는 호출 시점 값에 붙여요.
Cradle은 graph를 만들 때 누락한 등록, 중복된 등록, 순환 의존성처럼 연결할 수 없는 구성을 컴파일 단계에서 알려줘요. Factory 본문에서 하는 임의 호출이나 실행 중 상태까지 검사하지는 않아요.
## 설치
-아직 release tag가 없어요. 지금은 `develop` branch를 가리켜 설치해요.
+Cradle은 Swift Package Manager에서 `1.0.0` 이상 버전으로 설치해요.
```swift
dependencies: [
.package(
url: "https://github.com/opficdev/Cradle.git",
- branch: "develop"
+ from: "1.0.0"
)
]
```
@@ -114,23 +116,10 @@ Cradle을 쓸 target에는 `Cradle` product를 추가해요.
)
```
-
-첫 release tag 뒤 버전을 고정하기
-
-첫 release tag가 올라오면 의존성 버전을 고정할 수 있어요.
-
-```swift
-dependencies: [
- .package(url: "https://github.com/opficdev/Cradle.git", from: "1.0.0")
-]
-```
-
-
-
테스트와 Mermaid 산출물 추가하기
-테스트에서 Factory를 바꾸려면 `CradleTesting`을 test target에만 연결해요. graph 선언과 `.mock` 편의 API를 함께 쓰려면 `Cradle`도 같은 target에 추가해요.
+`CradleTesting`은 `DependencyOverride.mock` 편의 API를 제공해요. 테스트에서 `.mock`을 쓰려면 `CradleTesting`을, graph 선언도 한다면 `Cradle`을 같은 test target에 추가해요. `.replace`를 직접 쓰는 경우에는 `Cradle`만 필요해요.
```swift
.testTarget(
@@ -190,5 +179,6 @@ tag를 원격에 push한 뒤 exact version 소비자 검증이 실패하면 tag
## 더 살펴보기
- [ExampleApp](Examples/ExampleApp) — 단일 app target에서 `sources`, `@External`, SwiftUI `@Observable`과 `@State`를 쓰는 상품 상세 예제
+- [아키텍처](docs/Architecture.md) — Macro 확장, `CradlePlugin`, Mermaid artifact 제작 경로
- [DependencyGraph 안내](Sources/Cradle/Cradle.docc/DependencyGraph.md) — `sources`, 수명, actor graph, `CradlePlugin`, 선언 조건과 compiler diagnostic
- [CradleTesting 안내](Sources/CradleTesting/CradleTesting.docc/CradleTesting.md) — `overrides: true`, `.replace`, `.mock`, graph별 테스트 대역 구성
diff --git a/docs/Architecture.md b/docs/Architecture.md
new file mode 100644
index 0000000..247b43b
--- /dev/null
+++ b/docs/Architecture.md
@@ -0,0 +1,70 @@
+# Cradle 아키텍처
+
+Cradle은 compiler가 graph 선언을 확장하는 경로와 build 중 Mermaid를 만드는 경로를 나눠요. 둘 다 소비자 Swift source를 보지만, 서로의 결과를 사용하지 않아요.
+
+## 소비자 build 흐름
+
+아래 그림의 실선은 package target 의존성이에요. 점선은 compiler 확장, plugin 실행, 개발용 산출물 생성처럼 build 중에만 일어나는 흐름이에요.
+
+```mermaid
+flowchart LR
+ subgraph Consumer["소비자 target"]
+ App["앱 또는 library target
Swift source"]
+ Test["test target"]
+ end
+
+ subgraph Package["Cradle package"]
+ Cradle["Cradle
공개 Macro 선언과 runtime type"]
+ Macros["CradleMacros
Macro 확장과 compiler diagnostic"]
+ Testing["CradleTesting
선택 test support"]
+ Plugin["CradlePlugin
선택 Build Tool Plugin"]
+ Maker["CradleDiagramMaker
prebuilt executable artifact"]
+ Syntax["swift-syntax products"]
+ end
+
+ App -->|import| Cradle
+ Test -->|import| Cradle
+ Test -->|선택 import| Testing
+ Testing --> Cradle
+ Cradle --> Macros
+ Macros --> Syntax
+ App -.->|Macro 확장| Macros
+ Macros -.->|생성 멤버와 compiler diagnostic| App
+ App -.->|선택 plugin 연결| Plugin
+ Plugin --> Maker
+ Plugin -.->|현재 target Swift source 전달| Maker
+ Maker -.->|개발용 .mmd 생성| Output["plugin work directory
CradleDiagrams/module/DependencyGraph.mmd
binary 미포함"]
+```
+
+소비자 target은 `Cradle`만 import해요. `CradleMacros`는 `Cradle`이 참조하는 Macro 구현 target이므로 소비자가 직접 의존하거나 import하지 않아요. Macro는 `@DependencyGraph`와 `@Provide`를 확장하고, graph 연결이 성립하지 않는 경우 compiler diagnostic을 만들어요.
+
+`CradleTesting`은 test target에서만 선택해요. `CradlePlugin`도 별도 경로예요. plugin은 현재 target의 Swift source를 `CradleDiagramMaker`에 전달해 `.mmd`를 만들 뿐, app이나 library binary에 연결하지 않아요.
+
+## artifact 제작 경로
+
+소비자 build는 prebuilt `CradleDiagramMaker`를 사용해요. 아래 target들은 그 artifact를 제작하고 검증할 때만 쓰며, 소비자 target의 의존성이 아니에요.
+
+```mermaid
+flowchart LR
+ Script["Scripts/build-diagram-artifact.sh"]
+ Artifact["Artifacts/CradleDiagramMaker.artifactbundle
CradleDiagramMaker binary"]
+ Syntax["swift-syntax products"]
+ Parser["SwiftParser"]
+
+ subgraph ArtifactBuild["artifact 제작 전용 target"]
+ MakerSource["CradleDiagramMakerSource
executable target"]
+ MakerSupport["CradleDiagramMakerSupport"]
+ Analysis["CradleGraphAnalysis"]
+ end
+
+ MakerSource --> MakerSupport
+ MakerSupport --> Analysis
+ MakerSupport --> Parser
+ Analysis --> Syntax
+ Script -.->|arm64와 x86_64 build| MakerSource
+ MakerSource -.->|artifact 제작| Artifact
+```
+
+`CradleDiagramMakerSource`는 `CradleDiagramMakerSupport`와 `CradleGraphAnalysis`로 source의 선언을 읽어요. `Scripts/build-diagram-artifact.sh`는 arm64와 x86_64 실행 파일을 만들어 artifact에 넣어요. 소비자 build에서는 이 artifact만 `CradlePlugin`이 실행해요.
+
+Mermaid 분석은 Macro 확장과 별개예요. 따라서 이 문서는 runtime override 선택, graph 수명, `@External` 호출 경로를 설명하지 않아요. 그 계약은 [DependencyGraph 안내](../Sources/Cradle/Cradle.docc/DependencyGraph.md)에서 확인할 수 있어요.
From 98f7d14cb3cbf3f9b46f2735b648fb08d7794dd2 Mon Sep 17 00:00:00 2001
From: opficdev <162981733+opficdev@users.noreply.github.com>
Date: Sun, 6 Sep 2026 00:06:18 +0900
Subject: [PATCH 3/4] =?UTF-8?q?docs:=20=EC=84=B9=EC=84=A0=20=EC=88=9C?=
=?UTF-8?q?=EC=84=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 48 ++++++++++++++++++++++++------------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
index de6d360..7237cb8 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,30 @@ Cradle은 Swift Macro를 사용해 `@Provide` Factory를 반환 타입과 매개
Swift tools 6.3과 iOS 17 이상 또는 macOS 10.15 이상이 필요해요.
+## 설치
+
+Cradle은 Swift Package Manager에서 `1.0.0` 이상 버전으로 설치해요.
+
+```swift
+dependencies: [
+ .package(
+ url: "https://github.com/opficdev/Cradle.git",
+ from: "1.0.0"
+ )
+]
+```
+
+Cradle을 쓸 target에는 `Cradle` product를 추가해요.
+
+```swift
+.target(
+ name: "AppComposition",
+ dependencies: [
+ .product(name: "Cradle", package: "Cradle")
+ ]
+)
+```
+
## 첫 graph
이 예제에서는 `UserRepository`와 `LoadUserUseCase`를 graph가 만들고 보관해요. 화면마다 달라지는 `UserID`는 `userProfileViewModel`을 호출할 때 넘겨요.
@@ -92,30 +116,6 @@ let viewModel = graph.userProfileViewModel(
Cradle은 graph를 만들 때 누락한 등록, 중복된 등록, 순환 의존성처럼 연결할 수 없는 구성을 컴파일 단계에서 알려줘요. Factory 본문에서 하는 임의 호출이나 실행 중 상태까지 검사하지는 않아요.
-## 설치
-
-Cradle은 Swift Package Manager에서 `1.0.0` 이상 버전으로 설치해요.
-
-```swift
-dependencies: [
- .package(
- url: "https://github.com/opficdev/Cradle.git",
- from: "1.0.0"
- )
-]
-```
-
-Cradle을 쓸 target에는 `Cradle` product를 추가해요.
-
-```swift
-.target(
- name: "AppComposition",
- dependencies: [
- .product(name: "Cradle", package: "Cradle")
- ]
-)
-```
-
테스트와 Mermaid 산출물 추가하기
From 9cd09e35f77c4c5653e767c57d76770d94642d78 Mon Sep 17 00:00:00 2001
From: opficdev <162981733+opficdev@users.noreply.github.com>
Date: Sun, 6 Sep 2026 00:43:22 +0900
Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=EC=86=8C=EB=B9=84=EC=9E=90=20Merma?=
=?UTF-8?q?id=20=EC=95=88=EB=82=B4=20=EB=B3=B4=EC=99=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 7237cb8..37c9348 100644
--- a/README.md
+++ b/README.md
@@ -152,13 +152,13 @@ Cradle은 graph를 만들 때 누락한 등록, 중복된 등록, 순환 의존
Xcode에서 Mermaid 파일 열기
-`CradlePlugin`은 build 때 Mermaid 원본을 만들어요. Xcode에서 파일을 바로 열고 싶다면 target의 마지막 Run Script 단계에서 [CopyCradleMermaid.sh](Examples/ExampleApp/Scripts/CopyCradleMermaid.sh)를 실행하고 Based on dependency analysis를 선택 해제해요.
+`CradlePlugin`은 build 때 Mermaid 원본을 만들어요. 외부 Xcode 프로젝트에서 파일을 바로 열려면 먼저 [CopyCradleMermaid.sh](Examples/ExampleApp/Scripts/CopyCradleMermaid.sh)를 소비자 프로젝트의 `Scripts/CopyCradleMermaid.sh`로 복사해요. Mermaid가 필요한 같은 target에 `CradlePlugin`을 연결한 뒤, target의 마지막 Run Script 단계에서 다음 명령을 실행하고 Based on dependency analysis를 선택 해제해요.
```sh
/bin/sh "${SRCROOT}/Scripts/CopyCradleMermaid.sh"
```
-`Cmd+B` 뒤 `Examples/ExampleApp/.cradle/DependencyGraph.mmd`가 생겨요. `.cradle/`은 Git에 올리지 않고 앱과 라이브러리 binary에도 넣지 않아요. Xcode의 build 도구 작업 경로는 공개된 고정 경로가 아니에요. 경고가 나타나면 `CopyCradleMermaid.sh`의 검색 경로를 확인해요.
+`Cmd+B` 뒤 소비자 프로젝트의 `.cradle/DependencyGraph.mmd`가 생겨요. `.cradle/`은 Git에 올리지 않고 앱과 라이브러리 binary에도 넣지 않아요. Xcode의 build 도구 작업 경로는 공개된 고정 경로가 아니에요. 경고가 나타나면 `CopyCradleMermaid.sh`의 검색 경로를 확인해요.