switchroom 0.14.7 → 0.14.9
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/cli/switchroom.js +40 -2
- package/package.json +1 -1
- package/profiles/_base/start.sh.hbs +23 -0
- package/telegram-plugin/dist/gateway/gateway.js +397 -225
- package/telegram-plugin/gateway/config-approval-handler.ts +36 -0
- package/telegram-plugin/gateway/gateway.ts +285 -225
- package/telegram-plugin/gateway/hostd-dispatch.ts +2 -1
- package/telegram-plugin/permission-diff.ts +382 -0
- package/telegram-plugin/tests/always-allow-correlation.test.ts +147 -0
- package/telegram-plugin/tests/always-allow-grant.test.ts +84 -88
- package/telegram-plugin/tests/permission-diff.test.ts +336 -0
- package/telegram-plugin/tests/tool-activity-summary.test.ts +25 -229
- package/telegram-plugin/tool-activity-summary.ts +45 -212
package/dist/cli/switchroom.js
CHANGED
|
@@ -28477,6 +28477,30 @@ var init_doctor_status = __esm(() => {
|
|
|
28477
28477
|
init_source();
|
|
28478
28478
|
});
|
|
28479
28479
|
|
|
28480
|
+
// src/config/thinking-effort-risk.ts
|
|
28481
|
+
function isAdaptiveThinkingOpus(model) {
|
|
28482
|
+
if (!model)
|
|
28483
|
+
return false;
|
|
28484
|
+
const m = model.trim().toLowerCase();
|
|
28485
|
+
return m === "opus" || m.startsWith("claude-opus-4");
|
|
28486
|
+
}
|
|
28487
|
+
function assessThinkingEffortRisk(model, effort) {
|
|
28488
|
+
if (!effort)
|
|
28489
|
+
return { risky: false };
|
|
28490
|
+
if (!RISKY_EFFORTS.has(effort.trim().toLowerCase()))
|
|
28491
|
+
return { risky: false };
|
|
28492
|
+
if (!isAdaptiveThinkingOpus(model))
|
|
28493
|
+
return { risky: false };
|
|
28494
|
+
return {
|
|
28495
|
+
risky: true,
|
|
28496
|
+
reason: `thinking_effort '${effort}' on adaptive-thinking model '${model}' can trigger ` + `'400 thinking/redacted_thinking blocks cannot be modified' errors when work runs ` + `through concurrent sub-agents (issue #1978). Pin 'thinking_effort: low' (the safe ` + `floor) unless the bundled claude CLI includes the concurrent-agent thinking-block ` + `merge fix.`
|
|
28497
|
+
};
|
|
28498
|
+
}
|
|
28499
|
+
var RISKY_EFFORTS;
|
|
28500
|
+
var init_thinking_effort_risk = __esm(() => {
|
|
28501
|
+
RISKY_EFFORTS = new Set(["medium", "high", "xhigh", "max"]);
|
|
28502
|
+
});
|
|
28503
|
+
|
|
28480
28504
|
// src/manifest.ts
|
|
28481
28505
|
import {
|
|
28482
28506
|
existsSync as existsSync48,
|
|
@@ -31399,6 +31423,19 @@ function checkConfig(config, configPath) {
|
|
|
31399
31423
|
detail: foundSubagents.length > 0 ? foundSubagents.join(", ") : "no default subagents \u2014 main agent handles all work inline",
|
|
31400
31424
|
fix: foundSubagents.length > 0 ? undefined : "Add defaults.subagents to switchroom.yaml to enable Sonnet/Haiku delegation. See docs/sub-agents.md for the worker/researcher/reviewer pattern."
|
|
31401
31425
|
});
|
|
31426
|
+
const effortRisks = [];
|
|
31427
|
+
for (const [name, agentConfig] of Object.entries(config.agents)) {
|
|
31428
|
+
const resolved = resolveAgentConfig(config.defaults, config.profiles, agentConfig);
|
|
31429
|
+
if (assessThinkingEffortRisk(resolved.model, resolved.thinking_effort).risky) {
|
|
31430
|
+
effortRisks.push(name);
|
|
31431
|
+
}
|
|
31432
|
+
}
|
|
31433
|
+
results.push({
|
|
31434
|
+
name: "thinking_effort \u00d7 adaptive model",
|
|
31435
|
+
status: effortRisks.length > 0 ? "warn" : "ok",
|
|
31436
|
+
detail: effortRisks.length > 0 ? `${effortRisks.length} agent(s) on Opus 4.x with thinking_effort > low: ${effortRisks.join(", ")}` : "no risky model/effort combos",
|
|
31437
|
+
fix: effortRisks.length > 0 ? "Pin `thinking_effort: low` for Opus 4.x agents \u2014 medium+ can 400 on 'thinking blocks cannot be modified' with concurrent sub-agents (issue #1978). Removing the field is NOT a fix (Opus 4.8 defaults effort=high when unset)." : undefined
|
|
31438
|
+
});
|
|
31402
31439
|
return results;
|
|
31403
31440
|
}
|
|
31404
31441
|
function checkUserDeclaredMcps(name, agentConfig, config, renderedMcpServers) {
|
|
@@ -32833,6 +32870,7 @@ var init_doctor = __esm(() => {
|
|
|
32833
32870
|
init_vault();
|
|
32834
32871
|
init_loader();
|
|
32835
32872
|
init_merge();
|
|
32873
|
+
init_thinking_effort_risk();
|
|
32836
32874
|
init_paths();
|
|
32837
32875
|
init_helpers();
|
|
32838
32876
|
init_lifecycle();
|
|
@@ -49366,8 +49404,8 @@ var {
|
|
|
49366
49404
|
} = import__.default;
|
|
49367
49405
|
|
|
49368
49406
|
// src/build-info.ts
|
|
49369
|
-
var VERSION = "0.14.
|
|
49370
|
-
var COMMIT_SHA = "
|
|
49407
|
+
var VERSION = "0.14.9";
|
|
49408
|
+
var COMMIT_SHA = "fd8ed8ed";
|
|
49371
49409
|
|
|
49372
49410
|
// src/cli/agent.ts
|
|
49373
49411
|
init_source();
|
package/package.json
CHANGED
|
@@ -183,6 +183,29 @@ export PATH="$HOME/.bun/bin:$PATH"
|
|
|
183
183
|
# all land in these paths; survival across container restart is via the
|
|
184
184
|
# /state/agent bind mount (HOME=/state/agent/home).
|
|
185
185
|
export PATH="$HOME/.local/bin:$HOME/bin:$HOME/.npm-global/bin:$PATH"
|
|
186
|
+
# claude is delivered ONLY by the agent image (/usr/local, root-owned,
|
|
187
|
+
# version-pinned, rebuilt deliberately via `switchroom update`). The
|
|
188
|
+
# persistent-HOME dirs above precede /usr/local/bin on PATH so agents
|
|
189
|
+
# can install their own npm/pip tools — but that same precedence means
|
|
190
|
+
# a stray `claude` in the writable, state-persisted npm prefix would
|
|
191
|
+
# silently SHADOW the image's, surviving every restart and drifting the
|
|
192
|
+
# fleet off the tested binary (this bit test-harness with a months-old
|
|
193
|
+
# self-installed 2.1.139). DISABLE_AUTOUPDATER=1 stops claude's own
|
|
194
|
+
# self-update, but can't undo a pre-existing or manual drop. So prune
|
|
195
|
+
# any user-local claude at boot — narrowly, by name, leaving every
|
|
196
|
+
# other user-installed package intact — guaranteeing `claude` always
|
|
197
|
+
# resolves to the image binary. Idempotent; no-op when clean.
|
|
198
|
+
for _stray_claude in \
|
|
199
|
+
"$HOME/.npm-global/bin/claude" \
|
|
200
|
+
"$HOME/.local/bin/claude" \
|
|
201
|
+
"$HOME/bin/claude"; do
|
|
202
|
+
if [ -e "$_stray_claude" ] || [ -L "$_stray_claude" ]; then
|
|
203
|
+
echo "start.sh: pruning user-local claude shadow at $_stray_claude (image binary is authoritative)" >&2
|
|
204
|
+
rm -f "$_stray_claude"
|
|
205
|
+
fi
|
|
206
|
+
done
|
|
207
|
+
rm -rf "$HOME/.npm-global/lib/node_modules/@anthropic-ai/claude-code" 2>/dev/null || true
|
|
208
|
+
unset _stray_claude
|
|
186
209
|
export CLAUDE_CONFIG_DIR="{{agentDir}}/.claude"
|
|
187
210
|
# CLAUDE_CODE_OAUTH_TOKEN injection was removed with RFC H (auth-broker).
|
|
188
211
|
# Claude reads .credentials.json directly; the broker is the sole writer
|