No description
Find a file
fancivez e4b2ae3e22 refactor(settings): collapsible sections + smart auto-expand
The settings tab listed ~23 entries on first paint (API mode), most of
which the typical user never touches. Restructured into 5 sections,
of which only the first two are expanded by default.

Sections (default visibility):
- Quick setup (open):     backend / provider preset / credential / model / test
- Reading output (open):  prompt language / card range / export folder / UI lang
- Advanced connection:    api format / base URL / auth type / headers /
                          max tokens / streaming + timeout merged
- Advanced prompt:        max input chars / custom system prompt
- Cache & maintenance:    max entries / clear-all

First-paint count drops from ~23 to ~9 rows.

Smart auto-expand: Advanced connection opens automatically when the
user has departed from preset defaults — custom-* provider, custom
headers, non-default base URL, non-auto auth type, streaming=false,
non-default max tokens, or api format mismatching preset. Same idea
for Advanced prompt (custom prompt or non-default max input chars)
and CLI advanced (non-default cli timeout). Old users find their
configured values without manual digging.

Other simplifications:
- API key + env var fallback combined into one row. The env var input
  lives behind a tiny details/summary disclosure and is built with
  raw DOM (label + input) instead of a nested `new Setting` to avoid
  Obsidian theme CSS conflicts on .setting-item.
- Provider preset row gains an inline read-only summary of the
  derived API format and base URL, replacing the standalone rows
  for those two fields under built-in presets.
- Streaming toggle and streaming timeout are now one row; the
  timeout input is wrapped in its own div and toggled visible only
  when streaming is on.

No data.json changes — every settings key keeps its existing name and
default value. Existing installs upgrade with zero migration.

styles.css: add scoped classes for the collapsible sections, env-var
inline row, timeout inline input, and a generic .parallel-reader-hidden.
i18n: 7 new keys × zh+en for section headings + summary fallbacks.

Codex review pass:
- shouldOpenAdvancedConnection now also reacts to streaming=false /
  non-default apiMaxTokens / apiFormat ≠ preset.format.
- streaming + timeout merged row hides a dedicated wrapper instead of
  inputEl.parentElement (which on some themes shares the controlEl
  with the toggle).
- env-var fallback no longer nests `new Setting` inside a controlEl.
- "(no base url)" placeholder in the preset summary is now i18n'd.

Change-Id: I8ef11c56a89121df13a630b1c724652e78b4069f
2026-05-02 15:54:43 +08:00
.e2e ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
.github/workflows ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
scripts ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
src refactor(settings): collapsible sections + smart auto-expand 2026-05-02 15:54:43 +08:00
tests feat: toggle right sidebar instead of detaching tab + component tests 2026-05-02 15:38:41 +08:00
.editorconfig chore: add .editorconfig for consistent formatting 2026-04-25 23:48:27 +08:00
.gitignore ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
biome.json ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
esbuild.config.mjs build: enable linked source maps for production builds 2026-04-27 19:48:26 +08:00
LICENSE init: Obsidian Parallel Reader v0.1.0 2026-04-24 19:31:23 +08:00
main.ts feat: toggle right sidebar instead of detaching tab + component tests 2026-05-02 15:38:41 +08:00
manifest.json chore: bump version to 1.0.14 2026-05-02 15:38:41 +08:00
package-lock.json chore: improve engineering quality and hardening 2026-04-27 11:15:35 +08:00
package.json ci(e2e): enforce self-contained release gate 2026-04-30 14:45:56 +08:00
README.md docs: trim e2e gate section in readme 2026-05-02 12:51:19 +08:00
README.zh-CN.md docs: trim e2e gate section in readme 2026-05-02 12:51:19 +08:00
styles.css refactor(settings): collapsible sections + smart auto-expand 2026-05-02 15:54:43 +08:00
tsconfig.json build: align tsconfig target and esbuild target to ES2022 2026-04-27 19:47:41 +08:00
versions.json chore: bump version to 1.0.14 2026-05-02 15:38:41 +08:00

Obsidian Parallel Reader

Split-view reading for Obsidian — your original note on the left, AI-generated summary cards on the right, with scroll-sync highlighting.

Latest release Total downloads CI status License Obsidian 1.4+

Stars Open issues Last commit TypeScript strict Code style: Biome 中文文档

English · 中文


Inspired by this reading workflow demo.

Features

  • Adaptive segmentation — the LLM decides natural topic boundaries. Short sections merge, long ones split. No dependency on markdown headings.
  • Scroll-sync — scrolling the editor auto-highlights the matching card on the right.
  • Streaming — real-time SSE streaming for OpenAI Chat and Anthropic APIs, so you see progress as it generates.
  • 20+ providers — Anthropic, OpenAI, Gemini, OpenRouter, Groq, DeepSeek, Moonshot, Ollama, LM Studio, and more. Plus Claude Code CLI and Codex CLI backends.
  • Persistent cache — summaries are cached by content SHA-1 + settings fingerprint. Reopen a note and cards appear instantly. Edits or config changes show a stale banner.
  • Rich rendering — cards render through Obsidian's MarkdownRenderer, so tables, bold, code, and wikilinks all work natively.
  • Card editing — right-click any card to copy, edit, delete, or jump to source.
  • Export — save cards as a Markdown note in your vault, or copy to clipboard.
  • Bilingual UI — full Chinese and English support for commands, settings, and notices.

Quick Start

Step 1: Install the Plugin

  1. Go to the Releases page and download three files from the latest release: main.js, manifest.json, styles.css
  2. Open your vault folder, navigate to .obsidian/plugins/ (create it if it doesn't exist), and create a new folder called parallel-reader
  3. Put the three downloaded files into that folder
  4. Open Obsidian → SettingsCommunity plugins → find Parallel Reader → toggle it on

Tip: Can't see the .obsidian folder? On macOS press Cmd+Shift+. in Finder; on Windows enable "Show hidden files" in File Explorer.

Step 2: Set Up Your AI Provider

  1. In Obsidian, go to SettingsParallel Reader
  2. Choose a Provider preset (e.g. Anthropic, OpenAI, DeepSeek, etc.)
  3. Paste your API Key
  4. (Optional) Change the Model if you prefer a different one
  5. Click Test to verify the connection

That's it! Open any note and run the command "Parallel Reader: Generate" from the command palette (Cmd/Ctrl+P).

Supported providers
Provider Notes
Anthropic Default, recommended
OpenAI GPT models
Google Gemini Gemini models
OpenRouter / Groq / DeepSeek / Moonshot / ... OpenAI-compatible
Ollama / LM Studio Local models, no API key needed
Custom endpoint Any OpenAI or Anthropic compatible API
CLI backends (advanced)

If you have Claude Code or Codex installed locally, you can use them as backends instead of API keys. Just switch the backend in settings — the plugin automatically detects common install locations. If auto-detection fails, you can manually enter the path in settings.

Usage

Action Effect
Click a card Jump editor to that section
Right-click a card Context menu: copy, edit, delete, jump to source
Scroll the editor Right-side card auto-highlights
Alt+↑ / Alt+↓ Navigate between cards
Enter in summary pane Jump to active card's source line
Ribbon icon Open the parallel reader pane
File context menu Generate / regenerate / clear cache

How It Works

The LLM returns structured JSON:

{
  "cards": [
    {
      "title": "Short heading",
      "anchor": "Verbatim quote from source for positioning",
      "gist": "One-sentence lead-in",
      "bullets": ["Supporting detail 1", "Supporting detail 2"]
    }
  ]
}

Anchor is the key mechanism — a verbatim quote that the plugin locates via indexOf with multi-level fallbacks, keeping scroll-sync working without relying on headings.

Gist + bullets gives both overview and scannable detail — pure prose felt like a wall of text, pure bullets felt fragmented.

Development

npm install
npm run dev       # watch mode
npm run build     # production build
npm run typecheck # TypeScript strict mode
npm run lint      # Biome
npm test          # build + typecheck + tests
npm run test:unit
npm run test:component
npm run test:contract
npm run test:e2e  # packaged plugin + disposable Vault smoke

For CI / release evidence, run the contract gate:

bash .e2e/gate.sh --json    # writes .e2e/artifact.json (gitignored)

Add TEST_LIVE=1 to opt into real local Vault / provider checks.

Star History

Star History Chart

License

MIT