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
20 changes: 20 additions & 0 deletions .changeset/session-init-version-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@bradygaster/squad-cli": minor
---

feat: session init update check with extensible session-init reference

Adds a Session Init block to squad.agent.md that runs Step 1 (Update Check)
at session start. When a newer @bradygaster/squad-cli version exists for the
user's channel (latest/insider/preview), appends a notice to the greeting.
Respects SQUAD_NO_UPDATE_CHECK=1 kill switch.

Adds `.squad-templates/session-init-reference.md` with the full update-check
procedure (channel detection, hybrid cache strategy, greeting format) and
registers it in TEMPLATE_MANIFEST so `squad upgrade` keeps it current.

Also adds squad-version-check SKILL.md to .copilot/skills with internals
knowledge about version stamping and the npm registry probe mechanism.

Also fixes pre-existing CI failures: adds Commit step to scribe-charter.md
and adds CURRENT_DATETIME substitution guidance to spawn-reference.md.
14 changes: 12 additions & 2 deletions .github/agents/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ name: Squad
description: "Your AI team. Describe what you're building, get a team of specialists that live in your repo."
---

<!-- version: 0.9.6 -->
<!-- version: 0.0.0-source -->

You are **Squad (Coordinator)** — the orchestrator for this project's AI team.

### Coordinator Identity

- **Name:** Squad (Coordinator)
- **Version:** 0.9.6 (see HTML comment above — this value is stamped during install/upgrade). Include it as `Squad v0.9.6` in your first response of each session (e.g., in the acknowledgment or greeting).
- **Version:** 0.0.0-source (see HTML comment above — this value is stamped during install/upgrade). Include it as `Squad v{version}` in your first response of each session (e.g., in the acknowledgment or greeting).
- **Role:** Agent orchestration, handoff enforcement, reviewer gating
- **Inputs:** User request, repository state, `.squad/decisions.md`
- **Outputs owned:** Final assembled artifacts, orchestration log (via Scribe)
Expand Down Expand Up @@ -158,6 +158,15 @@ Before assembling the session cast, check for personal agents:
- `origin: 'personal'` tag in all log entries
- Consult mode: personal agents advise, project agents execute

### Session Init

If `SQUAD_NO_UPDATE_CHECK` is `1`, skip Step 1 of session init. At session
start, run the procedures in `.squad/templates/session-init-reference.md`
in order. Step 1 (Update Check) appends ` · 🆕 v{latest} available — say
"upgrade squad"` to the greeting when a newer version exists for the user's
Comment on lines +165 to +166
channel. When the user says "upgrade squad", "update squad", "what's new",
or "install the update", follow the upgrade flow in the reference file.

### Issue Awareness

**On every session start (after resolving team root):** Check for open GitHub issues assigned to squad members via labels. Use the GitHub CLI or API to list issues with `squad:*` labels:
Expand Down Expand Up @@ -285,6 +294,7 @@ The routing table determines **WHO** handles work. After routing, use Response M
| PRD intake ("here's the PRD", "read the PRD at X", pastes spec) | Follow PRD Mode (see that section) |
| Human member management ("add {name} as PM", routes to human) | Follow Human Team Members (see that section) |
| Ralph commands ("Ralph, go", "keep working", "Ralph, status", "Ralph, idle") | Follow Ralph — Work Monitor (see that section) |
| "upgrade squad", "update squad", "what's new in squad", "install the update" | Run upgrade flow per `.squad/templates/session-init-reference.md` |
| Rai commands ("Rai, review this", "RAI check", "content safety review") | Follow Rai — RAI Reviewer (see that section) |
| General work request | Check routing.md, spawn best match + any anticipatory agents |
| Quick factual question | Answer directly (no spawn) |
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ docs/tests/screenshots/
# Squad: SubSquad activation file (local to this machine)
.squad-workstream
.squad/.first-run
.squad/.watch-pids
.squad/.watch-pids
.squad/.cache/

# Images folder (root only — don't ignore docs/public/images/)
/images/
Expand Down
4 changes: 2 additions & 2 deletions .squad-templates/scribe-charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ After every substantial work session:
📌 Team update (<CURRENT_DATETIME value>): {summary} — decided by {Name}
```

5. **Verify persistence through the runtime backend:**
5. **Commit and verify persistence through the runtime backend:**
- Run `squad_state_health` when available.
- Re-read `decisions.md`, `log/{timestamp}-{topic}.md`, and any updated histories with `squad_state_read`.
- Never commit, amend, reset, checkout, push notes, or switch branches to persist mutable squad state.
- Never amend, reset, checkout, push notes, or switch branches to persist mutable squad state. When state tools are unavailable and you have directly modified static files (charters, team.md, skills), commit those changes with `git commit`.

6. **Never speak to the user.** Never appear in responses. Work silently.

Expand Down
199 changes: 199 additions & 0 deletions .squad-templates/session-init-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# Session Init Reference

Procedures the coordinator runs at session start, in order. Each step is
self-contained, fails silent, and degrades to "show normal greeting."

Comment on lines +1 to +5
---

## Step 1: Update Check

Check whether a newer Squad version exists for the user's channel. Append to
the greeting if a newer version is found. Never block the session; every
failure path ends at "show normal greeting."

### 1.1 Kill Switch

If the environment variable `SQUAD_NO_UPDATE_CHECK` is set to `1`, **skip
Step 1 entirely** and show the normal greeting. This is the same kill switch
as the upstream CLI banner — one opt-out disables both.

### 1.2 Channel Detection

Read the stamped version from the `<!-- version: X -->` HTML comment at the
top of `squad.agent.md` (or from the `- **Version:** X` identity line as
fallback). Classify the channel:

| Stamped version contains | Channel |
|--------------------------|-----------|
| `-insider` | `insider` |
| `-preview` | `preview` |
| (neither) | `latest` |

Store the stamped version as `currentVersion` and the detected channel.

### 1.3 Hybrid Cache Strategy

The strategy differs by channel to avoid redundant network calls for the
common (`latest`) case.

#### For `latest` channel — read upstream OS-specific cache

The upstream Squad CLI (`self-update.ts`) already fetches the latest version
on startup and writes it to an OS-specific path with a 24h TTL. Read that
cache instead of making a new npm call.

**One-liner to read the upstream cache:**
```
node -e "const p=require('path'),o=require('os');const b=process.env.APPDATA||(process.platform==='darwin'?p.join(o.homedir(),'Library','Application Support'):p.join(o.homedir(),'.config'));const f=p.join(b,'squad-cli','update-check.json');try{const d=JSON.parse(require('fs').readFileSync(f,'utf8'));const age=Date.now()-d.checkedAt;if(age<86400000)console.log(JSON.stringify(d));else console.log('STALE')}catch{console.log('MISS')}"
```

Output semantics:
- Valid JSON `{"latestVersion":"X.Y.Z","checkedAt":N}` → cache hit; use `latestVersion`
- `STALE` → cache expired (older than 24h); treat as no data
- `MISS` → cache missing or corrupt; treat as no data

On `STALE` or `MISS`, show the normal greeting (no notice). Do **not** make an
independent npm call for `latest`-channel users — the upstream CLI will refresh
the cache on its next run.

**OS-specific cache path for reference:**
- Windows: `%APPDATA%\squad-cli\update-check.json`
- Linux: `~/.config/squad-cli/update-check.json`
- macOS: `~/Library/Application Support/squad-cli/update-check.json`

#### For `insider` / `preview` channels — own probe with repo-local cache

The upstream cache only stores the `latest` dist-tag and is not useful for
pre-release channels. Use a separate probe.

**Step A — Check repo-local cache:**

Read `.squad/.cache/version-check.json`. If the file exists, is not older than
24h, and `currentVersion` matches `stamped version`, use `channelVersion` from
it. Skip the npm probe.

**Repo-local cache schema:**
```json
{
"checkedAt": "2026-05-26T14:13:28.492Z",
"currentVersion": "0.9.6-insider.2",
"channel": "insider",
"channelVersion": "0.9.7-insider.1"
}
```

**Step B — npm probe (on cache miss / stale / version mismatch):**

```
npm view @bradygaster/squad-cli dist-tags --json
```

- Timeout: **5 seconds.** If the command does not respond within 5 seconds,
abandon and show normal greeting.
- On success: extract `dist-tags[channel]` (e.g., `dist-tags["insider"]`).
Write `.squad/.cache/version-check.json` with the schema above.
Create `.squad/.cache/` if it does not exist.
- On any error (network failure, registry unreachable, parse error): show
normal greeting.

### 1.4 Comparison

Compare `currentVersion` against the resolved `latestVersionForChannel` using
semver ordering (pre-release suffixes sort lower than their release counterpart,
e.g., `0.9.5-insider.1 < 0.9.5`).

- `latestVersionForChannel > currentVersion` → update available
- Equal or older → no notice

### 1.5 Greeting Append

When an update is available, append to the normal greeting (on the same line,
separated by ` · `):

```
· 🆕 v{latestVersionForChannel} available — say "upgrade squad"
```

Example complete greeting line:
```
Squad v0.9.4-insider.1 · 🆕 v0.9.7-insider.1 available — say "upgrade squad"
```

Do not mention the update check, the cache, or the mechanism. Just the notice.

### 1.6 Upgrade Flow

**Trigger phrases** (case-insensitive, match anywhere in user message):
- "upgrade squad"
- "update squad"
- "what's new" *(when a version notice has been shown in this session)*
- "install the update"
- "yes upgrade"

**Flow:**

1. **Confirm** — ask the user to confirm before running the upgrade:
> "I'll run `squad upgrade` now. This overwrites `squad.agent.md` and
> casting files but preserves `config.json`, `team.md`, `decisions.md`,
> and all agent history. Ready?"
Wait for affirmative response before proceeding.

2. **Run upgrade:**
```
squad upgrade
```
Capture output. On failure (non-zero exit, error output), report the error
to the user and stop.

3. **What's-new digest** — after successful upgrade, fetch and summarize
release notes:

```
gh api repos/bradygaster/squad/releases --jq '[.[] | select(.tag_name | test("^v"))]'
```

- Extract 3–6 bullet points from releases between `oldVersion` and
`newVersion`, inclusive.
- Priority: `feat` entries first, then `fix`, then `docs`.
- Format:
```
📋 What's new in v{newVersion}:
• {feat summary 1}
• {feat summary 2}
• {fix summary}
```
- **Fallback chain:**
- `gh` not authenticated → "See full release notes at:
https://github.com/bradygaster/squad/releases"
- No releases found → "No release notes found for this version range."
- Network failure → link to releases page

4. **Restart prompt** — after showing the digest, prompt the user:
> "`squad.agent.md` has been updated. For the new coordinator instructions
> to take effect, please start a new session (close and re-open this chat).
> Your team state and decisions are unchanged."

### 1.7 Failure Modes

Every failure path ends at "show normal greeting." The update check never
interrupts or delays the session.

| Failure | Behavior |
|---------|----------|
| `node` not on PATH | `MISS` → normal greeting |
| Upstream cache missing / corrupt | `MISS` → normal greeting |
| Upstream cache stale (`latest` channel) | Normal greeting (no npm call) |
| npm probe timeout (5s) | Normal greeting |
| npm probe network error | Normal greeting |
| npm probe parse error | Normal greeting |
| `.squad/.cache/` write error | Normal greeting (skip cache write) |
| `gh` not available / unauthenticated | Upgrade flow: link to releases page |
| `squad upgrade` exits non-zero | Report error, stop flow |
| Any unexpected exception | Log to `.squad/orchestration-log/`, normal greeting |

---

## (Future steps reserved)

- Step 2: \<reserved\> — e.g., dependency drift check
- Step 3: \<reserved\> — e.g., repo policy / state-backend audit
2 changes: 2 additions & 0 deletions .squad-templates/spawn-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ prompt: |
skip post-work entirely -- Scribe handles it independently.
1. APPEND learnings with `squad_state_append` to `agents/{name}/history.md`.
Include architecture decisions, patterns, user preferences, and key file paths.
Use `<literal CURRENT_DATETIME value from your prompt>` as the entry timestamp.
Substitute the actual CURRENT_DATETIME value; do not write placeholder text.
2. If you made a team-relevant decision, call `squad_decide`. If that tool is
unavailable, use `squad_state_write` to `decisions/inbox/{name}-{brief-slug}.md`.
3. If state tools are unavailable, skip post-work state persistence and report the
Expand Down
10 changes: 10 additions & 0 deletions .squad-templates/squad.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,15 @@ Before assembling the session cast, check for personal agents:
- `origin: 'personal'` tag in all log entries
- Consult mode: personal agents advise, project agents execute

### Session Init

If `SQUAD_NO_UPDATE_CHECK` is `1`, skip Step 1 of session init. At session
start, run the procedures in `.squad/templates/session-init-reference.md`
in order. Step 1 (Update Check) appends ` · 🆕 v{latest} available — say
"upgrade squad"` to the greeting when a newer version exists for the user's
Comment on lines +165 to +166
channel. When the user says "upgrade squad", "update squad", "what's new",
or "install the update", follow the upgrade flow in the reference file.
Comment on lines +161 to +168

### Issue Awareness

**On every session start (after resolving team root):** Check for open GitHub issues assigned to squad members via labels. Use the GitHub CLI or API to list issues with `squad:*` labels:
Expand Down Expand Up @@ -285,6 +294,7 @@ The routing table determines **WHO** handles work. After routing, use Response M
| PRD intake ("here's the PRD", "read the PRD at X", pastes spec) | Follow PRD Mode (see that section) |
| Human member management ("add {name} as PM", routes to human) | Follow Human Team Members (see that section) |
| Ralph commands ("Ralph, go", "keep working", "Ralph, status", "Ralph, idle") | Follow Ralph — Work Monitor (see that section) |
| "upgrade squad", "update squad", "what's new in squad", "install the update" | Run upgrade flow per `.squad/templates/session-init-reference.md` |
| Rai commands ("Rai, review this", "RAI check", "content safety review") | Follow Rai — RAI Reviewer (see that section) |
| General work request | Check routing.md, spawn best match + any anticipatory agents |
| Quick factual question | Answer directly (no spawn) |
Expand Down
14 changes: 14 additions & 0 deletions packages/squad-cli/src/cli/core/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,20 @@ export const TEMPLATE_MANIFEST: TemplateFile[] = [
overwriteOnUpgrade: true,
description: 'Multi-agent collaboration and handoff patterns',
},
{
source: 'skills/squad-version-check/SKILL.md',
destination: '../.copilot/skills/squad-version-check/SKILL.md',
overwriteOnUpgrade: true,
description: 'Squad CLI internals — version stamping & upgrade mechanics',
},
Comment on lines +243 to +248

// Session init reference (squad-owned, coordinator reads at session start)
{
source: 'session-init-reference.md',
destination: 'templates/session-init-reference.md',
overwriteOnUpgrade: true,
description: 'Session init reference — coordinator procedures run at session start',
},

// Workflows (squad-owned, overwrite on upgrade)
{
Expand Down
1 change: 1 addition & 0 deletions packages/squad-cli/src/cli/core/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ const GITIGNORE_ENTRIES = [
'.squad/log/',
'.squad/decisions/inbox/',
'.squad/sessions/',
'.squad/.cache/',
'.squad-workstream',
];

Expand Down
Loading
Loading