Skip to content

feat: capture-to-Obsidian bridge with eval-backed local enrichment#3

Merged
0Smallcat0 merged 2 commits into
mainfrom
feat/obsidian-capture
Jul 9, 2026
Merged

feat: capture-to-Obsidian bridge with eval-backed local enrichment#3
0Smallcat0 merged 2 commits into
mainfrom
feat/obsidian-capture

Conversation

@0Smallcat0

@0Smallcat0 0Smallcat0 commented Jul 9, 2026

Copy link
Copy Markdown
Owner

What

Adds an optional capture-to-Obsidian bridge on top of the existing translation flow. Once a selection is translated, a + 儲存到 Obsidian button writes a Markdown note straight into an Obsidian vault via an obsidian://new URI.

Deliberately a thin bridge, not an Obsidian Web Clipper clone — the weight is on the handoff contract and an eval-backed local-enrichment stage, not the save button.

Design

  • No new permissions. The note is written by opening obsidian://new from the content script (reusing the user gesture); oversized notes fall back to the clipboard. The least-privilege manifest (storage, activeTab) is unchanged.
  • Raw handoff contract. Every note's YAML frontmatter is written status: raw. On-device small models are unreliable at structured output, so OpenRead ships a reliable raw note and defers heavy synthesis to a stronger downstream "second brain" that flips the flag.
  • Enrichment is best-effort, off by default. An optional local-model pass (title / summary / tags) runs through the background worker (same mixed-content / CORS reason as translation). parseEnrichResponse salvages usable metadata from fenced, preamble-wrapped, and trailing-prose replies.

Eval

pnpm eval:capture — deterministic and offline, over 14 real small-model reply shapes:

Metric Rate
Naive JSON.parse yields an object 42.9%
Robust parseEnrichResponse yields usable metadata 71.4%

Full report in eval/CAPTURE-RESULTS.md.

Also: CI fix

CI was pinned to pnpm v9, which cannot read pnpm 11's allowBuilds build-script approval in pnpm-workspace.yaml and was failing at pnpm store path before install even ran (this affected main too). Bumped pnpm/action-setup to v11 to match local dev; dropped the deprecated onlyBuiltDependencies key.

Gates (fresh install, pnpm 11)

  • pnpm install --frozen-lockfile exit 0 · pnpm compile clean · pnpm test 85 pass (+28) · pnpm lint clean · pnpm build ok
  • Pure-core coverage 100% funcs / ~94% lines

🤖 Generated with Claude Code

Turn any translated selection into a Markdown note in an Obsidian vault via an
obsidian://new URI opened from the content script — no new extension
permissions, with a clipboard fallback for notes too large for a protocol URL.
Every note carries a machine-readable YAML frontmatter written `status: raw`
as a handoff contract to a downstream "second brain"; heavy synthesis is
deliberately deferred rather than reimplemented on-device.

Optional local-model enrichment (title/summary/tags) is off by default and
strictly best-effort: parseEnrichResponse salvages usable metadata from fenced,
preamble-wrapped, and trailing-prose replies. A deterministic offline eval
(`pnpm eval:capture`) scores it — 42.9% naive JSON.parse vs 71.4% robust
recovery over 14 real small-model reply shapes.

- core: capture.ts (Markdown + obsidian:// builders), enrich.ts (prompt +
  tolerant parser); both fully unit-tested
- ui: capture orchestrator + a "save to Obsidian" button on the translate panel
- background: ENRICH_CAPTURE one-shot; api: enrichText (non-streamed)
- settings + popup: vault name, capture folder, enrichment toggle
- docs + eval harness updated

85 unit tests pass; pure-core coverage 100% funcs / ~94% lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@0Smallcat0
0Smallcat0 force-pushed the feat/obsidian-capture branch from db9dd88 to 5bc2bed Compare July 9, 2026 10:13
CI pinned pnpm to v9, which cannot read pnpm 11's `allowBuilds` build-script
approval in pnpm-workspace.yaml and died at `pnpm store path` with "packages
field missing or empty" before install ran (this affected main too). Bump
pnpm/action-setup to v11 and setup-node to Node 22 (pnpm 11 requires
Node >= 22.13 for node:sqlite; matches local dev). Drop the deprecated
onlyBuiltDependencies key and align engines.node to >= 22.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@0Smallcat0
0Smallcat0 force-pushed the feat/obsidian-capture branch from 5bc2bed to 694fb15 Compare July 9, 2026 10:14
@0Smallcat0
0Smallcat0 merged commit 6b51902 into main Jul 9, 2026
2 checks passed
@0Smallcat0
0Smallcat0 deleted the feat/obsidian-capture branch July 9, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant