Skip to content

Commit 6dcb29d

Browse files
committed
feat: initial release
0 parents  commit 6dcb29d

58 files changed

Lines changed: 4736 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Bug Report
2+
description: Something broke or behaved unexpectedly
3+
labels: [bug]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Before filing — check that you're on the latest version and that `ghscope cache clear` doesn't resolve it.
9+
10+
- type: textarea
11+
id: what-happened
12+
attributes:
13+
label: What happened?
14+
description: A clear description of the bug.
15+
placeholder: "Running `ghscope owner/repo` crashes with..."
16+
validations:
17+
required: true
18+
19+
- type: textarea
20+
id: reproduction
21+
attributes:
22+
label: Steps to reproduce
23+
description: Minimal steps to trigger the issue.
24+
placeholder: |
25+
1. Run `ghscope ...`
26+
2. Press ...
27+
3. See error
28+
validations:
29+
required: true
30+
31+
- type: textarea
32+
id: expected
33+
attributes:
34+
label: Expected behaviour
35+
validations:
36+
required: true
37+
38+
- type: input
39+
id: version
40+
attributes:
41+
label: ghscope version
42+
placeholder: "v0.1.0 or `go version` output if built from source"
43+
validations:
44+
required: true
45+
46+
- type: input
47+
id: os
48+
attributes:
49+
label: OS / terminal
50+
placeholder: "macOS 14.4, iTerm2 / Ubuntu 22.04, tmux"
51+
validations:
52+
required: true
53+
54+
- type: textarea
55+
id: extra
56+
attributes:
57+
label: Anything else?
58+
description: Stack traces, screenshots, relevant config.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Feature Request
2+
description: Suggest a new analysis, UX improvement, or CLI flag
3+
labels: [enhancement]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: What problem does this solve?
9+
description: What are you trying to understand about a repo that ghscope can't tell you today?
10+
validations:
11+
required: true
12+
13+
- type: textarea
14+
id: solution
15+
attributes:
16+
label: What would you like?
17+
description: Describe the feature. If it's a new analysis tab, mention the data source too.
18+
validations:
19+
required: true
20+
21+
- type: textarea
22+
id: alternatives
23+
attributes:
24+
label: Alternatives you considered
25+
description: Other ways to get this data, or why existing tools fall short.
26+
27+
- type: textarea
28+
id: extra
29+
attributes:
30+
label: Anything else?

.github/pull_request_template.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## What
2+
3+
<!-- One paragraph: what does this PR change and why? -->
4+
5+
## Type
6+
7+
- [ ] Bug fix
8+
- [ ] New feature / analysis
9+
- [ ] Refactor / cleanup
10+
- [ ] Docs / tests only
11+
12+
## Checklist
13+
14+
- [ ] `go test ./...` passes
15+
- [ ] `go vet ./...` clean
16+
- [ ] New public functions have at least a one-line comment
17+
- [ ] Cache keys updated if API calls changed
18+
- [ ] No new goroutines without context cancellation

.github/workflows/ci.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Test
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: stable
20+
21+
- name: Cache Go modules
22+
uses: actions/cache@v4
23+
with:
24+
path: ~/go/pkg/mod
25+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
26+
restore-keys: ${{ runner.os }}-go-
27+
28+
- name: Download modules
29+
run: go mod download
30+
31+
- name: Vet
32+
run: go vet ./...
33+
34+
- name: Test
35+
run: go test ./... -count=1 -race -coverprofile=coverage.txt -covermode=atomic
36+
37+
- name: Upload coverage
38+
uses: codecov/codecov-action@v4
39+
with:
40+
files: coverage.txt
41+
fail_ci_if_error: false
42+
43+
build:
44+
name: Build
45+
runs-on: ubuntu-latest
46+
steps:
47+
- uses: actions/checkout@v4
48+
49+
- name: Set up Go
50+
uses: actions/setup-go@v5
51+
with:
52+
go-version: stable
53+
54+
- name: Build
55+
run: go build -o ghscope .

.github/workflows/release.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
goreleaser:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Set up Go
20+
uses: actions/setup-go@v5
21+
with:
22+
go-version: stable
23+
24+
- name: Extract changelog for this release
25+
id: changelog
26+
run: |
27+
# Pull the block between the first two "## [" headings
28+
notes=$(awk '/^## \[/{if(found) exit; found=1; next} found{print}' CHANGELOG.md)
29+
# Write to a file so goreleaser can read it (avoids multiline env var issues)
30+
echo "$notes" > /tmp/release_notes.md
31+
32+
- name: Run GoReleaser
33+
uses: goreleaser/goreleaser-action@v6
34+
with:
35+
distribution: goreleaser
36+
version: latest
37+
args: release --clean --release-notes /tmp/release_notes.md
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# binary
2+
ghscope
3+
ghscope-*
4+
dist/
5+
6+
# build cache
7+
*.test
8+
*.out
9+
coverage.html
10+
coverage.txt
11+
12+
# macOS
13+
.DS_Store
14+
15+
# editor
16+
.idea/
17+
.vscode/
18+
*.swp
19+
*.swo
20+
21+
# demo output
22+
demo/*.gif
23+
demo/*.mp4
24+
25+
# go
26+
vendor/

.goreleaser.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
version: 2
2+
3+
before:
4+
hooks:
5+
- go mod tidy
6+
7+
builds:
8+
- env:
9+
- CGO_ENABLED=0
10+
goos:
11+
- linux
12+
- darwin
13+
- windows
14+
goarch:
15+
- amd64
16+
- arm64
17+
ignore:
18+
- goos: windows
19+
goarch: arm64
20+
ldflags:
21+
- -s -w -X main.version={{.Version}}
22+
binary: ghscope
23+
24+
archives:
25+
- format: tar.gz
26+
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
27+
format_overrides:
28+
- goos: windows
29+
format: zip
30+
files:
31+
- LICENSE
32+
- README.md
33+
34+
checksum:
35+
name_template: "checksums.txt"
36+
37+
snapshot:
38+
version_template: "{{ .Tag }}-next"
39+
40+
changelog:
41+
sort: asc
42+
filters:
43+
exclude:
44+
- "^docs:"
45+
- "^test:"
46+
- "^ci:"
47+
- "^chore:"
48+
- Merge pull request
49+
- Merge branch
50+
51+
brews:
52+
- name: ghscope
53+
repository:
54+
owner: phlx0
55+
name: homebrew-tap
56+
homepage: https://github.com/phlx0/ghscope
57+
description: "Deep terminal analysis for any GitHub repository"
58+
license: MIT
59+
install: |
60+
bin.install "ghscope"
61+
test: |
62+
system "#{bin}/ghscope", "--help"

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Changelog
2+
3+
All notable changes to ghscope are documented here.
4+
5+
## [Unreleased]
6+
7+
## [0.1.0] - 2025-04-05
8+
9+
### Added
10+
- Initial release
11+
- TUI with 9 tabs: Overview, Languages, Contributors, Geography, Activity, Releases, Health, Deps, PRs
12+
- Star geography — country breakdown of stargazers via IP resolution
13+
- Commit heatmap (day × hour) and 52-week sparkline
14+
- Dependency staleness checks across Go, Rust, Node, Python
15+
- PR velocity — merge rate, avg time to merge, open count
16+
- CI/CD signal detection (GitHub Actions, CircleCI, Travis CI)
17+
- Trending signal — rising / stable / declining based on star velocity
18+
- Bus factor and contributor stickiness analysis
19+
- Disk cache at `~/.cache/ghscope/` with per-resource TTLs
20+
- First-run setup wizard with token validation
21+
- `--skip-geo`, `--skip-deps`, `--no-cache` flags
22+
- `ghscope cache clear` subcommand
23+
- `o` to open repo in browser, `?` help overlay, number key tab shortcuts

CONTRIBUTING.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Contributing to ghscope
2+
3+
Thanks for wanting to contribute. Here's what you need to know.
4+
5+
## Getting started
6+
7+
```bash
8+
git clone https://github.com/phlx0/ghscope
9+
cd ghscope
10+
go build . # produces ./ghscope
11+
go test ./... # run tests
12+
```
13+
14+
A `GITHUB_TOKEN` with `public_repo` read scope speeds things up a lot — without it you're rate-limited to 60 req/h. Set it in your shell or run `./ghscope setup` after building.
15+
16+
## Project layout
17+
18+
```
19+
main.go entry point, cobra commands
20+
internal/
21+
api/ thin GitHub API wrappers, each with disk-cache support
22+
analysis/ pure computation on top of the API data
23+
ui/ Bubble Tea model, tab views, setup wizard
24+
cache/ SHA256-keyed JSON file cache (~/.cache/ghscope)
25+
config/ ~/.config/ghscope/config.json
26+
geo/ IP → country resolution for stargazers
27+
```
28+
29+
The layering matters: `api` never imports `analysis`, `analysis` never imports `ui`. Keep it that way.
30+
31+
## Adding a new analysis tab
32+
33+
1. Add an API call in `internal/api/` — always cache the response with a sensible TTL.
34+
2. Compute the stat in `internal/analysis/` — export the type from `types.go`, add the module constant to `ModuleOrder`.
35+
3. Wire the goroutine in `analysis/run.go` — call `done(ModuleXxx, err)` at the end.
36+
4. Add `internal/ui/tab_xxx.go` with a `renderXxx(s *analysis.RepoSummary, w, h int) string` function.
37+
5. Register the tab name in `ui/model.go` and add a `case "Xxx":` in the view switch.
38+
39+
## Style
40+
41+
- No comments except where the *why* isn't obvious from the code
42+
- Unexported helpers are fine; don't export something just because it might be useful later
43+
- Tests live next to the code they test (`foo_test.go` in the same package)
44+
- Commit messages: lowercase imperative, no period — `add trending signal to overview`
45+
46+
## Running the demo locally
47+
48+
Install [VHS](https://github.com/charmbracelet/vhs), then:
49+
50+
```bash
51+
make demo
52+
```
53+
54+
This writes `demo/demo.gif`.
55+
56+
## Pull requests
57+
58+
- Keep PRs focused — one thing at a time
59+
- If you're adding a new API call, note the approximate call cost in the PR description
60+
- Existing tests must pass; new analysis code should have at least one test
61+
62+
## Questions
63+
64+
Open a discussion or an issue — both work.

0 commit comments

Comments
 (0)