From 7c7efa7c43dfa281f1a7781e63501e6608c05f79 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Sun, 31 May 2026 22:50:17 -0400 Subject: [PATCH] =?UTF-8?q?release:=20v0.7.0=20=E2=80=94=20extension=20res?= =?UTF-8?q?tructure=20complete=20(Plan=20C=20Phases=203/4/6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completes the extension restructure begun in v0.6.0. Phases 3 (setup wizard SW migration + step registry), 4 (vault.ts split + vault_locked lift), and 6 (get_vault_status + sidebar status indicator) all merged to main (9df2fee, 3b8368d, 397cc78) via three parallel worktree streams. This commit is the release-prep wrap-up: - Version bump to v0.7.0 across the three relicario crates + Cargo.lock, extension/package.json, and both extension manifests (the manifests had lagged at 0.5.0 — corrected here). - CHANGELOG.md v0.7.0 entry. - STATUS.md: extension restructure moved to shipped; Phases 3/4/6 landing section added. - ROADMAP.md: v0.7.0 row added; Up-next now command palette. - extension/ARCHITECTURE.md: all three phases integrated (new vault-* modules, setup-steps.ts, get_vault_status protocol + status indicator, vault_locked lift, git-host sync cache). - Plan completion checkboxes ticked. Task 7.1 verification: done-criteria sweep all green; 423/423 vitest; build:all clean (only the pre-existing 4MB WASM size warning). Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 64 ++++++++++ Cargo.lock | 6 +- ROADMAP.md | 9 +- STATUS.md | 26 ++-- crates/relicario-cli/Cargo.toml | 2 +- crates/relicario-core/Cargo.toml | 2 +- crates/relicario-wasm/Cargo.toml | 2 +- .../plans/2026-05-30-extension-restructure.md | 14 +-- extension/ARCHITECTURE.md | 116 ++++++++++++++---- extension/manifest.firefox.json | 2 +- extension/manifest.json | 2 +- extension/package.json | 2 +- 12 files changed, 195 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a78f9d..7e87c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,69 @@ # Changelog +## v0.7.0 — 2026-06-01 + +Completes the extension restructure (Plan C) begun under v0.6.0. Phases +1/2/5 (StateHost typing, SW storage extract, the P2 cluster) shipped +2026-05-30; this tag adds the remaining three phases — executed as three +parallel worktree streams under PM coordination — which eliminate the +two steepest learning cliffs in the extension and close the last +`relicario status` CLI/extension parity gap. No crypto, wire-format, or +Rust-API changes; this is an internal-architecture + one-feature release. + +### Added + +- **`relicario status` parity in the extension.** New `get_vault_status` + service-worker message returns a cached sync summary + `{ ahead, behind, lastSyncAt, pendingItems }` with no network call — + `ahead`/`behind`/`lastSyncAt` read straight off the cached git-host + state (populated by the `sync` handler), `pendingItems` a live count of + active (non-trashed) manifest entries. A sidebar-footer status indicator + (`vault-status.ts` → `renderStatusIndicator`) renders `N pending` / + `N ahead` / `N behind` / `in sync` plus a `last sync …` / `never synced` + line, refreshed on mount and on a manual `↻` button — no timer polling, + matching the no-network-without-user-intent discipline. + +### Changed + +- **Setup wizard crypto moved into the service worker.** The wizard no + longer imports `relicario-wasm` or orchestrates the master key directly. + New `create_vault` / `attach_vault` SW handlers own the full flow + (image-secret embed/extract, unlock, manifest+settings encrypt + push, + `register_device` + `addDevice`, persist config + reference image, + `session.setCurrent`); on failure the SessionHandle is locked then freed, + with ownership transferring only on success. `setup.ts` collapses from + ~1230 LOC to a 58-LOC UI-only shell; the six render/attach step pairs + become a `SetupStep` registry in the new `setup/setup-steps.ts`. Adds + `clearWizardState` (bound to `beforeunload` and `goto('mode')`) to wipe + sensitive Uint8Array fields when the wizard is abandoned. The + non-extension copy-vault-config-JSON escape hatch is preserved. +- **`vault.ts` split from a 1037-LOC monolith to 194 LOC of routing + + state.** Extracted into five focused modules — `vault-shell` (DOM + scaffolding, color-scheme, onMessage wiring), `vault-sidebar` (category + nav, 80ms debounced search, bottom nav, status-indicator footer), + `vault-list` (list + row rendering), `vault-drawer` (open/close/render + + `ensureDrawerClosedForRoute`), `vault-form-wrapper` (wrapped form + sticky + bar) — plus two support modules for an acyclic split (`vault-context`, + the VaultController contract; `vault-router`, hash routing + pane + dispatch). +- **`vault_locked` RPC intercept unified.** Lifted out of `vault.ts` into + the `sendMessage` wrapper in `shared/state.ts`, so both popup and + vault-tab surfaces share one lock-redirect path. +- **`state.gitHost` now nulled on explicit lock**, symmetric with the + session-timer expiry path, so the new status indicator can't surface a + stale `lastSyncAt` after a lock → re-unlock within one service-worker + lifetime. + +### Internal + +- Three-stream parallel execution (Dev-A Phase 3, Dev-B Phase 4, Dev-C + Phase 6) coordinated via the relay message bus; merges sequenced + Phase 3 → 4 → 6 with per-phase done-criteria verification. +- Final merged-tree validation: **423/423** vitest (62 files); + `npm run build:all` clean for both Chrome and Firefox targets (only the + pre-existing ~4 MB WASM asset-size warning). Task 7.1 done-criteria + sweep all green. No change to `wasm.d.ts`. + ## v0.6.0 — 2026-05-30 Rolls up four weeks of post-v0.5.0 work into one tag: the Phase 2B diff --git a/Cargo.lock b/Cargo.lock index 7fd0362..1bda3a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2156,7 +2156,7 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "relicario-cli" -version = "0.6.0" +version = "0.7.0" dependencies = [ "anyhow", "arboard", @@ -2185,7 +2185,7 @@ dependencies = [ [[package]] name = "relicario-core" -version = "0.6.0" +version = "0.7.0" dependencies = [ "argon2", "base64", @@ -2231,7 +2231,7 @@ dependencies = [ [[package]] name = "relicario-wasm" -version = "0.6.0" +version = "0.7.0" dependencies = [ "base64", "ed25519-dalek", diff --git a/ROADMAP.md b/ROADMAP.md index 62e7f7b..7eb8ecf 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7,6 +7,7 @@ | Version | Highlights | |---|---| +| v0.7.0 *(2026-06-01)* | Extension restructure (Plan C) complete — Phases 3/4/6 merged via 3 parallel worktree streams under PM coordination: setup wizard crypto migrated into the SW (`create_vault`/`attach_vault`; `setup.ts` 1230→58 LOC + step registry); `vault.ts` split 1037→194 LOC into 5 focused + 2 support modules; `vault_locked` intercept lifted into `shared/state.ts`; `get_vault_status` SW message + sidebar status indicator closing the last `relicario status` CLI/extension parity gap | | v0.6.0 *(2026-05-30)* | Security audit fixes; device authentication; backup/restore + LastPass import; fullscreen UX Phases 1+2A+2B; v0.5.1 Streams A/B/C (3-column vault layout + bottom-sheet picker + toast system; left-nav settings; Recovery QR end-to-end + setup wizard Style C); 1C-γ (attachments + Document type + device registration + trash + field history); Plan B multi-stream refactor (commands/ split, prompt_or_flag, core/WASM seam); vault-tab management surfaces revamp (settings synced/local split, devices fingerprint, trash purge countdown, field-history polish, item-history-index, `#history/` routing); doc-structure redesign (rename to DESIGN/CRYPTO/docs/FORMATS, scope headers + Next: footers); GPL-3.0-or-later license | | v0.2.0 | Typed-item rewrite (Plans 1A/1B/1C-α/β₁/β₂) | @@ -14,15 +15,13 @@ See `CHANGELOG.md` for tagged-release detail and `STATUS.md` for the per-train c ## Up next -Per the 2026-05-30 post-v0.6.0 audit: of the three 2026-05-04 architecture-review specs, two are already shipped (CLI restructure = Plan B Cycles 1+2; security polish = Stream A Cycle 1). Only the third is genuinely outstanding: +All three 2026-05-04 architecture-review specs are now shipped (CLI restructure = Plan B Cycles 1+2; security polish = Stream A Cycle 1; extension restructure = Plan C Phases 1–6, completed v0.7.0 2026-06-01). The next committed item is: -- **Extension restructure** — half-shipped 2026-05-30. Phases 1 (StateHost typing) + 2 (SW storage extract) + 5 (P2 cluster) merged via 3 parallel worktrees. Remaining: Phase 3 (setup wizard SW migration, L), Phase 4 (vault.ts split, M), Phase 6 (vault status indicator, S-M). - Spec: `docs/superpowers/specs/2026-05-04-extension-restructure-design.md` - Plan: `docs/superpowers/plans/2026-05-30-extension-restructure.md` +- **Phase 4: command palette** — ⌘K global search + action dispatch across the vault tab (no spec yet) ## Medium-term -- **Phase 4: command palette** — ⌘K global search + action dispatch across the vault tab (no spec yet) +_(promote here once specced)_ ## Long-term / backlog diff --git a/STATUS.md b/STATUS.md index 4246b7d..2eb83ab 100644 --- a/STATUS.md +++ b/STATUS.md @@ -5,7 +5,7 @@ ## Version **Last release tagged:** v0.6.0 — rolled up Phase 2B, v0.5.1 Streams A/B/C, 1C-γ, Plan B refactor (Cycles 1+2), management-surfaces revamp, and the doc-structure redesign into one tag. -**Active track:** extension restructure execution — Plan C Phases 1, 2, 5 merged 2026-05-30 (three parallel worktree streams). Phases 3, 4, 6 remain. +**Active track:** **extension restructure (Plan C) — COMPLETE.** All six phases merged. Phases 1, 2, 5 merged 2026-05-30; Phases 3, 4, 6 merged 2026-05-31/06-01 via three parallel worktree streams (Dev-A/B/C under PM coordination). Versions bumped to v0.7.0; tag pending. ## What landed on main since the v0.5.0 version bump @@ -98,6 +98,19 @@ Plan: `docs/superpowers/plans/2026-05-24-vault-tab-management-surfaces-revamp.md - Item-history-index pane — top-level "items with history" list (`32e1632`) - Sidebar slot wiring + `#history/` route with `#field-history/` legacy normalization (`88d7228`) +### Extension restructure — Plan C Phases 3, 4, 6 (merged 2026-05-31 → 06-01, v0.7.0) + +Spec: `docs/superpowers/specs/2026-05-04-extension-restructure-design.md` +Plan: `docs/superpowers/plans/2026-05-30-extension-restructure.md` + +Three parallel worktree streams under PM coordination (relay-bus), completing the restructure begun with Phases 1/2/5: + +- **Phase 3 — setup wizard SW migration + step registry** (Dev-A, merge `9df2fee`). `create_vault` / `attach_vault` SW handlers own the full vault-creation/attach flow (embed/unlock, encrypt+push, register_device+addDevice, persist config+image, `session.setCurrent`; failure path locks+frees the handle). `setup.ts` collapses 1230→58 LOC (UI-only shell, no `relicario-wasm` import); step registry + state + `clearWizardState` + `finishSetup` extracted to new `setup/setup-steps.ts`. `clearWizardState` bound to `beforeunload` + `goto('mode')`. Copy-vault-JSON escape hatch preserved. +- **Phase 4 — vault.ts split + vault_locked lift** (Dev-B, merge `3b8368d`). `vault.ts` 1037→194 LOC. Five named modules (`vault-shell`, `vault-sidebar`, `vault-list`, `vault-drawer`, `vault-form-wrapper`) plus two support modules (`vault-context` — the VaultController contract; `vault-router` — hash routing + pane dispatch, to hold vault.ts ≤250). `vault_locked` RPC intercept lifted into `shared/state.ts`'s `sendMessage` wrapper. 80ms debounced sidebar search (`SEARCH_DEBOUNCE_MS`); `ensureDrawerClosedForRoute`; `#vault-status-slot` footer staged for Phase 6. +- **Phase 6 — get_vault_status + sidebar status indicator** (Dev-C, merge `397cc78`). `get_vault_status` SW handler returns cached `{ahead, behind, lastSyncAt, pendingItems}` with no network call; `vault-status.ts` renders the sidebar-footer indicator (`renderStatusIndicator` into `#vault-status-slot`, refreshed on mount + manual `↻` button, no timer polling). Closes the last `relicario status` CLI/extension parity gap. Also nulls `state.gitHost` on the explicit `lock` handler (symmetric with session-expiry) so the indicator can't show a stale `lastSyncAt`. + +Final merged-tree validation: **423/423 vitest** (62 files), `build:all` clean (only the pre-existing 4MB WASM size warning). Task 7.1 done-criteria sweep: all green. + ### Doc-structure redesign (2026-05-30, complete) Spec: `docs/superpowers/specs/2026-05-30-doc-structure-redesign-design.md` @@ -128,15 +141,8 @@ Per the 2026-05-30 post-v0.6.0 audit of the three 2026-05-04 architecture-review - **CLI restructure** (`2026-05-04-cli-restructure-design.md`) — *already shipped* as Plan B Cycles 1+2 (`b9bd152`, `3dd1e1b`, `3759f6a`, `e69b347`); the last gap (read-side `refresh_groups_cache` callers in list/get) closed in `d717f0d`. Done-criteria all met. - **Security polish** (`2026-05-04-security-polish-design.md`) — *already shipped* as Stream A Cycle 1 (`89090a8`) plus follow-ups (`0c9387f` start.sh fourth window, `229e483` recovery_qr.rs docs). All four phases done. -- **Extension restructure** (`2026-05-04-extension-restructure-design.md`, plan `docs/superpowers/plans/2026-05-30-extension-restructure.md`) — half-shipped: - - ✅ **Phase 1 (StateHost typing)** — merged `c3f8e35` (4 commits, 378/378 tests). View+PopupState moved to `shared/popup-state.ts`; `StateHost` interface fully typed; `__resetHostForTests` exported; double-registration guard. PopupState widened to absorb VaultState's vault-tab-only fields. - - ✅ **Phase 2 (SW storage extract)** — merged `b6707f4` (1 commit, 376/376 tests). `loadDeviceSettings` / `saveDeviceSettings` / `loadBlacklist` / `saveBlacklist` consolidated in `service-worker/storage.ts`; `itemToManifestEntry` moved to `service-worker/vault.ts`. Router files shrank ~70 LOC combined. - - ✅ **Phase 5 (P2 cluster)** — merged `0496dfe` (5 commits, 377/377 tests). Inactivity timer rule inverted (READ_ONLY_CONTENT_CALLABLE exclusion set); `state.gitHost` cleared on session expiry; `teardownSettingsCommon` extracted; `Promise.allSettled` in devices (trash.ts was a no-op — single-message load path on current main); MutationObserver `scan()` debounced 200ms. - - ⏳ **Phase 3 (Setup wizard SW migration + step registry)** — Effort: L. Depends on Phase 1 ✅. Biggest single phase. Adds `create_vault` / `attach_vault` SW handlers; setup.ts drops direct WASM imports + collapses six renderStepN/attachStepN pairs into a step registry + adds `clearWizardState`. - - ⏳ **Phase 4 (vault.ts split + vault_locked channel lift)** — Effort: M. Depends on Phase 1 ✅. Splits 1037-LOC vault.ts into 5 modules (vault-shell, vault-sidebar, vault-list, vault-drawer, vault-form-wrapper); lifts the vault_locked RPC intercept into shared/state.ts's sendMessage wrapper. - - ⏳ **Phase 6 (get_vault_status + sidebar status indicator)** — Effort: S-M. Depends on Phase 4. Closes the `relicario status` CLI/extension parity gap. - - Combined test count at end of three-stream merge: **389/389** vitest passing (baseline 371 + 18 new across the three phases). +- **Extension restructure** (`2026-05-04-extension-restructure-design.md`, plan `docs/superpowers/plans/2026-05-30-extension-restructure.md`) — ✅ **COMPLETE** (all six phases merged; see the dated landing section above). Phases 1/2/5 merged 2026-05-30; Phases 3/4/6 merged 2026-05-31 → 06-01. Final tree: 423/423 vitest, build:all clean. v0.7.0 versions bumped; tag pending. Beyond extension restructure, ROADMAP medium-term holds Phase 4 command palette (no spec yet). Long-term: relay server, mobile. -See `ROADMAP.md` for the longer arc and `CHANGELOG.md` for tagged-release history (current head: `v0.5.0` entry, dated 2026-05-02 — predates the v0.5.1 train work and will be revised when the next tag cuts). +See `ROADMAP.md` for the longer arc and `CHANGELOG.md` for tagged-release history (current head: `v0.6.0`; the `v0.7.0` entry covers this extension-restructure completion). diff --git a/crates/relicario-cli/Cargo.toml b/crates/relicario-cli/Cargo.toml index 7dfcd82..a5a853f 100644 --- a/crates/relicario-cli/Cargo.toml +++ b/crates/relicario-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "relicario-cli" -version = "0.6.0" +version = "0.7.0" edition = "2021" description = "CLI for relicario password manager" license = "GPL-3.0-or-later" diff --git a/crates/relicario-core/Cargo.toml b/crates/relicario-core/Cargo.toml index 273dd34..e4acec6 100644 --- a/crates/relicario-core/Cargo.toml +++ b/crates/relicario-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "relicario-core" -version = "0.6.0" +version = "0.7.0" edition = "2021" description = "Core library for relicario password manager" license = "GPL-3.0-or-later" diff --git a/crates/relicario-wasm/Cargo.toml b/crates/relicario-wasm/Cargo.toml index 6fa49ef..d8151de 100644 --- a/crates/relicario-wasm/Cargo.toml +++ b/crates/relicario-wasm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "relicario-wasm" -version = "0.6.0" +version = "0.7.0" edition = "2021" description = "WASM bindings for relicario password manager" license = "GPL-3.0-or-later" diff --git a/docs/superpowers/plans/2026-05-30-extension-restructure.md b/docs/superpowers/plans/2026-05-30-extension-restructure.md index 29a76db..6e78e2b 100644 --- a/docs/superpowers/plans/2026-05-30-extension-restructure.md +++ b/docs/superpowers/plans/2026-05-30-extension-restructure.md @@ -2627,13 +2627,13 @@ git push origin main ## Completion Checklist -- [ ] Phase 1: `StateHost` typed end-to-end (Tasks 1.1-1.5) -- [ ] Phase 2: SW helpers consolidated in `storage.ts` + `vault.ts` (Tasks 2.1-2.3) -- [ ] Phase 3: Setup wizard SW-orchestrated + step registry + `clearWizardState` (Tasks 3.1-3.7) -- [ ] Phase 4: `vault.ts` split into 5 modules + `vault_locked` channel unified (Tasks 4.1-4.7) -- [ ] Phase 5: Five P2 fixes (Tasks 5.1-5.5) -- [ ] Phase 6: `get_vault_status` + sidebar status indicator (Tasks 6.1-6.3) -- [ ] Task 7.1: Final verification + STATUS/ROADMAP update +- [x] Phase 1: `StateHost` typed end-to-end (Tasks 1.1-1.5) — merged 2026-05-30 +- [x] Phase 2: SW helpers consolidated in `storage.ts` + `vault.ts` (Tasks 2.1-2.3) — merged 2026-05-30 +- [x] Phase 3: Setup wizard SW-orchestrated + step registry + `clearWizardState` (Tasks 3.1-3.7) — merged `9df2fee` 2026-05-31 +- [x] Phase 4: `vault.ts` split into 5 modules + `vault_locked` channel unified (Tasks 4.1-4.7) — merged `3b8368d` 2026-06-01 +- [x] Phase 5: Five P2 fixes (Tasks 5.1-5.5) — merged 2026-05-30 +- [x] Phase 6: `get_vault_status` + sidebar status indicator (Tasks 6.1-6.3) — merged `397cc78` 2026-06-01 +- [x] Task 7.1: Final verification + STATUS/ROADMAP update — done-criteria sweep all green; 423/423 vitest; build:all clean; STATUS/ROADMAP/CHANGELOG/ARCHITECTURE updated; versions bumped to v0.7.0 --- diff --git a/extension/ARCHITECTURE.md b/extension/ARCHITECTURE.md index 152e354..7a1b293 100644 --- a/extension/ARCHITECTURE.md +++ b/extension/ARCHITECTURE.md @@ -37,7 +37,7 @@ Firefox build (the vault tab is Chrome-only for the moment). Verify in | `service-worker` | `src/service-worker/index.ts` | extension SW / bg | yes — initialized lazily on first message | | `popup` | `src/popup/popup.ts` | popup.html | no — goes through SW | | `vault` | `src/vault/vault.ts` (Chrome only) | vault.html (tab) | no — goes through SW | -| `setup` | `src/setup/setup.ts` | setup.html (tab) | yes — direct dynamic import (predates SW handle) | +| `setup` | `src/setup/setup.ts` | setup.html (tab) | no — goes through SW (`create_vault`/`attach_vault`) | | `content` | `src/content/detector.ts` | host page (top frame only by router check) | no | ### What each bundle owns @@ -183,17 +183,51 @@ before any new render. ### `src/vault/` -- `vault.ts` — fullscreen tab entry. Hash-based router (`#detail/`, - `#add/`, `#trash`, `#devices`, `#settings`, `#settings-vault`, - `#history`, `#history/`, `#backup`, `#import`). Legacy - `#field-history/` URLs are normalized to `#history/` on - `parseHash` (`vault.ts:139-173`); the internal view value stays - `'field-history'` so the per-item pane renders unchanged. Sidebar - bottom-nav: `+ new item · ▦ trash · ⌬ devices · ⚙ settings · ◷ history - · ⏻ lock`. Registers itself as the StateHost so all - `popup/components/*` renderers run unchanged. Maintains its own - `selectedItem` cache so hash navigation between already-loaded items - doesn't refetch. +- `vault.ts` (194 lines) — fullscreen tab entry, now a thin + routing + state shell after the Phase 4 split. Registers itself as + the StateHost so all `popup/components/*` renderers run unchanged, + maintains its own `selectedItem` cache so hash navigation between + already-loaded items doesn't refetch, and delegates DOM scaffolding, + navigation, list/drawer/form rendering, and route dispatch to the + sibling modules below. The hash-route set is + `#detail/`, `#add/`, `#trash`, `#devices`, `#settings`, + `#settings-vault`, `#history`, `#history/`, `#backup`, `#import`. +- `vault-context.ts` — the `VaultController` contract plus the shared + types and pure helpers the split modules depend on. Added so the + split is acyclic: the rendering modules import the controller + interface from here rather than from `vault.ts`. +- `vault-router.ts` — hash routing + pane dispatch + data loading, + extracted to keep `vault.ts` ≤250 LOC. Owns `parseHash`; legacy + `#field-history/` URLs are normalized to `#history/` here, but + the internal view value stays `'field-history'` so the per-item pane + renders unchanged. +- `vault-shell.ts` — DOM scaffolding, color-scheme apply, and the + `onMessage` wiring for the tab. +- `vault-sidebar.ts` — sidebar categories nav, 80ms-debounced search + (`SEARCH_DEBOUNCE_MS`), and the bottom-nav + (`+ new item · ▦ trash · ⌬ devices · ⚙ settings · ◷ history · ⏻ lock`). + Also owns the footer: a `#vault-status-slot` plus a manual `↻` refresh + button (`GLYPH_REFRESH`). `wireSidebar` calls `refreshStatus()` once on + mount and again on the button's click — sending `get_vault_status` via + `ctx.sendMessage` and rendering the result into the slot through + `vault-status.ts`. There is **no timer polling**: the indicator only + refreshes on mount + explicit button press, matching the spec's + no-network-without-user-intent discipline (sync is user-initiated). +- `vault-status.ts` — sidebar-footer sync indicator renderer. + `renderStatusIndicator(el, status)` is pure DOM: it renders, by + priority, `N pending` / `N ahead` / `N behind`, falling back to + `in sync`, plus a `last sync ` / `never synced` line. + Reuses `shared/glyphs.ts` (`GLYPH_PENDING`/`AHEAD`/`BEHIND`/`SYNCED`) + and `shared/relative-time.ts`. `VaultStatus` is an alias of + `GetVaultStatusResponse['data']`, so the renderer's input shape is + single-sourced from the message contract and can't drift from the SW + handler. +- `vault-list.ts` — the list pane and its row rendering. +- `vault-drawer.ts` — drawer open/close/render plus + `ensureDrawerClosedForRoute`, which closes the drawer on any + non-list navigation. +- `vault-form-wrapper.ts` — `renderFormWrapped` plus the sticky bar and + header that wrap form panes. - `vault.html` / `vault.css` — sidebar + pane layout. ### `src/vault/components/` @@ -211,12 +245,19 @@ exports `render…(app)` and a `teardown()`, same convention as ### `src/setup/` -- `setup.ts` (1137 lines) — the wizard state machine. Six steps - (0..5): mode picker (new vault / attach this device), host type - (Gitea/GitHub), host config + connection test + repo probe, the - forking step 3 (create-vault vs attach-this-device), device name, - finish. Loads WASM directly. State-coupled `updateStrengthUi` stays - here because it walks the live wizard state. +- `setup.ts` (58 lines) — a thin UI-only shell after the Phase 3 + split: the render loop + progress track + boot + re-exports. No longer + imports `relicario-wasm`; the wizard now drives vault creation/attach + through the SW. Binds `clearWizardState` to + `window.addEventListener('beforeunload', clearWizardState)` + (`setup.ts:53`) and also calls it on `goto('mode')` (`setup.ts:44`). +- `setup-steps.ts` (extracted in Phase 3) — the setup step registry + + wizard state + `clearWizardState` + `finishSetup`. One-directional + import (`setup.ts` → `setup-steps.ts`, no cycle). Crypto orchestration + no longer lives in the wizard: the device step (where `deviceName` + exists) fires `create_vault` and `attach_vault` SW messages instead of + calling WASM directly. State-coupled `updateStrengthUi` stays here + because it walks the live wizard state. - `setup-helpers.ts` (84 lines, extracted in commit `f79a67b`) — pure helpers: `escapeHtml`, `ratePassphrase`, `scheduleRate` (150ms debounced zxcvbn round-trip), `STRENGTH_LABELS`, `entropyText`, the @@ -273,7 +314,23 @@ exports `render…(app)` and a `teardown()`, same convention as `session.getCurrent()`, load via `vault.fetchAndDecrypt*`, mutate, re-encrypt, and `gitHost.writeFile`. `fill_credentials` lives here with its own captured-tab verification (see Key flows). New in - commit `a7dbf35`: `register_this_device`. + commit `a7dbf35`: `register_this_device`. Phase 3 added + `create_vault` and `attach_vault` (full SW-side vault + creation/attach: embed/unlock, encrypt+push, `register_device` + + `addDevice`, persist config+image, `session.setCurrent`; the failure + path locks and frees the handle). The `lock` handler now also nulls + `state.gitHost` (symmetric with session-expiry) so the status cache + can't go stale across a lock→unlock. Phase 6 added `get_vault_status` + (popup-only, read-only) — returns the cached sync summary + `{ ahead, behind, lastSyncAt, pendingItems }` with **no network + call**. `ahead`/`behind`/`lastSyncAt` are read straight off + `state.gitHost` (populated by the `sync` handler, which records + `lastSyncAt = Math.floor(Date.now()/1000)` — unix **seconds** — after + a successful manifest fetch). `pendingItems` is a live count of active + (non-trashed) manifest entries via `vault.listItems(manifest).length`. + `ahead`/`behind` are structurally always `0` in the extension (it + writes straight to the host via the Contents REST API; there is no + local commit graph) and exist for parity with `relicario status`. - `router/content-callable.ts` — handler match arms for every `CONTENT_CALLABLE_TYPES` message. Origin always derived from `sender.tab.url`, never from message fields. `capture_save_login` @@ -287,7 +344,13 @@ exports `render…(app)` and a `teardown()`, same convention as no www-stripping, no public-suffix), trash helpers (`listTrashed`, `restoreItem`, `purgeItem`, `purgeAllTrash`), and attachment helpers (`addAttachmentToItem`, `removeAttachmentsFromItem`, - with manifest summary sync). + with manifest summary sync). Now also includes the + `create_vault`/`attach_vault` orchestration handlers (Phase 3) and + `handleGetVaultStatus(state)` (Phase 6) — synchronous, no network; + returns the cached `{ ahead, behind, lastSyncAt, pendingItems }`. Its + `Pick`-typed param both breaks + the `PopupState` import cycle and structurally forbids it from making + a network call. - `session.ts` — single module-scope `SessionHandle | null`. α assumes one vault per install. Multi-vault would replace this with a `Map` keyed by vault id. @@ -301,6 +364,15 @@ exports `render…(app)` and a `teardown()`, same convention as `putBlob`, `getBlob`, `deleteBlob`) and the `createGitHost` factory. `BLOB_THRESHOLD_BYTES = 900*1024` is the cutover point at which attachment writes switch from the Contents API to the Git Data API. + The `GitHost` interface also carries cached sync metadata — + `lastSyncAt: number | null` (unix seconds), `ahead: number`, + `behind: number` — initialized to `null`/`0`/`0` in both `GiteaHost` + and `GitHubHost`. The cache rides the gitHost lifecycle: created on + unlock and cleared whenever `state.gitHost` is nulled — on + session-timer expiry (`index.ts`) **and** on the explicit `lock` + message handler (`popup-only.ts`), which now nulls `state.gitHost` + symmetrically so a lock→unlock cycle can't surface a stale + `lastSyncAt`. - `gitea.ts` / `github.ts` — the two GitHost implementations. Both use the host's Contents API for files under threshold, and Git Data API (blobs + tree + commit) for large attachment uploads. Auth differs @@ -322,7 +394,9 @@ exports `render…(app)` and a `teardown()`, same convention as - `state.ts` — `StateHost` interface + module-scope singleton. Both `popup.ts` and `vault.ts` register themselves on boot. All `popup/components/*` import from here, never from popup.ts directly, - so the same render code runs in both bundles. + so the same render code runs in both bundles. Its `sendMessage` + wrapper intercepts `vault_locked` responses (lifted out of `vault.ts` + in Phase 4, so the intercept now applies uniformly to both bundles). - `types.ts` — TypeScript mirrors of the Rust core's serde shapes: `Item`, `ItemCore` (internally-tagged on `type`), `Field` and `FieldValue` (adjacently-tagged on `kind` / `value`), `Manifest`, diff --git a/extension/manifest.firefox.json b/extension/manifest.firefox.json index f3cd0b2..984788b 100644 --- a/extension/manifest.firefox.json +++ b/extension/manifest.firefox.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Relicario", - "version": "0.5.0", + "version": "0.7.0", "description": "Two-factor encrypted password manager", "icons": { "16": "icons/icon-16.png", diff --git a/extension/manifest.json b/extension/manifest.json index c6fb5ce..265cc6e 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Relicario", - "version": "0.5.0", + "version": "0.7.0", "description": "Two-factor encrypted password manager", "icons": { "16": "icons/icon-16.png", diff --git a/extension/package.json b/extension/package.json index 792d9b7..47b63f9 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1,6 +1,6 @@ { "name": "relicario-extension", - "version": "0.6.0", + "version": "0.7.0", "private": true, "scripts": { "build": "webpack --mode production",