One board for the work you do with AI. Claude Code and Codex already write down everything they do, in files on your disk. Nothing reads them together. Plancia does: every open task from both on one board, a spoken recap of the day that ends with what is worth doing next, and one place to send the work back.
Website: plancia.
Local-first: no telemetry, no account, no server of ours. The only thing that
goes out is the work you explicitly hand to an agent, and it goes through the
claude or codex command already on your machine, under your own
subscription. No dependencies to install: Python 3 and its standard library,
Swift for the app.
| source | where | what it gets |
|---|---|---|
| Claude Code sessions | ~/.claude/projects/**/*.jsonl |
date, project, opening prompt, turns, tools, tokens |
| Claude memory | ~/.claude/projects/*/memory/*.md |
project descriptions, [[wiki]] links |
| skills, plugins, routines | ~/.claude/skills, plugins, scheduled-tasks |
what your Claude Code can do |
| GitHub | gh repo list, recent commits |
repos, commits, real material for posts |
| local git | your code roots | branch, uncommitted changes |
| Codex sessions and goals | ~/.codex/sessions, goals_1.sqlite |
the same, plus what Codex is stuck on |
| Claude Code task lists | ~/.claude/tasks/<session>/*.json |
what is open right now, per session |
| session hooks | SessionStart, SessionEnd |
which sessions are open right now |
Sources are never modified. Plancia reads them and stays out of the way.
See docs/NOVITA.md for what changed recently and why.
git clone https://github.com/nerln/plancia.git ~/dev/plancia
cd ~/dev/plancia
./bin/plancia install # command, MCP server, hooks, skills, autostart
./bin/plancia init # builds your project map from repos, folders, memory
./mac/build.sh --install # builds Plancia.app into /Applicationsplancia uninstall puts everything back. Your data stays in ~/.plancia/.
The app. A native window, a menu bar item, and the voice. It supervises the
backend, so there is nothing to start by hand. plancia://recap,
plancia://jarvis, plancia://ask?q=…, plancia://open?view=projects and
plancia://pdf are
URL actions you can bind to a system shortcut, Raycast or Shortcuts.
Claude Code and Codex. Twenty plancia_* MCP tools in every session of both, a SessionStart
hook that hands Claude your current state as opening context, and two skills that
tell it when to read from Plancia and when to write back.
The terminal. plancia recap --speak, plancia ask "what did I ship this week?", plancia task add, plancia search, plancia projects.
Plancia collects the day from real data, sessions and commits and tasks opened and closed and posts and what each project is waiting on, and turns it into something written to be heard: short sentences, no lists, no markdown, no file paths read out loud.
Two engines for the text. The template one is deterministic, costs nothing and
always works. The other passes the same data to Claude Code in headless mode
(claude -p) and gets a better told version in about eight seconds. If Claude
does not answer in time, the template takes over and you never notice.
Two engines for the voice. Voicebox if its local backend is up, so you get your own cloned voice. Otherwise the macOS system voices, which are always there, need no setup and start instantly. Both handle Italian, English, Spanish, French, German and Portuguese.
plancia recap --speak # today, out loud
plancia recap --lang en # in English
plancia ask "where did I leave the transcription pipeline?" --speak
plancia daily on 08:45 # every morning, as a notification
plancia daily on 08:45 --voce # every morning, out loudAsking a question goes through Claude Code with your Plancia context attached, so the answer is grounded in what actually happened, not in a guess.
The recap does not stop at the facts. Plancia looks for signals in the data and turns them into proposals, each with an action already prepared: a failed run to retry, a Codex goal out of quota, files uncommitted since yesterday, an approved post that never went out, a project whose declared next step has gone stale. Proposals only ever come from signals, never from a model's hunch, so a quiet day gives you a short recap instead of an invented suggestion. Say "do it", or "the second one", and it runs.
Hold nothing, press nothing. ⌥Space anywhere, or plancia://jarvis, opens a
panel that listens continuously and works out you have finished speaking from the
silence, not from a key you keep held down.
What it hears goes two ways. Phrases it can recognise with certainty (open a
view, note a task, close one, re-read the sources, read me the recap) run
locally in a tenth of a second. Everything else goes to Claude Code in headless
mode with the plancia_* tools open, so it can actually add the task, update the
project or search the archive, not just answer about it.
There is a text field at the bottom of the panel: it covers the case where the microphone is unavailable, and lets you correct a misheard sentence by typing instead of repeating it.
The microphone stays open while it answers, so you can cut it off by simply speaking again. Echo cancellation on the input node is what makes that possible: without it, it hears its own voice and interrupts itself. Say "cancel" to stop a running dispatch, "stop" to close the panel. When a dispatched run finishes it tells you out loud, even if you have moved on to something else.
plancia jarvis "remind me to write the migration note" # same thing, typedClaude Code has had voice input since March 2026: you hold the spacebar and dictate. It is input only, and by design there is no hands-free mode. This is the other half: it speaks back, and it acts.
Claude Code keeps its task list in one folder, Codex keeps its goals in a
different database, Plancia has its own. None of the three knows the other two
exist. The board reads all of them, normalises the states to open, in progress, blocked, done, gone, and shows one list.
From any row you can write how you want the work done and dispatch it:
plancia lavagna # the board, in the terminal
plancia manda "rerun the ablation" --agente codex --progetto atlas
plancia lanci # how the runs wentThe default mode is proposta: the agent reads and reports without touching a
file. --modo esegui lets it write, and that is a choice you make every time.
Runs are recorded with their outcome, tokens and cost.
Other tools should not have to poll a database to know something happened. Every
meaningful event is appended to ~/.plancia/eventi.jsonl, one JSON line, schema
plancia.evento/1:
{"schema":"plancia.evento/1","id":"9f2c…","ts":"2026-08-02T09:14:22Z",
"tipo":"lavoro.completato","titolo":"Rerun the ablation","progetto":"atlas",
"origine":"cantiere","dati":{"agente":"codex","modo":"esegui","token":22800}}Types: lavoro.avviato|completato|fallito, task.creato|chiuso,
post.pubblicato, progetto.archiviato|aggiornato, riepilogo.pronto. A
consumer keeps the id of the last event it saw and asks for what came after, with
plancia eventi --dopo <id> or GET /api/eventi. The file is append only and
rotates at 5 MB.
Plancia reads Codex sessions from ~/.codex/sessions alongside Claude Code's,
and registers its own MCP server inside ~/.codex/config.toml. Both agents see
the same projects, the same tasks, the same twenty tools. The Agents view shows
who worked on what and when the two handed work to each other, inside the
Archive.
Every claude -p costs about five seconds of startup before it even thinks. In a
spoken conversation that is five seconds of silence per question. Plancia takes
three routes, in this order:
| route | when | cost |
|---|---|---|
| commands | open a view, note a task, close one, archive a project | 0.1 s |
| data answers | how many tasks, what should I pick up, how much did I work | 0.1 s |
| Claude, kept warm | anything else, with the plancia_* tools open |
2.7 s |
The Claude process stays alive between questions instead of being restarted, so only the first one pays the startup, and the panel warms it up the moment you open it. The daily recap is precomputed at the end of every cold pass: asking for it costs 20 ms instead of ten seconds.
bin/plancia-hook --prova prints what it would hand to Claude without queueing
anything: testing the hook must not leave a session in the archive that never
happened.
sources ──▶ sync ──▶ SQLite ──▶ briefing.md · recap · REST · voice
Two rhythms, because reading twenty repos to find out you just opened a session is a waste:
- hot, every two minutes, ~0.01 s: the hook queue and the new tail of the transcripts. What you are doing right now.
- cold, every thirty minutes, ~1.3 s: memory, skills, repos, local git, project housekeeping, search index, recap.
plancia flusso prints every source, where it comes from, which pass reads it
and how fresh it is.
A project born from a folder you worked in once, three weeks ago, is not an active project: it is a memory. Plancia archives it on its own after two weeks if it has no repo, no memory note and fewer than three sessions. Anything you declared yourself is never touched. By voice: "archive the video project", or "the Ard footage is finished".
A project is whatever you say it is: a GitHub repo, a folder, a memory note, or
all three. plancia init proposes a map from what it finds; you correct it in
~/.plancia/seed.json. Sessions that run from a generic folder get attributed by
keyword, and re-attributed on every sync as you refine the keywords.
Transcripts are read by byte offset, not by line. They are hundreds of megabytes and they grow. Plancia keeps the offset of every file and only reads the new tail; lines over 256 KB (tool results) are never parsed, only probed. A full re-read of 60 sessions costs about seven seconds.
A record's type is matched in full. Inside message.content there are other
type fields (text, tool_use, tool_result) that come before the real one,
so searching for "type":" gives you the wrong answer. Plancia searches for
"type":"assistant" and "type":"user" whole.
bin/plancia command
bin/plancia-mcp MCP server (stdio)
bin/plancia-hook session hook, 20 ms
plancia/store.py schema and data access
plancia/ingest.py reading the sources
plancia/recap.py the daily recap
plancia/voice.py speech, playback, listening
plancia/briefing.py what Claude sees
plancia/actions.py writes, shared by HTTP and MCP
plancia/api.py local server and REST
plancia/mcp.py JSON-RPC over stdio
plancia/lavagna.py the unified board
plancia/cantiere.py dispatching work to an agent
plancia/proposte.py what is worth doing, from signals
plancia/eventi.py the append only event log
site/ the website, published on GitHub Pages
mac/Sources/main.swift the macOS app
web/ dashboard, no framework, no build step
Data lives in ~/.plancia/: plancia.db (SQLite), seed.json, token,
briefing.md, audio/. Keep it out of any synced folder: a SQLite file inside
Dropbox or Drive will corrupt.
Today (the recap, the rhythm, the proposals, the tasks), Board, Projects, Social, Archive (sessions, agents, memory, skills). Everything else goes through ⌘K. On first run a five step guide explains the parts that are not obvious, and it stays available under "Guide".
macOS 13 or later, Python 3.9+, Claude Code. Xcode command line tools only if you
want to build the app. gh is optional and only used to read your repos.
The server listens on loopback only. HTTP writes require the token in
~/.plancia/token; the dashboard receives it from the server inside the page.
Reads are open: it is your data, already on your disk.
git config core.hooksPath .githooksTurns on the hook that runs python3 tools/prova.py before every push: eighty
two checks in about ten seconds, against a throwaway archive that never touches
yours.
GPL-3.0-or-later. See LICENSE and COPYRIGHT. Versions up to 0.2.0 were MIT and stay MIT.
Building from source is free and always will be. A signed and notarised build, which opens with a double click, is pay what you want from €5 on the website. It is the same program: what you pay for is the Apple certificate, the notarisation and the maintenance. See docs/RILASCIO.md for how a release is cut.


