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.
- package/.bunignore +7 -0
- package/.github/workflows/ci.yml +73 -0
- package/CLAUDE.md +111 -0
- package/CONTRIBUTING.md +145 -0
- package/README.md +168 -0
- package/bun.lock +267 -0
- package/bunfig.toml +15 -0
- package/cli +0 -0
- package/config/gitforest.example.yaml +94 -0
- package/docs/ai/IMPROVEMENT_PLAN.md +341 -0
- package/docs/ai/VERIFICATION_REPORT.md +87 -0
- package/docs/ai/architecture.md +169 -0
- package/docs/ai/checks/check-2025-12-02-tests.md +40 -0
- package/docs/ai/checks/check-2025-12-02.md +55 -0
- package/docs/ai/checks/test-verification-report.md +85 -0
- package/docs/ai/implementation-guide.md +776 -0
- package/docs/ai/research/gitty-codebase-analysis.md +221 -0
- package/docs/ai/tickets/GENERAL-sitrep.md +30 -0
- package/docs/ai/tickets/TASK-database-tests-sitrep.md +25 -0
- package/docs/ai/tickets/TASK-deprecated-functions-sitrep.md +28 -0
- package/docs/ai/tickets/TASK-detail-modal-sitrep.md +28 -0
- package/docs/ai/tickets/TASK-filter-overlay-sitrep.md +24 -0
- package/docs/ai/tickets/TASK-github-service-sitrep.md +32 -0
- package/docs/ai/tickets/TASK-github-token-sitrep.md +51 -0
- package/docs/ai/tickets/TASK-hascommits-sitrep.md +35 -0
- package/docs/ai/tickets/TASK-keybindings-sitrep.md +26 -0
- package/docs/ai/tickets/TASK-layout-sitrep.md +25 -0
- package/docs/ai/tickets/TASK-markdown-sitrep.md +28 -0
- package/docs/ai/tickets/TASK-project-item-sitrep.md +79 -0
- package/docs/ai/tickets/TASK-sitrep.md +28 -0
- package/docs/ai/tickets/TASK-state-sitrep.md +26 -0
- package/docs/ai/tickets/TASK-types-sitrep.md +25 -0
- package/docs/ai/tickets/TASK-unified-item-fix-sitrep.md +26 -0
- package/docs/ai/tickets/TKT-001-sitrep.md +24 -0
- package/docs/ai/tickets/TKT-002-sitrep.md +25 -0
- package/docs/ai/tickets/TKT-003-git-service-refactoring-complete.md +46 -0
- package/docs/ai/tickets/TKT-003-git-service-refactoring-plan.md +135 -0
- package/docs/ai/tickets/TKT-003-sitrep.md +26 -0
- package/docs/ai/tickets/TKT-004-sitrep.md +27 -0
- package/docs/ai/tickets/TKT-005-sitrep.md +25 -0
- package/docs/ai/tickets/TKT-006-sitrep.md +26 -0
- package/docs/ai/tickets/TKT-007-sitrep.md +30 -0
- package/docs/ai/tickets/TKT-008-sitrep.md +32 -0
- package/docs/ai/tickets/TKT-009-sitrep.md +27 -0
- package/docs/ai/tickets/TKT-010-sitrep.md +27 -0
- package/docs/ai/tickets/TKT-011-sitrep.md +26 -0
- package/docs/ai/tickets/TKT-012-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-actions-sitrep.md +28 -0
- package/docs/ai/tickets/sitreps/TASK-actions-test-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-app-integration-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-background-fetch-sitrep.md +24 -0
- package/docs/ai/tickets/sitreps/TASK-background-fetch-test-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-batch-tests-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-bun-test-sitrep.md +26 -0
- package/docs/ai/tickets/sitreps/TASK-cache-tests-sitrep.md +30 -0
- package/docs/ai/tickets/sitreps/TASK-cli-tests-sitrep.md +28 -0
- package/docs/ai/tickets/sitreps/TASK-clone-error-handling-sitrep.md +26 -0
- package/docs/ai/tickets/sitreps/TASK-commands-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-component-tests-1-sitrep.md +30 -0
- package/docs/ai/tickets/sitreps/TASK-configloader-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-confirm-dialog-test-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-coverage-sitrep.md +95 -0
- package/docs/ai/tickets/sitreps/TASK-database-tests-summary.md +61 -0
- package/docs/ai/tickets/sitreps/TASK-error-boundary-sitrep.md +30 -0
- package/docs/ai/tickets/sitreps/TASK-error-tests-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-errors-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-extract-reducer-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-filter-overlay-test-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-final-verification-sitrep.md +28 -0
- package/docs/ai/tickets/sitreps/TASK-fix-all-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-fix-hooks-sitrep.md +26 -0
- package/docs/ai/tickets/sitreps/TASK-fix-remaining-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-fix-test-failures-sitrep.md +26 -0
- package/docs/ai/tickets/sitreps/TASK-fix-tests-sitrep.md +24 -0
- package/docs/ai/tickets/sitreps/TASK-formatters-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-git-timeouts-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-github-cache-test-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-githubcli-tests-sitrep.md +24 -0
- package/docs/ai/tickets/sitreps/TASK-gitstatus-tests-sitrep.md +24 -0
- package/docs/ai/tickets/sitreps/TASK-hooks-isolation-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-keybindings-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-layout-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-mock-factories-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-modal-tests-sitrep.md +32 -0
- package/docs/ai/tickets/sitreps/TASK-processbatch-fix-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-projectlist-tests-sitrep.md +30 -0
- package/docs/ai/tickets/sitreps/TASK-projectutils-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-scanner-tests-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-select-all-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-shell-error-handling-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-store-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-test-fixes-sitrep.md +26 -0
- package/docs/ai/tickets/sitreps/TASK-test-summary-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-test-verification-sitrep.md +27 -0
- package/docs/ai/tickets/sitreps/TASK-testsuite-sitrep.md +75 -0
- package/docs/ai/tickets/sitreps/TASK-unified-reducer-tests-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-unified-repos-test-sitrep.md +29 -0
- package/docs/ai/tickets/sitreps/TASK-unified-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-useprojects-tests-sitrep.md +25 -0
- package/docs/ai/tickets/sitreps/TASK-utility-tests-sitrep.md +32 -0
- package/docs/ai/tickets/sitreps/TKT-003-git-service-refactoring-sitrep.md +64 -0
- package/docs/ai/tkt-001-fix-database-error.md +217 -0
- package/docs/ai/ui-enhancement-plan.md +562 -0
- package/package.json +50 -0
- package/src/app.tsx +43 -0
- package/src/cli/config.ts +94 -0
- package/src/cli/formatters.ts +632 -0
- package/src/cli/index.ts +583 -0
- package/src/components/CloneDialog.tsx +137 -0
- package/src/components/ColumnHeader.tsx +128 -0
- package/src/components/CommandPalette.tsx +120 -0
- package/src/components/ConfirmDialog.tsx +105 -0
- package/src/components/ErrorBoundary.tsx +128 -0
- package/src/components/FilterBar.tsx +71 -0
- package/src/components/FilterOptionsOverlay.tsx +131 -0
- package/src/components/HelpOverlay.tsx +120 -0
- package/src/components/Layout.tsx +379 -0
- package/src/components/MarkdownRenderer.tsx +127 -0
- package/src/components/ProgressBar.tsx +53 -0
- package/src/components/ProjectItem.tsx +143 -0
- package/src/components/ProjectList.tsx +90 -0
- package/src/components/RepoDetailModal.tsx +367 -0
- package/src/components/StatusBar.tsx +188 -0
- package/src/components/UnifiedProjectItem.tsx +436 -0
- package/src/components/ViewModeIndicator.tsx +37 -0
- package/src/components/onboarding/CompleteStep.tsx +82 -0
- package/src/components/onboarding/DirectoriesStep.test.tsx +52 -0
- package/src/components/onboarding/DirectoriesStep.tsx +847 -0
- package/src/components/onboarding/DirectoriesStep.unit.test.ts +345 -0
- package/src/components/onboarding/GitHubAuthStep.tsx +268 -0
- package/src/components/onboarding/OnboardingWizard.tsx +130 -0
- package/src/components/onboarding/WelcomeStep.tsx +69 -0
- package/src/config/loader.ts +263 -0
- package/src/config/onboarding.ts +67 -0
- package/src/constants.ts +96 -0
- package/src/db/index.ts +147 -0
- package/src/db/schema.ts +70 -0
- package/src/git/commands.ts +283 -0
- package/src/git/index.ts +2 -0
- package/src/git/operations.ts +93 -0
- package/src/git/service.ts +539 -0
- package/src/git/status.ts +84 -0
- package/src/git/types.ts +5 -0
- package/src/github/auth.ts +311 -0
- package/src/github/cache.ts +231 -0
- package/src/github/cli.ts +22 -0
- package/src/github/unified.ts +415 -0
- package/src/hooks/useBackgroundFetch.ts +76 -0
- package/src/hooks/useConfirmDialogActions.ts +120 -0
- package/src/hooks/useKeyBindings.ts +656 -0
- package/src/hooks/useProjects.ts +47 -0
- package/src/hooks/useUnifiedRepos.ts +317 -0
- package/src/index.tsx +494 -0
- package/src/operations/batch.ts +280 -0
- package/src/operations/commands.ts +140 -0
- package/src/operations/index.ts +37 -0
- package/src/scanner/index.ts +424 -0
- package/src/scanner/markers.ts +43 -0
- package/src/scanner/submodules.ts +61 -0
- package/src/services/git.ts +484 -0
- package/src/services/github.ts +676 -0
- package/src/services/index.ts +28 -0
- package/src/services/types.ts +99 -0
- package/src/state/actions.ts +175 -0
- package/src/state/reducer.ts +294 -0
- package/src/state/store.tsx +216 -0
- package/src/state/types.ts +8 -0
- package/src/types/index.ts +383 -0
- package/src/ui/theme.ts +44 -0
- package/src/utils/array.ts +14 -0
- package/src/utils/debug.ts +38 -0
- package/src/utils/errors.ts +17 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/markdown.ts +230 -0
- package/src/utils/project-utils.ts +129 -0
- package/src/utils/rate-limiter.ts +134 -0
- package/src/utils/retry.ts +147 -0
- package/src/utils/timeout.ts +56 -0
- package/test/integration/app.isolated.tsx +240 -0
- package/test/integration/cli-commands.test.ts +287 -0
- package/test/integration/cli-validation.test.ts +264 -0
- package/test/integration/git-operations.test.ts +218 -0
- package/test/integration/scanner.test.ts +228 -0
- package/test/preload.ts +18 -0
- package/test/unit/cli/commands.test.ts +13 -0
- package/test/unit/cli/formatters.test.ts +1116 -0
- package/test/unit/cli/github-commands.test.ts +12 -0
- package/test/unit/components/CloneDialog.test.tsx +240 -0
- package/test/unit/components/ColumnHeader.test.tsx +128 -0
- package/test/unit/components/CommandPalette.test.tsx +355 -0
- package/test/unit/components/ConfirmDialog.test.tsx +111 -0
- package/test/unit/components/ErrorBoundary.test.tsx +139 -0
- package/test/unit/components/FilterBar.test.tsx +43 -0
- package/test/unit/components/FilterOptionsOverlay.test.tsx +197 -0
- package/test/unit/components/HelpOverlay.test.tsx +90 -0
- package/test/unit/components/Layout.test.tsx +328 -0
- package/test/unit/components/MarkdownRenderer.test.tsx +45 -0
- package/test/unit/components/ProgressBar.test.tsx +138 -0
- package/test/unit/components/ProjectItem.test.tsx +182 -0
- package/test/unit/components/ProjectList.test.tsx +311 -0
- package/test/unit/components/RepoDetailModal.test.tsx +445 -0
- package/test/unit/components/StatusBar.test.tsx +112 -0
- package/test/unit/components/UnifiedProjectItem.test.tsx +618 -0
- package/test/unit/components/ViewModeIndicator.test.tsx +137 -0
- package/test/unit/components/test-utils.tsx +63 -0
- package/test/unit/config/loader.test.ts +692 -0
- package/test/unit/db/database.test.ts +978 -0
- package/test/unit/db/index.test.ts +314 -0
- package/test/unit/fixtures/setup.ts +186 -0
- package/test/unit/git/commands-untested.test.ts +205 -0
- package/test/unit/git/commands.test.ts +269 -0
- package/test/unit/git/operations.test.ts +322 -0
- package/test/unit/git/status.test.ts +219 -0
- package/test/unit/github/auth.test.ts +317 -0
- package/test/unit/github/cache.test.ts +1028 -0
- package/test/unit/github/cli.test.ts +135 -0
- package/test/unit/github/unified.test.ts +1201 -0
- package/test/unit/graceful-shutdown.test.ts +83 -0
- package/test/unit/hooks/useBackgroundFetch.test.tsx +239 -0
- package/test/unit/hooks/useConfirmDialogActions.test.tsx +81 -0
- package/test/unit/hooks/useKeyBindings.isolated.ts +715 -0
- package/test/unit/hooks/useProjects.test.tsx +186 -0
- package/test/unit/hooks/useUnifiedRepos-simple.test.tsx +115 -0
- package/test/unit/hooks/useUnifiedRepos.test.tsx +177 -0
- package/test/unit/mocks/config.ts +109 -0
- package/test/unit/mocks/git-service.ts +274 -0
- package/test/unit/mocks/github-service.ts +250 -0
- package/test/unit/mocks/index.ts +72 -0
- package/test/unit/mocks/project.ts +148 -0
- package/test/unit/mocks/state-mocks.ts +187 -0
- package/test/unit/mocks/unified.ts +169 -0
- package/test/unit/operations/batch.test.ts +216 -0
- package/test/unit/operations/commands.test.ts +550 -0
- package/test/unit/scanner/errors.test.ts +297 -0
- package/test/unit/scanner/index.test.ts +1011 -0
- package/test/unit/scanner/markers.test.ts +150 -0
- package/test/unit/scanner/submodules.test.ts +99 -0
- package/test/unit/services/git-errors.test.ts +190 -0
- package/test/unit/services/git.test.ts +442 -0
- package/test/unit/services/github-errors.test.ts +293 -0
- package/test/unit/services/github.test.ts +200 -0
- package/test/unit/state/actions.test.ts +217 -0
- package/test/unit/state/reducer.test.ts +745 -0
- package/test/unit/state/store.test.tsx +711 -0
- package/test/unit/types/commands.test.ts +220 -0
- package/test/unit/types/schema.test.ts +179 -0
- package/test/unit/utils/array.test.ts +73 -0
- package/test/unit/utils/debug.test.ts +23 -0
- package/test/unit/utils/errors.test.ts +295 -0
- package/test/unit/utils/markdown.test.ts +163 -0
- package/test/unit/utils/project-utils.test.ts +756 -0
- package/test/unit/utils/rate-limiter.test.ts +256 -0
- package/test/unit/utils/retry.test.ts +165 -0
- package/test/unit/utils/strip-ansi.ts +13 -0
- package/test/unit/utils/timeout.test.ts +93 -0
- package/tsconfig.json +29 -0
package/.bunignore
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Bun test ignores
|
|
2
|
+
#
|
|
3
|
+
# Files named .test.isolated.ts/.tsx are automatically excluded from test discovery
|
|
4
|
+
# because they don't match the standard pattern (.test.ts, .spec.ts, etc.)
|
|
5
|
+
#
|
|
6
|
+
# No directories need to be excluded - all tests run with `bun test`
|
|
7
|
+
# except 2 isolated files that must run separately (see bunfig.toml)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master, main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master, main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
continue-on-error: true
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout code
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Setup Bun
|
|
20
|
+
uses: oven-sh/setup-bun@v1
|
|
21
|
+
with:
|
|
22
|
+
bun-version: latest
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: bun install
|
|
26
|
+
|
|
27
|
+
- name: Run tests
|
|
28
|
+
run: bun test
|
|
29
|
+
|
|
30
|
+
type-check:
|
|
31
|
+
name: Type Check
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout code
|
|
36
|
+
uses: actions/checkout@v4
|
|
37
|
+
|
|
38
|
+
- name: Setup Bun
|
|
39
|
+
uses: oven-sh/setup-bun@v1
|
|
40
|
+
with:
|
|
41
|
+
bun-version: latest
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: bun install
|
|
45
|
+
|
|
46
|
+
- name: Check TypeScript compilation (non-strict)
|
|
47
|
+
run: bun build src/cli/index.ts 2>&1 | head -5 || true
|
|
48
|
+
|
|
49
|
+
build:
|
|
50
|
+
name: Build
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
needs: [type-check]
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- name: Checkout code
|
|
56
|
+
uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- name: Setup Bun
|
|
59
|
+
uses: oven-sh/setup-bun@v1
|
|
60
|
+
with:
|
|
61
|
+
bun-version: latest
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: bun install
|
|
65
|
+
|
|
66
|
+
- name: Build CLI
|
|
67
|
+
run: bun build src/cli/index.ts --compile --outfile gitforest
|
|
68
|
+
|
|
69
|
+
- name: Upload build artifact
|
|
70
|
+
uses: actions/upload-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: gitforest-cli
|
|
73
|
+
path: gitforest
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Use Bun instead of Node.js, npm, pnpm, or vite.
|
|
3
|
+
globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Default to using Bun instead of Node.js.
|
|
8
|
+
|
|
9
|
+
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
|
|
10
|
+
- Use `bun test` instead of `jest` or `vitest`
|
|
11
|
+
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
|
|
12
|
+
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
|
|
13
|
+
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
|
|
14
|
+
- Bun automatically loads .env, so don't use dotenv.
|
|
15
|
+
|
|
16
|
+
## APIs
|
|
17
|
+
|
|
18
|
+
- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
|
|
19
|
+
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
|
|
20
|
+
- `Bun.redis` for Redis. Don't use `ioredis`.
|
|
21
|
+
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
|
|
22
|
+
- `WebSocket` is built-in. Don't use `ws`.
|
|
23
|
+
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
|
|
24
|
+
- Bun.$`ls` instead of execa.
|
|
25
|
+
|
|
26
|
+
## Testing
|
|
27
|
+
|
|
28
|
+
Use `bun test` to run tests.
|
|
29
|
+
|
|
30
|
+
```ts#index.test.ts
|
|
31
|
+
import { test, expect } from "bun:test";
|
|
32
|
+
|
|
33
|
+
test("hello world", () => {
|
|
34
|
+
expect(1).toBe(1);
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Frontend
|
|
39
|
+
|
|
40
|
+
Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
|
|
41
|
+
|
|
42
|
+
Server:
|
|
43
|
+
|
|
44
|
+
```ts#index.ts
|
|
45
|
+
import index from "./index.html"
|
|
46
|
+
|
|
47
|
+
Bun.serve({
|
|
48
|
+
routes: {
|
|
49
|
+
"/": index,
|
|
50
|
+
"/api/users/:id": {
|
|
51
|
+
GET: (req) => {
|
|
52
|
+
return new Response(JSON.stringify({ id: req.params.id }));
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
// optional websocket support
|
|
57
|
+
websocket: {
|
|
58
|
+
open: (ws) => {
|
|
59
|
+
ws.send("Hello, world!");
|
|
60
|
+
},
|
|
61
|
+
message: (ws, message) => {
|
|
62
|
+
ws.send(message);
|
|
63
|
+
},
|
|
64
|
+
close: (ws) => {
|
|
65
|
+
// handle close
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
development: {
|
|
69
|
+
hmr: true,
|
|
70
|
+
console: true,
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
|
|
76
|
+
|
|
77
|
+
```html#index.html
|
|
78
|
+
<html>
|
|
79
|
+
<body>
|
|
80
|
+
<h1>Hello, world!</h1>
|
|
81
|
+
<script type="module" src="./frontend.tsx"></script>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
With the following `frontend.tsx`:
|
|
87
|
+
|
|
88
|
+
```tsx#frontend.tsx
|
|
89
|
+
import React from "react";
|
|
90
|
+
|
|
91
|
+
// import .css files directly and it works
|
|
92
|
+
import './index.css';
|
|
93
|
+
|
|
94
|
+
import { createRoot } from "react-dom/client";
|
|
95
|
+
|
|
96
|
+
const root = createRoot(document.body);
|
|
97
|
+
|
|
98
|
+
export default function Frontend() {
|
|
99
|
+
return <h1>Hello, world!</h1>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
root.render(<Frontend />);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then, run index.ts
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
bun --hot ./index.ts
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Contributing to Gitforest
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to Gitforest! This document provides guidelines and instructions for contributing.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- [Bun](https://bun.sh/) runtime (v1.0 or later)
|
|
10
|
+
- [gh CLI](https://cli.github.com/) for GitHub operations (optional)
|
|
11
|
+
- Git
|
|
12
|
+
|
|
13
|
+
### Getting Started
|
|
14
|
+
|
|
15
|
+
1. Clone the repository:
|
|
16
|
+
```bash
|
|
17
|
+
git clone https://github.com/yourusername/gitforest.git
|
|
18
|
+
cd gitforest
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
2. Install dependencies:
|
|
22
|
+
```bash
|
|
23
|
+
bun install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Create a config file:
|
|
27
|
+
```bash
|
|
28
|
+
bun run start --init
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
4. Run tests to verify setup:
|
|
32
|
+
```bash
|
|
33
|
+
bun test
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
5. Start development:
|
|
37
|
+
```bash
|
|
38
|
+
bun run dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Project Structure
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
gitforest/
|
|
45
|
+
├── src/
|
|
46
|
+
│ ├── cli/ # Command-line interface
|
|
47
|
+
│ ├── components/ # React/Ink UI components
|
|
48
|
+
│ ├── config/ # Configuration loading
|
|
49
|
+
│ ├── db/ # SQLite database (Drizzle ORM)
|
|
50
|
+
│ ├── git/ # Git operations
|
|
51
|
+
│ ├── github/ # GitHub API integration
|
|
52
|
+
│ ├── hooks/ # React hooks
|
|
53
|
+
│ ├── operations/ # Batch operations
|
|
54
|
+
│ ├── scanner/ # Directory scanning
|
|
55
|
+
│ ├── services/ # Service abstractions
|
|
56
|
+
│ ├── state/ # State management
|
|
57
|
+
│ ├── types/ # TypeScript types
|
|
58
|
+
│ └── utils/ # Utility functions
|
|
59
|
+
├── test/ # Test files
|
|
60
|
+
├── docs/ # Documentation
|
|
61
|
+
└── config/ # Example configurations
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Development Guidelines
|
|
65
|
+
|
|
66
|
+
### Code Style
|
|
67
|
+
|
|
68
|
+
- Use TypeScript strict mode
|
|
69
|
+
- Follow existing code patterns
|
|
70
|
+
- Add JSDoc comments to public APIs
|
|
71
|
+
- Use meaningful variable and function names
|
|
72
|
+
|
|
73
|
+
### Testing
|
|
74
|
+
|
|
75
|
+
- Write tests for new features
|
|
76
|
+
- Ensure all tests pass before submitting PR
|
|
77
|
+
- Use mocks for external services (git, GitHub API)
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Run all tests
|
|
81
|
+
bun test
|
|
82
|
+
|
|
83
|
+
# Run tests with coverage
|
|
84
|
+
bun test --coverage
|
|
85
|
+
|
|
86
|
+
# Run specific test file
|
|
87
|
+
bun test test/path/to/file.test.ts
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Type Checking
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
bun run typecheck
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Commits
|
|
97
|
+
|
|
98
|
+
- Use clear, descriptive commit messages
|
|
99
|
+
- Reference issue numbers when applicable
|
|
100
|
+
- Keep commits focused and atomic
|
|
101
|
+
|
|
102
|
+
## Pull Request Process
|
|
103
|
+
|
|
104
|
+
1. Fork the repository
|
|
105
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
106
|
+
3. Make your changes
|
|
107
|
+
4. Run tests and type checking
|
|
108
|
+
5. Commit your changes
|
|
109
|
+
6. Push to your fork
|
|
110
|
+
7. Open a Pull Request
|
|
111
|
+
|
|
112
|
+
### PR Checklist
|
|
113
|
+
|
|
114
|
+
- [ ] Tests pass (`bun test`)
|
|
115
|
+
- [ ] Type checking passes (`bun run typecheck`)
|
|
116
|
+
- [ ] Code follows project style
|
|
117
|
+
- [ ] Documentation updated if needed
|
|
118
|
+
- [ ] Commit messages are clear
|
|
119
|
+
|
|
120
|
+
## Reporting Issues
|
|
121
|
+
|
|
122
|
+
When reporting issues, please include:
|
|
123
|
+
|
|
124
|
+
- Gitforest version
|
|
125
|
+
- Bun version (`bun --version`)
|
|
126
|
+
- Operating system
|
|
127
|
+
- Steps to reproduce
|
|
128
|
+
- Expected vs actual behavior
|
|
129
|
+
- Relevant error messages
|
|
130
|
+
|
|
131
|
+
## Feature Requests
|
|
132
|
+
|
|
133
|
+
Feature requests are welcome! Please:
|
|
134
|
+
|
|
135
|
+
- Check existing issues first
|
|
136
|
+
- Describe the use case
|
|
137
|
+
- Explain why it would be useful
|
|
138
|
+
|
|
139
|
+
## Questions?
|
|
140
|
+
|
|
141
|
+
Feel free to open an issue for questions or discussions.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
By contributing, you agree that your contributions will be licensed under the project's license.
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Gitforest
|
|
2
|
+
|
|
3
|
+
A terminal UI for managing multiple Git repositories and GitHub integration.
|
|
4
|
+
|
|
5
|
+
Built with Bun, TypeScript, Ink (React for CLI), and Drizzle ORM.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Project Discovery**: Scan configured directories for git repos, non-git projects, and submodules
|
|
10
|
+
- **Git Status Dashboard**: See unstaged changes, unpushed/unpulled commits, sync status
|
|
11
|
+
- **Sort & Filter**: Sort by name, status, or last activity; filter by text search
|
|
12
|
+
- **Git Operations**: Init git, pull, push, fetch for single or all repos
|
|
13
|
+
- **GitHub Integration**: Create private repos, archive repos (via `gh` CLI)
|
|
14
|
+
- **Background Sync**: Auto-fetch remotes every 5 minutes
|
|
15
|
+
- **Caching**: SQLite cache for fast subsequent runs
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# From the gitforest directory
|
|
21
|
+
bun install
|
|
22
|
+
|
|
23
|
+
# Create config file
|
|
24
|
+
bun run start --init
|
|
25
|
+
|
|
26
|
+
# Edit config to add your project directories
|
|
27
|
+
vim ~/.config/gitforest/config.yaml
|
|
28
|
+
|
|
29
|
+
# Run gitforest
|
|
30
|
+
bun run start
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Configuration
|
|
34
|
+
|
|
35
|
+
Config file location: `~/.config/gitforest/config.yaml`
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
directories:
|
|
39
|
+
- path: ~/projects
|
|
40
|
+
maxDepth: 2
|
|
41
|
+
label: Projects
|
|
42
|
+
- path: ~/.dotfiles
|
|
43
|
+
maxDepth: 3
|
|
44
|
+
label: Dotfiles
|
|
45
|
+
|
|
46
|
+
scan:
|
|
47
|
+
ignore:
|
|
48
|
+
- node_modules
|
|
49
|
+
- .git
|
|
50
|
+
- vendor
|
|
51
|
+
includeHidden: false
|
|
52
|
+
concurrency: 5
|
|
53
|
+
|
|
54
|
+
github:
|
|
55
|
+
defaultVisibility: private
|
|
56
|
+
|
|
57
|
+
display:
|
|
58
|
+
showSubmodules: true
|
|
59
|
+
sortBy: status # name | status | lastActivity
|
|
60
|
+
sortDirection: desc
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Keyboard Shortcuts
|
|
64
|
+
|
|
65
|
+
### Navigation
|
|
66
|
+
|
|
67
|
+
| Key | Action |
|
|
68
|
+
| --------- | ------------ |
|
|
69
|
+
| `j` / `↓` | Move down |
|
|
70
|
+
| `k` / `↑` | Move up |
|
|
71
|
+
| `g` | Go to top |
|
|
72
|
+
| `G` | Go to bottom |
|
|
73
|
+
|
|
74
|
+
### Selection
|
|
75
|
+
|
|
76
|
+
| Key | Action |
|
|
77
|
+
| ------- | ------------------------- |
|
|
78
|
+
| `space` | Toggle selection |
|
|
79
|
+
| `a` | Select all / deselect all |
|
|
80
|
+
|
|
81
|
+
### Git Operations
|
|
82
|
+
|
|
83
|
+
| Key | Action |
|
|
84
|
+
| --- | ------------------------------------- |
|
|
85
|
+
| `p` | Push selected repos |
|
|
86
|
+
| `P` | Pull all repos |
|
|
87
|
+
| `f` | Fetch all remotes |
|
|
88
|
+
| `i` | Init git in selected non-git projects |
|
|
89
|
+
|
|
90
|
+
### GitHub Operations
|
|
91
|
+
|
|
92
|
+
| Key | Action |
|
|
93
|
+
| --- | ------------------------------- |
|
|
94
|
+
| `c` | Create GitHub repo for selected |
|
|
95
|
+
| `A` | Archive GitHub repo |
|
|
96
|
+
|
|
97
|
+
### View Controls
|
|
98
|
+
|
|
99
|
+
| Key | Action |
|
|
100
|
+
| --- | -------------------- |
|
|
101
|
+
| `/` | Enter filter mode |
|
|
102
|
+
| `s` | Cycle sort field |
|
|
103
|
+
| `r` | Refresh project list |
|
|
104
|
+
| `?` | Show help |
|
|
105
|
+
| `q` | Quit |
|
|
106
|
+
|
|
107
|
+
## Status Icons
|
|
108
|
+
|
|
109
|
+
| Icon | Meaning |
|
|
110
|
+
| ---- | --------------------------- |
|
|
111
|
+
| ✓ | Clean (no changes) |
|
|
112
|
+
| ● | Dirty (uncommitted changes) |
|
|
113
|
+
| ○ | Submodule |
|
|
114
|
+
| - | Not a git repo |
|
|
115
|
+
| ↑N | N unpushed commits |
|
|
116
|
+
| ↓N | N unpulled commits |
|
|
117
|
+
|
|
118
|
+
## Project Detection
|
|
119
|
+
|
|
120
|
+
Gitforest detects projects by looking for:
|
|
121
|
+
|
|
122
|
+
- `.git` directory (git repository)
|
|
123
|
+
- `.gitmodules` file (for submodules)
|
|
124
|
+
- Project marker files:
|
|
125
|
+
- `package.json` (Node.js)
|
|
126
|
+
- `Cargo.toml` (Rust)
|
|
127
|
+
- `pyproject.toml` / `setup.py` (Python)
|
|
128
|
+
- `go.mod` (Go)
|
|
129
|
+
- `Gemfile` (Ruby)
|
|
130
|
+
- `pom.xml` / `build.gradle` (Java)
|
|
131
|
+
- And more...
|
|
132
|
+
|
|
133
|
+
## Requirements
|
|
134
|
+
|
|
135
|
+
- [Bun](https://bun.sh/) runtime
|
|
136
|
+
- [gh CLI](https://cli.github.com/) for GitHub operations (optional but recommended)
|
|
137
|
+
|
|
138
|
+
## Development
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Run in development mode with hot reload
|
|
142
|
+
bun run dev
|
|
143
|
+
|
|
144
|
+
# Run tests (recommended - handles test isolation)
|
|
145
|
+
bun run test
|
|
146
|
+
|
|
147
|
+
# Or run specific test groups
|
|
148
|
+
bun run test:unit # Unit tests only
|
|
149
|
+
bun run test:hooks # Hooks tests (isolated)
|
|
150
|
+
bun run test:db # Database tests (isolated)
|
|
151
|
+
bun run test:integration # Integration tests
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Architecture
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
src/
|
|
158
|
+
├── app.tsx # Root Ink application
|
|
159
|
+
├── config/ # Config loading & validation (Zod)
|
|
160
|
+
├── db/ # Drizzle + SQLite cache
|
|
161
|
+
├── git/ # Git operations (Bun.$)
|
|
162
|
+
├── github/ # GitHub CLI wrapper
|
|
163
|
+
├── scanner/ # Directory scanning
|
|
164
|
+
├── components/ # Ink UI components
|
|
165
|
+
├── hooks/ # React hooks
|
|
166
|
+
├── state/ # State management
|
|
167
|
+
└── types/ # TypeScript types
|
|
168
|
+
```
|