@tmustier/pi-files-widget 0.1.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/CHANGELOG.md +70 -0
- package/DESIGN.md +452 -0
- package/README.md +120 -0
- package/TODO.md +141 -0
- package/browser.ts +537 -0
- package/comment.ts +5 -0
- package/constants.ts +12 -0
- package/demo.svg +1 -0
- package/file-tree.ts +156 -0
- package/file-viewer.ts +93 -0
- package/git.ts +72 -0
- package/index.ts +139 -0
- package/input-utils.ts +3 -0
- package/package.json +22 -0
- package/types.ts +26 -0
- package/utils.ts +26 -0
- package/viewer.ts +422 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this extension will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.6] - 2026-01-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- Clearer install instructions and dependency notes in README
|
|
9
|
+
|
|
10
|
+
## [0.1.5] - 2026-01-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Demo recording embedded in README
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Comment sending now queues with follow-up delivery in streaming sessions
|
|
17
|
+
- Split viewer logic into `viewer.ts` and shared helpers
|
|
18
|
+
- Reduced browser render duplication with node format helpers
|
|
19
|
+
|
|
20
|
+
## [0.1.4] - 2026-01-24
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Split viewer logic into `viewer.ts` and shared helpers
|
|
24
|
+
- Reduced browser render duplication with node format helpers
|
|
25
|
+
|
|
26
|
+
## [0.1.3] - 2026-01-24
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- `c` in viewer now opens an inline comment prompt and sends a follow-up message
|
|
30
|
+
|
|
31
|
+
## [0.1.2] - 2026-01-24
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
- `c` in viewer now appends selection to editor input instead of sending immediately
|
|
35
|
+
|
|
36
|
+
## [0.1.1] - 2026-01-24
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- README with install steps, dependencies, and keybindings
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- Refactored into modular files (browser, git, tree, viewer, utils)
|
|
43
|
+
|
|
44
|
+
## [0.1.0] - 2026-01-24
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
- `/files` command opens full-screen file browser
|
|
48
|
+
- File tree with j/k navigation, Enter to open, h/l to collapse/expand
|
|
49
|
+
- File viewer with syntax highlighting via `bat`
|
|
50
|
+
- Markdown rendering via `glow`
|
|
51
|
+
- Git diff view via `delta` with line numbers
|
|
52
|
+
- Git status indicators (M, A, D, ?) on files
|
|
53
|
+
- Agent-modified file tracking (🤖 indicator)
|
|
54
|
+
- Changed files filter (`c` to toggle)
|
|
55
|
+
- Jump to next/prev changed file (`]`/`[`)
|
|
56
|
+
- Search in file tree (`/` then type)
|
|
57
|
+
- Search in file viewer (`/` then type, `n`/`N` for next/prev match)
|
|
58
|
+
- Select mode (`v`) to select lines and comment (`c`) to send to agent
|
|
59
|
+
- Line counts and diff stats (+/-) on files and collapsed folders
|
|
60
|
+
- Auto-refresh git status every 3 seconds (preserves expansion state)
|
|
61
|
+
- PageUp/PageDown support in browser and viewer
|
|
62
|
+
- Height adjustment (`+`/`-`)
|
|
63
|
+
- Works in non-git directories (git features gracefully disabled)
|
|
64
|
+
|
|
65
|
+
### Dependencies
|
|
66
|
+
- `bat` - syntax highlighting (recommended)
|
|
67
|
+
- `glow` - markdown rendering (recommended)
|
|
68
|
+
- `delta` - diff formatting (recommended)
|
|
69
|
+
|
|
70
|
+
Install with: `brew install bat git-delta glow`
|
package/DESIGN.md
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
# Pi Editor Extension
|
|
2
|
+
|
|
3
|
+
A Pi extension that provides an in-terminal file browser, viewer, and review workflow - enabling you to navigate, view, and comment on files without leaving Pi or interrupting the agent.
|
|
4
|
+
|
|
5
|
+
## Problem Statement
|
|
6
|
+
|
|
7
|
+
When working with coding agents in Pi:
|
|
8
|
+
- Viewing files requires either putting full content into context (`cat`) or leaving the terminal
|
|
9
|
+
- Reviewing diffs and agent changes means context-switching to an external editor
|
|
10
|
+
- No way to easily browse the project structure while the agent works
|
|
11
|
+
- No feedback loop for "I see this line, let me comment on it and send to agent"
|
|
12
|
+
|
|
13
|
+
## Goals
|
|
14
|
+
|
|
15
|
+
### MVP (v0.1)
|
|
16
|
+
1. **File Tree Widget** - Toggleable file browser showing project structure
|
|
17
|
+
2. **File Viewer** - View files with syntax highlighting, scroll, search
|
|
18
|
+
3. **Diff View** - Toggle diff vs HEAD for modified files
|
|
19
|
+
4. **Markdown Rendering** - Render .md files nicely (via `glow` or similar)
|
|
20
|
+
5. **Select + Comment + Send** - Select text, add comment, send to agent as steering message
|
|
21
|
+
|
|
22
|
+
### Future Enhancements
|
|
23
|
+
- Agent vs human edit attribution (Cursor Blame style)
|
|
24
|
+
- Word-level diff for prose (not just line-level git diff)
|
|
25
|
+
- Multiple comments before sending (queue workflow)
|
|
26
|
+
- Per-model attribution for agent edits
|
|
27
|
+
- Side-by-side diff view
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
### Extension Type
|
|
32
|
+
Pi extension (`~/.pi/agent/extensions/editor/index.ts`) using:
|
|
33
|
+
- `ctx.ui.setWidget()` for the file browser panel
|
|
34
|
+
- `ctx.ui.custom()` for the file viewer modal
|
|
35
|
+
- `pi.registerShortcut()` for hotkeys
|
|
36
|
+
- `pi.on("tool_result")` to track agent file modifications
|
|
37
|
+
|
|
38
|
+
### External Dependencies
|
|
39
|
+
- `bat` - Syntax highlighting for code files (falls back to `cat`)
|
|
40
|
+
- `delta` - Pretty git diff output (falls back to `git diff`)
|
|
41
|
+
- `glow` - Markdown rendering (falls back to plain text)
|
|
42
|
+
- `fd` or `find` - Fast file discovery
|
|
43
|
+
- `git` - Status, diff operations
|
|
44
|
+
|
|
45
|
+
### UI Layout
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
49
|
+
│ [Agent output / streaming...] │
|
|
50
|
+
│ │
|
|
51
|
+
├─────────────────────────────────────────────────────────────┤
|
|
52
|
+
│ 📁 File Browser (widget, toggleable with Ctrl+E) │
|
|
53
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
54
|
+
│ │ > src/ │ │
|
|
55
|
+
│ │ ├── index.ts M │ │
|
|
56
|
+
│ │ ├── utils.ts M │ │
|
|
57
|
+
│ │ └── types.ts │ │
|
|
58
|
+
│ │ > tests/ │ │
|
|
59
|
+
│ │ README.md ? │ │
|
|
60
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
61
|
+
├─────────────────────────────────────────────────────────────┤
|
|
62
|
+
│ [Your input editor] │
|
|
63
|
+
└─────────────────────────────────────────────────────────────┘
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When you press Enter on a file, it opens the **File Viewer** (full-screen via `ctx.ui.custom()`):
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
70
|
+
│ src/index.ts [Diff: ON] [q]uit │
|
|
71
|
+
├─────────────────────────────────────────────────────────────┤
|
|
72
|
+
│ 1 │ import { foo } from './utils'; │
|
|
73
|
+
│ 2 │ import { Bar } from './types'; │
|
|
74
|
+
│ 3 │ │
|
|
75
|
+
│ 4 │+export function main() { <- added line │
|
|
76
|
+
│ 5 │+ console.log('hello'); │
|
|
77
|
+
│ 6 │+} │
|
|
78
|
+
│ 7 │ │
|
|
79
|
+
│ │
|
|
80
|
+
├─────────────────────────────────────────────────────────────┤
|
|
81
|
+
│ j/k: scroll v: select d: toggle diff g: glow (md) q: quit│
|
|
82
|
+
└─────────────────────────────────────────────────────────────┘
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Selection mode (`v` to enter):
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
89
|
+
│ src/index.ts [SELECT MODE] lines 4-6 │
|
|
90
|
+
├─────────────────────────────────────────────────────────────┤
|
|
91
|
+
│ 1 │ import { foo } from './utils'; │
|
|
92
|
+
│ 2 │ import { Bar } from './types'; │
|
|
93
|
+
│ 3 │ │
|
|
94
|
+
│ ▌ 4 │ export function main() { <- selected │
|
|
95
|
+
│ ▌ 5 │ console.log('hello'); <- selected │
|
|
96
|
+
│ ▌ 6 │ } <- selected │
|
|
97
|
+
│ 7 │ │
|
|
98
|
+
│ │
|
|
99
|
+
├─────────────────────────────────────────────────────────────┤
|
|
100
|
+
│ j/k: extend c: comment Esc: cancel │
|
|
101
|
+
└─────────────────────────────────────────────────────────────┘
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
After pressing `c`, comment dialog appears, then sends to agent:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Steering message sent to agent:
|
|
108
|
+
|
|
109
|
+
In `src/index.ts` (lines 4-6):
|
|
110
|
+
```ts
|
|
111
|
+
export function main() {
|
|
112
|
+
console.log('hello');
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
User comment: "This should take a name parameter and greet by name"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Keybindings
|
|
120
|
+
|
|
121
|
+
| Key | Context | Action |
|
|
122
|
+
|-----|---------|--------|
|
|
123
|
+
| `Ctrl+E` | Global | Toggle file browser widget |
|
|
124
|
+
| `j/k` | File browser | Navigate files |
|
|
125
|
+
| `Enter` | File browser | Open file viewer |
|
|
126
|
+
| `/` | File browser | Fuzzy search |
|
|
127
|
+
| `q` | File viewer | Close viewer, return to pi |
|
|
128
|
+
| `j/k` | File viewer | Scroll up/down |
|
|
129
|
+
| `g/G` | File viewer | Go to top/bottom |
|
|
130
|
+
| `d` | File viewer | Toggle diff view |
|
|
131
|
+
| `v` | File viewer | Enter selection mode |
|
|
132
|
+
| `j/k` | Selection mode | Extend selection |
|
|
133
|
+
| `c` | Selection mode | Add comment to selection |
|
|
134
|
+
| `Esc` | Selection mode | Cancel selection |
|
|
135
|
+
|
|
136
|
+
## Implementation Plan
|
|
137
|
+
|
|
138
|
+
### Phase 1: File Browser Widget
|
|
139
|
+
- [ ] Create extension scaffold
|
|
140
|
+
- [ ] Implement file tree data structure (respect .gitignore)
|
|
141
|
+
- [ ] Git status integration (modified, untracked, staged indicators)
|
|
142
|
+
- [ ] Widget rendering with `ctx.ui.setWidget()`
|
|
143
|
+
- [ ] Toggle hotkey `Ctrl+E`
|
|
144
|
+
- [ ] Navigation (j/k, Enter to open)
|
|
145
|
+
- [ ] Fuzzy search (/)
|
|
146
|
+
|
|
147
|
+
### Phase 2: File Viewer
|
|
148
|
+
- [ ] Full-screen viewer via `ctx.ui.custom()`
|
|
149
|
+
- [ ] Syntax highlighting via `bat` (with fallback)
|
|
150
|
+
- [ ] Scroll, go to line
|
|
151
|
+
- [ ] Markdown rendering via `glow` (with fallback)
|
|
152
|
+
- [ ] Diff toggle via `delta`/`git diff`
|
|
153
|
+
|
|
154
|
+
### Phase 3: Select + Comment + Send
|
|
155
|
+
- [ ] Selection mode (v to enter, j/k to extend)
|
|
156
|
+
- [ ] Comment input dialog
|
|
157
|
+
- [ ] Format and send as steering message via `pi.sendUserMessage()`
|
|
158
|
+
- [ ] Handle mid-stream delivery (`deliverAs: "steer"`)
|
|
159
|
+
|
|
160
|
+
### Phase 4: Agent Awareness (Future)
|
|
161
|
+
- [ ] Track agent file modifications via `tool_result` events
|
|
162
|
+
- [ ] Badge files in tree with "agent modified" indicator
|
|
163
|
+
- [ ] Store modification metadata in session via `pi.appendEntry()`
|
|
164
|
+
- [ ] Per-line attribution (which tool call modified which lines)
|
|
165
|
+
|
|
166
|
+
## Technical Notes
|
|
167
|
+
|
|
168
|
+
### File Tree Performance
|
|
169
|
+
- Use `fd` if available (respects .gitignore by default, fast)
|
|
170
|
+
- Fall back to `find` + manual .gitignore parsing
|
|
171
|
+
- Cache tree, invalidate on file system events or manual refresh
|
|
172
|
+
|
|
173
|
+
### Syntax Highlighting
|
|
174
|
+
```bash
|
|
175
|
+
# Check for bat
|
|
176
|
+
bat --style=numbers,changes --color=always "$file"
|
|
177
|
+
|
|
178
|
+
# Fallback
|
|
179
|
+
cat -n "$file"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Diff Display
|
|
183
|
+
```bash
|
|
184
|
+
# Check for delta
|
|
185
|
+
git diff HEAD -- "$file" | delta --side-by-side
|
|
186
|
+
|
|
187
|
+
# Fallback
|
|
188
|
+
git diff HEAD -- "$file"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Markdown Rendering
|
|
192
|
+
```bash
|
|
193
|
+
# Check for glow
|
|
194
|
+
glow "$file"
|
|
195
|
+
|
|
196
|
+
# Fallback: just show raw markdown with bat
|
|
197
|
+
bat "$file"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Git Status
|
|
201
|
+
```bash
|
|
202
|
+
git status --porcelain
|
|
203
|
+
# M = modified (staged)
|
|
204
|
+
# _M = modified (unstaged)
|
|
205
|
+
# ?? = untracked
|
|
206
|
+
# A = added
|
|
207
|
+
# D = deleted
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Research Notes
|
|
211
|
+
|
|
212
|
+
### Cursor Blame (Cursor 2.4, Jan 2025)
|
|
213
|
+
|
|
214
|
+
Cursor introduced "Cursor Blame" which provides per-line attribution:
|
|
215
|
+
- Distinguishes code from **Tab completions**, **agent runs** (broken down by model), and **human edits**
|
|
216
|
+
- Gutter annotations showing who/what wrote each line
|
|
217
|
+
- Addresses the "which model made this change?" problem
|
|
218
|
+
- Users on Reddit specifically requested this to compare model performance
|
|
219
|
+
|
|
220
|
+
**Relevance**: The "agent vs human" distinction we want for Phase 4 is similar. We can track this via `tool_result` events for `write` and `edit` tools.
|
|
221
|
+
|
|
222
|
+
### tuicr (Rust, `cargo install tuicr`)
|
|
223
|
+
|
|
224
|
+
GitHub: https://github.com/agavra/tuicr
|
|
225
|
+
|
|
226
|
+
A TUI for reviewing AI-generated diffs like a GitHub PR:
|
|
227
|
+
- **Infinite scroll diff view** - all changed files in one continuous scroll
|
|
228
|
+
- **Vim keybindings** - j/k, Ctrl-d/u, g/G, {/} for file jumping
|
|
229
|
+
- **Comments** - file-level or line-level with types (Note, Suggestion, Issue, Praise)
|
|
230
|
+
- **Visual mode** - select line ranges with v/V, comment on multiple lines
|
|
231
|
+
- **Session persistence** - reviews auto-save and reload
|
|
232
|
+
- **Clipboard export** - structured Markdown optimized for LLM consumption
|
|
233
|
+
- Supports git, jujutsu, mercurial
|
|
234
|
+
|
|
235
|
+
**Sample export format**:
|
|
236
|
+
```markdown
|
|
237
|
+
In `src/index.ts` (lines 4-6):
|
|
238
|
+
```ts
|
|
239
|
+
export function main() {
|
|
240
|
+
console.log('hello');
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
[Issue] This should take a name parameter
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Relevance**: The "select + comment + export for LLM" workflow is exactly what we want. Could either integrate tuicr or replicate the pattern.
|
|
247
|
+
|
|
248
|
+
### critique (Bun/TypeScript, `bunx critique`)
|
|
249
|
+
|
|
250
|
+
GitHub: https://github.com/remorses/critique
|
|
251
|
+
|
|
252
|
+
Beautiful terminal diff viewer:
|
|
253
|
+
- **Word-level diff** - not just line-level, shows exactly what changed within lines
|
|
254
|
+
- **Split view** - side-by-side comparison
|
|
255
|
+
- **Syntax highlighting** - via tree-sitter
|
|
256
|
+
- **Watch mode** - `critique --watch` auto-refreshes on file changes
|
|
257
|
+
- **AI-powered explanation** - `critique review` uses Claude Code or OpenCode to explain changes
|
|
258
|
+
- **Web preview** - `critique web` generates shareable URL
|
|
259
|
+
- **Lazygit integration** - can be used as custom pager
|
|
260
|
+
- **Branch comparison** - `critique main feature-branch` for PR-style diffs
|
|
261
|
+
|
|
262
|
+
Commands:
|
|
263
|
+
```bash
|
|
264
|
+
critique # View unstaged changes
|
|
265
|
+
critique --staged # View staged changes
|
|
266
|
+
critique HEAD # View last commit
|
|
267
|
+
critique --watch # Auto-refresh on changes
|
|
268
|
+
critique review # AI-powered explanation
|
|
269
|
+
critique web # Generate shareable web preview
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Relevance**: Word-level diff is important for prose/markdown review. Could shell out to critique for diff viewing, or adopt their approach.
|
|
273
|
+
|
|
274
|
+
### Integration Options Considered
|
|
275
|
+
|
|
276
|
+
| Approach | Pros | Cons |
|
|
277
|
+
|----------|------|------|
|
|
278
|
+
| Shell out to tuicr/critique | Battle-tested, feature-rich | Context switch, lose pi output visibility |
|
|
279
|
+
| Embed in pi widget | No context switch, agent-aware | More work, rebuild existing features |
|
|
280
|
+
| Hybrid (tree in pi, diff in external) | Best of both | Still some context switch |
|
|
281
|
+
|
|
282
|
+
**Decision**: Build file browser in pi (stays visible), use external tools for complex diff viewing if user wants, but provide basic in-pi diff view for quick checks.
|
|
283
|
+
|
|
284
|
+
### tuicr Integration Analysis
|
|
285
|
+
|
|
286
|
+
**Value**: High - tuicr was built specifically for the "review AI changes and send feedback" workflow we want.
|
|
287
|
+
|
|
288
|
+
**Key Features**:
|
|
289
|
+
- Clipboard export in LLM-optimized markdown format
|
|
290
|
+
- Comment types (Note, Suggestion, Issue, Praise)
|
|
291
|
+
- Session persistence (reviews survive restarts)
|
|
292
|
+
- Visual mode for multi-line selection
|
|
293
|
+
|
|
294
|
+
**Integration Approach**:
|
|
295
|
+
```bash
|
|
296
|
+
# User triggers review mode from pi
|
|
297
|
+
# 1. Pi extension spawns tuicr
|
|
298
|
+
tuicr
|
|
299
|
+
|
|
300
|
+
# 2. User reviews, adds comments, presses :wq or y (copy to clipboard)
|
|
301
|
+
# 3. tuicr exits, clipboard contains structured review
|
|
302
|
+
|
|
303
|
+
# 4. Pi extension reads clipboard and sends to agent
|
|
304
|
+
pbpaste | pi.sendUserMessage(...)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**Feasibility**: Medium
|
|
308
|
+
- tuicr is a full TUI that takes over the terminal (can't see pi output while reviewing)
|
|
309
|
+
- No stdout/file output mode - only clipboard (would need to read clipboard after exit)
|
|
310
|
+
- User must quit tuicr to return to pi
|
|
311
|
+
- But: the workflow is natural - "let me review these changes" → review → return with feedback
|
|
312
|
+
|
|
313
|
+
**Proposed UX**:
|
|
314
|
+
```
|
|
315
|
+
You: [working with agent]
|
|
316
|
+
Agent: [makes changes to multiple files]
|
|
317
|
+
You: /review # or Ctrl+R
|
|
318
|
+
[tuicr opens, shows all unstaged changes]
|
|
319
|
+
[user navigates, adds comments]
|
|
320
|
+
[user presses :wq]
|
|
321
|
+
[tuicr exits, review copied to clipboard]
|
|
322
|
+
[pi reads clipboard, sends as steering message]
|
|
323
|
+
Agent: [receives structured feedback, addresses comments]
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Implementation**:
|
|
327
|
+
```typescript
|
|
328
|
+
pi.registerCommand("review", {
|
|
329
|
+
description: "Open tuicr to review changes, send feedback to agent",
|
|
330
|
+
handler: async (args, ctx) => {
|
|
331
|
+
// Check if tuicr is installed
|
|
332
|
+
if (!hasCommand("tuicr")) {
|
|
333
|
+
ctx.ui.notify("Install tuicr: brew install agavra/tap/tuicr", "error");
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Spawn tuicr (takes over terminal)
|
|
338
|
+
const result = await ctx.exec("tuicr", [], { stdio: "inherit" });
|
|
339
|
+
|
|
340
|
+
// Read clipboard after tuicr exits
|
|
341
|
+
const review = execSync("pbpaste", { encoding: "utf-8" });
|
|
342
|
+
|
|
343
|
+
if (review.includes("## Review Summary") || review.includes("```")) {
|
|
344
|
+
// Looks like a tuicr export, send to agent
|
|
345
|
+
pi.sendUserMessage(review, { deliverAs: "steer" });
|
|
346
|
+
ctx.ui.notify("Review sent to agent", "success");
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### critique Integration Analysis
|
|
353
|
+
|
|
354
|
+
**Value**: High for diff viewing, medium for review workflow (no built-in comment system).
|
|
355
|
+
|
|
356
|
+
**Key Features**:
|
|
357
|
+
- Word-level diff (great for prose/markdown)
|
|
358
|
+
- `--watch` mode for live updates
|
|
359
|
+
- `--stdin` for piping (lazygit integration)
|
|
360
|
+
- `critique review` uses AI to explain changes
|
|
361
|
+
- `critique web` for shareable URLs
|
|
362
|
+
|
|
363
|
+
**Integration Approaches**:
|
|
364
|
+
|
|
365
|
+
1. **As diff viewer only** (simple):
|
|
366
|
+
```bash
|
|
367
|
+
# View specific file diff
|
|
368
|
+
critique --filter "src/index.ts"
|
|
369
|
+
|
|
370
|
+
# Watch mode while agent works
|
|
371
|
+
critique --watch
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
2. **As lazygit pager** (if user has lazygit):
|
|
375
|
+
```yaml
|
|
376
|
+
# ~/.config/lazygit/config.yml
|
|
377
|
+
git:
|
|
378
|
+
paging:
|
|
379
|
+
pager: critique --stdin
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
3. **Web preview for sharing** (useful for async review):
|
|
383
|
+
```bash
|
|
384
|
+
critique web --title "Agent changes for review"
|
|
385
|
+
# Returns URL like critique.work/v/abc123
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Feasibility**: High
|
|
389
|
+
- `--watch` mode is ideal for "keep an eye on changes while agent works"
|
|
390
|
+
- No comment system, but pairs well with our in-pi select+comment flow
|
|
391
|
+
- Requires Bun (not Node.js)
|
|
392
|
+
|
|
393
|
+
**Proposed UX**:
|
|
394
|
+
```
|
|
395
|
+
You: /diff # Quick diff view
|
|
396
|
+
[critique opens showing current changes]
|
|
397
|
+
[user reviews, presses q to quit]
|
|
398
|
+
[returns to pi]
|
|
399
|
+
|
|
400
|
+
You: /diff --watch # Live watch mode
|
|
401
|
+
[critique opens in watch mode]
|
|
402
|
+
[updates as agent modifies files]
|
|
403
|
+
[user presses q when done]
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Recommended Integration Strategy
|
|
407
|
+
|
|
408
|
+
**Phase 1 (MVP)**: Built-in basic diff
|
|
409
|
+
- Simple `git diff` via `delta` in pi's file viewer
|
|
410
|
+
- No external dependencies required
|
|
411
|
+
- Good enough for quick checks
|
|
412
|
+
|
|
413
|
+
**Phase 2**: Optional tuicr integration
|
|
414
|
+
- `/review` command spawns tuicr
|
|
415
|
+
- Clipboard capture sends review to agent
|
|
416
|
+
- Requires `brew install agavra/tap/tuicr`
|
|
417
|
+
|
|
418
|
+
**Phase 3**: Optional critique integration
|
|
419
|
+
- `/diff` command spawns critique
|
|
420
|
+
- `/diff --watch` for live monitoring
|
|
421
|
+
- Requires Bun + `bun install -g critique`
|
|
422
|
+
|
|
423
|
+
**Phase 4**: Deep integration
|
|
424
|
+
- Track which tool calls modified which files
|
|
425
|
+
- Pass this metadata to tuicr/critique
|
|
426
|
+
- Show "agent modified" vs "human modified" in diff view
|
|
427
|
+
|
|
428
|
+
### Tools for Syntax Highlighting / Rendering
|
|
429
|
+
|
|
430
|
+
| Tool | Purpose | Install |
|
|
431
|
+
|------|---------|---------|
|
|
432
|
+
| `bat` | Syntax highlighting, line numbers | `brew install bat` |
|
|
433
|
+
| `delta` | Git diff beautifier, side-by-side | `brew install git-delta` |
|
|
434
|
+
| `glow` | Markdown rendering | `brew install glow` |
|
|
435
|
+
| `fd` | Fast file finder (respects .gitignore) | `brew install fd` |
|
|
436
|
+
|
|
437
|
+
These are standalone tools. This extension aims to provide similar functionality *inside* Pi without context switching, while optionally leveraging these tools for rendering.
|
|
438
|
+
|
|
439
|
+
### Pi Extension Capabilities Used
|
|
440
|
+
- `ctx.ui.setWidget()` - Persistent widget above/below editor
|
|
441
|
+
- `ctx.ui.custom()` - Full-screen custom TUI component
|
|
442
|
+
- `pi.registerShortcut()` - Custom keybindings
|
|
443
|
+
- `pi.sendUserMessage()` - Send steering messages to agent
|
|
444
|
+
- `pi.on("tool_result")` - Track file modifications
|
|
445
|
+
- `pi.appendEntry()` - Persist state in session
|
|
446
|
+
|
|
447
|
+
## Open Questions
|
|
448
|
+
|
|
449
|
+
1. **Widget height** - Fixed height or percentage of terminal? Collapsible?
|
|
450
|
+
2. **Multi-file comments** - Queue comments across files before sending, or send immediately?
|
|
451
|
+
3. **Diff base** - Always vs HEAD, or configurable (vs staged, vs specific commit)?
|
|
452
|
+
4. **File watcher** - Auto-refresh tree when files change, or manual refresh?
|
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# files-widget
|
|
2
|
+
|
|
3
|
+
In-terminal file browser and viewer for Pi. Navigate files, view diffs, select code, and send comments to the agent without leaving the terminal.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
**Quick install (Pi package manager):**
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pi install npm:@tmustier/pi-files-widget
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pi install git:github.com/tmustier/pi-extensions
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then add to `~/.pi/agent/settings.json`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"packages": [
|
|
24
|
+
{
|
|
25
|
+
"source": "git:github.com/tmustier/pi-extensions",
|
|
26
|
+
"extensions": ["files-widget/index.ts"]
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Local clone:**
|
|
33
|
+
|
|
34
|
+
Add to your Pi extensions list:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"extensions": [
|
|
39
|
+
"~/pi-extensions/files-widget"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If you prefer symlinking into `~/.pi/agent/extensions`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ln -sfn ~/pi-extensions/files-widget ~/.pi/agent/extensions/files-widget
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then reference it in your settings:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"extensions": [
|
|
55
|
+
"~/.pi/agent/extensions/files-widget"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Dependencies (recommended)
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
brew install bat git-delta glow
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- `bat`: syntax highlighting
|
|
67
|
+
- `delta`: formatted diffs
|
|
68
|
+
- `glow`: markdown rendering
|
|
69
|
+
|
|
70
|
+
If any are missing, the extension will notify you at session start and gracefully fall back to plain rendering.
|
|
71
|
+
|
|
72
|
+
## Commands
|
|
73
|
+
|
|
74
|
+
- `/files` - open the file browser
|
|
75
|
+
- `/review` - open tuicr review flow
|
|
76
|
+
- `/diff` - open critique (bunx critique)
|
|
77
|
+
|
|
78
|
+
### Review/Diff Dependencies
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
brew install agavra/tap/tuicr
|
|
82
|
+
brew install oven-sh/bun/bun
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- `tuicr` is required for `/review`
|
|
86
|
+
- `bun` is required for `/diff`
|
|
87
|
+
|
|
88
|
+
If missing, `/review` or `/diff` will show a clear install prompt.
|
|
89
|
+
|
|
90
|
+
## Browser Keybindings
|
|
91
|
+
|
|
92
|
+
- `j/k` or `↑/↓`: move
|
|
93
|
+
- `Enter`: open file / expand folder
|
|
94
|
+
- `h/l` or `←/→`: collapse/expand folder
|
|
95
|
+
- `PgUp/PgDn`: page up/down
|
|
96
|
+
- `c`: toggle changed-only view
|
|
97
|
+
- `]` / `[`: next/prev changed file
|
|
98
|
+
- `/`: search (type to filter, `Esc` to exit)
|
|
99
|
+
- `+` / `-`: increase/decrease browser height
|
|
100
|
+
- `q`: close
|
|
101
|
+
|
|
102
|
+
## Viewer Keybindings
|
|
103
|
+
|
|
104
|
+
- `j/k` or `↑/↓`: scroll
|
|
105
|
+
- `PgUp/PgDn`: page up/down
|
|
106
|
+
- `g/G`: top/bottom
|
|
107
|
+
- `d`: toggle diff (tracked files only)
|
|
108
|
+
- `/`: search (type to search)
|
|
109
|
+
- `n` / `N`: next/prev match
|
|
110
|
+
- `v`: select mode (line selection)
|
|
111
|
+
- `c`: comment on selected lines (inline prompt)
|
|
112
|
+
- `]` / `[`: next/prev changed file
|
|
113
|
+
- `+` / `-`: increase/decrease viewer height
|
|
114
|
+
- `q`: back to browser
|
|
115
|
+
|
|
116
|
+
## Notes
|
|
117
|
+
|
|
118
|
+
- Untracked files show as `[UNTRACKED]` and open in normal view.
|
|
119
|
+
- Folder LOCs are shown only when the folder is collapsed (expanded folders would duplicate counts).
|
|
120
|
+
- Git status refreshes every 3 seconds while `/files` is open.
|