@clawos-dev/clawd 0.2.71-beta.123.6a5ed6f → 0.2.71-beta.124.b09b0a0

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 +379 -131
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -612,8 +612,8 @@ var init_parseUtil = __esm({
612
612
  init_errors2();
613
613
  init_en();
614
614
  makeIssue = (params) => {
615
- const { data, path: path32, errorMaps, issueData } = params;
616
- const fullPath = [...path32, ...issueData.path || []];
615
+ const { data, path: path35, errorMaps, issueData } = params;
616
+ const fullPath = [...path35, ...issueData.path || []];
617
617
  const fullIssue = {
618
618
  ...issueData,
619
619
  path: fullPath
@@ -924,11 +924,11 @@ var init_types = __esm({
924
924
  init_parseUtil();
925
925
  init_util();
926
926
  ParseInputLazyPath = class {
927
- constructor(parent, value, path32, key) {
927
+ constructor(parent, value, path35, key) {
928
928
  this._cachedPath = [];
929
929
  this.parent = parent;
930
930
  this.data = value;
931
- this._path = path32;
931
+ this._path = path35;
932
932
  this._key = key;
933
933
  }
934
934
  get path() {
@@ -5400,8 +5400,8 @@ var require_req = __commonJS({
5400
5400
  if (req.originalUrl) {
5401
5401
  _req.url = req.originalUrl;
5402
5402
  } else {
5403
- const path32 = req.path;
5404
- _req.url = typeof path32 === "string" ? path32 : req.url ? req.url.path || req.url : void 0;
5403
+ const path35 = req.path;
5404
+ _req.url = typeof path35 === "string" ? path35 : req.url ? req.url.path || req.url : void 0;
5405
5405
  }
5406
5406
  if (req.query) {
5407
5407
  _req.query = req.query;
@@ -5566,14 +5566,14 @@ var require_redact = __commonJS({
5566
5566
  }
5567
5567
  return obj;
5568
5568
  }
5569
- function parsePath(path32) {
5569
+ function parsePath(path35) {
5570
5570
  const parts = [];
5571
5571
  let current = "";
5572
5572
  let inBrackets = false;
5573
5573
  let inQuotes = false;
5574
5574
  let quoteChar = "";
5575
- for (let i = 0; i < path32.length; i++) {
5576
- const char = path32[i];
5575
+ for (let i = 0; i < path35.length; i++) {
5576
+ const char = path35[i];
5577
5577
  if (!inBrackets && char === ".") {
5578
5578
  if (current) {
5579
5579
  parts.push(current);
@@ -5704,10 +5704,10 @@ var require_redact = __commonJS({
5704
5704
  return current;
5705
5705
  }
5706
5706
  function redactPaths(obj, paths, censor, remove = false) {
5707
- for (const path32 of paths) {
5708
- const parts = parsePath(path32);
5707
+ for (const path35 of paths) {
5708
+ const parts = parsePath(path35);
5709
5709
  if (parts.includes("*")) {
5710
- redactWildcardPath(obj, parts, censor, path32, remove);
5710
+ redactWildcardPath(obj, parts, censor, path35, remove);
5711
5711
  } else {
5712
5712
  if (remove) {
5713
5713
  removeKey(obj, parts);
@@ -5792,8 +5792,8 @@ var require_redact = __commonJS({
5792
5792
  }
5793
5793
  } else {
5794
5794
  if (afterWildcard.includes("*")) {
5795
- const wrappedCensor = typeof censor === "function" ? (value, path32) => {
5796
- const fullPath = [...pathArray.slice(0, pathLength), ...path32];
5795
+ const wrappedCensor = typeof censor === "function" ? (value, path35) => {
5796
+ const fullPath = [...pathArray.slice(0, pathLength), ...path35];
5797
5797
  return censor(value, fullPath);
5798
5798
  } : censor;
5799
5799
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -5828,8 +5828,8 @@ var require_redact = __commonJS({
5828
5828
  return null;
5829
5829
  }
5830
5830
  const pathStructure = /* @__PURE__ */ new Map();
5831
- for (const path32 of pathsToClone) {
5832
- const parts = parsePath(path32);
5831
+ for (const path35 of pathsToClone) {
5832
+ const parts = parsePath(path35);
5833
5833
  let current = pathStructure;
5834
5834
  for (let i = 0; i < parts.length; i++) {
5835
5835
  const part = parts[i];
@@ -5881,24 +5881,24 @@ var require_redact = __commonJS({
5881
5881
  }
5882
5882
  return cloneSelectively(obj, pathStructure);
5883
5883
  }
5884
- function validatePath(path32) {
5885
- if (typeof path32 !== "string") {
5884
+ function validatePath(path35) {
5885
+ if (typeof path35 !== "string") {
5886
5886
  throw new Error("Paths must be (non-empty) strings");
5887
5887
  }
5888
- if (path32 === "") {
5888
+ if (path35 === "") {
5889
5889
  throw new Error("Invalid redaction path ()");
5890
5890
  }
5891
- if (path32.includes("..")) {
5892
- throw new Error(`Invalid redaction path (${path32})`);
5891
+ if (path35.includes("..")) {
5892
+ throw new Error(`Invalid redaction path (${path35})`);
5893
5893
  }
5894
- if (path32.includes(",")) {
5895
- throw new Error(`Invalid redaction path (${path32})`);
5894
+ if (path35.includes(",")) {
5895
+ throw new Error(`Invalid redaction path (${path35})`);
5896
5896
  }
5897
5897
  let bracketCount = 0;
5898
5898
  let inQuotes = false;
5899
5899
  let quoteChar = "";
5900
- for (let i = 0; i < path32.length; i++) {
5901
- const char = path32[i];
5900
+ for (let i = 0; i < path35.length; i++) {
5901
+ const char = path35[i];
5902
5902
  if ((char === '"' || char === "'") && bracketCount > 0) {
5903
5903
  if (!inQuotes) {
5904
5904
  inQuotes = true;
@@ -5912,20 +5912,20 @@ var require_redact = __commonJS({
5912
5912
  } else if (char === "]" && !inQuotes) {
5913
5913
  bracketCount--;
5914
5914
  if (bracketCount < 0) {
5915
- throw new Error(`Invalid redaction path (${path32})`);
5915
+ throw new Error(`Invalid redaction path (${path35})`);
5916
5916
  }
5917
5917
  }
5918
5918
  }
5919
5919
  if (bracketCount !== 0) {
5920
- throw new Error(`Invalid redaction path (${path32})`);
5920
+ throw new Error(`Invalid redaction path (${path35})`);
5921
5921
  }
5922
5922
  }
5923
5923
  function validatePaths(paths) {
5924
5924
  if (!Array.isArray(paths)) {
5925
5925
  throw new TypeError("paths must be an array");
5926
5926
  }
5927
- for (const path32 of paths) {
5928
- validatePath(path32);
5927
+ for (const path35 of paths) {
5928
+ validatePath(path35);
5929
5929
  }
5930
5930
  }
5931
5931
  function slowRedact(options = {}) {
@@ -6093,8 +6093,8 @@ var require_redaction = __commonJS({
6093
6093
  if (shape[k2] === null) {
6094
6094
  o[k2] = (value) => topCensor(value, [k2]);
6095
6095
  } else {
6096
- const wrappedCensor = typeof censor === "function" ? (value, path32) => {
6097
- return censor(value, [k2, ...path32]);
6096
+ const wrappedCensor = typeof censor === "function" ? (value, path35) => {
6097
+ return censor(value, [k2, ...path35]);
6098
6098
  } : censor;
6099
6099
  o[k2] = Redact({
6100
6100
  paths: shape[k2],
@@ -6312,10 +6312,10 @@ var require_atomic_sleep = __commonJS({
6312
6312
  var require_sonic_boom = __commonJS({
6313
6313
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
6314
6314
  "use strict";
6315
- var fs29 = require("fs");
6315
+ var fs31 = require("fs");
6316
6316
  var EventEmitter2 = require("events");
6317
6317
  var inherits = require("util").inherits;
6318
- var path32 = require("path");
6318
+ var path35 = require("path");
6319
6319
  var sleep = require_atomic_sleep();
6320
6320
  var assert = require("assert");
6321
6321
  var BUSY_WRITE_TIMEOUT = 100;
@@ -6369,20 +6369,20 @@ var require_sonic_boom = __commonJS({
6369
6369
  const mode = sonic.mode;
6370
6370
  if (sonic.sync) {
6371
6371
  try {
6372
- if (sonic.mkdir) fs29.mkdirSync(path32.dirname(file), { recursive: true });
6373
- const fd = fs29.openSync(file, flags, mode);
6372
+ if (sonic.mkdir) fs31.mkdirSync(path35.dirname(file), { recursive: true });
6373
+ const fd = fs31.openSync(file, flags, mode);
6374
6374
  fileOpened(null, fd);
6375
6375
  } catch (err) {
6376
6376
  fileOpened(err);
6377
6377
  throw err;
6378
6378
  }
6379
6379
  } else if (sonic.mkdir) {
6380
- fs29.mkdir(path32.dirname(file), { recursive: true }, (err) => {
6380
+ fs31.mkdir(path35.dirname(file), { recursive: true }, (err) => {
6381
6381
  if (err) return fileOpened(err);
6382
- fs29.open(file, flags, mode, fileOpened);
6382
+ fs31.open(file, flags, mode, fileOpened);
6383
6383
  });
6384
6384
  } else {
6385
- fs29.open(file, flags, mode, fileOpened);
6385
+ fs31.open(file, flags, mode, fileOpened);
6386
6386
  }
6387
6387
  }
6388
6388
  function SonicBoom(opts) {
@@ -6423,8 +6423,8 @@ var require_sonic_boom = __commonJS({
6423
6423
  this.flush = flushBuffer;
6424
6424
  this.flushSync = flushBufferSync;
6425
6425
  this._actualWrite = actualWriteBuffer;
6426
- fsWriteSync = () => fs29.writeSync(this.fd, this._writingBuf);
6427
- fsWrite = () => fs29.write(this.fd, this._writingBuf, this.release);
6426
+ fsWriteSync = () => fs31.writeSync(this.fd, this._writingBuf);
6427
+ fsWrite = () => fs31.write(this.fd, this._writingBuf, this.release);
6428
6428
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
6429
6429
  this._writingBuf = "";
6430
6430
  this.write = write;
@@ -6433,15 +6433,15 @@ var require_sonic_boom = __commonJS({
6433
6433
  this._actualWrite = actualWrite;
6434
6434
  fsWriteSync = () => {
6435
6435
  if (Buffer.isBuffer(this._writingBuf)) {
6436
- return fs29.writeSync(this.fd, this._writingBuf);
6436
+ return fs31.writeSync(this.fd, this._writingBuf);
6437
6437
  }
6438
- return fs29.writeSync(this.fd, this._writingBuf, "utf8");
6438
+ return fs31.writeSync(this.fd, this._writingBuf, "utf8");
6439
6439
  };
6440
6440
  fsWrite = () => {
6441
6441
  if (Buffer.isBuffer(this._writingBuf)) {
6442
- return fs29.write(this.fd, this._writingBuf, this.release);
6442
+ return fs31.write(this.fd, this._writingBuf, this.release);
6443
6443
  }
6444
- return fs29.write(this.fd, this._writingBuf, "utf8", this.release);
6444
+ return fs31.write(this.fd, this._writingBuf, "utf8", this.release);
6445
6445
  };
6446
6446
  } else {
6447
6447
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -6498,7 +6498,7 @@ var require_sonic_boom = __commonJS({
6498
6498
  }
6499
6499
  }
6500
6500
  if (this._fsync) {
6501
- fs29.fsyncSync(this.fd);
6501
+ fs31.fsyncSync(this.fd);
6502
6502
  }
6503
6503
  const len = this._len;
6504
6504
  if (this._reopening) {
@@ -6612,7 +6612,7 @@ var require_sonic_boom = __commonJS({
6612
6612
  const onDrain = () => {
6613
6613
  if (!this._fsync) {
6614
6614
  try {
6615
- fs29.fsync(this.fd, (err) => {
6615
+ fs31.fsync(this.fd, (err) => {
6616
6616
  this._flushPending = false;
6617
6617
  cb(err);
6618
6618
  });
@@ -6714,7 +6714,7 @@ var require_sonic_boom = __commonJS({
6714
6714
  const fd = this.fd;
6715
6715
  this.once("ready", () => {
6716
6716
  if (fd !== this.fd) {
6717
- fs29.close(fd, (err) => {
6717
+ fs31.close(fd, (err) => {
6718
6718
  if (err) {
6719
6719
  return this.emit("error", err);
6720
6720
  }
@@ -6763,7 +6763,7 @@ var require_sonic_boom = __commonJS({
6763
6763
  buf = this._bufs[0];
6764
6764
  }
6765
6765
  try {
6766
- const n = Buffer.isBuffer(buf) ? fs29.writeSync(this.fd, buf) : fs29.writeSync(this.fd, buf, "utf8");
6766
+ const n = Buffer.isBuffer(buf) ? fs31.writeSync(this.fd, buf) : fs31.writeSync(this.fd, buf, "utf8");
6767
6767
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
6768
6768
  buf = releasedBufObj.writingBuf;
6769
6769
  this._len = releasedBufObj.len;
@@ -6779,7 +6779,7 @@ var require_sonic_boom = __commonJS({
6779
6779
  }
6780
6780
  }
6781
6781
  try {
6782
- fs29.fsyncSync(this.fd);
6782
+ fs31.fsyncSync(this.fd);
6783
6783
  } catch {
6784
6784
  }
6785
6785
  }
@@ -6800,7 +6800,7 @@ var require_sonic_boom = __commonJS({
6800
6800
  buf = mergeBuf(this._bufs[0], this._lens[0]);
6801
6801
  }
6802
6802
  try {
6803
- const n = fs29.writeSync(this.fd, buf);
6803
+ const n = fs31.writeSync(this.fd, buf);
6804
6804
  buf = buf.subarray(n);
6805
6805
  this._len = Math.max(this._len - n, 0);
6806
6806
  if (buf.length <= 0) {
@@ -6828,13 +6828,13 @@ var require_sonic_boom = __commonJS({
6828
6828
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
6829
6829
  if (this.sync) {
6830
6830
  try {
6831
- const written = Buffer.isBuffer(this._writingBuf) ? fs29.writeSync(this.fd, this._writingBuf) : fs29.writeSync(this.fd, this._writingBuf, "utf8");
6831
+ const written = Buffer.isBuffer(this._writingBuf) ? fs31.writeSync(this.fd, this._writingBuf) : fs31.writeSync(this.fd, this._writingBuf, "utf8");
6832
6832
  release(null, written);
6833
6833
  } catch (err) {
6834
6834
  release(err);
6835
6835
  }
6836
6836
  } else {
6837
- fs29.write(this.fd, this._writingBuf, release);
6837
+ fs31.write(this.fd, this._writingBuf, release);
6838
6838
  }
6839
6839
  }
6840
6840
  function actualWriteBuffer() {
@@ -6843,7 +6843,7 @@ var require_sonic_boom = __commonJS({
6843
6843
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
6844
6844
  if (this.sync) {
6845
6845
  try {
6846
- const written = fs29.writeSync(this.fd, this._writingBuf);
6846
+ const written = fs31.writeSync(this.fd, this._writingBuf);
6847
6847
  release(null, written);
6848
6848
  } catch (err) {
6849
6849
  release(err);
@@ -6852,7 +6852,7 @@ var require_sonic_boom = __commonJS({
6852
6852
  if (kCopyBuffer) {
6853
6853
  this._writingBuf = Buffer.from(this._writingBuf);
6854
6854
  }
6855
- fs29.write(this.fd, this._writingBuf, release);
6855
+ fs31.write(this.fd, this._writingBuf, release);
6856
6856
  }
6857
6857
  }
6858
6858
  function actualClose(sonic) {
@@ -6868,12 +6868,12 @@ var require_sonic_boom = __commonJS({
6868
6868
  sonic._lens = [];
6869
6869
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
6870
6870
  try {
6871
- fs29.fsync(sonic.fd, closeWrapped);
6871
+ fs31.fsync(sonic.fd, closeWrapped);
6872
6872
  } catch {
6873
6873
  }
6874
6874
  function closeWrapped() {
6875
6875
  if (sonic.fd !== 1 && sonic.fd !== 2) {
6876
- fs29.close(sonic.fd, done);
6876
+ fs31.close(sonic.fd, done);
6877
6877
  } else {
6878
6878
  done();
6879
6879
  }
@@ -7130,7 +7130,7 @@ var require_thread_stream = __commonJS({
7130
7130
  var { version: version2 } = require_package();
7131
7131
  var { EventEmitter: EventEmitter2 } = require("events");
7132
7132
  var { Worker } = require("worker_threads");
7133
- var { join: join5 } = require("path");
7133
+ var { join: join8 } = require("path");
7134
7134
  var { pathToFileURL } = require("url");
7135
7135
  var { wait } = require_wait();
7136
7136
  var {
@@ -7166,7 +7166,7 @@ var require_thread_stream = __commonJS({
7166
7166
  function createWorker(stream, opts) {
7167
7167
  const { filename, workerData } = opts;
7168
7168
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
7169
- const toExecute = bundlerOverrides["thread-stream-worker"] || join5(__dirname, "lib", "worker.js");
7169
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join8(__dirname, "lib", "worker.js");
7170
7170
  const worker = new Worker(toExecute, {
7171
7171
  ...opts.workerOpts,
7172
7172
  trackUnmanagedFds: false,
@@ -7552,7 +7552,7 @@ var require_transport = __commonJS({
7552
7552
  "use strict";
7553
7553
  var { createRequire } = require("module");
7554
7554
  var getCallers = require_caller();
7555
- var { join: join5, isAbsolute, sep } = require("path");
7555
+ var { join: join8, isAbsolute, sep: sep2 } = require("path");
7556
7556
  var sleep = require_atomic_sleep();
7557
7557
  var onExit = require_on_exit_leak_free();
7558
7558
  var ThreadStream = require_thread_stream();
@@ -7615,7 +7615,7 @@ var require_transport = __commonJS({
7615
7615
  throw new Error("only one of target or targets can be specified");
7616
7616
  }
7617
7617
  if (targets) {
7618
- target = bundlerOverrides["pino-worker"] || join5(__dirname, "worker.js");
7618
+ target = bundlerOverrides["pino-worker"] || join8(__dirname, "worker.js");
7619
7619
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
7620
7620
  return {
7621
7621
  ...dest,
@@ -7633,7 +7633,7 @@ var require_transport = __commonJS({
7633
7633
  });
7634
7634
  });
7635
7635
  } else if (pipeline2) {
7636
- target = bundlerOverrides["pino-worker"] || join5(__dirname, "worker.js");
7636
+ target = bundlerOverrides["pino-worker"] || join8(__dirname, "worker.js");
7637
7637
  options.pipelines = [pipeline2.map((dest) => {
7638
7638
  return {
7639
7639
  ...dest,
@@ -7655,12 +7655,12 @@ var require_transport = __commonJS({
7655
7655
  return origin;
7656
7656
  }
7657
7657
  if (origin === "pino/file") {
7658
- return join5(__dirname, "..", "file.js");
7658
+ return join8(__dirname, "..", "file.js");
7659
7659
  }
7660
7660
  let fixTarget2;
7661
7661
  for (const filePath of callers) {
7662
7662
  try {
7663
- const context = filePath === "node:repl" ? process.cwd() + sep : filePath;
7663
+ const context = filePath === "node:repl" ? process.cwd() + sep2 : filePath;
7664
7664
  fixTarget2 = createRequire(context).resolve(origin);
7665
7665
  break;
7666
7666
  } catch (err) {
@@ -8645,7 +8645,7 @@ var require_safe_stable_stringify = __commonJS({
8645
8645
  return circularValue;
8646
8646
  }
8647
8647
  let res = "";
8648
- let join5 = ",";
8648
+ let join8 = ",";
8649
8649
  const originalIndentation = indentation;
8650
8650
  if (Array.isArray(value)) {
8651
8651
  if (value.length === 0) {
@@ -8659,7 +8659,7 @@ var require_safe_stable_stringify = __commonJS({
8659
8659
  indentation += spacer;
8660
8660
  res += `
8661
8661
  ${indentation}`;
8662
- join5 = `,
8662
+ join8 = `,
8663
8663
  ${indentation}`;
8664
8664
  }
8665
8665
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -8667,13 +8667,13 @@ ${indentation}`;
8667
8667
  for (; i < maximumValuesToStringify - 1; i++) {
8668
8668
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
8669
8669
  res += tmp2 !== void 0 ? tmp2 : "null";
8670
- res += join5;
8670
+ res += join8;
8671
8671
  }
8672
8672
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
8673
8673
  res += tmp !== void 0 ? tmp : "null";
8674
8674
  if (value.length - 1 > maximumBreadth) {
8675
8675
  const removedKeys = value.length - maximumBreadth - 1;
8676
- res += `${join5}"... ${getItemCount(removedKeys)} not stringified"`;
8676
+ res += `${join8}"... ${getItemCount(removedKeys)} not stringified"`;
8677
8677
  }
8678
8678
  if (spacer !== "") {
8679
8679
  res += `
@@ -8694,7 +8694,7 @@ ${originalIndentation}`;
8694
8694
  let separator = "";
8695
8695
  if (spacer !== "") {
8696
8696
  indentation += spacer;
8697
- join5 = `,
8697
+ join8 = `,
8698
8698
  ${indentation}`;
8699
8699
  whitespace = " ";
8700
8700
  }
@@ -8708,13 +8708,13 @@ ${indentation}`;
8708
8708
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
8709
8709
  if (tmp !== void 0) {
8710
8710
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
8711
- separator = join5;
8711
+ separator = join8;
8712
8712
  }
8713
8713
  }
8714
8714
  if (keyLength > maximumBreadth) {
8715
8715
  const removedKeys = keyLength - maximumBreadth;
8716
8716
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
8717
- separator = join5;
8717
+ separator = join8;
8718
8718
  }
8719
8719
  if (spacer !== "" && separator.length > 1) {
8720
8720
  res = `
@@ -8755,7 +8755,7 @@ ${originalIndentation}`;
8755
8755
  }
8756
8756
  const originalIndentation = indentation;
8757
8757
  let res = "";
8758
- let join5 = ",";
8758
+ let join8 = ",";
8759
8759
  if (Array.isArray(value)) {
8760
8760
  if (value.length === 0) {
8761
8761
  return "[]";
@@ -8768,7 +8768,7 @@ ${originalIndentation}`;
8768
8768
  indentation += spacer;
8769
8769
  res += `
8770
8770
  ${indentation}`;
8771
- join5 = `,
8771
+ join8 = `,
8772
8772
  ${indentation}`;
8773
8773
  }
8774
8774
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -8776,13 +8776,13 @@ ${indentation}`;
8776
8776
  for (; i < maximumValuesToStringify - 1; i++) {
8777
8777
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
8778
8778
  res += tmp2 !== void 0 ? tmp2 : "null";
8779
- res += join5;
8779
+ res += join8;
8780
8780
  }
8781
8781
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
8782
8782
  res += tmp !== void 0 ? tmp : "null";
8783
8783
  if (value.length - 1 > maximumBreadth) {
8784
8784
  const removedKeys = value.length - maximumBreadth - 1;
8785
- res += `${join5}"... ${getItemCount(removedKeys)} not stringified"`;
8785
+ res += `${join8}"... ${getItemCount(removedKeys)} not stringified"`;
8786
8786
  }
8787
8787
  if (spacer !== "") {
8788
8788
  res += `
@@ -8795,7 +8795,7 @@ ${originalIndentation}`;
8795
8795
  let whitespace = "";
8796
8796
  if (spacer !== "") {
8797
8797
  indentation += spacer;
8798
- join5 = `,
8798
+ join8 = `,
8799
8799
  ${indentation}`;
8800
8800
  whitespace = " ";
8801
8801
  }
@@ -8804,7 +8804,7 @@ ${indentation}`;
8804
8804
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
8805
8805
  if (tmp !== void 0) {
8806
8806
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
8807
- separator = join5;
8807
+ separator = join8;
8808
8808
  }
8809
8809
  }
8810
8810
  if (spacer !== "" && separator.length > 1) {
@@ -8862,20 +8862,20 @@ ${originalIndentation}`;
8862
8862
  indentation += spacer;
8863
8863
  let res2 = `
8864
8864
  ${indentation}`;
8865
- const join6 = `,
8865
+ const join9 = `,
8866
8866
  ${indentation}`;
8867
8867
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
8868
8868
  let i = 0;
8869
8869
  for (; i < maximumValuesToStringify - 1; i++) {
8870
8870
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
8871
8871
  res2 += tmp2 !== void 0 ? tmp2 : "null";
8872
- res2 += join6;
8872
+ res2 += join9;
8873
8873
  }
8874
8874
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
8875
8875
  res2 += tmp !== void 0 ? tmp : "null";
8876
8876
  if (value.length - 1 > maximumBreadth) {
8877
8877
  const removedKeys = value.length - maximumBreadth - 1;
8878
- res2 += `${join6}"... ${getItemCount(removedKeys)} not stringified"`;
8878
+ res2 += `${join9}"... ${getItemCount(removedKeys)} not stringified"`;
8879
8879
  }
8880
8880
  res2 += `
8881
8881
  ${originalIndentation}`;
@@ -8891,16 +8891,16 @@ ${originalIndentation}`;
8891
8891
  return '"[Object]"';
8892
8892
  }
8893
8893
  indentation += spacer;
8894
- const join5 = `,
8894
+ const join8 = `,
8895
8895
  ${indentation}`;
8896
8896
  let res = "";
8897
8897
  let separator = "";
8898
8898
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
8899
8899
  if (isTypedArrayWithEntries(value)) {
8900
- res += stringifyTypedArray(value, join5, maximumBreadth);
8900
+ res += stringifyTypedArray(value, join8, maximumBreadth);
8901
8901
  keys = keys.slice(value.length);
8902
8902
  maximumPropertiesToStringify -= value.length;
8903
- separator = join5;
8903
+ separator = join8;
8904
8904
  }
8905
8905
  if (deterministic) {
8906
8906
  keys = sort(keys, comparator);
@@ -8911,13 +8911,13 @@ ${indentation}`;
8911
8911
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
8912
8912
  if (tmp !== void 0) {
8913
8913
  res += `${separator}${strEscape(key2)}: ${tmp}`;
8914
- separator = join5;
8914
+ separator = join8;
8915
8915
  }
8916
8916
  }
8917
8917
  if (keyLength > maximumBreadth) {
8918
8918
  const removedKeys = keyLength - maximumBreadth;
8919
8919
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
8920
- separator = join5;
8920
+ separator = join8;
8921
8921
  }
8922
8922
  if (separator !== "") {
8923
8923
  res = `
@@ -10008,11 +10008,11 @@ var init_lib = __esm({
10008
10008
  }
10009
10009
  }
10010
10010
  },
10011
- addToPath: function addToPath(path32, added, removed, oldPosInc, options) {
10012
- var last = path32.lastComponent;
10011
+ addToPath: function addToPath(path35, added, removed, oldPosInc, options) {
10012
+ var last = path35.lastComponent;
10013
10013
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10014
10014
  return {
10015
- oldPos: path32.oldPos + oldPosInc,
10015
+ oldPos: path35.oldPos + oldPosInc,
10016
10016
  lastComponent: {
10017
10017
  count: last.count + 1,
10018
10018
  added,
@@ -10022,7 +10022,7 @@ var init_lib = __esm({
10022
10022
  };
10023
10023
  } else {
10024
10024
  return {
10025
- oldPos: path32.oldPos + oldPosInc,
10025
+ oldPos: path35.oldPos + oldPosInc,
10026
10026
  lastComponent: {
10027
10027
  count: 1,
10028
10028
  added,
@@ -10080,7 +10080,7 @@ var init_lib = __esm({
10080
10080
  tokenize: function tokenize(value) {
10081
10081
  return Array.from(value);
10082
10082
  },
10083
- join: function join3(chars) {
10083
+ join: function join4(chars) {
10084
10084
  return chars.join("");
10085
10085
  },
10086
10086
  postProcess: function postProcess(changeObjects) {
@@ -10453,10 +10453,10 @@ function attachmentToHistoryMessage(o, ts) {
10453
10453
  const memories = raw.map((m2) => {
10454
10454
  if (!m2 || typeof m2 !== "object") return null;
10455
10455
  const rec = m2;
10456
- const path32 = typeof rec.path === "string" ? rec.path : null;
10456
+ const path35 = typeof rec.path === "string" ? rec.path : null;
10457
10457
  const content = typeof rec.content === "string" ? rec.content : null;
10458
- if (!path32 || content == null) return null;
10459
- const entry = { path: path32, content };
10458
+ if (!path35 || content == null) return null;
10459
+ const entry = { path: path35, content };
10460
10460
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10461
10461
  return entry;
10462
10462
  }).filter((m2) => m2 !== null);
@@ -10916,6 +10916,27 @@ var init_claude_history = __esm({
10916
10916
  }
10917
10917
  });
10918
10918
 
10919
+ // src/tools/sandbox.ts
10920
+ function shouldSandbox(cwd, personaRoot) {
10921
+ if (!personaRoot) return false;
10922
+ const sep2 = personaRoot.endsWith(path12.sep) ? "" : path12.sep;
10923
+ return cwd.startsWith(personaRoot + sep2) && cwd !== personaRoot;
10924
+ }
10925
+ function inferSandboxSettingsPath(cwd, personaRoot) {
10926
+ if (!shouldSandbox(cwd, personaRoot)) return null;
10927
+ const rel = path12.relative(personaRoot, cwd);
10928
+ const personaId = rel.split(path12.sep)[0];
10929
+ if (!personaId) return null;
10930
+ return path12.join(personaRoot, personaId, ".clawd", "sandbox-settings.json");
10931
+ }
10932
+ var path12;
10933
+ var init_sandbox = __esm({
10934
+ "src/tools/sandbox.ts"() {
10935
+ "use strict";
10936
+ path12 = __toESM(require("path"), 1);
10937
+ }
10938
+ });
10939
+
10919
10940
  // src/tools/claude.ts
10920
10941
  function macOSDesktopCandidates(home) {
10921
10942
  return [
@@ -10980,7 +11001,8 @@ function buildSpawnArgs(ctx) {
10980
11001
  throw new Error(`unexpected personaMode: ${String(_exhaustive)}`);
10981
11002
  }
10982
11003
  }
10983
- if (ctx.extraSettings) args.push("--settings", ctx.extraSettings);
11004
+ const sandboxSettings = ctx.extraSettings ?? inferSandboxSettingsPath(ctx.cwd, ctx.personaRoot);
11005
+ if (sandboxSettings) args.push("--settings", sandboxSettings);
10984
11006
  if (ctx.extraSystemPrompt) args.push("--append-system-prompt", ctx.extraSystemPrompt);
10985
11007
  if (ctx.effort) args.push("--effort", ctx.effort);
10986
11008
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
@@ -11260,10 +11282,10 @@ function parseAttachment(obj) {
11260
11282
  const memories = raw.map((m2) => {
11261
11283
  if (!m2 || typeof m2 !== "object") return null;
11262
11284
  const rec = m2;
11263
- const path32 = typeof rec.path === "string" ? rec.path : null;
11285
+ const path35 = typeof rec.path === "string" ? rec.path : null;
11264
11286
  const content = typeof rec.content === "string" ? rec.content : null;
11265
- if (!path32 || content == null) return null;
11266
- const out = { path: path32, content };
11287
+ if (!path35 || content == null) return null;
11288
+ const out = { path: path35, content };
11267
11289
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11268
11290
  return out;
11269
11291
  }).filter((m2) => m2 !== null);
@@ -11379,6 +11401,7 @@ var init_claude = __esm({
11379
11401
  init_protocol();
11380
11402
  init_claude_history();
11381
11403
  init_tool_result_extra();
11404
+ init_sandbox();
11382
11405
  ATTACHMENT_SILENT_SUBTYPES2 = /* @__PURE__ */ new Set([
11383
11406
  "hook_additional_context",
11384
11407
  "hook_success",
@@ -20708,6 +20731,9 @@ function createLogger(opts = {}) {
20708
20731
  return wrap(base);
20709
20732
  }
20710
20733
 
20734
+ // src/session/store-factory.ts
20735
+ var path5 = __toESM(require("path"), 1);
20736
+
20711
20737
  // src/session/store.ts
20712
20738
  var import_node_fs3 = __toESM(require("fs"), 1);
20713
20739
  var import_node_path4 = __toESM(require("path"), 1);
@@ -20745,12 +20771,16 @@ function safeFileName(sessionId) {
20745
20771
  var SessionStore = class {
20746
20772
  root;
20747
20773
  constructor(opts) {
20748
- const scope = opts.scope ?? { kind: "default" };
20749
- this.root = import_node_path4.default.join(
20750
- opts.dataDir,
20751
- "sessions",
20752
- ...scopeSubPath(scope).map(safeFileName)
20753
- );
20774
+ if ("root" in opts) {
20775
+ this.root = opts.root;
20776
+ } else {
20777
+ const scope = opts.scope ?? { kind: "default" };
20778
+ this.root = import_node_path4.default.join(
20779
+ opts.dataDir,
20780
+ "sessions",
20781
+ ...scopeSubPath(scope).map(safeFileName)
20782
+ );
20783
+ }
20754
20784
  }
20755
20785
  filePath(sessionId) {
20756
20786
  return import_node_path4.default.join(this.root, `${safeFileName(sessionId)}.json`);
@@ -20815,6 +20845,66 @@ var SessionStore = class {
20815
20845
  }
20816
20846
  };
20817
20847
 
20848
+ // src/session/store-factory.ts
20849
+ var SessionStoreFactory = class {
20850
+ dataDir;
20851
+ bareStore = null;
20852
+ vmOwnerStores = /* @__PURE__ */ new Map();
20853
+ // vmGuest 索引 key = `${pid}::${capId}`
20854
+ vmGuestStores = /* @__PURE__ */ new Map();
20855
+ constructor(opts) {
20856
+ this.dataDir = opts.dataDir;
20857
+ }
20858
+ // ---- root path 派生(暴露给 migration / revoke cascade 等外部消费方) ----
20859
+ bareRoot() {
20860
+ return path5.join(this.dataDir, "sessions");
20861
+ }
20862
+ vmOwnerRoot(personaId) {
20863
+ return path5.join(
20864
+ this.dataDir,
20865
+ "personas",
20866
+ safeFileName(personaId),
20867
+ ".clawd",
20868
+ "sessions",
20869
+ "owner"
20870
+ );
20871
+ }
20872
+ vmGuestRoot(personaId, capabilityId) {
20873
+ return path5.join(
20874
+ this.dataDir,
20875
+ "personas",
20876
+ safeFileName(personaId),
20877
+ ".clawd",
20878
+ "sessions",
20879
+ "guests",
20880
+ safeFileName(capabilityId)
20881
+ );
20882
+ }
20883
+ // ---- SessionStore 工厂(缓存) ----
20884
+ forBare() {
20885
+ if (!this.bareStore) {
20886
+ this.bareStore = new SessionStore({ root: this.bareRoot() });
20887
+ }
20888
+ return this.bareStore;
20889
+ }
20890
+ forVmOwner(personaId) {
20891
+ const key = personaId;
20892
+ const cached = this.vmOwnerStores.get(key);
20893
+ if (cached) return cached;
20894
+ const st = new SessionStore({ root: this.vmOwnerRoot(personaId) });
20895
+ this.vmOwnerStores.set(key, st);
20896
+ return st;
20897
+ }
20898
+ forVmGuest(personaId, capabilityId) {
20899
+ const key = `${personaId}::${capabilityId}`;
20900
+ const cached = this.vmGuestStores.get(key);
20901
+ if (cached) return cached;
20902
+ const st = new SessionStore({ root: this.vmGuestRoot(personaId, capabilityId) });
20903
+ this.vmGuestStores.set(key, st);
20904
+ return st;
20905
+ }
20906
+ };
20907
+
20818
20908
  // src/session/manager.ts
20819
20909
  var import_node_fs5 = __toESM(require("fs"), 1);
20820
20910
  var import_node_path6 = __toESM(require("path"), 1);
@@ -20974,7 +21064,10 @@ function buildSpawnContext(state, deps) {
20974
21064
  toolSessionId: file.toolSessionId,
20975
21065
  model: file.model,
20976
21066
  permissionMode: file.permissionMode,
20977
- effort: file.effort
21067
+ effort: file.effort,
21068
+ // Phase 2 capability platform (plan §3): personaRoot 透传给 buildSpawnArgs;
21069
+ // 内部 shouldSandbox(cwd, personaRoot) 决定是否注入 --settings sandbox-settings.
21070
+ personaRoot: deps.personaRoot
20978
21071
  };
20979
21072
  const meta = state.subSessionMeta;
20980
21073
  if (meta?.personaMode) {
@@ -21701,7 +21794,8 @@ var SessionRunner = class {
21701
21794
  now: this.hooks.now ?? Date.now,
21702
21795
  resolveContextWindow: this.hooks.resolveContextWindow,
21703
21796
  genUuid: this.hooks.genUuid ?? v4_default,
21704
- ownerDisplayName: this.hooks.ownerDisplayName
21797
+ ownerDisplayName: this.hooks.ownerDisplayName,
21798
+ personaRoot: this.hooks.personaRoot
21705
21799
  };
21706
21800
  const { state, effects } = reduceSession(this.state, inputMsg, deps);
21707
21801
  this.state = state;
@@ -22125,9 +22219,20 @@ var SessionManager = class {
22125
22219
  attachObserver(observer) {
22126
22220
  this.attachedObserver = observer;
22127
22221
  }
22128
- // 按 scope 拿对应的 SessionStore。default scope 复用 deps.store(保证与
22129
- // bootstrap 注入的 store 一致);persona scope 第一次访问时按需创建并缓存。
22222
+ // 按 scope 拿对应的 SessionStore.
22223
+ // Phase 2 (capability platform plan §1) 路由切到 SessionStoreFactory:
22224
+ // default → factory.forBare() <dataDir>/sessions/
22225
+ // persona/<pid>/owner → factory.forVmOwner(pid) <dataDir>/personas/<pid>/.clawd/sessions/owner/
22226
+ // persona/<pid>/listener → throw (listener 角色 #698 已下线, schema 字段保留但运行时不该出现)
22227
+ // 缺省 (无 factory 注入): 回退 dataDir+scope 老路径 (向后兼容旧 spec).
22130
22228
  storeFor(scope) {
22229
+ if (this.deps.storeFactory) {
22230
+ if (scope.kind === "default") return this.deps.storeFactory.forBare();
22231
+ if (scope.mode === "owner") return this.deps.storeFactory.forVmOwner(scope.personaId);
22232
+ throw new Error(
22233
+ `SessionManager: listener scope is deprecated (#698); use forVmGuest in Phase 3+ instead`
22234
+ );
22235
+ }
22131
22236
  if (scope.kind === "default") return this.deps.store;
22132
22237
  const key = scopeKey(scope);
22133
22238
  const cached = this.storesByScope.get(key);
@@ -22155,11 +22260,13 @@ var SessionManager = class {
22155
22260
  scopeForFile(file) {
22156
22261
  return file.ownerPersonaId ? { kind: "persona", personaId: file.ownerPersonaId, mode: "owner" } : { kind: "default" };
22157
22262
  }
22158
- // <dataDir>/sessions/ 列出所有 persona 命名空间(不含 'default')。
22159
- // 用于 findOwnedSession / listAllOwned scope 查询。
22263
+ // 扫所有 persona 命名空间. 用于 findOwnedSession / listAllOwned scope 查询.
22264
+ // Phase 2 capability platform: 新布局下 persona 资产在 <dataDir>/personas/<pid>/,
22265
+ // 直接 readdir 这个目录拿所有 personaId. 老布局 (无 storeFactory) fallback 扫
22266
+ // <dataDir>/sessions/ 列子目录 (排除 'default').
22160
22267
  listPersonaIdsOnDisk() {
22161
22268
  if (!this.deps.dataDir) return [];
22162
- const root = import_node_path6.default.join(this.deps.dataDir, "sessions");
22269
+ const root = this.deps.storeFactory ? import_node_path6.default.join(this.deps.dataDir, "personas") : import_node_path6.default.join(this.deps.dataDir, "sessions");
22163
22270
  let entries;
22164
22271
  try {
22165
22272
  entries = import_node_fs5.default.readdirSync(root, { withFileTypes: true });
@@ -22234,6 +22341,9 @@ var SessionManager = class {
22234
22341
  dataDir: this.deps.dataDir,
22235
22342
  personaStore: this.deps.personaStore,
22236
22343
  ownerDisplayName: this.deps.ownerDisplayName,
22344
+ // Phase 2 capability platform (plan §3): 透传 personaRoot, buildSpawnArgs 据
22345
+ // cwd 是否在 personaRoot 下自动决定是否注入 --settings sandbox-settings.json.
22346
+ personaRoot: this.deps.personaRoot,
22237
22347
  // file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
22238
22348
  onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
22239
22349
  scope,
@@ -23246,7 +23356,7 @@ var SessionManager = class {
23246
23356
 
23247
23357
  // src/persona/store.ts
23248
23358
  var fs6 = __toESM(require("fs"), 1);
23249
- var path7 = __toESM(require("path"), 1);
23359
+ var path8 = __toESM(require("path"), 1);
23250
23360
  init_protocol();
23251
23361
  var DEFAULT_SETTINGS = {
23252
23362
  permissions: {
@@ -23275,13 +23385,13 @@ var PersonaStore = class {
23275
23385
  }
23276
23386
  root;
23277
23387
  personaDir(personaId) {
23278
- return path7.join(this.root, safeFileName(personaId));
23388
+ return path8.join(this.root, safeFileName(personaId));
23279
23389
  }
23280
23390
  metaPath(personaId) {
23281
- return path7.join(this.personaDir(personaId), ".clawd", "persona.json");
23391
+ return path8.join(this.personaDir(personaId), ".clawd", "persona.json");
23282
23392
  }
23283
23393
  claudeMdPath(personaId) {
23284
- return path7.join(this.personaDir(personaId), "CLAUDE.md");
23394
+ return path8.join(this.personaDir(personaId), "CLAUDE.md");
23285
23395
  }
23286
23396
  /**
23287
23397
  * Sandbox settings 落盘路径 —— 故意放在 `.clawd/` 而不是 `.claude/`,让 CC 的
@@ -23291,11 +23401,11 @@ var PersonaStore = class {
23291
23401
  * 加载 persona 人格,只有 listener 多一层 OS sandbox。
23292
23402
  */
23293
23403
  sandboxSettingsPath(personaId) {
23294
- return path7.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
23404
+ return path8.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
23295
23405
  }
23296
23406
  write(persona, personality) {
23297
23407
  const dir = this.personaDir(persona.personaId);
23298
- fs6.mkdirSync(path7.join(dir, ".clawd"), { recursive: true });
23408
+ fs6.mkdirSync(path8.join(dir, ".clawd"), { recursive: true });
23299
23409
  this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
23300
23410
  this.atomicWrite(
23301
23411
  this.sandboxSettingsPath(persona.personaId),
@@ -23338,12 +23448,12 @@ var PersonaStore = class {
23338
23448
  }
23339
23449
  /** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
23340
23450
  skillsDir(personaId) {
23341
- return path7.join(this.personaDir(personaId), ".claude", "skills");
23451
+ return path8.join(this.personaDir(personaId), ".claude", "skills");
23342
23452
  }
23343
23453
  list() {
23344
23454
  if (!fs6.existsSync(this.root)) return [];
23345
23455
  return fs6.readdirSync(this.root).filter((name) => {
23346
- return fs6.existsSync(path7.join(this.root, name, ".clawd", "persona.json"));
23456
+ return fs6.existsSync(path8.join(this.root, name, ".clawd", "persona.json"));
23347
23457
  });
23348
23458
  }
23349
23459
  remove(personaId) {
@@ -23742,7 +23852,17 @@ var PersonaManager = class {
23742
23852
  }
23743
23853
  /**
23744
23854
  * 删除 persona。
23745
- * PersonaStore.remove(personaId) 已级联删除整个 <personaRoot>/<personaId>/ 目录。
23855
+ * PersonaStore.remove(personaId) 已级联删除整个 <personaRoot>/<personaId>/ 目录,
23856
+ * Phase 2 capability platform 新布局下含 .clawd/sessions/owner/ +
23857
+ * .clawd/sessions/guests/<capId>/, rmSync recursive force 一锅清.
23858
+ *
23859
+ * ⚠️ TODO (Phase 3+ design gap, reviewer P1 flagged):
23860
+ * ~/.clawd/capabilities.json 里若有 cap.grants 含本 personaId, grant 会变成
23861
+ * 悬空引用 (guest 仍能持 token 接入, 但调依赖该 persona 的 RPC 会 fail).
23862
+ * 选项: (A) 这里扫所有 cap 过滤掉该 personaId 的 grant; (B) revoke 所有 grant
23863
+ * 含该 personaId 的 cap. 当前因 cleanupGuestSessionsForCapability 用 rmSync
23864
+ * force=true 吞 ENOENT 不会 crash, 但 UI CapabilityManagerDrawer 会展示
23865
+ * "无效的 persona" grant. Phase 3 加 cross-reference 矩阵后正式实现.
23746
23866
  */
23747
23867
  delete(personaId) {
23748
23868
  this.deps.store.remove(personaId);
@@ -23807,7 +23927,7 @@ var PersonaManager = class {
23807
23927
 
23808
23928
  // src/persona/seed.ts
23809
23929
  var fs8 = __toESM(require("fs"), 1);
23810
- var path9 = __toESM(require("path"), 1);
23930
+ var path10 = __toESM(require("path"), 1);
23811
23931
  var import_node_url = require("url");
23812
23932
  var import_meta = {};
23813
23933
  var DEFAULT_PERSONAS = [
@@ -23843,14 +23963,14 @@ var DEFAULT_PERSONAS = [
23843
23963
  function findDefaultsRoot() {
23844
23964
  const candidates = [];
23845
23965
  try {
23846
- const here = path9.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
23847
- candidates.push(path9.resolve(here, "defaults"));
23848
- candidates.push(path9.resolve(here, "persona-defaults"));
23966
+ const here = path10.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
23967
+ candidates.push(path10.resolve(here, "defaults"));
23968
+ candidates.push(path10.resolve(here, "persona-defaults"));
23849
23969
  } catch {
23850
23970
  }
23851
23971
  if (process.argv[1]) {
23852
- const argvDir = path9.dirname(process.argv[1]);
23853
- candidates.push(path9.resolve(argvDir, "persona-defaults"));
23972
+ const argvDir = path10.dirname(process.argv[1]);
23973
+ candidates.push(path10.resolve(argvDir, "persona-defaults"));
23854
23974
  }
23855
23975
  for (const c of candidates) {
23856
23976
  try {
@@ -23867,7 +23987,7 @@ function seedDefaultPersonas(args) {
23867
23987
  args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
23868
23988
  continue;
23869
23989
  }
23870
- const bundleDir = path9.join(args.defaultsRoot, entry.personaId);
23990
+ const bundleDir = path10.join(args.defaultsRoot, entry.personaId);
23871
23991
  if (!fs8.existsSync(bundleDir)) {
23872
23992
  args.logger.warn("persona.seed.skip", {
23873
23993
  personaId: entry.personaId,
@@ -23876,7 +23996,7 @@ function seedDefaultPersonas(args) {
23876
23996
  });
23877
23997
  continue;
23878
23998
  }
23879
- const claudeMdPath = path9.join(bundleDir, "CLAUDE.md");
23999
+ const claudeMdPath = path10.join(bundleDir, "CLAUDE.md");
23880
24000
  if (!fs8.existsSync(claudeMdPath)) {
23881
24001
  args.logger.warn("persona.seed.skip", {
23882
24002
  personaId: entry.personaId,
@@ -23905,8 +24025,8 @@ function seedDefaultPersonas(args) {
23905
24025
  function copyBundleExtras(srcDir, dstDir) {
23906
24026
  for (const entry of fs8.readdirSync(srcDir, { withFileTypes: true })) {
23907
24027
  if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
23908
- const srcPath = path9.join(srcDir, entry.name);
23909
- const dstPath = path9.join(dstDir, entry.name);
24028
+ const srcPath = path10.join(srcDir, entry.name);
24029
+ const dstPath = path10.join(dstDir, entry.name);
23910
24030
  if (entry.isDirectory()) {
23911
24031
  fs8.cpSync(srcPath, dstPath, { recursive: true, dereference: true });
23912
24032
  } else if (entry.isFile()) {
@@ -25792,7 +25912,7 @@ function authenticate(token, deps) {
25792
25912
 
25793
25913
  // src/permission/capability-store.ts
25794
25914
  var fs15 = __toESM(require("fs"), 1);
25795
- var path16 = __toESM(require("path"), 1);
25915
+ var path18 = __toESM(require("path"), 1);
25796
25916
  var CAPABILITIES_FILE_NAME = "capabilities.json";
25797
25917
  var FILE_VERSION = 1;
25798
25918
  var CapabilityStore = class {
@@ -25822,7 +25942,7 @@ var CapabilityStore = class {
25822
25942
  this.flush();
25823
25943
  }
25824
25944
  filePath() {
25825
- return path16.join(this.dataDir, CAPABILITIES_FILE_NAME);
25945
+ return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
25826
25946
  }
25827
25947
  readFromDisk() {
25828
25948
  const file = this.filePath();
@@ -25976,6 +26096,115 @@ function sha256Hex2(s) {
25976
26096
  return crypto5.createHash("sha256").update(s).digest("hex");
25977
26097
  }
25978
26098
 
26099
+ // src/permission/cleanup.ts
26100
+ var fs16 = __toESM(require("fs"), 1);
26101
+ function cleanupGuestSessionsForCapability(cap, factory) {
26102
+ const removed = [];
26103
+ for (const g2 of cap.grants) {
26104
+ if (g2.resource.type !== "persona") continue;
26105
+ const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
26106
+ try {
26107
+ fs16.rmSync(dir, { recursive: true, force: true });
26108
+ removed.push(dir);
26109
+ } catch {
26110
+ }
26111
+ }
26112
+ return { removed };
26113
+ }
26114
+
26115
+ // src/migrations/2026-05-20-flatten-sessions.ts
26116
+ var fs17 = __toESM(require("fs"), 1);
26117
+ var path19 = __toESM(require("path"), 1);
26118
+ var MIGRATION_FLAG_NAME = ".migration.v1.done";
26119
+ function migrateFlattenSessions(opts) {
26120
+ const dataDir = opts.dataDir;
26121
+ const now = opts.now ?? Date.now;
26122
+ const sessionsDir = path19.join(dataDir, "sessions");
26123
+ const flagPath = path19.join(sessionsDir, MIGRATION_FLAG_NAME);
26124
+ if (existsSync3(flagPath)) {
26125
+ return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
26126
+ }
26127
+ let movedBare = 0;
26128
+ let movedVmOwner = 0;
26129
+ let archivedListener = 0;
26130
+ const defaultDir = path19.join(sessionsDir, "default");
26131
+ if (existsSync3(defaultDir)) {
26132
+ for (const entry of readdirSafe(defaultDir)) {
26133
+ if (!entry.endsWith(".json")) continue;
26134
+ const src = path19.join(defaultDir, entry);
26135
+ const dst = path19.join(sessionsDir, entry);
26136
+ fs17.renameSync(src, dst);
26137
+ movedBare += 1;
26138
+ }
26139
+ rmdirIfEmpty(defaultDir);
26140
+ }
26141
+ for (const pid of readdirSafe(sessionsDir)) {
26142
+ const personaDir = path19.join(sessionsDir, pid);
26143
+ if (!isDir(personaDir)) continue;
26144
+ if (pid === "default") continue;
26145
+ const ownerSrc = path19.join(personaDir, "owner");
26146
+ if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
26147
+ const ownerDst = path19.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
26148
+ fs17.mkdirSync(ownerDst, { recursive: true });
26149
+ for (const file of readdirSafe(ownerSrc)) {
26150
+ if (!file.endsWith(".json")) continue;
26151
+ fs17.renameSync(path19.join(ownerSrc, file), path19.join(ownerDst, file));
26152
+ movedVmOwner += 1;
26153
+ }
26154
+ rmdirIfEmpty(ownerSrc);
26155
+ }
26156
+ const listenerSrc = path19.join(personaDir, "listener");
26157
+ if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
26158
+ const archiveDst = path19.join(dataDir, ".legacy", `listener-${pid}`);
26159
+ fs17.mkdirSync(archiveDst, { recursive: true });
26160
+ for (const file of readdirSafe(listenerSrc)) {
26161
+ if (!file.endsWith(".json")) continue;
26162
+ fs17.renameSync(path19.join(listenerSrc, file), path19.join(archiveDst, file));
26163
+ archivedListener += 1;
26164
+ }
26165
+ rmdirIfEmpty(listenerSrc);
26166
+ }
26167
+ rmdirIfEmpty(personaDir);
26168
+ }
26169
+ fs17.mkdirSync(sessionsDir, { recursive: true });
26170
+ fs17.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
26171
+ return {
26172
+ skipped: false,
26173
+ flagWritten: true,
26174
+ movedBare,
26175
+ movedVmOwner,
26176
+ archivedListener
26177
+ };
26178
+ }
26179
+ function existsSync3(p2) {
26180
+ try {
26181
+ fs17.statSync(p2);
26182
+ return true;
26183
+ } catch {
26184
+ return false;
26185
+ }
26186
+ }
26187
+ function isDir(p2) {
26188
+ try {
26189
+ return fs17.statSync(p2).isDirectory();
26190
+ } catch {
26191
+ return false;
26192
+ }
26193
+ }
26194
+ function readdirSafe(p2) {
26195
+ try {
26196
+ return fs17.readdirSync(p2);
26197
+ } catch {
26198
+ return [];
26199
+ }
26200
+ }
26201
+ function rmdirIfEmpty(p2) {
26202
+ try {
26203
+ fs17.rmdirSync(p2);
26204
+ } catch {
26205
+ }
26206
+ }
26207
+
25979
26208
  // src/transport/http-router.ts
25980
26209
  var import_node_fs14 = __toESM(require("fs"), 1);
25981
26210
  var import_node_path16 = __toESM(require("path"), 1);
@@ -28213,6 +28442,13 @@ async function startDaemon(config) {
28213
28442
  revokedAt: cap.revokedAt
28214
28443
  });
28215
28444
  wsServer?.closeConnectionsByCapability(cap.id);
28445
+ const cleanup = cleanupGuestSessionsForCapability(cap, sessionStoreFactory);
28446
+ if (cleanup.removed.length > 0) {
28447
+ logger.info("capability revoke cascade: guest sessions removed", {
28448
+ capabilityId: cap.id,
28449
+ removedDirs: cleanup.removed
28450
+ });
28451
+ }
28216
28452
  }
28217
28453
  });
28218
28454
  let wsServer = null;
@@ -28231,7 +28467,16 @@ async function startDaemon(config) {
28231
28467
  sendOk: (h, payload) => wsServer?.sendToClient(h.id, payload)
28232
28468
  }) : null;
28233
28469
  resetRegistry();
28234
- const store = new SessionStore({ dataDir: config.dataDir });
28470
+ const migrateResult = migrateFlattenSessions({ dataDir: config.dataDir });
28471
+ if (!migrateResult.skipped && (migrateResult.movedBare || migrateResult.movedVmOwner || migrateResult.archivedListener)) {
28472
+ logger.info("sessions migration applied", {
28473
+ movedBare: migrateResult.movedBare,
28474
+ movedVmOwner: migrateResult.movedVmOwner,
28475
+ archivedListener: migrateResult.archivedListener
28476
+ });
28477
+ }
28478
+ const sessionStoreFactory = new SessionStoreFactory({ dataDir: config.dataDir });
28479
+ const store = sessionStoreFactory.forBare();
28235
28480
  const workspace = new WorkspaceBrowser();
28236
28481
  const skills = new SkillsScanner();
28237
28482
  const agents = new AgentsScanner();
@@ -28248,6 +28493,9 @@ async function startDaemon(config) {
28248
28493
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
28249
28494
  const manager = new SessionManager({
28250
28495
  store,
28496
+ // Phase 2 (capability platform plan §1): factory 注入后 manager.storeFor 走
28497
+ // 新布局派生 (sessions/* + personas/<pid>/.clawd/sessions/owner/*)
28498
+ storeFactory: sessionStoreFactory,
28251
28499
  logger,
28252
28500
  getAdapter,
28253
28501
  historyReader: history,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.71-beta.123.6a5ed6f",
3
+ "version": "0.2.71-beta.124.b09b0a0",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",