mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
Compare commits
6 commits
32e41a8ea7
...
aabce2732a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aabce2732a | ||
|
|
b85f2889b0 | ||
|
|
e091d1790f | ||
|
|
a4d63edecd | ||
|
|
4024b8dd98 | ||
|
|
766a680a34 |
5 changed files with 903 additions and 5 deletions
316
CONTRIBUTING.ko.md
Normal file
316
CONTRIBUTING.ko.md
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
# Open Design 기여 가이드
|
||||
|
||||
기여를 고민하고 있다니 고맙습니다. OD는 일부러 작게 유지합니다. 대부분의 가치는 프레임워크 코드가 아니라 **파일**(skill, design system, 프롬프트 조각)에 담겨 있습니다. 그래서 가장 효과가 큰 기여는 대개 폴더 하나, Markdown 파일 하나, 또는 PR 한 건 크기의 adapter입니다.
|
||||
|
||||
이 문서는 어떤 종류의 기여를 어디서 시작해야 하는지, 그리고 PR이 머지되려면 어떤 기준을 넘어야 하는지 정확히 알려줍니다.
|
||||
|
||||
<p align="center"><a href="CONTRIBUTING.md">English</a> · <a href="CONTRIBUTING.pt-BR.md">Português (Brasil)</a> · <a href="CONTRIBUTING.de.md">Deutsch</a> · <a href="CONTRIBUTING.fr.md">Français</a> · <a href="CONTRIBUTING.zh-CN.md">简体中文</a> · <a href="CONTRIBUTING.ja-JP.md">日本語</a> · <b>한국어</b></p>
|
||||
|
||||
---
|
||||
|
||||
## 오후 한나절이면 끝나는 세 가지 기여
|
||||
|
||||
| 하고 싶은 일 | 실제로 추가하는 것 | 위치 | 규모 |
|
||||
|---|---|---|---|
|
||||
| OD가 새로운 종류의 artifact를 렌더링하게 만들기 (청구서, iOS 설정 화면, 한 장짜리 문서 등) | **Skill** | [`skills/<your-skill>/`](skills/) | 폴더 하나, 파일 약 2개 |
|
||||
| OD가 새 브랜드의 비주얼 언어를 구사하게 만들기 | **Design System** | [`design-systems/<brand>/DESIGN.md`](design-systems/) | Markdown 파일 하나 |
|
||||
| 새 coding-agent CLI 연결하기 | **Agent adapter** | [`apps/daemon/src/agents.ts`](apps/daemon/src/agents.ts) | 배열 하나에 약 10줄 |
|
||||
| 기능 추가, 버그 수정, [`open-codesign`][ocod]에서 UX 패턴 가져오기 | 코드 | `apps/web/src/`, `apps/daemon/` | 일반 PR |
|
||||
| 문서 개선, 일부 섹션을 Français / Deutsch / 中文로 번역, 오타 수정 | 문서 | `README.md`, `README.fr.md`, `README.de.md`, `README.zh-CN.md`, `docs/`, `QUICKSTART.md` | PR 한 건 |
|
||||
|
||||
어느 쪽에 해당하는지 모르겠다면 [먼저 discussion이나 issue를 열어주세요](https://github.com/nexu-io/open-design/issues/new). 적절한 위치를 안내해 드리겠습니다.
|
||||
|
||||
---
|
||||
|
||||
## 로컬 환경 설정
|
||||
|
||||
한 페이지짜리 전체 설정 안내는 [`QUICKSTART.ko.md`](QUICKSTART.ko.md)에 있습니다. 기여자를 위한 요약은 다음과 같습니다.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nexu-io/open-design.git
|
||||
cd open-design
|
||||
corepack enable # packageManager에 고정된 pnpm을 선택합니다
|
||||
pnpm install
|
||||
pnpm tools-dev run web # daemon + web 포그라운드 루프
|
||||
pnpm typecheck # tsc -b --noEmit
|
||||
pnpm --filter @open-design/web build # 필요할 때 web 패키지 빌드
|
||||
```
|
||||
|
||||
Node `~24`와 pnpm `10.33.x`가 필요합니다. `nvm`이나 `fnm`은 선택 사항입니다. Node를 그렇게 관리하는 게 편하다면 `nvm install 24 && nvm use 24` 또는 `fnm install 24 && fnm use 24`를 실행하세요. macOS, Linux, WSL2가 주요 지원 환경입니다. Windows 네이티브도 지원합니다. 흔히 겪는 설정 문제는 [`docs/windows-troubleshooting.md`](docs/windows-troubleshooting.md)를 참고하세요.
|
||||
|
||||
## Docker 설정
|
||||
|
||||
Node.js나 pnpm을 설치하지 않고도 Open Design을 실행할 수 있습니다.
|
||||
|
||||
### 사전 준비
|
||||
|
||||
Compose v2가 포함된 Docker Desktop이 설치되어 있는지 확인하세요.
|
||||
|
||||
```bash
|
||||
docker compose version
|
||||
```
|
||||
|
||||
### Open Design 실행
|
||||
|
||||
```bash
|
||||
cd deploy
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
브라우저에서 다음 주소를 엽니다.
|
||||
|
||||
```text
|
||||
http://localhost:7456
|
||||
```
|
||||
|
||||
### 자주 쓰는 명령어
|
||||
|
||||
```bash
|
||||
# 로그 보기
|
||||
docker compose logs -f
|
||||
|
||||
# 컨테이너 재시작
|
||||
docker compose restart
|
||||
|
||||
# 컨테이너 중지
|
||||
docker compose down
|
||||
|
||||
# 최신 이미지 받기
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 선택적 환경 변수 재정의
|
||||
|
||||
`deploy/.env` 파일을 만듭니다.
|
||||
|
||||
```env
|
||||
OPEN_DESIGN_PORT=7456
|
||||
OPEN_DESIGN_MEM_LIMIT=384m
|
||||
OPEN_DESIGN_ALLOWED_ORIGINS=https://yourdomain.com
|
||||
OPEN_DESIGN_IMAGE=docker.io/vanjayak/open-design:latest
|
||||
```
|
||||
|
||||
> 프로젝트와 데이터베이스 데이터는 Docker 볼륨에 자동으로 보존됩니다.
|
||||
|
||||
전체 Docker 가이드와 고급 설정은 [`QUICKSTART.ko.md`](QUICKSTART.ko.md)를 참고하세요.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 새 Skill 추가하기
|
||||
|
||||
skill은 [`skills/`](skills/) 아래에 두는 폴더로, 루트에 `SKILL.md`를 두고 Claude Code의 [`SKILL.md` 규약][skill]에 우리의 선택적 `od:` 확장을 더한 형태입니다. **등록 절차는 없습니다.** 폴더를 넣고 daemon을 재시작하면 picker에 바로 나타납니다.
|
||||
|
||||
### → 전체 가이드는 [`docs/skills-contributing.md`](docs/skills-contributing.md)를 보세요
|
||||
|
||||
이 문서가 다음 내용을 단계별로 안내합니다.
|
||||
|
||||
- **빠른 시작** — 저장소 클론 → 가장 비슷한 기존 skill 복사 → `pnpm tools-dev run web` 실행 → picker 확인 → PR 열기.
|
||||
- **skill이란 무엇이고 무엇이 아닌가** — 당신의 아이디어가 사실은 기능이나 vendor 연동이었다면, 일주일을 아껴줍니다.
|
||||
- **skill 구조** — 최소한의 폴더 구성과 `SKILL.md` frontmatter 치트시트.
|
||||
- **로컬 실행** — 실제로 중요한 네 가지 명령어.
|
||||
- **머지 기준** — 리뷰어가 확인할 항목을 그대로 복사해 쓸 수 있는 체크리스트.
|
||||
- **PR 설명 템플릿** — PR 본문에 붙여넣고 채우면 됩니다.
|
||||
- **자주 거절되는 패턴** — 최근 실제로 사용한 거절 사유와 구체적인 예시.
|
||||
|
||||
프로토콜 명세(전체 frontmatter 문법 — 타입이 지정된 입력, 슬라이더 파라미터, craft 참조, 테스트 프리미티브)는 [`docs/skills-protocol.md`](docs/skills-protocol.md)에 별도로 정리되어 있습니다.
|
||||
|
||||
---
|
||||
|
||||
## 새 Design System 추가하기
|
||||
|
||||
design system은 `design-systems/<slug>/` 아래에 두는 [`DESIGN.md`](design-systems/README.md) 파일 하나입니다. **파일 하나뿐, 코드는 없습니다.** 넣고 daemon을 재시작하면 picker에 카테고리별로 묶여 나타납니다.
|
||||
|
||||
### design system 폴더 구성
|
||||
|
||||
```text
|
||||
design-systems/your-brand/
|
||||
└── DESIGN.md
|
||||
```
|
||||
|
||||
### `DESIGN.md` 형식
|
||||
|
||||
```markdown
|
||||
# Design System Inspired by YourBrand
|
||||
|
||||
> Category: Developer Tools
|
||||
> One-line summary that shows in the picker preview.
|
||||
|
||||
## 1. Visual Theme & Atmosphere
|
||||
…
|
||||
|
||||
## 2. Color
|
||||
- Primary: `#hex` / `oklch(...)`
|
||||
- …
|
||||
|
||||
## 3. Typography
|
||||
…
|
||||
|
||||
## 4. Spacing & Grid
|
||||
## 5. Layout & Composition
|
||||
## 6. Components
|
||||
## 7. Motion & Interaction
|
||||
## 8. Voice & Brand
|
||||
## 9. Anti-patterns
|
||||
```
|
||||
|
||||
9개 섹션 구조는 고정입니다. skill 본문이 이 구조를 grep으로 찾기 때문입니다. 첫 H1이 picker 라벨이 되고(`Design System Inspired by` 접두사는 자동으로 제거됩니다), `> Category: …` 줄이 어느 그룹에 들어갈지 결정합니다. 기존 카테고리는 [`design-systems/README.md`](design-systems/README.md)에 정리되어 있습니다. 브랜드가 정말 어디에도 안 맞으면 새 카테고리를 만들 수 있지만, **먼저 기존 카테고리부터 검토하세요**.
|
||||
|
||||
### 새 design system 머지 기준
|
||||
|
||||
1. **9개 섹션이 모두 있어야 합니다.** 찾기 어려운 데이터(예: motion 토큰)는 섹션 본문이 비어 있어도 괜찮지만, 제목은 반드시 있어야 합니다. 없으면 프롬프트의 grep이 깨집니다.
|
||||
2. **hex 코드는 실제 값이어야 합니다.** 기억이나 AI 추측이 아니라 브랜드의 사이트나 제품에서 직접 추출하세요. README의 "brand-spec extraction" 5단계 프로토콜은 maintainer에게도 똑같이 적용됩니다.
|
||||
3. **강조 색상의 OKLch 값**은 있으면 좋습니다. 라이트/다크 모드에서 팔레트가 예측 가능하게 보간됩니다.
|
||||
4. **마케팅 문구는 빼세요.** 브랜드 슬로건은 design 토큰이 아닙니다. 잘라내세요.
|
||||
5. **slug는 ASCII로 작성하세요.** `linear.app`은 `linear-app`이 되고 `x.ai`는 `x-ai`가 됩니다. 이미 가져온 69개 시스템이 이 규칙을 따르니 그대로 맞추세요.
|
||||
|
||||
우리가 제공하는 69개 제품 시스템은 [`scripts/sync-design-systems.ts`](scripts/sync-design-systems.ts)를 통해 [`VoltAgent/awesome-design-md`][acd2]에서 가져온 것입니다. 브랜드가 그 upstream에 속한다면 **그쪽에 먼저 PR을 보내세요.** 다음 동기화 때 자동으로 반영됩니다. `design-systems/` 폴더는 upstream에 맞지 않는 시스템과, 우리가 직접 작성한 스타터 2개를 위한 곳입니다.
|
||||
|
||||
---
|
||||
|
||||
## 새 coding-agent CLI 추가하기
|
||||
|
||||
새 agent(예: 어느 신생 업체의 `foo-coder` CLI)를 연결하는 일은 [`apps/daemon/src/agents.ts`](apps/daemon/src/agents.ts)에 항목 하나를 추가하는 것입니다.
|
||||
|
||||
```javascript
|
||||
{
|
||||
id: 'foo',
|
||||
name: 'Foo Coder',
|
||||
bin: 'foo',
|
||||
versionArgs: ['--version'],
|
||||
buildArgs: (prompt) => ['exec', '-p', prompt],
|
||||
streamFormat: 'plain', // 또는 해당 형식을 지원하면 'claude-stream-json'
|
||||
}
|
||||
```
|
||||
|
||||
이게 전부입니다. daemon이 `PATH`에서 감지하고, picker에 나타나며, 채팅 경로가 동작합니다. CLI가 (Claude Code의 `--output-format stream-json`처럼) **타입이 지정된 이벤트**를 내보낸다면 [`apps/daemon/src/claude-stream.ts`](apps/daemon/src/claude-stream.ts)에 파서를 연결하고 `streamFormat: 'claude-stream-json'`으로 설정하세요.
|
||||
|
||||
머지 기준:
|
||||
|
||||
1. 새 agent로 **실제 세션이 처음부터 끝까지 동작**해야 합니다. artifact가 스트리밍으로 통과한 것을 보여주는 daemon 로그를 PR 설명에 붙여넣으세요.
|
||||
2. CLI의 특이사항을 **`docs/agent-adapters.md`**에 정리하세요(키 파일이 필요한가? 이미지 입력을 지원하는가? 비대화형 플래그는 무엇인가?).
|
||||
3. **README의 "Supported coding agents" 표**에 한 줄을 추가하세요.
|
||||
|
||||
---
|
||||
|
||||
## 모델 `max_tokens` 메타데이터 갱신하기
|
||||
|
||||
API 모드 채팅은 매 요청마다 upstream provider에 `max_tokens`를 보냅니다. web 클라이언트는 [`apps/web/src/state/maxTokens.ts`](apps/web/src/state/maxTokens.ts)의 3단계 조회로 이 값을 정합니다.
|
||||
|
||||
1. 설정에서 사용자가 직접 지정한 값(있는 경우).
|
||||
2. 없으면 [`apps/web/src/state/litellm-models.json`](apps/web/src/state/litellm-models.json)의 모델별 기본값. 이는 [BerriAI/litellm][litellm]의 `model_prices_and_context_window.json`(MIT)에서 잘라온 vendored 데이터로, Anthropic, OpenAI, DeepSeek, Groq, Together, Mistral, Gemini, Bedrock, Vertex, OpenRouter 등 약 2천 개의 채팅 모델을 포함합니다.
|
||||
3. 그래도 없으면 `FALLBACK_MAX_TOKENS = 8192`.
|
||||
|
||||
새로 출시된 모델을 반영하려면 vendored JSON을 다시 생성하세요.
|
||||
|
||||
```bash
|
||||
node --experimental-strip-types scripts/sync-litellm-models.ts
|
||||
```
|
||||
|
||||
이 스크립트는 LiteLLM의 카탈로그를 가져와 `mode: 'chat'` 항목만 걸러내고, 각 항목을 `max_output_tokens`(없으면 `max_tokens`)로 매핑한 뒤 정렬된 스냅샷을 씁니다. 갱신을 유발한 PR과 함께 다시 생성된 `litellm-models.json`을 커밋하세요.
|
||||
|
||||
`maxTokens.ts`의 OVERRIDES 표는 실제로 쓰는 모델 id에 대해 LiteLLM에 값이 없거나 틀린 드문 경우를 위한 것입니다. 예를 들어 `mimo-v2.5-pro`가 그렇습니다(LiteLLM은 MiMo를 `openrouter/xiaomi/...`와 `novita/xiaomimimo/...` 별칭으로만 제공하는데, 둘 다 Xiaomi 직접 API가 쓰는 정식 id와 맞지 않습니다). 이 표는 작게 유지하세요. LiteLLM이 제대로 다루는 것은 모두 upstream에 두는 게 맞습니다.
|
||||
|
||||
[litellm]: https://github.com/BerriAI/litellm
|
||||
|
||||
---
|
||||
|
||||
## 현지화 유지보수
|
||||
|
||||
독일어는 격식 있는 `Sie`를 씁니다. OD는 1인 창작자, 에이전시, 엔지니어링 팀이 뒤섞인 사용자층에 말을 걸기 때문입니다. 비격식 `du` 어조가 더 잘 맞는다는 프로젝트 피드백이 나오기 전까지는, 격식 독일어가 가장 무난한 기본값입니다. 로케일 PR은 UI 요소, 핵심 문서, 그리고 `apps/web/src/i18n/content.ts`의 표시 전용 갤러리 메타데이터를 번역해야 하지만, `skills/`나 `design-systems/`, 또는 agent가 실행하는 프롬프트 본문은 번역하면 안 됩니다. 이런 원본 프롬프트는 워크플로우 입력으로 관리되며, 원본 언어를 하나로 유지해야 로케일마다 프롬프트 QA가 늘어나는 일을 막을 수 있습니다. skill, design system, 프롬프트 템플릿을 추가하거나 이름을 바꿀 때는 독일어 표시 메타데이터를 갱신하고 `pnpm --filter @open-design/web test`를 실행하세요. 독일어 표시 항목이 누락되면 `content.test.ts`가 실패합니다. daemon 오류, export 파일명, agent가 생성한 artifact 텍스트는 PR이 명시적으로 범위에 넣지 않는 한 알려진 한계로 둡니다.
|
||||
|
||||
새 로케일을 추가하는 단계별 안내(UI 사전, README, 언어 전환기, 지역별 용어)는 [`TRANSLATIONS.md`](TRANSLATIONS.md)를 참고하세요.
|
||||
|
||||
---
|
||||
|
||||
## 코드 스타일
|
||||
|
||||
포매팅에 까다롭게 굴지는 않지만(저장 시 Prettier로 충분합니다), 두 가지 규칙은 양보할 수 없습니다. 프롬프트 스택과 사용자에게 노출되는 API에 그대로 드러나기 때문입니다.
|
||||
|
||||
1. **JS/TS는 작은따옴표.** escape 때문에 보기 흉해지는 경우가 아니라면 문자열은 작은따옴표로 감쌉니다. 코드베이스는 이미 일관되니 맞춰주세요.
|
||||
2. **주석은 영어로.** PR이 Deutsch나 中文로 번역하는 작업이더라도 코드 주석은 영어로 둡니다. grep으로 찾을 수 있는 참조를 한 벌로 유지하기 위해서입니다.
|
||||
|
||||
그 외에:
|
||||
|
||||
- **설명조 주석은 쓰지 마세요.** `// import the module`이나 `// loop through items` 같은 것 말입니다. 코드만 봐도 명백하다면 그 주석은 잡음입니다. 주석은 코드로 표현할 수 없는 의도나 제약에만 쓰세요.
|
||||
- **`apps/web/src/`는 TypeScript를 씁니다.** daemon(`apps/daemon/`)은 타입이 중요한 곳에 JSDoc을 붙인 순수 ESM JavaScript입니다. 그대로 유지하세요.
|
||||
- **새 최상위 의존성을 추가하지 마세요.** 추가한다면 얻는 것과 늘어나는 번들 크기를 PR 설명에 한 단락으로 적으세요. [`package.json`](package.json)의 의존성 목록은 일부러 작게 둡니다.
|
||||
- **푸시 전에 `pnpm typecheck`를 실행하세요.** CI에서도 돌립니다. 실패하면 "고쳐주세요" 코멘트를 받게 됩니다.
|
||||
|
||||
---
|
||||
|
||||
## 커밋과 pull request
|
||||
|
||||
- **PR 하나에 관심사 하나.** skill 추가 + 파서 리팩터링 + 의존성 버전 업은 PR 세 개입니다.
|
||||
- **제목은 명령형 + 범위.** `add dating-web skill`, `fix daemon SSE backpressure when CLI hangs`, `docs: clarify .od layout`처럼 씁니다.
|
||||
- **PR 템플릿을 사용하세요.** [`.github/pull_request_template.md`](.github/pull_request_template.md)의 모든 섹션(Why, What users will see, Surface area, Screenshots(UI인 경우), Bug fix verification(버그 수정인 경우), Validation)을 채우세요. 빈 섹션에는 "채워주세요" 답변이 달립니다.
|
||||
- **본문에는 이유를 적으세요.** "이게 뭘 하는지"는 보통 diff만 봐도 알 수 있습니다. 정작 드러나지 않는 것은 "이게 왜 있어야 하는지"입니다.
|
||||
- **issue가 있다면 연결하세요.** issue가 없고 PR이 사소하지 않다면 먼저 issue를 열어주세요. 시간을 쏟기 전에 그 변경을 원하는지 합의할 수 있습니다.
|
||||
- **리뷰 중에는 squash하지 마세요.** fixup 커밋을 푸시하면 머지할 때 우리가 squash합니다.
|
||||
- **공유 브랜치에 force-push하지 마세요.** 리뷰어가 요청한 경우는 예외입니다.
|
||||
|
||||
CLA는 요구하지 않습니다. Apache-2.0으로 충분하며, 당신의 기여도 같은 라이선스를 따릅니다.
|
||||
|
||||
---
|
||||
|
||||
## 버그 신고하기
|
||||
|
||||
다음 내용을 담아 issue를 열어주세요.
|
||||
|
||||
- 무엇을 실행했는지(정확한 `pnpm tools-dev ...` 호출).
|
||||
- 어떤 agent CLI를 선택했는지(또는 BYOK 경로였는지).
|
||||
- 이를 유발한 skill + design system 조합.
|
||||
- 관련된 **daemon stderr 끝부분**. "artifact가 렌더링되지 않았다"는 신고 대부분은 `spawn ENOENT`나 CLI의 실제 오류가 보이면 30초 만에 원인이 잡힙니다.
|
||||
- UI 문제라면 스크린샷.
|
||||
|
||||
프롬프트 스택 버그("agent가 보라색 그라데이션 hero를 내보냈는데, slop 블랙리스트가 그걸 막았어야 했다")라면 **assistant 메시지 전문**을 함께 넣어주세요. 위반이 모델 탓인지 프롬프트 탓인지 볼 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
## 질문하기
|
||||
|
||||
- 아키텍처 질문, 설계 질문, "이게 버그인지 오용인지" → [GitHub Discussions](https://github.com/nexu-io/open-design/discussions) (권장 — 다음 사람이 검색할 수 있습니다).
|
||||
- "X를 하는 skill을 어떻게 작성하나요" → discussion을 열어주세요. 답해드리고, 빠져 있던 패턴이라면 그 답을 [`docs/skills-protocol.md`](docs/skills-protocol.md)에 정리합니다.
|
||||
|
||||
---
|
||||
|
||||
## 받지 않는 것
|
||||
|
||||
프로젝트의 초점을 유지하기 위해, 다음과 같은 PR은 열지 말아주세요.
|
||||
|
||||
- **모델 런타임을 vendor로 포함.** OD의 핵심 베팅은 "이미 쓰고 있는 CLI면 충분하다"입니다. `pi-ai`나 OpenAI 키, 모델 로더를 제공하지 않습니다.
|
||||
- **사전 논의 없이 현재 스택에서 벗어나는 프론트엔드 재작성.** Next.js 16 App Router + React 18 + TS가 기준선입니다. maintainer가 명시적으로 그 마이그레이션을 원하지 않는 한 Astro, Solid, Svelte 같은 다른 프레임워크로의 재작성은 받지 않습니다.
|
||||
- **daemon을 serverless 함수로 대체.** daemon의 존재 이유는 실제 `cwd`를 소유하고 실제 CLI를 spawn하는 것입니다. SPA를 Vercel에 배포하는 것은 괜찮지만, daemon은 daemon으로 남습니다.
|
||||
- **텔레메트리 / 분석 / phone-home 추가.** OD는 local-first입니다. 외부로 나가는 호출은 사용자가 명시적으로 설정한 provider로 향하는 것뿐입니다.
|
||||
- **바이너리 번들링** 시 라이선스 파일과 저작자 표기를 옆에 두지 않는 경우.
|
||||
|
||||
아이디어가 적합한지 모르겠다면 코드를 작성하기 전에 discussion을 열어주세요.
|
||||
|
||||
---
|
||||
|
||||
## Maintainer 되기
|
||||
|
||||
꾸준히 기여해 왔고 Maintainer가 되는 길이 궁금하다면, 규칙은 **[`MAINTAINERS.ko.md`](MAINTAINERS.ko.md)**에 있습니다. 요약하면 이렇습니다.
|
||||
|
||||
- Maintainer는 issue를 리뷰하고 승인하고 닫을 수 있습니다. 머지 버튼은 Core Team이 쥐고 있지만, 당신의 승인은 머지에 필요한 승인으로 그대로 인정됩니다.
|
||||
- 기준은 **머지된 PR 20건 이상**에 더해, 공개된 계정 품질 검증(봇 방지, sock-puppet 방지)과 기여 품질에 대한 Core Team의 판단입니다. 지원서 양식은 없습니다. Core Team이 내부적으로 후보를 올리고 직접 연락합니다.
|
||||
- **할당량도, SLA도, 정해진 임기도 없습니다.** 물러나는 일은 쉽고 되돌릴 수 있습니다(Emeritus → 여유가 생기면 복귀).
|
||||
- 모든 기준, 추천 절차, 물러나는 규칙, 초기 프로젝트 면제 조항은 [`MAINTAINERS.ko.md`](MAINTAINERS.ko.md)에 있습니다. 위 내용 중 관심 가는 게 있다면 그 문서를 읽어보세요.
|
||||
|
||||
요컨대 좋은 PR을 내고, 사려 깊게 리뷰하고, [Discussions][discussions]와 [Discord][discord]에서 어울리다 보면 나머지는 알아서 따라옵니다.
|
||||
|
||||
[discussions]: https://github.com/nexu-io/open-design/discussions
|
||||
[discord]: https://discord.gg/qhbcCH8Am4
|
||||
|
||||
---
|
||||
|
||||
## 라이선스
|
||||
|
||||
기여하면, 당신의 기여가 이 저장소의 [Apache-2.0 License](LICENSE)를 따른다는 데 동의하는 것입니다. 단 [`design-templates/guizang-ppt/`](design-templates/guizang-ppt/) 안의 파일은 예외로, 원래의 MIT 라이선스와 [op7418](https://github.com/op7418)에 대한 저작자 표기를 그대로 유지합니다.
|
||||
|
||||
[skill]: https://docs.anthropic.com/en/docs/claude-code/skills
|
||||
[guizang]: https://github.com/op7418/guizang-ppt-skill
|
||||
[acd2]: https://github.com/VoltAgent/awesome-design-md
|
||||
[ocod]: https://github.com/OpenCoworkAI/open-codesign
|
||||
191
MAINTAINERS.ko.md
Normal file
191
MAINTAINERS.ko.md
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
# Maintainers
|
||||
|
||||
<p align="center"><a href="MAINTAINERS.md">English</a> · <a href="MAINTAINERS.pt-BR.md">Português (Brasil)</a> · <a href="MAINTAINERS.de.md">Deutsch</a> · <a href="MAINTAINERS.fr.md">Français</a> · <a href="MAINTAINERS.zh-CN.md">简体中文</a> · <a href="MAINTAINERS.ja-JP.md">日本語</a> · <b>한국어</b></p>
|
||||
|
||||
이 문서는 `nexu-io/open-design`의 Maintainer가 되고, 그 역할을 맡고, 물러나는 규칙을 정합니다. Core Team의 개별 명단은 내부에서 관리하므로 여기에 적지 않습니다. 공개적으로 중요한 건 모두가 따르는 규칙 그 자체입니다.
|
||||
|
||||
> **상태**: v1, 2026-05-11 초안 작성. [`CONTRIBUTING.ko.md`](CONTRIBUTING.ko.md#maintainer-되기)와 짝을 이루는 문서입니다. CONTRIBUTING.ko.md는 전체 규칙을 확인하려는 기여자를 이 문서로 안내합니다.
|
||||
|
||||
---
|
||||
|
||||
## 역할
|
||||
|
||||
| 역할 | 권한 |
|
||||
|---|---|
|
||||
| **Contributor** | 머지된 PR이 1건 이상인 모든 사람. 특별한 권한은 없습니다. |
|
||||
| **External Maintainer** | 아래 규칙에 따라 승격된 커뮤니티 기여자. 리뷰, 승인, issue 닫기/다시 열기, issue 셀프 배정을 할 수 있습니다. **머지 버튼은 누를 수 없습니다** — 이 권한은 Core Team이 갖습니다. |
|
||||
| **Core Team** | Open Design의 내부 팀. 저장소 전체 쓰기 권한을 갖고, 거버넌스 결정의 최종 권한을 가집니다. 명단은 내부에서 관리합니다. |
|
||||
|
||||
별도 언급이 없으면 이 문서의 나머지는 모두 **External Maintainer**에 관한 내용입니다.
|
||||
|
||||
---
|
||||
|
||||
## Maintainer만 할 수 있고 Contributor는 할 수 없는 것
|
||||
|
||||
| 동작 | Contributor | Maintainer |
|
||||
|---|:---:|:---:|
|
||||
| PR 승인 | ⚠️ 단순 코멘트로 처리되며, 머지에 필요한 승인으로 **인정되지 않음** | ✓ 머지에 필요한 승인으로 인정됨 |
|
||||
| issue 닫기 / 다시 열기 | 본인이 연 issue만 | ✓ 모든 issue |
|
||||
| 열려 있고 배정되지 않은 issue 셀프 배정(P0 우선) | ✗ | ✓ |
|
||||
|
||||
### 머지 조건
|
||||
|
||||
PR은 누가 작성했든 다음 **세 가지를 모두** 만족해야 합니다.
|
||||
|
||||
1. 코드 충돌이 없을 것.
|
||||
2. CI가 완전히 통과(green)할 것.
|
||||
3. Maintainer 또는 Core Team 멤버의 승인이 최소 1건 있을 것.
|
||||
|
||||
대부분의 PR은 Maintainer의 승인을 거쳐 머지됩니다. Maintainer의 신뢰가 프로젝트의 일상에 가장 직접적으로 드러나는 방식입니다.
|
||||
|
||||
---
|
||||
|
||||
## Maintainer가 되는 방법
|
||||
|
||||
진입 조건은 **세 가지**이며, 모두 충족해야 합니다.
|
||||
|
||||
### 1. 기여량
|
||||
|
||||
- `nexu-io/open-design`에 머지된 PR **20건 이상**.
|
||||
|
||||
이 수치는 자동 통과 기준이 아니라 최소선입니다. PR 20건을 넘기면 검토 대상에 오를 뿐, 역할이 보장되지는 않습니다.
|
||||
|
||||
### 2. 계정 신뢰도(다중 계정·봇 방지)
|
||||
|
||||
후보의 GitHub 프로필을 일곱 가지 항목으로 점검합니다. **7개 중 5개 이상의 통과 기준을 만족하고, 거부 기준은 하나도 건드리지 않아야 합니다.**
|
||||
|
||||
| # | 항목 | 통과 기준 | 거부 기준 |
|
||||
|---|---|---|---|
|
||||
| 1 | GitHub 계정 나이 | 1년 이상 | 90일 미만 |
|
||||
| 2 | 공개 저장소 | 3개 이상 | 0개 |
|
||||
| 3 | 팔로워 | 10명 이상 | 3명 미만 |
|
||||
| 4 | 팔로워 / 팔로잉 비율 | 0.30 초과 | 0.05 미만(전형적인 팔로우 농장 패턴) |
|
||||
| 5 | 프로필 완성도 | 커스텀 아바타 **그리고** bio / company / blog / twitter 중 하나 이상 | 기본 아바타 **그리고** bio·company·blog가 모두 비어 있음 |
|
||||
| 6 | 다른 프로젝트 활동 | **다른** 공개 저장소에 머지된 PR이 하나 이상 있거나, issue/star 활동이 꾸준함 | 머지된 PR이 이 저장소에만 있음 |
|
||||
| 7 | 계정 상태 | GitHub 플랫폼 제재 이력 없음(스팸/차단/복구) | 위 항목 중 하나라도 해당 |
|
||||
|
||||
#### 초기 프로젝트 면제(저장소가 6개월이 되면 자동 만료)
|
||||
|
||||
`nexu-io/open-design`이 최초 커밋으로부터 6개월 미만인 동안에는, 다음 조건에서 **다른 프로젝트 활동**(#6) 거부 기준을 Core Team 합의로 면제할 수 있습니다.
|
||||
|
||||
- 항목 1, 2, 3, 5가 통과 기준을 명확히 넘을 것, **그리고**
|
||||
- 이 저장소에서의 PR 품질이 Core Team의 직접 리뷰로 높게 평가될 것.
|
||||
|
||||
면제할 때는 후보 이름과 날짜를 Core Team 내부 기록에 함께 남깁니다. 저장소가 6개월에 도달하면 이 면제 조항은 더 이상 적용되지 않습니다.
|
||||
|
||||
### 3. 기여 품질(Core Team 판단)
|
||||
|
||||
정성적인 평가이며 공식에 따르지 않습니다. Core Team은 다음을 봅니다.
|
||||
|
||||
- 머지된 PR의 **코드 품질**(정확성, 작업 범위 준수, 저장소 경계 존중).
|
||||
- 다른 사람의 PR에 남긴 리뷰 코멘트의 **리뷰 품질**.
|
||||
- **커뮤니티 참여** — Discussions, issue 분류, Discord 활동.
|
||||
- **협업 신호** — 피드백에 대한 반응, 기꺼이 수정하려는 자세.
|
||||
|
||||
앞의 두 조건을 통과하면 후보군에 들어갑니다. 이 세 번째 기준을 넘어서야 지명을 받습니다.
|
||||
|
||||
### 선정 절차
|
||||
|
||||
1. Core Team 멤버가 내부에서 후보를 제안합니다.
|
||||
2. Core Team이 합의에 이릅니다.
|
||||
3. Core Team 멤버가 비공개로 연락해 후보의 의사를 확인합니다.
|
||||
4. 온보딩.
|
||||
5. 공개 발표.
|
||||
|
||||
지명 PR도, 공개 투표도, 정해진 임기도 없습니다. 이는 의도적으로 **K8s/Apache의 승인자 투표 모델을 뒤집은** 방식입니다. 프로젝트 초기에는 가벼운 Core Team 합의가 더 빠르게 움직이면서도 같은 수준의 결과를 냅니다. Maintainer 인원이 External Maintainer 다섯 명을 넘어 늘어나면 이 부분을 다시 검토합니다.
|
||||
|
||||
---
|
||||
|
||||
## 책임과 기대
|
||||
|
||||
**엄격한 할당량은 없습니다.** 주간 PR 리뷰 횟수도, 최소 issue 분류 비율도, 응답 시간 SLA도 없습니다. Maintainer는 신뢰의 인정이지, 보수 없는 업무가 아닙니다.
|
||||
|
||||
다만 원칙적으로 부탁드리는 것은 다음과 같습니다.
|
||||
|
||||
- 맥락을 아는 PR은 승인하고, 모르는 PR은 판단을 보류하세요.
|
||||
- 머지 조건(§"머지 조건")을 지키세요. 당신의 승인은 형식적인 도장이 아니라 실질적인 신호입니다.
|
||||
- 오랜 기간 자리를 비울 때는 `#maintainers`에 알려 주세요.
|
||||
- `#maintainers`에서 공유되는 미공개 로드맵은 기밀로 다뤄 주세요.
|
||||
|
||||
Core Team이 나쁜 행태(형식적 승인, 악의적 issue 닫기, 미공개 로드맵 유출 등)의 패턴을 확인하면, §"사유 기반 사임"에 따라 권한을 회수합니다.
|
||||
|
||||
---
|
||||
|
||||
## Maintainer 전용 접근 권한
|
||||
|
||||
위에 적은 저장소 권한 외에도, Maintainer는 일반 커뮤니티가 받지 못하는 몇 가지를 받습니다.
|
||||
|
||||
- **Discord `#maintainers` 채널** — Core Team과 공유하는 비공개 작업 공간. 디자인 미리보기, RFC 초안, 그리고 아직 공개되지 않은 로드맵에 대한 내부 조율에 씁니다.
|
||||
- **기밀 로드맵** — 아직 발표되지 않은 작업을 미리 볼 수 있습니다. Maintainer는 Core Team 멤버가 공개로 발표하기 전까지 그 내용을 기밀로 다루기로 합의합니다.
|
||||
- **Core Team과의 직통 라인** — `#maintainers` 메시지는 공개 Discussions보다 더 빠르고 충실한 답을 받습니다. Core Team은 아키텍처와 로드맵 결정에 Maintainer의 의견을 진심으로 구합니다.
|
||||
- **Maintainer 배지** — GitHub 프로필과 MAINTAINERS 관련 저장소 화면에 표시되는 공개 신뢰 표식(GitHub 배지 기능이 준비되는 대로 적용).
|
||||
- **승격 시 공개 인정** — 합류할 때 Twitter, GitHub Discussions, Discord에서 발표합니다.
|
||||
|
||||
---
|
||||
|
||||
## 사임
|
||||
|
||||
Maintainer는 종신직이 아닙니다. 세 가지 퇴장 경로가 있습니다.
|
||||
|
||||
### 자발적 사임(스스로)
|
||||
|
||||
- Maintainer가 Core Team에 메시지를 보내거나 `#maintainers`에 글을 올립니다.
|
||||
- 권한은 24시간 안에 회수됩니다.
|
||||
- 해당 Maintainer는 **Emeritus** 상태로 전환됩니다.
|
||||
- 공개적인 사유는 필요 없습니다.
|
||||
|
||||
### 비활동 전환
|
||||
|
||||
다음 중 **하나라도** 해당하면 비활동 전환 대상으로 검토합니다.
|
||||
|
||||
- 활동 신호(머지된 PR, 리뷰 코멘트, issue 분류, 비중 있는 Discussion이나 Discord 참여)가 90일 연속 없거나, **또는**
|
||||
- @ 멘션(PR 리뷰 요청, issue 배정)에 60일 연속 응답이 없음.
|
||||
|
||||
절차:
|
||||
|
||||
1. Core Team이 `#maintainers`에서 해당 Maintainer를 비공개로 @ 멘션하고, **14일의 응답 기간**을 줍니다.
|
||||
2. 14일 안에 의미 있는 응답이 없으면 Emeritus로 전환되고 권한이 회수됩니다.
|
||||
3. GitHub Discussions에 짧고 따뜻한 공개 안내를 올립니다: "그동안의 기여에 감사합니다. Emeritus로 전환되었으며, 언제든 다시 돌아오셔도 좋습니다."
|
||||
4. 복귀는 쉽습니다 — 아래 "Emeritus"를 참고하세요.
|
||||
|
||||
### 사유 기반 사임
|
||||
|
||||
다음에 의해 발동됩니다.
|
||||
|
||||
- 반복되는 나쁜 행태(예: 함량 미달 PR에 대한 형식적 승인, 악의적 issue 닫기, 권한 남용).
|
||||
- 프로젝트 [행동 강령][coc] 위반.
|
||||
- 보안 등급의 사고(계정 탈취를 즉시 보고하지 않음, 미공개 로드맵 고의 유출 등).
|
||||
|
||||
절차:
|
||||
|
||||
1. Core Team 멤버는 누구나 논의를 시작할 수 있습니다.
|
||||
2. 조치를 취하기 전에 **Core Team 멤버 3명 이상**이 동의해야 합니다(Core Team 전원 합의까지는 필요하지 않습니다).
|
||||
3. 결정 후 24시간 안에: 권한 회수, `#maintainers`에서 제외, 모든 Maintainer 명단에서 제거(Emeritus로 전환되지 **않습니다**).
|
||||
4. 당사자에게 결정과 사유를 알리며, 한 차례 이의를 제기할 수 있습니다.
|
||||
|
||||
원칙은 **Maintainer를 가급적 유지하는 쪽**입니다. 작은 실수 한 번은 강제 사임의 사유가 되지 않습니다. 사유 기반 경로는 반복되는 패턴이나 심각한 일회성 사고에만 적용합니다.
|
||||
|
||||
[coc]: https://www.contributor-covenant.org/
|
||||
|
||||
---
|
||||
|
||||
## Emeritus
|
||||
|
||||
자발적으로 사임하거나 비활동으로 전환된 Maintainer는 **Emeritus**가 됩니다. Emeritus 상태는 다음과 같습니다.
|
||||
|
||||
- 쓰기/승인/닫기 권한을 회수합니다.
|
||||
- (내부) 명단의 Emeritus 항목에 이름을 남겨 공로를 기립니다.
|
||||
- Discord `#maintainers` 접근 권한을 유지합니다(읽기든 글쓰기든 Maintainer가 선택).
|
||||
- 이어지는 책임은 없습니다.
|
||||
|
||||
### Emeritus에서 복귀
|
||||
|
||||
가장 간단한 복귀 경로: 최근 30일 안에 머지된 PR 3건. 그러면 Core Team이 권한을 복원합니다. 다시 지명받을 필요는 없습니다.
|
||||
|
||||
Emeritus의 취지는 인생에는 늘 일이 생긴다는 점을 인정하는 것입니다. 안식년, 이직, 육아 같은 일을 양쪽 모두에게 아무런 부담이나 사회적 비용 없이 받아들이려는 것입니다.
|
||||
|
||||
---
|
||||
|
||||
## 이 문서의 변경
|
||||
|
||||
이 문서의 규칙은 Core Team 합의로 개정할 수 있습니다. 중대한 변경(진입 조건, 사임 기준)은 활동 중인 후보에게 적용되기 전에 GitHub Discussions에 발표합니다. 편집상의 명확화는 곧바로 반영할 수 있습니다.
|
||||
391
QUICKSTART.ko.md
Normal file
391
QUICKSTART.ko.md
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
# 빠른 시작
|
||||
|
||||
<p align="center"><a href="QUICKSTART.md">English</a> · <a href="QUICKSTART.pt-BR.md">Português (Brasil)</a> · <a href="QUICKSTART.de.md">Deutsch</a> · <a href="QUICKSTART.fr.md">Français</a> · <a href="QUICKSTART.ja-JP.md">日本語</a> · <a href="QUICKSTART.zh-CN.md">简体中文</a> · <a href="QUICKSTART.zh-TW.md">繁體中文</a> · <b>한국어</b></p>
|
||||
|
||||
제품 전체를 로컬에서 실행해 보세요.
|
||||
|
||||
## 환경 요구사항
|
||||
|
||||
- **Node.js:** `~24`(Node 24.x). `package.json#engines`로 버전을 강제합니다.
|
||||
- **pnpm:** `10.33.x`. `packageManager`에 `pnpm@10.33.2`를 고정해 두었으니, Corepack을 쓰면 고정된 버전이 자동으로 선택됩니다.
|
||||
- **OS:** macOS, Linux, WSL2가 주요 지원 환경입니다. Windows 네이티브도 지원합니다. 자주 겪는 설치 문제는 [`docs/windows-troubleshooting.md`](docs/windows-troubleshooting.md)를 참고하세요.
|
||||
- **선택: 로컬 에이전트 CLI:** Claude Code, Codex, Devin for Terminal, Gemini CLI, OpenCode, Cursor Agent, Qwen, Qoder CLI, GitHub Copilot CLI 등. 설치된 CLI가 없으면 Settings에서 BYOK API 모드를 쓰면 됩니다.
|
||||
|
||||
### 로컬 에이전트 CLI와 PATH
|
||||
|
||||
daemon은 **`PATH`**(여기에 더해 자주 쓰이는 사용자 툴체인 디렉터리)를 스캔합니다. **`npm install -g`**나 **Homebrew**로 CLI를 설치했는데도 Open Design이 *not installed*로 표시한다면, GUI가 최소한의 `PATH`로 시작하면서 전역 npm이나 Homebrew의 `bin` 디렉터리를 포함하지 못한 경우입니다(앱이 전체 로그인 셸에서 실행되지 않은 macOS에서 흔히 발생). daemon을 실행하는 프로세스의 `PATH`에 실행 파일 디렉터리가 들어 있는지 확인한 뒤, **Settings → Execution mode**에서 **Rescan**을 누르세요.
|
||||
|
||||
[`nvm`](https://github.com/nvm-sh/nvm) / [`fnm`](https://github.com/Schniz/fnm)은 편의를 위한 선택 도구일 뿐, 프로젝트 설정에 꼭 필요한 것은 아닙니다. 둘 중 하나를 쓴다면 pnpm을 실행하기 전에 Node 24를 설치하고 선택하세요.
|
||||
|
||||
```bash
|
||||
# nvm
|
||||
nvm install 24
|
||||
nvm use 24
|
||||
|
||||
# fnm
|
||||
fnm install 24
|
||||
fnm use 24
|
||||
```
|
||||
|
||||
그다음 Corepack을 켜고 리포지토리가 pnpm을 선택하도록 합니다.
|
||||
|
||||
```bash
|
||||
corepack enable
|
||||
corepack pnpm --version # 10.33.2가 출력되어야 합니다
|
||||
```
|
||||
|
||||
## Docker 설정
|
||||
|
||||
Node.js나 pnpm을 로컬에 설치하지 않고도, 완전히 컨테이너화된 환경에서 Open Design을 실행할 수 있습니다.
|
||||
|
||||
### 요구사항
|
||||
|
||||
* Docker Desktop
|
||||
* Docker Compose v2
|
||||
|
||||
Docker가 제대로 설치됐는지 확인하세요.
|
||||
|
||||
```bash
|
||||
docker compose version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Design 시작하기
|
||||
|
||||
리포지토리 루트에서 진행합니다.
|
||||
|
||||
1. deploy 디렉터리로 이동한 뒤 환경 변수 템플릿을 복사합니다.
|
||||
|
||||
```bash
|
||||
cd deploy
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2. 안전한 토큰을 생성합니다.
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
3. 에디터에서 `.env`를 열고 `OD_API_TOKEN=`을 찾아, 방금 생성한 토큰을 붙여 넣습니다.
|
||||
|
||||
이제 서비스를 시작합니다.
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
브라우저에서 앱을 엽니다.
|
||||
|
||||
```text
|
||||
http://localhost:7456
|
||||
```
|
||||
|
||||
처음 시작할 때는 Docker가 최신 이미지를 받아오느라 몇 초 걸릴 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
## 자주 쓰는 Docker 명령어
|
||||
|
||||
### 로그 보기
|
||||
|
||||
```bash
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
### 컨테이너 재시작
|
||||
|
||||
```bash
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
### 컨테이너 중지
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### 최신 이미지 받아오기
|
||||
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 로컬 앱 데이터 전부 삭제
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 환경 설정
|
||||
|
||||
기본 설정을 덮어쓰려면 `deploy/.env` 파일을 만드세요. 제공된 예시에서 시작하면 됩니다.
|
||||
|
||||
```bash
|
||||
cp deploy/.env.example deploy/.env
|
||||
```
|
||||
|
||||
`deploy/.env`를 편집해 직접 만든 토큰을 넣고, 나머지 값도 필요에 맞게 조정합니다.
|
||||
|
||||
```env
|
||||
# 호스트에 노출할 포트
|
||||
OPEN_DESIGN_PORT=7456
|
||||
|
||||
# 컨테이너 메모리 제한
|
||||
OPEN_DESIGN_MEM_LIMIT=384m
|
||||
|
||||
# 허용할 CORS origin
|
||||
OPEN_DESIGN_ALLOWED_ORIGINS=https://yourdomain.com
|
||||
|
||||
# Docker 이미지 태그
|
||||
OPEN_DESIGN_IMAGE=docker.io/vanjayak/open-design:latest
|
||||
|
||||
# daemon 보안에 필요한 API 토큰
|
||||
# 생성 방법: openssl rand -hex 32
|
||||
OD_API_TOKEN=
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 영구 저장소
|
||||
|
||||
Open Design은 프로젝트와 SQLite 데이터를 Docker 볼륨 안에 저장합니다.
|
||||
|
||||
```text
|
||||
open_design_data
|
||||
```
|
||||
|
||||
이 볼륨은 다음 경로에 마운트됩니다.
|
||||
|
||||
```text
|
||||
/app/.od
|
||||
```
|
||||
|
||||
데이터는 컨테이너를 재시작하거나 이미지를 업데이트해도 그대로 유지됩니다.
|
||||
|
||||
볼륨을 확인하려면:
|
||||
|
||||
```bash
|
||||
docker volume inspect open-design_open_design_data
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 참고
|
||||
|
||||
* Docker 모드는 로컬에 Node.js나 pnpm을 설치하고 싶지 않은 기여자에게 적합합니다.
|
||||
* 컨테이너는 프로덕션 daemon 빌드를 `7456` 포트에 직접 노출합니다.
|
||||
* 개발 워크플로우와 더 깊은 로컬 설정은 이 빠른 시작 가이드의 나머지 부분을 참고하세요.
|
||||
|
||||
---
|
||||
|
||||
## 한 번에 실행하기 (dev 모드)
|
||||
|
||||
```bash
|
||||
corepack enable
|
||||
pnpm install
|
||||
pnpm tools-dev run web # daemon + web을 포그라운드로 시작합니다
|
||||
# tools-dev가 출력한 web URL을 엽니다
|
||||
```
|
||||
|
||||
데스크톱 셸과 관리 대상 sidecar 전부를 백그라운드로 실행하려면:
|
||||
|
||||
```bash
|
||||
pnpm tools-dev # daemon + web + desktop을 백그라운드로 시작합니다
|
||||
```
|
||||
|
||||
처음 로드하면 앱은 설치된 코드 에이전트 CLI(Claude Code / Codex / Devin for Terminal / Gemini / OpenCode / Cursor Agent / Qwen / Qoder CLI)를 감지해 자동으로 선택하고, 기본값으로 `web-prototype` skill과 `Neutral Modern` 디자인 시스템을 씁니다. 프롬프트를 입력하고 **Send**를 누르세요. 에이전트가 왼쪽 패널에 스트리밍되고, `<artifact>` 태그가 파싱되면서 HTML이 오른쪽에 실시간으로 렌더링됩니다. 작업이 끝나면 **Save to disk**를 눌러 artifact를 `./.od/artifacts/<timestamp>-<slug>/index.html`에 저장하세요.
|
||||
|
||||
**Design system** 드롭다운에는 71개의 내장 시스템이 들어 있습니다. 직접 작성한 스타터 2개(Neutral Modern, Warm Editorial)와 [`awesome-design-md`](https://github.com/VoltAgent/awesome-design-md)에서 가져온 69개의 제품 시스템으로, 카테고리별(AI & LLM, Developer Tools, Productivity, Backend, Design Tools, Fintech, E-Commerce, Media, Automotive)로 묶여 있습니다. 하나를 고르면 모든 프로토타입이 그 브랜드의 미감으로 입혀집니다. 여기에 [`awesome-design-skills`](https://github.com/bergside/awesome-design-skills)에서 가져온 57개의 디자인 skill도 함께 제공됩니다.
|
||||
|
||||
**Skill** 드롭다운은 모드별(Prototype / Deck / Template / Design system)로 묶이며, 각 모드의 기본 skill에는 `· default` 접미사가 붙습니다. 함께 제공되는 skill은 다음과 같습니다.
|
||||
|
||||
- **Prototype** — `web-prototype`(범용), `saas-landing`, `dashboard`, `pricing-page`, `docs-page`, `blog-post`, `mobile-app`.
|
||||
- **Deck / PPT** — `simple-deck`(단일 파일 가로 스와이프)과 `magazine-web-ppt`([`op7418/guizang-ppt-skill`](https://github.com/op7418/guizang-ppt-skill)에서 가져온 `guizang-ppt` 번들. deck 모드의 기본값이며, 자체 에셋/템플릿과 레퍼런스 4개를 함께 제공). 사이드 파일이 있는 skill에는 "Skill root (absolute)" 머리말이 자동으로 붙어, 에이전트가 `assets/template.html`이나 `references/*.md`를 CWD가 아니라 실제 디스크 경로 기준으로 해석할 수 있습니다.
|
||||
|
||||
skill과 디자인 시스템을 짝지으면, 프롬프트 하나로 선택한 시각 언어에 맞는 프로토타입이나 deck이 레이아웃에 맞게 생성됩니다.
|
||||
|
||||
## 그 밖의 스크립트
|
||||
|
||||
```bash
|
||||
pnpm tools-dev # daemon + web + desktop을 백그라운드로
|
||||
pnpm tools-dev start web # daemon + web을 백그라운드로
|
||||
pnpm tools-dev run web # daemon + web을 포그라운드로 (e2e/dev 서버)
|
||||
pnpm tools-dev restart # daemon + web + desktop 재시작
|
||||
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
|
||||
pnpm tools-dev status # 관리 중인 런타임 확인
|
||||
pnpm tools-dev logs # daemon/web/desktop 로그 보기
|
||||
pnpm tools-dev check # 상태 + 최근 로그 + 일반 진단
|
||||
pnpm tools-dev stop # 관리 중인 런타임 중지
|
||||
pnpm --filter @open-design/daemon build # `od`용 apps/daemon/dist/cli.js 빌드
|
||||
pnpm --filter @open-design/web build # 필요할 때 web 패키지 빌드
|
||||
pnpm typecheck # 워크스페이스 타입 체크
|
||||
```
|
||||
|
||||
로컬 라이프사이클의 진입점은 `pnpm tools-dev` 하나뿐입니다. 삭제된 옛 루트 alias(`pnpm dev`, `pnpm dev:all`, `pnpm daemon`, `pnpm preview`, `pnpm start`)는 쓰지 마세요.
|
||||
|
||||
로컬 개발 중에는 `tools-dev`가 daemon을 먼저 띄우고 그 포트를 `apps/web`에 넘깁니다. `apps/web/next.config.ts`는 `/api/*`, `/artifacts/*`, `/frames/*`를 그 daemon 포트로 다시 매핑하므로, App Router 앱이 CORS 설정 없이도 옆에서 도는 Express 프로세스와 통신할 수 있습니다.
|
||||
|
||||
## 미디어 생성 / 에이전트 dispatcher 점검
|
||||
|
||||
이미지, 비디오, 오디오, HyperFrames skill은 daemon이 에이전트를 spawn할 때 주입하는 환경 변수를 통해 로컬 `od` CLI를 호출합니다.
|
||||
|
||||
- `OD_BIN` — `apps/daemon/dist/cli.js`의 절대 경로.
|
||||
- `OD_DAEMON_URL` — 실행 중인 daemon URL.
|
||||
- `OD_PROJECT_ID` — 활성 프로젝트 id.
|
||||
- `OD_PROJECT_DIR` — 활성 프로젝트의 파일 디렉터리.
|
||||
|
||||
미디어 생성이 `OD_BIN: parameter not set`, `apps/daemon/dist/cli.js` 누락, `failed to reach daemon at http://127.0.0.1:0` 같은 메시지로 실패하면, daemon CLI를 다시 빌드하고 관리 중인 런타임을 재시작하세요.
|
||||
|
||||
```bash
|
||||
pnpm --filter @open-design/daemon build
|
||||
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
|
||||
ls -la apps/daemon/dist/cli.js
|
||||
curl -s http://127.0.0.1:7457/api/health
|
||||
```
|
||||
|
||||
그다음 오래된 터미널 에이전트 세션을 이어 가지 말고, Open Design 앱에서 프로젝트를 다시 여세요. daemon이 spawn한 에이전트라면 다음과 같은 값이 보여야 합니다.
|
||||
|
||||
```bash
|
||||
echo "OD_BIN=$OD_BIN"
|
||||
echo "OD_PROJECT_ID=$OD_PROJECT_ID"
|
||||
echo "OD_PROJECT_DIR=$OD_PROJECT_DIR"
|
||||
echo "OD_DAEMON_URL=$OD_DAEMON_URL"
|
||||
ls -la "$OD_BIN"
|
||||
```
|
||||
|
||||
`OD_DAEMON_URL`은 `http://127.0.0.1:7457`처럼 실제 daemon 포트여야 하며, `http://127.0.0.1:0`이어서는 안 됩니다. `:0` 값은 "빈 포트를 골라라"라는 내부 실행 힌트일 뿐이라, 에이전트 세션으로 새어 나가면 안 됩니다.
|
||||
|
||||
daemon 단독 프로덕션 모드에서는 daemon이 정적 Next.js export를 `http://localhost:7456`에서 직접 서빙하므로, reverse proxy가 끼어들지 않습니다.
|
||||
|
||||
daemon 앞에 nginx를 둔다면, SSE 경로는 버퍼링과 압축을 끄세요. 흔한 실패는 80~90초 뒤 브라우저 콘솔에 `net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)`가 뜨는 경우입니다. daemon이 `X-Accel-Buffering: no`를 보내도 nginx의 `gzip on`이 청크 SSE 응답을 버퍼링하기 때문입니다.
|
||||
|
||||
```nginx
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:7456;
|
||||
|
||||
proxy_buffering off;
|
||||
gzip off;
|
||||
|
||||
proxy_read_timeout 86400s;
|
||||
proxy_send_timeout 86400s;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
```
|
||||
|
||||
## 두 가지 실행 모드
|
||||
|
||||
| 모드 | 선택값 | 요청이 흐르는 경로 |
|
||||
|---|---|---|
|
||||
| **Local CLI** (daemon이 에이전트를 감지하면 기본값) | "Local CLI" | 프론트엔드 → daemon `/api/chat` → `spawn(<agent>, ...)` → stdout → SSE → artifact 파서 → 미리보기 |
|
||||
| **API 모드** (대체 수단 / CLI 없음) | "Anthropic API" / "OpenAI API" / "Azure OpenAI" / "Google Gemini" | 프론트엔드 → daemon `/api/proxy/{provider}/stream` → 프로바이더 SSE를 `delta/end/error`로 정규화 → artifact 파서 → 미리보기 |
|
||||
|
||||
두 모드 모두 **같은** `<artifact>` 파서와 **같은** 샌드박스 iframe으로 들어갑니다. 다른 점은 전송 방식과 시스템 프롬프트 전달 방식뿐입니다(로컬 CLI는 별도의 시스템 채널이 없어서, 조합된 프롬프트를 사용자 메시지 안에 접어 넣습니다).
|
||||
|
||||
## 프롬프트 구성
|
||||
|
||||
전송할 때마다 앱은 세 개의 레이어로 시스템 프롬프트를 만들어 프로바이더에 보냅니다.
|
||||
|
||||
```
|
||||
BASE_SYSTEM_PROMPT (출력 규약: <artifact>로 감싸고, 코드 펜스는 쓰지 않는다)
|
||||
+ 활성 디자인 시스템 본문 (DESIGN.md — 팔레트/타입/레이아웃)
|
||||
+ 활성 skill 본문 (SKILL.md — 워크플로우와 출력 규칙)
|
||||
```
|
||||
|
||||
상단 바에서 skill이나 디자인 시스템을 바꾸면, 다음 전송부터 새 조합이 적용됩니다. 본문은 세션별로 메모리에 캐시되므로, 한 번 선택할 때 daemon에 한 번만 요청합니다.
|
||||
|
||||
## 파일 맵
|
||||
|
||||
```
|
||||
open-design/
|
||||
├── apps/
|
||||
│ ├── daemon/ # Node/Express — 로컬 에이전트 spawn + API 서빙
|
||||
│ │ └── src/
|
||||
│ │ ├── cli.ts # `od` bin 진입점
|
||||
│ │ ├── server.ts # /api/* + 정적 서빙
|
||||
│ │ ├── agents.ts # claude/codex/devin/gemini/opencode/cursor-agent/qwen/qoder/copilot용 PATH 스캐너
|
||||
│ │ ├── skills.ts # SKILL.md 로더 (frontmatter 파서)
|
||||
│ │ └── design-systems.ts # DESIGN.md 로더
|
||||
│ │ ├── sidecar/ # tools-dev daemon sidecar 래퍼
|
||||
│ │ └── tests/ # daemon 패키지 테스트
|
||||
│ ├── web/ # Next.js 16 App Router + React 클라이언트
|
||||
│ ├── app/ # App Router 진입점
|
||||
│ ├── src/ # React + TypeScript 클라이언트/런타임 모듈
|
||||
│ │ ├── App.tsx # 모드 / skill / DS 선택기 + 전송 조율
|
||||
│ │ ├── providers/ # daemon + BYOK API 전송 계층
|
||||
│ │ ├── prompts/ # system, discovery, directions, deck framework
|
||||
│ │ ├── artifacts/ # 스트리밍 <artifact> 파서 + manifest
|
||||
│ │ ├── runtime/ # iframe srcdoc, markdown, export 헬퍼
|
||||
│ │ └── state/ # localStorage + daemon 기반 프로젝트 상태
|
||||
│ ├── sidecar/ # tools-dev web sidecar 래퍼
|
||||
│ └── next.config.ts # tools-dev rewrite + prod apps/web/out export 설정
|
||||
│ └── desktop/ # tools-dev가 실행/점검하는 Electron 런타임
|
||||
├── packages/
|
||||
│ ├── contracts/ # 공유 web/daemon 앱 contract
|
||||
│ ├── sidecar-proto/ # Open Design sidecar 프로토콜 contract
|
||||
│ ├── sidecar/ # 범용 sidecar 런타임 프리미티브
|
||||
│ └── platform/ # 범용 process/platform 프리미티브
|
||||
├── tools/dev/ # `pnpm tools-dev` 라이프사이클 및 inspect CLI
|
||||
├── e2e/ # Playwright UI + 외부 통합/Vitest 하네스
|
||||
├── skills/ # SKILL.md — 어떤 Claude Code skill 리포지토리에서든 그대로 넣을 수 있음
|
||||
│ ├── web-prototype/ # 범용 단일 화면 프로토타입 (prototype 모드 기본값)
|
||||
│ ├── saas-landing/ # 마케팅 페이지 (hero / features / pricing / CTA)
|
||||
│ ├── dashboard/ # 관리자 / 분석 대시보드
|
||||
│ ├── pricing-page/ # 단독 가격 + 비교
|
||||
│ ├── docs-page/ # 3단 문서 레이아웃
|
||||
│ ├── blog-post/ # 에디토리얼 롱폼
|
||||
│ ├── mobile-app/ # 휴대폰 프레임 단일 화면
|
||||
│ ├── simple-deck/ # 미니멀 가로 스와이프 deck
|
||||
│ └── guizang-ppt/ # magazine-web-ppt — 번들된 deck/PPT 기본값
|
||||
│ ├── SKILL.md
|
||||
│ ├── assets/template.html
|
||||
│ └── references/{themes,layouts,components,checklist}.md
|
||||
├── design-systems/ # DESIGN.md — 9개 섹션 스키마 (awesome-claude-design)
|
||||
│ ├── default/ # Neutral Modern (스타터)
|
||||
│ ├── warm-editorial/ # Warm Editorial (스타터)
|
||||
│ ├── README.md # 카탈로그 개요
|
||||
│ └── …129개 시스템 # 스타터 2개 · 제품 시스템 70개 · 디자인 skill 57개
|
||||
├── scripts/sync-design-systems.ts # 업스트림 getdesign tarball에서 다시 import
|
||||
├── docs/ # 제품 비전 + 스펙
|
||||
├── .od/ # 런타임 데이터 (gitignore 처리, 자동 생성)
|
||||
│ ├── app.sqlite # 프로젝트 / 대화 / 메시지 / 탭
|
||||
│ ├── artifacts/ # 일회성 "Save to disk" 렌더링
|
||||
│ └── projects/<id>/ # 프로젝트별 작업 디렉터리 + 에이전트 cwd
|
||||
├── pnpm-workspace.yaml # apps/* + packages/* + tools/* + e2e
|
||||
└── package.json # 루트 품질 스크립트 + `od` bin
|
||||
```
|
||||
|
||||
## 문제 해결
|
||||
|
||||
- **Node.js 버전을 바꾼 뒤 `better-sqlite3`가 로드되지 않거나 ABI가 맞지 않을 때** — `pnpm install`이 `postinstall`을 자동으로 다시 돌려 현재 Node.js에 맞게 네이티브 애드온을 리빌드합니다. 직접 리빌드하거나 수정을 확인하려면 `pnpm --filter @open-design/daemon rebuild better-sqlite3`를 실행한 뒤 `pnpm --filter @open-design/daemon exec node -e "require('better-sqlite3')"`를 돌리세요. 빌드 도구 `python3`, `make`, `g++`(또는 `clang++`)가 필요합니다. `.npmrc`에 `ignore-scripts=true`가 있다면, `pnpm install` 후 `node scripts/postinstall.mjs`를 실행하세요.
|
||||
- **"no agents found on PATH"** — `claude`, `codex`, `devin`, `gemini`, `opencode`, `cursor-agent`, `qwen`, `qodercli`, `copilot` 중 하나를 설치하세요. 아니면 Settings에서 API 모드로 바꾸고 프로바이더 키를 붙여 넣으세요.
|
||||
- **Claude Code가 코드 1로 종료될 때** — Open Design이 `claude`를 시작하긴 했지만, spawn된 비대화형 실행이 응답을 내기 전에 실패한 경우입니다. Open Design을 시작하는 셸이나 앱 환경과 같은 곳에서 다음을 확인하세요.
|
||||
```bash
|
||||
claude --version
|
||||
claude auth status --text
|
||||
printf 'hello' | claude -p --output-format stream-json --verbose --permission-mode bypassPermissions
|
||||
```
|
||||
스모크 테스트가 커스텀 엔드포인트 없이 `401`, `apiKeySource: "none"`, 또는 다른 인증 오류를 낸다면, `claude`를 실행해 `/login`한 뒤 Claude를 종료하고 Open Design을 다시 시도하세요. Claude 프로필을 여러 개 쓴다면 **Settings -> Execution mode -> Claude Code config directory**를 `~/.claude-2` 같은 프로필 경로로 지정하세요. `ANTHROPIC_BASE_URL`이나 프록시가 설정돼 있다면 엔드포인트 URL, 프록시 자격 증명, 엔드포인트 인증 환경, 모델 접근 권한을 확인하세요. 표준 Claude Code 인증으로 다시 시도하려는 게 아니라면 커스텀 엔드포인트는 그대로 두세요. Windows에서는 네이티브 PowerShell과 WSL이 서로 다른 Claude 설치본과 자격 증명 저장소를 쓰므로, Open Design이 쓰는 것과 같은 환경에서 다시 인증하고, `/login`으로도 네이티브 Windows 자격 증명이 복구되지 않으면 Windows 자격 증명 관리자를 확인하세요.
|
||||
- **`/api/chat`에서 daemon 500** — daemon 터미널의 stderr 끝부분을 확인하세요. 대개 CLI가 자신의 인자를 거부한 경우입니다. CLI마다 받는 argv 형태가 다릅니다. 손봐야 한다면 `apps/daemon/src/agents.ts`의 `buildArgs`를 보세요.
|
||||
- **미디어 생성이 `OD_BIN` 누락 또는 daemon URL이 `:0`이라고 할 때** — 위의 미디어 dispatcher 점검을 실행하세요. 옛 CLI 세션을 이어 가지 말고, Open Design 앱에서 프로젝트를 다시 열어 daemon이 새 `OD_*` 변수를 주입하게 하세요.
|
||||
- **Codex가 플러그인 컨텍스트를 너무 많이 로드할 때** — `OD_CODEX_DISABLE_PLUGINS=1 pnpm tools-dev`로 Open Design을 시작하면, daemon이 spawn하는 Codex 프로세스가 `--disable plugins`로 실행됩니다.
|
||||
- **artifact가 끝내 렌더링되지 않을 때** — 모델이 `<artifact>`로 감싸지 않은 텍스트를 만든 경우입니다. 시스템 프롬프트가 제대로 전달되는지 확인하고(daemon 로그 확인), 더 강력한 모델이나 더 엄격한 skill로 바꿔 보세요.
|
||||
|
||||
## 비전과 다시 잇기
|
||||
|
||||
이 빠른 시작은 [`docs/`](docs/)에 담긴 스펙을 실제로 돌릴 수 있게 만든 씨앗입니다. 스펙은 이것이 어디로 자라날지 설명합니다([`docs/roadmap.md`](docs/roadmap.md) 참고). 핵심만 짚으면 다음과 같습니다.
|
||||
|
||||
- `docs/architecture.md`는 출시된 스택을 설명합니다. 앞단의 Next.js 16 App Router, 그 뒤의 로컬 daemon, 그리고 dev에서 `apps/web/next.config.ts`의 rewrite가 브라우저를 같은 `/api` 표면과 계속 통신하게 유지하는 구조입니다.
|
||||
- `docs/skills-protocol.md`는 `od:` frontmatter 전체(타입 입력, 슬라이더, 기능 게이팅)를 설명합니다. 이 MVP는 `name` / `description` / `triggers` / `od.mode` / `od.design_system.requires`만 읽습니다. 나머지를 추가하려면 `apps/daemon/src/skills.ts`를 확장하세요.
|
||||
- `docs/agent-adapters.md`는 더 풍부한 dispatch(기능 감지, 스트리밍 tool-call)를 내다봅니다. 우리의 `apps/daemon/src/agents.ts`는 배선을 증명할 만큼만 갖춘 최소 dispatcher입니다.
|
||||
- `docs/modes.md`는 네 가지 모드를 나열합니다. prototype / deck / template / design-system. 우리는 앞의 두 가지를 위한 skill을 제공하며, 선택기는 이미 `mode`로 필터링합니다.
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
<a href="#디자인-시스템"><img alt="Design systems" src="https://img.shields.io/badge/design%20systems-149-orange?style=flat-square" /></a>
|
||||
<a href="#내장-skills"><img alt="Skills" src="https://img.shields.io/badge/skills-131-teal?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/qhbcCH8Am4"><img alt="Discord" src="https://img.shields.io/badge/discord-join-5865F2?style=flat-square&logo=discord&logoColor=white" /></a>
|
||||
<a href="QUICKSTART.md"><img alt="Quickstart" src="https://img.shields.io/badge/quickstart-3%20commands-green?style=flat-square" /></a>
|
||||
<a href="QUICKSTART.ko.md"><img alt="Quickstart" src="https://img.shields.io/badge/quickstart-3%20commands-green?style=flat-square" /></a>
|
||||
</p>
|
||||
|
||||
<p align="center"><a href="README.md">English</a> · <a href="README.es.md">Español</a> · <a href="README.pt-BR.md">Português (Brasil)</a> · <a href="README.de.md">Deutsch</a> · <a href="README.fr.md">Français</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.zh-TW.md">繁體中文</a> · <b>한국어</b> · <a href="README.ja-JP.md">日本語</a> · <a href="README.ar.md">العربية</a> · <a href="README.ru.md">Русский</a> · <a href="README.uk.md">Українська</a> · <a href="README.tr.md">Türkçe</a></p>
|
||||
|
|
@ -332,7 +332,7 @@ pnpm tools-dev run web
|
|||
|
||||
Windows 사용자는 네이티브 설치 경로와 작은 더블 클릭 런처에 대해서는 [`docs/windows-troubleshooting.md`](docs/windows-troubleshooting.md)를 참고하세요.
|
||||
|
||||
데스크톱/백그라운드 시작, 고정 포트 재시작, 미디어 생성 dispatcher 확인(`OD_BIN`, `OD_DAEMON_URL`, `apps/daemon/dist/cli.js`)은 [`QUICKSTART.md`](QUICKSTART.md)를 참고하세요.
|
||||
데스크톱/백그라운드 시작, 고정 포트 재시작, 미디어 생성 dispatcher 확인(`OD_BIN`, `OD_DAEMON_URL`, `apps/daemon/dist/cli.js`)은 [`QUICKSTART.ko.md`](QUICKSTART.ko.md)를 참고하세요.
|
||||
|
||||
첫 번째 로드 시:
|
||||
|
||||
|
|
@ -360,7 +360,7 @@ Daemon은 저장소 루트에 하나의 숨겨진 폴더를 소유합니다. 그
|
|||
| 초기 상태로 재설정 | `pnpm tools-dev stop`, `rm -rf .od`, `pnpm tools-dev run web` 재실행 |
|
||||
| 다른 위치로 이동 | 아직 지원되지 않음 — 경로가 저장소 상대 경로로 하드코딩됨 |
|
||||
|
||||
전체 파일 맵, 스크립트, 트러블슈팅 → [`QUICKSTART.md`](QUICKSTART.md).
|
||||
전체 파일 맵, 스크립트, 트러블슈팅 → [`QUICKSTART.ko.md`](QUICKSTART.ko.md).
|
||||
|
||||
## 저장소 구조
|
||||
|
||||
|
|
@ -719,7 +719,7 @@ daemon 부팅 시 `PATH`에서 자동 감지됩니다. 설정 필요 없음. 스
|
|||
- **디자인 시스템 추가** — 9섹션 스키마를 사용하여 [`design-systems/<brand>/`](design-systems/)에 `DESIGN.md`를 드롭하세요.
|
||||
- **새 코딩 에이전트 CLI 연결** — [`apps/daemon/src/agents.ts`](apps/daemon/src/agents.ts)에 항목 하나 추가.
|
||||
|
||||
전체 설명, 병합 기준, 코드 스타일, 받지 않는 것 → [`CONTRIBUTING.md`](CONTRIBUTING.md) ([Deutsch](CONTRIBUTING.de.md), [Français](CONTRIBUTING.fr.md), [简体中文](CONTRIBUTING.zh-CN.md)).
|
||||
전체 설명, 병합 기준, 코드 스타일, 받지 않는 것 → [`CONTRIBUTING.ko.md`](CONTRIBUTING.ko.md) ([English](CONTRIBUTING.md), [Deutsch](CONTRIBUTING.de.md), [Français](CONTRIBUTING.fr.md), [简体中文](CONTRIBUTING.zh-CN.md)).
|
||||
|
||||
## 컨트리뷰터
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ Open Design currently supports **19 languages** across different surfaces:
|
|||
| Bahasa Indonesia | `id` | — | ✅ | — | active |
|
||||
| Italiano | `it` | — | ✅ | — | active |
|
||||
| 日本語 (Japanese) | `ja` | ✅ | ✅ | ✅ | active |
|
||||
| 한국어 (Korean) | `ko` | ✅ | ✅ | — | active |
|
||||
| 한국어 (Korean) | `ko` | ✅ | ✅ | ✅ | active |
|
||||
| Polski (Polish) | `pl` | — | ✅ | — | active |
|
||||
| Português (Brasil) | `pt-BR` | ✅ | ✅ | ✅ | active |
|
||||
| Русский (Russian) | `ru` | ✅ | ✅ | — | active |
|
||||
|
|
|
|||
Loading…
Reference in a new issue