Files
backnotprop__plannotator/packages/ui/utils/defaultNotesApp.ts
Michael Ramos d5e0ff6fe6 feat: Octarine notes integration + auto-save for all integrations (#297)
* feat: Octarine notes integration + auto-save for all integrations

Add Octarine as a third notes app integration alongside Obsidian and Bear.
Uses the octarine:// URI scheme to create notes via deep links, following
the same x-callback-url pattern as Bear.

- New file: packages/ui/utils/octarine.ts (cookie-backed settings)
- Server: saveToOctarine() in integrations.ts, wired into /api/approve
  and /api/save-notes endpoints
- UI: Octarine tab in Settings, card in Export > Notes, dropdown button,
  Cmd+S shortcut support
- Parallelize all integration saves with Promise.allSettled (was sequential)
- Add auto-save on plan arrival toggle to Bear and Octarine (Obsidian
  already had this), consolidate into a single effect + single API call

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add YAML frontmatter properties to Octarine notes

Prepend Octarine-compatible YAML frontmatter with tags, Status, Author,
and Last Edited properties. Uses the same extractTags() as Obsidian for
auto-generated tags (project name, title words, code fence languages).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use fresh=true for Octarine saves to prevent content duplication

Octarine's create action appends by default. If auto-save fires on plan
arrival and the user then approves within the same minute, the same path
gets hit twice — doubling the content. Using fresh=true replaces instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: trim workspace and folder in saveToOctarine before building URI

The UI checks workspace.trim().length > 0 but the server used raw values.
Accidental whitespace in settings would cause Octarine saves to fail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use isOctarineConfigured() for client-side Octarine guards

Auto-save and approve checks used raw workspace truthiness, so
whitespace-only workspace would trigger a save attempt that the server
rejects. Now uses isOctarineConfigured() which trims before checking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: prevent Bear duplicate notes and align default-save dropdown gates

Bear creates a new note on every save, so skip it on approve when
arrival auto-save already succeeded. Gate the default-save dropdown
by actual configuration (vault path for Obsidian, workspace for
Octarine) instead of just the enabled toggle, matching the shortcut
behavior. Self-heal stale defaults back to "ask".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:07:01 -07:00

21 lines
612 B
TypeScript

/**
* Default Notes App Preference
*
* Stores the user's preferred notes app for the Cmd/Ctrl+S shortcut.
* Uses cookies (not localStorage) because each hook invocation runs on a random port.
*/
import { storage } from './storage';
const STORAGE_KEY = 'plannotator-default-notes-app';
export type DefaultNotesApp = 'obsidian' | 'bear' | 'octarine' | 'download' | 'ask';
export function getDefaultNotesApp(): DefaultNotesApp {
return (storage.getItem(STORAGE_KEY) as DefaultNotesApp) || 'ask';
}
export function saveDefaultNotesApp(app: DefaultNotesApp): void {
storage.setItem(STORAGE_KEY, app);
}