Repository: dlvhdr/gh-dash Branch: main Commit: 129bf09618cb Files: 294 Total size: 3.9 MB Directory structure: gitextract_yckel_xs/ ├── .envrc ├── .gh-dash.yml ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ ├── pull_request_template.md │ └── workflows/ │ ├── build-and-test.yaml │ ├── build-docs.yaml │ ├── dependabot-sync.yml │ ├── go-release.yml │ ├── lint.yml │ └── publish-docs.yaml ├── .gitignore ├── .golangci.yml ├── .goreleaser.yaml ├── AI_POLICY.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── Taskfile.yaml ├── cmd/ │ ├── root.go │ └── sponsors.go ├── devbox.json ├── docs/ │ ├── .dockerignore │ ├── .envrc │ ├── .eslint.config.js │ ├── .gitignore │ ├── .prettierrc.mjs │ ├── Dockerfile │ ├── README.mdx │ ├── astro.config.mjs │ ├── devbox.json │ ├── package.json │ ├── public/ │ │ ├── custom-commands.webm │ │ ├── enhance-demo.webm │ │ ├── overview.webm │ │ ├── rerun.webm │ │ ├── sections.webm │ │ └── watch.webm │ ├── src/ │ │ ├── assets/ │ │ │ ├── custom-commands.tape │ │ │ ├── custom-commands.yml │ │ │ ├── demo.yml │ │ │ ├── overview.tape │ │ │ ├── sections.tape │ │ │ ├── sections.yml │ │ │ ├── theme-catpuccin.yml │ │ │ ├── theme-gruvbox.yml │ │ │ └── theme-tokyonight.yml │ │ ├── components/ │ │ │ ├── Box.astro │ │ │ ├── DashHeroLogo.astro │ │ │ ├── DecorationBottom.astro │ │ │ ├── DecorationSeparator.astro │ │ │ ├── DecorationTop.astro │ │ │ ├── DiffnavCard.astro │ │ │ ├── DiffnavMiniLogo.astro │ │ │ ├── Discord.astro │ │ │ ├── EnhanceCard.astro │ │ │ ├── EnhanceLogo.astro │ │ │ ├── EnhanceMiniLogo.astro │ │ │ ├── EnhanceOneLineLogo.astro │ │ │ ├── FadeImages.astro │ │ │ ├── FeatureCard.astro │ │ │ ├── FeatureSponsorshipGoal.astro │ │ │ ├── Footer.astro │ │ │ ├── Header.astro │ │ │ ├── Hero.astro │ │ │ ├── Logo.astro │ │ │ ├── NerdFontIcon.astro │ │ │ ├── PillLink.astro │ │ │ ├── ReleaseVersionButton.astro │ │ │ ├── Showcase.astro │ │ │ ├── Sponsorship.astro │ │ │ ├── SponsorshipGoal.astro │ │ │ ├── StargazersCount.astro │ │ │ ├── StargazersFallback.astro │ │ │ ├── SupportSection.astro │ │ │ ├── Terminal.astro │ │ │ └── ThemeSelect.astro │ │ ├── content/ │ │ │ └── docs/ │ │ │ ├── companions/ │ │ │ │ ├── enhance/ │ │ │ │ │ ├── dash-integration.mdx │ │ │ │ │ ├── getting-started.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── keybindings.mdx │ │ │ │ │ ├── theme.mdx │ │ │ │ │ └── usage.mdx │ │ │ │ └── index.mdx │ │ │ ├── configuration/ │ │ │ │ ├── defaults.mdx │ │ │ │ ├── examples.mdx │ │ │ │ ├── index.mdx │ │ │ │ ├── issue-section.mdx │ │ │ │ ├── keybindings/ │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── issues.mdx │ │ │ │ │ └── prs.mdx │ │ │ │ ├── layout/ │ │ │ │ │ ├── issue.mdx │ │ │ │ │ ├── options.mdx │ │ │ │ │ └── pr.mdx │ │ │ │ ├── notification-section.mdx │ │ │ │ ├── pr-section.mdx │ │ │ │ ├── repo-paths.mdx │ │ │ │ ├── reusing.mdx │ │ │ │ ├── schema.mdx │ │ │ │ ├── searching.mdx │ │ │ │ └── theme.mdx │ │ │ ├── contributing/ │ │ │ │ └── index.mdx │ │ │ ├── donating/ │ │ │ │ └── index.mdx │ │ │ ├── getting-started/ │ │ │ │ ├── index.mdx │ │ │ │ ├── keybindings/ │ │ │ │ │ ├── global.mdx │ │ │ │ │ ├── index.mdx │ │ │ │ │ ├── navigation.mdx │ │ │ │ │ ├── preview.mdx │ │ │ │ │ ├── selected-issue.mdx │ │ │ │ │ ├── selected-item.mdx │ │ │ │ │ ├── selected-notification.mdx │ │ │ │ │ └── selected-pr.mdx │ │ │ │ ├── updating.mdx │ │ │ │ └── usage.mdx │ │ │ └── insiders/ │ │ │ └── index.mdx │ │ ├── content.config.ts │ │ ├── data/ │ │ │ ├── latestVersion.ts │ │ │ ├── schemas/ │ │ │ │ ├── defaults.yaml │ │ │ │ ├── definitions/ │ │ │ │ │ ├── grow.yaml │ │ │ │ │ └── hexcolor.yaml │ │ │ │ ├── gh-dash.yaml │ │ │ │ ├── issue-section.yaml │ │ │ │ ├── keybindings/ │ │ │ │ │ ├── entry.yaml │ │ │ │ │ ├── issues.yaml │ │ │ │ │ └── prs.yaml │ │ │ │ ├── layout/ │ │ │ │ │ ├── issue.yaml │ │ │ │ │ ├── options.yaml │ │ │ │ │ └── pr.yaml │ │ │ │ ├── pr-section.yaml │ │ │ │ └── theme.yaml │ │ │ ├── sponsorshipGoal.ts │ │ │ └── stars.ts │ │ ├── fonts/ │ │ │ ├── CommitMono-400-Regular.otf │ │ │ ├── CommitMonoNerdFontMono-Regular.otf │ │ │ └── font-face.css │ │ ├── pages/ │ │ │ ├── enhance.astro │ │ │ ├── index.astro │ │ │ ├── robots.txt.ts │ │ │ ├── schema/ │ │ │ │ ├── defaults.json.ts │ │ │ │ ├── definitions/ │ │ │ │ │ ├── grow.json.ts │ │ │ │ │ └── hexcolor.json.ts │ │ │ │ ├── issue-section.json.ts │ │ │ │ ├── keybindings/ │ │ │ │ │ ├── entry.json.ts │ │ │ │ │ ├── issues.json.ts │ │ │ │ │ └── prs.json.ts │ │ │ │ ├── layout/ │ │ │ │ │ ├── issue.json.ts │ │ │ │ │ ├── options.json.ts │ │ │ │ │ └── pr.json.ts │ │ │ │ ├── pr-section.json.ts │ │ │ │ └── theme.json.ts │ │ │ └── schema.json.ts │ │ └── styles/ │ │ ├── custom.css │ │ ├── fade-images.css │ │ ├── index.css │ │ ├── nerd-font.css │ │ └── terminal.css │ └── tsconfig.json ├── gh-dash.go ├── go.mod ├── go.sum ├── internal/ │ ├── config/ │ │ ├── feature_flags.go │ │ ├── parser.go │ │ ├── parser_test.go │ │ ├── testdata/ │ │ │ ├── .gh-dash.yml │ │ │ ├── ansi-color-config.yml │ │ │ ├── gh-dash/ │ │ │ │ └── config.yml │ │ │ ├── global-config.golden.yml │ │ │ ├── merged-config.golden.yml │ │ │ ├── other-test-config.yml │ │ │ └── test-config.yml │ │ └── utils.go │ ├── data/ │ │ ├── assignee.go │ │ ├── bookmarks.go │ │ ├── bookmarks_test.go │ │ ├── cache.go │ │ ├── commonapi.go │ │ ├── donestore.go │ │ ├── donestore_test.go │ │ ├── donestore_testing.go │ │ ├── issueapi.go │ │ ├── labelapi.go │ │ ├── notificationapi.go │ │ ├── notificationapi_test.go │ │ ├── prapi.go │ │ ├── prapi_test.go │ │ ├── repository.go │ │ ├── user.go │ │ └── utils.go │ ├── git/ │ │ └── git.go │ ├── tui/ │ │ ├── common/ │ │ │ ├── diff.go │ │ │ ├── diff_test.go │ │ │ ├── labels.go │ │ │ ├── labels_test.go │ │ │ ├── repopath.go │ │ │ ├── repopath_test.go │ │ │ └── styles.go │ │ ├── components/ │ │ │ ├── autocomplete/ │ │ │ │ └── autocomplete.go │ │ │ ├── branch/ │ │ │ │ ├── branch.go │ │ │ │ ├── data.go │ │ │ │ ├── data_test.go │ │ │ │ └── utils.go │ │ │ ├── branchsidebar/ │ │ │ │ ├── branchsidebar.go │ │ │ │ └── branchsidebar_test.go │ │ │ ├── carousel/ │ │ │ │ └── carousel.go │ │ │ ├── common/ │ │ │ │ └── interface.go │ │ │ ├── footer/ │ │ │ │ └── footer.go │ │ │ ├── inputbox/ │ │ │ │ └── inputbox.go │ │ │ ├── issuerow/ │ │ │ │ └── issuerow.go │ │ │ ├── issuessection/ │ │ │ │ ├── constants.go │ │ │ │ └── issuessection.go │ │ │ ├── issueview/ │ │ │ │ ├── action.go │ │ │ │ ├── action_test.go │ │ │ │ ├── activity.go │ │ │ │ ├── issueview.go │ │ │ │ └── labels.go │ │ │ ├── listviewport/ │ │ │ │ └── listviewport.go │ │ │ ├── notificationrow/ │ │ │ │ ├── data.go │ │ │ │ ├── data_test.go │ │ │ │ ├── notificationrow.go │ │ │ │ └── notificationrow_test.go │ │ │ ├── notificationssection/ │ │ │ │ ├── DESIGN.md │ │ │ │ ├── commands.go │ │ │ │ ├── commands_test.go │ │ │ │ ├── filters_test.go │ │ │ │ └── notificationssection.go │ │ │ ├── notificationview/ │ │ │ │ ├── notificationview.go │ │ │ │ └── notificationview_test.go │ │ │ ├── prompt/ │ │ │ │ └── prompt.go │ │ │ ├── prrow/ │ │ │ │ ├── data.go │ │ │ │ ├── prrow.go │ │ │ │ └── prrow_test.go │ │ │ ├── prssection/ │ │ │ │ ├── checkout.go │ │ │ │ ├── diff.go │ │ │ │ ├── prssection.go │ │ │ │ ├── prssection_test.go │ │ │ │ └── watchChecks.go │ │ │ ├── prview/ │ │ │ │ ├── action.go │ │ │ │ ├── action_test.go │ │ │ │ ├── activity.go │ │ │ │ ├── checks.go │ │ │ │ ├── checks_test.go │ │ │ │ ├── commits.go │ │ │ │ ├── files.go │ │ │ │ ├── prview.go │ │ │ │ └── reviewers_test.go │ │ │ ├── reposection/ │ │ │ │ ├── commands.go │ │ │ │ └── reposection.go │ │ │ ├── search/ │ │ │ │ └── search.go │ │ │ ├── section/ │ │ │ │ ├── section.go │ │ │ │ └── section_test.go │ │ │ ├── sidebar/ │ │ │ │ └── sidebar.go │ │ │ ├── table/ │ │ │ │ └── table.go │ │ │ ├── tabs/ │ │ │ │ ├── tabs.go │ │ │ │ ├── tabs_test.go │ │ │ │ └── testdata/ │ │ │ │ ├── TestTabs/ │ │ │ │ │ ├── Should_allow_setting_new_tabs.golden │ │ │ │ │ ├── Should_display_loading_tabs.golden │ │ │ │ │ ├── Should_display_tab_counts.golden │ │ │ │ │ └── Should_show_overflow_symbol.golden │ │ │ │ └── test_section.go │ │ │ ├── tasks/ │ │ │ │ ├── issue.go │ │ │ │ ├── issue_test.go │ │ │ │ ├── pr.go │ │ │ │ └── pr_test.go │ │ │ └── utils.go │ │ ├── constants/ │ │ │ ├── constants.go │ │ │ ├── errMsg.go │ │ │ ├── initMsg.go │ │ │ └── progressMsg.go │ │ ├── context/ │ │ │ ├── context.go │ │ │ └── styles.go │ │ ├── keys/ │ │ │ ├── branchKeys.go │ │ │ ├── issueKeys.go │ │ │ ├── keys.go │ │ │ ├── keys_test.go │ │ │ ├── notificationKeys.go │ │ │ └── prKeys.go │ │ ├── markdown/ │ │ │ ├── markdownRenderer.go │ │ │ └── theme.go │ │ ├── modelUtils.go │ │ ├── tasks.go │ │ ├── testdata/ │ │ │ ├── searchIssues.json │ │ │ └── searchPullRequests.json │ │ ├── testutils/ │ │ │ └── utils.go │ │ ├── theme/ │ │ │ ├── theme.go │ │ │ └── theme_test.go │ │ ├── ui.go │ │ └── ui_test.go │ └── utils/ │ ├── templateHandler.go │ ├── utils.go │ └── utils_test.go └── testdata/ ├── api.github.com.graphql-schema.json ├── gh-dash/ │ └── config.yml └── graphql.http ================================================ FILE CONTENTS ================================================ ================================================ FILE: .envrc ================================================ #!/bin/bash # Automatically sets up your devbox environment whenever you cd into this # directory via our direnv integration: eval "$(devbox generate direnv --print-envrc)" # check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/ # for more details ================================================ FILE: .gh-dash.yml ================================================ # yaml-language-server: $schema=https://gh-dash.dev/schema.json prSections: - title: Mine filters: is:open author:@me repo:dlvhdr/gh-dash updated:>={{ nowModify "-3w" }} sort:updated-desc layout: author: hidden: true repoName: hidden: true - title: Review filters: repo:dlvhdr/gh-dash -author:@me is:open updated:>={{ nowModify "-2.5w" }} layout: repoName: hidden: true - title: All filters: repo:dlvhdr/gh-dash issuesSections: - title: Open filters: repo:dlvhdr/gh-dash is:open sort:reactions - title: Bugs filters: repo:dlvhdr/gh-dash is:open sort:reactions label:bug - title: Features filters: repo:dlvhdr/gh-dash is:open sort:reactions label:feat - title: High filters: repo:dlvhdr/gh-dash is:open sort:reactions label:high-pri - title: Mid filters: repo:dlvhdr/gh-dash is:open sort:reactions label:mid-pri - title: Low filters: repo:dlvhdr/gh-dash is:open sort:reactions label:low-pri - title: Unlabeled filters: repo:dlvhdr/gh-dash is:open sort:reactions -label:bug -label:feat - title: All filters: repo:dlvhdr/gh-dash sort:reactions defaults: view: prs refetchIntervalMinutes: 5 layout: prs: repoName: hidden: true base: hidden: true preview: open: true prsLimit: 20 issuesLimit: 20 ================================================ FILE: .github/FUNDING.yml ================================================ github: [dlvhdr] ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: "[BUG]" labels: bug assignees: "" --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Mac] - Terminal Emulator - Using tmux? ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/pull_request_template.md ================================================ # Summary - [] Closes issue #... - [] I have read the [CONTIBUTING.md](../CONTRIBUTING.md) and [AI_POLICY.md](../AI_POLICY.md) guides ## How Did You Test this Change? ## Images/Videos ================================================ FILE: .github/workflows/build-and-test.yaml ================================================ name: build and test on: pull_request: paths-ignore: - "docs/**" permissions: contents: read jobs: build-and-test: name: Build and test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v5 - name: Install Go uses: actions/setup-go@v6 with: go-version-file: ./go.mod - name: Download Go modules run: go mod download - name: Build run: go build ./... - name: Test run: go test ./... dependabot: needs: [build-and-test] runs-on: ubuntu-latest permissions: pull-requests: write contents: write if: ${{ github.actor == 'dependabot[bot]' && github.event_name == 'pull_request'}} steps: - id: metadata uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - run: | gh pr review --approve "$PR_URL" gh pr merge --squash --auto "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/build-docs.yaml ================================================ name: Build Docs on: pull_request: paths: - "docs/**" workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Checkout your repository using git uses: actions/checkout@v6 - name: Install, build, and upload your site output uses: withastro/action@v5 with: path: ./docs ================================================ FILE: .github/workflows/dependabot-sync.yml ================================================ name: dependabot-sync on: schedule: - cron: "0 0 * * 0" # every Sunday at midnight workflow_dispatch: # allows manual triggering permissions: contents: write pull-requests: write jobs: dependabot-sync: uses: charmbracelet/meta/.github/workflows/dependabot-sync.yml@main with: repo_name: ${{ github.event.repository.name }} secrets: gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} ================================================ FILE: .github/workflows/go-release.yml ================================================ name: goreleaser on: push: tags: - "*" permissions: contents: write jobs: goreleaser: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version: ">=1.21.0" cache: true - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 with: distribution: goreleaser version: "~> v2" args: release --clean --draft env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DISCORD_WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }} DISCORD_WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }} BLUESKY_APP_PASSWORD: ${{ secrets.BLUESKY_APP_PASSWORD }} ================================================ FILE: .github/workflows/lint.yml ================================================ name: lint on: pull_request: permissions: contents: read jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: stable - name: golangci-lint uses: golangci/golangci-lint-action@v9 ================================================ FILE: .github/workflows/publish-docs.yaml ================================================ name: Build and Push Docs Docker image on: push: branches: ["main"] paths: - "docs/**" jobs: build-and-push-dockerfile-image: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 - name: Log in to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: "{{defaultContext}}:docs" secrets: | gh_token=${{ secrets.GH_TOKEN }} file: ./Dockerfile push: ${{ github.event_name == 'push' }} # Make sure to replace with your own namespace and repository tags: | dlvhdr/gh-dash-docs:latest platforms: linux/amd64 ================================================ FILE: .gitignore ================================================ debug.log dist gh-prs /gh-dash .direnv/ /result* .DS_Store .killgrave.log docs/broken-links.log .devbox __debug* testdata/gh-schema.graphql ================================================ FILE: .golangci.yml ================================================ version: "2" linters: enable: - bodyclose # - exhaustive # - goconst # - godot # - godox # - gomoddirectives - goprintffuncname # - gosec - misspell # - nakedret # - nestif # - nilerr # - noctx - nolintlint # - prealloc # - revive - rowserrcheck - sqlclosecheck - staticcheck - tparallel # - unconvert # - unparam - whitespace # - wrapcheck disable: - errcheck - ineffassign - unused exclusions: generated: lax presets: - common-false-positives rules: - text: '(slog|log)\.\w+' linters: - noctx issues: max-issues-per-linter: 0 max-same-issues: 0 formatters: enable: - gofumpt - goimports - golines settings: golines: chain-split-dots: true exclusions: generated: lax ================================================ FILE: .goreleaser.yaml ================================================ version: 2 before: hooks: - go mod tidy gomod: proxy: true env: - GOPROXY=https://proxy.golang.org,direct - GOSUMDB=sum.golang.org - GOPRIVATE=github.com/dlvhdr/gh-dash mod: mod builds: - env: - CGO_ENABLED=0 flags: - -tags=nodbus goos: - android - freebsd - linux - windows - darwin goarch: - amd64 - arm64 - arm - "386" goarm: - "7" ldflags: - -s -w - -X github.com/dlvhdr/gh-dash/cmd.Version={{.Version}} - -X github.com/dlvhdr/gh-dash/cmd.Commit={{.Commit}} - -X github.com/dlvhdr/gh-dash/cmd.Date={{.CommitDate}} - -X github.com/dlvhdr/gh-dash/cmd.BuiltBy=goreleaser # Skipping builds for Android non-ARM64 architectures as they need CGO enabled # https://goreleaser.com/limitations/cgo/ ignore: - goos: android goarch: amd64 - goos: android goarch: arm - goos: android goarch: "386" - goos: windows goarch: arm archives: - formats: - binary name_template: "gh-dash_{{ .Tag }}_{{ .Os }}-{{ .Arch }}{{if .Arm}}_{{.Arm}}{{end}}" checksum: name_template: "checksums.txt" snapshot: version_template: "{{ incpatch .Version }}-next" release: header: | # {{ .Version }} To update run: ```bash gh extension upgrade dash ``` footer: | --- If you enjoy `dash`, consider [making a donation](https://www.gh-dash.dev/donating) ❤️ Have questions? Join our [Discord community](https://discord.gg/SXNXp9NctV)!
DASH Logo announce: bluesky: enabled: true username: "dlvhdr.me" # message_template: (Default) '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'. discord: enabled: true color: "8037112" icon_url: "https://www.gh-dash.dev/favicon.png" # message_template: (Default) '{{ .ProjectName }} {{ .Tag }} is out! Check it out at {{ .ReleaseURL }}'. changelog: sort: asc use: github filters: exclude: - "^test:" - "^chore" - "merge conflict" - Merge pull request - Merge remote-tracking branch - Merge branch - go mod tidy groups: - title: Dependency updates regexp: "^.*\\(deps\\)*:+.*$" order: 300 - title: "New Features" regexp: "^.*feat[(\\w)]*:+.*$" order: 100 - title: "Bug fixes" regexp: "^.*fix[(\\w)]*:+.*$" order: 200 - title: "Documentation updates" regexp: "^.*docs[(\\w)]*:+.*$" order: 400 - title: Other work order: 9999 ================================================ FILE: AI_POLICY.md ================================================ # AI Usage Policy This project has strict rules for AI usage: - **All AI usage in any form must be disclosed.** You must state the tool you used (e.g. Claude Code, Cursor, Amp) along with the extent that the work was AI-assisted. - **The human-in-the-loop must fully understand all code.** If you can't explain what your changes do and how they interact with the greater system without the aid of AI tools, do not contribute to this project. - **Issues and discussions can use AI assistance but must have a full human-in-the-loop.** This means that any content generated with AI must have been reviewed _and edited_ by a human before submission. AI is excellent at being overly verbose and including noise that distracts from the main point. Humans must do their research and trim this down. - **No AI-generated media is allowed (art, images, videos, audio, etc.).** Text and code are the only acceptable AI-generated content, per the other rules in this policy. These rules apply only to outside contributions. Maintainers are exempt from these rules and may use AI tools at their discretion; they've proven themselves trustworthy to apply good judgment. ## There Are Humans Here Please remember that this project is maintained by humans. Every discussion, issue, and pull request is read and reviewed by humans (and sometimes machines, too). It is a boundary point at which people interact with each other and the work done. It is rude and disrespectful to approach this boundary with low-effort, unqualified work, since it puts the burden of validation on the maintainer. In a perfect world, AI would produce high-quality, accurate work every time. But today, that reality depends on the driver of the AI. And today, most drivers of AI are just not good enough. So, until either the people get better, the AI gets better, or both, we have to have strict rules to protect maintainers. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing To `gh-dash` Thank you for investing your time in contributing to our project! In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR. ## The Critical Rule - The most important rule: you must understand your code. If you can't explain what your changes do and how they interact with the greater system without the aid of AI tools, do not contribute to this project. - The second most important rule: when you submit a PR you must be willing to address comments and maintain this code. Dot not submit drive-by PRs that solve your own issue without the willingness to iterate on it. Keep these in your own fork. - Using AI to write code is fine. You can gain understanding by interrogating an agent with access to the codebase until you grasp all edge cases and effects of your changes. What's not fine is submitting agent-generated slop without that understanding. Be sure to read the [AI Usage Policy](AI_POLICY.md). ## AI Usage The project has strict rules for AI usage. Please see the [AI Usage Policy](AI_POLICY.md). This is very important. ## Quick Guide ### I Have an Idea for a Feature Like bug reports, first search through both issues and discussions and try to find if your feature has already been requested. Otherwise, open a discussion in the ["Feature Requests, Ideas"](https://github.com/dlvhdr/gh-dash/issues/new?template=feature_request.md) category. ### I've Implemented a Feature - If there is an issue for the feature, open a pull request straight away. - If there is no issue, open a discussion and link to your branch. - If you want to live dangerously, open a pull request and hope for the best. ### I Have a Question Which Is Neither a Bug Report nor a Feature Request Open a [Q&A discussion](https://github.com/dlvhdr/gh-dash/discussions/categories/q-a), or join our [Discord Server](https://discord.gg/SXNXp9NctV) and ask away in the #help forum channel. ## Working on the Code ### Installing Required Tooling Our project uses [Devbox](https://github.com/jetpack-io/devbox) to manage its development environment. Using Devbox will get your dev environment up and running easily and make sure we're all using the same tools with the same versions. - Clone this repo ```sh git clone git@github.com:dlvhdr/gh-dash.git && cd gh-dash ``` - Install `devbox` ```sh curl -fsSL https://get.jetpack.io/devbox | bash ``` - Start the `devbox` shell and run the setup (will take a while on first time) ```sh devbox shell ``` _This will create a shell where all required tools are installed._ - _(Optional)_ Set up `direnv` so `devbox shell` runs automatically - [direnv](https://www.jetify.com/devbox/docs/ide_configuration/direnv/) is a tool that allows setting unique environment variables per directory in your filesystem. - Install `direnv` with: `brew install direnv` - Add the following line at the end of the `~/.bashrc` file: `eval "$(direnv hook bash)"` - See [direnv's installation instructions](https://direnv.net/docs/hook.html) for other shells. - Enable `direnv` by running `direnv allow` - _(Optional)_ Install the VSCode Extension - Follow [this guide](https://www.jetify.com/devbox/docs/ide_configuration/vscode/) to set up VSCode to automatically run `devbox shell`. #### Troubleshooting - delete the `.devbox` directory at the project's root ### Navigating the Codebase To navigate our codebase with confidence, familiarize yourself with: - [Bubbletea](https://github.com/charmbracelet/bubbletea) - the TUI framework we're using - [The Elm architecture](https://guide.elm-lang.org/architecture/) - [charmbracelet/glow](https://github.com/charmbracelet/glow) - for parsing and presenting Markdown #### Code Structure - `ui/` - this is the code that's responsible for rendering the different parts of the TUI - `data/` - the code that fetches data from GitHub's GraphQL API - `config/` - code to parse the user's `config.yml` file - `utils/` - various utilities ### Debugging - Write to the log by using Charm's `log` package - Tail the log by running `task logs` - Run `dash` in debug mode with `task debug` in another terminal window / pane ```go import "charm.land/log/v2" // more code... log.Debug("some message", "someVariable", someVariable) ``` ### Running the Docs Locally - Run the docs site by running `task docs` * Go to `localhost:4321` to view them ================================================ FILE: LICENSE.txt ================================================ MIT License Copyright (c) 2025 Dolev Hadar Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================

Text changing depending on mode. Light: 'So light!' Dark: 'So dark!'

→ https://gh-dash.dev ←

A rich terminal UI for GitHub that doesn't break your flow.

Latest Release Discord


## 🌟 Features > [!NOTE] > If you like quickly navigating with your keyboard, seeing the PRs and issues you need and you love the terminal - DASH is for you! 🫵🏽 - User-defined, per-repo, PRs & issues sections - Overridable vim-style keyboard hotkeys - Custom actions to perform your specific workflow needs - Everything you can do on GitHub - diff, comment, checkout, push, update etc. - Control every setting with a YAML config file ## 📃 Docs `DASH` has an extensive docs site at [gh-dash.dev/getting-started](https://gh-dash.dev/getting-started). ## ❤️ Donating If you enjoy `DASH` and want to help, consider supporting the project with a donation at the [sponsors page](https://github.com/sponsors/dlvhdr). ## 👥 Discord Have questions? Join our [Discord community](https://discord.gg/SXNXp9NctV)! ## 🙏 Contributing See the contribution guide at [https://www.gh-dash.dev/contributing](https://www.gh-dash.dev/contributing/). ## 🛞 Under the hood `DASH` uses: - [bubbletea](https://github.com/charmbracelet/bubbletea) for the TUI - [lipgloss](https://github.com/charmbracelet/lipgloss) for the styling - [glamour](https://github.com/charmbracelet/glamour) for rendering markdown - [vhs](https://github.com/charmbracelet/vhs) for generating the GIF - [cobra](https://github.com/spf13/cobra) for the CLI - [gh](https://github.com/cli/cli) for the GitHub functionality - [delta](https://github.com/dandavison/delta) for viewing PR diffs ## Author Dolev Hadar [@dlvhdr](https://github.com/dlvhdr). ================================================ FILE: Taskfile.yaml ================================================ # https://taskfile.dev version: "3" silent: true tasks: default: cmds: - go run . {{.CLI_ARGS}} interactive: true desc: Run build: - go build . uninstall: cmds: - gh ext remove dash install: cmds: - task: build - task: uninstall - echo "🕐 Installing local build..." && gh ext install . - gh dash --version install:prod: cmds: - task: uninstall - echo "🕐 Installing latest version..." && gh ext install dlvhdr/gh-dash - gh dash --version debug: cmds: - printf "~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n―――――――――――――――――――――――――――――――――――――――――――――――\n" > ./debug.log - DEBUG=true go run . --debug {{.CLI_ARGS}} interactive: true desc: Run in debug mode. Run `task logs` to watch the logs. debug:warn: cmds: - printf "~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n~\n―――――――――――――――――――――――――――――――――――――――――――――――\n" > ./debug.log - LOG_LEVEL=warn DEBUG=true go run . --debug {{.CLI_ARGS}} interactive: true desc: Run in debug mode, only log warning. Run `task logs` to watch the logs. dlv: cmds: - dlv debug --headless --api-version=2 --listen=127.0.0.1:43000 . desc: Debug with dlv logs: cmds: - rm -f ./debug.log - touch ./debug.log - tail -f ./debug.log interactive: true desc: Tail the debug logs lint: desc: Run base linters cmds: - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m env: GOEXPERIMENT: null lint:fix: desc: Run base linters and fix issues cmds: - golangci-lint run --path-mode=abs --config=".golangci.yml" --timeout=5m --fix env: GOEXPERIMENT: null test:one: cmds: - gotip desc: Run a test test:rerun: cmds: - gotip --rerun desc: Rerun the last test test: cmds: - prism test {{.CLI_ARGS}} ./... desc: Run tests fmt: desc: Run gofumpt cmds: - gofumpt -w $(git ls-files '*.go') check-nerd-font: cmds: - nerdfix check $(fd --extension go) desc: Find broken nerdfont characters fix-nerd-font: cmds: - nerdfix fix --format=json $(fd --extension go) desc: Fix broken nerdfont icons docs-prepare: cmds: - cd docs && pnpm i docs: cmds: - cd docs && pnpm dev desc: Start docs server docs-build: cmds: - task: docs-prepare - cd docs && pnpm build desc: Run docs production build docs-preview: cmds: - task: docs-build - cd docs && pnpm preview desc: Preview docs production build ================================================ FILE: cmd/root.go ================================================ /* Copyright © 2022 NAME HERE */ package cmd import ( "context" "fmt" slog "log" "os" "runtime" "runtime/debug" "runtime/pprof" "time" tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" "charm.land/log/v2" "github.com/charmbracelet/fang" zone "github.com/lrstanley/bubblezone/v2" "github.com/spf13/cobra" "github.com/dlvhdr/gh-dash/v4/internal/config" "github.com/dlvhdr/gh-dash/v4/internal/git" "github.com/dlvhdr/gh-dash/v4/internal/tui" "github.com/dlvhdr/gh-dash/v4/internal/tui/constants" dctx "github.com/dlvhdr/gh-dash/v4/internal/tui/context" ) var ( Version = "dev" Commit = "" Date = "" BuiltBy = "" ) var ( cfgFlag string logo = lipgloss.NewStyle().Foreground(dctx.LogoColor).MarginBottom(1).SetString(constants.Logo) rootCmd = &cobra.Command{ Use: "gh dash", Long: lipgloss.JoinVertical(lipgloss.Left, logo.Render(), "A rich terminal UI for GitHub that doesn't break your flow.", "Visit https://gh-dash.dev for the docs."), Short: "A rich terminal UI for GitHub that doesn't break your flow.", Version: "", Example: ` # Running without arguments will either: # - Use the global configuration file # - Use a local .gh-dash.yml file if in a git repo gh dash # Run with a specific configuration file gh dash --config /path/to/configuration/file.yml # Run with debug logging to debug.log gh dash --debug # Print version gh dash -v `, Args: cobra.MaximumNArgs(1), } ) func Execute() { if err := fang.Execute( context.Background(), rootCmd, fang.WithVersion(rootCmd.Version), fang.WithoutCompletions(), fang.WithoutManpage(), ); err != nil { os.Exit(1) } } func setDebugLogLevel() { switch os.Getenv("LOG_LEVEL") { case "debug", "": log.SetLevel(log.DebugLevel) case "info": log.SetLevel(log.InfoLevel) case "warn": log.SetLevel(log.WarnLevel) case "error": log.SetLevel(log.ErrorLevel) } } func createModel(location config.Location, debug bool) (tui.Model, *os.File) { var loggerFile *os.File if debug { var fileErr error loggerFile, fileErr = os.OpenFile("debug.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666) if fileErr == nil { log.SetOutput(loggerFile) log.SetTimeFormat(time.Kitchen) log.SetReportCaller(true) setDebugLogLevel() log.Info("Logging to debug.log") if location.RepoPath != "" { log.Info("Running in repo", "repo", location.RepoPath) } } else { loggerFile, _ = tea.LogToFile("debug.log", "debug") slog.Print("Failed setting up logging", fileErr) } } else { log.SetOutput(os.Stderr) log.SetLevel(log.FatalLevel) } return tui.NewModel(location), loggerFile } func buildVersion(version, commit, date, builtBy string) string { result := version if commit != "" { result = fmt.Sprintf("%s\ncommit: %s", result, commit) } if date != "" { result = fmt.Sprintf("%s\nbuilt at: %s", result, date) } if builtBy != "" { result = fmt.Sprintf("%s\nbuilt by: %s", result, builtBy) } result = fmt.Sprintf("%s\ngoos: %s\ngoarch: %s", result, runtime.GOOS, runtime.GOARCH) if info, ok := debug.ReadBuildInfo(); ok && info.Main.Sum != "" { result = fmt.Sprintf( "%s\nmodule version: %s, checksum: %s", result, info.Main.Version, info.Main.Sum, ) } return result } func init() { rootCmd.PersistentFlags().StringVarP( &cfgFlag, "config", "c", "", `use this configuration file (default lookup: 1. a .gh-dash.yml file if inside a git repo 2. $GH_DASH_CONFIG env var 3. $XDG_CONFIG_HOME/gh-dash/config.yml )`, ) err := rootCmd.MarkPersistentFlagFilename("config", "yaml", "yml") if err != nil { log.Fatal("Cannot mark config flag as filename", err) } rootCmd.Version = buildVersion(Version, Commit, Date, BuiltBy) rootCmd.SetVersionTemplate(`gh-dash {{printf "version %s\n" .Version}}`) rootCmd.Flags().Bool( "debug", false, "passing this flag will allow writing debug output to debug.log", ) rootCmd.Flags().String( "cpuprofile", "", "write cpu profile to file", ) rootCmd.Flags().BoolP( "help", "h", false, "help for gh-dash", ) rootCmd.Run = func(_ *cobra.Command, args []string) { var repo string repos := config.IsFeatureEnabled(config.FF_REPO_VIEW) if repos && len(args) > 0 { repo = args[0] } if repo == "" { r, err := git.GetRepoInPwd() if err == nil && r != nil { repo = r.Path() } } debug, err := rootCmd.Flags().GetBool("debug") if err != nil { log.Fatal("Cannot parse debug flag", err) } zone.NewGlobal() model, logger := createModel(config.Location{RepoPath: repo, ConfigFlag: cfgFlag}, debug) if logger != nil { defer logger.Close() } cpuprofile, err := rootCmd.Flags().GetString("cpuprofile") if err != nil { log.Fatal("Cannot parse cpuprofile flag", err) } if cpuprofile != "" { f, err := os.Create(cpuprofile) if err != nil { log.Fatal(err) } _ = pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } p := tea.NewProgram(model) if _, err := p.Run(); err != nil { log.Fatal("Failed starting the TUI", err) } } } ================================================ FILE: cmd/sponsors.go ================================================ /* Copyright © 2025 NAME HERE */ package cmd import ( "fmt" "charm.land/lipgloss/v2" "charm.land/log/v2" "github.com/spf13/cobra" "github.com/dlvhdr/gh-dash/v4/internal/data" ) // sponsorsCmd represents the sponsors command var sponsorsCmd = &cobra.Command{ Use: "sponsors", Short: "Show the list of current sponsors for gh-dash", Long: `Show the list of current sponsors for gh-dash from GitHub Sponsors under https://github.com/sponsors/dlvhdr. If you enjoy dash and want to help, consider supporting the project with a donation!`, RunE: func(cmd *cobra.Command, args []string) error { log.SetLevel(log.ErrorLevel) sponsors, err := data.FetchSponsors() if err != nil { return err } fmt.Print("\n") fmt.Print( lipgloss.JoinHorizontal( lipgloss.Top, lipgloss.NewStyle(). Foreground(lipgloss.Color("1")). Bold(true). Render("Thank you ❤️ "), lipgloss.NewStyle().Foreground(lipgloss.Color("255")).Render( "to all the current (and past!) sponsors - you rock! 🤘🏽"), )) fmt.Print("\n") fmt.Print("To help this project with a donation go to https://github.com/sponsors/dlvhdr\n") fmt.Print("\n") for _, sponsor := range sponsors.User.Sponsors.Nodes { if sponsor.Typename == "User" { fmt.Printf(" • %s (%s)\n", lipgloss.NewStyle().Bold(true).Render( fmt.Sprintf("@%s", sponsor.User.Login)), sponsor.User.Url) } else { fmt.Printf(" • %s (%s)\n", lipgloss.NewStyle().Bold(true).Render( sponsor.Organization.Name), sponsor.Organization.Url) } } return nil }, } func init() { rootCmd.AddCommand(sponsorsCmd) } ================================================ FILE: devbox.json ================================================ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json", "env": { "GOPATH": "$PWD/.devbox/go", "GOBIN": "$PWD/.devbox/go/bin", "PATH": "$PATH:$PWD/.devbox/go/bin" }, "packages": { "git": "latest", "gh": "latest", "go": "1.23", "golangci-lint": "2.10.1", "gofumpt": "0.8.0", "go-task": "3.44.1", "nerdfix": "0.4.2", "fd": "10.2.0" }, "shell": { "init_hook": [ "echo \"Creating devbox shell...\"", "[[ $(command -v prism) != \"$GOBIN/prism\" ]] && go install go.dalton.dog/prism@latest", "[[ $(command -v gotip) != \"$GOBIN/gotip\" ]] && go install github.com/lusingander/gotip/cmd/gotip@latest" ] } } ================================================ FILE: docs/.dockerignore ================================================ .DS_Store node_modules dist ================================================ FILE: docs/.envrc ================================================ #!/bin/bash # Automatically sets up your devbox environment whenever you cd into this # directory via our direnv integration: eval "$(devbox generate direnv --print-envrc)" # check out https://www.jetify.com/docs/devbox/ide_configuration/direnv/ # for more details ================================================ FILE: docs/.eslint.config.js ================================================ import eslintPluginAstro from "eslint-plugin-astro"; export default [ js.configs.recommended, ...eslintPluginAstro.configs.recommended, ]; ================================================ FILE: docs/.gitignore ================================================ # build output dist/ # generated types .astro/ # dependencies node_modules/ # logs npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* # environment variables .env .env.production # macOS-specific files .DS_Store ================================================ FILE: docs/.prettierrc.mjs ================================================ // .prettierrc.mjs /** @type {import("prettier").Config} */ export default { plugins: ["prettier-plugin-astro", "prettier-plugin-tailwindcss"], overrides: [ { files: "*.astro", options: { parser: "astro", }, }, ], }; ================================================ FILE: docs/Dockerfile ================================================ FROM node:20-slim AS base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable COPY . /app WORKDIR /app FROM base AS prod-deps RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile FROM base AS build RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile RUN --mount=type=secret,id=gh_token,env=GH_TOKEN pnpm run build FROM base COPY --from=prod-deps /app/node_modules /app/node_modules COPY --from=build /app/dist /app/dist ENV HOST=0.0.0.0 ENV PORT=4321 EXPOSE 4321 CMD node ./dist/server/entry.mjs ================================================ FILE: docs/README.mdx ================================================ # Docs Site [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) Live at [https://gh-dash.dev](https://gh-dash.dev). ## 🚀 Project Structure In this project you'll see the following folders and files: ``` . ├── public/ ├── src/ │ ├── assets/ │ ├── content/ │ │ └── docs/ │ └── content.config.ts ├── astro.config.mjs ├── package.json └── tsconfig.json ``` Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. Images can be added to `src/assets/` and embedded in Markdown with a relative link. Static assets, like favicons, can be placed in the `public/` directory. ## 🧞 Commands All commands are run from the root of the project, from a terminal: | Command | Action | | :--------------------- | :----------------------------------------------- | | `pnpm install` | Installs dependencies | | `pnpm dev` | Starts local dev server at `localhost:4321` | | `pnpm build` | Build your production site to `./dist/` | | `pnpm preview` | Preview your build locally, before deploying | | `pnpm astro ...` | Run CLI commands like `astro add`, `astro check` | | `pnpm astro -- --help` | Get help using the Astro CLI | ================================================ FILE: docs/astro.config.mjs ================================================ // @ts-check import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; import tailwindcss from "@tailwindcss/vite"; import astroBrokenLinksChecker from "astro-broken-links-checker"; import node from "@astrojs/node"; const ogUrl = new URL("og.png", "https://gh-dash.dev/").href; const ogImageAlt = "DASH Through Your GitHub"; // https://astro.build/config export default defineConfig({ site: "https://gh-dash.dev", integrations: [ astroBrokenLinksChecker({ logFilePath: "broken-links.log", checkExternalLinks: false, }), starlight({ title: "DASH", favicon: "/favicon.png", customCss: ["./src/styles/custom.css", "./src/fonts/font-face.css"], head: [ { tag: "meta", attrs: { property: "og:image", content: ogUrl }, }, { tag: "meta", attrs: { property: "og:image:alt", content: ogImageAlt }, }, { tag: "meta", attrs: { name: "description", content: "DASH - a rich terminal UI for GitHub that doesn't break your flow", }, }, ], components: { Header: "./src/components/Header.astro", }, social: [ { icon: "github", label: "GitHub", href: "https://github.com/dlvhdr/gh-dash", }, ], sidebar: [ { label: "Getting Started", items: [ "getting-started", "getting-started/usage", "getting-started/updating", ], }, { label: "Keybindings", collapsed: true, autogenerate: { directory: "getting-started/keybindings" }, }, { label: "Configuration", collapsed: true, items: [ "configuration", "configuration/schema", "configuration/defaults", "configuration/searching", "configuration/pr-section", "configuration/issue-section", "configuration/notification-section", "configuration/repo-paths", "configuration/keybindings", "configuration/theme", "configuration/reusing", "configuration/examples", { label: "Layout", items: [ "configuration/layout/options", "configuration/layout/pr", "configuration/layout/issue", ], }, ], }, { label: "Companion Apps", items: [ { label: "ENHANCE", collapsed: true, items: [ "companions/enhance/getting-started", "companions/enhance/usage", "companions/enhance/keybindings", "companions/enhance/dash-integration", "companions/enhance/theme", ], }, ], }, { label: "Insiders 🌟", items: ["insiders"], }, { slug: "contributing" }, { slug: "donating" }, ], }), ], vite: { plugins: [tailwindcss()], }, adapter: node({ mode: "standalone", }), }); ================================================ FILE: docs/devbox.json ================================================ { "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.16.0/.schema/devbox.schema.json", "env": { "DEVBOX_COREPACK_ENABLED": "true" }, "packages": { "nodejs": "22.14.0" }, "shell": { "init_hook": ["echo \"Creating devbox shell for docs site...\""] } } ================================================ FILE: docs/package.json ================================================ { "name": "docs", "type": "module", "version": "0.0.1", "scripts": { "dev": "astro dev", "start": "astro dev", "build": "astro build", "preview": "astro preview", "astro": "astro" }, "dependencies": { "@astrojs/node": "^9.4.3", "@astrojs/starlight": "^0.35.2", "@astrojs/starlight-tailwind": "^4.0.1", "@tailwindcss/vite": "^4.1.12", "astro": "^5.6.1", "astro-broken-links-checker": "github:imazen/astro-broken-link-checker", "sharp": "^0.34.2", "tailwindcss": "^4.1.12" }, "devDependencies": { "@typescript-eslint/parser": "^8.41.0", "eslint": "^9.34.0", "eslint-plugin-astro": "^1.3.1", "eslint-plugin-jsx-a11y": "^6.10.2", "prettier": "^3.6.2", "prettier-plugin-astro": "^0.14.1", "prettier-plugin-tailwindcss": "^0.6.14" }, "packageManager": "pnpm@10.14.0" } ================================================ FILE: docs/src/assets/custom-commands.tape ================================================ Output custom-commands.webm Output custom-commands.mp4 Output custom-commands.gif Set Theme TokyoNight Set Padding 0 Set FontSize 24 Set FontFamily "CommitMono Nerd Font" Set Width 1400 Set Height 600 Hide Type "gh dash --config custom-commands.yml" Enter Sleep 8s Show Sleep 1000ms Type "g" Sleep 1000ms Type@200ms "jjjjjjjjjj" Sleep 1000ms Type "q" ================================================ FILE: docs/src/assets/custom-commands.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:dlvhdr - title: Needs My Review filters: review-requested:@me owner:dlvhdr issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim defaults: preview: open: false width: 40 prsLimit: 20 issuesLimit: 20 view: repo keybindings: universal: - key: g name: lazygit command: > cd {{.RepoPath}} && lazygit - key: C name: code review command: > tmux new-window -c {{.RepoPath}} ' nvim -c ":silent Octo pr edit {{.PrNumber}}" ' repoPaths: dlvhdr/*: ~/code/personal/* pager: diff: diffnav theme: colors: text: primary: "#E2E1ED" secondary: "#666CA6" inverted: "#242347" faint: "#b0b3bf" warning: "#F23D5C" success: "#3DF294" background: selected: "#1b1b33" border: primary: "#383B5B" secondary: "#39386B" faint: "#2B2B40" smartFilteringAtLaunch: false ================================================ FILE: docs/src/assets/demo.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:charmbracelet - title: Review Requested filters: review-requested:@me owner:charmbraclet - title: My Team filters: is:open owner:neovim author:gpanders author:tjdevries - title: Open Source filters: is:open repo:ghostty-org/ghostty repo:neovim/neovim issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim - title: Bubbletea filters: repo:charmbracelet/bubbletea defaults: preview: open: true width: 40 prsLimit: 20 issuesLimit: 20 view: repo keybindings: prs: [] repoPaths: {} pager: diff: diffnav theme: colors: text: primary: "#E2E1ED" secondary: "#666CA6" inverted: "#242347" faint: "#b0b3bf" warning: "#F23D5C" success: "#3DF294" background: selected: "#1b1b33" border: primary: "#383B5B" secondary: "#39386B" faint: "#2B2B40" smartFilteringAtLaunch: false ================================================ FILE: docs/src/assets/overview.tape ================================================ Output overview.webm Output overview.mp4 Output overview.gif Set PlaybackSpeed 1.3 Set Theme TokyoNight Set Padding 0 Set FontSize 24 Set FontFamily "CommitMono Nerd Font" Set Width 1600 Set Height 800 Hide Type "gh dash --config demo.yml" Enter Sleep 8s Show Set TypingSpeed 600ms Sleep 500ms Type "j" Type "j" Type "]" Type "]" Type "?" Sleep 1s Type "?" Hide Type "d" Sleep 1s Type "jjjjjjjjj" Show Ctrl+D Sleep 500ms Ctrl+D Sleep 500ms Ctrl+D Sleep 300ms Type j Sleep 200ms Type j Sleep 200ms Type "q" Sleep 500ms Type "c" Type@60ms "Looks good to me! 🚀" Sleep 500ms Hide Ctrl+c Type y Sleep 500ms Show Hide Sleep 2s Show Sleep 500ms Type "l" Type "l" Type "l" Sleep 500ms Type "s" Hide Sleep 7s Type "j" Sleep 100ms Show Sleep 1500ms ================================================ FILE: docs/src/assets/sections.tape ================================================ Output sections.webm Output sections.mp4 Output sections.gif Set Theme TokyoNight Set Padding 0 Set FontSize 24 Set FontFamily "CommitMono Nerd Font" Set Width 1200 Set Height 600 Hide Type "gh dash --config sections.yml" Enter Sleep 8s Show Sleep 1500ms Type "l" Sleep 1000ms Hide Type "s" Sleep 8s Type "l" Type "h" Show Sleep 1500ms Type "l" Sleep 1000ms ================================================ FILE: docs/src/assets/sections.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:dlvhdr - title: Needs My Review filters: review-requested:@me owner:dlvhdr issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim defaults: preview: open: false width: 40 prsLimit: 20 issuesLimit: 20 view: repo keybindings: prs: [] repoPaths: {} pager: diff: diffnav theme: colors: text: primary: "#E2E1ED" secondary: "#666CA6" inverted: "#242347" faint: "#b0b3bf" warning: "#F23D5C" success: "#3DF294" background: selected: "#1b1b33" border: primary: "#383B5B" secondary: "#39386B" faint: "#2B2B40" smartFilteringAtLaunch: false ================================================ FILE: docs/src/assets/theme-catpuccin.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:dlvhdr - title: Needs My Review filters: review-requested:@me owner:dlvhdr issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim defaults: preview: open: true width: 50 prsLimit: 20 issuesLimit: 20 view: repo keybindings: prs: [] repoPaths: {} pager: diff: diffnav theme: colors: text: primary: "#89b4fa" secondary: "#b4befe" inverted: "#181825" faint: "#7f849c" warning: "#f9e2af" success: "#a6e3a1" background: selected: "#313244" border: primary: "#9399b2" secondary: "#585b70" faint: "#313244" smartFilteringAtLaunch: false ================================================ FILE: docs/src/assets/theme-gruvbox.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:dlvhdr - title: Needs My Review filters: review-requested:@me owner:dlvhdr issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim defaults: preview: open: true width: 50 prsLimit: 20 issuesLimit: 20 view: repo keybindings: prs: [] repoPaths: {} pager: diff: diffnav theme: colors: text: primary: "#fe8019" secondary: "#d65d0e" inverted: "#3c3836" faint: "#d5c4a1" warning: "#fabd2f" success: "#98971a" background: selected: "#282828" border: primary: "#665c54" secondary: "#3c3836" faint: "#1d2021" smartFilteringAtLaunch: false ================================================ FILE: docs/src/assets/theme-tokyonight.yml ================================================ prSections: - title: My Pull Requests filters: is:open author:@me owner:dlvhdr - title: Needs My Review filters: review-requested:@me owner:dlvhdr issuesSections: - title: Ghostty filters: is:open ghostty-org/ghostty - title: Neovim filters: is:open neovim/neovim defaults: preview: open: true width: 50 prsLimit: 20 issuesLimit: 20 view: repo keybindings: prs: [] repoPaths: {} pager: diff: diffnav theme: colors: text: primary: "#E2E1ED" secondary: "#666CA6" inverted: "#242347" faint: "#b0b3bf" warning: "#F23D5C" success: "#3DF294" background: selected: "#1b1b33" border: primary: "#383B5B" secondary: "#39386B" faint: "#2B2B40" smartFilteringAtLaunch: false ================================================ FILE: docs/src/components/Box.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; const { header, icon } = Astro.props; ---

{header}

================================================ FILE: docs/src/components/DashHeroLogo.astro ================================================ --- import Logo from "./Logo.astro"; --- ================================================ FILE: docs/src/components/DecorationBottom.astro ================================================ --- ---
 ────────────────·.   .·──────────────── 
(                  \_/                  )
 ‾                                     ‾ 
================================================ FILE: docs/src/components/DecorationSeparator.astro ================================================ --- ---
  {"<~-----------------◇-----------------~>"}
================================================ FILE: docs/src/components/DecorationTop.astro ================================================ --- ---
 _                  _                  _ 
(                  / \                  )
 ────────────────·´   `·──────────────── 
================================================ FILE: docs/src/components/DiffnavCard.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; import DiffnavMiniLogo from "./DiffnavMiniLogo.astro"; ---
================================================ FILE: docs/src/components/DiffnavMiniLogo.astro ================================================ --- const { class: className } = Astro.props; ---
▜▔▚ ▌▐▔▔▐▔▔▐▚ ▌▐▔▌▐ ▞
▟▁▞ ▌▐▔ ▐▔ ▐ ▚▌▐▔▌▐▞ 

A git diff pager based on delta but with a file tree, à la GitHub.

================================================ FILE: docs/src/components/Discord.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; const { class: className } = Astro.props; ---

Join Our Discord Community

If you want to keep up with the TUIs I'm developing or just want to nerd out about the terminal -
come join us!

================================================ FILE: docs/src/components/EnhanceCard.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; import EnhanceMiniLogo from "./EnhanceMiniLogo.astro"; ---
================================================ FILE: docs/src/components/EnhanceLogo.astro ================================================ --- const { className } = Astro.props; ---
      _.-·--._      
    .´        `.    
   ╱            \   
  ¡             ▕   
  |        ╱╱   ;|  
  :        ╱╱   ;;  
  :╲          .´/   
   \`-.__..·-´.'    
    `╱╱╱___.-´      
    ╱╱╱             
   ╱╱╱              
  ╱╱╱               
 (_╱                
▐▔▔▐▚ ▌▐ ▌▐▔▌▐▚ ▌▐▔▔▐▔▔
▐▛▁▐ ▚▌▐▔▌▐▔▌▐ ▚▌▐▁▁▐▛▁
================================================ FILE: docs/src/components/EnhanceMiniLogo.astro ================================================ --- const { class: className } = Astro.props; ---
▐▔▔▐▚ ▌▐ ▌▐▔▌▐▚ ▌▐▔▔▐▔▔
▐▛▁▐ ▚▌▐▔▌▐▔▌▐ ▚▌▐▁▁▐▛▁

A Blazingly Fast Terminal UI for GitHub Actions

================================================ FILE: docs/src/components/EnhanceOneLineLogo.astro ================================================ --- const { class: className } = Astro.props; ---
▐▔▔▐▚ ▌▐ ▌▐▔▌▐▚ ▌▐▔▔▐▔▔
▐▛▁▐ ▚▌▐▔▌▐▔▌▐ ▚▌▐▁▁▐▛▁
================================================ FILE: docs/src/components/FadeImages.astro ================================================ --- import "../styles/fade-images.css"; ---
================================================ FILE: docs/src/components/FeatureCard.astro ================================================ --- import FeatureSponsorshipGoal from "./FeatureSponsorshipGoal.astro"; const PROJECTS = { dash: { url: "/", colorClass: "text-[var(--sl-color-accent-high)]", }, enhance: { url: "/enhance", colorClass: "text-[#38E796]", }, } as const; interface Props { project: keyof typeof PROJECTS; feature: string; description: string; variant?: "mini" | "full"; future?: boolean; } const { feature, future = false, description, project, variant = "full", } = Astro.props; ---
================================================ FILE: docs/src/components/FeatureSponsorshipGoal.astro ================================================ --- import { getSponsorshipGoal } from "../data/sponsorshipGoal"; import { Icon } from "@astrojs/starlight/components"; const { variant, future = false, feature, description } = Astro.props; const response = await getSponsorshipGoal(); const current = response.data.user.monthlyEstimatedSponsorsIncomeInCents / 100; const GOAL = 250; // USD ---

{feature}

{description}

{ future ? null : (
{Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(current)}{" "} /{" "} {Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(GOAL)}

{Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( (current / GOAL) * 100, )} % towards ${GOAL} per month goal

Hitting the goal will open source it for everyone

) }
================================================ FILE: docs/src/components/Footer.astro ================================================ --- import DecorationTop from "./DecorationTop.astro"; import DecorationBottom from "./DecorationBottom.astro"; const { class: className, isCommunity = true } = Astro.props; ---

Created and maintained by @dlvhdr{ isCommunity ? ( <> {" "} and the{" "} community ) : null }

================================================ FILE: docs/src/components/Header.astro ================================================ --- import Search from "@astrojs/starlight/components/Search.astro"; import Logo from "./Logo.astro"; import { Icon } from "@astrojs/starlight/components"; import PillLink from "./PillLink.astro"; import ThemeSelect from "./ThemeSelect.astro"; import StargazersCount from "./StargazersCount.astro"; import StargazersFallback from "./StargazersFallback.astro"; const isDashHomepage = Astro.locals.starlightRoute.id === ""; const isEnhanceHomepage = Astro.locals.starlightRoute.id === "enhance"; ---
{ isEnhanceHomepage ? ( ) : null }
{ isDashHomepage ? ( ) : null }
================================================ FILE: docs/src/components/Hero.astro ================================================ --- import Default from "@astrojs/starlight/components/PageTitle.astro"; import Logo from "./Logo.astro"; import EnhanceLogo from "./EnhanceLogo.astro"; import ReleaseVersionButton from "./ReleaseVersionButton.astro"; import Terminal from "./Terminal.astro"; import { Icon } from "@astrojs/starlight/components"; const { tagline, githubUrl, videoUrl, getStartedUrl } = Astro.props; ---

{tagline}

================================================ FILE: docs/src/components/Logo.astro ================================================ --- const { className } = Astro.props; ---
▜▔▚▐▔▌▚▔▐ ▌
▟▁▞▐▔▌▁▚▐▔▌
================================================ FILE: docs/src/components/NerdFontIcon.astro ================================================ --- const { icon } = Astro.props; import "../styles/nerd-font.css"; --- ================================================ FILE: docs/src/components/PillLink.astro ================================================ --- const { href, target, class: className } = Astro.props; ---
================================================ FILE: docs/src/components/ReleaseVersionButton.astro ================================================ --- import { getLatestVersion } from "../data/latestVersion"; const response = await getLatestVersion(); ---
================================================ FILE: docs/src/components/Showcase.astro ================================================ --- const { reversed } = Astro.props; ---
──◇──
================================================ FILE: docs/src/components/Sponsorship.astro ================================================ --- import { getSponsorshipGoal } from "../data/sponsorshipGoal"; const response = await getSponsorshipGoal(); const current = response.data.user.monthlyEstimatedSponsorsIncomeInCents / 100; const GOAL = 250; // USD ---
{ Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(current) } / { Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(GOAL) }

{ Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( (current / GOAL) * 100, ) }% towards ${GOAL} per month goal

================================================ FILE: docs/src/components/SponsorshipGoal.astro ================================================ --- import { getSponsorshipGoal } from "../data/sponsorshipGoal"; import { Icon } from "@astrojs/starlight/components"; const { variant } = Astro.props; const response = await getSponsorshipGoal(); const current = response.data.user.monthlyEstimatedSponsorsIncomeInCents / 100; const GOAL = 150; // USD ---
{ Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(current) } / { Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(GOAL) }

{ Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format( (current / GOAL) * 100, ) }% towards ${GOAL} per month goal

Hitting the goal will open source the app

================================================ FILE: docs/src/components/StargazersCount.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; import PillLink from "./PillLink.astro"; import { getStars } from "../data/stars"; const response = await getStars(); --- ================================================ FILE: docs/src/components/StargazersFallback.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; import PillLink from "./PillLink.astro"; --- {" "} GitHub ================================================ FILE: docs/src/components/SupportSection.astro ================================================ --- import { Icon } from "@astrojs/starlight/components"; import Sponsorship from "../components/Sponsorship.astro"; ---

Donate To Support the Project

I'm always working on new terminal UIs to make my life easier.
By donating or joining Insiders you can support this and any of my other projects.

This is my current sponsorship goal

================================================ FILE: docs/src/components/Terminal.astro ================================================ --- import "../styles/terminal.css"; const { className, title = "gh dash" } = Astro.props; ---
{title} -- 70x32
================================================ FILE: docs/src/components/ThemeSelect.astro ================================================ --- import Select from "@astrojs/starlight/components/Select.astro"; --- { /* TODO: Can we give this select a width that works well for each language’s strings? */ }