Applies all required fixes from the bot's review of PR #12513
(obsidianmd/obsidian-releases). ESLint now passes 0 errors with the
Obsidian community ruleset; tsc passes; production build is clean.
Lint setup:
- Adopted eslint-plugin-obsidianmd@^0.2.9 in eslint.config.mjs
- Mirrored the bot's rule surface locally so violations surface in
`pnpm lint` instead of the marketplace PR thread
- Configured the ui/sentence-case rule with a brand allowlist
(Perplexity, Perplexica, Vane, Claude, Anthropic, LM Studio, Imgur,
ImageKit, OpenAI, Ollama, Sonar, Llama, GPT, YAML, JSON, URL, API)
so legitimate proper nouns aren't lowercased
Code fixes (487 → 0):
- console.log/info → console.debug across all sources (~130 sites)
- UI strings normalized to sentence case (~150 sites)
- Command IDs and names cleaned up: dropped "command" suffix, dropped
"perplexed" plugin-name prefix
- Settings tab section headers switched from createEl('h2') to
new Setting().setHeading() (5 sites)
- Inline element.style.color/width/minHeight/fontFamily migrated to
a new CSS class (.perplexed-json-textarea + .is-tall / .is-extra-tall)
in src/styles/settings-tab.css (8 textarea sites, 32 style assignments)
- Async input handlers wrapped: addEventListener('input', () => void
(async () => { ... })()) so the listener type matches (8 sites)
- forEach((opt) => dd.addOption(...)) blocks made void-returning to
satisfy no-misused-promises (9 modal sites)
- JSON.parse results typed as unknown then narrowed
- throw <string> → throw new Error(<string>)
- ${unknown} interpolations narrowed via instanceof Error
- Removed dotenv runtime dependency: published plugins shouldn't read
.env at runtime; user enters API keys via the settings tab
- Replaced builtin-modules dev-dependency with node:module's
builtinModules — same data, no extra package
- Logger console-method dispatch rewritten as a switch instead of
dynamic console[level] indexing (which the bot rejects)
Streaming exceptions:
- src/services/{perplexityService,lmStudioService,perplexicaService}.ts
retain `fetch()` for SSE / chunked streaming because Obsidian's
`requestUrl` buffers the whole body. Each site has an
`eslint-disable-next-line no-restricted-globals` with the marketplace
`/skip` justification inline. Plan to surface these on the PR with
a `/skip` reply.
Reference docs:
- context-v/issues/Obsidian-Review-Bot-Feedback-on-Perplexed-Submission.md
(issue log distilled into…)
- context-v/reminders/Obsidian-Marketplace-Compliance.md (the rules
themselves, reusable for image-gin and cite-wide submissions)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Perplexity's Sonar API stopped embedding inline citation markers in
message.content; responses now return prose plus separate citations
and search_results arrays. The plugin's addCitations() rendered a
correct bibliography, but the body had nothing to anchor the numbers
to.
Prepend a system message telling the model to append [1], [2], ...
markers inline, ordered to match search_results. All three payload
build sites now share one messagesWithSystem array.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings LMStudioModal, TextEnhancementModal, and TextEnhancementWithImagesModal
to the same shape as Ask Perplexity / Ask Claude / Ask Perplexica:
modalEl.addClass(...) wide-modal unlock, sectioned header/section/footer
layout, BEM-scoped class names, native Obsidian Setting components for
dropdowns and toggles, custom textareas where Setting is a poor fit,
Cmd/Ctrl+Enter submit, mobile breakpoint at 600px.
LMStudioModal: model dropdown with live taglines, Max Tokens input,
Temperature slider (0-2 with dynamic tooltip), optional System Prompt
textarea, Images + Stream toggles.
TextEnhancementModal + TextEnhancementWithImagesModal: read-only
Selected Text textarea (background-secondary tint to distinguish from
editable input) + editable prompt pre-filled from the plugin template,
button busy-state during the call.
Bonus: TextEnhancementWithImagesModal CSS class name now matches the
file/class name (was 'get-related-images-modal' on the .ts side while
the file was text-enhancement-with-images-modal.css).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
new file: changelog/2026-04-30_01.md
new file: changelog/2026-05-01_01.md
modified: changelog/2026-05-02_01.md
modified: context-v/specs/Using-Files-as-Prompt-Outlines.md
modified: src/modals/PerplexicaModal.ts
modified: src/styles/perplexica-modal.css
modified: styles.css
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
new file: .logs/obsidian.md-1777711786079.log
modified: context-v/issue-resolutions/Getting-Claude-to-Respond-With-Research.md
new file: context-v/specs/Using-Files-as-Prompt-Outlines.md
modified: src/modals/ArticleGeneratorModal.ts
modified: src/modals/ClaudeModal.ts
modified: src/modals/PerplexityModal.ts
modified: src/services/claudeService.ts
modified: src/styles/article-generator-modal.css
modified: src/styles/perplexity-modal.css
modified: styles.css
with getting returned research objects.
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
new file: context-v/reminders/Ideal-and-Overkill-Schema-for-Max-Flexibility.md
modified: main.ts
modified: package.json
modified: pnpm-lock.yaml
new file: src/modals/ClaudeModal.ts
new file: src/services/claudeService.ts
new file: src/styles/claude-modal.css
modified: src/styles/main.css
modified: styles.css
On branch development
Your branch is ahead of 'origin/development' by 1 commit.
(use "git push" to publish your local commits)
Changes to be committed:
deleted: .eslintignore
deleted: .eslintrc
new file: changelog/2026-05-02_01.md
new file: eslint.config.mjs
modified: package.json
modified: pnpm-lock.yaml
modified: src/services/perplexityService.ts
modified: styles.css
modified: tsconfig.json
On branch feature/perplexity-streaming
Changes to be committed:
modified: README.md
new file: src/docs/Understanding-the-Perplexity-Response-Object.md
modified: src/services/lmStudioService.ts
modified: src/services/perplexicaService.ts
modified: src/services/perplexityService.ts
new file: src/utils/formatDate.ts
modified: styles.css
new file: test-perplexity-api.sh
new file: test-perplexity-non-streaming.sh
- Split monolithic main.ts into modular services and modals
- Created separate service classes: PerplexityService,
PerplexicaService, LMStudioService
- Created modular modal classes: PerplexityModal, PerplexicaModal,
LMStudioModal, URLUpdateModal
- Deleted unused legacy files: CitationModal.ts, citationService.ts,
cleanReferencesSectionService.ts
## New Features
- Added ArticleGeneratorModal for one-page article generation with
predefined prompts
- Implemented intelligent image placement with [IMAGE n:
description] markers
- Added auto-scrolling during streaming responses for better
UX
- Created full callout formatting for query blocks with
multi-line support
## UI/UX Improvements
- Moved all inline styles to dedicated CSS files for
better maintainability
- Created modular CSS structure: perplexity-modal.css,
article-generator-modal.css, etc.
- Added proper spacing and padding to text inputs
across all modals
- Fixed sources placement to appear after last
non-empty line (no more huge gaps)
- Enhanced modal layouts with better visual
hierarchy
## Build System
- Updated esbuild.config.mjs to properly bundle
CSS files
- Created src/styles/main.css as CSS entry
point
- Implemented proper CSS build process with
minification support
## Bug Fixes
- Fixed TypeScript errors from unused
imports and parameters
- Resolved streaming scroll issues with
proper cursor tracking
- Fixed multi-line query formatting in
callout blocks
- Corrected sources insertion logic
for both streaming and
non-streaming responses
## Code Quality
- Improved separation of concerns
with service/modal architecture
- Enhanced maintainability with
modular CSS structure
- Added comprehensive error
handling and logging
- Implemented consistent
coding patterns across all
services
## Technical Details
- Services now handle API
calls, streaming, and
response processing
- Modals focus purely on
UI and user
interaction
- CSS uses Obsidian's
design system
variables for
theming
- All modals support
both streaming and
non-streaming
modes
- Image placement
supports both
inline markers
and fallback
sections
Breaking
Changes: None
Migration:
Existing
functionality
preserved,
enhanced with
new features
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
modified: README.md
modified: main.ts
modified: styles.css
On branch development
Your branch is up to date with 'origin/development'.
Changes to be committed:
modified: main.ts
new file: package-lock.json
modified: package.json
modified: styles.css
- Fixed method name mismatch between convertCitation and convertCitations
- Made generateHexId private and added public getNewHexId method
- Improved type safety for CitationMatch interface with explicit URL handling
- Cleaned up unused imports and variables in CitationModal
- Fixed file handling to use correct Obsidian API types
- Updated citation conversion logic to handle multiple groups
- Added proper error handling for file operations
- Improved code documentation and type annotations
- Formatted styles.css for better readability
On branch development
Changes to be committed:
modified: README.md
modified: esbuild.config.mjs
modified: main.ts
modified: manifest.json
new file: src/modals/CitationModal.ts
new file: src/services/citationService.ts
new file: src/styles/citations.css
new file: src/types/obsidian.d.ts
new file: src/utils/logger.ts