You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SB-062: st push command — push branches and sync stack state to backend
Epic: EP-010 (Remote-First Stack Management) Complexity: M (Medium) Depends on:#103 (SB-066 — Stack sync API endpoint)
Goal
Add st push to the stack CLI that pushes git branches to GitHub and syncs stack metadata to the Stack Bench backend API. After st push, the backend has everything it needs to render the UI — no local repo path required.
Current State
The StackProvider protocol already defines push() at:
The stack CLI state file (~/.claude/stacks/stack-bench.json) already tracks per-branch: name, tip (SHA), pr (number), and parentTip. This is exactly the payload the backend needs.
Flow
st push
├─ 1. git push origin <branch> (for each branch in stack)
├─ 2. Read stack state from ~/.claude/stacks/<repo>.json
├─ 3. POST /api/v1/stacks/{id}/sync with branch SHAs
│ (creates branches/PRs in DB if they don't exist)
└─ 4. Print sync results (SHAs updated, PRs linked)
SB-062:
st pushcommand — push branches and sync stack state to backendEpic: EP-010 (Remote-First Stack Management)
Complexity: M (Medium)
Depends on: #103 (SB-066 — Stack sync API endpoint)
Goal
Add
st pushto the stack CLI that pushes git branches to GitHub and syncs stack metadata to the Stack Bench backend API. Afterst push, the backend has everything it needs to render the UI — no local repo path required.Current State
The
StackProviderprotocol already definespush()at:app/backend/src/molecules/providers/stack_provider.py:51-53—async def push(self, stack_name: str, *, branch_positions: list[int] | None = None) -> StackResultapp/backend/src/molecules/providers/stack_cli_adapter.py:75-85—StackCLIAdapter.push()wrapsstack submit(pushes + creates PRs)The stack CLI state file (
~/.claude/stacks/stack-bench.json) already tracks per-branch:name,tip(SHA),pr(number), andparentTip. This is exactly the payload the backend needs.Flow
Implementation Steps
Stack CLI (
st pushcommand) — Add apushsubcommand that:git push origin <branch>for each/api/v1/stacks/{id}/sync)Backend sync endpoint — See SB-066: Stack sync API endpoint — update branch SHAs and PR state from GitHub #103. The
pushcommand is the primary consumer.StackCLIAdapter update — Update
app/backend/src/molecules/providers/stack_cli_adapter.pyto distinguishpush(git push only) fromsubmit(push + create PRs).API Contract (consumed by
st push)Key Files
app/backend/src/molecules/providers/stack_provider.pyStackProviderprotocol —push()methodapp/backend/src/molecules/providers/stack_cli_adapter.pypushwrapsstack submit~/.claude/stacks/stack-bench.jsonapp/backend/src/organisms/api/routers/stacks.pyapp/backend/src/molecules/apis/stack_api.pyDependencies
Acceptance Criteria
st pushpushes all stack branches to origin viagit pushst pushcalls backend sync endpoint after successful pushst push --branch 2pushes only branch at position 2