@clawos-dev/clawd 0.2.94 → 0.2.95

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 +110 -105
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -652,8 +652,8 @@ var init_parseUtil = __esm({
652
652
  init_errors2();
653
653
  init_en();
654
654
  makeIssue = (params) => {
655
- const { data, path: path47, errorMaps, issueData } = params;
656
- const fullPath = [...path47, ...issueData.path || []];
655
+ const { data, path: path48, errorMaps, issueData } = params;
656
+ const fullPath = [...path48, ...issueData.path || []];
657
657
  const fullIssue = {
658
658
  ...issueData,
659
659
  path: fullPath
@@ -964,11 +964,11 @@ var init_types = __esm({
964
964
  init_parseUtil();
965
965
  init_util();
966
966
  ParseInputLazyPath = class {
967
- constructor(parent, value, path47, key) {
967
+ constructor(parent, value, path48, key) {
968
968
  this._cachedPath = [];
969
969
  this.parent = parent;
970
970
  this.data = value;
971
- this._path = path47;
971
+ this._path = path48;
972
972
  this._key = key;
973
973
  }
974
974
  get path() {
@@ -5636,8 +5636,8 @@ var require_req = __commonJS({
5636
5636
  if (req.originalUrl) {
5637
5637
  _req.url = req.originalUrl;
5638
5638
  } else {
5639
- const path47 = req.path;
5640
- _req.url = typeof path47 === "string" ? path47 : req.url ? req.url.path || req.url : void 0;
5639
+ const path48 = req.path;
5640
+ _req.url = typeof path48 === "string" ? path48 : req.url ? req.url.path || req.url : void 0;
5641
5641
  }
5642
5642
  if (req.query) {
5643
5643
  _req.query = req.query;
@@ -5802,14 +5802,14 @@ var require_redact = __commonJS({
5802
5802
  }
5803
5803
  return obj;
5804
5804
  }
5805
- function parsePath(path47) {
5805
+ function parsePath(path48) {
5806
5806
  const parts = [];
5807
5807
  let current = "";
5808
5808
  let inBrackets = false;
5809
5809
  let inQuotes = false;
5810
5810
  let quoteChar = "";
5811
- for (let i = 0; i < path47.length; i++) {
5812
- const char = path47[i];
5811
+ for (let i = 0; i < path48.length; i++) {
5812
+ const char = path48[i];
5813
5813
  if (!inBrackets && char === ".") {
5814
5814
  if (current) {
5815
5815
  parts.push(current);
@@ -5940,10 +5940,10 @@ var require_redact = __commonJS({
5940
5940
  return current;
5941
5941
  }
5942
5942
  function redactPaths(obj, paths, censor, remove = false) {
5943
- for (const path47 of paths) {
5944
- const parts = parsePath(path47);
5943
+ for (const path48 of paths) {
5944
+ const parts = parsePath(path48);
5945
5945
  if (parts.includes("*")) {
5946
- redactWildcardPath(obj, parts, censor, path47, remove);
5946
+ redactWildcardPath(obj, parts, censor, path48, remove);
5947
5947
  } else {
5948
5948
  if (remove) {
5949
5949
  removeKey(obj, parts);
@@ -6028,8 +6028,8 @@ var require_redact = __commonJS({
6028
6028
  }
6029
6029
  } else {
6030
6030
  if (afterWildcard.includes("*")) {
6031
- const wrappedCensor = typeof censor === "function" ? (value, path47) => {
6032
- const fullPath = [...pathArray.slice(0, pathLength), ...path47];
6031
+ const wrappedCensor = typeof censor === "function" ? (value, path48) => {
6032
+ const fullPath = [...pathArray.slice(0, pathLength), ...path48];
6033
6033
  return censor(value, fullPath);
6034
6034
  } : censor;
6035
6035
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6064,8 +6064,8 @@ var require_redact = __commonJS({
6064
6064
  return null;
6065
6065
  }
6066
6066
  const pathStructure = /* @__PURE__ */ new Map();
6067
- for (const path47 of pathsToClone) {
6068
- const parts = parsePath(path47);
6067
+ for (const path48 of pathsToClone) {
6068
+ const parts = parsePath(path48);
6069
6069
  let current = pathStructure;
6070
6070
  for (let i = 0; i < parts.length; i++) {
6071
6071
  const part = parts[i];
@@ -6117,24 +6117,24 @@ var require_redact = __commonJS({
6117
6117
  }
6118
6118
  return cloneSelectively(obj, pathStructure);
6119
6119
  }
6120
- function validatePath(path47) {
6121
- if (typeof path47 !== "string") {
6120
+ function validatePath(path48) {
6121
+ if (typeof path48 !== "string") {
6122
6122
  throw new Error("Paths must be (non-empty) strings");
6123
6123
  }
6124
- if (path47 === "") {
6124
+ if (path48 === "") {
6125
6125
  throw new Error("Invalid redaction path ()");
6126
6126
  }
6127
- if (path47.includes("..")) {
6128
- throw new Error(`Invalid redaction path (${path47})`);
6127
+ if (path48.includes("..")) {
6128
+ throw new Error(`Invalid redaction path (${path48})`);
6129
6129
  }
6130
- if (path47.includes(",")) {
6131
- throw new Error(`Invalid redaction path (${path47})`);
6130
+ if (path48.includes(",")) {
6131
+ throw new Error(`Invalid redaction path (${path48})`);
6132
6132
  }
6133
6133
  let bracketCount = 0;
6134
6134
  let inQuotes = false;
6135
6135
  let quoteChar = "";
6136
- for (let i = 0; i < path47.length; i++) {
6137
- const char = path47[i];
6136
+ for (let i = 0; i < path48.length; i++) {
6137
+ const char = path48[i];
6138
6138
  if ((char === '"' || char === "'") && bracketCount > 0) {
6139
6139
  if (!inQuotes) {
6140
6140
  inQuotes = true;
@@ -6148,20 +6148,20 @@ var require_redact = __commonJS({
6148
6148
  } else if (char === "]" && !inQuotes) {
6149
6149
  bracketCount--;
6150
6150
  if (bracketCount < 0) {
6151
- throw new Error(`Invalid redaction path (${path47})`);
6151
+ throw new Error(`Invalid redaction path (${path48})`);
6152
6152
  }
6153
6153
  }
6154
6154
  }
6155
6155
  if (bracketCount !== 0) {
6156
- throw new Error(`Invalid redaction path (${path47})`);
6156
+ throw new Error(`Invalid redaction path (${path48})`);
6157
6157
  }
6158
6158
  }
6159
6159
  function validatePaths(paths) {
6160
6160
  if (!Array.isArray(paths)) {
6161
6161
  throw new TypeError("paths must be an array");
6162
6162
  }
6163
- for (const path47 of paths) {
6164
- validatePath(path47);
6163
+ for (const path48 of paths) {
6164
+ validatePath(path48);
6165
6165
  }
6166
6166
  }
6167
6167
  function slowRedact(options = {}) {
@@ -6329,8 +6329,8 @@ var require_redaction = __commonJS({
6329
6329
  if (shape[k2] === null) {
6330
6330
  o[k2] = (value) => topCensor(value, [k2]);
6331
6331
  } else {
6332
- const wrappedCensor = typeof censor === "function" ? (value, path47) => {
6333
- return censor(value, [k2, ...path47]);
6332
+ const wrappedCensor = typeof censor === "function" ? (value, path48) => {
6333
+ return censor(value, [k2, ...path48]);
6334
6334
  } : censor;
6335
6335
  o[k2] = Redact({
6336
6336
  paths: shape[k2],
@@ -6551,7 +6551,7 @@ var require_sonic_boom = __commonJS({
6551
6551
  var fs38 = require("fs");
6552
6552
  var EventEmitter2 = require("events");
6553
6553
  var inherits = require("util").inherits;
6554
- var path47 = require("path");
6554
+ var path48 = require("path");
6555
6555
  var sleep = require_atomic_sleep();
6556
6556
  var assert = require("assert");
6557
6557
  var BUSY_WRITE_TIMEOUT = 100;
@@ -6605,7 +6605,7 @@ var require_sonic_boom = __commonJS({
6605
6605
  const mode = sonic.mode;
6606
6606
  if (sonic.sync) {
6607
6607
  try {
6608
- if (sonic.mkdir) fs38.mkdirSync(path47.dirname(file), { recursive: true });
6608
+ if (sonic.mkdir) fs38.mkdirSync(path48.dirname(file), { recursive: true });
6609
6609
  const fd = fs38.openSync(file, flags, mode);
6610
6610
  fileOpened(null, fd);
6611
6611
  } catch (err) {
@@ -6613,7 +6613,7 @@ var require_sonic_boom = __commonJS({
6613
6613
  throw err;
6614
6614
  }
6615
6615
  } else if (sonic.mkdir) {
6616
- fs38.mkdir(path47.dirname(file), { recursive: true }, (err) => {
6616
+ fs38.mkdir(path48.dirname(file), { recursive: true }, (err) => {
6617
6617
  if (err) return fileOpened(err);
6618
6618
  fs38.open(file, flags, mode, fileOpened);
6619
6619
  });
@@ -10244,11 +10244,11 @@ var init_lib = __esm({
10244
10244
  }
10245
10245
  }
10246
10246
  },
10247
- addToPath: function addToPath(path47, added, removed, oldPosInc, options) {
10248
- var last = path47.lastComponent;
10247
+ addToPath: function addToPath(path48, added, removed, oldPosInc, options) {
10248
+ var last = path48.lastComponent;
10249
10249
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10250
10250
  return {
10251
- oldPos: path47.oldPos + oldPosInc,
10251
+ oldPos: path48.oldPos + oldPosInc,
10252
10252
  lastComponent: {
10253
10253
  count: last.count + 1,
10254
10254
  added,
@@ -10258,7 +10258,7 @@ var init_lib = __esm({
10258
10258
  };
10259
10259
  } else {
10260
10260
  return {
10261
- oldPos: path47.oldPos + oldPosInc,
10261
+ oldPos: path48.oldPos + oldPosInc,
10262
10262
  lastComponent: {
10263
10263
  count: 1,
10264
10264
  added,
@@ -10704,10 +10704,10 @@ function attachmentToHistoryMessage(o, ts) {
10704
10704
  const memories = raw.map((m2) => {
10705
10705
  if (!m2 || typeof m2 !== "object") return null;
10706
10706
  const rec = m2;
10707
- const path47 = typeof rec.path === "string" ? rec.path : null;
10707
+ const path48 = typeof rec.path === "string" ? rec.path : null;
10708
10708
  const content = typeof rec.content === "string" ? rec.content : null;
10709
- if (!path47 || content == null) return null;
10710
- const entry = { path: path47, content };
10709
+ if (!path48 || content == null) return null;
10710
+ const entry = { path: path48, content };
10711
10711
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10712
10712
  return entry;
10713
10713
  }).filter((m2) => m2 !== null);
@@ -11538,10 +11538,10 @@ function parseAttachment(obj) {
11538
11538
  const memories = raw.map((m2) => {
11539
11539
  if (!m2 || typeof m2 !== "object") return null;
11540
11540
  const rec = m2;
11541
- const path47 = typeof rec.path === "string" ? rec.path : null;
11541
+ const path48 = typeof rec.path === "string" ? rec.path : null;
11542
11542
  const content = typeof rec.content === "string" ? rec.content : null;
11543
- if (!path47 || content == null) return null;
11544
- const out = { path: path47, content };
11543
+ if (!path48 || content == null) return null;
11544
+ const out = { path: path48, content };
11545
11545
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11546
11546
  return out;
11547
11547
  }).filter((m2) => m2 !== null);
@@ -20456,7 +20456,7 @@ var require_websocket_server = __commonJS({
20456
20456
  // src/run-case/recorder.ts
20457
20457
  function startRunCaseRecorder(opts) {
20458
20458
  const now = opts.now ?? Date.now;
20459
- const dir = import_node_path33.default.dirname(opts.recordPath);
20459
+ const dir = import_node_path34.default.dirname(opts.recordPath);
20460
20460
  let stream = null;
20461
20461
  let closing = false;
20462
20462
  let closedSettled = false;
@@ -20496,12 +20496,12 @@ function startRunCaseRecorder(opts) {
20496
20496
  };
20497
20497
  return { tap, close, closed };
20498
20498
  }
20499
- var import_node_fs30, import_node_path33;
20499
+ var import_node_fs30, import_node_path34;
20500
20500
  var init_recorder = __esm({
20501
20501
  "src/run-case/recorder.ts"() {
20502
20502
  "use strict";
20503
20503
  import_node_fs30 = __toESM(require("fs"), 1);
20504
- import_node_path33 = __toESM(require("path"), 1);
20504
+ import_node_path34 = __toESM(require("path"), 1);
20505
20505
  }
20506
20506
  });
20507
20507
 
@@ -20544,7 +20544,7 @@ var init_wire = __esm({
20544
20544
  // src/run-case/controller.ts
20545
20545
  async function runController(opts) {
20546
20546
  const now = opts.now ?? Date.now;
20547
- const cwd = opts.cwd ?? (0, import_node_fs31.mkdtempSync)(import_node_path34.default.join(import_node_os15.default.tmpdir(), "clawd-runcase-"));
20547
+ const cwd = opts.cwd ?? (0, import_node_fs31.mkdtempSync)(import_node_path35.default.join(import_node_os15.default.tmpdir(), "clawd-runcase-"));
20548
20548
  const ownsCwd = opts.cwd === void 0;
20549
20549
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
20550
20550
  const spawnCtx = { cwd };
@@ -20711,13 +20711,13 @@ async function runController(opts) {
20711
20711
  }
20712
20712
  return exitCode ?? 0;
20713
20713
  }
20714
- var import_node_fs31, import_node_os15, import_node_path34;
20714
+ var import_node_fs31, import_node_os15, import_node_path35;
20715
20715
  var init_controller = __esm({
20716
20716
  "src/run-case/controller.ts"() {
20717
20717
  "use strict";
20718
20718
  import_node_fs31 = require("fs");
20719
20719
  import_node_os15 = __toESM(require("os"), 1);
20720
- import_node_path34 = __toESM(require("path"), 1);
20720
+ import_node_path35 = __toESM(require("path"), 1);
20721
20721
  init_claude();
20722
20722
  init_stdout_splitter();
20723
20723
  init_permission_stdio();
@@ -20949,7 +20949,7 @@ Env (advanced):
20949
20949
  `;
20950
20950
 
20951
20951
  // src/index.ts
20952
- var import_node_path32 = __toESM(require("path"), 1);
20952
+ var import_node_path33 = __toESM(require("path"), 1);
20953
20953
  var import_node_fs29 = __toESM(require("fs"), 1);
20954
20954
 
20955
20955
  // src/logger.ts
@@ -28803,22 +28803,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
28803
28803
 
28804
28804
  // src/tunnel/device-key.ts
28805
28805
  var import_node_os11 = __toESM(require("os"), 1);
28806
+ var import_node_path27 = __toESM(require("path"), 1);
28806
28807
  var import_node_crypto9 = __toESM(require("crypto"), 1);
28807
28808
  var DERIVE_SALT = "clawd-tunnel-device-v1";
28808
28809
  function deriveStableDeviceKey(opts = {}) {
28809
28810
  const hostname = opts.hostname ?? import_node_os11.default.hostname();
28810
28811
  const uid = opts.uid ?? (typeof import_node_os11.default.userInfo === "function" ? import_node_os11.default.userInfo().uid : 0);
28811
- const input = `${hostname}::${uid}`;
28812
+ const home = opts.home ?? import_node_os11.default.homedir();
28813
+ const defaultDataDir = import_node_path27.default.resolve(import_node_path27.default.join(home, ".clawd"));
28814
+ const normalizedDataDir = opts.dataDir ? import_node_path27.default.resolve(opts.dataDir) : null;
28815
+ const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
28816
+ const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
28812
28817
  return import_node_crypto9.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
28813
28818
  }
28814
28819
 
28815
28820
  // src/auth-store.ts
28816
28821
  var import_node_fs25 = __toESM(require("fs"), 1);
28817
- var import_node_path27 = __toESM(require("path"), 1);
28822
+ var import_node_path28 = __toESM(require("path"), 1);
28818
28823
  var import_node_crypto10 = __toESM(require("crypto"), 1);
28819
28824
  var AUTH_FILE_NAME = "auth.json";
28820
28825
  function authFilePath(dataDir) {
28821
- return import_node_path27.default.join(dataDir, AUTH_FILE_NAME);
28826
+ return import_node_path28.default.join(dataDir, AUTH_FILE_NAME);
28822
28827
  }
28823
28828
  function loadOrCreateAuthFile(opts) {
28824
28829
  const file = authFilePath(opts.dataDir);
@@ -28868,7 +28873,7 @@ function readAuthFile(file) {
28868
28873
  }
28869
28874
  }
28870
28875
  function writeAuthFile(file, content) {
28871
- import_node_fs25.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
28876
+ import_node_fs25.default.mkdirSync(import_node_path28.default.dirname(file), { recursive: true });
28872
28877
  import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
28873
28878
  try {
28874
28879
  import_node_fs25.default.chmodSync(file, 384);
@@ -28879,11 +28884,11 @@ function writeAuthFile(file, content) {
28879
28884
  // src/owner-profile.ts
28880
28885
  var import_node_fs26 = __toESM(require("fs"), 1);
28881
28886
  var import_node_os12 = __toESM(require("os"), 1);
28882
- var import_node_path28 = __toESM(require("path"), 1);
28887
+ var import_node_path29 = __toESM(require("path"), 1);
28883
28888
  var PROFILE_FILENAME = "profile.json";
28884
28889
  function loadOwnerDisplayName(dataDir) {
28885
28890
  const fallback = import_node_os12.default.userInfo().username;
28886
- const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
28891
+ const profilePath = import_node_path29.default.join(dataDir, PROFILE_FILENAME);
28887
28892
  let raw;
28888
28893
  try {
28889
28894
  raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
@@ -28917,7 +28922,7 @@ init_protocol();
28917
28922
  // src/session/fork.ts
28918
28923
  var import_node_fs27 = __toESM(require("fs"), 1);
28919
28924
  var import_node_os13 = __toESM(require("os"), 1);
28920
- var import_node_path29 = __toESM(require("path"), 1);
28925
+ var import_node_path30 = __toESM(require("path"), 1);
28921
28926
  init_claude_history();
28922
28927
  function readJsonlEntries(file) {
28923
28928
  const raw = import_node_fs27.default.readFileSync(file, "utf8");
@@ -28933,9 +28938,9 @@ function readJsonlEntries(file) {
28933
28938
  return out;
28934
28939
  }
28935
28940
  function forkSession(input) {
28936
- const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os13.default.homedir(), ".claude");
28937
- const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
28938
- const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
28941
+ const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os13.default.homedir(), ".claude");
28942
+ const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
28943
+ const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
28939
28944
  if (!import_node_fs27.default.existsSync(sourceFile)) {
28940
28945
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
28941
28946
  }
@@ -28966,7 +28971,7 @@ function forkSession(input) {
28966
28971
  }
28967
28972
  forkedLines.push(JSON.stringify(forked));
28968
28973
  }
28969
- const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
28974
+ const forkedFilePath = import_node_path30.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
28970
28975
  import_node_fs27.default.mkdirSync(projectDir, { recursive: true });
28971
28976
  import_node_fs27.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
28972
28977
  return { forkedToolSessionId, forkedFilePath };
@@ -29320,7 +29325,7 @@ function buildPermissionHandlers(deps) {
29320
29325
  }
29321
29326
 
29322
29327
  // src/handlers/history.ts
29323
- var path39 = __toESM(require("path"), 1);
29328
+ var path40 = __toESM(require("path"), 1);
29324
29329
  init_protocol();
29325
29330
 
29326
29331
  // src/session/recent-dirs.ts
@@ -29338,7 +29343,7 @@ function listRecentDirs(store, limit = 50) {
29338
29343
  }
29339
29344
 
29340
29345
  // src/permission/persona-paths.ts
29341
- var path38 = __toESM(require("path"), 1);
29346
+ var path39 = __toESM(require("path"), 1);
29342
29347
  function getAllowedPersonaIds(grants, action) {
29343
29348
  const ids = /* @__PURE__ */ new Set();
29344
29349
  for (const g2 of grants) {
@@ -29351,26 +29356,26 @@ function getAllowedPersonaIds(grants, action) {
29351
29356
  return ids;
29352
29357
  }
29353
29358
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read") {
29354
- const root = path38.resolve(personaRoot);
29355
- const target = path38.resolve(absPath);
29356
- const sep3 = root.endsWith(path38.sep) ? "" : path38.sep;
29359
+ const root = path39.resolve(personaRoot);
29360
+ const target = path39.resolve(absPath);
29361
+ const sep3 = root.endsWith(path39.sep) ? "" : path39.sep;
29357
29362
  if (!target.startsWith(root + sep3)) return false;
29358
- const rel = path38.relative(root, target);
29363
+ const rel = path39.relative(root, target);
29359
29364
  if (!rel || rel.startsWith("..")) return false;
29360
- const personaId = rel.split(path38.sep)[0];
29365
+ const personaId = rel.split(path39.sep)[0];
29361
29366
  if (!personaId) return false;
29362
29367
  const allowed = getAllowedPersonaIds(grants, action);
29363
29368
  if (allowed === "*") return true;
29364
29369
  return allowed.has(personaId);
29365
29370
  }
29366
29371
  function personaIdFromPath(absPath, personaRoot) {
29367
- const root = path38.resolve(personaRoot);
29368
- const target = path38.resolve(absPath);
29369
- const sep3 = root.endsWith(path38.sep) ? "" : path38.sep;
29372
+ const root = path39.resolve(personaRoot);
29373
+ const target = path39.resolve(absPath);
29374
+ const sep3 = root.endsWith(path39.sep) ? "" : path39.sep;
29370
29375
  if (!target.startsWith(root + sep3)) return null;
29371
- const rel = path38.relative(root, target);
29376
+ const rel = path39.relative(root, target);
29372
29377
  if (!rel || rel.startsWith("..")) return null;
29373
- const id = rel.split(path38.sep)[0];
29378
+ const id = rel.split(path39.sep)[0];
29374
29379
  return id || null;
29375
29380
  }
29376
29381
 
@@ -29395,7 +29400,7 @@ function buildHistoryHandlers(deps) {
29395
29400
  if (!pid) return false;
29396
29401
  return isGuestPathAllowed(
29397
29402
  ctx.grants,
29398
- path39.join(personaRoot, pid),
29403
+ path40.join(personaRoot, pid),
29399
29404
  personaRoot,
29400
29405
  "read"
29401
29406
  );
@@ -29406,7 +29411,7 @@ function buildHistoryHandlers(deps) {
29406
29411
  };
29407
29412
  const list = async (frame, _client, ctx) => {
29408
29413
  const args = HistoryListArgs.parse(frame);
29409
- assertGuestPath(ctx, path39.resolve(args.projectPath), personaRoot, "history:list");
29414
+ assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
29410
29415
  const sessions = await history.listSessions(args);
29411
29416
  return { response: { type: "history:list", sessions } };
29412
29417
  };
@@ -29438,13 +29443,13 @@ function buildHistoryHandlers(deps) {
29438
29443
  };
29439
29444
  const subagents = async (frame, _client, ctx) => {
29440
29445
  const args = HistorySubagentsArgs.parse(frame);
29441
- assertGuestPath(ctx, path39.resolve(args.cwd), personaRoot, "history:subagents");
29446
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents");
29442
29447
  const subs = await history.listSubagents(args);
29443
29448
  return { response: { type: "history:subagents", subagents: subs } };
29444
29449
  };
29445
29450
  const subagentRead = async (frame, _client, ctx) => {
29446
29451
  const args = HistorySubagentReadArgs.parse(frame);
29447
- assertGuestPath(ctx, path39.resolve(args.cwd), personaRoot, "history:subagent-read");
29452
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read");
29448
29453
  const res = await history.readSubagent(args);
29449
29454
  return { response: { type: "history:subagent-read", ...res } };
29450
29455
  };
@@ -29452,7 +29457,7 @@ function buildHistoryHandlers(deps) {
29452
29457
  const dirs = listRecentDirs(store);
29453
29458
  if (ctx?.principal.kind === "guest" && personaRoot) {
29454
29459
  const filtered = dirs.filter(
29455
- (d) => isGuestPathAllowed(ctx.grants, path39.resolve(d.cwd), personaRoot, "read")
29460
+ (d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read")
29456
29461
  );
29457
29462
  return { response: { type: "history:recentDirs", dirs: filtered } };
29458
29463
  }
@@ -29469,7 +29474,7 @@ function buildHistoryHandlers(deps) {
29469
29474
  }
29470
29475
 
29471
29476
  // src/handlers/workspace.ts
29472
- var path40 = __toESM(require("path"), 1);
29477
+ var path41 = __toESM(require("path"), 1);
29473
29478
  var os14 = __toESM(require("os"), 1);
29474
29479
  init_protocol();
29475
29480
  init_protocol();
@@ -29510,22 +29515,22 @@ function buildWorkspaceHandlers(deps) {
29510
29515
  const args = WorkspaceListArgs.parse(frame);
29511
29516
  const isGuest = ctx?.principal.kind === "guest";
29512
29517
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os14.homedir();
29513
- const resolvedCwd = path40.resolve(args.cwd ?? fallbackCwd);
29514
- const target = args.path ? path40.resolve(resolvedCwd, args.path) : resolvedCwd;
29518
+ const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
29519
+ const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
29515
29520
  assertGuestPath2(ctx, target, personaRoot, "workspace:list");
29516
29521
  const res = workspace.list({ ...args, cwd: resolvedCwd });
29517
29522
  return { response: { type: "workspace:list", ...res } };
29518
29523
  };
29519
29524
  const read = async (frame, _client, ctx) => {
29520
29525
  const args = WorkspaceReadArgs.parse(frame);
29521
- const target = path40.isAbsolute(args.path) ? path40.resolve(args.path) : path40.resolve(args.cwd, args.path);
29526
+ const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
29522
29527
  assertGuestPath2(ctx, target, personaRoot, "workspace:read");
29523
29528
  const res = workspace.read(args);
29524
29529
  return { response: { type: "workspace:read", ...res } };
29525
29530
  };
29526
29531
  const skillsList = async (frame, _client, ctx) => {
29527
29532
  const args = SkillsListArgs.parse(frame);
29528
- const cwdAbs = path40.resolve(args.cwd);
29533
+ const cwdAbs = path41.resolve(args.cwd);
29529
29534
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list");
29530
29535
  const list2 = skills.list(args);
29531
29536
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -29537,7 +29542,7 @@ function buildWorkspaceHandlers(deps) {
29537
29542
  };
29538
29543
  const agentsList = async (frame, _client, ctx) => {
29539
29544
  const args = AgentsListArgs.parse(frame);
29540
- const cwdAbs = path40.resolve(args.cwd);
29545
+ const cwdAbs = path41.resolve(args.cwd);
29541
29546
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list");
29542
29547
  const list2 = agents.list(args);
29543
29548
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -29556,18 +29561,18 @@ function buildWorkspaceHandlers(deps) {
29556
29561
  }
29557
29562
 
29558
29563
  // src/handlers/git.ts
29559
- var path42 = __toESM(require("path"), 1);
29564
+ var path43 = __toESM(require("path"), 1);
29560
29565
  init_protocol();
29561
29566
  init_protocol();
29562
29567
 
29563
29568
  // src/workspace/git.ts
29564
29569
  var import_node_child_process6 = require("child_process");
29565
29570
  var import_node_fs28 = __toESM(require("fs"), 1);
29566
- var import_node_path30 = __toESM(require("path"), 1);
29571
+ var import_node_path31 = __toESM(require("path"), 1);
29567
29572
  var import_node_util = require("util");
29568
29573
  var pexec = (0, import_node_util.promisify)(import_node_child_process6.execFile);
29569
29574
  function normalizePath(p2) {
29570
- const resolved = import_node_path30.default.resolve(p2);
29575
+ const resolved = import_node_path31.default.resolve(p2);
29571
29576
  try {
29572
29577
  return import_node_fs28.default.realpathSync(resolved);
29573
29578
  } catch {
@@ -29642,7 +29647,7 @@ async function listGitBranches(cwd) {
29642
29647
  // src/handlers/git.ts
29643
29648
  function assertGuestCwd(ctx, cwd, personaRoot, method) {
29644
29649
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
29645
- if (!isGuestPathAllowed(ctx.grants, path42.resolve(cwd), personaRoot, "read")) {
29650
+ if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read")) {
29646
29651
  throw new ClawdError(
29647
29652
  ERROR_CODES.UNAUTHORIZED,
29648
29653
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -30129,7 +30134,7 @@ function buildPersonaHandlers(deps) {
30129
30134
  }
30130
30135
 
30131
30136
  // src/handlers/attachment.ts
30132
- var import_node_path31 = __toESM(require("path"), 1);
30137
+ var import_node_path32 = __toESM(require("path"), 1);
30133
30138
  init_protocol();
30134
30139
  init_protocol();
30135
30140
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -30183,12 +30188,12 @@ function buildAttachmentHandlers(deps) {
30183
30188
  `session ${args.sessionId} scope unresolved`
30184
30189
  );
30185
30190
  }
30186
- const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
30187
- const candidateAbs = import_node_path31.default.isAbsolute(args.relPath) ? import_node_path31.default.resolve(args.relPath) : import_node_path31.default.resolve(cwdAbs, args.relPath);
30191
+ const cwdAbs = import_node_path32.default.resolve(sessionFile.cwd);
30192
+ const candidateAbs = import_node_path32.default.isAbsolute(args.relPath) ? import_node_path32.default.resolve(args.relPath) : import_node_path32.default.resolve(cwdAbs, args.relPath);
30188
30193
  assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl");
30189
30194
  const entries = deps.groupFileStore.list(scope, args.sessionId);
30190
30195
  const entry = entries.find((e) => {
30191
- const storedAbs = import_node_path31.default.isAbsolute(e.relPath) ? import_node_path31.default.resolve(e.relPath) : import_node_path31.default.resolve(cwdAbs, e.relPath);
30196
+ const storedAbs = import_node_path32.default.isAbsolute(e.relPath) ? import_node_path32.default.resolve(e.relPath) : import_node_path32.default.resolve(cwdAbs, e.relPath);
30192
30197
  return storedAbs === candidateAbs && !e.stale;
30193
30198
  });
30194
30199
  if (!entry) {
@@ -30212,7 +30217,7 @@ function buildAttachmentHandlers(deps) {
30212
30217
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
30213
30218
  const f = deps.sessionStore.read(sessionId);
30214
30219
  if (!f) return;
30215
- assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method);
30220
+ assertGuestAttachmentPath(ctx, import_node_path32.default.resolve(f.cwd), deps.personaRoot, method);
30216
30221
  }
30217
30222
  const groupAdd = async (frame, _client, ctx) => {
30218
30223
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -30454,7 +30459,7 @@ function computeGrantForFrame(method, frame) {
30454
30459
  async function startDaemon(config) {
30455
30460
  const logger = createLogger({
30456
30461
  level: config.logLevel,
30457
- file: import_node_path32.default.join(config.dataDir, "clawd.log")
30462
+ file: import_node_path33.default.join(config.dataDir, "clawd.log")
30458
30463
  });
30459
30464
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
30460
30465
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -30541,7 +30546,7 @@ async function startDaemon(config) {
30541
30546
  const agents = new AgentsScanner();
30542
30547
  const history = new ClaudeHistoryReader();
30543
30548
  let transport = null;
30544
- const personaStore = new PersonaStore(import_node_path32.default.join(config.dataDir, "personas"));
30549
+ const personaStore = new PersonaStore(import_node_path33.default.join(config.dataDir, "personas"));
30545
30550
  const defaultsRoot = findDefaultsRoot();
30546
30551
  if (defaultsRoot) {
30547
30552
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -30558,7 +30563,7 @@ async function startDaemon(config) {
30558
30563
  getAdapter,
30559
30564
  historyReader: history,
30560
30565
  dataDir: config.dataDir,
30561
- personaRoot: import_node_path32.default.join(config.dataDir, "personas"),
30566
+ personaRoot: import_node_path33.default.join(config.dataDir, "personas"),
30562
30567
  personaStore,
30563
30568
  ownerDisplayName,
30564
30569
  ownerPrincipalId,
@@ -30582,7 +30587,7 @@ async function startDaemon(config) {
30582
30587
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
30583
30588
  attachmentGroup: {
30584
30589
  onFileEdit: (input) => {
30585
- const absPath = import_node_path32.default.isAbsolute(input.relPath) ? input.relPath : import_node_path32.default.join(input.cwd, input.relPath);
30590
+ const absPath = import_node_path33.default.isAbsolute(input.relPath) ? input.relPath : import_node_path33.default.join(input.cwd, input.relPath);
30586
30591
  let size = 0;
30587
30592
  try {
30588
30593
  size = import_node_fs29.default.statSync(absPath).size;
@@ -30705,10 +30710,10 @@ async function startDaemon(config) {
30705
30710
  // 'persona/<pid>/owner',default 走 'default'。
30706
30711
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
30707
30712
  // guest path guard:candidate 必须在 personaRoot 子树下
30708
- personaRoot: import_node_path32.default.join(config.dataDir, "personas")
30713
+ personaRoot: import_node_path33.default.join(config.dataDir, "personas")
30709
30714
  },
30710
30715
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
30711
- personaRoot: import_node_path32.default.join(config.dataDir, "personas"),
30716
+ personaRoot: import_node_path33.default.join(config.dataDir, "personas"),
30712
30717
  // capability:list / delete handler 依赖
30713
30718
  capabilityManager,
30714
30719
  // personal-cap:get 返回的 shareBaseUrl 用此 base URL:
@@ -30897,7 +30902,7 @@ async function startDaemon(config) {
30897
30902
  tunnelMgr = new TunnelManager({
30898
30903
  dataDir: config.dataDir,
30899
30904
  clawosApi: config.clawosApi,
30900
- deviceKey: deriveStableDeviceKey(),
30905
+ deviceKey: deriveStableDeviceKey({ dataDir: config.dataDir }),
30901
30906
  frpcBinaryOverride: config.frpcBinary,
30902
30907
  noPersist: config.noTunnelPersist,
30903
30908
  logger,
@@ -30915,8 +30920,8 @@ async function startDaemon(config) {
30915
30920
  const lines = [
30916
30921
  `Tunnel: ${r.url}`,
30917
30922
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
30918
- `Frpc config: ${import_node_path32.default.join(config.dataDir, "frpc.toml")}`,
30919
- `Frpc log: ${import_node_path32.default.join(config.dataDir, "frpc.log")}`
30923
+ `Frpc config: ${import_node_path33.default.join(config.dataDir, "frpc.toml")}`,
30924
+ `Frpc log: ${import_node_path33.default.join(config.dataDir, "frpc.log")}`
30920
30925
  ];
30921
30926
  const width = Math.max(...lines.map((l) => l.length));
30922
30927
  const bar = "\u2550".repeat(width + 4);
@@ -30929,7 +30934,7 @@ ${bar}
30929
30934
 
30930
30935
  `);
30931
30936
  try {
30932
- const connectPath = import_node_path32.default.join(config.dataDir, "connect.txt");
30937
+ const connectPath = import_node_path33.default.join(config.dataDir, "connect.txt");
30933
30938
  import_node_fs29.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
30934
30939
  } catch {
30935
30940
  }
@@ -30995,7 +31000,7 @@ ${bar}
30995
31000
  };
30996
31001
  }
30997
31002
  function migrateDropPersonsDir(dataDir) {
30998
- const dir = import_node_path32.default.join(dataDir, "persons");
31003
+ const dir = import_node_path33.default.join(dataDir, "persons");
30999
31004
  try {
31000
31005
  import_node_fs29.default.rmSync(dir, { recursive: true, force: true });
31001
31006
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.94",
3
+ "version": "0.2.95",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",