@xbghc/warden 0.13.1 → 0.15.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
@@ -5,12 +5,20 @@ with line comments you can copy back to the agent as a prompt.
5
5
 
6
6
  - Runs as a single local process per repository (`127.0.0.1` only, no auth, no database).
7
7
  - Diff sources: working tree, staged, working tree vs HEAD, a branch since it forked off its base (commits and
8
- uncommitted work together), any commit, any two refs, and git worktrees.
8
+ uncommitted work together), any commit, any two refs, git worktrees, and checkpoints.
9
+ - Checkpoints: note the working tree as it is — untracked files included — and later see only what
10
+ changed since, staged, committed or neither. Taking one writes nothing to the repository (see
11
+ [Checkpoints](#checkpoints)).
9
12
  - Worktrees are made and taken down from the page, one per agent branch, with the path ready to paste.
10
13
  Their directories are numbered slots beside the repository that get reused rather than remade:
11
14
  releasing one keeps the directory, installed dependencies included, for the next branch.
12
15
  - Side-by-side **Unstaged** and **Staged** file lists: staged means reviewed. Stage from the UI by dragging
13
16
  over the lines you have read (or a hunk, or a file), and unstage the same way from the Staged view.
17
+ - Debug code marked in a comment is folded out of the review and left out of whole-file staging, and
18
+ the Staged block warns while any of it is in the index (see [Debug code](#debug-code)).
19
+ - Code blocks fold by indentation, as an editor does for a language it has no grammar for: the
20
+ chevron beside a line that heads one shuts its body, and the head then says how many lines and
21
+ changes it hides. A dragged pick across a shut block takes none of them; stage the hunk to take them.
14
22
  - GitHub-style unified / side-by-side diff with syntax highlighting, collapsed file tree, lazy per-file loading, context expansion, virtual scrolling.
15
23
  - Line comments (single line or a dragged range), Markdown, edit / delete.
16
24
  - One click copies all comments as an agent-readable prompt to the clipboard.
@@ -29,6 +37,7 @@ with line comments you can copy back to the agent as a prompt.
29
37
  `git apply --cached`, which is what the stage / unstage controls run, and the worktree slot
30
38
  operations (`worktree add` / `remove`, `branch`, `switch`). Reviewing and staging never write the
31
39
  working tree or HEAD; only checking a branch out into a free slot, or releasing one, does.
40
+ Checkpoints write into warden's own index copy and object store, never the repository.
32
41
 
33
42
  ## Install / run
34
43
 
@@ -70,6 +79,8 @@ for a global install. The check never delays startup and fails silently. `--no-u
70
79
  | Worktree, working tree | `worktree:<path>:working` | same, run inside the worktree |
71
80
  | Worktree, branch vs base | `worktree:<path>:range:<base>..<head>` | same, run inside the worktree |
72
81
  | Worktree, everything since base | `worktree:<path>:base:<ref>` | same, run inside the worktree |
82
+ | Working tree since a checkpoint (incl. untracked) | `checkpoint:<n>` | `git diff <checkpoint tree>`, see [Checkpoints](#checkpoints) |
83
+ | Worktree, since one of its checkpoints | `worktree:<path>:checkpoint:<n>` | same, run inside the worktree |
73
84
 
74
85
  Refs accept anything git can resolve (`main`, `v1.2`, `HEAD~3`, a sha). `@` is `HEAD`.
75
86
  Worktrees are discovered with `git worktree list` (and made in the *Worktree* view, see below) and
@@ -200,6 +211,34 @@ Limits, each reported as a plain error rather than a half-applied patch:
200
211
  (the agent kept editing), the server answers 409 and the page reloads instead of staging the wrong lines.
201
212
  - If another git process holds the index lock the server retries briefly, then gives up with 409.
202
213
 
214
+ ## Debug code
215
+
216
+ Code written to poke at a problem and not meant to be committed can be marked in a comment. There is no
217
+ single convention for this, so warden takes the ones in use, in any comment syntax (`//`, `/*`, `#`,
218
+ `--`, `<!--`, `;`, `%`) and any case, as long as the marker opens the comment:
219
+
220
+ - a block between `debug:start` and `debug:end`, or `develblock:start` and `develblock:end` (the
221
+ webpack-strip-block / gulp-strip-block spelling); markers included, blocks nest, and a block left
222
+ open runs to the end of the file;
223
+ - a single line tagged `nocommit`, `no-commit` or `do not commit` (optionally `@nocommit` / `!nocommit`),
224
+ the tag the usual pre-commit hooks look for.
225
+
226
+ With *忽略调试代码* ticked in the sidebar (the default):
227
+
228
+ - runs of debug lines in a hunk fold into one striped row that opens with a click; jumping to a comment
229
+ inside one opens it;
230
+ - *暂存文件* and *暂存此 hunk* leave debug lines out. Lines picked one by one go in regardless — that
231
+ is how debug code is staged on purpose. A file whose changes are all debug code is refused with a
232
+ note to pick the lines instead;
233
+ - a file whose unstaged changes are all debug code does not count as still to review.
234
+
235
+ Whether it is ticked or not, the 已暂存 heading carries a *调试代码 N* mark while N added lines in the
236
+ index are debug code, with the files in its tooltip.
237
+
238
+ A hunk rarely shows the marker that opened the block its lines sit in, so warden reads both sides of a
239
+ file whole — only for the files `git grep` finds a marker in. Marker detection is textual: a marker
240
+ inside a string literal that follows a comment leader counts too.
241
+
203
242
  ## Comments and export
204
243
 
205
244
  Press the `+` that appears next to a line (drag to cover several lines) and write Markdown. What you
@@ -257,12 +296,42 @@ them — the comment's current view first, then `working`, `staged`, `all`. So:
257
296
  **deleted** (and unlinked from any issue), because the code they were about is now history.
258
297
  Anything still visible in Unstaged or Staged survives, including as a context line.
259
298
 
260
- Commit, range and `base` targets each keep their own pool and only ever search themselves, and none of
261
- them deletes on a moved HEAD.
299
+ Commit, range, `base` and checkpoint targets each keep their own pool and only ever search
300
+ themselves, and none of them deletes on a moved HEAD.
262
301
 
263
302
  Comment markers in the diff belong to one view; the rail's *全部* tab lists the whole pool and
264
303
  *此文件* lists every comment on the open file regardless of which view it currently sits in.
265
304
 
305
+ ## Checkpoints
306
+
307
+ An agent works in rounds, and after the first one the question is no longer "what is uncommitted"
308
+ but "what did it do since I last looked". The working tree answers that only while the agent
309
+ neither stages nor commits, and a `base` target shows the whole branch every time. A checkpoint is
310
+ the working tree noted at the moment you choose, and `checkpoint:<n>` is one diff from it to the
311
+ working tree now — whatever was staged or committed in between does not show, only what changed.
312
+
313
+ - *新建检查点*, under the progress figure in 工作区, takes one: tracked and untracked files as they are
314
+ on disk, ignored ones left out. *对比检查点 #n* beside it opens the newest. A checkpoint of a working
315
+ tree that has not changed since the newest one is not taken twice; that one is handed back.
316
+ - In a checkpoint's view the picker reads *检查点 #n*, and the row under the figure switches to another
317
+ checkpoint, takes a new one — the round is over, so the view moves on to it, empty — or deletes
318
+ the one in front after asking.
319
+ - Files there carry the [已读 mark](#viewed-files), which the agent's next edit to a file drops, and
320
+ comments on a checkpoint are a pool of their own. Deleting the checkpoint deletes both.
321
+ - Checkpoints are numbered per worktree. A worktree keeps the newest 20; taking one more drops the
322
+ oldest, with its comments. A slot checked out to another branch drops its own.
323
+
324
+ Nothing of this is written to the repository. The snapshot is `git add --all` plus
325
+ `git write-tree` run against a copy of the index kept in warden's data directory, with
326
+ `GIT_OBJECT_DIRECTORY` pointing there too, so the tree and every blob git hashes for it land beside
327
+ the state file; files the index already has right are not hashed again, so taking one costs about
328
+ what changed. A diff runs `git diff <tree>` under another throwaway copy of the index with the
329
+ untracked files added as intent-to-add (which hashes nothing), reading the repository's objects
330
+ through `GIT_ALTERNATE_OBJECT_DIRECTORIES`. The alternates are only ever set for reads: git refreshes
331
+ the mtime of an object it finds in one while writing, and that would be a write to `.git`. Clean
332
+ filters configured for the repository run as they do for any `git add` (Git LFS keeps its cache in
333
+ `.git/lfs`).
334
+
266
335
  ## Viewed files
267
336
 
268
337
  Commit, range and `base` targets cannot be staged from, so a file there is ticked *已读* instead — the
@@ -337,12 +406,14 @@ jump to the nearest new-side line; for commit targets the working-tree file is o
337
406
 
338
407
  `~/.local/share/warden/<sha1(repoRoot)[:12]>/state.json` (respects `XDG_DATA_HOME`). Plain JSON with a
339
408
  `schemaVersion`, written atomically (temp file + rename) under a small lock file so multiple instances
340
- can share it. Delete the directory to reset.
409
+ can share it. Delete the directory to reset. Checkpoint objects live beside it in `checkpoints/objects`;
410
+ deleting a checkpoint leaves them there, since another may share them.
341
411
 
342
412
  `targets` is keyed by target key, plus one *comment scope* per worktree — `local`, or
343
413
  `worktree:<path>:local` — holding the comments the three local views share and the HEAD sha the last
344
- re-anchor saw. `viewed` sits on the key of the commit, range or `base` target it was ticked in; the
345
- local view keys hold nothing. Issues and todos are top level. State written by an older version is
414
+ re-anchor saw. `viewed` sits on the key of the commit, range, `base` or checkpoint target it was
415
+ ticked in; the local view keys hold nothing. Issues, todos and `checkpoints` (the tree sha, HEAD and
416
+ time of each, per worktree) are top level. State written by an older version is
346
417
  migrated on load: comments filed under `working` / `staged` / `all` move into the matching scope the
347
418
  first time the file is read, and the 已读 marks those views used to keep are dropped.
348
419
 
@@ -360,7 +431,8 @@ first time the file is read, and the 已读 marks those views used to keep are d
360
431
 
361
432
  Single user, local only. The server binds to `127.0.0.1` and executes git only through
362
433
  `execFile('git', [...])`. Reads go through an argument whitelist (`rev-parse`, `diff`, `show`, `log`,
363
- `worktree list`, `ls-files`, `status`, `merge-base`, `rev-list`) that refuses option-looking refs and any write-capable
434
+ `worktree list`, `ls-files`, `status`, `merge-base`, `rev-list`, `grep` without `-O` /
435
+ `--open-files-in-pager`) that refuses option-looking refs and any write-capable
364
436
  flag; requests that would need anything else get HTTP 400. The writes are few and each composes its
365
437
  own arguments. `POST /api/targets/:key/stage` runs `git apply --cached` (with `--reverse` for the
366
438
  Staged view) on a patch the server itself builds from the diff it just produced — the patch is never
@@ -375,7 +447,9 @@ and `git reset --hard` plus `git clean -fd` only on the forced release the revie
375
447
  a 409. Refs change only when a branch is made for a checkout (plus its upstream setting when it comes
376
448
  from a remote) — undone with `branch -D` should the switch into the slot then fail — or deleted on
377
449
  request after a release or removal (`-d`, so only a merged one), and the review state lives outside
378
- the repository. A mutating request the
450
+ the repository. A checkpoint writes only there: `git add --all [--intent-to-add]` and
451
+ `git write-tree --missing-ok`, with `GIT_INDEX_FILE` and `GIT_OBJECT_DIRECTORY` set to files in
452
+ warden's data directory and no alternates (see [Checkpoints](#checkpoints)). A mutating request the
379
453
  browser labels as coming from another site (`Sec-Fetch-Site: cross-site`) is refused with 403, so a
380
454
  page from elsewhere cannot drive the server through the browser it is open in.
381
455