Skip to content

Commit 37397b2

Browse files
serbrechCopilot
andcommitted
chore: upgrade squad agent runtime to v0.9.6-build.1
Key change: two-layer state backend now uses squad_state_* MCP tools instead of raw git notes / orphan branch commands. Agents no longer hand-write mutable state — the runtime abstracts storage via squad_state_read/write/append/delete/list/health. Also adds: memory governance, new workflows, fact-checker template, loop template, and refactored templates into on-demand references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Stephane Erbrech <stephane.erbrech@gmail.com>
1 parent 5037273 commit 37397b2

43 files changed

Lines changed: 2883 additions & 1427 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/agents/squad.agent.md

Lines changed: 102 additions & 640 deletions
Large diffs are not rendered by default.

.github/workflows/squad-ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Squad CI
2+
# go project — configure build/test commands below
3+
4+
on:
5+
pull_request:
6+
branches: [dev, preview, main, insider]
7+
types: [opened, synchronize, reopened]
8+
push:
9+
branches: [dev, insider]
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
test:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Build and test
21+
run: |
22+
# TODO: Add your go build/test commands here
23+
# Go: go test ./...
24+
# Python: pip install -r requirements.txt && pytest
25+
# .NET: dotnet test
26+
# Java (Maven): mvn test
27+
# Java (Gradle): ./gradlew test
28+
echo "No build commands configured — update squad-ci.yml"

.github/workflows/squad-docs.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Squad Docs — Build & Deploy
2+
# go project — configure documentation build commands below
3+
4+
on:
5+
workflow_dispatch:
6+
push:
7+
branches: [preview]
8+
paths:
9+
- 'docs/**'
10+
- '.github/workflows/squad-docs.yml'
11+
12+
permissions:
13+
contents: read
14+
pages: write
15+
id-token: write
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Build docs
24+
run: |
25+
# TODO: Add your documentation build commands here
26+
# This workflow is optional — remove or customize it for your project
27+
echo "No docs build commands configured — update or remove squad-docs.yml"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Squad Insider Release
2+
# go project — configure build, test, and insider release commands below
3+
4+
on:
5+
push:
6+
branches: [insider]
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
19+
- name: Build and test
20+
run: |
21+
# TODO: Add your go build/test commands here
22+
# Go: go test ./...
23+
# Python: pip install -r requirements.txt && pytest
24+
# .NET: dotnet test
25+
# Java (Maven): mvn test
26+
# Java (Gradle): ./gradlew test
27+
echo "No build commands configured — update squad-insider-release.yml"
28+
29+
- name: Create insider release
30+
env:
31+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
run: |
33+
# TODO: Add your insider/pre-release commands here
34+
echo "No release commands configured — update squad-insider-release.yml"
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
name: Squad Label Enforce
2+
3+
on:
4+
issues:
5+
types: [labeled]
6+
7+
permissions:
8+
issues: write
9+
contents: read
10+
11+
jobs:
12+
enforce:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Enforce mutual exclusivity
18+
uses: actions/github-script@v7
19+
with:
20+
script: |
21+
const issue = context.payload.issue;
22+
const appliedLabel = context.payload.label.name;
23+
24+
// Namespaces with mutual exclusivity rules
25+
const EXCLUSIVE_PREFIXES = ['go:', 'release:', 'type:', 'priority:'];
26+
27+
// Skip if not a managed namespace label
28+
if (!EXCLUSIVE_PREFIXES.some(p => appliedLabel.startsWith(p))) {
29+
core.info(`Label ${appliedLabel} is not in a managed namespace — skipping`);
30+
return;
31+
}
32+
33+
const allLabels = issue.labels.map(l => l.name);
34+
35+
// Handle go: namespace (mutual exclusivity)
36+
if (appliedLabel.startsWith('go:')) {
37+
const otherGoLabels = allLabels.filter(l =>
38+
l.startsWith('go:') && l !== appliedLabel
39+
);
40+
41+
if (otherGoLabels.length > 0) {
42+
// Remove conflicting go: labels
43+
for (const label of otherGoLabels) {
44+
await github.rest.issues.removeLabel({
45+
owner: context.repo.owner,
46+
repo: context.repo.repo,
47+
issue_number: issue.number,
48+
name: label
49+
});
50+
core.info(`Removed conflicting label: ${label}`);
51+
}
52+
53+
// Post update comment
54+
await github.rest.issues.createComment({
55+
owner: context.repo.owner,
56+
repo: context.repo.repo,
57+
issue_number: issue.number,
58+
body: `🏷️ Triage verdict updated → \`${appliedLabel}\``
59+
});
60+
}
61+
62+
// Auto-apply release:backlog if go:yes and no release target
63+
if (appliedLabel === 'go:yes') {
64+
const hasReleaseLabel = allLabels.some(l => l.startsWith('release:'));
65+
if (!hasReleaseLabel) {
66+
await github.rest.issues.addLabels({
67+
owner: context.repo.owner,
68+
repo: context.repo.repo,
69+
issue_number: issue.number,
70+
labels: ['release:backlog']
71+
});
72+
73+
await github.rest.issues.createComment({
74+
owner: context.repo.owner,
75+
repo: context.repo.repo,
76+
issue_number: issue.number,
77+
body: `📋 Marked as \`release:backlog\` — assign a release target when ready.`
78+
});
79+
80+
core.info('Applied release:backlog for go:yes issue');
81+
}
82+
}
83+
84+
// Remove release: labels if go:no
85+
if (appliedLabel === 'go:no') {
86+
const releaseLabels = allLabels.filter(l => l.startsWith('release:'));
87+
if (releaseLabels.length > 0) {
88+
for (const label of releaseLabels) {
89+
await github.rest.issues.removeLabel({
90+
owner: context.repo.owner,
91+
repo: context.repo.repo,
92+
issue_number: issue.number,
93+
name: label
94+
});
95+
core.info(`Removed release label from go:no issue: ${label}`);
96+
}
97+
}
98+
}
99+
}
100+
101+
// Handle release: namespace (mutual exclusivity)
102+
if (appliedLabel.startsWith('release:')) {
103+
const otherReleaseLabels = allLabels.filter(l =>
104+
l.startsWith('release:') && l !== appliedLabel
105+
);
106+
107+
if (otherReleaseLabels.length > 0) {
108+
// Remove conflicting release: labels
109+
for (const label of otherReleaseLabels) {
110+
await github.rest.issues.removeLabel({
111+
owner: context.repo.owner,
112+
repo: context.repo.repo,
113+
issue_number: issue.number,
114+
name: label
115+
});
116+
core.info(`Removed conflicting label: ${label}`);
117+
}
118+
119+
// Post update comment
120+
await github.rest.issues.createComment({
121+
owner: context.repo.owner,
122+
repo: context.repo.repo,
123+
issue_number: issue.number,
124+
body: `🏷️ Release target updated → \`${appliedLabel}\``
125+
});
126+
}
127+
}
128+
129+
// Handle type: namespace (mutual exclusivity)
130+
if (appliedLabel.startsWith('type:')) {
131+
const otherTypeLabels = allLabels.filter(l =>
132+
l.startsWith('type:') && l !== appliedLabel
133+
);
134+
135+
if (otherTypeLabels.length > 0) {
136+
for (const label of otherTypeLabels) {
137+
await github.rest.issues.removeLabel({
138+
owner: context.repo.owner,
139+
repo: context.repo.repo,
140+
issue_number: issue.number,
141+
name: label
142+
});
143+
core.info(`Removed conflicting label: ${label}`);
144+
}
145+
146+
await github.rest.issues.createComment({
147+
owner: context.repo.owner,
148+
repo: context.repo.repo,
149+
issue_number: issue.number,
150+
body: `🏷️ Issue type updated → \`${appliedLabel}\``
151+
});
152+
}
153+
}
154+
155+
// Handle priority: namespace (mutual exclusivity)
156+
if (appliedLabel.startsWith('priority:')) {
157+
const otherPriorityLabels = allLabels.filter(l =>
158+
l.startsWith('priority:') && l !== appliedLabel
159+
);
160+
161+
if (otherPriorityLabels.length > 0) {
162+
for (const label of otherPriorityLabels) {
163+
await github.rest.issues.removeLabel({
164+
owner: context.repo.owner,
165+
repo: context.repo.repo,
166+
issue_number: issue.number,
167+
name: label
168+
});
169+
core.info(`Removed conflicting label: ${label}`);
170+
}
171+
172+
await github.rest.issues.createComment({
173+
owner: context.repo.owner,
174+
repo: context.repo.repo,
175+
issue_number: issue.number,
176+
body: `🏷️ Priority updated → \`${appliedLabel}\``
177+
});
178+
}
179+
}
180+
181+
core.info(`Label enforcement complete for ${appliedLabel}`);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Squad Preview Validation
2+
# go project — configure build, test, and validation commands below
3+
4+
on:
5+
push:
6+
branches: [preview]
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
validate:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Build and test
18+
run: |
19+
# TODO: Add your go build/test commands here
20+
# Go: go test ./...
21+
# Python: pip install -r requirements.txt && pytest
22+
# .NET: dotnet test
23+
# Java (Maven): mvn test
24+
# Java (Gradle): ./gradlew test
25+
echo "No build commands configured — update squad-preview.yml"
26+
27+
- name: Validate
28+
run: |
29+
# TODO: Add pre-release validation commands here
30+
echo "No validation commands configured — update squad-preview.yml"

0 commit comments

Comments
 (0)