gitforest 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.
Files changed (256) hide show
  1. package/.bunignore +7 -0
  2. package/.github/workflows/ci.yml +73 -0
  3. package/CLAUDE.md +111 -0
  4. package/CONTRIBUTING.md +145 -0
  5. package/README.md +168 -0
  6. package/bun.lock +267 -0
  7. package/bunfig.toml +15 -0
  8. package/cli +0 -0
  9. package/config/gitforest.example.yaml +94 -0
  10. package/docs/ai/IMPROVEMENT_PLAN.md +341 -0
  11. package/docs/ai/VERIFICATION_REPORT.md +87 -0
  12. package/docs/ai/architecture.md +169 -0
  13. package/docs/ai/checks/check-2025-12-02-tests.md +40 -0
  14. package/docs/ai/checks/check-2025-12-02.md +55 -0
  15. package/docs/ai/checks/test-verification-report.md +85 -0
  16. package/docs/ai/implementation-guide.md +776 -0
  17. package/docs/ai/research/gitty-codebase-analysis.md +221 -0
  18. package/docs/ai/tickets/GENERAL-sitrep.md +30 -0
  19. package/docs/ai/tickets/TASK-database-tests-sitrep.md +25 -0
  20. package/docs/ai/tickets/TASK-deprecated-functions-sitrep.md +28 -0
  21. package/docs/ai/tickets/TASK-detail-modal-sitrep.md +28 -0
  22. package/docs/ai/tickets/TASK-filter-overlay-sitrep.md +24 -0
  23. package/docs/ai/tickets/TASK-github-service-sitrep.md +32 -0
  24. package/docs/ai/tickets/TASK-github-token-sitrep.md +51 -0
  25. package/docs/ai/tickets/TASK-hascommits-sitrep.md +35 -0
  26. package/docs/ai/tickets/TASK-keybindings-sitrep.md +26 -0
  27. package/docs/ai/tickets/TASK-layout-sitrep.md +25 -0
  28. package/docs/ai/tickets/TASK-markdown-sitrep.md +28 -0
  29. package/docs/ai/tickets/TASK-project-item-sitrep.md +79 -0
  30. package/docs/ai/tickets/TASK-sitrep.md +28 -0
  31. package/docs/ai/tickets/TASK-state-sitrep.md +26 -0
  32. package/docs/ai/tickets/TASK-types-sitrep.md +25 -0
  33. package/docs/ai/tickets/TASK-unified-item-fix-sitrep.md +26 -0
  34. package/docs/ai/tickets/TKT-001-sitrep.md +24 -0
  35. package/docs/ai/tickets/TKT-002-sitrep.md +25 -0
  36. package/docs/ai/tickets/TKT-003-git-service-refactoring-complete.md +46 -0
  37. package/docs/ai/tickets/TKT-003-git-service-refactoring-plan.md +135 -0
  38. package/docs/ai/tickets/TKT-003-sitrep.md +26 -0
  39. package/docs/ai/tickets/TKT-004-sitrep.md +27 -0
  40. package/docs/ai/tickets/TKT-005-sitrep.md +25 -0
  41. package/docs/ai/tickets/TKT-006-sitrep.md +26 -0
  42. package/docs/ai/tickets/TKT-007-sitrep.md +30 -0
  43. package/docs/ai/tickets/TKT-008-sitrep.md +32 -0
  44. package/docs/ai/tickets/TKT-009-sitrep.md +27 -0
  45. package/docs/ai/tickets/TKT-010-sitrep.md +27 -0
  46. package/docs/ai/tickets/TKT-011-sitrep.md +26 -0
  47. package/docs/ai/tickets/TKT-012-sitrep.md +25 -0
  48. package/docs/ai/tickets/sitreps/TASK-actions-sitrep.md +28 -0
  49. package/docs/ai/tickets/sitreps/TASK-actions-test-sitrep.md +25 -0
  50. package/docs/ai/tickets/sitreps/TASK-app-integration-sitrep.md +25 -0
  51. package/docs/ai/tickets/sitreps/TASK-background-fetch-sitrep.md +24 -0
  52. package/docs/ai/tickets/sitreps/TASK-background-fetch-test-sitrep.md +29 -0
  53. package/docs/ai/tickets/sitreps/TASK-batch-tests-sitrep.md +29 -0
  54. package/docs/ai/tickets/sitreps/TASK-bun-test-sitrep.md +26 -0
  55. package/docs/ai/tickets/sitreps/TASK-cache-tests-sitrep.md +30 -0
  56. package/docs/ai/tickets/sitreps/TASK-cli-tests-sitrep.md +28 -0
  57. package/docs/ai/tickets/sitreps/TASK-clone-error-handling-sitrep.md +26 -0
  58. package/docs/ai/tickets/sitreps/TASK-commands-tests-sitrep.md +25 -0
  59. package/docs/ai/tickets/sitreps/TASK-component-tests-1-sitrep.md +30 -0
  60. package/docs/ai/tickets/sitreps/TASK-configloader-tests-sitrep.md +25 -0
  61. package/docs/ai/tickets/sitreps/TASK-confirm-dialog-test-sitrep.md +29 -0
  62. package/docs/ai/tickets/sitreps/TASK-coverage-sitrep.md +95 -0
  63. package/docs/ai/tickets/sitreps/TASK-database-tests-summary.md +61 -0
  64. package/docs/ai/tickets/sitreps/TASK-error-boundary-sitrep.md +30 -0
  65. package/docs/ai/tickets/sitreps/TASK-error-tests-sitrep.md +27 -0
  66. package/docs/ai/tickets/sitreps/TASK-errors-tests-sitrep.md +25 -0
  67. package/docs/ai/tickets/sitreps/TASK-extract-reducer-sitrep.md +27 -0
  68. package/docs/ai/tickets/sitreps/TASK-filter-overlay-test-sitrep.md +25 -0
  69. package/docs/ai/tickets/sitreps/TASK-final-verification-sitrep.md +28 -0
  70. package/docs/ai/tickets/sitreps/TASK-fix-all-tests-sitrep.md +25 -0
  71. package/docs/ai/tickets/sitreps/TASK-fix-hooks-sitrep.md +26 -0
  72. package/docs/ai/tickets/sitreps/TASK-fix-remaining-tests-sitrep.md +25 -0
  73. package/docs/ai/tickets/sitreps/TASK-fix-test-failures-sitrep.md +26 -0
  74. package/docs/ai/tickets/sitreps/TASK-fix-tests-sitrep.md +24 -0
  75. package/docs/ai/tickets/sitreps/TASK-formatters-tests-sitrep.md +25 -0
  76. package/docs/ai/tickets/sitreps/TASK-git-timeouts-sitrep.md +29 -0
  77. package/docs/ai/tickets/sitreps/TASK-github-cache-test-sitrep.md +25 -0
  78. package/docs/ai/tickets/sitreps/TASK-githubcli-tests-sitrep.md +24 -0
  79. package/docs/ai/tickets/sitreps/TASK-gitstatus-tests-sitrep.md +24 -0
  80. package/docs/ai/tickets/sitreps/TASK-hooks-isolation-sitrep.md +27 -0
  81. package/docs/ai/tickets/sitreps/TASK-keybindings-tests-sitrep.md +25 -0
  82. package/docs/ai/tickets/sitreps/TASK-layout-tests-sitrep.md +25 -0
  83. package/docs/ai/tickets/sitreps/TASK-mock-factories-sitrep.md +27 -0
  84. package/docs/ai/tickets/sitreps/TASK-modal-tests-sitrep.md +32 -0
  85. package/docs/ai/tickets/sitreps/TASK-processbatch-fix-sitrep.md +27 -0
  86. package/docs/ai/tickets/sitreps/TASK-projectlist-tests-sitrep.md +30 -0
  87. package/docs/ai/tickets/sitreps/TASK-projectutils-tests-sitrep.md +25 -0
  88. package/docs/ai/tickets/sitreps/TASK-scanner-tests-sitrep.md +29 -0
  89. package/docs/ai/tickets/sitreps/TASK-select-all-sitrep.md +25 -0
  90. package/docs/ai/tickets/sitreps/TASK-shell-error-handling-sitrep.md +27 -0
  91. package/docs/ai/tickets/sitreps/TASK-store-tests-sitrep.md +25 -0
  92. package/docs/ai/tickets/sitreps/TASK-test-fixes-sitrep.md +26 -0
  93. package/docs/ai/tickets/sitreps/TASK-test-summary-sitrep.md +25 -0
  94. package/docs/ai/tickets/sitreps/TASK-test-verification-sitrep.md +27 -0
  95. package/docs/ai/tickets/sitreps/TASK-testsuite-sitrep.md +75 -0
  96. package/docs/ai/tickets/sitreps/TASK-unified-reducer-tests-sitrep.md +29 -0
  97. package/docs/ai/tickets/sitreps/TASK-unified-repos-test-sitrep.md +29 -0
  98. package/docs/ai/tickets/sitreps/TASK-unified-tests-sitrep.md +25 -0
  99. package/docs/ai/tickets/sitreps/TASK-useprojects-tests-sitrep.md +25 -0
  100. package/docs/ai/tickets/sitreps/TASK-utility-tests-sitrep.md +32 -0
  101. package/docs/ai/tickets/sitreps/TKT-003-git-service-refactoring-sitrep.md +64 -0
  102. package/docs/ai/tkt-001-fix-database-error.md +217 -0
  103. package/docs/ai/ui-enhancement-plan.md +562 -0
  104. package/package.json +50 -0
  105. package/src/app.tsx +43 -0
  106. package/src/cli/config.ts +94 -0
  107. package/src/cli/formatters.ts +632 -0
  108. package/src/cli/index.ts +583 -0
  109. package/src/components/CloneDialog.tsx +137 -0
  110. package/src/components/ColumnHeader.tsx +128 -0
  111. package/src/components/CommandPalette.tsx +120 -0
  112. package/src/components/ConfirmDialog.tsx +105 -0
  113. package/src/components/ErrorBoundary.tsx +128 -0
  114. package/src/components/FilterBar.tsx +71 -0
  115. package/src/components/FilterOptionsOverlay.tsx +131 -0
  116. package/src/components/HelpOverlay.tsx +120 -0
  117. package/src/components/Layout.tsx +379 -0
  118. package/src/components/MarkdownRenderer.tsx +127 -0
  119. package/src/components/ProgressBar.tsx +53 -0
  120. package/src/components/ProjectItem.tsx +143 -0
  121. package/src/components/ProjectList.tsx +90 -0
  122. package/src/components/RepoDetailModal.tsx +367 -0
  123. package/src/components/StatusBar.tsx +188 -0
  124. package/src/components/UnifiedProjectItem.tsx +436 -0
  125. package/src/components/ViewModeIndicator.tsx +37 -0
  126. package/src/components/onboarding/CompleteStep.tsx +82 -0
  127. package/src/components/onboarding/DirectoriesStep.test.tsx +52 -0
  128. package/src/components/onboarding/DirectoriesStep.tsx +847 -0
  129. package/src/components/onboarding/DirectoriesStep.unit.test.ts +345 -0
  130. package/src/components/onboarding/GitHubAuthStep.tsx +268 -0
  131. package/src/components/onboarding/OnboardingWizard.tsx +130 -0
  132. package/src/components/onboarding/WelcomeStep.tsx +69 -0
  133. package/src/config/loader.ts +263 -0
  134. package/src/config/onboarding.ts +67 -0
  135. package/src/constants.ts +96 -0
  136. package/src/db/index.ts +147 -0
  137. package/src/db/schema.ts +70 -0
  138. package/src/git/commands.ts +283 -0
  139. package/src/git/index.ts +2 -0
  140. package/src/git/operations.ts +93 -0
  141. package/src/git/service.ts +539 -0
  142. package/src/git/status.ts +84 -0
  143. package/src/git/types.ts +5 -0
  144. package/src/github/auth.ts +311 -0
  145. package/src/github/cache.ts +231 -0
  146. package/src/github/cli.ts +22 -0
  147. package/src/github/unified.ts +415 -0
  148. package/src/hooks/useBackgroundFetch.ts +76 -0
  149. package/src/hooks/useConfirmDialogActions.ts +120 -0
  150. package/src/hooks/useKeyBindings.ts +656 -0
  151. package/src/hooks/useProjects.ts +47 -0
  152. package/src/hooks/useUnifiedRepos.ts +317 -0
  153. package/src/index.tsx +494 -0
  154. package/src/operations/batch.ts +280 -0
  155. package/src/operations/commands.ts +140 -0
  156. package/src/operations/index.ts +37 -0
  157. package/src/scanner/index.ts +424 -0
  158. package/src/scanner/markers.ts +43 -0
  159. package/src/scanner/submodules.ts +61 -0
  160. package/src/services/git.ts +484 -0
  161. package/src/services/github.ts +676 -0
  162. package/src/services/index.ts +28 -0
  163. package/src/services/types.ts +99 -0
  164. package/src/state/actions.ts +175 -0
  165. package/src/state/reducer.ts +294 -0
  166. package/src/state/store.tsx +216 -0
  167. package/src/state/types.ts +8 -0
  168. package/src/types/index.ts +383 -0
  169. package/src/ui/theme.ts +44 -0
  170. package/src/utils/array.ts +14 -0
  171. package/src/utils/debug.ts +38 -0
  172. package/src/utils/errors.ts +17 -0
  173. package/src/utils/index.ts +8 -0
  174. package/src/utils/markdown.ts +230 -0
  175. package/src/utils/project-utils.ts +129 -0
  176. package/src/utils/rate-limiter.ts +134 -0
  177. package/src/utils/retry.ts +147 -0
  178. package/src/utils/timeout.ts +56 -0
  179. package/test/integration/app.isolated.tsx +240 -0
  180. package/test/integration/cli-commands.test.ts +287 -0
  181. package/test/integration/cli-validation.test.ts +264 -0
  182. package/test/integration/git-operations.test.ts +218 -0
  183. package/test/integration/scanner.test.ts +228 -0
  184. package/test/preload.ts +18 -0
  185. package/test/unit/cli/commands.test.ts +13 -0
  186. package/test/unit/cli/formatters.test.ts +1116 -0
  187. package/test/unit/cli/github-commands.test.ts +12 -0
  188. package/test/unit/components/CloneDialog.test.tsx +240 -0
  189. package/test/unit/components/ColumnHeader.test.tsx +128 -0
  190. package/test/unit/components/CommandPalette.test.tsx +355 -0
  191. package/test/unit/components/ConfirmDialog.test.tsx +111 -0
  192. package/test/unit/components/ErrorBoundary.test.tsx +139 -0
  193. package/test/unit/components/FilterBar.test.tsx +43 -0
  194. package/test/unit/components/FilterOptionsOverlay.test.tsx +197 -0
  195. package/test/unit/components/HelpOverlay.test.tsx +90 -0
  196. package/test/unit/components/Layout.test.tsx +328 -0
  197. package/test/unit/components/MarkdownRenderer.test.tsx +45 -0
  198. package/test/unit/components/ProgressBar.test.tsx +138 -0
  199. package/test/unit/components/ProjectItem.test.tsx +182 -0
  200. package/test/unit/components/ProjectList.test.tsx +311 -0
  201. package/test/unit/components/RepoDetailModal.test.tsx +445 -0
  202. package/test/unit/components/StatusBar.test.tsx +112 -0
  203. package/test/unit/components/UnifiedProjectItem.test.tsx +618 -0
  204. package/test/unit/components/ViewModeIndicator.test.tsx +137 -0
  205. package/test/unit/components/test-utils.tsx +63 -0
  206. package/test/unit/config/loader.test.ts +692 -0
  207. package/test/unit/db/database.test.ts +978 -0
  208. package/test/unit/db/index.test.ts +314 -0
  209. package/test/unit/fixtures/setup.ts +186 -0
  210. package/test/unit/git/commands-untested.test.ts +205 -0
  211. package/test/unit/git/commands.test.ts +269 -0
  212. package/test/unit/git/operations.test.ts +322 -0
  213. package/test/unit/git/status.test.ts +219 -0
  214. package/test/unit/github/auth.test.ts +317 -0
  215. package/test/unit/github/cache.test.ts +1028 -0
  216. package/test/unit/github/cli.test.ts +135 -0
  217. package/test/unit/github/unified.test.ts +1201 -0
  218. package/test/unit/graceful-shutdown.test.ts +83 -0
  219. package/test/unit/hooks/useBackgroundFetch.test.tsx +239 -0
  220. package/test/unit/hooks/useConfirmDialogActions.test.tsx +81 -0
  221. package/test/unit/hooks/useKeyBindings.isolated.ts +715 -0
  222. package/test/unit/hooks/useProjects.test.tsx +186 -0
  223. package/test/unit/hooks/useUnifiedRepos-simple.test.tsx +115 -0
  224. package/test/unit/hooks/useUnifiedRepos.test.tsx +177 -0
  225. package/test/unit/mocks/config.ts +109 -0
  226. package/test/unit/mocks/git-service.ts +274 -0
  227. package/test/unit/mocks/github-service.ts +250 -0
  228. package/test/unit/mocks/index.ts +72 -0
  229. package/test/unit/mocks/project.ts +148 -0
  230. package/test/unit/mocks/state-mocks.ts +187 -0
  231. package/test/unit/mocks/unified.ts +169 -0
  232. package/test/unit/operations/batch.test.ts +216 -0
  233. package/test/unit/operations/commands.test.ts +550 -0
  234. package/test/unit/scanner/errors.test.ts +297 -0
  235. package/test/unit/scanner/index.test.ts +1011 -0
  236. package/test/unit/scanner/markers.test.ts +150 -0
  237. package/test/unit/scanner/submodules.test.ts +99 -0
  238. package/test/unit/services/git-errors.test.ts +190 -0
  239. package/test/unit/services/git.test.ts +442 -0
  240. package/test/unit/services/github-errors.test.ts +293 -0
  241. package/test/unit/services/github.test.ts +200 -0
  242. package/test/unit/state/actions.test.ts +217 -0
  243. package/test/unit/state/reducer.test.ts +745 -0
  244. package/test/unit/state/store.test.tsx +711 -0
  245. package/test/unit/types/commands.test.ts +220 -0
  246. package/test/unit/types/schema.test.ts +179 -0
  247. package/test/unit/utils/array.test.ts +73 -0
  248. package/test/unit/utils/debug.test.ts +23 -0
  249. package/test/unit/utils/errors.test.ts +295 -0
  250. package/test/unit/utils/markdown.test.ts +163 -0
  251. package/test/unit/utils/project-utils.test.ts +756 -0
  252. package/test/unit/utils/rate-limiter.test.ts +256 -0
  253. package/test/unit/utils/retry.test.ts +165 -0
  254. package/test/unit/utils/strip-ansi.ts +13 -0
  255. package/test/unit/utils/timeout.test.ts +93 -0
  256. package/tsconfig.json +29 -0
@@ -0,0 +1,562 @@
1
+ # Gitforest TUI Enhancement Plan
2
+
3
+ ## Overview
4
+
5
+ This document outlines a comprehensive UI overhaul for Gitforest's TUI interface, transforming it from a basic list view into a feature-rich repository management interface with rich status indicators, detailed repo views, and comprehensive filtering.
6
+
7
+ ---
8
+
9
+ ## 1. Enhanced Repository List Item (Rich Status Display)
10
+
11
+ **Current**: Basic name, source icon, branch, sync badges, last activity
12
+
13
+ **Proposed**: Multi-column layout with visual indicators
14
+
15
+ ```
16
+ ┌─ Status Indicators ────────────────────────────────────────────────────────────────────────┐
17
+ │ [>] [x] ☁ ● autoclaude ⎇ main 🔒 TS ↑2 ↓0 ★12 🍴3 📅 1w ago 45.2 KB │
18
+ │ [ ] 🔗 ✓ gitforest ⎇ feat 🌐 TS ✓sync ★0 🍴0 📅 today 12.1 KB │
19
+ │ [ ] 💻 ● local-only ⎇ main — RS no-rem — — 📅 3d ago 8.4 KB │
20
+ │ [ ] ☁ bander — — 🔒 JS — ★5 🍴1 📅 5d ago 2.1 MB │
21
+ └────────────────────────────────────────────────────────────────────────────────────────────┘
22
+ ```
23
+
24
+ ### Legend
25
+
26
+ | Symbol | Meaning |
27
+ |--------|---------|
28
+ | **Source** | |
29
+ | ☁ | GitHub-only (not cloned locally) |
30
+ | 💻 | Local-only (not on GitHub) |
31
+ | 🔗 | Both (synced local + GitHub) |
32
+ | **Status** | |
33
+ | ● | Dirty (uncommitted changes) |
34
+ | ✓ | Clean |
35
+ | ? | Unknown |
36
+ | **Privacy** | |
37
+ | 🔒 | Private repository |
38
+ | 🌐 | Public repository |
39
+ | **Language** | 2-char abbreviation (TS, JS, RS, PY, GO, etc.) |
40
+ | **Sync** | |
41
+ | ↑N | N unpushed commits |
42
+ | ↓N | N unpulled commits |
43
+ | ✓sync | Fully synchronized |
44
+ | no-rem | No remote configured |
45
+ | **Stats** | |
46
+ | ★ | GitHub stars |
47
+ | 🍴 | GitHub forks |
48
+ | **Size** | Repository size (KB/MB/GB) |
49
+
50
+ ---
51
+
52
+ ## 2. New Data Fields from GitHub API
53
+
54
+ Extend `GitHubRepoInfo` interface with additional fields:
55
+
56
+ ```typescript
57
+ interface GitHubRepoInfo {
58
+ // Existing fields...
59
+ name: string;
60
+ fullName: string;
61
+ owner: string;
62
+ description: string | null;
63
+ htmlUrl: string;
64
+ sshUrl: string;
65
+ cloneUrl: string;
66
+ isPrivate: boolean;
67
+ isArchived: boolean;
68
+ isFork: boolean;
69
+ pushedAt: Date | null;
70
+ updatedAt: Date | null;
71
+ defaultBranch: string;
72
+ language: string | null;
73
+ size: number;
74
+
75
+ // NEW fields:
76
+ stargazersCount: number;
77
+ forksCount: number;
78
+ openIssuesCount: number;
79
+ watchersCount: number;
80
+ topics: string[];
81
+ license: string | null;
82
+ hasIssues: boolean;
83
+ hasWiki: boolean;
84
+ hasDiscussions: boolean;
85
+ visibility: "public" | "private" | "internal";
86
+ }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 3. Enhanced Filter Bar with Global Options
92
+
93
+ Press `?` to show filter options popup:
94
+
95
+ ```
96
+ ┌─ Filter Options ──────────────────────────────────────────────┐
97
+ │ Quick Filters: │
98
+ │ 0 All 1 Dirty 2 Unpushed 3 No-remote │
99
+ │ 4 GitHub-only 5 Local-only 6 Private 7 Public │
100
+ │ 8 Archived 9 Forks │
101
+ │ │
102
+ │ Language Filter: (type to filter by language) │
103
+ │ l:typescript l:javascript l:rust l:python l:go │
104
+ │ │
105
+ │ Sort: s to cycle (name → status → activity → stars → size) │
106
+ │ Search: / to search by name, description, or path │
107
+ │ │
108
+ │ Press any key to close │
109
+ └───────────────────────────────────────────────────────────────┘
110
+ ```
111
+
112
+ ### New Quick Filters
113
+
114
+ | Key | Filter | Description |
115
+ |-----|--------|-------------|
116
+ | 0 | All | Show all repositories |
117
+ | 1 | Dirty | Repos with uncommitted changes |
118
+ | 2 | Unpushed | Repos with unpushed commits |
119
+ | 3 | No-remote | Local repos without remote |
120
+ | 4 | GitHub-only | Repos on GitHub but not cloned |
121
+ | 5 | Local-only | Local repos (cloned or local-only) |
122
+ | 6 | Private | Private repositories |
123
+ | 7 | Public | Public repositories |
124
+ | 8 | Archived | Archived repositories |
125
+ | 9 | Forks | Forked repositories |
126
+
127
+ ### Language Filter
128
+
129
+ Type `l:` followed by language name to filter:
130
+ - `l:typescript` or `l:ts`
131
+ - `l:javascript` or `l:js`
132
+ - `l:rust` or `l:rs`
133
+ - `l:python` or `l:py`
134
+ - `l:go`
135
+
136
+ ---
137
+
138
+ ## 4. Column Headers (Sortable)
139
+
140
+ ```
141
+ ┌─ Column Headers ───────────────────────────────────────────────────────────────────────────┐
142
+ │ Sel Src Status Name Branch Vis Lang Sync Stars Fork Updated Size│
143
+ │ ─── ─── ────── ────────────────── ─────── ─── ───── ──────── ────── ───── ──────── ────│
144
+ │ [▼ sort] │
145
+ └────────────────────────────────────────────────────────────────────────────────────────────┘
146
+ ```
147
+
148
+ Press `s` to cycle through sort fields:
149
+ 1. Status (default) - prioritizes repos needing attention
150
+ 2. Name - alphabetical
151
+ 3. Last Activity - most recently updated first
152
+ 4. Stars - most starred first
153
+ 5. Size - largest first
154
+
155
+ ---
156
+
157
+ ## 5. Repository Detail Modal
158
+
159
+ Press `Enter` to open, `Escape` to close.
160
+
161
+ ```
162
+ ┌─────────────────────────────────── autoclaude ────────────────────────────────────────────┐
163
+ │ │
164
+ │ ☁ GitHub: bsunter/autoclaude 🔒 Private ★ 12 🍴 3 👀 5 │
165
+ │ 💻 Local: /Users/brian/code/autoclaude ⎇ main Size: 45.2 KB │
166
+ │ │
167
+ │ ┌─ Status ─────────────────────────────────────────────────────────────────────────────┐ │
168
+ │ │ ● Dirty: 3 modified, 1 staged, 2 untracked │ │
169
+ │ │ ↑ 2 commits to push ↓ 0 commits to pull │ │
170
+ │ │ Last local commit: 2 hours ago │ │
171
+ │ │ Last GitHub push: 1 week ago │ │
172
+ │ └──────────────────────────────────────────────────────────────────────────────────────┘ │
173
+ │ │
174
+ │ ┌─ Actions ────────────────────────────────────────────────────────────────────────────┐ │
175
+ │ │ [p] Push [P] Pull [f] Fetch [o] Open in Browser [c] Copy Clone URL │ │
176
+ │ │ [d] Open in Editor [g] Open GitHub [A] Archive │ │
177
+ │ └──────────────────────────────────────────────────────────────────────────────────────┘ │
178
+ │ │
179
+ │ ┌─ README.md ──────────────────────────────────────────────────────────────────────────┐ │
180
+ │ │ │ │
181
+ │ │ # Autoclaude │ │
182
+ │ │ │ │
183
+ │ │ > An AI-powered development assistant using Claude │ │
184
+ │ │ │ │
185
+ │ │ ## Features │ │
186
+ │ │ │ │
187
+ │ │ - **Code Generation**: Generate boilerplate and implement features │ │
188
+ │ │ - **Code Review**: Get instant feedback on your code │ │
189
+ │ │ - **Documentation**: Auto-generate docs from code │ │
190
+ │ │ │ │
191
+ │ │ ## Installation │ │
192
+ │ │ │ │
193
+ │ │ ```bash │ │
194
+ │ │ bun install autoclaude │ │
195
+ │ │ ``` │ │
196
+ │ │ │ │
197
+ │ │ [↑↓ scroll] │ │
198
+ │ └──────────────────────────────────────────────────────────────────────────────────────┘ │
199
+ │ │
200
+ │ Topics: ai, claude, typescript, automation │
201
+ │ License: MIT Created: Jan 2024 Language: TypeScript │
202
+ │ │
203
+ │ [Esc] Close [j/k] Scroll README [Tab] Next section │
204
+ └───────────────────────────────────────────────────────────────────────────────────────────┘
205
+ ```
206
+
207
+ ### Modal Sections
208
+
209
+ 1. **Header**: Repo name, GitHub link, privacy, stats
210
+ 2. **Location Info**: Local path, branch, size
211
+ 3. **Status Panel**: Git status details (dirty state, sync status, timestamps)
212
+ 4. **Actions Panel**: Quick action buttons with keyboard shortcuts
213
+ 5. **README Panel**: Scrollable markdown-rendered README
214
+ 6. **Footer**: Topics, license, language, help text
215
+
216
+ ### Modal Actions
217
+
218
+ | Key | Action | Description |
219
+ |-----|--------|-------------|
220
+ | p | Push | Push local commits to remote |
221
+ | P | Pull | Pull remote changes |
222
+ | f | Fetch | Fetch remote without merging |
223
+ | o | Open in Browser | Open GitHub page in browser |
224
+ | c | Copy Clone URL | Copy SSH/HTTPS clone URL to clipboard |
225
+ | d | Open in Editor | Open repo in configured editor |
226
+ | g | Open GitHub | Open GitHub repo page |
227
+ | A | Archive | Archive the repository on GitHub |
228
+ | j/k | Scroll | Scroll README up/down |
229
+ | Esc | Close | Close the modal |
230
+
231
+ ---
232
+
233
+ ## 6. TUI Markdown Renderer
234
+
235
+ For README display, implement a terminal-friendly markdown renderer:
236
+
237
+ ### Supported Elements
238
+
239
+ | Element | Rendering |
240
+ |---------|-----------|
241
+ | `# Header` | Bold + cyan color |
242
+ | `## H2` | Bold + blue color |
243
+ | `### H3` | Bold |
244
+ | `**bold**` | Bold text |
245
+ | `*italic*` | Italic/dim text |
246
+ | `` `code` `` | Gray background |
247
+ | ```` ```code``` ```` | Gray background block |
248
+ | `- list` | Indented bullet points |
249
+ | `> quote` | Gray with `│` prefix |
250
+ | `[link](url)` | Cyan underlined |
251
+ | `---` | Horizontal line |
252
+
253
+ ---
254
+
255
+ ## 7. New State & Types
256
+
257
+ ### Extended App Mode
258
+
259
+ ```typescript
260
+ export type AppMode =
261
+ | "normal"
262
+ | "filter"
263
+ | "action"
264
+ | "help"
265
+ | "confirm"
266
+ | "clone"
267
+ | "detail" // NEW: Detail modal open
268
+ | "filter-options"; // NEW: Filter options overlay
269
+ ```
270
+
271
+ ### Detail Modal State
272
+
273
+ ```typescript
274
+ export interface DetailModalState {
275
+ repo: UnifiedRepo;
276
+ readmeContent: string | null;
277
+ readmeLoading: boolean;
278
+ readmeError: string | null;
279
+ readmeScrollOffset: number;
280
+ activeSection: "status" | "actions" | "readme";
281
+ }
282
+ ```
283
+
284
+ ### Extended Quick Filters
285
+
286
+ ```typescript
287
+ export type QuickFilter =
288
+ | "all"
289
+ | "dirty"
290
+ | "unpushed"
291
+ | "no-remote"
292
+ | "github-only"
293
+ | "local-only"
294
+ | "private" // NEW
295
+ | "public" // NEW
296
+ | "archived" // NEW
297
+ | "forks"; // NEW
298
+ ```
299
+
300
+ ### Language Filter State
301
+
302
+ ```typescript
303
+ export interface FilterState {
304
+ text: string;
305
+ quickFilter: QuickFilter;
306
+ language: string | null; // NEW: Filter by programming language
307
+ }
308
+ ```
309
+
310
+ ---
311
+
312
+ ## 8. Key Bindings Summary
313
+
314
+ ### Global Keys
315
+
316
+ | Key | Action |
317
+ |-----|--------|
318
+ | `q` | Quit application |
319
+ | `?` | Show filter options overlay |
320
+ | `Tab` | Cycle view mode (local/github/all) |
321
+ | `r` | Refresh repository list |
322
+
323
+ ### Navigation
324
+
325
+ | Key | Action |
326
+ |-----|--------|
327
+ | `j` / `↓` | Move cursor down |
328
+ | `k` / `↑` | Move cursor up |
329
+ | `g` | Go to top |
330
+ | `G` | Go to bottom |
331
+ | `Enter` | Open detail modal |
332
+
333
+ ### Selection
334
+
335
+ | Key | Action |
336
+ |-----|--------|
337
+ | `Space` | Toggle selection |
338
+ | `a` | Select all / Deselect all |
339
+
340
+ ### Filtering & Sorting
341
+
342
+ | Key | Action |
343
+ |-----|--------|
344
+ | `/` | Enter text search mode |
345
+ | `s` | Cycle sort field |
346
+ | `0-9` | Quick filters |
347
+ | `l` | Enter language filter mode |
348
+ | `Esc` | Cancel filter / Close modal |
349
+
350
+ ### Git Operations (List View)
351
+
352
+ | Key | Action |
353
+ |-----|--------|
354
+ | `p` | Push selected repos |
355
+ | `P` | Pull all repos |
356
+ | `f` | Fetch all remotes |
357
+ | `i` | Init git in selected |
358
+
359
+ ### GitHub Operations (List View)
360
+
361
+ | Key | Action |
362
+ |-----|--------|
363
+ | `D` | Clone GitHub repos |
364
+ | `c` | Create GitHub repo |
365
+ | `C` | Full setup (init + create + push) |
366
+ | `A` | Archive GitHub repo |
367
+
368
+ ### Detail Modal Keys
369
+
370
+ | Key | Action |
371
+ |-----|--------|
372
+ | `Esc` | Close modal |
373
+ | `j/k` | Scroll README |
374
+ | `Tab` | Cycle sections |
375
+ | `p` | Push |
376
+ | `P` | Pull |
377
+ | `f` | Fetch |
378
+ | `o` | Open in browser |
379
+ | `c` | Copy clone URL |
380
+ | `d` | Open in editor |
381
+
382
+ ---
383
+
384
+ ## 9. Implementation Plan
385
+
386
+ ### Phase 1: Enhanced List View (Priority: High)
387
+
388
+ 1. Update `GitHubRepoInfo` type with new fields
389
+ 2. Update GitHub service to fetch additional data (stars, forks, etc.)
390
+ 3. Redesign `UnifiedProjectItem` component with compact rich display
391
+ 4. Create `ColumnHeader` component for sortable columns
392
+ 5. Update filtering to support new quick filters
393
+
394
+ **Files to modify:**
395
+ - `src/types/index.ts`
396
+ - `src/services/github.ts`
397
+ - `src/components/UnifiedProjectItem.tsx`
398
+ - `src/components/ColumnHeader.tsx` (new)
399
+ - `src/state/store.tsx`
400
+
401
+ ### Phase 2: Detail Modal (Priority: High)
402
+
403
+ 1. Create `RepoDetailModal` component
404
+ 2. Implement `MarkdownRenderer` component for TUI
405
+ 3. Add README fetching from GitHub API (or local file)
406
+ 4. Add modal state management
407
+ 5. Implement scrollable README view
408
+
409
+ **Files to create:**
410
+ - `src/components/RepoDetailModal.tsx`
411
+ - `src/components/MarkdownRenderer.tsx`
412
+ - `src/utils/markdown.ts`
413
+
414
+ **Files to modify:**
415
+ - `src/types/index.ts`
416
+ - `src/state/store.tsx`
417
+ - `src/components/Layout.tsx`
418
+
419
+ ### Phase 3: Enhanced Filtering (Priority: Medium)
420
+
421
+ 1. Create `FilterOptionsOverlay` component
422
+ 2. Add language filter functionality
423
+ 3. Add private/public/archived/fork filters
424
+ 4. Update filter state management
425
+ 5. Update keybindings
426
+
427
+ **Files to create:**
428
+ - `src/components/FilterOptionsOverlay.tsx`
429
+
430
+ **Files to modify:**
431
+ - `src/hooks/useKeyBindings.ts`
432
+ - `src/state/store.tsx`
433
+ - `src/github/unified.ts`
434
+
435
+ ### Phase 4: Actions & Polish (Priority: Medium)
436
+
437
+ 1. Implement action handlers in detail modal
438
+ 2. Add "Open in Browser" functionality (using `open` command)
439
+ 3. Add "Open in Editor" functionality (configurable editor)
440
+ 4. Add clipboard support for copying URLs
441
+ 5. Add loading states and error handling
442
+ 6. Performance optimization
443
+
444
+ **Files to modify:**
445
+ - `src/components/RepoDetailModal.tsx`
446
+ - `src/hooks/useKeyBindings.ts`
447
+ - `src/types/index.ts` (add editor config)
448
+
449
+ ### Phase 5: Testing & Documentation (Priority: Low)
450
+
451
+ 1. Add unit tests for new components
452
+ 2. Add integration tests for new features
453
+ 3. Update help overlay with new keybindings
454
+ 4. Update README with new features
455
+
456
+ ---
457
+
458
+ ## 10. File Structure
459
+
460
+ ### New Files
461
+
462
+ ```
463
+ src/
464
+ ├── components/
465
+ │ ├── RepoDetailModal.tsx # Full-screen detail view
466
+ │ ├── FilterOptionsOverlay.tsx # Filter help popup
467
+ │ ├── ColumnHeader.tsx # Sortable column headers
468
+ │ └── MarkdownRenderer.tsx # TUI markdown rendering
469
+ └── utils/
470
+ └── markdown.ts # Markdown parsing utilities
471
+ ```
472
+
473
+ ### Modified Files
474
+
475
+ ```
476
+ src/
477
+ ├── types/
478
+ │ └── index.ts # Extended types
479
+ ├── components/
480
+ │ ├── UnifiedProjectItem.tsx # Rich status display
481
+ │ ├── Layout.tsx # Modal routing
482
+ │ ├── FilterBar.tsx # Enhanced filters
483
+ │ └── HelpOverlay.tsx # Updated keybindings
484
+ ├── state/
485
+ │ └── store.tsx # New state management
486
+ ├── hooks/
487
+ │ └── useKeyBindings.ts # New keybindings
488
+ ├── services/
489
+ │ └── github.ts # Fetch additional data
490
+ └── github/
491
+ └── unified.ts # New filter functions
492
+ ```
493
+
494
+ ---
495
+
496
+ ## 11. Technical Considerations
497
+
498
+ ### Performance
499
+
500
+ - Use virtualization for long lists (already implemented)
501
+ - Lazy-load README content only when modal opens
502
+ - Cache GitHub API responses
503
+ - Debounce filter input
504
+
505
+ ### Accessibility
506
+
507
+ - Ensure all actions have keyboard shortcuts
508
+ - Provide clear visual feedback for current state
509
+ - Use consistent color coding
510
+
511
+ ### Error Handling
512
+
513
+ - Graceful fallback when GitHub API fails
514
+ - Show loading states during async operations
515
+ - Display meaningful error messages
516
+
517
+ ### Configuration
518
+
519
+ - Editor command (default: `$EDITOR` or `code`)
520
+ - Browser command (default: `open` on macOS)
521
+ - Default visibility for new repos
522
+ - Cache TTL settings
523
+
524
+ ---
525
+
526
+ ## 12. Success Metrics
527
+
528
+ After implementation, the UI should:
529
+
530
+ 1. **Show more information at a glance** - Users can see status, privacy, language, stars, and sync status without opening details
531
+ 2. **Faster filtering** - Quick filters allow instant narrowing of repo list
532
+ 3. **Better repo understanding** - Detail modal shows README and comprehensive status
533
+ 4. **Faster actions** - Common operations available via single keystroke
534
+ 5. **Intuitive navigation** - Consistent vim-like keybindings throughout
535
+
536
+ ---
537
+
538
+ ## Appendix: Language Abbreviations
539
+
540
+ | Language | Abbreviation |
541
+ |----------|-------------|
542
+ | TypeScript | TS |
543
+ | JavaScript | JS |
544
+ | Rust | RS |
545
+ | Python | PY |
546
+ | Go | GO |
547
+ | Ruby | RB |
548
+ | Java | JV |
549
+ | C | C |
550
+ | C++ | C+ |
551
+ | C# | C# |
552
+ | PHP | PH |
553
+ | Swift | SW |
554
+ | Kotlin | KT |
555
+ | Scala | SC |
556
+ | Elixir | EX |
557
+ | Haskell | HS |
558
+ | Shell | SH |
559
+ | HTML | HT |
560
+ | CSS | CS |
561
+ | Vue | VU |
562
+ | Svelte | SV |
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "gitforest",
3
+ "version": "0.1.0",
4
+ "description": "TUI for managing multiple Git repositories and GitHub integration",
5
+ "module": "src/index.tsx",
6
+ "type": "module",
7
+ "bin": {
8
+ "gitforest": "./src/index.tsx"
9
+ },
10
+ "scripts": {
11
+ "start": "bun run src/index.tsx",
12
+ "dev": "bun --hot run src/index.tsx",
13
+ "tui": "bun run src/index.tsx",
14
+ "cli": "bun run src/cli/index.ts",
15
+ "test": "bun test --timeout 30000 && bun test --timeout 10000 ./test/unit/hooks/useKeyBindings.isolated.ts && bun test --timeout 20000 ./test/integration/app.isolated.tsx",
16
+ "test:unit": "bun test --timeout 10000 test/unit/utils/ test/unit/cli/ test/unit/components/ test/unit/config/ test/unit/types/ test/unit/state/ test/unit/operations/ test/unit/github/ test/unit/services/ && bun test --timeout 15000 test/unit/scanner/ && bun test --timeout 15000 test/unit/git/",
17
+ "test:db": "./run-db-tests.sh",
18
+ "test:integration": "bun test --timeout 30000 test/integration/scanner.test.ts && bun test --timeout 20000 ./test/integration/app.isolated.tsx",
19
+ "test:all": "bun run test",
20
+ "test:fast": "bun test test/unit/utils/ test/unit/cli/ test/unit/components/ test/unit/config/ test/unit/types/ test/unit/state/ test/unit/operations/ test/unit/github/ test/unit/services/",
21
+ "test:watch": "bun test --watch",
22
+ "test:coverage": "bun test --coverage",
23
+ "test:hooks": "./run-hooks-tests.sh",
24
+ "test:scanner": "bun test --timeout 15000 test/unit/scanner/",
25
+ "test:git": "bun test --timeout 15000 test/unit/git/",
26
+ "typecheck": "tsc --noEmit",
27
+ "lint": "bun run typecheck",
28
+ "db:generate": "drizzle-kit generate",
29
+ "db:migrate": "drizzle-kit migrate"
30
+ },
31
+ "dependencies": {
32
+ "ink": "^5.0.1",
33
+ "@inkjs/ui": "^2.0.0",
34
+ "ink-select-input": "^6.0.0",
35
+ "react": "^18.3.1",
36
+ "zod": "^3.23.8",
37
+ "yaml": "^2.6.1",
38
+ "drizzle-orm": "^0.36.4",
39
+ "chalk": "^5.3.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/bun": "latest",
43
+ "@types/react": "^18.3.12",
44
+ "drizzle-kit": "^0.28.1",
45
+ "ink-testing-library": "^4.0.0"
46
+ },
47
+ "peerDependencies": {
48
+ "typescript": "^5"
49
+ }
50
+ }
package/src/app.tsx ADDED
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+ import { StoreProvider } from "./state/store.tsx";
3
+ import { Layout } from "./components/Layout.tsx";
4
+ import { useUnifiedRepos } from "./hooks/useUnifiedRepos.ts";
5
+ import { useKeyBindings } from "./hooks/useKeyBindings.ts";
6
+ import { useBackgroundFetch } from "./hooks/useBackgroundFetch.ts";
7
+ import type { GitforestConfig, UnifiedRepo } from "./types/index.ts";
8
+
9
+ interface AppContentProps {
10
+ config: GitforestConfig;
11
+ }
12
+
13
+ function AppContent({ config }: AppContentProps) {
14
+ const { loadUnifiedRepos, batchClone } = useUnifiedRepos(config);
15
+
16
+ // Clone handler for Layout
17
+ const handleClone = async (repos: UnifiedRepo[], targetDir: string, useSSH: boolean) => {
18
+ await batchClone(repos, targetDir, useSSH);
19
+ };
20
+
21
+ // Set up keyboard bindings
22
+ useKeyBindings({
23
+ config,
24
+ onRefresh: loadUnifiedRepos,
25
+ });
26
+
27
+ // Set up background fetch
28
+ useBackgroundFetch(config, loadUnifiedRepos);
29
+
30
+ return <Layout config={config} onRefresh={loadUnifiedRepos} onClone={handleClone} />;
31
+ }
32
+
33
+ interface AppProps {
34
+ config: GitforestConfig;
35
+ }
36
+
37
+ export function App({ config }: AppProps) {
38
+ return (
39
+ <StoreProvider>
40
+ <AppContent config={config} />
41
+ </StoreProvider>
42
+ );
43
+ }