# Claude Context – Obsidian Plugin ## Project overview An Obsidian community plugin that manages and copies vault context to clipboard for use with LLMs. Stores conventions, structure, and rules in a dedicated folder and provides one-hotkey copy with multi-LLM output formatting, prompt templates, frontmatter presets, granular section selection, and context history. - **Entry point**: `src/main.ts` → compiled to `main.js` via esbuild - **Release artifacts**: `main.js`, `manifest.json`, `styles.css` (optional) - **Plugin ID**: `claude-context` - **Desktop only**: `true` (uses Node.js `fs` and `child_process` for external sources) ## Environment & tooling - **Runtime**: Obsidian (Electron/Chromium) - **Language**: TypeScript (`strict: true`) - **Package manager**: npm - **Bundler**: esbuild (config in `esbuild.config.mjs`) - **Target**: ES2018, CommonJS output - **Dependencies**: only `obsidian` (latest) – no external runtime deps ### Commands ```bash npm install # Install dependencies npm run dev # Watch mode (incremental, inline sourcemaps) npm run build # Type-check + production build (minified, no sourcemaps) ``` ### Testing Manual only – copy `main.js`, `manifest.json`, `styles.css` to `/.obsidian/plugins/claude-context/`, reload Obsidian, enable plugin. ## Source file structure ``` src/ ├── main.ts # Plugin class, command registration, core copy logic ├── settings.ts # ClaudeContextSettings interface, defaults, settings tab UI ├── generator.ts # Context generator modal (vault structure setup wizard) ├── sources.ts # External context sources (freetext, file, folder, shell) ├── source-modal.ts # Modal for adding/editing context sources ├── presets.ts # Frontmatter preset parser & executor (ai-context block) ├── targets.ts # Multi-target output system (format, truncation, token limits) ├── target-modal.ts # Modal for adding/editing output targets ├── templates.ts # Prompt template engine & 5 starter templates ├── template-modal.ts # Modal for adding/editing templates + import/export ├── history.ts # Context history manager (save, cleanup, versioning) ├── history-modal.ts # History viewer modal (browse, diff, restore) ├── content-selector.ts # Heading/block tree parser for granular selection ├── file-selector-modal.ts # Modal for selecting files and sections ├── preview.ts # Preview modal before copying ``` ## Plugin commands | ID | Name | Description | |----|------|-------------| | `copy-context` | Copy context to clipboard | Main command – copies all context files + sources | | `copy-context-with-note` | Copy context with current note | Same as above but always includes active note | | `copy-context-selective` | Copy context (select sections) | Opens file/heading selector modal | | `copy-context-from-preset` | Copy context from frontmatter preset | Reads `ai-context` YAML block from active note | | `generate-context` | Generate context files | Opens setup wizard to create initial context folder | | `view-history` | View context history | Opens history browser with diff and restore | Ribbon icon: `clipboard-copy` → triggers `copy-context`. ## Settings (`ClaudeContextSettings`) | Setting | Type | Default | Description | |---------|------|---------|-------------| | `contextFolder` | `string` | `'_claude'` | Vault folder containing context `.md` files | | `separator` | `string` | `'---'` | Text separator between files in output | | `includeFilenames` | `boolean` | `true` | Add `# === filename ===` headers | | `showPreview` | `boolean` | `false` | Show preview modal before copying | | `includeActiveNote` | `boolean` | `false` | Always append the currently open note | | `excludedFiles` | `string[]` | `[]` | Filenames to skip (case-insensitive) | | `sources` | `ContextSource[]` | `[]` | External context sources | | `showSourceLabels` | `boolean` | `true` | Add position/name labels to source output | | `promptTemplates` | `PromptTemplate[]` | `[]` | Prompt templates with placeholders | | `defaultTemplateId` | `string \| null` | `null` | Template applied automatically on copy | | `history` | `HistorySettings` | see below | History configuration | | `targets` | `OutputTarget[]` | `[]` | Multi-LLM output targets | | `primaryTargetId` | `string \| null` | `null` | Target that goes to clipboard | | `targetOutputFolder` | `string` | `'_claude/outputs'` | Folder for secondary target files | ### History settings | Setting | Type | Default | |---------|------|---------| | `enabled` | `boolean` | `false` | | `storageFolder` | `string` | `'.context-history'` | | `maxEntries` | `number` | `50` | | `autoCleanupDays` | `number` | `30` | ## Architecture & key modules ### Context sources (`sources.ts`) Four source types, each with `position: 'prefix' | 'suffix'`: | Type | Config | Notes | |------|--------|-------| | `freetext` | `{ content: string }` | Inline text snippets | | `file` | `{ path: string }` | External file (absolute path, requires Node.js `fs`) | | `folder` | `{ path: string; recursive: boolean; pattern?: string }` | Directory with optional glob filter | | `shell` | `{ command: string; args: string[]; cwd?: string; timeout?: number }` | Command output (default timeout 5s, max 1MB) | ### Output targets (`targets.ts`) Three built-in targets (can add custom): | Name | Tokens | Format | Strategy | |------|--------|--------|----------| | Claude | 200,000 | `xml` | `summarize-headers` | | GPT-4o | 128,000 | `markdown` | `summarize-headers` | | Compact (8k) | 8,000 | `plain` | `drop-sections` | **Formats**: `markdown` (default), `xml` (wraps in `` tags), `plain` (strips markdown). **Truncation strategies**: `truncate` (hard cut), `summarize-headers` (keep headers, collapse content), `drop-sections` (remove low-priority sections entirely). **Priority order for truncation**: VAULT.md > context files > conventions > structure > active note > examples/templates. ### Prompt templates (`templates.ts`) Handlebars-like engine with variables: `{{context}}`, `{{selection}}`, `{{active_note}}`, `{{active_note_name}}`, `{{date}}`, `{{time}}`, `{{datetime}}`, `{{vault_name}}`. Supports `{{#if var}}...{{else}}...{{/if}}` conditionals. Five starter templates: Code Review, Summary, Q&A, Continue Writing, Explain. ### Frontmatter presets (`presets.ts`) Reads `ai-context` YAML block from the active note's frontmatter: ```yaml ai-context: template: "Template Name" include-linked: true link-depth: 2 # 0-10 include-tags: [tag1] exclude-paths: [archive/] exclude-tags: [draft] max-tokens: 50000 include-active-note: true ``` Features: hierarchical tag matching, link traversal with cycle detection, token budgeting, full validation with errors/warnings. ### Content selector (`content-selector.ts`) Parses heading tree (H1–H6) and block IDs (`^blockid`) from markdown files. Enables partial file selection via `FileSelectorModal`. Output marks partial files with `(partial)` suffix. ### History (`history.ts`) Stores each generated context as JSON in vault. Tracks metadata: template used, included files/sources, active note, char/token counts, user notes. Auto-cleanup by age and entry count. ## Coding conventions - `main.ts` handles plugin lifecycle and command registration – all feature logic lives in dedicated modules. - Each module exports its types/interfaces alongside implementation. - Modals are in separate `*-modal.ts` files, business logic in the corresponding `.ts` file. - Settings are persisted via `loadData()`/`saveData()` with `Object.assign` merge pattern. - VAULT.md is always sorted first in context output. - Token estimation: `chars / 4` (rough approximation). - No external runtime dependencies – everything bundled into `main.js`. ## Obsidian plugin conventions - Add commands with stable IDs – never rename after release. - Use `this.register*` helpers for cleanup on unload. - No network calls without explicit user opt-in and documentation. - No telemetry, no remote code execution. - Keep `minAppVersion` accurate (`0.15.0` currently). - Bump `version` in `manifest.json` (SemVer), update `versions.json`, create GitHub release (tag = version, no `v` prefix). ## Manifest (`manifest.json`) ```json { "id": "claude-context", "name": "Claude Context", "version": "1.0.0", "minAppVersion": "0.15.0", "description": "Copy .claude/ context files to clipboard with one hotkey.", "author": "Luca", "isDesktopOnly": true } ```