Perplexity's API stopped including Access-Control-Allow-Origin headers
for app://obsidian.md, so Electron's Chromium renderer began blocking
every streaming response body — even on successful 200 OK requests.
Every Perplexity query that used streaming was silently producing nothing.
Both streaming call sites now use https.request from node:https instead
of activeWindow.fetch. Node.js routes through the OS network stack and
has no CORS constraint at all. The resulting IncomingMessage stream is
wrapped in a Web ReadableStream<Uint8Array> and passed to the existing
SSE parsing machinery unchanged — idle-timeout, chunk accumulation,
citations, images, and AbortController signal handling all preserved.
Non-streaming requests (Obsidian's request() function) were never
affected and are untouched.
perplexityService.ts:
- Added import * as https from 'node:https' + import type { IncomingMessage }
- Replaced activeWindow.fetch in queryPerplexity streaming branch with
https.request → IncomingMessage → ReadableStream<Uint8Array> bridge
directoryTemplateService.ts:
- Same imports
- Replaced activeWindow.fetch in streamPerplexityToFile with same bridge
- AbortController.signal threaded into https.request signal option so
ceiling-timer and user-cancel abort behavior is fully preserved
Bumps to 0.3.1 — manifest.json, package.json, versions.json updated.
Files changed:
- src/services/perplexityService.ts
- src/services/directoryTemplateService.ts
- manifest.json
- package.json
- versions.json
- changelog/2026-07-06_01.md
- changelog/releases/0.3.1.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0.3.0 turns Perplexed into a serious analyst tooling layer for Venture
Capital, Private Equity, and equities-trading workflows. Three new directory
templates produce 6-9K-word cited analyst drafts in a single Perplexity
Deep Research run. Underneath them, four infrastructure fixes turn
deep-research from a brittle "might work" workflow into something you can
put real analyst time behind.
The three new templates: market-map-profile (analyst memo for Known
Category or Thesis-Driven maps), standards-and-specs-profile (open-spec
profiles with five-way authority typing and three-tier adoption framing),
market-category-profile (concept-folder reference card with three
financial-stage tiers — Incumbents / Challengers / Innovators). The four
infrastructure fixes: per-template request-timeout-ms wall-clock override
(yesterday, pressure-relief valve), structural port of per-chunk
idle-timeout discipline from the legacy modal flow into the
directory-template flow (yesterday, structural fix), per-template
max-tokens Perplexity output-budget override (today, fixes silent
clean-truncation when finish_reason=length fires mid-template), and a
strengthened mermaid-discipline partial plus new latex-discipline partial
(today, fixes the 4-of-5 broken-Mermaid rate via paired BAD/GOOD examples
and a six-item pre-emit self-check).
New templates (src/docs/templates/):
- market-map-profile.md — sonar-deep-research, request-timeout-ms 2400000
(40-min ceiling), max-tokens 24000. Anti-incumbent editorial stance.
- standards-and-specs-profile.md — sonar-deep-research, request-timeout-ms 0
(idle-only safety), max-tokens 24000. Five-way authority typing, named
editors, stewardship transitions, named critics.
- market-category-profile.md — sonar-deep-research, request-timeout-ms 0,
max-tokens 24000. Three-tier financial-stage framing, separate Why Now
and What's Happening sections, Industry Coverage sub-grouped into
Market Reports / Industry Articles / Financial News.
Rendering-discipline partials (src/docs/partials/):
- mermaid-discipline.md rewritten — paired BAD/GOOD examples throughout,
the & escape rule, explicit \n vs <br/> ban, six-item self-check
before emit, simplify-rather-than-break ethos. Original ~250 tokens
expanded to ~440.
- latex-discipline.md new — Obsidian MathJax delimiters and \$ escaping
in prose to avoid accidental inline-math spans.
- concept-profile.md wired in {{include: latex-discipline}} alongside the
existing {{include: mermaid-discipline}}, placed immediately after the
"render a mermaid codefence here" instruction so the rules are in scope
at the moment of generation.
Streaming, timeout, and output-budget infrastructure (src/services/
directoryTemplateService.ts):
- streamPerplexityToFile now races each reader.read() against a fresh
per-chunk idle timer (270s deep-research, 90s normal — matches the
legacy modal flow at perplexityService.ts:659). Closes the
"Wall-clock-timeout cuts off long deep-research streams" issue.
- request-timeout-ms cft override is now the optional absolute wall-clock
ceiling (belt-and-suspenders backstop on top of the idle timer);
explicit 0 disables.
- max-tokens cft override added to buildPayload — passes through to
Perplexity's max_tokens parameter; lifts the silent ~8K-token default
ceiling that was clean-truncating thorough drafts via finish_reason:
length.
Documentation (README.md, docs/directory-templates.md):
- README — new top-level section "For Venture Capital, Private Equity, and
Equities-Trading Workflows" with a five-row table mapping each analyst
workflow to the template that produces it. Directory Templates section
updated to seven shipped templates plus the new per-template cft-block
knobs.
- docs/directory-templates.md — new "Per-template max-tokens override"
section with the diagnostic table for distinguishing wall-clock-timeout
truncation (mid-sentence cutoff, no sources footer) from max_tokens
truncation (clean section-end, full sources footer). The diagnostic
vocabulary that did not exist before this release.
Seeding (src/services/templateSeederService.ts):
- Registered all three new templates plus the new latex-discipline partial
so they auto-seed into vaults on first plugin load and appear in
Re-seed runs.
Version bump (manifest.json, package.json, versions.json):
- 0.2.1 to 0.3.0. minAppVersion unchanged at 1.8.10.
Engineering changelog entries (changelog/):
- 2026-05-26_02.md — the structural idle-timeout port.
- 2026-05-27_01.md — the two new templates, max-tokens override, and
rendering-discipline partial work. Includes the diagnostic-led
narrative on the vault-drift bug that caused the 4-of-5 broken-Mermaid
rate.
Release narratives:
- changelog/releases/0.3.0.md — full marketing-quality release narrative
with frontmatter, four-audience cascade, three diagnostic-led stories
(streaming-timeout, max_tokens, rendering-discipline), explicit upgrade
notes including the vault-drift warning, three deferred items for 0.4.x.
- release-notes/0.3.0.md — prose-only release-page body picked up by the
release.yml workflow when the 0.3.0 tag is pushed. Tighter cut of the
same narrative, suited for the GitHub release page.
Context-v stamp:
- context-v/issues/Wall-Clock-Timeout-Cuts-Off-Long-Deep-Research-Streams.md
marked status: resolved, date_resolved 2026-05-26, with the four open
items reorganized into "what landed" (3 of 4) and "deferred follow-ups"
(cross-service audit, settings-pane exposure, deep-research detection
robustness).
Files changed:
- manifest.json, package.json, versions.json
- README.md, docs/directory-templates.md
- src/services/directoryTemplateService.ts
- src/services/templateSeederService.ts
- src/docs/templates/README.md
- src/docs/templates/concept-profile.md
- src/docs/templates/market-map-profile.md
- src/docs/templates/market-category-profile.md (new)
- src/docs/templates/standards-and-specs-profile.md (new)
- src/docs/partials/mermaid-discipline.md
- src/docs/partials/latex-discipline.md (new)
- changelog/2026-05-26_02.md (new)
- changelog/2026-05-27_01.md (new)
- changelog/releases/0.3.0.md (new)
- release-notes/0.3.0.md (new)
- context-v/issues/Wall-Clock-Timeout-Cuts-Off-Long-Deep-Research-Streams.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Directory-template runs with sonar-deep-research were silently discarding
~99% of every response. Perplexity's deep-research model delivers its whole
finished document in the first SSE event's message.content; the streaming
reader took delta.content (correct for the token-streaming sonar models) and
captured only a ~75-character tail fragment of a ~10,000-character report.
toolkit-profile shipped with sonar-deep-research as its default model, so
the default was the broken one. This release fixes the streaming, hardens it
against mid-stream disconnects, and adds the tooling the directory-template
research workflow was missing.
Both streaming paths now read Perplexity's cumulative message.content
snapshot and append only the new tail — correct for token-streaming sonar
models and for deep research's first-event document dump alike. A timed-out
or dropped stream now keeps the partial content and the citations it already
received instead of discarding the whole run. "Apply directory template"
gained a run dialog with a per-run model selector, so the model is no longer
locked to the template file, and the loading notice names the model that is
actually running instead of a hardcoded "deep research" string.
Streaming (perplexityService.ts, directoryTemplateService.ts):
- Read message.content (cumulative snapshot), diff against written text,
append the tail; a startsWith guard skips a changed prefix rather than
corrupting the note.
- streamPerplexityToFile returns a partial result with a `truncated` flag on
a read error instead of throwing; applyTemplate writes the partial with
its sources footer and a truncation notice. The modal catch block salvages
its citation metadata the same way.
- Deep-research idle timeout 90s -> 270s; request-timeout default 5 -> 10 min.
Model selection (DirectoryTemplateRunModal.ts, main.ts):
- New run dialog: a template dropdown plus a Perplexity model dropdown that
defaults to the template's cft model and overrides it for that run only.
- cf_last_run_model now stamps the model that actually ran.
Search scoping (directoryTemplateService.ts):
- search_domain_filter support via cf_search_domains (target frontmatter)
and search-domains (cft block); allow/deny entries, capped at 10; job
boards are denied automatically.
Template (src/docs/templates/toolkit-profile.md):
- System prompt rebuilt: anchors the entity on its real name rather than the
scraped marketing tagline, makes source quality a triage task instead of
an allow/deny list, adds a search-don't-recall rule and per-section length
ceilings. Default model -> sonar-pro.
Files changed:
- src/services/perplexityService.ts
- src/services/directoryTemplateService.ts
- src/modals/DirectoryTemplateRunModal.ts
- main.ts
- src/docs/templates/toolkit-profile.md
- manifest.json
- package.json
- versions.json
- changelog/releases/0.2.1.md
- release-notes/0.2.1.md
Also included:
- manifest.json description aligned with package.json ("Perplexica (now Vane)").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Gemini lands as the fourth research provider — Google Search grounded,
per-segment citation attribution via groundingSupports[] (the layer Claude's
web_search_20260209 dynamic-filter sandbox loses), redirect URLs resolved
through Obsidian's requestUrl with canonical/og:url + <title> parsing so
citations land with real source URLs and real page titles.
Plus the partials + preambles paradigm (vault-visible shared rules across
the four directory templates), the addClass token bug that was silently
breaking eight settings sections finally fixed, system-prompt textareas
promoted from 200px right-edge slots to full-width 3-line rows, seeder
made idempotent at both folder and file layers, and ERR_NETWORK_CHANGED
mid-stream errors translated into plain-English re-run guidance.
Per-day changelogs:
- changelog/2026-05-19_01.md — partials + preambles + 11 hidden sections fix
- changelog/2026-05-19_02.md — Gemini provider lands
- changelog/2026-05-20_01.md — Obsidian-shipping pass (today)
Release narrative: changelog/releases/0.2.0.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three things bundled:
1. Release workflow at .github/workflows/release.yml fires on every 3-digit-semver tag push. Builds main.js + styles.css in a clean Ubuntu runner, signs all three release assets via actions/attest-build-provenance@v1 (sigstore-backed via OIDC), creates the GitHub Release with notes pulled from release-notes/<tag>.md. Identical to the workflow landing across cite-wide, image-gin, metafetch as a family-wide pattern.
2. release-notes/0.1.2.md authored in marketing-shape per content-farm/context-v/skills/changelog-conventions/SKILL.md "These are marketing artifacts" section.
3. package.json description aligned with manifest.json. Previous package.json text "A plugin for Obsidian that allows you to generate source-cited content..." still contained the bot-flagged "Obsidian" + self-reference patterns that we'd already fixed in manifest.json; this synchronises the two so anything reading from npm-style metadata gets the same active-voice description users see in the directory listing.
Version bumped 0.1.1 → 0.1.2 across manifest.json / package.json / versions.json. No source-code changes — Directory Templates, the four shipped templates, the first-run seeder, the Claude integration, the wide modals all behave identically to 0.1.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The fundingUrl is meant to be a tip-jar / sponsorship destination per the
Obsidian manifest spec — was previously set to https://lossless.group (the
group homepage, no way to send money). Corrected to
https://buymeacoffee.com/losslessgroup, which is the actual destination
across all Lossless-authored plugins.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Patch release bundling the marketplace-compliance lint pass for the
Obsidian community plugin re-submission. No user-visible behavior
changes from 0.1.0; this is the bot-clean version.
versions.json picks up "0.1.1": "1.8.10" matching the manifest's
minAppVersion.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings the manifest in line with the rest of the content-farm plugins —
1.8.10 is the team's current minAppVersion baseline (image-gin, plunk-it,
lmstud-yo, filestarter, file-transporter all use it); the 0.15.0 here
was a 2022-era inheritance from the original Obsidian sample plugin.
Also adds fundingUrl for parity with the rest of the farm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Six docs-derived blockers fixed in one pass; punch-list plan filed
under context-v/plans/ for traceability.
manifest.json
- description rewritten: action-verb start (was "A plugin for
Obsidian…", which the docs call out as an anti-pattern), all four
providers named (Perplexity, Anthropic Claude, Perplexica, LM
Studio), 144 chars, ends with period.
- fundingUrl removed — was pointed at the company website, not a
donation service. Docs: "If you don't accept donations, remove
fundingUrl from your manifest."
main.ts
- Three command IDs un-prefixed: 'perplexed-debug-commands' →
'debug-commands', 'perplexed-reset-prompts' → 'reset-prompts',
'perplexed-reinitialize-services' → 'reinitialize-services'.
Obsidian auto-prefixes commands with the plugin id, so the
doubled form would have registered as 'perplexed.perplexed-…'.
- Deleted the top-level <h2>Perplexed Plugin Settings</h2> from the
settings tab. Docs: "Avoid adding a top-level heading in the
settings tab, such as 'General', 'Settings', or the name of your
plugin."
README.md
- Placeholder URLs replaced with the real lossless-group/perplexed-plugin
repo (clone command, Issues link x2, Discussions link).
- Stale "Version: 0.0.0.1" footer line deleted (manifest is the
source of truth).
- New "## Network use and accounts" section: per-provider table with
endpoint, account requirement, and API-key requirement, plus an
explicit no-telemetry / no-self-update statement. Required by
Developer Policies (network-use disclosure + paid-account
disclosure). Key Features bullet updated to mention Claude.
context-v/plans/2026-05-02_Submission-Blockers-Punch-List.md
- New plan documenting the audit findings: six blockers fixed here,
four will-be-flagged items (7-10: settings <h3>/<h4> → setHeading,
sentence case, console.log hygiene, vault.adapter.write in
logger.ts) deferred to a separate pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
standards
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
new file: LICENSE
new file: context-v/plans/20206-05-02_Assuring-Obsidian-Community-Plugin-Requirements.md
modified: eslint.config.mjs
modified: main.ts
modified: manifest.json
modified: package.json
modified: src/modals/ArticleGeneratorModal.ts
modified: src/modals/ClaudeModal.ts
modified: src/modals/LMStudioModal.ts
modified: src/modals/PerplexicaModal.ts
modified: src/modals/PerplexityModal.ts
modified: src/modals/TextEnhancementModal.ts
modified: src/modals/TextEnhancementWithImagesModal.ts
modified: src/modals/URLUpdateModal.ts
modified: src/services/lmStudioService.ts
modified: src/services/perplexicaService.ts
modified: src/services/perplexityService.ts
modified: src/types/obsidian.d.ts
new file: src/utils/coerce.ts
modified: src/utils/formatDate.ts
modified: src/utils/logger.ts
modified: styles.css
modified: versions.json
On branch development
Changes to be committed:
deleted: .cursor/mcp.json
deleted: .windsurfrules
modified: README.md
modified: manifest.json
modified: package.json
modified: versions.json