docs(release-notes): 0.2.0 — release-page body for the auto-release workflow

Workflow .github/workflows/release.yml looks for release-notes/<tag>.md
at the tagged commit; without this file it falls back to --generate-notes,
which produces a flat commit list instead of the marketing-shape body.

Mirrors the convention introduced in release-notes/0.1.2.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
mpstaton 2026-05-20 01:51:14 -05:00
parent e04c6cafa7
commit 160abebaa3

102
release-notes/0.2.0.md Normal file
View file

@ -0,0 +1,102 @@
**Ask Gemini joins Perplexity, Claude, Perplexica, and LM Studio as Perplexed's fourth research provider — Google Search grounded, with the per-claim citation attribution Claude's `web_search` round-trip silently loses.**
## Why care?
If you fill research notes in Obsidian — concept profiles, source dossiers, vocabulary entries, anything where the citation matters as much as the body — Perplexed 0.2.0 changes two things that show up the moment you use it.
**You have a fourth research provider, and it cites better than the three before it.** Ask Gemini joins the lineup with full Google Search grounding turned on by default. Where Claude's newer `web_search_20260209` drops per-claim citations on the round-trip through its dynamic-filtering sandbox (sources come back, attribution doesn't — text blocks return with `citations: null`), Gemini's `groundingSupports[]` carries the segment-to-source mapping intact. So the `### Citations` footer that lands in your note is actually attached to the prose above it, with the verbatim quote per source.
**Your shared editorial rules stop being duplicated across templates.** Four directory templates (concept, vocabulary, source, toolkit) used to repeat the same mermaid-discipline / citation-enforcement / image-placement / research-framing guidance inside each one, with some of it hardcoded in TypeScript users couldn't touch. Now those rules live in vault-visible `partials/` and `preambles/` folders. Fix the mermaid rules once in `partials/mermaid-discipline.md` and every template picks the fix up on the next generation.
The full provider lineup as of 0.2.0:
| Provider | Endpoint | Cost | Best for |
|---|---|---|---|
| **Perplexity** | api.perplexity.ai | Paid | Source-cited research with consistent citation formatting |
| **Anthropic Claude** | api.anthropic.com | Paid | Longer-form reasoning with `web_search` and adaptive thinking |
| **Google Gemini** *(new)* | generativelanguage.googleapis.com | Free tier (no credit card) + paid | Google Search grounding with per-segment citation attribution |
| **Perplexica / Vane** | localhost:3030 (self-hosted) | Free | Privacy-sensitive research; runs entirely on your machine |
| **LM Studio** | localhost:1234 (local) | Free | Local-only inference, no network |
Open Obsidian → **Settings → Community Plugins → Browse → "Perplexed" → Install → Enable**, then paste a Gemini API key from [aistudio.google.com](https://aistudio.google.com/apikey) (free tier, no credit card required) into Settings → Perplexed → Gemini (Google).
## Ask Gemini — what's in the box
A new **Ask Gemini** command opens a modal mirroring the Ask Claude shape: question textarea, model dropdown, behavior toggles, Cmd-Enter to submit. Default model is `gemini-flash-latest` (Google's always-current Flash alias, free-tier friendly) — `gemini-pro-latest` and pinned `gemini-2.5-pro` / `gemini-2.5-flash` are also selectable.
When `google_search` grounding is enabled (default on), the plugin streams the answer into your note and parses two layers of provenance from the response:
| Layer | Field | What it gives you |
|---|---|---|
| Page-level | `groundingChunks[]` | URL + title per page Gemini consulted |
| Segment-level | `groundingSupports[]` | Text span (`segment.text`) → indices into `groundingChunks[]` |
The plugin walks both layers and merges them by URL: page-level chunks become URL-and-title fallbacks; segment-level supports enrich them with the verbatim quote Gemini grounded against. Citation footer mirrors Claude's exactly (`[N]: [Title](url). > cited_text`) so [Cite Wide](https://community.obsidian.md/plugins/cite-wide)'s hex-substitution pass works on Gemini output too.
### The two Gemini-specific quirks Perplexed handles for you
Anyone who's wired the raw Gemini API will recognize these:
1. **`chunk.web.uri` is a short-lived Google redirect.** The URL Google returns is a `vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIY…` redirect that expires roughly 30 days after the response. Naive "just write the URL we got" means every cited note rots on a clock. Perplexed resolves each redirect via Obsidian's `requestUrl` (Node-side, no CORS friction) and parses the destination page's `<link rel="canonical">` / `<meta property="og:url">` for the durable source URL — **and** parses `<meta property="og:title">` / `<title>` for the real page title. So a citation that would naively render as `[bloomberg.com](vertexaisearch.cloud.google.com/...)` instead lands as `[Bloomberg Beta — Bloomberg LP](https://www.bloomberg.com/company/bloomberg-beta/)`.
2. **`searchEntryPoint.renderedContent` is 5KB of inline-styled HTML.** Google's grounding terms ask that this Search Suggestions chip be displayed when google_search is used; the chip itself is `<style>`-tag-prefixed HTML that Obsidian's Markdown renderer strips, leaving orphan `<div>` shells. Perplexed substitutes a Markdown-native `### Google Searches` section: a bullet list of the queries Gemini actually issued, each linked to `google.com/search?q=…` so you can re-run the suggested search. Same end-user behavior, rendered in a form Obsidian can actually display.
## Partials + preambles — shared template guidance, vault-visible
The four directory templates (`concept-profile`, `vocabulary-profile`, `source-profile`, `toolkit-profile`) historically duplicated their mermaid-discipline / citation-enforcement / image-placement / research-framing guidance inside each template, with some of it hardcoded in TypeScript constants users couldn't edit. 0.2.0 moves that guidance into two peer folders alongside `templates/`:
```
Content-Dev/
├── templates/ (the four profile templates)
├── partials/ (NEW — referenced from templates via {{include: name}})
│ └── mermaid-discipline.md
└── preambles/ (NEW — auto-attached to every Perplexity request)
├── inline-citation.md (was a hardcoded TS constant)
├── image-placement.md (was a hardcoded TS constant)
└── research-framing.md (was a TS function)
```
`{{include: name}}` resolves recursively (depth-limited, cycle-detected). Preambles auto-attach to every request with bundled defaults as fallback, and per-template overrides live in the `cft` fence: `preambles: { system: [...], skip-user: [...], skip-all: true }`.
## What else this release brings
- **Eight previously-hidden settings sections render again.** A long-standing `addClass('perplexed-json-textarea is-tall')` bug at two DOM API call sites was throwing `InvalidCharacterError` (the method takes a single token, not a space-separated string), aborting `display()` mid-render and silently hiding every settings row after the Article Generator block. Same shape of fix as the May 19 batch that switched eight `activeDocument.createEl` calls to `containerEl.createEl`.
- **System-prompt textareas widened to full-width 3-line rows.** The three system-prompt settings used `Setting.addTextArea` which crammed them into the 200px right edge of the row at 2 lines tall. Now each gets a name+description row on top and a full-width resizable textarea below.
- **Template seeder idempotent.** Both "Folder already exists" and "File already exists" race conditions (Obsidian's in-memory file index lagging the adapter write) now get swallowed cleanly. No more red console lines on plugin load.
- **`ERR_NETWORK_CHANGED` becomes a useful sentence.** WiFi roam, VPN reconnect, sleep/wake events mid-Perplexity-stream now write "Network changed mid-stream — re-run the query" into the note instead of a 30-line stack trace.
- **Ask Gemini modal** with Google-flavored visual identity: gradient title text (blue → purple → red → yellow via `background-clip: text`), Google four-color hairline under the header, Gemini-blue focus ring on the prompt textarea, gradient-on-hover CTA. Theme tokens everywhere structural so light, dark, and community themes all carry through.
## Verify the release assets
Every release asset in 0.2.0 is signed via [GitHub's artifact attestation system](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) at build time (the workflow introduced in 0.1.2). Before manual install, verify provenance:
```bash
gh attestation verify main.js --repo lossless-group/perplexed-plugin
gh attestation verify manifest.json --repo lossless-group/perplexed-plugin
gh attestation verify styles.css --repo lossless-group/perplexed-plugin
```
Exit code 0 means the file came out of a legitimate build of the source repo.
## The Lossless Group plugin family
| Plugin | What it does |
|---|---|
| [**Cite Wide**](https://community.obsidian.md/plugins/cite-wide) | Stable hex-identifier citations + URL-based dedupe + LLM-paste research conversion |
| [**Image Gin**](https://community.obsidian.md/plugins/image-gin) | Recraft + Ideogram image generation, Magnific stock search, ImageKit CDN, drag-gate |
| **Perplexed** *(this release)* | Source-cited research from Perplexity, Claude, **Gemini**, Perplexica, or LM Studio + per-directory templates |
| [**Metafetch**](https://community.obsidian.md/plugins/metafetch) | Pull OpenGraph metadata into note frontmatter via OpenGraph.io or Microlink |
Together they form a research-to-publication pipeline: Perplexed generates source-cited prose, Cite Wide canonicalizes the citations to stable hex identifiers, Metafetch fills URL frontmatter with OG metadata, Image Gin generates matching imagery.
If Perplexed saves you time, [buy us a coffee](https://buymeacoffee.com/losslessgroup). The plugins are free; the coffee keeps the next one coming.
## Under the hood — full per-day changelog index
Each substantive piece of work shipped in 0.2.0 has its own per-day changelog in the repo:
- [`changelog/2026-05-19_01.md`](https://github.com/lossless-group/perplexed-plugin/blob/main/changelog/2026-05-19_01.md) — partials + preambles paradigm; the one-line fix that resurrected 11 hidden settings sections
- [`changelog/2026-05-19_02.md`](https://github.com/lossless-group/perplexed-plugin/blob/main/changelog/2026-05-19_02.md) — Gemini provider lands; response shape dissected with curl
- [`changelog/2026-05-20_01.md`](https://github.com/lossless-group/perplexed-plugin/blob/main/changelog/2026-05-20_01.md) — Obsidian-shipping pass: CORS-blocked `fetch``requestUrl` + canonical/og:url + `<title>` parsing; `?key=``X-goog-api-key` header; default model → `gemini-flash-latest`; Gemini modal CSS; safeCreateFile race fix; `ERR_NETWORK_CHANGED` UX; system-prompt textareas promoted; `addClass` token bug fixed at two more call sites
Full marketing-grade release narrative with deeper context: [`changelog/releases/0.2.0.md`](https://github.com/lossless-group/perplexed-plugin/blob/main/changelog/releases/0.2.0.md).