checkpointer 0.1.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # checkpointer
2
2
 
3
- > Git-isolated checkpoints that humans and AI agents share — save working states, revert anytime, ship a range as one clean commit.
3
+ > Git-isolated checkpoints that humans and AI agents share — save working states, revert anytime, ship a range as one clean commit, and map your code's call graph in the browser.
4
4
 
5
5
  When you (or an AI agent) work through a long task, you want save points: a way to
6
6
  mark "this works", roll back when something breaks, and at the end turn all that
@@ -11,6 +11,7 @@ repo kept outside your project — so your real `git log` stays clean until you
11
11
  - **Isolated from your repo** — checkpoints live in `~/.checkpointer`, never in your project's `.git`. Nothing shows up in `git log` until you `ship`.
12
12
  - **Captures everything** — unlike editor undo, it snapshots the whole working tree, including files changed by scripts, formatters, and codemods.
13
13
  - **Ships to one commit** — bundle a range of checkpoints into a single commit on your branch, then push when you're ready.
14
+ - **Maps your code** — `checkpointer graph` opens an interactive, searchable function call-graph of your TypeScript/JavaScript project in the browser, so you can see how functions reach each other before you change them. Fully offline.
14
15
 
15
16
  ## Install
16
17
 
@@ -52,18 +53,45 @@ git push # ship never pushes — you do
52
53
  | `save [name]` | Snapshot the working tree (auto-names `cp-N` if no name) |
53
54
  | `list` (`ls`) | List all checkpoints |
54
55
  | `status` | Show how many checkpoints are waiting to be shipped |
56
+ | `changed [id]` | Probe whether the working tree differs from a checkpoint (exit `100` if not) |
55
57
  | `show <id>` | Show a checkpoint's details and tracked files |
56
58
  | `diff <a> [b]` | Diff two checkpoints, or one checkpoint vs current files |
57
59
  | `restore <id>` | Reset the working tree to a checkpoint (auto-saves first) |
58
60
  | `tag <id> <status>` | Mark a checkpoint `working`, `wip`, or `broken` |
59
61
  | `ship` | Bundle unshipped checkpoints into one commit on your repo |
62
+ | `graph` | Visualize the project's functions and call graph in your browser |
60
63
  | `info` | Show where checkpoints are stored and which paths are excluded |
61
64
  | `skill install` | Install the Claude Code skill so agents know how to use this |
62
65
 
63
66
  Reference any checkpoint by **name** (`login`), **sequence** (`#4`), or **short sha**.
64
- Add `--json` to any command for machine-readable output; on failure it prints
65
- `{"error": "...", "code": "..."}` to stdout and exits non-zero. Run `checkpointer
66
- <command> --help` for full options and examples.
67
+ Run `checkpointer <command> --help` for full options and examples.
68
+
69
+ ### Machine-readable output (`--json`)
70
+
71
+ Add `--json` to any command for a stable, versioned envelope on stdout:
72
+
73
+ ```jsonc
74
+ // success
75
+ { "schema": "checkpointer/v1", "ok": true, "data": { /* command payload */ } }
76
+ // failure (also exits non-zero)
77
+ { "schema": "checkpointer/v1", "ok": false, "error": { "message": "...", "code": "..." } }
78
+ ```
79
+
80
+ Branch on `ok` (and on the exit code) rather than parsing prose. Fields inside
81
+ `data` are additive; `schema` only changes on a breaking envelope change.
82
+
83
+ ### Exit codes
84
+
85
+ Commands exit `0` on success. On failure the exit code is stable and tells you
86
+ *why*, so scripts and agents can react without parsing the message:
87
+
88
+ | Code | Meaning | Examples |
89
+ | --- | --- | --- |
90
+ | `1` | generic / unexpected | a git plumbing failure |
91
+ | `3` | environment not ready | not initialized, not a git repo, lock held, corrupt metadata |
92
+ | `4` | bad input | no such checkpoint, duplicate name, invalid status, missing message |
93
+ | `5` | safety refusal — a human decision is needed | shipping a `broken` checkpoint without `--force`; shipping onto a detached HEAD; shipping a checkpoint a restore set aside |
94
+ | `6` | benign no-op — nothing to do | nothing unshipped, repo already matches the checkpoint |
67
95
 
68
96
  ### Key options
69
97
 
@@ -80,15 +108,70 @@ checkpointer ship --force -m "..." # include broken checkpoi
80
108
 
81
109
  - **Restore can't lose work.** Every `restore` first auto-saves your current state, so
82
110
  you can always restore that to undo. These auto checkpoints are marked and don't
83
- count toward what gets shipped.
111
+ count toward what gets shipped. Restoring an earlier checkpoint never deletes the
112
+ later ones — they stay in `list` so you can jump straight back to them; they are only
113
+ "set aside" (marked under a divider) so a later `ship` won't bundle the line of work
114
+ you rolled away from.
115
+ - **Ship follows the live line of work.** `ship` defaults to the latest checkpoint a
116
+ restore hasn't set aside, and refuses an explicit `--upto` on a set-aside one — so
117
+ after a rollback it always commits the tree you're actually on, never a stale or
118
+ abandoned snapshot. To ship set-aside content, `restore` it (or `save` your current
119
+ state) first, which makes it live again.
84
120
  - **Ship only adds a commit.** `ship` builds the commit from a checkpoint's snapshot
85
121
  using git plumbing — it never resets your working tree, so uncommitted edits and
86
122
  untracked files are left exactly as they were.
87
123
  - **Secrets stay put.** `.env`, `*.pem`, `*.key`, `secrets.*`, `node_modules`, and your
88
124
  `.git` are never snapshotted — so a restore never overwrites them. See `checkpointer
89
125
  info` for the full list; add your own patterns in the shown `ignore` file.
126
+ - **Saving is idempotent.** A plain `save` with nothing changed reuses the latest
127
+ checkpoint instead of creating an empty duplicate, so saving often is cheap. Pass
128
+ `--allow-empty` (or a name/message/status) to force a checkpoint anyway.
129
+ - **Nested git repos are skipped, not silently broken.** A submodule or accidental inner
130
+ repo can't be snapshotted faithfully, so checkpointer warns and skips it (listing it in
131
+ `nestedRepos` under `--json`) rather than recording a dangling pointer. The directory is
132
+ left on disk untouched; a restore simply won't recreate it.
90
133
  - **Nothing leaves your machine.** No telemetry. Checkpoints are local git objects.
91
134
 
135
+ ## Visualizing your code (`graph`)
136
+
137
+ Debugging an unfamiliar codebase is easier when you can *see* how functions call
138
+ each other. `checkpointer graph` parses your TypeScript/JavaScript project with the
139
+ TypeScript compiler (so calls resolve accurately — methods, `this.`, and imports,
140
+ not just name matches) and opens an interactive map in your browser:
141
+
142
+ ```bash
143
+ checkpointer graph # analyze + serve on localhost + open the browser
144
+ checkpointer graph --no-open # just print the localhost URL
145
+ checkpointer graph --out graph.html # write a standalone, shareable HTML file
146
+ checkpointer graph --json # emit the raw graph (nodes, edges, roots)
147
+ checkpointer graph --root ../other # analyze a different project
148
+ ```
149
+
150
+ In the viewer you can:
151
+
152
+ - **Read top-down** from each entrypoint (a "root" — a function nothing in the
153
+ project calls) and **click any function to expand what it calls**, drilling as deep
154
+ as you like.
155
+ - **Search** any function by name or file; jump straight to it.
156
+ - **Focus a function** to see its **ancestors** (everyone who reaches it, up to the
157
+ entrypoints) beside its **descendants** (everything it calls) — both expandable.
158
+ - See each function's **full signature** with type-checker-resolved parameter and
159
+ return types — so you learn what it takes and returns even when there's no comment —
160
+ alongside its description, a **per-parameter table** (name, type, optional, JSDoc
161
+ `@param` prose when present), kind (function/method/constructor), async flag, and
162
+ `file:line`, with recursion and cycles flagged inline.
163
+ - Hit **"view code"** on any function to read its source inline, embedded in the page —
164
+ nothing is fetched.
165
+
166
+ The page is fully self-contained and offline — no CDN, no telemetry, the graph data is
167
+ embedded inline. `--out` produces a single file you can commit or share. Analysis is
168
+ read-only and never creates a checkpoint.
169
+
170
+ Today `graph` analyzes **TypeScript/JavaScript** (`.ts`/`.tsx`/`.js`/`.jsx`/`.mjs`/`.cjs`),
171
+ since the accurate call resolution comes from the TypeScript compiler; support for more
172
+ languages is planned. In a project with no TS/JS sources it says so cleanly — the other
173
+ commands (`save`/`restore`/`ship`) work in any repository regardless of language.
174
+
92
175
  ## Using it with AI agents
93
176
 
94
177
  `checkpointer` is just a CLI, so any agent that can run shell commands can use it.