Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
76d8057
feat(scribe): core seams for a pro editor + settings sections
Jul 4, 2026
154b777
feat(scribe): add Scribe to the pro catalog + nav
Jul 4, 2026
bcb69a0
test(scribe): pro E2E — squiggle on typo, valid words untouched
Jul 4, 2026
4608108
docs(scribe): research findings + desktop implementation plan
Jul 4, 2026
39681b1
test(scribe): exercise the document review panel
Jul 4, 2026
ff09cd1
test(scribe): refresh squiggle screenshot for the two-column layout
Jul 4, 2026
d804c24
docs(scribe): roadmap — import→transform→edit, section feedback, lear…
Jul 4, 2026
f74d40e
test(scribe): settings expose style guides + learning loop
Jul 4, 2026
7526470
test(scribe): assert the import menu + refresh aligned-squiggle scree…
Jul 4, 2026
6481d8e
test(scribe): refresh review + settings screenshots
Jul 4, 2026
57cc8c5
feat(scribe): seed the chat composer from Scribe (continue-in-chat)
Jul 4, 2026
9480f78
test(scribe): refresh screenshots (readability report + hotkey settings)
Jul 4, 2026
e9719b4
feat(crm): preload bindings for create-entity + link-observation
Jul 4, 2026
71c76c4
test: fix stale clipboard placeholder assertion
Jul 4, 2026
0f18656
test(scribe): refresh screenshots
Jul 4, 2026
d0a315b
feat(stt): Parakeet transcription engine (additive, beside whisper)
Jul 4, 2026
1b89e7c
feat(stt): engine selector with whisper fallback
Jul 4, 2026
0e930a3
build(stt): CI staging for the Parakeet runtime
Jul 4, 2026
9b638d2
feat(models): Parakeet STT models in the catalog (downloadable)
Jul 4, 2026
d16b95f
feat(stt): use downloaded Parakeet models; keep whisper isolated
Jul 4, 2026
c011389
test(stt): e2e for the Parakeet model picker in Voice settings
Jul 4, 2026
3f15803
fix(stt): honor active whisper model by catalog id; de-em-dash catalo…
Jul 5, 2026
c42de2e
test(stt): point the model-picker e2e at the generalized component te…
Jul 5, 2026
ca7aa35
fix(stt): match active Parakeet model by catalog id; refresh screenshots
Jul 5, 2026
52e33dc
build(stt): stage Parakeet engine dylibs with the 0.0.28 gates
Jul 5, 2026
4b32e86
feat(onboarding): showcase Scribe in the Pro step
Jul 5, 2026
5417f05
fix(stt): correct sherpa-onnx flags + slim/robust staging (verified o…
Jul 5, 2026
fb1a0fd
test(stt): verify parser on real Parakeet output; gitignore the runtime
Jul 5, 2026
9c7c400
refactor(open-core): drop crm preload bindings for pro entity create/…
Jul 5, 2026
c71a807
fix(stt): honor Parakeet model pick when active slot stores a filename
Jul 5, 2026
705a1c5
fix(stt): route core transcription paths through the active engine
Jul 5, 2026
05576ea
fix(build): verify + harden Parakeet tarball staging (supply chain)
Jul 5, 2026
5e7a2ac
feat(stt): effectiveEngine() — single source of truth for engine labe…
Jul 5, 2026
034021d
fix(build): archive traversal check no longer fails open under pipefail
Jul 5, 2026
7076858
docs(scribe): system-wide inline overlay plan + AX feasibility probe
Jul 5, 2026
ed56b9b
feat(scribe): P1 overlay checkpoint — squiggles over native apps (ver…
Jul 5, 2026
e41d184
fix(scribe): overlay viewport culling + squiggle cap
Jul 5, 2026
708ac89
feat(scribe): overlay binary IPC mode (mechanism, engine-driven)
Jul 5, 2026
8533d51
build(scribe): compile + stage the overlay helper in CI
Jul 5, 2026
44e8d4c
perf(scribe): cache overlay bounds + gate selection measurement to ty…
Jul 5, 2026
035e986
feat(scribe): hover-to-fix — native menu at squiggles + AX apply
Jul 5, 2026
a31a271
docs(scribe): overlay build status (v1 implemented, on-device verific…
Jul 5, 2026
cff760a
feat(scribe): branded hover card (replaces the native NSMenu)
Jul 5, 2026
e9d040f
fix(scribe): correction card renders above the squiggle overlay
Jul 5, 2026
02f0f09
feat(scribe): respect macOS learned words (coexist, don't suppress)
Jul 5, 2026
c6214d2
fix(scribe): stop cursor disruption in Electron/browser + brand card …
Jul 5, 2026
c1811fc
fix(scribe): card clicks apply the fix + design-token card colors
Jul 5, 2026
ccd1944
feat(scribe): card category badge + settings gear
Jul 5, 2026
5dd4d20
feat(scribe): system-wide rewrite menu (Improve/Shorten/Tone/Translate)
Jul 5, 2026
258e446
feat(scribe): actionable AI rewrite on the card + on-brand styling
Jul 5, 2026
d07ae72
feat(scribe): theme-aware card + fix Rephrase not replacing text
Jul 5, 2026
481702d
fix(scribe): Rephrase rewrites the whole sentence (verified on-device)
Jul 5, 2026
8c8275c
fix(scribe): make Slack/Electron work + conservative live-underline +…
Jul 6, 2026
937d42c
build(scribe): compile the overlay binary automatically on npm run dev
Jul 6, 2026
732d041
docs(scribe): start gaps backlog (design-audit + functional + verific…
Jul 6, 2026
d764277
docs(scribe): mark G-1 (light-mode hex) resolved
Jul 6, 2026
92c1d98
feat(scribe): overlay squiggles use brand colors (red correctness / e…
Jul 6, 2026
c2bff00
docs(scribe): mark G-2 (color-coding) resolved - brand-aligned
Jul 6, 2026
c86aca2
feat(scribe): selection affordance — select a passage in any app → Re…
Jul 6, 2026
5014b68
fix(scribe): anchor the Rephrase pill to the selection, not the mouse
Jul 6, 2026
30cff1a
feat(a11y): honor prefers-reduced-motion app-wide (G-4)
Jul 6, 2026
b7e005f
docs(scribe): provit E2E findings writeup (G-9) + backlog G-3/G-4/G-9…
Jul 6, 2026
7ea9e85
docs(scribe): log G-11/12/13 (spelling false-positive fixes) in backlog
Jul 6, 2026
28dd46b
fix(scribe): don't offer Rephrase / squiggles on URL bars & non-prose
Jul 7, 2026
b24e31d
fix(scribe): style the markdown preview (Tailwind Preflight stripped …
Jul 7, 2026
6efe70f
feat(scribe): add TipTap for real rich-text mode + editor CSS
Jul 7, 2026
1f8ffd4
docs(scribe): log editor/rich-text items (G-14..G-17)
Jul 7, 2026
b3b0200
fix(scribe-overlay): never offer rephrase in the address bar
Jul 7, 2026
e3565ac
chore(scribe): bump pro (SOLID/DRY audit sweep) + log G-17..G-19
Jul 7, 2026
5a3aa2b
fix: remove posthog-js telemetry dep; fix onboarding Pro grid overflow
Jul 7, 2026
c977ec3
test: add jsdom component-integration test env for Scribe editors
Jul 7, 2026
01f43b3
docs: inherit shared design philosophy + add multi-agent operating model
Jul 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,25 @@ jobs:
mkdir -p resources/bin
cp scripts/dictation-hotkey/dictation-hotkey resources/bin/dictation-hotkey
chmod +x resources/bin/dictation-hotkey
# Compile the Scribe system-wide overlay helper (AX read/measure + squiggle window)
# and stage it into resources/bin. Self-contained, deployment target pinned. If it ever
# fails to ship, Scribe simply falls back to the select-and-hotkey flow (the overlay
# service no-ops when the binary is absent), so it can't break a release.
- name: Build Scribe overlay helper
run: |
bash scripts/build-scribe-overlay.sh
mkdir -p resources/bin
cp scripts/scribe-overlay/scribe-overlay resources/bin/scribe-overlay
chmod +x resources/bin/scribe-overlay
# Stage the Parakeet STT runtime (sherpa-onnx CLI + ONNX model) into
# resources/bin/parakeet. Additive: with SHERPA_ONNX_URL / PARAKEET_MODEL_URL
# unset this is a no-op and transcription stays on whisper, so it can't break a
# release. Set those vars once the exact sherpa-onnx build + Parakeet export are pinned.
- name: Stage Parakeet STT runtime (optional)
env:
SHERPA_ONNX_URL: ${{ vars.SHERPA_ONNX_URL }}
PARAKEET_MODEL_URL: ${{ vars.PARAKEET_MODEL_URL }}
run: bash scripts/fetch-parakeet.sh
# Private pro source into pro/ → __OFFGRID_PRO__ true. The checkout action
# injects the token as an http.extraheader (never in a clone URL) and scrubs
# it afterwards — safer than embedding ${TOKEN} in a git URL.
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ electron/accessibility/ocr
# them. Only the heavy optional runtimes we don't ship are excluded.
resources/bin/coreml-sd/
resources/bin/mflux/
# Parakeet STT runtime — CI-staged via scripts/fetch-parakeet.sh (like mflux/coreml-sd),
# not committed. Devs stage it locally with the same script.
resources/bin/parakeet/
# Gateway probe scratch output
.gateway-probe/
# TS build cache
Expand All @@ -50,3 +53,7 @@ scripts/dictation-hotkey/dictation-hotkey

# Local demo profile — synthetic-data run target for `npm run demo` (never real userData)
.demo-profile/

# local PR-campaign target list (not for commit)
pr-targets.local.md
scripts/scribe-overlay/scribe-overlay
13 changes: 12 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is **Off Grid AI Desktop** — an Electron (macOS) desktop app. The product

## Design — DESKTOP-FIRST, Off Grid brand

Full design doc: **`docs/DESIGN.md`**. The essentials, which OVERRIDE any mobile-first or monochrome assumptions:
Inherit the shared Off Grid design philosophy from **`../brand/DESIGN_PHILOSOPHY.md`** (the source of truth — brutalist/terminal, Menlo mono, emerald accent, tokens in `@offgrid/design`). Platform specifics: **`docs/DESIGN.md`** (brand canon) and **`docs/DESIGN_PHILOSOPHY.md`** (whole-app north star, motion, desktop-first density). The essentials below OVERRIDE any mobile-first or monochrome assumptions:

- **Desktop-first.** Wide canvas: multi-column layouts, dense lists/tables, side panels, detail screens, hover affordances. Never design mobile-first or for narrow viewports. (The mobile app is a separate product with its own guide.)
- **Typeface: Menlo** (monospace) everywhere — terminal/brutalist.
Expand Down Expand Up @@ -122,3 +122,14 @@ If the answer to 1 is "no", say so and write the simple version. If "yes", build
## Copy & content standards

Any change to UI strings, docs, essays, or marketing copy follows the brand voice (`mobile/docs/brand_tone_voice.md`). Easy-to-miss rules: proof-first ("15-30 tok/s", not "fast"); privacy as mechanism ("runs in your Mac's RAM, nothing leaves the device", not "we value privacy"); no em dashes (use " - "), no curly quotes, no exclamation marks; banned words (revolutionary, seamless, empower, leverage, robust, comprehensive, crucial, delve, tapestry, testament, foster, showcase, enhance) and AI-slop phrases ("serves as", "stands as", "it's not X, it's Y") — say it plainly. No emojis in UI.


## Multi-agent operating model (how we build here)

Substantial work is executed by a fleet of parallel subagents orchestrated by the main session — not one linear thread. The standard:

- **Parallel workers, 3 at a time.** Decompose work into worktree-isolated subagents that run concurrently in a rolling window of ~3, each on a DISJOINT file-set so they never merge-conflict. As each lands: review against the engineering standards, merge, run a **local production build gate** (typecheck + tests do NOT catch build/route errors — build before deploy), deploy, verify, then launch the next from the backlog. One agent owns nav/shared-file changes per round; the others avoid them.
- **The gap agent.** Any gap, regression, or "not fully done" is logged to the repo's gaps doc (`docs/GAPS_BACKLOG.md`). A standing gap agent is woken whenever there are gaps: it picks them up, closes them, and marks them resolved with evidence. Gaps are surfaced honestly, never hidden.
- **The QA / platform-integration + docs sweep agent.** After every 3 agent completions, run a sweep agent that (a) verifies the whole platform integrates and works end-to-end (run the integration harness + exercise real cross-service/-surface flows), (b) surfaces any new gaps into the gaps doc, and (c) writes/updates USER-FACING documentation live — how to use / what to do / why / when, per surface — so docs stay current with the build.
- **Merge gate (every merge, non-negotiable):** SOLID + pure logic isolated (unit-testable, zero-IO) separated from I/O; thin handlers; REAL tests exercising real behavior (mocks sparingly); typecheck clean; tests pass; a clean local production build; verify UI by screenshot (vision) and integration by the harness. Nothing is "done" until VERIFIED live, not merely merged.
- **Honesty bar:** report status as a gate (code / wired / verified), never inflate "done." A premature "complete" is a defect.
106 changes: 106 additions & 0 deletions docs/GAPS_BACKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Gaps backlog

Honest running list of gaps, regressions, and "not fully done" items. Each entry: what, why it
matters, where, and status. Close with evidence; don't hide gaps. (Convention from `CLAUDE.md`
multi-agent operating model.)

Status legend: **OPEN** · **IN PROGRESS** · **RESOLVED** (with evidence) · **DECISION NEEDED**

---

## Scribe (writing companion)

### Design-system compliance (audited against `../brand/DESIGN_PHILOSOPHY.md`, 2026-07-06)

- **G-1 · Hardcoded dark hex → broken in light mode** — RESOLVED. All four hex-hardcoded components
converted to theme-aware Tailwind (`neutral-*`/`emerald` → `--og-*` tokens): `ReviewPanel.tsx`,
`RewriteToolbar.tsx`, `LearnedStyle.tsx`, `StyleGuides.tsx`. typecheck clean, 554 tests pass.
Remaining inline hex is only in `AssistedTextarea.tsx` (squiggle overlay positioning + the
category hues, which is the G-2 decision) — not a light/dark bug. Evidence still owed: light-mode
screenshots of the settings panel + rewrite toolbar (folded into G-10).

- **G-2 · Color-coded issue categories** — RESOLVED (user decision: brand-align). Dropped the
rainbow for the two brand colors: **semantic error red** for correctness (spelling/grammar/
punctuation) and **emerald** for suggestions (style/clarity/tone/word-choice). Applied in all three
places: overlay binary `CATEGORY_COLOR`, `AssistedTextarea` `UNDERLINE`, `ReviewPanel`
`CATEGORY_COLOR`.

- **G-3 · a11y on icon-only buttons** — RESOLVED (DOM buttons). Added `aria-label` (+`title`) to the
settings-close X and the disabled-apps remove X. The overlay card's gear/× are native AppKit chips
(Swift `NSView`), not DOM — out of scope for web a11y; AppKit handles their accessibility.

- **G-4 · `prefers-reduced-motion` not honored** — RESOLVED. Added the standard global rule in
`src/renderer/src/assets/main.css` collapsing all transitions/animations to ~instant under
reduced-motion (was only disabling the shooting-star). App-wide, not just Scribe.

- **G-5 · Toggle uses `rounded-full`** — LOW / likely-accept. `WritingSettings` toggle is a pill.
Anti-pattern list says avoid pill shapes, but a toggle switch is a conventional control, not a
pill *button*. Flagging for awareness; probably keep.

### Spelling false-positives (proactive audit, 2026-07-06 — the class the user keeps hitting)

- **G-11 · Contractions flagged** — RESOLVED. `I'll`, `I've`, `don't`, `it's`, `o'clock` were
flagged (tokenize as one non-dictionary word). `isContraction()` accepts known head + standard
clitic. Tested. (User-reported.)
- **G-12 · URLs / emails / @mentions / #tags / `code` flagged** — RESOLVED. Their letter-runs
(getoffgridai, wednesday, handles) flooded chat/email with red squiggles. `protectedRanges()`
skips any token inside such a span. Benefits the overlay too (same engine). Tested.
- **G-13 · Hyphenated compounds flagged** — RESOLVED. `well-known`, `on-device`, `end-to-end`
accepted when every part is a valid word. Tested.

### Functional (from on-device testing, 2026-07-06)

- **G-6 · Slack live squiggles — not visually confirmed** — OPEN. Root cause fixed + PROVEN: the
overlay now sees Slack's field (`[scribe-overlay] focused Slack (com.tinyspeck.slackmacgap)` in
the log) after enabling `AXManualAccessibility` per app. NOT yet confirmed visually that squiggles
draw on misspelled Slack text after the ~1.2s typing-pause (blind automation kept hitting the wrong
window; risk of sending a real message). Evidence to close: user types a misspelling in Slack,
pauses, sees a squiggle; or a controlled capture.

- **G-7 · Live-underline pause behavior needs real-use tuning** — OPEN. In Chromium/Electron the
selection-trick moves the caret, so measurement is gated to ≥1.2s idle + collapsed caret. The
threshold is a guess; confirm it feels right (not too laggy, no cursor flicker) in real typing and
tune `selectionIdle`.

- **G-8 · No live squiggles while actively typing in Slack/browser** — BY DESIGN, documented. Only
native Cocoa apps get truly-live underlines (non-invasive bounds). Revisit if a non-invasive
per-range bounds method is found (AX text markers returned whole-element bounds in testing).

- **G-9 · provit E2E never got a clean green run** — OPEN (findings written up, handed off).
NativeMacActor works; the acceptance journey failed on foreground contention (other automations
stealing front), not a Scribe bug. Full writeup + ranked provit fixes + repro steps in
**`SCRIBE_PROVIT_FINDINGS.md`**. Ball is in the provit agent's court (re-focus appTarget per
capture; capture-by-windowID / serialize native-mac runs; fix the journey's red-vs-emerald copy).

### Verification debt (mine — built but not visually confirmed by me)

- **G-10 · New Scribe screen + busy card look** — OPEN. Redesign + compact busy card are typechecked
and code-reviewed but I did not screenshot the final look. Evidence to close: light + dark screenshots.

## Editor & rich text (2026-07-07)

- **G-14 · Markdown preview looked unstyled** — RESOLVED. It rendered but Tailwind Preflight strips
heading/bold/list styles; added scoped `.scribe-preview` prose CSS.
- **G-15 · Real rich-text mode (TipTap)** — DONE (needs on-device visual check). Rich text is now a
single WYSIWYG (TipTap/ProseMirror), no preview split; live squiggles as PM decorations, click-to-
fix; own toolbar. Compiles + production-bundles. NOT visually verified by me.
- **G-16 · Rich-mode side-panel "apply fix" is inert** — OPEN (minor). The Review panel's one-click
apply (onApply) edits plain text; in rich mode the doc is HTML, so applying from the side panel
won't reflect. Rich mode has its own inline click-to-fix instead. Wire the review panel's apply to
the TipTap doc later, or hide per-issue apply buttons in rich mode.
- **G-17 · Rich-mode squiggle hover card** — RESOLVED. Extracted a single shared `IssuePopover`
(message + fixes + Remove + Add-to-dictionary/Ignore) consumed by BOTH the plain-text editor and
the TipTap editor; rich mode now hovers the real card resolved to the ProseMirror range, not a dead
native `title=` tooltip. (User-reported: "I liked the card better, this is useless".)
- **G-18 · Rephrase pill / squiggles in the browser address bar** — RESOLVED. The `AXSearchField`
subrole alone missed Chromium's omnibox (Chrome/Arc/Edge/Brave expose a plain AXTextField). Added
`isAddressOrSearchField` (subrole + descriptive metadata: role-description/description/placeholder/
title matching address/search/url markers) gating BOTH the squiggle and pill paths; `isRephrasableProse`
also rejects selections whose tokens are bare URLs/domains/emails. Overlay recompiles clean.
(User-reported.)
- **G-19 · Whole-feature SOLID/DRY audit** — RESOLVED. 3 parallel auditors across engine / main-wiring
/ renderer, then 3 fixers. Collapsed every duplicated source of truth: category→color (was 4 copies),
button/chip primitives (6 copies), issue-card renderer (2), countSyllables (2), severity map (2),
extractJson (2), model-call seam (3 bypasses), REWRITE_ACTIONS/tone list/hover-close/escapeRegExp.
Fixed a real bug (rich-mode minimap/jump on stale text). ~400 dup lines removed, +tests. Gate: tsc
web+node clean, 617 tests, production build OK. See commit `ad88bf1` (pro) + `b3b0200` (overlay).
55 changes: 55 additions & 0 deletions docs/SCRIBE_PROVIT_FINDINGS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Scribe overlay × provit — E2E findings & handoff

Notes from running provit's `NativeMacActor` against the Scribe system-wide overlay (2026-07-05/06).
For the provit maintainer/agent. Provit lives at `../provit`; the acceptance journey is
`../provit/journeys/scribe-overlay.json`, the actor `../provit/src/mac/nativeMacActor.ts`, design
`../provit/docs/NATIVE_MAC_ACTOR.md`.

## What worked
- **NativeMacActor primitives pass.** `session() → "native-mac"`, `windowSize()` returns points,
full-screen `screenshot()` produces a real PNG. Permissions (Screen Recording + Accessibility on
the terminal) were sufficient — the same-process CGEvent helper is covered by the terminal grant.
- **The vision loop ran** — the gateway brain (`https://ai.getoffgridai.co/v1`, `qwen3-vl-8b`) judged
each `observe` step and returned structured pass/fail with a reason. The plumbing is sound.

## Why the run never went green (not a Scribe bug)
Every `observe` failed because the **captured frame showed the wrong app** — Gmail/Finder/iTerm
instead of TextEdit. Root cause: **foreground contention**. `NativeMacActor` captures the whole
screen, and other processes kept stealing the foreground mid-run:
1. The actor focuses `appTarget` **once** at `launchApp`, then never re-asserts it; focus drifts.
2. ~20 concurrent `web-todomvc` provit runs (separate session) repeatedly threw a Chromium window to
the front. Full-screen capture has no defense against that.
3. My own screenshot automation + the user working in parallel also pulled focus.

So the failures are an environment/harness issue, not the overlay. (The overlay itself was verified
by hand: emerald/red squiggles land accurately, the hover card applies fixes, Rephrase works — see
`GAPS_BACKLOG.md` and the desktop commits.)

## Recommended provit changes (ranked)
1. **Re-assert `frontmost(appTarget)` before every capture**, not just at `launchApp`. Cheap, and it
fixes the dominant failure mode. (Its own gotcha doc says "if a click lands in the wrong app,
focus shifted — re-run"; make it proactive instead of a manual retry.)
2. **Serialize native-mac runs behind a foreground lock.** A `surface: "native-mac"` run needs
exclusive display foreground — it must refuse/queue while any web/Electron automation is active
on the same display. Better: capture the **target window by `windowID`** (`CGWindowListCreateImage`
for that window) instead of the whole screen, so another app grabbing front doesn't corrupt the
frame. That's the real fix; #1 is the quick one.
3. **Fix the journey copy.** `journeys/scribe-overlay.json` step-1 `expect` says "emerald wavy
underlines under the misspelled words." The overlay now uses **brand color-coding**: red for
correctness (spelling/grammar/punctuation), **emerald for suggestions** (style/clarity/tone).
So spelling underlines are RED. Update the expectation to "red wavy underlines under the misspelled
words; emerald under the passive-voice/style sentence."

## To reproduce a clean run
Quit other automations, then (from `../provit`):
```
PROVIT_VISION=gateway PROVIT_PROVIDER=gateway \
PROVIT_ORACLE_URL="https://ai.getoffgridai.co/v1" PROVIT_ORACLE_KEY="<oglb_ key>" \
PROVIT_ORACLE_MODEL="qwythos-9b" PROVIT_VISION_MODEL="qwen3-vl-8b" \
PROVIT_MAC_TARGET="com.apple.TextEdit" \
node --experimental-strip-types --experimental-sqlite \
src/ios/visionReplay.ts journeys/scribe-overlay.json recordings/scribe
```
Setup first: run the desktop app (`OFFGRID_PRO=1`, overlay on) and `open -a TextEdit` a doc seeded
with `please recieve teh alot of wierd notes.` + a passive-voice line. Keep the machine's foreground
free for the duration (single-owner display).
Loading
Loading