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 <noreply@anthropic.com>
Adds top-level LICENSE (GPL-3.0 full text), updates README, and sets
`license = "GPL-3.0-or-later"` on all four crate manifests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Plan B Phase 8 — three #[wasm_bindgen] exports for the parsers migrated
in Phase 7, mirrored in extension/src/wasm.d.ts under "Pure parsers
(no session needed)". snake_case JS naming consistent with every
existing export; SessionHandle not required.
- parse_month_year(s) → { month, year } via js_value_for
- base32_decode_lenient(s) → Uint8Array
- guess_mime(filename) → string
Tests in session_tests mod cover the OK paths; error-path / JsValue
serialization can't be tested natively (JsError construction panics
off-wasm) and is covered in core (time::tests + base32::tests).
Plan C will wire SW message handlers consuming these exports in a
future round; this commit delivers only the seam.
Includes simplify-feedback fixes:
- relicario-core lib.rs module-list mentions base32 and mime
- item_types/totp.rs neighbour comment unified to ///-style block
cargo test --workspace: green
cargo clippy --workspace: silent
cargo build -p relicario-wasm --target wasm32-unknown-unknown: clean
cd extension && npm run test: 17 pre-existing failures only (baseline)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Closes the P1.1 defense-in-depth gap: wasm-bindgen's auto-generated
.free() previously dropped the SessionHandle wrapper (a u32) without
removing the SESSIONS HashMap entry, leaving the master key and
image_secret in WASM linear memory until JS explicitly called
lock(handle). Drop now wires .free() to session::remove, and the
new native test pins the contract.
Refs: docs/superpowers/specs/2026-05-04-security-polish-design.md (Phase 1)
Refs: docs/superpowers/reviews/2026-05-04-architecture-review.md (P1.1)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Catches the workspace and the extension manifests up to the v0.5.x
release line (was still showing 0.2.0).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- register_device() generates signing + deploy keypairs via core device
module, stores them in DEVICE_STATE (once_cell Lazy<Mutex>), and
returns only public keys to JS
- sign_for_git() signs data using the internal signing key
- get_device_info() returns name and public keys; returns null if not
registered
- clear_device() zeroes and drops device state (logout / re-registration)
- Removed generate_device_keypair() which exposed raw private key bytes
Fixes audit I5: private key material no longer crosses the WASM boundary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Returns { items: [Item], warnings: [ImportWarning] } as a JSON
string. The items already have fresh IDs + timestamps; the SW
caller encrypts and writes them through the existing
item_encrypt + manifest_encrypt bridges.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
generate_device_keypair returns an ed25519 keypair as JSON with hex pubkey
and base64 private key. get_field_history extracts tracked field history
from a decrypted item for the popup's history view.
Co-Authored-By: Claude <noreply@anthropic.com>
Maps serialize as JS objects, not Maps — what the extension popup
expects. Also ships hand-written TS declarations for the bridge
(consumed by Plan 1C).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Also ports TOTP RFC 6238 compute to relicario-core::item_types::totp
so native + CLI + WASM share one implementation (audit H5: CSPRNG
via core's Uniform-sampling generator).
Adds hmac = "0.12" and sha1 = "0.10" to relicario-core deps to support
HOTP/TOTP HMAC with Sha1/Sha256/Sha512. RFC 6238 test vector (t=59,
SHA-1, 8 digits) passes: "94287082".
Adds six #[wasm_bindgen] functions (manifest_encrypt/decrypt,
item_encrypt/decrypt, settings_encrypt/decrypt) plus a native
round-trip test that verifies encrypt→core_decrypt and nonce
uniqueness without calling js-sys (serde_wasm_bindgen::from_value
is wasm32-only; documented in test comment).
Master key never leaves WASM linear memory. Held in Zeroizing<[u8;32]>
inside a thread_local HashMap keyed by u32. lock() removes + zeroizes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>