switchroom 0.15.41 → 0.15.42

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.
@@ -11114,7 +11114,8 @@ var SubagentSchema = exports_external.object({
11114
11114
  var SessionSchema = exports_external.object({
11115
11115
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
11116
11116
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
11117
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
11117
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
11118
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
11118
11119
  }).optional();
11119
11120
  var SessionContinuitySchema = exports_external.object({
11120
11121
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -11114,7 +11114,8 @@ var SubagentSchema = exports_external.object({
11114
11114
  var SessionSchema = exports_external.object({
11115
11115
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
11116
11116
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
11117
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
11117
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
11118
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
11118
11119
  }).optional();
11119
11120
  var SessionContinuitySchema = exports_external.object({
11120
11121
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -11862,7 +11862,8 @@ var SubagentSchema = exports_external.object({
11862
11862
  var SessionSchema = exports_external.object({
11863
11863
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
11864
11864
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
11865
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
11865
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
11866
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
11866
11867
  }).optional();
11867
11868
  var SessionContinuitySchema = exports_external.object({
11868
11869
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -13678,7 +13678,8 @@ var init_schema = __esm(() => {
13678
13678
  SessionSchema = exports_external.object({
13679
13679
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
13680
13680
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
13681
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
13681
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
13682
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
13682
13683
  }).optional();
13683
13684
  SessionContinuitySchema = exports_external.object({
13684
13685
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -31678,6 +31679,46 @@ async function runMcpSecretChecks(config, deps = {}) {
31678
31679
  return results;
31679
31680
  }
31680
31681
 
31682
+ // src/cli/doctor-context.ts
31683
+ function fmtK(n) {
31684
+ return n >= 1000 ? `${(n / 1000).toFixed(n >= 1e4 ? 0 : 1)}k` : `${n}`;
31685
+ }
31686
+ function contextRow(agent, read) {
31687
+ const name = `context:${agent}`;
31688
+ if (read.kind === "absent") {
31689
+ return { name, status: "skip", detail: "no snapshot yet (agent idle since boot, or stopped)" };
31690
+ }
31691
+ if (read.kind === "unreadable") {
31692
+ return { name, status: "skip", detail: read.msg };
31693
+ }
31694
+ const s = read.snapshot;
31695
+ if (s.state === "unknown") {
31696
+ return { name, status: "skip", detail: "occupancy not yet measured" };
31697
+ }
31698
+ if (s.cap == null || s.pct == null) {
31699
+ return { name, status: "ok", detail: `${fmtK(s.occupancy)} tok (no cap \u2014 native compaction)` };
31700
+ }
31701
+ const pctLabel = `${Math.round(s.pct * 100)}%`;
31702
+ const detail = `${fmtK(s.occupancy)}/${fmtK(s.cap)} (${pctLabel})`;
31703
+ if (s.state === "tight") {
31704
+ return {
31705
+ name,
31706
+ status: "warn",
31707
+ detail: `${detail} \u2014 tight; a /compact is near`,
31708
+ fix: `Working context is ${pctLabel} of the cap. Normal if mid-large-task (it compacts automatically); if persistent, consider raising session.max_context_tokens or trimming this agent's tool/prose surface.`
31709
+ };
31710
+ }
31711
+ return { name, status: "ok", detail };
31712
+ }
31713
+ async function runContextChecks(config, deps = {}) {
31714
+ const agents = Object.keys(config.agents ?? {});
31715
+ if (agents.length === 0)
31716
+ return [];
31717
+ const read = deps.readSnapshot ?? (async () => ({ kind: "absent" }));
31718
+ const results = await Promise.all(agents.sort().map(async (a) => contextRow(a, await read(a))));
31719
+ return results;
31720
+ }
31721
+
31681
31722
  // src/cli/doctor-credentials-migration.ts
31682
31723
  import {
31683
31724
  existsSync as realExistsSync5,
@@ -34082,6 +34123,24 @@ function registerDoctorCommand(program3) {
34082
34123
  title: "MCP Connections (auth)",
34083
34124
  results: await runMcpSecretChecks(config, { vaultAclReader })
34084
34125
  },
34126
+ {
34127
+ title: "Context Headroom",
34128
+ results: await runContextChecks(config, {
34129
+ readSnapshot: async (agent) => {
34130
+ try {
34131
+ const { execFileSync: execFileSync19 } = await import("node:child_process");
34132
+ const out = execFileSync19("docker", ["exec", `switchroom-${agent}`, "cat", "/state/agent/context-occupancy.json"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"], timeout: 5000 });
34133
+ return { kind: "ok", snapshot: JSON.parse(out) };
34134
+ } catch (err) {
34135
+ const msg = err.message ?? String(err);
34136
+ if (/No such|cannot|not running|exited|No such container/i.test(msg)) {
34137
+ return { kind: "absent" };
34138
+ }
34139
+ return { kind: "unreadable", msg: `snapshot read failed: ${msg}` };
34140
+ }
34141
+ }
34142
+ })
34143
+ },
34085
34144
  { title: "MFF Skill", results: await checkMff(passphrase, vaultPath, config) },
34086
34145
  { title: "Webkite", results: runWebkiteChecks(config) },
34087
34146
  { title: "Cron Session", results: runCronSessionChecks(config) }
@@ -50708,8 +50767,8 @@ import { existsSync, readFileSync } from "node:fs";
50708
50767
  import { dirname, join } from "node:path";
50709
50768
 
50710
50769
  // src/build-info.ts
50711
- var VERSION = "0.15.41";
50712
- var COMMIT_SHA = "01f41098";
50770
+ var VERSION = "0.15.42";
50771
+ var COMMIT_SHA = "2c7e12da";
50713
50772
 
50714
50773
  // src/cli/resolve-version.ts
50715
50774
  function readPackageVersion() {
@@ -68965,6 +69024,29 @@ function stopHindsight() {
68965
69024
  execFileSync16("docker", ["rm", "switchroom-hindsight"], { stdio: "pipe" });
68966
69025
  } catch {}
68967
69026
  }
69027
+ function pullHindsightImage() {
69028
+ execFileSync16("docker", ["pull", HINDSIGHT_IMAGE], { stdio: "inherit" });
69029
+ }
69030
+ function getRunningHindsightPorts() {
69031
+ const readPort = (containerPort) => {
69032
+ try {
69033
+ const out = execFileSync16("docker", ["port", "switchroom-hindsight", `${containerPort}/tcp`], { stdio: "pipe", encoding: "utf-8" });
69034
+ const m = out.split(`
69035
+ `).map((l) => l.trim()).find((l) => l.length > 0);
69036
+ if (!m)
69037
+ return null;
69038
+ const port = Number(m.slice(m.lastIndexOf(":") + 1));
69039
+ return Number.isInteger(port) && port > 0 ? port : null;
69040
+ } catch {
69041
+ return null;
69042
+ }
69043
+ };
69044
+ const apiPort = readPort(HINDSIGHT_DEFAULT_API_PORT);
69045
+ if (apiPort === null)
69046
+ return null;
69047
+ const uiPort = readPort(HINDSIGHT_DEFAULT_UI_PORT) ?? (apiPort === HINDSIGHT_DEFAULT_API_PORT ? HINDSIGHT_DEFAULT_UI_PORT : 19999);
69048
+ return { apiPort, uiPort };
69049
+ }
68968
69050
  function getHindsightStatus() {
68969
69051
  try {
68970
69052
  const output = execFileSync16("docker", ["ps", "-a", "--filter", "name=switchroom-hindsight", "--format", "{{.Status}}"], { stdio: "pipe", encoding: "utf-8" });
@@ -69195,7 +69277,7 @@ Cross-agent reflection plan
69195
69277
  }
69196
69278
  console.log();
69197
69279
  }));
69198
- memory.command("setup").description("Manage the Hindsight Docker container").option("--stop", "Stop and remove the Hindsight container").option("--status", "Show Hindsight container status").option("--provider <provider>", "LLM provider (ollama, openai, anthropic)").action(async (opts) => {
69280
+ memory.command("setup").description("Manage the Hindsight Docker container").option("--stop", "Stop and remove the Hindsight container").option("--status", "Show Hindsight container status").option("--recreate", "Pull the latest image and recreate the container (reusing its current port). Used by `switchroom update` to keep the hindsight singleton current.").option("--provider <provider>", "LLM provider (ollama, openai, anthropic)").action(async (opts) => {
69199
69281
  if (opts.status) {
69200
69282
  if (!isDockerAvailable()) {
69201
69283
  console.log(source_default.red(" Docker is not available."));
@@ -69236,24 +69318,41 @@ Cross-agent reflection plan
69236
69318
  `));
69237
69319
  process.exit(1);
69238
69320
  }
69239
- if (isHindsightRunning()) {
69321
+ const recreate = opts.recreate === true;
69322
+ const reusePorts = recreate ? getRunningHindsightPorts() : null;
69323
+ if (isHindsightRunning() && !recreate) {
69240
69324
  console.log(source_default.green(`
69241
69325
  Hindsight container is already running (switchroom-hindsight).
69242
69326
  `));
69243
69327
  return;
69244
69328
  }
69329
+ if (recreate) {
69330
+ console.log(source_default.gray(" Pulling latest Hindsight image..."));
69331
+ try {
69332
+ pullHindsightImage();
69333
+ } catch (err) {
69334
+ console.error(source_default.red(`
69335
+ Failed to pull Hindsight image: ${err.message}
69336
+ `));
69337
+ process.exit(1);
69338
+ }
69339
+ }
69245
69340
  if (isHindsightContainerExists()) {
69246
- console.log(source_default.gray(" Removing stopped switchroom-hindsight container..."));
69341
+ console.log(source_default.gray(" Removing existing switchroom-hindsight container..."));
69247
69342
  stopHindsight();
69248
69343
  }
69249
69344
  let ports;
69250
- try {
69251
- ports = await pickHindsightPorts();
69252
- } catch (err) {
69253
- console.error(source_default.red(`
69345
+ if (reusePorts) {
69346
+ ports = reusePorts;
69347
+ } else {
69348
+ try {
69349
+ ports = await pickHindsightPorts();
69350
+ } catch (err) {
69351
+ console.error(source_default.red(`
69254
69352
  ${err.message}
69255
69353
  `));
69256
- process.exit(1);
69354
+ process.exit(1);
69355
+ }
69257
69356
  }
69258
69357
  if (ports.apiPort !== HINDSIGHT_DEFAULT_API_PORT) {
69259
69358
  console.log(source_default.yellow(` Port ${HINDSIGHT_DEFAULT_API_PORT} is already in use; ` + `using ${ports.apiPort}/${ports.uiPort} instead.`));
@@ -74629,6 +74728,17 @@ var DASHBOARD_CACHE_TTL = {
74629
74728
  approvals: 15000,
74630
74729
  grants: 15000
74631
74730
  };
74731
+ function readContextOccupancy(agentsDir, name) {
74732
+ try {
74733
+ const raw = readFileSync44(resolve28(agentsDir, name, "context-occupancy.json"), "utf-8");
74734
+ const s = JSON.parse(raw);
74735
+ if (typeof s?.occupancy !== "number")
74736
+ return null;
74737
+ return s;
74738
+ } catch {
74739
+ return null;
74740
+ }
74741
+ }
74632
74742
  function readLastTurnAt(agentsDir, name) {
74633
74743
  try {
74634
74744
  const db = openTurnsDb(resolve28(agentsDir, name));
@@ -74663,6 +74773,7 @@ async function cachedFleetStatus(now, fetchImpl = fetchFleetStatusViaHostd) {
74663
74773
  }
74664
74774
  async function handleGetAgents(config, deps = {}) {
74665
74775
  const readLastTurn = deps.readLastTurn ?? readLastTurnAt;
74776
+ const readContext = deps.readContext ?? readContextOccupancy;
74666
74777
  const statuses = getAllAgentStatuses(config);
74667
74778
  const authStatuses = getAllAuthStatuses(config);
74668
74779
  const agentsDir = resolveAgentsDir(config);
@@ -74695,7 +74806,8 @@ async function handleGetAgents(config, deps = {}) {
74695
74806
  expiresAt: auth?.expiresAt
74696
74807
  },
74697
74808
  memoryCollection: collection,
74698
- lastTurnAt: readLastTurn(agentsDir, name)
74809
+ lastTurnAt: readLastTurn(agentsDir, name),
74810
+ context: readContext(agentsDir, name)
74699
74811
  });
74700
74812
  }
74701
74813
  return agents;
@@ -78047,6 +78159,26 @@ function planUpdate(opts) {
78047
78159
  throw new Error("switchroom webd install failed");
78048
78160
  }
78049
78161
  });
78162
+ let memoryBackendHindsight;
78163
+ if (typeof opts.memoryBackendHindsight === "boolean") {
78164
+ memoryBackendHindsight = opts.memoryBackendHindsight;
78165
+ } else {
78166
+ try {
78167
+ memoryBackendHindsight = loadConfig().memory?.backend === "hindsight";
78168
+ } catch {
78169
+ memoryBackendHindsight = false;
78170
+ }
78171
+ }
78172
+ steps.push({
78173
+ name: "refresh-hindsight",
78174
+ description: "switchroom memory setup --recreate \u2014 pull latest hindsight image + recreate the memory singleton (standalone container, reusing its current port)",
78175
+ skipReason: !memoryBackendHindsight ? "memory.backend is not hindsight \u2014 no hindsight singleton to refresh" : opts.skipImages ? "--skip-images flag set" : undefined,
78176
+ run: () => {
78177
+ const r = runner(process.execPath, [scriptPath, "memory", "setup", "--recreate"]);
78178
+ if (r.status !== 0)
78179
+ throw new Error("switchroom memory setup --recreate failed");
78180
+ }
78181
+ });
78050
78182
  steps.push({
78051
78183
  name: "sync-bundled-skills",
78052
78184
  description: "Sync shipped skills/ to ~/.switchroom/skills/_bundled/ (host-stable pool dir).",
@@ -122,6 +122,15 @@
122
122
 
123
123
  .meta-item span { color: var(--text); }
124
124
 
125
+ /* Context-headroom gauge (RFC context-headroom-surface). */
126
+ .ctx-gauge { display: inline-flex; align-items: center; gap: 0.4rem; }
127
+ .ctx-text { color: var(--text); font-variant-numeric: tabular-nums; }
128
+ .ctx-bar {
129
+ display: inline-block; width: 48px; height: 6px; border-radius: 3px;
130
+ background: var(--bg-dim, rgba(255,255,255,0.12)); overflow: hidden;
131
+ }
132
+ .ctx-fill { display: block; height: 100%; border-radius: 3px; }
133
+
125
134
  .scope-toggle {
126
135
  cursor: pointer;
127
136
  color: var(--text);
@@ -1659,6 +1668,27 @@
1659
1668
  return 'inactive';
1660
1669
  }
1661
1670
 
1671
+ // Context-headroom gauge (RFC context-headroom-surface): occupancy/cap
1672
+ // with a fill bar, amber when tight (≥80%). '—' when no snapshot yet.
1673
+ function fmtTok(n) {
1674
+ return n >= 1000 ? (n / 1000).toFixed(n >= 10000 ? 0 : 1) + 'k' : String(n);
1675
+ }
1676
+ function formatContext(ctx) {
1677
+ if (!ctx || ctx.state === 'unknown' || typeof ctx.occupancy !== 'number') {
1678
+ return '<span style="color:var(--text-dim)">—</span>';
1679
+ }
1680
+ if (ctx.cap == null || ctx.pct == null) {
1681
+ return `<span>${fmtTok(ctx.occupancy)} <span style="color:var(--text-dim)">(no cap)</span></span>`;
1682
+ }
1683
+ const pct = Math.max(0, Math.min(1, ctx.pct));
1684
+ const tight = ctx.state === 'tight';
1685
+ const col = tight ? 'var(--amber, #d99)' : 'var(--green)';
1686
+ return `<span class="ctx-gauge" title="${fmtTok(ctx.occupancy)} / ${fmtTok(ctx.cap)} tokens — ${Math.round(pct * 100)}% of cap${tight ? ' (tight — /compact near)' : ''}">`
1687
+ + `<span class="ctx-text">${fmtTok(ctx.occupancy)}/${fmtTok(ctx.cap)} (${Math.round(pct * 100)}%)</span>`
1688
+ + `<span class="ctx-bar"><span class="ctx-fill" style="width:${(pct * 100).toFixed(0)}%;background:${col}"></span></span>`
1689
+ + `</span>`;
1690
+ }
1691
+
1662
1692
  function formatUptime(timestamp) {
1663
1693
  if (!timestamp) return '--';
1664
1694
  const d = new Date(timestamp);
@@ -1693,6 +1723,7 @@
1693
1723
  <div class="meta-item"><label>Uptime </label><span>${formatUptime(a.uptime)}</span></div>
1694
1724
  <div class="meta-item"><label>Mem </label><span>${a.memory || '--'}</span></div>
1695
1725
  <div class="meta-item"><label>Last turn </label><span>${a.lastTurnAt ? formatTimestamp(a.lastTurnAt) : '—'}</span></div>
1726
+ <div class="meta-item meta-context"><label>Context </label>${formatContext(a.context)}</div>
1696
1727
  <div class="meta-item"><label>Profile </label><span>${escapeHtml(a.extends)}</span></div>
1697
1728
  <div class="meta-item"><label>Auth </label><span>${a.auth.authenticated ? '✓' : '✗'}</span></div>
1698
1729
  <div class="meta-item"><label>Account </label><span>${a.primaryAccount ? escapeHtml(a.primaryAccount) : '<span style="color:var(--text-dim)">default</span>'}</span></div>
@@ -13849,7 +13849,8 @@ var SubagentSchema = exports_external.object({
13849
13849
  var SessionSchema = exports_external.object({
13850
13850
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
13851
13851
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
13852
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
13852
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
13853
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
13853
13854
  }).optional();
13854
13855
  var SessionContinuitySchema = exports_external.object({
13855
13856
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -11457,7 +11457,8 @@ var init_schema = __esm(() => {
11457
11457
  SessionSchema = exports_external.object({
11458
11458
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
11459
11459
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
11460
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
11460
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
11461
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
11461
11462
  }).optional();
11462
11463
  SessionContinuitySchema = exports_external.object({
11463
11464
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
@@ -11457,7 +11457,8 @@ var init_schema = __esm(() => {
11457
11457
  SessionSchema = exports_external.object({
11458
11458
  max_idle: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '2h', '30m')").optional().describe("Start a fresh session if the previous one has been idle " + "longer than this duration. Examples: '2h', '30m', '7200s'."),
11459
11459
  max_turns: exports_external.number().int().positive().optional().describe("Start a fresh session if the previous one has more user " + "turns than this. Useful for preventing context bloat on " + "long-running agents."),
11460
- max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context.")
11460
+ max_context_tokens: exports_external.number().int().positive().optional().describe("Proactively run /compact when the live context window " + "occupancy (latest assistant turn input + cache-read + " + "cache-creation tokens) reaches this many tokens. Opt-in: " + "unset means rely on Claude Code's native auto-compaction. " + "Useful on large-window models (e.g. 1M Opus) to hold a " + "deliberately lean working context."),
11461
+ idle_clear_after: exports_external.string().regex(/^\d+[smh]$/, "Duration must be a number followed by s, m, or h (e.g. '3h', '90m')").optional().describe("Auto-run /clear (wipe the working context) after the live " + "session has been idle this long. Defaults to '3h' when unset " + "(on by default); set '0s' to disable. Long-term memory lives " + "in Hindsight, so a clear loses only the in-session thread.")
11461
11462
  }).optional();
11462
11463
  SessionContinuitySchema = exports_external.object({
11463
11464
  enabled: exports_external.boolean().optional().describe("Master switch for the session-handoff briefing (default true)."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchroom",
3
- "version": "0.15.41",
3
+ "version": "0.15.42",
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": {