"ChromeEmbed v0.1 이 manifest 28 줄과 script file 넷. Lesson 1 이 manifest — 모든 field 정당화, 모든 선택이 이전 track 중 하나로 묶임."
28 줄
실제 ChromeEmbed manifest, end to end:
{
"manifest_version": 3,
"name": "Pippa ChromeEmbed",
"version": "0.1.0",
"description": "The household, present on the current page.",
"permissions": ["sidePanel", "activeTab", "storage", "tabs", "scripting"],
"host_permissions": [
"<all_urls>",
"http://localhost:5173/*",
"http://127.0.0.1:5173/*",
"http://100.x.x.x:5173/*"
],
"background": { "service_worker": "background.js" },
"side_panel": { "default_path": "sidepanel.html" },
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content-script.js"],
"run_at": "document_idle",
"all_frames": true
}],
"action": { "default_popup": "popup.html" },
"content_security_policy": {
"extension_pages": "script-src 'self'; object-src 'self'; frame-src http://localhost:5173 http://127.0.0.1:5173 http://100.x.x.x:5173;"
}
}
Permission — 각자 이유
sidePanel— chrome.sidePanel.* (Track 4) 위해 필수.activeTab— user-gesture-trigger 된 scripting 호출 cover, SW 가 standing host access 없이 현재 page 의 selection read (Track 6 Lesson 4).storage— future 사용 위해 선언; v0.1 이 SW 의 in-memory Map 에 의존. 유지 저렴.tabs— background.js 가 activeTab query 결과에서tab.url,tab.title,tab.favIconUrlread 해서 필요 (moderate 'browsing history' install 경고).scripting— background.js 가 content script 가 report 안 했을 때 selection read fallback 으로chrome.scripting.executeScript호출해서 필요 (all-frames 경로).
Host Permission — Localhost set
두 layer 가 double duty:
host_permissions의<all_urls>ANDcontent_scripts.matches— ChromeEmbed 가 특정 origin 만 아닌 user 방문하는 어떤 page 든 context 제공 원해서 필요.- Localhost 와 127.0.0.1 — development 위해. cwkPippa dev server 가 localhost:5173 에서 돔; side panel iframe 이 거기서 load.
- 100.x.x.x (Tailscale CGNAT host — 자기 private VPN IP 로 교체) — 같은 private network 의 다른 device 가 dev server 닿게 해 줘. ChromeEmbed 가 household 의 모든 Mac 에서 돔; 어느 시점에 cwkPippa host 하는 Mac 이든 그것의 Tailscale IP 로 닿음.
이 localhost / Tailscale URL 이 두 자리에 나타나는 거 주목: manifest 의 host_permissions 배열 (network access 위해) AND extension_pages CSP 의 frame-src directive (iframe specifically 위해). 어느 쪽에서든 제거하면 panel 깨짐; Track 4 Lesson 5 가 CSP detail walk.
all_frames 선택
Content script 가 all_frames: true 로 선언. ChromeEmbed 가 user 가 iframe 안에서 (embedded YouTube 댓글, Notion embed) 뭔가 highlight 할 때도 selection 과 viewport 텍스트 capture 원함. Default all_frames: false 는 그것들 놓침. Trade-off: 모든 iframe 이 content script load, 메모리 비용; Pippa-grade household extension 엔 받아들일 만.
action.default_popup 선택
Popup 존재 (popup.html 선언) 하지만 6-줄 doorway (Lesson 4). action.default_popup: "popup.html" 패턴이 popup 자체 chrome.sidePanel.open() + window.close() 와 함께 의미: toolbar icon click → popup 잠깐 flash → side panel 열림 → popup 닫힘. User 가 한 fluid 'click 이 panel 엶' 동작 봄.
각 결정 만든 Track
- Track 1 — manifest_version 3, name, version, 기본.
- Track 2 — service_worker 선언.
- Track 3 — all_frames 가진 content_scripts.
- Track 4 — sidePanel permission + side_panel.default_path + extension_pages CSP frame-src.
- Track 5 — action.default_popup.
- Track 6 — narrow permission set (downloads 없음, notifications 없음); storage permission 이 overhead 지만 v0.2 위해 예약.
이 중 novel 한 거 없음; 첫 여덟 track 이 one working file 로 composing 된 것.