# Dev-B Kickoff Prompt — extension-restructure (Phase 4 + Phase 6) > **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. Paste everything below the `---` line into a fresh Claude Code terminal as the first user message. --- You are **Dev-B** for the Relicario **extension-restructure** release. **Goal:** Own Phase 4 and Phase 6 in sequence. Phase 4 splits the 1027-LOC `vault.ts` monolith into five focused modules (`vault-shell.ts`, `vault-sidebar.ts`, `vault-list.ts`, `vault-drawer.ts`, `vault-form-wrapper.ts`) and lifts the `vault_locked` RPC intercept into `shared/state.ts`, building on the Phase 1 `StateHost` foundation that is already shipped. Phase 6 closes the CLI/extension parity gap by implementing the `get_vault_status` SW handler and wiring the sidebar status indicator — it depends on the `vault-sidebar.ts` module that Phase 4 produces. **Architecture:** TypeScript extension only. No Rust crates touched. All new modules live in `extension/src/vault/` (Phase 4) and `extension/src/service-worker/` (Phase 6). The `StateHost` foundation (`shared/state.ts`, typed `PopupState`, `__resetHostForTests`) was shipped in Phase 1 and is already on `main`. Do not redo it. **Tech Stack:** TypeScript, vitest + happy-dom, webpack, Rust core via WASM (no new WASM entry points needed). --- ## Step 0 — Worktree setup (do this FIRST, before anything else) ```bash git -C /home/alee/Sources/relicario worktree add /home/alee/Sources/relicario.ext-restructure-b -b feature/extension-restructure-phase-b ``` Then all subsequent work happens in `/home/alee/Sources/relicario.ext-restructure-b`. **ALL subagent prompts MUST begin with:** ``` cd /home/alee/Sources/relicario.ext-restructure-b && ``` Never rely on working-directory headers alone — subagents may commit to `main` if they do not force-cd into the worktree at prompt start. After setup, emit: ``` ## STATUS UPDATE — DEV-B Task: setup Status: COMPLETE Notes: Worktree created at /home/alee/Sources/relicario.ext-restructure-b on branch feature/extension-restructure-phase-b. Baseline test count confirmed. Next: Phase 4 Task 4.1 ``` Post this update to the relay (see Relay section below). --- ## Already-shipped context Phases 1, 2, and 5 have been merged to `main`. The following are done — do not redo: - `shared/popup-state.ts` — `View` + `PopupState` types extracted - `shared/state.ts` — typed `StateHost` with `registerHost`, `__resetHostForTests`, `sendMessage` wrapper - `shared/__tests__/state.test.ts` — 7 StateHost tests - `service-worker/storage.ts` — `loadDeviceSettings`, `saveDeviceSettings`, `loadBlacklist`, `saveBlacklist` - Phase 5 P2 fixes (inactivity-timer invert, `Promise.allSettled` in devices/trash, MutationObserver debounce, `teardownSettingsCommon`, WASM stub rounding-out) **Baseline:** 389/389 vitest tests pass on `main`. You must maintain or grow this count. Never let tests regress. --- ## Required reading Before writing any code, read: 1. `CLAUDE.md` — project rules (always applies) 2. `docs/superpowers/plans/2026-05-30-extension-restructure.md` — authoritative plan; Phase 4 and Phase 6 task details are defined there 3. `extension/ARCHITECTURE.md` — bundle structure, SW message protocol, component architecture 4. `extension/src/vault/vault.ts` — the 1027-LOC monolith you will split (read it in full before Task 4.1) 5. `extension/src/shared/state.ts` — shipped StateHost contract (Phase 4 lifts `vault_locked` into `sendMessage` here) --- ## Execution mode Use the **`superpowers:subagent-driven-development`** skill. Fresh subagent per task, two-stage review between tasks. Every subagent prompt MUST start with `cd /home/alee/Sources/relicario.ext-restructure-b &&`. --- ## Scope ### Phase 4 — Split `vault.ts` monolith (Tasks 4.1–4.7) You own all seven tasks: - **Task 4.1** — Extract `vault-shell.ts`: DOM scaffolding, color-scheme apply, `onMessage` wiring - **Task 4.2** — Extract `vault-sidebar.ts`: sidebar categories, debounced search, nav buttons, status slot wiring - **Task 4.3** — Extract `vault-list.ts`: list pane rendering and row rendering - **Task 4.4** — Extract `vault-drawer.ts` + `ensureDrawerClosedForRoute` + `drawer-state.test.ts` - **Task 4.5** — Extract `vault-form-wrapper.ts`: `renderFormWrapped`, sticky bar, header - **Task 4.6** — Trim `vault.ts` to ~200 LOC of routing + state (delete everything extracted above) - **Task 4.7** — Lift `vault_locked` RPC intercept into `shared/state.ts` `sendMessage` + write `state-vault-locked.test.ts` ### Phase 6 — CLI/extension parity: `get_vault_status` (Tasks 6.1–6.3) Phase 6 depends on `vault-sidebar.ts` from Phase 4. Do not start Phase 6 until Phase 4 is complete and all tests pass. - **Task 6.1** — Implement `get_vault_status` SW handler in `extension/src/service-worker/vault.ts` + write `vault-status.test.ts` - **Task 6.2** — Create `vault-status.ts` renderer (sidebar-footer status indicator) + write `status-indicator.test.ts` - **Task 6.3** — Wire the status indicator into `vault-sidebar.ts` sidebar footer ### Out of scope Phase 3 (Tasks 3.1–3.7) is owned by another developer. Do NOT touch `setup.ts`, `setup/__tests__/setup.test.ts`, or the SW `create_vault` / `attach_vault` handlers. If you need to coordinate on a shared file, post a question to the relay. --- ## Hard rules - **Maintain or grow the 389-test baseline.** No vitest regressions — ever. - **TDD for all new logic.** Write the failing test first, then the implementation. - **Commit after each task** (not each step — one logical commit per task, bundling its files). - **No `as any` casts.** The typed `StateHost` contract is in place; use it. - **Do not push or open a PR until both phases are complete and the final test run passes.** - **Do not merge to `main`.** The PM owns merges. --- ## Relay A message-bus server is running at `localhost:7331`. Your identity is `from="dev-b"`. **Python shim (use this to call the relay):** ```bash cd /home/alee/Sources/relicario/tools/relay && python3 call.py read_messages '{"for":"dev-b"}' cd /home/alee/Sources/relicario/tools/relay && python3 call.py post_message '{"from":"dev-b","to":"pm","kind":"status","body":"..."}' ``` Recipients: `pm`, `dev-a`, `dev-b`. **Before each task:** call `read_messages` with `{"for":"dev-b"}` to drain your inbox. **After each status update:** call `post_message` to relay your STATUS UPDATE block to `pm`. --- ## STATUS UPDATE format Use this format for every update — print it locally AND relay it to `pm`: ``` ## STATUS UPDATE — DEV-B Task: Status: COMPLETE | IN-PROGRESS | BLOCKED Notes: Next: ``` Emit IN-PROGRESS updates at meaningful moments: when a subagent is dispatched, a key architectural decision is made, a surprise is found, or a direction change occurs. Do not wait for phase boundaries. --- ## Phase 4 task details Refer to `docs/superpowers/plans/2026-05-30-extension-restructure.md` for the full step-by-step breakdown of each task. The plan is authoritative. Below is a summary of what each task produces to orient you before you read the plan: **Task 4.1 — `vault-shell.ts`** Extracts: the `initVaultShell(container)` bootstrapper, `applyColorScheme()`, `document.addEventListener('message', ...)` wiring. `vault.ts` imports `initVaultShell` and calls it at startup. **Task 4.2 — `vault-sidebar.ts`** Extracts: `renderSidebar(container, state)`, debounced search input handler, category nav button click wiring, and a `
` slot at the footer (empty until Phase 6 Task 6.3). Exports `renderSidebar` and `updateSidebarStatus(text: string)`. **Task 4.3 — `vault-list.ts`** Extracts: `renderList(container, entries, state)` and `renderRow(entry, state)`. The list pane is a pure render function — no side effects beyond DOM mutation. **Task 4.4 — `vault-drawer.ts` + drawer tests** Extracts: `openDrawer(view)`, `closeDrawer()`, `renderDrawerContent(view, state)`, and `ensureDrawerClosedForRoute(route)` (closes the drawer automatically when navigating to list/unlock). Creates `extension/src/vault/__tests__/drawer-state.test.ts` covering the auto-close behavior. **Task 4.5 — `vault-form-wrapper.ts`** Extracts: `renderFormWrapped(container, title, renderBody)` — the sticky-header + save-bar scaffold used by add/edit/detail views. **Task 4.6 — Trim `vault.ts` to ~200 LOC** After extracting all the above, `vault.ts` should contain only: route dispatch (`handleRoute`), top-level state management (`initVault`, `setState`), and import wiring. Delete the extracted code. Run the full test suite to confirm nothing broke. **Task 4.7 — Lift `vault_locked` intercept into `shared/state.ts`** The pre-Phase-4 `vault.ts` has a `vault_locked` channel intercept inside its local `sendMessage` wrapper. Lift this into the `sendMessage` export in `shared/state.ts` (Phase 1 left a placeholder comment there). Write `extension/src/shared/__tests__/state-vault-locked.test.ts` that: - registers a mock host - dispatches a `sendMessage` that returns `{ ok: false, error: 'vault_locked' }` - asserts that `navigate('unlock')` was called on the host - asserts the original rejection is re-thrown (or rethrown as appropriate per the existing intercept logic) --- ## Phase 6 task details Do not start Phase 6 until Phase 4 is fully committed and all 389+ tests pass. **Task 6.1 — `get_vault_status` SW handler** Add a `get_vault_status` case to `extension/src/service-worker/vault.ts`. The handler returns: ```typescript { ok: true, data: { unlocked: boolean, // whether a session is active vault_dir: string | null, // from cached state.vaultDir git_host: string | null, // from cached state.gitHost item_count: number, // manifest entry count or 0 } } ``` Add `get_vault_status` to `extension/src/shared/messages.ts` as a new `Request` variant. Write `extension/src/service-worker/__tests__/vault-status.test.ts` covering: unlocked path, locked path, and missing-vault path. **Task 6.2 — `vault-status.ts` renderer** Create `extension/src/vault/vault-status.ts` with: ```typescript export function renderVaultStatus(container: HTMLElement, status: VaultStatusData): void; ``` The renderer fills `container` with a one-line status indicator: a colored dot + short text (`Unlocked · 42 items` or `Locked` or `No vault`). Write `extension/src/vault/__tests__/status-indicator.test.ts` covering all three states with happy-dom. **Task 6.3 — Wire indicator into `vault-sidebar.ts`** At sidebar boot, call `sendMessage({ type: 'get_vault_status' })` and pass the result to `renderVaultStatus(statusSlot, data)`. Re-fetch on every `setState` call so the count stays current. The status slot element (`
`) was created in Task 4.2. --- ## Final verification Before opening a PR, run: ```bash cd /home/alee/Sources/relicario.ext-restructure-b && pnpm --filter extension test && pnpm --filter extension build ``` All tests must pass. Build must be clean. Post your final STATUS UPDATE to `pm` with Status: COMPLETE. --- ## Opening the PR Once both phases are complete and the final run passes: ```bash gh pr create --base main --title "feat(extension): restructure Phase 4 (Tasks 4.1-4.7): extract vault-shell.ts; extract vault-sidebar.ts with debounced search; extract vault-list.ts; extract vault-drawer.ts + ensureDrawerClosedForRoute + drawer-state tests; extract vault-form-wrapper.ts; trim vault.ts to ~200 LOC routing+state; lift vault_locked intercept into shared/state.ts + state-vault-locked tests+Phase 6 (Tasks 6.1-6.3): implement get_vault_status SW handler + vault-status.test.ts; create vault-status.ts renderer + status-indicator tests; wire indicator into vault-sidebar.ts sidebar footer — Dev-B" ``` Return the PR URL in your final STATUS UPDATE. --- ## First action 1. Run the worktree setup command above. 2. Confirm the baseline: `cd /home/alee/Sources/relicario.ext-restructure-b && pnpm --filter extension test 2>&1 | tail -5` 3. Emit STATUS UPDATE "setup complete" locally and relay it to `pm`. 4. Begin Phase 4 Task 4.1 by reading `extension/src/vault/vault.ts` in full, then dispatching a subagent.