* fix(code-mode): make packaged code mode work via on-demand engine provisioning Packaged builds could never run code mode: the Claude/Codex ACP adapters are spawned as separate `node <entry>` processes resolved at runtime, but esbuild can't inline a dynamic spawn target and Forge strips the workspace node_modules, so every release threw `Cannot find module '@agentclientprotocol/...'`. Dev worked only because of the pnpm symlink. Rather than bundle the ~400 MB of native engines (one claude + one codex binary per OS), provision them on demand: - forge.config.cjs: stage the two ACP adapters + their JS dependency closure into .package/acp/node_modules (npm-style nested layout, native engines skipped), exempt .package from the node_modules ignore rule, and only sign/notarize when APPLE_ID is set so unsigned local/CI builds can package. - agents.ts: resolve the adapter from the staged location first (node_modules fallback in dev); provision the pinned engine and point the adapter at it via CLAUDE_CODE_EXECUTABLE / CODEX_PATH. No dependence on a user's global install. - engine-provisioner.ts: ensureEngine() downloads the per-platform engine package from npm AT THE EXACT VERSION THE ADAPTER WAS BUILT AGAINST, verifies its sha512 integrity, extracts atomically into ~/.rowboat/engines/<agent>/<version>/, and caches it. Version-pinning keeps the ACP handshake compatible. - engine-manifest.ts + scripts/gen-engine-manifest.mjs: committed manifest of tarball URLs + integrity for all platforms, regenerated from the adapters' pinned versions on a bump. Verified on macOS arm64: both engines provision and run, and both adapters complete the ACP initialize handshake from the packaged .app against the provisioned engines. Installer drops from ~790 MB to 390 MB. * feat(code-mode): explicit per-agent Enable in Settings; no silent chat download Code mode now requires the user to explicitly enable an agent before use, instead of silently downloading a ~200 MB engine on the first chat message. - Settings → Code Mode: each agent shows "Not enabled" + an Enable button that downloads its engine with a live progress indicator (download % → verify → install), then flips to "Engine ready". Driven by a new codeMode:provisionEngine IPC call + a codeMode:engineProgress push channel. The section now states the prerequisite explicitly: the agent must be installed (Enable) and logged in (claude login / codex login — code mode reuses that saved credential). - Chat path no longer auto-downloads: getProvisionedEnginePath() returns the enabled engine or throws a clear "enable it in Settings → Code Mode" error, so there's never a surprise mid-conversation download. getAgentLaunchSpec is sync again. - Agent status: `installed` now means "engine provisioned" (downloaded), driving the Enable/Ready state; the new-session dialog shows "Enable in Settings" and disables un-enabled agents. Dropped the dead PATH-probing for a global CLI. Verified: empty cache -> status installed=false and the chat path throws the enable-in-Settings error (no download); core, renderer, and main typecheck/build; no new lint errors. * fix(code-mode): show only percentage during engine download in Settings * feat(code-mode): prune superseded engine versions after install After a successful provision, remove any other version dirs (and their .meta) for that agent so old ~200 MB engines don't accumulate across version bumps. Best-effort; never fails a good install. Verified: a planted stale version dir + meta are both removed after provisioning the current version. * fix(code-mode): keep showing engine download % after reopening Settings Provisioning state lived in the row component, which unmounts when the Settings dialog closes — so reopening mid-download showed the Enable button again even though the download was still running in the main process. Move provisioning state to a module-level store with one persistent listener on codeMode:engineProgress, so a row remounting (dialog reopened) reflects the live % and resolves to Ready on completion. * fix(code-mode): flip Enable row straight to Ready after install (no Enable flash) On successful provision the in-flight flag was cleared before the async status refresh completed, so the row briefly (or until reopen) showed the Enable button again. Await the status refresh before clearing the flag so it transitions directly to Ready. * fix(code-mode): optimistically show Ready right after Enable completes Awaiting the status refresh wasn't enough — setStatus re-renders the parent separately from the row, leaving a window where the in-flight flag was cleared but the status prop was stale, so the row flashed/stuck on the Enable button until reopen. Track just-enabled agents in a module-level set and treat them as installed immediately; loadStatus still syncs the real status in the background. * fix(code-mode): graft login-shell PATH + add startup deadline #1 (the gh/git "command not found" in packaged builds): GUI/Finder launches inherit launchd's stripped PATH (/usr/bin:/bin:...), so tools the engine spawns — gh, git, rg, bash — fail even though they work from a terminal (e.g. Homebrew's /opt/homebrew/bin/gh). Probe the user's login-shell PATH and graft it onto the engine's env before spawn (shell-env.ts; no-op on Windows / probe failure). #2: add a 60s startup deadline (initialize / session create+load) so a wedged engine fails with a clear, stderr-enriched error instead of an infinite "(pending...)". Overridable via ROWBOAT_ACP_STARTUP_TIMEOUT_MS. Manager now disposes the client on startup failure so the spawned adapter doesn't leak. Verified: getAgentLaunchSpec's env.PATH now includes /opt/homebrew/bin (where gh lives); core builds; no new lint errors. * chore(code-mode): comment out signing/notarization for local builds Revert to the explicit comment-out approach for osxSign/osxNotarize: uncomment them (with APPLE_ID/APPLE_PASSWORD/APPLE_TEAM_ID) for a signed release build. * chore(code-mode): keep signing/notarization active in committed config The repo's forge.config ships with osxSign/osxNotarize enabled (release-ready). Developers comment them out locally for unsigned test builds and don't commit that. * chore: approve workspace build scripts so packaging runs non-interactively The allowBuilds entries were left as "set this to true or false" placeholders, so `pnpm install` / the pre-build deps check aborted with ERR_PNPM_IGNORED_BUILDS and `npm run package` failed. Set them to true (and add node-pty, used by the code-mode embedded terminal) so build scripts are approved and packaging works without a manual `pnpm approve-builds`. |
||
|---|---|---|
| .github/workflows | ||
| apps | ||
| assets | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| build-electron.sh | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| Dockerfile.qdrant | ||
| google-setup.md | ||
| LICENSE | ||
| README.md | ||
| start.sh | ||
Rowboat
Open-source AI coworker that turns work into a knowledge graph and acts on it
Rowboat connects to your email and meeting notes, builds a long-lived knowledge graph, and uses that context to help you get work done - privately, on your machine.
You can do things like:
Build me a deck about our next quarter roadmap→ generates a PDF using context from your knowledge graphPrep me for my meeting with Alex→ pulls past decisions, open questions, and relevant threads into a crisp brief (or a voice note)- Track a person, company or topic through live notes
- Visualize, edit, and update your knowledge graph anytime (it’s just Markdown)
- Record voice memos that automatically capture and update key takeaways in the graph
Download latest for Mac/Windows/Linux: Download
⭐ If you find Rowboat useful, please star the repo. It helps more people find it.
Demo
Installation
Download latest for Mac/Windows/Linux: Download
All release files: https://github.com/rowboatlabs/rowboat/releases/latest
Google setup
To connect Google services (Gmail, Calendar, and Drive), follow Google setup.
Voice input
To enable voice input and voice notes (optional), add a Deepgram API key in ~/.rowboat/config/deepgram.json
Voice output
To enable voice output (optional), add an ElevenLabs API key in ~/.rowboat/config/elevenlabs.json
Web search
To use Exa research search (optional), add the Exa API key in ~/.rowboat/config/exa-search.json
External tools
To enable external tools (optional), you can add any MCP server or use Composio tools by adding an API key in ~/.rowboat/config/composio.json
All API key files use the same format:
{
"apiKey": "<key>"
}
What it does
Rowboat is a local-first AI coworker that can:
- Remember the important context you don’t want to re-explain (people, projects, decisions, commitments)
- Understand what’s relevant right now (before a meeting, while replying to an email, when writing a doc)
- Help you act by drafting, summarizing, planning, and producing real artifacts (briefs, emails, docs, PDF slides)
Under the hood, Rowboat maintains an Obsidian-compatible vault of plain Markdown notes with backlinks — a transparent “working memory” you can inspect and edit.
Integrations
Rowboat builds memory from the work you already do, including:
- Gmail (email)
- Google Calendar
- Rowboat meeting notes or Fireflies
It also contains a library of product integrations through Composio.dev
How it’s different
Most AI tools reconstruct context on demand by searching transcripts or documents.
Rowboat maintains long-lived knowledge instead:
- context accumulates over time
- relationships are explicit and inspectable
- notes are editable by you, not hidden inside a model
- everything lives on your machine as plain Markdown
The result is memory that compounds, rather than retrieval that starts cold every time.
What you can do with it
- Meeting prep from prior decisions, threads, and open questions
- Email drafting grounded in history and commitments
- Docs & decks generated from your ongoing context (including PDF slides)
- Follow-ups: capture decisions, action items, and owners so nothing gets dropped
- On-your-machine help: create files, summarize into notes, and run workflows using local tools (with explicit, reviewable actions)
Live notes
Live notes are notes that stay updated automatically. You can create one by typing '@rowboat' on a note.
- Track a competitor or market topic across X, Reddit, and the news
- Monitor a person, project, or deal across web or your communications
- Keep a running summary of any subject you care about
Everything is written back into your local Markdown vault. You control what runs and when.
Bring your own model
Rowboat works with the model setup you prefer:
- Local models via Ollama or LM Studio
- Hosted models (bring your own API key/provider)
- Swap models anytime — your data stays in your local Markdown vault
Extend Rowboat with tools (MCP)
Rowboat can connect to external tools and services via Model Context Protocol (MCP). That means you can plug in (for example) search, databases, CRMs, support tools, and automations - or your own internal tools.
Examples: Exa (web search), Twitter/X, ElevenLabs (voice), Slack, Linear/Jira, GitHub, and more.
Local-first by design
- All data is stored locally as plain Markdown
- No proprietary formats or hosted lock-in
- You can inspect, edit, back up, or delete everything at any time