@bradygaster/squad-sdk 0.8.24 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/client.d.ts +17 -0
- package/dist/adapter/client.d.ts.map +1 -1
- package/dist/adapter/client.js +101 -1
- package/dist/adapter/client.js.map +1 -1
- package/dist/agents/history-shadow.d.ts.map +1 -1
- package/dist/agents/history-shadow.js +99 -32
- package/dist/agents/history-shadow.js.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +2 -0
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/model-selector.d.ts +2 -0
- package/dist/agents/model-selector.d.ts.map +1 -1
- package/dist/agents/model-selector.js +41 -35
- package/dist/agents/model-selector.js.map +1 -1
- package/dist/agents/personal.d.ts +35 -0
- package/dist/agents/personal.d.ts.map +1 -0
- package/dist/agents/personal.js +67 -0
- package/dist/agents/personal.js.map +1 -0
- package/dist/builders/index.d.ts +3 -2
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +28 -0
- package/dist/builders/index.js.map +1 -1
- package/dist/builders/types.d.ts +13 -0
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/config/init.d.ts +8 -0
- package/dist/config/init.d.ts.map +1 -1
- package/dist/config/init.js +131 -20
- package/dist/config/init.js.map +1 -1
- package/dist/config/models.d.ts +112 -0
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +329 -18
- package/dist/config/models.js.map +1 -1
- package/dist/coordinator/index.js +2 -2
- package/dist/coordinator/index.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/platform/azure-devops.d.ts +42 -0
- package/dist/platform/azure-devops.d.ts.map +1 -1
- package/dist/platform/azure-devops.js +75 -0
- package/dist/platform/azure-devops.js.map +1 -1
- package/dist/platform/comms-file-log.d.ts.map +1 -1
- package/dist/platform/comms-file-log.js +2 -1
- package/dist/platform/comms-file-log.js.map +1 -1
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/index.js +1 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/ralph/capabilities.d.ts +67 -0
- package/dist/ralph/capabilities.d.ts.map +1 -0
- package/dist/ralph/capabilities.js +111 -0
- package/dist/ralph/capabilities.js.map +1 -0
- package/dist/ralph/index.d.ts +2 -0
- package/dist/ralph/index.d.ts.map +1 -1
- package/dist/ralph/index.js +6 -5
- package/dist/ralph/index.js.map +1 -1
- package/dist/ralph/rate-limiting.d.ts +99 -0
- package/dist/ralph/rate-limiting.d.ts.map +1 -0
- package/dist/ralph/rate-limiting.js +170 -0
- package/dist/ralph/rate-limiting.js.map +1 -0
- package/dist/resolution.d.ts +24 -2
- package/dist/resolution.d.ts.map +1 -1
- package/dist/resolution.js +106 -6
- package/dist/resolution.js.map +1 -1
- package/dist/roles/catalog-categories.d.ts +146 -0
- package/dist/roles/catalog-categories.d.ts.map +1 -0
- package/dist/roles/catalog-categories.js +374 -0
- package/dist/roles/catalog-categories.js.map +1 -0
- package/dist/roles/catalog-engineering.d.ts +212 -0
- package/dist/roles/catalog-engineering.d.ts.map +1 -0
- package/dist/roles/catalog-engineering.js +549 -0
- package/dist/roles/catalog-engineering.js.map +1 -0
- package/dist/roles/catalog.d.ts +24 -0
- package/dist/roles/catalog.d.ts.map +1 -0
- package/dist/roles/catalog.js +28 -0
- package/dist/roles/catalog.js.map +1 -0
- package/dist/roles/index.d.ts +69 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/dist/roles/index.js +197 -0
- package/dist/roles/index.js.map +1 -0
- package/dist/roles/types.d.ts +87 -0
- package/dist/roles/types.d.ts.map +1 -0
- package/dist/roles/types.js +14 -0
- package/dist/roles/types.js.map +1 -0
- package/dist/runtime/benchmarks.js +5 -5
- package/dist/runtime/benchmarks.js.map +1 -1
- package/dist/runtime/constants.d.ts +2 -2
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +5 -3
- package/dist/runtime/constants.js.map +1 -1
- package/dist/runtime/cross-squad.d.ts +118 -0
- package/dist/runtime/cross-squad.d.ts.map +1 -0
- package/dist/runtime/cross-squad.js +234 -0
- package/dist/runtime/cross-squad.js.map +1 -0
- package/dist/runtime/otel-init.d.ts +24 -17
- package/dist/runtime/otel-init.d.ts.map +1 -1
- package/dist/runtime/otel-init.js +29 -20
- package/dist/runtime/otel-init.js.map +1 -1
- package/dist/runtime/otel-metrics.d.ts +5 -0
- package/dist/runtime/otel-metrics.d.ts.map +1 -1
- package/dist/runtime/otel-metrics.js +54 -0
- package/dist/runtime/otel-metrics.js.map +1 -1
- package/dist/runtime/rework.d.ts +71 -0
- package/dist/runtime/rework.d.ts.map +1 -0
- package/dist/runtime/rework.js +107 -0
- package/dist/runtime/rework.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +128 -0
- package/dist/runtime/scheduler.d.ts.map +1 -0
- package/dist/runtime/scheduler.js +427 -0
- package/dist/runtime/scheduler.js.map +1 -0
- package/dist/runtime/squad-observer.d.ts.map +1 -1
- package/dist/runtime/squad-observer.js +4 -0
- package/dist/runtime/squad-observer.js.map +1 -1
- package/dist/runtime/streaming.d.ts +2 -0
- package/dist/runtime/streaming.d.ts.map +1 -1
- package/dist/runtime/streaming.js +6 -0
- package/dist/runtime/streaming.js.map +1 -1
- package/dist/runtime/telemetry.d.ts +2 -0
- package/dist/runtime/telemetry.d.ts.map +1 -1
- package/dist/runtime/telemetry.js +6 -0
- package/dist/runtime/telemetry.js.map +1 -1
- package/dist/sharing/consult.d.ts +2 -2
- package/dist/sharing/consult.js +6 -6
- package/dist/sharing/consult.js.map +1 -1
- package/dist/sharing/export.d.ts.map +1 -1
- package/dist/sharing/export.js +17 -4
- package/dist/sharing/export.js.map +1 -1
- package/dist/skills/handler-types.d.ts +271 -0
- package/dist/skills/handler-types.d.ts.map +1 -0
- package/dist/skills/handler-types.js +31 -0
- package/dist/skills/handler-types.js.map +1 -0
- package/dist/skills/index.d.ts +3 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +3 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/skill-script-loader.d.ts +65 -0
- package/dist/skills/skill-script-loader.d.ts.map +1 -0
- package/dist/skills/skill-script-loader.js +227 -0
- package/dist/skills/skill-script-loader.js.map +1 -0
- package/dist/skills/skill-source.d.ts.map +1 -1
- package/dist/skills/skill-source.js +5 -1
- package/dist/skills/skill-source.js.map +1 -1
- package/dist/tools/index.d.ts +10 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +49 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/upstream/resolver.d.ts.map +1 -1
- package/dist/upstream/resolver.js +14 -5
- package/dist/upstream/resolver.js.map +1 -1
- package/package.json +34 -3
- package/templates/casting/Futurama.json +10 -0
- package/templates/casting-policy.json +4 -2
- package/templates/casting-reference.md +104 -0
- package/templates/cooperative-rate-limiting.md +229 -0
- package/templates/issue-lifecycle.md +412 -0
- package/templates/keda-scaler.md +164 -0
- package/templates/machine-capabilities.md +75 -0
- package/templates/mcp-config.md +0 -8
- package/templates/orchestration-log.md +27 -27
- package/templates/package.json +3 -0
- package/templates/ralph-circuit-breaker.md +313 -0
- package/templates/ralph-triage.js +543 -0
- package/templates/routing.md +5 -20
- package/templates/schedule.json +19 -0
- package/templates/scribe-charter.md +1 -1
- package/templates/skills/agent-collaboration/SKILL.md +42 -0
- package/templates/skills/agent-conduct/SKILL.md +24 -0
- package/templates/skills/architectural-proposals/SKILL.md +151 -0
- package/templates/skills/ci-validation-gates/SKILL.md +84 -0
- package/templates/skills/cli-wiring/SKILL.md +47 -0
- package/templates/skills/client-compatibility/SKILL.md +89 -0
- package/templates/skills/cross-squad/SKILL.md +114 -0
- package/templates/skills/distributed-mesh/SKILL.md +287 -0
- package/templates/skills/distributed-mesh/mesh.json.example +30 -0
- package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
- package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
- package/templates/skills/docs-standards/SKILL.md +71 -0
- package/templates/skills/economy-mode/SKILL.md +114 -0
- package/templates/skills/external-comms/SKILL.md +329 -0
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
- package/templates/skills/git-workflow/SKILL.md +204 -0
- package/templates/skills/github-multi-account/SKILL.md +95 -0
- package/templates/skills/history-hygiene/SKILL.md +36 -0
- package/templates/skills/humanizer/SKILL.md +105 -0
- package/templates/skills/init-mode/SKILL.md +102 -0
- package/templates/skills/model-selection/SKILL.md +117 -0
- package/templates/skills/nap/SKILL.md +24 -0
- package/templates/skills/personal-squad/SKILL.md +57 -0
- package/templates/skills/release-process/SKILL.md +423 -0
- package/templates/skills/reskill/SKILL.md +92 -0
- package/templates/skills/reviewer-protocol/SKILL.md +79 -0
- package/templates/skills/secret-handling/SKILL.md +200 -0
- package/templates/skills/session-recovery/SKILL.md +155 -0
- package/templates/skills/squad-conventions/SKILL.md +69 -0
- package/templates/skills/test-discipline/SKILL.md +37 -0
- package/templates/skills/windows-compatibility/SKILL.md +74 -0
- package/templates/squad.agent.md +1287 -1146
- package/templates/workflows/squad-docs.yml +8 -4
- package/templates/workflows/squad-heartbeat.yml +55 -200
- package/templates/workflows/squad-insider-release.yml +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: secret-handling
|
|
3
|
+
description: Never read .env files or write secrets to .squad/ committed files
|
|
4
|
+
domain: security, file-operations, team-collaboration
|
|
5
|
+
confidence: high
|
|
6
|
+
source: earned (issue #267 — credential leak incident)
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives.
|
|
12
|
+
|
|
13
|
+
## Patterns
|
|
14
|
+
|
|
15
|
+
### Prohibited File Reads
|
|
16
|
+
|
|
17
|
+
**NEVER read these files:**
|
|
18
|
+
- `.env` (production secrets)
|
|
19
|
+
- `.env.local` (local dev secrets)
|
|
20
|
+
- `.env.production` (production environment)
|
|
21
|
+
- `.env.development` (development environment)
|
|
22
|
+
- `.env.staging` (staging environment)
|
|
23
|
+
- `.env.test` (test environment with real credentials)
|
|
24
|
+
- Any file matching `.env.*` UNLESS explicitly allowed (see below)
|
|
25
|
+
|
|
26
|
+
**Allowed alternatives:**
|
|
27
|
+
- `.env.example` (safe — contains placeholder values, no real secrets)
|
|
28
|
+
- `.env.sample` (safe — documentation template)
|
|
29
|
+
- `.env.template` (safe — schema/structure reference)
|
|
30
|
+
|
|
31
|
+
**If you need config info:**
|
|
32
|
+
1. **Ask the user directly** — "What's the database connection string?"
|
|
33
|
+
2. **Read `.env.example`** — shows structure without exposing secrets
|
|
34
|
+
3. **Read documentation** — check `README.md`, `docs/`, config guides
|
|
35
|
+
|
|
36
|
+
**NEVER assume you can "just peek at .env to understand the schema."** Use `.env.example` or ask.
|
|
37
|
+
|
|
38
|
+
### Prohibited Output Patterns
|
|
39
|
+
|
|
40
|
+
**NEVER write these to `.squad/` files:**
|
|
41
|
+
|
|
42
|
+
| Pattern Type | Examples | Regex Pattern (for scanning) |
|
|
43
|
+
|--------------|----------|-------------------------------|
|
|
44
|
+
| API Keys | `OPENAI_API_KEY=sk-proj-...`, `GITHUB_TOKEN=ghp_...` | `[A-Z_]+(?:KEY|TOKEN|SECRET)=[^\s]+` |
|
|
45
|
+
| Passwords | `DB_PASSWORD=super_secret_123`, `password: "..."` | `(?:PASSWORD|PASS|PWD)[:=]\s*["']?[^\s"']+` |
|
|
46
|
+
| Connection Strings | `postgres://user:pass@host:5432/db`, `Server=...;Password=...` | `(?:postgres|mysql|mongodb)://[^@]+@|(?:Server|Host)=.*(?:Password|Pwd)=` |
|
|
47
|
+
| JWT Tokens | `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...` | `eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+` |
|
|
48
|
+
| Private Keys | `-----BEGIN PRIVATE KEY-----`, `-----BEGIN RSA PRIVATE KEY-----` | `-----BEGIN [A-Z ]+PRIVATE KEY-----` |
|
|
49
|
+
| AWS Credentials | `AKIA...`, `aws_secret_access_key=...` | `AKIA[0-9A-Z]{16}|aws_secret_access_key=[^\s]+` |
|
|
50
|
+
| Email Addresses | `user@example.com` (PII violation per team decision) | `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}` |
|
|
51
|
+
|
|
52
|
+
**What to write instead:**
|
|
53
|
+
- Placeholder values: `DATABASE_URL=<set in .env>`
|
|
54
|
+
- Redacted references: `API key configured (see .env.example)`
|
|
55
|
+
- Architecture notes: "App uses JWT auth — token stored in session"
|
|
56
|
+
- Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)"
|
|
57
|
+
|
|
58
|
+
### Scribe Pre-Commit Validation
|
|
59
|
+
|
|
60
|
+
**Before committing `.squad/` changes, Scribe MUST:**
|
|
61
|
+
|
|
62
|
+
1. **Scan all staged files** for secret patterns (use regex table above)
|
|
63
|
+
2. **Check for prohibited file names** (don't commit `.env` even if manually staged)
|
|
64
|
+
3. **If secrets detected:**
|
|
65
|
+
- STOP the commit (do NOT proceed)
|
|
66
|
+
- Remove the file from staging: `git reset HEAD <file>`
|
|
67
|
+
- Report to user:
|
|
68
|
+
```
|
|
69
|
+
🚨 SECRET DETECTED — commit blocked
|
|
70
|
+
|
|
71
|
+
File: .squad/decisions/inbox/river-db-config.md
|
|
72
|
+
Pattern: DATABASE_URL=postgres://user:password@localhost:5432/prod
|
|
73
|
+
|
|
74
|
+
This file contains credentials and MUST NOT be committed.
|
|
75
|
+
Please remove the secret, replace with placeholder, and try again.
|
|
76
|
+
```
|
|
77
|
+
- Exit with error (never silently skip)
|
|
78
|
+
|
|
79
|
+
4. **If no secrets detected:**
|
|
80
|
+
- Proceed with commit as normal
|
|
81
|
+
|
|
82
|
+
**Implementation note for Scribe:**
|
|
83
|
+
- Run validation AFTER staging files, BEFORE calling `git commit`
|
|
84
|
+
- Use PowerShell `Select-String` or `git diff --cached` to scan staged content
|
|
85
|
+
- Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior
|
|
86
|
+
|
|
87
|
+
### Remediation — If a Secret Was Already Committed
|
|
88
|
+
|
|
89
|
+
**If you discover a secret in git history:**
|
|
90
|
+
|
|
91
|
+
1. **STOP immediately** — do not make more commits
|
|
92
|
+
2. **Alert the user:**
|
|
93
|
+
```
|
|
94
|
+
🚨 CREDENTIAL LEAK DETECTED
|
|
95
|
+
|
|
96
|
+
A secret was found in git history:
|
|
97
|
+
Commit: abc1234
|
|
98
|
+
File: .squad/decisions/inbox/agent-config.md
|
|
99
|
+
Pattern: API_KEY=sk-proj-...
|
|
100
|
+
|
|
101
|
+
This requires immediate remediation:
|
|
102
|
+
1. Revoke the exposed credential (regenerate API key, rotate password)
|
|
103
|
+
2. Remove from git history (git filter-repo or BFG)
|
|
104
|
+
3. Force-push the cleaned history
|
|
105
|
+
|
|
106
|
+
Do NOT proceed with new work until this is resolved.
|
|
107
|
+
```
|
|
108
|
+
3. **Do NOT attempt to fix it yourself** — secret removal requires specialized tools
|
|
109
|
+
4. **Wait for user confirmation** before resuming work
|
|
110
|
+
|
|
111
|
+
## Examples
|
|
112
|
+
|
|
113
|
+
### ✓ Correct: Reading Config Schema
|
|
114
|
+
|
|
115
|
+
**Agent needs to know what environment variables are required:**
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
Agent: "What environment variables does this app need?"
|
|
119
|
+
→ Reads `.env.example`:
|
|
120
|
+
OPENAI_API_KEY=sk-...
|
|
121
|
+
DATABASE_URL=postgres://user:pass@localhost:5432/db
|
|
122
|
+
REDIS_URL=redis://localhost:6379
|
|
123
|
+
|
|
124
|
+
→ Writes to .squad/decisions/inbox/river-env-setup.md:
|
|
125
|
+
"App requires three environment variables:
|
|
126
|
+
- OPENAI_API_KEY (OpenAI API key, format: sk-...)
|
|
127
|
+
- DATABASE_URL (Postgres connection string)
|
|
128
|
+
- REDIS_URL (Redis connection string)
|
|
129
|
+
See .env.example for full schema."
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### ✗ Incorrect: Reading Live Credentials
|
|
133
|
+
|
|
134
|
+
**Agent needs to know database schema:**
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
Agent: (reads .env)
|
|
138
|
+
DATABASE_URL=postgres://admin:super_secret_pw@prod.example.com:5432/appdb
|
|
139
|
+
|
|
140
|
+
→ Writes to .squad/decisions/inbox/river-db-schema.md:
|
|
141
|
+
"Database connection: postgres://admin:super_secret_pw@prod.example.com:5432/appdb"
|
|
142
|
+
|
|
143
|
+
🚨 VIOLATION: Live credential written to committed file
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Correct approach:**
|
|
147
|
+
```
|
|
148
|
+
Agent: (reads .env.example OR asks user)
|
|
149
|
+
User: "It's a Postgres database, schema is in migrations/"
|
|
150
|
+
|
|
151
|
+
→ Writes to .squad/decisions/inbox/river-db-schema.md:
|
|
152
|
+
"Database: Postgres (connection configured in .env). Schema defined in db/migrations/."
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### ✓ Correct: Scribe Pre-Commit Validation
|
|
156
|
+
|
|
157
|
+
**Scribe is about to commit:**
|
|
158
|
+
|
|
159
|
+
```powershell
|
|
160
|
+
# Stage files
|
|
161
|
+
git add .squad/
|
|
162
|
+
|
|
163
|
+
# Scan staged content for secrets
|
|
164
|
+
$stagedContent = git diff --cached
|
|
165
|
+
$secretPatterns = @(
|
|
166
|
+
'[A-Z_]+(?:KEY|TOKEN|SECRET)=[^\s]+',
|
|
167
|
+
'(?:PASSWORD|PASS|PWD)[:=]\s*["'']?[^\s"'']+',
|
|
168
|
+
'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+'
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
$detected = $false
|
|
172
|
+
foreach ($pattern in $secretPatterns) {
|
|
173
|
+
if ($stagedContent -match $pattern) {
|
|
174
|
+
$detected = $true
|
|
175
|
+
Write-Host "🚨 SECRET DETECTED: $($matches[0])"
|
|
176
|
+
break
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if ($detected) {
|
|
181
|
+
# Remove from staging, report, exit
|
|
182
|
+
git reset HEAD .squad/
|
|
183
|
+
Write-Error "Commit blocked — secret detected in staged files"
|
|
184
|
+
exit 1
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
# Safe to commit
|
|
188
|
+
git commit -F $msgFile
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Anti-Patterns
|
|
192
|
+
|
|
193
|
+
- ❌ Reading `.env` "just to check the schema" — use `.env.example` instead
|
|
194
|
+
- ❌ Writing "sanitized" connection strings that still contain credentials
|
|
195
|
+
- ❌ Assuming "it's just a dev environment" makes secrets safe to commit
|
|
196
|
+
- ❌ Committing first, scanning later — validation MUST happen before commit
|
|
197
|
+
- ❌ Silently skipping secret detection — fail loud, never silent
|
|
198
|
+
- ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture)
|
|
199
|
+
- ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes
|
|
200
|
+
- ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "session-recovery"
|
|
3
|
+
description: "Find and resume interrupted Copilot CLI sessions using session_store queries"
|
|
4
|
+
domain: "workflow-recovery"
|
|
5
|
+
confidence: "high"
|
|
6
|
+
source: "earned"
|
|
7
|
+
tools:
|
|
8
|
+
- name: "sql"
|
|
9
|
+
description: "Query session_store database for past session history"
|
|
10
|
+
when: "Always — session_store is the source of truth for session history"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
|
|
15
|
+
Squad agents run in Copilot CLI sessions that can be interrupted — terminal crashes, network drops, machine restarts, or accidental window closes. When this happens, in-progress work may be left in a partially-completed state: branches with uncommitted changes, issues marked in-progress with no active agent, or checkpoints that were never finalized.
|
|
16
|
+
|
|
17
|
+
Copilot CLI stores session history in a SQLite database called `session_store` (read-only, accessed via the `sql` tool with `database: "session_store"`). This skill teaches agents how to query that store to detect interrupted sessions and resume work.
|
|
18
|
+
|
|
19
|
+
## Patterns
|
|
20
|
+
|
|
21
|
+
### 1. Find Recent Sessions
|
|
22
|
+
|
|
23
|
+
Query the `sessions` table filtered by time window. Include the last checkpoint to understand where the session stopped:
|
|
24
|
+
|
|
25
|
+
```sql
|
|
26
|
+
SELECT
|
|
27
|
+
s.id,
|
|
28
|
+
s.summary,
|
|
29
|
+
s.cwd,
|
|
30
|
+
s.branch,
|
|
31
|
+
s.updated_at,
|
|
32
|
+
(SELECT title FROM checkpoints
|
|
33
|
+
WHERE session_id = s.id
|
|
34
|
+
ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
|
|
35
|
+
FROM sessions s
|
|
36
|
+
WHERE s.updated_at >= datetime('now', '-24 hours')
|
|
37
|
+
ORDER BY s.updated_at DESC;
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Filter Out Automated Sessions
|
|
41
|
+
|
|
42
|
+
Automated agents (monitors, keep-alive, heartbeat) create high-volume sessions that obscure human-initiated work. Exclude them:
|
|
43
|
+
|
|
44
|
+
```sql
|
|
45
|
+
SELECT s.id, s.summary, s.cwd, s.updated_at,
|
|
46
|
+
(SELECT title FROM checkpoints
|
|
47
|
+
WHERE session_id = s.id
|
|
48
|
+
ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
|
|
49
|
+
FROM sessions s
|
|
50
|
+
WHERE s.updated_at >= datetime('now', '-24 hours')
|
|
51
|
+
AND s.id NOT IN (
|
|
52
|
+
SELECT DISTINCT t.session_id FROM turns t
|
|
53
|
+
WHERE t.turn_index = 0
|
|
54
|
+
AND (LOWER(t.user_message) LIKE '%keep-alive%'
|
|
55
|
+
OR LOWER(t.user_message) LIKE '%heartbeat%')
|
|
56
|
+
)
|
|
57
|
+
ORDER BY s.updated_at DESC;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Search by Topic (FTS5)
|
|
61
|
+
|
|
62
|
+
Use the `search_index` FTS5 table for keyword search. Expand queries with synonyms since this is keyword-based, not semantic:
|
|
63
|
+
|
|
64
|
+
```sql
|
|
65
|
+
SELECT DISTINCT s.id, s.summary, s.cwd, s.updated_at
|
|
66
|
+
FROM search_index si
|
|
67
|
+
JOIN sessions s ON si.session_id = s.id
|
|
68
|
+
WHERE search_index MATCH 'auth OR login OR token OR JWT'
|
|
69
|
+
AND s.updated_at >= datetime('now', '-48 hours')
|
|
70
|
+
ORDER BY s.updated_at DESC
|
|
71
|
+
LIMIT 10;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 4. Search by Working Directory
|
|
75
|
+
|
|
76
|
+
```sql
|
|
77
|
+
SELECT s.id, s.summary, s.updated_at,
|
|
78
|
+
(SELECT title FROM checkpoints
|
|
79
|
+
WHERE session_id = s.id
|
|
80
|
+
ORDER BY checkpoint_number DESC LIMIT 1) AS last_checkpoint
|
|
81
|
+
FROM sessions s
|
|
82
|
+
WHERE s.cwd LIKE '%my-project%'
|
|
83
|
+
AND s.updated_at >= datetime('now', '-48 hours')
|
|
84
|
+
ORDER BY s.updated_at DESC;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 5. Get Full Session Context Before Resuming
|
|
88
|
+
|
|
89
|
+
Before resuming, inspect what the session was doing:
|
|
90
|
+
|
|
91
|
+
```sql
|
|
92
|
+
-- Conversation turns
|
|
93
|
+
SELECT turn_index, substr(user_message, 1, 200) AS ask, timestamp
|
|
94
|
+
FROM turns WHERE session_id = 'SESSION_ID' ORDER BY turn_index;
|
|
95
|
+
|
|
96
|
+
-- Checkpoint progress
|
|
97
|
+
SELECT checkpoint_number, title, overview
|
|
98
|
+
FROM checkpoints WHERE session_id = 'SESSION_ID' ORDER BY checkpoint_number;
|
|
99
|
+
|
|
100
|
+
-- Files touched
|
|
101
|
+
SELECT file_path, tool_name
|
|
102
|
+
FROM session_files WHERE session_id = 'SESSION_ID';
|
|
103
|
+
|
|
104
|
+
-- Linked PRs/issues/commits
|
|
105
|
+
SELECT ref_type, ref_value
|
|
106
|
+
FROM session_refs WHERE session_id = 'SESSION_ID';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 6. Detect Orphaned Issue Work
|
|
110
|
+
|
|
111
|
+
Find sessions that were working on issues but may not have completed:
|
|
112
|
+
|
|
113
|
+
```sql
|
|
114
|
+
SELECT DISTINCT s.id, s.branch, s.summary, s.updated_at,
|
|
115
|
+
sr.ref_type, sr.ref_value
|
|
116
|
+
FROM sessions s
|
|
117
|
+
JOIN session_refs sr ON s.id = sr.session_id
|
|
118
|
+
WHERE sr.ref_type = 'issue'
|
|
119
|
+
AND s.updated_at >= datetime('now', '-48 hours')
|
|
120
|
+
ORDER BY s.updated_at DESC;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Cross-reference with `gh issue list --label "status:in-progress"` to find issues that are marked in-progress but have no active session.
|
|
124
|
+
|
|
125
|
+
### 7. Resume a Session
|
|
126
|
+
|
|
127
|
+
Once you have the session ID:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Resume directly
|
|
131
|
+
copilot --resume SESSION_ID
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Examples
|
|
135
|
+
|
|
136
|
+
**Recovering from a crash during PR creation:**
|
|
137
|
+
1. Query recent sessions filtered by branch name
|
|
138
|
+
2. Find the session that was working on the PR
|
|
139
|
+
3. Check its last checkpoint — was the code committed? Was the PR created?
|
|
140
|
+
4. Resume or manually complete the remaining steps
|
|
141
|
+
|
|
142
|
+
**Finding yesterday's work on a feature:**
|
|
143
|
+
1. Use FTS5 search with feature keywords
|
|
144
|
+
2. Filter to the relevant working directory
|
|
145
|
+
3. Review checkpoint progress to see how far the session got
|
|
146
|
+
4. Resume if work remains, or start fresh with the context
|
|
147
|
+
|
|
148
|
+
## Anti-Patterns
|
|
149
|
+
|
|
150
|
+
- ❌ Searching by partial session IDs — always use full UUIDs
|
|
151
|
+
- ❌ Resuming sessions that completed successfully — they have no pending work
|
|
152
|
+
- ❌ Using `MATCH` with special characters without escaping — wrap paths in double quotes
|
|
153
|
+
- ❌ Skipping the automated-session filter — high-volume automated sessions will flood results
|
|
154
|
+
- ❌ Assuming FTS5 is semantic search — it's keyword-based; always expand queries with synonyms
|
|
155
|
+
- ❌ Ignoring checkpoint data — checkpoints show exactly where the session stopped
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "squad-conventions"
|
|
3
|
+
description: "Core conventions and patterns used in the Squad codebase"
|
|
4
|
+
domain: "project-conventions"
|
|
5
|
+
confidence: "high"
|
|
6
|
+
source: "manual"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
These conventions apply to all work on the Squad CLI tool (`create-squad`). Squad is a zero-dependency Node.js package that adds AI agent teams to any project. Understanding these patterns is essential before modifying any Squad source code.
|
|
11
|
+
|
|
12
|
+
## Patterns
|
|
13
|
+
|
|
14
|
+
### Zero Dependencies
|
|
15
|
+
Squad has zero runtime dependencies. Everything uses Node.js built-ins (`fs`, `path`, `os`, `child_process`). Do not add packages to `dependencies` in `package.json`. This is a hard constraint, not a preference.
|
|
16
|
+
|
|
17
|
+
### Node.js Built-in Test Runner
|
|
18
|
+
Tests use `node:test` and `node:assert/strict` — no test frameworks. Run with `npm test`. Test files live in `test/`. The test command is `node --test test/`.
|
|
19
|
+
|
|
20
|
+
### Error Handling — `fatal()` Pattern
|
|
21
|
+
All user-facing errors use the `fatal(msg)` function which prints a red `✗` prefix and exits with code 1. Never throw unhandled exceptions or print raw stack traces. The global `uncaughtException` handler calls `fatal()` as a safety net.
|
|
22
|
+
|
|
23
|
+
### ANSI Color Constants
|
|
24
|
+
Colors are defined as constants at the top of `index.js`: `GREEN`, `RED`, `DIM`, `BOLD`, `RESET`. Use these constants — do not inline ANSI escape codes.
|
|
25
|
+
|
|
26
|
+
### File Structure
|
|
27
|
+
- `.squad/` — Team state (user-owned, never overwritten by upgrades)
|
|
28
|
+
- `.squad/templates/` — Template files copied from `templates/` (Squad-owned, overwritten on upgrade)
|
|
29
|
+
- `.github/agents/squad.agent.md` — Coordinator prompt (Squad-owned, overwritten on upgrade)
|
|
30
|
+
- `templates/` — Source templates shipped with the npm package
|
|
31
|
+
- `.squad/skills/` — Team skills in SKILL.md format (user-owned)
|
|
32
|
+
- `.squad/decisions/inbox/` — Drop-box for parallel decision writes
|
|
33
|
+
|
|
34
|
+
### Windows Compatibility
|
|
35
|
+
Always use `path.join()` for file paths — never hardcode `/` or `\` separators. Squad must work on Windows, macOS, and Linux. All tests must pass on all platforms.
|
|
36
|
+
|
|
37
|
+
### Init Idempotency
|
|
38
|
+
The init flow uses a skip-if-exists pattern: if a file or directory already exists, skip it and report "already exists." Never overwrite user state during init. The upgrade flow overwrites only Squad-owned files.
|
|
39
|
+
|
|
40
|
+
### Copy Pattern
|
|
41
|
+
`copyRecursive(src, target)` handles both files and directories. It creates parent directories with `{ recursive: true }` and uses `fs.copyFileSync` for files.
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// Error handling
|
|
47
|
+
function fatal(msg) {
|
|
48
|
+
console.error(`${RED}✗${RESET} ${msg}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// File path construction (Windows-safe)
|
|
53
|
+
const agentDest = path.join(dest, '.github', 'agents', 'squad.agent.md');
|
|
54
|
+
|
|
55
|
+
// Skip-if-exists pattern
|
|
56
|
+
if (!fs.existsSync(ceremoniesDest)) {
|
|
57
|
+
fs.copyFileSync(ceremoniesSrc, ceremoniesDest);
|
|
58
|
+
console.log(`${GREEN}✓${RESET} .squad/ceremonies.md`);
|
|
59
|
+
} else {
|
|
60
|
+
console.log(`${DIM}ceremonies.md already exists — skipping${RESET}`);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Anti-Patterns
|
|
65
|
+
- **Adding npm dependencies** — Squad is zero-dep. Use Node.js built-ins only.
|
|
66
|
+
- **Hardcoded path separators** — Never use `/` or `\` directly. Always `path.join()`.
|
|
67
|
+
- **Overwriting user state on init** — Init skips existing files. Only upgrade overwrites Squad-owned files.
|
|
68
|
+
- **Raw stack traces** — All errors go through `fatal()`. Users see clean messages, not stack traces.
|
|
69
|
+
- **Inline ANSI codes** — Use the color constants (`GREEN`, `RED`, `DIM`, `BOLD`, `RESET`).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "test-discipline"
|
|
3
|
+
description: "Update tests when changing APIs — no exceptions"
|
|
4
|
+
domain: "quality"
|
|
5
|
+
confidence: "high"
|
|
6
|
+
source: "earned (Fenster/Hockney incident, test assertion sync violations)"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
When APIs or public interfaces change, tests must be updated in the same commit. When test assertions reference file counts or expected arrays, they must be kept in sync with disk reality. Stale tests block CI for other contributors.
|
|
12
|
+
|
|
13
|
+
## Patterns
|
|
14
|
+
|
|
15
|
+
- **API changes → test updates (same commit):** If you change a function signature, public interface, or exported API, update the corresponding tests before committing
|
|
16
|
+
- **Test assertions → disk reality:** When test files contain expected counts (e.g., `EXPECTED_FEATURES`, `EXPECTED_SCENARIOS`), they must match the actual files on disk
|
|
17
|
+
- **Add files → update assertions:** When adding docs pages, features, or any counted resource, update the test assertion array in the same commit
|
|
18
|
+
- **CI failures → check assertions first:** Before debugging complex failures, verify test assertion arrays match filesystem state
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
✓ **Correct:**
|
|
23
|
+
- Changed auth API signature → updated auth.test.ts in same commit
|
|
24
|
+
- Added `distributed-mesh.md` to features/ → added `'distributed-mesh'` to EXPECTED_FEATURES array
|
|
25
|
+
- Deleted two scenario files → removed entries from EXPECTED_SCENARIOS
|
|
26
|
+
|
|
27
|
+
✗ **Incorrect:**
|
|
28
|
+
- Changed spawn parameters → committed without updating casting.test.ts (CI breaks for next person)
|
|
29
|
+
- Added `built-in-roles.md` → left EXPECTED_FEATURES at old count (PR blocked)
|
|
30
|
+
- Test says "expected 7 files" but disk has 25 (assertion staleness)
|
|
31
|
+
|
|
32
|
+
## Anti-Patterns
|
|
33
|
+
|
|
34
|
+
- Committing API changes without test updates ("I'll fix tests later")
|
|
35
|
+
- Treating test assertion arrays as static (they evolve with content)
|
|
36
|
+
- Assuming CI passing means coverage is correct (stale assertions can pass while being wrong)
|
|
37
|
+
- Leaving gaps for other agents to discover
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "windows-compatibility"
|
|
3
|
+
description: "Cross-platform path handling and command patterns"
|
|
4
|
+
domain: "platform"
|
|
5
|
+
confidence: "high"
|
|
6
|
+
source: "earned (multiple Windows-specific bugs: colons in filenames, git -C failures, path separators)"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Squad runs on Windows, macOS, and Linux. Several bugs have been traced to platform-specific assumptions: ISO timestamps with colons (illegal on Windows), `git -C` with Windows paths (unreliable), forward-slash paths in Node.js on Windows.
|
|
12
|
+
|
|
13
|
+
## Patterns
|
|
14
|
+
|
|
15
|
+
### Filenames & Timestamps
|
|
16
|
+
- **Never use colons in filenames:** ISO 8601 format `2026-03-15T05:30:00Z` is illegal on Windows
|
|
17
|
+
- **Use `safeTimestamp()` utility:** Replaces colons with hyphens → `2026-03-15T05-30-00Z`
|
|
18
|
+
- **Centralize formatting:** Don't inline `.toISOString().replace(/:/g, '-')` — use the utility
|
|
19
|
+
|
|
20
|
+
### Git Commands
|
|
21
|
+
- **Never use `git -C {path}`:** Unreliable with Windows paths (backslashes, spaces, drive letters)
|
|
22
|
+
- **Always `cd` first:** Change directory, then run git commands
|
|
23
|
+
- **Check for changes before commit:** `git diff --cached --quiet` (exit 0 = no changes)
|
|
24
|
+
|
|
25
|
+
### Commit Messages
|
|
26
|
+
- **Never embed newlines in `-m` flag:** Backtick-n (`\n`) fails silently in PowerShell
|
|
27
|
+
- **Use temp file + `-F` flag:** Write message to file, commit with `git commit -F $msgFile`
|
|
28
|
+
|
|
29
|
+
### Paths
|
|
30
|
+
- **Never assume CWD is repo root:** Always use `TEAM ROOT` from spawn prompt or run `git rev-parse --show-toplevel`
|
|
31
|
+
- **Use path.join() or path.resolve():** Don't manually concatenate with `/` or `\`
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
✓ **Correct:**
|
|
36
|
+
```javascript
|
|
37
|
+
// Timestamp utility
|
|
38
|
+
const safeTimestamp = () => new Date().toISOString().replace(/:/g, '-').split('.')[0] + 'Z';
|
|
39
|
+
|
|
40
|
+
// Git workflow (PowerShell)
|
|
41
|
+
cd $teamRoot
|
|
42
|
+
git add .squad/
|
|
43
|
+
if ($LASTEXITCODE -eq 0) {
|
|
44
|
+
$msg = @"
|
|
45
|
+
docs(ai-team): session log
|
|
46
|
+
|
|
47
|
+
Changes:
|
|
48
|
+
- Added decisions
|
|
49
|
+
"@
|
|
50
|
+
$msgFile = [System.IO.Path]::GetTempFileName()
|
|
51
|
+
Set-Content -Path $msgFile -Value $msg -Encoding utf8
|
|
52
|
+
git commit -F $msgFile
|
|
53
|
+
Remove-Item $msgFile
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
✗ **Incorrect:**
|
|
58
|
+
```javascript
|
|
59
|
+
// Colon in filename
|
|
60
|
+
const logPath = `.squad/log/${new Date().toISOString()}.md`; // ILLEGAL on Windows
|
|
61
|
+
|
|
62
|
+
// git -C with Windows path
|
|
63
|
+
exec('git -C C:\\src\\squad add .squad/'); // UNRELIABLE
|
|
64
|
+
|
|
65
|
+
// Inline newlines in commit message
|
|
66
|
+
exec('git commit -m "First line\nSecond line"'); // FAILS silently in PowerShell
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Anti-Patterns
|
|
70
|
+
|
|
71
|
+
- Testing only on one platform (bugs ship to other platforms)
|
|
72
|
+
- Assuming Unix-style paths work everywhere
|
|
73
|
+
- Using `git -C` because it "looks cleaner" (it doesn't work)
|
|
74
|
+
- Skipping `git diff --cached --quiet` check (creates empty commits)
|