Commit Graph

164 Commits

Author SHA1 Message Date
Scott Idem
48a6734ec3 feat: Claude CLI OAuth token expiry warning
New GET /auth/status endpoint reads ~/.claude/.credentials.json and
returns hours remaining + warning flag. UI shows a dismissible amber
banner when < 24h remain, turning red if expired. Checked on page load
and every 30 minutes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:06:28 -04:00
Scott Idem
7b51e7cc44 UI: mobile-friendly header — move backend/display into settings panel
Header trimmed to 4 buttons (Sessions, Files, ⚙, ?). Backend toggle,
font size, and theme moved into the ⚙ settings panel under new Backend
and Display sections. Panels use responsive widths to avoid overflow on
small screens. Mobile breakpoints tighten padding and hide subtitle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 23:03:55 -04:00
Scott Idem
ce1561572a config: default scheduler timezone to America/New_York 2026-03-17 22:42:47 -04:00
Scott Idem
b123dc3117 Fix scheduler timezone: use ZoneInfo(settings.scheduler_timezone) not 'local' 2026-03-17 22:38:11 -04:00
Scott Idem
4253e69c0b Add auto memory distillation scheduler (APScheduler)
- scheduler.py: AsyncIOScheduler with three cron jobs
    short  daily     03:00 (no LLM, always fast)
    mid    weekly    Sun 03:30 (LLM)
    long   monthly   1st 04:00 (LLM — off by default)
- config.py: AUTO_DISTILL, AUTO_DISTILL_SHORT/MID/LONG .env flags
- main.py: start/stop scheduler in FastAPI lifespan
- routers/distill.py: GET /distill/status — next run times + config
- requirements.txt: apscheduler>=3.10
- HELP.md: updated planned items, added /distill/status to API table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 22:31:38 -04:00
Scott Idem
9fb5b8ae63 HELP.md: mark pfSense port 2222 as configured (pending test) 2026-03-17 22:23:12 -04:00
Scott Idem
0ebfbc6590 Refactor UI into separate CSS/JS, add help modal and HELP.md
- static/index.html: reduced to 127-line HTML shell
- static/style.css: all styles extracted (~900 lines) + help modal styles
  + shared markdown rendering for file-preview and help-modal-body
  including tables (previously missing)
- static/app.js: all JS extracted (~900 lines) + help modal fetch/render
- index.html: adds ? help button + help modal HTML
- inara/HELP.md: comprehensive reference doc covering all features,
  keyboard shortcuts, API endpoints, memory system, planned items
- routers/files.py: HELP.md added to ALLOWED set
- context_loader.py: HELP.md loaded at tier 2+ (after PROTOCOLS.md)
  so Inara can reference it when helping Scott with the interface

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:52:54 -04:00
Scott Idem
fa96c50935 UI: font size cycle button (Aa / A+ / A−)
Cycles normal (16px) → large (18px) → small (14px) on the root element
so all rem-based text scales together. Persisted in localStorage, applied
before first paint to avoid flash. Also include today's session log.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:40:14 -04:00
Scott Idem
c402b97bf3 UI: context panel popover, light/dark theme, contrast improvements
- Light/dark mode: full palette via @media + [data-theme] override;
  theme toggle button (☾/☀) persists to localStorage; no flash on load
- Dark mode softened: #1a1228 bg (was near-pure black), improved muted
  text contrast (#9080a8)
- CSS variables: --shadow, --modal-overlay, --code-bg, --pre-bg,
  --success, --success-dim replace all hardcoded rgba/hex values
- Context panel: ⚙ header button opens dropdown (like Sessions);
  tier badge shows current tier; closes on outside click
- Removed always-visible context bar; controls now in panel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:32:54 -04:00
Scott Idem
ce3c1f5f7f Add tiered memory system with manual distillation
- config.py: memory_budget_long/mid/short settings (overridable in .env)
- memory_distiller.py: distill_short (no LLM), distill_mid, distill_long (LLM)
- routers/distill.py: POST /distill/{short,mid,long,all} endpoints
- context_loader.py: rewrote to load long→mid→short order with include_* toggles
- routers/chat.py: ChatRequest gains include_long/mid/short fields
- routers/files.py: MEMORY_LONG/MID/SHORT.md added to ALLOWED set
- main.py: register distill router
- static/index.html: context bar — tier selector, L/M/S memory toggles,
  distill buttons with status feedback; send includes tier + memory flags
- inara/MEMORY_LONG.md: migrated from MEMORY.md + Cortex/Talk bot notes
- inara/MEMORY_MID.md, MEMORY_SHORT.md: stubs ready for distillation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:22:32 -04:00
Scott Idem
3455c7a09c Add SSE real-time Talk activity, file editor UI, and identity file API
- event_bus.py: in-process asyncio pub/sub (one Queue per SSE client)
- nextcloud_talk.py: publishes nct_message/nct_response events to bus
- chat.py: GET /events SSE endpoint streams Talk activity to browser
- routers/files.py: whitelist-protected GET/PUT for Inara identity .md files
- main.py: register files router
- static/index.html: real-time Talk feed, blue badge on Sessions btn,
  Files modal with preview/edit toggle and Ctrl+S save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 21:10:07 -04:00
Scott Idem
fe854ee534 Add Nextcloud Talk bot integration (Inara)
- New routers/nextcloud_talk.py: webhook handler verifies incoming HMAC,
  calls LLM via BackgroundTasks, posts reply with correctly computed
  signature (random + message_text, not raw body)
- llm_client.py: read Claude OAuth token live from
  ~/.claude/.credentials.json to avoid stale systemd env tokens;
  strip conflicting ANTHROPIC_API_KEY
- config.py: add nextcloud_url, nextcloud_talk_bot_secret,
  nextcloud_talk_timeout settings
- main.py: register nextcloud_talk router, add logging setup
- docs/NEXTCLOUD_TALK_BOT.md: installation guide + HMAC signing gotcha

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 23:04:26 -04:00
Scott Idem
8add4ffd02 Add edit/delete history, named sessions, scroll fix, systemd service
- Edit/delete individual messages from session context with inline editing
  (Ctrl+Enter saves, Escape cancels); changes sync to backend via PUT /history
- PUT /history/{session_id} endpoint to replace full message list
- Named sessions: readable slugs (e.g. quiet-spring) instead of UUID fragments
- Scroll no longer snaps to bottom when user has scrolled up to read history
- cortex.service: systemd unit for auto-start and restart-on-failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 23:38:39 -04:00
Scott Idem
2f675ee4bf Initial commit — Cortex API + Inara identity
Cortex: FastAPI backend serving Inara via Claude/Gemini CLI backends.
Includes SSE streaming chat, session persistence, Google Chat webhook
handler, and Docker support.

Inara: Identity files (persona, soul, protocols, memory, context tiers)
mounted read-only into the container at runtime.

Features in initial cut:
- /chat endpoint with SSE keepalive + LLM fallback
- Session store with rolling history window
- Markdown rendering, copy-to-clipboard, links open in new tab
- Stacked right-column input controls (height selector, enter toggle,
  note mode with public/private) — semi-hidden until textarea grows
- /note endpoint for injecting public context into session history
- Docker Compose config (local dev runs natively; Docker for server)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 03:41:00 -05:00