Files
amethyst/tools/buzz-agent/workflow-ship.sh
T
Claude 8e79abaa82 feat(cli): fewer steps to connect a Buzz agent — accept-from-channel, agent up, doctor
Collapses the operator setup from an 8-flag command + two hand-written scripts to
essentially two commands, without removing any of the safety.

- `buzz workflow run` gains `--accept-from-channel` (parity with the job
  scheduler): scope intake to the channel's kind-39002 roster instead of pasting
  every teammate key. `--worktree` now defaults to the current directory.
- Ship the gated reference wrappers (tools/buzz-agent/workflow-agent.sh →
  agent+commit; workflow-ship.sh → push+PR after the gate), split around the
  approval gate the way agent-exec.sh is the one-shot ungated version.
- `buzz agent up RELAY --repo DIR --approver NPUB` — one command: resolves the
  channel (the relay's only one, or --channel), defaults worktree/intake, extracts
  the bundled wrappers to ~/.amy/buzz-agent, and delegates to `workflow run`. The
  only thing it can't default is the human approver.
- `buzz agent doctor [--repo DIR]` — preflight that turns the security checklist
  into a green/red report: gh authenticated, token can write to the repo, default
  branch protected against force-push, worktree clean. Exits non-zero if not.
- cli build: set duplicatesStrategy on processResources (the explicit
  resources.srcDir re-adds the default root, which now doubles the bundled scripts).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mApqAbr8vkLC7gUDjavu6
2026-07-27 15:40:50 +00:00

47 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# workflow-ship.sh — the --on-approve step of `amy buzz workflow run` (the GATED path).
#
# The runner calls this ONLY after a human grants the run's 46010 approval gate. It pushes the
# run's branch and opens (or reuses) the PR, printing the PR URL as the run's result (46005). It
# NEVER touches the default branch and NEVER force-pushes — the merge stays a human action on GitHub.
#
# Contract (set by the runner):
# BUZZ_WORKTREE .... the run's git worktree (already carries the agent's commits)
# BUZZ_BRANCH ...... the run's branch to push
# BUZZ_RUN ......... the run id
# stdout ........... the PR URL → the run result (46005)
# non-zero exit .... fails the run; stderr is the detail
#
# Host requirements: git + gh authenticated with a PR-ONLY token (Contents:RW + PRs:RW on this repo),
# and branch protection on the default branch. See README.md.
set -euo pipefail
log() { printf '%s\n' "$*" >&2; }
die() { printf 'error: %s\n' "$*" >&2; exit 1; }
[[ -n "${BUZZ_WORKTREE:-}" ]] || die "BUZZ_WORKTREE unset — run this under 'amy buzz workflow run'"
[[ -n "${BUZZ_BRANCH:-}" ]] || die "BUZZ_BRANCH unset"
cd "$BUZZ_WORKTREE" || die "cannot cd into worktree $BUZZ_WORKTREE"
# The PR base = the repo's default branch. Never operate on it directly.
base_branch="$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name 2>/dev/null || echo main)"
case "$BUZZ_BRANCH" in
"$base_branch" | main | master) die "refusing to operate on the default branch ($BUZZ_BRANCH)" ;;
esac
title="$(git log -1 --format='%s' 2>/dev/null | cut -c1-72)"
[[ -n "$title" ]] || title="Buzz run ${BUZZ_RUN:-}"
log "[workflow-ship] pushing $BUZZ_BRANCH"
git push -u origin "HEAD:$BUZZ_BRANCH" || die "push failed (is a PR-only token configured?)"
pr_url="$(gh pr list --head "$BUZZ_BRANCH" --state open --json url -q '.[0].url' 2>/dev/null || true)"
if [[ -z "$pr_url" ]]; then
body="Approved via Buzz workflow run \`${BUZZ_RUN:-unknown}\`. Merge is a human action on GitHub."
pr_url="$(gh pr create --base "$base_branch" --head "$BUZZ_BRANCH" --title "$title" --body "$body" 2>/dev/null)" ||
die "gh pr create failed (PR-only token + branch protection configured?)"
fi
printf 'Opened PR: %s\n' "$pr_url"