@gallopsystems/agent-skills 1.27.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -22,7 +22,7 @@ doctl supports named auth contexts for managing multiple accounts/teams.
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
doctl auth list # list contexts; (current) marks the active one
|
|
25
|
-
doctl account get --context <name> # cheap probe: is this context valid, which account is it?
|
|
25
|
+
doctl account get --context <name> # cheap probe: is this context valid, which account is it, is it locked?
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
**Prefer the `--context` flag over switching.** Every doctl command accepts `--context <name>` (before or after the subcommand). This targets one account for one command without mutating global state — important when a session touches multiple accounts:
|
|
@@ -89,6 +89,24 @@ for i in $(seq 1 90); do
|
|
|
89
89
|
done
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
### Deployments failing for no visible reason: check account status first
|
|
93
|
+
|
|
94
|
+
A billing- or abuse-locked team leaves **running** resources up, but can't start **new** containers. App Platform doesn't say "locked" in any deployment error. Before digging into logs, code or the platform, run one command:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
doctl account get --context <ctx> -o json | jq '{status, status_message}'
|
|
98
|
+
# {"status": "locked", "status_message": "Your team has been locked due to lack of payment or improper use ..."}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Symptoms of a locked team, all at once:
|
|
102
|
+
- Every deployment stalls in a step that needs a new instance, such as a `PRE_DEPLOY` job. It stalls for about 30 minutes, then fails with `An internal error occurred. Contact support if this persists.`
|
|
103
|
+
- That component has no logs at all. `--type run` fails with `websocket: close 1011`, and the deploy log says `No further logs available`. The job never connects to its database.
|
|
104
|
+
- DigitalOcean's automated rollback to a previously good commit hangs the same way. That rules out a code regression.
|
|
105
|
+
- Mutations fail even for people who normally have access. `create-deployment` and `apps update` return 403 `forbidden`; the dashboard shows `You don't have permission` or `Something went wrong`.
|
|
106
|
+
- The live app keeps serving, and the status page is all green.
|
|
107
|
+
|
|
108
|
+
A locked team can only be fixed by its billing owner, who pays and opens a support ticket to unlock. Balance and invoice commands (`doctl balance get`, `doctl invoice list`) return 403 for non-billing members, so `account get` may be the only signal you can see. Failed deployments aren't retried after the unlock, so push or redeploy once the team is active again.
|
|
109
|
+
|
|
92
110
|
## Logs
|
|
93
111
|
|
|
94
112
|
```bash
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-github
|
|
3
|
-
description: Git and GitHub (gh CLI) workflows for agents - the branch-to-PR loop, reading PR and CI state, debugging failed GitHub Actions runs, getting unstuck from rejected pushes and rebase messes, gh api recipes, and release flows.
|
|
3
|
+
description: Git and GitHub (gh CLI) workflows for agents - the branch-to-PR loop, stacked PRs with gh stack, reading PR and CI state, debugging failed GitHub Actions runs, getting unstuck from rejected pushes and rebase messes, gh api recipes, and release flows.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Git + GitHub Workflows
|
|
@@ -50,7 +50,7 @@ EOF
|
|
|
50
50
|
- Merge style: `gh pr merge <n> --squash --delete-branch`; verify with `gh pr view <n> --json state,mergedAt`.
|
|
51
51
|
- After merge: `git switch main && git pull --ff-only`, clean up `[gone]` branches, start the next branch from fresh main.
|
|
52
52
|
- One concern per PR — hotfixes and review findings go in separate PRs unless told otherwise.
|
|
53
|
-
- Stacked PRs: `gh
|
|
53
|
+
- **Stacked PRs: use `gh stack` (github/gh-stack), never hand-set a PR's base to another feature branch.** Stack only when the child truly depends on the parent; otherwise branch from main. Core loop: `gh stack init <b1>` → `gh stack add <b2>` → `gh stack submit --auto --open` → `gh stack sync` after merges → `gh stack merge <n> --yes --squash` (the user's call). Plain `gh pr merge` doesn't work on stacked PRs. Full playbook, agent flags and error table: [stacked-prs.md](stacked-prs.md).
|
|
54
54
|
- If you discover uncommitted work on the wrong branch and the PR must be "off main", do not commit to the wrong branch. With a cleanly applicable worktree, `git fetch origin main && git switch -c feat/<short-description> origin/main` carries the unstaged changes onto a new branch from `origin/main`. Verify with `git status` and tests. If checkout would overwrite/conflict, stash with `-u`. Only resort to worktree if stash gets too complicated.
|
|
55
55
|
|
|
56
56
|
## Reading PR and CI State
|
|
@@ -81,6 +81,7 @@ Do not bypass failing hooks with `--no-verify` unless the user says to.
|
|
|
81
81
|
|
|
82
82
|
- **Debugging failed Actions runs** (the full playbook): [actions-debugging.md](actions-debugging.md)
|
|
83
83
|
- **Repair ladders** — rejected pushes, blocked checkouts, rebase/conflict recovery, shallow clones, worktrees: [getting-unstuck.md](getting-unstuck.md)
|
|
84
|
+
- **Stacked PRs with `gh stack`**: build, adopt, rebase, merge, and fix the errors it throws: [stacked-prs.md](stacked-prs.md)
|
|
84
85
|
- **gh api recipes** — PR comments, reading files without checkout, repo settings, PAT gotchas: [gh-api-recipes.md](gh-api-recipes.md)
|
|
85
86
|
- **Releases & publishing** — tags, gh release, npm Trusted Publishing, release-please: [releases.md](releases.md)
|
|
86
87
|
- **External review loop** — using the codex CLI as an adversarial pre-merge reviewer: [external-review.md](external-review.md)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Stacked PRs with `gh stack`
|
|
2
|
+
|
|
3
|
+
Use the [`github/gh-stack`](https://gh.io/stacks) extension for any chain of dependent PRs. It tracks the chain locally, keeps PR bases right, and registers a native **stack** on GitHub. GitHub merges a stack atomically, bottom-up.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
gh extension list | grep stack || gh extension install github/gh-stack # needs gh >= 2.90
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Stack only when the child truly depends on the parent
|
|
10
|
+
|
|
11
|
+
If the follow-up doesn't need the parent's code, branch it from main and skip stacking. When it does depend, **never hand-set a PR's base to another feature branch** (`gh pr create --base <parent-branch>`):
|
|
12
|
+
|
|
13
|
+
- **Merge order decides what reaches main.** Merge the child first and it lands on the parent's branch, not main. It only reaches main if the parent is merged *afterwards*. Nothing warns you either way.
|
|
14
|
+
- **GitHub may lock hand-chained PRs.** It can group PRs whose bases chain into a stack object. After that, `gh pr edit --base`, REST and GraphQL all refuse with `Cannot change the base branch because the pull request is part of a stack`. Deleting a merged base branch then **closes** the child PR instead of retargeting it.
|
|
15
|
+
|
|
16
|
+
## Command map
|
|
17
|
+
|
|
18
|
+
| Command | Does |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `gh stack init [b1 b2 …]` | Start a stack, or adopt existing branches bottom→top (missing branches are created, existing PRs are found). `--base <trunk>` for a non-default trunk. |
|
|
21
|
+
| `gh stack add <branch>` | Create a branch on top of the current stack and check it out. |
|
|
22
|
+
| `gh stack submit` | Push every branch, create missing PRs, fix bases, create/update the GitHub stack. |
|
|
23
|
+
| `gh stack push` | Push every branch only. No PR or stack changes. |
|
|
24
|
+
| `gh stack rebase` | Fetch trunk, then cascade-rebase every layer. Flags: `--upstack`, `--downstack`, `--no-trunk`, `--continue`, `--abort`. |
|
|
25
|
+
| `gh stack sync` | `rebase` + push + refresh PR state in one go (use after a PR merges). |
|
|
26
|
+
| `gh stack view` | Show the stack. `--short` or `--json` for parsing. `⚠` means the branch needs a rebase. |
|
|
27
|
+
| `gh stack checkout <stack#\|pr#\|url>` | Import a stack from GitHub (e.g. a teammate's) and set up local tracking. |
|
|
28
|
+
| `gh stack link <b\|pr> …` | Create or extend a GitHub stack from branches/PR numbers, with no local tracking. |
|
|
29
|
+
| `gh stack merge [<stack#\|pr#>]` | Atomic merge of the stack, up to and including the given PR. |
|
|
30
|
+
| `gh stack trunk` / `top` / `bottom` / `up` / `down` | Navigate. |
|
|
31
|
+
|
|
32
|
+
## Building a stack
|
|
33
|
+
|
|
34
|
+
**From scratch:**
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git switch main && git pull --ff-only
|
|
38
|
+
gh stack init feat/<part-1> # bottom branch, based on main
|
|
39
|
+
# …commit…
|
|
40
|
+
gh stack add feat/<part-2> # next layer on top
|
|
41
|
+
# …commit…
|
|
42
|
+
gh stack submit --auto --open # push all, open PRs, create the stack
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Adopt branches (and PRs) that already exist:** `gh stack init b1 b2 b3` (bottom→top), then `gh stack submit --auto --open`. Submit reports `Updated base branch for PR #n …` for any wrong base and creates the stack. This is also how you rescue a hand-chained set of PRs. If a branch exists only on `origin`, create it locally first (`git branch <b> origin/<b>`). Otherwise submit fails with `src refspec refs/heads/<b> does not match any`.
|
|
46
|
+
|
|
47
|
+
**Without local tracking:** `gh stack link <bottom> … <top>` takes branch names or PR numbers. It pushes the branches, creates missing PRs with chained bases, and creates or extends the stack.
|
|
48
|
+
- Grow an existing stack with `gh stack link <stack#> <new-branch-or-pr>`.
|
|
49
|
+
- Re-running `link` with the full list is idempotent (`Stack with N PRs is already up to date`). Use it to re-register the chain after hand-rebasing branches.
|
|
50
|
+
- PRs that `link` creates are **drafts**, so run `gh pr ready <n>`.
|
|
51
|
+
- `link` leaves nothing tracked locally, so `gh stack view` then says `not part of a stack`. Run `gh stack checkout <stack#>` to import tracking.
|
|
52
|
+
|
|
53
|
+
## Non-interactive use (agents)
|
|
54
|
+
|
|
55
|
+
- `gh stack submit` opens a TUI editor in a terminal. Pass `--auto` to skip it and use auto-generated titles. Fix those titles and bodies afterwards with `gh pr edit <n> --title … --body-file …`.
|
|
56
|
+
- `--auto` creates **drafts** unless you also pass `--open`. `--open` also flips **existing** draft PRs in the stack to ready. Leave it off if a PR must stay a draft.
|
|
57
|
+
- Conflict continue without an editor: `git add <files> && GIT_EDITOR=true gh stack rebase --continue`.
|
|
58
|
+
- Output carries ANSI codes and pre-push hook banners. Filter with `sed 's/\x1b\[[0-9;]*m//g'`, or read `gh stack view --json`.
|
|
59
|
+
|
|
60
|
+
## Changing a stack
|
|
61
|
+
|
|
62
|
+
1. Fix each issue **on the branch that introduced it**, committing bottom-up.
|
|
63
|
+
2. From that branch, run `gh stack rebase --upstack` (or plain `gh stack rebase` for the whole stack, trunk included).
|
|
64
|
+
3. On conflict, resolve, `git add`, then `gh stack rebase --continue`. `gh stack rebase --abort` restores every branch.
|
|
65
|
+
4. Run the checks on the **top** branch. A resolution that compiles on its own layer can still break a test a layer up.
|
|
66
|
+
5. Run `gh stack push` (branches only) or `gh stack submit` (also updates PRs/stack).
|
|
67
|
+
|
|
68
|
+
`gh stack rebase` refuses a dirty tree (`cannot rebase: You have unstaged changes`), so commit or stash first.
|
|
69
|
+
|
|
70
|
+
## After a PR in the stack merges
|
|
71
|
+
|
|
72
|
+
Run `gh stack sync` (or `gh stack rebase` then `gh stack push`). Merged branches are skipped (`Skipping <b> (PR #n merged)`). The next layer is replayed onto trunk with only its own commits (`adjusted for merged PR`), so a squash-merged parent causes none of the usual duplicate-commit conflicts. Verify with `git log --oneline main..HEAD`.
|
|
73
|
+
|
|
74
|
+
If the bottom PR merged before the stack object existed, `submit` prints `Could not create stack: Pull request #n is merged`. That is harmless: the remaining PR simply targets main.
|
|
75
|
+
|
|
76
|
+
## Merging
|
|
77
|
+
|
|
78
|
+
**Merging is the user's call.** Permission classifiers block agent-initiated merges as "Merge Without Review". Hand the user the exact command to run, e.g. `! gh stack merge <n> --yes --squash`.
|
|
79
|
+
|
|
80
|
+
- **Plain `gh pr merge` doesn't work on a stacked PR.** Use `gh stack merge`. The error it prints (`must be merged using the asynchronous merge REST API`) points at REST. Don't follow it; `gh stack merge` is the supported path.
|
|
81
|
+
- **`gh stack merge <n>`** merges everything up to and including PR `<n>`. A bare number is tried as a stack number first, then as a PR number.
|
|
82
|
+
- **Flags:** `--yes` plus `--squash`, `--merge` or `--rebase` (or `--merge-method <m>`). There is no `--method`. Without a method flag it reuses your last method.
|
|
83
|
+
- **All-or-nothing.** `merge failed: … has a merge conflict` then `Stack merges are atomic, so nothing was merged`. Rebase, push and retry.
|
|
84
|
+
- **A draft anywhere blocks it:** `cannot merge the whole stack: pull request #n is a draft`. Run `gh pr ready <n>` first.
|
|
85
|
+
- **Only open/not-draft is checked locally.** Branch protection and required checks are evaluated at merge time. Wait for CI on every PR first (`gh pr checks <n>` per PR).
|
|
86
|
+
- **CI may not run on upper PRs.** A workflow filtered to `pull_request: branches: [main]` doesn't run on PRs based on another stack branch. Those PRs only get checks once their base merges.
|
|
87
|
+
- **A single PR is not a stack.** `gh stack merge` says `#n is not a stack number or a stacked pull request`, so use `gh pr merge`.
|
|
88
|
+
- **Afterwards:** `gh stack trunk && git pull --ff-only`, then delete the merged local branches.
|
|
89
|
+
|
|
90
|
+
## Errors → fixes
|
|
91
|
+
|
|
92
|
+
| Error | Cause / fix |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `current branch "<b>" is not part of a stack` | Not tracked locally (fresh worktree, stack made with `link`, other clone). Run `gh stack init <b1> <b2> …` to adopt, or `gh stack checkout <stack#\|pr#>`. |
|
|
95
|
+
| `branch "main" belongs to multiple stacks; use an interactive terminal …` | You're on trunk. Check out a stack branch, or pass the number (`gh stack merge <stack#>`). |
|
|
96
|
+
| `… is already used by worktree at <path>` | `init`/`checkout` must switch branches, and another worktree holds that branch. Run from that worktree or remove it. Note that `checkout` may already have imported the stack before failing. |
|
|
97
|
+
| `branch "<b>" already exists in a stack` | An earlier (possibly half-finished) `init` tracked it. Use `gh stack checkout`. Don't `unstack` unless you mean it, because it also removes the stack on GitHub. |
|
|
98
|
+
| `✗ failed to push <b>: … failed to push some refs` (no detail) | Almost always the pre-push hook failed, and gh stack swallows its output. Run `git push origin <b>` to see it, fix it (often env vars the hook's tests need, which you then export in the same shell), and resubmit. |
|
|
99
|
+
| `src refspec refs/heads/<b> does not match any` | The branch exists only on the remote. Run `git branch <b> origin/<b>`. |
|
|
100
|
+
| `unknown flag: --method` | Use `--squash` / `--merge` / `--rebase` or `--merge-method`. |
|
|
101
|
+
| `GraphQL: This pull request is part of a stack and must be merged using the asynchronous merge REST API` (from `gh pr merge`) | The PR is in a stack. Run `gh stack merge <n> --yes --squash` instead; it merges everything up to `<n>`. |
|
|
102
|
+
| `Merging stacked PRs via this endpoint is not supported. Use the asynchronous merge endpoint instead.` (HTTP 403, from `PUT /repos/<owner>/<repo>/pulls/<n>/merge`) | Same cause. Use `gh stack merge`. The raw fallback is `PUT …/pulls/<n>/merge-async` (returns `.details.uuid`; poll `GET …/merge-async/<uuid>` until `status: merged`). It also merges **every open PR below `<n>`**, each as its own commit on trunk, so wait for CI on all of them first. |
|
|
103
|
+
|
|
104
|
+
## Several agents or worktrees on one repo
|
|
105
|
+
|
|
106
|
+
Stack tracking lives in the repo's shared git dir, so all worktrees see and mutate it. Give **one** agent ownership of `gh stack` commands. Other agents build branches with plain git (`git switch -c <b> origin/<parent>`), push, and report. The owner then runs `gh stack link <all PRs bottom→top>` (or `init` + `submit`) to register them.
|
|
107
|
+
|
|
108
|
+
## Recovering a hand-chained stack
|
|
109
|
+
|
|
110
|
+
- **PRs are open but chained by hand:** adopt them with `gh stack init <b1> <b2> …` then `gh stack submit`. Don't fight locked bases with `gh pr edit --base`.
|
|
111
|
+
- **The parent already squash-merged:** replay only the child's commits with `git rebase --onto origin/main origin/<parent-branch> <child-branch>` (see [getting-unstuck.md](getting-unstuck.md)). Then `git push --force-with-lease`, retarget, and fix any "stacked on #…" wording in the PR body. Confirm what actually reached main with `git diff origin/<parent-branch> origin/main --stat`.
|
|
112
|
+
- **GitHub has locked the bases and the parent is gone:** merge main into the child (resolve toward the child where it is a superset), then close the trapped PR and recreate it off main.
|