@clawos-dev/clawd 0.2.143-beta.304.b7f17df → 0.2.143-beta.306.9c50054

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
@@ -8435,7 +8435,7 @@ var require_transport = __commonJS({
8435
8435
  "use strict";
8436
8436
  var { createRequire } = require("module");
8437
8437
  var getCallers = require_caller();
8438
- var { join: join15, isAbsolute: isAbsolute2, sep: sep2 } = require("path");
8438
+ var { join: join15, isAbsolute: isAbsolute2, sep: sep3 } = require("path");
8439
8439
  var sleep2 = require_atomic_sleep();
8440
8440
  var onExit = require_on_exit_leak_free();
8441
8441
  var ThreadStream = require_thread_stream();
@@ -8543,7 +8543,7 @@ var require_transport = __commonJS({
8543
8543
  let fixTarget2;
8544
8544
  for (const filePath of callers) {
8545
8545
  try {
8546
- const context = filePath === "node:repl" ? process.cwd() + sep2 : filePath;
8546
+ const context = filePath === "node:repl" ? process.cwd() + sep3 : filePath;
8547
8547
  fixTarget2 = createRequire(context).resolve(origin);
8548
8548
  break;
8549
8549
  } catch (err) {
@@ -11406,12 +11406,12 @@ function readCurrentContent(filePath) {
11406
11406
  return null;
11407
11407
  }
11408
11408
  }
11409
- 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;
11409
+ var import_node_fs8, import_node_os5, 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;
11410
11410
  var init_claude_history = __esm({
11411
11411
  "src/tools/claude-history.ts"() {
11412
11412
  "use strict";
11413
11413
  import_node_fs8 = __toESM(require("fs"), 1);
11414
- import_node_os4 = __toESM(require("os"), 1);
11414
+ import_node_os5 = __toESM(require("os"), 1);
11415
11415
  import_node_path8 = __toESM(require("path"), 1);
11416
11416
  init_lib();
11417
11417
  init_tool_result_extra();
@@ -11436,7 +11436,7 @@ var init_claude_history = __esm({
11436
11436
  // 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
11437
11437
  fileHistoryRoot;
11438
11438
  constructor(opts = {}) {
11439
- const base = opts.baseDir ?? import_node_path8.default.join(import_node_os4.default.homedir(), ".claude");
11439
+ const base = opts.baseDir ?? import_node_path8.default.join(import_node_os5.default.homedir(), ".claude");
11440
11440
  this.projectsRoot = import_node_path8.default.join(base, "projects");
11441
11441
  this.fileHistoryRoot = import_node_path8.default.join(base, "file-history");
11442
11442
  }
@@ -30901,7 +30901,7 @@ var init_wire = __esm({
30901
30901
  // src/run-case/controller.ts
30902
30902
  async function runController(opts) {
30903
30903
  const now = opts.now ?? Date.now;
30904
- const cwd = opts.cwd ?? (0, import_node_fs36.mkdtempSync)(import_node_path48.default.join(import_node_os20.default.tmpdir(), "clawd-runcase-"));
30904
+ const cwd = opts.cwd ?? (0, import_node_fs36.mkdtempSync)(import_node_path48.default.join(import_node_os21.default.tmpdir(), "clawd-runcase-"));
30905
30905
  const ownsCwd = opts.cwd === void 0;
30906
30906
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
30907
30907
  const spawnCtx = { cwd };
@@ -31068,12 +31068,12 @@ async function runController(opts) {
31068
31068
  }
31069
31069
  return exitCode ?? 0;
31070
31070
  }
31071
- var import_node_fs36, import_node_os20, import_node_path48;
31071
+ var import_node_fs36, import_node_os21, import_node_path48;
31072
31072
  var init_controller = __esm({
31073
31073
  "src/run-case/controller.ts"() {
31074
31074
  "use strict";
31075
31075
  import_node_fs36 = require("fs");
31076
- import_node_os20 = __toESM(require("os"), 1);
31076
+ import_node_os21 = __toESM(require("os"), 1);
31077
31077
  import_node_path48 = __toESM(require("path"), 1);
31078
31078
  init_claude();
31079
31079
  init_stdout_splitter();
@@ -31338,7 +31338,7 @@ Env (advanced):
31338
31338
  // src/index.ts
31339
31339
  var import_node_path46 = __toESM(require("path"), 1);
31340
31340
  var import_node_fs34 = __toESM(require("fs"), 1);
31341
- var import_node_os19 = __toESM(require("os"), 1);
31341
+ var import_node_os20 = __toESM(require("os"), 1);
31342
31342
 
31343
31343
  // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
31344
31344
  var byteToHex = [];
@@ -31946,12 +31946,17 @@ var SessionStoreFactory = class {
31946
31946
  // src/session/manager.ts
31947
31947
  var import_node_fs6 = __toESM(require("fs"), 1);
31948
31948
  var import_node_path6 = __toESM(require("path"), 1);
31949
- var import_node_os2 = __toESM(require("os"), 1);
31949
+ var import_node_os3 = __toESM(require("os"), 1);
31950
31950
  init_protocol();
31951
31951
 
31952
31952
  // src/tools/guest-settings.ts
31953
+ var import_node_os2 = require("os");
31953
31954
  var FORCED_DENY_READ = ["~/"];
31954
- var FORCED_TOOL_DENY = ["Edit(./**)"];
31955
+ function personaEditDeny(personaDir) {
31956
+ const home = (0, import_node_os2.homedir)();
31957
+ const rel = personaDir.startsWith(`${home}/`) ? `~${personaDir.slice(home.length)}` : personaDir;
31958
+ return `Edit(${rel}/**)`;
31959
+ }
31955
31960
  function unionArr(a, b2) {
31956
31961
  const out = [...a ?? []];
31957
31962
  for (const x of b2) if (!out.includes(x)) out.push(x);
@@ -31965,9 +31970,9 @@ function isGuestSettingsLike(v2) {
31965
31970
  function buildGuestSettingsV1() {
31966
31971
  return {
31967
31972
  permissions: {
31968
- defaultMode: "dontAsk",
31969
- deny: [...FORCED_TOOL_DENY]
31970
- // 保留 persona 限制:挡 CC 工具改/读 persona(cwd=persona)
31973
+ defaultMode: "dontAsk"
31974
+ // persona-dir 的 Edit deny 由 composeGuestSandbox 按 spawnCwd 注入 '~/<persona>/**' 绝对规则
31975
+ // (base 不放相对 './'——会随 getCwd 漂移误拦项目,见 personaEditDeny)。
31971
31976
  },
31972
31977
  sandbox: {
31973
31978
  enabled: true,
@@ -32015,7 +32020,6 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
32015
32020
  s.sandbox.allowUnsandboxedCommands = false;
32016
32021
  fsv.denyRead = unionArr(fsv.denyRead, FORCED_DENY_READ);
32017
32022
  fsv.denyWrite = unionArr((fsv.denyWrite ?? []).filter((p2) => p2 !== "~/"), [spawnCwd]);
32018
- s.permissions.deny = unionArr(s.permissions.deny, FORCED_TOOL_DENY);
32019
32023
  fsv.allowRead = unionArr(fsv.allowRead, [userWorkDir]);
32020
32024
  fsv.allowWrite = unionArr(fsv.allowWrite, [userWorkDir]);
32021
32025
  return s;
@@ -33694,7 +33698,7 @@ var SessionManager = class {
33694
33698
  const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
33695
33699
  const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
33696
33700
  subSessionMeta.extraSettings = JSON.stringify(settings);
33697
- const home = import_node_os2.default.homedir();
33701
+ const home = import_node_os3.default.homedir();
33698
33702
  const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path6.default.join(home, p2.slice(2)) : p2;
33699
33703
  const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
33700
33704
  subSessionMeta.codexSandbox = {
@@ -34968,10 +34972,10 @@ var PersonaStore = class {
34968
34972
  return path9.join(this.personaDir(personaId), "AGENTS.md");
34969
34973
  }
34970
34974
  /**
34971
- * persona 级 sandbox 模板落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
34975
+ * persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
34972
34976
  * source 自动发现扫不到(owner `--setting-sources user,project,local` 不会顺手带进来)。
34973
- * 这份是 **UI 展示用模板**(readSandboxSettings);guest 真正加载的沙箱文件由 manager
34974
- * spawn 前 per-guest 动态拼到各自 session 目录(含本 guest userWorkDir carve),不是这份。
34977
+ * 这份是 guest 沙箱的 **base 真源**(manager compose 读它当 base);guest 实际加载的是 manager
34978
+ * spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
34975
34979
  */
34976
34980
  sandboxSettingsPath(personaId) {
34977
34981
  return path9.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
@@ -34981,10 +34985,7 @@ var PersonaStore = class {
34981
34985
  fs7.mkdirSync(path9.join(dir, ".clawd"), { recursive: true });
34982
34986
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
34983
34987
  this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
34984
- this.atomicWrite(
34985
- this.sandboxSettingsPath(persona.personaId),
34986
- JSON.stringify(buildGuestSettingsV1(), null, 2)
34987
- );
34988
+ this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
34988
34989
  this.atomicWrite(this.metaPath(persona.personaId), JSON.stringify(persona, null, 2));
34989
34990
  }
34990
34991
  writePersonality(personaId, personality) {
@@ -35007,15 +35008,24 @@ var PersonaStore = class {
35007
35008
  }
35008
35009
  /**
35009
35010
  * 覆盖式写 persona 级 sandbox 配置(seed 给有 profile 的 persona 写 base⊕profile;owner 之后可手编)。
35010
- * 这份是 guest 沙箱的 **base 真源**:manager spawn 时 composeGuestSandbox 读它 + 叠强制底座
35011
- * (enabled/denyRead/persona-deny owner 削弱不了)+ 注入本 guest userWorkDir → 写 per-guest 文件给 CC。
35011
+ * 这份是 guest 沙箱的 **base 真源**:manager spawn 时 composeGuestSandbox 读它 + 叠 sandbox 强制底座
35012
+ * (enabled/denyRead/denyWrite/userWorkDir owner 削弱不了)→ 写 per-guest 文件给 CC。
35013
+ * 写入时强制注入本 persona 的 Edit-deny('~/<persona>/**' 按实际 persona dir 算)+ 剥掉历史相对 'Edit(./**)',
35014
+ * 让落盘 base 就是 source of truth(compose 不再运行时替换 permission deny)。
35012
35015
  */
35013
35016
  writeSandboxSettings(personaId, settings) {
35014
35017
  this.atomicWrite(
35015
35018
  this.sandboxSettingsPath(personaId),
35016
- JSON.stringify(settings, null, 2)
35019
+ JSON.stringify(this.injectPersonaEditDeny(personaId, settings), null, 2)
35017
35020
  );
35018
35021
  }
35022
+ /** 把 persona Edit-deny(绝对 '~/<persona>/**')并进 settings.permissions.deny,剥掉历史相对 'Edit(./**)'。 */
35023
+ injectPersonaEditDeny(personaId, settings) {
35024
+ const s = settings;
35025
+ const rule = personaEditDeny(this.personaDir(personaId));
35026
+ const prev = (s.permissions?.deny ?? []).filter((r) => r !== "Edit(./**)" && r !== rule);
35027
+ return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
35028
+ }
35019
35029
  codexSandboxSettingsPath(personaId) {
35020
35030
  return path9.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
35021
35031
  }
@@ -35174,7 +35184,7 @@ var import_node_crypto3 = __toESM(require("crypto"), 1);
35174
35184
 
35175
35185
  // src/skills/scanner.ts
35176
35186
  var import_node_fs7 = __toESM(require("fs"), 1);
35177
- var import_node_os3 = __toESM(require("os"), 1);
35187
+ var import_node_os4 = __toESM(require("os"), 1);
35178
35188
  var import_node_path7 = __toESM(require("path"), 1);
35179
35189
 
35180
35190
  // src/skills/frontmatter.ts
@@ -35408,7 +35418,7 @@ var SkillsScanner = class {
35408
35418
  home;
35409
35419
  extraPluginRoots;
35410
35420
  constructor(opts = {}) {
35411
- this.home = opts.home ?? import_node_os3.default.homedir();
35421
+ this.home = opts.home ?? import_node_os4.default.homedir();
35412
35422
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
35413
35423
  }
35414
35424
  /**
@@ -35595,8 +35605,7 @@ var DEFAULT_PERSONAS = [
35595
35605
  // defaultMode bypassPermissions:开发流频繁用工具,免逐次审批;deny 规则仍生效、OS 沙箱照管(已验证)。
35596
35606
  permissions: {
35597
35607
  defaultMode: "bypassPermissions",
35598
- allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"],
35599
- deny: ["Read(./.secrets/**)"]
35608
+ allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"]
35600
35609
  },
35601
35610
  sandbox: {
35602
35611
  filesystem: {
@@ -35631,12 +35640,12 @@ var DEFAULT_PERSONAS = [
35631
35640
  iconKey: "assist",
35632
35641
  public: false,
35633
35642
  // 同 app-builder 的开发型 profile(逐字段照抄):web 工具 + node/pnpm 工具链精确路径
35634
- // + 出站 TLD 通配白名单 + .secrets deny。复用同一条流水线 → 同一套沙箱授权。
35643
+ // + 出站 TLD 通配白名单。复用同一条流水线 → 同一套沙箱授权。
35644
+ // 注:不带 .secrets deny —— dataclaw-builder 的 apikey 走生成 app 的 server/.env,persona .secrets 已清空。
35635
35645
  sandboxProfile: {
35636
35646
  permissions: {
35637
35647
  defaultMode: "bypassPermissions",
35638
- allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"],
35639
- deny: ["Read(./.secrets/**)"]
35648
+ allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"]
35640
35649
  },
35641
35650
  sandbox: {
35642
35651
  filesystem: {
@@ -35740,13 +35749,16 @@ function seedDefaultPersonas(args) {
35740
35749
  args.logger.info("persona.seed.created", { personaId: entry.personaId });
35741
35750
  }
35742
35751
  }
35752
+ function skipNodeModules(src) {
35753
+ return !src.split(path11.sep).includes("node_modules");
35754
+ }
35743
35755
  function copyBundleExtras(srcDir, dstDir) {
35744
35756
  for (const entry of fs9.readdirSync(srcDir, { withFileTypes: true })) {
35745
35757
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
35746
35758
  const srcPath = path11.join(srcDir, entry.name);
35747
35759
  const dstPath = path11.join(dstDir, entry.name);
35748
35760
  if (entry.isDirectory()) {
35749
- fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true });
35761
+ fs9.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModules });
35750
35762
  } else if (entry.isFile()) {
35751
35763
  fs9.copyFileSync(srcPath, dstPath);
35752
35764
  }
@@ -35765,7 +35777,7 @@ function refreshDaemonManagedDirs(args) {
35765
35777
  if (!fs9.existsSync(srcPath)) continue;
35766
35778
  const dstPath = path11.join(personaDir, relPath);
35767
35779
  try {
35768
- fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true });
35780
+ fs9.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModules });
35769
35781
  args.logger.info("persona.refresh.synced", {
35770
35782
  personaId: entry.personaId,
35771
35783
  path: relPath
@@ -35780,6 +35792,15 @@ function refreshDaemonManagedDirs(args) {
35780
35792
  }
35781
35793
  }
35782
35794
  }
35795
+ function refreshSandboxSettings(args) {
35796
+ const entries = args.entries ?? DEFAULT_PERSONAS;
35797
+ for (const entry of entries) {
35798
+ if (!args.store.has(entry.personaId)) continue;
35799
+ const settings = entry.sandboxProfile ? applyProfile(buildGuestSettingsV1(), entry.sandboxProfile) : buildGuestSettingsV1();
35800
+ args.store.writeSandboxSettings(entry.personaId, settings);
35801
+ args.logger.info("persona.sandbox.refreshed", { personaId: entry.personaId });
35802
+ }
35803
+ }
35783
35804
  function migrateAgentsMirror(args) {
35784
35805
  let mirrored = 0;
35785
35806
  for (const personaId of args.store.list()) {
@@ -36351,7 +36372,7 @@ var CodexAdapter = class {
36351
36372
 
36352
36373
  // src/tools/claude-tui.ts
36353
36374
  var import_node_fs11 = __toESM(require("fs"), 1);
36354
- var import_node_os5 = __toESM(require("os"), 1);
36375
+ var import_node_os6 = __toESM(require("os"), 1);
36355
36376
  var import_node_path9 = __toESM(require("path"), 1);
36356
36377
  var import_headless = __toESM(require_xterm_headless(), 1);
36357
36378
 
@@ -37353,7 +37374,7 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
37353
37374
  }
37354
37375
  function jsonlExistsForCtx(ctx) {
37355
37376
  if (!ctx.toolSessionId) return false;
37356
- const home = import_node_os5.default.homedir();
37377
+ const home = import_node_os6.default.homedir();
37357
37378
  const file = import_node_path9.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
37358
37379
  try {
37359
37380
  return import_node_fs11.default.statSync(file).isFile();
@@ -37746,7 +37767,7 @@ async function listCodexSkills(cwd, deps = {}) {
37746
37767
 
37747
37768
  // src/workspace/browser.ts
37748
37769
  var import_node_fs13 = __toESM(require("fs"), 1);
37749
- var import_node_os6 = __toESM(require("os"), 1);
37770
+ var import_node_os7 = __toESM(require("os"), 1);
37750
37771
  var import_node_path11 = __toESM(require("path"), 1);
37751
37772
  init_protocol();
37752
37773
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
@@ -37772,7 +37793,7 @@ function ensureCwd(cwd) {
37772
37793
  }
37773
37794
  var WorkspaceBrowser = class {
37774
37795
  list(args) {
37775
- const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
37796
+ const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os7.default.homedir();
37776
37797
  ensureCwd(cwd);
37777
37798
  const full = resolveInsideCwd(cwd, args.path);
37778
37799
  const dirents = import_node_fs13.default.readdirSync(full, { withFileTypes: true });
@@ -37831,7 +37852,7 @@ var WorkspaceBrowser = class {
37831
37852
 
37832
37853
  // src/skills/agents-scanner.ts
37833
37854
  var import_node_fs14 = __toESM(require("fs"), 1);
37834
- var import_node_os7 = __toESM(require("os"), 1);
37855
+ var import_node_os8 = __toESM(require("os"), 1);
37835
37856
  var import_node_path12 = __toESM(require("path"), 1);
37836
37857
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
37837
37858
  function isDirLikeSync2(p2) {
@@ -37974,7 +37995,7 @@ var AgentsScanner = class {
37974
37995
  extraPluginRoots;
37975
37996
  policyDir;
37976
37997
  constructor(opts = {}) {
37977
- this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os7.default.homedir();
37998
+ this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os8.default.homedir();
37978
37999
  this.extraPluginRoots = opts.extraPluginRoots ?? [];
37979
38000
  if (opts.policyDir !== void 0) {
37980
38001
  this.policyDir = opts.policyDir;
@@ -38022,20 +38043,20 @@ var AgentsScanner = class {
38022
38043
 
38023
38044
  // src/observer/session-observer.ts
38024
38045
  var import_node_fs16 = __toESM(require("fs"), 1);
38025
- var import_node_os9 = __toESM(require("os"), 1);
38046
+ var import_node_os10 = __toESM(require("os"), 1);
38026
38047
  var import_node_path14 = __toESM(require("path"), 1);
38027
38048
  init_claude_history();
38028
38049
 
38029
38050
  // src/observer/subagent-meta-observer.ts
38030
38051
  var import_node_fs15 = __toESM(require("fs"), 1);
38031
- var import_node_os8 = __toESM(require("os"), 1);
38052
+ var import_node_os9 = __toESM(require("os"), 1);
38032
38053
  var import_node_path13 = __toESM(require("path"), 1);
38033
38054
  init_claude_history();
38034
38055
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
38035
38056
  var SubagentMetaObserver = class {
38036
38057
  constructor(opts) {
38037
38058
  this.opts = opts;
38038
- this.home = opts.home ?? import_node_os8.default.homedir();
38059
+ this.home = opts.home ?? import_node_os9.default.homedir();
38039
38060
  }
38040
38061
  opts;
38041
38062
  home;
@@ -38146,7 +38167,7 @@ var SubagentMetaObserver = class {
38146
38167
  var SessionObserver = class {
38147
38168
  constructor(opts) {
38148
38169
  this.opts = opts;
38149
- this.home = opts.home ?? import_node_os9.default.homedir();
38170
+ this.home = opts.home ?? import_node_os10.default.homedir();
38150
38171
  this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
38151
38172
  }
38152
38173
  opts;
@@ -39953,7 +39974,7 @@ async function writeUploadedAttachment(args) {
39953
39974
  // src/extension/import.ts
39954
39975
  var import_promises2 = __toESM(require("fs/promises"), 1);
39955
39976
  var import_node_path17 = __toESM(require("path"), 1);
39956
- var import_node_os10 = __toESM(require("os"), 1);
39977
+ var import_node_os11 = __toESM(require("os"), 1);
39957
39978
  var import_jszip = __toESM(require_lib3(), 1);
39958
39979
  var ImportError = class extends Error {
39959
39980
  constructor(code, message) {
@@ -40013,7 +40034,7 @@ async function importZip(buf, root) {
40013
40034
  if (destExists) {
40014
40035
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
40015
40036
  }
40016
- const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
40037
+ const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os11.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
40017
40038
  try {
40018
40039
  for (const [name, entry] of Object.entries(zip.files)) {
40019
40040
  const dest = import_node_path17.default.join(stage, name);
@@ -40910,7 +40931,7 @@ function escape(v2) {
40910
40931
 
40911
40932
  // src/tunnel/frpc-binary.ts
40912
40933
  var import_node_fs23 = __toESM(require("fs"), 1);
40913
- var import_node_os11 = __toESM(require("os"), 1);
40934
+ var import_node_os12 = __toESM(require("os"), 1);
40914
40935
  var import_node_path23 = __toESM(require("path"), 1);
40915
40936
  var import_node_child_process7 = require("child_process");
40916
40937
  var import_node_stream3 = require("stream");
@@ -41371,14 +41392,14 @@ async function waitForFrpcReady(proc, timeoutMs) {
41371
41392
  }
41372
41393
 
41373
41394
  // src/tunnel/device-key.ts
41374
- var import_node_os12 = __toESM(require("os"), 1);
41395
+ var import_node_os13 = __toESM(require("os"), 1);
41375
41396
  var import_node_path26 = __toESM(require("path"), 1);
41376
41397
  var import_node_crypto8 = __toESM(require("crypto"), 1);
41377
41398
  var DERIVE_SALT = "clawd-tunnel-device-v1";
41378
41399
  function deriveStableDeviceKey(opts = {}) {
41379
- const hostname = opts.hostname ?? import_node_os12.default.hostname();
41380
- const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
41381
- const home = opts.home ?? import_node_os12.default.homedir();
41400
+ const hostname = opts.hostname ?? import_node_os13.default.hostname();
41401
+ const uid = opts.uid ?? (typeof import_node_os13.default.userInfo === "function" ? import_node_os13.default.userInfo().uid : 0);
41402
+ const home = opts.home ?? import_node_os13.default.homedir();
41382
41403
  const defaultDataDir = import_node_path26.default.resolve(import_node_path26.default.join(home, ".clawd"));
41383
41404
  const normalizedDataDir = opts.dataDir ? import_node_path26.default.resolve(opts.dataDir) : null;
41384
41405
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
@@ -41455,11 +41476,11 @@ function writeAuthFile(file, content) {
41455
41476
 
41456
41477
  // src/owner-profile.ts
41457
41478
  var import_node_fs27 = __toESM(require("fs"), 1);
41458
- var import_node_os13 = __toESM(require("os"), 1);
41479
+ var import_node_os14 = __toESM(require("os"), 1);
41459
41480
  var import_node_path28 = __toESM(require("path"), 1);
41460
41481
  var PROFILE_FILENAME = "profile.json";
41461
41482
  function loadOwnerDisplayName(dataDir) {
41462
- const fallback = import_node_os13.default.userInfo().username;
41483
+ const fallback = import_node_os14.default.userInfo().username;
41463
41484
  const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
41464
41485
  let raw;
41465
41486
  try {
@@ -41847,7 +41868,7 @@ init_protocol();
41847
41868
 
41848
41869
  // src/session/fork.ts
41849
41870
  var import_node_fs29 = __toESM(require("fs"), 1);
41850
- var import_node_os14 = __toESM(require("os"), 1);
41871
+ var import_node_os15 = __toESM(require("os"), 1);
41851
41872
  var import_node_path30 = __toESM(require("path"), 1);
41852
41873
  init_claude_history();
41853
41874
  function readJsonlEntries(file) {
@@ -41864,7 +41885,7 @@ function readJsonlEntries(file) {
41864
41885
  return out;
41865
41886
  }
41866
41887
  function forkSession(input) {
41867
- const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".claude");
41888
+ const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os15.default.homedir(), ".claude");
41868
41889
  const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41869
41890
  const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41870
41891
  if (!import_node_fs29.default.existsSync(sourceFile)) {
@@ -42313,8 +42334,8 @@ function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userW
42313
42334
  if (target === u || target.startsWith(u + usep)) return true;
42314
42335
  }
42315
42336
  const root = path40.resolve(personaRoot);
42316
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
42317
- if (!target.startsWith(root + sep2)) return false;
42337
+ const sep3 = root.endsWith(path40.sep) ? "" : path40.sep;
42338
+ if (!target.startsWith(root + sep3)) return false;
42318
42339
  const rel = path40.relative(root, target);
42319
42340
  if (!rel || rel.startsWith("..")) return false;
42320
42341
  const personaId = rel.split(path40.sep)[0];
@@ -42326,8 +42347,8 @@ function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userW
42326
42347
  function personaIdFromPath(absPath, personaRoot) {
42327
42348
  const root = path40.resolve(personaRoot);
42328
42349
  const target = path40.resolve(absPath);
42329
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
42330
- if (!target.startsWith(root + sep2)) return null;
42350
+ const sep3 = root.endsWith(path40.sep) ? "" : path40.sep;
42351
+ if (!target.startsWith(root + sep3)) return null;
42331
42352
  const rel = path40.relative(root, target);
42332
42353
  if (!rel || rel.startsWith("..")) return null;
42333
42354
  const id = rel.split(path40.sep)[0];
@@ -42999,7 +43020,7 @@ function buildDeviceHandlers(deps) {
42999
43020
  }
43000
43021
 
43001
43022
  // src/handlers/meta.ts
43002
- var import_node_os15 = __toESM(require("os"), 1);
43023
+ var import_node_os16 = __toESM(require("os"), 1);
43003
43024
  init_protocol();
43004
43025
 
43005
43026
  // src/version.ts
@@ -43031,7 +43052,7 @@ function buildReadyFrame(deps, client) {
43031
43052
  return {
43032
43053
  version,
43033
43054
  protocolVersion: PROTOCOL_VERSION,
43034
- hostname: import_node_os15.default.hostname(),
43055
+ hostname: import_node_os16.default.hostname(),
43035
43056
  os: process.platform,
43036
43057
  tools,
43037
43058
  runningSessions: info.runningSessions,
@@ -43371,15 +43392,15 @@ function computePublishCheck(args) {
43371
43392
  // src/extension/install-flow.ts
43372
43393
  var import_promises5 = __toESM(require("fs/promises"), 1);
43373
43394
  var import_node_path35 = __toESM(require("path"), 1);
43374
- var import_node_os17 = __toESM(require("os"), 1);
43395
+ var import_node_os18 = __toESM(require("os"), 1);
43375
43396
  var import_node_crypto12 = __toESM(require("crypto"), 1);
43376
43397
  var import_jszip3 = __toESM(require_lib3(), 1);
43377
43398
 
43378
43399
  // src/extension/paths.ts
43379
- var import_node_os16 = __toESM(require("os"), 1);
43400
+ var import_node_os17 = __toESM(require("os"), 1);
43380
43401
  var import_node_path34 = __toESM(require("path"), 1);
43381
43402
  function clawdHomeRoot(override) {
43382
- return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os16.default.homedir(), ".clawd");
43403
+ return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os17.default.homedir(), ".clawd");
43383
43404
  }
43384
43405
  function extensionsRoot(override) {
43385
43406
  return import_node_path34.default.join(clawdHomeRoot(override), "extensions");
@@ -43461,7 +43482,7 @@ async function installFromChannel(args, deps) {
43461
43482
  );
43462
43483
  }
43463
43484
  const stage = await import_promises5.default.mkdtemp(
43464
- import_node_path35.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
43485
+ import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
43465
43486
  );
43466
43487
  try {
43467
43488
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -43492,7 +43513,7 @@ async function installFromChannel(args, deps) {
43492
43513
  // src/extension/update-flow.ts
43493
43514
  var import_promises6 = __toESM(require("fs/promises"), 1);
43494
43515
  var import_node_path36 = __toESM(require("path"), 1);
43495
- var import_node_os18 = __toESM(require("os"), 1);
43516
+ var import_node_os19 = __toESM(require("os"), 1);
43496
43517
  var import_node_crypto13 = __toESM(require("crypto"), 1);
43497
43518
  var import_jszip4 = __toESM(require_lib3(), 1);
43498
43519
  var UpdateError = class extends Error {
@@ -43580,7 +43601,7 @@ async function updateFromChannel(args, deps) {
43580
43601
  await import_promises6.default.rm(prevDir, { recursive: true, force: true });
43581
43602
  await import_promises6.default.rename(liveDir, prevDir);
43582
43603
  const stage = await import_promises6.default.mkdtemp(
43583
- import_node_path36.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
43604
+ import_node_path36.default.join(import_node_os19.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
43584
43605
  );
43585
43606
  try {
43586
43607
  for (const [name, entry] of Object.entries(zip.files)) {
@@ -46007,7 +46028,7 @@ async function startDaemon(config) {
46007
46028
  },
46008
46029
  source: "daemon",
46009
46030
  sampling: logShippingCfg.sampling,
46010
- homeDir: import_node_os19.default.homedir()
46031
+ homeDir: import_node_os20.default.homedir()
46011
46032
  });
46012
46033
  const logger = createLogger({
46013
46034
  level: config.logLevel,
@@ -46163,6 +46184,7 @@ async function startDaemon(config) {
46163
46184
  } else {
46164
46185
  logger.warn("deploy-kit.bundle-missing", {});
46165
46186
  }
46187
+ refreshSandboxSettings({ store: personaStore, logger });
46166
46188
  migrateAgentsMirror({ store: personaStore, logger });
46167
46189
  migrateCodexSandbox({ store: personaStore, logger });
46168
46190
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
@@ -46559,7 +46581,7 @@ async function startDaemon(config) {
46559
46581
  throw new Error(`personaDispatch:run source session not found: ${args.sourceSessionId}`);
46560
46582
  }
46561
46583
  const sourceJsonlPath = sourceFile.toolSessionId ? import_node_path46.default.join(
46562
- import_node_os19.default.homedir(),
46584
+ import_node_os20.default.homedir(),
46563
46585
  ".claude",
46564
46586
  "projects",
46565
46587
  cwdToHashDir(sourceFile.cwd),
@@ -18,5 +18,9 @@ DEST="${3:?缺目标目录}"
18
18
  remaining="$(find "$DEST" -mindepth 1 -maxdepth 1 ! -name '.clawd-project.json' -print -quit)"
19
19
  [ -z "$remaining" ] || { echo "❌ 目标已有内容(非空目录): $DEST" >&2; exit 1; }
20
20
 
21
- cp -R "$SRC/." "$DEST/"
21
+ # 排除 node_modules:模板可能被 install 过,pnpm 的 node_modules 里有指向**模板绝对路径**的软链
22
+ # (tslib 等传递依赖)。cp 到新项目后这些软链 dangling(仍指模板原始路径);而 pnpm install 见
23
+ # node_modules 已在 + lockfile 没变会直接 skip、不重建软链 → 运行/打包时 Cannot find module。
24
+ # 新项目本来就要 install,故 scaffold 一律不拷 node_modules(保留 lockfile 以锁版本)。
25
+ rsync -a --exclude='node_modules' "$SRC/" "$DEST/"
22
26
  echo "✅ 新 extension: $DEST"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.143-beta.304.b7f17df",
3
+ "version": "0.2.143-beta.306.9c50054",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",