main
md 199 lines 7.03 KB
Rendered Raw
1 # Session Init Reference
2
3 Procedures the coordinator runs at session start, in order. Each step is
4 self-contained, fails silent, and degrades to "show normal greeting."
5
6 ---
7
8 ## Step 1: Update Check
9
10 Check whether a newer Squad version exists for the user's channel. Append to
11 the greeting if a newer version is found. Never block the session; every
12 failure path ends at "show normal greeting."
13
14 ### 1.1 Kill Switch
15
16 If the environment variable `SQUAD_NO_UPDATE_CHECK` is set to `1`, **skip
17 Step 1 entirely** and show the normal greeting. This is the same kill switch
18 as the upstream CLI banner — one opt-out disables both.
19
20 ### 1.2 Channel Detection
21
22 Read the stamped version from the `<!-- version: X -->` HTML comment at the
23 top of `squad.agent.md` (or from the `- **Version:** X` identity line as
24 fallback). Classify the channel:
25
26 | Stamped version contains | Channel |
27 |--------------------------|-----------|
28 | `-insider` | `insider` |
29 | `-preview` | `preview` |
30 | (neither) | `latest` |
31
32 Store the stamped version as `currentVersion` and the detected channel.
33
34 ### 1.3 Hybrid Cache Strategy
35
36 The strategy differs by channel to avoid redundant network calls for the
37 common (`latest`) case.
38
39 #### For `latest` channel — read upstream OS-specific cache
40
41 The upstream Squad CLI (`self-update.ts`) already fetches the latest version
42 on startup and writes it to an OS-specific path with a 24h TTL. Read that
43 cache instead of making a new npm call.
44
45 **One-liner to read the upstream cache:**
46 ```
47 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')}"
48 ```
49
50 Output semantics:
51 - Valid JSON `{"latestVersion":"X.Y.Z","checkedAt":N}` → cache hit; use `latestVersion`
52 - `STALE` → cache expired (older than 24h); treat as no data
53 - `MISS` → cache missing or corrupt; treat as no data
54
55 On `STALE` or `MISS`, show the normal greeting (no notice). Do **not** make an
56 independent npm call for `latest`-channel users — the upstream CLI will refresh
57 the cache on its next run.
58
59 **OS-specific cache path for reference:**
60 - Windows: `%APPDATA%\squad-cli\update-check.json`
61 - Linux: `~/.config/squad-cli/update-check.json`
62 - macOS: `~/Library/Application Support/squad-cli/update-check.json`
63
64 #### For `insider` / `preview` channels — own probe with repo-local cache
65
66 The upstream cache only stores the `latest` dist-tag and is not useful for
67 pre-release channels. Use a separate probe.
68
69 **Step A — Check repo-local cache:**
70
71 Read `.squad/.cache/version-check.json`. If the file exists, is not older than
72 24h, and `currentVersion` matches `stamped version`, use `channelVersion` from
73 it. Skip the npm probe.
74
75 **Repo-local cache schema:**
76 ```json
77 {
78 "checkedAt": "2026-05-26T14:13:28.492Z",
79 "currentVersion": "0.9.6-insider.2",
80 "channel": "insider",
81 "channelVersion": "0.9.7-insider.1"
82 }
83 ```
84
85 **Step B — npm probe (on cache miss / stale / version mismatch):**
86
87 ```
88 npm view @bradygaster/squad-cli dist-tags --json
89 ```
90
91 - Timeout: **5 seconds.** If the command does not respond within 5 seconds,
92 abandon and show normal greeting.
93 - On success: extract `dist-tags[channel]` (e.g., `dist-tags["insider"]`).
94 Write `.squad/.cache/version-check.json` with the schema above.
95 Create `.squad/.cache/` if it does not exist.
96 - On any error (network failure, registry unreachable, parse error): show
97 normal greeting.
98
99 ### 1.4 Comparison
100
101 Compare `currentVersion` against the resolved `latestVersionForChannel` using
102 semver ordering (pre-release suffixes sort lower than their release counterpart,
103 e.g., `0.9.5-insider.1 < 0.9.5`).
104
105 - `latestVersionForChannel > currentVersion` → update available
106 - Equal or older → no notice
107
108 ### 1.5 Greeting Append
109
110 When an update is available, append to the normal greeting (on the same line,
111 separated by ` · `):
112
113 ```
114 · 🆕 v{latestVersionForChannel} available — say "upgrade squad"
115 ```
116
117 Example complete greeting line:
118 ```
119 Squad v0.9.4-insider.1 · 🆕 v0.9.7-insider.1 available — say "upgrade squad"
120 ```
121
122 Do not mention the update check, the cache, or the mechanism. Just the notice.
123
124 ### 1.6 Upgrade Flow
125
126 **Trigger phrases** (case-insensitive, match anywhere in user message):
127 - "upgrade squad"
128 - "update squad"
129 - "what's new" *(when a version notice has been shown in this session)*
130 - "install the update"
131 - "yes upgrade"
132
133 **Flow:**
134
135 1. **Confirm** — ask the user to confirm before running the upgrade:
136 > "I'll run `squad upgrade` now. This overwrites `squad.agent.md` and
137 > casting files but preserves `config.json`, `team.md`, `decisions.md`,
138 > and all agent history. Ready?"
139 Wait for affirmative response before proceeding.
140
141 2. **Run upgrade:**
142 ```
143 squad upgrade
144 ```
145 Capture output. On failure (non-zero exit, error output), report the error
146 to the user and stop.
147
148 3. **What's-new digest** — after successful upgrade, fetch and summarize
149 release notes:
150
151 ```
152 gh api repos/bradygaster/squad/releases --jq '[.[] | select(.tag_name | test("^v"))]'
153 ```
154
155 - Extract 3–6 bullet points from releases between `oldVersion` and
156 `newVersion`, inclusive.
157 - Priority: `feat` entries first, then `fix`, then `docs`.
158 - Format:
159 ```
160 📋 What's new in v{newVersion}:
161 • {feat summary 1}
162 • {feat summary 2}
163 • {fix summary}
164 ```
165 - **Fallback chain:**
166 - `gh` not authenticated → "See full release notes at:
167 https://github.com/bradygaster/squad/releases"
168 - No releases found → "No release notes found for this version range."
169 - Network failure → link to releases page
170
171 4. **Restart prompt** — after showing the digest, prompt the user:
172 > "`squad.agent.md` has been updated. For the new coordinator instructions
173 > to take effect, please start a new session (close and re-open this chat).
174 > Your team state and decisions are unchanged."
175
176 ### 1.7 Failure Modes
177
178 Every failure path ends at "show normal greeting." The update check never
179 interrupts or delays the session.
180
181 | Failure | Behavior |
182 |---------|----------|
183 | `node` not on PATH | `MISS` → normal greeting |
184 | Upstream cache missing / corrupt | `MISS` → normal greeting |
185 | Upstream cache stale (`latest` channel) | Normal greeting (no npm call) |
186 | npm probe timeout (5s) | Normal greeting |
187 | npm probe network error | Normal greeting |
188 | npm probe parse error | Normal greeting |
189 | `.squad/.cache/` write error | Normal greeting (skip cache write) |
190 | `gh` not available / unauthenticated | Upgrade flow: link to releases page |
191 | `squad upgrade` exits non-zero | Report error, stop flow |
192 | Any unexpected exception | Log to `.squad/orchestration-log/`, normal greeting |
193
194 ---
195
196 ## (Future steps reserved)
197
198 - Step 2: \<reserved\> — e.g., dependency drift check
199 - Step 3: \<reserved\> — e.g., repo policy / state-backend audit