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
537 changes: 537 additions & 0 deletions .copilot/skills/pr-lifecycle/SKILL.md

Large diffs are not rendered by default.

19 changes: 13 additions & 6 deletions .github/agents/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ You are **Squad (Coordinator)** — the orchestrator for this project's AI team.
- You may NOT generate domain artifacts (code, designs, analyses) — spawn an agent
- You may NOT bypass reviewer approval on rejected work
- You may NOT invent facts or assumptions — ask the user or spawn an agent who knows
- You may NOT do work yourself — ALWAYS delegate to a team member, even for small tasks. The only exception is Direct Mode (status checks, factual questions, and simple answers from context — see Response Mode Selection).

Check: Does `.squad/team.md` exist? (fall back to `.ai-team/team.md` for repos migrating from older installs)
- **No** → Init Mode
Expand Down Expand Up @@ -104,7 +105,7 @@ The `union` merge driver keeps all lines from both sides, which is correct for a

**If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.**

**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Pass the team root into every spawn prompt as `TEAM_ROOT` and the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted.
**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Pass the team root and the current datetime (from `<current_datetime>` in your system context) into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted.

**⚡ Context caching:** After the first message in a session, `team.md`, `routing.md`, and `registry.json` are already in your context. Do NOT re-read them on subsequent messages — you already have the roster, routing rules, and cast names. Only re-read if the user explicitly modifies the team (adds/removes members, changes routing).

Expand Down Expand Up @@ -330,6 +331,7 @@ description: "{emoji} {Name}: {brief task summary}"
prompt: |
You are {Name}, the {Role} on this project.
TEAM ROOT: {team_root}
CURRENT_DATETIME: {current_datetime}
WORKTREE_PATH: {worktree_path}
WORKTREE_MODE: {true|false}
**Requested by:** {current user name}
Expand All @@ -348,7 +350,7 @@ prompt: |
⚠️ RESPONSE ORDER: After ALL tool calls, write a plain text summary as FINAL output.
```

For read-only queries, use the explore agent: `agent_type: "explore"` with `"You are {Name}, the {Role}. {question} TEAM ROOT: {team_root}"`
For read-only queries, use the explore agent: `agent_type: "explore"` with `"You are {Name}, the {Role}. CURRENT_DATETIME: {current_datetime} — {question} TEAM ROOT: {team_root}"`

### Per-Agent Model Selection

Expand Down Expand Up @@ -499,7 +501,7 @@ The `sql` tool is **CLI-only**. It does not exist on VS Code, JetBrains, or GitH

MCP (Model Context Protocol) servers extend Squad with tools for external services — Trello, Aspire dashboards, Azure, Notion, and more. The user configures MCP servers in their environment; Squad discovers and uses them.

> **Full patterns:** Read `.squad/skills/mcp-tool-discovery/SKILL.md` for discovery patterns, domain-specific usage, graceful degradation. Read `.squad/templates/mcp-config.md` for config file locations, sample configs, and authentication notes.
> **Config details:** Read `.squad/templates/mcp-config.md` for config file locations, sample configs, and authentication notes.

#### Detection

Expand Down Expand Up @@ -623,15 +625,17 @@ Squad and all spawned agents may be running inside a **git worktree** rather tha

**How the Coordinator resolves the team root (on every session start):**

1. Run `git rev-parse --show-toplevel` to get the current worktree root.
2. Check if `.squad/` exists at that root (fall back to `.ai-team/` for repos that haven't migrated yet).
1. **Check CWD first** — does `.squad/` exist in the current working directory?
- **Yes** → Team root = CWD. This handles monorepos where `.squad/` lives in a subfolder.
2. If not, run `git rev-parse --show-toplevel` to get the current worktree root.
3. Check if `.squad/` exists at that root (fall back to `.ai-team/` for repos that haven't migrated yet).
- **Yes** → use **worktree-local** strategy. Team root = current worktree root.
- **No** → use **main-checkout** strategy. Discover the main working tree:
```
git worktree list --porcelain
```
The first `worktree` line is the main working tree. Team root = that path.
3. The user may override the strategy at any time (e.g., *"use main checkout for team state"* or *"keep team state in this worktree"*).
4. The user may override the strategy at any time (e.g., *"use main checkout for team state"* or *"keep team state in this worktree"*).

**Passing the team root to agents:**
- The Coordinator includes `TEAM_ROOT: {resolved_path}` in every spawn prompt.
Expand Down Expand Up @@ -769,6 +773,7 @@ prompt: |
{paste contents of .squad/agents/{name}/charter.md here}

TEAM ROOT: {team_root}
CURRENT_DATETIME: {current_datetime}
All `.squad/` paths are relative to this root.

PERSONAL_AGENT: {true|false} # Whether this is a personal agent
Expand Down Expand Up @@ -815,6 +820,7 @@ prompt: |
Do the work. Respond as {Name}.

⚠️ OUTPUT: Report outcomes in human terms. Never expose tool internals or SQL.
⚠️ DATES: When writing dates in any file (decisions, history, logs), use ONLY the CURRENT_DATETIME value above. Never infer or guess the date.

AFTER work:
1. APPEND to .squad/agents/{name}/history.md under "## Learnings":
Expand Down Expand Up @@ -871,6 +877,7 @@ description: "📋 Scribe: Log session & merge decisions"
prompt: |
You are the Scribe. Read .squad/agents/scribe/charter.md.
TEAM ROOT: {team_root}
CURRENT_DATETIME: {current_datetime}

SPAWN MANIFEST: {spawn_manifest}

Expand Down
50 changes: 4 additions & 46 deletions .github/workflows/squad-insider-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,15 @@ on:
branches:
- insider

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
node-version: [22]
steps:
- uses: actions/checkout@v4

# CI Hardening: Composite action replaces duplicated setup-node + retry
# pattern (item 7). See .github/actions/setup-squad-node/action.yml.
- uses: ./.github/actions/setup-squad-node
with:
node-version: ${{ matrix.node-version }}

- name: Build
run: npm run build

test:
needs: build
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
Expand Down Expand Up @@ -109,38 +94,11 @@ jobs:
- name: Build packages
run: npm -w packages/squad-sdk run build && npm -w packages/squad-cli run build

- name: Pin CLI SDK dependency to exact workspace version
run: |
SDK_VERSION=$(node -p "require('./packages/squad-sdk/package.json').version")
echo "Pinning CLI SDK dep to exact version: $SDK_VERSION"
cd packages/squad-cli
node -e "
const pkg = require('./package.json');
pkg.dependencies['@bradygaster/squad-sdk'] = '$SDK_VERSION';
require('fs').writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
"
echo "Verified: $(node -p 'require("./package.json").dependencies["@bradygaster/squad-sdk"]')"

- name: Publish squad-sdk with insider tag
run: npm -w packages/squad-sdk publish --tag insider --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Verify SDK is available on registry
run: |
SDK_VERSION=$(node -p "require('./packages/squad-sdk/package.json').version")
echo "Waiting for @bradygaster/squad-sdk@$SDK_VERSION on npm..."
for i in 1 2 3 4 5; do
if npm view "@bradygaster/squad-sdk@$SDK_VERSION" version 2>/dev/null; then
echo "✅ SDK $SDK_VERSION is live on npm"
exit 0
fi
echo "Attempt $i/5 — not yet visible, waiting 10s..."
sleep 10
done
echo "::error::SDK $SDK_VERSION not visible on npm after 50s"
exit 1

- name: Publish squad-cli with insider tag
run: npm -w packages/squad-cli publish --tag insider --access public
env:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/squad-insider-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
branches: [insider]

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: write

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/squad-npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
description: 'Version to publish (e.g., 0.9.1)'
required: true
type: string

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false
permissions:
contents: read
id-token: write
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/squad-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
branches: [preview]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/squad-promote.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
type: choice
options: ['false', 'true']

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: write

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/squad-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
branches: [main]

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

permissions:
contents: write

Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/sync-squad-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
- '.ai-team/team.md'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}
cancel-in-progress: true

permissions:
issues: write
contents: read
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ docs/src/content/docs/reference/api/
docs/tests/screenshots/
# Squad: SubSquad activation file (local to this machine)
.squad-workstream
.squad/.first-run
.squad/.first-run
.squad/.watch-pids

# Images folder (root only — don't ignore docs/public/images/)
/images/
2 changes: 0 additions & 2 deletions .squad-templates/mcp-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

MCP (Model Context Protocol) servers extend Squad with tools for external services — Trello, Aspire dashboards, Azure, Notion, and more. The user configures MCP servers in their environment; Squad discovers and uses them.

> **Full patterns:** Read `.squad/skills/mcp-tool-discovery/SKILL.md` for discovery patterns, domain-specific usage, and graceful degradation.

## Config File Locations

Users configure MCP servers at these locations (checked in priority order):
Expand Down
2 changes: 1 addition & 1 deletion .squad-templates/scribe-charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ After every substantial work session:
- **Exact duplicates:** If two blocks share the same heading, keep the first and remove the rest.
- **Overlapping decisions:** Compare block content across all remaining blocks. If two or more blocks cover the same area (same topic, same architectural concern, same component) but were written independently (different dates, different authors), consolidate them:
a. Synthesize a single merged block that combines the intent and rationale from all overlapping blocks.
b. Use today's date and a new heading: `### {today}: {consolidated topic} (consolidated)`
b. Use the CURRENT_DATETIME value from your spawn prompt and a new heading: `### {CURRENT_DATETIME}: {consolidated topic} (consolidated)`
c. Credit all original authors: `**By:** {Name1}, {Name2}`
d. Under **What:**, combine the decisions. Note any differences or evolution.
e. Under **Why:**, merge the rationale, preserving unique reasoning from each.
Expand Down
6 changes: 6 additions & 0 deletions .squad/agents/eecom/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

## Learnings

### PR #942 rebase — cherry-pick from insider-based fork branch (2026-04-12)

**Context:** PR #942 from tamirdresher's fork was retargeted from `insider` to `dev`, causing 29 files in the diff when only 3 commits (4 files relevant to dev) were the actual fix. Cherry-picked the 3 fix commits onto a clean `squad/942-rebase-type-safety` branch from dev, resolving conflicts where insider-only files (skill.ts, cross-package-exports.test.ts) didn't exist on dev. Dropped the `escapeYamlValue` import and APM YAML generation function from init.ts since skill.ts doesn't exist on dev. Opened #963 as the clean replacement, closed #942.

**Key lesson:** When cherry-picking from an insider-based branch to dev, expect modify/delete conflicts for files that only exist on insider. Always verify the base assumptions of each change — imports referencing insider-only modules must be dropped or adapted.

### Loop command: second-round review fixes (#767) (2025-07-26)

**Context:** Three Copilot review comments on PR #767: (1) `teamRoot` was set to `workTreeRoot` but `.squad/` may live in the main checkout when running inside a git worktree — should derive from `detectSquadDir().path`, (2) `generateLoopFile()` hardcoded the full loop.md scaffold inline, duplicating `templates/loop.md`, (3) docs said `gh` was optional but code hard-requires `gh copilot` unless `--agent-cmd` is passed.
Expand Down
56 changes: 51 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,31 @@ Welcome to Squad development. This guide explains how to build, test, and contri
- **Git** with SSH agent (for package resolution)
- **gh CLI** (for GitHub integration testing)

## Community Guidelines & Spam Protection

Our repository uses automated spam detection to maintain a safe, productive community. Here's what you need to know:

### Spam Detection Guidelines
- **Comment screening** — Malicious links (shortened URLs, file-sharing services) and mass-mentions are monitored
- **Issue evaluation** — New issues are reviewed for spam patterns; suspected spam may be auto-closed
- **Auto-lock stale content** — Issues and PRs inactive for 30+ days are locked to prevent spam on old threads

### What Gets Flagged
- Shortened URLs (bit.ly, tinyurl, t.co, goo.gl, rb.gy)
- File-sharing links (Dropbox, Google Drive, Mega, MediaFire)
- Crypto/investment scams ("free bitcoin", "guaranteed profit", etc.)
- Adult content patterns
- Mass-mentions (4+ @-mentions in one comment)
- New accounts (< 30 days old) with 0 repos, 0 followers + suspicious content

### If Your Content Is Flagged
- **Comment not posted** — If your comment contains flagged patterns, it may be held for review
- **Issue closed as spam** (clear violation) — Likely closed with explanation; contact maintainers if you believe this is a mistake
- **Issue labeled "suspicious"** — Flagged for maintainer review but remains open
- **Issue locked** — If inactive for 30+ days, locked to prevent spam replies

If your legitimate issue/comment is caught by spam detection, please contact a maintainer. We're here to help.

## Monorepo Structure

Squad is an npm workspace monorepo with two packages:
Expand Down Expand Up @@ -151,10 +176,33 @@ The Co-authored-by trailer is **required** for all commits (added by Copilot CLI

1. Add a changeset: `npx changeset add` (required before PR — see Changesets section)
2. Push your branch: `git push origin {yourusername}/217-readme-help-update`
3. Create a PR with explicit base and head: `gh pr create --base dev --repo bradygaster/squad --head {yourusername}:your-branch`
3. Create a PR **as a draft**: `gh pr create --draft --base dev --repo bradygaster/squad --head {yourusername}:your-branch`
4. Link the issue: Add `Closes #217` to PR description
5. Wait for CI checks to pass
6. Request review from the team (agents will respond via comments)
5. Work on your changes until CI passes and you're satisfied
6. **Mark as "Ready for review"** — this is the handoff signal to the core team (see below)

### Handoff: Contributor → Core Team

External contributors don't have write access, so the review-to-merge flow has a handoff point. Here's exactly what happens:

**Your side (contributor):**

1. ✅ All required CI checks are green (build, test, lint; changeset/CHANGELOG gate only applies when `packages/squad-cli/src/` or `packages/squad-sdk/src/` files change)
2. ✅ PR is no longer a draft — mark as **"Ready for review"**
3. ✅ Copilot reviewer bot posts its review automatically
4. ✅ Review Copilot's suggestions and manually apply any you agree with in your fork
5. ✅ Push updates to your branch to address Copilot's feedback
6. ✅ If Copilot flags issues you can't resolve, note them in a PR comment

> **Note:** Copilot review suggestions appear as comments, but the "Commit suggestion" and "Fix with Copilot" buttons require repo write access and won't work for external contributors. Review the suggestions, apply them manually in your fork, and push your changes.

**Core team side (after you undraft):**

1. Look for CI-green, undrafted PRs from contributors
2. Address any remaining Copilot review issues (using "Fix with Copilot" or manual fixes)
3. Human review, resolve threads, and merge

**TL;DR:** Your job is done when the PR is undrafted, CI is green, and you've responded to Copilot suggestions. The core team takes it from there.

### PR Readiness Checklist

Expand All @@ -170,8 +218,6 @@ An automated readiness check runs on every PR and posts a checklist comment. Add
| **No merge conflicts** | Resolve any conflicts with the target branch |
| **CI passing** | All CI checks (build, test, lint) must be green |

The readiness comment also includes a **file list with line stats** — each changed file is shown with per-file addition/deletion counts, a scope classification (Product/Infrastructure/Mixed), and totals. This helps reviewers quickly gauge PR size and impact.

The readiness check is **informational** — it helps you self-serve before a human reviewer looks at your PR. It automatically re-runs after Squad CI completes, so the checklist stays up to date without manual intervention. See `.github/PR_REQUIREMENTS.md` for the full requirements spec.

## Code Style & Conventions
Expand Down
Loading
Loading