@clawos-dev/clawd 0.2.438 → 0.2.439

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.
package/dist/cli.cjs CHANGED
@@ -7051,7 +7051,7 @@ var init_onboarding_schemas = __esm({
7051
7051
  });
7052
7052
 
7053
7053
  // ../protocol/src/persona-schemas.ts
7054
- var PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema, CodexSandboxSettingsSchema;
7054
+ var PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, CodexSandboxSettingsSchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema;
7055
7055
  var init_persona_schemas = __esm({
7056
7056
  "../protocol/src/persona-schemas.ts"() {
7057
7057
  "use strict";
@@ -7084,6 +7084,17 @@ var init_persona_schemas = __esm({
7084
7084
  // settings.json 中 enabledPlugins 的 key,例如 'superpowers@claude-plugins-official'
7085
7085
  id: external_exports.string().min(1)
7086
7086
  });
7087
+ CodexSandboxSettingsSchema = external_exports.object({
7088
+ // 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
7089
+ writableRoots: external_exports.array(external_exports.string()).optional(),
7090
+ // 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
7091
+ denyRead: external_exports.array(external_exports.string()).optional(),
7092
+ // true → 网络全放(*);false → 断网。**缺省等于联网**:daemon 写入的默认值是 network:true
7093
+ // (对齐 claude guest 一贯的域名全放,见 spec 2026-09-01-codex-guest-network §1.3),
7094
+ // 且 manager / UI 读到 undefined 时都回落 true —— 两侧必须同向,否则出现
7095
+ // 「卡片显示开、实际断网」的幽灵态。
7096
+ network: external_exports.boolean().optional()
7097
+ }).strict();
7087
7098
  PersonaSandboxSettingsSchema = external_exports.object({
7088
7099
  permissions: external_exports.object({
7089
7100
  defaultMode: external_exports.string().optional(),
@@ -7132,7 +7143,10 @@ var init_persona_schemas = __esm({
7132
7143
  skills: external_exports.array(PersonaSkillSummarySchema).optional(),
7133
7144
  // 仅 'persona:get' 携带;空数组 = 没启用任何插件 / settings.json 不存在;undefined = 不在该响应类型上
7134
7145
  plugins: external_exports.array(PersonaPluginSummarySchema).optional(),
7135
- sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional()
7146
+ sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional(),
7147
+ // 仅 'persona:get' 携带;null = codex-sandbox.json 不存在 / parse 失败。
7148
+ // UI 的「访客联网」开关读它(见 PersonaCardSettings)。
7149
+ codexSandbox: CodexSandboxSettingsSchema.nullable().optional()
7136
7150
  });
7137
7151
  PersonaCreateArgsSchema = external_exports.object({
7138
7152
  // persona 身份。daemon 拼成 personaId = `persona-<slug>`——前缀由 daemon 拥有,调用方只给后半段,
@@ -7164,17 +7178,13 @@ var init_persona_schemas = __esm({
7164
7178
  personalityLocal: external_exports.string().optional(),
7165
7179
  public: external_exports.boolean().optional(),
7166
7180
  // pass `null` to clear; daemon strips the field from PersonaFile on null
7167
- iconKey: external_exports.string().nullable().optional()
7181
+ iconKey: external_exports.string().nullable().optional(),
7182
+ // codex guest 沙箱(落盘 .clawd/codex-sandbox.json,不在 PersonaFile 里)。与 personality
7183
+ // 同款分层写:handler 剥出来单独落盘,且**局部合并**——只带 network 的 patch 不能抹掉
7184
+ // owner 手配的 writableRoots / denyRead。
7185
+ codexSandbox: CodexSandboxSettingsSchema.optional()
7168
7186
  }).strict()
7169
7187
  }).strict();
7170
- CodexSandboxSettingsSchema = external_exports.object({
7171
- // 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
7172
- writableRoots: external_exports.array(external_exports.string()).optional(),
7173
- // 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
7174
- denyRead: external_exports.array(external_exports.string()).optional(),
7175
- // true → 网络全放(*);缺省/false → 断网。
7176
- network: external_exports.boolean().optional()
7177
- }).strict();
7178
7188
  }
7179
7189
  });
7180
7190
 
@@ -47059,7 +47069,7 @@ var SessionManager = class {
47059
47069
  subSessionMeta.codexSandbox = {
47060
47070
  writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
47061
47071
  denyRead: codexCfg?.denyRead ?? [],
47062
- network: codexCfg?.network ?? false
47072
+ network: codexCfg?.network ?? true
47063
47073
  };
47064
47074
  }
47065
47075
  if (subSessionMeta?.personaMode === "owner" && file.projectPath) {
@@ -49797,6 +49807,24 @@ var PersonaManager = class {
49797
49807
  return this.deps.store.readEnabledPlugins(personaId2);
49798
49808
  }
49799
49809
  /** 读 sandbox-settings.json;不存在 / 损坏返回 null。供 persona:get handler 拼响应。 */
49810
+ /** 读 codex guest 沙箱配置(`.clawd/codex-sandbox.json`);缺失 / 坏 → null。透传给 handler 拼响应。 */
49811
+ readCodexSandboxSettings(personaId2) {
49812
+ return this.deps.store.readCodexSandboxSettings(personaId2);
49813
+ }
49814
+ /**
49815
+ * 局部合并写 codex guest 沙箱配置,返回合并后的全量。
49816
+ *
49817
+ * **必须是合并不是覆盖**:UI 的「访客联网」开关只发 `{network}`,整体覆盖会静默抹掉 owner
49818
+ * 手配的 writableRoots / denyRead(丢的是安全边界,且用户不会立刻发现)。
49819
+ * 不走 PersonaManager.update 是因为它管的是 PersonaFile meta + 人格两层文本,
49820
+ * 而这份配置是另一个文件、另一套 schema。
49821
+ */
49822
+ mergeCodexSandbox(personaId2, patch) {
49823
+ if (!this.deps.registry.get(personaId2)) throw new Error(`persona not found: ${personaId2}`);
49824
+ const merged = { ...this.deps.store.readCodexSandboxSettings(personaId2) ?? {}, ...patch };
49825
+ this.deps.store.writeCodexSandboxSettings(personaId2, merged);
49826
+ return merged;
49827
+ }
49800
49828
  readSandboxSettings(personaId2) {
49801
49829
  return this.deps.store.readSandboxSettings(personaId2);
49802
49830
  }
@@ -50198,13 +50226,15 @@ function migrateAgentsMirror(args) {
50198
50226
  }
50199
50227
  if (mirrored > 0) args.logger.info("persona.agents-mirror.done", { mirrored });
50200
50228
  }
50229
+ var PKG_CACHE_ROOTS = ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"];
50230
+ var CODEX_SANDBOX_DEFAULT = { writableRoots: [...PKG_CACHE_ROOTS], denyRead: [], network: true };
50201
50231
  function migrateCodexSandbox(args) {
50202
50232
  const entries = args.entries ?? DEFAULT_PERSONAS;
50203
50233
  let n = 0;
50204
50234
  for (const personaId2 of args.store.list()) {
50205
50235
  if (args.store.readCodexSandboxSettings(personaId2)) continue;
50206
50236
  try {
50207
- const def = entries.find((e) => e.personaId === personaId2)?.codexSandbox ?? { writableRoots: [], denyRead: [], network: false };
50237
+ const def = entries.find((e) => e.personaId === personaId2)?.codexSandbox ?? CODEX_SANDBOX_DEFAULT;
50208
50238
  args.store.writeCodexSandboxSettings(personaId2, def);
50209
50239
  n++;
50210
50240
  args.logger.info("persona.codex-sandbox.synced", { personaId: personaId2 });
@@ -62807,7 +62837,7 @@ function computeMethodAccess(args) {
62807
62837
  }
62808
62838
 
62809
62839
  // src/version.ts
62810
- var version = "0.2.438".length > 0 ? "0.2.438" : "dev";
62840
+ var version = "0.2.439".length > 0 ? "0.2.439" : "dev";
62811
62841
 
62812
62842
  // src/cli-probe/probe.ts
62813
62843
  var fs65 = __toESM(require("fs"), 1);
@@ -62971,6 +63001,7 @@ function buildPersonaHandlers(deps) {
62971
63001
  const skills = personaManager.listSkills(args.personaId);
62972
63002
  const plugins = personaManager.listEnabledPlugins(args.personaId);
62973
63003
  const sandboxSettings = personaManager.readSandboxSettings(args.personaId);
63004
+ const codexSandbox = personaManager.readCodexSandboxSettings(args.personaId);
62974
63005
  return {
62975
63006
  response: {
62976
63007
  type: "persona:info",
@@ -62980,16 +63011,26 @@ function buildPersonaHandlers(deps) {
62980
63011
  personalityManaged,
62981
63012
  skills,
62982
63013
  plugins,
62983
- sandboxSettings
63014
+ sandboxSettings,
63015
+ codexSandbox
62984
63016
  }
62985
63017
  };
62986
63018
  };
62987
63019
  const update = async (frame) => {
62988
63020
  const { type: _type, requestId: _requestId, ...rest } = frame;
62989
63021
  const args = parseArgs2(PersonaUpdateArgsSchema, frame, "persona:update");
62990
- const { personality, personalityLocal, ...metaPatch } = args.patch;
63022
+ const { personality, personalityLocal, codexSandbox, ...metaPatch } = args.patch;
62991
63023
  const persona = personaManager.update(args.personaId, metaPatch, { personality, personalityLocal });
62992
- return { response: { type: "persona:info", ...persona } };
63024
+ const mergedCodexSandbox = codexSandbox ? personaManager.mergeCodexSandbox(args.personaId, codexSandbox) : void 0;
63025
+ return {
63026
+ response: {
63027
+ type: "persona:info",
63028
+ ...persona,
63029
+ // 只在本次确实动过时回带,让调用方拿到合并后的真值而不用再 get 一次;
63030
+ // 没动就不带(与 personality 等分层字段同口径:persona:update 的响应是 meta 视图)。
63031
+ ...mergedCodexSandbox ? { codexSandbox: mergedCodexSandbox } : {}
63032
+ }
63033
+ };
62993
63034
  };
62994
63035
  const del = async (frame) => {
62995
63036
  const args = parseArgs2(PersonaIdArgsSchema, frame, "persona:delete");
@@ -22237,6 +22237,17 @@ var PersonaPluginSummarySchema = external_exports.object({
22237
22237
  // settings.json 中 enabledPlugins 的 key,例如 'superpowers@claude-plugins-official'
22238
22238
  id: external_exports.string().min(1)
22239
22239
  });
22240
+ var CodexSandboxSettingsSchema = external_exports.object({
22241
+ // 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
22242
+ writableRoots: external_exports.array(external_exports.string()).optional(),
22243
+ // 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
22244
+ denyRead: external_exports.array(external_exports.string()).optional(),
22245
+ // true → 网络全放(*);false → 断网。**缺省等于联网**:daemon 写入的默认值是 network:true
22246
+ // (对齐 claude guest 一贯的域名全放,见 spec 2026-09-01-codex-guest-network §1.3),
22247
+ // 且 manager / UI 读到 undefined 时都回落 true —— 两侧必须同向,否则出现
22248
+ // 「卡片显示开、实际断网」的幽灵态。
22249
+ network: external_exports.boolean().optional()
22250
+ }).strict();
22240
22251
  var PersonaSandboxSettingsSchema = external_exports.object({
22241
22252
  permissions: external_exports.object({
22242
22253
  defaultMode: external_exports.string().optional(),
@@ -22285,7 +22296,10 @@ var PersonaInfoResponseSchema = PersonaFileSchema.extend({
22285
22296
  skills: external_exports.array(PersonaSkillSummarySchema).optional(),
22286
22297
  // 仅 'persona:get' 携带;空数组 = 没启用任何插件 / settings.json 不存在;undefined = 不在该响应类型上
22287
22298
  plugins: external_exports.array(PersonaPluginSummarySchema).optional(),
22288
- sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional()
22299
+ sandboxSettings: PersonaSandboxSettingsSchema.nullable().optional(),
22300
+ // 仅 'persona:get' 携带;null = codex-sandbox.json 不存在 / parse 失败。
22301
+ // UI 的「访客联网」开关读它(见 PersonaCardSettings)。
22302
+ codexSandbox: CodexSandboxSettingsSchema.nullable().optional()
22289
22303
  });
22290
22304
  var PersonaCreateArgsSchema = external_exports.object({
22291
22305
  // persona 身份。daemon 拼成 personaId = `persona-<slug>`——前缀由 daemon 拥有,调用方只给后半段,
@@ -22317,17 +22331,13 @@ var PersonaUpdateArgsSchema = external_exports.object({
22317
22331
  personalityLocal: external_exports.string().optional(),
22318
22332
  public: external_exports.boolean().optional(),
22319
22333
  // pass `null` to clear; daemon strips the field from PersonaFile on null
22320
- iconKey: external_exports.string().nullable().optional()
22334
+ iconKey: external_exports.string().nullable().optional(),
22335
+ // codex guest 沙箱(落盘 .clawd/codex-sandbox.json,不在 PersonaFile 里)。与 personality
22336
+ // 同款分层写:handler 剥出来单独落盘,且**局部合并**——只带 network 的 patch 不能抹掉
22337
+ // owner 手配的 writableRoots / denyRead。
22338
+ codexSandbox: CodexSandboxSettingsSchema.optional()
22321
22339
  }).strict()
22322
22340
  }).strict();
22323
- var CodexSandboxSettingsSchema = external_exports.object({
22324
- // 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
22325
- writableRoots: external_exports.array(external_exports.string()).optional(),
22326
- // 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
22327
- denyRead: external_exports.array(external_exports.string()).optional(),
22328
- // true → 网络全放(*);缺省/false → 断网。
22329
- network: external_exports.boolean().optional()
22330
- }).strict();
22331
22341
 
22332
22342
  // ../protocol/src/events.ts
22333
22343
  var SESSION_STATUS_VALUES = [