checkpointer 0.1.1 → 0.2.0

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