switchroom 0.8.1 → 0.11.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/README.md +54 -61
- package/bin/timezone-hook.sh +9 -7
- package/dist/agent-scheduler/index.js +285 -45
- package/dist/auth-broker/index.js +13932 -0
- package/dist/cli/drive-write-pretool.mjs +5418 -0
- package/dist/cli/switchroom.js +8890 -5560
- package/dist/host-control/main.js +582 -43
- package/dist/vault/approvals/kernel-server.js +276 -47
- package/dist/vault/broker/server.js +333 -69
- package/examples/minimal.yaml +63 -0
- package/examples/personal-google-workspace-mcp/.env.example +34 -0
- package/examples/personal-google-workspace-mcp/README.md +194 -0
- package/examples/personal-google-workspace-mcp/compose.yaml +66 -0
- package/examples/switchroom.yaml +220 -0
- package/package.json +6 -4
- package/profiles/_base/start.sh.hbs +3 -3
- package/profiles/_shared/agent-self-service.md.hbs +126 -0
- package/profiles/default/CLAUDE.md +10 -0
- package/profiles/default/CLAUDE.md.hbs +16 -0
- package/skills/buildkite-agent-infrastructure/SKILL.md +30 -11
- package/skills/buildkite-agent-runtime/SKILL.md +44 -11
- package/skills/buildkite-api/SKILL.md +31 -8
- package/skills/buildkite-cli/SKILL.md +27 -9
- package/skills/buildkite-migration/SKILL.md +22 -9
- package/skills/buildkite-pipelines/SKILL.md +26 -9
- package/skills/buildkite-secure-delivery/SKILL.md +23 -9
- package/skills/buildkite-test-engine/SKILL.md +25 -8
- package/skills/docx/SKILL.md +1 -1
- package/skills/file-bug/SKILL.md +34 -6
- package/skills/humanizer/SKILL.md +15 -0
- package/skills/humanizer-calibrate/SKILL.md +7 -1
- package/skills/mcp-builder/SKILL.md +1 -1
- package/skills/pdf/SKILL.md +1 -1
- package/skills/pptx/SKILL.md +1 -1
- package/skills/skill-creator/SKILL.md +21 -1
- package/skills/skill-creator/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/skill-creator/scripts/__pycache__/generate_report.cpython-313.pyc +0 -0
- package/skills/skill-creator/scripts/__pycache__/improve_description.cpython-313.pyc +0 -0
- package/skills/skill-creator/scripts/__pycache__/run_eval.cpython-313.pyc +0 -0
- package/skills/skill-creator/scripts/__pycache__/run_loop.cpython-313.pyc +0 -0
- package/skills/skill-creator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
- package/skills/switchroom-cli/SKILL.md +63 -64
- package/skills/switchroom-health/SKILL.md +23 -10
- package/skills/switchroom-install/SKILL.md +3 -3
- package/skills/switchroom-manage/SKILL.md +26 -19
- package/skills/switchroom-runtime/SKILL.md +67 -15
- package/skills/switchroom-status/SKILL.md +26 -1
- package/skills/telegram-test-harness/SKILL.md +3 -0
- package/skills/webapp-testing/SKILL.md +31 -1
- package/skills/xlsx/SKILL.md +1 -1
- package/telegram-plugin/admin-commands/dispatch.test.ts +1 -1
- package/telegram-plugin/admin-commands/index.ts +9 -5
- package/telegram-plugin/auth-snapshot-format.ts +612 -0
- package/telegram-plugin/auto-fallback-fleet.ts +215 -0
- package/telegram-plugin/auto-fallback.ts +28 -301
- package/telegram-plugin/dist/gateway/gateway.js +17453 -15100
- package/telegram-plugin/fleet-fallback-gate.ts +105 -0
- package/telegram-plugin/gateway/approval-callback.test.ts +104 -0
- package/telegram-plugin/gateway/approval-callback.ts +31 -3
- package/telegram-plugin/gateway/auth-add-flow.ts +326 -0
- package/telegram-plugin/gateway/auth-broker-client.ts +75 -0
- package/telegram-plugin/gateway/auth-command.ts +905 -0
- package/telegram-plugin/gateway/auth-line.ts +123 -0
- package/telegram-plugin/gateway/auth-status-adapter.ts +101 -0
- package/telegram-plugin/gateway/boot-card.ts +23 -37
- package/telegram-plugin/gateway/boot-probes.ts +9 -12
- package/telegram-plugin/gateway/diff-preview-card.test.ts +192 -0
- package/telegram-plugin/gateway/diff-preview-card.ts +170 -0
- package/telegram-plugin/gateway/drive-write-approval.test.ts +312 -0
- package/telegram-plugin/gateway/drive-write-approval.ts +243 -0
- package/telegram-plugin/gateway/folder-picker-handler.test.ts +314 -0
- package/telegram-plugin/gateway/folder-picker-handler.ts +348 -0
- package/telegram-plugin/gateway/gateway.ts +1156 -938
- package/telegram-plugin/gateway/hostd-dispatch.ts +244 -0
- package/telegram-plugin/gateway/ipc-protocol.ts +83 -2
- package/telegram-plugin/gateway/ipc-server.ts +69 -0
- package/telegram-plugin/hooks/sandbox-hint-posttool.mjs +103 -12
- package/telegram-plugin/hooks/tool-label-pretool.mjs +11 -0
- package/telegram-plugin/hooks/wedge-detect-posttool.mjs +303 -0
- package/telegram-plugin/model-unavailable.ts +28 -12
- package/telegram-plugin/permission-title.ts +56 -0
- package/telegram-plugin/quota-check.ts +19 -41
- package/telegram-plugin/scripts/build.mjs +0 -1
- package/telegram-plugin/shared/bot-runtime.ts +5 -4
- package/telegram-plugin/silence-poke.ts +153 -1
- package/telegram-plugin/tests/auth-add-flow.test.ts +559 -0
- package/telegram-plugin/tests/auth-code-redact.test.ts +8 -4
- package/telegram-plugin/tests/auth-command-format2.test.ts +156 -0
- package/telegram-plugin/tests/auth-command-vernacular.test.ts +531 -0
- package/telegram-plugin/tests/auth-snapshot-format.test.ts +429 -0
- package/telegram-plugin/tests/auth-status-adapter.test.ts +129 -0
- package/telegram-plugin/tests/auto-fallback-fleet.test.ts +211 -0
- package/telegram-plugin/tests/auto-fallback.test.ts +60 -358
- package/telegram-plugin/tests/boot-probes.test.ts +27 -22
- package/telegram-plugin/tests/fleet-fallback-gate.test.ts +197 -0
- package/telegram-plugin/tests/model-unavailable.test.ts +30 -5
- package/telegram-plugin/tests/permission-title.test.ts +31 -0
- package/telegram-plugin/tests/quota-check.test.ts +5 -35
- package/telegram-plugin/tests/sandbox-hint-posttool.test.ts +212 -2
- package/telegram-plugin/tests/silence-poke.test.ts +237 -0
- package/telegram-plugin/tests/turn-flush-safety.test.ts +112 -0
- package/telegram-plugin/turn-flush-safety.ts +55 -1
- package/telegram-plugin/uat/SETUP.md +35 -1
- package/telegram-plugin/uat/runners/agent-self-sufficiency.ts +457 -0
- package/telegram-plugin/uat/runners/paraphrases.ts +231 -0
- package/telegram-plugin/uat/runners/report.ts +150 -0
- package/telegram-plugin/uat/runners/run-agent-self-sufficiency.sh +50 -0
- package/telegram-plugin/uat/runners/scorer.test.ts +196 -0
- package/telegram-plugin/uat/runners/scorer.ts +106 -0
- package/telegram-plugin/uat/runners/skill-coverage.test.ts +100 -0
- package/telegram-plugin/uat/runners/skill-coverage.ts +620 -0
- package/telegram-plugin/uat/scenarios/jtbd-interrupt-marker-dm.test.ts +7 -1
- package/telegram-plugin/uat/scenarios/jtbd-rapid-followup-dm.test.ts +7 -1
- package/telegram-plugin/auth-dashboard.ts +0 -1104
- package/telegram-plugin/auth-slot-parser.ts +0 -497
- package/telegram-plugin/auto-fallback-dispatcher.ts +0 -68
- package/telegram-plugin/dist/foreman/foreman.js +0 -31358
- package/telegram-plugin/foreman/foreman-create-flow.ts +0 -202
- package/telegram-plugin/foreman/foreman-handlers.ts +0 -493
- package/telegram-plugin/foreman/foreman.ts +0 -1165
- package/telegram-plugin/foreman/setup-flow.ts +0 -345
- package/telegram-plugin/foreman/setup-state.ts +0 -239
- package/telegram-plugin/foreman/state.ts +0 -203
- package/telegram-plugin/tests/auth-account-identity-surface.test.ts +0 -118
- package/telegram-plugin/tests/auth-dashboard-edge-cases.test.ts +0 -260
- package/telegram-plugin/tests/auth-dashboard-restart-flow.test.ts +0 -140
- package/telegram-plugin/tests/auth-dashboard-v3b.test.ts +0 -559
- package/telegram-plugin/tests/auth-dashboard.test.ts +0 -1045
- package/telegram-plugin/tests/auth-slot-commands.test.ts +0 -640
- package/telegram-plugin/tests/auto-fallback-dispatcher.e2e.test.ts +0 -183
- package/telegram-plugin/tests/boot-card-account-quota.test.ts +0 -137
- package/telegram-plugin/tests/foreman-create-flow.test.ts +0 -359
- package/telegram-plugin/tests/foreman-handlers.test.ts +0 -347
- package/telegram-plugin/tests/foreman-state.test.ts +0 -164
- package/telegram-plugin/tests/foreman-write-ops.test.ts +0 -214
- package/telegram-plugin/tests/setup-flow.test.ts +0 -510
- package/telegram-plugin/tests/setup-state.test.ts +0 -146
package/README.md
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
# Switchroom
|
|
6
6
|
|
|
7
|
-
[](https://github.com/switchroom/switchroom/actions/workflows/ci-tests-core.yml)
|
|
8
|
+
[](https://github.com/switchroom/switchroom/actions/workflows/ci-tests-plugin.yml)
|
|
9
|
+
[](https://github.com/switchroom/switchroom/actions/workflows/docker-e2e.yml)
|
|
10
|
+
[](https://github.com/switchroom/switchroom/actions/workflows/ci-evals.yml)
|
|
11
|
+
[](https://github.com/switchroom/switchroom/actions/workflows/ci-evals.yml)
|
|
11
12
|
|
|
12
13
|
**A switchboard for your Pro or Max.** Your Claude subscription, as a fleet of always-on specialist agents you talk to from Telegram. Opinionated UX, done properly.
|
|
13
14
|
|
|
@@ -60,7 +61,7 @@ So I built this.
|
|
|
60
61
|
| Feature | What it does |
|
|
61
62
|
|---|---|
|
|
62
63
|
| **Progress cards** | Pinned, in-place, every tool call visible. The headline UX. |
|
|
63
|
-
| **Claude Pro/Max auth** | OAuth, not API keys. No per-token billing.
|
|
64
|
+
| **Claude Pro/Max auth** | OAuth, not API keys. No per-token billing. Fleet-wide active account + fallback order; broker-owned refresh and credential fanout. |
|
|
64
65
|
| **Approval kernel** | Inline allow/deny cards in Telegram for every gated tool. TTL'd grants, full audit trail. |
|
|
65
66
|
| **Sub-agents** | Opus plans, Sonnet implements. Sub-agent work surfaces in the parent card. |
|
|
66
67
|
| **Config cascade** | Defaults, then profiles, then per-agent YAML. Change one line, every agent updates. |
|
|
@@ -119,7 +120,7 @@ Each agent is a long-running service. They survive reboots, network drops, and y
|
|
|
119
120
|
- **Auto-restart.** Agent containers come up with `restart: unless-stopped`, and each service has a healthcheck — a crashed or wedged agent is brought back automatically. No silent dropped work.
|
|
120
121
|
- **Resume protocol.** When an agent reboots mid-turn, `start.sh` exports `SWITCHROOM_PENDING_TURN=true` plus the original chat / message ids. The agent's first action on boot is to acknowledge the gap and ask the user how to proceed (start over, summarise and continue, or drop it).
|
|
121
122
|
- **Wake-audit.** On every fresh boot the agent checks for owed replies, orphan sub-agents, and stale in-progress todos. If everything's clean it stays quiet. If it owed you a reply, it tells you.
|
|
122
|
-
- **Token refresh.**
|
|
123
|
+
- **Token refresh.** The `switchroom-auth-broker` daemon owns the refresh loop and is the sole writer of every `credentials.json`. Per-account quota state fans out across the fleet in seconds; `auth.fallback_order` cycles when an account is exhausted.
|
|
123
124
|
|
|
124
125
|
## How it stacks up
|
|
125
126
|
|
|
@@ -138,75 +139,62 @@ The wedge against OpenClaw and NanoClaw isn't the substrate — it's the stock `
|
|
|
138
139
|
|
|
139
140
|
## Install
|
|
140
141
|
|
|
141
|
-
Runs on the box you already have. The supported production runtime is Linux + Docker
|
|
142
|
+
Runs on the box you already have. The supported production runtime is Linux + Docker. **Canonical target: Ubuntu 24.04 LTS with ≥4 GiB RAM** (8 GiB recommended once you run more than one agent). Other Debian-derivatives work with the same script; non-apt distros need a manual prereq install. macOS (Docker Desktop) works for development but is not yet release-validated.
|
|
142
143
|
|
|
143
|
-
> **
|
|
144
|
+
> **Full new-user walkthrough — [`docs/install.md`](docs/install.md).** Zero to first Telegram message in ~15 minutes. Includes the [BotFather walkthrough](docs/botfather-walkthrough.md). Read that first if you're installing from scratch.
|
|
144
145
|
|
|
145
|
-
|
|
146
|
+
> **Heads up on the package name.** The npm package was originally `switchroom-ai`. It's now just `switchroom`. The old name is deprecated and will stop receiving updates — `npm install -g switchroom` is the current path.
|
|
146
147
|
|
|
147
|
-
|
|
148
|
+
### Fresh Linux box — one script
|
|
148
149
|
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
/plugin install switchroom@switchroom
|
|
152
|
-
/switchroom:setup
|
|
150
|
+
```bash
|
|
151
|
+
curl -fsSL https://github.com/switchroom/switchroom/raw/main/scripts/install-deps.sh | sudo bash
|
|
153
152
|
```
|
|
154
153
|
|
|
155
|
-
|
|
154
|
+
Installs Docker Engine + Compose v2, Node.js 20.11+, Bun, and the `@anthropic-ai/claude-code` + `switchroom` CLIs. Idempotent. Adds the invoking user to the `docker` group. Tested on Ubuntu 24.04 LTS and 26.04 LTS. Warns (does not block) on hosts under 4 GiB RAM.
|
|
156
155
|
|
|
157
|
-
|
|
156
|
+
Then log out and back in so the docker group takes effect, and:
|
|
158
157
|
|
|
159
158
|
```bash
|
|
160
|
-
|
|
159
|
+
switchroom setup # interactive: Telegram + vault + first agent
|
|
160
|
+
switchroom auth add me --from-oauth # OAuth into your Claude Pro or Max account (one flow, fleet-wide)
|
|
161
|
+
switchroom apply # write ~/.switchroom/compose/docker-compose.yml
|
|
162
|
+
docker compose -p switchroom -f ~/.switchroom/compose/docker-compose.yml up -d
|
|
161
163
|
```
|
|
162
164
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
The static binary still needs the `claude` CLI to run agents: `npm i -g @anthropic-ai/claude-code` (Node 20.11+).
|
|
165
|
+
After the last command you talk to the agent from Telegram. You don't touch the server again.
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
### Already have Docker + Node ≥ 20.11
|
|
168
168
|
|
|
169
169
|
```bash
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
chmod +x switchroom
|
|
173
|
-
sudo mv switchroom /usr/local/bin/
|
|
170
|
+
sudo npm install -g bun @anthropic-ai/claude-code switchroom
|
|
171
|
+
switchroom setup
|
|
174
172
|
```
|
|
175
173
|
|
|
176
|
-
|
|
174
|
+
`bun` is a hard runtime dep — the `switchroom` CLI's entrypoint is a Bun script. A Node-only CLI build is on the roadmap but not yet shipped.
|
|
177
175
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
**Mac (Sequoia+) one-time.** macOS 15 adds a second-stage notarization check that the `xattr` strip alone does not bypass — you may still see a Gatekeeper "cannot verify the developer" dialog the first time you run `switchroom`. `install.sh` attempts `sudo spctl --add /usr/local/bin/switchroom` automatically (best-effort, ignored if sudo isn't available). If the dialog still fires, run that `spctl --add` manually, or open System Settings → Privacy & Security → "Open Anyway" once.
|
|
176
|
+
### From inside Claude Code (the on-ramp)
|
|
181
177
|
|
|
182
|
-
|
|
178
|
+
If you already use Claude Code, this is the shortest path. Inside any session:
|
|
183
179
|
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
switchroom
|
|
188
|
-
switchroom apply # write docker-compose.yml
|
|
189
|
-
docker compose -p switchroom -f ~/.switchroom/compose/docker-compose.yml up -d
|
|
180
|
+
```
|
|
181
|
+
/plugin marketplace add switchroom/switchroom
|
|
182
|
+
/plugin install switchroom@switchroom
|
|
183
|
+
/switchroom:setup
|
|
190
184
|
```
|
|
191
185
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
### Already have node?
|
|
186
|
+
`/switchroom:setup` walks you through deps, `switchroom setup` (Telegram + vault + first agent), and `switchroom agent start`. Day-to-day: `/switchroom:start`, `/switchroom:stop`, `/switchroom:status`. See [`docs/publishing.md`](docs/publishing.md).
|
|
195
187
|
|
|
196
|
-
|
|
197
|
-
npm install -g @anthropic-ai/claude-code switchroom
|
|
198
|
-
switchroom setup
|
|
199
|
-
```
|
|
188
|
+
### Static binary (planned, not yet shipped)
|
|
200
189
|
|
|
201
|
-
Node
|
|
190
|
+
Pre-built single-binary releases (no Node or Bun required on the host) are scaffolded in [`install.sh`](install.sh) and referenced from the GitHub Releases page, but **the release workflow that publishes those binaries does not yet exist**. Until v0.9, use the one-script or npm paths above. Tracking work: switching the release pipeline to actually upload `switchroom-linux-{amd64,arm64}` and `switchroom-macos-{amd64,arm64}` on every tag.
|
|
202
191
|
|
|
203
192
|
### One-shot happy path (no wizard)
|
|
204
193
|
|
|
205
|
-
If you already have Telegram credentials in `~/.switchroom/switchroom.yaml
|
|
194
|
+
If you already have Telegram credentials in `~/.switchroom/switchroom.yaml` and one Anthropic account already added, skip `switchroom setup`. `agent create --profile` writes a minimal entry; the new agent inherits the fleet-wide active account automatically — no per-agent OAuth flow:
|
|
206
195
|
|
|
207
196
|
```bash
|
|
208
197
|
switchroom agent create coach --profile health-coach
|
|
209
|
-
switchroom auth login coach
|
|
210
198
|
switchroom apply && docker compose -p switchroom -f ~/.switchroom/compose/docker-compose.yml up -d
|
|
211
199
|
```
|
|
212
200
|
|
|
@@ -336,26 +324,29 @@ If the agent is already in yaml, `--profile` must match the existing `extends:`
|
|
|
336
324
|
|
|
337
325
|
Model aliases: the bare names `opus`, `sonnet`, `haiku` are accepted alongside the full IDs (`claude-opus-4-7`, `claude-sonnet-4-6`, `claude-haiku-4-5`). Use whichever reads cleaner in your config.
|
|
338
326
|
|
|
339
|
-
### Authentication (
|
|
327
|
+
### Authentication (one OAuth, many agents)
|
|
340
328
|
|
|
341
|
-
|
|
329
|
+
The **Anthropic account is the unit of authentication.** One OAuth flow per account, then every agent in the fleet inherits the fleet-wide active account. The `switchroom-auth-broker` daemon owns the refresh loop and is the sole writer of every `credentials.json`. Per-account quota state fans out across the fleet in seconds. See [`docs/auth.md`](docs/auth.md) for the full operator guide.
|
|
342
330
|
|
|
343
331
|
```bash
|
|
344
|
-
switchroom auth
|
|
345
|
-
switchroom auth
|
|
346
|
-
switchroom auth
|
|
347
|
-
switchroom auth
|
|
348
|
-
|
|
349
|
-
switchroom auth
|
|
350
|
-
switchroom auth
|
|
351
|
-
|
|
352
|
-
switchroom auth
|
|
353
|
-
switchroom auth
|
|
354
|
-
|
|
355
|
-
switchroom auth
|
|
332
|
+
switchroom auth add <label> --from-oauth # New account via OAuth (one flow per Anthropic account)
|
|
333
|
+
switchroom auth add <label> --from-agent <name> # Seed from an existing agent's creds
|
|
334
|
+
switchroom auth add <label> --from-credentials <path> # Import a credentials.json
|
|
335
|
+
switchroom auth add <label> --from-oauth --replace # Re-auth an existing label (drift recovery)
|
|
336
|
+
|
|
337
|
+
switchroom auth list # Accounts + health + which one is fleet-active
|
|
338
|
+
switchroom auth show [agent] # Full snapshot (fleet + agents + consumers), or one agent
|
|
339
|
+
switchroom auth use <label> # Fleet-wide active swap
|
|
340
|
+
switchroom auth rotate # Cycle to next non-exhausted in fallback_order
|
|
341
|
+
switchroom auth rm <label> # Remove an account (refused if it's the only one)
|
|
342
|
+
|
|
343
|
+
switchroom auth agent override <agent> <label> # Edge case: one agent on a different account
|
|
344
|
+
switchroom auth agent override <agent> --clear # Back to fleet active
|
|
345
|
+
|
|
346
|
+
switchroom auth refresh [label] # Diagnostic: force a refresh tick
|
|
356
347
|
```
|
|
357
348
|
|
|
358
|
-
The
|
|
349
|
+
The same surface is reachable from Telegram in any agent's chat: `/auth show` (read-only), `/auth use <label>`, `/auth rotate`. Mutating verbs are admin-gated against the per-agent `admin: true` flag (the same flag that gates `/agents`, `/restart`, `/update`, etc.). One knob to make an agent the fleet control panel.
|
|
359
350
|
|
|
360
351
|
### Workspace (agent bootstrap layer)
|
|
361
352
|
|
|
@@ -416,6 +407,8 @@ Overlay entries win on collision with built-in defaults. Unknown files that appe
|
|
|
416
407
|
|
|
417
408
|
| Guide | Description |
|
|
418
409
|
|---|---|
|
|
410
|
+
| **[Install](docs/install.md)** | Zero-to-first-message new-user walkthrough |
|
|
411
|
+
| **[BotFather walkthrough](docs/botfather-walkthrough.md)** | Step-by-step bot creation in Telegram |
|
|
419
412
|
| **[Changelog](CHANGELOG.md)** | Release notes, every version |
|
|
420
413
|
| **[Configuration](docs/configuration.md)** | Full field reference, cascade semantics, profiles |
|
|
421
414
|
| **[Vault](docs/vault.md)** | Architecture, per-cron secrets, ACL, audit log, threat model |
|
package/bin/timezone-hook.sh
CHANGED
|
@@ -10,16 +10,18 @@
|
|
|
10
10
|
# This hook fires on every UserPromptSubmit and prints a one-line hint that
|
|
11
11
|
# Claude Code prepends to the prompt as additionalContext, so the LLM sees
|
|
12
12
|
# fresh local time each turn. The resolved zone is passed in via
|
|
13
|
-
# SWITCHROOM_TIMEZONE (
|
|
14
|
-
#
|
|
15
|
-
#
|
|
13
|
+
# SWITCHROOM_TIMEZONE (set in the agent container's `environment:` block by
|
|
14
|
+
# the compose generator at `switchroom apply` time — see
|
|
15
|
+
# src/agents/compose.ts). If unset we fall back to UTC — same default as
|
|
16
|
+
# the resolver — so the hook never fails loudly.
|
|
16
17
|
#
|
|
17
18
|
# Stale-install detection: when SWITCHROOM_TIMEZONE is unset we also annotate
|
|
18
19
|
# the hint with an in-band WARNING. This makes the failure visible to the
|
|
19
20
|
# agent (and thus to the user), rather than silently emitting "UTC" while the
|
|
20
|
-
# operator's real zone is Australia/Melbourne. Typical cause:
|
|
21
|
-
#
|
|
22
|
-
#
|
|
21
|
+
# operator's real zone is Australia/Melbourne. Typical cause: the compose
|
|
22
|
+
# env block is stale because `switchroom apply` hasn't run since the
|
|
23
|
+
# operator added a `timezone:` cascade entry (or the agent container was
|
|
24
|
+
# rebuilt from an image that predates the #1198 compose-TZ wiring fix).
|
|
23
25
|
#
|
|
24
26
|
# Failure modes are silent: hooks that error block the turn in Claude Code,
|
|
25
27
|
# and a missing timezone hint is never worse than no hint at all.
|
|
@@ -46,7 +48,7 @@ ROUNDED=$(( NOW_UNIX - (NOW_UNIX % 900) ))
|
|
|
46
48
|
NOW=$(TZ="$TZ_VAL" date -d "@$ROUNDED" '+%Y-%m-%d %H:%M %Z (UTC%:z)')
|
|
47
49
|
|
|
48
50
|
if [ "$TZ_UNSET" = "1" ]; then
|
|
49
|
-
MSG="Current local time: $NOW ($TZ_VAL — WARNING: SWITCHROOM_TIMEZONE unset;
|
|
51
|
+
MSG="Current local time: $NOW ($TZ_VAL — WARNING: SWITCHROOM_TIMEZONE unset; compose env may be stale, run \`switchroom apply && switchroom agent restart <agent>\` to refresh)"
|
|
50
52
|
else
|
|
51
53
|
MSG="Current local time: $NOW ($TZ_VAL)"
|
|
52
54
|
fi
|