Skip to content
Merged
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
144 changes: 144 additions & 0 deletions workflows/shared/squad.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
# Squad Bootstrap Component — installs and initializes Squad
# (https://github.com/bradygaster/squad) in the activation job, then hands off
# the generated team state to the agent job.
#
# This is the DISTRIBUTION version of the bootstrap, living under workflows/shared/
# so users can pull it via:
# gh aw add bradygaster/squad/workflows/squad.md@latest
#
# Design credit: adapted from Peli de Halleux's proven gh-aw integration in
# github/gh-aw. Original:
# https://github.com/github/gh-aw/blob/main/.github/workflows/shared/squad.md
#
# The Squad CLI is never installed or executed in the agent job — only the files it
# produces (`.squad/` team state and `.github/agents/squad.agent.md`) are restored
# there. This is deliberate: gh-aw's network firewall only constrains the agent job,
# so all install/network work happens in the unrestricted activation job.
#
# Usage (as an import in your gh-aw workflow):
# imports:
# - shared/squad.md
#
# Usage (remote import, pinned to a ref):
# imports:
# - bradygaster/squad/workflows/shared/squad.md@latest
# (Pin to a SHA for reproducible builds:
# - bradygaster/squad/workflows/shared/squad.md@<40-char-commit-sha>)
#
# How the coordinator reaches the agent: gh-aw natively restores files under
# `.github/agents/*.agent.md` as inline sub-agents. The `squad.agent.md` that
# `squad init` writes is picked up by that mechanism. Additionally, `engine.agent`
# is set to `squad`, so the compiler emits `--agent squad` on the Copilot invocation.
#
# `ambient-folders` (gh-aw main): upstream now uses a top-level
# `ambient-folders: [.squad, .github/agents]` key to bundle Squad's files into the
# standard activation artifact. That feature is unreleased on stable — once it ships,
# the explicit artifact upload/download below can be replaced.
#
# Optional custom credentials for `squad init`:
# vars.SQUAD_GITHUB_APP_ID / secrets.SQUAD_GITHUB_APP_PRIVATE_KEY / vars.SQUAD_GITHUB_APP_OWNER
# — mints a GitHub App installation token
# secrets.SQUAD_GITHUB_TOKEN
# — fallback if the App ID is not set
# Auth precedence: GitHub App installation token > SQUAD_GITHUB_TOKEN > github.token
#
# Optional custom Squad CLI version:
# vars.SQUAD_CLI_VERSION
# Default is determined by the squad-init composite action (latest release).
#
# State backend is pinned to `local`: the compiled agent invocation passes
# `--disable-builtin-mcps`, so Squad's `state-mcp` bridge does not load. A non-local
# backend would fail silently. Cross-run state does NOT persist — every run starts
# from a fresh `squad init`.
engine:
id: copilot
agent: squad

ambient-folders:
- ".squad"
- ".github/agents"

jobs:
activation:
pre-steps:
- name: Mint Squad GitHub App token
id: squad-app-token
if: ${{ vars.SQUAD_GITHUB_APP_ID != '' }}
uses: actions/create-github-app-token@v3.2.0
with:
app-id: ${{ vars.SQUAD_GITHUB_APP_ID }}
private-key: ${{ secrets.SQUAD_GITHUB_APP_PRIVATE_KEY }}
owner: ${{ vars.SQUAD_GITHUB_APP_OWNER }}

- name: Initialize Squad team
uses: bradygaster/squad/.github/actions/squad-init@dev
with:
version: ${{ vars.SQUAD_CLI_VERSION || 'latest' }}
preset: default
state-backend: local
env:
GH_TOKEN: ${{ steps.squad-app-token.outputs.token || secrets.SQUAD_GITHUB_TOKEN || github.token }}

- name: Upload Squad state artifact
if: success()
uses: actions/upload-artifact@v7.0.1
with:
name: squad-state
include-hidden-files: true
path: |
.squad
.github/agents/squad.agent.md
if-no-files-found: ignore
retention-days: 1

steps:
- name: Restore Squad state from activation artifact
continue-on-error: true
uses: actions/download-artifact@v8.0.1
with:
name: squad-state
path: ${{ github.workspace }}
---

<!--

## Squad Bootstrap Component

This shared component handles the entire Squad install/init lifecycle outside the
agent sandbox:

1. **`jobs.activation.pre-steps`** — the repository is already checked out by the
activation job. This step optionally mints a GitHub App installation token (or
uses a supplied PAT), runs Squad initialization via the `squad-init` composite
action (from bradygaster/squad/.github/actions/squad-init@dev — the npm-free
replacement for `npx @bradygaster/squad-cli`), and uploads the resulting
`.squad/` team state plus `.github/agents/squad.agent.md` as a `squad-state`
artifact — all inside the activation job with unrestricted egress.

2. **`steps:`** (agent job) — downloads the `squad-state` artifact and restores it
into the workspace. The Squad CLI is never installed here; only the files it
produced are needed.

Key difference from the .github/workflows/shared/ version: this file uses the
squad-init composite action instead of npx, eliminating the npm registry dependency.

-->

## Working with Squad

Squad's team state (`.squad/`) and its Copilot custom agent
(`.github/agents/squad.agent.md`) were initialized during activation and restored
into this checkout before you started — do **not** install Squad or run `squad init`
yourself, and do **not** try to reach the npm registry.

- Verify `.squad/team.md` exists before delegating work to the team. If it is
missing, the activation-job bootstrap step failed — call `noop` and explain
why instead of proceeding.
- Coordinate work through the Squad team already defined in `.squad/` rather
than proposing a brand-new team from scratch.
- This run uses the `local` state backend, and the Squad `state-mcp` bridge is
**not** available (the agent runs with `--disable-builtin-mcps`). Treat `.squad/`
as plain files on disk.
- State does **not** carry over between runs. The casting registry, session logs,
and any output produced live only for this run.
109 changes: 109 additions & 0 deletions workflows/squad.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
name: Squad
description: Cast, connect, or adopt a Squad AI team for your repository
emoji: "🧑‍🤝‍🧑"
private: true
on:
slash_command:
name: squad
events:
- issue_comment
- pull_request_review_comment
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
copilot-requests: write
network:
allowed:
- defaults
imports:
- shared/squad.md
tools:
bash: true
github:
mode: gh-proxy
toolsets: [default]
safe-outputs:
create-pull-request:
title-prefix: "[squad] "
labels: [squad]
max: 3
expires: 14
close-older-prs: false
---

# Squad — Unified `/squad` Slash Command

Invoked via `/squad <mode> [options]` in issue comments or PR review comments,
or manually via workflow_dispatch.

## Modes

Parse the slash command text to determine the mode:

| Command | Mode | Description |
|---------|------|-------------|
| `/squad cast` | Cast | Analyze repo and generate a new Squad team |
| `/squad connect <source>` | Connect | Link to an existing Squad source |
| `/squad adopt <url>` | Adopt | Pull squad config from a remote source |
| `/squad cast-member <spec>` | Cast Member | Add/modify a single team member |
| `/squad retire <name>` | Retire | Remove a team member |
| `/squad status` | Status | Report current team composition |
| `/squad` (no args) | Cast | Default to cast mode |

## Task

<!-- TODO: Full implementation in #1614-#1617 -->

### 1. Parse Command

Extract mode and arguments from the slash command text. Default to `cast` if
no subcommand is provided.

### 2. Execute Mode

#### Cast Mode
<!-- TODO: Full implementation in #1614 -->

1. Analyze the repository structure, languages, and conventions
2. Run `squad init` via the squad-init composite action
3. Generate `meet-the-squad.md` introducing the cast team
4. Open a PR with the `.squad/` directory and `meet-the-squad.md`

#### Connect Mode
<!-- TODO: Full implementation in #1615 -->

1. Validate the provided `<source>` URL or repo reference
2. Write `.squad/config.json` with `squadSource` pointing to the remote team
3. Open a PR with the configuration change

#### Adopt Mode
<!-- TODO: Full implementation in #1616 -->

1. Fetch squad configuration from the provided `<url>`
2. Copy `.squad/` directory contents into the local repository
3. Run any necessary migrations or version checks
4. Open a PR with the adopted squad configuration

#### Cast Member Mutation
<!-- TODO: Full implementation in #1617 -->

1. Parse the member specification from arguments
2. Modify the existing squad (add, update, or mutate the specified member)
3. Push changes to a PR branch

#### Retire Mode
<!-- TODO: Full implementation in #1617 -->

1. Locate the named member in `.squad/agents/`
2. Remove from roster in `team.md` and routing table
3. Archive the agent's charter and history
4. Push changes to a PR branch

#### Status Mode

1. Read `.squad/team.md` and parse the roster
2. Report team composition: members, roles, and status
3. Post a comment summarizing the current squad state
Loading