switchroom 0.11.1 → 0.12.1
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 +32 -16
- package/dist/agent-scheduler/index.js +216 -97
- package/dist/auth-broker/index.js +176 -97
- package/dist/cli/drive-write-pretool.mjs +26 -11
- package/dist/cli/skill-validate-pretool.mjs +7209 -0
- package/dist/cli/switchroom.js +45571 -42642
- package/dist/cli/ui/index.html +1281 -0
- package/dist/host-control/main.js +3628 -309
- package/dist/vault/approvals/kernel-server.js +207 -98
- package/dist/vault/broker/server.js +249 -119
- package/examples/personal-google-workspace-mcp/README.md +8 -3
- package/examples/switchroom.yaml +91 -42
- package/package.json +4 -3
- package/profiles/_base/start.sh.hbs +76 -36
- package/profiles/_shared/agent-self-service.md.hbs +1 -1
- package/profiles/default/CLAUDE.md.hbs +4 -2
- package/skills/file-bug/SKILL.md +6 -4
- package/skills/skill-creator/SKILL.md +52 -0
- package/skills/switchroom-cli/SKILL.md +20 -4
- package/skills/switchroom-install/SKILL.md +3 -3
- package/telegram-plugin/auth-snapshot-format.ts +9 -9
- package/telegram-plugin/card-format.ts +3 -3
- package/telegram-plugin/dist/bridge/bridge.js +112 -112
- package/telegram-plugin/dist/gateway/gateway.js +853 -414
- package/telegram-plugin/dist/server.js +162 -161
- package/telegram-plugin/format.ts +71 -0
- package/telegram-plugin/gateway/access-validator.test.ts +8 -8
- package/telegram-plugin/gateway/access-validator.ts +1 -1
- package/telegram-plugin/gateway/approval-card.test.ts +18 -18
- package/telegram-plugin/gateway/approval-card.ts +1 -1
- package/telegram-plugin/gateway/auth-command.ts +2 -2
- package/telegram-plugin/gateway/boot-card.ts +40 -3
- package/telegram-plugin/gateway/boot-probes.ts +114 -30
- package/telegram-plugin/gateway/diff-preview-card.test.ts +15 -15
- package/telegram-plugin/gateway/diff-preview-card.ts +1 -1
- package/telegram-plugin/gateway/drive-write-approval.test.ts +2 -2
- package/telegram-plugin/gateway/gateway.ts +265 -22
- package/telegram-plugin/gateway/update-announce.ts +167 -0
- package/telegram-plugin/quota-check.ts +0 -195
- package/telegram-plugin/recent-outbound-dedup.ts +1 -1
- package/telegram-plugin/registry/turns-schema.ts +1 -1
- package/telegram-plugin/retry-api-call.ts +24 -0
- package/telegram-plugin/server.ts +8 -5
- package/telegram-plugin/tests/auth-add-flow.test.ts +32 -3
- package/telegram-plugin/tests/auth-command-format2.test.ts +4 -4
- package/telegram-plugin/tests/auth-snapshot-format.test.ts +17 -17
- package/telegram-plugin/tests/auto-fallback-fleet.test.ts +10 -10
- package/telegram-plugin/tests/boot-probes.test.ts +90 -2
- package/telegram-plugin/tests/bot-runtime.test.ts +23 -1
- package/telegram-plugin/tests/fixtures/service-log-current-claude-code.bin +1 -1
- package/telegram-plugin/tests/fleet-state.test.ts +3 -2
- package/telegram-plugin/tests/quota-check.test.ts +0 -409
- package/telegram-plugin/tests/retry-api-call.test.ts +76 -0
- package/telegram-plugin/tests/secret-detect-audit.test.ts +1 -1
- package/telegram-plugin/tests/secret-detect-pipeline.test.ts +7 -6
- package/telegram-plugin/tests/secret-detect-suppressor-no-silent-allow.test.ts +6 -5
- package/telegram-plugin/tests/secret-detect.test.ts +8 -8
- package/telegram-plugin/tests/telegram-format.test.ts +84 -1
- package/telegram-plugin/tests/update-announce.test.ts +154 -0
- package/telegram-plugin/tests/vault-grant-inbound-builders.test.ts +8 -8
- package/telegram-plugin/tests/vault-request-access-tool.test.ts +51 -0
- package/telegram-plugin/welcome-text.ts +1 -8
- package/profiles/default/CLAUDE.md +0 -192
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-313.pyc +0 -0
- 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/telegram-plugin/first-paint.ts +0 -225
- package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/telegram-plugin/server.js +0 -41795
- package/telegram-plugin/tests/html-balanced.ts +0 -63
- package/telegram-plugin/tests/snapshot-serializer.ts +0 -79
- package/telegram-plugin/tool-error-filter.ts +0 -89
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Every time an agent starts work, a **progress card** pins into its Telegram topi
|
|
|
22
22
|
|
|
23
23
|
No silent gaps. No ghosts. No squinting into a black box.
|
|
24
24
|
|
|
25
|
-
<p align="center"><img src="docs/diagrams/progress-card-anatomy.
|
|
25
|
+
<p align="center"><img src="docs/diagrams/progress-card-anatomy.svg" width="700" alt="Annotated progress card: pin badge, user quote, last 5 steps, collapsed older, in-flight pulse, elapsed timer, sub-agent indent"></p>
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
⚙️ Working… · ⏱ 12s
|
|
@@ -87,9 +87,12 @@ You (Telegram)
|
|
|
87
87
|
├─ Progress cards ├─ Approval kernel ◄─────┤ settings.json (tools, hooks, MCP)
|
|
88
88
|
├─ Pin / unpin lifecycle │ (allow/deny broker) ├─ Hindsight plugin (memory)
|
|
89
89
|
├─ SQLite history ├─ Vault broker ◄────────┤ Drive MCP, Playwright MCP, …
|
|
90
|
-
├─ Card-events.jsonl audit
|
|
91
|
-
├─ Emoji reactions │
|
|
92
|
-
└─ Format conversion
|
|
90
|
+
├─ Card-events.jsonl audit ├─ Auth broker ◄─────────┤ in-agent scheduler sidecar
|
|
91
|
+
├─ Emoji reactions │ (OAuth refresh, └─ (cron, fires across reboots)
|
|
92
|
+
└─ Format conversion │ sole creds writer)
|
|
93
|
+
├─ hostd (host-control:
|
|
94
|
+
│ /restart, /update apply)
|
|
95
|
+
└─ Docker Compose restart (unless-stopped)
|
|
93
96
|
```
|
|
94
97
|
|
|
95
98
|
See [`docs/architecture.md`](docs/architecture.md) for the process model, IPC layout, supervisor choice, and how each layer maps to the `claude` CLI.
|
|
@@ -98,7 +101,7 @@ See [`docs/architecture.md`](docs/architecture.md) for the process model, IPC la
|
|
|
98
101
|
|
|
99
102
|
Tools that touch the world — Bash, Edit, Write, anything not on an agent's pre-approved allowlist — pause for explicit approval. Switchroom's **approval kernel** (shipped in v0.5.1) routes every gated tool call through an inline Telegram card with the actual diff or command shown. Tap Allow and the tool resumes. Tap Deny and the agent gets a clean refusal it can recover from.
|
|
100
103
|
|
|
101
|
-
<p align="center"><img src="docs/diagrams/approval-grant-flow.
|
|
104
|
+
<p align="center"><img src="docs/diagrams/approval-grant-flow.svg" width="700" alt="Approval grant flow: agent tool call pauses at the kernel, broker writes pending grant to sqlite, user taps Allow on the Telegram card, broker releases the gate, tool resumes"></p>
|
|
102
105
|
|
|
103
106
|
- **Inline cards.** Allow / Deny / Allow once / Allow for 1h. No leaving Telegram.
|
|
104
107
|
- **TTL'd grants.** "Allow Bash for 1h" expires automatically. No silent permanent escalation.
|
|
@@ -115,7 +118,7 @@ Switchroom never intercepts auth, never proxies inference, never patches the CLI
|
|
|
115
118
|
|
|
116
119
|
Each agent is a long-running service. They survive reboots, network drops, and your laptop closing. But "always on" isn't enough on its own. Things still die. The product has to handle that gracefully or the illusion breaks.
|
|
117
120
|
|
|
118
|
-
<p align="center"><img src="docs/diagrams/wake-audit-lifecycle.
|
|
121
|
+
<p align="center"><img src="docs/diagrams/wake-audit-lifecycle.svg" width="700" alt="Wake-audit lifecycle: kill, crash-pane snapshot, auto-restart, agent boots with SWITCHROOM_PENDING_TURN, acks with three options"></p>
|
|
119
122
|
|
|
120
123
|
- **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.
|
|
121
124
|
- **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).
|
|
@@ -157,12 +160,13 @@ Then log out and back in so the docker group takes effect, and:
|
|
|
157
160
|
|
|
158
161
|
```bash
|
|
159
162
|
switchroom setup # interactive: Telegram + vault + first agent
|
|
160
|
-
switchroom
|
|
161
|
-
switchroom
|
|
162
|
-
|
|
163
|
+
switchroom apply # regenerate ~/.switchroom/compose/docker-compose.yml
|
|
164
|
+
docker compose -p switchroom -f ~/.switchroom/compose/docker-compose.yml up -d # bring the fleet up
|
|
165
|
+
switchroom auth add default --via-claude # OAuth your Claude Pro/Max account — run AFTER the fleet is up
|
|
166
|
+
switchroom auth use default # make it the fleet-wide active account
|
|
163
167
|
```
|
|
164
168
|
|
|
165
|
-
|
|
169
|
+
Auth comes *after* the fleet is up on purpose: the `switchroom-auth-broker` is the sole writer of credentials and doesn't exist until the compose stack is running (`switchroom auth …` beforehand just prints a "fleet not up" hint). After this you talk to the agent from Telegram and don't touch the server again. To catch a running host up later — pull images, refresh scaffolds, recreate — use **`switchroom update`**, not a raw `docker compose up` (a bare compose-up on a live fleet skips the operator restart-marker, so the boot cards render as crashes).
|
|
166
170
|
|
|
167
171
|
### Already have Docker + Node ≥ 20.11
|
|
168
172
|
|
|
@@ -187,7 +191,7 @@ If you already use Claude Code, this is the shortest path. Inside any session:
|
|
|
187
191
|
|
|
188
192
|
### Static binary (planned, not yet shipped)
|
|
189
193
|
|
|
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
|
|
194
|
+
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 still does not exist as of v0.12.0**. 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.
|
|
191
195
|
|
|
192
196
|
### One-shot happy path (no wizard)
|
|
193
197
|
|
|
@@ -292,7 +296,8 @@ Disable with `switchroom vault broker disable-auto-unlock`.
|
|
|
292
296
|
```bash
|
|
293
297
|
switchroom setup # Interactive wizard
|
|
294
298
|
switchroom doctor # Health check
|
|
295
|
-
switchroom apply # Reconcile +
|
|
299
|
+
switchroom apply # Reconcile + regenerate docker-compose.yml (self-elevates via sudo for scaffolds). Does NOT run docker — prints the `up` command
|
|
300
|
+
switchroom update [--check|--status|--rebuild] # Operator catch-up: pull images + apply + recreate fleet + doctor
|
|
296
301
|
switchroom restart [agent] [--force] # Bounce agent(s); drains in-flight turn by default
|
|
297
302
|
switchroom version # Show versions + running agent health summary
|
|
298
303
|
|
|
@@ -304,15 +309,23 @@ switchroom agent bootstrap <name> --profile <p> --bot-token <t> # One-shot scaf
|
|
|
304
309
|
switchroom agent reconcile <name|all> # Re-apply switchroom.yaml (without pulling/building)
|
|
305
310
|
switchroom agent start|stop|restart <name> # Lifecycle (with preflight)
|
|
306
311
|
switchroom agent interrupt <name> # Cancel in-flight turn without restarting
|
|
312
|
+
switchroom agent unquarantine <name> # Clear a crash-quarantine and resume supervision
|
|
307
313
|
switchroom agent rename <old> <new> # Rename an agent slug (#168)
|
|
308
314
|
switchroom agent destroy <name> # Remove from compose + scaffold dir
|
|
309
315
|
switchroom agent attach <name> # Interactive tmux session
|
|
316
|
+
switchroom agent send <name> <slash-cmd> # Inject a slash command into the agent's tmux pane
|
|
310
317
|
switchroom agent logs <name> [-f] # View logs
|
|
311
318
|
switchroom agent grant <name> <tool> # Grant a tool permission
|
|
312
319
|
switchroom agent permissions <name> # Show allow/deny list
|
|
313
320
|
switchroom agent dangerous <name> [off] # Toggle full tool access
|
|
321
|
+
|
|
322
|
+
switchroom soul path|show|reset <name> # Manage the agent's user-owned SOUL.md (persona)
|
|
323
|
+
switchroom hostd install|status|uninstall|audit # Host-control daemon (/restart, /update apply, …)
|
|
324
|
+
switchroom drive connect|disconnect <agent> # Per-agent Google Drive OAuth
|
|
314
325
|
```
|
|
315
326
|
|
|
327
|
+
`switchroom --help` lists every verb (also `deps`, `issues`, `migrate`).
|
|
328
|
+
|
|
316
329
|
Profiles live in `profiles/` at the repo root. Bundled ones for `--profile`: `coding`, `default`, `executive-assistant`, `health-coach` (the `_base/` dir is framework-internal render templates and is not a user-selectable profile).
|
|
317
330
|
|
|
318
331
|
`switchroom agent create <name> --profile <profile>` does two things in one step:
|
|
@@ -329,10 +342,11 @@ Model aliases: the bare names `opus`, `sonnet`, `haiku` are accepted alongside t
|
|
|
329
342
|
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.
|
|
330
343
|
|
|
331
344
|
```bash
|
|
332
|
-
switchroom auth add <label> --
|
|
345
|
+
switchroom auth add <label> --via-claude # New account, broader scope — recommended for first-time
|
|
346
|
+
switchroom auth add <label> --from-oauth # Narrow scope=user:inference (rejected by agents in server: mode)
|
|
333
347
|
switchroom auth add <label> --from-agent <name> # Seed from an existing agent's creds
|
|
334
348
|
switchroom auth add <label> --from-credentials <path> # Import a credentials.json
|
|
335
|
-
switchroom auth add <label> --
|
|
349
|
+
switchroom auth add <label> --via-claude --replace # Re-auth an existing label (drift recovery)
|
|
336
350
|
|
|
337
351
|
switchroom auth list # Accounts + health + which one is fleet-active
|
|
338
352
|
switchroom auth show [agent] # Full snapshot (fleet + agents + consumers), or one agent
|
|
@@ -350,7 +364,9 @@ The same surface is reachable from Telegram in any agent's chat: `/auth show` (r
|
|
|
350
364
|
|
|
351
365
|
### Workspace (agent bootstrap layer)
|
|
352
366
|
|
|
353
|
-
Each agent has a workspace directory (`~/.switchroom/agents/<name>/workspace/`) with editable stable files (`AGENTS.md`, `
|
|
367
|
+
Each agent has a workspace directory (`~/.switchroom/agents/<name>/workspace/`) with editable stable files (`AGENTS.md`, `USER.md`, `IDENTITY.md`, `TOOLS.md`) and dynamic files (`MEMORY.md`, `memory/YYYY-MM-DD.md`, `HEARTBEAT.md`) injected into the model's context at turn time.
|
|
368
|
+
|
|
369
|
+
`SOUL.md` (the persona) is a special case since v0.12.0: it's **user-owned and seeded once** — switchroom writes it at first scaffold (from the setup wizard's persona prompts or the profile default) and then *never overwrites it*, the deliberate inverse of the switchroom-managed `CLAUDE.md`. Edit it freely; `switchroom update` won't touch it. Use `switchroom soul reset <agent>` to re-seed from the profile (it backs the old one up first). See [docs/configuration.md § Persona & SOUL.md ownership](docs/configuration.md#persona--soulmd-ownership).
|
|
354
370
|
|
|
355
371
|
```bash
|
|
356
372
|
switchroom workspace path <agent> # Print the workspace dir
|
|
@@ -414,7 +430,7 @@ Overlay entries win on collision with built-in defaults. Unknown files that appe
|
|
|
414
430
|
| **[Vault](docs/vault.md)** | Architecture, per-cron secrets, ACL, audit log, threat model |
|
|
415
431
|
| **[Telegram Plugin](docs/telegram-plugin.md)** | Progress cards, 15 MCP tools, native checklists, sticker aliases, voice-in |
|
|
416
432
|
| **[Sub-Agents](docs/sub-agents.md)** | Model routing, delegation patterns, frontmatter spec |
|
|
417
|
-
| **[Scheduling](docs/scheduling.md)** | Cron tasks (
|
|
433
|
+
| **[Scheduling](docs/scheduling.md)** | Cron tasks (in-agent scheduler sidecar), model selection |
|
|
418
434
|
| **[Session Management](docs/session-optimization.md)** | Continuity, compaction, freshness policy |
|
|
419
435
|
| **[OpenClaw alternative](docs/vs-openclaw.md)** | Switchroom vs OpenClaw |
|
|
420
436
|
| **[NanoClaw alternative](docs/vs-nanoclaw.md)** | Switchroom vs NanoClaw |
|