New
Apps 785Makers 784This week 785
Promote your app−30%
pentimento screenshot 1
1views in
the last 30 days

pentimento

Derives status and lineage for the plan files Claude Code, Cursor, and Antigravity leave behind...

Built with Claude Code

by kjiwa · from CACanada · added Oct 29, 2026
no ratings0 comments

Status, intent, and lineage for Claude Code, Cursor, and Antigravity plan files.

demo

Claude Code, Cursor, and Antigravity leave plan files behind. After a few hundred of them you cannot tell which finished, which you still care about, or which plan replaced which — the filenames are random and the files say nothing about their own state. pentimento derives that state and gives you a CLI to list, filter, and render the lot as a lineage tree.

Three kinds of plan are worth finding again:

  • The long one: an infrastructure migration designed over months grows subplans, absorbs decisions made in discussion, and leaves behind the branches you rejected — the part you want back a quarter later. A superseded plan is a decision record, not garbage, which is why superseded is the one status no derivation produces or overwrites; tree <id> brings the whole thread back, tags or no tags.
  • The finished one that is not over: execution ends with findings you will not act on today. Tag it and set an intent, and list --tag or list --starred brings it back when you are ready to pick the thread up again.
  • The one that already answered your question: a plan from another project holds the reasoning behind a decision your current change would undo — why a CI matrix was cut, why one service avoids a library. A memory exists only if an agent chose to write one, and project docs only if you did; a plan exists whenever a decision was planned. list --title and list --grep search every project's plans at once, and the prior-plans skill has the agent run that search itself before it proposes a change.

In harness-engineering terms, plans are the state layer: what one session leaves for the next. pentimento hook keeps that state current as the agent writes it, and the prior-plans skill has the agent read it back.

A pentimento is the earlier composition showing through a repainted canvas; that is what a plans directory is.

Built with Claude Code.

Install

pip install pentimento
# or from source:
pip install git+https://github.com/kjiwa/pentimento.git

Tab completion for bash, zsh, and fish is in docs/reference.md#shell-completion.

Quick start

Point AGENT_PLANS_DIR at your plans directory (it defaults to ~/.claude/plans), then:

pentimento list          # see the corpus; derived fields show without backfill
pentimento backfill      # persist derived fields so they outlive the transcripts
pentimento set some-plan-id --intent active
pentimento list --starred

To park a finished plan you mean to return to, tag it and set an intent, then find it by tag later:

pentimento set some-plan-id --add-tag auth --intent someday
pentimento list --tag auth

To pull one thread of subplans back out by lineage, rather than by tag:

pentimento tree some-plan-id
pentimento tree some-plan-id --ancestors

To find how an earlier decision was made, search titles (or titles and bodies) across every project, then reopen the plan; to see what you finished recently, filter by date:

pentimento list --title 'github actions|\bGHA\b'
pentimento list --grep 'concurrency group' --status complete
pentimento show some-plan-id --full
pentimento list --status complete --since 1w

docs/workflows.md walks each of these end to end.

Sources and their default directories are covered in docs/integrations.md; Cursor's and Antigravity's rules and caveats are in the Cursor and Antigravity sections.

The samples below are regenerated by sh demo/capture.sh.

list

PLAN shows the short id, such as auth-rollout for api-auth-rollout. --columns (or PENTIMENTO_COLUMNS) chooses which columns show and in what order; see Columns. list and tree share their filters, listed in the synopsis.

PLAN                  STATUS       INTENT     PROJECT   SOURCE  TITLE                           TAGS             CREATED     UPDATED
style-guide           superseded   abandoned  platform  claude  Write a docs style guide                         2026-07-31       6w
auth-redesign         complete     abandoned  platform  claude  Redesign the auth API           [auth, +1]       2026-08-05       5w
dunning-copy          complete     someday    billing   claude  Rewrite dunning email copy      [billing]        2026-08-20       3w
auth-rollout          partial      active     platform  claude  Roll out the new auth API       [auth, +1]       2026-08-25       2w
auth-cleanup          not-started  queued     platform  claude  Remove the old auth API         [auth, +1]       2026-08-30       2w
auth-docs             not-started  unset      platform  claude  Document the new auth API                        2026-09-02       1w
invoice-retry         unknown      unset      billing   claude  Retry failed invoice charges    [billing]        2026-09-04       1w
relevance-tuning      not-started  active     billing   claude  Tune search relevance           [search]         2026-09-09       5d
onboarding-checklist  not-started  unset                claude  Write the onboarding checklist                   2026-09-13       1d

9 plans

Below the table threshold, list stacks each plan into a record; see the layout rule.

Write a docs style guide
  style-guide  superseded  abandoned  platform  claude  2026-07-31  6w
Redesign the auth API
  auth-redesign  complete  abandoned  platform  claude  [auth, security]
  2026-08-05  5w
Rewrite dunning email copy
  dunning-copy  complete  someday  billing  claude  [billing]  2026-08-20  3w
Roll out the new auth API
  auth-rollout  partial  active  platform  claude  [auth, security]  2026-08-25
  2w
Remove the old auth API
  auth-cleanup  not-started  queued  platform  claude  [auth, security]
  2026-08-30  2w
Document the new auth API
  auth-docs  not-started  unset  platform  claude  2026-09-02  1w
Retry failed invoice charges
  invoice-retry  unknown  unset  billing  claude  [billing]  2026-09-04  1w
Tune search relevance
  relevance-tuning  not-started  active  billing  claude  [search]  2026-09-09
  5d
Write the onboarding checklist
  onboarding-checklist  not-started  unset  claude  2026-09-13  1d

9 plans

tree

Plans nested under their parents, grouped by project. Plain tree renders the whole corpus this way; tree <id> roots it at one plan instead — that plan plus everything beneath it (see tree <id>). --ancestors also walks up to <id>'s topmost ancestor, spine only, for pulling a single thread out of a larger forest.

(no project)
`-- Write the onboarding checklist
      onboarding-checklist  not-started  unset  2026-09-13  1d

billing
|-- Rewrite dunning email copy
|     dunning-copy  complete  someday  [billing]  2026-08-20  3w
|-- Retry failed invoice charges
|     invoice-retry  unknown  unset  [billing]  2026-09-04  1w  (parent elided: no-such-plan)
`-- Tune search relevance
      relevance-tuning  not-started  active  [search]  2026-09-09  5d

platform
|-- Write a docs style guide
|     style-guide  superseded  abandoned  2026-07-31  6w
`-- Redesign the auth API
      auth-redesign  complete  abandoned  [auth, security]  2026-08-05  5w
    `-- Roll out the new auth API
          auth-rollout  partial  active  [auth, security]  2026-08-25  2w
        |-- Remove the old auth API
        |     auth-cleanup  not-started  queued  [auth, security]  2026-08-30  2w
        `-- Document the new auth API
              auth-docs  not-started  unset  2026-09-02  1w

9 plans
platform
`-- Redesign the auth API
      auth-redesign  complete  abandoned  [auth, security]  2026-08-05  5w
    `-- Roll out the new auth API
          auth-rollout  partial  active  [auth, security]  2026-08-25  2w
        |-- Remove the old auth API
        |     auth-cleanup  not-started  queued  [auth, security]  2026-08-30  2w
        `-- Document the new auth API
              auth-docs  not-started  unset  2026-09-02  1w

4 of 9 plans

show

# Roll out the new auth API

id: api-auth-rollout
path: ~/.claude/plans/api-auth-rollout.md
status: partial   intent: active   tags: [auth, security]
parent: api-auth-redesign   project: platform
created: 2026-08-25   source: claude   modified: 2026-08-25 12:30

Progress

[x] Ship behind a feature flag
[ ] Flip the flag for all tenants

Context

Tenants opt in via the auth_v2 flag in tenant_settings. Watch error rates before flipping the
remaining cohort. See the rollout runbook.

Cohort    Status
internal  complete
beta      in progress

check

check validates the whole corpus and exits 1 on any finding; it takes no plan id. PLAN uses the short id, and a line under the summary gives the fix for each CODE. --format json|tsv emits the full id in id and the fix in hint. To work through findings, see Working through check; docs/troubleshooting.md explains each CODE.

CODE                   PLAN           MESSAGE
dangling-parent        invoice-retry  parent 'no-such-plan' does not resolve to a plan
underivable-status     invoice-retry  '## Progress' has no checkboxes or recognized phrase
status-behind-history  auth-cleanup   status 'not-started' but 1 later session worked this plan
unadopted-tag          auth-docs      no tags, but its thread carries [auth, security]

9 plans checked, 4 findings
dangling-parent: pentimento set <id> --parent <id>, or --clear-parent
status-behind-history: tick the plan's '## Progress', or pentimento history <id>, then pentimento set <id>
  --status <value> (pins)
unadopted-tag: pentimento set <id> --add-tag <tag>
underivable-status: add a checklist to '## Progress', or pentimento show <id>, then pentimento set <id>
  --status <value>
narrow with: pentimento list --finding <code>

history

history shows which sessions touched a plan's file. The session whose id matches the plan's own id, or failing that the session whose first touch wrote the plan, is authored; any later session that edited, wrote, or delegated work on it is worked; one that only read it is read. Only Claude Code transcripts feed history. For an empty result, see history is empty.

WHEN              WHAT      SESSION                                TOUCHES
2026-08-30 12:30  authored  auth-cleanup                                 1
2026-09-11 12:30  worked    implement-api-auth-cleanup-eager-wolf        1
2026-09-13 12:30  read      review-api-auth-cleanup-calm-fox             1

Frontmatter

---
pentimento:
  status: not-started | partial | complete | superseded | unknown
  pinned: true                  # omitted unless set
  intent: active | queued | someday | abandoned | unset
  tags: [auth, security]        # omitted if untagged
  parent: some-other-plan-id    # omitted for roots
  project: platform             # omitted if undetermined
  created: 2026-09-08
---

The vocabulary lives in one place: pentimento/vocabulary.py.

Field Set by How
status derived Views derive it live from status signals, first match wins; backfill (including the per-write pentimento hook, which caps it at partial) persists it: ## Progress, then a Cursor plan's todos:, then checkboxes elsewhere in the body. set --status overrides it directly and pins it (see pinned); it is the only way to set superseded, which no derivation produces or overwrites.
pinned operator Never derived. set --status sets it to true automatically; set --unpin clears it. While set, backfill (with or without --rederive) leaves status untouched; see check findings for what check still reports.
intent operator Shown as unset until set; backfill writes unset the first time it sees the plan, then leaves it alone. Only set --intent changes it after that.
tags operator Never derived or written; check suggests them (unadopted-tag). set --add-tag/--remove-tag/--clear-tags; filter with list/tree --tag, which ANDs repeated tags.
parent derived, or operator Views derive it from a plan reference and backfill persists it (see parent is empty). --rederive recomputes it from scratch: it replaces a parent set with set --parent by the derived one, or removes it when no reference resolves. set --parent/--clear-parent set or clear it directly; set --parent rejects a value that would create a cycle. Read the chain back with tree <id>/tree <id> --ancestors.
project derived, or operator Views derive it from a session's cwd and backfill persists it, which keeps it after Claude Code prunes the transcript (a Cursor or Antigravity plan's: see Cursor and Antigravity). set --project/--clear-project set or clear it directly; --project . resolves to the current directory's name.
created derived once A local date, derived by views and persisted once by backfill, then immutable except through backfill --recreate.
modified derived, not stored Not a frontmatter field: max(session end time, file mtime). Neither backfill nor set bumps it when the write only touches frontmatter bookkeeping.

Lineage and source discovery are covered in full in docs/integrations.md and docs/troubleshooting.md. Cursor plans get project and prompt lineage from Cursor's agent transcripts, matched by name; a stop hook keeps their status current. The matching rule is in the integrations guide. Antigravity plans read their own conversation's transcript, so they need no matching, and a PostToolUse hook keeps their status current (setup).

Commands

Command Does
list flat table of plans
tree [<id>] lineage tree, grouped by project
show <id> H1, frontmatter, and the rendered body
set <id>... rewrite frontmatter in place
backfill gap-fill intent/created/project/parent; advance status
hook run as a PostToolUse hook; reads the payload on stdin
index write INDEX.md into the plans directory
check validate lineage, vocabulary, status, and tags; exits 1 on any finding
history <id> session-touch history for a plan
completion <shell> print a shell integration script

Full flags for every command, plus the environment variables, are in docs/reference.md.

Scope

pentimento is built for one operator's corpus on one machine. Shared, concurrent, or multi-author planning is out of scope and not a gap this tool intends to close — project, prompt lineage, and modified are all derived from local Claude Code transcripts, and deriving them across authors would need a different source, a sync, and an identity model.

Keeping the plans directory in git does get you review and history, and part of the derived state travels with the files: status, operator-set frontmatter, and body-referenced parent survive a checkout anywhere; project, prompt-derived parent, and session history do not. See docs/workflows.md for the details, and pentimento index for an INDEX.md worth committing.

Prior art

ccplan and planc track Claude Code plans by a status you set by hand, ccplan in a sidecar file and planc in frontmatter through a TUI. claude-plan-viewer browses and searches them in a web UI. planning-with-files keeps an agent's plan on disk while it works and recovers it after /clear or compaction; it manages the files it creates, not a directory of finished ones. None of them records which plan replaced which. pentimento reads a corpus it did not author and derives status, project, and parent across it. The longer comparison is in Managing Claude Code plan files.

Requirements and limitations

Stdlib-only Python 3.9+, zero runtime dependencies, no PyYAML.

pentimento enriches modified and lineage by reading Claude Code's session transcripts (AGENT_SESSIONS_DIR, default ~/.claude/projects) and Cursor's agent transcripts (CURSOR_SESSIONS_DIR, default ~/.cursor/projects), and Antigravity's conversation transcripts (next to each plan under ANTIGRAVITY_BRAIN_DIR, default ~/.gemini/antigravity/brain), all undocumented, private formats. If a format changes, or the transcripts are absent, this enrichment degrades to file mtimes and plain body/preamble references — it does not break, and the frontmatter itself stays plain, hand-editable markdown either way.

Development

Setup, checks, and CI are in CONTRIBUTING.md.

Docs

  • docs/reference.md — every command's full flags, and the environment variables.
  • docs/integrations.md — wiring backfill and pentimento hook into Claude Code, Cursor, and Antigravity, a slash command, a skill that searches past plans before a new one, a triage-nudge pattern, check in CI.
  • docs/workflows.md — triage, picking a plan back up, reusing a past decision, supersession, lineage trees, working through check, scripting with --format json.
  • docs/troubleshooting.md — every empty field and `che

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#plans · #lineage · #cli