@clawos-dev/clawd 0.2.71-beta.124.b09b0a0 → 0.2.71-beta.126.06f4cfa
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +631 -126
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -121,6 +121,18 @@ var init_methods = __esm({
|
|
|
121
121
|
"capability:issue",
|
|
122
122
|
"capability:list",
|
|
123
123
|
"capability:revoke",
|
|
124
|
+
// ---- inbox:* (capability platform Phase 3 跨用户通知 + Phase 4 DM) ----
|
|
125
|
+
// owner 接 guest 的 cross-principal 消息事件 + DM 双向私聊.
|
|
126
|
+
// inbox:list / markRead: admin-only (Phase 3); inbox:postMessage: DM 自带能力,
|
|
127
|
+
// 任何 principal (owner/guest) 可调 (Phase 4).
|
|
128
|
+
"inbox:list",
|
|
129
|
+
"inbox:markRead",
|
|
130
|
+
"inbox:postMessage",
|
|
131
|
+
// ---- remote-persona:* (Phase 4 远程 persona, v1 仅本地存储, 不接 outgoing WS) ----
|
|
132
|
+
// owner 添加 / 列出 / 删除远程 persona 入口. admin-only.
|
|
133
|
+
"remote-persona:add",
|
|
134
|
+
"remote-persona:list",
|
|
135
|
+
"remote-persona:remove",
|
|
124
136
|
"info",
|
|
125
137
|
"ping"
|
|
126
138
|
];
|
|
@@ -612,8 +624,8 @@ var init_parseUtil = __esm({
|
|
|
612
624
|
init_errors2();
|
|
613
625
|
init_en();
|
|
614
626
|
makeIssue = (params) => {
|
|
615
|
-
const { data, path:
|
|
616
|
-
const fullPath = [...
|
|
627
|
+
const { data, path: path37, errorMaps, issueData } = params;
|
|
628
|
+
const fullPath = [...path37, ...issueData.path || []];
|
|
617
629
|
const fullIssue = {
|
|
618
630
|
...issueData,
|
|
619
631
|
path: fullPath
|
|
@@ -924,11 +936,11 @@ var init_types = __esm({
|
|
|
924
936
|
init_parseUtil();
|
|
925
937
|
init_util();
|
|
926
938
|
ParseInputLazyPath = class {
|
|
927
|
-
constructor(parent, value,
|
|
939
|
+
constructor(parent, value, path37, key) {
|
|
928
940
|
this._cachedPath = [];
|
|
929
941
|
this.parent = parent;
|
|
930
942
|
this.data = value;
|
|
931
|
-
this._path =
|
|
943
|
+
this._path = path37;
|
|
932
944
|
this._key = key;
|
|
933
945
|
}
|
|
934
946
|
get path() {
|
|
@@ -5112,6 +5124,79 @@ var init_capability = __esm({
|
|
|
5112
5124
|
}
|
|
5113
5125
|
});
|
|
5114
5126
|
|
|
5127
|
+
// ../protocol/src/inbox.ts
|
|
5128
|
+
var INBOX_EVENT_KIND_VALUES, InboxEventKindSchema, INBOX_PREVIEW_MAX_LENGTH, InboxEventSchema, InboxListArgsSchema, InboxMarkReadArgsSchema, InboxPostMessageArgsSchema;
|
|
5129
|
+
var init_inbox = __esm({
|
|
5130
|
+
"../protocol/src/inbox.ts"() {
|
|
5131
|
+
"use strict";
|
|
5132
|
+
init_zod();
|
|
5133
|
+
init_principal();
|
|
5134
|
+
init_capability();
|
|
5135
|
+
INBOX_EVENT_KIND_VALUES = ["persona-mention", "direct-message"];
|
|
5136
|
+
InboxEventKindSchema = external_exports.enum(INBOX_EVENT_KIND_VALUES);
|
|
5137
|
+
INBOX_PREVIEW_MAX_LENGTH = 140;
|
|
5138
|
+
InboxEventSchema = external_exports.object({
|
|
5139
|
+
id: external_exports.string().min(1),
|
|
5140
|
+
kind: InboxEventKindSchema,
|
|
5141
|
+
fromPrincipal: PrincipalSchema,
|
|
5142
|
+
toPrincipal: PrincipalSchema,
|
|
5143
|
+
// persona-mention 才有, direct-message 不带
|
|
5144
|
+
resource: ResourceSchema.optional(),
|
|
5145
|
+
preview: external_exports.string().max(INBOX_PREVIEW_MAX_LENGTH),
|
|
5146
|
+
createdAt: external_exports.number().int().nonnegative(),
|
|
5147
|
+
readAt: external_exports.number().int().positive().optional(),
|
|
5148
|
+
// direct-message 才有, sha256 hex 64; 派生规则: sha256(min(A,B) + '/' + max(A,B))
|
|
5149
|
+
threadId: external_exports.string().regex(/^[a-f0-9]{64}$/).optional()
|
|
5150
|
+
}).strict();
|
|
5151
|
+
InboxListArgsSchema = external_exports.object({
|
|
5152
|
+
// false / 缺省 = 只返回未读; true = 含已读 (历史回溯用)
|
|
5153
|
+
includeRead: external_exports.boolean().optional()
|
|
5154
|
+
}).strict();
|
|
5155
|
+
InboxMarkReadArgsSchema = external_exports.object({
|
|
5156
|
+
eventId: external_exports.string().min(1)
|
|
5157
|
+
}).strict();
|
|
5158
|
+
InboxPostMessageArgsSchema = external_exports.object({
|
|
5159
|
+
peerPrincipalId: external_exports.string().min(1),
|
|
5160
|
+
text: external_exports.string().min(1).max(INBOX_PREVIEW_MAX_LENGTH)
|
|
5161
|
+
}).strict();
|
|
5162
|
+
}
|
|
5163
|
+
});
|
|
5164
|
+
|
|
5165
|
+
// ../protocol/src/remote-persona.ts
|
|
5166
|
+
function stripRemotePersonaSecret(rp) {
|
|
5167
|
+
const { capabilityToken: _t, ...wire } = rp;
|
|
5168
|
+
return wire;
|
|
5169
|
+
}
|
|
5170
|
+
var RemotePersonaSchema, RemotePersonaWireSchema, RemotePersonaAddArgsSchema, RemotePersonaRemoveArgsSchema;
|
|
5171
|
+
var init_remote_persona = __esm({
|
|
5172
|
+
"../protocol/src/remote-persona.ts"() {
|
|
5173
|
+
"use strict";
|
|
5174
|
+
init_zod();
|
|
5175
|
+
RemotePersonaSchema = external_exports.object({
|
|
5176
|
+
alias: external_exports.string().min(1),
|
|
5177
|
+
remoteUrl: external_exports.string().min(1),
|
|
5178
|
+
capabilityToken: external_exports.string().min(1),
|
|
5179
|
+
remotePersonaId: external_exports.string().min(1),
|
|
5180
|
+
remoteDisplayName: external_exports.string(),
|
|
5181
|
+
ownerDisplayName: external_exports.string().optional(),
|
|
5182
|
+
addedAt: external_exports.number().int().nonnegative(),
|
|
5183
|
+
lastConnectedAt: external_exports.number().int().positive().optional()
|
|
5184
|
+
}).strict();
|
|
5185
|
+
RemotePersonaWireSchema = RemotePersonaSchema.omit({ capabilityToken: true });
|
|
5186
|
+
RemotePersonaAddArgsSchema = external_exports.object({
|
|
5187
|
+
alias: external_exports.string().min(1),
|
|
5188
|
+
remoteUrl: external_exports.string().min(1),
|
|
5189
|
+
capabilityToken: external_exports.string().min(1),
|
|
5190
|
+
remotePersonaId: external_exports.string().min(1),
|
|
5191
|
+
remoteDisplayName: external_exports.string(),
|
|
5192
|
+
ownerDisplayName: external_exports.string().optional()
|
|
5193
|
+
}).strict();
|
|
5194
|
+
RemotePersonaRemoveArgsSchema = external_exports.object({
|
|
5195
|
+
alias: external_exports.string().min(1)
|
|
5196
|
+
}).strict();
|
|
5197
|
+
}
|
|
5198
|
+
});
|
|
5199
|
+
|
|
5115
5200
|
// ../protocol/src/runtime.ts
|
|
5116
5201
|
var init_runtime = __esm({
|
|
5117
5202
|
"../protocol/src/runtime.ts"() {
|
|
@@ -5126,6 +5211,8 @@ var init_runtime = __esm({
|
|
|
5126
5211
|
init_attachment_schemas();
|
|
5127
5212
|
init_principal();
|
|
5128
5213
|
init_capability();
|
|
5214
|
+
init_inbox();
|
|
5215
|
+
init_remote_persona();
|
|
5129
5216
|
}
|
|
5130
5217
|
});
|
|
5131
5218
|
|
|
@@ -5400,8 +5487,8 @@ var require_req = __commonJS({
|
|
|
5400
5487
|
if (req.originalUrl) {
|
|
5401
5488
|
_req.url = req.originalUrl;
|
|
5402
5489
|
} else {
|
|
5403
|
-
const
|
|
5404
|
-
_req.url = typeof
|
|
5490
|
+
const path37 = req.path;
|
|
5491
|
+
_req.url = typeof path37 === "string" ? path37 : req.url ? req.url.path || req.url : void 0;
|
|
5405
5492
|
}
|
|
5406
5493
|
if (req.query) {
|
|
5407
5494
|
_req.query = req.query;
|
|
@@ -5566,14 +5653,14 @@ var require_redact = __commonJS({
|
|
|
5566
5653
|
}
|
|
5567
5654
|
return obj;
|
|
5568
5655
|
}
|
|
5569
|
-
function parsePath(
|
|
5656
|
+
function parsePath(path37) {
|
|
5570
5657
|
const parts = [];
|
|
5571
5658
|
let current = "";
|
|
5572
5659
|
let inBrackets = false;
|
|
5573
5660
|
let inQuotes = false;
|
|
5574
5661
|
let quoteChar = "";
|
|
5575
|
-
for (let i = 0; i <
|
|
5576
|
-
const char =
|
|
5662
|
+
for (let i = 0; i < path37.length; i++) {
|
|
5663
|
+
const char = path37[i];
|
|
5577
5664
|
if (!inBrackets && char === ".") {
|
|
5578
5665
|
if (current) {
|
|
5579
5666
|
parts.push(current);
|
|
@@ -5704,10 +5791,10 @@ var require_redact = __commonJS({
|
|
|
5704
5791
|
return current;
|
|
5705
5792
|
}
|
|
5706
5793
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
5707
|
-
for (const
|
|
5708
|
-
const parts = parsePath(
|
|
5794
|
+
for (const path37 of paths) {
|
|
5795
|
+
const parts = parsePath(path37);
|
|
5709
5796
|
if (parts.includes("*")) {
|
|
5710
|
-
redactWildcardPath(obj, parts, censor,
|
|
5797
|
+
redactWildcardPath(obj, parts, censor, path37, remove);
|
|
5711
5798
|
} else {
|
|
5712
5799
|
if (remove) {
|
|
5713
5800
|
removeKey(obj, parts);
|
|
@@ -5792,8 +5879,8 @@ var require_redact = __commonJS({
|
|
|
5792
5879
|
}
|
|
5793
5880
|
} else {
|
|
5794
5881
|
if (afterWildcard.includes("*")) {
|
|
5795
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
5796
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
5882
|
+
const wrappedCensor = typeof censor === "function" ? (value, path37) => {
|
|
5883
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path37];
|
|
5797
5884
|
return censor(value, fullPath);
|
|
5798
5885
|
} : censor;
|
|
5799
5886
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -5828,8 +5915,8 @@ var require_redact = __commonJS({
|
|
|
5828
5915
|
return null;
|
|
5829
5916
|
}
|
|
5830
5917
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
5831
|
-
for (const
|
|
5832
|
-
const parts = parsePath(
|
|
5918
|
+
for (const path37 of pathsToClone) {
|
|
5919
|
+
const parts = parsePath(path37);
|
|
5833
5920
|
let current = pathStructure;
|
|
5834
5921
|
for (let i = 0; i < parts.length; i++) {
|
|
5835
5922
|
const part = parts[i];
|
|
@@ -5881,24 +5968,24 @@ var require_redact = __commonJS({
|
|
|
5881
5968
|
}
|
|
5882
5969
|
return cloneSelectively(obj, pathStructure);
|
|
5883
5970
|
}
|
|
5884
|
-
function validatePath(
|
|
5885
|
-
if (typeof
|
|
5971
|
+
function validatePath(path37) {
|
|
5972
|
+
if (typeof path37 !== "string") {
|
|
5886
5973
|
throw new Error("Paths must be (non-empty) strings");
|
|
5887
5974
|
}
|
|
5888
|
-
if (
|
|
5975
|
+
if (path37 === "") {
|
|
5889
5976
|
throw new Error("Invalid redaction path ()");
|
|
5890
5977
|
}
|
|
5891
|
-
if (
|
|
5892
|
-
throw new Error(`Invalid redaction path (${
|
|
5978
|
+
if (path37.includes("..")) {
|
|
5979
|
+
throw new Error(`Invalid redaction path (${path37})`);
|
|
5893
5980
|
}
|
|
5894
|
-
if (
|
|
5895
|
-
throw new Error(`Invalid redaction path (${
|
|
5981
|
+
if (path37.includes(",")) {
|
|
5982
|
+
throw new Error(`Invalid redaction path (${path37})`);
|
|
5896
5983
|
}
|
|
5897
5984
|
let bracketCount = 0;
|
|
5898
5985
|
let inQuotes = false;
|
|
5899
5986
|
let quoteChar = "";
|
|
5900
|
-
for (let i = 0; i <
|
|
5901
|
-
const char =
|
|
5987
|
+
for (let i = 0; i < path37.length; i++) {
|
|
5988
|
+
const char = path37[i];
|
|
5902
5989
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
5903
5990
|
if (!inQuotes) {
|
|
5904
5991
|
inQuotes = true;
|
|
@@ -5912,20 +5999,20 @@ var require_redact = __commonJS({
|
|
|
5912
5999
|
} else if (char === "]" && !inQuotes) {
|
|
5913
6000
|
bracketCount--;
|
|
5914
6001
|
if (bracketCount < 0) {
|
|
5915
|
-
throw new Error(`Invalid redaction path (${
|
|
6002
|
+
throw new Error(`Invalid redaction path (${path37})`);
|
|
5916
6003
|
}
|
|
5917
6004
|
}
|
|
5918
6005
|
}
|
|
5919
6006
|
if (bracketCount !== 0) {
|
|
5920
|
-
throw new Error(`Invalid redaction path (${
|
|
6007
|
+
throw new Error(`Invalid redaction path (${path37})`);
|
|
5921
6008
|
}
|
|
5922
6009
|
}
|
|
5923
6010
|
function validatePaths(paths) {
|
|
5924
6011
|
if (!Array.isArray(paths)) {
|
|
5925
6012
|
throw new TypeError("paths must be an array");
|
|
5926
6013
|
}
|
|
5927
|
-
for (const
|
|
5928
|
-
validatePath(
|
|
6014
|
+
for (const path37 of paths) {
|
|
6015
|
+
validatePath(path37);
|
|
5929
6016
|
}
|
|
5930
6017
|
}
|
|
5931
6018
|
function slowRedact(options = {}) {
|
|
@@ -6093,8 +6180,8 @@ var require_redaction = __commonJS({
|
|
|
6093
6180
|
if (shape[k2] === null) {
|
|
6094
6181
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
6095
6182
|
} else {
|
|
6096
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6097
|
-
return censor(value, [k2, ...
|
|
6183
|
+
const wrappedCensor = typeof censor === "function" ? (value, path37) => {
|
|
6184
|
+
return censor(value, [k2, ...path37]);
|
|
6098
6185
|
} : censor;
|
|
6099
6186
|
o[k2] = Redact({
|
|
6100
6187
|
paths: shape[k2],
|
|
@@ -6312,10 +6399,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
6312
6399
|
var require_sonic_boom = __commonJS({
|
|
6313
6400
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
6314
6401
|
"use strict";
|
|
6315
|
-
var
|
|
6402
|
+
var fs33 = require("fs");
|
|
6316
6403
|
var EventEmitter2 = require("events");
|
|
6317
6404
|
var inherits = require("util").inherits;
|
|
6318
|
-
var
|
|
6405
|
+
var path37 = require("path");
|
|
6319
6406
|
var sleep = require_atomic_sleep();
|
|
6320
6407
|
var assert = require("assert");
|
|
6321
6408
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -6369,20 +6456,20 @@ var require_sonic_boom = __commonJS({
|
|
|
6369
6456
|
const mode = sonic.mode;
|
|
6370
6457
|
if (sonic.sync) {
|
|
6371
6458
|
try {
|
|
6372
|
-
if (sonic.mkdir)
|
|
6373
|
-
const fd =
|
|
6459
|
+
if (sonic.mkdir) fs33.mkdirSync(path37.dirname(file), { recursive: true });
|
|
6460
|
+
const fd = fs33.openSync(file, flags, mode);
|
|
6374
6461
|
fileOpened(null, fd);
|
|
6375
6462
|
} catch (err) {
|
|
6376
6463
|
fileOpened(err);
|
|
6377
6464
|
throw err;
|
|
6378
6465
|
}
|
|
6379
6466
|
} else if (sonic.mkdir) {
|
|
6380
|
-
|
|
6467
|
+
fs33.mkdir(path37.dirname(file), { recursive: true }, (err) => {
|
|
6381
6468
|
if (err) return fileOpened(err);
|
|
6382
|
-
|
|
6469
|
+
fs33.open(file, flags, mode, fileOpened);
|
|
6383
6470
|
});
|
|
6384
6471
|
} else {
|
|
6385
|
-
|
|
6472
|
+
fs33.open(file, flags, mode, fileOpened);
|
|
6386
6473
|
}
|
|
6387
6474
|
}
|
|
6388
6475
|
function SonicBoom(opts) {
|
|
@@ -6423,8 +6510,8 @@ var require_sonic_boom = __commonJS({
|
|
|
6423
6510
|
this.flush = flushBuffer;
|
|
6424
6511
|
this.flushSync = flushBufferSync;
|
|
6425
6512
|
this._actualWrite = actualWriteBuffer;
|
|
6426
|
-
fsWriteSync = () =>
|
|
6427
|
-
fsWrite = () =>
|
|
6513
|
+
fsWriteSync = () => fs33.writeSync(this.fd, this._writingBuf);
|
|
6514
|
+
fsWrite = () => fs33.write(this.fd, this._writingBuf, this.release);
|
|
6428
6515
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
6429
6516
|
this._writingBuf = "";
|
|
6430
6517
|
this.write = write;
|
|
@@ -6433,15 +6520,15 @@ var require_sonic_boom = __commonJS({
|
|
|
6433
6520
|
this._actualWrite = actualWrite;
|
|
6434
6521
|
fsWriteSync = () => {
|
|
6435
6522
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
6436
|
-
return
|
|
6523
|
+
return fs33.writeSync(this.fd, this._writingBuf);
|
|
6437
6524
|
}
|
|
6438
|
-
return
|
|
6525
|
+
return fs33.writeSync(this.fd, this._writingBuf, "utf8");
|
|
6439
6526
|
};
|
|
6440
6527
|
fsWrite = () => {
|
|
6441
6528
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
6442
|
-
return
|
|
6529
|
+
return fs33.write(this.fd, this._writingBuf, this.release);
|
|
6443
6530
|
}
|
|
6444
|
-
return
|
|
6531
|
+
return fs33.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
6445
6532
|
};
|
|
6446
6533
|
} else {
|
|
6447
6534
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -6498,7 +6585,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6498
6585
|
}
|
|
6499
6586
|
}
|
|
6500
6587
|
if (this._fsync) {
|
|
6501
|
-
|
|
6588
|
+
fs33.fsyncSync(this.fd);
|
|
6502
6589
|
}
|
|
6503
6590
|
const len = this._len;
|
|
6504
6591
|
if (this._reopening) {
|
|
@@ -6612,7 +6699,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6612
6699
|
const onDrain = () => {
|
|
6613
6700
|
if (!this._fsync) {
|
|
6614
6701
|
try {
|
|
6615
|
-
|
|
6702
|
+
fs33.fsync(this.fd, (err) => {
|
|
6616
6703
|
this._flushPending = false;
|
|
6617
6704
|
cb(err);
|
|
6618
6705
|
});
|
|
@@ -6714,7 +6801,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6714
6801
|
const fd = this.fd;
|
|
6715
6802
|
this.once("ready", () => {
|
|
6716
6803
|
if (fd !== this.fd) {
|
|
6717
|
-
|
|
6804
|
+
fs33.close(fd, (err) => {
|
|
6718
6805
|
if (err) {
|
|
6719
6806
|
return this.emit("error", err);
|
|
6720
6807
|
}
|
|
@@ -6763,7 +6850,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6763
6850
|
buf = this._bufs[0];
|
|
6764
6851
|
}
|
|
6765
6852
|
try {
|
|
6766
|
-
const n = Buffer.isBuffer(buf) ?
|
|
6853
|
+
const n = Buffer.isBuffer(buf) ? fs33.writeSync(this.fd, buf) : fs33.writeSync(this.fd, buf, "utf8");
|
|
6767
6854
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
6768
6855
|
buf = releasedBufObj.writingBuf;
|
|
6769
6856
|
this._len = releasedBufObj.len;
|
|
@@ -6779,7 +6866,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6779
6866
|
}
|
|
6780
6867
|
}
|
|
6781
6868
|
try {
|
|
6782
|
-
|
|
6869
|
+
fs33.fsyncSync(this.fd);
|
|
6783
6870
|
} catch {
|
|
6784
6871
|
}
|
|
6785
6872
|
}
|
|
@@ -6800,7 +6887,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6800
6887
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
6801
6888
|
}
|
|
6802
6889
|
try {
|
|
6803
|
-
const n =
|
|
6890
|
+
const n = fs33.writeSync(this.fd, buf);
|
|
6804
6891
|
buf = buf.subarray(n);
|
|
6805
6892
|
this._len = Math.max(this._len - n, 0);
|
|
6806
6893
|
if (buf.length <= 0) {
|
|
@@ -6828,13 +6915,13 @@ var require_sonic_boom = __commonJS({
|
|
|
6828
6915
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
6829
6916
|
if (this.sync) {
|
|
6830
6917
|
try {
|
|
6831
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
6918
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs33.writeSync(this.fd, this._writingBuf) : fs33.writeSync(this.fd, this._writingBuf, "utf8");
|
|
6832
6919
|
release(null, written);
|
|
6833
6920
|
} catch (err) {
|
|
6834
6921
|
release(err);
|
|
6835
6922
|
}
|
|
6836
6923
|
} else {
|
|
6837
|
-
|
|
6924
|
+
fs33.write(this.fd, this._writingBuf, release);
|
|
6838
6925
|
}
|
|
6839
6926
|
}
|
|
6840
6927
|
function actualWriteBuffer() {
|
|
@@ -6843,7 +6930,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6843
6930
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
6844
6931
|
if (this.sync) {
|
|
6845
6932
|
try {
|
|
6846
|
-
const written =
|
|
6933
|
+
const written = fs33.writeSync(this.fd, this._writingBuf);
|
|
6847
6934
|
release(null, written);
|
|
6848
6935
|
} catch (err) {
|
|
6849
6936
|
release(err);
|
|
@@ -6852,7 +6939,7 @@ var require_sonic_boom = __commonJS({
|
|
|
6852
6939
|
if (kCopyBuffer) {
|
|
6853
6940
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
6854
6941
|
}
|
|
6855
|
-
|
|
6942
|
+
fs33.write(this.fd, this._writingBuf, release);
|
|
6856
6943
|
}
|
|
6857
6944
|
}
|
|
6858
6945
|
function actualClose(sonic) {
|
|
@@ -6868,12 +6955,12 @@ var require_sonic_boom = __commonJS({
|
|
|
6868
6955
|
sonic._lens = [];
|
|
6869
6956
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
6870
6957
|
try {
|
|
6871
|
-
|
|
6958
|
+
fs33.fsync(sonic.fd, closeWrapped);
|
|
6872
6959
|
} catch {
|
|
6873
6960
|
}
|
|
6874
6961
|
function closeWrapped() {
|
|
6875
6962
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
6876
|
-
|
|
6963
|
+
fs33.close(sonic.fd, done);
|
|
6877
6964
|
} else {
|
|
6878
6965
|
done();
|
|
6879
6966
|
}
|
|
@@ -7130,7 +7217,7 @@ var require_thread_stream = __commonJS({
|
|
|
7130
7217
|
var { version: version2 } = require_package();
|
|
7131
7218
|
var { EventEmitter: EventEmitter2 } = require("events");
|
|
7132
7219
|
var { Worker } = require("worker_threads");
|
|
7133
|
-
var { join:
|
|
7220
|
+
var { join: join10 } = require("path");
|
|
7134
7221
|
var { pathToFileURL } = require("url");
|
|
7135
7222
|
var { wait } = require_wait();
|
|
7136
7223
|
var {
|
|
@@ -7166,7 +7253,7 @@ var require_thread_stream = __commonJS({
|
|
|
7166
7253
|
function createWorker(stream, opts) {
|
|
7167
7254
|
const { filename, workerData } = opts;
|
|
7168
7255
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
7169
|
-
const toExecute = bundlerOverrides["thread-stream-worker"] ||
|
|
7256
|
+
const toExecute = bundlerOverrides["thread-stream-worker"] || join10(__dirname, "lib", "worker.js");
|
|
7170
7257
|
const worker = new Worker(toExecute, {
|
|
7171
7258
|
...opts.workerOpts,
|
|
7172
7259
|
trackUnmanagedFds: false,
|
|
@@ -7552,7 +7639,7 @@ var require_transport = __commonJS({
|
|
|
7552
7639
|
"use strict";
|
|
7553
7640
|
var { createRequire } = require("module");
|
|
7554
7641
|
var getCallers = require_caller();
|
|
7555
|
-
var { join:
|
|
7642
|
+
var { join: join10, isAbsolute, sep: sep2 } = require("path");
|
|
7556
7643
|
var sleep = require_atomic_sleep();
|
|
7557
7644
|
var onExit = require_on_exit_leak_free();
|
|
7558
7645
|
var ThreadStream = require_thread_stream();
|
|
@@ -7615,7 +7702,7 @@ var require_transport = __commonJS({
|
|
|
7615
7702
|
throw new Error("only one of target or targets can be specified");
|
|
7616
7703
|
}
|
|
7617
7704
|
if (targets) {
|
|
7618
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
7705
|
+
target = bundlerOverrides["pino-worker"] || join10(__dirname, "worker.js");
|
|
7619
7706
|
options.targets = targets.filter((dest) => dest.target).map((dest) => {
|
|
7620
7707
|
return {
|
|
7621
7708
|
...dest,
|
|
@@ -7633,7 +7720,7 @@ var require_transport = __commonJS({
|
|
|
7633
7720
|
});
|
|
7634
7721
|
});
|
|
7635
7722
|
} else if (pipeline2) {
|
|
7636
|
-
target = bundlerOverrides["pino-worker"] ||
|
|
7723
|
+
target = bundlerOverrides["pino-worker"] || join10(__dirname, "worker.js");
|
|
7637
7724
|
options.pipelines = [pipeline2.map((dest) => {
|
|
7638
7725
|
return {
|
|
7639
7726
|
...dest,
|
|
@@ -7655,7 +7742,7 @@ var require_transport = __commonJS({
|
|
|
7655
7742
|
return origin;
|
|
7656
7743
|
}
|
|
7657
7744
|
if (origin === "pino/file") {
|
|
7658
|
-
return
|
|
7745
|
+
return join10(__dirname, "..", "file.js");
|
|
7659
7746
|
}
|
|
7660
7747
|
let fixTarget2;
|
|
7661
7748
|
for (const filePath of callers) {
|
|
@@ -8645,7 +8732,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
8645
8732
|
return circularValue;
|
|
8646
8733
|
}
|
|
8647
8734
|
let res = "";
|
|
8648
|
-
let
|
|
8735
|
+
let join10 = ",";
|
|
8649
8736
|
const originalIndentation = indentation;
|
|
8650
8737
|
if (Array.isArray(value)) {
|
|
8651
8738
|
if (value.length === 0) {
|
|
@@ -8659,7 +8746,7 @@ var require_safe_stable_stringify = __commonJS({
|
|
|
8659
8746
|
indentation += spacer;
|
|
8660
8747
|
res += `
|
|
8661
8748
|
${indentation}`;
|
|
8662
|
-
|
|
8749
|
+
join10 = `,
|
|
8663
8750
|
${indentation}`;
|
|
8664
8751
|
}
|
|
8665
8752
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -8667,13 +8754,13 @@ ${indentation}`;
|
|
|
8667
8754
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8668
8755
|
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
8669
8756
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
8670
|
-
res +=
|
|
8757
|
+
res += join10;
|
|
8671
8758
|
}
|
|
8672
8759
|
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
8673
8760
|
res += tmp !== void 0 ? tmp : "null";
|
|
8674
8761
|
if (value.length - 1 > maximumBreadth) {
|
|
8675
8762
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8676
|
-
res += `${
|
|
8763
|
+
res += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8677
8764
|
}
|
|
8678
8765
|
if (spacer !== "") {
|
|
8679
8766
|
res += `
|
|
@@ -8694,7 +8781,7 @@ ${originalIndentation}`;
|
|
|
8694
8781
|
let separator = "";
|
|
8695
8782
|
if (spacer !== "") {
|
|
8696
8783
|
indentation += spacer;
|
|
8697
|
-
|
|
8784
|
+
join10 = `,
|
|
8698
8785
|
${indentation}`;
|
|
8699
8786
|
whitespace = " ";
|
|
8700
8787
|
}
|
|
@@ -8708,13 +8795,13 @@ ${indentation}`;
|
|
|
8708
8795
|
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
8709
8796
|
if (tmp !== void 0) {
|
|
8710
8797
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
8711
|
-
separator =
|
|
8798
|
+
separator = join10;
|
|
8712
8799
|
}
|
|
8713
8800
|
}
|
|
8714
8801
|
if (keyLength > maximumBreadth) {
|
|
8715
8802
|
const removedKeys = keyLength - maximumBreadth;
|
|
8716
8803
|
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
8717
|
-
separator =
|
|
8804
|
+
separator = join10;
|
|
8718
8805
|
}
|
|
8719
8806
|
if (spacer !== "" && separator.length > 1) {
|
|
8720
8807
|
res = `
|
|
@@ -8755,7 +8842,7 @@ ${originalIndentation}`;
|
|
|
8755
8842
|
}
|
|
8756
8843
|
const originalIndentation = indentation;
|
|
8757
8844
|
let res = "";
|
|
8758
|
-
let
|
|
8845
|
+
let join10 = ",";
|
|
8759
8846
|
if (Array.isArray(value)) {
|
|
8760
8847
|
if (value.length === 0) {
|
|
8761
8848
|
return "[]";
|
|
@@ -8768,7 +8855,7 @@ ${originalIndentation}`;
|
|
|
8768
8855
|
indentation += spacer;
|
|
8769
8856
|
res += `
|
|
8770
8857
|
${indentation}`;
|
|
8771
|
-
|
|
8858
|
+
join10 = `,
|
|
8772
8859
|
${indentation}`;
|
|
8773
8860
|
}
|
|
8774
8861
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
@@ -8776,13 +8863,13 @@ ${indentation}`;
|
|
|
8776
8863
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8777
8864
|
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
8778
8865
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
8779
|
-
res +=
|
|
8866
|
+
res += join10;
|
|
8780
8867
|
}
|
|
8781
8868
|
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
8782
8869
|
res += tmp !== void 0 ? tmp : "null";
|
|
8783
8870
|
if (value.length - 1 > maximumBreadth) {
|
|
8784
8871
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8785
|
-
res += `${
|
|
8872
|
+
res += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8786
8873
|
}
|
|
8787
8874
|
if (spacer !== "") {
|
|
8788
8875
|
res += `
|
|
@@ -8795,7 +8882,7 @@ ${originalIndentation}`;
|
|
|
8795
8882
|
let whitespace = "";
|
|
8796
8883
|
if (spacer !== "") {
|
|
8797
8884
|
indentation += spacer;
|
|
8798
|
-
|
|
8885
|
+
join10 = `,
|
|
8799
8886
|
${indentation}`;
|
|
8800
8887
|
whitespace = " ";
|
|
8801
8888
|
}
|
|
@@ -8804,7 +8891,7 @@ ${indentation}`;
|
|
|
8804
8891
|
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
8805
8892
|
if (tmp !== void 0) {
|
|
8806
8893
|
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
8807
|
-
separator =
|
|
8894
|
+
separator = join10;
|
|
8808
8895
|
}
|
|
8809
8896
|
}
|
|
8810
8897
|
if (spacer !== "" && separator.length > 1) {
|
|
@@ -8862,20 +8949,20 @@ ${originalIndentation}`;
|
|
|
8862
8949
|
indentation += spacer;
|
|
8863
8950
|
let res2 = `
|
|
8864
8951
|
${indentation}`;
|
|
8865
|
-
const
|
|
8952
|
+
const join11 = `,
|
|
8866
8953
|
${indentation}`;
|
|
8867
8954
|
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
8868
8955
|
let i = 0;
|
|
8869
8956
|
for (; i < maximumValuesToStringify - 1; i++) {
|
|
8870
8957
|
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
8871
8958
|
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
8872
|
-
res2 +=
|
|
8959
|
+
res2 += join11;
|
|
8873
8960
|
}
|
|
8874
8961
|
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
8875
8962
|
res2 += tmp !== void 0 ? tmp : "null";
|
|
8876
8963
|
if (value.length - 1 > maximumBreadth) {
|
|
8877
8964
|
const removedKeys = value.length - maximumBreadth - 1;
|
|
8878
|
-
res2 += `${
|
|
8965
|
+
res2 += `${join11}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
8879
8966
|
}
|
|
8880
8967
|
res2 += `
|
|
8881
8968
|
${originalIndentation}`;
|
|
@@ -8891,16 +8978,16 @@ ${originalIndentation}`;
|
|
|
8891
8978
|
return '"[Object]"';
|
|
8892
8979
|
}
|
|
8893
8980
|
indentation += spacer;
|
|
8894
|
-
const
|
|
8981
|
+
const join10 = `,
|
|
8895
8982
|
${indentation}`;
|
|
8896
8983
|
let res = "";
|
|
8897
8984
|
let separator = "";
|
|
8898
8985
|
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
8899
8986
|
if (isTypedArrayWithEntries(value)) {
|
|
8900
|
-
res += stringifyTypedArray(value,
|
|
8987
|
+
res += stringifyTypedArray(value, join10, maximumBreadth);
|
|
8901
8988
|
keys = keys.slice(value.length);
|
|
8902
8989
|
maximumPropertiesToStringify -= value.length;
|
|
8903
|
-
separator =
|
|
8990
|
+
separator = join10;
|
|
8904
8991
|
}
|
|
8905
8992
|
if (deterministic) {
|
|
8906
8993
|
keys = sort(keys, comparator);
|
|
@@ -8911,13 +8998,13 @@ ${indentation}`;
|
|
|
8911
8998
|
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
8912
8999
|
if (tmp !== void 0) {
|
|
8913
9000
|
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
8914
|
-
separator =
|
|
9001
|
+
separator = join10;
|
|
8915
9002
|
}
|
|
8916
9003
|
}
|
|
8917
9004
|
if (keyLength > maximumBreadth) {
|
|
8918
9005
|
const removedKeys = keyLength - maximumBreadth;
|
|
8919
9006
|
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
8920
|
-
separator =
|
|
9007
|
+
separator = join10;
|
|
8921
9008
|
}
|
|
8922
9009
|
if (separator !== "") {
|
|
8923
9010
|
res = `
|
|
@@ -10008,11 +10095,11 @@ var init_lib = __esm({
|
|
|
10008
10095
|
}
|
|
10009
10096
|
}
|
|
10010
10097
|
},
|
|
10011
|
-
addToPath: function addToPath(
|
|
10012
|
-
var last =
|
|
10098
|
+
addToPath: function addToPath(path37, added, removed, oldPosInc, options) {
|
|
10099
|
+
var last = path37.lastComponent;
|
|
10013
10100
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
10014
10101
|
return {
|
|
10015
|
-
oldPos:
|
|
10102
|
+
oldPos: path37.oldPos + oldPosInc,
|
|
10016
10103
|
lastComponent: {
|
|
10017
10104
|
count: last.count + 1,
|
|
10018
10105
|
added,
|
|
@@ -10022,7 +10109,7 @@ var init_lib = __esm({
|
|
|
10022
10109
|
};
|
|
10023
10110
|
} else {
|
|
10024
10111
|
return {
|
|
10025
|
-
oldPos:
|
|
10112
|
+
oldPos: path37.oldPos + oldPosInc,
|
|
10026
10113
|
lastComponent: {
|
|
10027
10114
|
count: 1,
|
|
10028
10115
|
added,
|
|
@@ -10453,10 +10540,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
10453
10540
|
const memories = raw.map((m2) => {
|
|
10454
10541
|
if (!m2 || typeof m2 !== "object") return null;
|
|
10455
10542
|
const rec = m2;
|
|
10456
|
-
const
|
|
10543
|
+
const path37 = typeof rec.path === "string" ? rec.path : null;
|
|
10457
10544
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
10458
|
-
if (!
|
|
10459
|
-
const entry = { path:
|
|
10545
|
+
if (!path37 || content == null) return null;
|
|
10546
|
+
const entry = { path: path37, content };
|
|
10460
10547
|
if (typeof rec.mtimeMs === "number") entry.mtimeMs = rec.mtimeMs;
|
|
10461
10548
|
return entry;
|
|
10462
10549
|
}).filter((m2) => m2 !== null);
|
|
@@ -11282,10 +11369,10 @@ function parseAttachment(obj) {
|
|
|
11282
11369
|
const memories = raw.map((m2) => {
|
|
11283
11370
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11284
11371
|
const rec = m2;
|
|
11285
|
-
const
|
|
11372
|
+
const path37 = typeof rec.path === "string" ? rec.path : null;
|
|
11286
11373
|
const content = typeof rec.content === "string" ? rec.content : null;
|
|
11287
|
-
if (!
|
|
11288
|
-
const out = { path:
|
|
11374
|
+
if (!path37 || content == null) return null;
|
|
11375
|
+
const out = { path: path37, content };
|
|
11289
11376
|
if (typeof rec.mtimeMs === "number") out.mtimeMs = rec.mtimeMs;
|
|
11290
11377
|
return out;
|
|
11291
11378
|
}).filter((m2) => m2 !== null);
|
|
@@ -18784,7 +18871,7 @@ var require_websocket = __commonJS({
|
|
|
18784
18871
|
var http2 = require("http");
|
|
18785
18872
|
var net = require("net");
|
|
18786
18873
|
var tls = require("tls");
|
|
18787
|
-
var { randomBytes:
|
|
18874
|
+
var { randomBytes: randomBytes3, createHash: createHash4 } = require("crypto");
|
|
18788
18875
|
var { Duplex, Readable: Readable3 } = require("stream");
|
|
18789
18876
|
var { URL: URL2 } = require("url");
|
|
18790
18877
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -19314,7 +19401,7 @@ var require_websocket = __commonJS({
|
|
|
19314
19401
|
}
|
|
19315
19402
|
}
|
|
19316
19403
|
const defaultPort = isSecure ? 443 : 80;
|
|
19317
|
-
const key =
|
|
19404
|
+
const key = randomBytes3(16).toString("base64");
|
|
19318
19405
|
const request = isSecure ? https.request : http2.request;
|
|
19319
19406
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
19320
19407
|
let perMessageDeflate;
|
|
@@ -19444,7 +19531,7 @@ var require_websocket = __commonJS({
|
|
|
19444
19531
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
19445
19532
|
return;
|
|
19446
19533
|
}
|
|
19447
|
-
const digest =
|
|
19534
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
19448
19535
|
if (res.headers["sec-websocket-accept"] !== digest) {
|
|
19449
19536
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
19450
19537
|
return;
|
|
@@ -19811,7 +19898,7 @@ var require_websocket_server = __commonJS({
|
|
|
19811
19898
|
var EventEmitter2 = require("events");
|
|
19812
19899
|
var http2 = require("http");
|
|
19813
19900
|
var { Duplex } = require("stream");
|
|
19814
|
-
var { createHash:
|
|
19901
|
+
var { createHash: createHash4 } = require("crypto");
|
|
19815
19902
|
var extension2 = require_extension();
|
|
19816
19903
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
19817
19904
|
var subprotocol2 = require_subprotocol();
|
|
@@ -20112,7 +20199,7 @@ var require_websocket_server = __commonJS({
|
|
|
20112
20199
|
);
|
|
20113
20200
|
}
|
|
20114
20201
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
20115
|
-
const digest =
|
|
20202
|
+
const digest = createHash4("sha1").update(key + GUID).digest("base64");
|
|
20116
20203
|
const headers = [
|
|
20117
20204
|
"HTTP/1.1 101 Switching Protocols",
|
|
20118
20205
|
"Upgrade: websocket",
|
|
@@ -25512,6 +25599,23 @@ var LocalWsServer = class {
|
|
|
25512
25599
|
this.safeSend(c.ws, frame);
|
|
25513
25600
|
}
|
|
25514
25601
|
}
|
|
25602
|
+
// Phase 4 capability platform DM: 广播到指定 principal 的所有活跃 ws.
|
|
25603
|
+
// principalId === 'owner' → 同 broadcastToOwners (所有 owner ws)
|
|
25604
|
+
// principalId === 'cap_xxx' → 该 capability 的所有 guest ws (多端 / 多 tab)
|
|
25605
|
+
// 用于 DM inbox:event 路由: from + to 两侧各播一次, 让双方 UI 实时看到 thread 更新.
|
|
25606
|
+
broadcastToPrincipal(principalId, frame) {
|
|
25607
|
+
if (principalId === "owner") {
|
|
25608
|
+
this.broadcastToOwners(frame);
|
|
25609
|
+
return;
|
|
25610
|
+
}
|
|
25611
|
+
const set = this.capabilityIdToClients.get(principalId);
|
|
25612
|
+
if (!set) return;
|
|
25613
|
+
for (const id of set) {
|
|
25614
|
+
const c = this.clients.get(id);
|
|
25615
|
+
if (!c) continue;
|
|
25616
|
+
this.safeSend(c.ws, frame);
|
|
25617
|
+
}
|
|
25618
|
+
}
|
|
25515
25619
|
firstSubscriber(sessionId) {
|
|
25516
25620
|
for (const c of this.clients.values()) {
|
|
25517
25621
|
if (c.handle.subscribedSessions.has(sessionId)) return c.handle;
|
|
@@ -26112,62 +26216,323 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
26112
26216
|
return { removed };
|
|
26113
26217
|
}
|
|
26114
26218
|
|
|
26115
|
-
// src/
|
|
26219
|
+
// src/inbox/inbox-store.ts
|
|
26116
26220
|
var fs17 = __toESM(require("fs"), 1);
|
|
26117
26221
|
var path19 = __toESM(require("path"), 1);
|
|
26222
|
+
var INBOX_FILE_NAME = "inbox.jsonl";
|
|
26223
|
+
var InboxStore = class {
|
|
26224
|
+
constructor(dataDir) {
|
|
26225
|
+
this.dataDir = dataDir;
|
|
26226
|
+
fs17.mkdirSync(dataDir, { recursive: true });
|
|
26227
|
+
}
|
|
26228
|
+
dataDir;
|
|
26229
|
+
list() {
|
|
26230
|
+
const file = this.filePath();
|
|
26231
|
+
let raw;
|
|
26232
|
+
try {
|
|
26233
|
+
raw = fs17.readFileSync(file, "utf8");
|
|
26234
|
+
} catch (err) {
|
|
26235
|
+
if (err?.code === "ENOENT") return [];
|
|
26236
|
+
return [];
|
|
26237
|
+
}
|
|
26238
|
+
return parseAllLines(raw);
|
|
26239
|
+
}
|
|
26240
|
+
append(ev) {
|
|
26241
|
+
const file = this.filePath();
|
|
26242
|
+
const line = JSON.stringify(ev) + "\n";
|
|
26243
|
+
fs17.appendFileSync(file, line, { mode: 384 });
|
|
26244
|
+
try {
|
|
26245
|
+
fs17.chmodSync(file, 384);
|
|
26246
|
+
} catch {
|
|
26247
|
+
}
|
|
26248
|
+
}
|
|
26249
|
+
/**
|
|
26250
|
+
* 标记某条 event 为已读. 已有 readAt 时不覆盖 (idempotent: 第二次调用维持第一次时间).
|
|
26251
|
+
* 未知 id 静默 no-op (不抛, 不写文件).
|
|
26252
|
+
*/
|
|
26253
|
+
markRead(id, at) {
|
|
26254
|
+
const events = this.list();
|
|
26255
|
+
let changed = false;
|
|
26256
|
+
const next = events.map((e) => {
|
|
26257
|
+
if (e.id !== id) return e;
|
|
26258
|
+
if (e.readAt !== void 0) return e;
|
|
26259
|
+
changed = true;
|
|
26260
|
+
return { ...e, readAt: at };
|
|
26261
|
+
});
|
|
26262
|
+
if (!changed) return;
|
|
26263
|
+
this.rewrite(next);
|
|
26264
|
+
}
|
|
26265
|
+
rewrite(events) {
|
|
26266
|
+
const file = this.filePath();
|
|
26267
|
+
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
26268
|
+
const content = events.map((e) => JSON.stringify(e)).join("\n") + (events.length > 0 ? "\n" : "");
|
|
26269
|
+
fs17.writeFileSync(tmp, content, { mode: 384 });
|
|
26270
|
+
fs17.renameSync(tmp, file);
|
|
26271
|
+
try {
|
|
26272
|
+
fs17.chmodSync(file, 384);
|
|
26273
|
+
} catch {
|
|
26274
|
+
}
|
|
26275
|
+
}
|
|
26276
|
+
filePath() {
|
|
26277
|
+
return path19.join(this.dataDir, INBOX_FILE_NAME);
|
|
26278
|
+
}
|
|
26279
|
+
};
|
|
26280
|
+
function parseAllLines(raw) {
|
|
26281
|
+
const out = [];
|
|
26282
|
+
for (const line of raw.split("\n")) {
|
|
26283
|
+
const trimmed = line.trim();
|
|
26284
|
+
if (!trimmed) continue;
|
|
26285
|
+
let parsed;
|
|
26286
|
+
try {
|
|
26287
|
+
parsed = JSON.parse(trimmed);
|
|
26288
|
+
} catch {
|
|
26289
|
+
continue;
|
|
26290
|
+
}
|
|
26291
|
+
const r = InboxEventSchema.safeParse(parsed);
|
|
26292
|
+
if (r.success) out.push(r.data);
|
|
26293
|
+
}
|
|
26294
|
+
return out;
|
|
26295
|
+
}
|
|
26296
|
+
|
|
26297
|
+
// src/inbox/inbox-manager.ts
|
|
26298
|
+
var crypto7 = __toESM(require("crypto"), 1);
|
|
26299
|
+
|
|
26300
|
+
// src/inbox/dm.ts
|
|
26301
|
+
var crypto6 = __toESM(require("crypto"), 1);
|
|
26302
|
+
function deriveDmThreadId(idA, idB) {
|
|
26303
|
+
const [low, high] = idA < idB ? [idA, idB] : [idB, idA];
|
|
26304
|
+
return crypto6.createHash("sha256").update(`${low}/${high}`).digest("hex");
|
|
26305
|
+
}
|
|
26306
|
+
|
|
26307
|
+
// src/inbox/inbox-manager.ts
|
|
26308
|
+
var InboxManager = class {
|
|
26309
|
+
constructor(store, broadcast, opts = {}) {
|
|
26310
|
+
this.store = store;
|
|
26311
|
+
this.broadcast = broadcast;
|
|
26312
|
+
this.now = opts.now ?? Date.now;
|
|
26313
|
+
this.genId = opts.genId ?? defaultGenId;
|
|
26314
|
+
}
|
|
26315
|
+
store;
|
|
26316
|
+
broadcast;
|
|
26317
|
+
now;
|
|
26318
|
+
genId;
|
|
26319
|
+
/**
|
|
26320
|
+
* persona VM 内某 sender 给 CC 发消息 → 跨 principal 时记 inbox event.
|
|
26321
|
+
* 返回 null = owner 自己 (no-op); 否则返回写入的 event (含派生 id / createdAt).
|
|
26322
|
+
*/
|
|
26323
|
+
recordPersonaMention(args) {
|
|
26324
|
+
if (args.sender.kind === "owner") return null;
|
|
26325
|
+
const resource = { type: "persona", id: args.personaId };
|
|
26326
|
+
const ev = {
|
|
26327
|
+
id: this.genId(),
|
|
26328
|
+
kind: "persona-mention",
|
|
26329
|
+
fromPrincipal: args.sender,
|
|
26330
|
+
toPrincipal: OWNER_PRINCIPAL,
|
|
26331
|
+
resource,
|
|
26332
|
+
preview: truncatePreview(args.preview),
|
|
26333
|
+
createdAt: this.now()
|
|
26334
|
+
};
|
|
26335
|
+
this.store.append(ev);
|
|
26336
|
+
this.broadcast({ type: "inbox:event", event: ev });
|
|
26337
|
+
return ev;
|
|
26338
|
+
}
|
|
26339
|
+
/**
|
|
26340
|
+
* Phase 4 Task 4.2: DM 私聊事件. 与 recordPersonaMention 区别:
|
|
26341
|
+
* - kind = 'direct-message' (不是 persona-mention)
|
|
26342
|
+
* - 不带 resource (DM 不挂某个 persona)
|
|
26343
|
+
* - threadId 由 from.id + to.id 派生 (sha256), 双向消息共享同一 thread
|
|
26344
|
+
* - 调用方 (handler) 已校验 sender = ctx.principal (防伪造)
|
|
26345
|
+
*
|
|
26346
|
+
* 返回值是 InboxEvent (含派生 threadId), daemon/index.ts 装配 broadcast 路由:
|
|
26347
|
+
* broadcastToPrincipal(from.id) + broadcastToPrincipal(to.id) (双侧 ws 都收).
|
|
26348
|
+
*/
|
|
26349
|
+
recordDirectMessage(args) {
|
|
26350
|
+
const ev = {
|
|
26351
|
+
id: this.genId(),
|
|
26352
|
+
kind: "direct-message",
|
|
26353
|
+
fromPrincipal: args.from,
|
|
26354
|
+
toPrincipal: args.to,
|
|
26355
|
+
preview: truncatePreview(args.text),
|
|
26356
|
+
createdAt: this.now(),
|
|
26357
|
+
threadId: deriveDmThreadId(args.from.id, args.to.id)
|
|
26358
|
+
};
|
|
26359
|
+
this.store.append(ev);
|
|
26360
|
+
this.broadcast({ type: "inbox:event", event: ev });
|
|
26361
|
+
return ev;
|
|
26362
|
+
}
|
|
26363
|
+
list(opts = {}) {
|
|
26364
|
+
const all = this.store.list();
|
|
26365
|
+
if (opts.includeRead) return all;
|
|
26366
|
+
return all.filter((e) => e.readAt === void 0);
|
|
26367
|
+
}
|
|
26368
|
+
markRead(eventId) {
|
|
26369
|
+
this.store.markRead(eventId, this.now());
|
|
26370
|
+
}
|
|
26371
|
+
};
|
|
26372
|
+
function truncatePreview(s) {
|
|
26373
|
+
if (s.length <= INBOX_PREVIEW_MAX_LENGTH) return s;
|
|
26374
|
+
return s.slice(0, INBOX_PREVIEW_MAX_LENGTH);
|
|
26375
|
+
}
|
|
26376
|
+
function defaultGenId() {
|
|
26377
|
+
return "inb_" + crypto7.randomBytes(6).toString("base64url");
|
|
26378
|
+
}
|
|
26379
|
+
|
|
26380
|
+
// src/remote-persona/store.ts
|
|
26381
|
+
var fs18 = __toESM(require("fs"), 1);
|
|
26382
|
+
var path20 = __toESM(require("path"), 1);
|
|
26383
|
+
var REMOTE_PERSONAS_DIR = "remote-personas";
|
|
26384
|
+
var RemotePersonaStore = class {
|
|
26385
|
+
constructor(dataDir) {
|
|
26386
|
+
this.dataDir = dataDir;
|
|
26387
|
+
fs18.mkdirSync(this.rootDir(), { recursive: true });
|
|
26388
|
+
}
|
|
26389
|
+
dataDir;
|
|
26390
|
+
list() {
|
|
26391
|
+
let entries;
|
|
26392
|
+
try {
|
|
26393
|
+
entries = fs18.readdirSync(this.rootDir());
|
|
26394
|
+
} catch (err) {
|
|
26395
|
+
if (err?.code === "ENOENT") return [];
|
|
26396
|
+
return [];
|
|
26397
|
+
}
|
|
26398
|
+
const out = [];
|
|
26399
|
+
for (const name of entries) {
|
|
26400
|
+
if (!name.endsWith(".json")) continue;
|
|
26401
|
+
if (name.includes(".tmp-")) continue;
|
|
26402
|
+
const file = path20.join(this.rootDir(), name);
|
|
26403
|
+
let raw;
|
|
26404
|
+
try {
|
|
26405
|
+
raw = fs18.readFileSync(file, "utf8");
|
|
26406
|
+
} catch {
|
|
26407
|
+
continue;
|
|
26408
|
+
}
|
|
26409
|
+
let parsed;
|
|
26410
|
+
try {
|
|
26411
|
+
parsed = JSON.parse(raw);
|
|
26412
|
+
} catch {
|
|
26413
|
+
continue;
|
|
26414
|
+
}
|
|
26415
|
+
const r = RemotePersonaSchema.safeParse(parsed);
|
|
26416
|
+
if (r.success) out.push(r.data);
|
|
26417
|
+
}
|
|
26418
|
+
return out.sort((a, b2) => a.addedAt > b2.addedAt ? -1 : a.addedAt < b2.addedAt ? 1 : 0);
|
|
26419
|
+
}
|
|
26420
|
+
get(alias) {
|
|
26421
|
+
const file = this.filePath(alias);
|
|
26422
|
+
let raw;
|
|
26423
|
+
try {
|
|
26424
|
+
raw = fs18.readFileSync(file, "utf8");
|
|
26425
|
+
} catch {
|
|
26426
|
+
return null;
|
|
26427
|
+
}
|
|
26428
|
+
try {
|
|
26429
|
+
const parsed = JSON.parse(raw);
|
|
26430
|
+
const r = RemotePersonaSchema.safeParse(parsed);
|
|
26431
|
+
return r.success ? r.data : null;
|
|
26432
|
+
} catch {
|
|
26433
|
+
return null;
|
|
26434
|
+
}
|
|
26435
|
+
}
|
|
26436
|
+
add(rp) {
|
|
26437
|
+
const file = this.filePath(rp.alias);
|
|
26438
|
+
if (fs18.existsSync(file)) {
|
|
26439
|
+
throw new Error(`RemotePersonaStore.add: alias already exists: ${rp.alias}`);
|
|
26440
|
+
}
|
|
26441
|
+
this.atomicWrite(file, rp);
|
|
26442
|
+
}
|
|
26443
|
+
remove(alias) {
|
|
26444
|
+
const file = this.filePath(alias);
|
|
26445
|
+
try {
|
|
26446
|
+
fs18.unlinkSync(file);
|
|
26447
|
+
return true;
|
|
26448
|
+
} catch (err) {
|
|
26449
|
+
if (err?.code === "ENOENT") return false;
|
|
26450
|
+
throw err;
|
|
26451
|
+
}
|
|
26452
|
+
}
|
|
26453
|
+
/**
|
|
26454
|
+
* patch lastConnectedAt (v2 outgoing client 连上时更新). 其他字段不动.
|
|
26455
|
+
* 不存在 alias → no-op.
|
|
26456
|
+
*/
|
|
26457
|
+
updateLastConnectedAt(alias, at) {
|
|
26458
|
+
const cur = this.get(alias);
|
|
26459
|
+
if (!cur) return;
|
|
26460
|
+
this.atomicWrite(this.filePath(alias), { ...cur, lastConnectedAt: at });
|
|
26461
|
+
}
|
|
26462
|
+
rootDir() {
|
|
26463
|
+
return path20.join(this.dataDir, REMOTE_PERSONAS_DIR);
|
|
26464
|
+
}
|
|
26465
|
+
filePath(alias) {
|
|
26466
|
+
return path20.join(this.rootDir(), `${safeFileName(alias)}.json`);
|
|
26467
|
+
}
|
|
26468
|
+
atomicWrite(file, content) {
|
|
26469
|
+
fs18.mkdirSync(this.rootDir(), { recursive: true });
|
|
26470
|
+
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
26471
|
+
fs18.writeFileSync(tmp, JSON.stringify(content, null, 2), { mode: 384 });
|
|
26472
|
+
fs18.renameSync(tmp, file);
|
|
26473
|
+
try {
|
|
26474
|
+
fs18.chmodSync(file, 384);
|
|
26475
|
+
} catch {
|
|
26476
|
+
}
|
|
26477
|
+
}
|
|
26478
|
+
};
|
|
26479
|
+
|
|
26480
|
+
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
26481
|
+
var fs19 = __toESM(require("fs"), 1);
|
|
26482
|
+
var path21 = __toESM(require("path"), 1);
|
|
26118
26483
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
26119
26484
|
function migrateFlattenSessions(opts) {
|
|
26120
26485
|
const dataDir = opts.dataDir;
|
|
26121
26486
|
const now = opts.now ?? Date.now;
|
|
26122
|
-
const sessionsDir =
|
|
26123
|
-
const flagPath =
|
|
26124
|
-
if (
|
|
26487
|
+
const sessionsDir = path21.join(dataDir, "sessions");
|
|
26488
|
+
const flagPath = path21.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
26489
|
+
if (existsSync4(flagPath)) {
|
|
26125
26490
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
26126
26491
|
}
|
|
26127
26492
|
let movedBare = 0;
|
|
26128
26493
|
let movedVmOwner = 0;
|
|
26129
26494
|
let archivedListener = 0;
|
|
26130
|
-
const defaultDir =
|
|
26131
|
-
if (
|
|
26495
|
+
const defaultDir = path21.join(sessionsDir, "default");
|
|
26496
|
+
if (existsSync4(defaultDir)) {
|
|
26132
26497
|
for (const entry of readdirSafe(defaultDir)) {
|
|
26133
26498
|
if (!entry.endsWith(".json")) continue;
|
|
26134
|
-
const src =
|
|
26135
|
-
const dst =
|
|
26136
|
-
|
|
26499
|
+
const src = path21.join(defaultDir, entry);
|
|
26500
|
+
const dst = path21.join(sessionsDir, entry);
|
|
26501
|
+
fs19.renameSync(src, dst);
|
|
26137
26502
|
movedBare += 1;
|
|
26138
26503
|
}
|
|
26139
26504
|
rmdirIfEmpty(defaultDir);
|
|
26140
26505
|
}
|
|
26141
26506
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
26142
|
-
const personaDir =
|
|
26507
|
+
const personaDir = path21.join(sessionsDir, pid);
|
|
26143
26508
|
if (!isDir(personaDir)) continue;
|
|
26144
26509
|
if (pid === "default") continue;
|
|
26145
|
-
const ownerSrc =
|
|
26146
|
-
if (
|
|
26147
|
-
const ownerDst =
|
|
26148
|
-
|
|
26510
|
+
const ownerSrc = path21.join(personaDir, "owner");
|
|
26511
|
+
if (existsSync4(ownerSrc) && isDir(ownerSrc)) {
|
|
26512
|
+
const ownerDst = path21.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
26513
|
+
fs19.mkdirSync(ownerDst, { recursive: true });
|
|
26149
26514
|
for (const file of readdirSafe(ownerSrc)) {
|
|
26150
26515
|
if (!file.endsWith(".json")) continue;
|
|
26151
|
-
|
|
26516
|
+
fs19.renameSync(path21.join(ownerSrc, file), path21.join(ownerDst, file));
|
|
26152
26517
|
movedVmOwner += 1;
|
|
26153
26518
|
}
|
|
26154
26519
|
rmdirIfEmpty(ownerSrc);
|
|
26155
26520
|
}
|
|
26156
|
-
const listenerSrc =
|
|
26157
|
-
if (
|
|
26158
|
-
const archiveDst =
|
|
26159
|
-
|
|
26521
|
+
const listenerSrc = path21.join(personaDir, "listener");
|
|
26522
|
+
if (existsSync4(listenerSrc) && isDir(listenerSrc)) {
|
|
26523
|
+
const archiveDst = path21.join(dataDir, ".legacy", `listener-${pid}`);
|
|
26524
|
+
fs19.mkdirSync(archiveDst, { recursive: true });
|
|
26160
26525
|
for (const file of readdirSafe(listenerSrc)) {
|
|
26161
26526
|
if (!file.endsWith(".json")) continue;
|
|
26162
|
-
|
|
26527
|
+
fs19.renameSync(path21.join(listenerSrc, file), path21.join(archiveDst, file));
|
|
26163
26528
|
archivedListener += 1;
|
|
26164
26529
|
}
|
|
26165
26530
|
rmdirIfEmpty(listenerSrc);
|
|
26166
26531
|
}
|
|
26167
26532
|
rmdirIfEmpty(personaDir);
|
|
26168
26533
|
}
|
|
26169
|
-
|
|
26170
|
-
|
|
26534
|
+
fs19.mkdirSync(sessionsDir, { recursive: true });
|
|
26535
|
+
fs19.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
26171
26536
|
return {
|
|
26172
26537
|
skipped: false,
|
|
26173
26538
|
flagWritten: true,
|
|
@@ -26176,9 +26541,9 @@ function migrateFlattenSessions(opts) {
|
|
|
26176
26541
|
archivedListener
|
|
26177
26542
|
};
|
|
26178
26543
|
}
|
|
26179
|
-
function
|
|
26544
|
+
function existsSync4(p2) {
|
|
26180
26545
|
try {
|
|
26181
|
-
|
|
26546
|
+
fs19.statSync(p2);
|
|
26182
26547
|
return true;
|
|
26183
26548
|
} catch {
|
|
26184
26549
|
return false;
|
|
@@ -26186,21 +26551,21 @@ function existsSync3(p2) {
|
|
|
26186
26551
|
}
|
|
26187
26552
|
function isDir(p2) {
|
|
26188
26553
|
try {
|
|
26189
|
-
return
|
|
26554
|
+
return fs19.statSync(p2).isDirectory();
|
|
26190
26555
|
} catch {
|
|
26191
26556
|
return false;
|
|
26192
26557
|
}
|
|
26193
26558
|
}
|
|
26194
26559
|
function readdirSafe(p2) {
|
|
26195
26560
|
try {
|
|
26196
|
-
return
|
|
26561
|
+
return fs19.readdirSync(p2);
|
|
26197
26562
|
} catch {
|
|
26198
26563
|
return [];
|
|
26199
26564
|
}
|
|
26200
26565
|
}
|
|
26201
26566
|
function rmdirIfEmpty(p2) {
|
|
26202
26567
|
try {
|
|
26203
|
-
|
|
26568
|
+
fs19.rmdirSync(p2);
|
|
26204
26569
|
} catch {
|
|
26205
26570
|
}
|
|
26206
26571
|
}
|
|
@@ -28051,6 +28416,113 @@ function buildCapabilityHandlers(deps) {
|
|
|
28051
28416
|
};
|
|
28052
28417
|
}
|
|
28053
28418
|
|
|
28419
|
+
// src/handlers/inbox.ts
|
|
28420
|
+
init_protocol();
|
|
28421
|
+
function buildInboxHandlers(deps) {
|
|
28422
|
+
const { manager, capabilityRegistry } = deps;
|
|
28423
|
+
function resolvePeerPrincipal(peerId) {
|
|
28424
|
+
if (peerId === "owner") {
|
|
28425
|
+
return { id: "owner", kind: "owner", displayName: "owner" };
|
|
28426
|
+
}
|
|
28427
|
+
const cap = capabilityRegistry.findById(peerId);
|
|
28428
|
+
if (!cap) {
|
|
28429
|
+
throw new ClawdError(
|
|
28430
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
28431
|
+
`peer principal not found: ${peerId}`
|
|
28432
|
+
);
|
|
28433
|
+
}
|
|
28434
|
+
return { id: cap.id, kind: "guest", displayName: cap.displayName };
|
|
28435
|
+
}
|
|
28436
|
+
const list = async (frame) => {
|
|
28437
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
28438
|
+
const args = InboxListArgsSchema.parse(rest);
|
|
28439
|
+
const events = manager.list({ includeRead: args.includeRead ?? false });
|
|
28440
|
+
return {
|
|
28441
|
+
response: { type: "inbox:list", events }
|
|
28442
|
+
};
|
|
28443
|
+
};
|
|
28444
|
+
const markRead = async (frame) => {
|
|
28445
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
28446
|
+
const args = InboxMarkReadArgsSchema.parse(rest);
|
|
28447
|
+
manager.markRead(args.eventId);
|
|
28448
|
+
return {
|
|
28449
|
+
response: { type: "inbox:markRead:ok", eventId: args.eventId }
|
|
28450
|
+
};
|
|
28451
|
+
};
|
|
28452
|
+
const postMessage = async (frame, _client, ctx) => {
|
|
28453
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
28454
|
+
const args = InboxPostMessageArgsSchema.parse(rest);
|
|
28455
|
+
if (!ctx) {
|
|
28456
|
+
throw new ClawdError(ERROR_CODES.INTERNAL, "inbox:postMessage: missing ConnectionContext");
|
|
28457
|
+
}
|
|
28458
|
+
const peer = resolvePeerPrincipal(args.peerPrincipalId);
|
|
28459
|
+
const ev = manager.recordDirectMessage({
|
|
28460
|
+
from: ctx.principal,
|
|
28461
|
+
to: peer,
|
|
28462
|
+
text: args.text
|
|
28463
|
+
});
|
|
28464
|
+
return {
|
|
28465
|
+
response: { type: "inbox:postMessage:ok", event: ev }
|
|
28466
|
+
};
|
|
28467
|
+
};
|
|
28468
|
+
return {
|
|
28469
|
+
"inbox:list": list,
|
|
28470
|
+
"inbox:markRead": markRead,
|
|
28471
|
+
"inbox:postMessage": postMessage
|
|
28472
|
+
};
|
|
28473
|
+
}
|
|
28474
|
+
|
|
28475
|
+
// src/handlers/remote-persona.ts
|
|
28476
|
+
init_protocol();
|
|
28477
|
+
function buildRemotePersonaHandlers(deps) {
|
|
28478
|
+
const { store } = deps;
|
|
28479
|
+
const now = deps.now ?? Date.now;
|
|
28480
|
+
const add = async (frame) => {
|
|
28481
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
28482
|
+
const args = RemotePersonaAddArgsSchema.parse(rest);
|
|
28483
|
+
const rp = {
|
|
28484
|
+
...args,
|
|
28485
|
+
addedAt: now()
|
|
28486
|
+
};
|
|
28487
|
+
try {
|
|
28488
|
+
store.add(rp);
|
|
28489
|
+
} catch (err) {
|
|
28490
|
+
if (err.message?.includes("alias already exists")) {
|
|
28491
|
+
throw new ClawdError(
|
|
28492
|
+
ERROR_CODES.VALIDATION_ERROR,
|
|
28493
|
+
`remote-persona alias already exists: ${args.alias}`
|
|
28494
|
+
);
|
|
28495
|
+
}
|
|
28496
|
+
throw err;
|
|
28497
|
+
}
|
|
28498
|
+
return {
|
|
28499
|
+
response: { type: "remote-persona:add:ok", remotePersona: stripRemotePersonaSecret(rp) }
|
|
28500
|
+
};
|
|
28501
|
+
};
|
|
28502
|
+
const list = async () => {
|
|
28503
|
+
const all = store.list();
|
|
28504
|
+
return {
|
|
28505
|
+
response: {
|
|
28506
|
+
type: "remote-persona:list",
|
|
28507
|
+
remotePersonas: all.map(stripRemotePersonaSecret)
|
|
28508
|
+
}
|
|
28509
|
+
};
|
|
28510
|
+
};
|
|
28511
|
+
const remove = async (frame) => {
|
|
28512
|
+
const { type: _t, requestId: _r, ...rest } = frame;
|
|
28513
|
+
const args = RemotePersonaRemoveArgsSchema.parse(rest);
|
|
28514
|
+
const removed = store.remove(args.alias);
|
|
28515
|
+
return {
|
|
28516
|
+
response: { type: "remote-persona:remove:ok", alias: args.alias, removed }
|
|
28517
|
+
};
|
|
28518
|
+
};
|
|
28519
|
+
return {
|
|
28520
|
+
"remote-persona:add": add,
|
|
28521
|
+
"remote-persona:list": list,
|
|
28522
|
+
"remote-persona:remove": remove
|
|
28523
|
+
};
|
|
28524
|
+
}
|
|
28525
|
+
|
|
28054
28526
|
// src/handlers/meta.ts
|
|
28055
28527
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
28056
28528
|
init_protocol();
|
|
@@ -28303,6 +28775,11 @@ function buildMethodHandlers(deps) {
|
|
|
28303
28775
|
personaRegistry: deps.personaRegistry
|
|
28304
28776
|
}),
|
|
28305
28777
|
...buildCapabilityHandlers({ manager: deps.capabilityManager }),
|
|
28778
|
+
...buildInboxHandlers({
|
|
28779
|
+
manager: deps.inboxManager,
|
|
28780
|
+
capabilityRegistry: deps.capabilityRegistry
|
|
28781
|
+
}),
|
|
28782
|
+
...buildRemotePersonaHandlers({ store: deps.remotePersonaStore }),
|
|
28306
28783
|
...deps.attachment ? buildAttachmentHandlers(deps.attachment) : {}
|
|
28307
28784
|
};
|
|
28308
28785
|
}
|
|
@@ -28321,6 +28798,16 @@ var METHOD_GRANT_MAP = {
|
|
|
28321
28798
|
"capability:issue": ADMIN_ANY,
|
|
28322
28799
|
"capability:list": ADMIN_ANY,
|
|
28323
28800
|
"capability:revoke": ADMIN_ANY,
|
|
28801
|
+
// ---- inbox 跨用户通知 (Phase 3 admin-only, owner 调; Phase 4 加 postMessage) ----
|
|
28802
|
+
"inbox:list": ADMIN_ANY,
|
|
28803
|
+
"inbox:markRead": ADMIN_ANY,
|
|
28804
|
+
// Phase 4 Task 4.2: DM 是 capability 自带能力 (plan §2),
|
|
28805
|
+
// 任何 principal (owner / guest) 可调, 不通过 grant 表达.
|
|
28806
|
+
"inbox:postMessage": { kind: "public" },
|
|
28807
|
+
// Phase 4 Task 4.3: 远程 persona 仅 owner 管理 (admin-only)
|
|
28808
|
+
"remote-persona:add": ADMIN_ANY,
|
|
28809
|
+
"remote-persona:list": ADMIN_ANY,
|
|
28810
|
+
"remote-persona:remove": ADMIN_ANY,
|
|
28324
28811
|
// ---- 业务方法:Phase 1 全 admin-only(owner 自动通过;guest 无法调用) ----
|
|
28325
28812
|
"session:create": ADMIN_ANY,
|
|
28326
28813
|
"session:list": ADMIN_ANY,
|
|
@@ -28451,6 +28938,18 @@ async function startDaemon(config) {
|
|
|
28451
28938
|
}
|
|
28452
28939
|
}
|
|
28453
28940
|
});
|
|
28941
|
+
const inboxStore = new InboxStore(config.dataDir);
|
|
28942
|
+
const remotePersonaStore = new RemotePersonaStore(config.dataDir);
|
|
28943
|
+
const inboxManager = new InboxManager(inboxStore, (frame) => {
|
|
28944
|
+
if (frame.event.kind === "direct-message") {
|
|
28945
|
+
const fromId = frame.event.fromPrincipal.id;
|
|
28946
|
+
const toId = frame.event.toPrincipal.id;
|
|
28947
|
+
wsServer?.broadcastToPrincipal(fromId, frame);
|
|
28948
|
+
if (toId !== fromId) wsServer?.broadcastToPrincipal(toId, frame);
|
|
28949
|
+
return;
|
|
28950
|
+
}
|
|
28951
|
+
wsServer?.broadcastToOwners(frame);
|
|
28952
|
+
});
|
|
28454
28953
|
let wsServer = null;
|
|
28455
28954
|
const authGate = authMode === "first-message" ? new AuthGate({
|
|
28456
28955
|
shouldEnforce: buildShouldEnforce({ tunnel: config.tunnel }),
|
|
@@ -28640,7 +29139,13 @@ async function startDaemon(config) {
|
|
|
28640
29139
|
}
|
|
28641
29140
|
},
|
|
28642
29141
|
// Task 1.9: capability:issue/list/revoke handler 依赖
|
|
28643
|
-
capabilityManager
|
|
29142
|
+
capabilityManager,
|
|
29143
|
+
// Phase 4 Task 4.2: inbox:postMessage 要查 capabilityRegistry 解析 peer Principal
|
|
29144
|
+
capabilityRegistry,
|
|
29145
|
+
// Phase 3 Task 3.4: inbox:list/markRead handler 依赖
|
|
29146
|
+
inboxManager,
|
|
29147
|
+
// Phase 4 Task 4.3: remote-persona:* handler 依赖 (本地存储, v1 不接 outgoing WS)
|
|
29148
|
+
remotePersonaStore
|
|
28644
29149
|
});
|
|
28645
29150
|
const authResolver = new AuthContextResolver({
|
|
28646
29151
|
ownerToken: resolvedAuthToken,
|
package/package.json
CHANGED