obsidian-promptfire/AGENTS.md
Luca G. Oelfke cc2d196911
feat: rename plugin from "Claude Context" to "Promptfire"
Rename before community plugin submission (plugin IDs are permanent).
Updates plugin ID, display name, package name, all class names,
CSS prefix (cc- → pf-), default folders (_claude → _context),
built-in target ID, and all documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 12:42:16 +01:00

8.6 KiB
Raw Permalink Blame History

Promptfire 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: promptfire
  • 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

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 <Vault>/.obsidian/plugins/promptfire/, reload Obsidian, enable plugin.

Source file structure

src/
├── main.ts                # Plugin class, command registration, core copy logic
├── settings.ts            # PromptfireSettings 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 (PromptfireSettings)

Setting Type Default Description
contextFolder string '_context' 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 '_context/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
Promptfire 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 <file name="..."> 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:

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 (H1H6) 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.
  • CSS class prefix: pf- (e.g. pf-settings-tabs, pf-gen-modal).

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)

{
  "id": "promptfire",
  "name": "Promptfire",
  "version": "1.0.0",
  "minAppVersion": "0.15.0",
  "description": "Copy vault context files to clipboard with one hotkey for any LLM.",
  "author": "Luca",
  "isDesktopOnly": true
}