SLOPSHOPPER

ko-labels

슬래시 명령과 /config 설정 행에 한국어 설명을 덧붙인다

new
v0.1.0no licenseupdated 2026-10-06dbsrjs/Nexus/.claude/mods/ko-labels
A shopper browsing a rack in a slop shop
README

Nexus

개발자를 위한 커뮤니케이션 허브. 대화 · 파일 · 이슈 · 저장소 · AI 를 한 화면에 모은다.

일반 메신저는 개발 맥락을 모르고, 개발 도구는 대화를 담지 못한다. Nexus 는 그 사이를 메운다.

  • 커밋 · PR · 푸시 이벤트가 채널 안으로 흘러 들어온다
  • 대화 중에 그 자리에서 이슈를 만든다 — 원문 링크가 남는다
  • AI 가 대화와 코드를 같은 맥락으로 읽는다 — 인덱싱된 저장소를 근거로 답하고 출처를 인용한다
  • 오프라인에서도 동작한다 — 캐시로 대화를 보여 주고, 쓴 메시지는 재연결 때 내보낸다

기능

영역내용
대화스페이스 · 카테고리 · 채널(공개/비공개) · 실시간 전송 · 스레드 · 답장(인용) · 멘션 · 리액션 · 핀 · 마크다운
DM · 프레즌스스페이스 안 1:1 DM · 온라인 / 자리비움(10분 무입력) / 오프라인 · 입력 중 표시
멤버 · 권한스페이스 만들기 · 초대 코드 · 초대 링크 · 역할(owner · admin · member · guest) · 비공개 채널 명단 · 역할별 채널 권한(가리기 · 읽기 전용)
알림알림함(멘션 · @channel · DM · 내 글의 답글) · 종류별 스위치 · 채널 음소거 · 앱을 보고 있지 않을 때 OS 알림(Windows 토스트 · 브라우저) · Windows 트레이
파일첨부 업로드(진행률) · 이미지 미리보기 · 스페이스 파일 목록 · 무기한 보관
이슈칸반 보드(끌어 옮기기) · 상세 · 댓글 · 라벨 · 대화 → 이슈 · 스프린트 · 번다운(스페이스마다 켜는 선택 기능)
GitHub계정 연결(OAuth) · 웹훅 자동 등록 · 브랜치 · 파일 트리 · 커밋 · PR 열람
인덱싱저장소를 청크로 나눠 임베딩 · 벡터 검색(pgvector HNSW) · push 마다 증분 갱신
AI 패널자유 지시문 + 프리셋(요약 · 이슈 초안) · 컨텍스트(메시지 · 채널 최근 대화 · 저장소 RAG) · 이어 묻기 · 지난 대화 다시 열기
설정표시 이름 · 프로필 사진 · 비밀번호 변경 · 알림 · 테마(시스템 · 라이트 · 다크)
화면자체 UI — Material · Cupertino 없이 직접 만든 부품(app/lib/ui/) · 반응형(데스크톱 · 태블릿 · 모바일) · 새로고침 · 로그인 뒤 원래 주소로

아키텍처

app/     Flutter — 한 코드베이스로 Windows · Android · Web (iOS 는 macOS 가 없어 동결)
   │     Riverpod · go_router · dio · drift(오프라인 캐시 + 전송 큐) · 자체 UI(WidgetsApp)
   │
   │  REST + Socket.IO
   ▼
server/  NestJS + Prisma
   ├─ PostgreSQL + pgvector   모든 데이터 · 코드 임베딩 · 작업 큐(AI · 인덱싱)
   ├─ 스토리지                첨부 파일 (개발은 로컬 디스크, 배포는 S3 호환 — R2)
   ├─ LLM                     gemini · local(Ollama) · fake
   └─ 임베딩                  gemini · local(Ollama) · fake

deploy/  VM 한 대 — Docker Compose(postgres · server · nginx · cloudflared · backup)
         웹과 API 를 nginx 한 오리진으로 낸다 · Cloudflare Tunnel · R2

Space 가 모든 데이터의 루트인 멀티테넌트 구조다. 채널 · 메시지 · 이슈 · 저장소는 전부 스페이스에 속하고, 스페이스에 속한 테이블은 spaceId 를 직접 가진다. 볼 수 없는 리소스는 403 이 아니라 404 로 답한다.

외부 원본(GitHub)은 사본을 두지 않고 프록시한다. Redis 는 쓰지 않는다 — 큐도 Postgres 에 둔다.


폴더 구조

폴더설명
server/NestJS 백엔드 — REST API · Socket.IO 게이트웨이 · 계약 검증 스크립트(scripts/)
app/Flutter 앱 — 실행법은 app/README.md
deploy/배포 구성 — prod compose · nginx · 절차는 deploy/README.md
design-system/디자인 토큰(tokens.css) · 컴포넌트 · 화면 프리뷰
docs/기획 · 설계 문서 · 진행 기록

시작하기

필요한 것: Node.js 22 · Flutter 3.44.9 이상 · WSL2(Ubuntu) 또는 Docker

서버

git clone https://github.com/dbsrjs/Nexus.git && cd Nexus

npm --prefix server install
npm run env:setup                          # server/.env 생성 · 시크릿 자동 채움

npm run db:setup                           # (1회) WSL 안에 Postgres + pgvector
npm run db:up                              # Docker 라면 위 둘 대신 npm run db:up:docker

npm --prefix server run prisma:generate
npm --prefix server run prisma:deploy
npm run db:seed

npm run server:dev                         # http://localhost:3000/api

env:setup 은 여러 번 돌려도 안전하다. 만들어 낼 수 없는 값(GITHUB_CLIENT_ID · GITHUB_CLIENT_SECRET · PUBLIC_BASE_URL)은 끝에 목록으로 알려 준다 — GitHub 연동을 쓸 때만 필요하다. AI · 인덱싱은 .env 의 LLM_PROVIDER · EMBEDDING_PROVIDER 를 채워야 켜진다.

Windows 에서는 DATABASE_URL 에 localhost 대신 127.0.0.1 을 쓴다(WSL 포워딩이 IPv4 만 동작한다). 서버가 listen EACCES ...:3000 으로 죽으면 Windows 가 그 포트를 예약한 것이다 — 처방은 CLAUDE.md §2.

앱

cd app
flutter pub get

flutter run -d windows --dart-define=API_BASE=http://127.0.0.1:3000
flutter run -d chrome  --web-port=5173     # 서버 CORS 가 5173 만 허용한다

Android 에뮬레이터는 --dart-define=API_BASE=http://10.0.2.2:3000 을 넘긴다(에뮬레이터에게 127.0.0.1 은 자기 자신이다). Windows 데스크톱 빌드에는 개발자 모드가 켜져 있어야 한다.


검증

명령내용
명령내용규모 (2026-10-09)
---------
npm run server:test · server:lint서버 단위 테스트(Jest) · ESLint — 순수 로직 · 가드 · 권한 규칙535개
npm run check:*실서버 · 실DB · 실소켓 계약 검증 — 실시간 · 리액션 · 스레드 · 첨부 · 이슈 · GitHub 연동 · 인덱싱 · AI · 설정 · 멤버 · 권한 · DM · 프레즌스 · 알림 · 테넌트 격리(check:tenancy — 스페이스 경로 전부를 남의 id 로 친다). GitHub 은 스스로 띄우는 가짜 서버로 대신한다20종 1,123개
npm run check:migrations · check:sql-time마이그레이션 · raw SQL 정적 검사 (DB 불필요)
cd app && flutter analyze && flutter test앱 정적 분석 · 단위 · 위젯 테스트591개
npm run app:flow앱 통합 테스트 — Windows 앱을 실서버에 붙여 로그인부터 전송 · 실시간 · 설정 · 멤버 · DM · 알림함 · AI 까지 돈다약 30초
npm run app:flow:headless같은 흐름을 창 없이(flutter_tester) 돈다 — CI 가 이것을 돈다약 15초

CI(.github/workflows/ci.yml)가 main 과 feat/** 의 push 마다 위 전부를 돈다 — 앱 통합 테스트는 창 없는 쪽(app:flow:headless)으로, 첨부는 S3 경로(SeaweedFS)로도 한 번 더. Windows 창으로 보는 app:flow 는 화면 모습을 바꿨을 때 사람이 돌린다.


진행 상황

1~19단계와 «마지막»(출시 준비)의 네 갈래가 끝났다(2026-10-09). 위 기능표가 전부 동작하고, 배포 구성(deploy/) · 테넌트 격리 통합 검증 · 딥링크 · 데스크톱 · 웹 알림 + Windows 트레이까지 들어갔다.

남은 것내용
실제 VM 배포구성과 절차(deploy/README.md)는 있다. VM · R2 · Cloudflare Tunnel 을 정하고 올리는 일
OS 수준 링크 연결Android App Links · Windows 프로토콜 등록 — 공개 도메인이 정해진 뒤
20 GitLab 연동provider 추상화 뒤에 GitLab. 배포 뒤로 미뤄도 되는 유일한 단계

모바일 푸시(FCM)는 범위에서 뺐다(2026-10-09). 단계마다의 결정과 확인 내역은 진행 기록 에 있다.

로드맵목표
Phase 0나 혼자 쓰는 개발 허브 — 프로젝트를 채널로 나누고 할 일 · 저장소를 붙인다
Phase 12~10인 소규모 팀 — 초대 · 온보딩 · 알림
Phase 2공개 서비스 — 테넌트 격리 · 스토리지 쿼터 · 과금

문서

문서내용
코드 둘러보기처음 열었을 때 여기부터. 돌려 보기 · 구조 · 한 줄기 따라가기
제품 기획방향 · 타겟 · 기능 범위 · 로드맵
백엔드 설계멀티테넌시 · 데이터 모델 · API 계약 · 실시간 · 인증
앱 설계Flutter 스택 · 화면 · 상태 관리 · 오프라인 전략
인프라 설계배포 구성 · 공개 저장소 보안 체크리스트
디자인 시스템색 · 타이포 · 간격 · 컴포넌트
전환 계획작업 목록과 진행 상황
진행 기록단계마다 갈린 결정 · 확인한 것 · 확인하지 못한 것
기술 스택 가이드스택별 학습 순서 · 코드 읽기 시작점
서버 README서버 셋업 · 규약 · Ollama · 실제 GitHub 웹훅 붙이는 법
배포 READMEVM · R2 · Cloudflare Tunnel 로 올리는 절차
단계별 설계 스펙단계마다 정한 것 · 범위에서 뺀 것과 그 이유
Source 2 files
hooks/register.ts 40 lines
1import type { Register } from 'claude-code'
2
3import { COMMANDS, CONFIG } from './dictionary'
4
5// 이미 한글이 들어 있으면(이 모드나 다른 플러그인이 붙였거나 원래 한국어) 다시 붙이지 않는다.
6const HANGUL = /[ㄱ-ㆎ가-힣]/
7
8// 플러그인 · 스킬 명령은 `anthropic-skills:pdf` 처럼 접두사가 붙는다. 정확한 이름을 먼저,
9// 없으면 마지막 마디로 찾는다.
10export function lookupCommand(name: string): string | undefined {
11  return COMMANDS[name] ?? COMMANDS[name.split(':').pop() ?? name]
12}
13
14// 명령 목록은 한 줄로 그려져 길면 뒤가 잘린다. 스킬 설명은 영어가 길어서 뒤에 붙이면
15// 한국어가 잘려 보이지 않으므로 앞에 둔다.
16export function koDescription(name: string, description: string): string | undefined {
17  const ko = lookupCommand(name)
18  if (!ko || HANGUL.test(description)) return undefined
19  return description ? `${ko} — ${description}` : ko
20}
21
22// 설정 행은 라벨이 짧아 잘릴 걱정이 없으므로 원문 옆에 둔다(원문을 먼저 두어 문서 · 검색어와 대조된다).
23export function koLabel(key: string, label: string): string | undefined {
24  const ko = CONFIG[key]
25  if (!ko || HANGUL.test(label)) return undefined
26  return `${label} · ${ko}`
27}
28
29export const register: Register = on => {
30  on('command.describe', ($, e, next) => {
31    const description = koDescription(e.command, e.description)
32    return description ? next({ ...e, description }) : next(e)
33  })
34
35  on('config.describe', ($, e, next) => {
36    const label = koLabel(e.key, e.label)
37    return label ? next({ ...e, label }) : next(e)
38  })
39}
40
hooks/dictionary.ts 173 lines
1// 이름 → 한국어 설명. 영어 고유 명칭(MCP · IDE · CLAUDE.md · Chrome 등)은 그대로 둔다.
2// 엔진이 이름으로만 찾으므로, 사전에 없는 명령 · 행은 원문 그대로 보인다(조용히 틀리게 번역하지 않는다).
3
4export const COMMANDS: Readonly<Record<string, string>> = {
5  // 내장 명령
6  'add-dir': '작업 디렉터리 추가',
7  advisor: '중요한 순간에 더 강한 모델에게 자문',
8  agents: '서브에이전트 관리',
9  autocompact: '자동 압축 창 크기 설정',
10  btw: '작업을 멈추지 않고 곁가지 질문',
11  bug: '버그 신고 · 피드백 보내기',
12  feedback: '버그 신고 · 피드백 보내기',
13  chrome: 'Claude in Chrome 설정',
14  clear: '빈 컨텍스트로 새 세션 시작(이전 세션은 /resume 으로 재개 가능)',
15  color: '이번 세션 입력창 색 설정',
16  compact: '지금까지의 대화를 요약해 컨텍스트 확보',
17  config: '설정 열기 · 키로 설정 변경',
18  context: '현재 컨텍스트 사용량 보기',
19  copy: '마지막 응답 복사',
20  cost: '세션 비용 · 사용량 보기',
21  debug: '디버그 로그 켜고 문제 진단',
22  doctor: 'Claude Code 설치 · 설정 상태 점검',
23  effort: '모델 추론 노력 수준 설정',
24  exit: 'Claude Code 종료',
25  quit: 'Claude Code 종료',
26  export: '대화를 파일 · 클립보드로 내보내기',
27  fast: '빠른 모드 전환',
28  focus: '집중 보기 전환(프롬프트 · 요약 · 응답만)',
29  goal: '조건을 만족할 때까지 계속 작업할 목표 설정',
30  heapdump: 'JS 힙 덤프 저장',
31  help: '도움말 · 명령 목록',
32  hooks: '훅 설정 관리',
33  ide: 'IDE 연결 관리',
34  import: '다른 AI 코딩 에이전트의 설정 가져오기',
35  init: '코드베이스 문서화용 CLAUDE.md 생성',
36  insights: 'Claude Code 세션 분석 보고서 생성',
37  'install-github-app': 'GitHub Actions 용 Claude 앱 설치',
38  'install-slack-app': 'Slack 용 Claude 앱 설치',
39  keybindings: '단축키 설정',
40  'list-agents': '메시지를 보낼 수 있는 서브에이전트 · 팀원 · 세션 목록',
41  login: '로그인 · 계정 전환',
42  logout: '로그아웃',
43  mcp: 'MCP 서버 관리',
44  memory: '메모리 파일(CLAUDE.md) 편집',
45  model: '사용할 AI 모델 설정',
46  'output-style': '출력 스타일 목록 · 전환',
47  permissions: '도구 허용 · 거부 규칙 관리',
48  allowed_tools: '도구 허용 · 거부 규칙 관리',
49  plugin: '플러그인 관리',
50  plugins: '플러그인 관리',
51  'pr-comments': 'GitHub PR 댓글 가져오기',
52  'privacy-settings': '개인정보 설정',
53  recap: '세션 한 줄 요약 지금 만들기',
54  'release-notes': '릴리스 노트 보기',
55  'reload-plugins': '변경된 플러그인을 이번 세션에 적용',
56  'reload-skills': '세션 중 추가 · 변경된 스킬 다시 읽기',
57  'remote-control': '다른 기기에서 이 세션 원격 제어',
58  rename: '현재 대화 이름 바꾸기',
59  resume: '이전 대화 재개',
60  continue: '이전 대화 재개',
61  review: 'PR 리뷰',
62  rewind: '대화 · 코드를 이전 시점으로 되감기',
63  checkpoint: '대화 · 코드를 이전 시점으로 되감기',
64  sandbox: '샌드박스 설정',
65  'security-review': '현재 브랜치 변경의 보안 리뷰',
66  'skill-doctor': '안 쓰이면서 컨텍스트를 차지하는 스킬 보기',
67  skills: '스킬 목록',
68  stats: '사용 통계 보기',
69  status: '버전 · 모델 · 계정 · 연결 상태 보기',
70  statusline: '상태 줄 설정',
71  tasks: '백그라운드 작업 목록',
72  bashes: '백그라운드 작업 목록',
73  'team-onboarding': '사용 기록으로 팀원용 Claude Code 안내서 만들기',
74  'terminal-setup': '터미널 줄바꿈 키(Shift+Enter) 설정',
75  theme: '테마 변경',
76  todos: '할 일 목록 보기',
77  upgrade: '요금제 업그레이드',
78  usage: '세션 비용 · 요금제 사용량 · 한도 기여 항목 보기',
79  vim: 'Vim 편집 모드 전환',
80
81  // 내장 스킬
82  batch: '대규모 변경을 계획하고 여러 worktree 에이전트로 병렬 실행',
83  'claude-api': 'Claude API · Anthropic SDK 참고 자료',
84  'code-review': '현재 diff · PR 의 버그 리뷰',
85  dataviz: '차트 · 그래프 · 대시보드 작성 가이드',
86  'deep-research': '여러 출처를 조사해 인용 보고서 작성',
87  design: '요청서로 새 Design 아티팩트 만들기',
88  'design-consent': 'Design 프로젝트 접근 권한 허용',
89  'design-revoke': 'Design 프로젝트 접근 권한 회수',
90  'design-sync': 'React 디자인 시스템을 claude.ai/design 으로 올리기',
91  'artifact-capabilities': '아티팩트 런타임 기능 안내',
92  'artifact-design': '아티팩트 디자인 가이드',
93  'artifact-diagramming': '아티팩트 다이어그램 가이드',
94  'fewer-permission-prompts': '자주 쓰는 읽기 전용 명령을 허용 목록에 추가해 권한 확인 줄이기',
95  'keybindings-help': '단축키 바꾸기 도움말',
96  loop: '프롬프트 · 명령을 주기적으로 반복 실행',
97  'plugin-authoring': '모드(띠 · 패널 · 상태 줄 · 훅) 만들기',
98  run: '앱을 실행해 변경을 직접 확인',
99  'run-skill-generator': '프로젝트별 run 스킬 작성 · 개선',
100  simplify: '변경 코드의 재사용 · 단순화 · 효율 정리',
101  slides: '요청서로 새 슬라이드 덱 만들기',
102  'update-config': 'settings.json 설정(훅 · 권한 · 환경 변수) 변경',
103  verify: '변경이 실제로 동작하는지 끝까지 실행해 확인',
104  'workflow-authoring': 'Workflow 스크립트 작성 참고 자료',
105
106  // 클라우드 · 사용자 스킬
107  'startup-hook-skill': '클라우드 세션용 시작 훅 만들기',
108  'session-start-hook': '클라우드 세션용 시작 훅 만들기',
109  'built-in-browser': '데스크톱 앱 내장 브라우저 사용 안내',
110  'chrome-browser': 'Claude in Chrome 확장 사용 안내',
111  'computer-use': '내 컴퓨터의 앱 조작(computer use) 안내',
112  docs: '함께 편집 · 공유하는 문서 만들기',
113  docx: 'Word(.docx) 문서 만들기 · 편집',
114  'google-workspace': 'Google Docs · Sheets · Slides 파일 만들기 · 편집',
115  'import-memory': '다른 AI 비서의 메모리 가져오기',
116  morning: '아침 브리핑 만들기 · 예약',
117  pdf: 'PDF 읽기 · 병합 · 분할 · 생성',
118  pptx: 'PowerPoint(.pptx) 만들기 · 편집',
119  'skill-creator': '스킬 만들기 · 개선 · 평가',
120  xlsx: '스프레드시트 만들기 · 편집',
121
122  // 이 저장소(Nexus) 스킬
123  'nexus-android-verify': 'Android 에뮬레이터 · 실기기에서 앱 변경 확인',
124  'nexus-deck': 'Nexus 발표 자료(PPT) 만들기',
125  'nexus-migration': 'Prisma 마이그레이션 추가 · 변경(HNSW 인덱스 보호)',
126  'nexus-pc-handoff': 'PC 를 옮길 때 git 으로 안 옮겨지는 것 챙기기',
127  'nexus-verify': 'check:* 계약 검증 실행 · 디버그',
128}
129
130export const CONFIG: Readonly<Record<string, string>> = {
131  autoCompact: '자동 압축',
132  autoContinueAtUsageLimit: '사용 한도에서 자동으로 계속',
133  switchModelsOnFlag: '메시지가 플래그되면 모델 전환',
134  tips: '팁 보기',
135  reduceMotion: '움직임 줄이기',
136  thinking: '생각 모드',
137  promptSuggestionEnabled: '프롬프트 제안',
138  recap: '세션 요약',
139  checkpoints: '코드 되감기(체크포인트)',
140  workflows: '동적 워크플로',
141  workflowKeywordTriggerEnabled: 'Ultracode 키워드로 시작',
142  workflowSizeGuideline: '동적 워크플로 규모',
143  artifacts: '아티팩트',
144  verbose: '자세한 출력',
145  progressBar: '터미널 진행 막대',
146  turnDuration: '턴 소요 시간 보기',
147  timeFormat: '시간 형식',
148  permissionMode: '기본 권한 모드',
149  worktreeBaseRef: 'worktree 기준 ref',
150  useAutoModeDuringPlan: '계획 중 자동 모드 사용',
151  gitignore: '파일 선택기에서 .gitignore 따르기',
152  copyFullResponse: '/copy 선택 창 건너뛰기',
153  copyOnSelect: '선택하면 복사',
154  autoScroll: '자동 스크롤',
155  defaultToAgentsView: '기본으로 에이전트 보기 열기',
156  leftArrowOpensAgents: '← 키로 에이전트 보기 열기',
157  autoUpdatesChannel: '자동 업데이트 채널',
158  theme: '테마',
159  notifChannel: '로컬 알림',
160  inputNeededNotifEnabled: '조치가 필요하면 푸시',
161  agentPushNotifEnabled: 'Claude 가 판단하면 푸시',
162  outputStyle: '출력 스타일',
163  language: '언어',
164  editor: '편집기 모드',
165  askUserQuestionTimeout: '질문 자동 진행 대기 시간',
166  externalEditorContext: '외부 편집기에 마지막 응답 표시',
167  prStatus: 'PR 상태 표시줄 보기',
168  model: '모델',
169  autoConnectIde: 'IDE 자동 연결(외부 터미널)',
170  chrome: 'Claude in Chrome 기본 사용',
171  dialogExpiry: '대화 상자 만료',
172}
173