@clawos-dev/clawd 0.2.142-beta.298.934a65b → 0.2.143-beta.300.c2a3792

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 (48) hide show
  1. package/dist/cli.cjs +664 -1367
  2. package/dist/persona-defaults/persona-app-builder/CLAUDE.md +0 -3
  3. package/dist/persona-defaults/persona-bug-fixer/CLAUDE.md +0 -2
  4. package/dist/persona-defaults/persona-dataclaw-builder/.mcp.json +4 -0
  5. package/dist/persona-defaults/persona-dataclaw-builder/.secrets/dataclaw.env.example +3 -0
  6. package/dist/persona-defaults/persona-dataclaw-builder/CLAUDE.md +20 -0
  7. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/README.md +96 -0
  8. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/config.env +20 -0
  9. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/contract/bootstrap +22 -0
  10. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/contract/s.yaml.tmpl +59 -0
  11. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/.env.example +15 -0
  12. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/.fcignore +7 -0
  13. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/nest-cli.json +8 -0
  14. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/package.json +29 -0
  15. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/app.module.ts +13 -0
  16. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/auth/gate.ts +70 -0
  17. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/auth/session.ts +52 -0
  18. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/auth/ttc-user-info.ts +23 -0
  19. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/dataclaw/dataclaw.client.ts +83 -0
  20. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/dataclaw/dataclaw.config.ts +18 -0
  21. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/dataclaw/dataclaw.controller.ts +30 -0
  22. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/dataclaw/dataclaw.module.ts +9 -0
  23. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/main.ts +116 -0
  24. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/src/polyfill.ts +6 -0
  25. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/server/tsconfig.json +14 -0
  26. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/index.html +12 -0
  27. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/package.json +18 -0
  28. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/App.jsx +9 -0
  29. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/api.js +19 -0
  30. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/auth.js +7 -0
  31. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/components/BarChart.jsx +38 -0
  32. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/components/FilterRow.jsx +79 -0
  33. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/components/ResultCards.jsx +17 -0
  34. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/components/ResultTable.jsx +21 -0
  35. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/components/SchemaFilters.jsx +93 -0
  36. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/enums.js +22 -0
  37. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/main.jsx +6 -0
  38. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/pages/PerformanceQueryPage.jsx +102 -0
  39. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/src/styles.css +83 -0
  40. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/examples/nestjs-react/web/vite.config.js +30 -0
  41. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/scripts/ensure-toolchain.sh +62 -0
  42. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/scripts/new-extension.sh +66 -0
  43. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/scripts/publish.sh +129 -0
  44. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/scripts/remove-extension.sh +70 -0
  45. package/dist/persona-defaults/persona-dataclaw-builder/extension-kit/scripts/verify.sh +38 -0
  46. package/dist/persona-defaults/persona-developer/CLAUDE.md +0 -2
  47. package/package.json +2 -5
  48. package/dist/dispatch/mcp-server.cjs +0 -39756
package/dist/cli.cjs CHANGED
@@ -720,8 +720,8 @@ var init_parseUtil = __esm({
720
720
  init_errors2();
721
721
  init_en();
722
722
  makeIssue = (params) => {
723
- const { data, path: path59, errorMaps, issueData } = params;
724
- const fullPath = [...path59, ...issueData.path || []];
723
+ const { data, path: path58, errorMaps, issueData } = params;
724
+ const fullPath = [...path58, ...issueData.path || []];
725
725
  const fullIssue = {
726
726
  ...issueData,
727
727
  path: fullPath
@@ -1032,11 +1032,11 @@ var init_types = __esm({
1032
1032
  init_parseUtil();
1033
1033
  init_util();
1034
1034
  ParseInputLazyPath = class {
1035
- constructor(parent, value, path59, key) {
1035
+ constructor(parent, value, path58, key) {
1036
1036
  this._cachedPath = [];
1037
1037
  this.parent = parent;
1038
1038
  this.data = value;
1039
- this._path = path59;
1039
+ this._path = path58;
1040
1040
  this._key = key;
1041
1041
  }
1042
1042
  get path() {
@@ -4752,13 +4752,6 @@ var init_schemas = __esm({
4752
4752
  * - native `session:*` handler 完全不感知 mirror(UI 操作 mirror 不走 native 路径)
4753
4753
  */
4754
4754
  originOwnerPrincipalId: external_exports.string().min(1).optional(),
4755
- /**
4756
- * Dispatch 派生的 session 在 create 时记录源 session 的 sessionId(稳定 key);
4757
- * sidebar 据此把 dispatch 出来的 sub-session 折叠在源 session 下。非 dispatch session 缺省。
4758
- * mirror SessionFile 上必须 strip(朋友 daemon 上的 sessionId 在本机无意义,会让本机
4759
- * 反查路径走错;按 #750 一族防线处理,跟 ownerPersonaId 同地点 strip)。
4760
- */
4761
- dispatchedFromSessionId: external_exports.string().min(1).optional(),
4762
4755
  createdAt: external_exports.string().min(1),
4763
4756
  updatedAt: external_exports.string().min(1)
4764
4757
  });
@@ -5899,7 +5892,9 @@ var init_feishu_auth = __esm({
5899
5892
  /** 显示名。TTC user_info 接口 data.name */
5900
5893
  displayName: external_exports.string().min(1),
5901
5894
  /** TTC user_info 接口 data.avatar_url,可缺省 */
5902
- avatarUrl: external_exports.string().optional()
5895
+ avatarUrl: external_exports.string().optional(),
5896
+ /** TTC user_info 接口 data.union_id(飞书 union_id;dataclaw 可信入口 X-User-UnionId 用),可缺省 */
5897
+ unionId: external_exports.string().optional()
5903
5898
  });
5904
5899
  AuthLoginStartResponseSchema = external_exports.object({
5905
5900
  type: external_exports.literal("auth:login:start:ok"),
@@ -5933,60 +5928,6 @@ var init_feishu_auth = __esm({
5933
5928
  }
5934
5929
  });
5935
5930
 
5936
- // ../protocol/src/dispatch.ts
5937
- var DispatchOutcomeSchema, DispatchRunArgsSchema, DispatchCompleteArgsSchema;
5938
- var init_dispatch = __esm({
5939
- "../protocol/src/dispatch.ts"() {
5940
- "use strict";
5941
- init_zod();
5942
- DispatchOutcomeSchema = external_exports.discriminatedUnion("kind", [
5943
- external_exports.object({
5944
- kind: external_exports.literal("success"),
5945
- text: external_exports.string(),
5946
- filePaths: external_exports.array(external_exports.string()).optional()
5947
- }),
5948
- external_exports.object({
5949
- kind: external_exports.literal("failure"),
5950
- reason: external_exports.string()
5951
- })
5952
- ]);
5953
- DispatchRunArgsSchema = external_exports.object({
5954
- targetPersona: external_exports.string().min(1),
5955
- prompt: external_exports.string()
5956
- });
5957
- DispatchCompleteArgsSchema = external_exports.object({
5958
- dispatchId: external_exports.string().min(1),
5959
- outcome: DispatchOutcomeSchema
5960
- });
5961
- }
5962
- });
5963
-
5964
- // ../protocol/src/log.ts
5965
- var LOG_SOURCES, LogSourceSchema, LOG_LEVELS, LogLevelSchema, LogRecordSchema;
5966
- var init_log = __esm({
5967
- "../protocol/src/log.ts"() {
5968
- "use strict";
5969
- init_zod();
5970
- LOG_SOURCES = ["daemon", "main", "renderer"];
5971
- LogSourceSchema = external_exports.enum(LOG_SOURCES);
5972
- LOG_LEVELS = ["debug", "info", "warn", "error"];
5973
- LogLevelSchema = external_exports.enum(LOG_LEVELS);
5974
- LogRecordSchema = external_exports.object({
5975
- ts: external_exports.number().int(),
5976
- source: LogSourceSchema,
5977
- level: LogLevelSchema,
5978
- msg: external_exports.string(),
5979
- ownerPrincipalId: external_exports.string(),
5980
- deviceId: external_exports.string(),
5981
- appVersion: external_exports.string(),
5982
- daemonVersion: external_exports.string().optional(),
5983
- os: external_exports.string(),
5984
- meta_json: external_exports.string().optional(),
5985
- sessionId: external_exports.string().optional()
5986
- });
5987
- }
5988
- });
5989
-
5990
5931
  // ../protocol/src/runtime.ts
5991
5932
  var init_runtime = __esm({
5992
5933
  "../protocol/src/runtime.ts"() {
@@ -6005,8 +5946,6 @@ var init_runtime = __esm({
6005
5946
  init_contact();
6006
5947
  init_extension();
6007
5948
  init_feishu_auth();
6008
- init_dispatch();
6009
- init_log();
6010
5949
  }
6011
5950
  });
6012
5951
 
@@ -6281,8 +6220,8 @@ var require_req = __commonJS({
6281
6220
  if (req.originalUrl) {
6282
6221
  _req.url = req.originalUrl;
6283
6222
  } else {
6284
- const path59 = req.path;
6285
- _req.url = typeof path59 === "string" ? path59 : req.url ? req.url.path || req.url : void 0;
6223
+ const path58 = req.path;
6224
+ _req.url = typeof path58 === "string" ? path58 : req.url ? req.url.path || req.url : void 0;
6286
6225
  }
6287
6226
  if (req.query) {
6288
6227
  _req.query = req.query;
@@ -6447,14 +6386,14 @@ var require_redact = __commonJS({
6447
6386
  }
6448
6387
  return obj;
6449
6388
  }
6450
- function parsePath(path59) {
6389
+ function parsePath(path58) {
6451
6390
  const parts = [];
6452
6391
  let current = "";
6453
6392
  let inBrackets = false;
6454
6393
  let inQuotes = false;
6455
6394
  let quoteChar = "";
6456
- for (let i = 0; i < path59.length; i++) {
6457
- const char = path59[i];
6395
+ for (let i = 0; i < path58.length; i++) {
6396
+ const char = path58[i];
6458
6397
  if (!inBrackets && char === ".") {
6459
6398
  if (current) {
6460
6399
  parts.push(current);
@@ -6585,10 +6524,10 @@ var require_redact = __commonJS({
6585
6524
  return current;
6586
6525
  }
6587
6526
  function redactPaths(obj, paths, censor, remove = false) {
6588
- for (const path59 of paths) {
6589
- const parts = parsePath(path59);
6527
+ for (const path58 of paths) {
6528
+ const parts = parsePath(path58);
6590
6529
  if (parts.includes("*")) {
6591
- redactWildcardPath(obj, parts, censor, path59, remove);
6530
+ redactWildcardPath(obj, parts, censor, path58, remove);
6592
6531
  } else {
6593
6532
  if (remove) {
6594
6533
  removeKey(obj, parts);
@@ -6673,8 +6612,8 @@ var require_redact = __commonJS({
6673
6612
  }
6674
6613
  } else {
6675
6614
  if (afterWildcard.includes("*")) {
6676
- const wrappedCensor = typeof censor === "function" ? (value, path59) => {
6677
- const fullPath = [...pathArray.slice(0, pathLength), ...path59];
6615
+ const wrappedCensor = typeof censor === "function" ? (value, path58) => {
6616
+ const fullPath = [...pathArray.slice(0, pathLength), ...path58];
6678
6617
  return censor(value, fullPath);
6679
6618
  } : censor;
6680
6619
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6709,8 +6648,8 @@ var require_redact = __commonJS({
6709
6648
  return null;
6710
6649
  }
6711
6650
  const pathStructure = /* @__PURE__ */ new Map();
6712
- for (const path59 of pathsToClone) {
6713
- const parts = parsePath(path59);
6651
+ for (const path58 of pathsToClone) {
6652
+ const parts = parsePath(path58);
6714
6653
  let current = pathStructure;
6715
6654
  for (let i = 0; i < parts.length; i++) {
6716
6655
  const part = parts[i];
@@ -6762,24 +6701,24 @@ var require_redact = __commonJS({
6762
6701
  }
6763
6702
  return cloneSelectively(obj, pathStructure);
6764
6703
  }
6765
- function validatePath(path59) {
6766
- if (typeof path59 !== "string") {
6704
+ function validatePath(path58) {
6705
+ if (typeof path58 !== "string") {
6767
6706
  throw new Error("Paths must be (non-empty) strings");
6768
6707
  }
6769
- if (path59 === "") {
6708
+ if (path58 === "") {
6770
6709
  throw new Error("Invalid redaction path ()");
6771
6710
  }
6772
- if (path59.includes("..")) {
6773
- throw new Error(`Invalid redaction path (${path59})`);
6711
+ if (path58.includes("..")) {
6712
+ throw new Error(`Invalid redaction path (${path58})`);
6774
6713
  }
6775
- if (path59.includes(",")) {
6776
- throw new Error(`Invalid redaction path (${path59})`);
6714
+ if (path58.includes(",")) {
6715
+ throw new Error(`Invalid redaction path (${path58})`);
6777
6716
  }
6778
6717
  let bracketCount = 0;
6779
6718
  let inQuotes = false;
6780
6719
  let quoteChar = "";
6781
- for (let i = 0; i < path59.length; i++) {
6782
- const char = path59[i];
6720
+ for (let i = 0; i < path58.length; i++) {
6721
+ const char = path58[i];
6783
6722
  if ((char === '"' || char === "'") && bracketCount > 0) {
6784
6723
  if (!inQuotes) {
6785
6724
  inQuotes = true;
@@ -6793,20 +6732,20 @@ var require_redact = __commonJS({
6793
6732
  } else if (char === "]" && !inQuotes) {
6794
6733
  bracketCount--;
6795
6734
  if (bracketCount < 0) {
6796
- throw new Error(`Invalid redaction path (${path59})`);
6735
+ throw new Error(`Invalid redaction path (${path58})`);
6797
6736
  }
6798
6737
  }
6799
6738
  }
6800
6739
  if (bracketCount !== 0) {
6801
- throw new Error(`Invalid redaction path (${path59})`);
6740
+ throw new Error(`Invalid redaction path (${path58})`);
6802
6741
  }
6803
6742
  }
6804
6743
  function validatePaths(paths) {
6805
6744
  if (!Array.isArray(paths)) {
6806
6745
  throw new TypeError("paths must be an array");
6807
6746
  }
6808
- for (const path59 of paths) {
6809
- validatePath(path59);
6747
+ for (const path58 of paths) {
6748
+ validatePath(path58);
6810
6749
  }
6811
6750
  }
6812
6751
  function slowRedact(options = {}) {
@@ -6974,8 +6913,8 @@ var require_redaction = __commonJS({
6974
6913
  if (shape[k2] === null) {
6975
6914
  o[k2] = (value) => topCensor(value, [k2]);
6976
6915
  } else {
6977
- const wrappedCensor = typeof censor === "function" ? (value, path59) => {
6978
- return censor(value, [k2, ...path59]);
6916
+ const wrappedCensor = typeof censor === "function" ? (value, path58) => {
6917
+ return censor(value, [k2, ...path58]);
6979
6918
  } : censor;
6980
6919
  o[k2] = Redact({
6981
6920
  paths: shape[k2],
@@ -7159,7 +7098,7 @@ var require_atomic_sleep = __commonJS({
7159
7098
  "../node_modules/.pnpm/atomic-sleep@1.0.0/node_modules/atomic-sleep/index.js"(exports2, module2) {
7160
7099
  "use strict";
7161
7100
  if (typeof SharedArrayBuffer !== "undefined" && typeof Atomics !== "undefined") {
7162
- let sleep2 = function(ms) {
7101
+ let sleep = function(ms) {
7163
7102
  const valid = ms > 0 && ms < Infinity;
7164
7103
  if (valid === false) {
7165
7104
  if (typeof ms !== "number" && typeof ms !== "bigint") {
@@ -7170,9 +7109,9 @@ var require_atomic_sleep = __commonJS({
7170
7109
  Atomics.wait(nil, 0, 0, Number(ms));
7171
7110
  };
7172
7111
  const nil = new Int32Array(new SharedArrayBuffer(4));
7173
- module2.exports = sleep2;
7112
+ module2.exports = sleep;
7174
7113
  } else {
7175
- let sleep2 = function(ms) {
7114
+ let sleep = function(ms) {
7176
7115
  const valid = ms > 0 && ms < Infinity;
7177
7116
  if (valid === false) {
7178
7117
  if (typeof ms !== "number" && typeof ms !== "bigint") {
@@ -7184,7 +7123,7 @@ var require_atomic_sleep = __commonJS({
7184
7123
  while (target > Date.now()) {
7185
7124
  }
7186
7125
  };
7187
- module2.exports = sleep2;
7126
+ module2.exports = sleep;
7188
7127
  }
7189
7128
  }
7190
7129
  });
@@ -7193,11 +7132,11 @@ var require_atomic_sleep = __commonJS({
7193
7132
  var require_sonic_boom = __commonJS({
7194
7133
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
7195
7134
  "use strict";
7196
- var fs52 = require("fs");
7135
+ var fs51 = require("fs");
7197
7136
  var EventEmitter3 = require("events");
7198
7137
  var inherits = require("util").inherits;
7199
- var path59 = require("path");
7200
- var sleep2 = require_atomic_sleep();
7138
+ var path58 = require("path");
7139
+ var sleep = require_atomic_sleep();
7201
7140
  var assert = require("assert");
7202
7141
  var BUSY_WRITE_TIMEOUT = 100;
7203
7142
  var kEmptyBuffer = Buffer.allocUnsafe(0);
@@ -7250,20 +7189,20 @@ var require_sonic_boom = __commonJS({
7250
7189
  const mode = sonic.mode;
7251
7190
  if (sonic.sync) {
7252
7191
  try {
7253
- if (sonic.mkdir) fs52.mkdirSync(path59.dirname(file), { recursive: true });
7254
- const fd = fs52.openSync(file, flags, mode);
7192
+ if (sonic.mkdir) fs51.mkdirSync(path58.dirname(file), { recursive: true });
7193
+ const fd = fs51.openSync(file, flags, mode);
7255
7194
  fileOpened(null, fd);
7256
7195
  } catch (err) {
7257
7196
  fileOpened(err);
7258
7197
  throw err;
7259
7198
  }
7260
7199
  } else if (sonic.mkdir) {
7261
- fs52.mkdir(path59.dirname(file), { recursive: true }, (err) => {
7200
+ fs51.mkdir(path58.dirname(file), { recursive: true }, (err) => {
7262
7201
  if (err) return fileOpened(err);
7263
- fs52.open(file, flags, mode, fileOpened);
7202
+ fs51.open(file, flags, mode, fileOpened);
7264
7203
  });
7265
7204
  } else {
7266
- fs52.open(file, flags, mode, fileOpened);
7205
+ fs51.open(file, flags, mode, fileOpened);
7267
7206
  }
7268
7207
  }
7269
7208
  function SonicBoom(opts) {
@@ -7304,8 +7243,8 @@ var require_sonic_boom = __commonJS({
7304
7243
  this.flush = flushBuffer;
7305
7244
  this.flushSync = flushBufferSync;
7306
7245
  this._actualWrite = actualWriteBuffer;
7307
- fsWriteSync = () => fs52.writeSync(this.fd, this._writingBuf);
7308
- fsWrite = () => fs52.write(this.fd, this._writingBuf, this.release);
7246
+ fsWriteSync = () => fs51.writeSync(this.fd, this._writingBuf);
7247
+ fsWrite = () => fs51.write(this.fd, this._writingBuf, this.release);
7309
7248
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
7310
7249
  this._writingBuf = "";
7311
7250
  this.write = write;
@@ -7314,15 +7253,15 @@ var require_sonic_boom = __commonJS({
7314
7253
  this._actualWrite = actualWrite;
7315
7254
  fsWriteSync = () => {
7316
7255
  if (Buffer.isBuffer(this._writingBuf)) {
7317
- return fs52.writeSync(this.fd, this._writingBuf);
7256
+ return fs51.writeSync(this.fd, this._writingBuf);
7318
7257
  }
7319
- return fs52.writeSync(this.fd, this._writingBuf, "utf8");
7258
+ return fs51.writeSync(this.fd, this._writingBuf, "utf8");
7320
7259
  };
7321
7260
  fsWrite = () => {
7322
7261
  if (Buffer.isBuffer(this._writingBuf)) {
7323
- return fs52.write(this.fd, this._writingBuf, this.release);
7262
+ return fs51.write(this.fd, this._writingBuf, this.release);
7324
7263
  }
7325
- return fs52.write(this.fd, this._writingBuf, "utf8", this.release);
7264
+ return fs51.write(this.fd, this._writingBuf, "utf8", this.release);
7326
7265
  };
7327
7266
  } else {
7328
7267
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -7343,7 +7282,7 @@ var require_sonic_boom = __commonJS({
7343
7282
  if ((err.code === "EAGAIN" || err.code === "EBUSY") && this.retryEAGAIN(err, this._writingBuf.length, this._len - this._writingBuf.length)) {
7344
7283
  if (this.sync) {
7345
7284
  try {
7346
- sleep2(BUSY_WRITE_TIMEOUT);
7285
+ sleep(BUSY_WRITE_TIMEOUT);
7347
7286
  this.release(void 0, 0);
7348
7287
  } catch (err2) {
7349
7288
  this.release(err2);
@@ -7379,7 +7318,7 @@ var require_sonic_boom = __commonJS({
7379
7318
  }
7380
7319
  }
7381
7320
  if (this._fsync) {
7382
- fs52.fsyncSync(this.fd);
7321
+ fs51.fsyncSync(this.fd);
7383
7322
  }
7384
7323
  const len = this._len;
7385
7324
  if (this._reopening) {
@@ -7493,7 +7432,7 @@ var require_sonic_boom = __commonJS({
7493
7432
  const onDrain = () => {
7494
7433
  if (!this._fsync) {
7495
7434
  try {
7496
- fs52.fsync(this.fd, (err) => {
7435
+ fs51.fsync(this.fd, (err) => {
7497
7436
  this._flushPending = false;
7498
7437
  cb(err);
7499
7438
  });
@@ -7595,7 +7534,7 @@ var require_sonic_boom = __commonJS({
7595
7534
  const fd = this.fd;
7596
7535
  this.once("ready", () => {
7597
7536
  if (fd !== this.fd) {
7598
- fs52.close(fd, (err) => {
7537
+ fs51.close(fd, (err) => {
7599
7538
  if (err) {
7600
7539
  return this.emit("error", err);
7601
7540
  }
@@ -7644,7 +7583,7 @@ var require_sonic_boom = __commonJS({
7644
7583
  buf = this._bufs[0];
7645
7584
  }
7646
7585
  try {
7647
- const n = Buffer.isBuffer(buf) ? fs52.writeSync(this.fd, buf) : fs52.writeSync(this.fd, buf, "utf8");
7586
+ const n = Buffer.isBuffer(buf) ? fs51.writeSync(this.fd, buf) : fs51.writeSync(this.fd, buf, "utf8");
7648
7587
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
7649
7588
  buf = releasedBufObj.writingBuf;
7650
7589
  this._len = releasedBufObj.len;
@@ -7656,11 +7595,11 @@ var require_sonic_boom = __commonJS({
7656
7595
  if (shouldRetry && !this.retryEAGAIN(err, buf.length, this._len - buf.length)) {
7657
7596
  throw err;
7658
7597
  }
7659
- sleep2(BUSY_WRITE_TIMEOUT);
7598
+ sleep(BUSY_WRITE_TIMEOUT);
7660
7599
  }
7661
7600
  }
7662
7601
  try {
7663
- fs52.fsyncSync(this.fd);
7602
+ fs51.fsyncSync(this.fd);
7664
7603
  } catch {
7665
7604
  }
7666
7605
  }
@@ -7681,7 +7620,7 @@ var require_sonic_boom = __commonJS({
7681
7620
  buf = mergeBuf(this._bufs[0], this._lens[0]);
7682
7621
  }
7683
7622
  try {
7684
- const n = fs52.writeSync(this.fd, buf);
7623
+ const n = fs51.writeSync(this.fd, buf);
7685
7624
  buf = buf.subarray(n);
7686
7625
  this._len = Math.max(this._len - n, 0);
7687
7626
  if (buf.length <= 0) {
@@ -7693,7 +7632,7 @@ var require_sonic_boom = __commonJS({
7693
7632
  if (shouldRetry && !this.retryEAGAIN(err, buf.length, this._len - buf.length)) {
7694
7633
  throw err;
7695
7634
  }
7696
- sleep2(BUSY_WRITE_TIMEOUT);
7635
+ sleep(BUSY_WRITE_TIMEOUT);
7697
7636
  }
7698
7637
  }
7699
7638
  }
@@ -7709,13 +7648,13 @@ var require_sonic_boom = __commonJS({
7709
7648
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
7710
7649
  if (this.sync) {
7711
7650
  try {
7712
- const written = Buffer.isBuffer(this._writingBuf) ? fs52.writeSync(this.fd, this._writingBuf) : fs52.writeSync(this.fd, this._writingBuf, "utf8");
7651
+ const written = Buffer.isBuffer(this._writingBuf) ? fs51.writeSync(this.fd, this._writingBuf) : fs51.writeSync(this.fd, this._writingBuf, "utf8");
7713
7652
  release(null, written);
7714
7653
  } catch (err) {
7715
7654
  release(err);
7716
7655
  }
7717
7656
  } else {
7718
- fs52.write(this.fd, this._writingBuf, release);
7657
+ fs51.write(this.fd, this._writingBuf, release);
7719
7658
  }
7720
7659
  }
7721
7660
  function actualWriteBuffer() {
@@ -7724,7 +7663,7 @@ var require_sonic_boom = __commonJS({
7724
7663
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
7725
7664
  if (this.sync) {
7726
7665
  try {
7727
- const written = fs52.writeSync(this.fd, this._writingBuf);
7666
+ const written = fs51.writeSync(this.fd, this._writingBuf);
7728
7667
  release(null, written);
7729
7668
  } catch (err) {
7730
7669
  release(err);
@@ -7733,7 +7672,7 @@ var require_sonic_boom = __commonJS({
7733
7672
  if (kCopyBuffer) {
7734
7673
  this._writingBuf = Buffer.from(this._writingBuf);
7735
7674
  }
7736
- fs52.write(this.fd, this._writingBuf, release);
7675
+ fs51.write(this.fd, this._writingBuf, release);
7737
7676
  }
7738
7677
  }
7739
7678
  function actualClose(sonic) {
@@ -7749,12 +7688,12 @@ var require_sonic_boom = __commonJS({
7749
7688
  sonic._lens = [];
7750
7689
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
7751
7690
  try {
7752
- fs52.fsync(sonic.fd, closeWrapped);
7691
+ fs51.fsync(sonic.fd, closeWrapped);
7753
7692
  } catch {
7754
7693
  }
7755
7694
  function closeWrapped() {
7756
7695
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7757
- fs52.close(sonic.fd, done);
7696
+ fs51.close(sonic.fd, done);
7758
7697
  } else {
7759
7698
  done();
7760
7699
  }
@@ -8434,7 +8373,7 @@ var require_transport = __commonJS({
8434
8373
  var { createRequire } = require("module");
8435
8374
  var getCallers = require_caller();
8436
8375
  var { join: join15, isAbsolute: isAbsolute2, sep: sep2 } = require("path");
8437
- var sleep2 = require_atomic_sleep();
8376
+ var sleep = require_atomic_sleep();
8438
8377
  var onExit = require_on_exit_leak_free();
8439
8378
  var ThreadStream = require_thread_stream();
8440
8379
  function setupOnExit(stream) {
@@ -8468,7 +8407,7 @@ var require_transport = __commonJS({
8468
8407
  return;
8469
8408
  }
8470
8409
  stream.flushSync();
8471
- sleep2(100);
8410
+ sleep(100);
8472
8411
  stream.end();
8473
8412
  }
8474
8413
  return stream;
@@ -10118,7 +10057,7 @@ var require_multistream = __commonJS({
10118
10057
  var require_pino = __commonJS({
10119
10058
  "../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
10120
10059
  "use strict";
10121
- var os22 = require("os");
10060
+ var os21 = require("os");
10122
10061
  var stdSerializers = require_pino_std_serializers();
10123
10062
  var caller = require_caller();
10124
10063
  var redaction = require_redaction();
@@ -10165,7 +10104,7 @@ var require_pino = __commonJS({
10165
10104
  } = symbols;
10166
10105
  var { epochTime, nullTime } = time;
10167
10106
  var { pid } = process;
10168
- var hostname = os22.hostname();
10107
+ var hostname = os21.hostname();
10169
10108
  var defaultErrorSerializer = stdSerializers.err;
10170
10109
  var defaultOptions = {
10171
10110
  level: "info",
@@ -10889,11 +10828,11 @@ var init_lib = __esm({
10889
10828
  }
10890
10829
  }
10891
10830
  },
10892
- addToPath: function addToPath(path59, added, removed, oldPosInc, options) {
10893
- var last = path59.lastComponent;
10831
+ addToPath: function addToPath(path58, added, removed, oldPosInc, options) {
10832
+ var last = path58.lastComponent;
10894
10833
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10895
10834
  return {
10896
- oldPos: path59.oldPos + oldPosInc,
10835
+ oldPos: path58.oldPos + oldPosInc,
10897
10836
  lastComponent: {
10898
10837
  count: last.count + 1,
10899
10838
  added,
@@ -10903,7 +10842,7 @@ var init_lib = __esm({
10903
10842
  };
10904
10843
  } else {
10905
10844
  return {
10906
- oldPos: path59.oldPos + oldPosInc,
10845
+ oldPos: path58.oldPos + oldPosInc,
10907
10846
  lastComponent: {
10908
10847
  count: 1,
10909
10848
  added,
@@ -11349,10 +11288,10 @@ function attachmentToHistoryMessage(o, ts) {
11349
11288
  const memories = raw.map((m2) => {
11350
11289
  if (!m2 || typeof m2 !== "object") return null;
11351
11290
  const rec3 = m2;
11352
- const path59 = typeof rec3.path === "string" ? rec3.path : null;
11291
+ const path58 = typeof rec3.path === "string" ? rec3.path : null;
11353
11292
  const content = typeof rec3.content === "string" ? rec3.content : null;
11354
- if (!path59 || content == null) return null;
11355
- const entry = { path: path59, content };
11293
+ if (!path58 || content == null) return null;
11294
+ const entry = { path: path58, content };
11356
11295
  if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
11357
11296
  return entry;
11358
11297
  }).filter((m2) => m2 !== null);
@@ -11872,9 +11811,6 @@ function buildSpawnArgs(ctx) {
11872
11811
  if (ctx.addDirs) {
11873
11812
  for (const dir of ctx.addDirs) args.push("--add-dir", dir);
11874
11813
  }
11875
- if (ctx.dispatchMcpConfigPath) {
11876
- args.push("--mcp-config", ctx.dispatchMcpConfigPath);
11877
- }
11878
11814
  if (ctx.effort) args.push("--effort", ctx.effort);
11879
11815
  if (ctx.toolSessionId) args.push("--resume", ctx.toolSessionId);
11880
11816
  return args;
@@ -12154,10 +12090,10 @@ function parseAttachment(obj) {
12154
12090
  const memories = raw.map((m2) => {
12155
12091
  if (!m2 || typeof m2 !== "object") return null;
12156
12092
  const rec3 = m2;
12157
- const path59 = typeof rec3.path === "string" ? rec3.path : null;
12093
+ const path58 = typeof rec3.path === "string" ? rec3.path : null;
12158
12094
  const content = typeof rec3.content === "string" ? rec3.content : null;
12159
- if (!path59 || content == null) return null;
12160
- const out = { path: path59, content };
12095
+ if (!path58 || content == null) return null;
12096
+ const out = { path: path58, content };
12161
12097
  if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
12162
12098
  return out;
12163
12099
  }).filter((m2) => m2 !== null);
@@ -18187,7 +18123,7 @@ var require_validation = __commonJS({
18187
18123
  var require_receiver = __commonJS({
18188
18124
  "../node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/receiver.js"(exports2, module2) {
18189
18125
  "use strict";
18190
- var { Writable: Writable3 } = require("stream");
18126
+ var { Writable: Writable2 } = require("stream");
18191
18127
  var PerMessageDeflate2 = require_permessage_deflate();
18192
18128
  var {
18193
18129
  BINARY_TYPES,
@@ -18205,7 +18141,7 @@ var require_receiver = __commonJS({
18205
18141
  var GET_DATA = 4;
18206
18142
  var INFLATING = 5;
18207
18143
  var DEFER_EVENT = 6;
18208
- var Receiver2 = class extends Writable3 {
18144
+ var Receiver2 = class extends Writable2 {
18209
18145
  /**
18210
18146
  * Creates a Receiver instance.
18211
18147
  *
@@ -21468,7 +21404,7 @@ var require_stream_writable = __commonJS({
21468
21404
  "../node_modules/.pnpm/readable-stream@2.3.8/node_modules/readable-stream/lib/_stream_writable.js"(exports2, module2) {
21469
21405
  "use strict";
21470
21406
  var pna = require_process_nextick_args();
21471
- module2.exports = Writable3;
21407
+ module2.exports = Writable2;
21472
21408
  function CorkedRequest(state) {
21473
21409
  var _this = this;
21474
21410
  this.next = null;
@@ -21479,7 +21415,7 @@ var require_stream_writable = __commonJS({
21479
21415
  }
21480
21416
  var asyncWrite = !process.browser && ["v0.10", "v0.9."].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick;
21481
21417
  var Duplex;
21482
- Writable3.WritableState = WritableState;
21418
+ Writable2.WritableState = WritableState;
21483
21419
  var util2 = Object.create(require_util());
21484
21420
  util2.inherits = require_inherits();
21485
21421
  var internalUtil = {
@@ -21496,7 +21432,7 @@ var require_stream_writable = __commonJS({
21496
21432
  return Buffer2.isBuffer(obj) || obj instanceof OurUint8Array;
21497
21433
  }
21498
21434
  var destroyImpl = require_destroy();
21499
- util2.inherits(Writable3, Stream);
21435
+ util2.inherits(Writable2, Stream);
21500
21436
  function nop() {
21501
21437
  }
21502
21438
  function WritableState(options, stream) {
@@ -21561,10 +21497,10 @@ var require_stream_writable = __commonJS({
21561
21497
  var realHasInstance;
21562
21498
  if (typeof Symbol === "function" && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === "function") {
21563
21499
  realHasInstance = Function.prototype[Symbol.hasInstance];
21564
- Object.defineProperty(Writable3, Symbol.hasInstance, {
21500
+ Object.defineProperty(Writable2, Symbol.hasInstance, {
21565
21501
  value: function(object) {
21566
21502
  if (realHasInstance.call(this, object)) return true;
21567
- if (this !== Writable3) return false;
21503
+ if (this !== Writable2) return false;
21568
21504
  return object && object._writableState instanceof WritableState;
21569
21505
  }
21570
21506
  });
@@ -21573,10 +21509,10 @@ var require_stream_writable = __commonJS({
21573
21509
  return object instanceof this;
21574
21510
  };
21575
21511
  }
21576
- function Writable3(options) {
21512
+ function Writable2(options) {
21577
21513
  Duplex = Duplex || require_stream_duplex();
21578
- if (!realHasInstance.call(Writable3, this) && !(this instanceof Duplex)) {
21579
- return new Writable3(options);
21514
+ if (!realHasInstance.call(Writable2, this) && !(this instanceof Duplex)) {
21515
+ return new Writable2(options);
21580
21516
  }
21581
21517
  this._writableState = new WritableState(options, this);
21582
21518
  this.writable = true;
@@ -21588,7 +21524,7 @@ var require_stream_writable = __commonJS({
21588
21524
  }
21589
21525
  Stream.call(this);
21590
21526
  }
21591
- Writable3.prototype.pipe = function() {
21527
+ Writable2.prototype.pipe = function() {
21592
21528
  this.emit("error", new Error("Cannot pipe, not readable"));
21593
21529
  };
21594
21530
  function writeAfterEnd(stream, cb) {
@@ -21611,7 +21547,7 @@ var require_stream_writable = __commonJS({
21611
21547
  }
21612
21548
  return valid;
21613
21549
  }
21614
- Writable3.prototype.write = function(chunk, encoding, cb) {
21550
+ Writable2.prototype.write = function(chunk, encoding, cb) {
21615
21551
  var state = this._writableState;
21616
21552
  var ret = false;
21617
21553
  var isBuf = !state.objectMode && _isUint8Array(chunk);
@@ -21632,18 +21568,18 @@ var require_stream_writable = __commonJS({
21632
21568
  }
21633
21569
  return ret;
21634
21570
  };
21635
- Writable3.prototype.cork = function() {
21571
+ Writable2.prototype.cork = function() {
21636
21572
  var state = this._writableState;
21637
21573
  state.corked++;
21638
21574
  };
21639
- Writable3.prototype.uncork = function() {
21575
+ Writable2.prototype.uncork = function() {
21640
21576
  var state = this._writableState;
21641
21577
  if (state.corked) {
21642
21578
  state.corked--;
21643
21579
  if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
21644
21580
  }
21645
21581
  };
21646
- Writable3.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
21582
+ Writable2.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
21647
21583
  if (typeof encoding === "string") encoding = encoding.toLowerCase();
21648
21584
  if (!(["hex", "utf8", "utf-8", "ascii", "binary", "base64", "ucs2", "ucs-2", "utf16le", "utf-16le", "raw"].indexOf((encoding + "").toLowerCase()) > -1)) throw new TypeError("Unknown encoding: " + encoding);
21649
21585
  this._writableState.defaultEncoding = encoding;
@@ -21655,7 +21591,7 @@ var require_stream_writable = __commonJS({
21655
21591
  }
21656
21592
  return chunk;
21657
21593
  }
21658
- Object.defineProperty(Writable3.prototype, "writableHighWaterMark", {
21594
+ Object.defineProperty(Writable2.prototype, "writableHighWaterMark", {
21659
21595
  // making it explicit this property is not enumerable
21660
21596
  // because otherwise some prototype manipulation in
21661
21597
  // userland will fail
@@ -21801,11 +21737,11 @@ var require_stream_writable = __commonJS({
21801
21737
  state.bufferedRequest = entry;
21802
21738
  state.bufferProcessing = false;
21803
21739
  }
21804
- Writable3.prototype._write = function(chunk, encoding, cb) {
21740
+ Writable2.prototype._write = function(chunk, encoding, cb) {
21805
21741
  cb(new Error("_write() is not implemented"));
21806
21742
  };
21807
- Writable3.prototype._writev = null;
21808
- Writable3.prototype.end = function(chunk, encoding, cb) {
21743
+ Writable2.prototype._writev = null;
21744
+ Writable2.prototype.end = function(chunk, encoding, cb) {
21809
21745
  var state = this._writableState;
21810
21746
  if (typeof chunk === "function") {
21811
21747
  cb = chunk;
@@ -21880,7 +21816,7 @@ var require_stream_writable = __commonJS({
21880
21816
  }
21881
21817
  state.corkedRequestsFree.next = corkReq;
21882
21818
  }
21883
- Object.defineProperty(Writable3.prototype, "destroyed", {
21819
+ Object.defineProperty(Writable2.prototype, "destroyed", {
21884
21820
  get: function() {
21885
21821
  if (this._writableState === void 0) {
21886
21822
  return false;
@@ -21894,9 +21830,9 @@ var require_stream_writable = __commonJS({
21894
21830
  this._writableState.destroyed = value;
21895
21831
  }
21896
21832
  });
21897
- Writable3.prototype.destroy = destroyImpl.destroy;
21898
- Writable3.prototype._undestroy = destroyImpl.undestroy;
21899
- Writable3.prototype._destroy = function(err, cb) {
21833
+ Writable2.prototype.destroy = destroyImpl.destroy;
21834
+ Writable2.prototype._undestroy = destroyImpl.undestroy;
21835
+ Writable2.prototype._destroy = function(err, cb) {
21900
21836
  this.end();
21901
21837
  cb(err);
21902
21838
  };
@@ -21919,13 +21855,13 @@ var require_stream_duplex = __commonJS({
21919
21855
  var util2 = Object.create(require_util());
21920
21856
  util2.inherits = require_inherits();
21921
21857
  var Readable3 = require_stream_readable();
21922
- var Writable3 = require_stream_writable();
21858
+ var Writable2 = require_stream_writable();
21923
21859
  util2.inherits(Duplex, Readable3);
21924
21860
  {
21925
- keys = objectKeys(Writable3.prototype);
21861
+ keys = objectKeys(Writable2.prototype);
21926
21862
  for (v2 = 0; v2 < keys.length; v2++) {
21927
21863
  method = keys[v2];
21928
- if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable3.prototype[method];
21864
+ if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable2.prototype[method];
21929
21865
  }
21930
21866
  }
21931
21867
  var keys;
@@ -21934,7 +21870,7 @@ var require_stream_duplex = __commonJS({
21934
21870
  function Duplex(options) {
21935
21871
  if (!(this instanceof Duplex)) return new Duplex(options);
21936
21872
  Readable3.call(this, options);
21937
- Writable3.call(this, options);
21873
+ Writable2.call(this, options);
21938
21874
  if (options && options.readable === false) this.readable = false;
21939
21875
  if (options && options.writable === false) this.writable = false;
21940
21876
  this.allowHalfOpen = true;
@@ -23944,8 +23880,8 @@ var require_utils = __commonJS({
23944
23880
  var result = transform[inputType][outputType](input);
23945
23881
  return result;
23946
23882
  };
23947
- exports2.resolve = function(path59) {
23948
- var parts = path59.split("/");
23883
+ exports2.resolve = function(path58) {
23884
+ var parts = path58.split("/");
23949
23885
  var result = [];
23950
23886
  for (var index = 0; index < parts.length; index++) {
23951
23887
  var part = parts[index];
@@ -29798,18 +29734,18 @@ var require_object = __commonJS({
29798
29734
  var object = new ZipObject(name, zipObjectContent, o);
29799
29735
  this.files[name] = object;
29800
29736
  };
29801
- var parentFolder = function(path59) {
29802
- if (path59.slice(-1) === "/") {
29803
- path59 = path59.substring(0, path59.length - 1);
29737
+ var parentFolder = function(path58) {
29738
+ if (path58.slice(-1) === "/") {
29739
+ path58 = path58.substring(0, path58.length - 1);
29804
29740
  }
29805
- var lastSlash = path59.lastIndexOf("/");
29806
- return lastSlash > 0 ? path59.substring(0, lastSlash) : "";
29741
+ var lastSlash = path58.lastIndexOf("/");
29742
+ return lastSlash > 0 ? path58.substring(0, lastSlash) : "";
29807
29743
  };
29808
- var forceTrailingSlash = function(path59) {
29809
- if (path59.slice(-1) !== "/") {
29810
- path59 += "/";
29744
+ var forceTrailingSlash = function(path58) {
29745
+ if (path58.slice(-1) !== "/") {
29746
+ path58 += "/";
29811
29747
  }
29812
- return path59;
29748
+ return path58;
29813
29749
  };
29814
29750
  var folderAdd = function(name, createFolders) {
29815
29751
  createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
@@ -30811,7 +30747,7 @@ var require_lib3 = __commonJS({
30811
30747
  // src/run-case/recorder.ts
30812
30748
  function startRunCaseRecorder(opts) {
30813
30749
  const now = opts.now ?? Date.now;
30814
- const dir = import_node_path47.default.dirname(opts.recordPath);
30750
+ const dir = import_node_path46.default.dirname(opts.recordPath);
30815
30751
  let stream = null;
30816
30752
  let closing = false;
30817
30753
  let closedSettled = false;
@@ -30825,8 +30761,8 @@ function startRunCaseRecorder(opts) {
30825
30761
  });
30826
30762
  const ensureStream = () => {
30827
30763
  if (stream) return stream;
30828
- import_node_fs35.default.mkdirSync(dir, { recursive: true });
30829
- stream = import_node_fs35.default.createWriteStream(opts.recordPath, { flags: "a" });
30764
+ import_node_fs34.default.mkdirSync(dir, { recursive: true });
30765
+ stream = import_node_fs34.default.createWriteStream(opts.recordPath, { flags: "a" });
30830
30766
  stream.on("close", () => closedResolve());
30831
30767
  return stream;
30832
30768
  };
@@ -30851,12 +30787,12 @@ function startRunCaseRecorder(opts) {
30851
30787
  };
30852
30788
  return { tap, close, closed };
30853
30789
  }
30854
- var import_node_fs35, import_node_path47;
30790
+ var import_node_fs34, import_node_path46;
30855
30791
  var init_recorder = __esm({
30856
30792
  "src/run-case/recorder.ts"() {
30857
30793
  "use strict";
30858
- import_node_fs35 = __toESM(require("fs"), 1);
30859
- import_node_path47 = __toESM(require("path"), 1);
30794
+ import_node_fs34 = __toESM(require("fs"), 1);
30795
+ import_node_path46 = __toESM(require("path"), 1);
30860
30796
  }
30861
30797
  });
30862
30798
 
@@ -30899,7 +30835,7 @@ var init_wire = __esm({
30899
30835
  // src/run-case/controller.ts
30900
30836
  async function runController(opts) {
30901
30837
  const now = opts.now ?? Date.now;
30902
- const cwd = opts.cwd ?? (0, import_node_fs36.mkdtempSync)(import_node_path48.default.join(import_node_os20.default.tmpdir(), "clawd-runcase-"));
30838
+ const cwd = opts.cwd ?? (0, import_node_fs35.mkdtempSync)(import_node_path47.default.join(import_node_os19.default.tmpdir(), "clawd-runcase-"));
30903
30839
  const ownsCwd = opts.cwd === void 0;
30904
30840
  const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
30905
30841
  const spawnCtx = { cwd };
@@ -31060,19 +30996,19 @@ async function runController(opts) {
31060
30996
  if (sigintHandler) process.off("SIGINT", sigintHandler);
31061
30997
  if (ownsCwd) {
31062
30998
  try {
31063
- (0, import_node_fs36.rmSync)(cwd, { recursive: true, force: true });
30999
+ (0, import_node_fs35.rmSync)(cwd, { recursive: true, force: true });
31064
31000
  } catch {
31065
31001
  }
31066
31002
  }
31067
31003
  return exitCode ?? 0;
31068
31004
  }
31069
- var import_node_fs36, import_node_os20, import_node_path48;
31005
+ var import_node_fs35, import_node_os19, import_node_path47;
31070
31006
  var init_controller = __esm({
31071
31007
  "src/run-case/controller.ts"() {
31072
31008
  "use strict";
31073
- import_node_fs36 = require("fs");
31074
- import_node_os20 = __toESM(require("os"), 1);
31075
- import_node_path48 = __toESM(require("path"), 1);
31009
+ import_node_fs35 = require("fs");
31010
+ import_node_os19 = __toESM(require("os"), 1);
31011
+ import_node_path47 = __toESM(require("path"), 1);
31076
31012
  init_claude();
31077
31013
  init_stdout_splitter();
31078
31014
  init_permission_stdio();
@@ -31176,24 +31112,6 @@ init_protocol();
31176
31112
  var DEFAULT_PORT = 18790;
31177
31113
  var DEFAULT_HOST = "127.0.0.1";
31178
31114
  var DEFAULT_CLAWOS_API = "https://api.clawos.chat";
31179
- var DEFAULT_LOG_ENDPOINT = "https://clawd-prod.cn-hangzhou.log.aliyuncs.com/logstores/app-logs/track";
31180
- function resolveLogShipping(raw, cliNoShipping) {
31181
- if (cliNoShipping) {
31182
- return { mode: "off", endpoint: null, sampling: {} };
31183
- }
31184
- const rawMode = raw?.mode;
31185
- const mode = rawMode === "off" || rawMode === "errors-only" ? rawMode : "on";
31186
- if (mode === "off") {
31187
- return { mode, endpoint: null, sampling: {} };
31188
- }
31189
- const endpoint = typeof raw?.endpoint === "string" && raw.endpoint ? raw.endpoint : raw?.endpoint === null ? null : DEFAULT_LOG_ENDPOINT;
31190
- const sampling = mode === "errors-only" ? { debug: 0, info: 0, warn: 1, error: 1 } : isPlainSamplingMap(raw?.sampling) ? raw.sampling : {};
31191
- return { mode, endpoint, sampling };
31192
- }
31193
- function isPlainSamplingMap(v2) {
31194
- if (!v2 || typeof v2 !== "object") return false;
31195
- return Object.values(v2).every((n) => typeof n === "number");
31196
- }
31197
31115
  function parseArgs(argv) {
31198
31116
  const out = {};
31199
31117
  for (let i = 0; i < argv.length; i++) {
@@ -31239,9 +31157,6 @@ function parseArgs(argv) {
31239
31157
  case "-v":
31240
31158
  out.version = true;
31241
31159
  break;
31242
- case "--no-log-shipping":
31243
- out.noLogShipping = true;
31244
- break;
31245
31160
  default:
31246
31161
  if (a.startsWith("--")) throw new Error(`unknown flag: ${a}`);
31247
31162
  break;
@@ -31287,10 +31202,6 @@ function resolveConfig(opts) {
31287
31202
  const mode = DAEMON_MODE_VALUES.includes(rawMode ?? "") ? rawMode : "sdk";
31288
31203
  const filePreviewPorts = Array.isArray(fileCfg.previewPorts) ? fileCfg.previewPorts.map((n) => Number(n)).filter((n) => Number.isInteger(n) && n > 0) : null;
31289
31204
  const previewPorts = env.CLAWD_PREVIEW_PORTS ? env.CLAWD_PREVIEW_PORTS.split(",").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n) && n > 0) : filePreviewPorts && filePreviewPorts.length > 0 ? filePreviewPorts : null;
31290
- const logShipping = resolveLogShipping(
31291
- fileCfg.logShipping,
31292
- args.noLogShipping ?? false
31293
- );
31294
31205
  return {
31295
31206
  port,
31296
31207
  host,
@@ -31303,8 +31214,7 @@ function resolveConfig(opts) {
31303
31214
  noTunnelPersist,
31304
31215
  frpcBinary,
31305
31216
  mode,
31306
- previewPorts,
31307
- logShipping
31217
+ previewPorts
31308
31218
  };
31309
31219
  }
31310
31220
  var HELP_TEXT = `clawd [options]
@@ -31315,7 +31225,6 @@ var HELP_TEXT = `clawd [options]
31315
31225
  --tunnel \u542F\u7528 frp tunnel \u628A\u672C\u5730\u7AEF\u53E3\u66B4\u9732\u5230\u516C\u7F51
31316
31226
  --clawos-api <url> tunnel register \u63A5\u53E3\u7684 base url\uFF08\u9ED8\u8BA4 https://api.clawos.chat\uFF09
31317
31227
  --auth-token <s> \u6307\u5B9A daemon auth token\uFF1B\u7F3A\u7701\u65F6 tunnel \u6A21\u5F0F\u4ECE ~/.clawd/auth.json \u590D\u7528\uFF0C\u6CA1\u6709\u5C31\u751F\u6210
31318
- --no-log-shipping \u7981\u7528 SLS \u65E5\u5FD7\u4E0A\u884C\uFF08\u8986\u76D6 config.json logShipping.mode=off\uFF09
31319
31228
  --help / -h \u663E\u793A\u5E2E\u52A9
31320
31229
  --version / -v \u663E\u793A\u7248\u672C
31321
31230
 
@@ -31334,64 +31243,12 @@ Env (advanced):
31334
31243
  `;
31335
31244
 
31336
31245
  // src/index.ts
31337
- var import_node_path46 = __toESM(require("path"), 1);
31338
- var import_node_fs34 = __toESM(require("fs"), 1);
31339
- var import_node_os19 = __toESM(require("os"), 1);
31340
-
31341
- // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
31342
- var byteToHex = [];
31343
- for (let i = 0; i < 256; ++i) {
31344
- byteToHex.push((i + 256).toString(16).slice(1));
31345
- }
31346
- function unsafeStringify(arr, offset = 0) {
31347
- return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
31348
- }
31349
-
31350
- // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/rng.js
31351
- var import_node_crypto = __toESM(require("crypto"));
31352
- var rnds8Pool = new Uint8Array(256);
31353
- var poolPtr = rnds8Pool.length;
31354
- function rng() {
31355
- if (poolPtr > rnds8Pool.length - 16) {
31356
- import_node_crypto.default.randomFillSync(rnds8Pool);
31357
- poolPtr = 0;
31358
- }
31359
- return rnds8Pool.slice(poolPtr, poolPtr += 16);
31360
- }
31361
-
31362
- // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/native.js
31363
- var import_node_crypto2 = __toESM(require("crypto"));
31364
- var native_default = {
31365
- randomUUID: import_node_crypto2.default.randomUUID
31366
- };
31367
-
31368
- // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/v4.js
31369
- function v4(options, buf, offset) {
31370
- if (native_default.randomUUID && !buf && !options) {
31371
- return native_default.randomUUID();
31372
- }
31373
- options = options || {};
31374
- const rnds = options.random || (options.rng || rng)();
31375
- rnds[6] = rnds[6] & 15 | 64;
31376
- rnds[8] = rnds[8] & 63 | 128;
31377
- if (buf) {
31378
- offset = offset || 0;
31379
- for (let i = 0; i < 16; ++i) {
31380
- buf[offset + i] = rnds[i];
31381
- }
31382
- return buf;
31383
- }
31384
- return unsafeStringify(rnds);
31385
- }
31386
- var v4_default = v4;
31387
-
31388
- // src/index.ts
31389
- var import_node_url2 = require("url");
31246
+ var import_node_path45 = __toESM(require("path"), 1);
31247
+ var import_node_fs33 = __toESM(require("fs"), 1);
31390
31248
 
31391
31249
  // src/logger.ts
31392
31250
  var import_node_fs2 = __toESM(require("fs"), 1);
31393
31251
  var import_node_path2 = __toESM(require("path"), 1);
31394
- var import_node_stream = require("stream");
31395
31252
  var import_pino = __toESM(require_pino(), 1);
31396
31253
  function wrap(inner) {
31397
31254
  return {
@@ -31417,329 +31274,12 @@ function createLogger(opts = {}) {
31417
31274
  } catch {
31418
31275
  }
31419
31276
  }
31420
- if (opts.logClient) {
31421
- const client = opts.logClient;
31422
- const sink = new import_node_stream.Writable({
31423
- write(chunk, _enc, cb) {
31424
- try {
31425
- const line = String(chunk).trim();
31426
- if (line) {
31427
- const obj = JSON.parse(line);
31428
- const lvl = pinoLevelToString(obj.level);
31429
- if (lvl) {
31430
- const meta = {};
31431
- for (const [k2, v2] of Object.entries(obj)) {
31432
- if (k2 === "level" || k2 === "msg" || k2 === "time" || k2 === "pid" || k2 === "hostname") continue;
31433
- if (k2 === "sessionId") continue;
31434
- meta[k2] = v2;
31435
- }
31436
- client.push({
31437
- ts: typeof obj.time === "number" ? obj.time : void 0,
31438
- level: lvl,
31439
- msg: typeof obj.msg === "string" ? obj.msg : "",
31440
- meta: Object.keys(meta).length > 0 ? meta : void 0,
31441
- sessionId: typeof obj.sessionId === "string" ? obj.sessionId : void 0
31442
- });
31443
- }
31444
- }
31445
- } catch {
31446
- }
31447
- cb();
31448
- }
31449
- });
31450
- streams.push({ stream: sink, level });
31451
- }
31452
31277
  const base = (0, import_pino.default)(
31453
31278
  { level, base: { pid: process.pid } },
31454
31279
  import_pino.default.multistream(streams)
31455
31280
  );
31456
31281
  return wrap(base);
31457
31282
  }
31458
- function pinoLevelToString(n) {
31459
- if (typeof n !== "number") return null;
31460
- if (n >= 50) return "error";
31461
- if (n >= 40) return "warn";
31462
- if (n >= 30) return "info";
31463
- if (n >= 20) return "debug";
31464
- return null;
31465
- }
31466
-
31467
- // ../log-client/src/types.ts
31468
- var DEFAULT_BATCH = {
31469
- maxRecords: 100,
31470
- maxBytes: 512 * 1024,
31471
- maxWaitMs: 5e3
31472
- };
31473
- var DEFAULT_BUFFER_CAP = 5e3;
31474
- var DEFAULT_SAMPLING = {
31475
- debug: 0,
31476
- info: 1,
31477
- warn: 1,
31478
- error: 1
31479
- };
31480
- var MAX_MSG_BYTES = 1024;
31481
- var MAX_META_JSON_BYTES = 2048;
31482
- var REDACT_KEY_REGEX = /token|secret|password|auth(?!or)|apikey|signsecret/i;
31483
- var REDACTED_PLACEHOLDER = "[REDACTED]";
31484
-
31485
- // ../log-client/src/redactor.ts
31486
- var TRUNCATE_SUFFIX = "\u2026[truncated]";
31487
- function redactMeta(meta, homeDir) {
31488
- const cleaned = cleanValue(meta, homeDir, 0);
31489
- const json = safeStringify(cleaned);
31490
- if (json.length <= MAX_META_JSON_BYTES) return cleaned;
31491
- const truncated = json.slice(0, MAX_META_JSON_BYTES) + TRUNCATE_SUFFIX;
31492
- return { __truncated__: truncated };
31493
- }
31494
- function cleanValue(v2, homeDir, depth) {
31495
- if (depth > 10) return "[depth-limit]";
31496
- if (v2 == null) return v2;
31497
- if (typeof v2 === "string") {
31498
- return homeDir ? v2.split(homeDir).join("~") : v2;
31499
- }
31500
- if (typeof v2 !== "object") return v2;
31501
- if (Array.isArray(v2)) return v2.map((x) => cleanValue(x, homeDir, depth + 1));
31502
- const out = {};
31503
- for (const [k2, val] of Object.entries(v2)) {
31504
- if (REDACT_KEY_REGEX.test(k2)) {
31505
- out[k2] = REDACTED_PLACEHOLDER;
31506
- } else {
31507
- out[k2] = cleanValue(val, homeDir, depth + 1);
31508
- }
31509
- }
31510
- return out;
31511
- }
31512
- function safeStringify(v2) {
31513
- try {
31514
- return JSON.stringify(v2) ?? "";
31515
- } catch {
31516
- return '"[serialize-failed]"';
31517
- }
31518
- }
31519
- function truncateMsg(msg) {
31520
- if (msg.length <= MAX_MSG_BYTES) return msg;
31521
- return msg.slice(0, MAX_MSG_BYTES) + TRUNCATE_SUFFIX;
31522
- }
31523
-
31524
- // ../log-client/src/sampling.ts
31525
- function shouldSample(level, config, rng2) {
31526
- const rate = config[level] ?? DEFAULT_SAMPLING[level];
31527
- if (rate <= 0) return false;
31528
- if (rate >= 1) return true;
31529
- return rng2() < rate;
31530
- }
31531
-
31532
- // ../log-client/src/batcher.ts
31533
- var Batcher = class {
31534
- constructor(deps) {
31535
- this.deps = deps;
31536
- }
31537
- deps;
31538
- queue = [];
31539
- bytes = 0;
31540
- droppedSinceFlush = 0;
31541
- identityReady = false;
31542
- timer = null;
31543
- disposed = false;
31544
- pendingSends = [];
31545
- enqueue(record) {
31546
- if (this.disposed) return;
31547
- const sz = approxSize(record);
31548
- while (this.queue.length >= this.deps.bufferCap) {
31549
- this.queue.shift();
31550
- this.droppedSinceFlush++;
31551
- }
31552
- this.queue.push(record);
31553
- this.bytes += sz;
31554
- if (!this.identityReady) return;
31555
- this.maybeTrigger();
31556
- }
31557
- setIdentityReady(ready) {
31558
- this.identityReady = ready;
31559
- if (ready && this.queue.length > 0) this.maybeTrigger();
31560
- }
31561
- async flush() {
31562
- if (this.queue.length > 0) {
31563
- this.fire("flush");
31564
- }
31565
- await Promise.allSettled(this.pendingSends);
31566
- }
31567
- stats() {
31568
- return { queued: this.queue.length, dropped: this.droppedSinceFlush };
31569
- }
31570
- async dispose() {
31571
- if (this.disposed) return;
31572
- this.disposed = true;
31573
- if (this.timer) {
31574
- clearTimeout(this.timer);
31575
- this.timer = null;
31576
- }
31577
- await this.flush();
31578
- }
31579
- maybeTrigger() {
31580
- const { maxRecords, maxBytes, maxWaitMs } = this.deps.batch;
31581
- if (this.queue.length >= maxRecords) {
31582
- this.fire("records");
31583
- return;
31584
- }
31585
- if (this.bytes >= maxBytes) {
31586
- this.fire("bytes");
31587
- return;
31588
- }
31589
- if (this.timer == null) {
31590
- this.timer = setTimeout(() => {
31591
- this.timer = null;
31592
- if (this.queue.length > 0 && this.identityReady) this.fire("time");
31593
- }, maxWaitMs);
31594
- }
31595
- }
31596
- fire(reason) {
31597
- if (this.timer) {
31598
- clearTimeout(this.timer);
31599
- this.timer = null;
31600
- }
31601
- const records = this.queue;
31602
- const droppedCarryover = this.droppedSinceFlush;
31603
- this.queue = [];
31604
- this.bytes = 0;
31605
- this.droppedSinceFlush = 0;
31606
- const p2 = this.deps.onBatch({ reason, records, droppedCarryover }).catch(() => {
31607
- });
31608
- this.pendingSends.push(p2);
31609
- p2.finally(() => {
31610
- this.pendingSends = this.pendingSends.filter((x) => x !== p2);
31611
- });
31612
- }
31613
- };
31614
- function approxSize(record) {
31615
- return (record.msg?.length ?? 0) + (record.meta_json?.length ?? 0) + 200;
31616
- }
31617
-
31618
- // ../log-client/src/sender.ts
31619
- var BACKOFF_MS = [1e3, 2e3, 4e3];
31620
- async function sendBatch(deps, batch) {
31621
- const body = JSON.stringify({
31622
- __topic__: deps.topic ?? "clawd",
31623
- __source__: deps.source,
31624
- __logs__: batch.records,
31625
- __dropped__: batch.droppedCarryover
31626
- });
31627
- for (let attempt = 0; attempt < BACKOFF_MS.length; attempt++) {
31628
- if (attempt > 0) await sleep(BACKOFF_MS[attempt - 1]);
31629
- try {
31630
- const res = await deps.fetchImpl(deps.endpoint, {
31631
- method: "POST",
31632
- headers: { "Content-Type": "application/json" },
31633
- body
31634
- });
31635
- if (res.status >= 200 && res.status < 300) {
31636
- return { sent: batch.records.length, failed: 0 };
31637
- }
31638
- if (res.status >= 400 && res.status < 500) {
31639
- return { sent: 0, failed: batch.records.length };
31640
- }
31641
- } catch {
31642
- }
31643
- }
31644
- return { sent: 0, failed: batch.records.length };
31645
- }
31646
- function sleep(ms) {
31647
- return new Promise((r) => setTimeout(r, ms));
31648
- }
31649
-
31650
- // ../log-client/src/client.ts
31651
- function createLogClient(opts) {
31652
- const stats = { sent: 0, dropped: 0, queued: 0, failed: 0 };
31653
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
31654
- const now = opts.now ?? Date.now;
31655
- const sampling = { ...DEFAULT_SAMPLING, ...opts.sampling ?? {} };
31656
- const homeDir = opts.homeDir === void 0 ? null : opts.homeDir;
31657
- const batchConfig = { ...DEFAULT_BATCH, ...opts.batch ?? {} };
31658
- const bufferCap = opts.bufferCap ?? DEFAULT_BUFFER_CAP;
31659
- let identity = opts.identity;
31660
- let disposed = false;
31661
- if (opts.endpoint == null) {
31662
- return {
31663
- push: () => {
31664
- if (disposed) return;
31665
- stats.dropped++;
31666
- },
31667
- flush: async () => {
31668
- },
31669
- setIdentity: (next) => {
31670
- identity = next;
31671
- },
31672
- stats: () => ({ ...stats }),
31673
- dispose: async () => {
31674
- disposed = true;
31675
- }
31676
- };
31677
- }
31678
- const endpoint = opts.endpoint;
31679
- const batcher = new Batcher({
31680
- batch: batchConfig,
31681
- bufferCap,
31682
- now,
31683
- onBatch: async (b2) => {
31684
- const res = await sendBatch({ endpoint, source: opts.source, fetchImpl }, b2);
31685
- stats.sent += res.sent;
31686
- stats.failed += res.failed;
31687
- }
31688
- });
31689
- batcher.setIdentityReady(identity != null);
31690
- return {
31691
- push(input) {
31692
- if (disposed) return;
31693
- try {
31694
- if (!shouldSample(input.level, sampling, Math.random)) {
31695
- stats.dropped++;
31696
- return;
31697
- }
31698
- const record = buildRecord(input, identity, opts.source, homeDir, now);
31699
- batcher.enqueue(record);
31700
- } catch {
31701
- }
31702
- },
31703
- async flush() {
31704
- try {
31705
- await batcher.flush();
31706
- } catch {
31707
- }
31708
- },
31709
- setIdentity(next) {
31710
- identity = next;
31711
- batcher.setIdentityReady(next != null);
31712
- },
31713
- stats() {
31714
- const bs = batcher.stats();
31715
- return { ...stats, queued: bs.queued, dropped: stats.dropped + bs.dropped };
31716
- },
31717
- async dispose() {
31718
- disposed = true;
31719
- try {
31720
- await batcher.dispose();
31721
- } catch {
31722
- }
31723
- }
31724
- };
31725
- }
31726
- function buildRecord(input, identity, source, homeDir, now) {
31727
- const cleanedMeta = input.meta ? redactMeta(input.meta, homeDir) : void 0;
31728
- const meta_json = cleanedMeta ? JSON.stringify(cleanedMeta) : void 0;
31729
- return {
31730
- ts: input.ts ?? now(),
31731
- source,
31732
- level: input.level,
31733
- msg: truncateMsg(input.msg),
31734
- ownerPrincipalId: identity?.ownerPrincipalId ?? "__pending__",
31735
- deviceId: identity?.deviceId ?? "__pending__",
31736
- appVersion: identity?.appVersion ?? "__pending__",
31737
- daemonVersion: identity?.daemonVersion,
31738
- os: identity?.os ?? "unknown",
31739
- meta_json,
31740
- sessionId: input.sessionId
31741
- };
31742
- }
31743
31283
 
31744
31284
  // src/session/store-factory.ts
31745
31285
  var path5 = __toESM(require("path"), 1);
@@ -31946,6 +31486,55 @@ var SessionStoreFactory = class {
31946
31486
  var import_node_fs6 = __toESM(require("fs"), 1);
31947
31487
  var import_node_path6 = __toESM(require("path"), 1);
31948
31488
  var import_node_os2 = __toESM(require("os"), 1);
31489
+
31490
+ // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
31491
+ var byteToHex = [];
31492
+ for (let i = 0; i < 256; ++i) {
31493
+ byteToHex.push((i + 256).toString(16).slice(1));
31494
+ }
31495
+ function unsafeStringify(arr, offset = 0) {
31496
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
31497
+ }
31498
+
31499
+ // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/rng.js
31500
+ var import_node_crypto = __toESM(require("crypto"));
31501
+ var rnds8Pool = new Uint8Array(256);
31502
+ var poolPtr = rnds8Pool.length;
31503
+ function rng() {
31504
+ if (poolPtr > rnds8Pool.length - 16) {
31505
+ import_node_crypto.default.randomFillSync(rnds8Pool);
31506
+ poolPtr = 0;
31507
+ }
31508
+ return rnds8Pool.slice(poolPtr, poolPtr += 16);
31509
+ }
31510
+
31511
+ // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/native.js
31512
+ var import_node_crypto2 = __toESM(require("crypto"));
31513
+ var native_default = {
31514
+ randomUUID: import_node_crypto2.default.randomUUID
31515
+ };
31516
+
31517
+ // ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/v4.js
31518
+ function v4(options, buf, offset) {
31519
+ if (native_default.randomUUID && !buf && !options) {
31520
+ return native_default.randomUUID();
31521
+ }
31522
+ options = options || {};
31523
+ const rnds = options.random || (options.rng || rng)();
31524
+ rnds[6] = rnds[6] & 15 | 64;
31525
+ rnds[8] = rnds[8] & 63 | 128;
31526
+ if (buf) {
31527
+ offset = offset || 0;
31528
+ for (let i = 0; i < 16; ++i) {
31529
+ buf[offset + i] = rnds[i];
31530
+ }
31531
+ return buf;
31532
+ }
31533
+ return unsafeStringify(rnds);
31534
+ }
31535
+ var v4_default = v4;
31536
+
31537
+ // src/session/manager.ts
31949
31538
  init_protocol();
31950
31539
 
31951
31540
  // src/tools/guest-settings.ts
@@ -32070,32 +31659,6 @@ function buildConnectionPrompt(args) {
32070
31659
  return result;
32071
31660
  }
32072
31661
 
32073
- // src/dispatch/system-prompt.ts
32074
- var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
32075
-
32076
- \u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-bug-fixer\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP tool \`mcp__clawd-dispatch__personaDispatch\` \u59D4\u6D3E\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
32077
-
32078
- - \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
32079
- - \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
32080
-
32081
- tool \u4F1A\u963B\u585E\u6302\u8D77\u7B49\u5BF9\u65B9\u4EBA\u683C\u5E72\u5B8C\uFF0C\u628A outcome\uFF08\u542B text + \u53EF\u9009 filePaths\uFF09\u4F5C\u4E3A tool_result \u56DE\u7ED9\u4F60\uFF0C\u4F60\u518D\u7EFC\u5408\u56DE\u5E94\u7528\u6237\u3002
32082
-
32083
- - **\u4E0D\u8981**\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF08\u4F60\u4E0D\u662F\u90A3\u4E2A persona\uFF09
32084
- - **\u4E0D\u8981** in-place \u6A21\u4EFF\u5BF9\u65B9\u4EBA\u683C \u2014\u2014 dispatch \u662F\u771F\u5207\u5230\u53E6\u4E00\u4E2A\u72EC\u7ACB session
32085
- - \u4E00\u53E5\u8BDD\u91CC\u591A\u4E2A \`@persona/<id>\` \u65F6\u9009\u7B2C\u4E00\u4E2A\uFF08tool \u4E00\u6B21\u53EA\u5904\u7406\u4E00\u4E2A target\uFF09
32086
- - \u59D4\u6D3E\u5931\u8D25\uFF08tool_result.is_error=true\uFF09\u65F6\u5982\u5B9E\u544A\u8BC9\u7528\u6237\u539F\u56E0\uFF0C**\u4E0D\u8981\u91CD\u8BD5**
32087
-
32088
- ## \u88AB dispatch \u63A5\u5230\u4EFB\u52A1
32089
-
32090
- \u5982\u679C\u4F60\u7684 session \u7B2C\u4E00\u6761 user message \u662F\u4EE5 \`[Dispatched from owner \u2014 another persona session\u59D4\u6D3E\u7ED9\u4F60\u6267\u884C\u4EFB\u52A1]\` \u8D77\u5934\u7684 plain text \u4EFB\u52A1\u5305\uFF0C\u4F60\u662F\u88AB\u53E6\u4E00\u4E2A persona \u59D4\u6D3E\u6765\u5E72\u6D3B\u7684\uFF08\u4EFB\u52A1\u5305\u4E0D\u7528 \`<system-reminder>\` \u5305\u662F\u4E3A\u4E86 reducer dedup \u5DE5\u4F5C\u6B63\u5E38\uFF0C\u89C1 manager.ts buildDispatchTaskPack \u6CE8\u91CA\uFF09\uFF1A
32091
-
32092
- - \u4EFB\u52A1\u5728 \`Task:\` \u6BB5
32093
- - \u539F\u4F1A\u8BDD\u7684\u5BF9\u8BDD\u5386\u53F2\u5728 \`Source conversation\` \u6BB5\u7ED9\u7684 jsonl \u8DEF\u5F84\u4E0B\uFF1B\u6309\u9700 Read \u5B83\u4E86\u89E3\u4E0A\u4E0B\u6587\uFF08\u4E0D\u5FC5\u8BFB\u5B8C\uFF09
32094
- - \u5E72\u5B8C\u540E**\u5FC5\u987B**\u8C03 \`mcp__clawd-dispatch__personaDispatchComplete\` \u62A5\u544A\u7ED3\u679C\uFF1A
32095
- - \u6210\u529F\uFF1A\`{ text: "\u603B\u7ED3/\u7ED3\u8BBA", filePaths?: ["\u4F60\u4EA7\u51FA/\u6539\u7684\u6587\u4EF6\u7EDD\u5BF9\u8DEF\u5F84"] }\`
32096
- - \u5931\u8D25\uFF1A\`{ isFailure: true, reason: "..." }\`
32097
- - \u62A5\u544A\u5B8C\u540E\u4F60\u7684 session \u5C31\u7ED3\u675F\u4E86\uFF0C\u4E0D\u8981\u7EE7\u7EED\u8F93\u51FA`;
32098
-
32099
31662
  // src/session/reducer.ts
32100
31663
  function cloneState(s) {
32101
31664
  return {
@@ -32174,9 +31737,6 @@ function buildSpawnContext(state, deps) {
32174
31737
  env.CLAWD_SESSION_ID = file.sessionId;
32175
31738
  const daemonUrl = deps.getDaemonUrl?.() ?? null;
32176
31739
  if (daemonUrl) env.CLAWD_DAEMON_URL = daemonUrl;
32177
- const dispatchId = deps.lookupDispatchByBSessionId?.(file.sessionId);
32178
- if (dispatchId) env.CLAWD_DISPATCH_ID = dispatchId;
32179
- const dispatchMcpConfigPath2 = deps.getDispatchMcpConfigPath?.() ?? null;
32180
31740
  const ctx = {
32181
31741
  cwd: file.cwd,
32182
31742
  toolSessionId: file.toolSessionId,
@@ -32186,10 +31746,7 @@ function buildSpawnContext(state, deps) {
32186
31746
  env,
32187
31747
  // Phase 2 capability platform (plan §3): personaRoot 透传给 buildSpawnArgs;
32188
31748
  // 内部 shouldSandbox(cwd, personaRoot) 决定是否注入 --settings sandbox-settings.
32189
- personaRoot: deps.personaRoot,
32190
- // Persona dispatch:所有 session(A 和 B)都挂同一份 dispatch.mcp.json,让两边的 cc
32191
- // 都能看到 personaDispatch / personaDispatchComplete tool;按 env 区分实际行为。
32192
- dispatchMcpConfigPath: dispatchMcpConfigPath2 ?? void 0
31749
+ personaRoot: deps.personaRoot
32193
31750
  };
32194
31751
  const meta = state.subSessionMeta;
32195
31752
  if (meta?.personaMode) {
@@ -32200,9 +31757,6 @@ function buildSpawnContext(state, deps) {
32200
31757
  workDir: meta.userWorkDir
32201
31758
  });
32202
31759
  }
32203
- if (dispatchMcpConfigPath2) {
32204
- ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + DISPATCH_SYSTEM_PROMPT_HINT;
32205
- }
32206
31760
  if (meta?.extraSettings) {
32207
31761
  ctx.extraSettings = meta.extraSettings;
32208
31762
  }
@@ -32868,6 +32422,35 @@ function startRecorder(opts) {
32868
32422
  };
32869
32423
  }
32870
32424
 
32425
+ // src/persona/mention-injection.ts
32426
+ var MENTION_RE = /@persona\/([A-Za-z0-9_-]+)(?=\s|$|[^A-Za-z0-9_-])/g;
32427
+ function injectPersonaMentions(rawText, store) {
32428
+ const resolved = [];
32429
+ const body = rawText.replace(MENTION_RE, (match, id) => {
32430
+ const meta = store.read(id);
32431
+ const personality = store.readPersonality(id);
32432
+ if (meta && personality !== null) {
32433
+ resolved.push({ label: meta.label, personality });
32434
+ return "";
32435
+ }
32436
+ return match;
32437
+ });
32438
+ if (resolved.length === 0) {
32439
+ return { systemReminder: null, userText: rawText };
32440
+ }
32441
+ const blocks = resolved.map((r) => {
32442
+ const safe = r.personality.replace(/<\/system-reminder>/gi, "</ system-reminder>");
32443
+ return `[Acting as persona "${r.label}" for this message]
32444
+ ${safe}`;
32445
+ });
32446
+ return {
32447
+ systemReminder: `<system-reminder>
32448
+ ${blocks.join("\n\n")}
32449
+ </system-reminder>`,
32450
+ userText: body.trim()
32451
+ };
32452
+ }
32453
+
32871
32454
  // src/session/runner.ts
32872
32455
  var DEFAULT_CONTROL_REQUEST_TIMEOUT_MS = 1e4;
32873
32456
  function encodeAllowWithInputControlResponse(requestId, updatedInput) {
@@ -32916,6 +32499,7 @@ var SessionRunner = class {
32916
32499
  }
32917
32500
  // 外部推送 input 到 reducer,然后执行产出的 effects
32918
32501
  input(inputMsg) {
32502
+ const personaStore = this.hooks.personaStore;
32919
32503
  const adapter = this.hooks.adapter;
32920
32504
  const deps = {
32921
32505
  // file-sharing (spec §6 PR 3):在 stdout-line 解析时同步观察 file-edit 工具事件,
@@ -32925,10 +32509,20 @@ var SessionRunner = class {
32925
32509
  if (this.hooks.onFileEdit) this.observeForFileEdit(events);
32926
32510
  return events;
32927
32511
  },
32928
- // Persona dispatch (Task 9):原 in-place `@persona/<id>` 注入路径已删,cc 自己看到字面
32929
- // token 会调 personaDispatch MCP tool 委派(dispatch.mcp.json 通过 cc --mcp-config 加载,
32930
- // CLAUDE.md cc 触发条件)。encodeStdin 现在是 adapter 的简单 passthrough。
32931
- encodeStdin: (t, ctx) => adapter.encodeStdin(t, ctx) ?? "",
32512
+ // persona mention injection deps 装配处包一层,对 reducer 完全透明。
32513
+ // 命中 mention 时拆成两条 stdin 帧(先 system-reminder 块、后 user 原文):
32514
+ // - CC stream-json 按行处理,落盘是两条独立 user message;
32515
+ // - 第一条文本起头 `<system-reminder>` classifyUserMessage 命中 UI 折叠;
32516
+ // - 第二条正常用户气泡,刷新页面不再暴露 personality 文本。
32517
+ encodeStdin: (t, ctx) => {
32518
+ if (!personaStore) return adapter.encodeStdin(t, ctx) ?? "";
32519
+ const { systemReminder, userText } = injectPersonaMentions(t, personaStore);
32520
+ if (systemReminder === null) return adapter.encodeStdin(userText, ctx) ?? "";
32521
+ const metaFrame = adapter.encodeStdin(systemReminder, ctx) ?? "";
32522
+ if (userText === "") return metaFrame;
32523
+ const userFrame = adapter.encodeStdin(userText, ctx) ?? "";
32524
+ return metaFrame + userFrame;
32525
+ },
32932
32526
  bufferCap: this.hooks.bufferCap ?? 500,
32933
32527
  now: this.hooks.now ?? Date.now,
32934
32528
  resolveContextWindow: this.hooks.resolveContextWindow,
@@ -32938,10 +32532,6 @@ var SessionRunner = class {
32938
32532
  // 单栏 refactor (spec 2026-06-02 §5.1): cc 子进程 env 注入 CLAWD_DAEMON_URL,让 assistant
32939
32533
  // curl daemon HTTP RPC adapter (/api/rpc/<method>) 触发管理操作。null = HTTP adapter 未启。
32940
32534
  getDaemonUrl: this.hooks.getDaemonUrl,
32941
- // Persona dispatch:透传 dispatch.mcp.json 路径闭包 + B→dispatchId 反查闭包。
32942
- // 见 reducer.buildSpawnContext 注 CLAWD_DISPATCH_ID env / 派生 SpawnContext.dispatchMcpConfigPath
32943
- getDispatchMcpConfigPath: this.hooks.getDispatchMcpConfigPath,
32944
- lookupDispatchByBSessionId: this.hooks.lookupDispatchByBSessionId,
32945
32535
  // ReadyGate v2:透传 mode 让 reducer send / ready-detected 分支决定走暂存队列还是直写
32946
32536
  mode: this.hooks.mode,
32947
32537
  // [RG-DBG] 注入 logger 让 reducer rgDbg 走 pino 进 clawd.log;定位完跟 rgDbg 一起删
@@ -33401,22 +32991,6 @@ function nowIso2(deps) {
33401
32991
  function newSessionId() {
33402
32992
  return v4_default().replace(/-/g, "").slice(0, 16);
33403
32993
  }
33404
- function buildDispatchTaskPack(args) {
33405
- return `[Dispatched from owner \u2014 another persona session\u59D4\u6D3E\u7ED9\u4F60\u6267\u884C\u4EFB\u52A1]
33406
-
33407
- Task:
33408
- ${args.prompt}
33409
-
33410
- Source conversation (jsonl, CC stream-json format, one message per line):
33411
- ${args.sourceJsonlPath}
33412
- You may read this file with your Read tool to understand context. You do not have to read it all.
33413
-
33414
- When done, call the MCP tool \`mcp__clawd-dispatch__personaDispatchComplete\` with your result:
33415
- - Success: { text: "...", filePaths?: ["abs/path", ...] }
33416
- - Failure: { isFailure: true, reason: "..." }
33417
-
33418
- dispatchId for this task: ${args.dispatchId}`;
33419
- }
33420
32994
  function derivePersonaSpawnCwd(file, personaRoot) {
33421
32995
  const personaId = file.ownerPersonaId;
33422
32996
  if (!personaId) return file.cwd;
@@ -33714,8 +33288,7 @@ var SessionManager = class {
33714
33288
  // adapter 自己持有模型表 + 兜底逻辑(contains / opus-1M / [1m] 等),manager 不再 cache 转发
33715
33289
  resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId),
33716
33290
  dataDir: this.deps.dataDir,
33717
- // personaStore 不再透给 runner hooks(in-place mention 注入路径已删,runner 不用);
33718
- // manager 自身的 sandbox 派生仍直接读 this.deps.personaStore。
33291
+ personaStore: this.deps.personaStore,
33719
33292
  ownerDisplayName: this.deps.ownerDisplayName,
33720
33293
  // Phase 2 capability platform (plan §3): 透传 personaRoot, buildSpawnArgs 据
33721
33294
  // cwd 是否在 personaRoot 下自动决定是否注入 --settings sandbox-settings.json.
@@ -33723,10 +33296,6 @@ var SessionManager = class {
33723
33296
  // 单栏 refactor (spec 2026-06-02 §5.1): 透传 daemon HTTP RPC base URL 闭包,
33724
33297
  // reducer 把它注入 cc 子进程 env CLAWD_DAEMON_URL.
33725
33298
  getDaemonUrl: this.deps.getDaemonUrl,
33726
- // Persona dispatch (Task 7): dispatch.mcp.json 路径 + B sessionId → dispatchId 反查
33727
- // 闭包透传给 reducer,让 cc spawn 加 --mcp-config flag + B session 注 CLAWD_DISPATCH_ID env.
33728
- getDispatchMcpConfigPath: this.deps.dispatchMcpConfigPath ? () => this.deps.dispatchMcpConfigPath ?? null : void 0,
33729
- lookupDispatchByBSessionId: this.deps.personaDispatchManager ? (bSid) => this.deps.personaDispatchManager?.lookupDispatchByBSessionId(bSid) : void 0,
33730
33299
  // file-sharing (spec §6 PR 3):闭包 scope + sessionId,runner 只暴露 tool/relPath/cwd
33731
33300
  onFileEdit: attachmentGroup ? (input) => attachmentGroup.onFileEdit({
33732
33301
  scope,
@@ -33942,20 +33511,15 @@ var SessionManager = class {
33942
33511
  // 强制走 deps.store(即 default scope),不走 scopeForFile:mirror 物理落 default 即可。
33943
33512
  // 远端 creator / origin 字段原值保留(不被本机 ctx 派生覆写)。
33944
33513
  //
33945
- // strip 远端 personaId / dispatchedFromSessionId:mirror SessionFile 上这两个字段都指向
33946
- // 朋友 daemon 上的本地 id,本机不持有对应 persona / 源 session。留着会让按这些字段反查的
33947
- // 本机消费者(MyPersonasSection ownerPersonaId 反查 persona、sidebar
33948
- // dispatchedFromSessionId 折叠 sub-session)走错分支。写入前清掉。#750 一族防线。
33514
+ // strip 远端 personaId:mirror SessionFile 上的 ownerPersonaId 是朋友 daemon 的 persona
33515
+ // 目录 id,本机不持有对应 persona。留着会让按 ownerPersonaId 反查的本机消费者
33516
+ // MyPersonasSection 等)把 mirror 误聚到同 id persona 下。写入前清掉。
33949
33517
  //
33950
33518
  // 与 manager.create / manager.update 区别:
33951
33519
  // - 不走 newRunner / attachObserver / cwd 校验(mirror 是纯 metadata 层)
33952
33520
  // - 不发 session:info 帧(manager.create / .update 通过 reducer/wireCollector 发 push)
33953
33521
  mirrorUpsert(file) {
33954
- const {
33955
- ownerPersonaId: _strippedPid,
33956
- dispatchedFromSessionId: _strippedDsp,
33957
- ...rest
33958
- } = file;
33522
+ const { ownerPersonaId: _stripped, ...rest } = file;
33959
33523
  return this.deps.store.write(rest);
33960
33524
  }
33961
33525
  // mirror peer sessions:删本机 mirror SessionFile。mirror 一律落 default(mirrorUpsert
@@ -34540,66 +34104,6 @@ var SessionManager = class {
34540
34104
  this.runners.set(file.sessionId, runner);
34541
34105
  return runner;
34542
34106
  }
34543
- /**
34544
- * Persona dispatch: 启动 B session 并投递任务包当第一条 user message。
34545
- *
34546
- * - 复用 persona-owner 创建路径(cwd=personaDir、scope=persona-owner、不沙箱)
34547
- * - SessionFile 上写 dispatchedFromSessionId 关联回 A(UI 折叠用;mirror 一侧 strip)
34548
- * - 跟 PersonaDispatchManager 双向登记 dispatchId ↔ B sessionId,让后续 reducer
34549
- * buildSpawnContext 能反查到 dispatchId 注 CLAWD_DISPATCH_ID env
34550
- * - 投 inject-owner-text 任务包;包尾教 B 用 personaDispatchComplete tool 回传
34551
- *
34552
- * cwd 派生与 SessionManager.create 的 owner persona 路径一致(derivePersonaSpawnCwd)。
34553
- */
34554
- createDispatchedSession(args) {
34555
- if (!this.deps.personaRoot) {
34556
- throw new Error("createDispatchedSession: personaRoot missing in ManagerDeps");
34557
- }
34558
- if (!this.deps.personaDispatchManager) {
34559
- throw new Error("createDispatchedSession: personaDispatchManager missing in ManagerDeps");
34560
- }
34561
- const sessionId = newSessionId();
34562
- const scope = {
34563
- kind: "persona",
34564
- personaId: args.targetPersona,
34565
- mode: "owner"
34566
- };
34567
- const cwd = import_node_path6.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
34568
- const now = (/* @__PURE__ */ new Date()).toISOString();
34569
- const file = {
34570
- sessionId,
34571
- cwd,
34572
- tool: "claude",
34573
- ownerPersonaId: args.targetPersona,
34574
- dispatchedFromSessionId: args.sourceSessionId,
34575
- createdAt: now,
34576
- updatedAt: now
34577
- };
34578
- this.storeFor(scope).write(file);
34579
- this.deps.personaDispatchManager.registerBSession(args.dispatchId, sessionId);
34580
- this.deps.logger?.info("dispatch.createDispatchedSession.file-written", {
34581
- dispatchId: args.dispatchId,
34582
- bSessionId: sessionId,
34583
- targetPersona: args.targetPersona,
34584
- cwd
34585
- });
34586
- const runner = this.ensureRunnerForScope(file, scope);
34587
- this.deps.logger?.info("dispatch.createDispatchedSession.runner-ready", {
34588
- dispatchId: args.dispatchId,
34589
- bSessionId: sessionId
34590
- });
34591
- const taskPack = buildDispatchTaskPack({
34592
- prompt: args.prompt,
34593
- sourceJsonlPath: args.sourceJsonlPath,
34594
- dispatchId: args.dispatchId
34595
- });
34596
- runner.input({ kind: "command", command: { kind: "send", text: taskPack } });
34597
- this.deps.logger?.info("dispatch.createDispatchedSession.task-pack-sent", {
34598
- dispatchId: args.dispatchId,
34599
- bSessionId: sessionId
34600
- });
34601
- return { sessionId };
34602
- }
34603
34107
  /**
34604
34108
  * 老板插话:把 'inject-owner-text' input 喂给对应 runner,
34605
34109
  * runner 不存在时按 scope 懒创建。
@@ -35621,6 +35125,39 @@ var DEFAULT_PERSONAS = [
35621
35125
  network: true
35622
35126
  }
35623
35127
  },
35128
+ {
35129
+ // 数据查询搭建师:复用 app-builder 流水线生成 dataclaw 只读查询页
35130
+ // spec: clawd/superpowers/specs/2026-06-14-dataclaw-builder-design.md
35131
+ personaId: "persona-dataclaw-builder",
35132
+ label: "\u6570\u636E\u67E5\u8BE2\u642D\u5EFA\u5E08",
35133
+ model: "opus",
35134
+ iconKey: "assist",
35135
+ public: false,
35136
+ // 同 app-builder 的开发型 profile(逐字段照抄):web 工具 + node/pnpm 工具链精确路径
35137
+ // + 出站 TLD 通配白名单 + .secrets deny。复用同一条流水线 → 同一套沙箱授权。
35138
+ sandboxProfile: {
35139
+ permissions: {
35140
+ defaultMode: "bypassPermissions",
35141
+ allow: ["Read", "Edit", "Write", "Glob", "Grep", "WebFetch", "WebSearch"],
35142
+ deny: ["Read(./.secrets/**)"]
35143
+ },
35144
+ sandbox: {
35145
+ filesystem: {
35146
+ allowRead: ["~/.npmrc", "~/Library/Preferences/pnpm", "~/.nvm", "~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"],
35147
+ allowWrite: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"]
35148
+ },
35149
+ network: {
35150
+ allowedDomains: ["*.com", "*.org", "*.io", "*.net", "*.dev", "*.app", "*.cn", "*.co", "*.chat", "*.ai"],
35151
+ allowLocalBinding: true
35152
+ }
35153
+ }
35154
+ },
35155
+ codexSandbox: {
35156
+ writableRoots: ["~/Library/pnpm", "~/.local/share/pnpm", "~/.local/state/pnpm", "~/.npm", "~/.pnpm-store"],
35157
+ denyRead: [".secrets/**"],
35158
+ network: true
35159
+ }
35160
+ },
35624
35161
  {
35625
35162
  personaId: "persona-developer",
35626
35163
  label: "\u5F00\u53D1\u8005",
@@ -36033,8 +35570,8 @@ function turnStartInput(text) {
36033
35570
  const items = [];
36034
35571
  let leftover = text;
36035
35572
  for (const m2 of text.matchAll(SKILL_RE)) {
36036
- const [marker, name, path59] = m2;
36037
- items.push({ type: "skill", name, path: path59 });
35573
+ const [marker, name, path58] = m2;
35574
+ items.push({ type: "skill", name, path: path58 });
36038
35575
  leftover = leftover.replace(marker, "");
36039
35576
  }
36040
35577
  for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
@@ -36685,7 +36222,7 @@ init_claude_history();
36685
36222
 
36686
36223
  // src/pty/pty-child-process.ts
36687
36224
  var import_node_events = require("events");
36688
- var import_node_stream2 = require("stream");
36225
+ var import_node_stream = require("stream");
36689
36226
  var PtyChildProcess = class extends import_node_events.EventEmitter {
36690
36227
  constructor(pty, opts = {}) {
36691
36228
  super();
@@ -36714,7 +36251,7 @@ var PtyChildProcess = class extends import_node_events.EventEmitter {
36714
36251
  pty.write(data);
36715
36252
  }
36716
36253
  };
36717
- this.stdin = new import_node_stream2.Writable({
36254
+ this.stdin = new import_node_stream.Writable({
36718
36255
  decodeStrings: false,
36719
36256
  write: (chunk, _enc, cb) => {
36720
36257
  const s = typeof chunk === "string" ? chunk : chunk.toString("utf8");
@@ -36733,7 +36270,7 @@ var PtyChildProcess = class extends import_node_events.EventEmitter {
36733
36270
  }
36734
36271
  }
36735
36272
  });
36736
- this.stdout = new import_node_stream2.Readable({ read() {
36273
+ this.stdout = new import_node_stream.Readable({ read() {
36737
36274
  } });
36738
36275
  pty.onData((data) => {
36739
36276
  if (!this.firstDataLogged) {
@@ -36746,7 +36283,7 @@ var PtyChildProcess = class extends import_node_events.EventEmitter {
36746
36283
  }
36747
36284
  this.stdout.push(Buffer.from(data, "utf8"));
36748
36285
  });
36749
- this.stderr = new import_node_stream2.Readable({ read() {
36286
+ this.stderr = new import_node_stream.Readable({ read() {
36750
36287
  } });
36751
36288
  pty.onExit(({ exitCode, signal }) => {
36752
36289
  this.exitCode = exitCode;
@@ -37261,9 +36798,6 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
37261
36798
  if (ctx.addDirs) {
37262
36799
  for (const dir of ctx.addDirs) args.push("--add-dir", dir);
37263
36800
  }
37264
- if (ctx.dispatchMcpConfigPath) {
37265
- args.push("--mcp-config", ctx.dispatchMcpConfigPath);
37266
- }
37267
36801
  if (ctx.effort) args.push("--effort", ctx.effort);
37268
36802
  return args;
37269
36803
  }
@@ -37281,155 +36815,6 @@ function jsonlExistsForCtx(ctx) {
37281
36815
  // src/index.ts
37282
36816
  init_claude_history();
37283
36817
 
37284
- // src/dispatch/manager.ts
37285
- function defer() {
37286
- let resolve6;
37287
- const promise = new Promise((r) => {
37288
- resolve6 = r;
37289
- });
37290
- return { promise, resolve: resolve6 };
37291
- }
37292
- var PersonaDispatchManager = class {
37293
- constructor(deps) {
37294
- this.deps = deps;
37295
- }
37296
- deps;
37297
- map = /* @__PURE__ */ new Map();
37298
- start(args) {
37299
- const dispatchId = this.deps.genId();
37300
- this.map.set(dispatchId, {
37301
- dispatchId,
37302
- sourceSessionId: args.sourceSessionId,
37303
- targetPersona: args.targetPersona,
37304
- waiters: [],
37305
- outcome: null
37306
- });
37307
- return { dispatchId };
37308
- }
37309
- get(dispatchId) {
37310
- return this.map.get(dispatchId);
37311
- }
37312
- async wait(dispatchId) {
37313
- const state = this.map.get(dispatchId);
37314
- if (!state) throw new Error(`unknown dispatchId: ${dispatchId}`);
37315
- if (state.outcome) return state.outcome;
37316
- const d = defer();
37317
- state.waiters.push(d);
37318
- return d.promise;
37319
- }
37320
- complete(dispatchId, outcome) {
37321
- const state = this.map.get(dispatchId);
37322
- if (!state) throw new Error(`unknown dispatchId: ${dispatchId}`);
37323
- state.outcome = outcome;
37324
- const waiters = state.waiters;
37325
- state.waiters = [];
37326
- for (const w2 of waiters) w2.resolve(outcome);
37327
- }
37328
- /** SessionManager 在 createDispatchedSession 时调,建立 dispatchId → B sessionId 映射 */
37329
- registerBSession(dispatchId, bSessionId) {
37330
- const state = this.map.get(dispatchId);
37331
- if (!state) throw new Error(`unknown dispatchId: ${dispatchId}`);
37332
- state.bSessionId = bSessionId;
37333
- }
37334
- /** reducer buildSpawnContext 调,按 B 的 sessionId 反查 dispatchId(用于注 CLAWD_DISPATCH_ID env) */
37335
- lookupDispatchByBSessionId(bSessionId) {
37336
- for (const state of this.map.values()) {
37337
- if (state.bSessionId === bSessionId) return state.dispatchId;
37338
- }
37339
- return void 0;
37340
- }
37341
- };
37342
-
37343
- // src/dispatch/mcp-config.ts
37344
- var import_node_fs12 = __toESM(require("fs"), 1);
37345
- var import_node_path10 = __toESM(require("path"), 1);
37346
- function dispatchMcpConfigPath(dataDir) {
37347
- return import_node_path10.default.join(dataDir, "dispatch.mcp.json");
37348
- }
37349
- function writeDispatchMcpConfig(args) {
37350
- const cfgPath = dispatchMcpConfigPath(args.dataDir);
37351
- const content = {
37352
- _comment: "daemon \u542F\u52A8\u65F6\u81EA\u52A8\u751F\u6210\uFF1Bcc spawn \u901A\u8FC7 --mcp-config \u6CE8\u5165\u3002dispatch-mcp-server.cjs \u662F daemon \u81EA\u5E26\u7684 stdio MCP server\u3002env.CLAWD_DISPATCH_LOG \u6307 server \u5199\u65E5\u5FD7\u7684 append \u6587\u4EF6\u8DEF\u5F84\uFF08dispatch \u6D41\u7A0B\u8282\u70B9 + fetch \u9519\u8BEF\u7EC6\u8282\uFF09\u3002",
37353
- mcpServers: {
37354
- "clawd-dispatch": {
37355
- type: "stdio",
37356
- command: "node",
37357
- args: [args.serverScriptPath],
37358
- ...args.logPath ? { env: { CLAWD_DISPATCH_LOG: args.logPath } } : {}
37359
- }
37360
- }
37361
- };
37362
- import_node_fs12.default.mkdirSync(args.dataDir, { recursive: true });
37363
- import_node_fs12.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
37364
- return cfgPath;
37365
- }
37366
-
37367
- // src/handlers/persona-dispatch.ts
37368
- init_protocol();
37369
- function buildPersonaDispatchHandlers(deps) {
37370
- const { personaDispatchManager: mgr, spawnB, logger } = deps;
37371
- const run = async (frame) => {
37372
- const { type: _t, requestId: _r, ...rest } = frame;
37373
- const sourceSessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
37374
- const args = DispatchRunArgsSchema.parse(rest);
37375
- if (!sourceSessionId) {
37376
- throw new Error(
37377
- "personaDispatch:run requires sessionId (caller must pass x-clawd-session-id header)"
37378
- );
37379
- }
37380
- const { dispatchId } = mgr.start({
37381
- sourceSessionId,
37382
- targetPersona: args.targetPersona
37383
- });
37384
- logger?.info("dispatch.run.received", {
37385
- dispatchId,
37386
- sourceSessionId,
37387
- targetPersona: args.targetPersona,
37388
- promptLen: args.prompt.length
37389
- });
37390
- void spawnB({
37391
- dispatchId,
37392
- sourceSessionId,
37393
- targetPersona: args.targetPersona,
37394
- prompt: args.prompt
37395
- }).then(() => {
37396
- logger?.info("dispatch.spawnB.ok", { dispatchId });
37397
- }).catch((err) => {
37398
- const reason = err instanceof Error ? err.message : String(err);
37399
- logger?.warn("dispatch.spawnB.failed", { dispatchId, reason });
37400
- mgr.complete(dispatchId, {
37401
- kind: "failure",
37402
- reason: `failed to spawn B: ${reason}`
37403
- });
37404
- });
37405
- logger?.info("dispatch.run.waiting", { dispatchId });
37406
- const outcome = await mgr.wait(dispatchId);
37407
- logger?.info("dispatch.run.resolved", {
37408
- dispatchId,
37409
- outcomeKind: outcome.kind
37410
- });
37411
- return {
37412
- response: { type: "personaDispatch:run:ok", outcome }
37413
- };
37414
- };
37415
- const complete = async (frame) => {
37416
- const { type: _t, requestId: _r, ...rest } = frame;
37417
- const args = DispatchCompleteArgsSchema.parse(rest);
37418
- logger?.info("dispatch.complete.received", {
37419
- dispatchId: args.dispatchId,
37420
- outcomeKind: args.outcome.kind
37421
- });
37422
- mgr.complete(args.dispatchId, args.outcome);
37423
- return {
37424
- response: { type: "personaDispatch:complete:ok" }
37425
- };
37426
- };
37427
- return {
37428
- "personaDispatch:run": run,
37429
- "personaDispatch:complete": complete
37430
- };
37431
- }
37432
-
37433
36818
  // src/tools/codex-history.ts
37434
36819
  var import_node_child_process5 = require("child_process");
37435
36820
  var DEFAULT_TIMEOUT_MS = 8e3;
@@ -37616,13 +37001,13 @@ function mapSkillsListResponse(res) {
37616
37001
  const r = s ?? {};
37617
37002
  const name = str3(r.name);
37618
37003
  if (!name) continue;
37619
- const path59 = str3(r.path);
37004
+ const path58 = str3(r.path);
37620
37005
  const description = str3(r.description);
37621
37006
  const isPlugin = name.includes(":");
37622
37007
  out.push({
37623
37008
  name,
37624
37009
  source: isPlugin ? "plugin" : "project",
37625
- ...path59 ? { path: path59 } : {},
37010
+ ...path58 ? { path: path58 } : {},
37626
37011
  ...description ? { description } : {},
37627
37012
  ...isPlugin ? { plugin: name.split(":")[0] } : {}
37628
37013
  });
@@ -37661,23 +37046,23 @@ async function listCodexSkills(cwd, deps = {}) {
37661
37046
  }
37662
37047
 
37663
37048
  // src/workspace/browser.ts
37664
- var import_node_fs13 = __toESM(require("fs"), 1);
37049
+ var import_node_fs12 = __toESM(require("fs"), 1);
37665
37050
  var import_node_os6 = __toESM(require("os"), 1);
37666
- var import_node_path11 = __toESM(require("path"), 1);
37051
+ var import_node_path10 = __toESM(require("path"), 1);
37667
37052
  init_protocol();
37668
37053
  var MAX_FILE_BYTES = 2 * 1024 * 1024;
37669
37054
  function resolveInsideCwd(cwd, subpath) {
37670
- const absCwd = import_node_path11.default.resolve(cwd);
37671
- const joined = import_node_path11.default.resolve(absCwd, subpath ?? ".");
37672
- const rel = import_node_path11.default.relative(absCwd, joined);
37673
- if (rel.startsWith("..") || import_node_path11.default.isAbsolute(rel)) {
37055
+ const absCwd = import_node_path10.default.resolve(cwd);
37056
+ const joined = import_node_path10.default.resolve(absCwd, subpath ?? ".");
37057
+ const rel = import_node_path10.default.relative(absCwd, joined);
37058
+ if (rel.startsWith("..") || import_node_path10.default.isAbsolute(rel)) {
37674
37059
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
37675
37060
  }
37676
37061
  return joined;
37677
37062
  }
37678
37063
  function ensureCwd(cwd) {
37679
37064
  try {
37680
- const stat = import_node_fs13.default.statSync(cwd);
37065
+ const stat = import_node_fs12.default.statSync(cwd);
37681
37066
  if (!stat.isDirectory()) {
37682
37067
  throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
37683
37068
  }
@@ -37691,7 +37076,7 @@ var WorkspaceBrowser = class {
37691
37076
  const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os6.default.homedir();
37692
37077
  ensureCwd(cwd);
37693
37078
  const full = resolveInsideCwd(cwd, args.path);
37694
- const dirents = import_node_fs13.default.readdirSync(full, { withFileTypes: true });
37079
+ const dirents = import_node_fs12.default.readdirSync(full, { withFileTypes: true });
37695
37080
  const entries = [];
37696
37081
  for (const d of dirents) {
37697
37082
  if (!args.showHidden && d.name.startsWith(".")) continue;
@@ -37701,7 +37086,7 @@ var WorkspaceBrowser = class {
37701
37086
  mtime: ""
37702
37087
  };
37703
37088
  try {
37704
- const st = import_node_fs13.default.statSync(import_node_path11.default.join(full, d.name));
37089
+ const st = import_node_fs12.default.statSync(import_node_path10.default.join(full, d.name));
37705
37090
  entry.mtime = new Date(st.mtimeMs).toISOString();
37706
37091
  if (d.isFile()) entry.size = st.size;
37707
37092
  } catch {
@@ -37717,14 +37102,14 @@ var WorkspaceBrowser = class {
37717
37102
  read(args) {
37718
37103
  ensureCwd(args.cwd);
37719
37104
  const full = resolveInsideCwd(args.cwd, args.path);
37720
- const st = import_node_fs13.default.statSync(full);
37105
+ const st = import_node_fs12.default.statSync(full);
37721
37106
  if (!st.isFile()) {
37722
37107
  throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
37723
37108
  }
37724
37109
  if (st.size > MAX_FILE_BYTES) {
37725
37110
  throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
37726
37111
  }
37727
- const buf = import_node_fs13.default.readFileSync(full);
37112
+ const buf = import_node_fs12.default.readFileSync(full);
37728
37113
  const isBinary = buf.includes(0);
37729
37114
  if (isBinary) {
37730
37115
  return {
@@ -37746,20 +37131,20 @@ var WorkspaceBrowser = class {
37746
37131
  };
37747
37132
 
37748
37133
  // src/skills/agents-scanner.ts
37749
- var import_node_fs14 = __toESM(require("fs"), 1);
37134
+ var import_node_fs13 = __toESM(require("fs"), 1);
37750
37135
  var import_node_os7 = __toESM(require("os"), 1);
37751
- var import_node_path12 = __toESM(require("path"), 1);
37136
+ var import_node_path11 = __toESM(require("path"), 1);
37752
37137
  var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
37753
37138
  function isDirLikeSync2(p2) {
37754
37139
  try {
37755
- return import_node_fs14.default.statSync(p2).isDirectory();
37140
+ return import_node_fs13.default.statSync(p2).isDirectory();
37756
37141
  } catch {
37757
37142
  return false;
37758
37143
  }
37759
37144
  }
37760
37145
  function fileExistsSync(p2) {
37761
37146
  try {
37762
- return import_node_fs14.default.statSync(p2).isFile();
37147
+ return import_node_fs13.default.statSync(p2).isFile();
37763
37148
  } catch {
37764
37149
  return false;
37765
37150
  }
@@ -37767,7 +37152,7 @@ function fileExistsSync(p2) {
37767
37152
  function parseAgentFile(filePath) {
37768
37153
  let content;
37769
37154
  try {
37770
- content = import_node_fs14.default.readFileSync(filePath, "utf8");
37155
+ content = import_node_fs13.default.readFileSync(filePath, "utf8");
37771
37156
  } catch {
37772
37157
  return {};
37773
37158
  }
@@ -37780,16 +37165,16 @@ function parseAgentFile(filePath) {
37780
37165
  function scanAgentsDir(dir, source, seen, out) {
37781
37166
  let entries;
37782
37167
  try {
37783
- entries = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
37168
+ entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
37784
37169
  } catch {
37785
37170
  return;
37786
37171
  }
37787
37172
  for (const ent of entries) {
37788
37173
  if (!ent.name.endsWith(".md")) continue;
37789
- if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path12.default.join(dir, ent.name)))) {
37174
+ if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path11.default.join(dir, ent.name)))) {
37790
37175
  continue;
37791
37176
  }
37792
- const filePath = import_node_path12.default.join(dir, ent.name);
37177
+ const filePath = import_node_path11.default.join(dir, ent.name);
37793
37178
  const baseName = ent.name.replace(/\.md$/, "");
37794
37179
  if (seen.has(baseName)) continue;
37795
37180
  seen.add(baseName);
@@ -37807,12 +37192,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
37807
37192
  function walk2(dir, namespaces) {
37808
37193
  let entries;
37809
37194
  try {
37810
- entries = import_node_fs14.default.readdirSync(dir, { withFileTypes: true });
37195
+ entries = import_node_fs13.default.readdirSync(dir, { withFileTypes: true });
37811
37196
  } catch {
37812
37197
  return;
37813
37198
  }
37814
37199
  for (const ent of entries) {
37815
- const childPath = import_node_path12.default.join(dir, ent.name);
37200
+ const childPath = import_node_path11.default.join(dir, ent.name);
37816
37201
  if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
37817
37202
  walk2(childPath, [...namespaces, ent.name]);
37818
37203
  continue;
@@ -37837,13 +37222,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
37837
37222
  walk2(root, []);
37838
37223
  }
37839
37224
  function readInstalledPlugins2(home) {
37840
- const pluginsDir = import_node_path12.default.join(home, ".claude", "plugins");
37841
- const v2 = import_node_path12.default.join(pluginsDir, "installed_plugins_v2.json");
37842
- const v1 = import_node_path12.default.join(pluginsDir, "installed_plugins.json");
37225
+ const pluginsDir = import_node_path11.default.join(home, ".claude", "plugins");
37226
+ const v2 = import_node_path11.default.join(pluginsDir, "installed_plugins_v2.json");
37227
+ const v1 = import_node_path11.default.join(pluginsDir, "installed_plugins.json");
37843
37228
  let raw = null;
37844
37229
  for (const candidate of [v2, v1]) {
37845
37230
  try {
37846
- raw = import_node_fs14.default.readFileSync(candidate, "utf8");
37231
+ raw = import_node_fs13.default.readFileSync(candidate, "utf8");
37847
37232
  break;
37848
37233
  } catch {
37849
37234
  }
@@ -37868,19 +37253,19 @@ function readInstalledPlugins2(home) {
37868
37253
  return out;
37869
37254
  }
37870
37255
  function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
37871
- let cur = import_node_path12.default.resolve(startCwd);
37872
- const fsRoot = import_node_path12.default.parse(cur).root;
37256
+ let cur = import_node_path11.default.resolve(startCwd);
37257
+ const fsRoot = import_node_path11.default.parse(cur).root;
37873
37258
  while (true) {
37874
- scanAgentsDir(import_node_path12.default.join(cur, ".claude", "agents"), "project", seen, out);
37259
+ scanAgentsDir(import_node_path11.default.join(cur, ".claude", "agents"), "project", seen, out);
37875
37260
  let hasGit = false;
37876
37261
  try {
37877
- hasGit = import_node_fs14.default.existsSync(import_node_path12.default.join(cur, ".git"));
37262
+ hasGit = import_node_fs13.default.existsSync(import_node_path11.default.join(cur, ".git"));
37878
37263
  } catch {
37879
37264
  }
37880
37265
  if (hasGit) return;
37881
37266
  if (cur === home) return;
37882
37267
  if (cur === fsRoot) return;
37883
- const parent = import_node_path12.default.dirname(cur);
37268
+ const parent = import_node_path11.default.dirname(cur);
37884
37269
  if (parent === cur) return;
37885
37270
  cur = parent;
37886
37271
  }
@@ -37915,7 +37300,7 @@ var AgentsScanner = class {
37915
37300
  }
37916
37301
  const fsBlock = [];
37917
37302
  scanAgentsDir(
37918
- import_node_path12.default.join(this.home, ".claude", "agents"),
37303
+ import_node_path11.default.join(this.home, ".claude", "agents"),
37919
37304
  "global",
37920
37305
  seen,
37921
37306
  fsBlock
@@ -37929,7 +37314,7 @@ var AgentsScanner = class {
37929
37314
  ...this.extraPluginRoots
37930
37315
  ];
37931
37316
  for (const { name, root } of plugins) {
37932
- const agentsRoot = import_node_path12.default.join(root, "agents");
37317
+ const agentsRoot = import_node_path11.default.join(root, "agents");
37933
37318
  scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
37934
37319
  }
37935
37320
  return [...builtinBlock, ...fsBlock];
@@ -37937,15 +37322,15 @@ var AgentsScanner = class {
37937
37322
  };
37938
37323
 
37939
37324
  // src/observer/session-observer.ts
37940
- var import_node_fs16 = __toESM(require("fs"), 1);
37325
+ var import_node_fs15 = __toESM(require("fs"), 1);
37941
37326
  var import_node_os9 = __toESM(require("os"), 1);
37942
- var import_node_path14 = __toESM(require("path"), 1);
37327
+ var import_node_path13 = __toESM(require("path"), 1);
37943
37328
  init_claude_history();
37944
37329
 
37945
37330
  // src/observer/subagent-meta-observer.ts
37946
- var import_node_fs15 = __toESM(require("fs"), 1);
37331
+ var import_node_fs14 = __toESM(require("fs"), 1);
37947
37332
  var import_node_os8 = __toESM(require("os"), 1);
37948
- var import_node_path13 = __toESM(require("path"), 1);
37333
+ var import_node_path12 = __toESM(require("path"), 1);
37949
37334
  init_claude_history();
37950
37335
  var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
37951
37336
  var SubagentMetaObserver = class {
@@ -37958,7 +37343,7 @@ var SubagentMetaObserver = class {
37958
37343
  watches = /* @__PURE__ */ new Map();
37959
37344
  // public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
37960
37345
  resolveSubagentDir(cwd, toolSessionId) {
37961
- return import_node_path13.default.join(
37346
+ return import_node_path12.default.join(
37962
37347
  this.home,
37963
37348
  ".claude",
37964
37349
  "projects",
@@ -37988,7 +37373,7 @@ var SubagentMetaObserver = class {
37988
37373
  attachWatcher(w2) {
37989
37374
  if (w2.watcher) return;
37990
37375
  try {
37991
- w2.watcher = import_node_fs15.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
37376
+ w2.watcher = import_node_fs14.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
37992
37377
  if (!name) return;
37993
37378
  const m2 = META_RE.exec(String(name));
37994
37379
  if (!m2) return;
@@ -38000,7 +37385,7 @@ var SubagentMetaObserver = class {
38000
37385
  scan(w2) {
38001
37386
  let entries;
38002
37387
  try {
38003
- entries = import_node_fs15.default.readdirSync(w2.dirPath);
37388
+ entries = import_node_fs14.default.readdirSync(w2.dirPath);
38004
37389
  } catch {
38005
37390
  return;
38006
37391
  }
@@ -38014,10 +37399,10 @@ var SubagentMetaObserver = class {
38014
37399
  if (!m2) return;
38015
37400
  const agentId = m2[1];
38016
37401
  if (w2.emitted.has(agentId)) return;
38017
- const file = import_node_path13.default.join(w2.dirPath, name);
37402
+ const file = import_node_path12.default.join(w2.dirPath, name);
38018
37403
  let raw;
38019
37404
  try {
38020
- raw = import_node_fs15.default.readFileSync(file, "utf8");
37405
+ raw = import_node_fs14.default.readFileSync(file, "utf8");
38021
37406
  } catch {
38022
37407
  return;
38023
37408
  }
@@ -38074,14 +37459,14 @@ var SessionObserver = class {
38074
37459
  metaObserver;
38075
37460
  resolveJsonlPath(cwd, toolSessionId, override) {
38076
37461
  if (override) return override;
38077
- return import_node_path14.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
37462
+ return import_node_path13.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
38078
37463
  }
38079
37464
  start(args) {
38080
37465
  this.stop(args.sessionId);
38081
37466
  const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
38082
37467
  let size = 0;
38083
37468
  try {
38084
- size = import_node_fs16.default.statSync(filePath).size;
37469
+ size = import_node_fs15.default.statSync(filePath).size;
38085
37470
  } catch {
38086
37471
  }
38087
37472
  const w2 = {
@@ -38095,10 +37480,10 @@ var SessionObserver = class {
38095
37480
  prevIsRejectSentinel: false
38096
37481
  };
38097
37482
  try {
38098
- import_node_fs16.default.mkdirSync(import_node_path14.default.dirname(filePath), { recursive: true });
37483
+ import_node_fs15.default.mkdirSync(import_node_path13.default.dirname(filePath), { recursive: true });
38099
37484
  } catch {
38100
37485
  }
38101
- w2.watcher = import_node_fs16.default.watch(import_node_path14.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
37486
+ w2.watcher = import_node_fs15.default.watch(import_node_path13.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
38102
37487
  if (!changedName || !filePath.endsWith(changedName)) return;
38103
37488
  this.poll(w2);
38104
37489
  });
@@ -38121,7 +37506,7 @@ var SessionObserver = class {
38121
37506
  // 异常静默吞,不阻塞 watcher 启动
38122
37507
  hydrateMetaTail(w2, maxLines = 200) {
38123
37508
  try {
38124
- const raw = import_node_fs16.default.readFileSync(w2.filePath, "utf8");
37509
+ const raw = import_node_fs15.default.readFileSync(w2.filePath, "utf8");
38125
37510
  if (!raw) return;
38126
37511
  const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
38127
37512
  if (allLines.length === 0) return;
@@ -38145,7 +37530,7 @@ var SessionObserver = class {
38145
37530
  poll(w2) {
38146
37531
  let size = 0;
38147
37532
  try {
38148
- size = import_node_fs16.default.statSync(w2.filePath).size;
37533
+ size = import_node_fs15.default.statSync(w2.filePath).size;
38149
37534
  } catch {
38150
37535
  return;
38151
37536
  }
@@ -38154,11 +37539,11 @@ var SessionObserver = class {
38154
37539
  w2.buf = "";
38155
37540
  }
38156
37541
  if (size === w2.lastSize) return;
38157
- const fd = import_node_fs16.default.openSync(w2.filePath, "r");
37542
+ const fd = import_node_fs15.default.openSync(w2.filePath, "r");
38158
37543
  try {
38159
37544
  const len = size - w2.lastSize;
38160
37545
  const buf = Buffer.alloc(len);
38161
- import_node_fs16.default.readSync(fd, buf, 0, len, w2.lastSize);
37546
+ import_node_fs15.default.readSync(fd, buf, 0, len, w2.lastSize);
38162
37547
  w2.lastSize = size;
38163
37548
  w2.buf += buf.toString("utf8");
38164
37549
  let newlineIndex;
@@ -38181,7 +37566,7 @@ var SessionObserver = class {
38181
37566
  }
38182
37567
  }
38183
37568
  } finally {
38184
- import_node_fs16.default.closeSync(fd);
37569
+ import_node_fs15.default.closeSync(fd);
38185
37570
  }
38186
37571
  }
38187
37572
  // 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
@@ -38276,7 +37661,7 @@ var import_stream = __toESM(require_stream(), 1);
38276
37661
  var import_extension = __toESM(require_extension(), 1);
38277
37662
  var import_permessage_deflate = __toESM(require_permessage_deflate(), 1);
38278
37663
  var import_receiver = __toESM(require_receiver(), 1);
38279
- var import_sender2 = __toESM(require_sender(), 1);
37664
+ var import_sender = __toESM(require_sender(), 1);
38280
37665
  var import_subprotocol = __toESM(require_subprotocol(), 1);
38281
37666
  var import_websocket = __toESM(require_websocket(), 1);
38282
37667
  var import_websocket_server = __toESM(require_websocket_server(), 1);
@@ -38904,14 +38289,14 @@ async function authenticate(token, deps) {
38904
38289
  }
38905
38290
 
38906
38291
  // src/permission/capability-store.ts
38907
- var fs19 = __toESM(require("fs"), 1);
38908
- var path19 = __toESM(require("path"), 1);
38292
+ var fs18 = __toESM(require("fs"), 1);
38293
+ var path18 = __toESM(require("path"), 1);
38909
38294
  var CAPABILITIES_FILE_NAME = "capabilities.json";
38910
38295
  var FILE_VERSION = 1;
38911
38296
  var CapabilityStore = class {
38912
38297
  constructor(dataDir) {
38913
38298
  this.dataDir = dataDir;
38914
- fs19.mkdirSync(dataDir, { recursive: true });
38299
+ fs18.mkdirSync(dataDir, { recursive: true });
38915
38300
  this.cache = this.readFromDisk();
38916
38301
  }
38917
38302
  dataDir;
@@ -38935,13 +38320,13 @@ var CapabilityStore = class {
38935
38320
  this.flush();
38936
38321
  }
38937
38322
  filePath() {
38938
- return path19.join(this.dataDir, CAPABILITIES_FILE_NAME);
38323
+ return path18.join(this.dataDir, CAPABILITIES_FILE_NAME);
38939
38324
  }
38940
38325
  readFromDisk() {
38941
38326
  const file = this.filePath();
38942
38327
  let raw;
38943
38328
  try {
38944
- raw = fs19.readFileSync(file, "utf8");
38329
+ raw = fs18.readFileSync(file, "utf8");
38945
38330
  } catch (err) {
38946
38331
  if (err?.code === "ENOENT") return [];
38947
38332
  return [];
@@ -38969,10 +38354,10 @@ var CapabilityStore = class {
38969
38354
  }
38970
38355
  atomicWrite(file, content) {
38971
38356
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
38972
- fs19.writeFileSync(tmp, content, { mode: 384 });
38973
- fs19.renameSync(tmp, file);
38357
+ fs18.writeFileSync(tmp, content, { mode: 384 });
38358
+ fs18.renameSync(tmp, file);
38974
38359
  try {
38975
- fs19.chmodSync(file, 384);
38360
+ fs18.chmodSync(file, 384);
38976
38361
  } catch {
38977
38362
  }
38978
38363
  }
@@ -39065,14 +38450,14 @@ var CapabilityManager = class {
39065
38450
  };
39066
38451
 
39067
38452
  // src/permission/cleanup.ts
39068
- var fs20 = __toESM(require("fs"), 1);
38453
+ var fs19 = __toESM(require("fs"), 1);
39069
38454
  function cleanupGuestSessionsForCapability(cap, factory) {
39070
38455
  const removed = [];
39071
38456
  for (const g2 of cap.grants) {
39072
38457
  if (g2.resource.type !== "persona") continue;
39073
38458
  const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
39074
38459
  try {
39075
- fs20.rmSync(dir, { recursive: true, force: true });
38460
+ fs19.rmSync(dir, { recursive: true, force: true });
39076
38461
  removed.push(dir);
39077
38462
  } catch {
39078
38463
  }
@@ -39081,13 +38466,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
39081
38466
  }
39082
38467
 
39083
38468
  // src/inbox/inbox-store.ts
39084
- var fs21 = __toESM(require("fs"), 1);
39085
- var path20 = __toESM(require("path"), 1);
38469
+ var fs20 = __toESM(require("fs"), 1);
38470
+ var path19 = __toESM(require("path"), 1);
39086
38471
  var INBOX_SUBDIR = "inbox";
39087
38472
  var InboxStore = class {
39088
38473
  constructor(dataDir) {
39089
38474
  this.dataDir = dataDir;
39090
- fs21.mkdirSync(this.dirPath(), { recursive: true });
38475
+ fs20.mkdirSync(this.dirPath(), { recursive: true });
39091
38476
  }
39092
38477
  dataDir;
39093
38478
  /**
@@ -39099,7 +38484,7 @@ var InboxStore = class {
39099
38484
  const file = this.filePath(peerDeviceId);
39100
38485
  let raw;
39101
38486
  try {
39102
- raw = fs21.readFileSync(file, "utf8");
38487
+ raw = fs20.readFileSync(file, "utf8");
39103
38488
  } catch (err) {
39104
38489
  if (err?.code === "ENOENT") return [];
39105
38490
  return [];
@@ -39115,7 +38500,7 @@ var InboxStore = class {
39115
38500
  const dir = this.dirPath();
39116
38501
  let entries;
39117
38502
  try {
39118
- entries = fs21.readdirSync(dir);
38503
+ entries = fs20.readdirSync(dir);
39119
38504
  } catch (err) {
39120
38505
  if (err?.code === "ENOENT") return [];
39121
38506
  return [];
@@ -39131,9 +38516,9 @@ var InboxStore = class {
39131
38516
  if (existing.some((m2) => m2.id === message.id)) return;
39132
38517
  const file = this.filePath(message.peerDeviceId);
39133
38518
  const line = JSON.stringify(message) + "\n";
39134
- fs21.appendFileSync(file, line, { mode: 384 });
38519
+ fs20.appendFileSync(file, line, { mode: 384 });
39135
38520
  try {
39136
- fs21.chmodSync(file, 384);
38521
+ fs20.chmodSync(file, 384);
39137
38522
  } catch {
39138
38523
  }
39139
38524
  }
@@ -39163,7 +38548,7 @@ var InboxStore = class {
39163
38548
  removeByPeerDeviceId(peerDeviceId) {
39164
38549
  const file = this.filePath(peerDeviceId);
39165
38550
  try {
39166
- fs21.unlinkSync(file);
38551
+ fs20.unlinkSync(file);
39167
38552
  } catch (err) {
39168
38553
  if (err?.code === "ENOENT") return;
39169
38554
  }
@@ -39172,18 +38557,18 @@ var InboxStore = class {
39172
38557
  const file = this.filePath(peerDeviceId);
39173
38558
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
39174
38559
  const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
39175
- fs21.writeFileSync(tmp, content, { mode: 384 });
39176
- fs21.renameSync(tmp, file);
38560
+ fs20.writeFileSync(tmp, content, { mode: 384 });
38561
+ fs20.renameSync(tmp, file);
39177
38562
  try {
39178
- fs21.chmodSync(file, 384);
38563
+ fs20.chmodSync(file, 384);
39179
38564
  } catch {
39180
38565
  }
39181
38566
  }
39182
38567
  dirPath() {
39183
- return path20.join(this.dataDir, INBOX_SUBDIR);
38568
+ return path19.join(this.dataDir, INBOX_SUBDIR);
39184
38569
  }
39185
38570
  filePath(peerDeviceId) {
39186
- return path20.join(this.dirPath(), `${peerDeviceId}.jsonl`);
38571
+ return path19.join(this.dirPath(), `${peerDeviceId}.jsonl`);
39187
38572
  }
39188
38573
  };
39189
38574
  function parseAllLines(raw) {
@@ -39270,8 +38655,8 @@ var InboxManager = class {
39270
38655
  };
39271
38656
 
39272
38657
  // src/state/contact-store.ts
39273
- var fs22 = __toESM(require("fs"), 1);
39274
- var path21 = __toESM(require("path"), 1);
38658
+ var fs21 = __toESM(require("fs"), 1);
38659
+ var path20 = __toESM(require("path"), 1);
39275
38660
  var FILE_NAME = "contacts.json";
39276
38661
  var ContactStore = class {
39277
38662
  constructor(dataDir) {
@@ -39281,10 +38666,10 @@ var ContactStore = class {
39281
38666
  contacts = /* @__PURE__ */ new Map();
39282
38667
  load() {
39283
38668
  this.contacts.clear();
39284
- const file = path21.join(this.dataDir, FILE_NAME);
38669
+ const file = path20.join(this.dataDir, FILE_NAME);
39285
38670
  let raw;
39286
38671
  try {
39287
- raw = fs22.readFileSync(file, "utf8");
38672
+ raw = fs21.readFileSync(file, "utf8");
39288
38673
  } catch (err) {
39289
38674
  if (err?.code !== "ENOENT") this.renameBak(file);
39290
38675
  return;
@@ -39327,20 +38712,20 @@ var ContactStore = class {
39327
38712
  return existed;
39328
38713
  }
39329
38714
  flush() {
39330
- const file = path21.join(this.dataDir, FILE_NAME);
38715
+ const file = path20.join(this.dataDir, FILE_NAME);
39331
38716
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
39332
38717
  const content = JSON.stringify(
39333
38718
  { contacts: Array.from(this.contacts.values()) },
39334
38719
  null,
39335
38720
  2
39336
38721
  );
39337
- fs22.mkdirSync(this.dataDir, { recursive: true });
39338
- fs22.writeFileSync(tmp, content, { mode: 384 });
39339
- fs22.renameSync(tmp, file);
38722
+ fs21.mkdirSync(this.dataDir, { recursive: true });
38723
+ fs21.writeFileSync(tmp, content, { mode: 384 });
38724
+ fs21.renameSync(tmp, file);
39340
38725
  }
39341
38726
  renameBak(file) {
39342
38727
  try {
39343
- fs22.renameSync(file, `${file}.bak`);
38728
+ fs21.renameSync(file, `${file}.bak`);
39344
38729
  } catch {
39345
38730
  }
39346
38731
  }
@@ -39490,61 +38875,61 @@ async function autoReverseContact(args) {
39490
38875
  }
39491
38876
 
39492
38877
  // src/migrations/2026-05-20-flatten-sessions.ts
39493
- var fs23 = __toESM(require("fs"), 1);
39494
- var path22 = __toESM(require("path"), 1);
38878
+ var fs22 = __toESM(require("fs"), 1);
38879
+ var path21 = __toESM(require("path"), 1);
39495
38880
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
39496
38881
  function migrateFlattenSessions(opts) {
39497
38882
  const dataDir = opts.dataDir;
39498
38883
  const now = opts.now ?? Date.now;
39499
- const sessionsDir = path22.join(dataDir, "sessions");
39500
- const flagPath = path22.join(sessionsDir, MIGRATION_FLAG_NAME);
38884
+ const sessionsDir = path21.join(dataDir, "sessions");
38885
+ const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
39501
38886
  if (existsSync3(flagPath)) {
39502
38887
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
39503
38888
  }
39504
38889
  let movedBare = 0;
39505
38890
  let movedVmOwner = 0;
39506
38891
  let archivedListener = 0;
39507
- const defaultDir = path22.join(sessionsDir, "default");
38892
+ const defaultDir = path21.join(sessionsDir, "default");
39508
38893
  if (existsSync3(defaultDir)) {
39509
38894
  for (const entry of readdirSafe(defaultDir)) {
39510
38895
  if (!entry.endsWith(".json")) continue;
39511
- const src = path22.join(defaultDir, entry);
39512
- const dst = path22.join(sessionsDir, entry);
39513
- fs23.renameSync(src, dst);
38896
+ const src = path21.join(defaultDir, entry);
38897
+ const dst = path21.join(sessionsDir, entry);
38898
+ fs22.renameSync(src, dst);
39514
38899
  movedBare += 1;
39515
38900
  }
39516
38901
  rmdirIfEmpty(defaultDir);
39517
38902
  }
39518
38903
  for (const pid of readdirSafe(sessionsDir)) {
39519
- const personaDir = path22.join(sessionsDir, pid);
38904
+ const personaDir = path21.join(sessionsDir, pid);
39520
38905
  if (!isDir(personaDir)) continue;
39521
38906
  if (pid === "default") continue;
39522
- const ownerSrc = path22.join(personaDir, "owner");
38907
+ const ownerSrc = path21.join(personaDir, "owner");
39523
38908
  if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
39524
- const ownerDst = path22.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
39525
- fs23.mkdirSync(ownerDst, { recursive: true });
38909
+ const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
38910
+ fs22.mkdirSync(ownerDst, { recursive: true });
39526
38911
  for (const file of readdirSafe(ownerSrc)) {
39527
38912
  if (!file.endsWith(".json")) continue;
39528
- fs23.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
38913
+ fs22.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
39529
38914
  movedVmOwner += 1;
39530
38915
  }
39531
38916
  rmdirIfEmpty(ownerSrc);
39532
38917
  }
39533
- const listenerSrc = path22.join(personaDir, "listener");
38918
+ const listenerSrc = path21.join(personaDir, "listener");
39534
38919
  if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
39535
- const archiveDst = path22.join(dataDir, ".legacy", `listener-${pid}`);
39536
- fs23.mkdirSync(archiveDst, { recursive: true });
38920
+ const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
38921
+ fs22.mkdirSync(archiveDst, { recursive: true });
39537
38922
  for (const file of readdirSafe(listenerSrc)) {
39538
38923
  if (!file.endsWith(".json")) continue;
39539
- fs23.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
38924
+ fs22.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
39540
38925
  archivedListener += 1;
39541
38926
  }
39542
38927
  rmdirIfEmpty(listenerSrc);
39543
38928
  }
39544
38929
  rmdirIfEmpty(personaDir);
39545
38930
  }
39546
- fs23.mkdirSync(sessionsDir, { recursive: true });
39547
- fs23.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
38931
+ fs22.mkdirSync(sessionsDir, { recursive: true });
38932
+ fs22.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
39548
38933
  return {
39549
38934
  skipped: false,
39550
38935
  flagWritten: true,
@@ -39555,7 +38940,7 @@ function migrateFlattenSessions(opts) {
39555
38940
  }
39556
38941
  function existsSync3(p2) {
39557
38942
  try {
39558
- fs23.statSync(p2);
38943
+ fs22.statSync(p2);
39559
38944
  return true;
39560
38945
  } catch {
39561
38946
  return false;
@@ -39563,31 +38948,31 @@ function existsSync3(p2) {
39563
38948
  }
39564
38949
  function isDir(p2) {
39565
38950
  try {
39566
- return fs23.statSync(p2).isDirectory();
38951
+ return fs22.statSync(p2).isDirectory();
39567
38952
  } catch {
39568
38953
  return false;
39569
38954
  }
39570
38955
  }
39571
38956
  function readdirSafe(p2) {
39572
38957
  try {
39573
- return fs23.readdirSync(p2);
38958
+ return fs22.readdirSync(p2);
39574
38959
  } catch {
39575
38960
  return [];
39576
38961
  }
39577
38962
  }
39578
38963
  function rmdirIfEmpty(p2) {
39579
38964
  try {
39580
- fs23.rmdirSync(p2);
38965
+ fs22.rmdirSync(p2);
39581
38966
  } catch {
39582
38967
  }
39583
38968
  }
39584
38969
 
39585
38970
  // src/transport/http-router.ts
39586
- var import_node_fs18 = __toESM(require("fs"), 1);
39587
- var import_node_path18 = __toESM(require("path"), 1);
38971
+ var import_node_fs17 = __toESM(require("fs"), 1);
38972
+ var import_node_path17 = __toESM(require("path"), 1);
39588
38973
 
39589
38974
  // src/attachment/mime.ts
39590
- var import_node_path15 = __toESM(require("path"), 1);
38975
+ var import_node_path14 = __toESM(require("path"), 1);
39591
38976
  var TEXT_PLAIN = "text/plain; charset=utf-8";
39592
38977
  var EXT_TO_NATIVE_MIME = {
39593
38978
  // 图片
@@ -39694,7 +39079,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
39694
39079
  ".mk"
39695
39080
  ]);
39696
39081
  function lookupMime(filePathOrName) {
39697
- const ext = import_node_path15.default.extname(filePathOrName).toLowerCase();
39082
+ const ext = import_node_path14.default.extname(filePathOrName).toLowerCase();
39698
39083
  if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
39699
39084
  if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
39700
39085
  return "application/octet-stream";
@@ -39763,8 +39148,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
39763
39148
  }
39764
39149
 
39765
39150
  // src/attachment/upload.ts
39766
- var import_node_fs17 = __toESM(require("fs"), 1);
39767
- var import_node_path16 = __toESM(require("path"), 1);
39151
+ var import_node_fs16 = __toESM(require("fs"), 1);
39152
+ var import_node_path15 = __toESM(require("path"), 1);
39768
39153
  var import_node_crypto5 = __toESM(require("crypto"), 1);
39769
39154
  var import_promises = require("stream/promises");
39770
39155
  var UploadError = class extends Error {
@@ -39776,22 +39161,22 @@ var UploadError = class extends Error {
39776
39161
  code;
39777
39162
  };
39778
39163
  function assertValidFileName(fileName) {
39779
- if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path16.default.basename(fileName)) {
39164
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path15.default.basename(fileName)) {
39780
39165
  throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
39781
39166
  }
39782
39167
  }
39783
39168
  var HASH_PREFIX_LEN = 16;
39784
39169
  async function writeUploadedAttachment(args) {
39785
39170
  assertValidFileName(args.fileName);
39786
- const attachmentsRoot = import_node_path16.default.join(args.sessionDir, ".attachments");
39171
+ const attachmentsRoot = import_node_path15.default.join(args.sessionDir, ".attachments");
39787
39172
  try {
39788
- import_node_fs17.default.mkdirSync(attachmentsRoot, { recursive: true });
39173
+ import_node_fs16.default.mkdirSync(attachmentsRoot, { recursive: true });
39789
39174
  } catch (err) {
39790
39175
  throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
39791
39176
  }
39792
39177
  const hasher = import_node_crypto5.default.createHash("sha256");
39793
39178
  let actualSize = 0;
39794
- const tmpPath = import_node_path16.default.join(
39179
+ const tmpPath = import_node_path15.default.join(
39795
39180
  attachmentsRoot,
39796
39181
  `.upload-${process.pid}-${Date.now()}-${import_node_crypto5.default.randomBytes(4).toString("hex")}`
39797
39182
  );
@@ -39806,18 +39191,18 @@ async function writeUploadedAttachment(args) {
39806
39191
  yield buf;
39807
39192
  }
39808
39193
  },
39809
- import_node_fs17.default.createWriteStream(tmpPath, { mode: 384 })
39194
+ import_node_fs16.default.createWriteStream(tmpPath, { mode: 384 })
39810
39195
  );
39811
39196
  } catch (err) {
39812
39197
  try {
39813
- import_node_fs17.default.unlinkSync(tmpPath);
39198
+ import_node_fs16.default.unlinkSync(tmpPath);
39814
39199
  } catch {
39815
39200
  }
39816
39201
  throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
39817
39202
  }
39818
39203
  if (actualSize !== args.contentLength) {
39819
39204
  try {
39820
- import_node_fs17.default.unlinkSync(tmpPath);
39205
+ import_node_fs16.default.unlinkSync(tmpPath);
39821
39206
  } catch {
39822
39207
  }
39823
39208
  throw new UploadError(
@@ -39826,35 +39211,35 @@ async function writeUploadedAttachment(args) {
39826
39211
  );
39827
39212
  }
39828
39213
  const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
39829
- const hashDir = import_node_path16.default.join(attachmentsRoot, attachmentId);
39214
+ const hashDir = import_node_path15.default.join(attachmentsRoot, attachmentId);
39830
39215
  let finalFileName;
39831
39216
  let hashDirExists = false;
39832
39217
  try {
39833
- hashDirExists = import_node_fs17.default.statSync(hashDir).isDirectory();
39218
+ hashDirExists = import_node_fs16.default.statSync(hashDir).isDirectory();
39834
39219
  } catch {
39835
39220
  }
39836
39221
  if (hashDirExists) {
39837
- const existing = import_node_fs17.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
39222
+ const existing = import_node_fs16.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
39838
39223
  finalFileName = existing[0] ?? args.fileName;
39839
39224
  try {
39840
- import_node_fs17.default.unlinkSync(tmpPath);
39225
+ import_node_fs16.default.unlinkSync(tmpPath);
39841
39226
  } catch {
39842
39227
  }
39843
39228
  } else {
39844
39229
  try {
39845
- import_node_fs17.default.mkdirSync(hashDir, { recursive: true });
39230
+ import_node_fs16.default.mkdirSync(hashDir, { recursive: true });
39846
39231
  finalFileName = args.fileName;
39847
- import_node_fs17.default.renameSync(tmpPath, import_node_path16.default.join(hashDir, finalFileName));
39232
+ import_node_fs16.default.renameSync(tmpPath, import_node_path15.default.join(hashDir, finalFileName));
39848
39233
  } catch (err) {
39849
39234
  try {
39850
- import_node_fs17.default.unlinkSync(tmpPath);
39235
+ import_node_fs16.default.unlinkSync(tmpPath);
39851
39236
  } catch {
39852
39237
  }
39853
39238
  throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
39854
39239
  }
39855
39240
  }
39856
- const absPath = import_node_path16.default.join(hashDir, finalFileName);
39857
- const relPath = import_node_path16.default.relative(args.sessionDir, absPath);
39241
+ const absPath = import_node_path15.default.join(hashDir, finalFileName);
39242
+ const relPath = import_node_path15.default.relative(args.sessionDir, absPath);
39858
39243
  args.groupFileStore.upsert(args.scope, args.sessionId, {
39859
39244
  relPath: absPath,
39860
39245
  // 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
@@ -39868,7 +39253,7 @@ async function writeUploadedAttachment(args) {
39868
39253
 
39869
39254
  // src/extension/import.ts
39870
39255
  var import_promises2 = __toESM(require("fs/promises"), 1);
39871
- var import_node_path17 = __toESM(require("path"), 1);
39256
+ var import_node_path16 = __toESM(require("path"), 1);
39872
39257
  var import_node_os10 = __toESM(require("os"), 1);
39873
39258
  var import_jszip = __toESM(require_lib3(), 1);
39874
39259
  var ImportError = class extends Error {
@@ -39886,7 +39271,7 @@ async function importZip(buf, root) {
39886
39271
  throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
39887
39272
  }
39888
39273
  for (const name of Object.keys(zip.files)) {
39889
- if (name.includes("..") || name.startsWith("/") || import_node_path17.default.isAbsolute(name)) {
39274
+ if (name.includes("..") || name.startsWith("/") || import_node_path16.default.isAbsolute(name)) {
39890
39275
  throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
39891
39276
  }
39892
39277
  }
@@ -39919,7 +39304,7 @@ async function importZip(buf, root) {
39919
39304
  );
39920
39305
  }
39921
39306
  }
39922
- const destDir = import_node_path17.default.join(root, manifest.id);
39307
+ const destDir = import_node_path16.default.join(root, manifest.id);
39923
39308
  let destExists = false;
39924
39309
  try {
39925
39310
  await import_promises2.default.access(destDir);
@@ -39929,15 +39314,15 @@ async function importZip(buf, root) {
39929
39314
  if (destExists) {
39930
39315
  throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
39931
39316
  }
39932
- const stage = await import_promises2.default.mkdtemp(import_node_path17.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39317
+ const stage = await import_promises2.default.mkdtemp(import_node_path16.default.join(import_node_os10.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
39933
39318
  try {
39934
39319
  for (const [name, entry] of Object.entries(zip.files)) {
39935
- const dest = import_node_path17.default.join(stage, name);
39320
+ const dest = import_node_path16.default.join(stage, name);
39936
39321
  if (entry.dir) {
39937
39322
  await import_promises2.default.mkdir(dest, { recursive: true });
39938
39323
  continue;
39939
39324
  }
39940
- await import_promises2.default.mkdir(import_node_path17.default.dirname(dest), { recursive: true });
39325
+ await import_promises2.default.mkdir(import_node_path16.default.dirname(dest), { recursive: true });
39941
39326
  const content = await entry.async("nodebuffer");
39942
39327
  await import_promises2.default.writeFile(dest, content);
39943
39328
  }
@@ -39963,11 +39348,9 @@ var EXPOSED_RPC_METHODS = [
39963
39348
  "appBuilder.reportStage",
39964
39349
  // 单栏 §5.6.5 fix: UI 切 session 时调(assistant 不需要主动调,但暴露白名单避免误猜成 forbidden)
39965
39350
  "appBuilder.setActiveSession",
39966
- // Persona dispatch (Task 4): A 端 dispatch MCP server 调 run(hold-and-wait 一次);
39967
- // B dispatch MCP server 调 complete(带 outcome 触发 run 端 resolve)。详见
39968
- // protocol/src/dispatch.ts。
39969
- "personaDispatch.run",
39970
- "personaDispatch.complete"
39351
+ // dataclaw-builder:persona 建页时取建页人身份(含 union_id)写进生成 app 的配置。
39352
+ // 路由到 handlers['auth:getIdentity'],只返 identity、绝不带 ttcToken(见 handlers/feishu-auth.ts)。
39353
+ "auth.getIdentity"
39971
39354
  ];
39972
39355
  async function handleRpcRequest(input) {
39973
39356
  const { method, body, sessionId, dispatcher } = input;
@@ -40056,7 +39439,7 @@ function isValidUploadFileName(fileName) {
40056
39439
  if (fileName === "." || fileName === "..") return false;
40057
39440
  if (fileName.startsWith(".")) return false;
40058
39441
  if (fileName.includes("/") || fileName.includes("\\")) return false;
40059
- return fileName === import_node_path18.default.basename(fileName);
39442
+ return fileName === import_node_path17.default.basename(fileName);
40060
39443
  }
40061
39444
  function createHttpRouter(deps) {
40062
39445
  return async (req, res) => {
@@ -40103,8 +39486,6 @@ function createHttpRouter(deps) {
40103
39486
  sendJson(res, 403, { code: "NOT_LOOPBACK", message: "RPC adapter only accepts loopback connections" });
40104
39487
  return true;
40105
39488
  }
40106
- req.socket.setTimeout(0);
40107
- res.socket?.setTimeout(0);
40108
39489
  const method = url.pathname.slice(RPC_ROUTE_PREFIX.length).split("?")[0] ?? "";
40109
39490
  const sessionId = req.headers["x-clawd-session-id"] ?? void 0;
40110
39491
  let body;
@@ -40287,7 +39668,7 @@ function createHttpRouter(deps) {
40287
39668
  return true;
40288
39669
  }
40289
39670
  let absPath;
40290
- if (import_node_path18.default.isAbsolute(pathParam)) {
39671
+ if (import_node_path17.default.isAbsolute(pathParam)) {
40291
39672
  absPath = pathParam;
40292
39673
  } else if (deps.sessionStore) {
40293
39674
  const file = deps.sessionStore.read(sid);
@@ -40295,7 +39676,7 @@ function createHttpRouter(deps) {
40295
39676
  sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
40296
39677
  return true;
40297
39678
  }
40298
- absPath = import_node_path18.default.join(file.cwd, pathParam);
39679
+ absPath = import_node_path17.default.join(file.cwd, pathParam);
40299
39680
  } else {
40300
39681
  sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
40301
39682
  return true;
@@ -40378,7 +39759,7 @@ function withCtx(ctx, body) {
40378
39759
  function streamFile(res, absPath, logger) {
40379
39760
  let stat;
40380
39761
  try {
40381
- stat = import_node_fs18.default.statSync(absPath);
39762
+ stat = import_node_fs17.default.statSync(absPath);
40382
39763
  } catch (err) {
40383
39764
  const code = err?.code;
40384
39765
  if (code === "ENOENT") {
@@ -40393,7 +39774,7 @@ function streamFile(res, absPath, logger) {
40393
39774
  return;
40394
39775
  }
40395
39776
  const mime = lookupMime(absPath);
40396
- const basename = import_node_path18.default.basename(absPath);
39777
+ const basename = import_node_path17.default.basename(absPath);
40397
39778
  res.writeHead(200, {
40398
39779
  "Content-Type": mime,
40399
39780
  "Content-Length": String(stat.size),
@@ -40401,7 +39782,7 @@ function streamFile(res, absPath, logger) {
40401
39782
  // 防止浏览器把任意 mime 当 html 渲染
40402
39783
  "X-Content-Type-Options": "nosniff"
40403
39784
  });
40404
- const stream = import_node_fs18.default.createReadStream(absPath);
39785
+ const stream = import_node_fs17.default.createReadStream(absPath);
40405
39786
  stream.on("error", (err) => {
40406
39787
  logger?.warn("streamFile read error", { absPath, err: err.message });
40407
39788
  res.destroy();
@@ -40410,8 +39791,8 @@ function streamFile(res, absPath, logger) {
40410
39791
  }
40411
39792
 
40412
39793
  // src/attachment/gc.ts
40413
- var import_node_fs19 = __toESM(require("fs"), 1);
40414
- var import_node_path19 = __toESM(require("path"), 1);
39794
+ var import_node_fs18 = __toESM(require("fs"), 1);
39795
+ var import_node_path18 = __toESM(require("path"), 1);
40415
39796
  var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
40416
39797
  function runAttachmentGc(args) {
40417
39798
  const now = (args.now ?? Date.now)();
@@ -40420,38 +39801,38 @@ function runAttachmentGc(args) {
40420
39801
  for (const { scope, sessionId } of args.sessionScopes) {
40421
39802
  for (const entry of args.groupFileStore.list(scope, sessionId)) {
40422
39803
  if (entry.stale) continue;
40423
- if (import_node_path19.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
39804
+ if (import_node_path18.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
40424
39805
  }
40425
39806
  }
40426
39807
  for (const { scope, sessionId } of args.sessionScopes) {
40427
- const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path19.default.join(
39808
+ const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path18.default.join(
40428
39809
  args.dataDir,
40429
39810
  "sessions",
40430
39811
  ...scopeSubPath(scope).map(safeFileName),
40431
39812
  safeFileName(sessionId)
40432
39813
  );
40433
- const attRoot = import_node_path19.default.join(sessionDir, ".attachments");
39814
+ const attRoot = import_node_path18.default.join(sessionDir, ".attachments");
40434
39815
  let hashDirs;
40435
39816
  try {
40436
- hashDirs = import_node_fs19.default.readdirSync(attRoot);
39817
+ hashDirs = import_node_fs18.default.readdirSync(attRoot);
40437
39818
  } catch (err) {
40438
39819
  if (err.code === "ENOENT") continue;
40439
39820
  args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
40440
39821
  continue;
40441
39822
  }
40442
39823
  for (const hashDir of hashDirs) {
40443
- const hashDirAbs = import_node_path19.default.join(attRoot, hashDir);
39824
+ const hashDirAbs = import_node_path18.default.join(attRoot, hashDir);
40444
39825
  let files;
40445
39826
  try {
40446
- files = import_node_fs19.default.readdirSync(hashDirAbs);
39827
+ files = import_node_fs18.default.readdirSync(hashDirAbs);
40447
39828
  } catch {
40448
39829
  continue;
40449
39830
  }
40450
39831
  for (const name of files) {
40451
- const file = import_node_path19.default.join(hashDirAbs, name);
39832
+ const file = import_node_path18.default.join(hashDirAbs, name);
40452
39833
  let stat;
40453
39834
  try {
40454
- stat = import_node_fs19.default.statSync(file);
39835
+ stat = import_node_fs18.default.statSync(file);
40455
39836
  } catch {
40456
39837
  continue;
40457
39838
  }
@@ -40460,26 +39841,26 @@ function runAttachmentGc(args) {
40460
39841
  if (age < ttlMs) continue;
40461
39842
  if (liveAbs.has(file)) continue;
40462
39843
  try {
40463
- import_node_fs19.default.unlinkSync(file);
39844
+ import_node_fs18.default.unlinkSync(file);
40464
39845
  } catch (err) {
40465
39846
  args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
40466
39847
  }
40467
39848
  }
40468
39849
  try {
40469
- if (import_node_fs19.default.readdirSync(hashDirAbs).length === 0) import_node_fs19.default.rmdirSync(hashDirAbs);
39850
+ if (import_node_fs18.default.readdirSync(hashDirAbs).length === 0) import_node_fs18.default.rmdirSync(hashDirAbs);
40470
39851
  } catch {
40471
39852
  }
40472
39853
  }
40473
39854
  try {
40474
- if (import_node_fs19.default.readdirSync(attRoot).length === 0) import_node_fs19.default.rmdirSync(attRoot);
39855
+ if (import_node_fs18.default.readdirSync(attRoot).length === 0) import_node_fs18.default.rmdirSync(attRoot);
40475
39856
  } catch {
40476
39857
  }
40477
39858
  }
40478
39859
  }
40479
39860
 
40480
39861
  // src/attachment/group.ts
40481
- var import_node_fs20 = __toESM(require("fs"), 1);
40482
- var import_node_path20 = __toESM(require("path"), 1);
39862
+ var import_node_fs19 = __toESM(require("fs"), 1);
39863
+ var import_node_path19 = __toESM(require("path"), 1);
40483
39864
  var import_node_crypto6 = __toESM(require("crypto"), 1);
40484
39865
  init_protocol();
40485
39866
  var GroupFileStore = class {
@@ -40491,11 +39872,11 @@ var GroupFileStore = class {
40491
39872
  this.logger = opts.logger;
40492
39873
  }
40493
39874
  rootForScope(scope) {
40494
- return import_node_path20.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
39875
+ return import_node_path19.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
40495
39876
  }
40496
39877
  /** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
40497
39878
  filePath(scope, sessionId) {
40498
- return import_node_path20.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
39879
+ return import_node_path19.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
40499
39880
  }
40500
39881
  cacheKey(scope, sessionId) {
40501
39882
  return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
@@ -40504,7 +39885,7 @@ var GroupFileStore = class {
40504
39885
  readFile(scope, sessionId) {
40505
39886
  const file = this.filePath(scope, sessionId);
40506
39887
  try {
40507
- const raw = import_node_fs20.default.readFileSync(file, "utf8");
39888
+ const raw = import_node_fs19.default.readFileSync(file, "utf8");
40508
39889
  const parsed = JSON.parse(raw);
40509
39890
  if (!Array.isArray(parsed)) {
40510
39891
  this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
@@ -40530,10 +39911,10 @@ var GroupFileStore = class {
40530
39911
  }
40531
39912
  writeFile(scope, sessionId, entries) {
40532
39913
  const file = this.filePath(scope, sessionId);
40533
- import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(file), { recursive: true });
39914
+ import_node_fs19.default.mkdirSync(import_node_path19.default.dirname(file), { recursive: true });
40534
39915
  const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
40535
- import_node_fs20.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
40536
- import_node_fs20.default.renameSync(tmp, file);
39916
+ import_node_fs19.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
39917
+ import_node_fs19.default.renameSync(tmp, file);
40537
39918
  }
40538
39919
  /** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
40539
39920
  list(scope, sessionId) {
@@ -40619,10 +40000,10 @@ var GroupFileStore = class {
40619
40000
  };
40620
40001
 
40621
40002
  // src/discovery/state-file.ts
40622
- var import_node_fs21 = __toESM(require("fs"), 1);
40623
- var import_node_path21 = __toESM(require("path"), 1);
40003
+ var import_node_fs20 = __toESM(require("fs"), 1);
40004
+ var import_node_path20 = __toESM(require("path"), 1);
40624
40005
  function defaultStateFilePath(dataDir) {
40625
- return import_node_path21.default.join(dataDir, "state.json");
40006
+ return import_node_path20.default.join(dataDir, "state.json");
40626
40007
  }
40627
40008
  function isPidAlive(pid) {
40628
40009
  if (!Number.isFinite(pid) || pid <= 0) return false;
@@ -40644,7 +40025,7 @@ var StateFileManager = class {
40644
40025
  }
40645
40026
  read() {
40646
40027
  try {
40647
- const raw = import_node_fs21.default.readFileSync(this.file, "utf8");
40028
+ const raw = import_node_fs20.default.readFileSync(this.file, "utf8");
40648
40029
  const parsed = JSON.parse(raw);
40649
40030
  return parsed;
40650
40031
  } catch {
@@ -40658,20 +40039,20 @@ var StateFileManager = class {
40658
40039
  return { status: "stale", existing };
40659
40040
  }
40660
40041
  write(state) {
40661
- import_node_fs21.default.mkdirSync(import_node_path21.default.dirname(this.file), { recursive: true });
40042
+ import_node_fs20.default.mkdirSync(import_node_path20.default.dirname(this.file), { recursive: true });
40662
40043
  const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
40663
- import_node_fs21.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
40664
- import_node_fs21.default.renameSync(tmp, this.file);
40044
+ import_node_fs20.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
40045
+ import_node_fs20.default.renameSync(tmp, this.file);
40665
40046
  if (process.platform !== "win32") {
40666
40047
  try {
40667
- import_node_fs21.default.chmodSync(this.file, 384);
40048
+ import_node_fs20.default.chmodSync(this.file, 384);
40668
40049
  } catch {
40669
40050
  }
40670
40051
  }
40671
40052
  }
40672
40053
  delete() {
40673
40054
  try {
40674
- import_node_fs21.default.unlinkSync(this.file);
40055
+ import_node_fs20.default.unlinkSync(this.file);
40675
40056
  } catch {
40676
40057
  }
40677
40058
  }
@@ -40686,14 +40067,14 @@ function readDaemonSourceFromEnv(env = process.env) {
40686
40067
  }
40687
40068
 
40688
40069
  // src/tunnel/tunnel-manager.ts
40689
- var import_node_fs25 = __toESM(require("fs"), 1);
40690
- var import_node_path25 = __toESM(require("path"), 1);
40070
+ var import_node_fs24 = __toESM(require("fs"), 1);
40071
+ var import_node_path24 = __toESM(require("path"), 1);
40691
40072
  var import_node_crypto7 = __toESM(require("crypto"), 1);
40692
40073
  var import_node_child_process9 = require("child_process");
40693
40074
 
40694
40075
  // src/tunnel/tunnel-store.ts
40695
- var import_node_fs22 = __toESM(require("fs"), 1);
40696
- var import_node_path22 = __toESM(require("path"), 1);
40076
+ var import_node_fs21 = __toESM(require("fs"), 1);
40077
+ var import_node_path21 = __toESM(require("path"), 1);
40697
40078
  var TunnelStore = class {
40698
40079
  constructor(filePath) {
40699
40080
  this.filePath = filePath;
@@ -40701,7 +40082,7 @@ var TunnelStore = class {
40701
40082
  filePath;
40702
40083
  async get() {
40703
40084
  try {
40704
- const raw = await import_node_fs22.default.promises.readFile(this.filePath, "utf8");
40085
+ const raw = await import_node_fs21.default.promises.readFile(this.filePath, "utf8");
40705
40086
  const obj = JSON.parse(raw);
40706
40087
  if (!isPersistedTunnel(obj)) return null;
40707
40088
  return obj;
@@ -40712,22 +40093,22 @@ var TunnelStore = class {
40712
40093
  }
40713
40094
  }
40714
40095
  async set(v2) {
40715
- const dir = import_node_path22.default.dirname(this.filePath);
40716
- await import_node_fs22.default.promises.mkdir(dir, { recursive: true });
40096
+ const dir = import_node_path21.default.dirname(this.filePath);
40097
+ await import_node_fs21.default.promises.mkdir(dir, { recursive: true });
40717
40098
  const data = JSON.stringify(v2, null, 2);
40718
40099
  const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
40719
- await import_node_fs22.default.promises.writeFile(tmp, data, { mode: 384 });
40100
+ await import_node_fs21.default.promises.writeFile(tmp, data, { mode: 384 });
40720
40101
  if (process.platform !== "win32") {
40721
40102
  try {
40722
- await import_node_fs22.default.promises.chmod(tmp, 384);
40103
+ await import_node_fs21.default.promises.chmod(tmp, 384);
40723
40104
  } catch {
40724
40105
  }
40725
40106
  }
40726
- await import_node_fs22.default.promises.rename(tmp, this.filePath);
40107
+ await import_node_fs21.default.promises.rename(tmp, this.filePath);
40727
40108
  }
40728
40109
  async clear() {
40729
40110
  try {
40730
- await import_node_fs22.default.promises.unlink(this.filePath);
40111
+ await import_node_fs21.default.promises.unlink(this.filePath);
40731
40112
  } catch (err) {
40732
40113
  const code = err?.code;
40733
40114
  if (code !== "ENOENT") throw err;
@@ -40822,11 +40203,11 @@ function escape(v2) {
40822
40203
  }
40823
40204
 
40824
40205
  // src/tunnel/frpc-binary.ts
40825
- var import_node_fs23 = __toESM(require("fs"), 1);
40206
+ var import_node_fs22 = __toESM(require("fs"), 1);
40826
40207
  var import_node_os11 = __toESM(require("os"), 1);
40827
- var import_node_path23 = __toESM(require("path"), 1);
40208
+ var import_node_path22 = __toESM(require("path"), 1);
40828
40209
  var import_node_child_process7 = require("child_process");
40829
- var import_node_stream3 = require("stream");
40210
+ var import_node_stream2 = require("stream");
40830
40211
  var import_promises3 = require("stream/promises");
40831
40212
  var FRPC_VERSION = "0.68.0";
40832
40213
  var UnsupportedPlatformError = class extends Error {
@@ -40856,20 +40237,20 @@ function frpcDownloadUrl(version2, p2) {
40856
40237
  }
40857
40238
  async function ensureFrpcBinary(opts) {
40858
40239
  if (opts.override) {
40859
- if (!import_node_fs23.default.existsSync(opts.override)) {
40240
+ if (!import_node_fs22.default.existsSync(opts.override)) {
40860
40241
  throw new Error(`frpc binary not found at override path: ${opts.override}`);
40861
40242
  }
40862
40243
  return opts.override;
40863
40244
  }
40864
40245
  const version2 = opts.version ?? FRPC_VERSION;
40865
40246
  const platform = opts.platform ?? detectPlatform();
40866
- const binDir = import_node_path23.default.join(opts.dataDir, "bin");
40867
- import_node_fs23.default.mkdirSync(binDir, { recursive: true });
40247
+ const binDir = import_node_path22.default.join(opts.dataDir, "bin");
40248
+ import_node_fs22.default.mkdirSync(binDir, { recursive: true });
40868
40249
  cleanupStaleArtifacts(binDir);
40869
- const stableBin = import_node_path23.default.join(binDir, "frpc");
40870
- if (import_node_fs23.default.existsSync(stableBin)) return stableBin;
40250
+ const stableBin = import_node_path22.default.join(binDir, "frpc");
40251
+ if (import_node_fs22.default.existsSync(stableBin)) return stableBin;
40871
40252
  const partialBin = `${stableBin}.partial`;
40872
- const tarballPath = import_node_path23.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
40253
+ const tarballPath = import_node_path22.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
40873
40254
  try {
40874
40255
  const url = frpcDownloadUrl(version2, platform);
40875
40256
  await downloadToFile(url, tarballPath, opts.fetchImpl);
@@ -40878,8 +40259,8 @@ async function ensureFrpcBinary(opts) {
40878
40259
  } else {
40879
40260
  await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
40880
40261
  }
40881
- import_node_fs23.default.chmodSync(partialBin, 493);
40882
- import_node_fs23.default.renameSync(partialBin, stableBin);
40262
+ import_node_fs22.default.chmodSync(partialBin, 493);
40263
+ import_node_fs22.default.renameSync(partialBin, stableBin);
40883
40264
  } finally {
40884
40265
  safeUnlink(tarballPath);
40885
40266
  safeUnlink(partialBin);
@@ -40889,15 +40270,15 @@ async function ensureFrpcBinary(opts) {
40889
40270
  function cleanupStaleArtifacts(binDir) {
40890
40271
  let entries;
40891
40272
  try {
40892
- entries = import_node_fs23.default.readdirSync(binDir);
40273
+ entries = import_node_fs22.default.readdirSync(binDir);
40893
40274
  } catch {
40894
40275
  return;
40895
40276
  }
40896
40277
  for (const name of entries) {
40897
40278
  if (name.endsWith(".partial") || name.startsWith("extract-")) {
40898
- const full = import_node_path23.default.join(binDir, name);
40279
+ const full = import_node_path22.default.join(binDir, name);
40899
40280
  try {
40900
- import_node_fs23.default.rmSync(full, { recursive: true, force: true });
40281
+ import_node_fs22.default.rmSync(full, { recursive: true, force: true });
40901
40282
  } catch {
40902
40283
  }
40903
40284
  }
@@ -40905,7 +40286,7 @@ function cleanupStaleArtifacts(binDir) {
40905
40286
  }
40906
40287
  function safeUnlink(p2) {
40907
40288
  try {
40908
- import_node_fs23.default.unlinkSync(p2);
40289
+ import_node_fs22.default.unlinkSync(p2);
40909
40290
  } catch {
40910
40291
  }
40911
40292
  }
@@ -40916,13 +40297,13 @@ async function downloadToFile(url, dest, fetchImpl) {
40916
40297
  if (!res.ok || !res.body) {
40917
40298
  throw new Error(`download failed: ${res.status} ${res.statusText}`);
40918
40299
  }
40919
- const out = import_node_fs23.default.createWriteStream(dest);
40920
- const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
40300
+ const out = import_node_fs22.default.createWriteStream(dest);
40301
+ const nodeStream = import_node_stream2.Readable.fromWeb(res.body);
40921
40302
  await (0, import_promises3.pipeline)(nodeStream, out);
40922
40303
  }
40923
40304
  async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
40924
- const work = import_node_path23.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
40925
- import_node_fs23.default.mkdirSync(work, { recursive: true });
40305
+ const work = import_node_path22.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
40306
+ import_node_fs22.default.mkdirSync(work, { recursive: true });
40926
40307
  try {
40927
40308
  await new Promise((resolve6, reject) => {
40928
40309
  const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
@@ -40930,32 +40311,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
40930
40311
  proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
40931
40312
  });
40932
40313
  const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
40933
- const src = import_node_path23.default.join(work, dirName, "frpc");
40934
- if (!import_node_fs23.default.existsSync(src)) {
40314
+ const src = import_node_path22.default.join(work, dirName, "frpc");
40315
+ if (!import_node_fs22.default.existsSync(src)) {
40935
40316
  throw new Error(`frpc not found inside tarball at ${src}`);
40936
40317
  }
40937
- import_node_fs23.default.copyFileSync(src, destBin);
40318
+ import_node_fs22.default.copyFileSync(src, destBin);
40938
40319
  } finally {
40939
- import_node_fs23.default.rmSync(work, { recursive: true, force: true });
40320
+ import_node_fs22.default.rmSync(work, { recursive: true, force: true });
40940
40321
  }
40941
40322
  }
40942
40323
 
40943
40324
  // src/tunnel/frpc-process.ts
40944
- var import_node_fs24 = __toESM(require("fs"), 1);
40945
- var import_node_path24 = __toESM(require("path"), 1);
40325
+ var import_node_fs23 = __toESM(require("fs"), 1);
40326
+ var import_node_path23 = __toESM(require("path"), 1);
40946
40327
  var import_node_child_process8 = require("child_process");
40947
40328
  function frpcPidFilePath(dataDir) {
40948
- return import_node_path24.default.join(dataDir, "frpc.pid");
40329
+ return import_node_path23.default.join(dataDir, "frpc.pid");
40949
40330
  }
40950
40331
  function writeFrpcPid(dataDir, pid) {
40951
40332
  try {
40952
- import_node_fs24.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
40333
+ import_node_fs23.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
40953
40334
  } catch {
40954
40335
  }
40955
40336
  }
40956
40337
  function clearFrpcPid(dataDir) {
40957
40338
  try {
40958
- import_node_fs24.default.unlinkSync(frpcPidFilePath(dataDir));
40339
+ import_node_fs23.default.unlinkSync(frpcPidFilePath(dataDir));
40959
40340
  } catch {
40960
40341
  }
40961
40342
  }
@@ -40971,7 +40352,7 @@ function defaultIsPidAlive(pid) {
40971
40352
  }
40972
40353
  function defaultReadPidFile(file) {
40973
40354
  try {
40974
- return import_node_fs24.default.readFileSync(file, "utf8");
40355
+ return import_node_fs23.default.readFileSync(file, "utf8");
40975
40356
  } catch {
40976
40357
  return null;
40977
40358
  }
@@ -40987,12 +40368,12 @@ function defaultSleep(ms) {
40987
40368
  }
40988
40369
  async function killStaleFrpc(deps) {
40989
40370
  const pidFile = frpcPidFilePath(deps.dataDir);
40990
- const tomlPath = import_node_path24.default.join(deps.dataDir, "frpc.toml");
40371
+ const tomlPath = import_node_path23.default.join(deps.dataDir, "frpc.toml");
40991
40372
  const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
40992
40373
  const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
40993
40374
  const killPid = deps.killPidImpl ?? defaultKillPid;
40994
40375
  const scanPids = deps.scanFrpcPidsImpl ?? ((tp) => defaultScanFrpcPidsByCmdline(tp, deps.logger));
40995
- const sleep2 = deps.sleepImpl ?? defaultSleep;
40376
+ const sleep = deps.sleepImpl ?? defaultSleep;
40996
40377
  const victims = /* @__PURE__ */ new Set();
40997
40378
  const raw = readPidFile(pidFile);
40998
40379
  if (raw) {
@@ -41011,7 +40392,7 @@ async function killStaleFrpc(deps) {
41011
40392
  }
41012
40393
  if (victims.size === 0) {
41013
40394
  try {
41014
- import_node_fs24.default.unlinkSync(pidFile);
40395
+ import_node_fs23.default.unlinkSync(pidFile);
41015
40396
  } catch {
41016
40397
  }
41017
40398
  return;
@@ -41020,9 +40401,9 @@ async function killStaleFrpc(deps) {
41020
40401
  deps.logger?.warn("tunnel: killing stale frpc before respawn", { pid });
41021
40402
  killPid(pid, "SIGKILL");
41022
40403
  }
41023
- await sleep2(deps.reapWaitMs ?? 300);
40404
+ await sleep(deps.reapWaitMs ?? 300);
41024
40405
  try {
41025
- import_node_fs24.default.unlinkSync(pidFile);
40406
+ import_node_fs23.default.unlinkSync(pidFile);
41026
40407
  } catch {
41027
40408
  }
41028
40409
  }
@@ -41059,7 +40440,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
41059
40440
  var TunnelManager = class {
41060
40441
  constructor(deps) {
41061
40442
  this.deps = deps;
41062
- this.store = deps.store ?? new TunnelStore(import_node_path25.default.join(deps.dataDir, "tunnel.json"));
40443
+ this.store = deps.store ?? new TunnelStore(import_node_path24.default.join(deps.dataDir, "tunnel.json"));
41063
40444
  this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
41064
40445
  this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
41065
40446
  }
@@ -41186,7 +40567,7 @@ var TunnelManager = class {
41186
40567
  dataDir: this.deps.dataDir,
41187
40568
  override: this.deps.frpcBinaryOverride ?? void 0
41188
40569
  });
41189
- const tomlPath = import_node_path25.default.join(this.deps.dataDir, "frpc.toml");
40570
+ const tomlPath = import_node_path24.default.join(this.deps.dataDir, "frpc.toml");
41190
40571
  const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto7.default.randomBytes(3).toString("hex")}`;
41191
40572
  const toml = buildFrpcToml({
41192
40573
  serverAddr: t.frpsHost,
@@ -41197,12 +40578,12 @@ var TunnelManager = class {
41197
40578
  localPort,
41198
40579
  logLevel: "info"
41199
40580
  });
41200
- await import_node_fs25.default.promises.writeFile(tomlPath, toml, { mode: 384 });
40581
+ await import_node_fs24.default.promises.writeFile(tomlPath, toml, { mode: 384 });
41201
40582
  const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
41202
40583
  stdio: ["ignore", "pipe", "pipe"]
41203
40584
  });
41204
- const logFilePath = import_node_path25.default.join(this.deps.dataDir, "frpc.log");
41205
- const logStream = import_node_fs25.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
40585
+ const logFilePath = import_node_path24.default.join(this.deps.dataDir, "frpc.log");
40586
+ const logStream = import_node_fs24.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
41206
40587
  logStream.on("error", () => {
41207
40588
  });
41208
40589
  const tee = (chunk) => {
@@ -41285,27 +40666,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
41285
40666
 
41286
40667
  // src/tunnel/device-key.ts
41287
40668
  var import_node_os12 = __toESM(require("os"), 1);
41288
- var import_node_path26 = __toESM(require("path"), 1);
40669
+ var import_node_path25 = __toESM(require("path"), 1);
41289
40670
  var import_node_crypto8 = __toESM(require("crypto"), 1);
41290
40671
  var DERIVE_SALT = "clawd-tunnel-device-v1";
41291
40672
  function deriveStableDeviceKey(opts = {}) {
41292
40673
  const hostname = opts.hostname ?? import_node_os12.default.hostname();
41293
40674
  const uid = opts.uid ?? (typeof import_node_os12.default.userInfo === "function" ? import_node_os12.default.userInfo().uid : 0);
41294
40675
  const home = opts.home ?? import_node_os12.default.homedir();
41295
- const defaultDataDir = import_node_path26.default.resolve(import_node_path26.default.join(home, ".clawd"));
41296
- const normalizedDataDir = opts.dataDir ? import_node_path26.default.resolve(opts.dataDir) : null;
40676
+ const defaultDataDir = import_node_path25.default.resolve(import_node_path25.default.join(home, ".clawd"));
40677
+ const normalizedDataDir = opts.dataDir ? import_node_path25.default.resolve(opts.dataDir) : null;
41297
40678
  const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
41298
40679
  const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
41299
40680
  return import_node_crypto8.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
41300
40681
  }
41301
40682
 
41302
40683
  // src/auth-store.ts
41303
- var import_node_fs26 = __toESM(require("fs"), 1);
41304
- var import_node_path27 = __toESM(require("path"), 1);
40684
+ var import_node_fs25 = __toESM(require("fs"), 1);
40685
+ var import_node_path26 = __toESM(require("path"), 1);
41305
40686
  var import_node_crypto9 = __toESM(require("crypto"), 1);
41306
40687
  var AUTH_FILE_NAME = "auth.json";
41307
40688
  function authFilePath(dataDir) {
41308
- return import_node_path27.default.join(dataDir, AUTH_FILE_NAME);
40689
+ return import_node_path26.default.join(dataDir, AUTH_FILE_NAME);
41309
40690
  }
41310
40691
  function loadOrCreateAuthFile(opts) {
41311
40692
  const file = authFilePath(opts.dataDir);
@@ -41339,7 +40720,7 @@ function defaultGenerateOwnerPrincipalId() {
41339
40720
  }
41340
40721
  function readAuthFile(file) {
41341
40722
  try {
41342
- const raw = import_node_fs26.default.readFileSync(file, "utf8");
40723
+ const raw = import_node_fs25.default.readFileSync(file, "utf8");
41343
40724
  const parsed = JSON.parse(raw);
41344
40725
  if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
41345
40726
  return null;
@@ -41358,25 +40739,25 @@ function readAuthFile(file) {
41358
40739
  }
41359
40740
  }
41360
40741
  function writeAuthFile(file, content) {
41361
- import_node_fs26.default.mkdirSync(import_node_path27.default.dirname(file), { recursive: true });
41362
- import_node_fs26.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
40742
+ import_node_fs25.default.mkdirSync(import_node_path26.default.dirname(file), { recursive: true });
40743
+ import_node_fs25.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
41363
40744
  try {
41364
- import_node_fs26.default.chmodSync(file, 384);
40745
+ import_node_fs25.default.chmodSync(file, 384);
41365
40746
  } catch {
41366
40747
  }
41367
40748
  }
41368
40749
 
41369
40750
  // src/owner-profile.ts
41370
- var import_node_fs27 = __toESM(require("fs"), 1);
40751
+ var import_node_fs26 = __toESM(require("fs"), 1);
41371
40752
  var import_node_os13 = __toESM(require("os"), 1);
41372
- var import_node_path28 = __toESM(require("path"), 1);
40753
+ var import_node_path27 = __toESM(require("path"), 1);
41373
40754
  var PROFILE_FILENAME = "profile.json";
41374
40755
  function loadOwnerDisplayName(dataDir) {
41375
40756
  const fallback = import_node_os13.default.userInfo().username;
41376
- const profilePath = import_node_path28.default.join(dataDir, PROFILE_FILENAME);
40757
+ const profilePath = import_node_path27.default.join(dataDir, PROFILE_FILENAME);
41377
40758
  let raw;
41378
40759
  try {
41379
- raw = import_node_fs27.default.readFileSync(profilePath, "utf8");
40760
+ raw = import_node_fs26.default.readFileSync(profilePath, "utf8");
41380
40761
  } catch {
41381
40762
  return fallback;
41382
40763
  }
@@ -41399,18 +40780,18 @@ function loadOwnerDisplayName(dataDir) {
41399
40780
  }
41400
40781
 
41401
40782
  // src/feishu-auth/owner-identity-store.ts
41402
- var import_node_fs28 = __toESM(require("fs"), 1);
41403
- var import_node_path29 = __toESM(require("path"), 1);
40783
+ var import_node_fs27 = __toESM(require("fs"), 1);
40784
+ var import_node_path28 = __toESM(require("path"), 1);
41404
40785
  var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
41405
40786
  var OwnerIdentityStore = class {
41406
40787
  file;
41407
40788
  constructor(dataDir) {
41408
- this.file = import_node_path29.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
40789
+ this.file = import_node_path28.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
41409
40790
  }
41410
40791
  read() {
41411
40792
  let raw;
41412
40793
  try {
41413
- raw = import_node_fs28.default.readFileSync(this.file, "utf8");
40794
+ raw = import_node_fs27.default.readFileSync(this.file, "utf8");
41414
40795
  } catch {
41415
40796
  return null;
41416
40797
  }
@@ -41429,7 +40810,8 @@ var OwnerIdentityStore = class {
41429
40810
  ownerId: r.identity.ownerId,
41430
40811
  provider: r.identity.provider,
41431
40812
  displayName: r.identity.displayName,
41432
- ...typeof r.identity.avatarUrl === "string" ? { avatarUrl: r.identity.avatarUrl } : {}
40813
+ ...typeof r.identity.avatarUrl === "string" ? { avatarUrl: r.identity.avatarUrl } : {},
40814
+ ...typeof r.identity.unionId === "string" ? { unionId: r.identity.unionId } : {}
41433
40815
  },
41434
40816
  ttcToken: r.ttcToken,
41435
40817
  ttcTokenExpiresAt: typeof r.ttcTokenExpiresAt === "number" ? r.ttcTokenExpiresAt : null,
@@ -41437,16 +40819,16 @@ var OwnerIdentityStore = class {
41437
40819
  };
41438
40820
  }
41439
40821
  write(record) {
41440
- import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(this.file), { recursive: true });
41441
- import_node_fs28.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
40822
+ import_node_fs27.default.mkdirSync(import_node_path28.default.dirname(this.file), { recursive: true });
40823
+ import_node_fs27.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
41442
40824
  try {
41443
- import_node_fs28.default.chmodSync(this.file, 384);
40825
+ import_node_fs27.default.chmodSync(this.file, 384);
41444
40826
  } catch {
41445
40827
  }
41446
40828
  }
41447
40829
  clear() {
41448
40830
  try {
41449
- import_node_fs28.default.unlinkSync(this.file);
40831
+ import_node_fs27.default.unlinkSync(this.file);
41450
40832
  } catch (err) {
41451
40833
  const code = err?.code;
41452
40834
  if (code !== "ENOENT") throw err;
@@ -41550,7 +40932,9 @@ async function fetchTtcUserInfo(opts) {
41550
40932
  ownerId: d.unique_id,
41551
40933
  provider: "ttc",
41552
40934
  displayName: d.name,
41553
- ...typeof d.avatar_url === "string" && d.avatar_url.length > 0 ? { avatarUrl: d.avatar_url } : {}
40935
+ ...typeof d.avatar_url === "string" && d.avatar_url.length > 0 ? { avatarUrl: d.avatar_url } : {},
40936
+ // union_id 捕获:dataclaw 可信入口用 X-User-UnionId(ownerId 仍是 unique_id,跨登录方式稳定)
40937
+ ...typeof d.union_id === "string" && d.union_id.length > 0 ? { unionId: d.union_id } : {}
41554
40938
  };
41555
40939
  }
41556
40940
 
@@ -41565,9 +40949,9 @@ var CentralClientError = class extends Error {
41565
40949
  code;
41566
40950
  cause;
41567
40951
  };
41568
- async function centralRequest(opts, path59, init) {
40952
+ async function centralRequest(opts, path58, init) {
41569
40953
  const f = opts.fetchImpl ?? globalThis.fetch;
41570
- const url = `${opts.api.replace(/\/+$/, "")}${path59}`;
40954
+ const url = `${opts.api.replace(/\/+$/, "")}${path58}`;
41571
40955
  const ctrl = new AbortController();
41572
40956
  const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
41573
40957
  let res;
@@ -41709,8 +41093,8 @@ function verifyConnectToken(args) {
41709
41093
  }
41710
41094
 
41711
41095
  // src/feishu-auth/server-key.ts
41712
- var fs37 = __toESM(require("fs"), 1);
41713
- var path38 = __toESM(require("path"), 1);
41096
+ var fs36 = __toESM(require("fs"), 1);
41097
+ var path37 = __toESM(require("path"), 1);
41714
41098
  var FILE_NAME2 = "server-signing-key.json";
41715
41099
  var ServerKeyStore = class {
41716
41100
  constructor(dataDir) {
@@ -41718,12 +41102,12 @@ var ServerKeyStore = class {
41718
41102
  }
41719
41103
  dataDir;
41720
41104
  filePath() {
41721
- return path38.join(this.dataDir, FILE_NAME2);
41105
+ return path37.join(this.dataDir, FILE_NAME2);
41722
41106
  }
41723
41107
  /** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
41724
41108
  read() {
41725
41109
  try {
41726
- const raw = fs37.readFileSync(this.filePath(), "utf8");
41110
+ const raw = fs36.readFileSync(this.filePath(), "utf8");
41727
41111
  const parsed = JSON.parse(raw);
41728
41112
  if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
41729
41113
  return parsed.publicKeyPem;
@@ -41738,12 +41122,12 @@ var ServerKeyStore = class {
41738
41122
  publicKeyPem,
41739
41123
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
41740
41124
  };
41741
- fs37.mkdirSync(this.dataDir, { recursive: true });
41742
- fs37.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
41125
+ fs36.mkdirSync(this.dataDir, { recursive: true });
41126
+ fs36.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
41743
41127
  }
41744
41128
  clear() {
41745
41129
  try {
41746
- fs37.unlinkSync(this.filePath());
41130
+ fs36.unlinkSync(this.filePath());
41747
41131
  } catch {
41748
41132
  }
41749
41133
  }
@@ -41756,12 +41140,12 @@ init_protocol();
41756
41140
  init_protocol();
41757
41141
 
41758
41142
  // src/session/fork.ts
41759
- var import_node_fs29 = __toESM(require("fs"), 1);
41143
+ var import_node_fs28 = __toESM(require("fs"), 1);
41760
41144
  var import_node_os14 = __toESM(require("os"), 1);
41761
- var import_node_path30 = __toESM(require("path"), 1);
41145
+ var import_node_path29 = __toESM(require("path"), 1);
41762
41146
  init_claude_history();
41763
41147
  function readJsonlEntries(file) {
41764
- const raw = import_node_fs29.default.readFileSync(file, "utf8");
41148
+ const raw = import_node_fs28.default.readFileSync(file, "utf8");
41765
41149
  const out = [];
41766
41150
  for (const line of raw.split("\n")) {
41767
41151
  const t = line.trim();
@@ -41774,10 +41158,10 @@ function readJsonlEntries(file) {
41774
41158
  return out;
41775
41159
  }
41776
41160
  function forkSession(input) {
41777
- const baseDir = input.baseDir ?? import_node_path30.default.join(import_node_os14.default.homedir(), ".claude");
41778
- const projectDir = import_node_path30.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41779
- const sourceFile = import_node_path30.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41780
- if (!import_node_fs29.default.existsSync(sourceFile)) {
41161
+ const baseDir = input.baseDir ?? import_node_path29.default.join(import_node_os14.default.homedir(), ".claude");
41162
+ const projectDir = import_node_path29.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
41163
+ const sourceFile = import_node_path29.default.join(projectDir, `${input.toolSessionId}.jsonl`);
41164
+ if (!import_node_fs28.default.existsSync(sourceFile)) {
41781
41165
  throw new Error(`fork: source transcript not found: ${sourceFile}`);
41782
41166
  }
41783
41167
  const entries = readJsonlEntries(sourceFile);
@@ -41807,9 +41191,9 @@ function forkSession(input) {
41807
41191
  }
41808
41192
  forkedLines.push(JSON.stringify(forked));
41809
41193
  }
41810
- const forkedFilePath = import_node_path30.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
41811
- import_node_fs29.default.mkdirSync(projectDir, { recursive: true });
41812
- import_node_fs29.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
41194
+ const forkedFilePath = import_node_path29.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
41195
+ import_node_fs28.default.mkdirSync(projectDir, { recursive: true });
41196
+ import_node_fs28.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
41813
41197
  return { forkedToolSessionId, forkedFilePath };
41814
41198
  }
41815
41199
 
@@ -42185,7 +41569,7 @@ function buildPermissionHandlers(deps) {
42185
41569
  }
42186
41570
 
42187
41571
  // src/handlers/history.ts
42188
- var path41 = __toESM(require("path"), 1);
41572
+ var path40 = __toESM(require("path"), 1);
42189
41573
  init_protocol();
42190
41574
 
42191
41575
  // src/session/recent-dirs.ts
@@ -42203,7 +41587,7 @@ function listRecentDirs(store, limit = 50) {
42203
41587
  }
42204
41588
 
42205
41589
  // src/permission/persona-paths.ts
42206
- var path40 = __toESM(require("path"), 1);
41590
+ var path39 = __toESM(require("path"), 1);
42207
41591
  function getAllowedPersonaIds(grants, action) {
42208
41592
  const ids = /* @__PURE__ */ new Set();
42209
41593
  for (const g2 of grants) {
@@ -42216,31 +41600,31 @@ function getAllowedPersonaIds(grants, action) {
42216
41600
  return ids;
42217
41601
  }
42218
41602
  function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
42219
- const target = path40.resolve(absPath);
41603
+ const target = path39.resolve(absPath);
42220
41604
  if (userWorkDir) {
42221
- const u = path40.resolve(userWorkDir);
42222
- const usep = u.endsWith(path40.sep) ? "" : path40.sep;
41605
+ const u = path39.resolve(userWorkDir);
41606
+ const usep = u.endsWith(path39.sep) ? "" : path39.sep;
42223
41607
  if (target === u || target.startsWith(u + usep)) return true;
42224
41608
  }
42225
- const root = path40.resolve(personaRoot);
42226
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
41609
+ const root = path39.resolve(personaRoot);
41610
+ const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
42227
41611
  if (!target.startsWith(root + sep2)) return false;
42228
- const rel = path40.relative(root, target);
41612
+ const rel = path39.relative(root, target);
42229
41613
  if (!rel || rel.startsWith("..")) return false;
42230
- const personaId = rel.split(path40.sep)[0];
41614
+ const personaId = rel.split(path39.sep)[0];
42231
41615
  if (!personaId) return false;
42232
41616
  const allowed = getAllowedPersonaIds(grants, action);
42233
41617
  if (allowed === "*") return true;
42234
41618
  return allowed.has(personaId);
42235
41619
  }
42236
41620
  function personaIdFromPath(absPath, personaRoot) {
42237
- const root = path40.resolve(personaRoot);
42238
- const target = path40.resolve(absPath);
42239
- const sep2 = root.endsWith(path40.sep) ? "" : path40.sep;
41621
+ const root = path39.resolve(personaRoot);
41622
+ const target = path39.resolve(absPath);
41623
+ const sep2 = root.endsWith(path39.sep) ? "" : path39.sep;
42240
41624
  if (!target.startsWith(root + sep2)) return null;
42241
- const rel = path40.relative(root, target);
41625
+ const rel = path39.relative(root, target);
42242
41626
  if (!rel || rel.startsWith("..")) return null;
42243
- const id = rel.split(path40.sep)[0];
41627
+ const id = rel.split(path39.sep)[0];
42244
41628
  return id || null;
42245
41629
  }
42246
41630
 
@@ -42267,7 +41651,7 @@ function buildHistoryHandlers(deps) {
42267
41651
  if (!pid) return false;
42268
41652
  return isGuestPathAllowed(
42269
41653
  ctx.grants,
42270
- path41.join(personaRoot, pid),
41654
+ path40.join(personaRoot, pid),
42271
41655
  personaRoot,
42272
41656
  "read",
42273
41657
  userWorkDir
@@ -42279,7 +41663,7 @@ function buildHistoryHandlers(deps) {
42279
41663
  };
42280
41664
  const list = async (frame, _client, ctx) => {
42281
41665
  const args = HistoryListArgs.parse(frame);
42282
- assertGuestPath(ctx, path41.resolve(args.projectPath), personaRoot, "history:list");
41666
+ assertGuestPath(ctx, path40.resolve(args.projectPath), personaRoot, "history:list");
42283
41667
  const sessions = await history.listSessions(args);
42284
41668
  return { response: { type: "history:list", sessions } };
42285
41669
  };
@@ -42311,13 +41695,13 @@ function buildHistoryHandlers(deps) {
42311
41695
  };
42312
41696
  const subagents = async (frame, _client, ctx) => {
42313
41697
  const args = HistorySubagentsArgs.parse(frame);
42314
- assertGuestPath(ctx, path41.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
41698
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
42315
41699
  const subs = await history.listSubagents(args);
42316
41700
  return { response: { type: "history:subagents", subagents: subs } };
42317
41701
  };
42318
41702
  const subagentRead = async (frame, _client, ctx) => {
42319
41703
  const args = HistorySubagentReadArgs.parse(frame);
42320
- assertGuestPath(ctx, path41.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
41704
+ assertGuestPath(ctx, path40.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
42321
41705
  const res = await history.readSubagent(args);
42322
41706
  return { response: { type: "history:subagent-read", ...res } };
42323
41707
  };
@@ -42326,7 +41710,7 @@ function buildHistoryHandlers(deps) {
42326
41710
  if (ctx?.principal.kind === "guest" && personaRoot) {
42327
41711
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
42328
41712
  const filtered = dirs.filter(
42329
- (d) => isGuestPathAllowed(ctx.grants, path41.resolve(d.cwd), personaRoot, "read", userWorkDir)
41713
+ (d) => isGuestPathAllowed(ctx.grants, path40.resolve(d.cwd), personaRoot, "read", userWorkDir)
42330
41714
  );
42331
41715
  return { response: { type: "history:recentDirs", dirs: filtered } };
42332
41716
  }
@@ -42343,7 +41727,7 @@ function buildHistoryHandlers(deps) {
42343
41727
  }
42344
41728
 
42345
41729
  // src/handlers/workspace.ts
42346
- var path42 = __toESM(require("path"), 1);
41730
+ var path41 = __toESM(require("path"), 1);
42347
41731
  var os15 = __toESM(require("os"), 1);
42348
41732
  init_protocol();
42349
41733
  init_protocol();
@@ -42385,22 +41769,22 @@ function buildWorkspaceHandlers(deps) {
42385
41769
  const args = WorkspaceListArgs.parse(frame);
42386
41770
  const isGuest = ctx?.principal.kind === "guest";
42387
41771
  const fallbackCwd = isGuest && personaRoot ? personaRoot : os15.homedir();
42388
- const resolvedCwd = path42.resolve(args.cwd ?? fallbackCwd);
42389
- const target = args.path ? path42.resolve(resolvedCwd, args.path) : resolvedCwd;
41772
+ const resolvedCwd = path41.resolve(args.cwd ?? fallbackCwd);
41773
+ const target = args.path ? path41.resolve(resolvedCwd, args.path) : resolvedCwd;
42390
41774
  assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
42391
41775
  const res = workspace.list({ ...args, cwd: resolvedCwd });
42392
41776
  return { response: { type: "workspace:list", ...res } };
42393
41777
  };
42394
41778
  const read = async (frame, _client, ctx) => {
42395
41779
  const args = WorkspaceReadArgs.parse(frame);
42396
- const target = path42.isAbsolute(args.path) ? path42.resolve(args.path) : path42.resolve(args.cwd, args.path);
41780
+ const target = path41.isAbsolute(args.path) ? path41.resolve(args.path) : path41.resolve(args.cwd, args.path);
42397
41781
  assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
42398
41782
  const res = workspace.read(args);
42399
41783
  return { response: { type: "workspace:read", ...res } };
42400
41784
  };
42401
41785
  const skillsList = async (frame, _client, ctx) => {
42402
41786
  const args = SkillsListArgs.parse(frame);
42403
- const cwdAbs = path42.resolve(args.cwd);
41787
+ const cwdAbs = path41.resolve(args.cwd);
42404
41788
  assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
42405
41789
  const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
42406
41790
  if (ctx?.principal.kind === "guest" && personaRoot) {
@@ -42412,7 +41796,7 @@ function buildWorkspaceHandlers(deps) {
42412
41796
  };
42413
41797
  const agentsList = async (frame, _client, ctx) => {
42414
41798
  const args = AgentsListArgs.parse(frame);
42415
- const cwdAbs = path42.resolve(args.cwd);
41799
+ const cwdAbs = path41.resolve(args.cwd);
42416
41800
  assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
42417
41801
  if (args.tool === "codex") {
42418
41802
  return { response: { type: "agents:list", agents: [] } };
@@ -42434,20 +41818,20 @@ function buildWorkspaceHandlers(deps) {
42434
41818
  }
42435
41819
 
42436
41820
  // src/handlers/git.ts
42437
- var path44 = __toESM(require("path"), 1);
41821
+ var path43 = __toESM(require("path"), 1);
42438
41822
  init_protocol();
42439
41823
  init_protocol();
42440
41824
 
42441
41825
  // src/workspace/git.ts
42442
41826
  var import_node_child_process10 = require("child_process");
42443
- var import_node_fs30 = __toESM(require("fs"), 1);
42444
- var import_node_path31 = __toESM(require("path"), 1);
41827
+ var import_node_fs29 = __toESM(require("fs"), 1);
41828
+ var import_node_path30 = __toESM(require("path"), 1);
42445
41829
  var import_node_util = require("util");
42446
41830
  var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
42447
41831
  function normalizePath(p2) {
42448
- const resolved = import_node_path31.default.resolve(p2);
41832
+ const resolved = import_node_path30.default.resolve(p2);
42449
41833
  try {
42450
- return import_node_fs30.default.realpathSync(resolved);
41834
+ return import_node_fs29.default.realpathSync(resolved);
42451
41835
  } catch {
42452
41836
  return resolved;
42453
41837
  }
@@ -42521,7 +41905,7 @@ async function listGitBranches(cwd) {
42521
41905
  function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
42522
41906
  if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
42523
41907
  const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
42524
- if (!isGuestPathAllowed(ctx.grants, path44.resolve(cwd), personaRoot, "read", userWorkDir)) {
41908
+ if (!isGuestPathAllowed(ctx.grants, path43.resolve(cwd), personaRoot, "read", userWorkDir)) {
42525
41909
  throw new ClawdError(
42526
41910
  ERROR_CODES.UNAUTHORIZED,
42527
41911
  `guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
@@ -42937,7 +42321,6 @@ function buildReadyFrame(deps, client) {
42937
42321
  if (deps.httpToken) fileSharing.httpToken = deps.httpToken;
42938
42322
  }
42939
42323
  const daemonSource = process.env.CLAWD_DAEMON_SOURCE === "ota" ? "ota" : "packaged";
42940
- const logShipping = deps.getLogShipping ? deps.getLogShipping() : null;
42941
42324
  return {
42942
42325
  version,
42943
42326
  protocolVersion: PROTOCOL_VERSION,
@@ -42948,8 +42331,7 @@ function buildReadyFrame(deps, client) {
42948
42331
  tunnelUrl,
42949
42332
  mode: deps.mode,
42950
42333
  daemonSource,
42951
- ...fileSharing,
42952
- ...logShipping ? { logShipping } : {}
42334
+ ...fileSharing
42953
42335
  };
42954
42336
  }
42955
42337
  function buildMetaHandlers(deps) {
@@ -43037,7 +42419,7 @@ function buildPersonaHandlers(deps) {
43037
42419
  }
43038
42420
 
43039
42421
  // src/handlers/attachment.ts
43040
- var import_node_path32 = __toESM(require("path"), 1);
42422
+ var import_node_path31 = __toESM(require("path"), 1);
43041
42423
  init_protocol();
43042
42424
  init_protocol();
43043
42425
  var DEFAULT_TTL_SECONDS = 24 * 3600;
@@ -43092,12 +42474,12 @@ function buildAttachmentHandlers(deps) {
43092
42474
  `session ${args.sessionId} scope unresolved`
43093
42475
  );
43094
42476
  }
43095
- const cwdAbs = import_node_path32.default.resolve(sessionFile.cwd);
43096
- const candidateAbs = import_node_path32.default.isAbsolute(args.relPath) ? import_node_path32.default.resolve(args.relPath) : import_node_path32.default.resolve(cwdAbs, args.relPath);
42477
+ const cwdAbs = import_node_path31.default.resolve(sessionFile.cwd);
42478
+ const candidateAbs = import_node_path31.default.isAbsolute(args.relPath) ? import_node_path31.default.resolve(args.relPath) : import_node_path31.default.resolve(cwdAbs, args.relPath);
43097
42479
  assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
43098
42480
  const entries = deps.groupFileStore.list(scope, args.sessionId);
43099
42481
  const entry = entries.find((e) => {
43100
- const storedAbs = import_node_path32.default.isAbsolute(e.relPath) ? import_node_path32.default.resolve(e.relPath) : import_node_path32.default.resolve(cwdAbs, e.relPath);
42482
+ const storedAbs = import_node_path31.default.isAbsolute(e.relPath) ? import_node_path31.default.resolve(e.relPath) : import_node_path31.default.resolve(cwdAbs, e.relPath);
43101
42483
  return storedAbs === candidateAbs && !e.stale;
43102
42484
  });
43103
42485
  if (!entry) {
@@ -43121,7 +42503,7 @@ function buildAttachmentHandlers(deps) {
43121
42503
  if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
43122
42504
  const f = deps.sessionStore.read(sessionId);
43123
42505
  if (!f) return;
43124
- assertGuestAttachmentPath(ctx, import_node_path32.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
42506
+ assertGuestAttachmentPath(ctx, import_node_path31.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
43125
42507
  }
43126
42508
  const groupAdd = async (frame, _client, ctx) => {
43127
42509
  if (!deps.groupFileStore || !deps.getSessionScope) {
@@ -43193,19 +42575,19 @@ function buildAttachmentHandlers(deps) {
43193
42575
 
43194
42576
  // src/handlers/extension.ts
43195
42577
  var import_promises7 = __toESM(require("fs/promises"), 1);
43196
- var import_node_path37 = __toESM(require("path"), 1);
42578
+ var import_node_path36 = __toESM(require("path"), 1);
43197
42579
  init_protocol();
43198
42580
 
43199
42581
  // src/extension/bundle-zip.ts
43200
42582
  var import_promises4 = __toESM(require("fs/promises"), 1);
43201
- var import_node_path33 = __toESM(require("path"), 1);
42583
+ var import_node_path32 = __toESM(require("path"), 1);
43202
42584
  var import_node_crypto11 = __toESM(require("crypto"), 1);
43203
42585
  var import_jszip2 = __toESM(require_lib3(), 1);
43204
42586
  async function bundleExtensionDir(dir) {
43205
42587
  const entries = await listFilesSorted(dir);
43206
42588
  const zip = new import_jszip2.default();
43207
42589
  for (const rel of entries) {
43208
- const abs = import_node_path33.default.join(dir, rel);
42590
+ const abs = import_node_path32.default.join(dir, rel);
43209
42591
  const content = await import_promises4.default.readFile(abs);
43210
42592
  zip.file(rel, content, { date: FIXED_DATE });
43211
42593
  }
@@ -43226,7 +42608,7 @@ async function listFilesSorted(rootDir) {
43226
42608
  return out;
43227
42609
  }
43228
42610
  async function walk(absRoot, relPrefix, out) {
43229
- const dirAbs = import_node_path33.default.join(absRoot, relPrefix);
42611
+ const dirAbs = import_node_path32.default.join(absRoot, relPrefix);
43230
42612
  const entries = await import_promises4.default.readdir(dirAbs, { withFileTypes: true });
43231
42613
  for (const e of entries) {
43232
42614
  if (IGNORE_BASENAMES.has(e.name)) continue;
@@ -43280,25 +42662,25 @@ function computePublishCheck(args) {
43280
42662
 
43281
42663
  // src/extension/install-flow.ts
43282
42664
  var import_promises5 = __toESM(require("fs/promises"), 1);
43283
- var import_node_path35 = __toESM(require("path"), 1);
42665
+ var import_node_path34 = __toESM(require("path"), 1);
43284
42666
  var import_node_os17 = __toESM(require("os"), 1);
43285
42667
  var import_node_crypto12 = __toESM(require("crypto"), 1);
43286
42668
  var import_jszip3 = __toESM(require_lib3(), 1);
43287
42669
 
43288
42670
  // src/extension/paths.ts
43289
42671
  var import_node_os16 = __toESM(require("os"), 1);
43290
- var import_node_path34 = __toESM(require("path"), 1);
42672
+ var import_node_path33 = __toESM(require("path"), 1);
43291
42673
  function clawdHomeRoot(override) {
43292
- return override ?? process.env.CLAWD_HOME ?? import_node_path34.default.join(import_node_os16.default.homedir(), ".clawd");
42674
+ return override ?? process.env.CLAWD_HOME ?? import_node_path33.default.join(import_node_os16.default.homedir(), ".clawd");
43293
42675
  }
43294
42676
  function extensionsRoot(override) {
43295
- return import_node_path34.default.join(clawdHomeRoot(override), "extensions");
42677
+ return import_node_path33.default.join(clawdHomeRoot(override), "extensions");
43296
42678
  }
43297
42679
  function publishedChannelsFile(override) {
43298
- return import_node_path34.default.join(clawdHomeRoot(override), "extensions-published.json");
42680
+ return import_node_path33.default.join(clawdHomeRoot(override), "extensions-published.json");
43299
42681
  }
43300
42682
  function bundleCacheRoot(override) {
43301
- return import_node_path34.default.join(clawdHomeRoot(override), "extension-bundles");
42683
+ return import_node_path33.default.join(clawdHomeRoot(override), "extension-bundles");
43302
42684
  }
43303
42685
 
43304
42686
  // src/extension/install-flow.ts
@@ -43325,7 +42707,7 @@ async function installFromChannel(args, deps) {
43325
42707
  throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
43326
42708
  }
43327
42709
  for (const name of Object.keys(zip.files)) {
43328
- if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
42710
+ if (name.includes("..") || name.startsWith("/") || import_node_path34.default.isAbsolute(name)) {
43329
42711
  throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
43330
42712
  }
43331
42713
  }
@@ -43357,7 +42739,7 @@ async function installFromChannel(args, deps) {
43357
42739
  );
43358
42740
  }
43359
42741
  const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
43360
- const destDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
42742
+ const destDir = import_node_path34.default.join(deps.extensionsRoot, localExtId);
43361
42743
  let destExists = false;
43362
42744
  try {
43363
42745
  await import_promises5.default.access(destDir);
@@ -43371,16 +42753,16 @@ async function installFromChannel(args, deps) {
43371
42753
  );
43372
42754
  }
43373
42755
  const stage = await import_promises5.default.mkdtemp(
43374
- import_node_path35.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
42756
+ import_node_path34.default.join(import_node_os17.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
43375
42757
  );
43376
42758
  try {
43377
42759
  for (const [name, entry] of Object.entries(zip.files)) {
43378
- const dest = import_node_path35.default.join(stage, name);
42760
+ const dest = import_node_path34.default.join(stage, name);
43379
42761
  if (entry.dir) {
43380
42762
  await import_promises5.default.mkdir(dest, { recursive: true });
43381
42763
  continue;
43382
42764
  }
43383
- await import_promises5.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
42765
+ await import_promises5.default.mkdir(import_node_path34.default.dirname(dest), { recursive: true });
43384
42766
  if (name === "manifest.json") {
43385
42767
  const rewritten = { ...parsed.data, id: localExtId };
43386
42768
  await import_promises5.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -43401,7 +42783,7 @@ async function installFromChannel(args, deps) {
43401
42783
 
43402
42784
  // src/extension/update-flow.ts
43403
42785
  var import_promises6 = __toESM(require("fs/promises"), 1);
43404
- var import_node_path36 = __toESM(require("path"), 1);
42786
+ var import_node_path35 = __toESM(require("path"), 1);
43405
42787
  var import_node_os18 = __toESM(require("os"), 1);
43406
42788
  var import_node_crypto13 = __toESM(require("crypto"), 1);
43407
42789
  var import_jszip4 = __toESM(require_lib3(), 1);
@@ -43418,11 +42800,11 @@ async function updateFromChannel(args, deps) {
43418
42800
  channelRef.extId,
43419
42801
  channelRef.ownerPrincipalId
43420
42802
  );
43421
- const liveDir = import_node_path36.default.join(deps.extensionsRoot, localExtId);
42803
+ const liveDir = import_node_path35.default.join(deps.extensionsRoot, localExtId);
43422
42804
  const prevDir = `${liveDir}.prev`;
43423
42805
  let existingVersion;
43424
42806
  try {
43425
- const raw = await import_promises6.default.readFile(import_node_path36.default.join(liveDir, "manifest.json"), "utf8");
42807
+ const raw = await import_promises6.default.readFile(import_node_path35.default.join(liveDir, "manifest.json"), "utf8");
43426
42808
  const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
43427
42809
  if (!parsed2.success) {
43428
42810
  throw new UpdateError(
@@ -43455,7 +42837,7 @@ async function updateFromChannel(args, deps) {
43455
42837
  throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
43456
42838
  }
43457
42839
  for (const name of Object.keys(zip.files)) {
43458
- if (name.includes("..") || name.startsWith("/") || import_node_path36.default.isAbsolute(name)) {
42840
+ if (name.includes("..") || name.startsWith("/") || import_node_path35.default.isAbsolute(name)) {
43459
42841
  throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
43460
42842
  }
43461
42843
  }
@@ -43490,16 +42872,16 @@ async function updateFromChannel(args, deps) {
43490
42872
  await import_promises6.default.rm(prevDir, { recursive: true, force: true });
43491
42873
  await import_promises6.default.rename(liveDir, prevDir);
43492
42874
  const stage = await import_promises6.default.mkdtemp(
43493
- import_node_path36.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
42875
+ import_node_path35.default.join(import_node_os18.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
43494
42876
  );
43495
42877
  try {
43496
42878
  for (const [name, entry] of Object.entries(zip.files)) {
43497
- const dest = import_node_path36.default.join(stage, name);
42879
+ const dest = import_node_path35.default.join(stage, name);
43498
42880
  if (entry.dir) {
43499
42881
  await import_promises6.default.mkdir(dest, { recursive: true });
43500
42882
  continue;
43501
42883
  }
43502
- await import_promises6.default.mkdir(import_node_path36.default.dirname(dest), { recursive: true });
42884
+ await import_promises6.default.mkdir(import_node_path35.default.dirname(dest), { recursive: true });
43503
42885
  if (name === "manifest.json") {
43504
42886
  const rewritten = { ...parsed.data, id: localExtId };
43505
42887
  await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
@@ -43592,7 +42974,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
43592
42974
  );
43593
42975
  }
43594
42976
  }
43595
- const manifestPath = import_node_path37.default.join(root, extId, "manifest.json");
42977
+ const manifestPath = import_node_path36.default.join(root, extId, "manifest.json");
43596
42978
  const manifest = await readManifest(root, extId);
43597
42979
  const next = { ...manifest, version: newVersion };
43598
42980
  const tmp = `${manifestPath}.tmp`;
@@ -43600,7 +42982,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
43600
42982
  await import_promises7.default.rename(tmp, manifestPath);
43601
42983
  }
43602
42984
  async function readManifest(root, extId) {
43603
- const file = import_node_path37.default.join(root, extId, "manifest.json");
42985
+ const file = import_node_path36.default.join(root, extId, "manifest.json");
43604
42986
  let raw;
43605
42987
  try {
43606
42988
  raw = await import_promises7.default.readFile(file, "utf8");
@@ -43691,7 +43073,7 @@ function buildExtensionHandlers(deps) {
43691
43073
  };
43692
43074
  async function buildSnapshotMeta(extId) {
43693
43075
  const manifest = await readManifest(deps.root, extId);
43694
- const { sha256, buffer } = await bundleExtensionDir(import_node_path37.default.join(deps.root, extId));
43076
+ const { sha256, buffer } = await bundleExtensionDir(import_node_path36.default.join(deps.root, extId));
43695
43077
  return { manifest, contentHash: sha256, buffer };
43696
43078
  }
43697
43079
  const publish = async (frame, _client, ctx) => {
@@ -43987,8 +43369,8 @@ var PublishJobRegistry = class {
43987
43369
 
43988
43370
  // src/app-builder/publish-job-runner.ts
43989
43371
  var import_node_child_process12 = require("child_process");
43990
- var import_node_fs31 = require("fs");
43991
- var import_node_path38 = require("path");
43372
+ var import_node_fs30 = require("fs");
43373
+ var import_node_path37 = require("path");
43992
43374
 
43993
43375
  // src/app-builder/publish-stage-parser.ts
43994
43376
  var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
@@ -44020,10 +43402,10 @@ async function startPublishJob(deps, args) {
44020
43402
  return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
44021
43403
  }
44022
43404
  const projDir = projectDir(args.name);
44023
- const logPath = (0, import_node_path38.join)(projDir, ".publish.log");
43405
+ const logPath = (0, import_node_path37.join)(projDir, ".publish.log");
44024
43406
  let logStream = null;
44025
43407
  try {
44026
- logStream = (0, import_node_fs31.createWriteStream)(logPath, { flags: "w" });
43408
+ logStream = (0, import_node_fs30.createWriteStream)(logPath, { flags: "w" });
44027
43409
  } catch {
44028
43410
  logStream = null;
44029
43411
  }
@@ -44280,9 +43662,9 @@ async function recoverInterruptedJobs(deps) {
44280
43662
 
44281
43663
  // src/handlers/app-builder.ts
44282
43664
  init_protocol();
44283
- var import_node_path39 = require("path");
44284
- var import_node_fs32 = require("fs");
44285
- var APP_BUILDER_PERSONAS = ["persona-app-builder"];
43665
+ var import_node_path38 = require("path");
43666
+ var import_node_fs31 = require("fs");
43667
+ var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
44286
43668
  var PUBLISH_SCRIPT_REL = "extension-kit/scripts/publish.sh";
44287
43669
  var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
44288
43670
  async function recoverInterruptedPublishJobs(store, logger) {
@@ -44363,7 +43745,7 @@ function buildAppBuilderHandlers(deps) {
44363
43745
  async function listAllUsersProjects() {
44364
43746
  if (!deps.usersRoot || !deps.getStore) return [];
44365
43747
  const getStore = deps.getStore;
44366
- const userIds = await import_node_fs32.promises.readdir(deps.usersRoot).catch(() => []);
43748
+ const userIds = await import_node_fs31.promises.readdir(deps.usersRoot).catch(() => []);
44367
43749
  const perUser = await Promise.all(
44368
43750
  userIds.map((uid) => getStore(uid).list().catch(() => []))
44369
43751
  );
@@ -44438,7 +43820,8 @@ function buildAppBuilderHandlers(deps) {
44438
43820
  const reservedPorts = new Set((await listAllUsersProjects()).map((p2) => p2.port));
44439
43821
  const project = await userStore.create(f.name, reservedPorts);
44440
43822
  try {
44441
- const scaffoldResult = await userStore.scaffold(project.name, void 0, deps.personaRoot);
43823
+ const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
43824
+ const scaffoldResult = await userStore.scaffold(project.name, void 0, personaRoot);
44442
43825
  deps.logger?.info("app-builder.scaffold.done", {
44443
43826
  name: project.name,
44444
43827
  stdout: scaffoldResult.stdout.slice(0, 200)
@@ -44657,7 +44040,7 @@ function buildAppBuilderHandlers(deps) {
44657
44040
  });
44658
44041
  await userStore.clearPublishJob(args.name);
44659
44042
  }
44660
- const scriptPath = (0, import_node_path39.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
44043
+ const scriptPath = (0, import_node_path38.join)(deps.personaRoot, PUBLISH_SCRIPT_REL);
44661
44044
  deps.logger?.info("app-builder.publish.start", {
44662
44045
  name: args.name,
44663
44046
  sessionId: boundSession.sessionId,
@@ -44751,7 +44134,7 @@ function buildAppBuilderHandlers(deps) {
44751
44134
 
44752
44135
  // src/extension/registry.ts
44753
44136
  var import_promises8 = __toESM(require("fs/promises"), 1);
44754
- var import_node_path40 = __toESM(require("path"), 1);
44137
+ var import_node_path39 = __toESM(require("path"), 1);
44755
44138
  async function loadAll(root) {
44756
44139
  let entries;
44757
44140
  try {
@@ -44764,13 +44147,13 @@ async function loadAll(root) {
44764
44147
  for (const ent of entries) {
44765
44148
  if (!ent.isDirectory()) continue;
44766
44149
  if (ent.name.startsWith(".")) continue;
44767
- records.push(await loadOne(import_node_path40.default.join(root, ent.name), ent.name));
44150
+ records.push(await loadOne(import_node_path39.default.join(root, ent.name), ent.name));
44768
44151
  }
44769
44152
  records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
44770
44153
  return records;
44771
44154
  }
44772
44155
  async function loadOne(dir, dirName) {
44773
- const manifestPath = import_node_path40.default.join(dir, "manifest.json");
44156
+ const manifestPath = import_node_path39.default.join(dir, "manifest.json");
44774
44157
  let raw;
44775
44158
  try {
44776
44159
  raw = await import_promises8.default.readFile(manifestPath, "utf8");
@@ -44815,7 +44198,7 @@ async function loadOne(dir, dirName) {
44815
44198
 
44816
44199
  // src/extension/uninstall.ts
44817
44200
  var import_promises9 = __toESM(require("fs/promises"), 1);
44818
- var import_node_path41 = __toESM(require("path"), 1);
44201
+ var import_node_path40 = __toESM(require("path"), 1);
44819
44202
  var UninstallError = class extends Error {
44820
44203
  constructor(code, message) {
44821
44204
  super(message);
@@ -44824,7 +44207,7 @@ var UninstallError = class extends Error {
44824
44207
  code;
44825
44208
  };
44826
44209
  async function uninstall(deps) {
44827
- const dir = import_node_path41.default.join(deps.root, deps.extId);
44210
+ const dir = import_node_path40.default.join(deps.root, deps.extId);
44828
44211
  try {
44829
44212
  await import_promises9.default.access(dir);
44830
44213
  } catch {
@@ -44897,15 +44280,16 @@ function buildMethodHandlers(deps) {
44897
44280
  // personaRoot 用于拼 publish.sh 绝对路径;broadcastSessionFrame 用于失败回灌路径
44898
44281
  // (runner 调 manager.send 后逐帧 dispatch 到 transport)。
44899
44282
  personaRoot: deps.appBuilderPersonaRoot,
44283
+ resolvePersonaRoot: deps.resolvePersonaRoot,
44900
44284
  broadcastSessionFrame: deps.broadcastSessionFrame
44901
44285
  })
44902
44286
  };
44903
44287
  }
44904
44288
 
44905
44289
  // src/app-builder/project-store.ts
44906
- var import_node_fs33 = require("fs");
44290
+ var import_node_fs32 = require("fs");
44907
44291
  var import_node_child_process13 = require("child_process");
44908
- var import_node_path42 = require("path");
44292
+ var import_node_path41 = require("path");
44909
44293
  init_protocol();
44910
44294
  var PROJECTS_DIR = "projects";
44911
44295
  var META_FILE = ".clawd-project.json";
@@ -44920,19 +44304,19 @@ var ProjectStore = class {
44920
44304
  root;
44921
44305
  /** projects/<name>/.clawd-project.json 路径 */
44922
44306
  metaPath(name) {
44923
- return (0, import_node_path42.join)(this.projectsRoot(), name, META_FILE);
44307
+ return (0, import_node_path41.join)(this.projectsRoot(), name, META_FILE);
44924
44308
  }
44925
44309
  /** projects/<name>/ 目录路径(cwd 用) */
44926
44310
  projectDir(name) {
44927
- return (0, import_node_path42.join)(this.projectsRoot(), name);
44311
+ return (0, import_node_path41.join)(this.projectsRoot(), name);
44928
44312
  }
44929
44313
  projectsRoot() {
44930
- return (0, import_node_path42.join)(this.root, PROJECTS_DIR);
44314
+ return (0, import_node_path41.join)(this.root, PROJECTS_DIR);
44931
44315
  }
44932
44316
  async list() {
44933
44317
  let entries;
44934
44318
  try {
44935
- entries = await import_node_fs33.promises.readdir(this.projectsRoot());
44319
+ entries = await import_node_fs32.promises.readdir(this.projectsRoot());
44936
44320
  } catch (err) {
44937
44321
  if (err.code === "ENOENT") return [];
44938
44322
  throw err;
@@ -44940,7 +44324,7 @@ var ProjectStore = class {
44940
44324
  const out = [];
44941
44325
  for (const name of entries) {
44942
44326
  try {
44943
- const raw = await import_node_fs33.promises.readFile(this.metaPath(name), "utf8");
44327
+ const raw = await import_node_fs32.promises.readFile(this.metaPath(name), "utf8");
44944
44328
  const json = JSON.parse(raw);
44945
44329
  let migrated = false;
44946
44330
  if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
@@ -44951,7 +44335,7 @@ var ProjectStore = class {
44951
44335
  if (parsed.success) {
44952
44336
  out.push(parsed.data);
44953
44337
  if (migrated) {
44954
- void import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
44338
+ void import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
44955
44339
  });
44956
44340
  }
44957
44341
  }
@@ -44995,8 +44379,8 @@ var ProjectStore = class {
44995
44379
  throw new Error(`invalid name "${name}": ${validated.error.message}`);
44996
44380
  }
44997
44381
  const dir = this.projectDir(name);
44998
- await import_node_fs33.promises.mkdir(dir, { recursive: true });
44999
- await import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
44382
+ await import_node_fs32.promises.mkdir(dir, { recursive: true });
44383
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
45000
44384
  return meta;
45001
44385
  }
45002
44386
  /**
@@ -45008,7 +44392,7 @@ var ProjectStore = class {
45008
44392
  * 代码再参考"。assistant 进 project 时目录已是完整模板,直接 pnpm install 即可。
45009
44393
  */
45010
44394
  async scaffold(name, template = DEFAULT_TEMPLATE, personaRoot = this.root) {
45011
- const scriptPath = (0, import_node_path42.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
44395
+ const scriptPath = (0, import_node_path41.join)(personaRoot, SCAFFOLD_SCRIPT_REL);
45012
44396
  const destDir = this.projectDir(name);
45013
44397
  return await new Promise((resolve6, reject) => {
45014
44398
  const child = (0, import_node_child_process13.spawn)("bash", [scriptPath, name, template, destDir], {
@@ -45041,7 +44425,7 @@ var ProjectStore = class {
45041
44425
  }
45042
44426
  async delete(name) {
45043
44427
  const dir = this.projectDir(name);
45044
- await import_node_fs33.promises.rm(dir, { recursive: true, force: true });
44428
+ await import_node_fs32.promises.rm(dir, { recursive: true, force: true });
45045
44429
  }
45046
44430
  async updatePort(name, newPort) {
45047
44431
  if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
@@ -45057,7 +44441,7 @@ var ProjectStore = class {
45057
44441
  throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
45058
44442
  }
45059
44443
  const updated = { ...target, port: newPort };
45060
- await import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
44444
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
45061
44445
  return updated;
45062
44446
  }
45063
44447
  /**
@@ -45074,7 +44458,7 @@ var ProjectStore = class {
45074
44458
  if (!validated.success) {
45075
44459
  throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
45076
44460
  }
45077
- await import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44461
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
45078
44462
  return validated.data;
45079
44463
  }
45080
44464
  /**
@@ -45095,7 +44479,7 @@ var ProjectStore = class {
45095
44479
  if (!validated.success) {
45096
44480
  throw new Error(`invalid publishJob: ${validated.error.message}`);
45097
44481
  }
45098
- await import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44482
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
45099
44483
  return validated.data;
45100
44484
  }
45101
44485
  /** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
@@ -45110,7 +44494,7 @@ var ProjectStore = class {
45110
44494
  if (!validated.success) {
45111
44495
  throw new Error(`failed to clear publishJob: ${validated.error.message}`);
45112
44496
  }
45113
- await import_node_fs33.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
44497
+ await import_node_fs32.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
45114
44498
  return validated.data;
45115
44499
  }
45116
44500
  };
@@ -45546,7 +44930,7 @@ function computeGrantForFrame(method, frame) {
45546
44930
 
45547
44931
  // src/extension/runtime.ts
45548
44932
  var import_node_child_process15 = require("child_process");
45549
- var import_node_path43 = __toESM(require("path"), 1);
44933
+ var import_node_path42 = __toESM(require("path"), 1);
45550
44934
  var import_promises10 = require("timers/promises");
45551
44935
 
45552
44936
  // src/extension/port-allocator.ts
@@ -45647,7 +45031,7 @@ var Runtime = class {
45647
45031
  /\$CLAWOS_EXT_PORT/g,
45648
45032
  String(port)
45649
45033
  );
45650
- const dir = import_node_path43.default.join(this.root, extId);
45034
+ const dir = import_node_path42.default.join(this.root, extId);
45651
45035
  const env = {
45652
45036
  ...process.env,
45653
45037
  CLAWOS_EXT_PORT: String(port),
@@ -45759,7 +45143,7 @@ ${handle.stderrTail}`
45759
45143
 
45760
45144
  // src/extension/published-channels.ts
45761
45145
  var import_promises11 = __toESM(require("fs/promises"), 1);
45762
- var import_node_path44 = __toESM(require("path"), 1);
45146
+ var import_node_path43 = __toESM(require("path"), 1);
45763
45147
  init_zod();
45764
45148
  var PublishedChannelsError = class extends Error {
45765
45149
  constructor(code, message) {
@@ -45858,7 +45242,7 @@ var PublishedChannelStore = class {
45858
45242
  )
45859
45243
  };
45860
45244
  const tmp = `${this.filePath}.tmp`;
45861
- await import_promises11.default.mkdir(import_node_path44.default.dirname(this.filePath), { recursive: true });
45245
+ await import_promises11.default.mkdir(import_node_path43.default.dirname(this.filePath), { recursive: true });
45862
45246
  await import_promises11.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
45863
45247
  await import_promises11.default.rename(tmp, this.filePath);
45864
45248
  }
@@ -45866,7 +45250,7 @@ var PublishedChannelStore = class {
45866
45250
 
45867
45251
  // src/extension/bundle-cache.ts
45868
45252
  var import_promises12 = __toESM(require("fs/promises"), 1);
45869
- var import_node_path45 = __toESM(require("path"), 1);
45253
+ var import_node_path44 = __toESM(require("path"), 1);
45870
45254
  var BundleCache = class {
45871
45255
  constructor(rootDir) {
45872
45256
  this.rootDir = rootDir;
@@ -45875,14 +45259,14 @@ var BundleCache = class {
45875
45259
  /** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
45876
45260
  async write(snapshotHash, buffer) {
45877
45261
  await import_promises12.default.mkdir(this.rootDir, { recursive: true });
45878
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45262
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45879
45263
  const tmp = `${file}.tmp`;
45880
45264
  await import_promises12.default.writeFile(tmp, buffer, { mode: 384 });
45881
45265
  await import_promises12.default.rename(tmp, file);
45882
45266
  }
45883
45267
  /** Returns the bundle bytes, or null when the file doesn't exist. */
45884
45268
  async read(snapshotHash) {
45885
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45269
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45886
45270
  try {
45887
45271
  return await import_promises12.default.readFile(file);
45888
45272
  } catch (e) {
@@ -45892,33 +45276,16 @@ var BundleCache = class {
45892
45276
  }
45893
45277
  /** Idempotent — missing file is not an error. */
45894
45278
  async delete(snapshotHash) {
45895
- const file = import_node_path45.default.join(this.rootDir, `${snapshotHash}.zip`);
45279
+ const file = import_node_path44.default.join(this.rootDir, `${snapshotHash}.zip`);
45896
45280
  await import_promises12.default.rm(file, { force: true });
45897
45281
  }
45898
45282
  };
45899
45283
 
45900
45284
  // src/index.ts
45901
- var import_meta4 = {};
45902
45285
  async function startDaemon(config) {
45903
- const authFile = loadOrCreateAuthFile({ dataDir: config.dataDir });
45904
- const logShippingCfg = config.logShipping ?? { endpoint: null, sampling: {}, mode: "off" };
45905
- const logClient = createLogClient({
45906
- endpoint: logShippingCfg.endpoint,
45907
- identity: {
45908
- ownerPrincipalId: authFile.ownerPrincipalId,
45909
- deviceId: authFile.deviceId,
45910
- appVersion: version,
45911
- daemonVersion: version,
45912
- os: `${process.platform}-${process.arch}`
45913
- },
45914
- source: "daemon",
45915
- sampling: logShippingCfg.sampling,
45916
- homeDir: import_node_os19.default.homedir()
45917
- });
45918
45286
  const logger = createLogger({
45919
45287
  level: config.logLevel,
45920
- file: import_node_path46.default.join(config.dataDir, "clawd.log"),
45921
- logClient
45288
+ file: import_node_path45.default.join(config.dataDir, "clawd.log")
45922
45289
  });
45923
45290
  logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
45924
45291
  const stateMgr = new StateFileManager({ dataDir: config.dataDir });
@@ -45929,6 +45296,7 @@ async function startDaemon(config) {
45929
45296
  if (pre.status === "stale") {
45930
45297
  logger.warn("stale state file detected, overwriting", { pid: pre.existing.pid });
45931
45298
  }
45299
+ const authFile = loadOrCreateAuthFile({ dataDir: config.dataDir });
45932
45300
  let resolvedAuthToken = null;
45933
45301
  if (config.authToken && config.authToken.trim()) {
45934
45302
  resolvedAuthToken = config.authToken.trim();
@@ -46053,8 +45421,8 @@ async function startDaemon(config) {
46053
45421
  const agents = new AgentsScanner();
46054
45422
  const history = new ClaudeHistoryReader();
46055
45423
  let transport = null;
46056
- const personaStore = new PersonaStore(import_node_path46.default.join(config.dataDir, "personas"));
46057
- const usersRoot = import_node_path46.default.join(config.dataDir, "users");
45424
+ const personaStore = new PersonaStore(import_node_path45.default.join(config.dataDir, "personas"));
45425
+ const usersRoot = import_node_path45.default.join(config.dataDir, "users");
46058
45426
  const defaultsRoot = findDefaultsRoot();
46059
45427
  if (defaultsRoot) {
46060
45428
  seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
@@ -46065,33 +45433,6 @@ async function startDaemon(config) {
46065
45433
  migrateAgentsMirror({ store: personaStore, logger });
46066
45434
  migrateCodexSandbox({ store: personaStore, logger });
46067
45435
  const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
46068
- const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
46069
- const here = typeof __dirname === "string" ? __dirname : import_node_path46.default.dirname((0, import_node_url2.fileURLToPath)(import_meta4.url));
46070
- const dispatchServerCandidates = [
46071
- import_node_path46.default.join(here, "dispatch", "mcp-server.cjs"),
46072
- // 生产 dist/index → dist/dispatch/mcp-server.cjs
46073
- import_node_path46.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
46074
- // dev tsx src/index → ../dist/dispatch/mcp-server.cjs
46075
- ];
46076
- const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs34.default.existsSync(p2));
46077
- let dispatchMcpConfigPath2;
46078
- if (dispatchServerScriptPath) {
46079
- const dispatchLogPath = import_node_path46.default.join(config.dataDir, "dispatch-mcp-server.log");
46080
- dispatchMcpConfigPath2 = writeDispatchMcpConfig({
46081
- dataDir: config.dataDir,
46082
- serverScriptPath: dispatchServerScriptPath,
46083
- logPath: dispatchLogPath
46084
- });
46085
- logger.info("dispatch.mcp.json written", {
46086
- path: dispatchMcpConfigPath2,
46087
- server: dispatchServerScriptPath,
46088
- serverLog: dispatchLogPath
46089
- });
46090
- } else {
46091
- logger.warn("dispatch-mcp-server.cjs not found; persona dispatch disabled (dev tsx \u6A21\u5F0F\u4E0B\u9700\u5148\u8DD1\u8FC7 build)", {
46092
- tried: dispatchServerCandidates
46093
- });
46094
- }
46095
45436
  const manager = new SessionManager({
46096
45437
  store,
46097
45438
  // Phase 2 (capability platform plan §1): factory 注入后 manager.storeFor 走
@@ -46101,7 +45442,7 @@ async function startDaemon(config) {
46101
45442
  getAdapter,
46102
45443
  historyReader: history,
46103
45444
  dataDir: config.dataDir,
46104
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45445
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
46105
45446
  usersRoot,
46106
45447
  personaStore,
46107
45448
  ownerDisplayName,
@@ -46112,12 +45453,6 @@ async function startDaemon(config) {
46112
45453
  // 127.0.0.1(不是 config.host)—— cc 跑在本机,loopback 最稳;外部访问限制 + http-router
46113
45454
  // 的 isLoopback 兜底已确保安全。
46114
45455
  getDaemonUrl: () => `http://127.0.0.1:${config.port}`,
46115
- // Persona dispatch (Task 8): manager 通过这两个 deps 跟 PersonaDispatchManager 协作。
46116
- // - personaDispatchManager: manager.createDispatchedSession 用它 registerBSession;
46117
- // reducer 通过闭包反查 dispatchId 注 CLAWD_DISPATCH_ID env。
46118
- // - dispatchMcpConfigPath: reducer 透传到 SpawnContext,cc spawn 加 --mcp-config flag。
46119
- personaDispatchManager,
46120
- dispatchMcpConfigPath: dispatchMcpConfigPath2,
46121
45456
  broadcastFrame: (frame, target) => {
46122
45457
  if (target === "all") {
46123
45458
  transport?.broadcastAll(frame);
@@ -46137,10 +45472,10 @@ async function startDaemon(config) {
46137
45472
  // 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
46138
45473
  attachmentGroup: {
46139
45474
  onFileEdit: (input) => {
46140
- const absPath = import_node_path46.default.isAbsolute(input.relPath) ? input.relPath : import_node_path46.default.join(input.cwd, input.relPath);
45475
+ const absPath = import_node_path45.default.isAbsolute(input.relPath) ? input.relPath : import_node_path45.default.join(input.cwd, input.relPath);
46141
45476
  let size = 0;
46142
45477
  try {
46143
- size = import_node_fs34.default.statSync(absPath).size;
45478
+ size = import_node_fs33.default.statSync(absPath).size;
46144
45479
  } catch (err) {
46145
45480
  logger.warn("attachment.onFileEdit stat failed", {
46146
45481
  sessionId: input.sessionId,
@@ -46326,11 +45661,11 @@ async function startDaemon(config) {
46326
45661
  // 'persona/<pid>/owner',default 走 'default'。
46327
45662
  getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
46328
45663
  // guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
46329
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45664
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
46330
45665
  usersRoot
46331
45666
  },
46332
45667
  // workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
46333
- personaRoot: import_node_path46.default.join(config.dataDir, "personas"),
45668
+ personaRoot: import_node_path45.default.join(config.dataDir, "personas"),
46334
45669
  // v2 多人 persona 隔离:handler 派生 guest user-dir 放行
46335
45670
  usersRoot,
46336
45671
  // capability:list / delete handler 依赖
@@ -46419,7 +45754,9 @@ async function startDaemon(config) {
46419
45754
  // 发布上线脚手架化 (spec 2026-06-03 §5.2):
46420
45755
  // appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
46421
45756
  // dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
46422
- appBuilderPersonaRoot: import_node_path46.default.join(config.dataDir, "personas", "persona-app-builder"),
45757
+ appBuilderPersonaRoot: import_node_path45.default.join(config.dataDir, "personas", "persona-app-builder"),
45758
+ // scaffold 按当前 session 的 persona 解析其安装根,让新 persona 复用流水线用自己的模板。
45759
+ resolvePersonaRoot: (personaId) => import_node_path45.default.join(config.dataDir, "personas", personaId),
46423
45760
  // 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
46424
45761
  // 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
46425
45762
  // 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
@@ -46440,41 +45777,6 @@ async function startDaemon(config) {
46440
45777
  logger
46441
45778
  });
46442
45779
  let handlers = makeHandlers();
46443
- const dispatchHandlers = buildPersonaDispatchHandlers({
46444
- personaDispatchManager,
46445
- logger,
46446
- spawnB: async (args) => {
46447
- logger.info("dispatch.spawnB.start", {
46448
- dispatchId: args.dispatchId,
46449
- targetPersona: args.targetPersona,
46450
- sourceSessionId: args.sourceSessionId
46451
- });
46452
- const sourceFile = manager.findOwnedSession(args.sourceSessionId);
46453
- if (!sourceFile) {
46454
- throw new Error(`personaDispatch:run source session not found: ${args.sourceSessionId}`);
46455
- }
46456
- const sourceJsonlPath = sourceFile.toolSessionId ? import_node_path46.default.join(
46457
- import_node_os19.default.homedir(),
46458
- ".claude",
46459
- "projects",
46460
- cwdToHashDir(sourceFile.cwd),
46461
- `${sourceFile.toolSessionId}.jsonl`
46462
- ) : "(no transcript yet \u2014 operate from the task description alone)";
46463
- logger.info("dispatch.spawnB.source-resolved", {
46464
- dispatchId: args.dispatchId,
46465
- sourceJsonlPath,
46466
- hasToolSessionId: Boolean(sourceFile.toolSessionId)
46467
- });
46468
- manager.createDispatchedSession({
46469
- dispatchId: args.dispatchId,
46470
- sourceSessionId: args.sourceSessionId,
46471
- targetPersona: args.targetPersona,
46472
- prompt: args.prompt,
46473
- sourceJsonlPath
46474
- });
46475
- }
46476
- });
46477
- handlers = { ...handlers, ...dispatchHandlers };
46478
45780
  const authResolver = new AuthContextResolver({
46479
45781
  ownerToken: resolvedAuthToken
46480
45782
  });
@@ -46549,10 +45851,6 @@ async function startDaemon(config) {
46549
45851
  manager,
46550
45852
  getAdapter,
46551
45853
  getTunnelUrl: () => currentTunnelUrl,
46552
- getLogShipping: () => config.logShipping ? {
46553
- endpoint: config.logShipping.endpoint,
46554
- sampling: config.logShipping.sampling
46555
- } : null,
46556
45854
  // ready 帧 mode = daemon CC spawn 模式('sdk' | 'tui');UI 用它挂 XtermPanel
46557
45855
  mode: config.mode,
46558
45856
  // file-sharing 字段:httpBaseUrl 跟 tunnel 状态走;httpToken 复用 owner WS token
@@ -46707,8 +46005,8 @@ async function startDaemon(config) {
46707
46005
  const lines = [
46708
46006
  `Tunnel: ${r.url}`,
46709
46007
  ...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
46710
- `Frpc config: ${import_node_path46.default.join(config.dataDir, "frpc.toml")}`,
46711
- `Frpc log: ${import_node_path46.default.join(config.dataDir, "frpc.log")}`
46008
+ `Frpc config: ${import_node_path45.default.join(config.dataDir, "frpc.toml")}`,
46009
+ `Frpc log: ${import_node_path45.default.join(config.dataDir, "frpc.log")}`
46712
46010
  ];
46713
46011
  const width = Math.max(...lines.map((l) => l.length));
46714
46012
  const bar = "\u2550".repeat(width + 4);
@@ -46721,8 +46019,8 @@ ${bar}
46721
46019
 
46722
46020
  `);
46723
46021
  try {
46724
- const connectPath = import_node_path46.default.join(config.dataDir, "connect.txt");
46725
- import_node_fs34.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
46022
+ const connectPath = import_node_path45.default.join(config.dataDir, "connect.txt");
46023
+ import_node_fs33.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
46726
46024
  } catch {
46727
46025
  }
46728
46026
  } catch (err) {
@@ -46783,7 +46081,6 @@ ${bar}
46783
46081
  }
46784
46082
  await wss.stop();
46785
46083
  stateMgr.delete();
46786
- if (logClient) await logClient.dispose();
46787
46084
  };
46788
46085
  return {
46789
46086
  stop: shutdown,
@@ -46794,9 +46091,9 @@ ${bar}
46794
46091
  };
46795
46092
  }
46796
46093
  function migrateDropPersonsDir(dataDir) {
46797
- const dir = import_node_path46.default.join(dataDir, "persons");
46094
+ const dir = import_node_path45.default.join(dataDir, "persons");
46798
46095
  try {
46799
- import_node_fs34.default.rmSync(dir, { recursive: true, force: true });
46096
+ import_node_fs33.default.rmSync(dir, { recursive: true, force: true });
46800
46097
  } catch {
46801
46098
  }
46802
46099
  }