switchroom 0.15.11 → 0.15.12

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.
@@ -13711,6 +13711,11 @@ var init_schema = __esm(() => {
13711
13711
  }).optional().describe("Per-source rate limit for the webhook ingest path (#714). " + "Off by default \u2014 when this key is absent the handler skips " + "rate-limit checks entirely. Opt in by setting `rpm` to an " + "integer requests-per-minute (token bucket per (agent, source); " + "burst equal to rpm). When enabled, exceeding the limit returns " + "429 with Retry-After header; first throttle event per " + "(agent, source) per 60s window is written to " + "<agent>/telegram/issues.jsonl. " + "Cascades from defaults.channels.telegram.webhook_rate_limit."),
13712
13712
  webhook_via_gateway: exports_external.boolean().optional().describe("Route verified webhook events to the agent's in-container gateway " + "over a peercred-gated UDS (<agent>/telegram/webhook.sock) instead " + "of having the host-side web receiver write the agent dir directly. " + "Required under the Docker runtime: the receiver runs as the host " + "operator UID and cannot write the per-agent-UID-owned agent dir " + "(EACCES 500) nor connect the gateway socket. When true the gateway " + "(running as the agent UID) becomes the sole writer of " + "webhook-events.jsonl + dedup/cooldown state and also fires " + "webhook_dispatch. Off by default for back-compat with host-runtime " + "installs. See docs/rfcs/webhook-via-gateway-socket.md."),
13713
13713
  webhook_require_edge: exports_external.boolean().optional().describe("Cloudflare-only edge lock: require the X-Switchroom-Edge header " + "(injected by a Cloudflare Transform Rule on hooks.switchroom.ai) to " + "match the operator's edge secret at ~/.switchroom/webhook-edge-secret " + "before any HMAC verification; reject 403 otherwise. Proves the " + "request entered through our Cloudflare edge \u2014 the per-agent HMAC " + "alone can't (it proves body provenance, not network path). Stacks " + "on the GitHub-IP WAF + per-agent HMAC. Fail-closed: when required " + "but the secret file is missing/empty every request is rejected. Off " + "by default. See docs/rfcs/webhook-cloudflare-edge-lock.md."),
13714
+ linear_agent: exports_external.object({
13715
+ enabled: exports_external.boolean(),
13716
+ token: exports_external.string().describe("vault:<key> reference to the Linear OAuth app token (actor=app). " + "Resolved at runtime via the vault broker (canonically " + "vault:linear/<agent>/token). Never an inline literal."),
13717
+ workspace_id: exports_external.string().optional().describe("Optional Linear workspace (organization) id this agent is " + "installed into. Informational \u2014 used for setup hints and " + "multi-workspace disambiguation; the token already scopes the " + "app to its workspace.")
13718
+ }).optional().describe("Linear first-class agent integration (#2298). When enabled, the " + "agent appears in a Linear workspace as an app actor (own name/" + "avatar, @-mentionable, delegate-assignable). Linear AgentSessionEvent " + "webhooks (mention / delegation) wake the agent instantly via the " + "same gateway inject path as webhook_dispatch, tagged " + 'meta.source="linear" with the agent_session_id, and the agent ' + "responds with structured AgentActivity (thought/message/complete/" + "error) via the linear_agent_activity MCP tool. Builds the " + "session-lifecycle layer on top of the plain webhook_sources:[linear] " + "+ webhook_dispatch support (#2272). The OAuth app token is stored in " + "the vault and referenced here as vault:linear/<agent>/token; run " + "`switchroom linear-agent setup <agent>` to provision it. Off by " + "default \u2014 opt in per agent. Cascades from " + "defaults.channels.telegram.linear_agent."),
13714
13719
  chat_id: exports_external.string().regex(/^-\d+$/, 'supergroup chat_id must be a negative integer as a string (e.g. "-1001234567890")').optional().describe("Per-agent supergroup ID \u2014 overrides fleet `telegram.forum_chat_id`. " + "When set, requires `default_topic_id`. Negative integer as string. " + "Forbidden when `dm_only: true`. See docs/rfcs/supergroup-mode.md."),
13715
13720
  default_topic_id: exports_external.number().int().positive().optional().describe("Forum topic ID this agent's automated outbounds default to when " + "no more-specific alias resolves. Defaults to General (topic 1) when " + "`chat_id` is set and this is omitted \u2014 set it only to pin a different " + "fallback topic. " + "Telegram's General topic is `id=1` at MTProto but sends omit the " + "field \u2014 the outbound wrapper strips `message_thread_id === 1` " + "on send. Forbidden when `dm_only: true`."),
13716
13721
  topic_aliases: exports_external.record(exports_external.string(), exports_external.number().int().positive()).optional().describe("Operator-friendly names for forum topic IDs (e.g. " + "`{ general: 1, planning: 17, cron: 23, admin: 31, alerts: 41 }`). " + "Referenced from per-cron `topic:` fields and the outbound router " + "for autonomous events (boot \u2192 alerts, hostd \u2192 admin, etc.). " + "Cascades per-key through defaults \u2192 profile \u2192 agent.")
@@ -29166,7 +29171,7 @@ var init_thinking_effort_risk = __esm(() => {
29166
29171
  // src/manifest.ts
29167
29172
  import {
29168
29173
  existsSync as existsSync52,
29169
- readFileSync as readFileSync47,
29174
+ readFileSync as readFileSync48,
29170
29175
  readdirSync as readdirSync19
29171
29176
  } from "node:fs";
29172
29177
  import { dirname as dirname12, join as join47 } from "node:path";
@@ -29188,7 +29193,7 @@ function loadManifest(manifestPath) {
29188
29193
  }
29189
29194
  let raw;
29190
29195
  try {
29191
- raw = readFileSync47(path4, "utf-8");
29196
+ raw = readFileSync48(path4, "utf-8");
29192
29197
  } catch (err) {
29193
29198
  throw new Error(`Failed to read manifest at ${path4}: ${err.message}`);
29194
29199
  }
@@ -29253,7 +29258,7 @@ function probePlaywrightMcpVersion() {
29253
29258
  const pkgPath = join47(npxCache, entry, "node_modules/@playwright/mcp/package.json");
29254
29259
  if (existsSync52(pkgPath)) {
29255
29260
  try {
29256
- const pkg = JSON.parse(readFileSync47(pkgPath, "utf-8"));
29261
+ const pkg = JSON.parse(readFileSync48(pkgPath, "utf-8"));
29257
29262
  if (pkg.version)
29258
29263
  return pkg.version;
29259
29264
  } catch {}
@@ -29488,7 +29493,7 @@ var init_doctor_memory = __esm(() => {
29488
29493
  });
29489
29494
 
29490
29495
  // src/cli/doctor-docker.ts
29491
- import { readFileSync as readFileSync48 } from "node:fs";
29496
+ import { readFileSync as readFileSync49 } from "node:fs";
29492
29497
  function imageTagOf(ref) {
29493
29498
  if (!ref)
29494
29499
  return "<absent>";
@@ -29503,7 +29508,7 @@ function isDockerMode(opts) {
29503
29508
  return true;
29504
29509
  if (opts?.composePath) {
29505
29510
  try {
29506
- readFileSync48(opts.composePath, "utf8");
29511
+ readFileSync49(opts.composePath, "utf8");
29507
29512
  return true;
29508
29513
  } catch {}
29509
29514
  }
@@ -29692,7 +29697,7 @@ var init_doctor_docker = __esm(() => {
29692
29697
  });
29693
29698
 
29694
29699
  // src/cli/doctor-auth-broker.ts
29695
- import { existsSync as existsSync53, readFileSync as readFileSync49 } from "node:fs";
29700
+ import { existsSync as existsSync53, readFileSync as readFileSync50 } from "node:fs";
29696
29701
  import { createHash as createHash10 } from "node:crypto";
29697
29702
  import { spawnSync as spawnSync6 } from "node:child_process";
29698
29703
  import { homedir as homedir26 } from "node:os";
@@ -29806,7 +29811,7 @@ function checkAuthBrokerDrift(deps = {}) {
29806
29811
  }
29807
29812
  let index;
29808
29813
  try {
29809
- index = JSON.parse(readFileSync49(indexPath, "utf-8"));
29814
+ index = JSON.parse(readFileSync50(indexPath, "utf-8"));
29810
29815
  } catch (err) {
29811
29816
  return {
29812
29817
  name: "auth-broker: drift",
@@ -29826,7 +29831,7 @@ function checkAuthBrokerDrift(deps = {}) {
29826
29831
  }
29827
29832
  let got;
29828
29833
  try {
29829
- got = sha256Hex(readFileSync49(credsPath, "utf-8"));
29834
+ got = sha256Hex(readFileSync50(credsPath, "utf-8"));
29830
29835
  } catch (err) {
29831
29836
  divergent.push(`${label} (read failed: ${err.message})`);
29832
29837
  continue;
@@ -29867,7 +29872,7 @@ function checkAuthBrokerThresholdViolations(deps = {}) {
29867
29872
  }
29868
29873
  let violations;
29869
29874
  try {
29870
- violations = JSON.parse(readFileSync49(path4, "utf-8"));
29875
+ violations = JSON.parse(readFileSync50(path4, "utf-8"));
29871
29876
  } catch (err) {
29872
29877
  return {
29873
29878
  name: "auth-broker: threshold violations",
@@ -31903,7 +31908,7 @@ import {
31903
31908
  existsSync as existsSync57,
31904
31909
  lstatSync as lstatSync6,
31905
31910
  mkdirSync as mkdirSync31,
31906
- readFileSync as readFileSync50,
31911
+ readFileSync as readFileSync51,
31907
31912
  readdirSync as readdirSync21,
31908
31913
  statSync as statSync25
31909
31914
  } from "node:fs";
@@ -32663,7 +32668,7 @@ function classifyReadError(err) {
32663
32668
  }
32664
32669
  function tryReadHostFile(path4) {
32665
32670
  try {
32666
- return { kind: "ok", content: readFileSync50(path4, "utf-8") };
32671
+ return { kind: "ok", content: readFileSync51(path4, "utf-8") };
32667
32672
  } catch (err) {
32668
32673
  const kind = classifyReadError(err);
32669
32674
  const error = err?.message ?? String(err);
@@ -32679,7 +32684,7 @@ function parseEnvFile(path4) {
32679
32684
  return {};
32680
32685
  let content;
32681
32686
  try {
32682
- content = readFileSync50(path4, "utf-8");
32687
+ content = readFileSync51(path4, "utf-8");
32683
32688
  } catch {
32684
32689
  return {};
32685
32690
  }
@@ -32796,7 +32801,7 @@ function checkStartShStale(agentName, startShPath) {
32796
32801
  }
32797
32802
  let content;
32798
32803
  try {
32799
- content = readFileSync50(startShPath, "utf-8");
32804
+ content = readFileSync51(startShPath, "utf-8");
32800
32805
  } catch (err) {
32801
32806
  return {
32802
32807
  name: label,
@@ -32909,7 +32914,7 @@ function isSwitchroomCheckout(dir) {
32909
32914
  const pkgPath = join59(dir, "package.json");
32910
32915
  if (!existsSync57(pkgPath))
32911
32916
  return false;
32912
- const pkg = JSON.parse(readFileSync50(pkgPath, "utf-8"));
32917
+ const pkg = JSON.parse(readFileSync51(pkgPath, "utf-8"));
32913
32918
  return pkg.name === "switchroom";
32914
32919
  } catch {
32915
32920
  return false;
@@ -33030,7 +33035,7 @@ function checkAgents(config, configPath) {
33030
33035
  });
33031
33036
  } else {
33032
33037
  try {
33033
- const mcp = JSON.parse(readFileSync50(mcpJsonPath, "utf-8"));
33038
+ const mcp = JSON.parse(readFileSync51(mcpJsonPath, "utf-8"));
33034
33039
  const hasSwitchroomTelegram = !!mcp.mcpServers?.["switchroom-telegram"];
33035
33040
  const memoryEnabled = isHindsightEnabled(config);
33036
33041
  const hasHindsight = !!mcp.mcpServers?.hindsight;
@@ -33525,11 +33530,11 @@ function runDockerSection(config) {
33525
33530
  let composeYaml;
33526
33531
  let dockerfileAgent;
33527
33532
  try {
33528
- composeYaml = readFileSync50(composePath, "utf8");
33533
+ composeYaml = readFileSync51(composePath, "utf8");
33529
33534
  } catch {}
33530
33535
  const dockerfilePath = resolve32(process.env.HOME ?? "", ".switchroom", "docker", "Dockerfile.agent");
33531
33536
  try {
33532
- dockerfileAgent = readFileSync50(dockerfilePath, "utf8");
33537
+ dockerfileAgent = readFileSync51(dockerfilePath, "utf8");
33533
33538
  } catch {}
33534
33539
  return runDockerChecks({
33535
33540
  config,
@@ -49836,7 +49841,7 @@ __export(exports_server2, {
49836
49841
  TOOLS: () => TOOLS2
49837
49842
  });
49838
49843
  import { randomBytes as randomBytes15 } from "node:crypto";
49839
- import { existsSync as existsSync83, readFileSync as readFileSync69 } from "node:fs";
49844
+ import { existsSync as existsSync83, readFileSync as readFileSync70 } from "node:fs";
49840
49845
  function selfSocketPath() {
49841
49846
  return `/run/switchroom/hostd/${SELF_AGENT}/sock`;
49842
49847
  }
@@ -50014,7 +50019,7 @@ function getLastUpdateApplyStatus() {
50014
50019
  }
50015
50020
  let raw;
50016
50021
  try {
50017
- raw = readFileSync69(path8, "utf-8");
50022
+ raw = readFileSync70(path8, "utf-8");
50018
50023
  } catch (err2) {
50019
50024
  return errorText2(`get_status: failed to read audit log at ${path8}: ${err2.message}`);
50020
50025
  }
@@ -50247,8 +50252,8 @@ var {
50247
50252
  } = import__.default;
50248
50253
 
50249
50254
  // src/build-info.ts
50250
- var VERSION = "0.15.11";
50251
- var COMMIT_SHA = "43331954";
50255
+ var VERSION = "0.15.12";
50256
+ var COMMIT_SHA = "18b7b6e6";
50252
50257
 
50253
50258
  // src/cli/agent.ts
50254
50259
  init_source();
@@ -67029,6 +67034,15 @@ import { createInterface as createInterface4 } from "node:readline";
67029
67034
 
67030
67035
  // src/cli/telegram-yaml.ts
67031
67036
  var import_yaml11 = __toESM(require_dist(), 1);
67037
+ function setLinearAgent(yamlText, agentName, opts) {
67038
+ const doc = import_yaml11.parseDocument(yamlText);
67039
+ ensureAgent(doc, agentName);
67040
+ const block = { enabled: true, token: opts.token };
67041
+ if (opts.workspaceId)
67042
+ block.workspace_id = opts.workspaceId;
67043
+ doc.setIn(["agents", agentName, "channels", "telegram", "linear_agent"], block);
67044
+ return String(doc);
67045
+ }
67032
67046
  function setTelegramFeature(yamlText, agentName, feature, value) {
67033
67047
  const doc = import_yaml11.parseDocument(yamlText);
67034
67048
  ensureAgent(doc, agentName);
@@ -67587,6 +67601,100 @@ function promptHidden2(prompt) {
67587
67601
  });
67588
67602
  }
67589
67603
 
67604
+ // src/cli/linear-agent.ts
67605
+ init_source();
67606
+ init_helpers();
67607
+ import { readFileSync as readFileSync39, writeFileSync as writeFileSync22 } from "node:fs";
67608
+ function registerLinearAgentCommand(program3) {
67609
+ const linear = program3.command("linear-agent").description("Install an agent into a Linear workspace as a first-class app actor (#2298) \u2014 @-mentionable, delegate-assignable, agent sessions wake it instantly.");
67610
+ linear.command("setup").description("Provision <agent> as a Linear agent. Vault-stores the Linear OAuth app token (actor=app) under 'linear/<agent>/token' and enables the linear_agent block in switchroom.yaml. The OAuth browser authorize step is printed as instructions (it can't run headless); pass the already-obtained --token.").requiredOption("--agent <name>", "Agent name (must exist in switchroom.yaml)").requiredOption("--token <token>", "The Linear OAuth app token (actor=app), obtained out-of-band via the browser authorize step. Stored in the vault, never in switchroom.yaml.").option("--client-id <id>", "Linear OAuth app client id (for the printed authorize-URL hint).").option("--client-secret <secret>", "Linear OAuth app client secret (informational \u2014 not stored by this verb).").option("--redirect-uri <uri>", "OAuth redirect URI registered on the Linear app (for the authorize-URL hint).").option("--workspace-id <id>", "Optional Linear workspace (organization) id to record in config.").option("--webhook-base <url>", "Base URL of the switchroom web server (e.g. https://hooks.switchroom.ai). Used to print the webhook URL to register in Linear. Defaults to a placeholder.").option("--dry-run", "Print the YAML diff + instructions without writing or vaulting anything").action(withConfigError(async (opts) => {
67611
+ if (!/^[a-z][a-z0-9_-]{0,63}$/.test(opts.agent)) {
67612
+ fail2(`--agent must be a lowercase agent slug (got '${opts.agent}').`);
67613
+ }
67614
+ if (!opts.token || opts.token.trim().length === 0) {
67615
+ fail2("--token must be a non-empty Linear app token.");
67616
+ }
67617
+ const vaultKey = `linear/${opts.agent}/token`;
67618
+ if (!opts.dryRun) {
67619
+ await vaultPut(program3, vaultKey, opts.token);
67620
+ } else {
67621
+ console.log(source_default.gray(`[dry-run] would store the Linear token in the vault as '${vaultKey}'`));
67622
+ }
67623
+ const path4 = getConfigPath(program3);
67624
+ const before = readFileSync39(path4, "utf-8");
67625
+ let after;
67626
+ try {
67627
+ after = setLinearAgent(before, opts.agent, {
67628
+ token: `vault:${vaultKey}`,
67629
+ ...opts.workspaceId ? { workspaceId: opts.workspaceId } : {}
67630
+ });
67631
+ } catch (err) {
67632
+ fail2(err.message);
67633
+ }
67634
+ if (opts.dryRun) {
67635
+ console.log(source_default.bold(`[dry-run] would edit ${path4}`));
67636
+ console.log(makeUnifiedDiff2(before, after));
67637
+ } else {
67638
+ writeFileSync22(path4, after, "utf-8");
67639
+ console.log(source_default.green(`\u2713 Enabled linear-agent for agent '${opts.agent}'`));
67640
+ console.log(source_default.gray(` Vault key: ${vaultKey}`));
67641
+ console.log(source_default.gray(` Run 'switchroom agent restart ${opts.agent}' to pick up the change.`));
67642
+ }
67643
+ printLinearInstructions(opts, vaultKey);
67644
+ }));
67645
+ }
67646
+ function printLinearInstructions(opts, vaultKey) {
67647
+ const base = opts.webhookBase ?? "https://<your-switchroom-web-host>";
67648
+ const webhookUrl = `${base.replace(/\/$/, "")}/webhook/${opts.agent}/linear`;
67649
+ console.log("");
67650
+ console.log(source_default.bold("Next steps in Linear (browser, one-time per agent):"));
67651
+ console.log(source_default.gray(" 1. Create / open your Linear OAuth app with actor=app and scopes"));
67652
+ console.log(source_default.gray(" app:mentionable + app:assignable (https://linear.app/developers/agents)."));
67653
+ if (opts.clientId) {
67654
+ const redirect = opts.redirectUri ?? `${base.replace(/\/$/, "")}/oauth/callback`;
67655
+ const authorizeUrl = `https://linear.app/oauth/authorize?` + `client_id=${encodeURIComponent(opts.clientId)}` + `&redirect_uri=${encodeURIComponent(redirect)}` + `&response_type=code` + `&scope=${encodeURIComponent("read,write,app:assignable,app:mentionable")}` + `&actor=app`;
67656
+ console.log(source_default.gray(" 2. Authorize the app as an actor (open in a browser):"));
67657
+ console.log(source_default.cyan(` ${authorizeUrl}`));
67658
+ console.log(source_default.gray(" The redirect delivers the app token you pass to this verb via --token."));
67659
+ } else {
67660
+ console.log(source_default.gray(" 2. Authorize the app (actor=app) in a browser; capture the app token and"));
67661
+ console.log(source_default.gray(" re-run this verb with --token (and optionally --client-id to print the"));
67662
+ console.log(source_default.gray(" authorize URL)."));
67663
+ }
67664
+ console.log(source_default.gray(" 3. Register this webhook URL on the app (AgentSessionEvent + Issue/Comment):"));
67665
+ console.log(source_default.cyan(` ${webhookUrl}`));
67666
+ console.log(source_default.gray(" Use Linear's signing secret as the webhook secret \u2014 store it in the vault " + `under webhook/${opts.agent}/linear (e.g. 'switchroom telegram enable webhook ` + `--agent ${opts.agent} --source linear --secret <signing-secret>').`));
67667
+ console.log("");
67668
+ console.log(source_default.gray(` Token is read at runtime from vault:${vaultKey} (actor=app).`));
67669
+ }
67670
+ function makeUnifiedDiff2(before, after) {
67671
+ const a = before.split(`
67672
+ `);
67673
+ const b = after.split(`
67674
+ `);
67675
+ const out = [];
67676
+ let i = 0, j = 0;
67677
+ while (i < a.length || j < b.length) {
67678
+ if (i < a.length && j < b.length && a[i] === b[j]) {
67679
+ out.push(` ${a[i]}`);
67680
+ i++;
67681
+ j++;
67682
+ } else if (j < b.length && (i >= a.length || a[i] !== b[j])) {
67683
+ out.push(source_default.green(`+ ${b[j]}`));
67684
+ j++;
67685
+ } else {
67686
+ out.push(source_default.red(`- ${a[i]}`));
67687
+ i++;
67688
+ }
67689
+ }
67690
+ return out.join(`
67691
+ `);
67692
+ }
67693
+ function fail2(msg) {
67694
+ console.error(source_default.red(`Error: ${msg}`));
67695
+ process.exit(1);
67696
+ }
67697
+
67590
67698
  // src/cli/memory.ts
67591
67699
  init_source();
67592
67700
  init_hindsight();
@@ -67856,7 +67964,7 @@ async function ensureHindsightConsumer(configPath, account, uid = HINDSIGHT_DEFA
67856
67964
  // src/cli/memory.ts
67857
67965
  init_loader();
67858
67966
  var import_yaml12 = __toESM(require_dist(), 1);
67859
- import { existsSync as existsSync44, readFileSync as readFileSync39, writeFileSync as writeFileSync22 } from "node:fs";
67967
+ import { existsSync as existsSync44, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "node:fs";
67860
67968
  import { join as join39 } from "node:path";
67861
67969
  function readRecallLog(agentDir, limit) {
67862
67970
  const path4 = join39(agentDir, ".claude", "plugins", "data", "hindsight-memory-inline", "state", "recall_log.jsonl");
@@ -67864,7 +67972,7 @@ function readRecallLog(agentDir, limit) {
67864
67972
  return [];
67865
67973
  let raw;
67866
67974
  try {
67867
- raw = readFileSync39(path4, "utf-8");
67975
+ raw = readFileSync40(path4, "utf-8");
67868
67976
  } catch {
67869
67977
  return [];
67870
67978
  }
@@ -68059,7 +68167,7 @@ Cross-agent reflection plan
68059
68167
  const configPath = getConfigPath(program3);
68060
68168
  try {
68061
68169
  if (existsSync44(configPath)) {
68062
- const raw = readFileSync39(configPath, "utf-8");
68170
+ const raw = readFileSync40(configPath, "utf-8");
68063
68171
  const doc = import_yaml12.default.parseDocument(raw);
68064
68172
  if (!doc.has("memory")) {
68065
68173
  doc.set("memory", { backend: "hindsight", shared_collection: "shared", config: { provider, url } });
@@ -68075,7 +68183,7 @@ Cross-agent reflection plan
68075
68183
  }
68076
68184
  }
68077
68185
  }
68078
- writeFileSync22(configPath, doc.toString(), "utf-8");
68186
+ writeFileSync23(configPath, doc.toString(), "utf-8");
68079
68187
  console.log(source_default.gray(` Updated ${configPath} with memory.config.url = ${url}`));
68080
68188
  console.log(source_default.gray(" Run `switchroom agent reconcile all --restart` to apply this to existing agents."));
68081
68189
  }
@@ -68168,7 +68276,7 @@ init_loader();
68168
68276
  init_client();
68169
68277
  init_lifecycle();
68170
68278
  import {
68171
- readFileSync as readFileSync45,
68279
+ readFileSync as readFileSync46,
68172
68280
  existsSync as existsSync50,
68173
68281
  realpathSync as realpathSync4,
68174
68282
  mkdirSync as mkdirSync29,
@@ -68187,7 +68295,7 @@ init_lifecycle();
68187
68295
  init_manager();
68188
68296
  init_hindsight();
68189
68297
  import { spawnSync as spawnSync5 } from "node:child_process";
68190
- import { existsSync as existsSync47, readFileSync as readFileSync42, statSync as statSync22 } from "node:fs";
68298
+ import { existsSync as existsSync47, readFileSync as readFileSync43, statSync as statSync22 } from "node:fs";
68191
68299
  import { resolve as resolve27 } from "node:path";
68192
68300
  init_audit_reader();
68193
68301
 
@@ -72695,8 +72803,8 @@ init_paths();
72695
72803
  import {
72696
72804
  existsSync as existsSync45,
72697
72805
  mkdirSync as mkdirSync25,
72698
- readFileSync as readFileSync40,
72699
- writeFileSync as writeFileSync23
72806
+ readFileSync as readFileSync41,
72807
+ writeFileSync as writeFileSync24
72700
72808
  } from "node:fs";
72701
72809
  import { dirname as dirname9 } from "node:path";
72702
72810
  import { randomUUID as randomUUID3 } from "node:crypto";
@@ -72716,7 +72824,7 @@ function getDistinctId() {
72716
72824
  const path4 = resolveStatePath("analytics-id");
72717
72825
  try {
72718
72826
  if (existsSync45(path4)) {
72719
- const existing = readFileSync40(path4, "utf-8").trim();
72827
+ const existing = readFileSync41(path4, "utf-8").trim();
72720
72828
  if (existing) {
72721
72829
  cachedDistinctId = existing;
72722
72830
  return existing;
@@ -72727,7 +72835,7 @@ function getDistinctId() {
72727
72835
  cachedDistinctId = id;
72728
72836
  try {
72729
72837
  mkdirSync25(dirname9(path4), { recursive: true });
72730
- writeFileSync23(path4, id, "utf-8");
72838
+ writeFileSync24(path4, id, "utf-8");
72731
72839
  } catch {}
72732
72840
  return id;
72733
72841
  }
@@ -72852,7 +72960,7 @@ function getAgentWorkspaceAccount(yamlText, provider, agent) {
72852
72960
  // src/web/config-edit-plan.ts
72853
72961
  init_schema();
72854
72962
  var import_yaml14 = __toESM(require_dist(), 1);
72855
- import { readFileSync as readFileSync41 } from "node:fs";
72963
+ import { readFileSync as readFileSync42 } from "node:fs";
72856
72964
 
72857
72965
  class ConfigPlanError extends Error {
72858
72966
  }
@@ -72862,7 +72970,7 @@ function composeTransforms(...transforms) {
72862
72970
  function planConfigEdit(configPath, transform) {
72863
72971
  let before;
72864
72972
  try {
72865
- before = readFileSync41(configPath, "utf-8");
72973
+ before = readFileSync42(configPath, "utf-8");
72866
72974
  } catch (err) {
72867
72975
  throw new ConfigPlanError(`could not read config: ${err.message}`);
72868
72976
  }
@@ -72893,7 +73001,7 @@ import {
72893
73001
  mkdirSync as mkdirSync26,
72894
73002
  mkdtempSync as mkdtemp,
72895
73003
  rmSync as rmrf,
72896
- writeFileSync as writeFileSync24
73004
+ writeFileSync as writeFileSync25
72897
73005
  } from "node:fs";
72898
73006
  import { spawnSync as spawnSync4 } from "node:child_process";
72899
73007
  import { tmpdir as tmpdir4 } from "node:os";
@@ -72908,8 +73016,8 @@ function generateUnifiedDiff(before, after, name = "switchroom.yaml", gitBin = "
72908
73016
  try {
72909
73017
  mkdirSync26(join41(dir, "cur"), { recursive: true });
72910
73018
  mkdirSync26(join41(dir, "new"), { recursive: true });
72911
- writeFileSync24(join41(dir, "cur", name), before);
72912
- writeFileSync24(join41(dir, "new", name), after);
73019
+ writeFileSync25(join41(dir, "cur", name), before);
73020
+ writeFileSync25(join41(dir, "new", name), after);
72913
73021
  const r = spawnSync4(gitBin, ["diff", "--no-index", "--no-color", "--", `cur/${name}`, `new/${name}`], { cwd: dir, encoding: "utf-8", timeout: 1e4 });
72914
73022
  if (r.status === 0)
72915
73023
  return "";
@@ -73546,7 +73654,7 @@ async function handleGetSystemHealth(config, home2) {
73546
73654
  const logPath = defaultAuditLogPath2(home2);
73547
73655
  if (existsSync47(logPath)) {
73548
73656
  hostd.auditLogPresent = true;
73549
- const raw = readFileSync42(logPath, "utf-8");
73657
+ const raw = readFileSync43(logPath, "utf-8");
73550
73658
  hostd.recent = readAndFilter(raw, {}, 10);
73551
73659
  }
73552
73660
  } catch (err) {
@@ -73906,7 +74014,7 @@ async function handleGetMemoryHealth(config, opts) {
73906
74014
  }
73907
74015
 
73908
74016
  // src/web/webhook-handler.ts
73909
- import { appendFileSync as appendFileSync4, existsSync as existsSync49, mkdirSync as mkdirSync28, readFileSync as readFileSync44, writeFileSync as writeFileSync25 } from "fs";
74017
+ import { appendFileSync as appendFileSync4, existsSync as existsSync49, mkdirSync as mkdirSync28, readFileSync as readFileSync45, writeFileSync as writeFileSync26 } from "fs";
73910
74018
  import { join as join45 } from "path";
73911
74019
  import { homedir as homedir24 } from "os";
73912
74020
 
@@ -74113,7 +74221,7 @@ function forwardToGateway(socketPath, req, opts = {}) {
74113
74221
  }
74114
74222
 
74115
74223
  // src/web/webhook-edge.ts
74116
- import { existsSync as existsSync48, readFileSync as readFileSync43 } from "fs";
74224
+ import { existsSync as existsSync48, readFileSync as readFileSync44 } from "fs";
74117
74225
  import { join as join44 } from "path";
74118
74226
  import { homedir as homedir23 } from "os";
74119
74227
  import { timingSafeEqual as timingSafeEqual2 } from "crypto";
@@ -74126,7 +74234,7 @@ function loadEdgeSecret(path4) {
74126
74234
  try {
74127
74235
  if (!existsSync48(p))
74128
74236
  return null;
74129
- const raw = readFileSync43(p, "utf-8").trim();
74237
+ const raw = readFileSync44(p, "utf-8").trim();
74130
74238
  return raw.length > 0 ? raw : null;
74131
74239
  } catch {
74132
74240
  return null;
@@ -74160,7 +74268,7 @@ function loadDedupFile(path4) {
74160
74268
  try {
74161
74269
  if (!existsSync49(path4))
74162
74270
  return {};
74163
- const raw = JSON.parse(readFileSync44(path4, "utf-8"));
74271
+ const raw = JSON.parse(readFileSync45(path4, "utf-8"));
74164
74272
  return typeof raw.deliveries === "object" && raw.deliveries !== null ? raw.deliveries : {};
74165
74273
  } catch {
74166
74274
  return {};
@@ -74174,7 +74282,7 @@ function saveDedupFile(path4, deliveries, now) {
74174
74282
  }
74175
74283
  const sorted = Object.entries(pruned).sort((a, b) => b[1] - a[1]).slice(0, DEDUP_MAX);
74176
74284
  const final = Object.fromEntries(sorted);
74177
- writeFileSync25(path4, JSON.stringify({ deliveries: final }), {
74285
+ writeFileSync26(path4, JSON.stringify({ deliveries: final }), {
74178
74286
  mode: 384
74179
74287
  });
74180
74288
  }
@@ -74443,7 +74551,7 @@ function resolveWebToken() {
74443
74551
  const home2 = process.env.HOME ?? homedir25();
74444
74552
  const tokenPath = join46(home2, ".switchroom", "web-token");
74445
74553
  if (existsSync50(tokenPath)) {
74446
- const existing = readFileSync45(tokenPath, "utf8").trim();
74554
+ const existing = readFileSync46(tokenPath, "utf8").trim();
74447
74555
  if (existing.length > 0)
74448
74556
  return existing;
74449
74557
  }
@@ -74460,7 +74568,7 @@ function resolveWebToken() {
74460
74568
  return token;
74461
74569
  } catch (err) {
74462
74570
  if (err.code === "EEXIST") {
74463
- const existing = readFileSync45(tokenPath, "utf8").trim();
74571
+ const existing = readFileSync46(tokenPath, "utf8").trim();
74464
74572
  if (existing.length > 0)
74465
74573
  return existing;
74466
74574
  }
@@ -74530,7 +74638,7 @@ function loadWebhookSecrets() {
74530
74638
  if (!existsSync50(path4))
74531
74639
  return {};
74532
74640
  try {
74533
- const parsed = JSON.parse(readFileSync45(path4, "utf-8"));
74641
+ const parsed = JSON.parse(readFileSync46(path4, "utf-8"));
74534
74642
  return parsed && typeof parsed === "object" ? parsed : {};
74535
74643
  } catch (err) {
74536
74644
  process.stderr.write(`webhook-ingest: failed to parse ${path4}: ${err.message} \u2014 webhooks will return 401 until fixed
@@ -74903,7 +75011,7 @@ function startWebServer(config, port, hostname = "127.0.0.1", configPath) {
74903
75011
  }
74904
75012
  const ext = extname(realFullPath);
74905
75013
  const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
74906
- const content = readFileSync45(realFullPath);
75014
+ const content = readFileSync46(realFullPath);
74907
75015
  return new Response(content, {
74908
75016
  headers: { "Content-Type": contentType }
74909
75017
  });
@@ -75037,7 +75145,7 @@ Starting Switchroom dashboard...
75037
75145
  // src/cli/setup.ts
75038
75146
  init_source();
75039
75147
  init_loader();
75040
- import { existsSync as existsSync51, copyFileSync as copyFileSync8, readFileSync as readFileSync46, writeFileSync as writeFileSync26, mkdirSync as mkdirSync30 } from "node:fs";
75148
+ import { existsSync as existsSync51, copyFileSync as copyFileSync8, readFileSync as readFileSync47, writeFileSync as writeFileSync27, mkdirSync as mkdirSync30 } from "node:fs";
75041
75149
  import { resolve as resolve29, dirname as dirname11 } from "node:path";
75042
75150
  init_vault();
75043
75151
  init_manager();
@@ -75766,10 +75874,10 @@ async function stepAutoUnlock(config, switchroomConfigPath, nonInteractive) {
75766
75874
  try {
75767
75875
  const yamlPath = existsSync51(resolve29(process.cwd(), "switchroom.yaml")) ? resolve29(process.cwd(), "switchroom.yaml") : resolve29(process.cwd(), "switchroom.yml");
75768
75876
  if (existsSync51(yamlPath)) {
75769
- const content = readFileSync46(yamlPath, "utf-8");
75877
+ const content = readFileSync47(yamlPath, "utf-8");
75770
75878
  const result = insertVaultBrokerApprovalAuth(content, "telegram-id");
75771
75879
  if (result.kind === "rewritten") {
75772
- writeFileSync26(yamlPath, result.content, "utf-8");
75880
+ writeFileSync27(yamlPath, result.content, "utf-8");
75773
75881
  console.log(source_default.green(` ${STEP_DONE} Set vault.broker.approvalAuth: telegram-id in ${yamlPath}`));
75774
75882
  } else if (result.kind === "already-set") {
75775
75883
  console.log(source_default.gray(" approvalAuth already set \u2014 leaving it alone."));
@@ -75801,7 +75909,7 @@ async function stepDangerousMode(config, nonInteractive) {
75801
75909
  ];
75802
75910
  for (const configPath of configPaths) {
75803
75911
  if (existsSync51(configPath)) {
75804
- let content = readFileSync46(configPath, "utf-8");
75912
+ let content = readFileSync47(configPath, "utf-8");
75805
75913
  const agentNames = Object.keys(config.agents);
75806
75914
  for (const name of agentNames) {
75807
75915
  const agentPattern = new RegExp(`(^ ${name}:\\s*\\n)`, "m");
@@ -75815,7 +75923,7 @@ async function stepDangerousMode(config, nonInteractive) {
75815
75923
  }
75816
75924
  config.agents[name].dangerous_mode = true;
75817
75925
  }
75818
- writeFileSync26(configPath, content, "utf-8");
75926
+ writeFileSync27(configPath, content, "utf-8");
75819
75927
  console.log(source_default.green(` ${STEP_DONE} Enabled dangerous_mode for all agents in ${configPath}`));
75820
75928
  break;
75821
75929
  }
@@ -75930,7 +76038,7 @@ init_doctor();
75930
76038
  init_source();
75931
76039
  init_loader();
75932
76040
  init_lifecycle();
75933
- import { cpSync as cpSync2, existsSync as existsSync58, mkdirSync as mkdirSync32, readFileSync as readFileSync51, realpathSync as realpathSync6, rmSync as rmSync12, statSync as statSync26 } from "node:fs";
76041
+ import { cpSync as cpSync2, existsSync as existsSync58, mkdirSync as mkdirSync32, readFileSync as readFileSync52, realpathSync as realpathSync6, rmSync as rmSync12, statSync as statSync26 } from "node:fs";
75934
76042
  import { spawnSync as spawnSync9 } from "node:child_process";
75935
76043
  import { join as join60, dirname as dirname14, resolve as resolve33 } from "node:path";
75936
76044
  import { homedir as homedir36 } from "node:os";
@@ -75940,7 +76048,7 @@ function runningFromSwitchroomCheckout(scriptPath) {
75940
76048
  for (let i = 0;i < 12; i++) {
75941
76049
  if (existsSync58(join60(dir, ".git"))) {
75942
76050
  try {
75943
- const pkg = JSON.parse(readFileSync51(join60(dir, "package.json"), "utf-8"));
76051
+ const pkg = JSON.parse(readFileSync52(join60(dir, "package.json"), "utf-8"));
75944
76052
  if (pkg.name === "switchroom")
75945
76053
  return true;
75946
76054
  } catch {}
@@ -76208,7 +76316,7 @@ function defaultStatusProbe(composePath) {
76208
76316
  const pkgPath = join60(dir, "package.json");
76209
76317
  if (existsSync58(pkgPath)) {
76210
76318
  try {
76211
- const pkg = JSON.parse(readFileSync51(pkgPath, "utf-8"));
76319
+ const pkg = JSON.parse(readFileSync52(pkgPath, "utf-8"));
76212
76320
  if (typeof pkg.version === "string")
76213
76321
  cliVersion = pkg.version;
76214
76322
  } catch (err) {
@@ -76424,7 +76532,7 @@ init_source();
76424
76532
  init_helpers();
76425
76533
  init_lifecycle();
76426
76534
  import { execSync as execSync4 } from "node:child_process";
76427
- import { existsSync as existsSync59, readFileSync as readFileSync52 } from "node:fs";
76535
+ import { existsSync as existsSync59, readFileSync as readFileSync53 } from "node:fs";
76428
76536
  import { dirname as dirname15, join as join61 } from "node:path";
76429
76537
  function getClaudeCodeVersion() {
76430
76538
  try {
@@ -76478,7 +76586,7 @@ function locateSwitchroomInstallDir() {
76478
76586
  const pkgPath = join61(dir, "package.json");
76479
76587
  if (existsSync59(pkgPath)) {
76480
76588
  try {
76481
- const pkg = JSON.parse(readFileSync52(pkgPath, "utf-8"));
76589
+ const pkg = JSON.parse(readFileSync53(pkgPath, "utf-8"));
76482
76590
  if (pkg.name === "switchroom" && existsSync59(join61(dir, ".git"))) {
76483
76591
  return dir;
76484
76592
  }
@@ -76709,11 +76817,11 @@ import {
76709
76817
  mkdirSync as mkdirSync33,
76710
76818
  openSync as openSync11,
76711
76819
  readdirSync as readdirSync22,
76712
- readFileSync as readFileSync53,
76820
+ readFileSync as readFileSync54,
76713
76821
  renameSync as renameSync12,
76714
76822
  statSync as statSync27,
76715
76823
  unlinkSync as unlinkSync11,
76716
- writeFileSync as writeFileSync27,
76824
+ writeFileSync as writeFileSync28,
76717
76825
  writeSync as writeSync7
76718
76826
  } from "node:fs";
76719
76827
  import { join as join62 } from "node:path";
@@ -77119,7 +77227,7 @@ function readAll(stateDir) {
77119
77227
  return [];
77120
77228
  let raw;
77121
77229
  try {
77122
- raw = readFileSync53(path4, "utf-8");
77230
+ raw = readFileSync54(path4, "utf-8");
77123
77231
  } catch {
77124
77232
  return [];
77125
77233
  }
@@ -77267,7 +77375,7 @@ function writeAll(stateDir, events) {
77267
77375
  const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
77268
77376
  `) + `
77269
77377
  `;
77270
- writeFileSync27(tmp, body, "utf-8");
77378
+ writeFileSync28(tmp, body, "utf-8");
77271
77379
  renameSync12(tmp, path4);
77272
77380
  }
77273
77381
  var ORPHAN_TMP_TTL_MS = 60000;
@@ -77330,7 +77438,7 @@ function withLock(stateDir, fn) {
77330
77438
  function tryStealStaleLock(lockPath) {
77331
77439
  let pidStr;
77332
77440
  try {
77333
- pidStr = readFileSync53(lockPath, "utf-8").trim();
77441
+ pidStr = readFileSync54(lockPath, "utf-8").trim();
77334
77442
  } catch {
77335
77443
  return true;
77336
77444
  }
@@ -77587,9 +77695,9 @@ import { createHash as createHash11 } from "node:crypto";
77587
77695
  import {
77588
77696
  existsSync as existsSync61,
77589
77697
  mkdirSync as mkdirSync34,
77590
- readFileSync as readFileSync54,
77698
+ readFileSync as readFileSync55,
77591
77699
  rmSync as rmSync13,
77592
- writeFileSync as writeFileSync28
77700
+ writeFileSync as writeFileSync29
77593
77701
  } from "node:fs";
77594
77702
  import { dirname as dirname16, join as join63 } from "node:path";
77595
77703
  import { homedir as homedir37 } from "node:os";
@@ -77607,7 +77715,7 @@ function defaultPythonCacheRoot() {
77607
77715
  return join63(homedir37(), ".switchroom", "deps", "python");
77608
77716
  }
77609
77717
  function hashFile(path4) {
77610
- return createHash11("sha256").update(readFileSync54(path4)).digest("hex");
77718
+ return createHash11("sha256").update(readFileSync55(path4)).digest("hex");
77611
77719
  }
77612
77720
  function ensurePythonEnv(opts) {
77613
77721
  const { skillName, requirementsPath, force = false } = opts;
@@ -77623,7 +77731,7 @@ function ensurePythonEnv(opts) {
77623
77731
  const pipBin = join63(binDir, "pip");
77624
77732
  const targetHash = hashFile(requirementsPath);
77625
77733
  if (!force && existsSync61(stampPath) && existsSync61(pythonBin)) {
77626
- const existingHash = readFileSync54(stampPath, "utf8").trim();
77734
+ const existingHash = readFileSync55(stampPath, "utf8").trim();
77627
77735
  if (existingHash === targetHash) {
77628
77736
  return {
77629
77737
  skillName,
@@ -77657,7 +77765,7 @@ function ensurePythonEnv(opts) {
77657
77765
  const e = err;
77658
77766
  throw new PythonEnvError(`Failed to install requirements for skill "${skillName}": ${e.message}`, e.stderr?.toString());
77659
77767
  }
77660
- writeFileSync28(stampPath, targetHash + `
77768
+ writeFileSync29(stampPath, targetHash + `
77661
77769
  `);
77662
77770
  return {
77663
77771
  skillName,
@@ -77675,9 +77783,9 @@ import {
77675
77783
  copyFileSync as copyFileSync9,
77676
77784
  existsSync as existsSync62,
77677
77785
  mkdirSync as mkdirSync35,
77678
- readFileSync as readFileSync55,
77786
+ readFileSync as readFileSync56,
77679
77787
  rmSync as rmSync14,
77680
- writeFileSync as writeFileSync29
77788
+ writeFileSync as writeFileSync30
77681
77789
  } from "node:fs";
77682
77790
  import { dirname as dirname17, join as join64 } from "node:path";
77683
77791
  import { homedir as homedir38 } from "node:os";
@@ -77710,7 +77818,7 @@ function hashDepInputs(packageJsonPath) {
77710
77818
  const hasher = createHash12("sha256");
77711
77819
  hasher.update(`package.json
77712
77820
  `);
77713
- hasher.update(readFileSync55(packageJsonPath));
77821
+ hasher.update(readFileSync56(packageJsonPath));
77714
77822
  for (const lockName of ALL_LOCKFILES) {
77715
77823
  const lockPath = join64(sourceDir, lockName);
77716
77824
  if (existsSync62(lockPath)) {
@@ -77719,7 +77827,7 @@ function hashDepInputs(packageJsonPath) {
77719
77827
  hasher.update(lockName);
77720
77828
  hasher.update(`
77721
77829
  `);
77722
- hasher.update(readFileSync55(lockPath));
77830
+ hasher.update(readFileSync56(lockPath));
77723
77831
  }
77724
77832
  }
77725
77833
  return hasher.digest("hex");
@@ -77738,7 +77846,7 @@ function ensureNodeEnv(opts) {
77738
77846
  const binDir = join64(nodeModulesDir, ".bin");
77739
77847
  const targetHash = hashDepInputs(packageJsonPath);
77740
77848
  if (!force && existsSync62(stampPath) && existsSync62(nodeModulesDir)) {
77741
- const existingHash = readFileSync55(stampPath, "utf8").trim();
77849
+ const existingHash = readFileSync56(stampPath, "utf8").trim();
77742
77850
  if (existingHash === targetHash) {
77743
77851
  return {
77744
77852
  skillName,
@@ -77774,7 +77882,7 @@ function ensureNodeEnv(opts) {
77774
77882
  const e = err;
77775
77883
  throw new NodeEnvError(`Failed to install node deps for skill "${skillName}" with ${installer}: ${e.message}`, e.stderr?.toString());
77776
77884
  }
77777
- writeFileSync29(stampPath, targetHash + `
77885
+ writeFileSync30(stampPath, targetHash + `
77778
77886
  `);
77779
77887
  return {
77780
77888
  skillName,
@@ -78757,7 +78865,7 @@ function safeParseInt(value, fallback) {
78757
78865
  init_helpers();
78758
78866
  init_loader();
78759
78867
  init_merge();
78760
- import { copyFileSync as copyFileSync10, existsSync as existsSync65, readFileSync as readFileSync56, writeFileSync as writeFileSync30 } from "node:fs";
78868
+ import { copyFileSync as copyFileSync10, existsSync as existsSync65, readFileSync as readFileSync57, writeFileSync as writeFileSync31 } from "node:fs";
78761
78869
  import { join as join66, resolve as resolve39 } from "node:path";
78762
78870
  init_schema();
78763
78871
  function resolveSoulTargetOrExit(program3, agentName) {
@@ -78803,7 +78911,7 @@ function registerSoulCommand(program3) {
78803
78911
  console.error(`soul: ${t.soulPath} does not exist yet \u2014 run ` + `\`switchroom soul reset ${agentName}\` to seed it.`);
78804
78912
  process.exit(1);
78805
78913
  }
78806
- process.stdout.write(readFileSync56(t.soulPath, "utf-8"));
78914
+ process.stdout.write(readFileSync57(t.soulPath, "utf-8"));
78807
78915
  }));
78808
78916
  cmd.command("reset <agent>").description("Re-seed SOUL.md from the agent's current profile " + "(backs the existing file up to SOUL.md.bak first)").option("-y, --yes", "Skip the confirmation prompt").action(withConfigError(async (agentName, opts) => {
78809
78917
  const t = resolveSoulTargetOrExit(program3, agentName);
@@ -78834,7 +78942,7 @@ function registerSoulCommand(program3) {
78834
78942
  }
78835
78943
  copyFileSync10(t.soulPath, backupPath);
78836
78944
  }
78837
- writeFileSync30(t.soulPath, content, "utf-8");
78945
+ writeFileSync31(t.soulPath, content, "utf-8");
78838
78946
  if (backupPath) {
78839
78947
  console.log(`soul: re-seeded ${agentName}'s SOUL.md from profile ` + `"${t.profileName}".
78840
78948
  ` + ` Previous version saved to ${backupPath}`);
@@ -78848,7 +78956,7 @@ function registerSoulCommand(program3) {
78848
78956
  // src/cli/debug.ts
78849
78957
  init_helpers();
78850
78958
  init_loader();
78851
- import { existsSync as existsSync66, readFileSync as readFileSync57, readdirSync as readdirSync23, statSync as statSync28 } from "node:fs";
78959
+ import { existsSync as existsSync66, readFileSync as readFileSync58, readdirSync as readdirSync23, statSync as statSync28 } from "node:fs";
78852
78960
  import { resolve as resolve40, join as join67 } from "node:path";
78853
78961
  import { createHash as createHash13 } from "node:crypto";
78854
78962
  init_merge();
@@ -78864,7 +78972,7 @@ function readMcpServerNames(agentDir) {
78864
78972
  if (!existsSync66(mcpPath))
78865
78973
  return [];
78866
78974
  try {
78867
- const parsed = JSON.parse(readFileSync57(mcpPath, "utf-8"));
78975
+ const parsed = JSON.parse(readFileSync58(mcpPath, "utf-8"));
78868
78976
  return Object.keys(parsed.mcpServers ?? {});
78869
78977
  } catch {
78870
78978
  return null;
@@ -78899,7 +79007,7 @@ function findLatestTranscriptJsonl(claudeConfigDir) {
78899
79007
  }
78900
79008
  function extractLatestUserMessage(transcriptPath) {
78901
79009
  try {
78902
- const content = readFileSync57(transcriptPath, "utf-8");
79010
+ const content = readFileSync58(transcriptPath, "utf-8");
78903
79011
  const lines = content.trim().split(`
78904
79012
  `).filter(Boolean);
78905
79013
  for (let i = lines.length - 1;i >= 0; i--) {
@@ -79003,7 +79111,7 @@ function registerDebugCommand(program3) {
79003
79111
  }
79004
79112
  console.log(`=== Append System Prompt (per-session) ===
79005
79113
  `);
79006
- const handoffContent = existsSync66(handoffPath) ? readFileSync57(handoffPath, "utf-8") : "";
79114
+ const handoffContent = existsSync66(handoffPath) ? readFileSync58(handoffPath, "utf-8") : "";
79007
79115
  if (handoffContent.trim().length > 0) {
79008
79116
  console.log(`-- Handoff Briefing (${formatBytes(handoffContent.length)}) --`);
79009
79117
  console.log(handoffContent);
@@ -79014,7 +79122,7 @@ function registerDebugCommand(program3) {
79014
79122
  }
79015
79123
  console.log(`=== CLAUDE.md (auto-loaded by Claude Code) ===
79016
79124
  `);
79017
- const claudeMdContent = existsSync66(claudeMdPath) ? readFileSync57(claudeMdPath, "utf-8") : "";
79125
+ const claudeMdContent = existsSync66(claudeMdPath) ? readFileSync58(claudeMdPath, "utf-8") : "";
79018
79126
  if (claudeMdContent.trim().length > 0) {
79019
79127
  console.log(`(${formatBytes(claudeMdContent.length)})`);
79020
79128
  console.log(claudeMdContent);
@@ -79025,7 +79133,7 @@ function registerDebugCommand(program3) {
79025
79133
  }
79026
79134
  console.log(`=== Persona (SOUL.md) ===
79027
79135
  `);
79028
- const soulMdContent = existsSync66(soulMdPath) ? readFileSync57(soulMdPath, "utf-8") : existsSync66(workspaceSoulMdPath) ? readFileSync57(workspaceSoulMdPath, "utf-8") : "";
79136
+ const soulMdContent = existsSync66(soulMdPath) ? readFileSync58(soulMdPath, "utf-8") : existsSync66(workspaceSoulMdPath) ? readFileSync58(workspaceSoulMdPath, "utf-8") : "";
79029
79137
  if (soulMdContent.trim().length > 0) {
79030
79138
  console.log(`(${formatBytes(soulMdContent.length)})`);
79031
79139
  console.log(soulMdContent);
@@ -79089,8 +79197,8 @@ function registerDebugCommand(program3) {
79089
79197
  const fleetDir = join67(agentsDir, "..", "fleet");
79090
79198
  const fleetInvPath = join67(fleetDir, "switchroom-invariants.md");
79091
79199
  const fleetClaudePath = join67(fleetDir, "CLAUDE.md");
79092
- const fleetInvBytes = existsSync66(fleetInvPath) ? readFileSync57(fleetInvPath, "utf-8").length : 0;
79093
- const fleetClaudeBytes = existsSync66(fleetClaudePath) ? readFileSync57(fleetClaudePath, "utf-8").length : 0;
79200
+ const fleetInvBytes = existsSync66(fleetInvPath) ? readFileSync58(fleetInvPath, "utf-8").length : 0;
79201
+ const fleetClaudeBytes = existsSync66(fleetClaudePath) ? readFileSync58(fleetClaudePath, "utf-8").length : 0;
79094
79202
  const fleetBytes = fleetInvBytes + fleetClaudeBytes;
79095
79203
  const totalBytes = stableBytes + perSessionBytes + claudeMdBytes + fleetBytes + perTurnBytes + userBytes;
79096
79204
  console.log(`Stable prefix: ${formatBytes(stableBytes).padEnd(20)} (cache-hot; includes SOUL.md ${soulMdBytes.toLocaleString()}B)`);
@@ -79131,8 +79239,8 @@ import { randomBytes as randomBytes13 } from "node:crypto";
79131
79239
  // src/worktree/registry.ts
79132
79240
  import {
79133
79241
  mkdirSync as mkdirSync36,
79134
- writeFileSync as writeFileSync31,
79135
- readFileSync as readFileSync58,
79242
+ writeFileSync as writeFileSync32,
79243
+ readFileSync as readFileSync59,
79136
79244
  readdirSync as readdirSync24,
79137
79245
  unlinkSync as unlinkSync12,
79138
79246
  existsSync as existsSync67,
@@ -79153,14 +79261,14 @@ function writeRecord(record2) {
79153
79261
  ensureDir2();
79154
79262
  const target = recordPath(record2.id);
79155
79263
  const tmp = `${target}.tmp${process.pid}`;
79156
- writeFileSync31(tmp, JSON.stringify(record2, null, 2) + `
79264
+ writeFileSync32(tmp, JSON.stringify(record2, null, 2) + `
79157
79265
  `, { mode: 384 });
79158
79266
  renameSync13(tmp, target);
79159
79267
  }
79160
79268
  function readRecord(id) {
79161
79269
  const path7 = recordPath(id);
79162
79270
  try {
79163
- const raw = readFileSync58(path7, "utf8");
79271
+ const raw = readFileSync59(path7, "utf8");
79164
79272
  return JSON.parse(raw);
79165
79273
  } catch {
79166
79274
  return null;
@@ -79525,7 +79633,7 @@ import {
79525
79633
  mkdirSync as mkdirSync38,
79526
79634
  readdirSync as readdirSync25,
79527
79635
  rmSync as rmSync15,
79528
- writeFileSync as writeFileSync32
79636
+ writeFileSync as writeFileSync33
79529
79637
  } from "node:fs";
79530
79638
  import { join as join70 } from "node:path";
79531
79639
  function encodeCredentialsFilename(email) {
@@ -79727,7 +79835,7 @@ function writeSeedFile(dir, email, seed) {
79727
79835
  }
79728
79836
  const filename = encodeCredentialsFilename(email);
79729
79837
  const filePath = join70(dir, filename);
79730
- writeFileSync32(filePath, JSON.stringify(seed), { mode: 384 });
79838
+ writeFileSync33(filePath, JSON.stringify(seed), { mode: 384 });
79731
79839
  chmodSync9(filePath, 384);
79732
79840
  return filePath;
79733
79841
  }
@@ -79885,7 +79993,7 @@ function registerDriveMcpLauncherCommand(program3) {
79885
79993
  // src/cli/m365-mcp-launcher.ts
79886
79994
  init_scaffold_integration();
79887
79995
  import { spawn as spawn6 } from "node:child_process";
79888
- import { writeFileSync as writeFileSync33, mkdirSync as mkdirSync39 } from "node:fs";
79996
+ import { writeFileSync as writeFileSync34, mkdirSync as mkdirSync39 } from "node:fs";
79889
79997
  import { dirname as dirname18, join as join71 } from "node:path";
79890
79998
  var SOFTERIA_TOKEN_ENV = "MS365_MCP_OAUTH_TOKEN";
79891
79999
  var DEFAULT_REFRESH_LEAD_MS = 5 * 60 * 1000;
@@ -79912,7 +80020,7 @@ function writeRefreshHeartbeat(agentName, data) {
79912
80020
  const path7 = heartbeatPath(agentName);
79913
80021
  try {
79914
80022
  mkdirSync39(dirname18(path7), { recursive: true });
79915
- writeFileSync33(path7, JSON.stringify(data, null, 2), { mode: 420 });
80023
+ writeFileSync34(path7, JSON.stringify(data, null, 2), { mode: 420 });
79916
80024
  } catch {}
79917
80025
  }
79918
80026
  function heartbeatPath(agentName) {
@@ -80103,7 +80211,7 @@ function registerM365McpLauncherCommand(program3) {
80103
80211
  // src/cli/notion-mcp-launcher.ts
80104
80212
  init_scaffold_integration();
80105
80213
  import { spawn as spawn7 } from "node:child_process";
80106
- import { existsSync as existsSync71, mkdirSync as mkdirSync40, writeFileSync as writeFileSync34 } from "node:fs";
80214
+ import { existsSync as existsSync71, mkdirSync as mkdirSync40, writeFileSync as writeFileSync35 } from "node:fs";
80107
80215
  import { dirname as dirname19 } from "node:path";
80108
80216
  var HEARTBEAT_WRITE_INTERVAL_MS = 30 * 1000;
80109
80217
  var DEFAULT_HEARTBEAT_PATH = "/state/agent/notion-launcher.heartbeat.json";
@@ -80117,7 +80225,7 @@ function defaultWriteHeartbeat(path7, contents) {
80117
80225
  const dir = dirname19(path7);
80118
80226
  if (!existsSync71(dir))
80119
80227
  mkdirSync40(dir, { recursive: true });
80120
- writeFileSync34(path7, contents);
80228
+ writeFileSync35(path7, contents);
80121
80229
  } catch {}
80122
80230
  }
80123
80231
  async function runNotionMcpLauncher(opts, runtime) {
@@ -80227,7 +80335,7 @@ function registerNotionMcpLauncherCommand(program3) {
80227
80335
 
80228
80336
  // src/cli/deliver-file.ts
80229
80337
  init_client2();
80230
- import { readFileSync as readFileSync59, statSync as statSync29 } from "node:fs";
80338
+ import { readFileSync as readFileSync60, statSync as statSync29 } from "node:fs";
80231
80339
  import { basename as basename8 } from "node:path";
80232
80340
 
80233
80341
  // src/delivery/onedrive.ts
@@ -80567,7 +80675,7 @@ async function defaultResolveProvider() {
80567
80675
  async function runDeliverFile(localPath, deps = {}) {
80568
80676
  const agentName = safeAgentName(deps.agentName ?? process.env.SWITCHROOM_AGENT_NAME);
80569
80677
  const sizeOf = deps.fileSize ?? ((p) => statSync29(p).size);
80570
- const read = deps.readFile ?? ((p) => new Uint8Array(readFileSync59(p)));
80678
+ const read = deps.readFile ?? ((p) => new Uint8Array(readFileSync60(p)));
80571
80679
  const resolveProvider = deps.resolveProvider ?? defaultResolveProvider;
80572
80680
  let size;
80573
80681
  try {
@@ -80857,7 +80965,7 @@ async function fetchToken(vaultKey) {
80857
80965
 
80858
80966
  // src/cli/apply.ts
80859
80967
  init_source();
80860
- import { accessSync as accessSync3, chownSync as chownSync5, constants as fsConstants6, copyFileSync as copyFileSync11, existsSync as existsSync74, mkdirSync as mkdirSync42, readFileSync as readFileSync61, readdirSync as readdirSync26, renameSync as renameSync14, writeFileSync as writeFileSync36 } from "node:fs";
80968
+ import { accessSync as accessSync3, chownSync as chownSync5, constants as fsConstants6, copyFileSync as copyFileSync11, existsSync as existsSync74, mkdirSync as mkdirSync42, readFileSync as readFileSync62, readdirSync as readdirSync26, renameSync as renameSync14, writeFileSync as writeFileSync37 } from "node:fs";
80861
80969
  import { mkdir as mkdir2 } from "node:fs/promises";
80862
80970
  import { spawnSync as childSpawnSync } from "node:child_process";
80863
80971
  import readline from "node:readline";
@@ -81254,7 +81362,7 @@ init_loader();
81254
81362
  init_loader();
81255
81363
 
81256
81364
  // src/cli/update-prompt-hook.ts
81257
- import { existsSync as existsSync72, readFileSync as readFileSync60, writeFileSync as writeFileSync35, chmodSync as chmodSync10, mkdirSync as mkdirSync41 } from "node:fs";
81365
+ import { existsSync as existsSync72, readFileSync as readFileSync61, writeFileSync as writeFileSync36, chmodSync as chmodSync10, mkdirSync as mkdirSync41 } from "node:fs";
81258
81366
  import { join as join72 } from "node:path";
81259
81367
  var HOOK_FILENAME = "update-card-on-prompt.sh";
81260
81368
  function updatePromptHookScript() {
@@ -81326,9 +81434,9 @@ function installUpdatePromptHook(agentDir) {
81326
81434
  const scriptPath = join72(hooksDir, HOOK_FILENAME);
81327
81435
  const desired = updatePromptHookScript();
81328
81436
  let installed = false;
81329
- const existing = existsSync72(scriptPath) ? readFileSync60(scriptPath, "utf-8") : "";
81437
+ const existing = existsSync72(scriptPath) ? readFileSync61(scriptPath, "utf-8") : "";
81330
81438
  if (existing !== desired) {
81331
- writeFileSync35(scriptPath, desired, { mode: 493 });
81439
+ writeFileSync36(scriptPath, desired, { mode: 493 });
81332
81440
  chmodSync10(scriptPath, 493);
81333
81441
  installed = true;
81334
81442
  } else {
@@ -81340,7 +81448,7 @@ function installUpdatePromptHook(agentDir) {
81340
81448
  if (!existsSync72(settingsPath)) {
81341
81449
  return { scriptPath, settingsPath, installed };
81342
81450
  }
81343
- const raw = readFileSync60(settingsPath, "utf-8");
81451
+ const raw = readFileSync61(settingsPath, "utf-8");
81344
81452
  let parsed;
81345
81453
  try {
81346
81454
  parsed = JSON.parse(raw);
@@ -81373,7 +81481,7 @@ function installUpdatePromptHook(agentDir) {
81373
81481
  });
81374
81482
  hooks.UserPromptSubmit = list2;
81375
81483
  parsed.hooks = hooks;
81376
- writeFileSync35(settingsPath, JSON.stringify(parsed, null, 2) + `
81484
+ writeFileSync36(settingsPath, JSON.stringify(parsed, null, 2) + `
81377
81485
  `, { mode: 384 });
81378
81486
  installed = true;
81379
81487
  }
@@ -81496,24 +81604,24 @@ async function ensureHostMountSources(config) {
81496
81604
  }
81497
81605
  const autoUnlockPath = join74(home2, ".switchroom", "vault-auto-unlock");
81498
81606
  if (!existsSync74(autoUnlockPath)) {
81499
- writeFileSync36(autoUnlockPath, "", { mode: 384 });
81607
+ writeFileSync37(autoUnlockPath, "", { mode: 384 });
81500
81608
  }
81501
81609
  const auditLogPath = join74(home2, ".switchroom", "vault-audit.log");
81502
81610
  if (!existsSync74(auditLogPath)) {
81503
- writeFileSync36(auditLogPath, "", { mode: 420 });
81611
+ writeFileSync37(auditLogPath, "", { mode: 420 });
81504
81612
  }
81505
81613
  const grantsDbPath = join74(home2, ".switchroom", "vault-grants.db");
81506
81614
  if (!existsSync74(grantsDbPath)) {
81507
- writeFileSync36(grantsDbPath, "", { mode: 384 });
81615
+ writeFileSync37(grantsDbPath, "", { mode: 384 });
81508
81616
  }
81509
81617
  const hostdAuditLogPath = join74(home2, ".switchroom", "host-control-audit.log");
81510
81618
  if (!existsSync74(hostdAuditLogPath)) {
81511
- writeFileSync36(hostdAuditLogPath, "", { mode: 420 });
81619
+ writeFileSync37(hostdAuditLogPath, "", { mode: 420 });
81512
81620
  }
81513
81621
  for (const name of Object.keys(config.agents)) {
81514
81622
  const tokenPath = join74(home2, ".switchroom", "agents", name, ".vault-token");
81515
81623
  if (!existsSync74(tokenPath)) {
81516
- writeFileSync36(tokenPath, "", { mode: 384 });
81624
+ writeFileSync37(tokenPath, "", { mode: 384 });
81517
81625
  }
81518
81626
  try {
81519
81627
  const uid = allocateAgentUid(name);
@@ -81524,13 +81632,13 @@ async function ensureHostMountSources(config) {
81524
81632
  await mkdir2(fleetDir, { recursive: true });
81525
81633
  const invariantsPath = join74(fleetDir, "switchroom-invariants.md");
81526
81634
  const invariantsCanonical = renderFleetInvariants();
81527
- const invariantsCurrent = existsSync74(invariantsPath) ? readFileSync61(invariantsPath, "utf-8") : null;
81635
+ const invariantsCurrent = existsSync74(invariantsPath) ? readFileSync62(invariantsPath, "utf-8") : null;
81528
81636
  if (invariantsCurrent !== invariantsCanonical) {
81529
- writeFileSync36(invariantsPath, invariantsCanonical, { mode: 420 });
81637
+ writeFileSync37(invariantsPath, invariantsCanonical, { mode: 420 });
81530
81638
  }
81531
81639
  const fleetClaudePath = join74(fleetDir, "CLAUDE.md");
81532
81640
  if (!existsSync74(fleetClaudePath)) {
81533
- writeFileSync36(fleetClaudePath, [
81641
+ writeFileSync37(fleetClaudePath, [
81534
81642
  "# Switchroom fleet defaults",
81535
81643
  "",
81536
81644
  "Operator-owned fleet brain. Every agent reads this via",
@@ -81622,7 +81730,7 @@ function writeInstallTypeCache(homeDir = homedir43()) {
81622
81730
  detected_at: new Date().toISOString(),
81623
81731
  source_paths: ctx.source_paths
81624
81732
  };
81625
- writeFileSync36(tmp, JSON.stringify(payload, null, 2), { mode: 420 });
81733
+ writeFileSync37(tmp, JSON.stringify(payload, null, 2), { mode: 420 });
81626
81734
  renameSync14(tmp, out);
81627
81735
  return out;
81628
81736
  }
@@ -81818,10 +81926,10 @@ Done. Scaffolded ${scaffolded}/${allAgentNames.length} agents.
81818
81926
  };
81819
81927
  }
81820
81928
  function formatScaffoldFailureResolution(failures, scaffolded, agentsTotal) {
81821
- const fail2 = failures.length;
81929
+ const fail3 = failures.length;
81822
81930
  const lines = [];
81823
81931
  lines.push("");
81824
- lines.push(`ERROR: Scaffolded ${scaffolded}/${agentsTotal} agents. ${fail2} failed.`);
81932
+ lines.push(`ERROR: Scaffolded ${scaffolded}/${agentsTotal} agents. ${fail3} failed.`);
81825
81933
  lines.push("");
81826
81934
  lines.push("Per-agent state dirs are mode 0700 owned by per-agent UIDs (the v0.7+");
81827
81935
  lines.push("docker model). The operator cannot write into them without privilege");
@@ -81854,7 +81962,7 @@ function copyExampleConfig2(name) {
81854
81962
  }
81855
81963
  const embedded = EMBEDDED_EXAMPLES[name];
81856
81964
  if (embedded !== undefined) {
81857
- writeFileSync36(dest, embedded, { encoding: "utf8" });
81965
+ writeFileSync37(dest, embedded, { encoding: "utf8" });
81858
81966
  console.log(source_default.green(`Copied ${name}.yaml -> switchroom.yaml`));
81859
81967
  return;
81860
81968
  }
@@ -82049,7 +82157,7 @@ function runRedactStdin() {
82049
82157
  }
82050
82158
 
82051
82159
  // src/cli/status-ask.ts
82052
- import { readFileSync as readFileSync62, existsSync as existsSync75, readdirSync as readdirSync27 } from "node:fs";
82160
+ import { readFileSync as readFileSync63, existsSync as existsSync75, readdirSync as readdirSync27 } from "node:fs";
82053
82161
  import { join as join75 } from "node:path";
82054
82162
  import { homedir as homedir44 } from "node:os";
82055
82163
 
@@ -82325,7 +82433,7 @@ function runReport(opts) {
82325
82433
  for (const src of sources) {
82326
82434
  let content;
82327
82435
  try {
82328
- content = readFileSync62(src.path, "utf-8");
82436
+ content = readFileSync63(src.path, "utf-8");
82329
82437
  } catch (err) {
82330
82438
  process.stderr.write(`status-ask report: cannot read ${src.path}: ${err instanceof Error ? err.message : String(err)}
82331
82439
  `);
@@ -82430,7 +82538,7 @@ import {
82430
82538
  mkdirSync as mkdirSync43,
82431
82539
  openSync as openSync13,
82432
82540
  readdirSync as readdirSync28,
82433
- readFileSync as readFileSync63,
82541
+ readFileSync as readFileSync64,
82434
82542
  renameSync as renameSync15,
82435
82543
  statSync as statSync30,
82436
82544
  unlinkSync as unlinkSync14,
@@ -82554,7 +82662,7 @@ function listSkillsOverlayEntries(agent, opts = {}) {
82554
82662
  continue;
82555
82663
  const full = join76(paths.skillsDir, name);
82556
82664
  try {
82557
- const raw = readFileSync63(full, "utf-8");
82665
+ const raw = readFileSync64(full, "utf-8");
82558
82666
  const slug = name.replace(/\.ya?ml$/i, "");
82559
82667
  out.push({ slug, path: full, raw });
82560
82668
  } catch {}
@@ -82581,7 +82689,7 @@ function listOverlayEntries(agent, opts = {}) {
82581
82689
  continue;
82582
82690
  const full = join76(paths.scheduleDir, name);
82583
82691
  try {
82584
- const raw = readFileSync63(full, "utf-8");
82692
+ const raw = readFileSync64(full, "utf-8");
82585
82693
  const slug = name.replace(/\.ya?ml$/i, "");
82586
82694
  out.push({ slug, path: full, raw });
82587
82695
  } catch {}
@@ -82729,10 +82837,10 @@ import {
82729
82837
  mkdirSync as mkdirSync44,
82730
82838
  openSync as openSync14,
82731
82839
  readdirSync as readdirSync29,
82732
- readFileSync as readFileSync64,
82840
+ readFileSync as readFileSync65,
82733
82841
  renameSync as renameSync16,
82734
82842
  unlinkSync as unlinkSync15,
82735
- writeFileSync as writeFileSync37,
82843
+ writeFileSync as writeFileSync38,
82736
82844
  writeSync as writeSync9
82737
82845
  } from "node:fs";
82738
82846
  import { join as join77 } from "node:path";
@@ -82775,7 +82883,7 @@ function stagePendingScheduleEntry(opts) {
82775
82883
  }
82776
82884
  renameSync16(yamlTmp, yamlPath);
82777
82885
  }
82778
- writeFileSync37(metaPath, JSON.stringify(meta, null, 2) + `
82886
+ writeFileSync38(metaPath, JSON.stringify(meta, null, 2) + `
82779
82887
  `, { mode: 384 });
82780
82888
  return { stageId, yamlPath, metaPath };
82781
82889
  }
@@ -82793,7 +82901,7 @@ function listPendingScheduleEntries(agent, opts = {}) {
82793
82901
  if (!existsSync77(yamlPath))
82794
82902
  continue;
82795
82903
  try {
82796
- const meta = JSON.parse(readFileSync64(metaPath, "utf-8"));
82904
+ const meta = JSON.parse(readFileSync65(metaPath, "utf-8"));
82797
82905
  if (meta?.v !== 1 || typeof meta.stage_id !== "string")
82798
82906
  continue;
82799
82907
  out.push({ stageId: meta.stage_id, agent: meta.agent, yamlPath, metaPath, meta });
@@ -82831,7 +82939,7 @@ function denyPendingScheduleEntry(opts) {
82831
82939
  }
82832
82940
 
82833
82941
  // src/cli/agent-config-write.ts
82834
- import { existsSync as existsSync78, readFileSync as readFileSync65 } from "node:fs";
82942
+ import { existsSync as existsSync78, readFileSync as readFileSync66 } from "node:fs";
82835
82943
  import { execFileSync as execFileSync25 } from "node:child_process";
82836
82944
 
82837
82945
  // src/scheduler/schedule-report.ts
@@ -83199,7 +83307,7 @@ function scheduleRemove(opts) {
83199
83307
  let priorContent = null;
83200
83308
  try {
83201
83309
  if (existsSync78(match.path))
83202
- priorContent = readFileSync65(match.path, "utf-8");
83310
+ priorContent = readFileSync66(match.path, "utf-8");
83203
83311
  } catch {}
83204
83312
  deleteOverlayEntry(agent, match.slug, { root: opts.root });
83205
83313
  const reconcileFn = opts.reconcile === undefined ? opts.root ? null : reconcileAgentCronOnly : opts.reconcile;
@@ -83402,7 +83510,7 @@ function registerAgentConfigWriteCommands(program3) {
83402
83510
  }
83403
83511
  let blob;
83404
83512
  if (opts.jsonl) {
83405
- blob = existsSync78(opts.jsonl) ? readFileSync65(opts.jsonl, "utf-8") : "";
83513
+ blob = existsSync78(opts.jsonl) ? readFileSync66(opts.jsonl, "utf-8") : "";
83406
83514
  } else {
83407
83515
  try {
83408
83516
  blob = execFileSync25("docker", ["exec", `switchroom-${agent}`, "cat", "/state/agent/scheduler.jsonl"], {
@@ -83682,13 +83790,13 @@ import {
83682
83790
  mkdirSync as mkdirSync45,
83683
83791
  mkdtempSync as mkdtempSync5,
83684
83792
  openSync as openSync15,
83685
- readFileSync as readFileSync66,
83793
+ readFileSync as readFileSync67,
83686
83794
  readdirSync as readdirSync30,
83687
83795
  realpathSync as realpathSync7,
83688
83796
  renameSync as renameSync17,
83689
83797
  rmSync as rmSync16,
83690
83798
  statSync as statSync31,
83691
- writeFileSync as writeFileSync38
83799
+ writeFileSync as writeFileSync39
83692
83800
  } from "node:fs";
83693
83801
  import { tmpdir as tmpdir5, homedir as homedir45 } from "node:os";
83694
83802
  import { dirname as dirname23, join as join79, relative as relative2, resolve as resolve46 } from "node:path";
@@ -83918,7 +84026,7 @@ function isTarballPath(p) {
83918
84026
  function loadFromDir(dir) {
83919
84027
  const abs = realpathSync7(dir);
83920
84028
  if (!statSync31(abs).isDirectory()) {
83921
- fail2(`--from path is not a directory: ${dir}`);
84029
+ fail3(`--from path is not a directory: ${dir}`);
83922
84030
  }
83923
84031
  const files = {};
83924
84032
  const walk2 = (sub) => {
@@ -83927,14 +84035,14 @@ function loadFromDir(dir) {
83927
84035
  const full = join79(sub, ent.name);
83928
84036
  const rel = relative2(abs, full);
83929
84037
  if (ent.isSymbolicLink()) {
83930
- fail2(`refusing to read symlink inside --from dir: ${rel}`);
84038
+ fail3(`refusing to read symlink inside --from dir: ${rel}`);
83931
84039
  }
83932
84040
  if (ent.isDirectory()) {
83933
84041
  walk2(full);
83934
84042
  continue;
83935
84043
  }
83936
84044
  if (ent.isFile()) {
83937
- const buf = readFileSync66(full);
84045
+ const buf = readFileSync67(full);
83938
84046
  files[rel.replace(/\\/g, "/")] = buf.toString("utf-8");
83939
84047
  }
83940
84048
  }
@@ -83950,13 +84058,13 @@ function loadFromTarball(tarPath) {
83950
84058
  stdio: ["ignore", "pipe", "pipe"]
83951
84059
  });
83952
84060
  if (list2.status !== 0) {
83953
- fail2(`tar list failed (exit ${list2.status}): ${(list2.stderr ?? "").trim()}`);
84061
+ fail3(`tar list failed (exit ${list2.status}): ${(list2.stderr ?? "").trim()}`);
83954
84062
  }
83955
84063
  const entries = (list2.stdout ?? "").split(`
83956
84064
  `).map((s) => s.trim()).filter((s) => s.length > 0 && !s.endsWith("/"));
83957
84065
  for (const entry of entries) {
83958
84066
  if (!validateRelPath(entry)) {
83959
- fail2(`tarball contains disallowed path: ${JSON.stringify(entry)} \u2014 ` + `refusing to extract before any file is written`);
84067
+ fail3(`tarball contains disallowed path: ${JSON.stringify(entry)} \u2014 ` + `refusing to extract before any file is written`);
83960
84068
  }
83961
84069
  }
83962
84070
  const staging = mkdtempSync5(join79(tmpdir5(), "skill-apply-extract-"));
@@ -83973,7 +84081,7 @@ function loadFromTarball(tarPath) {
83973
84081
  ], { stdio: "pipe" });
83974
84082
  if (r.status !== 0) {
83975
84083
  const stderr = r.stderr?.toString("utf-8") ?? "(no stderr)";
83976
- fail2(`tar extraction failed (exit ${r.status}): ${stderr.trim()}`);
84084
+ fail3(`tar extraction failed (exit ${r.status}): ${stderr.trim()}`);
83977
84085
  }
83978
84086
  return loadFromDir(staging);
83979
84087
  } finally {
@@ -83983,13 +84091,13 @@ function loadFromTarball(tarPath) {
83983
84091
  }
83984
84092
  }
83985
84093
  function loadSingleFile(filePath) {
83986
- const content = readFileSync66(filePath, "utf-8");
84094
+ const content = readFileSync67(filePath, "utf-8");
83987
84095
  return { "SKILL.md": content };
83988
84096
  }
83989
84097
  function loadFromStdin() {
83990
84098
  const content = readStdinSync();
83991
84099
  if (content.length === 0) {
83992
- fail2("no content on stdin; either pipe SKILL.md content in or pass --from");
84100
+ fail3("no content on stdin; either pipe SKILL.md content in or pass --from");
83993
84101
  }
83994
84102
  return { "SKILL.md": content };
83995
84103
  }
@@ -84048,7 +84156,7 @@ function validatePayload(name, files) {
84048
84156
  const tmp = mkdtempSync5(join79(tmpdir5(), "skill-apply-py-"));
84049
84157
  const tmpPy = join79(tmp, "check.py");
84050
84158
  try {
84051
- writeFileSync38(tmpPy, content);
84159
+ writeFileSync39(tmpPy, content);
84052
84160
  const r = spawnSync11("python3", ["-m", "py_compile", tmpPy], {
84053
84161
  encoding: "utf-8"
84054
84162
  });
@@ -84074,7 +84182,7 @@ function diffSummary(currentDir, files) {
84074
84182
  if (ent.isDirectory()) {
84075
84183
  walk2(full);
84076
84184
  } else if (ent.isFile()) {
84077
- currentFiles[rel.replace(/\\/g, "/")] = readFileSync66(full, "utf-8");
84185
+ currentFiles[rel.replace(/\\/g, "/")] = readFileSync67(full, "utf-8");
84078
84186
  }
84079
84187
  }
84080
84188
  };
@@ -84114,7 +84222,7 @@ function writePayload(poolDir, name, files) {
84114
84222
  }
84115
84223
  } catch {}
84116
84224
  if (targetIsSymlink) {
84117
- fail2(`refusing to overwrite symlink at ${target}; investigate manually`);
84225
+ fail3(`refusing to overwrite symlink at ${target}; investigate manually`);
84118
84226
  }
84119
84227
  const staging = mkdtempSync5(join79(poolDir, `.skill-apply-stage-${name}-`));
84120
84228
  let oldRename = null;
@@ -84124,7 +84232,7 @@ function writePayload(poolDir, name, files) {
84124
84232
  mkdirSync45(dirname23(full), { recursive: true, mode: 493 });
84125
84233
  const fd = openSync15(full, "wx");
84126
84234
  try {
84127
- writeFileSync38(fd, content);
84235
+ writeFileSync39(fd, content);
84128
84236
  } finally {
84129
84237
  closeSync15(fd);
84130
84238
  }
@@ -84162,7 +84270,7 @@ function writePayload(poolDir, name, files) {
84162
84270
  throw err2;
84163
84271
  }
84164
84272
  }
84165
- function fail2(msg) {
84273
+ function fail3(msg) {
84166
84274
  console.error(source_default.red(`error: ${msg}`));
84167
84275
  process.exit(2);
84168
84276
  }
@@ -84175,7 +84283,7 @@ function registerSkillCommand(program3) {
84175
84283
  } else {
84176
84284
  const fromPath = resolve46(opts.from);
84177
84285
  if (!existsSync80(fromPath)) {
84178
- fail2(`--from path does not exist: ${opts.from}`);
84286
+ fail3(`--from path does not exist: ${opts.from}`);
84179
84287
  }
84180
84288
  const st = statSync31(fromPath);
84181
84289
  if (st.isDirectory()) {
@@ -84185,7 +84293,7 @@ function registerSkillCommand(program3) {
84185
84293
  } else if (fromPath.endsWith(".md")) {
84186
84294
  files = loadSingleFile(fromPath);
84187
84295
  } else {
84188
- fail2(`--from must be a directory, a .tar/.tar.gz/.tgz tarball, or a ` + `.md file. Got: ${opts.from}`);
84296
+ fail3(`--from must be a directory, a .tar/.tar.gz/.tgz tarball, or a ` + `.md file. Got: ${opts.from}`);
84189
84297
  }
84190
84298
  }
84191
84299
  const v = validatePayload(name, files);
@@ -84234,13 +84342,13 @@ import {
84234
84342
  mkdirSync as mkdirSync46,
84235
84343
  mkdtempSync as mkdtempSync6,
84236
84344
  openSync as openSync16,
84237
- readFileSync as readFileSync67,
84345
+ readFileSync as readFileSync68,
84238
84346
  readdirSync as readdirSync31,
84239
84347
  renameSync as renameSync18,
84240
84348
  rmSync as rmSync17,
84241
84349
  statSync as statSync32,
84242
84350
  utimesSync,
84243
- writeFileSync as writeFileSync39
84351
+ writeFileSync as writeFileSync40
84244
84352
  } from "node:fs";
84245
84353
  import { dirname as dirname24, join as join80, relative as relative3, resolve as resolve47 } from "node:path";
84246
84354
  import { homedir as homedir46, tmpdir as tmpdir6 } from "node:os";
@@ -84316,7 +84424,7 @@ function mirrorToConfigRepo(agent, name, liveSkillDir) {
84316
84424
  if (ent.isDirectory())
84317
84425
  walk2(s, d);
84318
84426
  else if (ent.isFile()) {
84319
- writeFileSync39(d, readFileSync67(s));
84427
+ writeFileSync40(d, readFileSync68(s));
84320
84428
  }
84321
84429
  }
84322
84430
  };
@@ -84331,7 +84439,7 @@ function mirrorToConfigRepo(agent, name, liveSkillDir) {
84331
84439
  `));
84332
84440
  }
84333
84441
  }
84334
- function fail3(msg, exit = 2) {
84442
+ function fail4(msg, exit = 2) {
84335
84443
  console.error(source_default.red(`error: ${msg}`));
84336
84444
  process.exit(exit);
84337
84445
  }
@@ -84339,10 +84447,10 @@ function resolveAgent(opts) {
84339
84447
  const fromEnv = process.env.SWITCHROOM_AGENT_NAME;
84340
84448
  const agent = opts.agent ?? fromEnv;
84341
84449
  if (!agent) {
84342
- fail3("agent name required: pass --agent <name>, or set SWITCHROOM_AGENT_NAME " + "in the calling environment (set by switchroom for in-container agents).");
84450
+ fail4("agent name required: pass --agent <name>, or set SWITCHROOM_AGENT_NAME " + "in the calling environment (set by switchroom for in-container agents).");
84343
84451
  }
84344
84452
  if (!SKILL_SLUG_RE.test(agent)) {
84345
- fail3(`agent name has invalid shape: ${JSON.stringify(agent)}`);
84453
+ fail4(`agent name has invalid shape: ${JSON.stringify(agent)}`);
84346
84454
  }
84347
84455
  return agent;
84348
84456
  }
@@ -84380,14 +84488,14 @@ function readStdinSync2() {
84380
84488
  function loadFromDir2(dir) {
84381
84489
  const abs = resolve47(dir);
84382
84490
  if (!statSync32(abs).isDirectory()) {
84383
- fail3(`--from path is not a directory: ${dir}`);
84491
+ fail4(`--from path is not a directory: ${dir}`);
84384
84492
  }
84385
84493
  const files = {};
84386
84494
  const walk2 = (sub) => {
84387
84495
  for (const ent of readdirSync31(sub, { withFileTypes: true })) {
84388
84496
  const full = join80(sub, ent.name);
84389
84497
  if (ent.isSymbolicLink()) {
84390
- fail3(`refusing to read symlink in --from dir: ${relative3(abs, full)}`);
84498
+ fail4(`refusing to read symlink in --from dir: ${relative3(abs, full)}`);
84391
84499
  }
84392
84500
  if (ent.isDirectory()) {
84393
84501
  walk2(full);
@@ -84395,7 +84503,7 @@ function loadFromDir2(dir) {
84395
84503
  }
84396
84504
  if (ent.isFile()) {
84397
84505
  const rel = relative3(abs, full).replace(/\\/g, "/");
84398
- files[rel] = readFileSync67(full, "utf-8");
84506
+ files[rel] = readFileSync68(full, "utf-8");
84399
84507
  }
84400
84508
  }
84401
84509
  };
@@ -84405,7 +84513,7 @@ function loadFromDir2(dir) {
84405
84513
  function loadFromStdin2() {
84406
84514
  const raw = readStdinSync2();
84407
84515
  if (raw.length === 0) {
84408
- fail3("no content on stdin; pipe a SKILL.md or JSON file-map");
84516
+ fail4("no content on stdin; pipe a SKILL.md or JSON file-map");
84409
84517
  }
84410
84518
  const trimmed = raw.trimStart();
84411
84519
  if (trimmed.startsWith("{")) {
@@ -84413,15 +84521,15 @@ function loadFromStdin2() {
84413
84521
  try {
84414
84522
  parsed = JSON.parse(raw);
84415
84523
  } catch (err2) {
84416
- fail3(`stdin starts with '{' but is not valid JSON: ${err2.message}`);
84524
+ fail4(`stdin starts with '{' but is not valid JSON: ${err2.message}`);
84417
84525
  }
84418
84526
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
84419
- fail3("stdin JSON must be an object of {path: content, ...}");
84527
+ fail4("stdin JSON must be an object of {path: content, ...}");
84420
84528
  }
84421
84529
  const files = {};
84422
84530
  for (const [k, v] of Object.entries(parsed)) {
84423
84531
  if (typeof v !== "string") {
84424
- fail3(`stdin JSON: value for ${JSON.stringify(k)} must be a string`);
84532
+ fail4(`stdin JSON: value for ${JSON.stringify(k)} must be a string`);
84425
84533
  }
84426
84534
  files[k] = v;
84427
84535
  }
@@ -84441,7 +84549,7 @@ function behavioralValidate(files) {
84441
84549
  const tmp = mkdtempSync6(join80(tmpdir6(), "skill-personal-py-"));
84442
84550
  const tmpPy = join80(tmp, "check.py");
84443
84551
  try {
84444
- writeFileSync39(tmpPy, content);
84552
+ writeFileSync40(tmpPy, content);
84445
84553
  const r = spawnSync12("python3", ["-m", "py_compile", tmpPy], {
84446
84554
  encoding: "utf-8"
84447
84555
  });
@@ -84481,7 +84589,7 @@ function writePersonalSkill(targetDir, files) {
84481
84589
  }
84482
84590
  } catch {}
84483
84591
  if (targetIsSymlink) {
84484
- fail3(`refusing to overwrite symlink at ${targetDir}; investigate manually`);
84592
+ fail4(`refusing to overwrite symlink at ${targetDir}; investigate manually`);
84485
84593
  }
84486
84594
  mkdirSync46(dirname24(targetDir), { recursive: true, mode: 493 });
84487
84595
  const staging = mkdtempSync6(join80(dirname24(targetDir), `.skill-personal-stage-`));
@@ -84492,7 +84600,7 @@ function writePersonalSkill(targetDir, files) {
84492
84600
  mkdirSync46(dirname24(full), { recursive: true, mode: 493 });
84493
84601
  const fd = openSync16(full, "wx");
84494
84602
  try {
84495
- writeFileSync39(fd, content);
84603
+ writeFileSync40(fd, content);
84496
84604
  } finally {
84497
84605
  closeSync16(fd);
84498
84606
  }
@@ -84533,7 +84641,7 @@ function writePersonalSkill(targetDir, files) {
84533
84641
  function loadValidateWrite(agentsRoot, agent, name, files, ensureNew) {
84534
84642
  sweepTrash(agentsRoot, agent);
84535
84643
  if (!SKILL_SLUG_RE.test(name)) {
84536
- fail3(`skill name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(name)}`);
84644
+ fail4(`skill name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(name)}`);
84537
84645
  }
84538
84646
  const target = personalSkillDir(agentsRoot, agent, name);
84539
84647
  const exists = (() => {
@@ -84545,10 +84653,10 @@ function loadValidateWrite(agentsRoot, agent, name, files, ensureNew) {
84545
84653
  }
84546
84654
  })();
84547
84655
  if (ensureNew && exists) {
84548
- fail3(`personal skill ${JSON.stringify(name)} already exists for agent ${JSON.stringify(agent)}. ` + `Use \`skill edit-personal\` to overwrite, or \`skill remove-personal\` first.`, 9);
84656
+ fail4(`personal skill ${JSON.stringify(name)} already exists for agent ${JSON.stringify(agent)}. ` + `Use \`skill edit-personal\` to overwrite, or \`skill remove-personal\` first.`, 9);
84549
84657
  }
84550
84658
  if (!ensureNew && !exists) {
84551
- fail3(`personal skill ${JSON.stringify(name)} does not exist for agent ${JSON.stringify(agent)}. ` + `Use \`skill init-personal\` to create it.`, 9);
84659
+ fail4(`personal skill ${JSON.stringify(name)} does not exist for agent ${JSON.stringify(agent)}. ` + `Use \`skill init-personal\` to create it.`, 9);
84552
84660
  }
84553
84661
  const v = validateSkillBundle(name, files);
84554
84662
  if (!v.ok) {
@@ -84574,16 +84682,16 @@ function loadFiles(opts) {
84574
84682
  }
84575
84683
  const p = resolve47(opts.from);
84576
84684
  if (!existsSync81(p)) {
84577
- fail3(`--from path does not exist: ${opts.from}`);
84685
+ fail4(`--from path does not exist: ${opts.from}`);
84578
84686
  }
84579
84687
  const st = statSync32(p);
84580
84688
  if (st.isDirectory()) {
84581
84689
  return loadFromDir2(p);
84582
84690
  }
84583
84691
  if (p.endsWith(".md")) {
84584
- return { "SKILL.md": readFileSync67(p, "utf-8") };
84692
+ return { "SKILL.md": readFileSync68(p, "utf-8") };
84585
84693
  }
84586
- fail3(`--from must be a directory or a .md file. Got: ${opts.from}`);
84694
+ fail4(`--from must be a directory or a .md file. Got: ${opts.from}`);
84587
84695
  }
84588
84696
  function initPersonalAction(name, opts) {
84589
84697
  const agent = resolveAgent(opts);
@@ -84629,18 +84737,18 @@ function defaultBundledRoot() {
84629
84737
  function resolveCloneSource(source, opts) {
84630
84738
  const m = CLONE_SOURCE_RE.exec(source);
84631
84739
  if (!m) {
84632
- fail3(`source must be \`shared:<name>\` or \`bundled:<name>\` (got ${JSON.stringify(source)})`);
84740
+ fail4(`source must be \`shared:<name>\` or \`bundled:<name>\` (got ${JSON.stringify(source)})`);
84633
84741
  }
84634
84742
  const tier = m[1];
84635
84743
  const slug = m[2];
84636
84744
  const root = tier === "bundled" ? opts.bundledRoot ?? defaultBundledRoot() : opts.sharedRoot ?? defaultSharedRoot();
84637
84745
  const dir = join80(root, slug);
84638
84746
  if (!existsSync81(dir)) {
84639
- fail3(`clone source ${JSON.stringify(source)} not found at ${dir}; ` + `check \`switchroom skill search --tier ${tier}\``, 1);
84747
+ fail4(`clone source ${JSON.stringify(source)} not found at ${dir}; ` + `check \`switchroom skill search --tier ${tier}\``, 1);
84640
84748
  }
84641
84749
  const st = lstatSync9(dir);
84642
84750
  if (st.isSymbolicLink()) {
84643
- fail3(`clone source ${JSON.stringify(source)} is a symlink at ${dir}; ` + `point clone at the canonical pool path instead`);
84751
+ fail4(`clone source ${JSON.stringify(source)} is a symlink at ${dir}; ` + `point clone at the canonical pool path instead`);
84644
84752
  }
84645
84753
  return { tier, slug, dir };
84646
84754
  }
@@ -84667,10 +84775,10 @@ function readSourceFiles(dir) {
84667
84775
  try {
84668
84776
  const st = lstatSync9(full);
84669
84777
  if (st.size > CLONE_MAX_FILE_BYTES) {
84670
- fail3(`clone source has oversized file ${rel} (${st.size} bytes > ${CLONE_MAX_FILE_BYTES}); ` + `refuse to read`, 3);
84778
+ fail4(`clone source has oversized file ${rel} (${st.size} bytes > ${CLONE_MAX_FILE_BYTES}); ` + `refuse to read`, 3);
84671
84779
  }
84672
84780
  } catch {}
84673
- files[rel] = readFileSync67(full, "utf-8");
84781
+ files[rel] = readFileSync68(full, "utf-8");
84674
84782
  }
84675
84783
  }
84676
84784
  };
@@ -84701,11 +84809,11 @@ function clonePersonalAction(source, opts) {
84701
84809
  const src = resolveCloneSource(source, opts);
84702
84810
  const newName = opts.name ?? src.slug;
84703
84811
  if (!SKILL_SLUG_RE.test(newName)) {
84704
- fail3(`destination name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(newName)}`);
84812
+ fail4(`destination name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(newName)}`);
84705
84813
  }
84706
84814
  const { files, skipped } = readSourceFiles(src.dir);
84707
84815
  if (!files["SKILL.md"]) {
84708
- fail3(`source ${JSON.stringify(source)} has no SKILL.md at ${src.dir}`);
84816
+ fail4(`source ${JSON.stringify(source)} has no SKILL.md at ${src.dir}`);
84709
84817
  }
84710
84818
  if (newName !== src.slug) {
84711
84819
  files["SKILL.md"] = rewriteSkillMdName(files["SKILL.md"], newName);
@@ -84743,18 +84851,18 @@ function removePersonalAction(name, opts) {
84743
84851
  const agentsRoot = resolveAgentsRoot(opts);
84744
84852
  sweepTrash(agentsRoot, agent);
84745
84853
  if (!SKILL_SLUG_RE.test(name)) {
84746
- fail3(`skill name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(name)}`);
84854
+ fail4(`skill name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(name)}`);
84747
84855
  }
84748
84856
  const target = personalSkillDir(agentsRoot, agent, name);
84749
84857
  try {
84750
84858
  const st = lstatSync9(target);
84751
84859
  if (st.isSymbolicLink()) {
84752
- fail3(`refusing to remove symlink at ${target}; investigate manually`);
84860
+ fail4(`refusing to remove symlink at ${target}; investigate manually`);
84753
84861
  }
84754
84862
  } catch (err2) {
84755
84863
  const e = err2;
84756
84864
  if (e.code === "ENOENT") {
84757
- fail3(`personal skill ${JSON.stringify(name)} does not exist for agent ${JSON.stringify(agent)}`, 1);
84865
+ fail4(`personal skill ${JSON.stringify(name)} does not exist for agent ${JSON.stringify(agent)}`, 1);
84758
84866
  }
84759
84867
  throw err2;
84760
84868
  }
@@ -84839,7 +84947,7 @@ function registerSkillPersonalCommands(program3) {
84839
84947
  // src/cli/skill-search.ts
84840
84948
  init_helpers();
84841
84949
  var import_yaml23 = __toESM(require_dist(), 1);
84842
- import { existsSync as existsSync82, readdirSync as readdirSync32, readFileSync as readFileSync68, statSync as statSync33 } from "node:fs";
84950
+ import { existsSync as existsSync82, readdirSync as readdirSync32, readFileSync as readFileSync69, statSync as statSync33 } from "node:fs";
84843
84951
  import { homedir as homedir47 } from "node:os";
84844
84952
  import { join as join81, resolve as resolve48 } from "node:path";
84845
84953
  var PERSONAL_PREFIX2 = "personal-";
@@ -84860,7 +84968,7 @@ function readSkillFrontmatter(skillDir) {
84860
84968
  return null;
84861
84969
  let content;
84862
84970
  try {
84863
- content = readFileSync68(mdPath, "utf-8");
84971
+ content = readFileSync69(mdPath, "utf-8");
84864
84972
  } catch {
84865
84973
  return null;
84866
84974
  }
@@ -85132,7 +85240,7 @@ function registerHostdMcpCommand(program3) {
85132
85240
  // src/cli/hostd.ts
85133
85241
  init_source();
85134
85242
  init_helpers();
85135
- import { existsSync as existsSync84, mkdirSync as mkdirSync47, readdirSync as readdirSync33, readFileSync as readFileSync70, writeFileSync as writeFileSync40, statSync as statSync34, copyFileSync as copyFileSync12 } from "node:fs";
85243
+ import { existsSync as existsSync84, mkdirSync as mkdirSync47, readdirSync as readdirSync33, readFileSync as readFileSync71, writeFileSync as writeFileSync41, statSync as statSync34, copyFileSync as copyFileSync12 } from "node:fs";
85136
85244
  import { homedir as homedir48 } from "node:os";
85137
85245
  import { join as join82 } from "node:path";
85138
85246
  import { spawnSync as spawnSync14 } from "node:child_process";
@@ -85308,7 +85416,7 @@ async function doInstall(opts, program3) {
85308
85416
  const bak = backupExistingCompose();
85309
85417
  if (bak)
85310
85418
  console.log(source_default.dim(` Backed up existing compose to ${bak}`));
85311
- writeFileSync40(composePath, yaml, "utf8");
85419
+ writeFileSync41(composePath, yaml, "utf8");
85312
85420
  console.log(source_default.green(` \u2713 Wrote ${composePath}`));
85313
85421
  const adminAgents = Object.entries(cfg.agents ?? {}).filter(([, a]) => a?.admin === true).map(([name]) => name);
85314
85422
  console.log(source_default.dim(` agents served (one socket each): ${allAgents.length === 0 ? "(none)" : allAgents.join(", ")}`));
@@ -85415,7 +85523,7 @@ function registerHostdCommand(program3) {
85415
85523
  The log is created when hostd handles its first privileged-verb request.`));
85416
85524
  return;
85417
85525
  }
85418
- const raw = readFileSync70(logPath, "utf-8");
85526
+ const raw = readFileSync71(logPath, "utf-8");
85419
85527
  const limit = Math.max(1, parseInt(opts.tail ?? "50", 10) || 50);
85420
85528
  const filters = {
85421
85529
  agent: opts.agent,
@@ -85457,7 +85565,7 @@ The log is created when hostd handles its first privileged-verb request.`));
85457
85565
  // src/cli/webd.ts
85458
85566
  init_source();
85459
85567
  init_helpers();
85460
- import { existsSync as existsSync85, mkdirSync as mkdirSync48, writeFileSync as writeFileSync41, copyFileSync as copyFileSync13 } from "node:fs";
85568
+ import { existsSync as existsSync85, mkdirSync as mkdirSync48, writeFileSync as writeFileSync42, copyFileSync as copyFileSync13 } from "node:fs";
85461
85569
  import { homedir as homedir49 } from "node:os";
85462
85570
  import { join as join83 } from "node:path";
85463
85571
  import { spawnSync as spawnSync15 } from "node:child_process";
@@ -85593,7 +85701,7 @@ async function doInstall2(opts, program3) {
85593
85701
  const bak = backupExistingCompose2();
85594
85702
  if (bak)
85595
85703
  console.log(source_default.dim(` Backed up existing compose to ${bak}`));
85596
- writeFileSync41(composePath, yaml, "utf8");
85704
+ writeFileSync42(composePath, yaml, "utf8");
85597
85705
  console.log(source_default.green(` \u2713 Wrote ${composePath}`));
85598
85706
  console.log(source_default.dim(` running as uid ${operatorUid} (operator), network_mode: host`));
85599
85707
  console.log(source_default.dim(` Pulling ghcr.io/switchroom/switchroom-web:${imageTag}\u2026`));
@@ -85698,6 +85806,7 @@ registerTopicsCommand(program3);
85698
85806
  registerAuthCommand(program3);
85699
85807
  registerVaultCommand(program3);
85700
85808
  registerTelegramCommand(program3);
85809
+ registerLinearAgentCommand(program3);
85701
85810
  registerMemoryCommand(program3);
85702
85811
  registerWebCommand(program3);
85703
85812
  registerHandoffCommand(program3);