본문으로 건너뛰기
5분 AI.
GITHUB 레포 딥다이브 · 2026-07-30 · BHOLMESDEV/HUBBLE.MD · 사람과 AI 에이전트가 함께 쓰는 마크다운 노트장

bholmesdev/hubble.md 딥다이브
— 폴더 하나가 곧 API가 되는 로컬 우선 노트 앱

데스크탑 앱

빠른 판단

무엇
로컬 Markdown을 블록 에디터로 편집하고 에이전트의 파일 변경을 화면에 반영하는 노트 앱
이럴 때
노트를 일반 파일로 소유하면서 사람은 에디터로, 코딩 에이전트는 같은 폴더의 파일로 함께 편집할 때
Hubble은 모든 노트를 내 컴퓨터의 평범한 마크다운(.md) 파일로 저장하는 무료·오픈소스 데스크톱 노트 앱이다. Notion·애플 노트처럼 블록 에디터로 편하게 쓰지만, 뒤에서는 독점 클라우드 DB가 아니라 그냥 폴더 안의 텍스트 파일이 쌓인다.

진짜 차별점은 슬로건에 있다 — "The best notepad for you and your agents"(당신과 당신의 에이전트를 위한 최고의 노트장). 노트가 그냥 파일이라, Claude Code·Codex·Cursor 같은 코딩 에이전트를 그 폴더에 붙이면 에이전트가 파일을 직접 읽고 고치고, Hubble은 그 변경을 실시간으로 다시 불러온다(live-reload). 나아가 에이전트에게 "이 노트들을 표로 보여줘"라고 시키면, 에이전트가 HTML 앱을 하나 써넣고 Hubble이 그걸 샌드박스 미니앱으로 실행한다.

(저장소 bholmesdev/hubble.md · 언어 TypeScript(모노레포) · 라이선스 MIT · 데스크톱 버전 v0.1.23 · 별 약 1,090 · 포크 63 · 생성 2026-02-17 · 저자 Ben Holmes(@bholmesdev, Astro 코어팀))
목차
  1. 한 줄 정체
  2. 왜 주목받는가 — 에이전트 시대의 노트장
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 — Electron 3분할과 HTML 앱 샌드박스
  5. 디렉토리 구조 해부
  6. 학습 포인트 — 기술별 배울 것
  7. 시스템 / 실행 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 로드맵 (주차별)
  10. 핵심 키워드 사전
  11. 참고 링크

1한 줄 정체

이 프로젝트가 정확히 무엇인지 한 문장으로

Hubble은 "내 폴더에 쌓이는 마크다운 파일을, 사람도 AI 에이전트도 함께 편집하는 노트 앱"이다. Notion 같은 블록 에디터(/ 명령, 마크다운 단축키, 프론트매터 속성)를 쓰지만 저장 형식은 평범한 .md 텍스트다. 그래서 에이전트를 그 폴더에 붙이면 곧바로 협업이 되고, 에이전트가 노트를 고치면 Hubble이 즉시 화면을 갱신한다. 여기에 "HTML 앱"이라는 확장 개념으로, 노트 폴더를 표·책장·지도 같은 맞춤 뷰로 바꿀 수 있다.

한 장의 비유

"클라우드 사서 대신, 내 책장 위에서 같이 일하는 도우미"

Notion은 책(노트)을 회사 창고(클라우드 DB)에 넣어 두고, 창고 규칙(플러그인 SDK)을 통해서만 정리를 돕는다. Hubble은 책을 내 방 책장(로컬 폴더)에 그대로 두고, 사람이든 AI 도우미든 같은 책장에서 직접 책을 꺼내 고치게 한다.

도우미(에이전트)가 새 정리 도구가 필요하면? Hubble은 앱스토어를 뒤지지 않는다. 도우미에게 "이 책들 목록표 하나 만들어 줘"라고 말하면, 도우미가 그 자리에서 HTML 파일 한 장을 써넣고, 그게 곧 그 폴더 전용 미니앱이 된다.

용어
로컬 우선(local-first)
데이터의 원본(진실의 출처)이 내 컴퓨터 디스크에 있고, 클라우드는 있으면 좋은 보조(동기화)일 뿐인 설계 철학. 인터넷이 끊겨도 동작하고, 서비스가 망해도 내 파일은 남는다. Hubble에서 노트는 언제나 폴더 안 .md 파일이며, 클라우드 동기화는 선택 기능(그것도 아직 개발 중)이다.
용어
프론트매터(frontmatter)
마크다운 파일 맨 위에 ---로 감싸 적는 YAML 메타데이터 영역. 제목·태그·날짜·완료여부 같은 "속성"을 담는다. Hubble은 이 프론트매터를 File Properties(파일 속성)의 단일 진실원으로 삼아, true/false는 체크박스로, 2026-07-30은 날짜로 자동 해석한다.

2왜 주목받는가 — 에이전트 시대의 노트장

트렌딩 이유와 비슷한 도구 대비 강점

Hubble이 떠오른 배경엔 "코딩 에이전트가 파일을 직접 다루는" 흐름이 있다. Claude Code·Codex·Cursor는 결국 폴더 안 파일을 읽고 쓰는 도구다. 그렇다면 노트 앱이 파일을 독점 DB에 가둘 게 아니라 그냥 폴더에 풀어 두면, 에이전트가 곧바로 1급 협업자가 된다는 게 Hubble의 통찰이다. README의 핵심 문구: "Point your agent at your notes folder to start collaborating. Hubble will live-reload as your agent edits."

두 번째 무기는 확장 방식이다. 보통 앱은 플러그인 SDK(자바스크립트 API)를 배워야 기능을 늘린다. Hubble은 "에이전트에게 HTML 앱을 짜 달라"로 대체한다. 파일시스템 자체가 확장 표면이 되는 셈이다.

비슷한 것들과의 비교

항목HubbleNotionObsidian
저장 형식로컬 .md + 프론트매터클라우드 독점 DB로컬 .md
편집 경험블록 에디터(WYSIWYG)블록 에디터주로 마크다운 원문
에이전트 협업폴더가 곧 API · 라이브리로드API 있으나 파일 아님파일 편집 가능(리로드 수동)
확장 방식에이전트가 HTML 앱 작성제한적 API/통합JS 플러그인 SDK
가격/라이선스무료 · MIT 오픈소스상용(부분 무료)무료(비오픈소스)

"그냥 마크다운 폴더 열면 되잖아?"에 대한 답

맞다, 텍스트 에디터로도 .md는 연다. 어려운 건 (1) Notion급 편집 경험을 주면서도 원본을 평문으로 유지, (2) 외부(에이전트) 편집을 안전하게 실시간 반영, (3) 에이전트가 짠 임의의 HTML을 시스템을 망치지 않게 실행하는 것이다. Hubble은 마크다운↔리치텍스트 왕복 변환 엔진, chokidar 파일 감시 라이브리로드, 그리고 불투명 출처(opaque origin) 샌드박스 iframe + 토큰 인증 브로커로 이 셋을 각각 정공법으로 풀었다.

비유

번역가와 원문의 관계. 당신은 예쁜 편집 화면(리치텍스트)에서 글을 쓰지만, 디스크에는 늘 "원문 마크다운"이 저장된다. 화면과 원문 사이를 오가는 동시통역사(remark 파서 + ProseMirror 직렬화기)가 있어, 어느 쪽에서 고쳐도 뜻이 어긋나지 않게 왕복 번역을 보장한다. 그래서 에이전트가 원문을 고쳐도, 사람이 화면에서 고쳐도 충돌 없이 같은 파일이 유지된다.

3기술 스택 전체 지도

package.json과 소스에서 읽어낸 실제 의존성

Hubble은 pnpm 워크스페이스 모노레포다(전부 TypeScript ~5.8, 린트·포맷은 ESLint+Prettier가 아니라 Biome 2.4, React Compiler까지 켜져 있음). 크게 apps/*(실행되는 3개 앱)와 packages/*(공유 코어)로 나뉜다.

① apps/desktop — 메인 Hubble 앱 (Electron)

② apps/web — 마케팅 랜딩(hubble.md)

③ apps/www — 브라우저판 Hubble (개발 중, HEAVILY WIP)

④ packages/* — 공유 코어

용어
ProseMirror / Tiptap
ProseMirror는 리치텍스트(WYSIWYG) 에디터를 만드는 저수준 툴킷으로, 문서를 사람이 보기 좋은 트리 구조(document model)로 다룬다. Tiptap은 그 위에 얹은 사용하기 쉬운 래퍼다. Hubble은 이 트리와 마크다운 텍스트 사이를 왕복 변환한다.

4아키텍처 심화 — Electron 3분할과 HTML 앱 샌드박스

파일이 화면이 되고, 에이전트가 그 파일을 만지기까지

Hubble의 도메인 모델은 CONTEXT.md의 용어집이 곧 설계도다. 핵심 개념: Workspace(.hubble/config.json이 있는 논리적 노트 묶음. 클라우드가 아니라 설정 파일의 존재로 정의됨), HTML App(폴더 안의 .html 파일을 Hubble이 실행하는 미니 UI), Embed(마크다운 안에 인라인으로 박은 HTML 앱), Workspace Snapshot(원자적으로 조립된 로딩 완료 상태 — 이게 완성돼야 화면을 그린다).

┌──────────────────────────────────────────────────────────────┐ │ 코딩 에이전트 (Claude Code / Codex / Cursor) │ │ └─ 노트 폴더의 .md 파일을 직접 편집 │ └───────────────────────────┬──────────────────────────────────┘ chokidar 파일 감시 │ 변경 감지 → externalFileChange ▼ ┌──────────────────────────────────────────────────────────────┐ │ Main 프로세스 (electron/main.ts, ~1,935줄) │ │ 유일한 Node/파일시스템 접근자 │ │ 파일 read/write/watch · 워크스페이스 설정 · 전역 검색 │ │ ★ 권한 그랜트(grantedFiles/grantedRoots @ grants.json) │ │ hubble-asset:// 프로토콜로 HTML 앱 서빙 · 자동 업데이트 │ └───────────────────────────┬──────────────────────────────────┘ contextBridge (contextIsolation:true, nodeIntegration:false) window.desktopApi ── 타입 안전한 단일 IPC 다리 ── ▼ ┌──────────────────────────────────────────────────────────────┐ │ Renderer (React 19, src/) │ │ Tiptap 에디터 · 사이드바 · 툴바 · 터미널 패널 · 설정 │ │ 상태: @simplestack/store (src/store/) │ │ │ │ ┌── 마크다운 왕복 변환 ──────────────────────────────┐ │ │ │ .md 텍스트 → [remark AST] → markdownToProsemirror │ │ │ │ ← prosemirrorToMarkdown ← [편집] │ │ │ │ (frontmatter는 YAML로 분리 = File Properties 원본) │ │ │ └────────────────────────────────────────────────────┘ │ │ │ │ ┌── HTML 앱 실행 (IframeView.tsx) ────────────────────┐ │ │ │ <iframe sandbox="allow-scripts allow-forms" │ │ │ │ name={token}> ← 불투명 출처, same-origin ✗ │ │ │ │ window.hubble.files.{list,read,create,update,...} │ │ │ │ │ postMessage {token, method, params} │ │ │ │ ▼ (Zod 검증 + 워크스페이스 경로 확인) │ │ │ │ 브로커 → desktopApi(IPC) → Main → 실제 .md 파일 │ │ │ └────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────┘

① Electron 3분할 — 권한을 좁게 나누기

흥미로운 사실: 이 팀은 원래 Tauri에서 Electron으로 옮겼다(ADR-0002). 이유는 렌더러를 Chrome DevTools Protocol로 노출해 에이전트가 UI를 테스트할 수 있게 하려던 것. Main 프로세스만 파일시스템을 만지고, Preload는 contextBridge로 타입 안전한 window.desktopApi 하나만 노출하며(contextIsolation:true, nodeIntegration:false), Renderer는 결론만 받는다. 특히 렌더러는 사용자가 허용한 경로(grantedFiles/grantedRoots)만 만질 수 있는 권한 그랜트 모델을 쓴다 — 앰비언트 파일 접근이 없다.

② 마크다운 ⇄ 리치텍스트 왕복 변환

Hubble의 "평문을 유지하면서 예쁜 편집"을 가능케 하는 엔진(packages/editor). .md 텍스트는 먼저 프론트매터(YAML)를 본문과 분리(ADR-0003)한 뒤, remark AST를 거쳐 Tiptap/ProseMirror 문서로 바뀐다. 편집 후엔 다시 마크다운으로 직렬화해 디스크에 쓴다. 이 왕복 신뢰성(round-trip fidelity)은 MarkdownRoundtrip.test.ts 등으로 집요하게 테스트된다 — "화면에서 고치고 저장했더니 원문이 미묘하게 망가지는" 사고를 막는 계약이다.

③ HTML 앱 샌드박스 — 에이전트가 짠 코드를 안전하게 실행

가장 배울 게 많은 부분(ADR-0004/0005). 에이전트가 써넣은 임의의 HTML을 어떻게 안전하게 실행할까? Hubble은 불투명 출처(opaque origin) 샌드박스 iframe에 그 HTML을 넣는다: sandbox="allow-scripts allow-forms"(same-origin 없음), name={token}으로 고유 토큰 부여. iframe은 파일시스템에 직접 못 닿고, 오직 주입된 window.hubble.files.* API를 postMessage로 호출한다. 호스트 쪽 브로커(IframeView.tsx)가 토큰을 확인하고 Zod 스키마 검증 + 워크스페이스 경로 확인(assertPathInWorkspace)을 거친 뒤에만 실제 파일 작업을 대행한다.

배울 점
신뢰 경계(trust boundary)를 코드로 강제하기

"에이전트가 짠 코드니까 조심"이 문구가 아니라 구조다. ① 불투명 출처 iframe으로 브라우저 레벨 격리 → ② postMessage로만 통신(직접 호출 불가) → ③ 토큰으로 "이 iframe이 맞는지" 확인 → ④ Zod로 입력 검증 → ⑤ 경로가 워크스페이스 안인지 확인. 다섯 겹의 방어선이 겹쳐 있다. 신뢰할 수 없는 플러그인/코드를 실행해야 하는 모든 앱의 교과서.

용어
불투명 출처(opaque origin) / 샌드박스 iframe
<iframe sandbox>에 allow-same-origin을 빼면, 그 iframe은 부모 페이지와 다른 "출처 없는(null) 출처"로 취급된다. 부모의 쿠키·localStorage·DOM에 접근할 수 없고, 오직 postMessage로만 대화할 수 있다. 신뢰할 수 없는 코드를 유리 상자에 가두는 웹 표준 기법.

④ HTML 앱 런타임 — 왜 "그냥 HTML"이 동작하나

에이전트는 Tailwind 클래스와 Alpine x-data만 쓴 평범한 .html을 써넣으면 된다. 비결은 Main 프로세스가 hubble-asset:// 프로토콜로 그 파일을 서빙하기 전에 테마 CSS·Hubble 런타임·Tailwind 브라우저 빌드·Alpine.js를 자동 주입하기 때문이다. 주입되는 packages/runtime/global.js가 window.hubble을 만든다:

// packages/runtime/global.js — HTML 앱이 파일을 다루는 유일한 통로
window.hubble = {
  files: {
    list:   (glob = "**/*") => requestHubble("files.list", { glob }),
    read:   (path)          => requestHubble("files.read", { path }),
    create: (input)         => requestHubble("files.create", { input }),
    update: (path, patch)   => requestHubble("files.update", { path, patch }),
    remove: (path)          => requestHubble("files.remove", { path }),
    open:   (path)          => requestHubble("files.open", { path }),
    // safeList/safeRead/... = 던지지 않고 { ok, value } 반환하는 변형
  },
};

호스트 쪽 브로커는 각 메서드를 Zod로 검증하고 경로를 워크스페이스 안으로 가둔다. update는 패치형이라 생략한 본문·속성 키는 보존되고, 속성 삭제는 명시적으로만 된다:

// apps/desktop/src/editor/IframeView.tsx (요지)
if (request.method === "files.update") {
  const path = await resolveFilePath(parseInput(markdownPathSchema, params.path), true);
  const patch = parseInput(filePatchSchema, params.patch);          // Zod 검증
  const absolutePath = await resolveWorkspaceFile(workspacePath, path, { exists: true });
  const markdown = await applyMarkdownPatch(absolutePath, patch);   // 실제 파일 수정
  await refreshFiles(workspacePath);
  return { ok: true, value: parseMarkdownFile(path, markdown) };
}

5디렉토리 구조 해부

모노레포가 어떻게 나뉘어 있나
hubble.md/ ├── apps/ │ ├── desktop/ ← ★ 메인 Electron 앱 │ │ ├── electron/ │ │ │ ├── main.ts Main 프로세스(파일 I/O·프로토콜·권한그랜트·자동업데이트) │ │ │ ├── preload.ts contextBridge로 window.desktopApi 노출 │ │ │ ├── terminal.ts node-pty 내장 터미널 │ │ │ └── telemetry.ts / zoom.ts │ │ ├── src/ │ │ │ ├── App.tsx │ │ │ ├── editor/ IframeView·EmbedExtension·ImageExtension·htmlAppFileApi │ │ │ ├── store/ actions/state/history/persistence (@simplestack/store) │ │ │ ├── lib/ path·search·clipboard 유틸 │ │ │ └── desktopApi/ │ │ └── fixtures/playground/ 예제 워크스페이스(todo-demo.html 등 실제 HTML 앱) │ ├── web/ Astro 랜딩 페이지 │ └── www/ WIP 브라우저판(React + Convex) ├── packages/ │ ├── editor/ ← ★ 프레임워크 독립 마크다운↔ProseMirror 코어 │ │ └── src/ markdownToProsemirror·prosemirrorToMarkdown·frontMatter │ │ Link·List·Heading·ReviewMark + 다수 *.test.ts │ ├── ui/ 공유 React 에디터 UI │ ├── runtime/ ← ★ HTML 앱에 주입되는 코드(global.js, 테마 CSS) │ ├── sync/ WIP 파일시스템 동기화 엔진 │ ├── convex-client / sync-backend Convex 클라우드 동기화 │ └── cli/ `hubble` CLI ├── docs/ │ ├── adr/ ★ 아키텍처 결정 기록 8건(ADR) │ ├── agents/ 에이전트 스킬 문서(issue-tracker·triage·domain) │ └── plans/ ├── specs/gh-*/ 이슈별 PRODUCT.md + TECH.md 스펙 쌍 ├── .agents/skills · .claude/skills · .codex/environments ← 레포 자동화용 에이전트 설정 ├── AGENTS.md · CONTEXT.md · CHANGELOG.md · skills-lock.json └── biome.json · package.json · pnpm-workspace.yaml

구조에서 읽히는 의도는 "코어와 껍데기의 분리"다. 마크다운 엔진(editor)은 React를 모르는 순수 로직으로 떼어 두고, React UI(ui)가 그 위에 얹힌다. 그래서 데스크톱(Electron)·브라우저(Convex)·CLI가 같은 코어를 공유한다. 그리고 레포 자체가 에이전트로 운영된다 — .agents/.claude/.codex 설정과 docs/adr(설계 결정 기록)이 그 증거다.

배울 점
"소프트웨어 공장" 운영 — 레포를 에이전트가 돌린다

Hubble 저장소 자동화는 Warp Factory 에이전트로 굴러간다: 이슈가 올라오면 에이전트가 분류(triage)·라벨링하고, ready-to-implement 이슈엔 드래프트 PR을 열며, PR은 사람이 보기 전에 AI 코드 리뷰를 거친다. skills-lock.json은 사용 스킬을 콘텐츠 해시로 고정해(mattpocock/skills, vercel-labs/agent-skills 등) 재현성을 확보한다. "AI가 만든 노트 앱을 AI가 유지보수한다"는 실제 사례.

6학습 포인트 — 기술별 배울 것

이 레포를 뜯으며 실제로 손에 남는 것

1) Electron 보안을 제대로 하는 법

contextIsolation:true, nodeIntegration:false, 타입 안전한 단일 contextBridge API, 그리고 권한 그랜트 모델(렌더러는 사용자가 허용한 경로만 접근). "권한은 기본 없음, 필요한 것만 명시"의 실전판. electron/main.ts와 preload.ts가 교과서.

2) 신뢰할 수 없는 코드를 iframe으로 격리하기 (가장 희귀)

불투명 출처 샌드박스 iframe + postMessage 비동기 RPC 브로커 + 토큰 인증 + Zod 검증 + 경로 제한. 임의의 사용자/에이전트 작성 HTML을 안전하게 실행하는 보안 아키텍처 사례 연구. ADR-0004/0005를 함께 읽자.

3) 마크다운 ⇄ 리치텍스트 양방향 변환

remark(unified) 파싱 + 커스텀 ProseMirror 직렬화기, 그리고 왕복 테스트를 정확성 계약으로 삼는 법. 평문을 진실의 출처로 유지하는 WYSIWYG 에디터를 만드는 진지한 수업.

4) 프론트매터를 타입 있는 속성 저장소로

YAML 1.2 의미론, 타입 추론(true/false→체크박스, YYYY-MM-DD→날짜), 패치 시 알 수 없는 키 보존(ADR-0003). "구조화 데이터를 평문에 얹는" 실전 패턴.

5) 모노레포 엔지니어링

pnpm 워크스페이스(workspace:* 의존), 프레임워크 독립 코어(editor)와 React UI(ui) 분리, ESLint+Prettier 대신 Biome, React Compiler + 감사(audit) 게이트. 여러 앱이 코어를 공유하는 대형 구조의 정석.

6) 로컬 우선 동기화 설계

디스크를 진실의 출처로 두고 Convex에 콘텐츠 해시 기반 충돌 감지로 조정하는 packages/sync/src/sync.ts. pushed/pulled/deleted/conflicts를 반환하는 재조정(reconciliation) 로직.

용어
Convex
실시간 반응형 백엔드 서비스(BaaS). 데이터 저장·쿼리·실시간 구독을 코드로 다룬다. Hubble의 클라우드 동기화(브라우저판 포함)에 쓰이지만, 에이전트는 Convex를 절대 만지지 않는다 — 에이전트는 오직 로컬 .md 파일만 편집하고, 동기화는 앱이 알아서 한다.

7시스템 / 실행 요구사항

돌리려면 무엇이 필요한가
항목요구 / 권장
일반 사용자GitHub Releases에서 프리빌드 앱 다운로드. macOS는 서명·공증됨, Windows/Linux는 미서명(첫 실행 시 OS 경고 가능)
자동 업데이트현재 macOS 한정
빌드 도구Node.js, pnpm, (macOS 빌드 시) Xcode CLT xcode-select --install
빌드 명령pnpm install → pnpm bundle:desktop:mac(또는 :win/:linux) → 결과 apps/desktop/release/
개발pnpm dev:desktop (또는 :debug — 렌더러를 CDP 127.0.0.1:9222로 노출)
검사pnpm build(Biome+빌드+타입체크) · pnpm check(Biome) · pnpm typecheck
apps/webNode 22.x
에이전트 연동(선택)Claude Code/Codex/Cursor 등 코딩 에이전트를 노트 폴더에 지정 + npx skills add bholmesdev/hubble-skills
주의
초기 버전 · 일부 기능은 개발 중(WIP)

데스크톱은 v0.1.23(2026-02-17 생성, 활발히 개발 중)이다. 클라우드 동기화(sync)와 브라우저판(www)은 HEAVILY WIP로 표시돼 있어 안정성을 기대하기 이르다. 자동 업데이트는 macOS만 지원하고, Windows/Linux 빌드는 미서명이라 첫 실행 시 OS가 막을 수 있다. 지금의 안정 경로는 로컬 데스크톱 앱 + 폴더 편집이다.

8직접 해볼 수 있는 실습 과제

읽기만 하지 말고 손으로 — 난이도별
LV.1 — 입문 30분

노트 폴더를 에이전트에게 열어 주기

Hubble에서 새 워크스페이스(폴더)를 만들고 노트를 몇 개 쓴 뒤, 같은 폴더를 Claude Code/Cursor로 열어 에이전트에게 "이 노트에 요약 문단 추가해 줘"라고 시켜 보자. Hubble 화면이 실시간으로 갱신되는지 관찰하라. 프론트매터(--- 블록)를 손으로 넣어 보고 속성으로 인식되는지도 확인.

LV.2 — 기초 1~2시간

예제 HTML 앱 뜯어보기

apps/desktop/fixtures/playground/todo-demo.html를 열어, Alpine.js x-data와 window.hubble.files.* 호출이 어떻게 노트를 목록·생성·토글하는지 읽자. hubble.files.list()와 create()를 직접 한두 줄 바꿔 동작 변화를 관찰하라.

LV.3 — 중급 반나절

마크다운 왕복 변환 테스트 돌려보기

packages/editor에서 pnpm test로 MarkdownRoundtrip.test.ts를 실행하고, 표·체크박스·중첩 리스트가 들어간 마크다운을 새 테스트 케이스로 추가해 보자. 왕복 후 원문이 보존되는지(혹은 깨지는지) 직접 확인하며 변환기의 한계를 체감하라.

LV.4 — 심화 1~2일

나만의 HTML 앱 뷰 만들기

hubble-skills를 설치한 뒤 에이전트에게 "이 노트들의 프론트매터 date를 읽어 타임라인 뷰를 그리는 HTML 앱을 만들어 줘"라고 요청하자. 생성된 파일이 어떤 hubble.files API를 쓰는지, 샌드박스 안에서 왜 안전한지 코드로 추적하라.

LV.5 — 도전 주말 프로젝트

브로커에 새 파일 메서드 추가하기

IframeView.tsx 브로커와 runtime/global.js에 files.rename 같은 새 메서드를 end-to-end로 추가해 보자. Zod 스키마·경로 확인·에러 처리(safe 변형)를 모두 갖추고, HTML 앱에서 호출해 동작시키면 신뢰 경계 설계를 온전히 이해하게 된다.

9관련 기술 심화 로드맵 (주차별)

Hubble을 발판 삼아 데스크톱·에디터·에이전트 인프라로
주차주제무엇을 / 왜
1주차마크다운 & 프론트매터CommonMark/GFM 문법, YAML 프론트매터. "글이 곧 구조화 데이터"라는 관점 잡기.
2주차unified / remark AST마크다운을 트리(mdast)로 파싱·변형·직렬화. Hubble editor 코어의 기반.
3주차ProseMirror / Tiptap리치텍스트 문서 모델, 스키마, 트랜잭션. 마크다운↔에디터 변환 구현.
4주차Electron 아키텍처·보안Main/Renderer/Preload 3분할, contextIsolation·sandbox·IPC, 권한 그랜트.
5주차웹 샌드박싱iframe sandbox, 불투명 출처, postMessage RPC, CSP. 신뢰할 수 없는 코드 격리.
6주차파일 감시 & 로컬 우선chokidar 감시, 외부 변경 반영, 콘텐츠 해시 충돌 감지(Convex 동기화).
7주차모노레포 & 툴링pnpm workspace, Biome, React Compiler, electron-builder 크로스플랫폼 배포.
8주차에이전트 친화 설계"파일시스템을 API로", 스킬(skills) 패턴, 레포 자동화. 나만의 에이전트-네이티브 도구 설계.

10핵심 키워드 사전

이 문서에 나온 용어 총정리
용어
로컬 우선(local-first)
데이터 원본이 내 디스크에 있고 클라우드는 보조인 설계. 오프라인 동작·데이터 소유·서비스 종료 내성이 장점.
용어
프론트매터(frontmatter)
.md 맨 위 ---로 감싼 YAML 메타데이터. Hubble의 File Properties 단일 진실원(타입 자동 추론).
용어
ProseMirror / Tiptap
리치텍스트 에디터 툴킷(문서를 트리로 다룸)과 그 위 래퍼. Hubble의 블록 편집 엔진.
용어
왕복 변환(round-trip)
마크다운→에디터→마크다운으로 돌아왔을 때 원문이 보존되는 성질. 테스트로 정확성을 계약화.
용어
불투명 출처 샌드박스 iframe
allow-same-origin 없는 iframe. 부모 자원 접근 불가, postMessage로만 통신. 신뢰 불가 코드 격리.
용어
HTML 앱 / Embed
폴더 안 .html을 Hubble이 실행하는 미니 UI(HTML 앱), 마크다운 안에 인라인으로 박은 것(Embed).
용어
window.hubble.files.*
HTML 앱이 노트를 다루는 유일한 API(list/read/create/update/remove/open). 던지지 않는 safe 변형 제공.
용어
contextBridge / contextIsolation
Electron 보안 핵심. 렌더러를 격리하고 preload로 타입 안전한 최소 API(desktopApi)만 노출.
용어
권한 그랜트(grantedFiles/Roots)
렌더러가 사용자가 허용한 경로만 만질 수 있게 하는 모델. 앰비언트 파일 접근 차단.
용어
Convex
실시간 반응형 백엔드. Hubble 클라우드 동기화(WIP)와 브라우저판에 사용. 에이전트는 접근 안 함.
용어
ADR (Architecture Decision Record)
아키텍처 결정을 이유와 함께 기록한 문서. Hubble은 docs/adr에 8건(Tauri→Electron, 프론트매터, iframe 샌드박스 등)을 남겨 설계 근거를 추적 가능하게 했다.

11참고 링크

더 파고들 때