@clawos-dev/clawd 0.2.71-beta.135.eac0f51 → 0.2.71-beta.137.a346461

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.cjs +218 -373
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -142,13 +142,10 @@ var init_methods = __esm({
142
142
  // - list 返回 PersonWithLinks[](含派生 linkedCapabilityIds / linkedRemoteAliases)
143
143
  // - create / update / delete 操作 Person 实体(delete 触发 cascade:revoke 全部
144
144
  // linked cap + remove subscribed alias + clear linked inbox events)
145
- // - link 重新指向某 principal 到目标 personId(手动合并 / 重链入口;自动 link
146
- // 在 capability:issue / remote-persona:add handler 内部直接写 PersonAliasStore)
147
145
  "person:list",
148
146
  "person:create",
149
147
  "person:update",
150
- "person:delete",
151
- "person:link"
148
+ "person:delete"
152
149
  ];
153
150
  }
154
151
  });
@@ -638,8 +635,8 @@ var init_parseUtil = __esm({
638
635
  init_errors2();
639
636
  init_en();
640
637
  makeIssue = (params) => {
641
- const { data, path: path39, errorMaps, issueData } = params;
642
- const fullPath = [...path39, ...issueData.path || []];
638
+ const { data, path: path38, errorMaps, issueData } = params;
639
+ const fullPath = [...path38, ...issueData.path || []];
643
640
  const fullIssue = {
644
641
  ...issueData,
645
642
  path: fullPath
@@ -950,11 +947,11 @@ var init_types = __esm({
950
947
  init_parseUtil();
951
948
  init_util();
952
949
  ParseInputLazyPath = class {
953
- constructor(parent, value, path39, key) {
950
+ constructor(parent, value, path38, key) {
954
951
  this._cachedPath = [];
955
952
  this.parent = parent;
956
953
  this.data = value;
957
- this._path = path39;
954
+ this._path = path38;
958
955
  this._key = key;
959
956
  }
960
957
  get path() {
@@ -5113,12 +5110,11 @@ var init_capability = __esm({
5113
5110
  maxUses: external_exports.number().int().positive().optional(),
5114
5111
  usedCount: external_exports.number().int().nonnegative(),
5115
5112
  /**
5116
- * Person identity Phase 1: guest 真实身份。
5117
- * - 纯访客 / 尚未 authenticate undefined
5118
- * - guest authenticate 上报 selfPrincipalId 后 daemon 落入此字段(immutable,不允许 owner 修改)
5119
- * - PersonAliasStore 的 alias key 来源优先 linkedPrincipalId,否则 fallback cap.id
5113
+ * Person identity per-People token (2026-05-21): cap 直接绑死 Person 主人。
5114
+ * Person cap:capability:issue person 第二次调用 = 合并 grants,
5115
+ * 不新建 cap。删 PersonAlias 表整套(cap.personId 直接含信息,无需反查)。
5120
5116
  */
5121
- linkedPrincipalId: external_exports.string().min(1).optional()
5117
+ personId: external_exports.string().min(1)
5122
5118
  }).strict();
5123
5119
  CapabilityWireSchema = CapabilitySchema.omit({ secretHash: true });
5124
5120
  CapabilityErrorCodeSchema = external_exports.enum([
@@ -5208,7 +5204,12 @@ var init_remote_persona = __esm({
5208
5204
  remoteDisplayName: external_exports.string(),
5209
5205
  ownerDisplayName: external_exports.string().optional(),
5210
5206
  addedAt: external_exports.number().int().nonnegative(),
5211
- lastConnectedAt: external_exports.number().int().positive().optional()
5207
+ lastConnectedAt: external_exports.number().int().positive().optional(),
5208
+ /**
5209
+ * Person identity per-People token (2026-05-21): RemotePersona 直接绑死本地 Person。
5210
+ * 删 PersonAlias 表后由该字段提供"远端 owner principal 对应本地哪个 person"。
5211
+ */
5212
+ personId: external_exports.string().min(1)
5212
5213
  }).strict();
5213
5214
  RemotePersonaWireSchema = RemotePersonaSchema.omit({ capabilityToken: true });
5214
5215
  RemotePersonaAddArgsSchema = external_exports.object({
@@ -5223,9 +5224,8 @@ var init_remote_persona = __esm({
5223
5224
  remoteDisplayName: external_exports.string(),
5224
5225
  ownerDisplayName: external_exports.string().optional(),
5225
5226
  /**
5226
- * Person identity Phase 1: add 时必须关联到一个 Person(owner 视角的"对方是谁")。
5227
- * daemon handler 内 atomic 写 RemotePersona + PersonAliasStore
5228
- * (alias key = ownerPrincipalId)。
5227
+ * Person identity per-People token: add 时必须关联到一个 Person(owner 视角的"对方是谁")。
5228
+ * daemon handler 内 atomic 写 RemotePersona.personId(PersonAlias 2026-05-21 删除)。
5229
5229
  */
5230
5230
  personId: external_exports.string().min(1)
5231
5231
  }).strict();
@@ -5236,7 +5236,7 @@ var init_remote_persona = __esm({
5236
5236
  });
5237
5237
 
5238
5238
  // ../protocol/src/person.ts
5239
- var PersonSchema, PersonAliasSchema, PersonWithLinksSchema, PersonCreateArgsSchema, PersonUpdateArgsSchema, PersonDeleteArgsSchema, PersonLinkArgsSchema, PersonListResponseSchema, PersonCreateResponseSchema, PersonUpdateResponseSchema, PersonDeleteResponseSchema, PersonLinkResponseSchema;
5239
+ var PersonSchema, PersonWithLinksSchema, PersonCreateArgsSchema, PersonUpdateArgsSchema, PersonDeleteArgsSchema, PersonListResponseSchema, PersonCreateResponseSchema, PersonUpdateResponseSchema, PersonDeleteResponseSchema;
5240
5240
  var init_person = __esm({
5241
5241
  "../protocol/src/person.ts"() {
5242
5242
  "use strict";
@@ -5250,10 +5250,6 @@ var init_person = __esm({
5250
5250
  createdAt: external_exports.number().int().nonnegative(),
5251
5251
  updatedAt: external_exports.number().int().nonnegative()
5252
5252
  }).strict();
5253
- PersonAliasSchema = external_exports.object({
5254
- principalId: external_exports.string().min(1),
5255
- personId: external_exports.string().min(1)
5256
- }).strict();
5257
5253
  PersonWithLinksSchema = PersonSchema.extend({
5258
5254
  linkedCapabilityIds: external_exports.array(external_exports.string()),
5259
5255
  linkedRemoteAliases: external_exports.array(external_exports.string())
@@ -5273,10 +5269,6 @@ var init_person = __esm({
5273
5269
  PersonDeleteArgsSchema = external_exports.object({
5274
5270
  id: external_exports.string().min(1)
5275
5271
  }).strict();
5276
- PersonLinkArgsSchema = external_exports.object({
5277
- principalId: external_exports.string().min(1),
5278
- personId: external_exports.string().min(1)
5279
- }).strict();
5280
5272
  PersonListResponseSchema = external_exports.object({
5281
5273
  type: external_exports.literal("person:list:ok"),
5282
5274
  persons: external_exports.array(PersonWithLinksSchema)
@@ -5298,9 +5290,6 @@ var init_person = __esm({
5298
5290
  /** cascade 清掉了多少条 inbox 事件 */
5299
5291
  deletedInboxEvents: external_exports.number().int().nonnegative()
5300
5292
  }).strict();
5301
- PersonLinkResponseSchema = external_exports.object({
5302
- type: external_exports.literal("person:link:ok")
5303
- }).strict();
5304
5293
  }
5305
5294
  });
5306
5295
 
@@ -5595,8 +5584,8 @@ var require_req = __commonJS({
5595
5584
  if (req.originalUrl) {
5596
5585
  _req.url = req.originalUrl;
5597
5586
  } else {
5598
- const path39 = req.path;
5599
- _req.url = typeof path39 === "string" ? path39 : req.url ? req.url.path || req.url : void 0;
5587
+ const path38 = req.path;
5588
+ _req.url = typeof path38 === "string" ? path38 : req.url ? req.url.path || req.url : void 0;
5600
5589
  }
5601
5590
  if (req.query) {
5602
5591
  _req.query = req.query;
@@ -5761,14 +5750,14 @@ var require_redact = __commonJS({
5761
5750
  }
5762
5751
  return obj;
5763
5752
  }
5764
- function parsePath(path39) {
5753
+ function parsePath(path38) {
5765
5754
  const parts = [];
5766
5755
  let current = "";
5767
5756
  let inBrackets = false;
5768
5757
  let inQuotes = false;
5769
5758
  let quoteChar = "";
5770
- for (let i = 0; i < path39.length; i++) {
5771
- const char = path39[i];
5759
+ for (let i = 0; i < path38.length; i++) {
5760
+ const char = path38[i];
5772
5761
  if (!inBrackets && char === ".") {
5773
5762
  if (current) {
5774
5763
  parts.push(current);
@@ -5899,10 +5888,10 @@ var require_redact = __commonJS({
5899
5888
  return current;
5900
5889
  }
5901
5890
  function redactPaths(obj, paths, censor, remove = false) {
5902
- for (const path39 of paths) {
5903
- const parts = parsePath(path39);
5891
+ for (const path38 of paths) {
5892
+ const parts = parsePath(path38);
5904
5893
  if (parts.includes("*")) {
5905
- redactWildcardPath(obj, parts, censor, path39, remove);
5894
+ redactWildcardPath(obj, parts, censor, path38, remove);
5906
5895
  } else {
5907
5896
  if (remove) {
5908
5897
  removeKey(obj, parts);
@@ -5987,8 +5976,8 @@ var require_redact = __commonJS({
5987
5976
  }
5988
5977
  } else {
5989
5978
  if (afterWildcard.includes("*")) {
5990
- const wrappedCensor = typeof censor === "function" ? (value, path39) => {
5991
- const fullPath = [...pathArray.slice(0, pathLength), ...path39];
5979
+ const wrappedCensor = typeof censor === "function" ? (value, path38) => {
5980
+ const fullPath = [...pathArray.slice(0, pathLength), ...path38];
5992
5981
  return censor(value, fullPath);
5993
5982
  } : censor;
5994
5983
  redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
@@ -6023,8 +6012,8 @@ var require_redact = __commonJS({
6023
6012
  return null;
6024
6013
  }
6025
6014
  const pathStructure = /* @__PURE__ */ new Map();
6026
- for (const path39 of pathsToClone) {
6027
- const parts = parsePath(path39);
6015
+ for (const path38 of pathsToClone) {
6016
+ const parts = parsePath(path38);
6028
6017
  let current = pathStructure;
6029
6018
  for (let i = 0; i < parts.length; i++) {
6030
6019
  const part = parts[i];
@@ -6076,24 +6065,24 @@ var require_redact = __commonJS({
6076
6065
  }
6077
6066
  return cloneSelectively(obj, pathStructure);
6078
6067
  }
6079
- function validatePath(path39) {
6080
- if (typeof path39 !== "string") {
6068
+ function validatePath(path38) {
6069
+ if (typeof path38 !== "string") {
6081
6070
  throw new Error("Paths must be (non-empty) strings");
6082
6071
  }
6083
- if (path39 === "") {
6072
+ if (path38 === "") {
6084
6073
  throw new Error("Invalid redaction path ()");
6085
6074
  }
6086
- if (path39.includes("..")) {
6087
- throw new Error(`Invalid redaction path (${path39})`);
6075
+ if (path38.includes("..")) {
6076
+ throw new Error(`Invalid redaction path (${path38})`);
6088
6077
  }
6089
- if (path39.includes(",")) {
6090
- throw new Error(`Invalid redaction path (${path39})`);
6078
+ if (path38.includes(",")) {
6079
+ throw new Error(`Invalid redaction path (${path38})`);
6091
6080
  }
6092
6081
  let bracketCount = 0;
6093
6082
  let inQuotes = false;
6094
6083
  let quoteChar = "";
6095
- for (let i = 0; i < path39.length; i++) {
6096
- const char = path39[i];
6084
+ for (let i = 0; i < path38.length; i++) {
6085
+ const char = path38[i];
6097
6086
  if ((char === '"' || char === "'") && bracketCount > 0) {
6098
6087
  if (!inQuotes) {
6099
6088
  inQuotes = true;
@@ -6107,20 +6096,20 @@ var require_redact = __commonJS({
6107
6096
  } else if (char === "]" && !inQuotes) {
6108
6097
  bracketCount--;
6109
6098
  if (bracketCount < 0) {
6110
- throw new Error(`Invalid redaction path (${path39})`);
6099
+ throw new Error(`Invalid redaction path (${path38})`);
6111
6100
  }
6112
6101
  }
6113
6102
  }
6114
6103
  if (bracketCount !== 0) {
6115
- throw new Error(`Invalid redaction path (${path39})`);
6104
+ throw new Error(`Invalid redaction path (${path38})`);
6116
6105
  }
6117
6106
  }
6118
6107
  function validatePaths(paths) {
6119
6108
  if (!Array.isArray(paths)) {
6120
6109
  throw new TypeError("paths must be an array");
6121
6110
  }
6122
- for (const path39 of paths) {
6123
- validatePath(path39);
6111
+ for (const path38 of paths) {
6112
+ validatePath(path38);
6124
6113
  }
6125
6114
  }
6126
6115
  function slowRedact(options = {}) {
@@ -6288,8 +6277,8 @@ var require_redaction = __commonJS({
6288
6277
  if (shape[k2] === null) {
6289
6278
  o[k2] = (value) => topCensor(value, [k2]);
6290
6279
  } else {
6291
- const wrappedCensor = typeof censor === "function" ? (value, path39) => {
6292
- return censor(value, [k2, ...path39]);
6280
+ const wrappedCensor = typeof censor === "function" ? (value, path38) => {
6281
+ return censor(value, [k2, ...path38]);
6293
6282
  } : censor;
6294
6283
  o[k2] = Redact({
6295
6284
  paths: shape[k2],
@@ -6507,10 +6496,10 @@ var require_atomic_sleep = __commonJS({
6507
6496
  var require_sonic_boom = __commonJS({
6508
6497
  "../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
6509
6498
  "use strict";
6510
- var fs35 = require("fs");
6499
+ var fs34 = require("fs");
6511
6500
  var EventEmitter2 = require("events");
6512
6501
  var inherits = require("util").inherits;
6513
- var path39 = require("path");
6502
+ var path38 = require("path");
6514
6503
  var sleep = require_atomic_sleep();
6515
6504
  var assert = require("assert");
6516
6505
  var BUSY_WRITE_TIMEOUT = 100;
@@ -6564,20 +6553,20 @@ var require_sonic_boom = __commonJS({
6564
6553
  const mode = sonic.mode;
6565
6554
  if (sonic.sync) {
6566
6555
  try {
6567
- if (sonic.mkdir) fs35.mkdirSync(path39.dirname(file), { recursive: true });
6568
- const fd = fs35.openSync(file, flags, mode);
6556
+ if (sonic.mkdir) fs34.mkdirSync(path38.dirname(file), { recursive: true });
6557
+ const fd = fs34.openSync(file, flags, mode);
6569
6558
  fileOpened(null, fd);
6570
6559
  } catch (err) {
6571
6560
  fileOpened(err);
6572
6561
  throw err;
6573
6562
  }
6574
6563
  } else if (sonic.mkdir) {
6575
- fs35.mkdir(path39.dirname(file), { recursive: true }, (err) => {
6564
+ fs34.mkdir(path38.dirname(file), { recursive: true }, (err) => {
6576
6565
  if (err) return fileOpened(err);
6577
- fs35.open(file, flags, mode, fileOpened);
6566
+ fs34.open(file, flags, mode, fileOpened);
6578
6567
  });
6579
6568
  } else {
6580
- fs35.open(file, flags, mode, fileOpened);
6569
+ fs34.open(file, flags, mode, fileOpened);
6581
6570
  }
6582
6571
  }
6583
6572
  function SonicBoom(opts) {
@@ -6618,8 +6607,8 @@ var require_sonic_boom = __commonJS({
6618
6607
  this.flush = flushBuffer;
6619
6608
  this.flushSync = flushBufferSync;
6620
6609
  this._actualWrite = actualWriteBuffer;
6621
- fsWriteSync = () => fs35.writeSync(this.fd, this._writingBuf);
6622
- fsWrite = () => fs35.write(this.fd, this._writingBuf, this.release);
6610
+ fsWriteSync = () => fs34.writeSync(this.fd, this._writingBuf);
6611
+ fsWrite = () => fs34.write(this.fd, this._writingBuf, this.release);
6623
6612
  } else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
6624
6613
  this._writingBuf = "";
6625
6614
  this.write = write;
@@ -6628,15 +6617,15 @@ var require_sonic_boom = __commonJS({
6628
6617
  this._actualWrite = actualWrite;
6629
6618
  fsWriteSync = () => {
6630
6619
  if (Buffer.isBuffer(this._writingBuf)) {
6631
- return fs35.writeSync(this.fd, this._writingBuf);
6620
+ return fs34.writeSync(this.fd, this._writingBuf);
6632
6621
  }
6633
- return fs35.writeSync(this.fd, this._writingBuf, "utf8");
6622
+ return fs34.writeSync(this.fd, this._writingBuf, "utf8");
6634
6623
  };
6635
6624
  fsWrite = () => {
6636
6625
  if (Buffer.isBuffer(this._writingBuf)) {
6637
- return fs35.write(this.fd, this._writingBuf, this.release);
6626
+ return fs34.write(this.fd, this._writingBuf, this.release);
6638
6627
  }
6639
- return fs35.write(this.fd, this._writingBuf, "utf8", this.release);
6628
+ return fs34.write(this.fd, this._writingBuf, "utf8", this.release);
6640
6629
  };
6641
6630
  } else {
6642
6631
  throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
@@ -6693,7 +6682,7 @@ var require_sonic_boom = __commonJS({
6693
6682
  }
6694
6683
  }
6695
6684
  if (this._fsync) {
6696
- fs35.fsyncSync(this.fd);
6685
+ fs34.fsyncSync(this.fd);
6697
6686
  }
6698
6687
  const len = this._len;
6699
6688
  if (this._reopening) {
@@ -6807,7 +6796,7 @@ var require_sonic_boom = __commonJS({
6807
6796
  const onDrain = () => {
6808
6797
  if (!this._fsync) {
6809
6798
  try {
6810
- fs35.fsync(this.fd, (err) => {
6799
+ fs34.fsync(this.fd, (err) => {
6811
6800
  this._flushPending = false;
6812
6801
  cb(err);
6813
6802
  });
@@ -6909,7 +6898,7 @@ var require_sonic_boom = __commonJS({
6909
6898
  const fd = this.fd;
6910
6899
  this.once("ready", () => {
6911
6900
  if (fd !== this.fd) {
6912
- fs35.close(fd, (err) => {
6901
+ fs34.close(fd, (err) => {
6913
6902
  if (err) {
6914
6903
  return this.emit("error", err);
6915
6904
  }
@@ -6958,7 +6947,7 @@ var require_sonic_boom = __commonJS({
6958
6947
  buf = this._bufs[0];
6959
6948
  }
6960
6949
  try {
6961
- const n = Buffer.isBuffer(buf) ? fs35.writeSync(this.fd, buf) : fs35.writeSync(this.fd, buf, "utf8");
6950
+ const n = Buffer.isBuffer(buf) ? fs34.writeSync(this.fd, buf) : fs34.writeSync(this.fd, buf, "utf8");
6962
6951
  const releasedBufObj = releaseWritingBuf(buf, this._len, n);
6963
6952
  buf = releasedBufObj.writingBuf;
6964
6953
  this._len = releasedBufObj.len;
@@ -6974,7 +6963,7 @@ var require_sonic_boom = __commonJS({
6974
6963
  }
6975
6964
  }
6976
6965
  try {
6977
- fs35.fsyncSync(this.fd);
6966
+ fs34.fsyncSync(this.fd);
6978
6967
  } catch {
6979
6968
  }
6980
6969
  }
@@ -6995,7 +6984,7 @@ var require_sonic_boom = __commonJS({
6995
6984
  buf = mergeBuf(this._bufs[0], this._lens[0]);
6996
6985
  }
6997
6986
  try {
6998
- const n = fs35.writeSync(this.fd, buf);
6987
+ const n = fs34.writeSync(this.fd, buf);
6999
6988
  buf = buf.subarray(n);
7000
6989
  this._len = Math.max(this._len - n, 0);
7001
6990
  if (buf.length <= 0) {
@@ -7023,13 +7012,13 @@ var require_sonic_boom = __commonJS({
7023
7012
  this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
7024
7013
  if (this.sync) {
7025
7014
  try {
7026
- const written = Buffer.isBuffer(this._writingBuf) ? fs35.writeSync(this.fd, this._writingBuf) : fs35.writeSync(this.fd, this._writingBuf, "utf8");
7015
+ const written = Buffer.isBuffer(this._writingBuf) ? fs34.writeSync(this.fd, this._writingBuf) : fs34.writeSync(this.fd, this._writingBuf, "utf8");
7027
7016
  release(null, written);
7028
7017
  } catch (err) {
7029
7018
  release(err);
7030
7019
  }
7031
7020
  } else {
7032
- fs35.write(this.fd, this._writingBuf, release);
7021
+ fs34.write(this.fd, this._writingBuf, release);
7033
7022
  }
7034
7023
  }
7035
7024
  function actualWriteBuffer() {
@@ -7038,7 +7027,7 @@ var require_sonic_boom = __commonJS({
7038
7027
  this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
7039
7028
  if (this.sync) {
7040
7029
  try {
7041
- const written = fs35.writeSync(this.fd, this._writingBuf);
7030
+ const written = fs34.writeSync(this.fd, this._writingBuf);
7042
7031
  release(null, written);
7043
7032
  } catch (err) {
7044
7033
  release(err);
@@ -7047,7 +7036,7 @@ var require_sonic_boom = __commonJS({
7047
7036
  if (kCopyBuffer) {
7048
7037
  this._writingBuf = Buffer.from(this._writingBuf);
7049
7038
  }
7050
- fs35.write(this.fd, this._writingBuf, release);
7039
+ fs34.write(this.fd, this._writingBuf, release);
7051
7040
  }
7052
7041
  }
7053
7042
  function actualClose(sonic) {
@@ -7063,12 +7052,12 @@ var require_sonic_boom = __commonJS({
7063
7052
  sonic._lens = [];
7064
7053
  assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
7065
7054
  try {
7066
- fs35.fsync(sonic.fd, closeWrapped);
7055
+ fs34.fsync(sonic.fd, closeWrapped);
7067
7056
  } catch {
7068
7057
  }
7069
7058
  function closeWrapped() {
7070
7059
  if (sonic.fd !== 1 && sonic.fd !== 2) {
7071
- fs35.close(sonic.fd, done);
7060
+ fs34.close(sonic.fd, done);
7072
7061
  } else {
7073
7062
  done();
7074
7063
  }
@@ -7325,7 +7314,7 @@ var require_thread_stream = __commonJS({
7325
7314
  var { version: version2 } = require_package();
7326
7315
  var { EventEmitter: EventEmitter2 } = require("events");
7327
7316
  var { Worker } = require("worker_threads");
7328
- var { join: join12 } = require("path");
7317
+ var { join: join11 } = require("path");
7329
7318
  var { pathToFileURL } = require("url");
7330
7319
  var { wait } = require_wait();
7331
7320
  var {
@@ -7361,7 +7350,7 @@ var require_thread_stream = __commonJS({
7361
7350
  function createWorker(stream, opts) {
7362
7351
  const { filename, workerData } = opts;
7363
7352
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
7364
- const toExecute = bundlerOverrides["thread-stream-worker"] || join12(__dirname, "lib", "worker.js");
7353
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join11(__dirname, "lib", "worker.js");
7365
7354
  const worker = new Worker(toExecute, {
7366
7355
  ...opts.workerOpts,
7367
7356
  trackUnmanagedFds: false,
@@ -7747,7 +7736,7 @@ var require_transport = __commonJS({
7747
7736
  "use strict";
7748
7737
  var { createRequire } = require("module");
7749
7738
  var getCallers = require_caller();
7750
- var { join: join12, isAbsolute, sep: sep2 } = require("path");
7739
+ var { join: join11, isAbsolute, sep: sep2 } = require("path");
7751
7740
  var sleep = require_atomic_sleep();
7752
7741
  var onExit = require_on_exit_leak_free();
7753
7742
  var ThreadStream = require_thread_stream();
@@ -7810,7 +7799,7 @@ var require_transport = __commonJS({
7810
7799
  throw new Error("only one of target or targets can be specified");
7811
7800
  }
7812
7801
  if (targets) {
7813
- target = bundlerOverrides["pino-worker"] || join12(__dirname, "worker.js");
7802
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
7814
7803
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
7815
7804
  return {
7816
7805
  ...dest,
@@ -7828,7 +7817,7 @@ var require_transport = __commonJS({
7828
7817
  });
7829
7818
  });
7830
7819
  } else if (pipeline2) {
7831
- target = bundlerOverrides["pino-worker"] || join12(__dirname, "worker.js");
7820
+ target = bundlerOverrides["pino-worker"] || join11(__dirname, "worker.js");
7832
7821
  options.pipelines = [pipeline2.map((dest) => {
7833
7822
  return {
7834
7823
  ...dest,
@@ -7850,7 +7839,7 @@ var require_transport = __commonJS({
7850
7839
  return origin;
7851
7840
  }
7852
7841
  if (origin === "pino/file") {
7853
- return join12(__dirname, "..", "file.js");
7842
+ return join11(__dirname, "..", "file.js");
7854
7843
  }
7855
7844
  let fixTarget2;
7856
7845
  for (const filePath of callers) {
@@ -8840,7 +8829,7 @@ var require_safe_stable_stringify = __commonJS({
8840
8829
  return circularValue;
8841
8830
  }
8842
8831
  let res = "";
8843
- let join12 = ",";
8832
+ let join11 = ",";
8844
8833
  const originalIndentation = indentation;
8845
8834
  if (Array.isArray(value)) {
8846
8835
  if (value.length === 0) {
@@ -8854,7 +8843,7 @@ var require_safe_stable_stringify = __commonJS({
8854
8843
  indentation += spacer;
8855
8844
  res += `
8856
8845
  ${indentation}`;
8857
- join12 = `,
8846
+ join11 = `,
8858
8847
  ${indentation}`;
8859
8848
  }
8860
8849
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -8862,13 +8851,13 @@ ${indentation}`;
8862
8851
  for (; i < maximumValuesToStringify - 1; i++) {
8863
8852
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
8864
8853
  res += tmp2 !== void 0 ? tmp2 : "null";
8865
- res += join12;
8854
+ res += join11;
8866
8855
  }
8867
8856
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
8868
8857
  res += tmp !== void 0 ? tmp : "null";
8869
8858
  if (value.length - 1 > maximumBreadth) {
8870
8859
  const removedKeys = value.length - maximumBreadth - 1;
8871
- res += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
8860
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
8872
8861
  }
8873
8862
  if (spacer !== "") {
8874
8863
  res += `
@@ -8889,7 +8878,7 @@ ${originalIndentation}`;
8889
8878
  let separator = "";
8890
8879
  if (spacer !== "") {
8891
8880
  indentation += spacer;
8892
- join12 = `,
8881
+ join11 = `,
8893
8882
  ${indentation}`;
8894
8883
  whitespace = " ";
8895
8884
  }
@@ -8903,13 +8892,13 @@ ${indentation}`;
8903
8892
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
8904
8893
  if (tmp !== void 0) {
8905
8894
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
8906
- separator = join12;
8895
+ separator = join11;
8907
8896
  }
8908
8897
  }
8909
8898
  if (keyLength > maximumBreadth) {
8910
8899
  const removedKeys = keyLength - maximumBreadth;
8911
8900
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
8912
- separator = join12;
8901
+ separator = join11;
8913
8902
  }
8914
8903
  if (spacer !== "" && separator.length > 1) {
8915
8904
  res = `
@@ -8950,7 +8939,7 @@ ${originalIndentation}`;
8950
8939
  }
8951
8940
  const originalIndentation = indentation;
8952
8941
  let res = "";
8953
- let join12 = ",";
8942
+ let join11 = ",";
8954
8943
  if (Array.isArray(value)) {
8955
8944
  if (value.length === 0) {
8956
8945
  return "[]";
@@ -8963,7 +8952,7 @@ ${originalIndentation}`;
8963
8952
  indentation += spacer;
8964
8953
  res += `
8965
8954
  ${indentation}`;
8966
- join12 = `,
8955
+ join11 = `,
8967
8956
  ${indentation}`;
8968
8957
  }
8969
8958
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -8971,13 +8960,13 @@ ${indentation}`;
8971
8960
  for (; i < maximumValuesToStringify - 1; i++) {
8972
8961
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
8973
8962
  res += tmp2 !== void 0 ? tmp2 : "null";
8974
- res += join12;
8963
+ res += join11;
8975
8964
  }
8976
8965
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
8977
8966
  res += tmp !== void 0 ? tmp : "null";
8978
8967
  if (value.length - 1 > maximumBreadth) {
8979
8968
  const removedKeys = value.length - maximumBreadth - 1;
8980
- res += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
8969
+ res += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
8981
8970
  }
8982
8971
  if (spacer !== "") {
8983
8972
  res += `
@@ -8990,7 +8979,7 @@ ${originalIndentation}`;
8990
8979
  let whitespace = "";
8991
8980
  if (spacer !== "") {
8992
8981
  indentation += spacer;
8993
- join12 = `,
8982
+ join11 = `,
8994
8983
  ${indentation}`;
8995
8984
  whitespace = " ";
8996
8985
  }
@@ -8999,7 +8988,7 @@ ${indentation}`;
8999
8988
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
9000
8989
  if (tmp !== void 0) {
9001
8990
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
9002
- separator = join12;
8991
+ separator = join11;
9003
8992
  }
9004
8993
  }
9005
8994
  if (spacer !== "" && separator.length > 1) {
@@ -9057,20 +9046,20 @@ ${originalIndentation}`;
9057
9046
  indentation += spacer;
9058
9047
  let res2 = `
9059
9048
  ${indentation}`;
9060
- const join13 = `,
9049
+ const join12 = `,
9061
9050
  ${indentation}`;
9062
9051
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
9063
9052
  let i = 0;
9064
9053
  for (; i < maximumValuesToStringify - 1; i++) {
9065
9054
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
9066
9055
  res2 += tmp2 !== void 0 ? tmp2 : "null";
9067
- res2 += join13;
9056
+ res2 += join12;
9068
9057
  }
9069
9058
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
9070
9059
  res2 += tmp !== void 0 ? tmp : "null";
9071
9060
  if (value.length - 1 > maximumBreadth) {
9072
9061
  const removedKeys = value.length - maximumBreadth - 1;
9073
- res2 += `${join13}"... ${getItemCount(removedKeys)} not stringified"`;
9062
+ res2 += `${join12}"... ${getItemCount(removedKeys)} not stringified"`;
9074
9063
  }
9075
9064
  res2 += `
9076
9065
  ${originalIndentation}`;
@@ -9086,16 +9075,16 @@ ${originalIndentation}`;
9086
9075
  return '"[Object]"';
9087
9076
  }
9088
9077
  indentation += spacer;
9089
- const join12 = `,
9078
+ const join11 = `,
9090
9079
  ${indentation}`;
9091
9080
  let res = "";
9092
9081
  let separator = "";
9093
9082
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
9094
9083
  if (isTypedArrayWithEntries(value)) {
9095
- res += stringifyTypedArray(value, join12, maximumBreadth);
9084
+ res += stringifyTypedArray(value, join11, maximumBreadth);
9096
9085
  keys = keys.slice(value.length);
9097
9086
  maximumPropertiesToStringify -= value.length;
9098
- separator = join12;
9087
+ separator = join11;
9099
9088
  }
9100
9089
  if (deterministic) {
9101
9090
  keys = sort(keys, comparator);
@@ -9106,13 +9095,13 @@ ${indentation}`;
9106
9095
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
9107
9096
  if (tmp !== void 0) {
9108
9097
  res += `${separator}${strEscape(key2)}: ${tmp}`;
9109
- separator = join12;
9098
+ separator = join11;
9110
9099
  }
9111
9100
  }
9112
9101
  if (keyLength > maximumBreadth) {
9113
9102
  const removedKeys = keyLength - maximumBreadth;
9114
9103
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
9115
- separator = join12;
9104
+ separator = join11;
9116
9105
  }
9117
9106
  if (separator !== "") {
9118
9107
  res = `
@@ -10203,11 +10192,11 @@ var init_lib = __esm({
10203
10192
  }
10204
10193
  }
10205
10194
  },
10206
- addToPath: function addToPath(path39, added, removed, oldPosInc, options) {
10207
- var last = path39.lastComponent;
10195
+ addToPath: function addToPath(path38, added, removed, oldPosInc, options) {
10196
+ var last = path38.lastComponent;
10208
10197
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
10209
10198
  return {
10210
- oldPos: path39.oldPos + oldPosInc,
10199
+ oldPos: path38.oldPos + oldPosInc,
10211
10200
  lastComponent: {
10212
10201
  count: last.count + 1,
10213
10202
  added,
@@ -10217,7 +10206,7 @@ var init_lib = __esm({
10217
10206
  };
10218
10207
  } else {
10219
10208
  return {
10220
- oldPos: path39.oldPos + oldPosInc,
10209
+ oldPos: path38.oldPos + oldPosInc,
10221
10210
  lastComponent: {
10222
10211
  count: 1,
10223
10212
  added,
@@ -10648,10 +10637,10 @@ function attachmentToHistoryMessage(o, ts) {
10648
10637
  const memories = raw.map((m2) => {
10649
10638
  if (!m2 || typeof m2 !== "object") return null;
10650
10639
  const rec = m2;
10651
- const path39 = typeof rec.path === "string" ? rec.path : null;
10640
+ const path38 = typeof rec.path === "string" ? rec.path : null;
10652
10641
  const content = typeof rec.content === "string" ? rec.content : null;
10653
- if (!path39 || content == null) return null;
10654
- const entry = { path: path39, content };
10642
+ if (!path38 || content == null) return null;
10643
+ const entry = { path: path38, content };
10655
10644
  if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
10656
10645
  return entry;
10657
10646
  }).filter((m2) => m2 !== null);
@@ -11477,10 +11466,10 @@ function parseAttachment(obj) {
11477
11466
  const memories = raw.map((m2) => {
11478
11467
  if (!m2 || typeof m2 !== "object") return null;
11479
11468
  const rec = m2;
11480
- const path39 = typeof rec.path === "string" ? rec.path : null;
11469
+ const path38 = typeof rec.path === "string" ? rec.path : null;
11481
11470
  const content = typeof rec.content === "string" ? rec.content : null;
11482
- if (!path39 || content == null) return null;
11483
- const out = { path: path39, content };
11471
+ if (!path38 || content == null) return null;
11472
+ const out = { path: path38, content };
11484
11473
  if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
11485
11474
  return out;
11486
11475
  }).filter((m2) => m2 !== null);
@@ -21045,7 +21034,7 @@ var SessionStoreFactory = class {
21045
21034
  dataDir;
21046
21035
  bareStore = null;
21047
21036
  vmOwnerStores = /* @__PURE__ */ new Map();
21048
- // vmGuest 索引 key = `${pid}::${capId}`
21037
+ // vmGuest 索引 key = `${pid}::${personId}`(per-People token: 一 person 一目录)
21049
21038
  vmGuestStores = /* @__PURE__ */ new Map();
21050
21039
  constructor(opts) {
21051
21040
  this.dataDir = opts.dataDir;
@@ -21064,7 +21053,7 @@ var SessionStoreFactory = class {
21064
21053
  "owner"
21065
21054
  );
21066
21055
  }
21067
- vmGuestRoot(personaId, capabilityId) {
21056
+ vmGuestRoot(personaId, personId) {
21068
21057
  return path5.join(
21069
21058
  this.dataDir,
21070
21059
  "personas",
@@ -21072,7 +21061,7 @@ var SessionStoreFactory = class {
21072
21061
  ".clawd",
21073
21062
  "sessions",
21074
21063
  "guests",
21075
- safeFileName(capabilityId)
21064
+ safeFileName(personId)
21076
21065
  );
21077
21066
  }
21078
21067
  // ---- SessionStore 工厂(缓存) ----
@@ -21090,11 +21079,11 @@ var SessionStoreFactory = class {
21090
21079
  this.vmOwnerStores.set(key, st);
21091
21080
  return st;
21092
21081
  }
21093
- forVmGuest(personaId, capabilityId) {
21094
- const key = `${personaId}::${capabilityId}`;
21082
+ forVmGuest(personaId, personId) {
21083
+ const key = `${personaId}::${personId}`;
21095
21084
  const cached = this.vmGuestStores.get(key);
21096
21085
  if (cached) return cached;
21097
- const st = new SessionStore({ root: this.vmGuestRoot(personaId, capabilityId) });
21086
+ const st = new SessionStore({ root: this.vmGuestRoot(personaId, personId) });
21098
21087
  this.vmGuestStores.set(key, st);
21099
21088
  return st;
21100
21089
  }
@@ -26215,22 +26204,6 @@ var CapabilityRegistry = class {
26215
26204
  findById(id) {
26216
26205
  return this.store.list().find((c) => c.id === id) ?? null;
26217
26206
  }
26218
- /**
26219
- * Person identity Phase 1 (B11): guest authenticate 上报 selfPrincipalId 时
26220
- * daemon 把它落到 cap.linkedPrincipalId(之前 undefined)。设计上 immutable:
26221
- * 只允许 undefined → set;已设置后再调本方法 noop(reject 留给 caller 判断)。
26222
- *
26223
- * 返回 true = 实际写入;false = 不存在 / 已设置过(caller 用此区分用户行为)。
26224
- */
26225
- updateLinkedPrincipalId(id, principalId) {
26226
- const current = this.store.list().find((c) => c.id === id);
26227
- if (!current) return false;
26228
- if (current.linkedPrincipalId !== void 0) return false;
26229
- const updated = { ...current, linkedPrincipalId: principalId };
26230
- this.bySecretHash.set(updated.secretHash, updated);
26231
- this.store.upsert(updated);
26232
- return true;
26233
- }
26234
26207
  };
26235
26208
  function sha256Hex(s) {
26236
26209
  return crypto4.createHash("sha256").update(s).digest("hex");
@@ -26267,24 +26240,31 @@ var CapabilityManager = class {
26267
26240
  grants: args.grants,
26268
26241
  issuedAt: now,
26269
26242
  usedCount: 0,
26243
+ personId: args.personId,
26270
26244
  ...args.expiresAt !== void 0 ? { expiresAt: args.expiresAt } : {},
26271
26245
  ...args.maxUses !== void 0 ? { maxUses: args.maxUses } : {}
26272
26246
  };
26273
26247
  this.registry.upsertCapability(cap);
26274
- if (args.atomicAfterPersist) {
26275
- try {
26276
- args.atomicAfterPersist(cap);
26277
- } catch (err) {
26278
- try {
26279
- this.registry.delete(cap.id);
26280
- } catch {
26281
- }
26282
- throw err;
26283
- }
26284
- }
26285
26248
  this.hooks.onIssued?.(cap, token);
26286
26249
  return { token, capability: cap };
26287
26250
  }
26251
+ /**
26252
+ * Per-People token: 同 personId 已有 cap 时 add grants(merge unique by resource+action)。
26253
+ * 返回 updated cap。如果 personId 没有 cap 返 null(caller 应该调 issue 新建)。
26254
+ */
26255
+ addGrantsToPerson(personId, newGrants) {
26256
+ const existing = this.registry.list().find((c) => c.personId === personId);
26257
+ if (!existing) return null;
26258
+ const merged = mergeGrants(existing.grants, newGrants);
26259
+ const updated = { ...existing, grants: merged };
26260
+ this.registry.upsertCapability(updated);
26261
+ this.hooks.onIssued?.(updated, "__merged__");
26262
+ return updated;
26263
+ }
26264
+ /** 按 personId 反查现有 cap(per-People token dedupe)。 */
26265
+ findByPerson(personId) {
26266
+ return this.registry.list().find((c) => c.personId === personId) ?? null;
26267
+ }
26288
26268
  /**
26289
26269
  * Hard delete:从 registry / store 物理移除 capability。
26290
26270
  * idempotent:不存在 → null(handler 翻译成 VALIDATION_ERROR)
@@ -26296,15 +26276,19 @@ var CapabilityManager = class {
26296
26276
  this.hooks.onDeleted?.(removed);
26297
26277
  return { capability: removed };
26298
26278
  }
26299
- /**
26300
- * Person identity Phase 1 (B11) passthrough:guest authenticate 上报
26301
- * selfPrincipalId 时升级 cap.linkedPrincipalId(一次性,undefined → set)。
26302
- * 详见 CapabilityRegistry.updateLinkedPrincipalId JSDoc。
26303
- */
26304
- updateLinkedPrincipalId(id, principalId) {
26305
- return this.registry.updateLinkedPrincipalId(id, principalId);
26306
- }
26307
26279
  };
26280
+ function mergeGrants(existing, add) {
26281
+ const key = (g2) => JSON.stringify({ r: g2.resource, a: [...g2.actions].sort() });
26282
+ const seen = new Set(existing.map(key));
26283
+ const out = [...existing];
26284
+ for (const g2 of add) {
26285
+ if (!seen.has(key(g2))) {
26286
+ out.push(g2);
26287
+ seen.add(key(g2));
26288
+ }
26289
+ }
26290
+ return out;
26291
+ }
26308
26292
  function defaultGenerateToken() {
26309
26293
  return crypto5.randomBytes(24).toString("base64url");
26310
26294
  }
@@ -26321,7 +26305,7 @@ function cleanupGuestSessionsForCapability(cap, factory) {
26321
26305
  const removed = [];
26322
26306
  for (const g2 of cap.grants) {
26323
26307
  if (g2.resource.type !== "persona") continue;
26324
- const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
26308
+ const dir = factory.vmGuestRoot(g2.resource.id, cap.personId);
26325
26309
  try {
26326
26310
  fs16.rmSync(dir, { recursive: true, force: true });
26327
26311
  removed.push(dir);
@@ -26718,149 +26702,62 @@ var PersonStore = class {
26718
26702
  }
26719
26703
  };
26720
26704
 
26721
- // src/person/alias-store.ts
26705
+ // src/migrations/2026-05-20-flatten-sessions.ts
26722
26706
  var fs20 = __toESM(require("fs"), 1);
26723
26707
  var path22 = __toESM(require("path"), 1);
26724
- var PERSON_ALIASES_SUBDIR = "persons-meta";
26725
- var PERSON_ALIASES_FILE = "aliases.json";
26726
- var PersonAliasStore = class {
26727
- constructor(dataDir) {
26728
- this.dataDir = dataDir;
26729
- fs20.mkdirSync(path22.join(this.dataDir, PERSON_ALIASES_SUBDIR), { recursive: true });
26730
- }
26731
- dataDir;
26732
- get filePath() {
26733
- return path22.join(this.dataDir, PERSON_ALIASES_SUBDIR, PERSON_ALIASES_FILE);
26734
- }
26735
- list() {
26736
- let raw;
26737
- try {
26738
- raw = fs20.readFileSync(this.filePath, "utf8");
26739
- } catch (err) {
26740
- if (err?.code === "ENOENT") return [];
26741
- return [];
26742
- }
26743
- let parsed;
26744
- try {
26745
- parsed = JSON.parse(raw);
26746
- } catch {
26747
- return [];
26748
- }
26749
- if (!Array.isArray(parsed)) return [];
26750
- const out = [];
26751
- for (const item of parsed) {
26752
- const r = PersonAliasSchema.safeParse(item);
26753
- if (r.success) out.push(r.data);
26754
- }
26755
- return out;
26756
- }
26757
- get(principalId) {
26758
- return this.list().find((a) => a.principalId === principalId)?.personId;
26759
- }
26760
- set(principalId, personId) {
26761
- const all = this.list().filter((a) => a.principalId !== principalId);
26762
- all.push({ principalId, personId });
26763
- this.write(all);
26764
- }
26765
- remove(principalId) {
26766
- const all = this.list();
26767
- const next = all.filter((a) => a.principalId !== principalId);
26768
- if (next.length === all.length) return false;
26769
- this.write(next);
26770
- return true;
26771
- }
26772
- removeAllByPerson(personId) {
26773
- const all = this.list();
26774
- const next = all.filter((a) => a.personId !== personId);
26775
- if (next.length === all.length) return;
26776
- this.write(next);
26777
- }
26778
- /**
26779
- * 把某条 alias 的 principalId 改为新 key,personId 不变。
26780
- * 用于 guest 第一次 authenticate 上报 selfPrincipalId 时,把 alias key 从
26781
- * cap.id(fallback)升级到真实 ownerPrincipalId。
26782
- *
26783
- * 若 oldKey 不存在 → no-op。
26784
- * 若 newKey 已存在另一条 entry → 用 oldKey 的 personId 覆盖("old wins"),并去重。
26785
- */
26786
- rekey(oldPrincipalId, newPrincipalId) {
26787
- const all = this.list();
26788
- const old = all.find((a) => a.principalId === oldPrincipalId);
26789
- if (!old) return;
26790
- const filtered = all.filter(
26791
- (a) => a.principalId !== oldPrincipalId && a.principalId !== newPrincipalId
26792
- );
26793
- filtered.push({ principalId: newPrincipalId, personId: old.personId });
26794
- this.write(filtered);
26795
- }
26796
- write(entries) {
26797
- fs20.mkdirSync(path22.join(this.dataDir, PERSON_ALIASES_SUBDIR), { recursive: true });
26798
- const tmp = `${this.filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
26799
- fs20.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
26800
- fs20.renameSync(tmp, this.filePath);
26801
- try {
26802
- fs20.chmodSync(this.filePath, 384);
26803
- } catch {
26804
- }
26805
- }
26806
- };
26807
-
26808
- // src/migrations/2026-05-20-flatten-sessions.ts
26809
- var fs21 = __toESM(require("fs"), 1);
26810
- var path23 = __toESM(require("path"), 1);
26811
26708
  var MIGRATION_FLAG_NAME = ".migration.v1.done";
26812
26709
  function migrateFlattenSessions(opts) {
26813
26710
  const dataDir = opts.dataDir;
26814
26711
  const now = opts.now ?? Date.now;
26815
- const sessionsDir = path23.join(dataDir, "sessions");
26816
- const flagPath = path23.join(sessionsDir, MIGRATION_FLAG_NAME);
26712
+ const sessionsDir = path22.join(dataDir, "sessions");
26713
+ const flagPath = path22.join(sessionsDir, MIGRATION_FLAG_NAME);
26817
26714
  if (existsSync5(flagPath)) {
26818
26715
  return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
26819
26716
  }
26820
26717
  let movedBare = 0;
26821
26718
  let movedVmOwner = 0;
26822
26719
  let archivedListener = 0;
26823
- const defaultDir = path23.join(sessionsDir, "default");
26720
+ const defaultDir = path22.join(sessionsDir, "default");
26824
26721
  if (existsSync5(defaultDir)) {
26825
26722
  for (const entry of readdirSafe(defaultDir)) {
26826
26723
  if (!entry.endsWith(".json")) continue;
26827
- const src = path23.join(defaultDir, entry);
26828
- const dst = path23.join(sessionsDir, entry);
26829
- fs21.renameSync(src, dst);
26724
+ const src = path22.join(defaultDir, entry);
26725
+ const dst = path22.join(sessionsDir, entry);
26726
+ fs20.renameSync(src, dst);
26830
26727
  movedBare += 1;
26831
26728
  }
26832
26729
  rmdirIfEmpty(defaultDir);
26833
26730
  }
26834
26731
  for (const pid of readdirSafe(sessionsDir)) {
26835
- const personaDir = path23.join(sessionsDir, pid);
26732
+ const personaDir = path22.join(sessionsDir, pid);
26836
26733
  if (!isDir(personaDir)) continue;
26837
26734
  if (pid === "default") continue;
26838
- const ownerSrc = path23.join(personaDir, "owner");
26735
+ const ownerSrc = path22.join(personaDir, "owner");
26839
26736
  if (existsSync5(ownerSrc) && isDir(ownerSrc)) {
26840
- const ownerDst = path23.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
26841
- fs21.mkdirSync(ownerDst, { recursive: true });
26737
+ const ownerDst = path22.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
26738
+ fs20.mkdirSync(ownerDst, { recursive: true });
26842
26739
  for (const file of readdirSafe(ownerSrc)) {
26843
26740
  if (!file.endsWith(".json")) continue;
26844
- fs21.renameSync(path23.join(ownerSrc, file), path23.join(ownerDst, file));
26741
+ fs20.renameSync(path22.join(ownerSrc, file), path22.join(ownerDst, file));
26845
26742
  movedVmOwner += 1;
26846
26743
  }
26847
26744
  rmdirIfEmpty(ownerSrc);
26848
26745
  }
26849
- const listenerSrc = path23.join(personaDir, "listener");
26746
+ const listenerSrc = path22.join(personaDir, "listener");
26850
26747
  if (existsSync5(listenerSrc) && isDir(listenerSrc)) {
26851
- const archiveDst = path23.join(dataDir, ".legacy", `listener-${pid}`);
26852
- fs21.mkdirSync(archiveDst, { recursive: true });
26748
+ const archiveDst = path22.join(dataDir, ".legacy", `listener-${pid}`);
26749
+ fs20.mkdirSync(archiveDst, { recursive: true });
26853
26750
  for (const file of readdirSafe(listenerSrc)) {
26854
26751
  if (!file.endsWith(".json")) continue;
26855
- fs21.renameSync(path23.join(listenerSrc, file), path23.join(archiveDst, file));
26752
+ fs20.renameSync(path22.join(listenerSrc, file), path22.join(archiveDst, file));
26856
26753
  archivedListener += 1;
26857
26754
  }
26858
26755
  rmdirIfEmpty(listenerSrc);
26859
26756
  }
26860
26757
  rmdirIfEmpty(personaDir);
26861
26758
  }
26862
- fs21.mkdirSync(sessionsDir, { recursive: true });
26863
- fs21.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
26759
+ fs20.mkdirSync(sessionsDir, { recursive: true });
26760
+ fs20.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
26864
26761
  return {
26865
26762
  skipped: false,
26866
26763
  flagWritten: true,
@@ -26871,7 +26768,7 @@ function migrateFlattenSessions(opts) {
26871
26768
  }
26872
26769
  function existsSync5(p2) {
26873
26770
  try {
26874
- fs21.statSync(p2);
26771
+ fs20.statSync(p2);
26875
26772
  return true;
26876
26773
  } catch {
26877
26774
  return false;
@@ -26879,21 +26776,21 @@ function existsSync5(p2) {
26879
26776
  }
26880
26777
  function isDir(p2) {
26881
26778
  try {
26882
- return fs21.statSync(p2).isDirectory();
26779
+ return fs20.statSync(p2).isDirectory();
26883
26780
  } catch {
26884
26781
  return false;
26885
26782
  }
26886
26783
  }
26887
26784
  function readdirSafe(p2) {
26888
26785
  try {
26889
- return fs21.readdirSync(p2);
26786
+ return fs20.readdirSync(p2);
26890
26787
  } catch {
26891
26788
  return [];
26892
26789
  }
26893
26790
  }
26894
26791
  function rmdirIfEmpty(p2) {
26895
26792
  try {
26896
- fs21.rmdirSync(p2);
26793
+ fs20.rmdirSync(p2);
26897
26794
  } catch {
26898
26795
  }
26899
26796
  }
@@ -28239,7 +28136,15 @@ function buildSessionHandlers(deps) {
28239
28136
  }
28240
28137
  }
28241
28138
  ensurePersonaAccess(ctx, args.ownerPersonaId, "send");
28242
- const creatorPrincipalId = ctx?.principal.id ?? "";
28139
+ let creatorPrincipalId = "";
28140
+ if (ctx) {
28141
+ if (ctx.principal.kind === "guest" && ctx.capabilityId && deps.capabilityManager) {
28142
+ const cap = deps.capabilityManager.findById(ctx.capabilityId);
28143
+ creatorPrincipalId = cap?.personId ?? ctx.principal.id;
28144
+ } else {
28145
+ creatorPrincipalId = ctx.principal.id;
28146
+ }
28147
+ }
28243
28148
  const { response, broadcast } = manager.create(args, creatorPrincipalId);
28244
28149
  return { response: { type: "session:info", ...response }, broadcast };
28245
28150
  };
@@ -28693,7 +28598,7 @@ var DeleteArgsSchema = external_exports.object({
28693
28598
  capabilityId: external_exports.string().min(1)
28694
28599
  }).strict();
28695
28600
  function buildCapabilityHandlers(deps) {
28696
- const { manager, getShareBaseUrl, personStore, aliasStore } = deps;
28601
+ const { manager, getShareBaseUrl, personStore } = deps;
28697
28602
  const issue = async (frame) => {
28698
28603
  const { type: _type, requestId: _requestId, ...rest } = frame;
28699
28604
  const args = CapabilityIssueArgsSchema.parse(rest);
@@ -28703,12 +28608,25 @@ function buildCapabilityHandlers(deps) {
28703
28608
  `Person not found: ${args.personId}`
28704
28609
  );
28705
28610
  }
28611
+ const existing = manager.findByPerson(args.personId);
28612
+ if (existing) {
28613
+ const updated = manager.addGrantsToPerson(args.personId, args.grants);
28614
+ if (!updated) {
28615
+ throw new ClawdError(ERROR_CODES.INTERNAL, "addGrantsToPerson returned null");
28616
+ }
28617
+ return {
28618
+ response: {
28619
+ type: "capability:issued",
28620
+ token: "__merged__",
28621
+ shareUrl: "",
28622
+ capability: stripSecretHash(updated)
28623
+ }
28624
+ };
28625
+ }
28706
28626
  const { personId, ...managerArgs } = args;
28707
28627
  const { token, capability } = manager.issue({
28708
28628
  ...managerArgs,
28709
- atomicAfterPersist: (cap) => {
28710
- aliasStore.set(cap.id, personId);
28711
- }
28629
+ personId
28712
28630
  });
28713
28631
  const base = getShareBaseUrl().replace(/\/$/, "");
28714
28632
  const shareUrl = `${base}/?token=${encodeURIComponent(token)}`;
@@ -28739,10 +28657,6 @@ function buildCapabilityHandlers(deps) {
28739
28657
  `capability not found: ${args.capabilityId}`
28740
28658
  );
28741
28659
  }
28742
- aliasStore.remove(args.capabilityId);
28743
- if (result.capability.linkedPrincipalId !== void 0) {
28744
- aliasStore.remove(result.capability.linkedPrincipalId);
28745
- }
28746
28660
  return {
28747
28661
  response: {
28748
28662
  type: "capability:deleted",
@@ -28768,7 +28682,7 @@ function assertChannelAccess(ctx, capabilityId) {
28768
28682
  );
28769
28683
  }
28770
28684
  function buildInboxHandlers(deps) {
28771
- const { manager, personStore, aliasStore } = deps;
28685
+ const { manager, personStore, capabilityManager } = deps;
28772
28686
  const postMessage = async (frame, _client, ctx) => {
28773
28687
  const { type: _t, requestId: _r, ...rest } = frame;
28774
28688
  const args = InboxPostMessageArgsSchema.parse(rest);
@@ -28776,11 +28690,10 @@ function buildInboxHandlers(deps) {
28776
28690
  throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:postMessage: missing ConnectionContext");
28777
28691
  }
28778
28692
  assertChannelAccess(ctx, args.capabilityId);
28779
- if (ctx.principal.kind === "guest") {
28780
- const senderPrincipalId = ctx.principal.id;
28781
- const personId = aliasStore.get(senderPrincipalId);
28782
- if (personId !== void 0) {
28783
- const person = personStore.get(personId);
28693
+ if (ctx.principal.kind === "guest" && ctx.capabilityId) {
28694
+ const cap = capabilityManager.findById(ctx.capabilityId);
28695
+ if (cap) {
28696
+ const person = personStore.get(cap.personId);
28784
28697
  if (person && !person.dmEnabled) {
28785
28698
  throw new ClawdError(
28786
28699
  ERROR_CODES.VALIDATION_ERROR,
@@ -28841,7 +28754,7 @@ function buildInboxHandlers(deps) {
28841
28754
  // src/handlers/remote-persona.ts
28842
28755
  init_protocol();
28843
28756
  function buildRemotePersonaHandlers(deps) {
28844
- const { store, personStore, aliasStore } = deps;
28757
+ const { store, personStore } = deps;
28845
28758
  const now = deps.now ?? Date.now;
28846
28759
  const add = async (frame) => {
28847
28760
  const { type: _t, requestId: _r, ...rest } = frame;
@@ -28852,9 +28765,8 @@ function buildRemotePersonaHandlers(deps) {
28852
28765
  `Person not found: ${args.personId}`
28853
28766
  );
28854
28767
  }
28855
- const { personId, ...persistFields } = args;
28856
28768
  const rp = {
28857
- ...persistFields,
28769
+ ...args,
28858
28770
  addedAt: now()
28859
28771
  };
28860
28772
  try {
@@ -28868,15 +28780,6 @@ function buildRemotePersonaHandlers(deps) {
28868
28780
  }
28869
28781
  throw err;
28870
28782
  }
28871
- try {
28872
- aliasStore.set(rp.ownerPrincipalId, personId);
28873
- } catch (err) {
28874
- try {
28875
- store.remove(rp.alias);
28876
- } catch {
28877
- }
28878
- throw err;
28879
- }
28880
28783
  return {
28881
28784
  response: { type: "remote-persona:add:ok", remotePersona: stripRemotePersonaSecret(rp) }
28882
28785
  };
@@ -28894,11 +28797,7 @@ function buildRemotePersonaHandlers(deps) {
28894
28797
  const remove = async (frame) => {
28895
28798
  const { type: _t, requestId: _r, ...rest } = frame;
28896
28799
  const args = RemotePersonaRemoveArgsSchema.parse(rest);
28897
- const existing = store.get(args.alias);
28898
28800
  const removed = store.remove(args.alias);
28899
- if (existing) {
28900
- aliasStore.remove(existing.ownerPrincipalId);
28901
- }
28902
28801
  return {
28903
28802
  response: { type: "remote-persona:remove:ok", alias: args.alias, removed }
28904
28803
  };
@@ -28925,7 +28824,9 @@ function buildWhoamiHandler(deps) {
28925
28824
  displayName: deps.ownerDisplayName,
28926
28825
  grants: ctx.grants,
28927
28826
  issuedAt: 0,
28928
- usedCount: 0
28827
+ usedCount: 0,
28828
+ // owner self cap 没有真实 Person 主人;用 ownerPrincipalId 自指,UI 不会反查这条
28829
+ personId: deps.ownerPrincipalId
28929
28830
  };
28930
28831
  } else {
28931
28832
  if (!ctx.capabilityId) {
@@ -29088,12 +28989,8 @@ var EMPTY_RESULT = {
29088
28989
  };
29089
28990
  function cascadeDeletePerson(personId, deps) {
29090
28991
  if (!deps.personStore.get(personId)) return { ...EMPTY_RESULT };
29091
- const principalIds = deps.aliasStore.list().filter((a) => a.personId === personId).map((a) => a.principalId);
29092
- const principalSet = new Set(principalIds);
29093
28992
  const allCaps = deps.capabilityManager.list();
29094
- const capsToDelete = allCaps.filter(
29095
- (c) => principalSet.has(c.id) || c.linkedPrincipalId !== void 0 && principalSet.has(c.linkedPrincipalId)
29096
- );
28993
+ const capsToDelete = allCaps.filter((c) => c.personId === personId);
29097
28994
  let deletedInboxEvents = 0;
29098
28995
  for (const c of capsToDelete) {
29099
28996
  deletedInboxEvents += deps.inboxStore.list(c.id).length;
@@ -29105,14 +29002,13 @@ function cascadeDeletePerson(personId, deps) {
29105
29002
  }
29106
29003
  }
29107
29004
  const allRemotes = deps.remotePersonaStore.list();
29108
- const remotesToRemove = allRemotes.filter((r) => principalSet.has(r.ownerPrincipalId));
29005
+ const remotesToRemove = allRemotes.filter((r) => r.personId === personId);
29109
29006
  const removedRemoteAliases = [];
29110
29007
  for (const r of remotesToRemove) {
29111
29008
  if (deps.remotePersonaStore.remove(r.alias)) {
29112
29009
  removedRemoteAliases.push(r.alias);
29113
29010
  }
29114
29011
  }
29115
- deps.aliasStore.removeAllByPerson(personId);
29116
29012
  deps.personStore.remove(personId);
29117
29013
  return { deletedCapabilityIds, removedRemoteAliases, deletedInboxEvents };
29118
29014
  }
@@ -29123,22 +29019,13 @@ function buildPersonHandlers(deps) {
29123
29019
  const genId = deps.genId ?? defaultGenId2;
29124
29020
  const list = async () => {
29125
29021
  const persons = deps.personStore.list();
29126
- const aliases = deps.aliasStore.list();
29127
- const personIdByPrincipal = new Map(aliases.map((a) => [a.principalId, a.personId]));
29128
29022
  const allCaps = deps.capabilityManager.list();
29129
29023
  const allRemotes = deps.remotePersonaStore.list();
29130
- const out = persons.map((p2) => {
29131
- const linkedCapabilityIds = [];
29132
- for (const c of allCaps) {
29133
- const key = c.linkedPrincipalId ?? c.id;
29134
- if (personIdByPrincipal.get(key) === p2.id) linkedCapabilityIds.push(c.id);
29135
- }
29136
- const linkedRemoteAliases = [];
29137
- for (const r of allRemotes) {
29138
- if (personIdByPrincipal.get(r.ownerPrincipalId) === p2.id) linkedRemoteAliases.push(r.alias);
29139
- }
29140
- return { ...p2, linkedCapabilityIds, linkedRemoteAliases };
29141
- });
29024
+ const out = persons.map((p2) => ({
29025
+ ...p2,
29026
+ linkedCapabilityIds: allCaps.filter((c) => c.personId === p2.id).map((c) => c.id),
29027
+ linkedRemoteAliases: allRemotes.filter((r) => r.personId === p2.id).map((r) => r.alias)
29028
+ }));
29142
29029
  return { response: { type: "person:list:ok", persons: out } };
29143
29030
  };
29144
29031
  const create = async (frame) => {
@@ -29192,21 +29079,11 @@ function buildPersonHandlers(deps) {
29192
29079
  }
29193
29080
  };
29194
29081
  };
29195
- const link = async (frame) => {
29196
- const { type: _t, requestId: _r, ...rest } = frame;
29197
- const args = PersonLinkArgsSchema.parse(rest);
29198
- if (!deps.personStore.get(args.personId)) {
29199
- throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `Person not found: ${args.personId}`);
29200
- }
29201
- deps.aliasStore.set(args.principalId, args.personId);
29202
- return { response: { type: "person:link:ok" } };
29203
- };
29204
29082
  return {
29205
29083
  "person:list": list,
29206
29084
  "person:create": create,
29207
29085
  "person:update": update,
29208
- "person:delete": del,
29209
- "person:link": link
29086
+ "person:delete": del
29210
29087
  };
29211
29088
  }
29212
29089
  function defaultGenId2() {
@@ -29331,27 +29208,21 @@ function buildMethodHandlers(deps) {
29331
29208
  ...buildCapabilityHandlers({
29332
29209
  manager: deps.capabilityManager,
29333
29210
  getShareBaseUrl: deps.getShareBaseUrl,
29334
- personStore: deps.personStore,
29335
- aliasStore: deps.personAliasStore
29211
+ personStore: deps.personStore
29336
29212
  }),
29337
29213
  ...buildInboxHandlers({
29338
29214
  manager: deps.inboxManager,
29339
29215
  personStore: deps.personStore,
29340
- aliasStore: deps.personAliasStore
29216
+ capabilityManager: deps.capabilityManager
29341
29217
  }),
29342
29218
  ...buildRemotePersonaHandlers({
29343
29219
  store: deps.remotePersonaStore,
29344
- personStore: deps.personStore,
29345
- aliasStore: deps.personAliasStore
29220
+ personStore: deps.personStore
29346
29221
  }),
29347
29222
  ...buildPersonHandlers({
29348
29223
  personStore: deps.personStore,
29349
- aliasStore: deps.personAliasStore,
29350
29224
  capabilityManager: deps.capabilityManager,
29351
29225
  remotePersonaStore: deps.remotePersonaStore,
29352
- // inbox channel cascade: person:delete 时用 inboxStore.list 统计每个 cap channel
29353
- // 消息数 sum 起来作为 deletedInboxEvents 返回 (实际删除走 capability:delete
29354
- // onDeleted hook → inboxManager.removeChannel, cascade 不主动 rm 文件).
29355
29226
  inboxStore: deps.inboxStore
29356
29227
  }),
29357
29228
  whoami: buildWhoamiHandler({
@@ -29398,7 +29269,6 @@ var METHOD_GRANT_MAP = {
29398
29269
  "person:create": ADMIN_ANY,
29399
29270
  "person:update": ADMIN_ANY,
29400
29271
  "person:delete": ADMIN_ANY,
29401
- "person:link": ADMIN_ANY,
29402
29272
  // ---- session:* / chat:* 业务方法(v2 Phase 8 两层模型)----
29403
29273
  // dispatcher 不验资源,handler 内按 ctx + frame.args 反查 ownerPersonaId 调 assertGrant。
29404
29274
  // owner 自动通过(ctx 自带 '*':'admin' grant 一切 match);guest 在被授权 persona 内可调。
@@ -29526,43 +29396,19 @@ async function startDaemon(config) {
29526
29396
  });
29527
29397
  const remotePersonaStore = new RemotePersonaStore(config.dataDir);
29528
29398
  const personStore = new PersonStore(config.dataDir);
29529
- const personAliasStore = new PersonAliasStore(config.dataDir);
29530
29399
  let wsServer = null;
29531
29400
  const authGate = authMode === "first-message" ? new AuthGate({
29532
29401
  shouldEnforce: buildShouldEnforce({ tunnel: config.tunnel }),
29533
29402
  // Task 1.7:authenticate 注入路径替代 expectedToken 单 token 比对。
29534
29403
  // owner 路径 constantTimeEqual 防侧信道;guest 路径走 capabilityRegistry.
29535
29404
  expectedToken: resolvedAuthToken,
29536
- authenticate: (t, selfPrincipalId) => {
29537
- const r = authenticate(t, {
29405
+ authenticate: (t, _selfPrincipalId) => {
29406
+ return authenticate(t, {
29538
29407
  isOwnerToken: (x) => resolvedAuthToken != null && constantTimeEqual(x, resolvedAuthToken),
29539
29408
  ownerPrincipalId,
29540
29409
  ownerDisplayName,
29541
29410
  capabilityRegistry
29542
29411
  });
29543
- if (r.ok && selfPrincipalId && r.context.principal.kind === "guest" && r.context.capabilityId) {
29544
- const capId = r.context.capabilityId;
29545
- const cap = capabilityManager.findById(capId);
29546
- if (cap && cap.linkedPrincipalId === void 0) {
29547
- capabilityManager.updateLinkedPrincipalId(capId, selfPrincipalId);
29548
- try {
29549
- personAliasStore.rekey(capId, selfPrincipalId);
29550
- } catch (e) {
29551
- logger.warn("auth.alias.rekey.failed", {
29552
- capId,
29553
- selfPrincipalId,
29554
- err: e.message
29555
- });
29556
- }
29557
- } else if (cap && cap.linkedPrincipalId !== selfPrincipalId) {
29558
- logger.warn("auth.selfPrincipalId.mismatch", {
29559
- capId,
29560
- expected: cap.linkedPrincipalId,
29561
- got: selfPrincipalId
29562
- });
29563
- }
29564
- }
29565
- return r;
29566
29412
  },
29567
29413
  onAuthed: (h, ctx) => wsServer?.attachClientContext(h.id, ctx),
29568
29414
  buildOwnerContext: () => ownerContext(ownerPrincipalId, ownerDisplayName),
@@ -29759,10 +29605,9 @@ async function startDaemon(config) {
29759
29605
  inboxStore,
29760
29606
  // Phase 4 Task 4.3: remote-persona:* handler 依赖 (本地存储, v1 不接 outgoing WS)
29761
29607
  remotePersonaStore,
29762
- // Person identity Phase 1 (B13): person:* RPC handlers + capability:issue /
29763
- // remote-persona:add atomic 写 alias / cascade 删 Person 用
29764
- personStore,
29765
- personAliasStore
29608
+ // Per-People token (2026-05-21): person:* RPC handlers + cap/remote 自带
29609
+ // personId 字段(PersonAlias 表已删)
29610
+ personStore
29766
29611
  });
29767
29612
  const authResolver = new AuthContextResolver({
29768
29613
  ownerToken: resolvedAuthToken