prosa

module
v0.27.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 25, 2026 License: CC0-1.0

README

CI Release GitHub tag

prosa

a work log for AI-agent sessions

prosa /ˈpɾɔ.zɐ/  noun A conversation, a chat, an informal exchange of ideas. Prosa lets you have a conversation with your own work history.

prosa turns scattered Claude Code, Codex, Cursor, Gemini, and Antigravity session histories into one local, searchable timeline. It is built around a single load-bearing question:

What did I work on in the last N days?

— and the natural follow-ups around it: where, on which projects, with which agents and models, using which tools, taking how long, costing roughly what.

What prosa is — and isn't

prosa is a local-first, offline-friendly work log. Three small Go binaries share one module and one typed contract:

  • prosa — the CLI you actually use. Reads the local store by default.
  • prosa-server — a thin personal API server (Postgres + S3-compatible object storage) for the cross-device view.
  • prosa-panel — a server-rendered web panel that talks to the server.

It is not a chat manager, a residential TUI, an analytics warehouse, or a multi-user SaaS. The shape and the boundaries live in INTENT.md; read that file before proposing anything substantial.

Install

# macOS — Homebrew tap (auto-published on every release)
brew install c3-oss/prosa/prosa
prosa setup

# Linux + macOS — POSIX install.sh with sha256 verification
curl -fsSL https://raw.githubusercontent.com/c3-oss/prosa/master/install.sh | sh
prosa setup

# Anywhere with Node.js 22+ — npm picks the right platform binary
npm install -g @c3-oss/prosa
prosa setup

prosa setup is a short wizard: device auth, agent discovery, scheduled-sync install (LaunchAgent on macOS, systemd user timer on Linux), and the first scan. You can also drive it manually — see docs/install.md for the full matrix (including PROSA_VERSION, INSTALL_DIR, and INSTALL_BINS for install.sh).

First timeline

Today
  11:24  laptop   claude-code   prosa       "refactor sync logic"
         -> 32min

  09:02* laptop   codex         mz-iac      "setup terraform module"
         -> 18min

Yesterday
  23:55  laptop   claude-code   prosa       "intent doc"
         -> 1h12

By default prosa reads the local store, scopes to the current project when it can detect one, and shows the last 7 days. --all lifts the scope.

Commands

Command What it does
prosa Timeline (auto-scoped when inside a known project)
prosa --all Timeline across every project
prosa sync Import local agent sessions, push to the server
prosa search <query> Full-text search across turns (FTS5 local)
prosa show <session-id> Print the preserved raw JSONL
prosa analytics <report> Fixed reports: sessions/tools/errors/models/projects
prosa devices list | rename | revoke Manage known machines (cross-device)
prosa schedule install | status | uninstall Manage the background sync job
prosa setup Interactive first-run wizard
prosa login Re-authenticate (sub-step of setup)

Useful flags everywhere:

  • --last 12h|7d|30d — rolling window (default 7d).
  • --since 2026-01-01 — anchored lower bound, UTC.
  • --between 2026-01-01..2026-03-15 — closed UTC range.
  • --project <name> — project filter.
  • --agent claude-code|codex|cursor|gemini|antigravity|hermes — agent filter.
  • --device <name-or-id> — device filter; matches a device id or friendly name.
  • --remote — query the server instead of the local store.
  • --json — machine-readable NDJSON output.

The three time flags (--last, --since, --between) are mutually exclusive — pick one at a time.

By default data lives under ~/.local/share/prosa (XDG). Override with PROSA_HOME. Full reference: docs/usage.md.

Self-hosting (server + panel)

If you only use prosa locally, skip this. Each binary ships as its own distroless Docker image — the image name tells you what it runs:

docker compose up -d                                          # Postgres + MinIO dev stack
docker run --rm ghcr.io/c3-oss/prosa-server:latest            # server
docker run --rm ghcr.io/c3-oss/prosa-panel:latest             # panel
docker run --rm ghcr.io/c3-oss/prosa:latest --help            # CLI

Env vars, auth, dev-login bypass, OAuth, schema details: docs/self-hosting.md.

Build from source

The repo uses devbox + just. Inside devbox shell:

just build               # builds ./bin/{prosa,prosa-server,prosa-panel}
just test                # go test ./...
just quality             # docs, links, agents, and secret scanning
just ci                  # full local pipeline (tidy/gen/vet/lint/test-race/build)
just snapshot            # local GoReleaser dry-run into dist/

The Devbox shell also installs the repo's Husky hooks for commit messages, staged Markdown, agent config, and staged secret scanning.

The deeper guide — conventions, how to add a new importer, commit style — lives in docs/contributing.md.

Documentation map

INTENT.md                            philosophy, scope, trade-offs (read first)
README.md                            you are here
ROADMAP.md                           what is being worked on next
TECH_DEBT.md                         known trade-offs we've accepted
AGENTS.md                            operational guide for repo contributors
CLAUDE.md                            pointer for Claude Code agents

docs/
├── README.md                        documentation index
├── install.md                       end-user install across channels
├── usage.md                         CLI tutorial + command reference
├── self-hosting.md                  server + panel deployment
├── concepts.md                      session lifecycle, identity, MVP scope
├── contributing.md                  code conventions + adding an importer
├── agents.md                        AI agent orientation (full)
│
├── architecture/                    how the code is really structured
├── cli/                             CLI surface design (motion, rendering, screens)
├── panel/                           web panel design (screens, components, mocks)
├── sources/                         per-agent JSONL formats
└── distribution/                    homebrew, npm, install.sh, docker, release flow

For AI agents

If you are an AI agent working on this repo, orient yourself in this order:

  1. INTENT.md — read it end-to-end before proposing anything.
  2. AGENTS.md — operational guide (paths, commands, conventions).
  3. docs/agents.md — deeper orientation, decision checklist, where each specialist agent lives.

Specialist agents and skills are in .codex/ and .claude/. They all point back to INTENT.md and docs/; if you find a path reference that doesn't exist, that is a bug — report it.

Releases

Releases are tag-driven. Pushing a v* tag runs GoReleaser and publishes:

  • macOS/Linux archives for amd64 and arm64;
  • checksums.txt (sha256);
  • the Homebrew cask in c3-oss/homebrew-prosa;
  • the npm metapackage and four platform sub-packages;
  • three multi-arch Docker images at ghcr.io/c3-oss/{prosa,prosa-server,prosa-panel}:<tag> and :latest.

Maintainer runbook: docs/distribution/release.md.

License

To the extent possible under law, Caian Ertl has waived all copyright and related or neighboring rights to this work. In the spirit of freedom of information, I encourage you to fork, modify, change, share, or do whatever you like with this project! ^C ^V

License

Directories

Path Synopsis
cmd
prosa command
prosa is the local CLI: import, list, drill-down into agent sessions.
prosa is the local CLI: import, list, drill-down into agent sessions.
prosa-panel command
prosa-panel is the web UI for prosa.
prosa-panel is the web UI for prosa.
prosa-server command
prosa-server is the cross-device backend: receives push uploads, hosts FTS reads, and brokers CLI PKCE login.
prosa-server is the cross-device backend: receives push uploads, hosts FTS reads, and brokers CLI PKCE login.
gen
internal
buildinfo
Package buildinfo exposes version metadata injected by release builds.
Package buildinfo exposes version metadata injected by release builds.
cli
Package cli wires up the prosa CLI: cobra command tree, persistent flags, and the dispatcher for sub-commands.
Package cli wires up the prosa CLI: cobra command tree, persistent flags, and the dispatcher for sub-commands.
cli/browser
Package browser opens URLs in the system default browser.
Package browser opens URLs in the system default browser.
cli/render
Package render formats the prosa timeline for both interactive terminals (Lipgloss colors, day-grouped headers, active markers) and non-interactive sinks (pipes/redirects/scripts — plain tab-separated rows without escape codes).
Package render formats the prosa timeline for both interactive terminals (Lipgloss colors, day-grouped headers, active markers) and non-interactive sinks (pipes/redirects/scripts — plain tab-separated rows without escape codes).
cli/rpc
Package rpc loads the saved auth.json and constructs Connect clients that automatically attach the Bearer token.
Package rpc loads the saved auth.json and constructs Connect clients that automatically attach the Bearer token.
cli/schedule
Package schedule installs and removes the prosa-sync background job using the OS-native scheduler: launchd on macOS, systemd user timers on Linux.
Package schedule installs and removes the prosa-sync background job using the OS-native scheduler: launchd on macOS, systemd user timers on Linux.
cli/spinner
Package spinner provides a Bubble Tea progress display for `prosa sync`.
Package spinner provides a Bubble Tea progress display for `prosa sync`.
device
Package device resolves the stable per-machine identity prosa uses for the sessions.device_id column and the future server-side device row.
Package device resolves the stable per-machine identity prosa uses for the sessions.device_id column and the future server-side device row.
httpserver
Package httpserver runs an *http.Server bound to a context, with a bounded graceful shutdown and a force-close fallback so CTRL+C always returns the prompt — even when long-lived handlers (SSE, streaming proxies) ignore request-context cancellation.
Package httpserver runs an *http.Server bound to a context, with a bounded graceful shutdown and a force-close fallback so CTRL+C always returns the prompt — even when long-lived handlers (SSE, streaming proxies) ignore request-context cancellation.
importers/antigravity
Package antigravity implements the prosa importer for the Antigravity CLI (Google's `agy`, the successor to Gemini CLI).
Package antigravity implements the prosa importer for the Antigravity CLI (Google's `agy`, the successor to Gemini CLI).
importers/claudecode
Package claudecode implements the prosa importer for Claude Code JSONL transcripts stored under ~/.claude/projects/.
Package claudecode implements the prosa importer for Claude Code JSONL transcripts stored under ~/.claude/projects/.
importers/codex
Package codex implements the prosa importer for Codex CLI session JSONL transcripts stored under ~/.codex/sessions/<YYYY>/<MM>/<DD>/ rollout-*.jsonl.
Package codex implements the prosa importer for Codex CLI session JSONL transcripts stored under ~/.codex/sessions/<YYYY>/<MM>/<DD>/ rollout-*.jsonl.
importers/cursor
Package cursor implements the prosa importer for Cursor "agent" chats preserved as SQLite databases under ~/.cursor/chats/<workspace>/<agent>/ store.db.
Package cursor implements the prosa importer for Cursor "agent" chats preserved as SQLite databases under ~/.cursor/chats/<workspace>/<agent>/ store.db.
importers/gemini
Package gemini implements the prosa importer for Gemini CLI chat histories preserved under ~/.gemini/tmp/<projectHash>/.
Package gemini implements the prosa importer for Gemini CLI chat histories preserved under ~/.gemini/tmp/<projectHash>/.
importers/hermes
Package hermes implements the prosa importer for Hermes CLI session histories preserved under ~/.hermes/.
Package hermes implements the prosa importer for Hermes CLI session histories preserved under ~/.hermes/.
legacy
Package legacy reads the prosa v1 ".prosa" data bundle (a SQLite catalog + content-addressed zstd-compressed raw source files) so the v3 importers can re-ingest historical sessions whose original source files have since disappeared from the filesystem (e.g., Claude Code retention deleted ~/.claude/projects/.../*.jsonl past a few weeks).
Package legacy reads the prosa v1 ".prosa" data bundle (a SQLite catalog + content-addressed zstd-compressed raw source files) so the v3 importers can re-ingest historical sessions whose original source files have since disappeared from the filesystem (e.g., Claude Code retention deleted ~/.claude/projects/.../*.jsonl past a few weeks).
panel
Package panel hosts the web UI for prosa.
Package panel hosts the web UI for prosa.
panel/assets
Package assets embeds the panel's static files.
Package assets embeds the panel's static files.
panel/charts
Package charts builds chart specs serialized to a JSON island and rendered client-side by Frappe Charts (see assets/charts-init.js).
Package charts builds chart specs serialized to a JSON island and rendered client-side by Frappe Charts (see assets/charts-init.js).
panel/oauth
Package oauth speaks the minimal GitHub OAuth web flow needed by the panel: build the consent URL, exchange the code, fetch the primary verified email.
Package oauth speaks the minimal GitHub OAuth web flow needed by the panel: build the consent URL, exchange the code, fetch the primary verified email.
panel/render
Package render turns canonical session content into the HTML the sidepanel template ships.
Package render turns canonical session content into the HTML the sidepanel template ships.
panel/rpc
Package rpc wraps Connect clients that call prosa-server, pre-injecting "Authorization: Admin <token>" so callers never need to remember it.
Package rpc wraps Connect clients that call prosa-server, pre-injecting "Authorization: Admin <token>" so callers never need to remember it.
panel/session
Package session implements the panel's HMAC-signed cookie.
Package session implements the panel's HMAC-signed cookie.
panel/templates
Package templates holds the html/template sources rendered by the panel handlers.
Package templates holds the html/template sources rendered by the panel handlers.
paths
Package paths centralizes resolution of prosa's on-disk locations so the rest of the codebase never hard-codes ~/...
Package paths centralizes resolution of prosa's on-disk locations so the rest of the codebase never hard-codes ~/...
profiles
Package profiles loads and saves the local per-agent profile config (profiles.json).
Package profiles loads and saves the local per-agent profile config (profiles.json).
projectid
Package projectid resolves the canonical identity of the project a prosa session ran in.
Package projectid resolves the canonical identity of the project a prosa session ran in.
server
Package server hosts the prosa server runtime: config, HTTP wiring, Connect handlers, and storage adapters (Postgres + S3-compatible).
Package server hosts the prosa server runtime: config, HTTP wiring, Connect handlers, and storage adapters (Postgres + S3-compatible).
server/auth
Package auth implements PKCE + localhost-callback login for the CLI and bearer middleware for all other RPCs.
Package auth implements PKCE + localhost-callback login for the CLI and bearer middleware for all other RPCs.
server/handlers
Package handlers binds the Connect-generated service interfaces to the prosa internal/server services (auth, sessions, devices).
Package handlers binds the Connect-generated service interfaces to the prosa internal/server services (auth, sessions, devices).
server/storage
Package storage wraps the Postgres pool and the S3-compatible object store.
Package storage wraps the Postgres pool and the S3-compatible object store.
sessionkind
Package sessionkind classifies a session into zero-or-more "special session" kinds from the turns and tool counters an importer already projected.
Package sessionkind classifies a session into zero-or-more "special session" kinds from the turns and tool counters an importer already projected.
sessiontext
Package sessiontext classifies and cleans the operational/meta blocks agents inject as user-role messages of a session.
Package sessiontext classifies and cleans the operational/meta blocks agents inject as user-role messages of a session.
store
Package store wraps the local SQLite database that holds the canonical session metadata projected from raw agent transcripts.
Package store wraps the local SQLite database that holds the canonical session metadata projected from raw agent transcripts.
migrations
local
Package local exposes the embedded SQLite migrations as an fs.FS so the store package can apply them at startup without depending on the filesystem at runtime.
Package local exposes the embedded SQLite migrations as an fs.FS so the store package can apply them at startup without depending on the filesystem at runtime.
server
Package server exposes the embedded Postgres migrations as an fs.FS so the internal/server/storage package can apply them at startup without depending on the filesystem at runtime — same convention as migrations/local.
Package server exposes the embedded Postgres migrations as an fs.FS so the internal/server/storage package can apply them at startup without depending on the filesystem at runtime — same convention as migrations/local.
pkg
importer
Package importer defines the plugin contract every per-agent connector implements to turn JSONL (or other) transcripts into canonical sessions.
Package importer defines the plugin contract every per-agent connector implements to turn JSONL (or other) transcripts into canonical sessions.
session
Package session defines the canonical domain types every importer maps agent-specific session histories into.
Package session defines the canonical domain types every importer maps agent-specific session histories into.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL