mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-04-24 16:06:25 +02:00
Track blocks are YAML-fenced sections embedded in markdown notes whose output is rewritten by a background agent. Three trigger types: manual (Run button or Copilot), scheduled (cron / window / once with a 2 min grace window), and event-driven (Gmail/Calendar sync events routed via an LLM classifier with a second-pass agent decision). Output lives between <!--track-target:ID--> comment markers that render as editable content in the Tiptap editor so users can read and extend AI-generated content inline. Core: - Schedule and event pipelines run as independent polling loops (15s / 5s), both calling the same triggerTrackUpdate orchestrator. Events are FIFO via monotonic IDs; a per-track Set guards against duplicate runs. - Track-run agent builds three message variants (manual/timed/event) — the event variant includes a Pass 2 directive to skip updates on false positives flagged by the liberal Pass 1 router. - IPC surface: track:run/get/update/replaceYaml/delete plus tracks:events forward of the pub-sub bus to the renderer. - Gmail emits per-thread events; Calendar bundles a digest per sync. Copilot: - New `tracks` skill (auto-generated canonical schema from Zod via z.toJSONSchema) teaches block creation, editing, and proactive suggestion. - `run-track-block` tool with optional `context` parameter for backfills (e.g. seeding a new email-tracking block from existing synced emails). Renderer: - Tiptap chip (display-only) opens a rich modal with tabs, toggle, schedule details, raw YAML editor, and confirm-to-delete. All mutations go through IPC so the backend stays the single writer. - Target regions use two atom marker nodes (open/close) around real editable content — custom blocks render natively, users can add their own notes. - "Edit with Copilot" seeds a chat session with the note attached. Docs: apps/x/TRACKS.md covers product flows, technical pipeline, and a catalog of every LLM prompt involved with file+line pointers.
160 lines
5.4 KiB
Markdown
160 lines
5.4 KiB
Markdown
# CLAUDE.md - AI Coding Agent Context
|
|
|
|
This file provides context for AI coding agents working on the Rowboat monorepo.
|
|
|
|
## Quick Reference Commands
|
|
|
|
```bash
|
|
# 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 |
|
|
|---------|-----|
|
|
| Track Blocks — auto-updating note content (scheduled / event-driven / manual), Copilot skill, prompts catalog | `apps/x/TRACKS.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
|
|
1. Edit `apps/x/packages/shared/src/`
|
|
2. Run `cd apps/x && npm run deps` to rebuild
|
|
|
|
### Modify main process
|
|
1. Edit `apps/x/apps/main/src/`
|
|
2. Restart dev server (main doesn't hot-reload)
|
|
|
|
### Modify renderer (React UI)
|
|
1. Edit `apps/x/apps/renderer/src/`
|
|
2. Changes hot-reload automatically in dev mode
|
|
|
|
### Add a new dependency to main
|
|
1. `cd apps/x/apps/main && pnpm add <package>`
|
|
2. Import in source - esbuild will bundle it
|
|
|
|
### Verify compilation
|
|
```bash
|
|
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 ID
|
|
- `APPLE_PASSWORD` - App-specific password
|
|
- `APPLE_TEAM_ID` - Team ID
|
|
|
|
Not required for local development.
|