Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Phase log 1: Phases 1–3 (pre-2026-06-05)

Salvaged from the Session History of CLAUDE.original.md, a rolling log that held every session before Phase 12 in one file. That file was split up and deleted on 2026-08-25; its pitfalls and decisions live in CLAUDE.md. This entry is its text verbatim - written as a log, not to the handoff template, so it has no Goal/Next Steps sections.

Goal: Build core Tauri desktop app: encrypted local vault, TypeScript/Vite frontend, inline handler elimination, Projects groundwork.

Phase 1 - What Was Built

  • VaultStore abstraction (LocalVaultStore ↔ TauriVaultStore) - zero UI changes to swap implementations
  • Schema-driven form tooltips via schema.json
  • Simple Icons CDN with letter-avatar fallback
  • CSS themes via data-theme on <html> (6 themes)
  • repeat(auto-fill, minmax(...)) set in JS - CSS repeat(var(...)) is invalid
  • closeIconPicker onClose callback pattern
  • Tauri CSP as single string - array form rejected by Tauri 2 schema
  • Removed devUrl from tauri.conf.json - Tauri 2 needs HTTP URI or absent

Phase 2 - What Was Built

  • mod commands {} - all #[tauri::command] fns in submodule to avoid E0255 proc-macro collision
  • execCommand clipboard fallback for WebKitGTK silently-failing navigator.clipboard
  • data-action delegation - replaced all onclick="..." in innerHTML
  • -webkit-appearance: none on <select> for WebKit CSS colours
  • NO_STRIP=1 env var - workaround for linuxdeploy strip on Fedora 43
  • productName without spaces - prevents unquoted path in linuxdeploy
  • APPIMAGE_EXTRACT_AND_RUN=1 must be in ~/.bashrc, not just PowerShell
  • GDK_BACKEND=x11 in run() via std::env::set_var
  • Argon2id Phase 1 migration: unlock_vault imports legacy vault.json → SQLCipher → deletes plaintext

Phase 3 - What Was Built

  • Source moved public/ → src/ for Vite; vault.js → vault.ts, icons.js → icons.ts, new types.ts
  • "type": "module" in package.json - fixes Vite CJS deprecation warning
  • dist/ is now Tauri frontendDist
  • Card grid, icon picker, export/copy dropdowns, load banner all converted to data-action delegation
  • Global <img> error listener (capture phase) replaces all onerror fallbacks
  • iconPicker refactored to mutable object (ESM import reassignment breaks at runtime)
  • WebKitGTK <input type="file"> ghost: removed static inputs from HTML; openFilePicker() creates input dynamically, appends, clicks, removes on change/cancel/window.focus with done flag
  • <select multiple size> ghost: replaced with custom div-based picker (project-pick-item)
  • position:fixed ghost: top:-9999px; left:-9999px; display:none CSS default; JS cssText sets coords on open
  • Header/unlock overlay collision: hide #header when overlay opens - backdrop-filter creates separate compositing layer
  • Sidebar styling unified - both Projects and Categories emit button.sidebar-item + span.sidebar-label + span.sidebar-count
  • Rename/delete for projects and categories; category tree toggle deselect on re-click
  • Categories ↔ Projects section swap (Categories section = vault.user_categories; Projects section = vault.projects)
  • Sort dropdown: native <select> → <button> + showDropdown() callback map
  • VSCode activity bar (48px icon-only #activity-bar); switchPanel() always called in init()
  • Tools panel with 10 panes wired via initTools()
  • version_history per VaultEntry - auto-populated in Rust on api_key change, capped 50
  • vault_audit table - append-only, written on add/update/delete
  • cert_key_data?: string | null - PEM private key for certificate entries
  • env_var_subtype - display hint for env_var entries
  • generate_certificate + generate_ssh_keypair Rust commands in mod commands {}
  • WireGuard + Docker project types with chunk system, chunk edit modal, project creation modal
  • SI_REGISTRY expanded from ~120 to ~300 entries

Phase 3 Issues (all resolved)

#IssueFix
1<input type="file"> ghost widget (WebKitGTK)Dynamic DOM insert/remove
2<select multiple size> ghost listbox (WebKitGTK)Custom div picker
3.dropdown/.custom-select-list top-left ghosttop:-9999px; left:-9999px CSS default
4Header collides with unlock overlayHide #header when overlay opens
5Categories/Projects section label swapHTML text fixes (IDs unchanged)
6new-category-form dropped by HTML linterRe-added; always verify IDs after formatting
7Category tree no deselect on re-clickToggle: ids[0] === id ? ['Universal'] : [id]
8Projects/Categories styling mismatchUnified button.sidebar-item pattern
9Sidebar startup overlap (tools panel ghost)Always call switchPanel(activePanel) in init()
10Sort dropdown native/whiteCustom showDropdown() callback map
11initTools() not idempotent_toolsInited guard