diffbutler 0.6.0__tar.gz → 0.7.0__tar.gz

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.
Files changed (118) hide show
  1. {diffbutler-0.6.0 → diffbutler-0.7.0}/PKG-INFO +32 -7
  2. {diffbutler-0.6.0 → diffbutler-0.7.0}/README.md +30 -5
  3. {diffbutler-0.6.0 → diffbutler-0.7.0}/pyproject.toml +4 -3
  4. {diffbutler-0.6.0 → diffbutler-0.7.0}/pyproject.toml.orig +4 -3
  5. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/default.toml +2 -5
  6. diffbutler-0.7.0/src/diffbutler/config/editor.py +535 -0
  7. diffbutler-0.7.0/src/diffbutler/config/file.py +70 -0
  8. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/settings.py +101 -18
  9. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/setup.py +16 -27
  10. diffbutler-0.7.0/src/diffbutler/config/transport.py +58 -0
  11. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/application.py +10 -3
  12. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/context.py +3 -1
  13. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/dashboard.py +20 -6
  14. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/managed.py +1 -0
  15. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/native.py +29 -5
  16. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/polling.py +24 -4
  17. diffbutler-0.7.0/src/diffbutler/core/pr_lookup.py +83 -0
  18. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/workspaces.py +54 -39
  19. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/forge.py +8 -0
  20. diffbutler-0.7.0/src/diffbutler/domain/polling.py +72 -0
  21. diffbutler-0.7.0/src/diffbutler/domain/redaction.py +90 -0
  22. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/sync.py +42 -3
  23. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/base.py +27 -0
  24. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/diagnostics.py +16 -17
  25. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/adapter.py +23 -12
  26. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/http.py +18 -2
  27. diffbutler-0.7.0/src/diffbutler/forges/github/repositories.py +104 -0
  28. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/native.py +22 -4
  29. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/presets.toml +4 -2
  30. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/sources/git.py +62 -32
  31. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/dashboard.py +3 -1
  32. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/database.py +66 -10
  33. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/lifecycle.py +2 -0
  34. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/queue.py +69 -12
  35. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/review.py +4 -0
  36. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/cli/__init__.py +28 -12
  37. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/_foreground_exec.py +2 -1
  38. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/dashboard.py +116 -33
  39. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/foreground.py +6 -1
  40. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/review_prompt.py +3 -2
  41. diffbutler-0.7.0/src/diffbutler/ui/tui/settings.py +337 -0
  42. diffbutler-0.6.0/src/diffbutler/config/file.py +0 -30
  43. diffbutler-0.6.0/src/diffbutler/config/transport.py +0 -65
  44. diffbutler-0.6.0/src/diffbutler/core/pr_lookup.py +0 -50
  45. diffbutler-0.6.0/src/diffbutler/domain/polling.py +0 -92
  46. diffbutler-0.6.0/src/diffbutler/domain/redaction.py +0 -61
  47. diffbutler-0.6.0/src/diffbutler/forges/github/repositories.py +0 -62
  48. {diffbutler-0.6.0 → diffbutler-0.7.0}/LICENSE.txt +0 -0
  49. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/__init__.py +0 -0
  50. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/__main__.py +0 -0
  51. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/__init__.py +0 -0
  52. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/diagnostics.py +0 -0
  53. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/config/instance.py +0 -0
  54. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/__init__.py +0 -0
  55. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/doctor.py +0 -0
  56. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/lifecycle.py +0 -0
  57. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/process.py +0 -0
  58. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/repositories.py +0 -0
  59. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/reset.py +0 -0
  60. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/resources.py +0 -0
  61. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/review.py +0 -0
  62. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/setup.py +0 -0
  63. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/snapshot.py +0 -0
  64. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/sync.py +0 -0
  65. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/core/worker.py +0 -0
  66. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/__init__.py +0 -0
  67. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/dashboard.py +0 -0
  68. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/diff.py +0 -0
  69. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/lifecycle.py +0 -0
  70. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/process.py +0 -0
  71. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/resources.py +0 -0
  72. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/domain/review.py +0 -0
  73. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/__init__.py +0 -0
  74. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/__init__.py +0 -0
  75. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/auth.py +0 -0
  76. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/mapping.py +0 -0
  77. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/github/setup.py +0 -0
  78. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/forges/registry.py +0 -0
  79. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/py.typed +0 -0
  80. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/__init__.py +0 -0
  81. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/base.py +0 -0
  82. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/extraction.py +0 -0
  83. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/parsing.py +0 -0
  84. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/process.py +0 -0
  85. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/prompt.py +0 -0
  86. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/redaction.py +0 -0
  87. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/reviewers/resources.py +0 -0
  88. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/sources/__init__.py +0 -0
  89. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/sources/diagnostics.py +0 -0
  90. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/sources/fetch.py +0 -0
  91. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/sources/remotes.py +0 -0
  92. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/__init__.py +0 -0
  93. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/base.py +0 -0
  94. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/__init__.py +0 -0
  95. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/env.py +0 -0
  96. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0001_initial.py +0 -0
  97. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0002_monitoring.py +0 -0
  98. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0003_reviews.py +0 -0
  99. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0004_claims.py +0 -0
  100. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0005_results.py +0 -0
  101. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0006_anchors.py +0 -0
  102. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0007_lifecycle.py +0 -0
  103. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0008_processes.py +0 -0
  104. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0009_dashboard.py +0 -0
  105. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0010_run_reasons.py +0 -0
  106. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/0011_explicit_reviews.py +0 -0
  107. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/migrations/versions/__init__.py +0 -0
  108. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/models.py +0 -0
  109. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/store/process.py +0 -0
  110. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/__init__.py +0 -0
  111. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/cli/editor.py +0 -0
  112. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/__init__.py +0 -0
  113. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/_fake_agent.py +0 -0
  114. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/app.py +0 -0
  115. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/browse.py +0 -0
  116. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/browser.py +0 -0
  117. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/handoff_probe.py +0 -0
  118. {diffbutler-0.6.0 → diffbutler-0.7.0}/src/diffbutler/ui/tui/terminal_theme.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffbutler
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: A terminal dashboard for human-directed AI code reviews.
5
5
  Keywords: code-review,github,terminal,ai
6
6
  License-Expression: MIT
7
7
  License-File: LICENSE.txt
8
- Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Development Status :: 4 - Beta
9
9
  Classifier: Environment :: Console
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -34,7 +34,7 @@ Keep track of what each pull request needs next: AI review, your review, or auth
34
34
  changes. Start an AI review, discuss its findings in the agent's own session, and
35
35
  finish your review in the browser.
36
36
 
37
- ![DiffButler dashboard showing pull requests and the next review action](diffbutler.png)
37
+ ![DiffButler dashboard showing pull requests and the next review action](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/diffbutler.png)
38
38
 
39
39
  ## Install
40
40
 
@@ -108,8 +108,8 @@ The dashboard shows active reviews, including followed PRs whose GitHub review
108
108
  requests have disappeared after you posted feedback. Waiting-for-author reviews
109
109
  stay visible across refreshes and restarts. If an approved PR receives new commits,
110
110
  it reappears as `done+` at the end of the queue without starting another AI review.
111
- Authenticated polling slows when API quota is scarce and speeds back up when it
112
- recovers, accounting for refresh cost and time until the quota resets.
111
+ Polling spreads API quota evenly until it resets, leaving 10% in reserve: it slows
112
+ when quota is scarce or refreshes are costly and speeds back up when quota recovers.
113
113
 
114
114
  Select a PR with the arrow keys, then work through the review:
115
115
 
@@ -128,7 +128,8 @@ Select a PR with the arrow keys, then work through the review:
128
128
  starts a new run with the current reviewer and replaces the current review details.
129
129
  Ask questions and explicitly tell the agent which comments to post, if any.
130
130
  3. Exit the agent to return to the dashboard, which refreshes activity from GitHub.
131
- Press `w` if you are waiting for author changes, or `o` to review in your browser.
131
+ Press `o` to open the PR in your browser at any time; it does not change the state.
132
+ Press `w` if you are waiting for author changes, or `a` once you are ready to approve.
132
133
  4. After approving on GitHub, press `m` to mark the task complete locally. DiffButler
133
134
  also detects your approval, closure, or merge and cleans up owned session resources
134
135
  while retaining review history.
@@ -140,7 +141,7 @@ uses the agent's [native permission controls](docs/native-reviews.md#native-perm
140
141
  and read-only review instructions; source sent to the agent may go to its model provider.
141
142
 
142
143
  - `/`: Filter the queue.
143
- - `a`: Toggle monitoring all open PRs in configured repositories.
144
+ - `A`: Toggle monitoring all open PRs in configured repositories.
144
145
  - `b`: Browse accessible PRs and follow one.
145
146
  - `R`: Find and add a PR by link or number, then review it; choose a repository if
146
147
  the number is ambiguous. Explicitly selected PRs bypass queue visibility filters.
@@ -148,6 +149,7 @@ and read-only review instructions; source sent to the agent may go to its model
148
149
  - `k`: Stop the selected PR's review and reset its local tracking and owned resources.
149
150
  It disappears until a forge refresh rediscovers it; review history is retained.
150
151
  - `h`: View completed review history.
152
+ - `,`: Edit settings; saved changes apply without restarting.
151
153
  - `?`: Show all keyboard shortcuts.
152
154
  - `q`: Quit.
153
155
 
@@ -161,6 +163,29 @@ PRs assigned to you are also hidden by default, even when
161
163
  you are requested directly or through a team. Set `include_assigned_prs = true` in
162
164
  `[ui]` to include them, or select one with `R`.
163
165
 
166
+ ### How PRs move through the board
167
+
168
+ Solid arrows are actions you take; dashed arrows happen automatically.
169
+
170
+ How a PR arrives:
171
+
172
+ ![Flow diagram: review requests and all-PR monitoring reach the board through polling, browsing adds followed PRs, and your own or assigned PRs are hidden unless enabled; R adds a PR directly and starts a review. New PRs start as pending unless already approved, closed, or merged.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-arrival.svg)
173
+
174
+ How its status changes:
175
+
176
+ ![State diagram: r queues a review, the worker runs it, and the result is approve or check; w, a, and m move a PR between author, approve, and done; Ctrl+C or a failed agent returns it to pending; GitHub commits, your submitted reviews, and closes or merges move it automatically; new commits after approval show done+.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-status.svg)
177
+
178
+ `r`, `a`, `w`, and `m` work from any open status, not only along the arrows shown,
179
+ though `r` refuses while a review is already queued or running. New commits on a
180
+ `done+` PR keep it `done+` rather than returning it to `pending`.
181
+
182
+ How it leaves:
183
+
184
+ ![Flow diagram: m, your approval, or a close or merge moves a PR to done and history; k removes it until a refresh finds it still requested or monitored; becoming an assignee hides it unless include_assigned_prs is set or it was selected with R.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-exit.svg)
185
+
186
+ A PR stays on the board when its review request is withdrawn; press `k` to remove it.
187
+ A PR you only followed stays away after `k` until you follow it again.
188
+
164
189
  ## Reset
165
190
 
166
191
  Close running DiffButler sessions, then run:
@@ -6,7 +6,7 @@ Keep track of what each pull request needs next: AI review, your review, or auth
6
6
  changes. Start an AI review, discuss its findings in the agent's own session, and
7
7
  finish your review in the browser.
8
8
 
9
- ![DiffButler dashboard showing pull requests and the next review action](diffbutler.png)
9
+ ![DiffButler dashboard showing pull requests and the next review action](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/diffbutler.png)
10
10
 
11
11
  ## Install
12
12
 
@@ -80,8 +80,8 @@ The dashboard shows active reviews, including followed PRs whose GitHub review
80
80
  requests have disappeared after you posted feedback. Waiting-for-author reviews
81
81
  stay visible across refreshes and restarts. If an approved PR receives new commits,
82
82
  it reappears as `done+` at the end of the queue without starting another AI review.
83
- Authenticated polling slows when API quota is scarce and speeds back up when it
84
- recovers, accounting for refresh cost and time until the quota resets.
83
+ Polling spreads API quota evenly until it resets, leaving 10% in reserve: it slows
84
+ when quota is scarce or refreshes are costly and speeds back up when quota recovers.
85
85
 
86
86
  Select a PR with the arrow keys, then work through the review:
87
87
 
@@ -100,7 +100,8 @@ Select a PR with the arrow keys, then work through the review:
100
100
  starts a new run with the current reviewer and replaces the current review details.
101
101
  Ask questions and explicitly tell the agent which comments to post, if any.
102
102
  3. Exit the agent to return to the dashboard, which refreshes activity from GitHub.
103
- Press `w` if you are waiting for author changes, or `o` to review in your browser.
103
+ Press `o` to open the PR in your browser at any time; it does not change the state.
104
+ Press `w` if you are waiting for author changes, or `a` once you are ready to approve.
104
105
  4. After approving on GitHub, press `m` to mark the task complete locally. DiffButler
105
106
  also detects your approval, closure, or merge and cleans up owned session resources
106
107
  while retaining review history.
@@ -112,7 +113,7 @@ uses the agent's [native permission controls](docs/native-reviews.md#native-perm
112
113
  and read-only review instructions; source sent to the agent may go to its model provider.
113
114
 
114
115
  - `/`: Filter the queue.
115
- - `a`: Toggle monitoring all open PRs in configured repositories.
116
+ - `A`: Toggle monitoring all open PRs in configured repositories.
116
117
  - `b`: Browse accessible PRs and follow one.
117
118
  - `R`: Find and add a PR by link or number, then review it; choose a repository if
118
119
  the number is ambiguous. Explicitly selected PRs bypass queue visibility filters.
@@ -120,6 +121,7 @@ and read-only review instructions; source sent to the agent may go to its model
120
121
  - `k`: Stop the selected PR's review and reset its local tracking and owned resources.
121
122
  It disappears until a forge refresh rediscovers it; review history is retained.
122
123
  - `h`: View completed review history.
124
+ - `,`: Edit settings; saved changes apply without restarting.
123
125
  - `?`: Show all keyboard shortcuts.
124
126
  - `q`: Quit.
125
127
 
@@ -133,6 +135,29 @@ PRs assigned to you are also hidden by default, even when
133
135
  you are requested directly or through a team. Set `include_assigned_prs = true` in
134
136
  `[ui]` to include them, or select one with `R`.
135
137
 
138
+ ### How PRs move through the board
139
+
140
+ Solid arrows are actions you take; dashed arrows happen automatically.
141
+
142
+ How a PR arrives:
143
+
144
+ ![Flow diagram: review requests and all-PR monitoring reach the board through polling, browsing adds followed PRs, and your own or assigned PRs are hidden unless enabled; R adds a PR directly and starts a review. New PRs start as pending unless already approved, closed, or merged.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-arrival.svg)
145
+
146
+ How its status changes:
147
+
148
+ ![State diagram: r queues a review, the worker runs it, and the result is approve or check; w, a, and m move a PR between author, approve, and done; Ctrl+C or a failed agent returns it to pending; GitHub commits, your submitted reviews, and closes or merges move it automatically; new commits after approval show done+.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-status.svg)
149
+
150
+ `r`, `a`, `w`, and `m` work from any open status, not only along the arrows shown,
151
+ though `r` refuses while a review is already queued or running. New commits on a
152
+ `done+` PR keep it `done+` rather than returning it to `pending`.
153
+
154
+ How it leaves:
155
+
156
+ ![Flow diagram: m, your approval, or a close or merge moves a PR to done and history; k removes it until a refresh finds it still requested or monitored; becoming an assignee hides it unless include_assigned_prs is set or it was selected with R.](https://raw.githubusercontent.com/heikkitoivonen/diffbutler/main/docs/diagrams/pr-exit.svg)
157
+
158
+ A PR stays on the board when its review request is withdrawn; press `k` to remove it.
159
+ A PR you only followed stays away after `k` until you follow it again.
160
+
136
161
  ## Reset
137
162
 
138
163
  Close running DiffButler sessions, then run:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "diffbutler"
3
- version = "0.6.0"
3
+ version = "0.7.0"
4
4
  description = "A terminal dashboard for human-directed AI code reviews."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -13,7 +13,7 @@ keywords = [
13
13
  "ai",
14
14
  ]
15
15
  classifiers = [
16
- "Development Status :: 3 - Alpha",
16
+ "Development Status :: 4 - Beta",
17
17
  "Environment :: Console",
18
18
  "Intended Audience :: Developers",
19
19
  "Programming Language :: Python :: 3 :: Only",
@@ -53,11 +53,12 @@ dev = [
53
53
  "pytest-cov>=7.1.0",
54
54
  "pytest-xdist>=3.8.0",
55
55
  "ruff>=0.16.5",
56
+ "zizmor>=1.32.0",
56
57
  ]
57
58
 
58
59
  [tool.uv]
59
60
  required-version = ">=0.12.13"
60
- exclude-newer = "2 days"
61
+ exclude-newer = "8 days"
61
62
 
62
63
  [tool.ruff]
63
64
  target-version = "py314"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "diffbutler"
3
- version = "0.6.0"
3
+ version = "0.7.0"
4
4
  description = "A terminal dashboard for human-directed AI code reviews."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -8,7 +8,7 @@ license = "MIT"
8
8
  license-files = ["LICENSE.txt"]
9
9
  keywords = ["code-review", "github", "terminal", "ai"]
10
10
  classifiers = [
11
- "Development Status :: 3 - Alpha",
11
+ "Development Status :: 4 - Beta",
12
12
  "Environment :: Console",
13
13
  "Intended Audience :: Developers",
14
14
  "Programming Language :: Python :: 3 :: Only",
@@ -48,12 +48,13 @@ dev = [
48
48
  "pytest-cov>=7.1.0",
49
49
  "pytest-xdist>=3.8.0",
50
50
  "ruff>=0.16.5",
51
+ "zizmor>=1.32.0",
51
52
  ]
52
53
 
53
54
  [tool.uv]
54
55
  required-version = ">=0.12.13"
55
56
  # Give new dependency releases time to settle before routine upgrades.
56
- exclude-newer = "2 days"
57
+ exclude-newer = "8 days"
57
58
 
58
59
  [tool.ruff]
59
60
  target-version = "py314"
@@ -5,7 +5,7 @@ reviewers = []
5
5
 
6
6
  [general]
7
7
  # Minimum: 60 seconds with authenticated accounts, 600 with any public account.
8
- # poll_interval_s = 600 # Override the minimum; low authenticated quota slows polling.
8
+ # poll_interval_s = 600 # Override the minimum; low quota slows polling.
9
9
  max_concurrent_reviews = 2
10
10
  # Omit workspace_root to follow $XDG_DATA_HOME/diffbutler/reviews
11
11
  # (default ~/.local/share/diffbutler/reviews).
@@ -27,9 +27,7 @@ auto_migrate = true
27
27
  [review]
28
28
  findings_threshold = "minor" # blocking | important | minor | nit | question
29
29
  min_confidence = 0.5
30
- exclude_globs = ["**/*.lock", "**/vendor/**", "**/*.min.js", "**/generated/**"]
31
30
  mode = "source_only"
32
- checkout = "worktree" # Native reviews currently use pinned source snapshots.
33
31
  # default_reviewer = "codex"
34
32
  # prompt = "~/review-instructions.md"
35
33
 
@@ -37,7 +35,7 @@ checkout = "worktree" # Native reviews currently use pinned source snapshots.
37
35
  include_own_prs = false # Set true to review PRs authored by your account.
38
36
  include_assigned_prs = false # Set true to review PRs assigned to your account.
39
37
  columns = ["number", "title", "author", "state"]
40
- sort_by = "attention"
38
+ sort_by = "state"
41
39
  sort_desc = true
42
40
  preview_pane = true
43
41
  default_filter = "active"
@@ -60,7 +58,6 @@ open_in_browser = ["o", "ctrl+o"]
60
58
  # git_transport = "auto" # auto | https | ssh; remembers the last successful fetch.
61
59
  # default_reviewer = "codex"
62
60
  # prompt = "~/review-instructions.md"
63
- # checkout = "mediated"
64
61
 
65
62
  # Remove the top-level forges = [] before adding forge accounts:
66
63
  # [[forges]]