"ChromeEmbed v0.1은 README 에 'v1 Boundary' 라는 절을 달고 나왔어. 일부러 안 한 큰 거 넷을 거기다 이름 붙여 놨지. 이 lesson은 그 넷을 하나씩 짚어 보고, 각각이 뭘 열어 주는지, 방금 끝낸 여덟 track이 그걸 만들 때 뭘 쥐여 주는지 본다."
미뤄둔 기능 넷
embeds/chrome/README.md 에 그대로 이렇게 적혀 있어:
Dock, hybrid, input-only, and DOM tools are intentionally out of v1.
넷 다 ChromeEmbed가 가질 수도 있었던 다른 모양이야. v0.1은 그중 side panel 하나만 골라서 내보냈고, 나머지는 나중으로 미뤘어.
1. Dock
오른쪽에 붙는 게 아니라 페이지 위에 떠서 끌어 옮길 수 있는 피파 창. Extension UI 라기보다 '데스크톱 위젯' 에 가까워. 만들려면 이런 게 필요해:
- Content script가 z-index를 끝까지 올린 fixed-position 요소를 주입해 (Track 7 Lesson 6의 shadow root + 2147483647 패턴 그대로).
- 그 요소는 cwkPippa의 /embed/dock route를 가리키는 iframe을 품어. Dock은 공간이 좁으니까 /embed/panel 과는 다른 surface를 써야 하거든.
- Drag 핸들, resize 손잡이, 가장자리에 붙는 동작 — 전부 content script 안에서 하는 DOM 작업이야.
v1 에 안 넣은 이유: side panel이 코드 10% 로 같은 UX의 90% 를 풀어 줬어. Dock이 진짜 중요해지는 건 피파를 동영상 플레이어나 지도 위에 띄우고 싶은 사용자한테인데 — 실재하지만 두 번째 순위인 use case 야.
2. Hybrid
Side panel 이랑 dock이 화면에 동시에 떠 있고, dock은 짧게 던지는 용도, panel은 길게 얘기하는 용도로 갈리는 모양. 사용자가 둘 사이를 오가거나 하나를 고정해 두는 거지. 만들려면:
- Dock 에 드는 작업 전부, 거기에 panel과 dock을 맞춰 주는 hand-off 층까지. 아마 chrome.storage를 같이 쓰면서 bus 패턴을 태우는 형태가 될 거야.
- 구현보다 UX 질문이 더 어려워. 언제 뭐가 보여야 해? Dock 에 친 글은 panel 대화로 보내는 거야, 아니면 그 자리에서 바로 처리하는 거야?
v1 에 안 넣은 이유: dock을 먼저 내보내도 hybrid는 그다음 얘기야. Dock 혼자 어떤 느낌인지 배우기 전에는 거기다 hybrid를 접붙일 수가 없어.
3. Input-Only
방향을 뒤집은 거야. 피파가 페이지를 읽는 게 아니라, 피파가 내놓은 답을 페이지 입력창에 넣어 주는 것. 이런 그림이야 — panel에서 피파랑 얘기하다가 'Gmail 작성창에 이 답장 넣어' 를 누르면, Track 7 Lesson 5의 React-friendly fill-input 기술이랑 Lesson 6의 preview-and-confirm이 같이 돌아서 텍스트가 제자리에 떨어져.
- 이미 절반은 만들어져 있어. Track 7의 Lesson 5와 6이 그 기술을 이미 내놨거든.
- Schema는 좀 붙여야 해. 피파 답변이 '어디에 붙일지' 를 들고 다녀야 하니까 — 어느 입력창인지, 미리 보여 줄 텍스트가 뭔지.
- 어려운 쪽은 UX 야. 이건 페이지를 바꾸는 일이고, 바꾸는 일에는 신뢰가 필요해 (Track 7 Lesson 6의 패턴 전부).
v1 에 안 넣은 이유: ChromeEmbed v0.1은 읽기만 해. 읽고 얘기하는 그 고리가 사용자 대부분이 실제로 원하는 거였거든. 쓰기는 진짜 요청이 들어오면 그때 여는 v0.2 기능이야.
4. DOM Tool
피파가 입력창 너머로 페이지에 직접 손대는 데 쓰는 연장통 — 버튼 누르기, 어느 구역으로 스크롤, 문단 강조, 특정 요소만 스크린샷. 전부 Track 7에서 만든 도구를 message bus로 감싼 거야.
- Track 7 Lesson 1의 dispatcher 패턴이 딱 맞는 모양이야. 도구에 이름 붙여 등록하고, SW → content script → 도구 실행 → 결과 돌려주기로 라우팅하면 돼.
- 도구 하나하나는 content script 안의 함수야. 정해진 인자를 받아서 정해진 결과를 돌려주는.
- 그게 모이면 피파가 사용자 대신 페이지에서 일하려고 부를 수 있는 API가 돼.
v1 에 안 넣은 이유: 연장통은 끝이 없어. use case 하나 늘 때마다 도구가 하나씩 늘거든. 내보내려면 실제 use case가 뭔지부터 알아야 하는데, 읽기만 하는 v0.1이 그걸 알기에 가장 작은 쓸모 있는 덩어리였어.
이 quest가 v0.2 에 쥐여 주는 것
여덟 track을 돌아봐:
- Track 1 — MV3 manifest의 기본기.
- Track 2 — 오래 사는 bus 로서의 service worker.
- Track 3 — 감지기이자 손으로서의 content script.
- Track 4 — 계속 떠 있는 surface 로서의 side panel.
- Track 5 — popup / badge / context menu / omnibox, 표면이란 표면 전부.
- Track 6 — permission 모델과 필요한 순간에 요청하기.
- Track 7 — DOM 도구: Readability / selection / screenshot / fill-input / preview-and-confirm.
- Track 8 — packaging과 배포.
미뤄둔 기능 넷은 각자 그 블록들을 다르게 조합한 거야. Dock은 Track 4의 panel 패턴에 Track 7의 DOM 주입을 더한 것. Hybrid는 거기에 Track 5의 '어느 표면에 뭘 둘까' 사고를 얹은 것. Input-only는 Track 7의 Lesson 5와 6 에 피파 쪽 schema를 조금 붙인 것. DOM Tool은 Track 7 Lesson 1의 dispatcher 패턴을 넓힌 것.
이 quest가 가르친 건 ChromeEmbed v0.1 자체가 아니야. v0.1을 읽어 내고 v0.2를 자신 있게 그려 볼 수 있는 어휘를 쥐여 준 거지.
Quest 마무리
Track 1을 시작할 땐 Manifest V3 service worker가 뭔지도 몰랐어. 여덟 track을 지나면서 ClipDeck을 Create-Read-Update-Delete 끝까지 따라갔고, 피파 ChromeEmbed v0.1을 파일 하나하나 걸어 봤고, 뭘 내보내고 뭘 미룰지 고르는 감각을 얻었어.
여기서 할 일은 이거야. chrome://extensions를 열고, 직접 쓴 unpacked extension을 올리고, 원하던 대로 도는지 지켜봐. 그다음은 내보내는 것 — Web Store 에 unlisted 로든, 팀한테든, 아니면 그냥 자기가 매일 쓰는 Chrome 에든. 첫 번째가 제일 어려워. 그다음부터는 전부 이제 손에 쥔 패턴의 변주야.