refactor: route picker actions and :Forge commands through shared operations #148

Closed
opened 2026-04-11 19:09:35 +00:00 by barrettruth · 0 comments
barrettruth commented 2026-04-11 19:09:35 +00:00

Prerequisites

  • I have searched existing issues.

Problem

Issue #145 proposes command parity for meaningful picker capabilities, but parity alone is not enough if the picker and command line take different implementation paths.

Today there is a risk that we will end up with:

  • picker-only business logic for some operations
  • command-only business logic for others
  • duplicated validation, permission checks, and follow-up behavior
  • drift between what the picker does and what direct commands do

If the new :Forge CLI is going to be canonical, picker workflows and commands should be thin frontends over the same underlying operations.

Proposed solution

Add or extract a shared operation layer for semantic forge actions.

Principle

No meaningful forge capability should be picker-only, and no command should need a separate bespoke implementation path if the picker already performs the same semantic operation.

Candidate operations

At minimum, operations should exist for:

PR

  • list
  • review
  • checkout
  • worktree
  • browse
  • checks / CI
  • close / reopen
  • edit
  • create
  • approve
  • merge
  • mark draft / ready

Issue

  • list
  • browse
  • close / reopen
  • create

CI

  • list
  • log
  • watch
  • browse/open if supported

Release

  • list
  • browse
  • delete

Browse

  • browse target / location

What this is not

This is not about exposing picker mechanics as commands.

Not required:

  • back
  • nested menus
  • filter-next / filter-prev
  • load-more entries
  • picker session navigation

Those remain UI behavior.

Implementation direction

Introduce a layer of shared operation functions or modules that:

  • take normalized command / target inputs
  • validate and resolve inputs once
  • call backend-specific command builders / behaviors
  • are reusable from both picker actions and :Forge subcommands

The picker can still provide richer interaction, but it should call the same semantic operations that commands call.

Acceptance criteria

  • shared operations are identified for PR/issue/CI/release/browse actions
  • picker actions and direct commands reuse the same operation path where practical
  • command parity work in #145 does not duplicate business logic already used by pickers
  • tests cover at least one operation being invoked from both command and picker entrypoints with equivalent behavior
  • the architecture is documented well enough to keep future features from becoming picker-only again

Alternatives considered

  • Add direct commands first and clean up duplication later. This is faster initially, but makes long-term drift between picker and CLI much more likely.
  • Leave the picker as the “real” workflow and keep the command line as a shallow subset. That undermines scripting, precision, and the stated goal of a canonical CLI.
## Prerequisites - [x] I have searched existing issues. ## Problem Issue #145 proposes command parity for meaningful picker capabilities, but parity alone is not enough if the picker and command line take different implementation paths. Today there is a risk that we will end up with: - picker-only business logic for some operations - command-only business logic for others - duplicated validation, permission checks, and follow-up behavior - drift between what the picker does and what direct commands do If the new `:Forge` CLI is going to be canonical, picker workflows and commands should be thin frontends over the same underlying operations. ## Proposed solution Add or extract a shared operation layer for semantic forge actions. ### Principle No meaningful forge capability should be picker-only, and no command should need a separate bespoke implementation path if the picker already performs the same semantic operation. ### Candidate operations At minimum, operations should exist for: #### PR - list - review - checkout - worktree - browse - checks / CI - close / reopen - edit - create - approve - merge - mark draft / ready #### Issue - list - browse - close / reopen - create #### CI - list - log - watch - browse/open if supported #### Release - list - browse - delete #### Browse - browse target / location ### What this is not This is not about exposing picker mechanics as commands. Not required: - back - nested menus - filter-next / filter-prev - load-more entries - picker session navigation Those remain UI behavior. ### Implementation direction Introduce a layer of shared operation functions or modules that: - take normalized command / target inputs - validate and resolve inputs once - call backend-specific command builders / behaviors - are reusable from both picker actions and `:Forge` subcommands The picker can still provide richer interaction, but it should call the same semantic operations that commands call. ### Acceptance criteria - [ ] shared operations are identified for PR/issue/CI/release/browse actions - [ ] picker actions and direct commands reuse the same operation path where practical - [ ] command parity work in #145 does not duplicate business logic already used by pickers - [ ] tests cover at least one operation being invoked from both command and picker entrypoints with equivalent behavior - [ ] the architecture is documented well enough to keep future features from becoming picker-only again ## Alternatives considered - Add direct commands first and clean up duplication later. This is faster initially, but makes long-term drift between picker and CLI much more likely. - Leave the picker as the “real” workflow and keep the command line as a shallow subset. That undermines scripting, precision, and the stated goal of a canonical CLI.
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#148
No description provided.