scope a picker-agnostic master workflow for :Forge #79

Closed
opened 2026-04-07 03:59:32 +00:00 by barrettruth · 2 comments
barrettruth commented 2026-04-07 03:59:32 +00:00

Motivation

Issue #59 captured the rough idea of a "master picker", but the current top-level workflow is still pretty thin and hard to reason about.

Today :Forge is mostly a route launcher:

  • routes.lua builds the root sections (prs, issues, ci, branches, commits, worktrees, browse, releases)
  • each section resolves to a route alias from vim.g.forge.routes
  • the route handler then opens a concrete picker from pickers.lua

That works, but it does not make the overall workflow obvious from the top:

  • the root picker does not explain what each section actually does
  • local git sections (branches, commits, worktrees) are useful but visually lighter than PR/issue/CI pickers
  • there is no user-facing inventory of what each picker shells out to
  • backend differences are implicit rather than documented in one place

I’d like a scoped pass that defines what the “master workflow” should be and whether it should stay backend-driven or become something more first-party.

Current state

Root workflow

require('forge').open() -> routes.open() -> open_root().

The root menu is section-based and currently only renders plain labels. It uses the client abstraction, but only for the root menu; nested pickers go straight through forge.picker.

Default route map:

  • prs -> prs.open
  • issues -> issues.open
  • ci -> ci.current_branch
  • browse -> browse.contextual
  • releases -> releases.all
  • branches -> branches.local
  • commits -> commits.current_branch
  • worktrees -> worktrees.list

What it shells out to today

For a GitHub repo like this one:

  • root/context detection:
    • git rev-parse --show-toplevel
    • git branch --show-current
    • git rev-parse HEAD
    • git remote get-url origin
  • issues:
    • gh issue list --limit <n> --state <state> --json ...
  • PRs:
    • gh pr list --limit <n> --state <state> --json ...
  • branches:
    • git for-each-ref --format=... refs/heads
    • action: git switch <branch>
  • commits:
    • git log --max-count=100 --format=... <branch>
    • action: git show --stat --patch --decorate=short <sha>
  • worktrees:
    • git worktree list --porcelain
    • action: :cd <path> inside Neovim
  • PR worktree creation:
    • git fetch origin pull/<num>/head:pr-<num>
    • git worktree add ../pr-<num> pr-<num>

Equivalent forge-specific commands exist for GitLab (glab) and Codeberg/Gitea/Forgejo (tea).

Picker backend support

Current built-in backends:

  • fzf-lua
  • snacks.nvim
  • telescope.nvim

All three backends currently support:

  • segmented row rendering/highlighting
  • action bindings
  • non-closing actions
  • root + nested picker usage

Notable differences:

  • fzf-lua has the richest action header treatment (FzfLuaHeaderBind / FzfLuaHeaderText)
  • telescope and snacks preserve row highlights, but do not currently get the same header UX
  • there is a public client extension point for the root menu, but there is no equivalent public picker-backend registration API yet

Scope

  • define what the “master workflow” should be at the :Forge entry point
  • make the top-level UX clearer and richer, especially for branches, commits, and worktrees
  • document, or expose in-code, the exact route -> command -> action mapping
  • document backend capability differences in one place
  • decide whether the right direction is:
    • a richer root client
    • a fuller picker-agnostic workflow layer
    • or a first-party picker/UI owned by forge.nvim

Deliverables

  • design note for the :Forge master workflow
  • explicit inventory of per-route shell commands and actions
  • visual pass on root/branch/commit/worktree entries and highlighting
  • backend capability matrix for fzf-lua, snacks, and telescope
  • recommendation on whether to keep extending the current abstraction or build a first-party picker/client

Nice-to-haves

  • secondary text in the root picker (route target, scope, or short description)
  • a way to surface command provenance/debug info from the UI
  • a public registration API for custom picker backends if we stay backend-agnostic
## Motivation Issue #59 captured the rough idea of a "master picker", but the current top-level workflow is still pretty thin and hard to reason about. Today `:Forge` is mostly a route launcher: - `routes.lua` builds the root sections (`prs`, `issues`, `ci`, `branches`, `commits`, `worktrees`, `browse`, `releases`) - each section resolves to a route alias from `vim.g.forge.routes` - the route handler then opens a concrete picker from `pickers.lua` That works, but it does not make the overall workflow obvious from the top: - the root picker does not explain what each section actually does - local git sections (`branches`, `commits`, `worktrees`) are useful but visually lighter than PR/issue/CI pickers - there is no user-facing inventory of what each picker shells out to - backend differences are implicit rather than documented in one place I’d like a scoped pass that defines what the “master workflow” should be and whether it should stay backend-driven or become something more first-party. ## Current state ### Root workflow `require('forge').open()` -> `routes.open()` -> `open_root()`. The root menu is section-based and currently only renders plain labels. It uses the `client` abstraction, but only for the root menu; nested pickers go straight through `forge.picker`. Default route map: - `prs` -> `prs.open` - `issues` -> `issues.open` - `ci` -> `ci.current_branch` - `browse` -> `browse.contextual` - `releases` -> `releases.all` - `branches` -> `branches.local` - `commits` -> `commits.current_branch` - `worktrees` -> `worktrees.list` ### What it shells out to today For a GitHub repo like this one: - root/context detection: - `git rev-parse --show-toplevel` - `git branch --show-current` - `git rev-parse HEAD` - `git remote get-url origin` - issues: - `gh issue list --limit <n> --state <state> --json ...` - PRs: - `gh pr list --limit <n> --state <state> --json ...` - branches: - `git for-each-ref --format=... refs/heads` - action: `git switch <branch>` - commits: - `git log --max-count=100 --format=... <branch>` - action: `git show --stat --patch --decorate=short <sha>` - worktrees: - `git worktree list --porcelain` - action: `:cd <path>` inside Neovim - PR worktree creation: - `git fetch origin pull/<num>/head:pr-<num>` - `git worktree add ../pr-<num> pr-<num>` Equivalent forge-specific commands exist for GitLab (`glab`) and Codeberg/Gitea/Forgejo (`tea`). ### Picker backend support Current built-in backends: - `fzf-lua` - `snacks.nvim` - `telescope.nvim` All three backends currently support: - segmented row rendering/highlighting - action bindings - non-closing actions - root + nested picker usage Notable differences: - `fzf-lua` has the richest action header treatment (`FzfLuaHeaderBind` / `FzfLuaHeaderText`) - `telescope` and `snacks` preserve row highlights, but do not currently get the same header UX - there is a public `client` extension point for the root menu, but there is no equivalent public picker-backend registration API yet ## Scope - define what the “master workflow” should be at the `:Forge` entry point - make the top-level UX clearer and richer, especially for `branches`, `commits`, and `worktrees` - document, or expose in-code, the exact route -> command -> action mapping - document backend capability differences in one place - decide whether the right direction is: - a richer root `client` - a fuller picker-agnostic workflow layer - or a first-party picker/UI owned by forge.nvim ## Deliverables - [ ] design note for the `:Forge` master workflow - [ ] explicit inventory of per-route shell commands and actions - [ ] visual pass on root/branch/commit/worktree entries and highlighting - [ ] backend capability matrix for `fzf-lua`, `snacks`, and `telescope` - [ ] recommendation on whether to keep extending the current abstraction or build a first-party picker/client ## Nice-to-haves - secondary text in the root picker (route target, scope, or short description) - a way to surface command provenance/debug info from the UI - a public registration API for custom picker backends if we stay backend-agnostic
barrettruth commented 2026-04-07 17:08:41 +00:00

Consolidating this into #59, which now tracks the :Forge master picker / home workflow more explicitly. The review-centric work stays under #63 and its child issues.

Consolidating this into #59, which now tracks the :Forge master picker / home workflow more explicitly. The review-centric work stays under #63 and its child issues.
barrettruth commented 2026-04-07 17:38:07 +00:00

Consolidating the detailed planning in #87.

#87 rolls up the architecture/scope work from this issue and #59 into a single thread, with a clearer statement of philosophy, concrete implementation phases, and the recommendation to start with root picker legibility plus branches/commits/worktrees polish.

Consolidating the detailed planning in #87. #87 rolls up the architecture/scope work from this issue and #59 into a single thread, with a clearer statement of philosophy, concrete implementation phases, and the recommendation to start with root picker legibility plus branches/commits/worktrees polish.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
barrettruth/forge.nvim#79
No description provided.