기여하기
git clone https://github.com/lidge-jun/opencodex.gitcd opencodexbun installbun run dev:proxy # 개발 모드 프록시 APIbun run dev:gui # 대시보드 dev 서버(다른 터미널)bun run typecheck # bun x tsc --noEmitbun run test # bun test ./tests/bun run dev는 계속 bun run dev:proxy의 별칭으로 동작합니다. 대시보드 dev 서버는
bun run dev:gui이며, GET /에서 제공하는 패키지 대시보드는 bun run build:gui로 빌드해
gui/dist에 만듭니다.
빌드 및 테스트 명령
섹션 제목: “빌드 및 테스트 명령”루트 패키지는 Bun 네이티브 TypeScript이며 서버를 따로 compile하는 단계가 없습니다. 저장소에 정의된 스크립트를 사용하면 로컬 실행과 CI를 맞출 수 있습니다.
bun run typecheck # 엄격한 TypeScript 검사bun run test # tests/ 전체 스위트bun test tests/router.test.ts # 특정 테스트 파일bun run build:gui # Vite GUI 빌드 + 패키지 준비bun run privacy:scan # CI에서 쓰는 자격 증명/개인정보 검사bun run prepare:package # 패키지 런처/asset 갱신대부분의 테스트는 tests/*.test.ts에 나란히 놓인 Bun 테스트입니다. 공용 fixture는
tests/helpers/, 범위가 넓은 네이티브 동등성 시나리오는 tests/e2e-style/에 있습니다. 바꾼
subsystem의 기존 테스트 근처에 집중된 회귀 테스트를 추가하세요. 공용 라우팅, 어댑터, 설정, 서버
동작을 건드렸다면 전체 스위트도 실행합니다.
지금 읽고 있는 문서 사이트는 docs-site/에 있습니다(Astro + Starlight).
cd docs-site && bun install && bun dev문서 배포
섹션 제목: “문서 배포”공개 문서는 GitHub Pages의 https://opencodex.me/ko/에 게시됩니다.
.github/workflows/deploy-docs.yml은 main push에서 docs-site/**나 워크플로 자체가 바뀌면
실행됩니다. docs-site를 빌드한 뒤 생성된 사이트를 배포합니다. 문서 변경을 push하기 전에 다음을
실행하세요.
cd docs-sitebun install --frozen-lockfilebun run buildCI와 릴리즈
섹션 제목: “CI와 릴리즈”GitHub Actions는 필요한 작업만 수행합니다.
- Windows CI(
.github/workflows/ci.yml)는 런타임, 테스트, 패키지, 스크립트, TypeScript, 워크플로 파일이 바뀐 pull request와mainpush에서 실행됩니다. Windows 작업에서 install, typecheck, tests, privacy scan, release helper build smoke, GUI build,ocx help, 그리고 번들 런타임을 사용하는 npm global install을 검사합니다. - Release(
.github/workflows/release.yml)는 수동으로 실행합니다. 두 번째 전체 CI 파이프라인이 아니며, dry-run이나 publish 전에 정확한 릴리즈 커밋(GITHUB_SHA)에서 Windows CI가 성공했는지 확인합니다. - Super express release(
.github/workflows/super-express-release.yml)는 Windows용 수동 패키징 경로입니다. 선택한 ref를 하나의 변경 불가능한 커밋 SHA로 확정하고, Release와 마찬가지로 그 정확한 SHA의 Windows CI가 성공하지 않았으면 publish를 거부합니다. 데스크톱 릴리즈에는 의도적으로 서명하지 않은 Squirrel.WindowsSetup.exe,RELEASES, 전체.nupkg가 포함됩니다.
서명되지 않은 Windows 설치 파일은 Unknown Publisher 또는 Microsoft Defender SmartScreen 경고를 표시할 수 있습니다. 관련 CI, 패키징, 릴리즈 작업은 앞 단계가 실패한 뒤에도 방어적인 artifact collector를 실행합니다. collector는 명시적으로 안전한 설치 파일/feed 출력과 run metadata만 GitHub Actions artifact에 보관하며, collector 자체의 실패는 원래 job verdict를 숨기거나 바꾸지 않도록 무시됩니다. 증거가 보관되어도 실패한 build가 publish 대상이 되지는 않습니다.
릴리즈에는 helper를 사용하세요.
bun run release <version> # 버전 bump를 commit/push, publish workflow는 기본 dry-runbun run release <version> --publish # CI-gated dry-run을 확인한 뒤 실제 publishbun run release:watch # 가장 최근 Release workflow run 감시브랜치
섹션 제목: “브랜치”dev— 기본 통합 대상. 아래 범위 브랜치에 해당하지 않으면 여기로 PR을 올립니다.dev2-go— Go 네이티브 포트(go/, 네이티브 런타임 진입점, Go 릴리즈 자산 도구)를 위한 병렬 통합선입니다.dev와 함께 PR을 받습니다. Go 포트에 속하는 작업만 여기로 보내고, 나머지는dev로 보내세요. 타깃 브랜치 검사는 두 브랜치를 모두 허용하지만 둘을 구분하지 못하므로, 범위는 리뷰에서 정합니다. 메인테이너가dev로 옮겨달라고 요청할 수 있습니다.main— 릴리즈 전용.dev에서 메인테이너가 승격시킬 때만 움직이며, 기능 PR을 직접 올리지 않습니다.preview— 프리릴리즈 트레인.
주 런타임을 Go 네이티브 포트로 옮기는 동안 dev에 들어간 변경은 dev2-go에도 그대로
올라가야 합니다. 기여자가 할 일은 달라지지 않습니다. 지금처럼 dev로 PR을 올리면 됩니다.
머지한 메인테이너가 그 작업을 dev2-go 위로 리베이스하고 go/ 쪽에 대응이 필요한 부분을
포팅하며, 두 라인에 모두 반영되어야 작업이 끝난 것으로 봅니다.
포팅 PR과 리베이스 PR을 환영합니다. 한 통합선의 수정을 다른 쪽으로 옮기거나, 오래된 브랜치를 현재 head 위로 리베이스하는 것은 잡음이 아니라 정상적인 기여입니다. 설명란에 출처 커밋을 적어주세요.
컨벤션
섹션 제목: “컨벤션”- ES Modules 전용(
import/export), TypeScript,strict모드.bun x tsc --noEmit을 깨끗하게 유지하세요. - 파일당 최대 약 500줄 — 책임별로 나누세요. 단일
index.ts뒤에 작고 집중된 모듈을 둔web-search/와vision/사이드카가 좋은 예입니다. - 비동기 오류는 경계에서 처리 — 사이드카는 요청 경로로 오류를 던지지 않고 적절한 marker로 저하됩니다.
- Structure SOT — 현재 유지보수 불변식은
structure/에 둡니다. 공개 사용자 워크플로는docs-site/, 과거 조사/진단 기록은docs/에 둡니다. - export 보존 — 다른 모듈이 의존할 수 있습니다.
카탈로그에 프로바이더 추가하기
섹션 제목: “카탈로그에 프로바이더 추가하기”모든 프로바이더 선택기와 seed는 canonical registry(src/providers/registry.ts)에서 파생됩니다.
{ id: "my-provider", label: "My Provider", baseUrl: "https://api.example.com/v1", adapter: "openai-chat", authKind: "key", dashboardUrl: "https://example.com/keys", models: ["model-a", "model-b"], defaultModel: "model-a", noVisionModels: ["model-a"], // text-only models → vision sidecar describes images},src/providers/derive.ts는 이 항목을 ocx init, ocx provider, 대시보드 preset, API 키 로그인,
OAuth 설정 seed에 공급합니다. enrichProviderFromCatalog()는 모델 메타데이터와 capability 분류를
저장할 프로바이더 설정에 복사합니다. OAuth 프로토콜 구현은 여전히 src/oauth/에 있습니다.
레지스트리 메타데이터만 추가해서 OAuth flow가 생기지는 않습니다.
어댑터 추가하기
섹션 제목: “어댑터 추가하기”src/adapters/에 ProviderAdapter(어댑터 참조)를 구현하고,
src/server/adapter-resolve.ts에 이름을 등록한 뒤 출력을 내부 AdapterEvent로 브리징하세요. 이미지
처리에는 image.ts를 재사용하고, 일반적인 스트리밍/툴 호출은 openai-chat.ts를 참고합니다.
어댑터가 전송 재시도를 직접 맡을 때만 fetchResponse를 사용하고, Cursor처럼 실제 양방향 전송에는
runTurn을 사용하세요. tests/ 아래에 집중된 테스트를 추가하고, public package API에 포함되는
factory라면 src/index.ts에서도 export합니다.
완료를 주장하기 전에 검증하기
섹션 제목: “완료를 주장하기 전에 검증하기”변경을 증명하는 가장 좁은 명령부터 실행하세요. 타입은 bun run typecheck, 동작은 집중된
bun test tests/<name>.test.ts 또는 런타임 probe로 확인한 뒤 영향 범위에 맞는 넓은 gate를
실행합니다. opencodex는 큰 batch보다 작고 검증 가능한 commit을 선호합니다.

