@clawos-dev/clawd 0.2.44-beta.65.0ec3371 → 0.2.45-beta.66.2111d29

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +53 -5
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -10784,7 +10784,7 @@ function buildSpawnArgs(ctx) {
10784
10784
  args.push("--setting-sources", "project,local");
10785
10785
  break;
10786
10786
  case "owner":
10787
- args.push("--setting-sources", "user");
10787
+ args.push("--setting-sources", "user,project,local");
10788
10788
  args.push("--permission-mode", "bypassPermissions");
10789
10789
  break;
10790
10790
  case void 0:
@@ -10795,6 +10795,7 @@ function buildSpawnArgs(ctx) {
10795
10795
  throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
10796
10796
  }
10797
10797
  }
10798
+ if (ctx.extraSettings) args.push("--settings", ctx.extraSettings);
10798
10799
  if (ctx.effort) args.push("--effort", ctx.effort);
10799
10800
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
10800
10801
  return args;
@@ -15709,6 +15710,9 @@ function buildSpawnContext(state) {
15709
15710
  if (meta?.personaMode) {
15710
15711
  ctx.personaMode = meta.personaMode;
15711
15712
  }
15713
+ if (meta?.extraSettings) {
15714
+ ctx.extraSettings = meta.extraSettings;
15715
+ }
15712
15716
  return ctx;
15713
15717
  }
15714
15718
  function sessionInfoFrame(file) {
@@ -17631,16 +17635,52 @@ var PersonaStore = class {
17631
17635
  claudeMdPath(personaId) {
17632
17636
  return path6.join(this.personaDir(personaId), "CLAUDE.md");
17633
17637
  }
17634
- settingsPath(personaId) {
17638
+ /**
17639
+ * Sandbox settings 落盘路径 —— 故意放在 `.clawd/` 而不是 `.claude/`,让 CC 的
17640
+ * project source 自动发现机制扫不到。owner 模式 spawn 时不会被 `--setting-sources
17641
+ * user,project,local` 顺手带进来;listener 模式靠 `--settings <这个路径>` 显式拉回。
17642
+ * 把 sandbox 跟 persona CLAUDE.md(仍在 `<persona>/CLAUDE.md`)解耦后,两种模式都能
17643
+ * 加载 persona 人格,只有 listener 多一层 OS sandbox。
17644
+ */
17645
+ sandboxSettingsPath(personaId) {
17646
+ return path6.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
17647
+ }
17648
+ /** 旧布局(< owner-personality-fix)的 sandbox 落点;只用于迁移 + 测试断言 */
17649
+ legacySettingsPath(personaId) {
17635
17650
  return path6.join(this.personaDir(personaId), ".claude", "settings.json");
17636
17651
  }
17637
17652
  write(persona, personality) {
17638
17653
  const dir = this.personaDir(persona.personaId);
17639
- fs6.mkdirSync(path6.join(dir, ".claude"), { recursive: true });
17640
17654
  fs6.mkdirSync(path6.join(dir, ".clawd"), { recursive: true });
17641
17655
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
17642
- this.atomicWrite(this.settingsPath(persona.personaId), JSON.stringify(DEFAULT_SETTINGS, null, 2));
17656
+ this.atomicWrite(
17657
+ this.sandboxSettingsPath(persona.personaId),
17658
+ JSON.stringify(DEFAULT_SETTINGS, null, 2)
17659
+ );
17643
17660
  this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
17661
+ this.removeLegacyLayout(persona.personaId);
17662
+ }
17663
+ /**
17664
+ * 把旧布局(`<persona>/.claude/settings.json` 持有 sandbox)迁到新布局
17665
+ * (`<persona>/.clawd/sandbox-settings.json`)。在 PersonaRegistry boot reload
17666
+ * 时对每个已存在 persona 调一次;幂等,新布局已就位则直接 noop / 清残留。
17667
+ * 返回 true 表示真做了迁移(写日志 / 测试断言用)。
17668
+ */
17669
+ migrateLegacyLayout(personaId) {
17670
+ const legacy = this.legacySettingsPath(personaId);
17671
+ const target = this.sandboxSettingsPath(personaId);
17672
+ if (!fs6.existsSync(legacy)) return false;
17673
+ if (fs6.existsSync(target)) {
17674
+ fs6.unlinkSync(legacy);
17675
+ return true;
17676
+ }
17677
+ fs6.mkdirSync(path6.dirname(target), { recursive: true });
17678
+ fs6.renameSync(legacy, target);
17679
+ return true;
17680
+ }
17681
+ removeLegacyLayout(personaId) {
17682
+ const legacy = this.legacySettingsPath(personaId);
17683
+ if (fs6.existsSync(legacy)) fs6.unlinkSync(legacy);
17644
17684
  }
17645
17685
  writePersonality(personaId, personality) {
17646
17686
  this.atomicWrite(this.claudeMdPath(personaId), personality);
@@ -17694,6 +17734,7 @@ var PersonaRegistry = class {
17694
17734
  reload() {
17695
17735
  this.cache.clear();
17696
17736
  for (const id of this.store.list()) {
17737
+ this.store.migrateLegacyLayout(id);
17697
17738
  const p = this.store.read(id);
17698
17739
  if (p) this.cache.set(p.personaId, p);
17699
17740
  }
@@ -17840,7 +17881,14 @@ var PersonaManager = class {
17840
17881
  tool: "claude",
17841
17882
  label: subLabel,
17842
17883
  model: persona.model,
17843
- subSessionMeta: { idleKillEnabled: true, personaMode: "listener" }
17884
+ // listener OS sandbox:sandbox JSON 不在 project 自动发现路径上(PersonaStore 把它
17885
+ // 落在 .clawd/sandbox-settings.json),靠 extraSettings 透传到 spawn 的 `--settings <file>`
17886
+ // 显式拉回。owner 路径不传 extraSettings,天然无 sandbox。
17887
+ subSessionMeta: {
17888
+ idleKillEnabled: true,
17889
+ personaMode: "listener",
17890
+ extraSettings: this.deps.store.sandboxSettingsPath(personaId)
17891
+ }
17844
17892
  });
17845
17893
  return { sessionFile, isNew: true };
17846
17894
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.44-beta.65.0ec3371",
3
+ "version": "0.2.45-beta.66.2111d29",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",