git-cleaner-tui 2.0.0__tar.gz → 2.2.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.
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/PKG-INFO +2 -22
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/README.md +1 -21
- git_cleaner_tui-2.2.0/logo/logo.png +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/pyproject.toml +1 -1
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/app.py +85 -60
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/config.py +1 -1
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/uv.lock +1 -1
- git_cleaner_tui-2.0.0/logo/ascii_banner.py +0 -15
- git_cleaner_tui-2.0.0/logo/concept1-horizontal.svg +0 -41
- git_cleaner_tui-2.0.0/logo/concept1-icon.svg +0 -36
- git_cleaner_tui-2.0.0/logo/concept2-horizontal.svg +0 -29
- git_cleaner_tui-2.0.0/logo/concept2-icon.svg +0 -25
- git_cleaner_tui-2.0.0/logo/favicon.svg +0 -31
- git_cleaner_tui-2.0.0/logo/logo-readme.svg +0 -40
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.gitignore +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/-1783610394.49273/state/server-stopped +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610443.14345/state/server-stopped +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610443.14345/state/server.err +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610443.14345/state/server.log +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610469.94912/content/sidebar-layouts.html +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610469.94912/content/waiting.html +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610469.94912/state/events +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/.superpowers/brainstorm/brainstorm-1783610469.94912/state/server-stopped +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/__init__.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/__main__.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/cli.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/src/git_cleaner/git_ops.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/tests/__init__.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/tests/test_config.py +0 -0
- {git_cleaner_tui-2.0.0 → git_cleaner_tui-2.2.0}/tests/test_git_ops.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: git-cleaner-tui
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: TUI tool for browsing and bulk-deleting git branches
|
|
5
5
|
Author: git-cleaner
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -8,7 +8,7 @@ Requires-Dist: textual
|
|
|
8
8
|
Requires-Dist: textual-timepiece>=0.7.0
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+

|
|
12
12
|
|
|
13
13
|
TUI tool for interactively browsing and bulk-deleting git branches, with repo maintenance (GC, repack, prune), a stash browser, and multi-repo bookmarks.
|
|
14
14
|
|
|
@@ -129,26 +129,6 @@ Hardcoded defaults (always active): `main`, `master`, `develop`. The checked-out
|
|
|
129
129
|
|
|
130
130
|
---
|
|
131
131
|
|
|
132
|
-
## Project Structure
|
|
133
|
-
|
|
134
|
-
```
|
|
135
|
-
git-cleaner/
|
|
136
|
-
├── pyproject.toml
|
|
137
|
-
├── README.md
|
|
138
|
-
├── src/git_cleaner/
|
|
139
|
-
│ ├── __init__.py
|
|
140
|
-
│ ├── __main__.py
|
|
141
|
-
│ ├── cli.py # --repo flag, launches app
|
|
142
|
-
│ ├── app.py # Textual TUI (screens, widgets, CSS)
|
|
143
|
-
│ ├── config.py # TOML loading, protected/blacklist/theme/bookmarks
|
|
144
|
-
│ └── git_ops.py # Git wrappers (branch/stash/GC ops)
|
|
145
|
-
└── tests/
|
|
146
|
-
├── test_config.py
|
|
147
|
-
└── test_git_ops.py
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
132
|
## Development
|
|
153
133
|
|
|
154
134
|
```bash
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
TUI tool for interactively browsing and bulk-deleting git branches, with repo maintenance (GC, repack, prune), a stash browser, and multi-repo bookmarks.
|
|
4
4
|
|
|
@@ -119,26 +119,6 @@ Hardcoded defaults (always active): `main`, `master`, `develop`. The checked-out
|
|
|
119
119
|
|
|
120
120
|
---
|
|
121
121
|
|
|
122
|
-
## Project Structure
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
git-cleaner/
|
|
126
|
-
├── pyproject.toml
|
|
127
|
-
├── README.md
|
|
128
|
-
├── src/git_cleaner/
|
|
129
|
-
│ ├── __init__.py
|
|
130
|
-
│ ├── __main__.py
|
|
131
|
-
│ ├── cli.py # --repo flag, launches app
|
|
132
|
-
│ ├── app.py # Textual TUI (screens, widgets, CSS)
|
|
133
|
-
│ ├── config.py # TOML loading, protected/blacklist/theme/bookmarks
|
|
134
|
-
│ └── git_ops.py # Git wrappers (branch/stash/GC ops)
|
|
135
|
-
└── tests/
|
|
136
|
-
├── test_config.py
|
|
137
|
-
└── test_git_ops.py
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
122
|
## Development
|
|
143
123
|
|
|
144
124
|
```bash
|
|
Binary file
|
|
@@ -104,19 +104,20 @@ Footer {
|
|
|
104
104
|
background: $primary 10%;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
/* === Tab styling
|
|
107
|
+
/* === Tab styling === */
|
|
108
108
|
ContentTabs {
|
|
109
109
|
background: $surface 50%;
|
|
110
|
-
height:
|
|
110
|
+
height: 1;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
Tab {
|
|
114
114
|
width: auto;
|
|
115
|
-
height:
|
|
115
|
+
height: 1;
|
|
116
116
|
padding: 0 2;
|
|
117
117
|
text-align: center;
|
|
118
118
|
color: $text-muted;
|
|
119
119
|
text-style: bold;
|
|
120
|
+
content-align: center middle;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
Tab:hover {
|
|
@@ -150,54 +151,83 @@ Tab:disabled {
|
|
|
150
151
|
padding: 0 1 0 0;
|
|
151
152
|
}
|
|
152
153
|
|
|
154
|
+
/* === Date range picker === */
|
|
155
|
+
DateRangePicker {
|
|
156
|
+
max-height: 8;
|
|
157
|
+
}
|
|
158
|
+
|
|
153
159
|
/* === Date picker + Load button row === */
|
|
154
160
|
#date-btn-row {
|
|
155
161
|
height: auto;
|
|
156
162
|
align: center middle;
|
|
157
|
-
margin:
|
|
163
|
+
margin: 1 1 1 1;
|
|
164
|
+
overflow-x: auto;
|
|
158
165
|
}
|
|
159
166
|
|
|
167
|
+
/* === Compact buttons (all except DateRangePicker internals) === */
|
|
168
|
+
#load-btn, .preset-btn, #toggle-remote, #toggle-dry-run,
|
|
169
|
+
#export-csv, #export-json,
|
|
170
|
+
.task-button, #refresh-health,
|
|
171
|
+
#stash-drop, #stash-apply, #stash-pop, #stash-refresh,
|
|
172
|
+
#cancel, #confirm,
|
|
173
|
+
#repo-add, #repo-remove, #repo-close {
|
|
174
|
+
min-height: 1;
|
|
175
|
+
padding: 0;
|
|
176
|
+
border: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Date row buttons match DateRangePicker height */
|
|
160
180
|
#date-btn-row > #load-btn {
|
|
161
181
|
margin: 0 0 0 2;
|
|
182
|
+
height: 3;
|
|
183
|
+
min-height: 3;
|
|
162
184
|
}
|
|
163
185
|
|
|
164
186
|
.preset-btn {
|
|
165
187
|
margin: 0 0 0 1;
|
|
166
188
|
min-width: 5;
|
|
167
189
|
height: 3;
|
|
190
|
+
min-height: 3;
|
|
168
191
|
}
|
|
169
192
|
|
|
170
193
|
/* === Filter row: search + author === */
|
|
171
194
|
#filter-row {
|
|
172
195
|
height: auto;
|
|
173
|
-
margin: 0 1
|
|
196
|
+
margin: 0 1 1 1;
|
|
174
197
|
align: left middle;
|
|
175
198
|
}
|
|
176
199
|
|
|
177
200
|
#search-input {
|
|
178
201
|
width: 1fr;
|
|
179
|
-
min-width:
|
|
202
|
+
min-width: 12;
|
|
180
203
|
}
|
|
181
204
|
|
|
182
205
|
#author-select {
|
|
183
|
-
width:
|
|
184
|
-
min-width:
|
|
185
|
-
margin: 0 0 0
|
|
206
|
+
width: 20;
|
|
207
|
+
min-width: 12;
|
|
208
|
+
margin: 0 0 0 1;
|
|
186
209
|
}
|
|
187
210
|
|
|
188
211
|
/* === Error / status messages === */
|
|
189
212
|
#status-bar {
|
|
190
213
|
height: 1;
|
|
191
214
|
padding: 0 2;
|
|
215
|
+
margin: 0 1;
|
|
192
216
|
color: $text-muted;
|
|
193
217
|
}
|
|
194
218
|
|
|
195
|
-
/* === Action row (remote toggle) === */
|
|
219
|
+
/* === Action row (remote toggle + export) === */
|
|
196
220
|
#action-row {
|
|
197
221
|
height: auto;
|
|
198
|
-
margin: 0
|
|
222
|
+
margin: 0 1;
|
|
199
223
|
align: left middle;
|
|
200
224
|
width: 100%;
|
|
225
|
+
overflow-x: auto;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
#action-spacer {
|
|
229
|
+
width: 1fr;
|
|
230
|
+
height: 1;
|
|
201
231
|
}
|
|
202
232
|
|
|
203
233
|
#toggle-remote {
|
|
@@ -211,17 +241,25 @@ Tab:disabled {
|
|
|
211
241
|
margin: 0 0 0 1;
|
|
212
242
|
}
|
|
213
243
|
|
|
214
|
-
|
|
244
|
+
#export-csv, #export-json {
|
|
245
|
+
margin: 0 0 0 1;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* === Branch tree === */
|
|
249
|
+
#branches-pane > Vertical, #stash-pane > Vertical {
|
|
250
|
+
height: 1fr;
|
|
251
|
+
}
|
|
252
|
+
|
|
215
253
|
#branch-table {
|
|
216
254
|
height: 1fr;
|
|
217
|
-
margin: 0 1
|
|
255
|
+
margin: 0 1;
|
|
218
256
|
width: 100%;
|
|
219
257
|
}
|
|
220
258
|
|
|
221
259
|
#details-pane {
|
|
222
260
|
height: auto;
|
|
223
|
-
max-height:
|
|
224
|
-
margin: 0 1;
|
|
261
|
+
max-height: 6;
|
|
262
|
+
margin: 0 1 1 1;
|
|
225
263
|
padding: 0 1;
|
|
226
264
|
border: solid $primary 20%;
|
|
227
265
|
background: $surface 50%;
|
|
@@ -238,21 +276,21 @@ Tree:focus {
|
|
|
238
276
|
|
|
239
277
|
/* === Tabbed content pane === */
|
|
240
278
|
#branches-pane, #maintenance-pane, #stash-pane {
|
|
241
|
-
padding:
|
|
279
|
+
padding: 0 0;
|
|
242
280
|
height: 1fr;
|
|
243
281
|
}
|
|
244
282
|
|
|
245
283
|
/* === Maintenance pane === */
|
|
246
284
|
.section-title {
|
|
247
285
|
text-style: bold;
|
|
248
|
-
padding: 0
|
|
286
|
+
padding: 0;
|
|
249
287
|
color: $text;
|
|
250
288
|
}
|
|
251
289
|
|
|
252
290
|
#health-stats {
|
|
253
291
|
height: auto;
|
|
254
|
-
margin: 0
|
|
255
|
-
padding: 0 1
|
|
292
|
+
margin: 0 1 1 1;
|
|
293
|
+
padding: 0 1;
|
|
256
294
|
border: solid $primary 30%;
|
|
257
295
|
}
|
|
258
296
|
|
|
@@ -281,7 +319,6 @@ Tree:focus {
|
|
|
281
319
|
#health-status-bar {
|
|
282
320
|
height: auto;
|
|
283
321
|
padding: 0 1;
|
|
284
|
-
margin: 0 0 0 0;
|
|
285
322
|
}
|
|
286
323
|
|
|
287
324
|
#health-status-label {
|
|
@@ -336,7 +373,7 @@ Tree:focus {
|
|
|
336
373
|
|
|
337
374
|
#tasks-section {
|
|
338
375
|
height: auto;
|
|
339
|
-
margin: 1
|
|
376
|
+
margin: 0 1 1 1;
|
|
340
377
|
}
|
|
341
378
|
|
|
342
379
|
.task-row {
|
|
@@ -347,14 +384,14 @@ Tree:focus {
|
|
|
347
384
|
}
|
|
348
385
|
|
|
349
386
|
.task-button {
|
|
350
|
-
margin: 0 1
|
|
351
|
-
min-width:
|
|
387
|
+
margin: 0 1;
|
|
388
|
+
min-width: 14;
|
|
352
389
|
}
|
|
353
390
|
|
|
354
391
|
/* === Status bar (always visible above task buttons) === */
|
|
355
392
|
#task-status-bar {
|
|
356
393
|
height: auto;
|
|
357
|
-
margin: 0
|
|
394
|
+
margin: 0 1 1 1;
|
|
358
395
|
padding: 0 1;
|
|
359
396
|
border: solid $primary 30%;
|
|
360
397
|
align: center middle;
|
|
@@ -373,25 +410,24 @@ Tree:focus {
|
|
|
373
410
|
|
|
374
411
|
/* === Command output log === */
|
|
375
412
|
#task-output {
|
|
376
|
-
height:
|
|
377
|
-
max-height:
|
|
378
|
-
margin: 0
|
|
379
|
-
padding: 1;
|
|
413
|
+
height: 4;
|
|
414
|
+
max-height: 20;
|
|
415
|
+
margin: 0 1 1 1;
|
|
416
|
+
padding: 0 1;
|
|
380
417
|
border: solid $surface;
|
|
381
418
|
background: $surface 50%;
|
|
382
419
|
}
|
|
383
420
|
|
|
384
421
|
#maintenance-actions {
|
|
385
422
|
height: auto;
|
|
386
|
-
margin: 1 0;
|
|
387
423
|
align: center middle;
|
|
388
424
|
}
|
|
389
425
|
|
|
390
426
|
/* === Task help legend === */
|
|
391
427
|
#help-legend {
|
|
392
428
|
height: auto;
|
|
393
|
-
margin: 0
|
|
394
|
-
padding: 1
|
|
429
|
+
margin: 0 1 1 1;
|
|
430
|
+
padding: 0 1;
|
|
395
431
|
border: dashed $surface;
|
|
396
432
|
overflow-x: auto;
|
|
397
433
|
}
|
|
@@ -405,53 +441,41 @@ Tree:focus {
|
|
|
405
441
|
/* === Confirmation dialog === */
|
|
406
442
|
#dialog {
|
|
407
443
|
width: auto;
|
|
408
|
-
min-width:
|
|
409
|
-
max-width:
|
|
444
|
+
min-width: 30;
|
|
445
|
+
max-width: 60;
|
|
410
446
|
height: auto;
|
|
411
447
|
border: solid $primary;
|
|
412
|
-
padding: 1
|
|
448
|
+
padding: 0 1;
|
|
413
449
|
background: $surface;
|
|
414
450
|
align: center middle;
|
|
415
451
|
}
|
|
416
452
|
|
|
417
453
|
#dialog > Label {
|
|
418
454
|
text-style: bold;
|
|
419
|
-
padding: 0
|
|
455
|
+
padding: 0;
|
|
420
456
|
}
|
|
421
457
|
|
|
422
458
|
#dialog Horizontal {
|
|
423
459
|
height: auto;
|
|
424
|
-
margin: 1 0;
|
|
425
460
|
align: center middle;
|
|
426
461
|
}
|
|
427
462
|
|
|
428
463
|
#dialog Button {
|
|
429
464
|
margin: 0 1;
|
|
430
|
-
min-width: 10;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/* === Export row === */
|
|
434
|
-
#export-row {
|
|
435
|
-
height: auto;
|
|
436
|
-
margin: 0 0 0 2;
|
|
437
|
-
align: left middle;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
#export-row Button {
|
|
441
465
|
min-width: 8;
|
|
442
|
-
margin: 0 1 0 0;
|
|
443
466
|
}
|
|
444
467
|
|
|
445
468
|
/* === Stash browser === */
|
|
446
469
|
#stash-table {
|
|
447
470
|
height: 1fr;
|
|
448
|
-
margin: 0 1;
|
|
471
|
+
margin: 0 1 1 1;
|
|
449
472
|
}
|
|
450
473
|
|
|
451
474
|
#stash-actions {
|
|
452
475
|
height: auto;
|
|
453
476
|
margin: 0 1;
|
|
454
477
|
align: center middle;
|
|
478
|
+
overflow-x: auto;
|
|
455
479
|
}
|
|
456
480
|
|
|
457
481
|
#stash-actions Button {
|
|
@@ -461,6 +485,7 @@ Tree:focus {
|
|
|
461
485
|
|
|
462
486
|
#stash-status {
|
|
463
487
|
height: 1;
|
|
488
|
+
margin: 0 0 1 0;
|
|
464
489
|
padding: 0 2;
|
|
465
490
|
color: $text-muted;
|
|
466
491
|
}
|
|
@@ -475,7 +500,7 @@ Tree:focus {
|
|
|
475
500
|
|
|
476
501
|
/* === Bottom repo label === */
|
|
477
502
|
#repo-label-bottom {
|
|
478
|
-
padding: 1
|
|
503
|
+
padding: 0 1;
|
|
479
504
|
color: $text-muted;
|
|
480
505
|
text-align: left;
|
|
481
506
|
height: 1;
|
|
@@ -483,7 +508,7 @@ Tree:focus {
|
|
|
483
508
|
|
|
484
509
|
#bottom-bar {
|
|
485
510
|
height: auto;
|
|
486
|
-
margin:
|
|
511
|
+
margin: 0 1;
|
|
487
512
|
align: left middle;
|
|
488
513
|
padding: 0 1;
|
|
489
514
|
}
|
|
@@ -491,7 +516,7 @@ Tree:focus {
|
|
|
491
516
|
.footer-repo-label {
|
|
492
517
|
color: $text-muted;
|
|
493
518
|
padding: 0 1;
|
|
494
|
-
height:
|
|
519
|
+
height: auto;
|
|
495
520
|
text-align: left;
|
|
496
521
|
}
|
|
497
522
|
"""
|
|
@@ -526,22 +551,22 @@ class BranchesContent(Vertical):
|
|
|
526
551
|
def compose(self) -> ComposeResult:
|
|
527
552
|
with Horizontal(id="date-btn-row"):
|
|
528
553
|
yield DateRangePicker(id="date-picker")
|
|
529
|
-
yield Button("Load Branches", id="load-btn", variant="primary")
|
|
530
554
|
yield Button("7d", id="preset-7d", classes="preset-btn")
|
|
531
555
|
yield Button("30d", id="preset-30d", classes="preset-btn")
|
|
532
556
|
yield Button("90d", id="preset-90d", classes="preset-btn")
|
|
533
557
|
yield Button("1y", id="preset-1y", classes="preset-btn")
|
|
558
|
+
yield Button("Load Branches", id="load-btn", variant="primary")
|
|
534
559
|
with Horizontal(id="filter-row"):
|
|
535
560
|
yield Input(placeholder="Search branches...", id="search-input")
|
|
536
561
|
yield Select([], id="author-select", prompt="All authors", allow_blank=True)
|
|
537
562
|
yield Tree("", id="branch-table")
|
|
538
563
|
yield Vertical(Static("Click a branch to see details", id="details-content"), id="details-pane")
|
|
539
564
|
with Horizontal(id="action-row"):
|
|
540
|
-
yield Button("Remote: OFF", id="toggle-remote", variant="
|
|
541
|
-
yield Button("Dry Run: OFF", id="toggle-dry-run", variant="
|
|
542
|
-
|
|
543
|
-
yield Button("CSV", id="export-csv", variant="
|
|
544
|
-
yield Button("JSON", id="export-json", variant="
|
|
565
|
+
yield Button("Remote: OFF", id="toggle-remote", variant="warning")
|
|
566
|
+
yield Button("Dry Run: OFF", id="toggle-dry-run", variant="primary")
|
|
567
|
+
yield Static("", id="action-spacer")
|
|
568
|
+
yield Button("Export as CSV", id="export-csv", variant="primary")
|
|
569
|
+
yield Button("Export as JSON", id="export-json", variant="primary")
|
|
545
570
|
yield Static(id="status-bar")
|
|
546
571
|
|
|
547
572
|
async def on_mount(self) -> None:
|
|
@@ -794,14 +819,14 @@ class BranchesContent(Vertical):
|
|
|
794
819
|
self.delete_remote = not self.delete_remote
|
|
795
820
|
btn = self.query_one("#toggle-remote", Button)
|
|
796
821
|
btn.label = "Remote: ON" if self.delete_remote else "Remote: OFF"
|
|
797
|
-
btn.variant = "
|
|
822
|
+
btn.variant = "error" if self.delete_remote else "warning"
|
|
798
823
|
self._update_status()
|
|
799
824
|
|
|
800
825
|
def _toggle_dry_run(self) -> None:
|
|
801
826
|
self.dry_run = not self.dry_run
|
|
802
827
|
btn = self.query_one("#toggle-dry-run", Button)
|
|
803
828
|
btn.label = "Dry Run: ON" if self.dry_run else "Dry Run: OFF"
|
|
804
|
-
btn.variant = "
|
|
829
|
+
btn.variant = "success" if self.dry_run else "primary"
|
|
805
830
|
self._update_status()
|
|
806
831
|
|
|
807
832
|
def undo_deletion(self) -> None:
|
|
@@ -101,7 +101,7 @@ def save_bookmarks(bookmarks: list[str]) -> None:
|
|
|
101
101
|
in_section = False
|
|
102
102
|
if not in_section:
|
|
103
103
|
out.append(line)
|
|
104
|
-
quoted = [f'
|
|
104
|
+
quoted = [f"'{p}'" for p in bookmarks]
|
|
105
105
|
out += ["", "[bookmarks]", f"paths = [{', '.join(quoted)}]"]
|
|
106
106
|
_GLOBAL_CFG.write_text("\n".join(out) + "\n")
|
|
107
107
|
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ASCII logo for git-cleaner TUI.
|
|
3
|
-
|
|
4
|
-
Rendered in the terminal using box-drawing characters.
|
|
5
|
-
Import and display as a Static widget with Rich markup.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
BANNER = (
|
|
9
|
-
"[bold #6366F1]"
|
|
10
|
-
"╔═══╗ ╔═╗ ╔═══╗ ╔═══╗ ╔═══╗ ╔═══╗ ╔═══╗ ═╗ ╔╗ ╔═══╗\n"
|
|
11
|
-
"║ ══╝ ║ ║ ║ ║ ║ ║ ║ ║ ══╝ ║ ║║ ║║ ║ ══╝\n"
|
|
12
|
-
"║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║╚═╝║ ║ \n"
|
|
13
|
-
"╚═╝ ╚═╝ ╚═══╝ ╚═══╝ ╚═══╝ ╚═╝ ╚═══╝ ╚═╝ ╚╝ ╚═══╝"
|
|
14
|
-
"[/]"
|
|
15
|
-
)
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 80" width="320" height="80" role="img" aria-labelledby="gc-logo-title">
|
|
2
|
-
<title id="gc-logo-title">git-cleaner</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="broom-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
6
|
-
<stop offset="100%" stop-color="#6366F1"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="sweep-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
10
|
-
<stop offset="100%" stop-color="#34D399"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
<linearGradient id="bg-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
13
|
-
<stop offset="0%" stop-color="#EEF2FF"/>
|
|
14
|
-
<stop offset="100%" stop-color="#E0E7FF"/>
|
|
15
|
-
</linearGradient>
|
|
16
|
-
</defs>
|
|
17
|
-
|
|
18
|
-
<!-- Circular badge background -->
|
|
19
|
-
<circle cx="36" cy="40" r="32" fill="url(#bg-grad)"/>
|
|
20
|
-
<circle cx="36" cy="40" r="32" fill="none" stroke="#4F46E5" stroke-width="2"/>
|
|
21
|
-
|
|
22
|
-
<!-- Broom handle -->
|
|
23
|
-
<line x1="14" y1="58" x2="44" y2="18" stroke="url(#broom-grad)" stroke-width="3.5" stroke-linecap="round"/>
|
|
24
|
-
|
|
25
|
-
<!-- Broom bristles (fan shape) -->
|
|
26
|
-
<line x1="42" y1="22" x2="52" y2="12" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
27
|
-
<line x1="44" y1="26" x2="56" y2="18" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
28
|
-
<line x1="44" y1="30" x2="58" y2="24" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
29
|
-
<line x1="44" y1="34" x2="58" y2="30" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
30
|
-
<line x1="42" y1="38" x2="56" y2="36" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
31
|
-
<line x1="40" y1="42" x2="52" y2="42" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
32
|
-
|
|
33
|
-
<!-- Git branch being swept (dot + branch line) -->
|
|
34
|
-
<circle cx="50" cy="44" r="2" fill="#10B981" opacity="0.5"/>
|
|
35
|
-
<path d="M48,48 Q52,44 52,36" stroke="#10B981" stroke-width="1.5" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
36
|
-
<circle cx="52" cy="36" r="1.5" fill="#10B981" opacity="0.3"/>
|
|
37
|
-
|
|
38
|
-
<!-- Text -->
|
|
39
|
-
<text x="80" y="38" font-family="system-ui, -apple-system, sans-serif" font-size="24" font-weight="700" fill="#1F2937" letter-spacing="-0.3">git-cleaner</text>
|
|
40
|
-
<text x="80" y="54" font-family="system-ui, -apple-system, sans-serif" font-size="11" fill="#6B7280" letter-spacing="2.5">MAINTENANCE & CLEANUP</text>
|
|
41
|
-
</svg>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72" width="72" height="72" role="img" aria-labelledby="gc-icon-title">
|
|
2
|
-
<title id="gc-icon-title">git-cleaner icon</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="broom-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
6
|
-
<stop offset="100%" stop-color="#6366F1"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="sweep-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
10
|
-
<stop offset="100%" stop-color="#34D399"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
<linearGradient id="bg-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
13
|
-
<stop offset="0%" stop-color="#EEF2FF"/>
|
|
14
|
-
<stop offset="100%" stop-color="#E0E7FF"/>
|
|
15
|
-
</linearGradient>
|
|
16
|
-
</defs>
|
|
17
|
-
|
|
18
|
-
<!-- Circular badge -->
|
|
19
|
-
<circle cx="36" cy="36" r="34" fill="url(#bg-grad)"/>
|
|
20
|
-
<circle cx="36" cy="36" r="34" fill="none" stroke="#4F46E5" stroke-width="2.5"/>
|
|
21
|
-
|
|
22
|
-
<!-- Broom handle -->
|
|
23
|
-
<line x1="12" y1="54" x2="44" y2="16" stroke="url(#broom-grad)" stroke-width="4" stroke-linecap="round"/>
|
|
24
|
-
|
|
25
|
-
<!-- Broom bristles -->
|
|
26
|
-
<line x1="42" y1="20" x2="52" y2="10" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
27
|
-
<line x1="44" y1="24" x2="56" y2="16" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
28
|
-
<line x1="44" y1="28" x2="58" y2="22" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
29
|
-
<line x1="44" y1="32" x2="58" y2="28" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
30
|
-
<line x1="42" y1="36" x2="56" y2="34" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
31
|
-
<line x1="40" y1="40" x2="52" y2="40" stroke="url(#sweep-grad)" stroke-width="3" stroke-linecap="round"/>
|
|
32
|
-
|
|
33
|
-
<!-- Git element being swept -->
|
|
34
|
-
<circle cx="50" cy="42" r="2" fill="#10B981" opacity="0.5"/>
|
|
35
|
-
<path d="M48,46 Q52,42 52,34" stroke="#10B981" stroke-width="1.5" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
36
|
-
</svg>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 80" width="300" height="80" role="img" aria-labelledby="gc2-logo-title">
|
|
2
|
-
<title id="gc2-logo-title">git-cleaner</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="gc-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
6
|
-
<stop offset="100%" stop-color="#7C3AED"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="accent-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
10
|
-
<stop offset="100%" stop-color="#059669"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
</defs>
|
|
13
|
-
|
|
14
|
-
<!-- Rounded square badge -->
|
|
15
|
-
<rect x="4" y="8" width="64" height="64" rx="16" fill="url(#gc-grad)"/>
|
|
16
|
-
|
|
17
|
-
<!-- Stylized "g" — descender forms broom handle -->
|
|
18
|
-
<path d="M24,30 Q24,22 32,22 Q40,22 40,30 L40,42 Q40,52 32,54 Q26,55.5 22,50" stroke="#FFFFFF" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
19
|
-
|
|
20
|
-
<!-- Stylized "c" — open curve, like a sweeping motion -->
|
|
21
|
-
<path d="M52,30 Q50,22 42,22 Q34,22 34,34 L34,42 Q34,54 42,54 Q50,54 52,48" stroke="#FFFFFF" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
22
|
-
|
|
23
|
-
<!-- Clean accent dot (the "sparkle" — something being cleaned) -->
|
|
24
|
-
<circle cx="38" cy="28" r="2.5" fill="url(#accent-grad)"/>
|
|
25
|
-
|
|
26
|
-
<!-- Text -->
|
|
27
|
-
<text x="82" y="42" font-family="system-ui, -apple-system, sans-serif" font-size="24" font-weight="700" fill="#1F2937" letter-spacing="-0.3">git-cleaner</text>
|
|
28
|
-
<text x="82" y="56" font-family="system-ui, -apple-system, sans-serif" font-size="10" fill="#6B7280" letter-spacing="2.5">MAINTENANCE & CLEANUP</text>
|
|
29
|
-
</svg>
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72" width="72" height="72" role="img" aria-labelledby="gc2-icon-title">
|
|
2
|
-
<title id="gc2-icon-title">git-cleaner icon</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="gc-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
6
|
-
<stop offset="100%" stop-color="#7C3AED"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="accent-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
10
|
-
<stop offset="100%" stop-color="#059669"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
</defs>
|
|
13
|
-
|
|
14
|
-
<!-- Rounded square badge -->
|
|
15
|
-
<rect x="4" y="4" width="64" height="64" rx="16" fill="url(#gc-grad)"/>
|
|
16
|
-
|
|
17
|
-
<!-- Stylized "g" -->
|
|
18
|
-
<path d="M24,26 Q24,18 32,18 Q40,18 40,26 L40,38 Q40,48 32,50 Q26,51.5 22,46" stroke="#FFFFFF" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
19
|
-
|
|
20
|
-
<!-- Stylized "c" -->
|
|
21
|
-
<path d="M52,26 Q50,18 42,18 Q34,18 34,30 L34,38 Q34,50 42,50 Q50,50 52,44" stroke="#FFFFFF" stroke-width="3.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
|
22
|
-
|
|
23
|
-
<!-- Clean accent dot -->
|
|
24
|
-
<circle cx="38" cy="24" r="2.5" fill="url(#accent-grad)"/>
|
|
25
|
-
</svg>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100" role="img" aria-labelledby="favicon-title">
|
|
2
|
-
<title id="favicon-title">git-cleaner</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#EEF2FF"/>
|
|
6
|
-
<stop offset="100%" stop-color="#E0E7FF"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="handle" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
10
|
-
<stop offset="100%" stop-color="#6366F1"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
<linearGradient id="bristles" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
13
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
14
|
-
<stop offset="100%" stop-color="#34D399"/>
|
|
15
|
-
</linearGradient>
|
|
16
|
-
</defs>
|
|
17
|
-
|
|
18
|
-
<circle cx="50" cy="50" r="48" fill="url(#bg)"/>
|
|
19
|
-
<circle cx="50" cy="50" r="48" fill="none" stroke="#4F46E5" stroke-width="2.5"/>
|
|
20
|
-
|
|
21
|
-
<line x1="24" y1="70" x2="58" y2="28" stroke="url(#handle)" stroke-width="4" stroke-linecap="round"/>
|
|
22
|
-
<line x1="56" y1="32" x2="66" y2="22" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
23
|
-
<line x1="58" y1="36" x2="70" y2="28" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
24
|
-
<line x1="58" y1="40" x2="72" y2="34" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
25
|
-
<line x1="58" y1="44" x2="72" y2="40" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
26
|
-
<line x1="56" y1="48" x2="70" y2="46" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
27
|
-
<line x1="54" y1="52" x2="66" y2="52" stroke="url(#bristles)" stroke-width="3" stroke-linecap="round"/>
|
|
28
|
-
|
|
29
|
-
<circle cx="64" cy="54" r="2.5" fill="#10B981" opacity="0.5"/>
|
|
30
|
-
<path d="M60,58 Q64,54 64,46" stroke="#10B981" stroke-width="1.5" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
31
|
-
</svg>
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 120" width="400" height="120" role="img" aria-labelledby="readme-logo-title">
|
|
2
|
-
<title id="readme-logo-title">git-cleaner</title>
|
|
3
|
-
<defs>
|
|
4
|
-
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
-
<stop offset="0%" stop-color="#EEF2FF"/>
|
|
6
|
-
<stop offset="100%" stop-color="#E0E7FF"/>
|
|
7
|
-
</linearGradient>
|
|
8
|
-
<linearGradient id="handle" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
9
|
-
<stop offset="0%" stop-color="#4F46E5"/>
|
|
10
|
-
<stop offset="100%" stop-color="#6366F1"/>
|
|
11
|
-
</linearGradient>
|
|
12
|
-
<linearGradient id="bristles" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
13
|
-
<stop offset="0%" stop-color="#10B981"/>
|
|
14
|
-
<stop offset="100%" stop-color="#34D399"/>
|
|
15
|
-
</linearGradient>
|
|
16
|
-
</defs>
|
|
17
|
-
|
|
18
|
-
<!-- Logo badge -->
|
|
19
|
-
<circle cx="52" cy="60" r="44" fill="url(#bg)"/>
|
|
20
|
-
<circle cx="52" cy="60" r="44" fill="none" stroke="#4F46E5" stroke-width="2.5"/>
|
|
21
|
-
|
|
22
|
-
<!-- Broom handle -->
|
|
23
|
-
<line x1="26" y1="86" x2="64" y2="34" stroke="url(#handle)" stroke-width="4.5" stroke-linecap="round"/>
|
|
24
|
-
|
|
25
|
-
<!-- Broom bristles -->
|
|
26
|
-
<line x1="62" y1="38" x2="74" y2="26" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
27
|
-
<line x1="64" y1="42" x2="78" y2="32" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
28
|
-
<line x1="64" y1="46" x2="80" y2="38" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
29
|
-
<line x1="64" y1="50" x2="80" y2="44" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
30
|
-
<line x1="62" y1="54" x2="78" y2="50" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
31
|
-
<line x1="60" y1="58" x2="74" y2="56" stroke="url(#bristles)" stroke-width="3.5" stroke-linecap="round"/>
|
|
32
|
-
|
|
33
|
-
<!-- Swept git branch -->
|
|
34
|
-
<circle cx="72" cy="60" r="2.5" fill="#10B981" opacity="0.5"/>
|
|
35
|
-
<path d="M68,64 Q72,60 72,50" stroke="#10B981" stroke-width="1.5" fill="none" opacity="0.4" stroke-linecap="round"/>
|
|
36
|
-
|
|
37
|
-
<!-- Wordmark -->
|
|
38
|
-
<text x="114" y="60" font-family="system-ui, -apple-system, sans-serif" font-size="34" font-weight="700" fill="#1F2937" letter-spacing="-0.5">git-cleaner</text>
|
|
39
|
-
<text x="114" y="80" font-family="system-ui, -apple-system, sans-serif" font-size="12" fill="#6B7280" letter-spacing="3">MAINTENANCE & CLEANUP</text>
|
|
40
|
-
</svg>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|