mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-10 15:52:38 +02:00
Folds the multi-`track:`-array model into one `live:` block per note: a single persistent objective the live-note agent maintains, plus an optional triggers object (`cronExpr` / `windows` / `eventMatchCriteria`, each independently optional). A note is now passive or live — no per-track scopes, no section ownership contract, no `once` trigger. The agent owns the whole body and makes patch-style incremental edits per run. Highlights: - Schema: `track:` array → single `live:` object (`packages/shared/src/live-note.ts`). - Runtime: scheduler / event processor / runner under `core/knowledge/live-note/`, with split `lastAttemptAt` (every run, drives 5-min backoff) vs `lastRunAt` (success only, anchors cycles). `throwOnError` on agent runs surfaces LLM / billing failures into `lastRunError`. - Today.md: regenerated by template v2 (single objective covering overview / calendar / emails / what-you-missed / priorities; existing files renamed to `Today.md.bkp.<stamp>`). - Renderer: `LiveNoteSidebar` mounts inside the editor row (no chat overlap, auto-closes on note switch); toolbar Radio button becomes a status pill; `LiveNotesView` replaces background-agents view. - Copilot: new `live-note` skill with act-first stance, default folder/cadence pickers, and a non-negotiable rule to extend an existing objective rather than add a second one. Shared `KNOWLEDGE_NOTE_STYLE_GUIDE` enforces terse-and-scannable writing across `doc-collab` and the live-note agent. - Analytics: `track_block` use-case → `live_note_agent`; trigger (`manual` / `cron` / `window` / `event`) becomes the Pass-2 sub-use-case, alongside `routing` for Pass 1. Legacy run files with the old value are read-mapped via `LegacyStartEvent` so they stay openable in the runs list. Hard cutover — no back-compat shims for legacy `track:` frontmatter arrays. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.6 KiB
5.6 KiB
CLAUDE.md - AI Coding Agent Context
This file provides context for AI coding agents working on the Rowboat monorepo.
Quick Reference Commands
# Electron App (apps/x)
cd apps/x && pnpm install # Install dependencies
cd apps/x && npm run deps # Build workspace packages (shared → core → preload)
cd apps/x && npm run dev # Development mode (builds deps, runs app)
cd apps/x && npm run lint # Lint check
cd apps/x/apps/main && npm run package # Production build (.app)
cd apps/x/apps/main && npm run make # Create DMG distributable
Monorepo Structure
rowboat/
├── apps/
│ ├── x/ # Electron desktop app (focus of this doc)
│ ├── rowboat/ # Next.js web dashboard
│ ├── rowboatx/ # Next.js frontend
│ ├── cli/ # CLI tool
│ ├── python-sdk/ # Python SDK
│ └── docs/ # Documentation site
├── CLAUDE.md # This file
└── README.md # User-facing readme
Electron App Architecture (apps/x)
The Electron app is a nested pnpm workspace with its own package management.
apps/x/
├── package.json # Workspace root, dev scripts
├── pnpm-workspace.yaml # Defines workspace packages
├── pnpm-lock.yaml # Lockfile
├── apps/
│ ├── main/ # Electron main process
│ │ ├── src/ # Main process source
│ │ ├── forge.config.cjs # Electron Forge config
│ │ └── bundle.mjs # esbuild bundler
│ ├── renderer/ # React UI (Vite)
│ │ ├── src/ # React components
│ │ └── vite.config.ts
│ └── preload/ # Electron preload scripts
│ └── src/
└── packages/
├── shared/ # @x/shared - Types, utilities, validators
└── core/ # @x/core - Business logic, AI, OAuth, MCP
Build Order (Dependencies)
shared (no deps)
↓
core (depends on shared)
↓
preload (depends on shared)
↓
renderer (depends on shared)
main (depends on shared, core)
The npm run deps command builds: shared → core → preload
Key Entry Points
| Component | Entry | Output |
|---|---|---|
| main | apps/main/src/main.ts |
.package/dist/main.cjs |
| renderer | apps/renderer/src/main.tsx |
apps/renderer/dist/ |
| preload | apps/preload/src/preload.ts |
apps/preload/dist/preload.js |
Build System
- Package manager: pnpm (required for
workspace:*protocol) - Main bundler: esbuild (bundles to single CommonJS file)
- Renderer bundler: Vite
- Packaging: Electron Forge
- TypeScript: ES2022 target
Why esbuild bundling?
pnpm uses symlinks for workspace packages. Electron Forge's dependency walker can't follow these symlinks. esbuild bundles everything into a single file, eliminating the need for node_modules in the packaged app.
Key Files Reference
| Purpose | File |
|---|---|
| Electron main entry | apps/x/apps/main/src/main.ts |
| React app entry | apps/x/apps/renderer/src/main.tsx |
| Forge config (packaging) | apps/x/apps/main/forge.config.cjs |
| Main process bundler | apps/x/apps/main/bundle.mjs |
| Vite config | apps/x/apps/renderer/vite.config.ts |
| Shared types | apps/x/packages/shared/src/ |
| Core business logic | apps/x/packages/core/src/ |
| Workspace config | apps/x/pnpm-workspace.yaml |
| Root scripts | apps/x/package.json |
Feature Deep-Dives
Long-form docs for specific features. Read the relevant file before making changes in that area — it has the full product flow, technical flows, and (where applicable) a catalog of the LLM prompts involved with exact file:line pointers.
| Feature | Doc |
|---|---|
Live Notes — single live: frontmatter block (one objective + optional cron / windows / eventMatchCriteria) that turns a note into a self-updating artifact, panel UI, Copilot skill, prompts catalog |
apps/x/LIVE_NOTE.md |
| Analytics — PostHog event catalog, person properties, use-case taxonomy, how to add a new event | apps/x/ANALYTICS.md |
Common Tasks
LLM configuration (single provider)
- Config file:
~/.rowboat/config/models.json - Schema:
{ provider: { flavor, apiKey?, baseURL?, headers? }, model: string } - Models catalog cache:
~/.rowboat/config/models.dev.json(OpenAI/Anthropic/Google only)
Add a new shared type
- Edit
apps/x/packages/shared/src/ - Run
cd apps/x && npm run depsto rebuild
Modify main process
- Edit
apps/x/apps/main/src/ - Restart dev server (main doesn't hot-reload)
Modify renderer (React UI)
- Edit
apps/x/apps/renderer/src/ - Changes hot-reload automatically in dev mode
Add a new dependency to main
cd apps/x/apps/main && pnpm add <package>- Import in source - esbuild will bundle it
Verify compilation
cd apps/x && npm run deps && npm run lint
Tech Stack
| Layer | Technology |
|---|---|
| Desktop | Electron 39.x |
| UI | React 19, Vite 7 |
| Styling | TailwindCSS, Radix UI |
| State | React hooks |
| AI | Vercel AI SDK, OpenAI/Anthropic/Google/OpenRouter providers, Vercel AI Gateway, Ollama, models.dev catalog |
| IPC | Electron contextBridge |
| Build | TypeScript 5.9, esbuild, Electron Forge |
Environment Variables (for packaging)
For production builds with code signing:
APPLE_ID- Apple Developer IDAPPLE_PASSWORD- App-specific passwordAPPLE_TEAM_ID- Team ID
Not required for local development.