개발자를 위한 탭 컨텍스트 관리자. 브라우저 탭을 작업 단위로 자동 그룹화하고, 작업 전체를 클릭 한 번으로 아카이브·복원하며, 모든 것을 즉시 검색합니다. Chrome / Edge 사이드 패널 확장 프로그램 — 로컬 우선, 계정 불필요.
cairn은 산길을 표시하는 돌무더기입니다 — 흩어진 탭들을 위한 이정표. 원래 코드명은 TabCtx였습니다.
tabctx-prd-tech-spec.md를 참고하세요.
MVP 핵심 루프, v1.1 개발자 특화 기능, v1.5 AI 기능이 모두 구현되어 동작 중입니다(현재 1.0):
-
사이드바 — 현재 탭을 작업별로 그룹화하여 실시간으로 표시; 통계 바와 하단 상태 바; 헤더에서 클릭 한 번으로 전체 펼침 / 접기 (활성 작업 + Inbox).
-
수동 작업 — 작업 생성 / 이름 변경 / 삭제; 작업 간 탭 드래그 이동.
-
작업 전체 아카이브 / 복원 — 클릭 한 번으로 아카이브 후 닫기, 클릭 한 번으로 복원 (재열기 속도 제한 적용); 5초 실행 취소.
-
AI로 전체 정리 — 헤더의 "✦ 전체 정리" 버튼이 열려 있는 모든 탭을 한 번에 재클러스터링하여 잔여 탭을 최소화하도록 그룹 간 탭을 이동합니다. 별표 탭과 수동으로 배치한 탭은 그대로 유지되며, 빈 그룹은 정리됩니다. 미리보기에서 각 탭의 원래 그룹이 표시되고, 전체 재구성은 클릭 한 번으로 취소할 수 있습니다. (Inbox는 자체적인 보수적인 "✦ AI 정리"를 유지합니다; 아래 참조.)
-
세션 복구 — 브라우저를 재시작해도 작업이 유지됩니다. 재시작 시 탭은 URL을 기준으로 레코드에 재바인딩되고, 작업은 제목을 기준으로 네이티브 그룹에 재연결되어 아무것도 손실되지 않습니다. Chrome이 작업의 탭을 전혀 복원하지 않은 경우, 해당 작업은 자동으로 아카이브됩니다(URL은 보존). 클릭 한 번으로 복원할 수 있습니다.
-
중복 감지 및 병합 (F-05) — 동일한 URL의 중복 탭을 표시; 클릭 한 번으로 병합 (가장 최근에 활성화된 탭 유지).
-
전역 검색 (
⌘⇧K) — fuse.js로 열린 탭과 아카이브된 탭을 퍼지 검색;↵로 탭으로 이동,⌘↵로 전체 작업 복원. 입력 전에는 최근 탭과 ★ 별표 탭을 보여주는 런처 형태로 열립니다. -
양방향 네이티브 tabGroups 동기화 (F-06) — Inbox = 그룹 없음; 이름이 있는 각 작업 = 네이티브 탭 그룹 하나, 제목/색상 1:1 매핑; 네이티브 측에서의 그룹 추가 / 제거 / 편집이 역으로 동기화되며, 수동으로 생성된 그룹도 자동으로 채택됩니다.
-
자동 그룹화 엔진 (F-07) — 새 탭은 열기 체인 / 시간 창 / 도메인을 기준으로 점수가 매겨지며, 충분히 확신될 때만(예: 이미 해당 작업에 있는 탭에서 열린 경우) 기존 작업에 합류하고, 그렇지 않으면 Inbox에 남습니다. 수정 사항을 학습합니다(탭을 드래그하여 꺼내면 음수 샘플이 기록되고, 수동 할당 시 고정됨). 기본적으로 보수적으로 동작하며 잘못된 분류보다 Inbox를 선호합니다. 새 작업(새 그룹) 생성은 항상 사용자의 확인이 필요합니다 — Inbox 탭을 새 작업으로 자동 승격하지 않습니다. 같은 사이트 제안: Inbox 탭 중 같은 사이트(eTLD+1)를 공유하는 탭이 충분히 많으면(기본 임계값 4, 설정에서 2–8 조정 가능), 상단에 "그룹" 제안이 표시되며 사용자가 확인할 때만 새 작업이 됩니다. 엔진 전체를 설정에서 끌 수 있습니다 (끄면 새 탭은 Inbox에만 들어갑니다).
-
localhost 프로젝트 이름 매핑 (F-08) —
localhost:3000에 바인딩한 프로젝트 이름이 표시됩니다(예:auth-service). 포트는 행 끝에 모노스페이스로 렌더링되며, 바인딩되지 않은 포트에는 인라인 원클릭 바인딩 제안이 표시됩니다. -
GitHub / Bitbucket 메타데이터 (F-09) — GitHub PR/Issue 및 Bitbucket Cloud PR/Issue 행에 "type + number" 모노스페이스 배지(
PR #482/#212)가 표시되고, 호버 시owner/repo(workspace/repofor Bitbucket)가 표시됩니다. GitHub는 긴 후행 제목을 제거하고 실제 제목만 유지합니다. 순수 URL 파싱 — 요청 없음, 권한 없음. -
별표 (하이라이트) — 탭 행에 호버하여 "하이라이트"로 별표 표시: 별표 탭은 해당 작업 상단으로 올라가고, 패널 상단의 "★ 하이라이트" 섹션에 모여 빠른 접근이 가능하며, 오래됨/침하로 표시되거나 자동 폐기되지 않습니다 (시스템이 중요한 탭을 임의로 처리하지 않습니다). 별표는 아카이브/복원 시에도 유지됩니다.
-
AI 이름 변경 (AI 구성 필요) — 작업 이름을 변경할 때 입력 옆의 "✦ AI" 버튼이 AI에게 해당 작업의 탭 제목과 도메인으로부터 짧은 작업 이름을 제안하도록 요청하고 입력란을 채워줍니다. 사용자가 확인하거나 수정할 수 있습니다(제목과 도메인만 전송, 자동 적용 없음; 실행 중에는 버튼이 "✦ 취소"로 변경되어 중단 가능).
-
오래됨 감지 (F-10) — 임계값(기본 7일, 조정 가능)을 초과하여 방문하지 않은 열린 탭은 작업에서 빠져나와 하단에 흐릿한 "침하" 영역에 표시되며, 원클릭 "전체 아카이브"(취소 가능)가 제공됩니다. 알림 없음; 설정에서 비활성화 가능.
-
탭 폐기 및 메모리 회수 (F-11) — 기본적으로 꺼져 있음; 켜면 5분마다 검사하여 임계값(기본 30분, 조정 가능)을 초과해 유휴 상태인 탭 중 비활성 / 소리 없음 / 고정되지 않은 탭이며 localhost가 아닌 탭을 폐기하여 메모리를 확보합니다(클릭으로 자동 새로고침). 하단 상태 바에 누적 예상 회수량이 표시됩니다. localhost 화이트리스트가 개발 서버를 보호합니다.
-
내보내기 및 가져오기 (F-12) — 작업을 Markdown으로 원클릭 내보내기 (제목 + 링크, 클립보드에 복사, 스탠드업 / Notion용); 설정의 "전체 데이터 내보내기 (JSON)"로 백업하고 "JSON 가져오기"로 복원. 가져오기는 추가 방식이며 비파괴적 — 가져온 작업은 아카이브에 들어가고 기존 데이터는 절대 덮어쓰지 않으므로, 기기 간 백업 / 마이그레이션에 안전하게 사용할 수 있습니다.
-
Inbox AI 정리 (F-13, 선택 사항) — 본인의 Anthropic / OpenAI API 키를 입력한 후 Inbox 헤더에 "✦ AI 정리" 버튼이 나타납니다. AI가 탭 제목과 도메인 및 각 기존 작업의 도메인과 샘플 제목을 읽어 새 작업을 제안하거나 적합한 기존 작업과 병합을 제안하며, 미리보기 후 적용됩니다. 분석 도중 취소할 수 있습니다. 기본적으로 꺼져 있으며, 제목 + 도메인 + 작업 이름만 전송하고(기존 작업의 도메인/샘플 포함), 공식 API에 직접 연결하며, 키는 기기에 저장됩니다.
- 커스텀 릴레이 — 공식 API 외에도 "커스텀 릴레이"를 선택하여 OpenAI 호환 엔드포인트(예:
https://newapi.elevatesphere.com/v1) + 키 + 모델을 입력하면 자체 릴레이에 연결할 수 있습니다. 개인정보 보호 범위는 동일하며(여전히 제목 + 도메인 + 작업 이름만), 키는 로컬에 저장되고, 권한은 입력한 호스트로만 제한됩니다. - 연결 테스트 — 설정의 원클릭 "연결 테스트"가 소규모 요청을 전송하여 키 / 엔드포인트 / 모델을 검증하며,
✓ Connected · model · Nms또는 평이한 언어의 오류(인증 실패 / 엔드포인트 또는 모델을 찾을 수 없음 / 타임아웃 / 네트워크 오류 등)로 즉시 피드백을 제공합니다.
- 커스텀 릴레이 — 공식 API 외에도 "커스텀 릴레이"를 선택하여 OpenAI 호환 엔드포인트(예:
-
다국어 UI — 전체 인터페이스가 English / 简体中文 / 日本語 / 한국어를 지원합니다; 기본적으로 브라우저 UI 언어를 따르며, 설정에서 언제든지 전환할 수 있습니다.
아직 구현되지 않음(설계 문서 로드맵 참조): Firefox 지원, 크로스 디바이스 동기화.
아직 스토어에 등록되지 않았습니다 — 빌드 후 "압축 해제된 확장 프로그램"으로 로드하면 장기적으로 사용할 수 있습니다(계정 불필요, 서버 없음, 모든 데이터는 로컬에 저장).
사전 요구 사항: Node 20+ 및 pnpm (npm i -g pnpm).
1. 빌드
git clone https://github.com/JavaLyHn/cairn-tabs.git
cd cairn-tabs
pnpm install
pnpm build # output in .output/chrome-mv32. 브라우저에 로드 (Chrome / Edge)
chrome://extensions를 엽니다(Edge에서는edge://extensions).- 개발자 모드를 활성화합니다(오른쪽 상단).
- **"압축 해제된 항목 로드"**를 클릭하고 프로젝트의
.output/chrome-mv3디렉터리를 선택합니다. - 툴바 아이콘을 고정하고 클릭하여 사이드 패널을 엽니다(또는
⌘⇧O/Ctrl+Shift+O로 패널을 열고,⌘⇧K/Ctrl+Shift+K로 검색 창을 엽니다).
⚠️ 반드시 **.output/chrome-mv3**를 선택하세요(프로덕션 빌드 — 독립 실행형, 즉시 사용 가능)..output/chrome-mv3-dev는 개발 빌드이며pnpm dev가 계속 실행 중이어야 합니다. 그렇지 않으면 빈 패널이 표시됩니다 — 일반 사용 시에는 로드하지 마세요.
3. 새 버전으로 업데이트
git pull && pnpm build그런 다음 chrome://extensions로 이동하여 확장 프로그램의 새로고침 ↻를 클릭합니다(제거 후 다시 추가할 필요 없음).
4. (선택 사항) AI 활성화 — 설정 ⚙ → AI 정리 → 제공업체를 선택하고 API 키(또는 커스텀 릴레이의 엔드포인트 + 키 + 모델)를 입력 → "연결 테스트"를 클릭하여 확인 → 저장. 기본적으로 꺼져 있으며, 탭 제목 + 도메인 + 작업 이름만 전송합니다.
데이터 및 백업: 모든 작업/탭은 브라우저의 로컬 IndexedDB에 저장되며 업로드되지 않습니다. 설정의 "전체 데이터 내보내기 (JSON)"로 언제든지 백업하고, "JSON 가져오기"로 복원하거나 다른 기기로 마이그레이션하세요(가져온 작업은 아카이브에 들어가며 기존 데이터는 덮어쓰지 않습니다).
WXT (Manifest V3) · React 19 · TypeScript · Tailwind CSS · Dexie (IndexedDB) · Zustand · fuse.js · Vitest
아키텍처 주요 사항: Service Worker가 유일한 쓰기 주체이며, UI는 명령을 전송하고 상태 스냅샷을 구독하기만 합니다. 자체적으로 시작된 모든 탭/그룹 작업은 이벤트 루프를 방지하기 위해 동기화 잠금 내에서 실행됩니다. SW가 슬립 상태가 된 후에는 hydrate + reconcile을 통해 재구성 및 정합성을 복원합니다.
pnpm install
pnpm dev # start the dev server (HMR); doesn't open a browser — load .output/chrome-mv3-dev manually
pnpm build # production build to .output/chrome-mv3
pnpm compile # type-check (tsc --noEmit)
pnpm test # run Vitest일반 사용의 경우 위의 설치 및 사용을 참고하세요. 개발 시에는 pnpm dev를 실행하고 .output/chrome-mv3-dev를 로드하세요(핫 리로드를 지원하지만, 개발 서버가 실행 중이어야 합니다. 그렇지 않으면 패널이 빈 화면으로 표시됩니다).
core/ UI-agnostic domain logic (unit-testable)
store/ Dexie schema and repository layer
background/ SW: tab sync / command handling / native group sync / undo / sync lock
search/ fuse.js index
entrypoints/ WXT entry points: background + sidepanel (React)
shared/ types and the message protocol
tests/ Vitest (incl. fake-chrome integration tests)
docs/ design docs
기여를 환영합니다 — 먼저 CONTRIBUTING.md를 읽어주세요.
AGPL-3.0-only © JavaLyHn. 파생 저작물(네트워크 SaaS 포함)은 동일한 라이선스 하에 오픈 소스로 공개해야 합니다.