switchroom 0.13.50 → 0.13.51

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.
@@ -23263,6 +23263,12 @@ function emitAgentService(lines, a, imageTag, buildMode, buildContext, homePrefi
23263
23263
  mkdirSync8(`${hostHomeForChecks}/.switchroom/agents/${a.name}/schedule.d`, { recursive: true });
23264
23264
  } catch {}
23265
23265
  lines.push(` - ${homePrefix}/.switchroom/audit/${a.name}:${homePrefix}/.switchroom/audit/${a.name}:rw`);
23266
+ if (existsSync12(`${hostHomeForChecks}/.switchroom-config`)) {
23267
+ try {
23268
+ mkdirSync8(`${hostHomeForChecks}/.switchroom-config/agents/${a.name}/personal-skills`, { recursive: true });
23269
+ } catch {}
23270
+ lines.push(` - ${homePrefix}/.switchroom-config/agents/${a.name}/personal-skills:${homePrefix}/.switchroom-config/agents/${a.name}/personal-skills:rw`);
23271
+ }
23266
23272
  if (bundledSkillsPoolDir && existsSync12(bundledSkillsPoolDir) && !bundledSkillsPoolDir.startsWith(`${hostHomeForChecks}/.switchroom/skills`)) {
23267
23273
  lines.push(` - ${bundledSkillsPoolDir}:${bundledSkillsPoolDir}:ro`);
23268
23274
  }
@@ -47947,8 +47953,8 @@ var {
47947
47953
  } = import__.default;
47948
47954
 
47949
47955
  // src/build-info.ts
47950
- var VERSION = "0.13.50";
47951
- var COMMIT_SHA = "99e127b1";
47956
+ var VERSION = "0.13.51";
47957
+ var COMMIT_SHA = "9494f463";
47952
47958
 
47953
47959
  // src/cli/agent.ts
47954
47960
  init_source();
@@ -48520,6 +48526,7 @@ function alignAgentUid(name, agentDir, uid, opts = {}) {
48520
48526
  const writeOut = opts.writeOut ?? ((s) => process.stdout.write(s));
48521
48527
  const logsDir = join8(homedir4(), ".switchroom", "logs", name);
48522
48528
  const auditDir = join8(homedir4(), ".switchroom", "audit", name);
48529
+ const configMirrorDir = join8(homedir4(), ".switchroom-config", "agents", name, "personal-skills");
48523
48530
  const paths = [];
48524
48531
  if (existsSync11(agentDir))
48525
48532
  paths.push(agentDir);
@@ -48527,6 +48534,8 @@ function alignAgentUid(name, agentDir, uid, opts = {}) {
48527
48534
  paths.push(logsDir);
48528
48535
  if (existsSync11(auditDir))
48529
48536
  paths.push(auditDir);
48537
+ if (existsSync11(configMirrorDir))
48538
+ paths.push(configMirrorDir);
48530
48539
  if (paths.length === 0)
48531
48540
  return { chowned: false, paths: [] };
48532
48541
  const priors = [];
@@ -74762,6 +74771,9 @@ async function ensureHostMountSources(config) {
74762
74771
  dirs.push(join62(home2, ".switchroom", "logs", name));
74763
74772
  dirs.push(join62(home2, ".claude", "projects", name));
74764
74773
  dirs.push(join62(home2, ".switchroom", "audit", name));
74774
+ if (existsSync68(join62(home2, ".switchroom-config"))) {
74775
+ dirs.push(join62(home2, ".switchroom-config", "agents", name, "personal-skills"));
74776
+ }
74765
74777
  }
74766
74778
  for (const dir of dirs) {
74767
74779
  await mkdir(dir, { recursive: true });
@@ -78037,6 +78049,7 @@ function resolveCloneSource(source, opts) {
78037
78049
  var CLONE_MAX_FILE_BYTES = 1024 * 1024;
78038
78050
  function readSourceFiles(dir) {
78039
78051
  const files = {};
78052
+ const skipped = [];
78040
78053
  const walk2 = (sub) => {
78041
78054
  for (const ent of readdirSync30(sub, { withFileTypes: true })) {
78042
78055
  const full = join69(sub, ent.name);
@@ -78049,6 +78062,10 @@ function readSourceFiles(dir) {
78049
78062
  }
78050
78063
  if (ent.isFile()) {
78051
78064
  const rel = relative3(dir, full).replace(/\\/g, "/");
78065
+ if (!validateRelPath(rel)) {
78066
+ skipped.push(rel);
78067
+ continue;
78068
+ }
78052
78069
  try {
78053
78070
  const st = lstatSync9(full);
78054
78071
  if (st.size > CLONE_MAX_FILE_BYTES) {
@@ -78060,7 +78077,7 @@ function readSourceFiles(dir) {
78060
78077
  }
78061
78078
  };
78062
78079
  walk2(dir);
78063
- return files;
78080
+ return { files, skipped };
78064
78081
  }
78065
78082
  function rewriteSkillMdName(content, newName) {
78066
78083
  if (!content.startsWith(`---
@@ -78088,13 +78105,17 @@ function clonePersonalAction(source, opts) {
78088
78105
  if (!SKILL_SLUG_RE.test(newName)) {
78089
78106
  fail3(`destination name must match ${SKILL_SLUG_RE.source}: got ${JSON.stringify(newName)}`);
78090
78107
  }
78091
- const files = readSourceFiles(src.dir);
78108
+ const { files, skipped } = readSourceFiles(src.dir);
78092
78109
  if (!files["SKILL.md"]) {
78093
78110
  fail3(`source ${JSON.stringify(source)} has no SKILL.md at ${src.dir}`);
78094
78111
  }
78095
78112
  if (newName !== src.slug) {
78096
78113
  files["SKILL.md"] = rewriteSkillMdName(files["SKILL.md"], newName);
78097
78114
  }
78115
+ if (skipped.length > 0) {
78116
+ process.stderr.write(source_default.yellow(`note: skipped ${skipped.length} non-allowlisted path${skipped.length === 1 ? "" : "s"} from source: ${skipped.join(", ")}
78117
+ `));
78118
+ }
78098
78119
  loadValidateWrite(agentsRoot, agent, newName, files, true);
78099
78120
  const skillDir = personalSkillDir(agentsRoot, agent, newName);
78100
78121
  mirrorToConfigRepo(agent, newName, skillDir);
@@ -78107,14 +78128,16 @@ function clonePersonalAction(source, opts) {
78107
78128
  source_slug: src.slug,
78108
78129
  name: newName,
78109
78130
  path: skillDir,
78110
- files: Object.keys(files).length
78131
+ files: Object.keys(files).length,
78132
+ skipped
78111
78133
  }));
78112
78134
  appendAudit(agent, "skill.clone_to_personal", {
78113
78135
  source,
78114
78136
  source_tier: src.tier,
78115
78137
  source_slug: src.slug,
78116
78138
  name: newName,
78117
- files: Object.keys(files).length
78139
+ files: Object.keys(files).length,
78140
+ skipped_count: skipped.length
78118
78141
  }, 0);
78119
78142
  }
78120
78143
  function removePersonalAction(name, opts) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchroom",
3
- "version": "0.13.50",
3
+ "version": "0.13.51",
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": {
@@ -159,6 +159,19 @@ fi
159
159
  if [ ! -e "$HOME/.switchroom" ] || [ -L "$HOME/.switchroom" ]; then
160
160
  ln -sfn {{{hostHomeQ}}}/.switchroom "$HOME/.switchroom" 2>/dev/null || true
161
161
  fi
162
+ # Host ~/.switchroom-config symlink (#1846). Same shape as the
163
+ # ~/.switchroom link above, for the operator's git-tracked config repo.
164
+ # The compose generator bind-mounts a per-agent slice at
165
+ # <host-home>/.switchroom-config/agents/<self>/personal-skills/ (when
166
+ # the operator has opted in). Without this symlink, the CLI's
167
+ # resolveConfigSkillsDir would call existsSync("$HOME/.switchroom-config")
168
+ # and miss the bind-mounted path entirely → mirror silently no-ops.
169
+ # The link lands ONLY when the host slice is actually mounted (the dir
170
+ # the bind-mount targets) — leaving a dangling link when the operator
171
+ # hasn't opted in is fine, existsSync resolves false through it.
172
+ if [ ! -e "$HOME/.switchroom-config" ] || [ -L "$HOME/.switchroom-config" ]; then
173
+ ln -sfn {{{hostHomeQ}}}/.switchroom-config "$HOME/.switchroom-config" 2>/dev/null || true
174
+ fi
162
175
  {{/if}}
163
176
 
164
177
  export NVM_DIR="$HOME/.nvm"
@@ -48732,10 +48732,10 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
48732
48732
  }
48733
48733
 
48734
48734
  // ../src/build-info.ts
48735
- var VERSION = "0.13.50";
48736
- var COMMIT_SHA = "99e127b1";
48737
- var COMMIT_DATE = "2026-05-25T22:55:41Z";
48738
- var LATEST_PR = 1845;
48735
+ var VERSION = "0.13.51";
48736
+ var COMMIT_SHA = "9494f463";
48737
+ var COMMIT_DATE = "2026-05-25T23:39:25Z";
48738
+ var LATEST_PR = 1861;
48739
48739
  var COMMITS_AHEAD_OF_TAG = 0;
48740
48740
 
48741
48741
  // gateway/boot-version.ts