Skip to content
nerlnPublic

About

One board for every task Claude Code and Codex have open, a spoken daily recap, and one place to send the work back. No account, no telemetry.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Plancia

collaudo

Claude Code and Codex already write down everything they do, in files on your disk. Nothing reads them together. Plancia does: one row per project tells you what to do next, Resume reopens the conversation that wrote the task, and a spoken recap of the day closes with what is worth doing. The rest stays folded, one click away.

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.

Italiano

Plancia for Mac: Today, with one row per project

Every screenshot in this README is the app running on the demonstration archive (tools/demo-data.py), never on anyone's real data.

The Mac app

Plancia 2.0 is a native SwiftUI app for macOS 26 or later: the system controls and the Liquid Glass materials, a sidebar with six sections, the system search field in the toolbar and an inspector on the right. No logo, no web page inside a window.

Memory as a map. Every note is a node, coloured by kind, and every project (or kind of note, for the ones that belong to none) is an island with its name on the edge. The links between islands are drawn as ribbons, so you see at a glance which projects share what you know. Hover lights a note and its neighbours, drag a node and its island follows, pinch or scroll to zoom. The physics runs off the main thread and stops by itself when the picture is still.

The memory map: islands per project, ribbons for the links between them

Zoom in and the nodes carry a short human title instead of their file name:

One island up close, with the titles of its notes

Wood. Settings has a Style: System, or Wood, a modern take on the skeuomorphic dashboard of the app icon. Mahogany boards in the sidebar and under the toolbar, solid brass for the selection, warm paper for the content. Controls and glass stay the system's.

The Wood style

Light and dark, and text size on ⌘+, ⌘- and ⌘0:

The memory map in dark

The sections have their own pictures further down: Search, Jarvis, All tasks and Projects.

What it reads

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.

Install

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 /Applications (macOS 26 or later)

plancia uninstall puts everything back. Your data stays in ~/.plancia/.

Windows and Linux

macOS comes first: that is where the native app lives. The rest of Plancia is Python and a local web server, so it also runs on Windows and Linux, with the dashboard in your browser. You need Python 3.9+ and Claude Code or Codex.

Windows (PowerShell):

git clone https://github.com/nerln/plancia.git $HOME/plancia
cd $HOME/plancia
python bin/plancia install       # command, MCP server, hooks, skills, autostart
python bin/plancia init          # builds your project map
python bin/plancia serve --open  # the dashboard, in your browser

Linux:

git clone https://github.com/nerln/plancia.git ~/dev/plancia
cd ~/dev/plancia
python3 bin/plancia install
python3 bin/plancia init
python3 bin/plancia serve --open

install also writes a plancia command. On Windows it is a plancia.cmd shim in %LOCALAPPDATA%\Plancia\bin, and it tells you to add that folder to your PATH if it is not there yet; bin/plancia.cmd does the same job from inside a clone. On Linux it is a link in ~/.local/bin. plancia uninstall puts everything back. If python is not on your PATH (the python.org installer does not add it by default, and python can be the Microsoft Store stub), use py -3 bin/plancia install instead. pip install is not a supported route yet: the package does not carry the dashboard files or the bin/ scripts, so use the clone.

What works the same: the dashboard, the plancia_* MCP tools in Claude Code and Codex, the session hooks and the memory recall, the skills, search, the recap, Resume (it opens a terminal in the right folder), and starting the server at every login.

What each system uses underneath:

macOS Windows Linux
start at login, daily recap launchd Task Scheduler, or the Startup folder if that is refused systemd --user, or ~/.config/autostart
Resume opens Terminal Windows Terminal, else a new console window the first of x-terminal-emulator, gnome-terminal, konsole, xterm
clipboard pbcopy clip wl-copy, xclip or xsel
spoken recap say the built-in speech synthesizer espeak-ng (or espeak) and an audio player
notification osascript PowerShell balloon notify-send, if installed

On Windows and Linux there is no native app: open http://127.0.0.1:7773 in Chrome or Edge and choose Install Plancia. It gets its own window and icon, and it still opens with the server off, showing the last state it saw. Safari on macOS does the same with Add to Dock.

What does not exist outside macOS: the native app, its menu bar item, the plancia:// URL actions and the hands-free voice panel. plancia jarvis "..." from a terminal still works. If a piece is missing on your machine the rest carries on: no notification tool means no notification, and no clipboard tool means nothing is copied. With no speech engine, plancia say, plancia voice prova, plancia recap --speak, plancia ask --speak and plancia jarvis --speak say so and what to install, the MCP speak action answers letto: false with the reason, and plancia doctor reports the voice as missing. The dashboard keeps working too: the recap, "Ask" and Jarvis answer with the text and a voce: null field plus a nota_voce explaining that there is no speech engine, and only the playback is skipped ("Listen" shows that note instead of a generic error). Outside macOS the voice engine is reported by its real name (System.Speech, espeak-ng) and the voice list comes from it. On Windows, Resume needs Windows Terminal for a lost task when claude is a .cmd file (an npm install): its multi-line prompt cannot be handed to cmd.exe safely, and Resume says so instead of opening a broken command. On Windows the server starts at login but is not restarted after a crash, and its errors are not logged (launchd on macOS and systemd on Linux do restart it). A second plancia serve while the login one is running says so (and with --open opens the browser on it) instead of failing on the busy port. plancia esporta --apri opens the file with the system's own opener (open -R, os.startfile, xdg-open). Folders that hold projects without being one (an external disk, another projects folder) go in config.json under contenitori, a list of paths, next to the ones Plancia recognises by itself (~/dev, ~/Siti, the Google Drive folders). On macOS that includes the disks you used to add by hand: an external disk is a container only if it is listed there ("contenitori": ["/Volumes/Disco/dev"]), and plancia doctor prints the containers in use. Start at login and the daily recap never load launchd, Task Scheduler or systemd jobs from a throwaway environment: if the process HOME is not the user's real home (or PLANCIA_HOME points outside it) the files are written but not loaded ("file scritti, non caricati (HOME di prova)"). PLANCIA_AUTOSTART_FORZA=1 forces the commands, for a machine where they are stubs. The commands Plancia builds for each system are covered by the suite, but Windows and Linux have had far less real use than macOS: plancia doctor tells you what is connected.

The dashboard in the browser

The same data in a browser, on any system with Python: python3 bin/plancia serve --open (python bin/plancia serve --open on Windows). It follows the Mac app: system fonts, six sections in a sidebar, Today as one reading column, Tasks as a table with a detail panel, Memory with a physics graph on canvas, search in the top field. It installs as a web app from the browser menu. This is what Windows and Linux use, and a Mac that cannot run the 2.0 app.

Today in the browser

Tasks in the browser, with the detail panel

The memory graph in the browser

Search in the browser

The three ways in

The app. A native SwiftUI window (2.0, macOS 26 or later): a sidebar with Today, Tasks, Projects, Social, Memory and Archive, the system search field, an inspector on the right for whatever you select, and Settings for language, appearance and style. Style is System (the standard macOS look) or Wood, a warm skeuomorphic one with mahogany boards in the sidebar and brass for the selection, drawn from the app icon. Text size follows ⌘+, ⌘- and ⌘0 (seven steps, 85% to 125%). Memory has a third mode, Map: every note as a node in a physics graph you can drag, with levels 1, 2 and All and a smooth zoom, running off the main thread. Plus a menu bar item and the voice panel. It supervises the backend, so there is nothing to start by hand. On macOS 13 to 15 the 1.1.0 app is the last one that runs; the dashboard in the browser works everywhere. 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. Seven 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. Seven and not twenty: the six that get used stay exposed, the rest sit behind one plancia tool you call with azione. Tool schemas are paid for in every single request of a session, so the surface is the bill. Measured: 1195 tokens per Claude Code session and 1020 per Codex session, down from 2870 and 2196.

The terminal. plancia recap --speak, plancia ask "what did I ship this week?", plancia task add, plancia cerca "a phrase you remember", plancia projects.

Search: inside what was said

Transcripts are the largest thing you own and the hardest to get back into. A session title tells you nothing six weeks later; the sentence you are trying to find is somewhere in the middle of a conversation.

Plancia keeps an FTS5 index over the prose of every turn, yours and the agent's, from Claude Code and Codex. Tool results stay out on purpose: they are most of the bytes and almost never the thing you remember. On this machine that is 13,000 turns from 1,287 transcripts, 20 MB indexed out of 979 MB on disk, rebuilt from scratch in 5 seconds and kept current incrementally, which costs one stat per unchanged file.

Every hit comes back verbatim with the file and the line it came from, so you reopen the moment instead of reading a summary of it.

Search: tasks, sessions, memory and the turns themselves

plancia cerca "the blending denominator"
plancia cerca "cookies" --project molo

In the dashboard, / opens search from any view; chips above the results count the hits per project across the whole index, not just the page. In Claude Code and Codex it is plancia_search.

What a session actually worked on

A session used to land in the project of the folder it was opened from. That works for Codex, which is opened inside the project. It does not work for Claude Code: measured on this machine, 199 sessions out of 587 were opened from the Drive root, from ~/dev or from the home folder, places you work on everything from.

Plancia now also looks at what the session touched: the files in its tool_use blocks and the absolute paths inside Bash commands, counted per project folder. If the folder it was opened from says nothing, the most touched folder wins; if that folder is already a project, it is kept unless 70 percent of the paths are somewhere else. Every row carries the inferred folder and the reason, so the attribution can be checked instead of trusted.

plancia sessioni                         # the catalogue, by project
plancia sessioni --progetto molo --giorni 30
plancia sync --riattribuisci             # recompute the whole archive

A tilde at the end of a row, and the "inferred from paths" note in the dashboard, mark the sessions attributed this way. Plancia's own internal calls and throwaway sessions stay out of the way: --tutte shows them.

The daily recap

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 kinds of voice. A local neural one when it answers: Kokoro (not installed by default, see Jarvis below), then Pocket, then Voicebox if its backend is up, which is how you get your own cloned voice. Otherwise the macOS system voices, which are always there, need no setup and start instantly. The system voices handle Italian, English, Spanish, French, German and Portuguese; each neural engine covers the languages its own voices do.

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 loud

Asking a question goes through Claude Code with your Plancia context attached, so the answer is grounded in what actually happened, not in a guess.

It ends with a decision

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.

Next up

One row per active project, on Today, next to the recap: its first open task, or its declared next step when nothing is open, grouped by area, sorted by deadline and then by last activity. Up to seven rows show per group; the rest sit behind an "N more". It needs the area map from plancia riordina to group by anything but a flat list.

Jarvis

⌥Space anywhere opens a glass panel and turns the microphone on. A waveform follows your voice while it listens, the answer scrolls in as it arrives, and it starts speaking with the first sentence, not when the whole answer is done.

Jarvis asking for confirmation before it sends an agent

Jarvis reads, and proposes. The model behind the panel is read-only: the tools that write are denied by name, not just left off a list. Phrases like "note a task", "I did that", "archive Atlas", "do it" or "resume task 4" never run on their own. Each one becomes a card that says exactly what would happen (which agent, in which folder, whether it may edit files, which session it picks up) and nothing happens until you press Confirm on the card. Saying "yes" out loud does not confirm. Esc or Cancel throw the card away, and so does closing the panel. The only things that happen without a card are opening a view and changing how fast it speaks.

The microphone opens only when you ask, with the shortcut or the microphone button, and you can see it: an orange dot and "Microphone on" in the panel, next to the system's own indicator. Recognition runs on the Mac. If dictation for your language is not installed for on-device use, it says so and you type; audio never goes to a server. It closes by itself after each sentence and reopens only if you turn on "Continuous conversation" in the panel menu. Esc or Stop ends everything at once.

The voice is a neural one when there is one: Kokoro first, then Pocket, then Voicebox, all running locally, sentence by sentence, so the second sentence is being made while the first plays (the first sentence is cut at its commas, so the sound starts sooner). Without one it uses the enhanced or premium voices installed on the Mac and says so at the bottom of the panel. It never uses the basic robotic voice: with none installed it stays text-only and tells you where to download one.

Kokoro is not installed by default. plancia voce installa builds a Python environment under <PLANCIA_HOME>/voce, tells you it will download about 354 MB of model files, and asks before doing it. It then runs as one warm background process of roughly 450 to 700 MB (about 1 GB for a moment on a long sentence) that starts when Jarvis opens and quits after 5 minutes of silence; if it dies or is too slow, the next engine speaks and the panel footer says so. The voice per language is voce_kokoro in config.json (defaults: if_sara for Italian, af_heart for English, ef_dora for Spanish; im_nicola is a male Italian one). plancia voce prova says which engine Jarvis would use and why, without playing anything. Tried on macOS only.

The text field at the bottom covers the case where the microphone is unavailable.

plancia jarvis "remind me to write the migration note"   # shows the card, asks [y/N]

The terminal and the dashboard (Windows and Linux) use the same rules. There is one Jarvis, read-only: the old second one, which kept a model with the write tools open and ran what you typed, is gone. plancia jarvis prints the card and asks you to confirm at the keyboard; without a real terminal (a script, a pipe, another agent calling it) it never confirms. On the dashboard the card shows up with Confirm and Cancel, and the Relaunch button goes through it too.

Claude 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 can act once you confirm.

All tasks

All tasks, with Resume in the inspector

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. This view reads all of them, normalises the states to open, in progress, blocked, done, gone, and shows one list.

Resume is the first thing a row offers. A task carries the id of the session that wrote it, so the button on its row does not relaunch anything from scratch: it reopens the actual conversation, in one of three states. Alive, and Resume copies to the clipboard the message to paste into the conversation that is already running (resume task 42 of Plancia: <title>): there is nothing to launch. Closed, and pressing Resume opens a visible Terminal on its own, running claude --resume <id> (or codex resume <id>) in the task's own folder; Plancia never touches a transcript from a second process. Lost, because the session was never recorded or has expired, and then it says so instead of pretending, and starting over, with the context written by hand, is the only option left.

plancia lavagna                          # every open task, in the terminal
plancia riprendi 42                      # resume task 42, in its own state
plancia riprendi 42 --apri               # do it now, exactly what the button does
plancia lanci                            # how a background dispatch went

Sending work off in the background is the other, secondary path, for when resuming is not what you want: plancia riprendi 42 --background --scrive --istruzioni "rerun the ablation" runs it unattended, inside that task's own session (claude -p --resume <id>, codex exec resume <id>, same id, its own folder), and records the outcome. It never opens a new session behind your back: if the session is still open somewhere nothing starts and you get the message to paste (--copia asks for a copy instead), and only when the session is really lost does a new one start, said before it does. The same goes for the Relaunch and Resume buttons, the MCP tool and Jarvis. If the ChatGPT/Codex desktop app holds a Codex thread open, the run stops and says so instead of failing silently. The default is read-only; --scrive lets the agent write, and that is a choice you make every time. plancia manda "rerun the ablation" --agente codex --progetto atlas is the older alias for the same thing without a task id: it still works but prints a deprecation warning on stderr and is going away in a future release. The run lives inside that command, so it waits for the agent to finish before it exits. Inside Claude Code and Codex, the same resume lives behind the plancia tool with azione="riprendi" and the task's id.

The event log

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.

Two agents, one archive

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 tools. The Agents view shows who worked on what and when the two handed work to each other, inside the Archive.

Where the time goes

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.

The data flow

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, ~40 ms: the hook queue and the new tail of the transcripts. What you are doing right now.
  • cold, every thirty minutes, ~1.5 s: memory, skills, repos, local git, project housekeeping, both search indexes, recap.

The cold pass used to take 40 seconds, and 20 of those were one folder. git status inside a cloud-synced folder has to check every tracked file with the file provider: measured cold on a 681 file repo, 2 minutes 51 seconds, against 10 ms for a repo on disk. Folders are now read eight at a time, a folder that does not answer within four seconds is remembered and left alone for six hours, and a status that never arrived is stored as unknown rather than as clean.

plancia flusso prints every source, where it comes from, which pass reads it and how fresh it is.

Projects end

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".

Projects

Projects grouped by area, with the selected one on the right

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.

Areas

A project map is only useful if it can be corrected, and correcting 122 projects one at a time never happens. plancia riordina --proponi computes a map of parents for every project (an area like a thesis, or a real repo with its worktrees) and writes it to a file instead of the database, so you can read it before anything changes.

plancia riordina --proponi                    # writes the proposed map to a file
plancia riordina --mostra <file>              # prints it as a table
plancia riordina --applica <file>             # assigns the parents, states and mergers in it
plancia riordina --annulla <batch>            # puts back exactly what it changed

The file is plain JSON, one row per project, and you can edit it by hand or have an agent that has studied your projects write it. Beyond padre (the parent's key) a row can carry:

[
  {"chiave": "old-experiment", "inglobato_in": "atlas",
   "motivo": "the code now lives inside the atlas folder"},
  {"chiave": "thesis-draft", "stato": "concluso",
   "motivo": "handed in last June"}
]
  • stato: attivo, archiviato or concluso. Missing means the state is left alone.
  • inglobato_in: the project this one was folded into. It means parent = that project, state archiviato, and a line "Inglobato in atlas: " added to the end of the project's summary. If that project cannot be a parent (it is automatic, or is itself a child) the parent is left alone but the state and the line are still written, and --applica says so.
  • motivo: the reason, one sentence. It is required on every row that has a stato or an inglobato_in; --applica refuses a row without one and --mostra marks it [DA CORREGGERE].

--mostra prints all of it as one table (key, parent, rule, state, reason). A row is all or nothing: if the parent is refused, the state does not change (an inglobato_in is the one exception, see above). A file that does not parse is one line of error, not a traceback, and --applica exits with 1 when it refused a row. A manual project is only touched by a row that names it with a parent, a state or an inglobato_in; a project that is not in the file is never touched. The format is documented in full at the top of plancia/riordina.py.

Applying is one batch, and undoing it restores each project's previous parent, state and summary, not just a blank one. Undo works field by field and only where the field is still what the batch left: a state you changed by hand afterwards, or set with a later batch, is not overwritten. Today (the recap view) and Next up group projects by area once this map exists; before it does, they fall back to one flat list, so nothing breaks for a fresh install.

Compartments

Two groups of work on the same machine that must not see each other: a project shared with someone else, and the rest. compartimenti in ~/.plancia/config.json names one or more compartments (each with its cartelle and sessioni); everything else is the default one. Without it Plancia does what it always did.

With it, every object gets a compartment from the data it already has: a session from its id, its folder and its transcript; a task from the session that made it, or from its project; a project from its paths and the memory notes linked to it; a memory note from the file it lives in (Claude Code's automatic memory of a folder belongs to that folder's compartment). Then each surface shows only its own. The session briefing and the recall of notes "written in other folders" leave the other compartments out. The MCP server filters what it reads, and a write on another compartment's project, task or post is refused with a plain message. The dashboard is your view, not an agent's, so it shows everything but separated: a selector at the top picks the compartment (the default one first), every view follows it, and what you create there belongs there. ?compartimento=name in the address opens it on one.

A session with signs of two compartments sees nothing. This decides what Plancia shows; it is not a security boundary, same user and same disk.

The plancia command in a terminal works out its compartment the way the MCP server does, from CLAUDE_CODE_SESSION_ID and the current folder: a command run from a session of a named compartment sees that compartment only (board, events, runs, briefing, search, sessions, recap, ask, jarvis, export, and the rest), and a write on another compartment's project or task is refused. A human terminal with no session id and a current folder outside every named compartment is the default one and sees the default one; inside a named compartment's folder it sees that one. The dashboard's voice assistant works from the compartment picked in the selector, and from a named compartment a free-form question is answered with that compartment's data in the prompt, not by the warm process with the Plancia tools. A run started from a compartment belongs to it, even when its project has no folder. Commands that administer all of Plancia (init, riordina --applica, riprendi --backfill) are refused from a named compartment. With compartments on, briefing.md is not written (one file per compartment instead) and it comes back when they are removed.

Limits worth knowing: folder rules compare POSIX paths (starting with / or ~), so compartments and the guard below are for macOS and Linux only. On Windows they are switched off, on purpose and in the code: a compartimenti or guardiano entry in config.json is ignored, every session sees everything (the briefing is the plain one), the guard exits at once without denying anything and says "not supported on Windows" once per session, and plancia doctor and plancia guardiano say so. The daily recap that a scheduler runs has no session, so it is the default compartment's.

Two decisions worth knowing about

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 430 sessions costs 1.5 seconds, and rebuilding the turn index from scratch on top of it another 5.

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.

Layout

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/turni.py       the full text index over what was said
plancia/recap.py       the daily recap
plancia/voice.py       speech, playback, listening
plancia/briefing.py    what Claude sees
plancia/compartimenti_viste.py  what each compartment 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/          the macOS app (SwiftUI, macOS 26 and later)
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.

Seven surfaces

Today (the recap, the rhythm, the proposals, and Next up: one row per project, grouped by area, with what to resume), Search, All tasks, Projects, Social, Memory, Archive (sessions, agents, skills). Everything else goes through ⌘K. On first run a guide explains the parts that are not obvious, and it stays available under "Guide".

Requirements

Python 3.9+ and Claude Code, on macOS 13 or later, Windows or Linux (see above). The native Mac app needs macOS 26 or later, and the Xcode command line tools to build it. gh is optional and only used to read your repos.

The native Mac app 2.0 is SwiftUI and needs macOS 26 or later. On macOS 13 to 15 stay on the 1.1.0 app, or use the dashboard in the browser (it installs as a web app). The web dashboard was redrawn in 2.0 to match the Mac app (system fonts, sidebar, tables with a detail panel, a physics graph for memory, five-step text size in Settings). The memory graph is drawn as islands: each note sits in its group (the project it belongs to, or the type for who-you-are and preferences notes), a group is a coloured region with a big name, and links between groups are bridges. From far away you read the groups, up close the note titles (the link text in the folder's MEMORY.md, or the first sentence of the description, never the slug). The server lays the map out once per memory fingerprint, in a separate low-priority process, and reuses it until notes or links change.

Security

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.

The compartment guard, and what it cannot see

bin/plancia-guardiano is an optional PreToolUse hook that keeps two groups of work apart on one machine (see plancia/compartimenti.py). It reads POSIX paths and shell commands, so it does nothing on Windows (see the limits above). It is a heuristic analyser of what a tool call says it will touch: a guard against incidents, and not a security boundary. It stops what an agent does without thinking, such as reading the other group's files, overwriting the guard's own config, or a recursive search that walks into a forbidden folder. It does not stop someone who is trying to get around it, and it does not claim to: a real boundary is a separate operating-system user or a container. Start it in solo-registro (log only), read the log, then decide.

What it does not see, honestly: paths built at run time inside programs and scripts that already exist (a script written in one call and run in another, a build, a test that opens files); downloaded or generated code that is then executed; child processes that start themselves and outlive the command (a daemon, a scheduled job, a watcher); third-party MCP tools whose file arguments it does not know by name; paths that travel through another channel (the clipboard, the local network, a database); a command it cannot finish analysing in two seconds (a nominated session is denied with "too complex to check in time, split it", the default session is allowed with a warning each time). The full list is in the docstring of plancia/compartimenti.py.

Contributing

git config core.hooksPath .githooks

Turns on the hook that runs python3 tools/prova.py before every push: 4954 checks in a few minutes, against a throwaway archive that never touches yours. They cover the schema, the board, the proposals, the search index, the recap, the MCP surface and its token budget, every read route of the HTTP API, the hook, the skills and a full install and uninstall into a fake home.

Licence and price

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.

About

One board for every task Claude Code and Codex have open, a spoken daily recap, and one place to send the work back. No account, no telemetry.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages