Files
ar9av__obsidian-wiki/extensions/brain/README.md
ar9av d3e545b012 feat(extensions): fill web forms from the vault; rename to Brain
The brain-capture extension only went one way: browser -> vault. This adds
the return path — read the form on the current page, answer what the vault
supports, and leave the rest blank — and folds both directions into a single
two-tab extension renamed from "Brain Vault Capture" to "Brain".

Retrieval never calls a model. `obsidian-wiki context-pack --json` ranks the
vault deterministically and the model does one narrow job: map retrieved facts
onto fields. One `claude -p` / `codex exec` invocation per fill, billed to the
subscription the user already has. Nothing is ever submitted.

A native messaging host bridges the two, staged into ~/.obsidian-wiki/ rather
than run from the checkout. Chrome's children do not inherit your shell, and
all three consequences bite:

- macOS TCC: ~/Documents is mode 700 with an ACL, and a native host inherits
  Chrome's TCC context, so a checkout there cannot be exec'd at all. Chrome
  reports this as "Native host has exited", identical to a crash.
- PATH: Chrome passes a minimal PATH, hiding claude/codex in ~/.local/bin.
- USER/LOGNAME: Claude Code reads OAuth credentials from the macOS login
  Keychain and needs these to find them, else "Not logged in" despite a valid
  session.

The host bookends every run in its log so those failures stay distinguishable,
re-validates every returned fill against the real form schema (an injected
value cannot reach a field the page never advertised), and forwards the pack's
instruction_policy so vault excerpts stay data rather than instruction.

Form-schema extraction resolves labels via aria-labelledby before aria-label:
Google Forms puts aria-label="Your answer" on every paragraph field while the
real question sits behind aria-labelledby, so checking aria-label first
silently mislabelled exactly the textarea fields. Values are written through
the native setter with input/change dispatched, so React-controlled forms see
a genuine edit.

Docs: docs/browser-extension.md, linked from both READMEs and the docs index.
Also backfills the untranslated tagline from #159 into README_TW.md.
2026-08-14 23:43:19 -07:00

40 lines
1.3 KiB
Markdown

# Brain
A zero-build Chrome extension connecting your browser to your Obsidian vault in
both directions:
- **Capture** — save the current page or a selection into the vault's `_raw/`.
- **Fill form** — answer this page's form from what the vault knows, using the
Claude Code or Codex CLI you already pay for.
## Quickstart
1. `chrome://extensions` → enable **Developer mode** → **Load unpacked** → select
this folder. Capture works now.
2. For form filling, run `host/install.sh`, then fully quit Chrome (⌘Q) and
reopen it.
Test the native host without Chrome:
```bash
python3 host/test_host.py claude # or: codex
```
Logs: `~/.obsidian-wiki/brain-fill.log`.
## Full documentation
**[docs/browser-extension.md](../../docs/browser-extension.md)** covers the
architecture, the security model, how to structure vault pages so they actually
fill, why the native host is staged outside the repo, and troubleshooting.
## Layout
| Path | What it is |
|---|---|
| `manifest.json` | MV3 manifest; fixed `key` gives a stable extension ID |
| `popup.{html,css,js}` | Two-tab popup, plus the functions injected into the page |
| `background.js` | Context-menu capture |
| `host/brain_fill_host.py` | Native messaging host: retrieve → reason → validate |
| `host/install.sh` | Stages the host and registers it with Chrome |