@rotorsoft/gent 1.16.0 → 1.17.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 +169 -163
- package/dist/index.js +47 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# @rotorsoft/gent
|
|
2
2
|
|
|
3
|
-
AI-powered GitHub workflow
|
|
3
|
+
AI-powered GitHub workflow tool - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs from an interactive dashboard.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
`gent`
|
|
7
|
+
`gent` provides an interactive dashboard that integrates AI with GitHub to automate your development workflow. Just run `gent` to launch:
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
9
|
+
- **Dashboard at a glance** - See your current ticket, branch, PR, and commits in one view
|
|
10
|
+
- **Context-aware actions** - The dashboard adapts to your workflow state with relevant shortcuts
|
|
11
|
+
- **Create AI-enhanced tickets** - Describe what you need, the AI generates detailed GitHub issues
|
|
12
|
+
- **Implement with AI** - Select a ticket and let the AI implement it with automatic branch management
|
|
12
13
|
- **Create smart PRs** - Generate AI-enhanced pull requests with proper descriptions
|
|
13
14
|
- **Iterate on feedback** - Address PR review comments with AI assistance
|
|
14
15
|
|
|
@@ -32,7 +33,7 @@ Verify prerequisites:
|
|
|
32
33
|
gh auth status # Should show authenticated
|
|
33
34
|
claude --version # Should show version (if using Claude)
|
|
34
35
|
gemini --version # Should show version (if using Gemini)
|
|
35
|
-
codex --version
|
|
36
|
+
codex --version # Should show version (if using Codex)
|
|
36
37
|
```
|
|
37
38
|
|
|
38
39
|
## Quick Start
|
|
@@ -57,97 +58,167 @@ gent setup-labels
|
|
|
57
58
|
|
|
58
59
|
Creates workflow labels (`ai-ready`, `ai-in-progress`, etc.) and category labels.
|
|
59
60
|
|
|
60
|
-
### 3.
|
|
61
|
+
### 3. Launch the dashboard
|
|
61
62
|
|
|
62
63
|
```bash
|
|
63
|
-
gent
|
|
64
|
+
gent
|
|
64
65
|
```
|
|
65
66
|
|
|
66
|
-
The AI
|
|
67
|
-
- Generate a detailed issue with technical context
|
|
68
|
-
- Infer appropriate labels (type, priority, risk, area)
|
|
69
|
-
- Create the issue on GitHub with `ai-ready` label
|
|
67
|
+
The dashboard is your primary interface. From here you can create tickets, switch between issues, run AI implementations, commit, push, and create PRs - all with single-key shortcuts.
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
## Dashboard
|
|
72
70
|
|
|
73
|
-
|
|
74
|
-
# Pick a specific issue
|
|
75
|
-
gent run 123
|
|
71
|
+
Running `gent` launches an interactive dashboard that shows your current workflow at a glance:
|
|
76
72
|
|
|
77
|
-
|
|
78
|
-
gent
|
|
73
|
+
```
|
|
74
|
+
┌ gent v1.17.0 ────────────────────────────────────────┐
|
|
75
|
+
│ Provider: Claude │
|
|
76
|
+
│ GitHub: authenticated │
|
|
77
|
+
├ Ticket ──────────────────────────────────────────────┤
|
|
78
|
+
│ · #47 Add interactive TUI interface │
|
|
79
|
+
│ IN PROGRESS type:feature priority:high area:ui │
|
|
80
|
+
├ Branch ──────────────────────────────────────────────┤
|
|
81
|
+
│ · ro/feature-47-add-interactive-tui │
|
|
82
|
+
│ 3 ahead · ● uncommitted · ● unpushed │
|
|
83
|
+
├ Pull Request ────────────────────────────────────────┤
|
|
84
|
+
│ No PR created │
|
|
85
|
+
├ Commits ─────────────────────────────────────────────┤
|
|
86
|
+
│ · feat: add TUI state aggregation │
|
|
87
|
+
│ · feat: add TUI display components │
|
|
88
|
+
├──────────────────────────────────────────────────────┤
|
|
89
|
+
│ new commit push pr run list refresh ai quit │
|
|
90
|
+
└──────────────────────────────────────────────────────┘
|
|
79
91
|
```
|
|
80
92
|
|
|
81
|
-
|
|
82
|
-
- Create a feature branch
|
|
83
|
-
- Update labels to `ai-in-progress`
|
|
84
|
-
- Implement the feature following your `AGENT.md` instructions
|
|
85
|
-
- Run validation commands
|
|
86
|
-
- Create a commit
|
|
87
|
-
- Update labels to `ai-completed`
|
|
93
|
+
### Dashboard Panels
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
- **Settings** - Shows AI provider, GitHub auth status, and update notifications
|
|
96
|
+
- **Ticket** - Current issue with labels, priority, and workflow status badges
|
|
97
|
+
- **Branch** - Current branch with sync status (ahead/uncommitted/unpushed/synced)
|
|
98
|
+
- **Pull Request** - PR state (open/draft/merged/closed), review decision, and actionable feedback count
|
|
99
|
+
- **Commits** - Recent commits on the current branch
|
|
100
|
+
- **Hint** - Contextual suggestion based on your workflow state
|
|
90
101
|
|
|
91
|
-
|
|
92
|
-
gent pr
|
|
93
|
-
```
|
|
102
|
+
### Keyboard Shortcuts
|
|
94
103
|
|
|
95
|
-
The
|
|
96
|
-
- Generate a PR description from commits and linked issue
|
|
97
|
-
- Include "Closes #" reference
|
|
98
|
-
- Create the PR on GitHub
|
|
104
|
+
The dashboard shows only the actions relevant to your current context:
|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
| Key | Action | When Available |
|
|
107
|
+
|-----|--------|----------------|
|
|
108
|
+
| `n` | New ticket | Always |
|
|
109
|
+
| `c` | Commit changes | Uncommitted changes on feature branch |
|
|
110
|
+
| `s` | Push (send) to remote | Unpushed commits on feature branch |
|
|
111
|
+
| `p` | Create PR | Feature branch with commits, no PR yet |
|
|
112
|
+
| `r` | Run AI implementation | Feature branch with linked issue, PR not merged |
|
|
113
|
+
| `l` | List and switch tickets | Always |
|
|
114
|
+
| `f` | Refresh dashboard | Always |
|
|
115
|
+
| `a` | Switch AI provider | Always |
|
|
116
|
+
| `q` | Quit | Always |
|
|
101
117
|
|
|
102
|
-
|
|
118
|
+
### Context-Aware Behavior
|
|
103
119
|
|
|
104
|
-
|
|
105
|
-
gent fix
|
|
106
|
-
```
|
|
120
|
+
The dashboard adapts to your current state:
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
-
- Auto-reply to addressed feedback comments
|
|
122
|
+
- **On main branch** - Shows "ready to start new work"; use `n` to create a ticket or `l` to pick an existing one
|
|
123
|
+
- **Uncommitted changes** - Hints to commit before creating a PR
|
|
124
|
+
- **No PR yet** - Offers to create a pull request after commits are pushed
|
|
125
|
+
- **PR with review feedback** - Shows actionable comment count and hints to address feedback
|
|
126
|
+
- **UI changes with Playwright** - Notes that video capture is available
|
|
114
127
|
|
|
115
|
-
|
|
128
|
+
### Modal Dialogs
|
|
116
129
|
|
|
117
|
-
|
|
130
|
+
Actions that need input (commit, list, create, switch provider) open floating modal dialogs over the dashboard. Modals support:
|
|
118
131
|
|
|
119
|
-
|
|
132
|
+
- **Select** - Arrow keys to navigate, Enter to confirm, Escape to cancel
|
|
133
|
+
- **Confirm** - y/n to confirm or cancel
|
|
134
|
+
- **Input** - Type text, Enter to submit, Escape to cancel
|
|
135
|
+
- **Multiline input** - For ticket descriptions; Enter for newline, Ctrl+S to submit
|
|
120
136
|
|
|
121
|
-
|
|
122
|
-
gent v2.0.0 Claude · gh
|
|
137
|
+
### Typical Workflow from the Dashboard
|
|
123
138
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
│ No PR created │
|
|
132
|
-
├ Commits ─────────────────────────────────────────────┤
|
|
133
|
-
│ feat: add TUI state aggregation │
|
|
134
|
-
│ feat: add TUI display components │
|
|
135
|
-
└──────────────────────────────────────────────────────┘
|
|
139
|
+
1. Press `n` to create a new ticket (describe the feature in the multiline input)
|
|
140
|
+
2. Press `l` to list tickets and switch to the new one (creates a branch automatically)
|
|
141
|
+
3. Press `r` to run AI implementation (opens an interactive AI session)
|
|
142
|
+
4. Press `c` to commit (choose AI-generated or manual commit message)
|
|
143
|
+
5. Press `s` to send (push) to remote
|
|
144
|
+
6. Press `p` to create a pull request
|
|
145
|
+
7. After review feedback, press `r` again to address comments (review context is included automatically)
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
## Workflow
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
151
|
+
│ GENT WORKFLOW │
|
|
152
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
153
|
+
|
|
154
|
+
┌──────────┐ n (new) ┌──────────┐
|
|
155
|
+
│ Idea │ ─────────────────>│ Issue │
|
|
156
|
+
└──────────┘ │ ai-ready │
|
|
157
|
+
└────┬─────┘
|
|
158
|
+
│
|
|
159
|
+
l (list) → select
|
|
160
|
+
│
|
|
161
|
+
v
|
|
162
|
+
┌──────────┐
|
|
163
|
+
│ Branch │
|
|
164
|
+
│ created │
|
|
165
|
+
└────┬─────┘
|
|
166
|
+
│
|
|
167
|
+
r (run)
|
|
168
|
+
│
|
|
169
|
+
v
|
|
170
|
+
┌──────────┐
|
|
171
|
+
│ Issue │
|
|
172
|
+
│ai-complete│
|
|
173
|
+
└────┬─────┘
|
|
174
|
+
│
|
|
175
|
+
c (commit) → s (send) → p (pr)
|
|
176
|
+
│
|
|
177
|
+
v
|
|
178
|
+
┌──────────┐
|
|
179
|
+
│ PR │
|
|
180
|
+
│ created │
|
|
181
|
+
└────┬─────┘
|
|
182
|
+
│
|
|
183
|
+
Human review
|
|
184
|
+
│
|
|
185
|
+
┌──────────┴──────────┐
|
|
186
|
+
│ │
|
|
187
|
+
Changes Approved
|
|
188
|
+
requested │
|
|
189
|
+
│ │
|
|
190
|
+
r (run) │
|
|
191
|
+
│ │
|
|
192
|
+
v │
|
|
193
|
+
┌──────────┐ │
|
|
194
|
+
│ AI │ │
|
|
195
|
+
│ fixes │───────────────┤
|
|
196
|
+
└────┬─────┘ │
|
|
197
|
+
│ │
|
|
198
|
+
└─── (repeat if needed)
|
|
199
|
+
│
|
|
200
|
+
Merge PR
|
|
201
|
+
│
|
|
202
|
+
v
|
|
203
|
+
┌──────────┐
|
|
204
|
+
│ Issue │
|
|
205
|
+
│ closed │
|
|
206
|
+
└──────────┘
|
|
139
207
|
```
|
|
140
208
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
- **No PR yet** - offers to create a pull request
|
|
145
|
-
- **PR with review feedback** - offers to fix review comments
|
|
146
|
-
- **UI changes with Playwright** - offers to record demo videos
|
|
209
|
+
## CLI Reference
|
|
210
|
+
|
|
211
|
+
All dashboard actions map to CLI commands that can also be run directly. This is useful for scripting, CI pipelines, or if you prefer a command-driven workflow.
|
|
147
212
|
|
|
148
|
-
|
|
213
|
+
### `gent`
|
|
149
214
|
|
|
150
|
-
|
|
215
|
+
Launch the interactive dashboard (default when no command is given).
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
gent
|
|
219
|
+
# or explicitly
|
|
220
|
+
gent ui
|
|
221
|
+
```
|
|
151
222
|
|
|
152
223
|
### `gent init`
|
|
153
224
|
|
|
@@ -177,11 +248,11 @@ Creates labels in these categories:
|
|
|
177
248
|
|
|
178
249
|
### `gent create <description>`
|
|
179
250
|
|
|
180
|
-
Create an AI-enhanced GitHub issue.
|
|
251
|
+
Create an AI-enhanced GitHub issue (dashboard: `n`).
|
|
181
252
|
|
|
182
253
|
```bash
|
|
183
254
|
gent create "Add dark mode toggle to settings page"
|
|
184
|
-
gent create "Fix login bug" --provider gemini
|
|
255
|
+
gent create "Fix login bug" --provider gemini
|
|
185
256
|
```
|
|
186
257
|
|
|
187
258
|
Options:
|
|
@@ -190,7 +261,7 @@ Options:
|
|
|
190
261
|
|
|
191
262
|
### `gent list`
|
|
192
263
|
|
|
193
|
-
List GitHub issues
|
|
264
|
+
List and switch between GitHub issues (dashboard: `l`).
|
|
194
265
|
|
|
195
266
|
```bash
|
|
196
267
|
gent list # Show ai-ready issues
|
|
@@ -206,21 +277,19 @@ Options:
|
|
|
206
277
|
|
|
207
278
|
### `gent run [issue-number]`
|
|
208
279
|
|
|
209
|
-
Run AI to implement a GitHub issue.
|
|
280
|
+
Run AI to implement a GitHub issue (dashboard: `r`).
|
|
210
281
|
|
|
211
282
|
```bash
|
|
212
283
|
gent run 123 # Implement issue #123
|
|
213
|
-
gent run --auto # Auto-select highest priority ai-ready issue
|
|
214
284
|
gent run 123 --provider gemini # Use specific AI provider
|
|
215
285
|
```
|
|
216
286
|
|
|
217
287
|
Options:
|
|
218
|
-
- `-a, --auto` - Auto-select highest priority ai-ready issue
|
|
219
288
|
- `-p, --provider <provider>` - AI provider to use (`claude`, `gemini`, or `codex`)
|
|
220
289
|
|
|
221
290
|
### `gent pr`
|
|
222
291
|
|
|
223
|
-
Create an AI-enhanced pull request.
|
|
292
|
+
Create an AI-enhanced pull request (dashboard: `p`).
|
|
224
293
|
|
|
225
294
|
```bash
|
|
226
295
|
gent pr # Create PR
|
|
@@ -254,7 +323,7 @@ Options:
|
|
|
254
323
|
|
|
255
324
|
### `gent status`
|
|
256
325
|
|
|
257
|
-
Show current workflow status.
|
|
326
|
+
Show current workflow status (useful for scripting and debugging).
|
|
258
327
|
|
|
259
328
|
```bash
|
|
260
329
|
gent status
|
|
@@ -269,18 +338,6 @@ Displays:
|
|
|
269
338
|
- PR status
|
|
270
339
|
- Suggested actions
|
|
271
340
|
|
|
272
|
-
### `gent ui`
|
|
273
|
-
|
|
274
|
-
Launch the interactive dashboard. Also available by running `gent` with no arguments.
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
gent ui
|
|
278
|
-
# or simply
|
|
279
|
-
gent
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
The dashboard displays panels for Ticket, Branch, Pull Request, and Commits with context-aware keyboard shortcuts at the bottom. Actions refresh the dashboard automatically after completion.
|
|
283
|
-
|
|
284
341
|
## Configuration
|
|
285
342
|
|
|
286
343
|
### .gent.yml
|
|
@@ -360,68 +417,6 @@ Append-only log that tracks AI implementation sessions. Each entry includes:
|
|
|
360
417
|
|
|
361
418
|
This provides context for future AI sessions and human reviewers.
|
|
362
419
|
|
|
363
|
-
## Workflow
|
|
364
|
-
|
|
365
|
-
```
|
|
366
|
-
┌─────────────────────────────────────────────────────────────────┐
|
|
367
|
-
│ GENT WORKFLOW │
|
|
368
|
-
└─────────────────────────────────────────────────────────────────┘
|
|
369
|
-
|
|
370
|
-
┌──────────┐ gent create ┌──────────┐
|
|
371
|
-
│ Idea │ ─────────────────>│ Issue │
|
|
372
|
-
└──────────┘ │ ai-ready │
|
|
373
|
-
└────┬─────┘
|
|
374
|
-
│
|
|
375
|
-
gent run
|
|
376
|
-
│
|
|
377
|
-
v
|
|
378
|
-
┌──────────┐
|
|
379
|
-
│ Branch │
|
|
380
|
-
│ created │
|
|
381
|
-
└────┬─────┘
|
|
382
|
-
│
|
|
383
|
-
AI implements
|
|
384
|
-
│
|
|
385
|
-
v
|
|
386
|
-
┌──────────┐
|
|
387
|
-
│ Issue │
|
|
388
|
-
│ai-complete│
|
|
389
|
-
└────┬─────┘
|
|
390
|
-
│
|
|
391
|
-
gent pr
|
|
392
|
-
│
|
|
393
|
-
v
|
|
394
|
-
┌──────────┐
|
|
395
|
-
│ PR │
|
|
396
|
-
│ created │
|
|
397
|
-
└────┬─────┘
|
|
398
|
-
│
|
|
399
|
-
Human review
|
|
400
|
-
│
|
|
401
|
-
┌──────────┴──────────┐
|
|
402
|
-
│ │
|
|
403
|
-
Changes Approved
|
|
404
|
-
requested │
|
|
405
|
-
│ │
|
|
406
|
-
gent fix │
|
|
407
|
-
│ │
|
|
408
|
-
v │
|
|
409
|
-
┌──────────┐ │
|
|
410
|
-
│ AI │ │
|
|
411
|
-
│ fixes │───────────────┤
|
|
412
|
-
└────┬─────┘ │
|
|
413
|
-
│ │
|
|
414
|
-
└─── (repeat if needed)
|
|
415
|
-
│
|
|
416
|
-
Merge PR
|
|
417
|
-
│
|
|
418
|
-
v
|
|
419
|
-
┌──────────┐
|
|
420
|
-
│ Issue │
|
|
421
|
-
│ closed │
|
|
422
|
-
└──────────┘
|
|
423
|
-
```
|
|
424
|
-
|
|
425
420
|
## Label Conventions
|
|
426
421
|
|
|
427
422
|
### Workflow Status
|
|
@@ -473,7 +468,7 @@ Examples:
|
|
|
473
468
|
The author is derived from:
|
|
474
469
|
1. `GENT_AUTHOR` environment variable (if `author_source: env`)
|
|
475
470
|
2. `git config user.initials` (if set)
|
|
476
|
-
3. Initials from `git config user.name` (e.g., "John Doe"
|
|
471
|
+
3. Initials from `git config user.name` (e.g., "John Doe" -> "jd")
|
|
477
472
|
|
|
478
473
|
## Environment Variables
|
|
479
474
|
|
|
@@ -481,12 +476,15 @@ The author is derived from:
|
|
|
481
476
|
|----------|-------------|
|
|
482
477
|
| `GENT_AUTHOR` | Override author initials for branch naming |
|
|
483
478
|
| `GENT_AI_PROVIDER` | Override AI provider (`claude`, `gemini`, or `codex`) |
|
|
479
|
+
| `GENT_SKIP_UPDATE_CHECK` | Set to `1` to disable update notifications |
|
|
484
480
|
| `DEBUG` | Enable debug output |
|
|
485
481
|
|
|
486
482
|
## Tips
|
|
487
483
|
|
|
488
484
|
### Writing Good Descriptions
|
|
489
485
|
|
|
486
|
+
When creating tickets (via `n` in the dashboard or `gent create`):
|
|
487
|
+
|
|
490
488
|
```bash
|
|
491
489
|
# Good - specific and actionable
|
|
492
490
|
gent create "Add password reset functionality with email verification"
|
|
@@ -518,23 +516,31 @@ If the AI gets stuck (`ai-blocked` label):
|
|
|
518
516
|
|
|
519
517
|
### PR Review Iteration
|
|
520
518
|
|
|
521
|
-
|
|
519
|
+
After receiving review feedback, press `r` in the dashboard (or run `gent fix` from the CLI) to address comments. The AI automatically includes review context and only focuses on new feedback since your last commit. Unresolved threads are always included regardless of age.
|
|
522
520
|
|
|
523
521
|
```bash
|
|
524
|
-
#
|
|
522
|
+
# CLI equivalent for review iteration
|
|
525
523
|
gent fix # AI addresses the feedback
|
|
526
524
|
git push # Push the fixes
|
|
527
525
|
|
|
528
|
-
# If more feedback comes in
|
|
529
|
-
gent fix # AI only focuses on
|
|
526
|
+
# If more feedback comes in
|
|
527
|
+
gent fix # AI only focuses on NEW comments
|
|
530
528
|
git push # Push again
|
|
531
529
|
```
|
|
532
530
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
-
|
|
537
|
-
-
|
|
531
|
+
### Dashboard vs CLI
|
|
532
|
+
|
|
533
|
+
The dashboard (`gent`) is the recommended way to use gent. It provides:
|
|
534
|
+
- A unified view of your workflow state
|
|
535
|
+
- Context-aware actions (only shows what's relevant)
|
|
536
|
+
- Modal dialogs for input (no need to remember command flags)
|
|
537
|
+
- Automatic refresh after actions
|
|
538
|
+
|
|
539
|
+
CLI commands are available for:
|
|
540
|
+
- Scripting and automation (`gent create --yes "..."`)
|
|
541
|
+
- CI/CD pipelines
|
|
542
|
+
- Users who prefer a command-driven workflow
|
|
543
|
+
- Advanced filtering (`gent list --status all --label priority:high`)
|
|
538
544
|
|
|
539
545
|
## Contributing
|
|
540
546
|
|
package/dist/index.js
CHANGED
|
@@ -2221,7 +2221,7 @@ import { homedir } from "os";
|
|
|
2221
2221
|
// package.json
|
|
2222
2222
|
var package_default = {
|
|
2223
2223
|
name: "@rotorsoft/gent",
|
|
2224
|
-
version: "1.
|
|
2224
|
+
version: "1.17.1",
|
|
2225
2225
|
description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
|
|
2226
2226
|
keywords: [
|
|
2227
2227
|
"cli",
|
|
@@ -2786,13 +2786,13 @@ function getAvailableActions(state) {
|
|
|
2786
2786
|
actions.push({ id: "commit", label: "commit", shortcut: "c" });
|
|
2787
2787
|
}
|
|
2788
2788
|
if (state.hasUnpushedCommits && state.commits.length > 0) {
|
|
2789
|
-
actions.push({ id: "push", label: "push", shortcut: "
|
|
2789
|
+
actions.push({ id: "push", label: "push", shortcut: "s" });
|
|
2790
2790
|
}
|
|
2791
2791
|
if (!state.pr && state.commits.length > 0) {
|
|
2792
|
-
actions.push({ id: "pr", label: "pr", shortcut: "
|
|
2792
|
+
actions.push({ id: "pr", label: "pr", shortcut: "p" });
|
|
2793
2793
|
}
|
|
2794
2794
|
if (state.issue && state.pr?.state !== "merged") {
|
|
2795
|
-
actions.push({ id: "run", label: "run", shortcut: "
|
|
2795
|
+
actions.push({ id: "run", label: "run", shortcut: "r" });
|
|
2796
2796
|
}
|
|
2797
2797
|
}
|
|
2798
2798
|
actions.push({ id: "list", label: "list", shortcut: "l" });
|
|
@@ -2907,14 +2907,14 @@ var shortcutColors = [
|
|
|
2907
2907
|
chalk3.red.bold
|
|
2908
2908
|
];
|
|
2909
2909
|
function formatAction(a, color) {
|
|
2910
|
-
const
|
|
2911
|
-
const
|
|
2910
|
+
const idx = a.label.indexOf(a.shortcut);
|
|
2911
|
+
const styledKey = color(chalk3.underline(a.shortcut));
|
|
2912
2912
|
if (idx >= 0) {
|
|
2913
2913
|
const before = a.label.slice(0, idx);
|
|
2914
|
-
const after = a.label.slice(idx +
|
|
2915
|
-
return chalk3.dim(before) +
|
|
2914
|
+
const after = a.label.slice(idx + a.shortcut.length);
|
|
2915
|
+
return chalk3.dim(before) + styledKey + chalk3.dim(after);
|
|
2916
2916
|
}
|
|
2917
|
-
return
|
|
2917
|
+
return styledKey + " " + chalk3.dim(a.label);
|
|
2918
2918
|
}
|
|
2919
2919
|
function formatCommandBar(actions, w) {
|
|
2920
2920
|
const parts = actions.map((a, i) => {
|
|
@@ -2971,14 +2971,22 @@ function buildDashboardLines(state, actions, hint, refreshing, versionCheck) {
|
|
|
2971
2971
|
out(topRow(titleLabel, w));
|
|
2972
2972
|
renderSettingsTo(state, w, out, versionCheck);
|
|
2973
2973
|
if (!state.isGitRepo) {
|
|
2974
|
-
out(row(chalk3.
|
|
2975
|
-
out(row(chalk3.dim("
|
|
2974
|
+
out(row(chalk3.yellow("Not a git repository"), w));
|
|
2975
|
+
out(row(chalk3.dim("Navigate to a git repository to get started"), w));
|
|
2976
|
+
out(divRow(w));
|
|
2977
|
+
for (const line of formatCommandBar(actions, w)) {
|
|
2978
|
+
out(row(line, w));
|
|
2979
|
+
}
|
|
2976
2980
|
out(botRow(w));
|
|
2977
2981
|
return lines;
|
|
2978
2982
|
}
|
|
2979
2983
|
if (!state.isGhAuthenticated) {
|
|
2980
2984
|
out(row(chalk3.red("GitHub CLI not authenticated"), w));
|
|
2981
2985
|
out(row(chalk3.dim("Run: gh auth login"), w));
|
|
2986
|
+
out(divRow(w));
|
|
2987
|
+
for (const line of formatCommandBar(actions, w)) {
|
|
2988
|
+
out(row(line, w));
|
|
2989
|
+
}
|
|
2982
2990
|
out(botRow(w));
|
|
2983
2991
|
return lines;
|
|
2984
2992
|
}
|
|
@@ -3138,7 +3146,7 @@ function buildModalFrame(title, contentLines, footerText, width) {
|
|
|
3138
3146
|
function isSeparator(entry) {
|
|
3139
3147
|
return "separator" in entry;
|
|
3140
3148
|
}
|
|
3141
|
-
function buildSelectContent(items, selectedIndex, maxWidth) {
|
|
3149
|
+
function buildSelectContent(items, selectedIndex, maxWidth, currentIndex) {
|
|
3142
3150
|
const lines = [];
|
|
3143
3151
|
let selectableIdx = 0;
|
|
3144
3152
|
for (const item of items) {
|
|
@@ -3146,12 +3154,12 @@ function buildSelectContent(items, selectedIndex, maxWidth) {
|
|
|
3146
3154
|
lines.push(chalk4.dim(item.separator));
|
|
3147
3155
|
} else {
|
|
3148
3156
|
const isSelected = selectableIdx === selectedIndex;
|
|
3157
|
+
const isCurrent = currentIndex != null && selectableIdx === currentIndex;
|
|
3149
3158
|
const prefix = isSelected ? chalk4.cyan.bold("> ") : " ";
|
|
3150
3159
|
const bullet = chalk4.dim("\xB7 ");
|
|
3151
3160
|
const label = truncateAnsi(item.name, maxWidth - 4);
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
);
|
|
3161
|
+
const styledLabel = isSelected ? chalk4.bold(label) : isCurrent ? chalk4.cyan(label) : label;
|
|
3162
|
+
lines.push(prefix + bullet + styledLabel);
|
|
3155
3163
|
selectableIdx++;
|
|
3156
3164
|
}
|
|
3157
3165
|
}
|
|
@@ -3320,9 +3328,9 @@ async function showSelect(opts) {
|
|
|
3320
3328
|
const w = modalWidth();
|
|
3321
3329
|
const maxItems = selectableCount(opts.items);
|
|
3322
3330
|
if (maxItems === 0) return null;
|
|
3323
|
-
let selectedIndex = 0;
|
|
3331
|
+
let selectedIndex = opts.initialIndex ?? 0;
|
|
3324
3332
|
const render = () => {
|
|
3325
|
-
const content = buildSelectContent(opts.items, selectedIndex, w - 6);
|
|
3333
|
+
const content = buildSelectContent(opts.items, selectedIndex, w - 6, opts.currentIndex);
|
|
3326
3334
|
const footer = "\u2191\u2193 Navigate Enter Select Esc Cancel";
|
|
3327
3335
|
const lines = buildModalFrame(opts.title, content, footer, w);
|
|
3328
3336
|
renderOverlay(opts.dashboardLines, lines, w);
|
|
@@ -3725,6 +3733,8 @@ async function handleList(dashboardLines) {
|
|
|
3725
3733
|
const currentBranch = await getCurrentBranch();
|
|
3726
3734
|
const defaultBranch = await getDefaultBranch();
|
|
3727
3735
|
const items = [];
|
|
3736
|
+
let initialIndex = 0;
|
|
3737
|
+
let selectableIdx = 0;
|
|
3728
3738
|
const isMain = currentBranch === defaultBranch;
|
|
3729
3739
|
const mainLabel = defaultBranch + (isMain ? " (current)" : "");
|
|
3730
3740
|
if (dirty && !isMain) {
|
|
@@ -3735,42 +3745,42 @@ async function handleList(dashboardLines) {
|
|
|
3735
3745
|
} else {
|
|
3736
3746
|
items.push({ name: mainLabel, value: "__main__" });
|
|
3737
3747
|
}
|
|
3748
|
+
if (isMain) initialIndex = selectableIdx;
|
|
3749
|
+
selectableIdx++;
|
|
3738
3750
|
const inProgressChoices = choices.filter(
|
|
3739
3751
|
(c) => c.category === "in-progress"
|
|
3740
3752
|
);
|
|
3741
3753
|
const openPrChoices = choices.filter((c) => c.category === "open-pr");
|
|
3742
3754
|
const readyChoices = choices.filter((c) => c.category === "ready");
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3755
|
+
const addChoices = (list) => {
|
|
3756
|
+
for (const c of list) {
|
|
3757
|
+
const isCurrent = c.branch === currentBranch;
|
|
3746
3758
|
items.push({
|
|
3747
3759
|
name: `#${c.issueNumber} ${c.title}`,
|
|
3748
3760
|
value: String(c.issueNumber)
|
|
3749
3761
|
});
|
|
3762
|
+
if (isCurrent) initialIndex = selectableIdx;
|
|
3763
|
+
selectableIdx++;
|
|
3750
3764
|
}
|
|
3765
|
+
};
|
|
3766
|
+
if (inProgressChoices.length > 0) {
|
|
3767
|
+
items.push({ separator: "\u2500\u2500 In Progress \u2500\u2500" });
|
|
3768
|
+
addChoices(inProgressChoices);
|
|
3751
3769
|
}
|
|
3752
3770
|
if (openPrChoices.length > 0) {
|
|
3753
3771
|
items.push({ separator: "\u2500\u2500 Open PRs \u2500\u2500" });
|
|
3754
|
-
|
|
3755
|
-
items.push({
|
|
3756
|
-
name: `#${c.issueNumber} ${c.title}`,
|
|
3757
|
-
value: String(c.issueNumber)
|
|
3758
|
-
});
|
|
3759
|
-
}
|
|
3772
|
+
addChoices(openPrChoices);
|
|
3760
3773
|
}
|
|
3761
3774
|
if (readyChoices.length > 0) {
|
|
3762
3775
|
items.push({ separator: "\u2500\u2500 Ready \u2500\u2500" });
|
|
3763
|
-
|
|
3764
|
-
items.push({
|
|
3765
|
-
name: `#${c.issueNumber} ${c.title}`,
|
|
3766
|
-
value: String(c.issueNumber)
|
|
3767
|
-
});
|
|
3768
|
-
}
|
|
3776
|
+
addChoices(readyChoices);
|
|
3769
3777
|
}
|
|
3770
3778
|
const selected = await showSelect({
|
|
3771
3779
|
title: "Switch Ticket",
|
|
3772
3780
|
items,
|
|
3773
|
-
dashboardLines
|
|
3781
|
+
dashboardLines,
|
|
3782
|
+
initialIndex,
|
|
3783
|
+
currentIndex: initialIndex
|
|
3774
3784
|
});
|
|
3775
3785
|
if (!selected) return false;
|
|
3776
3786
|
if (selected === "__main_disabled__") {
|
|
@@ -3877,13 +3887,16 @@ async function tuiCommand() {
|
|
|
3877
3887
|
isPlaywrightAvailable: false
|
|
3878
3888
|
};
|
|
3879
3889
|
let needsRefresh = true;
|
|
3890
|
+
let isFirstLoad = true;
|
|
3880
3891
|
while (running) {
|
|
3881
3892
|
if (needsRefresh) {
|
|
3882
3893
|
clearScreen();
|
|
3883
3894
|
renderDashboard(lastState, lastActions, void 0, true, versionCheck);
|
|
3895
|
+
const checkInterval = isFirstLoad ? 0 : VERSION_CHECK_INTERVAL_MS;
|
|
3896
|
+
isFirstLoad = false;
|
|
3884
3897
|
const [state, versionResult] = await Promise.all([
|
|
3885
3898
|
aggregateState(),
|
|
3886
|
-
checkForUpdates(
|
|
3899
|
+
checkForUpdates(checkInterval).catch(() => null)
|
|
3887
3900
|
]);
|
|
3888
3901
|
const actions = getAvailableActions(state);
|
|
3889
3902
|
lastState = state;
|