Skip to content

feat: worktrunk (wt) core integration#123

Merged
actionshrimp merged 6 commits intomainfrom
feature/worktrunk-core
Mar 12, 2026
Merged

feat: worktrunk (wt) core integration#123
actionshrimp merged 6 commits intomainfrom
feature/worktrunk-core

Conversation

@actionshrimp
Copy link
Owner

Summary

Builds on PR #122 (persistent popup switches). Wires up the wt worktrunk CLI as a first-class worktree workflow layer.

  • Adds lua/gitlad/worktrunk/ — async wrappers around the wt CLI: is_installed, is_active, list, switch, merge, remove, copy_ignored
  • Adds three new worktree config fields: worktrunk ("auto"|"always"|"never"), copy_ignored_on_create, copy_ignored_from
  • Bifurcates the worktree popup (% / Z) into a worktrunk-oriented mode when wt is installed (auto-detected), with Switch/Merge/Remove/Steps sections plus a "Git Worktree" escape hatch for raw git ops
  • Adds a dedicated wt merge popup with no-squash/no-rebase/no-remove/no-verify switches and a target-branch option
  • Adds a persistent -i (copy-ignored) switch and a ci standalone step action

How to test

Prerequisites

The worktrunk features require the wt CLI to be installed. Without it in PATH, the popup silently falls back to the standard git mode — no config needed.

Default behaviour (auto-detect)

  1. Open a git repo in Neovim and run :Gitlad
  2. Press % (or Z) to open the worktree popup
  3. With wt installed: popup is titled Worktrees [worktrunk] with Switch / Merge / Remove / Steps sections + "Git Worktree" escape hatch
  4. Without wt: standard popup, unchanged

Force git mode (even if wt installed)

require("gitlad").setup({ worktree = { worktrunk = "never" } })

Worktrunk popup keys

Key Action
-i Toggle "copy ignored on create" (persists across restarts)
s Switch to existing worktree (from wt list)
S Create + switch (wt switch -c <branch>)
m Open wt Merge popup
R Remove worktree (wt remove)
ci Run wt step copy-ignored now
b/c/k/g/l/u/p Git escape hatch — identical to standard popup

wt Merge popup (m → opens separate popup)

Key Action
-s/-r/-R/-v no-squash / no-rebase / no-remove / no-verify
=t Target branch
m Run wt merge

Running tests

make test      # full suite (all 653 pass)
make test-unit # unit tests only, no wt needed

# worktrunk-specific
make test-file FILE=tests/unit/test_worktrunk_parse.lua
make test-file FILE=tests/unit/test_worktrunk_detect.lua
make test-file FILE=tests/unit/test_worktrunk_popup.lua
make test-file FILE=tests/unit/test_worktree_merge_popup.lua

# guarded e2e (auto-skip if wt not in PATH)
make test-file FILE=tests/e2e/test_worktrunk_popup.lua
make test-file FILE=tests/e2e/test_worktrunk_ops.lua

Notes

  • wt list --format=json outputs a JSON array (not NDJSON). The parser handles both formats.
  • Existing worktree e2e tests updated to set worktrunk = "never" so they're stable regardless of whether wt is installed locally.

Adds lua/gitlad/worktrunk/parse.lua with WorktreeInfo type and
parse_list() for NDJSON output from `wt list --format=json`, and
lua/gitlad/worktrunk/init.lua with is_installed, is_active, list,
switch, merge, remove, and copy_ignored async CLI wrappers.

Includes a representative NDJSON fixture and unit tests for both
the parser and the detection/is_active logic.
Adds worktrunk, copy_ignored_on_create, and copy_ignored_from fields
to GitladWorktreeConfig with safe defaults ("auto", "never", "trunk").
When worktrunk (wt) is installed and cfg.worktree.worktrunk != "never",
M.open() now bifurcates into _open_worktrunk_popup or _open_git_popup.

The worktrunk popup provides Switch (s/S), Merge (m), and Remove (R)
sections wired to wt CLI, plus a "Git Worktree" escape hatch section
reusing all existing git worktree action implementations verbatim.

Includes unit tests for popup structure/bifurcation logic and a guarded
e2e test (skipped when wt is not in PATH).
Adds lua/gitlad/popups/worktree_merge.lua with switches (no-squash,
no-rebase, no-remove, no-verify), a target branch option (=t), and
a single merge action (m) that calls wt.merge().

Reachable via the `m` action in the worktrunk worktree popup.
- Adds -i (copy-ignored) switch with persist_key=wt_copy_ignored to the
  worktrunk popup so users can toggle copy-ignored per-session and have
  it persist across popup invocations
- Adds ci (Copy ignored files) action under a Steps heading for running
  wt step copy-ignored immediately against the current or context worktree
- _wt_create_and_switch now checks the -i switch and
  cfg.worktree.copy_ignored_on_create to decide whether to run copy-ignored
  automatically after creating a new worktree

Unit tests cover the new switch (persist_key) and ci action.
Guarded e2e test for wt switch/remove ops (skipped without wt).
The actual wt CLI outputs a JSON array, not NDJSON. Updated parse.lua
to handle JSON arrays (with NDJSON fallback), updated the fixture and
parse unit tests to match the real format.

Also fixed existing e2e worktree tests that were failing because wt is
installed locally and the popup was bifurcating into worktrunk mode.
Fixed worktrunk_ops e2e test to not pre-initialize globals to false
(wait_for_var checks ~= nil, so false would return immediately).
Fixed worktrunk_popup e2e tests to use the correct state/workflow API.
@actionshrimp actionshrimp merged commit 2d4eb73 into main Mar 12, 2026
3 checks passed
@actionshrimp actionshrimp deleted the feature/worktrunk-core branch March 12, 2026 20:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant