@clawos-dev/clawd 0.2.135-beta.281.fb1ead2 → 0.2.135-beta.282.8ee36dc

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 +183 -71
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -4495,7 +4495,7 @@ var init_attachment_schemas = __esm({
4495
4495
  });
4496
4496
 
4497
4497
  // ../protocol/src/persona-schemas.ts
4498
- var PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema;
4498
+ var PersonaFileSchema, PersonaSkillSummarySchema, PersonaPluginSummarySchema, PersonaSandboxSettingsSchema, PersonaInfoResponseSchema, PersonaCreateArgsSchema, PersonaIdArgsSchema, PersonaUpdateArgsSchema, CodexSandboxSettingsSchema;
4499
4499
  var init_persona_schemas = __esm({
4500
4500
  "../protocol/src/persona-schemas.ts"() {
4501
4501
  "use strict";
@@ -4580,6 +4580,14 @@ var init_persona_schemas = __esm({
4580
4580
  iconKey: external_exports.string().nullable().optional()
4581
4581
  }).strict()
4582
4582
  }).strict();
4583
+ CodexSandboxSettingsSchema = external_exports.object({
4584
+ // 额外可写的绝对路径或 ~ 路径(pnpm 工具链等);workspace(cwd) 和 userWorkDir 由 daemon 自动加,不用列。
4585
+ writableRoots: external_exports.array(external_exports.string()).optional(),
4586
+ // 禁读 glob(相对 workspace root 或绝对),如 ".secrets/**"、"**/*.env"。
4587
+ denyRead: external_exports.array(external_exports.string()).optional(),
4588
+ // true → 网络全放(*);缺省/false → 断网。
4589
+ network: external_exports.boolean().optional()
4590
+ }).strict();
4583
4591
  }
4584
4592
  });
4585
4593
 
@@ -10047,7 +10055,7 @@ var require_multistream = __commonJS({
10047
10055
  var require_pino = __commonJS({
10048
10056
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10049
10057
  "use strict";
10050
- var os21 = require("os");
10058
+ var os22 = require("os");
10051
10059
  var stdSerializers = require_pino_std_serializers();
10052
10060
  var caller = require_caller();
10053
10061
  var redaction = require_redaction();
@@ -10094,7 +10102,7 @@ var require_pino = __commonJS({
10094
10102
  } = symbols;
10095
10103
  var { epochTime, nullTime } = time;
10096
10104
  var { pid } = process;
10097
- var hostname = os21.hostname();
10105
+ var hostname = os22.hostname();
10098
10106
  var defaultErrorSerializer = stdSerializers.err;
10099
10107
  var defaultOptions = {
10100
10108
  level: "info",
@@ -11333,12 +11341,12 @@ function readCurrentContent(filePath) {
11333
11341
  return null;
11334
11342
  }
11335
11343
  }
11336
- var import_node_fs8, import_node_os3, import_node_path8, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11344
+ var import_node_fs8, import_node_os4, import_node_path8, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
11337
11345
  var init_claude_history = __esm({
11338
11346
  "src/tools/claude-history.ts"() {
11339
11347
  "use strict";
11340
11348
  import_node_fs8 = __toESM(require("fs"), 1);
11341
- import_node_os3 = __toESM(require("os"), 1);
11349
+ import_node_os4 = __toESM(require("os"), 1);
11342
11350
  import_node_path8 = __toESM(require("path"), 1);
11343
11351
  init_lib();
11344
11352
  init_tool_result_extra();
@@ -11363,7 +11371,7 @@ var init_claude_history = __esm({
11363
11371
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11364
11372
  fileHistoryRoot;
11365
11373
  constructor(opts = {}) {
11366
- const base = opts.baseDir ?? import_node_path8.default.join(import_node_os3.default.homedir(), ".claude");
11374
+ const base = opts.baseDir ?? import_node_path8.default.join(import_node_os4.default.homedir(), ".claude");
11367
11375
  this.projectsRoot = import_node_path8.default.join(base, "projects");
11368
11376
  this.fileHistoryRoot = import_node_path8.default.join(base, "file-history");
11369
11377
  }
@@ -11760,7 +11768,7 @@ function probeViaWhich() {
11760
11768
  }
11761
11769
  return null;
11762
11770
  }
11763
- async function probeClaude(env = process.env, home = import_node_os4.default.homedir()) {
11771
+ async function probeClaude(env = process.env, home = import_node_os5.default.homedir()) {
11764
11772
  if (env.CLAUDE_BIN && import_node_fs9.default.existsSync(env.CLAUDE_BIN)) {
11765
11773
  return { available: true, path: env.CLAUDE_BIN };
11766
11774
  }
@@ -12200,14 +12208,14 @@ function encodeClaudeStdin(text) {
12200
12208
  };
12201
12209
  return JSON.stringify(frame) + "\n";
12202
12210
  }
12203
- var import_node_child_process, import_node_child_process2, import_node_fs9, import_node_os4, import_node_path9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12211
+ var import_node_child_process, import_node_child_process2, import_node_fs9, import_node_os5, import_node_path9, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
12204
12212
  var init_claude = __esm({
12205
12213
  "src/tools/claude.ts"() {
12206
12214
  "use strict";
12207
12215
  import_node_child_process = require("child_process");
12208
12216
  import_node_child_process2 = require("child_process");
12209
12217
  import_node_fs9 = __toESM(require("fs"), 1);
12210
- import_node_os4 = __toESM(require("os"), 1);
12218
+ import_node_os5 = __toESM(require("os"), 1);
12211
12219
  import_node_path9 = __toESM(require("path"), 1);
12212
12220
  init_protocol();
12213
12221
  init_claude_history();
@@ -30840,7 +30848,7 @@ var init_wire = __esm({
30840
30848
  // src/run-case/controller.ts
30841
30849
  async function runController(opts) {
30842
30850
  const now = opts.now ?? Date.now;
30843
- const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path48.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
30851
+ const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path48.default.join(import_node_os20.default.tmpdir(), "clawd-runcase-"));
30844
30852
  const ownsCwd = opts.cwd === void 0;
30845
30853
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
30846
30854
  const spawnCtx = { cwd };
@@ -31007,12 +31015,12 @@ async function runController(opts) {
31007
31015
  }
31008
31016
  return exitCode ?? 0;
31009
31017
  }
31010
- var import_node_fs35, import_node_os19, import_node_path48;
31018
+ var import_node_fs35, import_node_os20, import_node_path48;
31011
31019
  var init_controller = __esm({
31012
31020
  "src/run-case/controller.ts"() {
31013
31021
  "use strict";
31014
31022
  import_node_fs35 = require("fs");
31015
- import_node_os19 = __toESM(require("os"), 1);
31023
+ import_node_os20 = __toESM(require("os"), 1);
31016
31024
  import_node_path48 = __toESM(require("path"), 1);
31017
31025
  init_claude();
31018
31026
  init_stdout_splitter();
@@ -31490,6 +31498,7 @@ var SessionStoreFactory = class {
31490
31498
  // src/session/manager.ts
31491
31499
  var import_node_fs6 = __toESM(require("fs"), 1);
31492
31500
  var import_node_path6 = __toESM(require("path"), 1);
31501
+ var import_node_os2 = __toESM(require("os"), 1);
31493
31502
 
31494
31503
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
31495
31504
  var byteToHex = [];
@@ -31767,8 +31776,8 @@ function buildSpawnContext(state, deps) {
31767
31776
  if (meta?.addDirs && meta.addDirs.length > 0) {
31768
31777
  ctx.addDirs = meta.addDirs;
31769
31778
  }
31770
- if (meta?.networkAccess !== void 0) {
31771
- ctx.networkAccess = meta.networkAccess;
31779
+ if (meta?.codexSandbox) {
31780
+ ctx.codexSandbox = meta.codexSandbox;
31772
31781
  }
31773
31782
  return ctx;
31774
31783
  }
@@ -33266,8 +33275,14 @@ var SessionManager = class {
33266
33275
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
33267
33276
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
33268
33277
  subSessionMeta.extraSettings = JSON.stringify(settings);
33269
- const domains = settings.sandbox?.network?.allowedDomains;
33270
- subSessionMeta.networkAccess = Array.isArray(domains) && domains.length > 0;
33278
+ const home = import_node_os2.default.homedir();
33279
+ const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
33280
+ const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
33281
+ subSessionMeta.codexSandbox = {
33282
+ writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
33283
+ denyRead: codexCfg?.denyRead ?? [],
33284
+ network: codexCfg?.network ?? false
33285
+ };
33271
33286
  }
33272
33287
  const attachmentGroup = this.deps.attachmentGroup;
33273
33288
  const runner = new SessionRunner(makeInitialState(file, subSessionMeta), {
@@ -34536,6 +34551,25 @@ var PersonaStore = class {
34536
34551
  JSON.stringify(settings, null, 2)
34537
34552
  );
34538
34553
  }
34554
+ codexSandboxSettingsPath(personaId) {
34555
+ return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
34556
+ }
34557
+ /** 读 codex-sandbox.json;不存在/损坏 → null。 */
34558
+ readCodexSandboxSettings(personaId) {
34559
+ const p2 = this.codexSandboxSettingsPath(personaId);
34560
+ if (!fs7.existsSync(p2)) return null;
34561
+ try {
34562
+ return CodexSandboxSettingsSchema.parse(JSON.parse(fs7.readFileSync(p2, "utf8")));
34563
+ } catch {
34564
+ return null;
34565
+ }
34566
+ }
34567
+ /** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
34568
+ writeCodexSandboxSettings(personaId, settings) {
34569
+ const dir = path9.join(this.personaDir(personaId), ".clawd");
34570
+ fs7.mkdirSync(dir, { recursive: true });
34571
+ this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
34572
+ }
34539
34573
  writeMeta(persona) {
34540
34574
  this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
34541
34575
  }
@@ -34675,7 +34709,7 @@ var import_node_crypto3 = __toESM(require("crypto"), 1);
34675
34709
 
34676
34710
  // src/skills/scanner.ts
34677
34711
  var import_node_fs7 = __toESM(require("fs"), 1);
34678
- var import_node_os2 = __toESM(require("os"), 1);
34712
+ var import_node_os3 = __toESM(require("os"), 1);
34679
34713
  var import_node_path7 = __toESM(require("path"), 1);
34680
34714
 
34681
34715
  // src/skills/frontmatter.ts
@@ -34909,7 +34943,7 @@ var SkillsScanner = class {
34909
34943
  home;
34910
34944
  extraPluginRoots;
34911
34945
  constructor(opts = {}) {
34912
- this.home = opts.home ?? import_node_os2.default.homedir();
34946
+ this.home = opts.home ?? import_node_os3.default.homedir();
34913
34947
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
34914
34948
  }
34915
34949
  /**
@@ -35116,6 +35150,11 @@ var DEFAULT_PERSONAS = [
35116
35150
  allowLocalBinding: true
35117
35151
  }
35118
35152
  }
35153
+ },
35154
+ codexSandbox: {
35155
+ writableRoots: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"],
35156
+ denyRead: [".secrets/**"],
35157
+ network: true
35119
35158
  }
35120
35159
  },
35121
35160
  {
@@ -35195,6 +35234,10 @@ function seedDefaultPersonas(args) {
35195
35234
  args.store.writeSandboxSettings(entry.personaId, settings);
35196
35235
  args.logger.info("persona.seed.sandbox-profile", { personaId: entry.personaId });
35197
35236
  }
35237
+ if (entry.codexSandbox) {
35238
+ args.store.writeCodexSandboxSettings(entry.personaId, entry.codexSandbox);
35239
+ args.logger.info("persona.seed.codex-sandbox", { personaId: entry.personaId });
35240
+ }
35198
35241
  copyBundleExtras(bundleDir, args.store.personaDirPath(entry.personaId));
35199
35242
  args.logger.info("persona.seed.created", { personaId: entry.personaId });
35200
35243
  }
@@ -35256,6 +35299,22 @@ function migrateAgentsMirror(args) {
35256
35299
  }
35257
35300
  if (mirrored > 0) args.logger.info("persona.agents-mirror.done", { mirrored });
35258
35301
  }
35302
+ function migrateCodexSandbox(args) {
35303
+ const entries = args.entries ?? DEFAULT_PERSONAS;
35304
+ let n = 0;
35305
+ for (const personaId of args.store.list()) {
35306
+ if (args.store.readCodexSandboxSettings(personaId)) continue;
35307
+ try {
35308
+ const def = entries.find((e) => e.personaId === personaId)?.codexSandbox ?? { writableRoots: [], denyRead: [], network: false };
35309
+ args.store.writeCodexSandboxSettings(personaId, def);
35310
+ n++;
35311
+ args.logger.info("persona.codex-sandbox.synced", { personaId });
35312
+ } catch (err) {
35313
+ args.logger.warn("persona.codex-sandbox.failed", { personaId, error: err instanceof Error ? err.message : String(err) });
35314
+ }
35315
+ }
35316
+ if (n > 0) args.logger.info("persona.codex-sandbox.done", { migrated: n });
35317
+ }
35259
35318
 
35260
35319
  // src/index.ts
35261
35320
  init_claude();
@@ -35452,19 +35511,58 @@ function resolveApprovalPolicy(ctx) {
35452
35511
  if (m2 === "untrusted" || m2 === "on-failure" || m2 === "on-request" || m2 === "never") return m2;
35453
35512
  return "on-request";
35454
35513
  }
35514
+ function buildCodexGuestConfig(cs) {
35515
+ const filesystem = {};
35516
+ for (const w2 of cs.writableRoots ?? []) filesystem[w2] = "write";
35517
+ const deny = cs.denyRead ?? [];
35518
+ if (deny.length > 0) {
35519
+ const wsScoped = {};
35520
+ for (const d of deny) wsScoped[d] = "deny";
35521
+ filesystem[":workspace_roots"] = wsScoped;
35522
+ }
35523
+ return {
35524
+ default_permissions: "clawos_guest",
35525
+ permissions: {
35526
+ clawos_guest: {
35527
+ extends: ":workspace",
35528
+ filesystem,
35529
+ network: cs.network ? { enabled: true, domains: { "*": "allow" } } : { enabled: false }
35530
+ }
35531
+ }
35532
+ };
35533
+ }
35534
+ function tomlValue(v2) {
35535
+ if (typeof v2 === "string") return JSON.stringify(v2);
35536
+ if (typeof v2 === "boolean" || typeof v2 === "number") return String(v2);
35537
+ if (Array.isArray(v2)) return "[" + v2.map(tomlValue).join(",") + "]";
35538
+ if (v2 && typeof v2 === "object") {
35539
+ return "{" + Object.entries(v2).map(([k2, val]) => `${/^[A-Za-z0-9_-]+$/.test(k2) ? k2 : JSON.stringify(k2)}=${tomlValue(val)}`).join(",") + "}";
35540
+ }
35541
+ return JSON.stringify(v2);
35542
+ }
35543
+ function codexGuestCliArgs(cs) {
35544
+ const cfg = buildCodexGuestConfig(cs);
35545
+ const profile = cfg.permissions.clawos_guest;
35546
+ return [
35547
+ "-c",
35548
+ `default_permissions=${tomlValue("clawos_guest")}`,
35549
+ "-c",
35550
+ `permissions.clawos_guest=${tomlValue(profile)}`
35551
+ ];
35552
+ }
35455
35553
  function threadStartParams(ctx) {
35456
35554
  const params = {
35457
35555
  cwd: ctx.cwd,
35458
- sandbox: resolveSandbox(ctx),
35459
35556
  approvalPolicy: resolveApprovalPolicy(ctx),
35460
35557
  approvalsReviewer: "user",
35461
- ...ctx.model ? { model: ctx.model } : {}
35558
+ ...ctx.model ? { model: ctx.model } : {},
35559
+ // guest 沙箱由 app-server 启动 -c 注入的 permission profile(codexGuestCliArgs)控制——profile 是
35560
+ // 进程启动解析的。故 guest **不发 sandbox 字段**(避免 sandbox mode 覆盖 profile);owner/普通按 sandbox mode。
35561
+ ...ctx.personaMode === "guest" ? {} : { sandbox: resolveSandbox(ctx) },
35562
+ // 连接 intro(owner/guest 人称差异化)走 developerInstructions(developer 级、不进消息流、不显示在 UI),
35563
+ // 取代旧的"折进首条 turn 文本"(那个被当用户消息显示)。thread/start + thread/resume 都带,幂等。
35564
+ ...ctx.extraSystemPrompt ? { developerInstructions: ctx.extraSystemPrompt } : {}
35462
35565
  };
35463
- if (ctx.personaMode === "guest") {
35464
- params.config = {
35465
- sandbox_workspace_write: { writable_roots: ctx.addDirs ?? [], network_access: ctx.networkAccess ?? false }
35466
- };
35467
- }
35468
35566
  return params;
35469
35567
  }
35470
35568
  var ATTACHMENT_RE2 = /\[attachment:(image|file):([^\]]+)\]/g;
@@ -35493,12 +35591,14 @@ function turnStartInput(text) {
35493
35591
  function createCodexSession(ctx, sink, deps = {}) {
35494
35592
  const cmd = process.env.CODEX_BIN ?? "codex";
35495
35593
  const args = ["app-server", "--listen", "stdio://"];
35594
+ if (ctx.personaMode === "guest" && ctx.codexSandbox) {
35595
+ args.push(...codexGuestCliArgs(ctx.codexSandbox));
35596
+ }
35496
35597
  const env = { ...process.env, ...ctx.env };
35497
35598
  const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process3.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
35498
35599
  let threadId = ctx.toolSessionId;
35499
35600
  let turnId;
35500
35601
  const approvalIds = /* @__PURE__ */ new Map();
35501
- let pendingSystemPrompt = ctx.toolSessionId ? void 0 : ctx.extraSystemPrompt;
35502
35602
  const effort = ctx.effort;
35503
35603
  let exited = false;
35504
35604
  const finish = (code) => {
@@ -35561,15 +35661,11 @@ function createCodexSession(ctx, sink, deps = {}) {
35561
35661
  })().catch((e) => sink.onError(`codex app-server init failed: ${e.message}`));
35562
35662
  return {
35563
35663
  startTurn(text) {
35564
- const body = pendingSystemPrompt ? `${pendingSystemPrompt}
35565
-
35566
- ${text}` : text;
35567
- pendingSystemPrompt = void 0;
35568
35664
  void ready.then(() => {
35569
35665
  if (threadId)
35570
35666
  void client.request("turn/start", {
35571
35667
  threadId,
35572
- input: turnStartInput(body),
35668
+ input: turnStartInput(text),
35573
35669
  // TurnStartParams 字段是 `effort`(不是 `reasoningEffort`,0.138 改名)——传错名字
35574
35670
  // codex 静默忽略, reasoning effort 改了不生效。"override for this turn and subsequent turns"。
35575
35671
  ...effort ? { effort } : {}
@@ -35708,7 +35804,7 @@ var CodexAdapter = class {
35708
35804
 
35709
35805
  // src/tools/claude-tui.ts
35710
35806
  var import_node_fs11 = __toESM(require("fs"), 1);
35711
- var import_node_os5 = __toESM(require("os"), 1);
35807
+ var import_node_os6 = __toESM(require("os"), 1);
35712
35808
  var import_node_path10 = __toESM(require("path"), 1);
35713
35809
  var import_headless = __toESM(require_xterm_headless(), 1);
35714
35810
 
@@ -36688,7 +36784,7 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
36688
36784
  }
36689
36785
  function jsonlExistsForCtx(ctx) {
36690
36786
  if (!ctx.toolSessionId) return false;
36691
- const home = import_node_os5.default.homedir();
36787
+ const home = import_node_os6.default.homedir();
36692
36788
  const file = import_node_path10.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
36693
36789
  try {
36694
36790
  return import_node_fs11.default.statSync(file).isFile();
@@ -36932,7 +37028,7 @@ async function listCodexSkills(cwd, deps = {}) {
36932
37028
 
36933
37029
  // src/workspace/browser.ts
36934
37030
  var import_node_fs12 = __toESM(require("fs"), 1);
36935
- var import_node_os6 = __toESM(require("os"), 1);
37031
+ var import_node_os7 = __toESM(require("os"), 1);
36936
37032
  var import_node_path11 = __toESM(require("path"), 1);
36937
37033
  init_protocol();
36938
37034
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
@@ -36958,7 +37054,7 @@ function ensureCwd(cwd) {
36958
37054
  }
36959
37055
  var WorkspaceBrowser = class {
36960
37056
  list(args) {
36961
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
37057
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
36962
37058
  ensureCwd(cwd);
36963
37059
  const full = resolveInsideCwd(cwd, args.path);
36964
37060
  const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
@@ -37017,7 +37113,7 @@ var WorkspaceBrowser = class {
37017
37113
 
37018
37114
  // src/skills/agents-scanner.ts
37019
37115
  var import_node_fs13 = __toESM(require("fs"), 1);
37020
- var import_node_os7 = __toESM(require("os"), 1);
37116
+ var import_node_os8 = __toESM(require("os"), 1);
37021
37117
  var import_node_path12 = __toESM(require("path"), 1);
37022
37118
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
37023
37119
  function isDirLikeSync2(p2) {
@@ -37160,7 +37256,7 @@ var AgentsScanner = class {
37160
37256
  extraPluginRoots;
37161
37257
  policyDir;
37162
37258
  constructor(opts = {}) {
37163
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
37259
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
37164
37260
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
37165
37261
  if (opts.policyDir !== void 0) {
37166
37262
  this.policyDir = opts.policyDir;
@@ -37208,20 +37304,20 @@ var AgentsScanner = class {
37208
37304
 
37209
37305
  // src/observer/session-observer.ts
37210
37306
  var import_node_fs15 = __toESM(require("fs"), 1);
37211
- var import_node_os9 = __toESM(require("os"), 1);
37307
+ var import_node_os10 = __toESM(require("os"), 1);
37212
37308
  var import_node_path14 = __toESM(require("path"), 1);
37213
37309
  init_claude_history();
37214
37310
 
37215
37311
  // src/observer/subagent-meta-observer.ts
37216
37312
  var import_node_fs14 = __toESM(require("fs"), 1);
37217
- var import_node_os8 = __toESM(require("os"), 1);
37313
+ var import_node_os9 = __toESM(require("os"), 1);
37218
37314
  var import_node_path13 = __toESM(require("path"), 1);
37219
37315
  init_claude_history();
37220
37316
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
37221
37317
  var SubagentMetaObserver = class {
37222
37318
  constructor(opts) {
37223
37319
  this.opts = opts;
37224
- this.home = opts.home ?? import_node_os8.default.homedir();
37320
+ this.home = opts.home ?? import_node_os9.default.homedir();
37225
37321
  }
37226
37322
  opts;
37227
37323
  home;
@@ -37332,7 +37428,7 @@ var SubagentMetaObserver = class {
37332
37428
  var SessionObserver = class {
37333
37429
  constructor(opts) {
37334
37430
  this.opts = opts;
37335
- this.home = opts.home ?? import_node_os9.default.homedir();
37431
+ this.home = opts.home ?? import_node_os10.default.homedir();
37336
37432
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
37337
37433
  }
37338
37434
  opts;
@@ -38650,20 +38746,35 @@ async function connectRemote(args) {
38650
38746
  return;
38651
38747
  }
38652
38748
  if (f.type === "auth:ok") {
38653
- ws.off("message", onMessage);
38749
+ finish();
38654
38750
  resolve6();
38655
38751
  return;
38656
38752
  }
38657
38753
  if (f.type === "auth:error" || f.code === 4401) {
38658
- ws.off("message", onMessage);
38754
+ finish();
38659
38755
  reject(new Error(`auth failed: ${f.message ?? f.type ?? "unknown"}`));
38660
38756
  }
38661
38757
  };
38662
- ws.on("message", onMessage);
38663
- setTimeout(() => {
38664
- ws.off("message", onMessage);
38758
+ const onClose = (code, reason) => {
38759
+ finish();
38760
+ const detail = reason.toString() || (code === 4401 ? "BAD_TOKEN" : `code ${code}`);
38761
+ reject(
38762
+ new Error(
38763
+ code === 4401 ? `auth rejected: ${detail}` : `connection closed before auth (code ${code})`
38764
+ )
38765
+ );
38766
+ };
38767
+ const timer = setTimeout(() => {
38768
+ finish();
38665
38769
  reject(new Error("auth handshake timeout"));
38666
38770
  }, HANDSHAKE_TIMEOUT_MS);
38771
+ function finish() {
38772
+ ws.off("message", onMessage);
38773
+ ws.off("close", onClose);
38774
+ clearTimeout(timer);
38775
+ }
38776
+ ws.on("message", onMessage);
38777
+ ws.once("close", onClose);
38667
38778
  });
38668
38779
  function call(method, payload) {
38669
38780
  const requestId = crypto5.randomUUID();
@@ -39124,7 +39235,7 @@ async function writeUploadedAttachment(args) {
39124
39235
  // src/extension/import.ts
39125
39236
  var import_promises2 = __toESM(require("fs/promises"), 1);
39126
39237
  var import_node_path17 = __toESM(require("path"), 1);
39127
- var import_node_os10 = __toESM(require("os"), 1);
39238
+ var import_node_os11 = __toESM(require("os"), 1);
39128
39239
  var import_jszip = __toESM(require_lib3(), 1);
39129
39240
  var ImportError = class extends Error {
39130
39241
  constructor(code, message) {
@@ -39184,7 +39295,7 @@ async function importZip(buf, root) {
39184
39295
  if (destExists) {
39185
39296
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
39186
39297
  }
39187
- const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39298
+ const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39188
39299
  try {
39189
39300
  for (const [name, entry] of Object.entries(zip.files)) {
39190
39301
  const dest = import_node_path17.default.join(stage, name);
@@ -40063,7 +40174,7 @@ function escape(v2) {
40063
40174
 
40064
40175
  // src/tunnel/frpc-binary.ts
40065
40176
  var import_node_fs22 = __toESM(require("fs"), 1);
40066
- var import_node_os11 = __toESM(require("os"), 1);
40177
+ var import_node_os12 = __toESM(require("os"), 1);
40067
40178
  var import_node_path23 = __toESM(require("path"), 1);
40068
40179
  var import_node_child_process7 = require("child_process");
40069
40180
  var import_node_stream2 = require("stream");
@@ -40524,14 +40635,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
40524
40635
  }
40525
40636
 
40526
40637
  // src/tunnel/device-key.ts
40527
- var import_node_os12 = __toESM(require("os"), 1);
40638
+ var import_node_os13 = __toESM(require("os"), 1);
40528
40639
  var import_node_path26 = __toESM(require("path"), 1);
40529
40640
  var import_node_crypto8 = __toESM(require("crypto"), 1);
40530
40641
  var DERIVE_SALT = "clawd-tunnel-device-v1";
40531
40642
  function deriveStableDeviceKey(opts = {}) {
40532
- const hostname = opts.hostname ?? import_node_os12.default.hostname();
40533
- const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
40534
- const home = opts.home ?? import_node_os12.default.homedir();
40643
+ const hostname = opts.hostname ?? import_node_os13.default.hostname();
40644
+ const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
40645
+ const home = opts.home ?? import_node_os13.default.homedir();
40535
40646
  const defaultDataDir = import_node_path26.default.resolve(import_node_path26.default.join(home, ".clawd"));
40536
40647
  const normalizedDataDir = opts.dataDir ? import_node_path26.default.resolve(opts.dataDir) : null;
40537
40648
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
@@ -40608,11 +40719,11 @@ function writeAuthFile(file, content) {
40608
40719
 
40609
40720
  // src/owner-profile.ts
40610
40721
  var import_node_fs26 = __toESM(require("fs"), 1);
40611
- var import_node_os13 = __toESM(require("os"), 1);
40722
+ var import_node_os14 = __toESM(require("os"), 1);
40612
40723
  var import_node_path28 = __toESM(require("path"), 1);
40613
40724
  var PROFILE_FILENAME = "profile.json";
40614
40725
  function loadOwnerDisplayName(dataDir) {
40615
- const fallback = import_node_os13.default.userInfo().username;
40726
+ const fallback = import_node_os14.default.userInfo().username;
40616
40727
  const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
40617
40728
  let raw;
40618
40729
  try {
@@ -40997,7 +41108,7 @@ init_protocol();
40997
41108
 
40998
41109
  // src/session/fork.ts
40999
41110
  var import_node_fs28 = __toESM(require("fs"), 1);
41000
- var import_node_os14 = __toESM(require("os"), 1);
41111
+ var import_node_os15 = __toESM(require("os"), 1);
41001
41112
  var import_node_path30 = __toESM(require("path"), 1);
41002
41113
  init_claude_history();
41003
41114
  function readJsonlEntries(file) {
@@ -41014,7 +41125,7 @@ function readJsonlEntries(file) {
41014
41125
  return out;
41015
41126
  }
41016
41127
  function forkSession(input) {
41017
- const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".claude");
41128
+ const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os15.default.homedir(), ".claude");
41018
41129
  const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41019
41130
  const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41020
41131
  if (!import_node_fs28.default.existsSync(sourceFile)) {
@@ -41584,7 +41695,7 @@ function buildHistoryHandlers(deps) {
41584
41695
 
41585
41696
  // src/handlers/workspace.ts
41586
41697
  var path42 = __toESM(require("path"), 1);
41587
- var os15 = __toESM(require("os"), 1);
41698
+ var os16 = __toESM(require("os"), 1);
41588
41699
  init_protocol();
41589
41700
  init_protocol();
41590
41701
  function buildEnabledPluginNames(personaManager, personaId) {
@@ -41624,7 +41735,7 @@ function buildWorkspaceHandlers(deps) {
41624
41735
  const list = async (frame, _client, ctx) => {
41625
41736
  const args = WorkspaceListArgs.parse(frame);
41626
41737
  const isGuest = ctx?.principal.kind === "guest";
41627
- const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
41738
+ const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
41628
41739
  const resolvedCwd = path42.resolve(args.cwd ?? fallbackCwd);
41629
41740
  const target = args.path ? path42.resolve(resolvedCwd, args.path) : resolvedCwd;
41630
41741
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
@@ -42051,6 +42162,7 @@ function buildFeishuAuthHandlers(deps) {
42051
42162
  };
42052
42163
  const logout = async () => {
42053
42164
  deps.ownerIdentityStore.clear();
42165
+ deps.serverKeyStore.clear();
42054
42166
  return {
42055
42167
  response: { type: "auth:logout:ok" }
42056
42168
  };
@@ -42148,7 +42260,7 @@ function buildDeviceHandlers(deps) {
42148
42260
  }
42149
42261
 
42150
42262
  // src/handlers/meta.ts
42151
- var import_node_os15 = __toESM(require("os"), 1);
42263
+ var import_node_os16 = __toESM(require("os"), 1);
42152
42264
  init_protocol();
42153
42265
 
42154
42266
  // src/version.ts
@@ -42179,7 +42291,7 @@ function buildReadyFrame(deps, client) {
42179
42291
  return {
42180
42292
  version,
42181
42293
  protocolVersion: PROTOCOL_VERSION,
42182
- hostname: import_node_os15.default.hostname(),
42294
+ hostname: import_node_os16.default.hostname(),
42183
42295
  os: process.platform,
42184
42296
  tools,
42185
42297
  runningSessions: info.runningSessions,
@@ -42518,15 +42630,15 @@ function computePublishCheck(args) {
42518
42630
  // src/extension/install-flow.ts
42519
42631
  var import_promises5 = __toESM(require("fs/promises"), 1);
42520
42632
  var import_node_path35 = __toESM(require("path"), 1);
42521
- var import_node_os17 = __toESM(require("os"), 1);
42633
+ var import_node_os18 = __toESM(require("os"), 1);
42522
42634
  var import_node_crypto12 = __toESM(require("crypto"), 1);
42523
42635
  var import_jszip3 = __toESM(require_lib3(), 1);
42524
42636
 
42525
42637
  // src/extension/paths.ts
42526
- var import_node_os16 = __toESM(require("os"), 1);
42638
+ var import_node_os17 = __toESM(require("os"), 1);
42527
42639
  var import_node_path34 = __toESM(require("path"), 1);
42528
42640
  function clawdHomeRoot(override) {
42529
- return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os16.default.homedir(), ".clawd");
42641
+ return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os17.default.homedir(), ".clawd");
42530
42642
  }
42531
42643
  function extensionsRoot(override) {
42532
42644
  return import_node_path34.default.join(clawdHomeRoot(override), "extensions");
@@ -42608,7 +42720,7 @@ async function installFromChannel(args, deps) {
42608
42720
  );
42609
42721
  }
42610
42722
  const stage = await import_promises5.default.mkdtemp(
42611
- import_node_path35.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
42723
+ import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
42612
42724
  );
42613
42725
  try {
42614
42726
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -42639,7 +42751,7 @@ async function installFromChannel(args, deps) {
42639
42751
  // src/extension/update-flow.ts
42640
42752
  var import_promises6 = __toESM(require("fs/promises"), 1);
42641
42753
  var import_node_path36 = __toESM(require("path"), 1);
42642
- var import_node_os18 = __toESM(require("os"), 1);
42754
+ var import_node_os19 = __toESM(require("os"), 1);
42643
42755
  var import_node_crypto13 = __toESM(require("crypto"), 1);
42644
42756
  var import_jszip4 = __toESM(require_lib3(), 1);
42645
42757
  var UpdateError = class extends Error {
@@ -42727,7 +42839,7 @@ async function updateFromChannel(args, deps) {
42727
42839
  await import_promises6.default.rm(prevDir, { recursive: true, force: true });
42728
42840
  await import_promises6.default.rename(liveDir, prevDir);
42729
42841
  const stage = await import_promises6.default.mkdtemp(
42730
- import_node_path36.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
42842
+ import_node_path36.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
42731
42843
  );
42732
42844
  try {
42733
42845
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -45284,6 +45396,7 @@ async function startDaemon(config) {
45284
45396
  logger.warn("persona.seed.skip", { reason: "defaults-root-not-found" });
45285
45397
  }
45286
45398
  migrateAgentsMirror({ store: personaStore, logger });
45399
+ migrateCodexSandbox({ store: personaStore, logger });
45287
45400
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
45288
45401
  const manager = new SessionManager({
45289
45402
  store,
@@ -45434,15 +45547,14 @@ async function startDaemon(config) {
45434
45547
  };
45435
45548
  const fetchServerKey = async () => {
45436
45549
  if (!feishuActive) return;
45437
- if (serverKeyStore.read()) return;
45438
45550
  try {
45439
45551
  const { publicKeyPem } = await centralGetPublicKey({
45440
45552
  api: config.clawosApi ?? DEFAULT_CLAWOS_API
45441
45553
  });
45442
45554
  serverKeyStore.write(publicKeyPem);
45443
- logger.info("server signing key cached");
45555
+ logger.info("server signing key refreshed");
45444
45556
  } catch (err) {
45445
- logger.warn("server signing key fetch failed (guest \u5165\u7AD9\u5C06\u88AB\u62D2\u7EDD)", {
45557
+ logger.warn("server signing key fetch failed (\u4FDD\u7559\u65E7\u7F13\u5B58)", {
45446
45558
  err: err.message
45447
45559
  });
45448
45560
  }
@@ -45548,7 +45660,7 @@ async function startDaemon(config) {
45548
45660
  bundleCache,
45549
45661
  // 飞书统一身份 Phase 1:登录 RPC handlers(auth:login:start / getIdentity / logout)
45550
45662
  // deviceId(决策 #15):getIdentity 返回给 UI 拼"我的设备标识"
45551
- feishuAuth: { loginFlow, ownerIdentityStore, deviceId: authFile.deviceId },
45663
+ feishuAuth: { loginFlow, ownerIdentityStore, deviceId: authFile.deviceId, serverKeyStore },
45552
45664
  // 设备目录 + 连接(决策 #15:daemon 代理中心 server)。
45553
45665
  // exchange/listDevices 包掉 owner ttcJwt(每次现读 store——热切换后立即用新身份);
45554
45666
  // dispatcher 的 FEISHU_GATED_METHODS gate 已保证未登录时这些 RPC 到不了 handler,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.135-beta.281.fb1ead2",
3
+ "version": "0.2.135-beta.282.8ee36dc",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",