switchroom 0.16.7 → 0.16.8

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.
@@ -22587,7 +22587,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:f
22587
22587
  import { dirname as dirname4, join as join2 } from "node:path";
22588
22588
 
22589
22589
  // src/build-info.ts
22590
- var VERSION = "0.16.7";
22590
+ var VERSION = "0.16.8";
22591
22591
 
22592
22592
  // src/cli/resolve-version.ts
22593
22593
  function readPackageVersion() {
@@ -22827,7 +22827,7 @@ function parseUpdateResultLine(stdout) {
22827
22827
  // src/host-control/config-edit-validator.ts
22828
22828
  import { mkdtempSync, writeFileSync as writeFileSync2, rmSync as rmSync2, existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
22829
22829
  import { tmpdir } from "node:os";
22830
- import { join as join4, isAbsolute as isAbsolute2, normalize } from "node:path";
22830
+ import { join as join4, isAbsolute as isAbsolute2, normalize, basename as basename2 } from "node:path";
22831
22831
  import { spawnSync as spawnSync2 } from "node:child_process";
22832
22832
  import { isDeepStrictEqual } from "node:util";
22833
22833
  var MAX_PATCH_BYTES = 1024 * 1024;
@@ -22847,7 +22847,7 @@ function isTargetPathHeader(headerPath, targetBasename) {
22847
22847
  const norm = normalize(p);
22848
22848
  if (norm.includes("..") || isAbsolute2(norm))
22849
22849
  return false;
22850
- return norm === targetBasename;
22850
+ return norm === targetBasename || basename2(norm) === targetBasename;
22851
22851
  }
22852
22852
  function validateShape(unifiedDiff, targetPath) {
22853
22853
  const byteLen = Buffer.byteLength(unifiedDiff, "utf8");
@@ -22923,8 +22923,8 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
22923
22923
  const liveContent = readFileSync5(configPath, "utf8");
22924
22924
  const scratchDir = mkdtempSync(join4(tmpdir(), "config-propose-edit-"));
22925
22925
  try {
22926
- const basename2 = configPath.split("/").pop() ?? "switchroom.yaml";
22927
- const scratchFile = join4(scratchDir, basename2);
22926
+ const basename3 = configPath.split("/").pop() ?? "switchroom.yaml";
22927
+ const scratchFile = join4(scratchDir, basename3);
22928
22928
  writeFileSync2(scratchFile, liveContent);
22929
22929
  const patchFile = join4(scratchDir, "proposal.patch");
22930
22930
  writeFileSync2(patchFile, unifiedDiff);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchroom",
3
- "version": "0.16.7",
3
+ "version": "0.16.8",
4
4
  "description": "Run Claude Code 24/7 on your Claude Pro/Max subscription over Telegram. Open-source alternative to OpenClaw and NanoClaw — no API keys.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,6 +51,41 @@ if [ "$SWITCHROOM_RUNTIME" = "docker" ] && [ -z "$SWITCHROOM_DOCKER_TMUX_INNER"
51
51
  {{/each}}
52
52
  {{/if}}
53
53
 
54
+ # LiteLLM virtual-key fetch for the GATEWAY process (outer-pass hoist).
55
+ # The INNER block below fetches this same key for the `claude` process;
56
+ # the gateway daemon forks HERE (in the outer pass) so it needs
57
+ # ANTHROPIC_CUSTOM_HEADERS exported BEFORE the gateway fork below, or
58
+ # discoverSrModels() returns [] and /model never shows OpenRouter entries.
59
+ #
60
+ # Mirrors the INNER block's fail-open logic exactly:
61
+ # - missing key → log + skip export (gateway talks direct OAuth)
62
+ # - proxy down → log + strip ALL routing env (fail-open)
63
+ # - ANTHROPIC_CUSTOM_HEADERS already set → skip (idempotent)
64
+ #
65
+ # SWITCHROOM_AGENT_NAME is injected by compose env (compose.ts:1816)
66
+ # so it is available here, before the inner-pass export at line ~320.
67
+ if [ -n "$SWITCHROOM_LITELLM" ] && [ -z "$ANTHROPIC_CUSTOM_HEADERS" ] && command -v switchroom >/dev/null 2>&1; then
68
+ sr_ll_key="$(switchroom vault get "litellm/$SWITCHROOM_AGENT_NAME/api-key" 2>/dev/null || true)"
69
+ sr_ll_ok=""
70
+ if [ -z "$sr_ll_key" ]; then
71
+ echo "litellm(outer): no virtual key for agent '$SWITCHROOM_AGENT_NAME' — gateway will use direct OAuth (no tracking/guardrail)" >&2
72
+ elif command -v curl >/dev/null 2>&1 && [ -n "$ANTHROPIC_BASE_URL" ] \
73
+ && ! curl -fsS -m 5 -o /dev/null "${ANTHROPIC_BASE_URL%/}/health/liveliness" 2>/dev/null; then
74
+ echo "litellm(outer): proxy unreachable at $ANTHROPIC_BASE_URL — falling back to direct OAuth (no tracking/guardrail this session)" >&2
75
+ else
76
+ sr_ll_ok="1"
77
+ fi
78
+ if [ -n "$sr_ll_ok" ]; then
79
+ export ANTHROPIC_CUSTOM_HEADERS="x-litellm-api-key: Bearer $sr_ll_key
80
+ x-litellm-customer-id: $SWITCHROOM_AGENT_NAME
81
+ x-litellm-tags: agent:$SWITCHROOM_AGENT_NAME,profile:${SWITCHROOM_AGENT_PROFILE:-default}"
82
+ export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
83
+ else
84
+ unset ANTHROPIC_BASE_URL ANTHROPIC_SMALL_FAST_MODEL SWITCHROOM_LITELLM
85
+ fi
86
+ unset sr_ll_key sr_ll_ok
87
+ fi
88
+
54
89
  # Tiny in-process supervisor: runs cmd in a respawn loop with
55
90
  # exponential backoff (1→2→4…→60s cap) and NEVER permanently gives
56
91
  # up. Rationale (RFC J / install-validation 2026-05-17): the
@@ -54803,6 +54803,8 @@ function naturalAction(toolName, inputPreview) {
54803
54803
  return "update its task list";
54804
54804
  case "ExitPlanMode":
54805
54805
  return "exit plan mode";
54806
+ case "config_propose_edit":
54807
+ return "edit switchroom config";
54806
54808
  default:
54807
54809
  return `use ${toolName}`;
54808
54810
  }
@@ -56013,11 +56015,11 @@ function readTurnActiveMarkerAgeMs(stateDir, now) {
56013
56015
  }
56014
56016
 
56015
56017
  // ../src/build-info.ts
56016
- var VERSION = "0.16.7";
56017
- var COMMIT_SHA = "696eea91";
56018
- var COMMIT_DATE = "2026-06-28T04:56:27Z";
56019
- var LATEST_PR = 2615;
56020
- var COMMITS_AHEAD_OF_TAG = 0;
56018
+ var VERSION = "0.16.8";
56019
+ var COMMIT_SHA = "c2668516";
56020
+ var COMMIT_DATE = "2026-06-28T15:28:08+10:00";
56021
+ var LATEST_PR = null;
56022
+ var COMMITS_AHEAD_OF_TAG = 5;
56021
56023
 
56022
56024
  // gateway/boot-version.ts
56023
56025
  function formatRelativeAgo(iso) {
@@ -212,6 +212,11 @@ export function naturalAction(
212
212
  return "update its task list";
213
213
  case "ExitPlanMode":
214
214
  return "exit plan mode";
215
+ // hostd config-edit verb (#2605) — not mcp__-prefixed (it's a direct
216
+ // wire call from the agent-config MCP server), so it falls through to
217
+ // the switch rather than naturalMcpAction. Give it a readable title.
218
+ case "config_propose_edit":
219
+ return "edit switchroom config";
215
220
  default:
216
221
  return `use ${toolName}`;
217
222
  }