Commit Graph

7 Commits

Author SHA1 Message Date
f311fdc47f v0.3 Phase 5d: Files page migrated to quietware skeleton
Same gated-layout pattern as Phase 5c. v0.2 surface untouched;
quietware path renders FilesPage via LumotiaPageSkeleton with the
four zones the page actually needs:

  Capture header    "File transcription" + "Transcribe audio files locally."
  Primary surface   drop zone / progress / transcript states
  Action dock       Browse files / Copy / Export
  Mono footer       formats · model · Local only

State + handlers preserved.

  fileTranscript, segments, isDragOver, progress, progressText,
  fileName, error, transcribing, showExportMenu — all unchanged.

  handleBrowse, transcribeFiles, copyAll, handleExport — all
  unchanged. Tauri drag-drop listeners stay live on onMount; new
  MutationObserver for data-design joins them.

Primary surface state machine.

  transcribing      Upload icon, "Transcribing" label, mono file
                    name, LumotiaProgress (tone="transcribing", so
                    the blue Phase 4k progress fill applies).
                    Progress text below.

  empty             Dashed drop zone using --button-primary-bg
                    accent when isDragOver, neutral subtle border
                    otherwise. Empty-state typography mirrors
                    Dictation: Young Serif italic "Drop an audio
                    file.", Work Sans support, format list in
                    JetBrains Mono.

  has transcript    Full-bleed editable textarea.

Action dock.

  Browse files (primary when no transcript; secondary when transcript
  exists — at that point Export becomes the primary action).
  Copy (tertiary, disabled until transcript exists).
  Export (LumotiaMenu trigger — primary when transcript exists,
  secondary otherwise).

  Disabled controls render neutral per the Phase 4k token contract.

Mono footer.

  Single line: "MP3 · WAV · M4A · MP4 · FLAC · OGG · {model} · Local only"

Capture script updated.

  scripts/capture-quietware-screenshots.mjs now navigates to the
  Files page via the sidebar nav button after capturing the root
  route, and screenshots both quietware modes.

Verified.

  - npm run check: 0 errors, 0 warnings across 5707 files.
  - Headless captures confirm the new layout in both modes:
    drop zone + action dock + mono footer with the right Phase 4j
    colour grammar applied. Browse Files blue primary, disabled
    actions neutral, dashed border picks up --button-primary-bg
    when isDragOver.

Phase 5e (Tasks) and 5f (History) follow same pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 18:03:45 +01:00
b9dd598937 v0.3 Phase 4k: palette architecture hardening — scales + component tokens + contrast check
Token-hardening pass per round-9 redirect. No new visual decisions —
just plumbing the tokens correctly so the colour grammar locked in
Phase 4j has a system underneath instead of hand-tuned hex.

Scales.

  NEW: src/design-system/v0.3-quietware-scales.css. 11-step tonal
  scales (50, 100, ..., 900, 950) for five source hues and their five
  complement sources. Saturation drops at extremes to avoid neon
  highs and washed-out lows. Hue-stable lightness curve picked to
  mimic Material 3 / IBM Carbon tonal scales.

  Generated by scripts/generate-quietware-scales.py (committed) so
  values are reproducible. To regenerate:
    python3 scripts/generate-quietware-scales.py > scales.css

  Wired into src/app.css directly before v0.3-quietware-tokens.css.

Component tokens consume scale references only.

  All --button-{role}-{tier} and --progress-{state}-fill tokens now
  read from var(--{hue}-{step}) instead of raw hex literals. Future
  scale tuning happens in one place; component callers never change.

    --button-record-bg:    var(--red-600)
    --button-primary-bg:   var(--blue-700)
    --button-success-bg:   var(--green-800)   /* darkened so white
                                                  text clears AA */
    --button-caution-bg:   var(--yellow-400)
    --button-neutral-bg:   var(--color-bg-elevated)
    --button-disabled-bg:  var(--color-bg-elevated)
    --brand-accent:        var(--orange-500)

Progress component tokens.

  New family: --progress-{download,transcribing,success,caution,danger,
  disk,disk-caution,disk-danger}-fill plus --progress-track. Each
  mode tunes the shade step so the bar reads on its track:

    Dark:    blue-400 / green-500 / yellow-500 / red-500
    Light:   blue-700 / green-800 / yellow-600 / red-700
    HC-light: blue-700 / green-800 / yellow-700 / red-700
    HC-dark:  blue-300 / green-400 / yellow-400 / red-400

  LumotiaProgress.svelte gains tone="transcribing", "disk",
  "disk-caution", "disk-danger" so callers map progress role to
  token explicitly.

Border / wireline / focus-ring discipline.

  Three distinct token families:
    --button-primary-border    structural component edge
    --button-primary-wire      complementary identity detail
    --focus-ring-color         keyboard interaction

  Documented as separate concerns in the tokens file.

Contrast check script.

  NEW: scripts/check-colour-contrast.mjs. Parses scales + tokens
  CSS, builds per-scope token tables for dark / light / HC-light /
  HC-dark, resolves var() chains and color-mix() expressions, then
  verifies twelve load-bearing component pairs against WCAG 2.2
  minima (4.5:1 text, 3:1 UI). Exit code 1 on failure.

  Current state: 0 failures across 4 modes.

  Two pairs reported as "warn" rather than "fail": caution progress
  on cream + caution notice border on cream. The yellow source colour
  cannot clear 3:1 on a near-white surface without losing its
  identity. Role recognition is carried by left-bar + icon + label,
  not by surface contrast.

Verified.

  - node scripts/check-colour-contrast.mjs: 0 failures, 4 modes, 12
    load-bearing pairs + 2 known-limitation warns.
  - npm run check: 0 errors, 0 warnings across 5707 files.

Phase 5c (Dictation layout migration) is the natural next focused
sitting. This commit gives Phase 5c the systematic colour grammar to
build on, and the contrast check gates future palette regressions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 16:00:17 +01:00
8e612d1753 v0.3 infra: dev server from worktree + quietware screenshot capture
Two small infra changes to support visual verification of v0.3 phases
from a git worktree.

  - vite.config.js. server.fs.allow extended to ["..", "../.."]. When
    the dev server runs inside .worktrees/v0.3-tactile-quietware/ the
    shared node_modules sits one extra directory up, which Vite's
    default fs.strict policy rejected with HTTP 403 on the @sveltejs
    runtime client. Allowing the parent path unblocks dev runs from
    any worktree of this repo. No effect when dev runs from the main
    checkout.

  - scripts/capture-quietware-screenshots.mjs. Headless Playwright
    driver that visits /design-system-v2 (and best-effort /) under
    five attribute combinations (v0.2 baseline, quietware-dark,
    quietware-light, quietware-hc-dark, quietware-hc-light) and
    writes one PNG per combination to /tmp/lumotia-v0.3-screenshots/.
    Used to email Jake the visual proof for Phase 4a review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 13:37:44 +01:00
7f933f3ca2 v0.2 UI capture: scripts/capture-v0.2-screenshots.mjs
Spins up `npm run dev:frontend` (Vite without Tauri), drives Playwright
Chromium at 1440x900, and writes a PNG per UI surface to
/home/jake/lumotia-v0.2-screenshots/.

Surfaces captured (16 total):

  01 Dictation (default)
  02 Files
  03 Tasks
  04 History
  05 Settings
  06 Dictation × dark/light × cave/energy/reset (6 surface sets)
  07 /float — frame-less task panel
  08 /viewer — transcript viewer
  09 /preview — Wayland-hardened transcription overlay
  10 /design-system-v2 — internal primitives showcase

The design-system-v2 route is gated by VITE_LUMOTIA_DESIGN_SYSTEM_V2=1
per Phase 5; the screenshot run picks this up via a local-only
`.env.local` (now gitignored). shootRoute() waits on a Lumotia
text node before screenshotting so the 11-primitive showcase has time
to hydrate.

Browser-preview-only console noise ("transformCallback") is expected:
some Tauri-only code paths still call invoke() during initial render
even with hasTauriRuntime() gates upstream. No effect on the
captured surfaces.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:13:13 +01:00
100e04fa70 v0.2 Phase 0+1: planning doc + tooling baseline
Phase 0 — docs/release/v0.2-frontend-overhaul.md as single source of
truth for the v0.2 frontend coherence pass. Records hard rules,
tooling pins, sacred-behaviour contract list, wrapper catalogue,
per-page migration order, verification matrix, KI-05 plan, and the
explicit "DO NOT add Skeleton" line.

Phase 1 — tooling baseline. All exact-pinned per the plan:

- @playwright/test@1.60.0 + playwright@1.60.0 + @axe-core/playwright@4.11.3
- rollup-plugin-visualizer@7.0.1 (wired behind ANALYZE=1)
- @vitest/browser@4.1.6 + @vitest/browser-playwright@4.1.6 (provider)
- vitest-browser-svelte@2.1.1 (runes-aware Svelte 5 bridge)
- cargo-nextest installed globally

New configs: playwright.config.ts (frontend-only, dev:frontend webServer,
900x700 + 1440x900 projects, visual baselines deferred), vitest.browser.config.js
(separate from jsdom suite). New scripts: test:e2e, test:e2e:ui,
test:browser, analyze, test:rust:fast, guard:no-skeleton.

guard-no-skeleton.mjs walks package.json + package-lock + src/ for any
@skeletonlabs reference and exits 1 if found — locks in the no-Skeleton
hard rule for any future agent.

Smoke baseline (tests/e2e/smoke.spec.ts): 16 tests passing across two
viewports — app loads without Tauri runtime, keyboard nav, axe scan
(color-contrast deferred to Phase 7 per docs/release/v0.1-contrast-audit.md),
light/dark theme cycle, all three sensory zones (cave/energy/reset).
10 screenshots emitted to test-results/ as non-failing artefacts.

Surfaced + fixed two browser-preview bugs while landing the baseline:

- src/lib/utils/osInfo.ts: FALLBACK_BROWSER_INFO was evaluated at SSR
  module-load (navigator undefined → os: 'unknown'), and the UA check
  ran before navigator.platform — so Playwright's Windows-UA Chromium
  on a Linux runner detected as Windows, useCustomChrome went true,
  Titlebar mounted and tripped Tauri-only APIs. Now lazy-built per
  call; platform is the primary signal, UA only a fallback.

- src/lib/components/Titlebar.svelte: defensive hasTauriRuntime() guard
  on every handler and the $effect. Titlebar should not crash if any
  future code path mounts it without Tauri.

.gitignore: reports/, .playwright/, test-results/, playwright-report/.

Per-phase gate green: npm run check (0/0), npm test (0/0), npm run
test:e2e (16/16), npm run guard:no-skeleton (clean).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:28:51 +01:00
3770815fbf agent: lumotia — v0.1 release-completion run
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
Closes the code-side v0.1 ship gate. All quality gates green:
cargo fmt/clippy/test (~327 tests), npm check (0/0), vitest 13/13,
scripts/dogfood-rebrand-drill.sh 8/8.

Phase F — first-run onboarding promoted to v0.1
- FirstRunPage with skip-to-main + failure recovery + event recording
- Six onboarding commands (record/list/has-completed + lumotia_events)
- Storage migration v17 (onboarding_events + lumotia_events tables)

UI hardening (in-scope items from v0.1-ui-hardening.md)
- StatusPill + PostCaptureCard components, 21st preview entry
- Sidebar recording-as-sacred-state (opacity + aria-disabled, reduced-motion)
- Settings 6-section regroup + Help section + Activation log + Privacy toggle
- Error-state copy sweep (DictationPage + SettingsPage, plain-language)
- Global :focus-visible rule, textarea outlines restored
- Ctrl+K / Ctrl+, / Escape bindings in +layout

LLM resilience
- rule_based_extract_tasks (regex-free imperative-verb extractor) +
  extract_tasks_with_fallback wrapper — task extraction never returns zero
- tokio::time::timeout(120s) wraps cleanup/tags/tasks commands

Release artefacts
- LICENSE (canonical AGPL-3.0), CHANGELOG (Keep-a-Changelog format)
- v0.1-release-notes, privacy-and-ai-use, install-warnings,
  tester-onboarding-kit, tester-acceptance-runbook, code-signing-setup,
  apple-silicon-rb08-runbook, virtual-audio-setup, v0.1-contrast-audit
- Workspace versioning + AGPL spdx; npm exact-pin (10 ranges removed)
- AppImage SHA-256 sidecar in build.yml
- README v0.1 section + Reporting-issues; canonical repo slug

Closure pass — items moved from human-required to code-complete
- KI-02 Linux idle inhibit: zbus 5 → org.freedesktop.login1.Manager.Inhibit
- KI-03 Windows sleep prevention: SetThreadExecutionState(ES_CONTINUOUS|...)
- acquire/release_idle_inhibit Tauri commands, wired in DictationPage
- Diagnostic-bundle frontend wire-up (Settings → Help button)
- WCAG-AA contrast fix via .btn-filled-text utility (no token changes)
- 8 destructive-action sites wrapped in plain-language confirm() guards
- KNOWN-ISSUES.md + v0.1-known-limitations.md updated (KI-02/03 fixed)

Scripts
- pre-tag-verify.sh, tag-day.sh, smoke-linux + driver
- parse-diagnostic-bundle.sh, parse-activation-log.py

Per-item audit trail: docs/release/v0.1-completion-status.md
Remaining: W-01…W-08 (signing certs, hardware probes, smoke matrix,
tester recruitment) — see docs/release/v0.1-known-limitations.md.
2026-05-15 06:59:08 +01:00
2aac366f32 agent: lumotia — Phase A.6 dogfood drill for rebrand migration on real OS paths
scripts/dogfood-rebrand-drill.sh — end-to-end probe that launches the real
lumotia binary against synthetic legacy magnotia state on disk, then
verifies both migration paths produced the expected outcome:

  1. paths.rs: ~/.local/share/magnotia/ -> ~/.local/share/lumotia/, including
     magnotia.db -> lumotia.db rename + non-DB companion files carried along
     by the directory rename.
  2. tauri_app_data_migration.rs: ~/.local/share/uk.co.corbel.magnotia/
     copied via atomic staging to ~/.local/share/consulting.corbel.lumotia/,
     with legacy preserved as a backup and staging dir cleaned up.

Closes the last gap in Phase A: every other test (paths::tests + storage
integration test + localStorageMigration.test.ts) uses synthetic in-process
state. The drill is the only verification that the real binary's startup
hook calls migrate_legacy_data_dir + migrate_tauri_app_data_dir_with_paths
against real OS path resolution.

Two modes:
  (default)            Sandbox: HOME=<tempdir>, faithful on Linux. NOT
                       faithful on macOS — Tauri 2 uses
                       NSSearchPathForDirectoriesInDomains which ignores
                       HOME overrides. Drill refuses to start in sandbox
                       mode on macOS rather than silently writing to the
                       user's real Application Support tree.
  --against-real-home  Real $HOME. Refuses to start if any lumotia data
                       already exists at the real paths (no clobbering
                       real user data). Cleans up planted state on exit
                       unless --keep is passed.

Eight probes covering: data-dir rename outcome, db file rename, legacy
removal, companion file survival, Tauri app_data_dir copy, legacy-backup
preservation, staging-dir cleanup, and lumotia_startup log line presence.

README: documents the drill alongside cargo test + npm test in the
Testing section, with the macOS caveat clearly flagged.

Not run as part of this commit — the drill launches a Tauri WebView
window for a few seconds. Jake to invoke when ready to dogfood.
2026-05-14 07:40:33 +01:00