pi-diff-widget 0.1.1 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.1.3] - 2026-10-12
8
+
9
+ ### Added
10
+
11
+ - `pi.image` gallery preview: a screenshot of the live edits widget, shown on the
12
+ pi.dev package page and in the README.
13
+
14
+ ## [0.1.2] - 2026-10-12
15
+
16
+ ### Changed
17
+
18
+ - README: document the `/diff-widget` actions (`on`, `off`, `accept`, `reject`)
19
+ as a table, link them from the `/diff` usage section, and correct the
20
+ local-checkout path in the install block.
21
+
7
22
  ## [0.1.1] - 2026-09-25
8
23
 
9
24
  ### Fixed
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Interactive diff viewer and live edits widget for [pi](https://pi.dev).
4
4
 
5
+ ![Live edits widget showing 4 files, +17 -2](https://cdn.jsdelivr.net/gh/omgzsa/pi-diff-widget@v0.1.3/docs/widget.png)
6
+
5
7
  ## Install
6
8
 
7
9
  ```bash
@@ -9,7 +11,7 @@ pi install npm:pi-diff-widget
9
11
  # straight from the repo, no npm required
10
12
  pi install git:github.com/omgzsa/pi-diff-widget
11
13
  # or from a local checkout
12
- pi install /absolute/path/to/pi-diff
14
+ pi install /absolute/path/to/pi-diff-widget
13
15
  ```
14
16
 
15
17
  ## Usage
@@ -38,6 +40,9 @@ Keys:
38
40
  - `g` / `G`: jump to top / bottom
39
41
  - `q` / `Esc`: close
40
42
 
43
+ See [Live edits widget](#live-edits-widget) for the `/diff-widget` actions
44
+ (`on`, `off`, `accept`, `reject`).
45
+
41
46
  ## Live edits widget
42
47
 
43
48
  Above the editor, pi-diff shows the net effect of the agent's edits this
@@ -55,14 +60,34 @@ touch and diffs it against the current content. Reverted files drop out and the
55
60
  counts are net, so it shows what the agent has actually changed, not cumulative
56
61
  churn. Committing a file drops it from the panel automatically, so what remains
57
62
  is the agent's work that is not yet committed. Paths are shown relative to the
58
- working directory. Baselines live in the session, capped at 256 KB per file.
59
-
60
- It hides itself when nothing differs. `/diff-widget` toggles it. `/diff-widget
61
- accept` (alias `keep`) makes the current state the new baseline, the equivalent of
62
- Zed's Keep All. `/diff-widget reject` restores every tracked file to its
63
- pre-agent content, deleting files the agent created and recreating ones it
64
- deleted. It asks for confirmation first, and cannot be undone. Unknown actions
65
- report a warning rather than toggling the widget.
63
+ working directory. Baselines live in the session, capped at 256 KB per file. A
64
+ baseline whose parent directory no longer exists is dropped, so a checkout you
65
+ move or delete stops counting as a whole-file deletion.
66
+
67
+ It hides itself when nothing differs.
68
+
69
+ ### `/diff-widget` actions
70
+
71
+ | Command | Effect |
72
+ |---|---|
73
+ | `/diff-widget` | Toggle the panel. With no argument it shows a hidden panel and hides a visible one |
74
+ | `/diff-widget on` | Show it |
75
+ | `/diff-widget off` | Hide it |
76
+ | `/diff-widget accept` | Keep the agent's edits: the current content becomes the baseline and the panel clears. Alias: `keep` |
77
+ | `/diff-widget reject` | Undo the agent's edits: restore every tracked file to its pre-agent content, delete the files the agent created, and recreate the ones it deleted |
78
+
79
+ `accept` is Zed's Keep All. `reject` asks for confirmation first, naming up to
80
+ five affected paths, and cannot be undone. Whole files only: there is no
81
+ hunk-level accept or reject. With nothing to reject it reports `Nothing to
82
+ reject`, and any unrecognized argument warns instead of toggling the panel, so a
83
+ typo never hides the widget by accident.
84
+
85
+ ```
86
+ /diff-widget
87
+ /diff-widget on
88
+ /diff-widget accept
89
+ /diff-widget reject
90
+ ```
66
91
 
67
92
  ## Status
68
93
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-diff-widget",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Interactive diff viewer for pi: uncommitted changes and per-turn diffs",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -26,6 +26,7 @@
26
26
  "LICENSE"
27
27
  ],
28
28
  "pi": {
29
+ "image": "https://cdn.jsdelivr.net/gh/omgzsa/pi-diff-widget@v0.1.3/docs/widget.png",
29
30
  "extensions": [
30
31
  "./src/index.ts"
31
32
  ]
package/src/baseline.ts CHANGED
@@ -38,7 +38,11 @@ export async function readBaseline(
38
38
  return { content, existed: true };
39
39
  }
40
40
 
41
- /** Content only, for callers that do not care whether the file existed. */
41
+ /**
42
+ * Content only, for callers that do not care whether the file existed. A missing
43
+ * path returns an empty string, not undefined, so callers that must tell a
44
+ * vanished file apart from an empty one use readBaseline or locationGone.
45
+ */
42
46
  export async function readFileCapped(
43
47
  path: string,
44
48
  maxBytes = MAX_BASELINE_BYTES,
package/src/git.ts CHANGED
@@ -19,6 +19,8 @@ export interface DiffFile {
19
19
  diff: string;
20
20
  }
21
21
 
22
+ // Files larger than this are reported as too-large instead of read into memory,
23
+ // and diffs are cut off at the line cap so one huge file cannot stall the view.
22
24
  const MAX_TEXT_BYTES = 512 * 1024;
23
25
  const MAX_DIFF_LINES = 4000;
24
26
 
package/src/ui.ts CHANGED
@@ -76,7 +76,9 @@ export class DiffViewer implements Component {
76
76
  const label = this.turns[this.turnIndex]?.label ?? '';
77
77
  return `${this.title} · turns ${this.theme.fg('dim', `${counter} ${label}`)}`;
78
78
  }
79
- return `${this.title} · uncommitted ${this.theme.fg('dim', `[${this.uncommitted.length} files]`)}`;
79
+ const count = this.uncommitted.length;
80
+ const label = count === 1 ? '1 file' : `${count} files`;
81
+ return `${this.title} · uncommitted ${this.theme.fg('dim', `[${label}]`)}`;
80
82
  }
81
83
 
82
84
  private footerHint(): string {