This file provides guidance to WARP (warp.dev) when working with code in this repository.
Perplexed is an Obsidian plugin for AI-powered content generation with source citations. It integrates with Perplexity (commercial), Perplexica (self-hosted), and LM Studio (local) to generate research-grade content directly in Obsidian notes.
# Install dependencies
pnpm install
# Development mode with watch (auto-rebuilds on changes)
pnpm dev
# Production build
pnpm build
# Type check without emitting
tsc -noEmit -skipLibCheck# Test Perplexity API (streaming)
./test-perplexity-api.sh
# Test Perplexity API (non-streaming)
./test-perplexity-non-streaming.sh# Bump version (updates manifest.json and versions.json)
pnpm version# Create symbolic link to Obsidian plugins folder (macOS/Linux)
ln -s $(pwd) /path/to/obsidian/vault/.obsidian/plugins/perplexed
# Windows (PowerShell)
New-Item -ItemType SymbolicLink -Path "C:\path\to\vault\.obsidian\plugins\perplexed" -Target "C:\path\to\perplexed"Core Files:
main.ts- Plugin entry point with all command registration and API logic (64KB monolithic file)manifest.json- Plugin metadata for Obsidianstyles.css- Plugin UI styles (generated fromsrc/styles/main.css)
Source Organization (src/):
modals/- Modal UI components for user inputservices/- API integration services (Perplexity, Perplexica, LM Studio)types/- TypeScript type definitionsutils/- Utility functionsstyles/- CSS source filesdocs/- Additional documentation
Build Configuration:
esbuild.config.mjs- Build system (bundles TypeScript → JavaScript)tsconfig.json- TypeScript compiler configuration (strict mode).eslintrc- Code quality rules
1. Monolithic Main File
The entire plugin logic lives in main.ts (64KB). All commands, API calls, modals, and settings are in a single PerplexedPlugin class.
2. Command Registration Three provider-specific command registration methods:
registerPerplexityCommands()- Perplexity commercial APIregisterPerplexicaCommands()- Self-hosted PerplexicaregisterLMStudioCommands()- Local LM Studio
3. Modal-Based UI Each command creates an Obsidian Modal with configuration options (model selection, streaming toggle, etc.)
4. Streaming Responses
Uses fetch with streaming to display AI responses in real-time via response.body.getReader()
5. Settings Persistence
Settings stored via Obsidian's loadData()/saveData() API
esbuild configuration:
- Target: ES2022
- Format: CommonJS (required by Obsidian)
- Bundle: Single
main.jsoutput - External: Obsidian API, Electron, CodeMirror
- CSS: Separate build from
src/styles/main.css→styles.css - Dev mode: Watch mode with inline sourcemaps
- Production: Minified, no sourcemaps
Extremely strict TypeScript settings enabled:
strict: truewith all sub-flagsnoUnusedLocals,noUnusedParametersexactOptionalPropertyTypesnoImplicitReturnsnoUncheckedIndexedAccess
- Endpoint:
https://api.perplexity.ai/chat/completions - Models:
sonar-pro,sonar-small,sonar-deep-research, etc. - Features: Citations, images, related questions, recency filters
- Streaming: Supported via SSE
- Default endpoint:
http://localhost:3030/api/search - Focus modes: webSearch, academicSearch, writingAssistant, wolframAlpha, etc.
- Optimization: speed, balanced, quality
- Streaming: Supported
- Default endpoint:
http://localhost:1234/v1/chat/completions - Local model support (e.g.,
ibm/granite-3.2-8b,microsoft/phi-4-reasoning-plus) - Custom system prompts, temperature, max tokens
- Make changes to
main.tsor files insrc/ - Build (dev watch mode auto-rebuilds):
pnpm dev - Test in Obsidian: Reload plugin or restart Obsidian
- Check console:
Cmd/Ctrl + Shift + Ifor errors - Iterate: Edit → auto-rebuild → test
- Monolithic architecture: All logic in
main.ts- no module splitting - Obsidian API: External dependency, not bundled
- No automated tests: Manual testing in Obsidian required
- Desktop only: Plugin marked as
isDesktopOnly: truein manifest - ESLint configured: Use
eslintfor linting (config in.eslintrc) - Strict TypeScript: Code must satisfy very strict type checking
- CSS build: CSS is built separately then imported as text in main bundle