Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ No Makefile, no code generation, no external linter config. Standard Go toolchai

- Return typed `ExitError` sentinels (codes 1-10 in `cmd/utils.go`) from `RunE`. Never call `os.Exit()` directly.
- Check errors with `var exitErr *ExitError; errors.As(err, &exitErr)`.
- Table-driven tests with `t.Run()` subtests.
- Define each test case as an individual `Test...` function, sharing setup helpers where useful.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Consistent Copilot entry point: This instruction can independently steer new cases into loops that have already required a requested rewrite. Individually defined cases can retain the existing shared-setup pattern without changing mock restoration or validation requirements.

Commit

- Use `config.NewTestConfig()` for test configs with captured I/O.
- Mock git: `restore := git.SetOps(&git.MockOps{...}); defer restore()`. Always defer restore.
- Mock GitHub: `cfg.GitHubClientOverride = &github.MockClient{...}`.
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ if errors.As(err, &exitErr) { ... }
### Testing patterns

- **Framework:** `stretchr/testify` (`assert`, `require`) for assertions.
- **Table-driven tests** are the norm. See `cmd/utils_test.go` for examples.
- **Test cases:** Define each case as an individual `Test...` function, sharing setup helpers where useful.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Consistent test guidance: Table-first advice can repeat the requested restyling detour. The confirmed repository preference keeps cases individually defined while existing command tests reuse shared setup; the old table-example pointer reinforces the superseded direction.

Commit

- **Config:** Use `config.NewTestConfig()` which returns `(*Config, stdoutReader, stderrReader)` with captured I/O and no-op color functions.
- **Git mocking:** Call `git.SetOps(&git.MockOps{...})`. It returns a restore function. Always `defer restore()` to prevent test pollution.
- **GitHub mocking:** Set `cfg.GitHubClientOverride = &github.MockClient{...}`.
Expand Down Expand Up @@ -144,7 +144,6 @@ if errors.As(err, &exitErr) { ... }
- The `Queued` field on `BranchRef` is transient (populated from GitHub API, never persisted to the stack JSON file).
- `git.SetOps()` replaces the **package-level** ops variable. Forgetting `defer restore()` in a test will break every subsequent test in the package.
- Interrupt detection: Ctrl+C is caught as `terminal.InterruptErr`, wrapped into an `errInterrupt` sentinel, and printed with a friendly message before a silent exit.
- Rerere: on first rebase conflict, the user is prompted to enable `git rerere`. If declined, a flag file prevents future prompts. `tryAutoResolveRebase()` loops up to 1000 times auto-continuing when rerere resolves conflicts.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Accurate setup lifecycle: Wrong prompt timing and storage assumptions can send maintenance work to the wrong place: init calls setup before its operation, the helper skips noninteractive use, and decline is Git configuration. The incidental loop ceiling remains at its definition.

Commit

- Rebase commands disable automatic maintenance through command-local configuration so detached `rerere gc` cannot race conflict handling. Repository settings and unrelated Git commands are unchanged.
- Date-preserving rebase starts use the merge backend so Git persists the date setting across conflicts. Continuations use native saved settings, not start-only date flags.
- The `.gitignore` ignores `/gh-stack` and `/gh-stack.exe` (the built binary).
Expand Down
5 changes: 0 additions & 5 deletions skills/gh-stack/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ Agent harnesses differ, so always pass the flags below instead of relying on tha
| `gh stack up` / `down` / `top` / `bottom` | `gh stack switch` | `switch` is menu-only |
| — | `gh stack modify` | TUI-only, no non-interactive path |

- `view --short` is safe in both modes, but it is formatted for humans. Use `--json` to parse.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Prompt-free state reading: Calling short view safe can lead an unattended agent into ordinary stack lookup and its shared-trunk selector. The existing JSON table entry already preserves the agent action; human short-format advice remains in the reference.

Commit

- **`checkout <pr>` when a different local stack already covers those branches** cannot be forced.
Run `gh stack unstack --local` first (this keeps the stack on GitHub), then retry.
- **Worktrees:** local stacks share one common-directory catalog. Use `--print-path` with
Expand All @@ -68,8 +67,6 @@ Agent harnesses differ, so always pass the flags below instead of relying on tha

## Branch placement

- **Starting multi-part work:** create the stack before writing files. Do not implement every

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 One complete planning procedure: Maintaining the same duties twice adds drift without another reader action. The already-required stack-design reference preserves dependency order and creation before editing and concern-specific commits. Existing-stack editing remains separate.

Commit

concern on trunk and split it later. Put one dependent concern in each layer, bottom to top.
- **Editing an existing stack:** check out the layer that owns the change before editing. Never
commit a lower layer's concern on the current top branch. Run `gh stack view --json`; if
ownership is unclear, inspect `git log --all -- <path>`. Then check out the owner, edit, commit,
Expand Down Expand Up @@ -175,8 +172,6 @@ an ancestor of the branch.
affected clean owners; unoccupied branches use the origin. Drop/fold source branches and
worktrees are preserved. Recovery flags may run from any worktree and use recorded native
operation owners; never resolve/stage in the caller's tree unless the diagnostic names it.
- There is no non-interactive reorder or removal. Errors may suggest `gh stack modify`, but it is

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 One complete restructuring procedure: This shorter recipe adds upkeep to a procedure readers already must load when restructuring. The surviving recipe keeps the same limitation and action plus ancestry and preservation prerequisites; root editor and recorded-owner recovery warnings stay.

Commit

TUI-only — restructure with `unstack` then `init` instead.
- PR titles and bodies are auto-generated. Use `gh pr edit` afterwards to change them.

## More detail
Expand Down
6 changes: 3 additions & 3 deletions skills/gh-stack/references/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ branch does not exist, it is created from the trunk; each later new branch is cr
branch immediately before it. There is no separate adopt mode — existence decides. `--base`
selects a non-default trunk.

`init` also enables `git rerere`. Under a TTY the first run in a repo asks for confirmation; set
Under a TTY the first run in a repo asks for confirmation; set

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Explicit setup expectations: Assuming init enabled rerere can leave unattended workflows without remembered resolutions; noninteractive setup deliberately skips enablement. The explicit configuration command and interactive confirmation advice stay.

Commit

`git config rerere.enabled true` beforehand to skip it.
Comment on lines +34 to 35

## add
Expand Down Expand Up @@ -190,9 +190,9 @@ Removes the stack **grouping** only. It never deletes pull requests or branches.

## Navigation

`up`, `down`, `top`, `bottom`, and `trunk` are always non-interactive. `up` and `down` accept a
`up` and `down` accept a

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Conditional navigation prompts: An unconditional guarantee can make unattended navigation wait for input. Ordinary navigation loads the stack through the interactive ambiguity resolver; count syntax and the checked path-mode procedure stay.

Commit

count (`gh stack up 3`). Movement clamps at the stack bounds, and merged branches are skipped when
navigating from an active branch, so `bottom` lands on the lowest *unmerged* branch.
navigating from an active branch, so `bottom` lands on the lowest *active* branch.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Correct editing destination: An unmerged layer can still be queued, so the old wording can point readers at a different branch than navigation selects. Bottom uses the first active index, whose definition excludes merged and queued layers. The existing active-branch condition is preserved.

Commit


`gh stack switch` is a selection menu with no non-interactive path. Use the commands above instead.

Expand Down
4 changes: 1 addition & 3 deletions skills/gh-stack/references/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ gh stack rebase --continue # repeat if the next branch also conflicts

`gh stack rebase --abort` restores every branch in the stack, not just the current one.

Because `init` enables `git rerere`, a conflict you resolve once is replayed automatically the next
time the same conflict appears — which is common, since a change low in the stack is rebased through
every branch above it. Without `rerere`, repeated conflicts may need manual resolution on each
Without `rerere`, repeated conflicts may need manual resolution on each

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Reliable recovery expectations: The replay guarantee and dependent layer explanation rely on configuration that noninteractive init does not establish. Manual recovery and the independent warning remain, with explicit setup still available.

Commit

affected layer.

## After a squash merge
Expand Down
Loading