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>
24 KiB
Directory Templates
Per-folder content generation for Obsidian vaults — one template fills a category of files.
This is the long-form reference for Perplexed's directory-template system. For the short summary that lives in your vault after first plugin load, see <your-vault>/Content-Dev/Templates/README.md (auto-seeded from src/docs/templates/README.md). For the engineering changelog that introduced the feature, see changelog/2026-05-10_01.md.
The feature was originally specced as "prompt outlines" (see
context-v/specs/Using-Files-as-Prompt-Outlines.md). The shipped naming — "directory templates" — reflects the eventual scope: it's not just an outline you point at a prompt, it's a template bound to a directory via a glob, with auto-seeding, frontmatter stamps, image embedding, and citation hygiene baked into the runtime.
Why this exists
A working Obsidian vault collects categories of files that share a shape — concepts, vocabulary terms, sources, tooling profiles. The pre-template Perplexed flow had one mega-command per content type, each hand-tuned, each running on whichever file you happened to have open. Filling out 1,600 nearly-empty tool profiles in Tooling/, several hundred concepts in concepts/, the vocabulary, the source profiles, one editor-callback at a time, is untenable.
Directory templates close the gap. The paradigm has three primitives:
- A template — a markdown file in your
Content-Dev/Templates/folder, with frontmatter that says which paths it applies to via a glob (concepts/**), a fencedcftconfiguration block, and a heading skeleton that tells the model what to write. - A runtime — two commands (
Apply directory template to current file,Apply directory template to folder) match the template to a target via the glob, build a streaming request, and write the response back as it arrives. - A cleanup pipeline — after the stream completes, the runtime wraps
<think>blocks, swaps[IMAGE N: …]markers for real embeds (with a fallback# Imagessection when the model didn't emit markers but Perplexity returned images), strips unreplaced placeholder bullets, appends a# Sourcesfooter in the format cite-wide can convert to hex citations, and stampscf_last_runandcf_last_run_modelinto the target's frontmatter.
The combination — template + runtime + editorial stance baked into the system prompts — turns a one-file-at-a-time chore into a batched generative pass with auditable provenance.
Anatomy of a template
A template file has three zones:
---
title: Concept Profile
applies-to-paths:
- "concepts/**"
description: Encyclopedia-style entry on a concept, pattern, or mental model.
---
# Free-form intro (ignored)
Anything before the cft block is documentation for the human editing
the template. The runtime drops it from the request.
` ` `cft
provider: perplexity
model: sonar-pro
return-citations: true
return-images: true
system: |
You are writing an encyclopedia-style entry about {{basename}}.
Editorial stance:
- Tech giants are adopters/popularizers, not innovators, unless
documented heyday-era origination supports otherwise.
- Cap big tech at 1–2 of 5–7 entries in any Examples section.
- Prefer founder interviews, startup origin stories, and
research-lab papers as attribution.
` ` `
# Definition
- One-paragraph definition. Plain language. No marketing prose.
# Origins
- Who originated this concept and when. Cite the founder, paper, or
originating startup, not the company that later popularized it.
- [IMAGE 1: a diagram or screenshot illustrating the concept]
# Examples
- 5–7 real-world examples. At most 1–2 from big tech.
***
# User Notes
Anything below the *** divider is excluded from the request.
You can keep your own notes here without polluting the prompt.
(In the actual file, cft is a real code-fence — the spaces in the example above are a markdown-escape trick for this doc.)
The three zones
- Frontmatter (between
---lines at the top) — carriestitle,applies-to-paths(array of globs), and an optionaldescription. The runtime usesapplies-to-pathsto match a template to a target file. cftblock (a code fence with languagecft) — YAML carryingprovider,model, optionalsearch-recency,return-citations,return-images, optionalstream-idle-timeout-ms:andrequest-timeout-ms:(per-template timeout overrides — see Per-template timeout overrides below), optionalmax-tokens:(per-template output-token budget — see Per-template max-tokens override below), and a multi-linesystem:prompt. Everything above thecftblock is dropped from the request.- Heading skeleton — the markdown structure between the
cftblock's closing fence and the first***divider. This becomes the user prompt. Bullets under each heading are instructions to the model, not literal output. Everything below the first***is excluded from the request.
Interpolation tokens
These tokens are substituted into the system: prompt before the request is sent:
| Token | Resolves to |
|---|---|
{{basename}} |
The target file's filename without extension. Use this for any H1 the template wants the model to emit — never use the frontmatter title, which the user may have customized away from the basename. |
{{title}} |
The target file's frontmatter title field, or the basename if missing. |
{{today}} |
Today's date in YYYY-MM-DD form. |
{{frontmatter}} |
The whole frontmatter (whitelisted keys only) as YAML, useful for giving the model existing context about the file. |
{{frontmatter.<key>}} or {{<key>}} |
A specific frontmatter value (string, number, or array joined with commas). |
The interpolation whitelist is configurable in plugin settings (default: title, og_description, tags, og_image). Only whitelisted keys are exposed to prompts.
How a run works
Path matching
When you invoke Apply directory template to current file, the runtime walks every template in Content-Dev/Templates/, expands each one's applies-to-paths globs, and picks the first that matches the active file's vault path. If multiple templates match (overlapping globs), the first-loaded wins — specificity is not ranked. Don't write overlapping patterns.
When you invoke Apply directory template to folder, you get a folder picker, then a template picker (defaults to the template whose glob covers the folder), then a confirmation modal with the file count. The runtime iterates each markdown file under the folder and applies the chosen template. Stop directory template batch halts an in-flight batch.
Fill vs. append
- Fill mode runs when the target file's body (everything after frontmatter) is empty or whitespace-only. The streamed output replaces the empty body.
- Append mode runs when the target file already has content. The streamed output is appended after the existing body, before the sources footer. The intent: re-running a template never destroys prior work, it accretes.
Streaming + the cleanup pipeline
The streaming primitive is a real fetch() SSE connection — Obsidian's request() and requestUrl both buffer the whole response, which defeats the point. The runtime:
- Streams the response, parses each
data:chunk, and flushes accumulated text to the file every ~500ms so you see progress. Failures surface within seconds instead of after a 60-second silent wait. - Captures Perplexity's
search_resultsandimagesarrays as they arrive in the SSE metadata. - After the stream ends, runs the cleanup pipeline:
wrapThinkBlocks— converts<think>…</think>to fenced```think-outputblocks.processContentWithImages— swaps[IMAGE N: …]markers (permissive regex matches[Image …],[IMAGE …], and the markdown-image-shapedvariant) forusing the capturedimagesarray.buildFallbackImagesSection— if no markers replaced butimages.length > 0, emit a# Imagesblock before the sources footer so images never silently vanish.stripUnreplacedImagePlaceholders— remove any[Image embed placeholder …]lines the model emitted but didn't replace.buildSourcesFooter— emit***,# Sources, and[N]: [Title](URL)reference definitions in the canonical Lossless format that cite-wide'sREFDEF_NUM_RErecognises. Run Convert All Citations to Hex Format afterward to swap the numeric markers for stable hex IDs.
Frontmatter stamps
Every successful run stamps three keys into the target's frontmatter via Obsidian's processFrontMatter:
| Key | Value | When |
|---|---|---|
cf_last_run |
ISO timestamp | Every run |
cf_last_run_model |
Provider model label (e.g. Perplexity sonar-pro) |
Every run |
google_books_url |
Harvested URL | Only for book-type sources, only when not already present |
These let you query for stale files later (cf_last_run older than X), audit which model produced an entry, and skip Google-Books-URL lookups on subsequent runs.
Shipped templates
Five templates ship inlined into main.js (via esbuild's .md text loader) and are seeded into the user's vault on first plugin load.
| File | Targets | Model | Notes |
|---|---|---|---|
concept-profile.md |
concepts/** |
sonar-pro |
Encyclopedia-style entries on ideas, patterns, mental models. Anti-incumbent editorial stance baked in. Switched off sonar-deep-research because deep-research is unreliable for image return. |
vocabulary-profile.md |
Vocabulary/** |
sonar-pro |
Term definitions with disambiguation through an innovation-consulting lens. |
source-profile.md |
Sources/** |
sonar-pro |
Profiles of trusted sources — books, people, channels, publications, journals, reports, events. Type-aware: the system prompt enumerates seven canonical types and the model picks one from frontmatter signals (youtube_channel_url → channel, aliases → likely book, etc.). Each section has per-type bullet shapes. |
toolkit-profile.md |
Tooling/** |
sonar-pro |
Profiles of tools, products, platforms, frameworks. |
market-map-profile.md |
lost-in-public/market-maps/**, market-maps/** |
sonar-deep-research |
Analyst-grade market-map drafts. Dual flavor: Known Category (Quantum Computing, Humanoid Robots) or Thesis-Driven (e.g., Neural Network Hardware as Brains for Robotics) traversing adjacent categories. Lean v1, single-stage. Skips image return by design — deep-research's image metadata is unreliable and market-map imagery is generated separately (Ideogram → frontmatter banner_image / portrait_image / square_image). Multi-stage v2 (RAG pre-flight to inject canonical Lossless tools/concepts as context + Claude editorial pass to emit [[wikilink]]s) is deferred — see the User Notes zone of the template for the roadmap. |
source-profile is the trickiest because Sources/ is genuinely heterogeneous. The solution is one template, type-conditional content. Books also trigger Google Books URL handling: frontmatter google_books_url is used if present, otherwise the model finds it; either way the URL is harvested into frontmatter post-generation via regex, so subsequent runs skip the search.
The anti-incumbent editorial stance
concept-profile, vocabulary-profile, and source-profile all embed an "editorial stance — attribute innovation correctly" block in their system prompts. The rules:
- Tech giants (Microsoft, Google, Amazon, Apple, Meta, Oracle, Salesforce, post-1990s IBM) are adopters/popularizers, not innovators, unless documented heyday-era origination or a research-lab paper supports innovator framing.
- Origins favor founder / paper / originating-startup attribution.
- "Best Real-World Examples" caps big tech at 1–2 of 5–7 entries.
- Case studies prefer narratives of smaller innovators outpacing incumbents.
This is saved as project memory in the parent monorepo so future templates inherit the rule. It's not Perplexity-specific bias — every default LLM corpus leans incumbent because that's where the training-data signal is.
First-run seeder and re-seed
templateSeederService.ts bundles the four templates plus the user-facing README into main.js at build time, then writes them to the configured templates folder on onload. The policy is two-tier:
- README (
Content-Dev/Templates/README.md) — always ensured present. If you delete it, the next plugin load writes it back. - Templates — only seeded when the templates folder is missing or contains no non-README markdown. A folder with even one shipped template is treated as user-managed and left alone.
The Re-seed templates button in plugin settings (under Directory templates) writes any shipped file whose filename doesn't already exist. Use it after a plugin update introduced a new template, without overwriting your edits to existing ones. To force-reset a template to its shipped default, delete the file first, then click Re-seed.
Writing your own template
- Copy any shipped template under a new filename (
<your-name>-profile.md). - Change the frontmatter —
title,description, and especiallyapplies-to-paths. - Rewrite the
cftblock'ssystem:to your domain. Use{{basename}}for any H1 you want the model to emit. Add interpolation tokens ({{frontmatter.tags}}, etc.) where prior context should reach the model. - Rewrite the heading skeleton with the structure you want. Use bullets to instruct the model. Use
[IMAGE N: <description>]markers in places where an image would help — setreturn-images: truein the cft block to activate image embedding. - Save it in
Content-Dev/Templates/. The plugin picks it up on the next palette invocation — no reload needed.
Don't write overlapping applies-to-paths patterns across templates; the first matched wins and there's no ranking.
Commands
| Command | Behavior |
|---|---|
| Apply directory template to current file | Match the active file's path to a template's applies-to-paths; fill or append according to file state. |
| Apply directory template to folder | Folder picker → template picker → confirmation modal with file count → batch apply. |
| Stop directory template batch | Halt an in-flight batch at the current file boundary. |
All three appear in the Obsidian command palette under Perplexed: ….
Per-template timeout overrides
The runtime applies two complementary timers to every Perplexity stream (see directoryTemplateService.ts streamPerplexityToFile):
| Timer | What it does | Default |
|---|---|---|
| Stream-idle timeout (per-chunk) | Each reader.read() is raced against a fresh timer. As long as bytes keep arriving, the timer is cleared and re-armed — the stream only dies if it goes quiet for the idle duration. |
270_000 ms (4.5 min) for deep-research models (matched by /deep-research/i against the resolved model name); 90_000 ms (1.5 min) otherwise. Matches the legacy modal flow in perplexityService.ts:659. |
| Wall-clock ceiling (absolute) | An optional AbortController deadline armed once at fetch time. Belt-and-suspenders backstop. |
Plugin-level settings.requestTimeoutMs (default 30 min). Set to 0 in settings to disable; the idle timer alone is responsible for safety. |
The idle timer is the primary safety mechanism. It catches the two pathologies that a single wall-clock timer handles poorly:
- Silently stalled stream (Perplexity rate-limit, socket close, upstream stall): the idle timer surfaces the failure within
idleMsseconds rather than making the user wait the full ceiling. - Slow-but-healthy stream: as long as some byte arrives every
idleMsseconds, the stream completes naturally — it does not get cut off mid-sentence at the ceiling regardless of whether it's still producing.
Templates can override either or both via their cft block:
provider: perplexity
model: sonar-deep-research
stream-idle-timeout-ms: 270000 # per-chunk idle (default already 270s for deep-research)
request-timeout-ms: 2400000 # absolute ceiling (40 min)
system: |
...
Override semantics:
- A numeric value or a numeric string both work.
- For
stream-idle-timeout-ms:: non-positive / non-numeric values fall through to the model-class default (270s deep, 90s normal). - For
request-timeout-ms:: an explicit0disables the ceiling entirely (idle-only). Non-numeric or missing falls through tosettings.requestTimeoutMs. - Overrides apply only to that template's runs.
- The runtime tolerates mid-stream truncation gracefully: a stream killed by either timer leaves a partial draft on disk with
truncated: trueflagged in the result and a Notice telling the user to re-run.
When to override the defaults:
sonar-deep-researchon a multi-section analyst template (market maps, in-depth research reports, sector overviews) routinely emits 6–8K-word bodies. The 270s idle default lets the slow trickle complete naturally — no override needed for the idle key in most cases.- Bump
request-timeout-ms:(or set to0) when you want truly unbounded healthy runs and trust the idle timer to catch stalls. - Lower
stream-idle-timeout-ms:for short non-deep-research templates that should fail fast (the 90s default already does this for them). - Templates that declare a large
include-sources:block (per the multi-stage exploration) when that feature ships — RAG context inflation adds first-byte latency; consider bumpingstream-idle-timeout-ms:if first-byte routinely exceeds the default.
Market-map-profile ships with request-timeout-ms: 2400000 (40 min ceiling) as a safety cap on absolutely-runaway runs; the per-chunk idle timer (270s, inherited) is what actually keeps the stream healthy. Concept, vocabulary, source, and toolkit profiles declare neither key and inherit settings.requestTimeoutMs for the ceiling and the 90s idle default — they all finish comfortably under both.
Per-template max-tokens: override
Perplexity's default output-token cap silently truncates long analyst-grade templates by ending the stream cleanly with finish_reason: "length" mid-skeleton. The symptom is hostile: the run looks like a healthy completion (sources footer renders, no Notice, no truncation warning), but the back half of the section skeleton never appears. Default is approximately 8,192 tokens for sonar-deep-research (~6,000 English words).
Templates can override the default by declaring max-tokens: inside their cft block:
provider: perplexity
model: sonar-deep-research
max-tokens: 24000 # ~18K-word budget
system: |
...
Override semantics:
- A numeric value or a numeric string both work; non-positive / non-numeric values are silently ignored and Perplexity's default applies.
- The override is per-template. Other templates continue to use Perplexity's default.
- Perplexity may itself cap the request below your declared
max-tokens:based on the model's context window minus the prompt length. If you request more than the model can deliver, Perplexity returns the model's actual cap; your override is the ceiling you're willing to accept.
When to bump above the default:
- Any analyst-grade template that asks for >6K words of body.
market-map-profileandstandards-and-specs-profileboth ship withmax-tokens: 24000for this reason. - Templates with deeply nested skeletons (3+ heading levels) — the model rations its token budget across the skeleton, and a deep skeleton means more sections competing for the same budget.
- Templates that demand multiple cards per section (e.g., the three-tier adoption skeleton in
standards-and-specs-profilewith deeper implementation cards). Each card takes ~150-300 tokens; 15-30 cards × 200 tokens = 3,000-6,000 tokens just for the card sections.
The diagnostic to distinguish max-tokens truncation from wall-clock truncation:
| Symptom | Cause |
|---|---|
| Mid-sentence cutoff (literally ends with a partial word or trailing punctuation); no sources footer; user sees "stream went idle" or no Notice at all | Wall-clock timer (request-timeout-ms: ceiling) or idle timer (stream-idle-timeout-ms:) fired during streaming |
| Clean section-end cutoff (last byte is a paragraph break or full sentence); sources footer renders correctly with all citations; no Notice | Perplexity max_tokens cap; the stream completed cleanly via finish_reason: "length" |
The wall-clock and idle timers are streaming-time controls; max-tokens is an output-budget control. They are independent — a template can hit either, neither, or both. Set both knobs generously for thorough deep-research templates.
Settings
Plugin settings → Directory templates:
- Content-Dev folder path — root for content-development resources (default:
Content-Dev). - Templates folder path — where templates live (default:
Content-Dev/Templates). - Frontmatter interpolation whitelist — comma-separated keys exposed to
{{frontmatter.<key>}}(default:title, og_description, tags, og_image). - Re-seed templates — write any shipped template whose filename doesn't exist in the templates folder.
Known limits and open items
(Mirrored from the changelog's Open Items section for completeness — see changelog/2026-05-10_01.md for the canonical list.)
- Image quality on abstract concepts. Perplexity image search keyword-matches against alt text, so it favors marketing heroes over feature/dashboard screenshots even when the latter would be more illustrative. For concept and vocabulary entries with no canonical visual referent, image search often returns nothing useful. Tier-2 mitigations (multimodal re-rank, headless screenshot service, Ideogram-generated illustrations) are deferred.
<think>block streaming UX. Raw<think>…</think>blocks land in the file during streaming and only get wrapped to a fenced block at the end. A live wrap during streaming would be cleaner.- Multi-
cftper template. Each template has onecftblock today. A multi-block template would let a single template define per-section refresh prompts. Unblocked but not designed. - Defensive model capture from API response. The stamped model name comes from the cft config. If Perplexity silently substitutes a different model (rate-limit fallback), we won't reflect that. Capturing the model name from the SSE response and stamping that instead would close the loop.
- Citation/backlink preservation under cite-wide. The image-placeholder strip and
[IMAGE N: …]replacement run on the streamed string before any cite-wide processing. The ordering is consistent today but isn't pre-flight-checked.
See also
changelog/2026-05-10_01.md— the changelog entry that shipped this paradigm, with full What Was Built / What Changed in Approach / Files Touched breakdown.src/docs/templates/README.md— the shorter doc that gets seeded into the user's vault on first plugin load.context-v/specs/Using-Files-as-Prompt-Outlines.md— the original "outlines" spec sketch (kept as historical context; the shipped naming and shape evolved past this).cite-wideplugin'sllmCitationParserService.ts(REFDEF_NUM_RE) — the[N]: [Title](URL)form the sources footer emits is what cite-wide's Convert All Citations to Hex Format command consumes.