Open-source AI coworker, with memory https://www.rowboatlabs.com
Find a file
Ramnique Singh ae296c7723 serialize knowledge file writes behind a per-path mutex
Concurrent track runs on the same note were corrupting the file. In a
fresh workspace, four tracks fired on cron at 05:09:17Z (all failed on
AI_LoadAPIKeyError, but each still wrote lastRunAt/lastRunId before the
agent ran) and three more fired at 05:09:32Z. The resulting Today.md
ended with stray fragments "\n>\nes-->\n-->" — tail pieces of
<!--/track-target:priorities--> that a mis-aimed splice had truncated —
and the priorities YAML lost its lastRunId entirely.

Two compounding issues in knowledge/track/fileops.ts:

1. updateTrackBlock read the file twice: once via fetch() to resolve
   fenceStart/fenceEnd, and again via fs.readFile to get the bytes to
   splice. If another writer landed between the reads, the line indices
   from read #1 pointed into unrelated content in read #2, so the
   splice replaced the wrong range and left tag fragments behind.

2. None of the mutators (updateContent, updateTrackBlock,
   replaceTrackBlockYaml, deleteTrackBlock) held any lock, so
   concurrent read-modify-writes clobbered each other's updates. The
   missing lastRunId was exactly that: set by one run, overwritten by
   another run's stale snapshot.

The fix: introduce withFileLock(absPath, fn) in knowledge/file-lock.ts,
a per-path Promise-chain mutex modeled on the commitLock pattern in
knowledge/version_history.ts. Callers append onto that file's chain
and await — wait-queue semantics, FIFO, no timeout. The map self-cleans
when a file's chain goes idle so it stays bounded across a long-running
process.

Wrap all four fileops mutators in it, and also wrap workspace.writeFile
(which can touch the same files from the agent's tool surface and
previously raced with fileops). Both callers key on the resolved
absolute path so they share the same lock for the same file.

Reads (fetchAll, fetch, fetchYaml) stay lock-free — fs.writeFile on
files this size is atomic enough that readers see either pre- or
post-state, never corruption, and stale reads are not a correctness
issue for the callers that use them (scheduler, event dispatcher).

The debounced version-history commit in workspace.writeFile stays
outside the lock; it's deferred work that shouldn't hold up the write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 11:11:33 +05:30
.github/workflows Upgrade GitHub Actions for Node 24 compatibility 2026-02-13 09:19:03 +00:00
apps serialize knowledge file writes behind a per-path mutex 2026-04-21 11:11:33 +05:30
assets Readme updates (#58) 2025-04-03 23:35:15 +05:30
.env.example Run mongodb in docker 2025-04-07 13:30:27 +05:30
.gitattributes Mega UI revamp 2025-04-03 17:56:31 +05:30
.gitignore update .gitignore 2026-04-13 09:45:43 +05:30
build-electron.sh wip-electron 2026-01-16 12:05:33 +05:30
CLAUDE.md Add tracks — auto-updating note blocks with scheduled and event-driven triggers 2026-04-14 13:51:45 +05:30
docker-compose.yml merge job workers 2025-08-17 11:06:53 +05:30
Dockerfile.qdrant improve embedding index docs and setup 2025-05-09 09:38:09 +05:30
google-setup.md feat(oauth): switch Google OAuth from PKCE to authorization code flow with client secret 2026-04-10 00:43:34 +05:30
LICENSE Fill license placeholder 2025-01-31 16:29:39 +05:30
README.md Revise voice input/output and tools integration sections 2026-04-08 17:14:08 +05:30
start.sh Revert auth related changes to start.sh 2025-09-16 16:55:29 +04:00

rowboat-github-2

rowboatlabs/rowboat | Trendshift

Website Discord Twitter Y Combinator

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 graph
  • Prep 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 (its 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

Demo

Watch the full video


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

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 dont want to re-explain (people, projects, decisions, commitments)
  • Understand whats 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 its 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