NEW  v2.32.0 — Themes from a link · a changelog and a privacy ledger

Agents write the code.
You keep the memory.

While Claude Code · Codex · Cursor write your code, Ocul-PM records every unit of work — shows you what actually changed as a local diff — and hands the pile back as standups, PR bodies and retrospectives. Local-first. No account, no server, no telemetry.

Get v2.32.0Free · macOS (Apple Silicon) Watch the keynote →

On Claude Code? Two lines in /plugin is another way in

Ocul-PM — find us on Product Hunt

Ocul-PM's Claude Code screen — a finished turn with edit diff cards and a turn receipt
A real screen. Claude Code, inside the app, edited a file — showed the diff — and wrote its own work journal.

Yesterday, your agent changed 3,000 lines.

Code has never been faster. Understanding has never been slower. Speed bought with memory — that is the trade of the agent era, and Ocul-PM is where it stops.

The record · the proof · the console

It looks like three tools.
It is one app.

A record that writes itself as your agents work. A proof that shows every change where it happened. And a console with the agent itself inside it.

01 · The record

Recording should be free.

The moment an agent finishes, the entry is already written — what changed and why, which agent ran it on which model, classified as bug, feature, refactor, error or chore, in markdown a human reads.

  • The Today brief — open it in the morning and yesterday is already organized; the standup is one copy button
  • Records become deliverables — PR bodies · weekly reports · AI retrospectives, each one button
  • Planner and discussions — a plan is a living document your agents keep up to date
Automatic work journal — entries grouped by agent and model
The automatic journal — all 112 of these entries, not one written by a person.
The Today daily brief — yesterday's work summarized with an activity flow
Today — the rear-view mirror becomes a steering wheel.
02 · The proof

Don't trust it. Look at it.

The files an agent claims it touched — check them as a local diff, inside the app, before you commit. Put it side by side with the journal and compare what was said with what actually changed.

  • Code map — know that "this touches 12 files" before the edit, not after
  • Three search modes — semantic (local embeddings) · symbol (AST) · text (exact match)
  • All local — the embeddings are computed here. Not one character of your code leaves
The change diff screen — a line-level local diff of what the agent changed
Change diff — before the commit, inside the app.
Code map — a dependency graph with change-impact analysis
Code map — dependencies you can see are dependencies you stop fearing.
03 · The console

So we brought
the agent inside.

The real Claude Code runs inside the app. Every step — reading files, editing them, running commands — arrives as a card, and since v2.11 the edit itself is drawn as a diff.

  • Approvals you can see — the command that will run and the lines that will change, in the card. The end of blind approval
  • Turn receipts — when it finishes, one line stays: "4 tools · 2m 14s"
  • ⌘J terminal — a dock on any screen, and the shell survives being pulled into its own window
An approval card with the diff of the pending change inside it
Visible approval — removed lines red, added lines green. Inside the card.
The ⌘J terminal dock open over another screen
⌘J — a terminal that does not make you leave the screen.
And all of it

The rest of the workshop
is already in the box.

Conversation import

Bring past chats in

Pick only what belongs to this project out of an export. Browsing the list is entirely offline and free.

Declarative config

Settings as one document

Rules, skills and automations as one YAML file. A teammate's document shows what would change before it applies.

Offline

Nothing goes quietly wrong

A fallback answer carries a badge, unreachable models are dimmed not hidden, and automations defer instead of failing.

Capability list

It stops re-reading

Reloading the whole plan, journal and rules on every question is over. The list once, the bodies on demand.

Recall gate

The past, only when asked

"What did I do last week" gets history. "What should I name this" does not. No AI is called to decide.

Rules in full

No more truncation

A 2,500-character cut once swallowed "never write secrets". Now three lines stay resident and the rest arrives whole.

Theme files

Build your own colors

Five baked-in palettes used to be all of it. Now you build one and trade it as .json — the built-ins use the same format, so the built-ins are the examples.

Live preview

The app is the preview

There is no preview box. Change one color and the whole app changes with it. Colors you did not touch stay untouched.

Project themes

Know where you are, by color

Bind a theme to a project and only that window wears it. Five repos open at once stop blurring together.

Watch automation

It records when your hands stop

It watches the folder, and when the edits go quiet it drafts what just happened. How long to wait is six tiers — 0.2s to 10min.

Provenance

You can see who wrote it

By hand · by agent · auto-draft · schedule · watcher · MCP — every entry carries its source. With one kind in the list, the filter row removes itself.

Firing diagnostics

It names the rules that never fired

Actual firings over 7 days, and the rules that never caught once. A carefully written rule quietly doing nothing is invisible otherwise.

Agent control

See which one is waiting

With four running, finding the one waiting on you meant clicking through windows. Now that session turns amber and "N waiting" takes you there.

Command blocks

See where it broke

Each command gets a status bar and failures are dotted down the right edge. ⌘↑/⌘↓ jump between them, and long output keeps its command pinned on top.

Terminal → record

Into a journal, right there

Click a block for "save as a journal entry" and "attach to the planner". Command, exit code, duration and the tail of the output arrive prefilled.

⌘K · ⌘1–0

Command palette

Move between screens, and find journals, plans, discussions and docs by title. Diff review and plan toggles are finished from the keyboard.

Multi-project

Windows and tabs

One window holds many projects as Chrome-style tabs. Tear one off into a window, drop it back to merge — the right-click menu does the same. Terminal sessions never drop.

Automation

On the hour, by itself

Set "every Friday at 17:00, summarize this week" and the app runs it then. Even the reason it did not run is logged, and if the Mac was off it catches up exactly once.

/plugin, two lines

Claude Code plugin

You can start without the app — a hook bridge, 7 MCP tools and 5 skills install in two lines.

Menu bar

Lives in the Mac menu bar

A session status icon and a popover briefing — you know a new entry landed without opening the app.

English · 한국어

Pick your language

The UI is English or Korean, and the language the AI writes journals in is set separately.

Code intelligence

Completion and diagnostics

Completions as you type, underlines where it is wrong. Hover types · go to definition · rename · code actions — standard LSP.

Four languages

It finds the servers

Rust · TypeScript · Python · Go. On your PATH it attaches, and when it is missing it says so — it does not fail quietly.

Dotfiles

Hidden files in the tree

.oculpm/ · .github/ · .gitignore — the ones you open most often are visible.

Tabs · split

Finished as an IDE

Several files in tabs, two side by side in a split. Create, rename, drag to move; delete goes to the trash. Bring files in from Finder or with ⌘V.

Debugger

Breakpoints and stepping

Click the gutter for a breakpoint, then unfold the call stack and variables where it stopped. Rust · Python · Go.

Firing badges

See whether rules catch

Per item, "N times in 30 days" / "never fired", plus KB injected per session. Claude Code transcripts are counted on this machine — zero LLM, zero network.

Agent diff

Changes inside the text

Everything since the commit is overlaid in the editor, and you jump straight to the journal entry that changed this file.

Code screen

An editor inside the app

Open from the tree, edit with syntax highlighting and save with ⌘S. 12 languages, and the theme follows the app.

Conflict-safe

Coexists with agents

If an agent edits the same file, saving asks with a banner instead of overwriting. Unsaved edits survive leaving the screen.

Line jump

From result to code

One button in a search result or the code map opens that file at that line, in the app.

Preview

Images and PDFs too

No more leaving for Finder to look at a screenshot. Fit-to-window ↔ actual size on a checkerboard, PDFs as documents — up to 16MB.

⇧⌘F

Project-wide search and replace

Not the index — what is on disk right now. Case, whole word, regex, and replace one, one file or everything.

Accessibility

Screen readers read it

The Today activity ring reads as "N entries · N files · +N/−N lines". The tooltips that announced themselves on every hover went quiet.

Keynote

Want the whole thing
in a five-minute keynote?

"Yesterday, your agent changed 3,000 lines" — a product story told through real screens. Narrated in Korean; the screens do most of the talking.

Watch the keynote →
Changelog

A little every week.

This app is built with itself — every line below came out of Ocul-PM's own work journal.

Older releases

Full changelog — every release → · GitHub releases →

Local-first

Where does
your data live?

Noaccount Noserver Notelemetry

All of it sits in one folder inside your project — as markdown a human can read.
Delete the app and the memory stays. Because it is yours.

FAQ

Frequently asked

What is Ocul-PM?

A local-first AI project manager for developers who work with AI coding agents. It records what the agents did, organizes it, and lets you verify every change against a local diff before you commit it.

Which AI coding agents does it work with?

Claude Code, Codex CLI, Gemini CLI, Antigravity and pi work with no extra setup. Cursor, Windsurf, GitHub Copilot, aider, Cline and Zed work once you enable their rules file in Settings. Anything that reads AGENTS.md can be used with it, so you are never tied to one tool.

Can I read and edit code inside the app?

Yes. The Code screen browses the project tree, opens files and saves with ⌘S. Since v2.15.0 the editor understands the code — completion as you type, diagnostics underlined where they belong, hover types and docs, F12 / ⌘-click to jump to a definition, symbol rename that updates every file that uses it, and the code actions that come with a diagnostic. It works for Rust, TypeScript/JavaScript, Python and Go, and when a language server is missing from your machine it says so instead of failing quietly. It is not a VS Code fork — standard LSP is wired directly. Dotfiles (.oculpm/ · .github/ · .gitignore) show up in the tree. Search results and the code map jump straight to the line, and if an agent edits the same file, saving does not overwrite it — a banner asks which version to keep, and unsaved edits survive leaving the screen. Since v2.16.0 you get tabs and a split view, file create/rename/drag-move (delete goes to the trash), a breakpoint debugger (Rust · Python · Go) and an inline comparison that overlays what the agent changed. Since v2.19.0 ⇧⌘F adds project-wide search and replace against what is actually on disk. Since v2.20.0 images (png · jpg · gif · webp) and PDFs open in a preview instead of the editor — pictures on a checkerboard that reveals transparency, toggling fit-to-window ↔ actual size, PDFs as documents, up to 16MB regardless of the editor's 2MB limit (svg is both picture and code, so it still opens in the editor). Since v2.21.0 you can drag files and folders in from Finder or paste them with ⌘V — same names are never overwritten, they get a -2 suffix, folders recurse, and symlinks are skipped.

Can I see the terminal next to another screen?

Yes. Since v2.10.1 ⌘J opens a terminal dock over whatever screen you are on. Dock it to the bottom (wide), the left or the right (tall) and drag the edge to size it. You can pull it out into a window of its own without dropping the shell — scrollback comes along. Since v2.22.0 sessions stand in a vertical list on the left where each card carries status, agent, elapsed time and last command — drag a session to the edge of the screen and the pane splits so you can watch two at once, and the split's handle (⠿) swaps them or pops one out as its own session. Font size is set in px in Settings → Appearance; line height and padding are a separate density setting (roomy / standard / compact).

Running several agents at once gets confusing. Does the app help?

That is exactly what v2.23.0 targets. When an agent calls for a human (terminal bell) that session turns amber and a "N waiting" banner appears above the list — click it and you land on the session that is waiting, then cycle to the next. A bell is certain because the program rang it; "quiet for 20 seconds" is a guess, and it is written as a guess. Output is also split per command: each command gets a status bar (green success, red failure), failure points are dotted along the right edge of the whole scrollback, and ⌘↑ / ⌘↓ jump between commands. Clicking a status bar offers copy, plus "save as a journal entry" and "attach to the planner" — the entry opens prefilled with the command line, exit code, duration and the last 40 lines of output. There is deliberately no re-run button; it only prefills the prompt, so nothing you have not looked at runs by itself.

Can I tell whether my rules and skills are actually being read?

Yes, since v2.24.0. Every item on the Skills & Rules screen carries an "N times in 30 days" or "never fired" badge, and the rules tab shows how many KB of conditional rules are injected per session. It is counted deterministically from the Claude Code transcripts on this machine — the moments a rule was actually injected and a skill was actually invoked — so no LLM and no network is involved. Rules without a paths filter load in full every session, so they are marked "every session" rather than counted, and "recount firings" starts over from scratch.

What leaves my machine?

Exactly five things. ① LLM requests — sent straight to the provider you chose; we have no relay server. ② Update checks — one GitHub release file. ③ GitHub fetches for patch notes, bundles and theme files — only when you click. ④ A one-time embedding-model download the first time you enable semantic search: the model comes down, your code never goes up, and search is offline afterwards. ⑤ Notion, only if you opt in. Never leaves: journal entries (except what you ask the AI about), everything under .oculpm/, your source code (except snippets sent with a question), and API keys (OS keychain only). No usage statistics, no crash reporting — there is no analytics SDK in the app. The full list, and how to count the calls yourself, is on the privacy page.

Can I bring in conversations from another tool?

Yes. Since v2.30.0, Settings → Data → "Import past conversations" opens an export (.json or .zip) from Claude and friends and lists what is inside with dates, titles, turn counts and a guessed entry type; you pick the ones that belong to this project and they become journal entries. Nothing leaves your machine while you read that list — skimming hundreds of conversations is entirely offline and free, and only what you pick calls the background model, once each. Entries land on their original dates, and re-opening the same file marks already-imported ones "imported" rather than billing you twice (they are not hidden — a conversation vanishing with no explanation is worse). Everything imported starts unverified: it did not happen in this repository, so it stays a draft until you read it and tick it off.

What happens when the network drops?

Everything local — journals, search, diffs, the planner — keeps working. Where models are involved, three things changed in v2.30.0. ① When your chosen model does not answer and a fallback replies instead, that reply carries a badge — previously a different model answered while the screen still showed the name you picked. The fallback applies to that one call; your settings are untouched. ② Unreachable providers are dimmed rather than hidden — hiding them reads as your settings having been wiped, and blocking them means you cannot pick one the moment connectivity returns (the reason is in the tooltip). ③ Automations defer instead of failing: a run that could not reach the network is recorded as "deferred" and does not burn its slot, so the catch-up rule picks it up once you are back. A failure that did get a reply (a 429, an auth error) means the network was fine — that is still a failure.

Does the AI panel resend the same context on every question?

No. Since v2.29.0 it no longer reloads the whole plan, the recent journal and the working rules for every question. When a conversation starts it loads a list of what exists exactly once — and that list does not change by a single character until the conversation ends, because a stable prefix is what keeps the model-side prompt cache alive — and bodies are pulled only when needed. Past records attach only to questions carrying a recall signal: "what did I do last week", "what did I say", "how far did the plan get". The decision uses a Korean/English signal-word dictionary, so it calls no AI, and past the ~800 token ceiling it drops whole records starting with the least relevant. Rules used to be truncated at 2,500 characters, and that cut once swallowed the "never write secrets" clause outright — now only three lines stay resident and everything else arrives in full. To push something in deliberately: /rules · /plan · /journal · /skill. Settings → Context shows you exactly what goes in.

Can I build my own theme colors?

Yes. Since v2.28.0 a theme is a file. In Settings → Appearance you create one or "duplicate and edit" any of the five built-ins (Solarized · Sepia · Nord · Dracula · High Contrast), then export and import as .json — the built-ins use the same format, so the built-ins are the examples. There is no separate preview box because the app itself is the preview: change one color and the sidebar, cards, borders and status colors change with it. Colors you did not change are left alone — a theme that sets five background lines is a complete theme, everything else inherits the light or dark default, and each token has "reset to family default". A theme that specifies no accent keeps the accent you chose, and on macOS "follow the system accent" paints it with the OS color. Bind a theme to a project in the project editor and only the window looking at that project wears it. An imported file gets a fresh identifier, and a name collision asks whether to overwrite or keep a copy. A theme can only paint a fixed list of colors, so nothing else in the file reaches the screen.

Can I tell my own journal entries apart from the ones AI wrote?

Yes. Since v2.27.0 every record carries a provenance badge — by hand (a person writing in the app) · by agent (Claude Code and friends following the journaling rules) · auto-draft (a background model after the edits went quiet) · schedule · watcher · MCP · backfill (restored from git history). It shows on journal cards and details, in the Today activity feed and in the agent contribution rows of a retro, and a filter row above the journal narrows by source — not drawn at all when the list has only one kind, because a filter that cannot narrow anything is noise. No new field was invented: it is read deterministically from the session id and agent id already written in the entry file.

Can it produce a summary on a schedule?

Yes. Since v2.26.0, set an instruction and a frequency in Settings → Automation and the app runs it at that hour — "every Friday at 17:00, summarize this week's commits and open items", for example. Frequencies cover once, every N minutes, every N hours, daily, weekly, monthly, yearly and cron, and the first visit suggests three examples (weekly dev summary, morning briefing, monthly retro) switched off — you create them with a click and decide about enabling afterwards. Definitions are markdown files under .oculpm/automation/, so you can edit them by hand and commit them with your team. Automation is entirely opt-in, and if no background model is chosen it is skipped silently rather than erroring — so nothing bills you without your knowing. There is a daily run cap (20 by default), and the run log records skips, drops and failures with reasons, not just successes. If the Mac was asleep or the app was closed, it catches up exactly once instead of stacking up. Since v2.27.0 the trigger can be the working folder rather than the clock: when file changes go quiet for the interval you set (0.2s to 10min), it drafts a journal entry or updates the plan.

Can I open several projects at once?

Yes. Since v2.9.0 one window holds several projects as tabs. Drag to reorder, or out of the window to make a new one, and since v2.22.0 you can drop a tab onto another window's tab strip to merge them back (the insertion point is shown while you drag, and moving the last tab closes the empty window). Since v2.24.0 it behaves exactly like Chrome — the moment a tab leaves the strip it becomes a real window that follows your hand off-screen and over other apps, and aiming at another window's tab strip hides the one you are holding and shows where it will land. Since v2.25.0 a torn-off window can be dragged back: a window with a single tab is picked up whole and merges when dropped (Escape puts it back where it was). Right-click a tab for the same operations from a menu, or Shift+F10 from the keyboard. Each project remembers its own screen, filters and sidebar state, and terminal sessions belong to the project, so they survive a tab moving between windows. ⌘T new tab, ⌘W close tab, ⇧⌘N new window.

Does it only record, or does it produce something?

From the journal entries it generates standup text, PR bodies and weekly reports, plus retrospectives over a date range and .md export. With an AI configured it polishes the result; without one it still works with the default format.

Can I use it from a phone or tablet?

Yes, in beta. Since v2.18.0 the Mac runs a server reachable only inside your Tailscale network, and a phone browser opens today's journal, the planner, discussions and the AI chat. Turn the server on in Settings → Mobile, scan the QR code and pair once with a six-digit code; add it to the home screen and it behaves like an app. The theme you picked on the desktop carries over (themes you built yourself follow only their light/dark family on the phone for now), and your AI API keys stay in the Mac keychain. During the beta, search, retros and the code screen are desktop-only.

Does my code or data leave the machine?

No. Everything lives in your project's .oculpm/ folder and a local SQLite cache. Only three things leave: the LLM API calls you make yourself, the update check for new versions, and a GitHub fetch when you ask for a plugin bundle or release notes. The v2.18.0 mobile bridge (beta) is the same — it is served only inside your own Tailscale network, never exposed to the public internet, and the phone talks to your Mac without passing through a third-party server.

Do terminal sessions survive an app update?

They survive. Since v2.19.0 terminal sessions are held by a process detached from the app, so after an auto-update or a restart your terminal tabs come back with their scrollback and whatever was running (including Claude Code sessions). Closing a terminal tab or a project tab yourself still cleans that session up as before.

Can I use it without the app, just the Claude Code plugin?

Yes. In Claude Code, run /plugin marketplace add bunhine0452/Ocul-PM and then /plugin install oculpm@oculpm — two lines that set up the hook bridge, 7 MCP tools and 5 skills across all your projects. Journals and plans accumulate as markdown under .oculpm/, and if you install the app later it reads those records exactly as they are.

Is the app available in English?

Yes. Since v2.8.5, Settings → Appearance lets you pick English or 한국어 and all 12 screens plus the error messages follow. The language the AI writes journals, retros and planner items in is set separately, so an English UI with Korean records (or the reverse) is possible, and documents already written are never rewritten.

Can I download it now?

Yes. The macOS (Apple Silicon) build is a free download from GitHub Releases. Intel and Windows builds are planned, and later versions update themselves from inside the app.

Can I ask about team, enterprise or partnership use?

Yes. Because Ocul-PM is local-first, adopting it on a team does not move your code or your records anywhere. For enterprise rollouts, team adoption and partnership proposals, write to bunhine0452@gmail.com — the person who built it reads and answers.

v2.32.0 — download now · macOS (Apple Silicon)

Nothing is required
to start.

No sign-up, no setup, no fee. You download it, and that is the whole thing.

Get v2.32.0Free · auto-updating Start with the plugin → Enterprise · partnerships

Plenty of developers move fast. The ones who remember go far.