@clawos-dev/clawd 0.2.293 → 0.2.295
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
CHANGED
|
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
|
|
|
450
450
|
init_errors();
|
|
451
451
|
init_en();
|
|
452
452
|
makeIssue = (params) => {
|
|
453
|
-
const { data, path:
|
|
454
|
-
const fullPath = [...
|
|
453
|
+
const { data, path: path79, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path79, ...issueData.path || []];
|
|
455
455
|
const fullIssue = {
|
|
456
456
|
...issueData,
|
|
457
457
|
path: fullPath
|
|
@@ -762,11 +762,11 @@ var init_types = __esm({
|
|
|
762
762
|
init_parseUtil();
|
|
763
763
|
init_util();
|
|
764
764
|
ParseInputLazyPath = class {
|
|
765
|
-
constructor(parent, value,
|
|
765
|
+
constructor(parent, value, path79, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path79;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -7034,8 +7034,10 @@ var init_schemas = __esm({
|
|
|
7034
7034
|
* 由 daemon lark-bot-connector 模块写入,UI 只读(sidebar 按此字段隐藏,Drawer 群清单按此聚合)。
|
|
7035
7035
|
*/
|
|
7036
7036
|
larkChatId: external_exports.string().min(1).optional(),
|
|
7037
|
-
/**
|
|
7037
|
+
/** 飞书会话名快照(展示用):群会话为群名、私聊会话为对方用户名;随事件更新,可能滞后 */
|
|
7038
7038
|
larkChatName: external_exports.string().min(1).optional(),
|
|
7039
|
+
/** lark 会话类型(spec 2026-08-06 P9):p2p 与群的 chat_id 形态无法区分,UI 文案分支需要。可选=兼容老数据(缺省按 group 展示) */
|
|
7040
|
+
larkChatType: external_exports.enum(["p2p", "group"]).optional(),
|
|
7039
7041
|
createdAt: external_exports.string().min(1),
|
|
7040
7042
|
updatedAt: external_exports.string().min(1)
|
|
7041
7043
|
});
|
|
@@ -8769,8 +8771,8 @@ var require_req = __commonJS({
|
|
|
8769
8771
|
if (req.originalUrl) {
|
|
8770
8772
|
_req.url = req.originalUrl;
|
|
8771
8773
|
} else {
|
|
8772
|
-
const
|
|
8773
|
-
_req.url = typeof
|
|
8774
|
+
const path79 = req.path;
|
|
8775
|
+
_req.url = typeof path79 === "string" ? path79 : req.url ? req.url.path || req.url : void 0;
|
|
8774
8776
|
}
|
|
8775
8777
|
if (req.query) {
|
|
8776
8778
|
_req.query = req.query;
|
|
@@ -8935,14 +8937,14 @@ var require_redact = __commonJS({
|
|
|
8935
8937
|
}
|
|
8936
8938
|
return obj;
|
|
8937
8939
|
}
|
|
8938
|
-
function parsePath(
|
|
8940
|
+
function parsePath(path79) {
|
|
8939
8941
|
const parts = [];
|
|
8940
8942
|
let current = "";
|
|
8941
8943
|
let inBrackets = false;
|
|
8942
8944
|
let inQuotes = false;
|
|
8943
8945
|
let quoteChar = "";
|
|
8944
|
-
for (let i = 0; i <
|
|
8945
|
-
const char =
|
|
8946
|
+
for (let i = 0; i < path79.length; i++) {
|
|
8947
|
+
const char = path79[i];
|
|
8946
8948
|
if (!inBrackets && char === ".") {
|
|
8947
8949
|
if (current) {
|
|
8948
8950
|
parts.push(current);
|
|
@@ -9073,10 +9075,10 @@ var require_redact = __commonJS({
|
|
|
9073
9075
|
return current;
|
|
9074
9076
|
}
|
|
9075
9077
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
9076
|
-
for (const
|
|
9077
|
-
const parts = parsePath(
|
|
9078
|
+
for (const path79 of paths) {
|
|
9079
|
+
const parts = parsePath(path79);
|
|
9078
9080
|
if (parts.includes("*")) {
|
|
9079
|
-
redactWildcardPath(obj, parts, censor,
|
|
9081
|
+
redactWildcardPath(obj, parts, censor, path79, remove);
|
|
9080
9082
|
} else {
|
|
9081
9083
|
if (remove) {
|
|
9082
9084
|
removeKey(obj, parts);
|
|
@@ -9161,8 +9163,8 @@ var require_redact = __commonJS({
|
|
|
9161
9163
|
}
|
|
9162
9164
|
} else {
|
|
9163
9165
|
if (afterWildcard.includes("*")) {
|
|
9164
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
9165
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
9166
|
+
const wrappedCensor = typeof censor === "function" ? (value, path79) => {
|
|
9167
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path79];
|
|
9166
9168
|
return censor(value, fullPath);
|
|
9167
9169
|
} : censor;
|
|
9168
9170
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -9197,8 +9199,8 @@ var require_redact = __commonJS({
|
|
|
9197
9199
|
return null;
|
|
9198
9200
|
}
|
|
9199
9201
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
9200
|
-
for (const
|
|
9201
|
-
const parts = parsePath(
|
|
9202
|
+
for (const path79 of pathsToClone) {
|
|
9203
|
+
const parts = parsePath(path79);
|
|
9202
9204
|
let current = pathStructure;
|
|
9203
9205
|
for (let i = 0; i < parts.length; i++) {
|
|
9204
9206
|
const part = parts[i];
|
|
@@ -9250,24 +9252,24 @@ var require_redact = __commonJS({
|
|
|
9250
9252
|
}
|
|
9251
9253
|
return cloneSelectively(obj, pathStructure);
|
|
9252
9254
|
}
|
|
9253
|
-
function validatePath(
|
|
9254
|
-
if (typeof
|
|
9255
|
+
function validatePath(path79) {
|
|
9256
|
+
if (typeof path79 !== "string") {
|
|
9255
9257
|
throw new Error("Paths must be (non-empty) strings");
|
|
9256
9258
|
}
|
|
9257
|
-
if (
|
|
9259
|
+
if (path79 === "") {
|
|
9258
9260
|
throw new Error("Invalid redaction path ()");
|
|
9259
9261
|
}
|
|
9260
|
-
if (
|
|
9261
|
-
throw new Error(`Invalid redaction path (${
|
|
9262
|
+
if (path79.includes("..")) {
|
|
9263
|
+
throw new Error(`Invalid redaction path (${path79})`);
|
|
9262
9264
|
}
|
|
9263
|
-
if (
|
|
9264
|
-
throw new Error(`Invalid redaction path (${
|
|
9265
|
+
if (path79.includes(",")) {
|
|
9266
|
+
throw new Error(`Invalid redaction path (${path79})`);
|
|
9265
9267
|
}
|
|
9266
9268
|
let bracketCount = 0;
|
|
9267
9269
|
let inQuotes = false;
|
|
9268
9270
|
let quoteChar = "";
|
|
9269
|
-
for (let i = 0; i <
|
|
9270
|
-
const char =
|
|
9271
|
+
for (let i = 0; i < path79.length; i++) {
|
|
9272
|
+
const char = path79[i];
|
|
9271
9273
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
9272
9274
|
if (!inQuotes) {
|
|
9273
9275
|
inQuotes = true;
|
|
@@ -9281,20 +9283,20 @@ var require_redact = __commonJS({
|
|
|
9281
9283
|
} else if (char === "]" && !inQuotes) {
|
|
9282
9284
|
bracketCount--;
|
|
9283
9285
|
if (bracketCount < 0) {
|
|
9284
|
-
throw new Error(`Invalid redaction path (${
|
|
9286
|
+
throw new Error(`Invalid redaction path (${path79})`);
|
|
9285
9287
|
}
|
|
9286
9288
|
}
|
|
9287
9289
|
}
|
|
9288
9290
|
if (bracketCount !== 0) {
|
|
9289
|
-
throw new Error(`Invalid redaction path (${
|
|
9291
|
+
throw new Error(`Invalid redaction path (${path79})`);
|
|
9290
9292
|
}
|
|
9291
9293
|
}
|
|
9292
9294
|
function validatePaths(paths) {
|
|
9293
9295
|
if (!Array.isArray(paths)) {
|
|
9294
9296
|
throw new TypeError("paths must be an array");
|
|
9295
9297
|
}
|
|
9296
|
-
for (const
|
|
9297
|
-
validatePath(
|
|
9298
|
+
for (const path79 of paths) {
|
|
9299
|
+
validatePath(path79);
|
|
9298
9300
|
}
|
|
9299
9301
|
}
|
|
9300
9302
|
function slowRedact(options = {}) {
|
|
@@ -9462,8 +9464,8 @@ var require_redaction = __commonJS({
|
|
|
9462
9464
|
if (shape[k2] === null) {
|
|
9463
9465
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
9464
9466
|
} else {
|
|
9465
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
9466
|
-
return censor(value, [k2, ...
|
|
9467
|
+
const wrappedCensor = typeof censor === "function" ? (value, path79) => {
|
|
9468
|
+
return censor(value, [k2, ...path79]);
|
|
9467
9469
|
} : censor;
|
|
9468
9470
|
o[k2] = Redact({
|
|
9469
9471
|
paths: shape[k2],
|
|
@@ -9681,10 +9683,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
9681
9683
|
var require_sonic_boom = __commonJS({
|
|
9682
9684
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
9683
9685
|
"use strict";
|
|
9684
|
-
var
|
|
9686
|
+
var fs69 = require("fs");
|
|
9685
9687
|
var EventEmitter3 = require("events");
|
|
9686
9688
|
var inherits = require("util").inherits;
|
|
9687
|
-
var
|
|
9689
|
+
var path79 = require("path");
|
|
9688
9690
|
var sleep2 = require_atomic_sleep();
|
|
9689
9691
|
var assert = require("assert");
|
|
9690
9692
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -9738,20 +9740,20 @@ var require_sonic_boom = __commonJS({
|
|
|
9738
9740
|
const mode = sonic.mode;
|
|
9739
9741
|
if (sonic.sync) {
|
|
9740
9742
|
try {
|
|
9741
|
-
if (sonic.mkdir)
|
|
9742
|
-
const fd =
|
|
9743
|
+
if (sonic.mkdir) fs69.mkdirSync(path79.dirname(file), { recursive: true });
|
|
9744
|
+
const fd = fs69.openSync(file, flags, mode);
|
|
9743
9745
|
fileOpened(null, fd);
|
|
9744
9746
|
} catch (err) {
|
|
9745
9747
|
fileOpened(err);
|
|
9746
9748
|
throw err;
|
|
9747
9749
|
}
|
|
9748
9750
|
} else if (sonic.mkdir) {
|
|
9749
|
-
|
|
9751
|
+
fs69.mkdir(path79.dirname(file), { recursive: true }, (err) => {
|
|
9750
9752
|
if (err) return fileOpened(err);
|
|
9751
|
-
|
|
9753
|
+
fs69.open(file, flags, mode, fileOpened);
|
|
9752
9754
|
});
|
|
9753
9755
|
} else {
|
|
9754
|
-
|
|
9756
|
+
fs69.open(file, flags, mode, fileOpened);
|
|
9755
9757
|
}
|
|
9756
9758
|
}
|
|
9757
9759
|
function SonicBoom(opts) {
|
|
@@ -9792,8 +9794,8 @@ var require_sonic_boom = __commonJS({
|
|
|
9792
9794
|
this.flush = flushBuffer;
|
|
9793
9795
|
this.flushSync = flushBufferSync;
|
|
9794
9796
|
this._actualWrite = actualWriteBuffer;
|
|
9795
|
-
fsWriteSync = () =>
|
|
9796
|
-
fsWrite = () =>
|
|
9797
|
+
fsWriteSync = () => fs69.writeSync(this.fd, this._writingBuf);
|
|
9798
|
+
fsWrite = () => fs69.write(this.fd, this._writingBuf, this.release);
|
|
9797
9799
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
9798
9800
|
this._writingBuf = "";
|
|
9799
9801
|
this.write = write;
|
|
@@ -9802,15 +9804,15 @@ var require_sonic_boom = __commonJS({
|
|
|
9802
9804
|
this._actualWrite = actualWrite;
|
|
9803
9805
|
fsWriteSync = () => {
|
|
9804
9806
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
9805
|
-
return
|
|
9807
|
+
return fs69.writeSync(this.fd, this._writingBuf);
|
|
9806
9808
|
}
|
|
9807
|
-
return
|
|
9809
|
+
return fs69.writeSync(this.fd, this._writingBuf, "utf8");
|
|
9808
9810
|
};
|
|
9809
9811
|
fsWrite = () => {
|
|
9810
9812
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
9811
|
-
return
|
|
9813
|
+
return fs69.write(this.fd, this._writingBuf, this.release);
|
|
9812
9814
|
}
|
|
9813
|
-
return
|
|
9815
|
+
return fs69.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
9814
9816
|
};
|
|
9815
9817
|
} else {
|
|
9816
9818
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -9867,7 +9869,7 @@ var require_sonic_boom = __commonJS({
|
|
|
9867
9869
|
}
|
|
9868
9870
|
}
|
|
9869
9871
|
if (this._fsync) {
|
|
9870
|
-
|
|
9872
|
+
fs69.fsyncSync(this.fd);
|
|
9871
9873
|
}
|
|
9872
9874
|
const len = this._len;
|
|
9873
9875
|
if (this._reopening) {
|
|
@@ -9981,7 +9983,7 @@ var require_sonic_boom = __commonJS({
|
|
|
9981
9983
|
const onDrain = () => {
|
|
9982
9984
|
if (!this._fsync) {
|
|
9983
9985
|
try {
|
|
9984
|
-
|
|
9986
|
+
fs69.fsync(this.fd, (err) => {
|
|
9985
9987
|
this._flushPending = false;
|
|
9986
9988
|
cb(err);
|
|
9987
9989
|
});
|
|
@@ -10083,7 +10085,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10083
10085
|
const fd = this.fd;
|
|
10084
10086
|
this.once("ready", () => {
|
|
10085
10087
|
if (fd !== this.fd) {
|
|
10086
|
-
|
|
10088
|
+
fs69.close(fd, (err) => {
|
|
10087
10089
|
if (err) {
|
|
10088
10090
|
return this.emit("error", err);
|
|
10089
10091
|
}
|
|
@@ -10132,7 +10134,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10132
10134
|
buf = this._bufs[0];
|
|
10133
10135
|
}
|
|
10134
10136
|
try {
|
|
10135
|
-
const n = Buffer.isBuffer(buf) ?
|
|
10137
|
+
const n = Buffer.isBuffer(buf) ? fs69.writeSync(this.fd, buf) : fs69.writeSync(this.fd, buf, "utf8");
|
|
10136
10138
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
10137
10139
|
buf = releasedBufObj.writingBuf;
|
|
10138
10140
|
this._len = releasedBufObj.len;
|
|
@@ -10148,7 +10150,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10148
10150
|
}
|
|
10149
10151
|
}
|
|
10150
10152
|
try {
|
|
10151
|
-
|
|
10153
|
+
fs69.fsyncSync(this.fd);
|
|
10152
10154
|
} catch {
|
|
10153
10155
|
}
|
|
10154
10156
|
}
|
|
@@ -10169,7 +10171,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10169
10171
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
10170
10172
|
}
|
|
10171
10173
|
try {
|
|
10172
|
-
const n =
|
|
10174
|
+
const n = fs69.writeSync(this.fd, buf);
|
|
10173
10175
|
buf = buf.subarray(n);
|
|
10174
10176
|
this._len = Math.max(this._len - n, 0);
|
|
10175
10177
|
if (buf.length <= 0) {
|
|
@@ -10197,13 +10199,13 @@ var require_sonic_boom = __commonJS({
|
|
|
10197
10199
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
10198
10200
|
if (this.sync) {
|
|
10199
10201
|
try {
|
|
10200
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
10202
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs69.writeSync(this.fd, this._writingBuf) : fs69.writeSync(this.fd, this._writingBuf, "utf8");
|
|
10201
10203
|
release(null, written);
|
|
10202
10204
|
} catch (err) {
|
|
10203
10205
|
release(err);
|
|
10204
10206
|
}
|
|
10205
10207
|
} else {
|
|
10206
|
-
|
|
10208
|
+
fs69.write(this.fd, this._writingBuf, release);
|
|
10207
10209
|
}
|
|
10208
10210
|
}
|
|
10209
10211
|
function actualWriteBuffer() {
|
|
@@ -10212,7 +10214,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10212
10214
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
10213
10215
|
if (this.sync) {
|
|
10214
10216
|
try {
|
|
10215
|
-
const written =
|
|
10217
|
+
const written = fs69.writeSync(this.fd, this._writingBuf);
|
|
10216
10218
|
release(null, written);
|
|
10217
10219
|
} catch (err) {
|
|
10218
10220
|
release(err);
|
|
@@ -10221,7 +10223,7 @@ var require_sonic_boom = __commonJS({
|
|
|
10221
10223
|
if (kCopyBuffer) {
|
|
10222
10224
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
10223
10225
|
}
|
|
10224
|
-
|
|
10226
|
+
fs69.write(this.fd, this._writingBuf, release);
|
|
10225
10227
|
}
|
|
10226
10228
|
}
|
|
10227
10229
|
function actualClose(sonic) {
|
|
@@ -10237,12 +10239,12 @@ var require_sonic_boom = __commonJS({
|
|
|
10237
10239
|
sonic._lens = [];
|
|
10238
10240
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
10239
10241
|
try {
|
|
10240
|
-
|
|
10242
|
+
fs69.fsync(sonic.fd, closeWrapped);
|
|
10241
10243
|
} catch {
|
|
10242
10244
|
}
|
|
10243
10245
|
function closeWrapped() {
|
|
10244
10246
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
10245
|
-
|
|
10247
|
+
fs69.close(sonic.fd, done);
|
|
10246
10248
|
} else {
|
|
10247
10249
|
done();
|
|
10248
10250
|
}
|
|
@@ -13377,11 +13379,11 @@ var init_lib = __esm({
|
|
|
13377
13379
|
}
|
|
13378
13380
|
}
|
|
13379
13381
|
},
|
|
13380
|
-
addToPath: function addToPath(
|
|
13381
|
-
var last =
|
|
13382
|
+
addToPath: function addToPath(path79, added, removed, oldPosInc, options) {
|
|
13383
|
+
var last = path79.lastComponent;
|
|
13382
13384
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
13383
13385
|
return {
|
|
13384
|
-
oldPos:
|
|
13386
|
+
oldPos: path79.oldPos + oldPosInc,
|
|
13385
13387
|
lastComponent: {
|
|
13386
13388
|
count: last.count + 1,
|
|
13387
13389
|
added,
|
|
@@ -13391,7 +13393,7 @@ var init_lib = __esm({
|
|
|
13391
13393
|
};
|
|
13392
13394
|
} else {
|
|
13393
13395
|
return {
|
|
13394
|
-
oldPos:
|
|
13396
|
+
oldPos: path79.oldPos + oldPosInc,
|
|
13395
13397
|
lastComponent: {
|
|
13396
13398
|
count: 1,
|
|
13397
13399
|
added,
|
|
@@ -13900,10 +13902,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
13900
13902
|
const memories = raw.map((m2) => {
|
|
13901
13903
|
if (!m2 || typeof m2 !== "object") return null;
|
|
13902
13904
|
const rec3 = m2;
|
|
13903
|
-
const
|
|
13905
|
+
const path79 = typeof rec3.path === "string" ? rec3.path : null;
|
|
13904
13906
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
13905
|
-
if (!
|
|
13906
|
-
const entry = { path:
|
|
13907
|
+
if (!path79 || content == null) return null;
|
|
13908
|
+
const entry = { path: path79, content };
|
|
13907
13909
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
13908
13910
|
return entry;
|
|
13909
13911
|
}).filter((m2) => m2 !== null);
|
|
@@ -14720,10 +14722,10 @@ function parseAttachment(obj) {
|
|
|
14720
14722
|
const memories = raw.map((m2) => {
|
|
14721
14723
|
if (!m2 || typeof m2 !== "object") return null;
|
|
14722
14724
|
const rec3 = m2;
|
|
14723
|
-
const
|
|
14725
|
+
const path79 = typeof rec3.path === "string" ? rec3.path : null;
|
|
14724
14726
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
14725
|
-
if (!
|
|
14726
|
-
const out = { path:
|
|
14727
|
+
if (!path79 || content == null) return null;
|
|
14728
|
+
const out = { path: path79, content };
|
|
14727
14729
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
14728
14730
|
return out;
|
|
14729
14731
|
}).filter((m2) => m2 !== null);
|
|
@@ -35692,8 +35694,8 @@ var require_utils = __commonJS({
|
|
|
35692
35694
|
var result = transform[inputType][outputType](input);
|
|
35693
35695
|
return result;
|
|
35694
35696
|
};
|
|
35695
|
-
exports2.resolve = function(
|
|
35696
|
-
var parts =
|
|
35697
|
+
exports2.resolve = function(path79) {
|
|
35698
|
+
var parts = path79.split("/");
|
|
35697
35699
|
var result = [];
|
|
35698
35700
|
for (var index = 0; index < parts.length; index++) {
|
|
35699
35701
|
var part = parts[index];
|
|
@@ -41546,18 +41548,18 @@ var require_object = __commonJS({
|
|
|
41546
41548
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
41547
41549
|
this.files[name] = object;
|
|
41548
41550
|
};
|
|
41549
|
-
var parentFolder = function(
|
|
41550
|
-
if (
|
|
41551
|
-
|
|
41551
|
+
var parentFolder = function(path79) {
|
|
41552
|
+
if (path79.slice(-1) === "/") {
|
|
41553
|
+
path79 = path79.substring(0, path79.length - 1);
|
|
41552
41554
|
}
|
|
41553
|
-
var lastSlash =
|
|
41554
|
-
return lastSlash > 0 ?
|
|
41555
|
+
var lastSlash = path79.lastIndexOf("/");
|
|
41556
|
+
return lastSlash > 0 ? path79.substring(0, lastSlash) : "";
|
|
41555
41557
|
};
|
|
41556
|
-
var forceTrailingSlash = function(
|
|
41557
|
-
if (
|
|
41558
|
-
|
|
41558
|
+
var forceTrailingSlash = function(path79) {
|
|
41559
|
+
if (path79.slice(-1) !== "/") {
|
|
41560
|
+
path79 += "/";
|
|
41559
41561
|
}
|
|
41560
|
-
return
|
|
41562
|
+
return path79;
|
|
41561
41563
|
};
|
|
41562
41564
|
var folderAdd = function(name, createFolders) {
|
|
41563
41565
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -42559,7 +42561,7 @@ var require_lib3 = __commonJS({
|
|
|
42559
42561
|
// src/run-case/recorder.ts
|
|
42560
42562
|
function startRunCaseRecorder(opts) {
|
|
42561
42563
|
const now = opts.now ?? Date.now;
|
|
42562
|
-
const dir =
|
|
42564
|
+
const dir = import_node_path66.default.dirname(opts.recordPath);
|
|
42563
42565
|
let stream = null;
|
|
42564
42566
|
let closing = false;
|
|
42565
42567
|
let closedSettled = false;
|
|
@@ -42573,8 +42575,8 @@ function startRunCaseRecorder(opts) {
|
|
|
42573
42575
|
});
|
|
42574
42576
|
const ensureStream = () => {
|
|
42575
42577
|
if (stream) return stream;
|
|
42576
|
-
|
|
42577
|
-
stream =
|
|
42578
|
+
import_node_fs50.default.mkdirSync(dir, { recursive: true });
|
|
42579
|
+
stream = import_node_fs50.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
42578
42580
|
stream.on("close", () => closedResolve());
|
|
42579
42581
|
return stream;
|
|
42580
42582
|
};
|
|
@@ -42599,12 +42601,12 @@ function startRunCaseRecorder(opts) {
|
|
|
42599
42601
|
};
|
|
42600
42602
|
return { tap, close, closed };
|
|
42601
42603
|
}
|
|
42602
|
-
var
|
|
42604
|
+
var import_node_fs50, import_node_path66;
|
|
42603
42605
|
var init_recorder = __esm({
|
|
42604
42606
|
"src/run-case/recorder.ts"() {
|
|
42605
42607
|
"use strict";
|
|
42606
|
-
|
|
42607
|
-
|
|
42608
|
+
import_node_fs50 = __toESM(require("fs"), 1);
|
|
42609
|
+
import_node_path66 = __toESM(require("path"), 1);
|
|
42608
42610
|
}
|
|
42609
42611
|
});
|
|
42610
42612
|
|
|
@@ -42647,7 +42649,7 @@ var init_wire = __esm({
|
|
|
42647
42649
|
// src/run-case/controller.ts
|
|
42648
42650
|
async function runController(opts) {
|
|
42649
42651
|
const now = opts.now ?? Date.now;
|
|
42650
|
-
const cwd = opts.cwd ?? (0,
|
|
42652
|
+
const cwd = opts.cwd ?? (0, import_node_fs51.mkdtempSync)(import_node_path67.default.join(import_node_os23.default.tmpdir(), "clawd-runcase-"));
|
|
42651
42653
|
const ownsCwd = opts.cwd === void 0;
|
|
42652
42654
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
42653
42655
|
const spawnCtx = { cwd };
|
|
@@ -42808,19 +42810,19 @@ async function runController(opts) {
|
|
|
42808
42810
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
42809
42811
|
if (ownsCwd) {
|
|
42810
42812
|
try {
|
|
42811
|
-
(0,
|
|
42813
|
+
(0, import_node_fs51.rmSync)(cwd, { recursive: true, force: true });
|
|
42812
42814
|
} catch {
|
|
42813
42815
|
}
|
|
42814
42816
|
}
|
|
42815
42817
|
return exitCode ?? 0;
|
|
42816
42818
|
}
|
|
42817
|
-
var
|
|
42819
|
+
var import_node_fs51, import_node_os23, import_node_path67;
|
|
42818
42820
|
var init_controller = __esm({
|
|
42819
42821
|
"src/run-case/controller.ts"() {
|
|
42820
42822
|
"use strict";
|
|
42821
|
-
|
|
42823
|
+
import_node_fs51 = require("fs");
|
|
42822
42824
|
import_node_os23 = __toESM(require("os"), 1);
|
|
42823
|
-
|
|
42825
|
+
import_node_path67 = __toESM(require("path"), 1);
|
|
42824
42826
|
init_claude();
|
|
42825
42827
|
init_stdout_splitter();
|
|
42826
42828
|
init_permission_stdio();
|
|
@@ -43095,8 +43097,8 @@ Env (advanced):
|
|
|
43095
43097
|
`;
|
|
43096
43098
|
|
|
43097
43099
|
// src/index.ts
|
|
43098
|
-
var
|
|
43099
|
-
var
|
|
43100
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
43101
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
43100
43102
|
var import_node_os22 = __toESM(require("os"), 1);
|
|
43101
43103
|
|
|
43102
43104
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -43778,6 +43780,9 @@ var FORCED_DENY_READ = ["~/"];
|
|
|
43778
43780
|
function personaEditDeny(personaDir) {
|
|
43779
43781
|
return `Edit(${tildePath(personaDir)}/**)`;
|
|
43780
43782
|
}
|
|
43783
|
+
function personaReadAllow(personaDir) {
|
|
43784
|
+
return `Read(${tildePath(personaDir)}/**)`;
|
|
43785
|
+
}
|
|
43781
43786
|
function tildePath(p2) {
|
|
43782
43787
|
const home = (0, import_node_os2.homedir)();
|
|
43783
43788
|
return p2.startsWith(`${home}/`) ? `~${p2.slice(home.length)}` : p2;
|
|
@@ -43850,6 +43855,7 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
43850
43855
|
fsv.denyWrite = unionArr((fsv.denyWrite ?? []).filter((p2) => p2 !== "~/"), [spawnCwd]);
|
|
43851
43856
|
fsv.allowRead = unionArr(fsv.allowRead, [userWorkDir]);
|
|
43852
43857
|
fsv.allowWrite = unionArr(fsv.allowWrite, [userWorkDir]);
|
|
43858
|
+
s.permissions.allow = unionArr(s.permissions.allow, [`Read(${tildePath(userWorkDir)}/**)`]);
|
|
43853
43859
|
return s;
|
|
43854
43860
|
}
|
|
43855
43861
|
|
|
@@ -43995,17 +44001,24 @@ function extractLarkReplyText(events) {
|
|
|
43995
44001
|
break;
|
|
43996
44002
|
}
|
|
43997
44003
|
}
|
|
43998
|
-
const
|
|
44004
|
+
const texts = events.slice(lastUserIdx + 1).filter((ev) => ev.kind === "text");
|
|
44005
|
+
const snapshots = texts.filter((ev) => !ev.partialId);
|
|
44006
|
+
if (snapshots.length > 0) {
|
|
44007
|
+
return snapshots.map((ev) => ev.text).filter((t) => t.length > 0).join("\n").trim();
|
|
44008
|
+
}
|
|
43999
44009
|
const order = [];
|
|
44000
|
-
const
|
|
44001
|
-
|
|
44002
|
-
|
|
44003
|
-
|
|
44004
|
-
|
|
44005
|
-
|
|
44006
|
-
|
|
44010
|
+
const chunks = /* @__PURE__ */ new Map();
|
|
44011
|
+
for (const ev of texts) {
|
|
44012
|
+
const key = ev.partialId ?? "";
|
|
44013
|
+
let list = chunks.get(key);
|
|
44014
|
+
if (!list) {
|
|
44015
|
+
list = [];
|
|
44016
|
+
chunks.set(key, list);
|
|
44017
|
+
order.push(key);
|
|
44018
|
+
}
|
|
44019
|
+
list.push(ev.text);
|
|
44007
44020
|
}
|
|
44008
|
-
return order.map((k2) =>
|
|
44021
|
+
return order.map((k2) => (chunks.get(k2) ?? []).join("")).filter((t) => t.length > 0).join("\n").trim();
|
|
44009
44022
|
}
|
|
44010
44023
|
|
|
44011
44024
|
// src/session/runner.ts
|
|
@@ -47181,8 +47194,9 @@ var SessionManager = class {
|
|
|
47181
47194
|
// guest 三件套:creatorPrincipalId=capId(scopeForFile 回落防线)、
|
|
47182
47195
|
// creatorDisplayName(reducer guest 分支硬性要求,缺则 spawn 抛)
|
|
47183
47196
|
creatorPrincipalId: capId,
|
|
47184
|
-
creatorDisplayName:
|
|
47197
|
+
creatorDisplayName: `${(args.chatType ?? "group") === "p2p" ? "\u98DE\u4E66\u79C1\u804A" : "\u98DE\u4E66\u7FA4"}\xB7${args.chatName ?? args.chatId}`,
|
|
47185
47198
|
larkChatId: args.chatId,
|
|
47199
|
+
larkChatType: args.chatType ?? "group",
|
|
47186
47200
|
...args.chatName ? { larkChatName: args.chatName } : {},
|
|
47187
47201
|
createdAt: now,
|
|
47188
47202
|
updatedAt: now
|
|
@@ -47752,7 +47766,10 @@ var PersonaStore = class {
|
|
|
47752
47766
|
/**
|
|
47753
47767
|
* persona 基线注入:Edit-deny(绝对 '~/<persona>/**')并进 permissions.deny + 剥掉历史相对
|
|
47754
47768
|
* 'Edit(./**)';persona 目录 '~/' 路径 union 进 sandbox.filesystem.allowRead(guest 读权
|
|
47755
|
-
* 落盘即真源,compose 不再运行时注入——spec 2026-08-06-persona-workdir-discipline §1-§2
|
|
47769
|
+
* 落盘即真源,compose 不再运行时注入——spec 2026-08-06-persona-workdir-discipline §1-§2);
|
|
47770
|
+
* `Read(~/<persona>/**)` union 进 permissions.allow——OS 沙箱层可读只放行了 Bash,CC 自带
|
|
47771
|
+
* Read 工具在最严格 base(dontAsk + 无 allow)下仍被拒,工具层与 OS 层必须同构放行
|
|
47772
|
+
* (guest「自由读 persona 目录、只写自己 userWorkDir」,spec 2026-08-06-lark-dm §P10 通用化)。
|
|
47756
47773
|
*/
|
|
47757
47774
|
injectPersonaBaseline(personaId2, settings) {
|
|
47758
47775
|
const dir = this.personaDir(personaId2);
|
|
@@ -47760,6 +47777,9 @@ var PersonaStore = class {
|
|
|
47760
47777
|
const rule = personaEditDeny(dir);
|
|
47761
47778
|
const rawDeny = s.permissions && typeof s.permissions === "object" ? s.permissions.deny : void 0;
|
|
47762
47779
|
const prevDeny = (Array.isArray(rawDeny) ? rawDeny : []).filter((r) => r !== "Edit(./**)" && r !== rule);
|
|
47780
|
+
const readRule = personaReadAllow(dir);
|
|
47781
|
+
const rawAllow = s.permissions && typeof s.permissions === "object" ? s.permissions.allow : void 0;
|
|
47782
|
+
const prevAllow = (Array.isArray(rawAllow) ? rawAllow : []).filter((r) => r !== readRule);
|
|
47763
47783
|
const readPath = tildePath(dir);
|
|
47764
47784
|
const sandbox = s.sandbox && typeof s.sandbox === "object" && !Array.isArray(s.sandbox) ? s.sandbox : {};
|
|
47765
47785
|
const rawFs = sandbox.filesystem;
|
|
@@ -47770,6 +47790,7 @@ var PersonaStore = class {
|
|
|
47770
47790
|
...s,
|
|
47771
47791
|
permissions: {
|
|
47772
47792
|
...s.permissions && typeof s.permissions === "object" ? s.permissions : {},
|
|
47793
|
+
allow: [...prevAllow, readRule],
|
|
47773
47794
|
deny: [...prevDeny, rule]
|
|
47774
47795
|
},
|
|
47775
47796
|
sandbox: { ...sandbox, filesystem: { ...filesystem, allowRead: [...prevRead, readPath] } }
|
|
@@ -48654,7 +48675,10 @@ function migrateSandboxAllowRead(args) {
|
|
|
48654
48675
|
continue;
|
|
48655
48676
|
}
|
|
48656
48677
|
const allowRead = raw.sandbox?.filesystem?.allowRead;
|
|
48657
|
-
|
|
48678
|
+
const permAllow = raw.permissions?.allow;
|
|
48679
|
+
const readRule = personaReadAllow(args.store.personaDirPath(personaId2));
|
|
48680
|
+
if (Array.isArray(allowRead) && allowRead.includes(readPath) && Array.isArray(permAllow) && permAllow.includes(readRule))
|
|
48681
|
+
continue;
|
|
48658
48682
|
args.store.writeSandboxSettings(personaId2, raw);
|
|
48659
48683
|
n++;
|
|
48660
48684
|
args.logger.info("persona.sandbox.allow-read.migrated", { personaId: personaId2 });
|
|
@@ -49301,8 +49325,8 @@ function turnStartInput(text) {
|
|
|
49301
49325
|
const items = [];
|
|
49302
49326
|
let leftover = text;
|
|
49303
49327
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
49304
|
-
const [marker, name,
|
|
49305
|
-
items.push({ type: "skill", name, path:
|
|
49328
|
+
const [marker, name, path79] = m2;
|
|
49329
|
+
items.push({ type: "skill", name, path: path79 });
|
|
49306
49330
|
leftover = leftover.replace(marker, "");
|
|
49307
49331
|
}
|
|
49308
49332
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -51996,14 +52020,62 @@ function createLarkBotCloudClient(opts) {
|
|
|
51996
52020
|
async claimEvents() {
|
|
51997
52021
|
const json = await request("POST", "/api/lark-bot/events/claim");
|
|
51998
52022
|
return json.items ?? [];
|
|
52023
|
+
},
|
|
52024
|
+
async fetchResource(appId, messageId, fileKey, maxBytes) {
|
|
52025
|
+
const ac = new AbortController();
|
|
52026
|
+
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 15e3);
|
|
52027
|
+
const qs = new URLSearchParams({
|
|
52028
|
+
appId,
|
|
52029
|
+
messageId,
|
|
52030
|
+
fileKey,
|
|
52031
|
+
...maxBytes ? { maxBytes: String(maxBytes) } : {}
|
|
52032
|
+
}).toString();
|
|
52033
|
+
let res;
|
|
52034
|
+
try {
|
|
52035
|
+
res = await f(`${base}/api/lark-bot/resource?${qs}`, {
|
|
52036
|
+
method: "GET",
|
|
52037
|
+
signal: ac.signal,
|
|
52038
|
+
headers: {
|
|
52039
|
+
authorization: `Bearer ${opts.apiKey}`,
|
|
52040
|
+
"x-did": encodeURIComponent(opts.deviceId),
|
|
52041
|
+
"x-name": encodeURIComponent(opts.displayName),
|
|
52042
|
+
"x-scene": "daemon"
|
|
52043
|
+
}
|
|
52044
|
+
});
|
|
52045
|
+
} catch (err) {
|
|
52046
|
+
throw new LarkBotCloudError(`lark-bot cloud resource fetch failed: ${err.message}`);
|
|
52047
|
+
} finally {
|
|
52048
|
+
clearTimeout(timer);
|
|
52049
|
+
}
|
|
52050
|
+
if (!res.ok) {
|
|
52051
|
+
throw new LarkBotCloudError(`lark-bot cloud resource: HTTP ${res.status}`, res.status);
|
|
52052
|
+
}
|
|
52053
|
+
const data = Buffer.from(await res.arrayBuffer());
|
|
52054
|
+
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
52055
|
+
return { data, contentType };
|
|
51999
52056
|
}
|
|
52000
52057
|
};
|
|
52001
52058
|
}
|
|
52002
52059
|
|
|
52003
52060
|
// src/lark-bot-connector/chat-router.ts
|
|
52061
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
52062
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
52004
52063
|
init_protocol();
|
|
52005
52064
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
52006
52065
|
var DEFAULT_TURN_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
52066
|
+
var MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
52067
|
+
var EXT_BY_MIME = {
|
|
52068
|
+
"image/png": "png",
|
|
52069
|
+
"image/jpeg": "jpg",
|
|
52070
|
+
"image/gif": "gif",
|
|
52071
|
+
"image/webp": "webp"
|
|
52072
|
+
};
|
|
52073
|
+
var IMAGE_OVERSIZE_TEXT = "[\u56FE\u7247\u6D88\u606F\uFF0C\u8D85\u51FA\u5927\u5C0F\u9650\u5236]";
|
|
52074
|
+
var IMAGE_UNAVAILABLE_TEXT = "[\u56FE\u7247\u6D88\u606F\uFF0C\u6682\u4E0D\u652F\u6301\u67E5\u770B]";
|
|
52075
|
+
function safeMediaName(raw) {
|
|
52076
|
+
const cleaned = raw.replace(/[^a-zA-Z0-9_\-.]/g, "_").replace(/^\.+/, (d) => "_".repeat(d.length));
|
|
52077
|
+
return (cleaned || "msg").replace(/\.\./g, "__");
|
|
52078
|
+
}
|
|
52007
52079
|
function createLarkChatRouter(deps) {
|
|
52008
52080
|
const timeoutMs = deps.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;
|
|
52009
52081
|
const replyDelays = deps.replyRetryDelaysMs ?? [2e3, 8e3, 3e4];
|
|
@@ -52016,7 +52088,34 @@ function createLarkChatRouter(deps) {
|
|
|
52016
52088
|
return;
|
|
52017
52089
|
}
|
|
52018
52090
|
const speaker = env.senderName || env.senderOpenId || "\u672A\u77E5\u6210\u5458";
|
|
52019
|
-
const
|
|
52091
|
+
const imageLines = [];
|
|
52092
|
+
for (const [i, key] of (env.imageKeys ?? []).entries()) {
|
|
52093
|
+
try {
|
|
52094
|
+
if (!deps.fetchResource || !deps.mediaRootFor) throw new Error("resource pipeline not wired");
|
|
52095
|
+
const r = await deps.fetchResource(env.appId, env.messageId, key, MAX_IMAGE_BYTES);
|
|
52096
|
+
if (r.data.byteLength > MAX_IMAGE_BYTES) {
|
|
52097
|
+
deps.logger?.warn(`larkBot image oversize ${key}: ${r.data.byteLength}B`);
|
|
52098
|
+
imageLines.push(IMAGE_OVERSIZE_TEXT);
|
|
52099
|
+
continue;
|
|
52100
|
+
}
|
|
52101
|
+
const ext = EXT_BY_MIME[r.contentType];
|
|
52102
|
+
if (!ext) {
|
|
52103
|
+
deps.logger?.warn(`larkBot image unsupported mime ${key}: ${r.contentType}`);
|
|
52104
|
+
imageLines.push(IMAGE_UNAVAILABLE_TEXT);
|
|
52105
|
+
continue;
|
|
52106
|
+
}
|
|
52107
|
+
const dir = deps.mediaRootFor(env.chatId);
|
|
52108
|
+
import_node_fs27.default.mkdirSync(dir, { recursive: true });
|
|
52109
|
+
const p2 = import_node_path28.default.join(dir, `${safeMediaName(env.messageId)}-${i}.${ext}`);
|
|
52110
|
+
import_node_fs27.default.writeFileSync(p2, r.data);
|
|
52111
|
+
imageLines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
52112
|
+
} catch (err) {
|
|
52113
|
+
deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
|
|
52114
|
+
imageLines.push(IMAGE_UNAVAILABLE_TEXT);
|
|
52115
|
+
}
|
|
52116
|
+
}
|
|
52117
|
+
const rawBody = [env.text?.trim(), ...imageLines].filter(Boolean).join("\n");
|
|
52118
|
+
const body = rawBody || "[\u975E\u6587\u672C\u6D88\u606F]";
|
|
52020
52119
|
const text = `${body}
|
|
52021
52120
|
|
|
52022
52121
|
${formatLarkSpeakerReminder(speaker)}`;
|
|
@@ -52024,6 +52123,7 @@ ${formatLarkSpeakerReminder(speaker)}`;
|
|
|
52024
52123
|
personaId: env.personaId,
|
|
52025
52124
|
chatId: env.chatId,
|
|
52026
52125
|
chatName: env.chatName,
|
|
52126
|
+
chatType: env.chatType ?? "group",
|
|
52027
52127
|
senderOpenId: env.senderOpenId ?? "",
|
|
52028
52128
|
senderName: env.senderName ?? env.senderOpenId ?? "\u672A\u77E5\u6210\u5458",
|
|
52029
52129
|
text
|
|
@@ -52786,7 +52886,7 @@ var CodexHistoryReader = class {
|
|
|
52786
52886
|
};
|
|
52787
52887
|
|
|
52788
52888
|
// src/tools/codex-skills.ts
|
|
52789
|
-
var
|
|
52889
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
52790
52890
|
function str3(v2) {
|
|
52791
52891
|
return typeof v2 === "string" ? v2 : void 0;
|
|
52792
52892
|
}
|
|
@@ -52801,13 +52901,13 @@ function mapSkillsListResponse(res) {
|
|
|
52801
52901
|
const r = s ?? {};
|
|
52802
52902
|
const name = str3(r.name);
|
|
52803
52903
|
if (!name) continue;
|
|
52804
|
-
const
|
|
52904
|
+
const path79 = str3(r.path);
|
|
52805
52905
|
const description = str3(r.description);
|
|
52806
52906
|
const isPlugin = name.includes(":");
|
|
52807
52907
|
out.push({
|
|
52808
52908
|
name,
|
|
52809
52909
|
source: isPlugin ? "plugin" : "project",
|
|
52810
|
-
...
|
|
52910
|
+
...path79 ? { path: path79 } : {},
|
|
52811
52911
|
...description ? { description } : {},
|
|
52812
52912
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
52813
52913
|
});
|
|
@@ -52823,30 +52923,30 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
52823
52923
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
52824
52924
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
52825
52925
|
beforeRequest: (client) => {
|
|
52826
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
52926
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path29.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
52827
52927
|
}
|
|
52828
52928
|
});
|
|
52829
52929
|
return mapSkillsListResponse(res);
|
|
52830
52930
|
}
|
|
52831
52931
|
|
|
52832
52932
|
// src/workspace/browser.ts
|
|
52833
|
-
var
|
|
52933
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
52834
52934
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
52835
|
-
var
|
|
52935
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
52836
52936
|
init_protocol();
|
|
52837
52937
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
52838
52938
|
function resolveInsideCwd(cwd, subpath) {
|
|
52839
|
-
const absCwd =
|
|
52840
|
-
const joined =
|
|
52841
|
-
const rel =
|
|
52842
|
-
if (rel.startsWith("..") ||
|
|
52939
|
+
const absCwd = import_node_path30.default.resolve(cwd);
|
|
52940
|
+
const joined = import_node_path30.default.resolve(absCwd, subpath ?? ".");
|
|
52941
|
+
const rel = import_node_path30.default.relative(absCwd, joined);
|
|
52942
|
+
if (rel.startsWith("..") || import_node_path30.default.isAbsolute(rel)) {
|
|
52843
52943
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
52844
52944
|
}
|
|
52845
52945
|
return joined;
|
|
52846
52946
|
}
|
|
52847
52947
|
function ensureCwd(cwd) {
|
|
52848
52948
|
try {
|
|
52849
|
-
const stat =
|
|
52949
|
+
const stat = import_node_fs28.default.statSync(cwd);
|
|
52850
52950
|
if (!stat.isDirectory()) {
|
|
52851
52951
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
52852
52952
|
}
|
|
@@ -52860,7 +52960,7 @@ var WorkspaceBrowser = class {
|
|
|
52860
52960
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
52861
52961
|
ensureCwd(cwd);
|
|
52862
52962
|
const full = resolveInsideCwd(cwd, args.path);
|
|
52863
|
-
const dirents =
|
|
52963
|
+
const dirents = import_node_fs28.default.readdirSync(full, { withFileTypes: true });
|
|
52864
52964
|
const entries = [];
|
|
52865
52965
|
for (const d of dirents) {
|
|
52866
52966
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -52870,7 +52970,7 @@ var WorkspaceBrowser = class {
|
|
|
52870
52970
|
mtime: ""
|
|
52871
52971
|
};
|
|
52872
52972
|
try {
|
|
52873
|
-
const st =
|
|
52973
|
+
const st = import_node_fs28.default.statSync(import_node_path30.default.join(full, d.name));
|
|
52874
52974
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
52875
52975
|
if (d.isFile()) entry.size = st.size;
|
|
52876
52976
|
} catch {
|
|
@@ -52886,14 +52986,14 @@ var WorkspaceBrowser = class {
|
|
|
52886
52986
|
read(args) {
|
|
52887
52987
|
ensureCwd(args.cwd);
|
|
52888
52988
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
52889
|
-
const st =
|
|
52989
|
+
const st = import_node_fs28.default.statSync(full);
|
|
52890
52990
|
if (!st.isFile()) {
|
|
52891
52991
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
52892
52992
|
}
|
|
52893
52993
|
if (st.size > MAX_FILE_BYTES) {
|
|
52894
52994
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
52895
52995
|
}
|
|
52896
|
-
const buf =
|
|
52996
|
+
const buf = import_node_fs28.default.readFileSync(full);
|
|
52897
52997
|
const isBinary = buf.includes(0);
|
|
52898
52998
|
if (isBinary) {
|
|
52899
52999
|
return {
|
|
@@ -52915,20 +53015,20 @@ var WorkspaceBrowser = class {
|
|
|
52915
53015
|
};
|
|
52916
53016
|
|
|
52917
53017
|
// src/skills/agents-scanner.ts
|
|
52918
|
-
var
|
|
53018
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
52919
53019
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
52920
|
-
var
|
|
53020
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
52921
53021
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
52922
53022
|
function isDirLikeSync2(p2) {
|
|
52923
53023
|
try {
|
|
52924
|
-
return
|
|
53024
|
+
return import_node_fs29.default.statSync(p2).isDirectory();
|
|
52925
53025
|
} catch {
|
|
52926
53026
|
return false;
|
|
52927
53027
|
}
|
|
52928
53028
|
}
|
|
52929
53029
|
function fileExistsSync(p2) {
|
|
52930
53030
|
try {
|
|
52931
|
-
return
|
|
53031
|
+
return import_node_fs29.default.statSync(p2).isFile();
|
|
52932
53032
|
} catch {
|
|
52933
53033
|
return false;
|
|
52934
53034
|
}
|
|
@@ -52936,7 +53036,7 @@ function fileExistsSync(p2) {
|
|
|
52936
53036
|
function parseAgentFile(filePath) {
|
|
52937
53037
|
let content;
|
|
52938
53038
|
try {
|
|
52939
|
-
content =
|
|
53039
|
+
content = import_node_fs29.default.readFileSync(filePath, "utf8");
|
|
52940
53040
|
} catch {
|
|
52941
53041
|
return {};
|
|
52942
53042
|
}
|
|
@@ -52949,16 +53049,16 @@ function parseAgentFile(filePath) {
|
|
|
52949
53049
|
function scanAgentsDir(dir, source, seen, out) {
|
|
52950
53050
|
let entries;
|
|
52951
53051
|
try {
|
|
52952
|
-
entries =
|
|
53052
|
+
entries = import_node_fs29.default.readdirSync(dir, { withFileTypes: true });
|
|
52953
53053
|
} catch {
|
|
52954
53054
|
return;
|
|
52955
53055
|
}
|
|
52956
53056
|
for (const ent of entries) {
|
|
52957
53057
|
if (!ent.name.endsWith(".md")) continue;
|
|
52958
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
53058
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path31.default.join(dir, ent.name)))) {
|
|
52959
53059
|
continue;
|
|
52960
53060
|
}
|
|
52961
|
-
const filePath =
|
|
53061
|
+
const filePath = import_node_path31.default.join(dir, ent.name);
|
|
52962
53062
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
52963
53063
|
if (seen.has(baseName)) continue;
|
|
52964
53064
|
seen.add(baseName);
|
|
@@ -52976,12 +53076,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
52976
53076
|
function walk2(dir, namespaces) {
|
|
52977
53077
|
let entries;
|
|
52978
53078
|
try {
|
|
52979
|
-
entries =
|
|
53079
|
+
entries = import_node_fs29.default.readdirSync(dir, { withFileTypes: true });
|
|
52980
53080
|
} catch {
|
|
52981
53081
|
return;
|
|
52982
53082
|
}
|
|
52983
53083
|
for (const ent of entries) {
|
|
52984
|
-
const childPath =
|
|
53084
|
+
const childPath = import_node_path31.default.join(dir, ent.name);
|
|
52985
53085
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
52986
53086
|
walk2(childPath, [...namespaces, ent.name]);
|
|
52987
53087
|
continue;
|
|
@@ -53006,13 +53106,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
53006
53106
|
walk2(root, []);
|
|
53007
53107
|
}
|
|
53008
53108
|
function readInstalledPlugins2(home) {
|
|
53009
|
-
const pluginsDir =
|
|
53010
|
-
const v2 =
|
|
53011
|
-
const v1 =
|
|
53109
|
+
const pluginsDir = import_node_path31.default.join(home, ".claude", "plugins");
|
|
53110
|
+
const v2 = import_node_path31.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
53111
|
+
const v1 = import_node_path31.default.join(pluginsDir, "installed_plugins.json");
|
|
53012
53112
|
let raw = null;
|
|
53013
53113
|
for (const candidate of [v2, v1]) {
|
|
53014
53114
|
try {
|
|
53015
|
-
raw =
|
|
53115
|
+
raw = import_node_fs29.default.readFileSync(candidate, "utf8");
|
|
53016
53116
|
break;
|
|
53017
53117
|
} catch {
|
|
53018
53118
|
}
|
|
@@ -53037,19 +53137,19 @@ function readInstalledPlugins2(home) {
|
|
|
53037
53137
|
return out;
|
|
53038
53138
|
}
|
|
53039
53139
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
53040
|
-
let cur =
|
|
53041
|
-
const fsRoot =
|
|
53140
|
+
let cur = import_node_path31.default.resolve(startCwd);
|
|
53141
|
+
const fsRoot = import_node_path31.default.parse(cur).root;
|
|
53042
53142
|
while (true) {
|
|
53043
|
-
scanAgentsDir(
|
|
53143
|
+
scanAgentsDir(import_node_path31.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
53044
53144
|
let hasGit = false;
|
|
53045
53145
|
try {
|
|
53046
|
-
hasGit =
|
|
53146
|
+
hasGit = import_node_fs29.default.existsSync(import_node_path31.default.join(cur, ".git"));
|
|
53047
53147
|
} catch {
|
|
53048
53148
|
}
|
|
53049
53149
|
if (hasGit) return;
|
|
53050
53150
|
if (cur === home) return;
|
|
53051
53151
|
if (cur === fsRoot) return;
|
|
53052
|
-
const parent =
|
|
53152
|
+
const parent = import_node_path31.default.dirname(cur);
|
|
53053
53153
|
if (parent === cur) return;
|
|
53054
53154
|
cur = parent;
|
|
53055
53155
|
}
|
|
@@ -53084,7 +53184,7 @@ var AgentsScanner = class {
|
|
|
53084
53184
|
}
|
|
53085
53185
|
const fsBlock = [];
|
|
53086
53186
|
scanAgentsDir(
|
|
53087
|
-
|
|
53187
|
+
import_node_path31.default.join(this.home, ".claude", "agents"),
|
|
53088
53188
|
"global",
|
|
53089
53189
|
seen,
|
|
53090
53190
|
fsBlock
|
|
@@ -53098,7 +53198,7 @@ var AgentsScanner = class {
|
|
|
53098
53198
|
...this.extraPluginRoots
|
|
53099
53199
|
];
|
|
53100
53200
|
for (const { name, root } of plugins) {
|
|
53101
|
-
const agentsRoot =
|
|
53201
|
+
const agentsRoot = import_node_path31.default.join(root, "agents");
|
|
53102
53202
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
53103
53203
|
}
|
|
53104
53204
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -53106,15 +53206,15 @@ var AgentsScanner = class {
|
|
|
53106
53206
|
};
|
|
53107
53207
|
|
|
53108
53208
|
// src/observer/session-observer.ts
|
|
53109
|
-
var
|
|
53209
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
53110
53210
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
53111
|
-
var
|
|
53211
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
53112
53212
|
init_claude_history();
|
|
53113
53213
|
|
|
53114
53214
|
// src/observer/subagent-meta-observer.ts
|
|
53115
|
-
var
|
|
53215
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
53116
53216
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
53117
|
-
var
|
|
53217
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
53118
53218
|
init_claude_history();
|
|
53119
53219
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
53120
53220
|
var SubagentMetaObserver = class {
|
|
@@ -53127,7 +53227,7 @@ var SubagentMetaObserver = class {
|
|
|
53127
53227
|
watches = /* @__PURE__ */ new Map();
|
|
53128
53228
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
53129
53229
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
53130
|
-
return
|
|
53230
|
+
return import_node_path32.default.join(
|
|
53131
53231
|
this.home,
|
|
53132
53232
|
".claude",
|
|
53133
53233
|
"projects",
|
|
@@ -53157,7 +53257,7 @@ var SubagentMetaObserver = class {
|
|
|
53157
53257
|
attachWatcher(w2) {
|
|
53158
53258
|
if (w2.watcher) return;
|
|
53159
53259
|
try {
|
|
53160
|
-
w2.watcher =
|
|
53260
|
+
w2.watcher = import_node_fs30.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
53161
53261
|
if (!name) return;
|
|
53162
53262
|
const m2 = META_RE.exec(String(name));
|
|
53163
53263
|
if (!m2) return;
|
|
@@ -53169,7 +53269,7 @@ var SubagentMetaObserver = class {
|
|
|
53169
53269
|
scan(w2) {
|
|
53170
53270
|
let entries;
|
|
53171
53271
|
try {
|
|
53172
|
-
entries =
|
|
53272
|
+
entries = import_node_fs30.default.readdirSync(w2.dirPath);
|
|
53173
53273
|
} catch {
|
|
53174
53274
|
return;
|
|
53175
53275
|
}
|
|
@@ -53183,10 +53283,10 @@ var SubagentMetaObserver = class {
|
|
|
53183
53283
|
if (!m2) return;
|
|
53184
53284
|
const agentId = m2[1];
|
|
53185
53285
|
if (w2.emitted.has(agentId)) return;
|
|
53186
|
-
const file =
|
|
53286
|
+
const file = import_node_path32.default.join(w2.dirPath, name);
|
|
53187
53287
|
let raw;
|
|
53188
53288
|
try {
|
|
53189
|
-
raw =
|
|
53289
|
+
raw = import_node_fs30.default.readFileSync(file, "utf8");
|
|
53190
53290
|
} catch {
|
|
53191
53291
|
return;
|
|
53192
53292
|
}
|
|
@@ -53243,14 +53343,14 @@ var SessionObserver = class {
|
|
|
53243
53343
|
metaObserver;
|
|
53244
53344
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
53245
53345
|
if (override) return override;
|
|
53246
|
-
return
|
|
53346
|
+
return import_node_path33.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
53247
53347
|
}
|
|
53248
53348
|
start(args) {
|
|
53249
53349
|
this.stop(args.sessionId);
|
|
53250
53350
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
53251
53351
|
let size = 0;
|
|
53252
53352
|
try {
|
|
53253
|
-
size =
|
|
53353
|
+
size = import_node_fs31.default.statSync(filePath).size;
|
|
53254
53354
|
} catch {
|
|
53255
53355
|
}
|
|
53256
53356
|
const w2 = {
|
|
@@ -53263,16 +53363,16 @@ var SessionObserver = class {
|
|
|
53263
53363
|
adapter: args.adapter,
|
|
53264
53364
|
prevIsRejectSentinel: false,
|
|
53265
53365
|
toolSessionId: args.toolSessionId,
|
|
53266
|
-
sawFile:
|
|
53366
|
+
sawFile: import_node_fs31.default.existsSync(filePath),
|
|
53267
53367
|
lastRelocateScanMs: 0,
|
|
53268
53368
|
pendingCwdDerive: false,
|
|
53269
53369
|
lastDeriveMs: 0
|
|
53270
53370
|
};
|
|
53271
53371
|
try {
|
|
53272
|
-
|
|
53372
|
+
import_node_fs31.default.mkdirSync(import_node_path33.default.dirname(filePath), { recursive: true });
|
|
53273
53373
|
} catch {
|
|
53274
53374
|
}
|
|
53275
|
-
w2.watcher =
|
|
53375
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path33.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
53276
53376
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
53277
53377
|
this.poll(w2);
|
|
53278
53378
|
});
|
|
@@ -53295,7 +53395,7 @@ var SessionObserver = class {
|
|
|
53295
53395
|
// 异常静默吞,不阻塞 watcher 启动
|
|
53296
53396
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
53297
53397
|
try {
|
|
53298
|
-
const raw =
|
|
53398
|
+
const raw = import_node_fs31.default.readFileSync(w2.filePath, "utf8");
|
|
53299
53399
|
if (!raw) return;
|
|
53300
53400
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
53301
53401
|
if (allLines.length === 0) return;
|
|
@@ -53319,7 +53419,7 @@ var SessionObserver = class {
|
|
|
53319
53419
|
poll(w2) {
|
|
53320
53420
|
let size = 0;
|
|
53321
53421
|
try {
|
|
53322
|
-
size =
|
|
53422
|
+
size = import_node_fs31.default.statSync(w2.filePath).size;
|
|
53323
53423
|
} catch {
|
|
53324
53424
|
if (w2.sawFile) this.maybeRelocate(w2);
|
|
53325
53425
|
return;
|
|
@@ -53330,11 +53430,11 @@ var SessionObserver = class {
|
|
|
53330
53430
|
w2.buf = "";
|
|
53331
53431
|
}
|
|
53332
53432
|
if (size === w2.lastSize) return;
|
|
53333
|
-
const fd =
|
|
53433
|
+
const fd = import_node_fs31.default.openSync(w2.filePath, "r");
|
|
53334
53434
|
try {
|
|
53335
53435
|
const len = size - w2.lastSize;
|
|
53336
53436
|
const buf = Buffer.alloc(len);
|
|
53337
|
-
|
|
53437
|
+
import_node_fs31.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
53338
53438
|
w2.lastSize = size;
|
|
53339
53439
|
w2.buf += buf.toString("utf8");
|
|
53340
53440
|
let newlineIndex;
|
|
@@ -53357,7 +53457,7 @@ var SessionObserver = class {
|
|
|
53357
53457
|
}
|
|
53358
53458
|
}
|
|
53359
53459
|
} finally {
|
|
53360
|
-
|
|
53460
|
+
import_node_fs31.default.closeSync(fd);
|
|
53361
53461
|
}
|
|
53362
53462
|
if (w2.pendingCwdDerive) this.maybeDeriveCwd(w2);
|
|
53363
53463
|
}
|
|
@@ -53369,7 +53469,7 @@ var SessionObserver = class {
|
|
|
53369
53469
|
const now = Date.now();
|
|
53370
53470
|
if (now - w2.lastRelocateScanMs < 1e3) return;
|
|
53371
53471
|
w2.lastRelocateScanMs = now;
|
|
53372
|
-
const projectsRoot =
|
|
53472
|
+
const projectsRoot = import_node_path33.default.join(this.home, ".claude", "projects");
|
|
53373
53473
|
const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
|
|
53374
53474
|
if (!found || found === w2.filePath) return;
|
|
53375
53475
|
try {
|
|
@@ -53378,7 +53478,7 @@ var SessionObserver = class {
|
|
|
53378
53478
|
}
|
|
53379
53479
|
w2.filePath = found;
|
|
53380
53480
|
try {
|
|
53381
|
-
w2.watcher =
|
|
53481
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path33.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
53382
53482
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
53383
53483
|
this.poll(w2);
|
|
53384
53484
|
});
|
|
@@ -54173,8 +54273,8 @@ async function authenticate(token, deps) {
|
|
|
54173
54273
|
}
|
|
54174
54274
|
|
|
54175
54275
|
// src/legacy-cleanup.ts
|
|
54176
|
-
var
|
|
54177
|
-
var
|
|
54276
|
+
var fs36 = __toESM(require("fs/promises"), 1);
|
|
54277
|
+
var path38 = __toESM(require("path"), 1);
|
|
54178
54278
|
var LEGACY_FILES = [
|
|
54179
54279
|
"personal-capability.json",
|
|
54180
54280
|
"received-capabilities.json",
|
|
@@ -54183,9 +54283,9 @@ var LEGACY_FILES = [
|
|
|
54183
54283
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
54184
54284
|
const removed = [];
|
|
54185
54285
|
for (const name of LEGACY_FILES) {
|
|
54186
|
-
const p2 =
|
|
54286
|
+
const p2 = path38.join(dataDir, name);
|
|
54187
54287
|
try {
|
|
54188
|
-
await
|
|
54288
|
+
await fs36.unlink(p2);
|
|
54189
54289
|
removed.push(name);
|
|
54190
54290
|
logger.debug("legacy capability file removed", { file: name });
|
|
54191
54291
|
} catch (err) {
|
|
@@ -54197,13 +54297,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
54197
54297
|
}
|
|
54198
54298
|
|
|
54199
54299
|
// src/inbox/inbox-store.ts
|
|
54200
|
-
var
|
|
54201
|
-
var
|
|
54300
|
+
var fs37 = __toESM(require("fs"), 1);
|
|
54301
|
+
var path39 = __toESM(require("path"), 1);
|
|
54202
54302
|
var INBOX_SUBDIR = "inbox";
|
|
54203
54303
|
var InboxStore = class {
|
|
54204
54304
|
constructor(dataDir) {
|
|
54205
54305
|
this.dataDir = dataDir;
|
|
54206
|
-
|
|
54306
|
+
fs37.mkdirSync(this.dirPath(), { recursive: true });
|
|
54207
54307
|
}
|
|
54208
54308
|
dataDir;
|
|
54209
54309
|
/**
|
|
@@ -54215,7 +54315,7 @@ var InboxStore = class {
|
|
|
54215
54315
|
const file = this.filePath(peerDeviceId);
|
|
54216
54316
|
let raw;
|
|
54217
54317
|
try {
|
|
54218
|
-
raw =
|
|
54318
|
+
raw = fs37.readFileSync(file, "utf8");
|
|
54219
54319
|
} catch (err) {
|
|
54220
54320
|
if (err?.code === "ENOENT") return [];
|
|
54221
54321
|
return [];
|
|
@@ -54231,7 +54331,7 @@ var InboxStore = class {
|
|
|
54231
54331
|
const dir = this.dirPath();
|
|
54232
54332
|
let entries;
|
|
54233
54333
|
try {
|
|
54234
|
-
entries =
|
|
54334
|
+
entries = fs37.readdirSync(dir);
|
|
54235
54335
|
} catch (err) {
|
|
54236
54336
|
if (err?.code === "ENOENT") return [];
|
|
54237
54337
|
return [];
|
|
@@ -54247,9 +54347,9 @@ var InboxStore = class {
|
|
|
54247
54347
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
54248
54348
|
const file = this.filePath(message.peerDeviceId);
|
|
54249
54349
|
const line = JSON.stringify(message) + "\n";
|
|
54250
|
-
|
|
54350
|
+
fs37.appendFileSync(file, line, { mode: 384 });
|
|
54251
54351
|
try {
|
|
54252
|
-
|
|
54352
|
+
fs37.chmodSync(file, 384);
|
|
54253
54353
|
} catch {
|
|
54254
54354
|
}
|
|
54255
54355
|
}
|
|
@@ -54279,7 +54379,7 @@ var InboxStore = class {
|
|
|
54279
54379
|
removeByPeerDeviceId(peerDeviceId) {
|
|
54280
54380
|
const file = this.filePath(peerDeviceId);
|
|
54281
54381
|
try {
|
|
54282
|
-
|
|
54382
|
+
fs37.unlinkSync(file);
|
|
54283
54383
|
} catch (err) {
|
|
54284
54384
|
if (err?.code === "ENOENT") return;
|
|
54285
54385
|
}
|
|
@@ -54288,18 +54388,18 @@ var InboxStore = class {
|
|
|
54288
54388
|
const file = this.filePath(peerDeviceId);
|
|
54289
54389
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
54290
54390
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
54291
|
-
|
|
54292
|
-
|
|
54391
|
+
fs37.writeFileSync(tmp, content, { mode: 384 });
|
|
54392
|
+
fs37.renameSync(tmp, file);
|
|
54293
54393
|
try {
|
|
54294
|
-
|
|
54394
|
+
fs37.chmodSync(file, 384);
|
|
54295
54395
|
} catch {
|
|
54296
54396
|
}
|
|
54297
54397
|
}
|
|
54298
54398
|
dirPath() {
|
|
54299
|
-
return
|
|
54399
|
+
return path39.join(this.dataDir, INBOX_SUBDIR);
|
|
54300
54400
|
}
|
|
54301
54401
|
filePath(peerDeviceId) {
|
|
54302
|
-
return
|
|
54402
|
+
return path39.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
54303
54403
|
}
|
|
54304
54404
|
};
|
|
54305
54405
|
function parseAllLines(raw) {
|
|
@@ -54387,8 +54487,8 @@ var InboxManager = class {
|
|
|
54387
54487
|
};
|
|
54388
54488
|
|
|
54389
54489
|
// src/state/contact-store.ts
|
|
54390
|
-
var
|
|
54391
|
-
var
|
|
54490
|
+
var fs38 = __toESM(require("fs"), 1);
|
|
54491
|
+
var path40 = __toESM(require("path"), 1);
|
|
54392
54492
|
var FILE_NAME = "contacts.json";
|
|
54393
54493
|
var ContactStore = class {
|
|
54394
54494
|
constructor(dataDir) {
|
|
@@ -54398,10 +54498,10 @@ var ContactStore = class {
|
|
|
54398
54498
|
contacts = /* @__PURE__ */ new Map();
|
|
54399
54499
|
load() {
|
|
54400
54500
|
this.contacts.clear();
|
|
54401
|
-
const file =
|
|
54501
|
+
const file = path40.join(this.dataDir, FILE_NAME);
|
|
54402
54502
|
let raw;
|
|
54403
54503
|
try {
|
|
54404
|
-
raw =
|
|
54504
|
+
raw = fs38.readFileSync(file, "utf8");
|
|
54405
54505
|
} catch (err) {
|
|
54406
54506
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
54407
54507
|
return;
|
|
@@ -54470,20 +54570,20 @@ var ContactStore = class {
|
|
|
54470
54570
|
return true;
|
|
54471
54571
|
}
|
|
54472
54572
|
flush() {
|
|
54473
|
-
const file =
|
|
54573
|
+
const file = path40.join(this.dataDir, FILE_NAME);
|
|
54474
54574
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
54475
54575
|
const content = JSON.stringify(
|
|
54476
54576
|
{ contacts: Array.from(this.contacts.values()) },
|
|
54477
54577
|
null,
|
|
54478
54578
|
2
|
|
54479
54579
|
);
|
|
54480
|
-
|
|
54481
|
-
|
|
54482
|
-
|
|
54580
|
+
fs38.mkdirSync(this.dataDir, { recursive: true });
|
|
54581
|
+
fs38.writeFileSync(tmp, content, { mode: 384 });
|
|
54582
|
+
fs38.renameSync(tmp, file);
|
|
54483
54583
|
}
|
|
54484
54584
|
renameBak(file) {
|
|
54485
54585
|
try {
|
|
54486
|
-
|
|
54586
|
+
fs38.renameSync(file, `${file}.bak`);
|
|
54487
54587
|
} catch {
|
|
54488
54588
|
}
|
|
54489
54589
|
}
|
|
@@ -54591,61 +54691,61 @@ async function connectRemote(args) {
|
|
|
54591
54691
|
}
|
|
54592
54692
|
|
|
54593
54693
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
54594
|
-
var
|
|
54595
|
-
var
|
|
54694
|
+
var fs39 = __toESM(require("fs"), 1);
|
|
54695
|
+
var path41 = __toESM(require("path"), 1);
|
|
54596
54696
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
54597
54697
|
function migrateFlattenSessions(opts) {
|
|
54598
54698
|
const dataDir = opts.dataDir;
|
|
54599
54699
|
const now = opts.now ?? Date.now;
|
|
54600
|
-
const sessionsDir =
|
|
54601
|
-
const flagPath =
|
|
54700
|
+
const sessionsDir = path41.join(dataDir, "sessions");
|
|
54701
|
+
const flagPath = path41.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
54602
54702
|
if (existsSync3(flagPath)) {
|
|
54603
54703
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
54604
54704
|
}
|
|
54605
54705
|
let movedBare = 0;
|
|
54606
54706
|
let movedVmOwner = 0;
|
|
54607
54707
|
let archivedListener = 0;
|
|
54608
|
-
const defaultDir =
|
|
54708
|
+
const defaultDir = path41.join(sessionsDir, "default");
|
|
54609
54709
|
if (existsSync3(defaultDir)) {
|
|
54610
54710
|
for (const entry of readdirSafe(defaultDir)) {
|
|
54611
54711
|
if (!entry.endsWith(".json")) continue;
|
|
54612
|
-
const src =
|
|
54613
|
-
const dst =
|
|
54614
|
-
|
|
54712
|
+
const src = path41.join(defaultDir, entry);
|
|
54713
|
+
const dst = path41.join(sessionsDir, entry);
|
|
54714
|
+
fs39.renameSync(src, dst);
|
|
54615
54715
|
movedBare += 1;
|
|
54616
54716
|
}
|
|
54617
54717
|
rmdirIfEmpty(defaultDir);
|
|
54618
54718
|
}
|
|
54619
54719
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
54620
|
-
const personaDir =
|
|
54720
|
+
const personaDir = path41.join(sessionsDir, pid);
|
|
54621
54721
|
if (!isDir(personaDir)) continue;
|
|
54622
54722
|
if (pid === "default") continue;
|
|
54623
|
-
const ownerSrc =
|
|
54723
|
+
const ownerSrc = path41.join(personaDir, "owner");
|
|
54624
54724
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
54625
|
-
const ownerDst =
|
|
54626
|
-
|
|
54725
|
+
const ownerDst = path41.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
54726
|
+
fs39.mkdirSync(ownerDst, { recursive: true });
|
|
54627
54727
|
for (const file of readdirSafe(ownerSrc)) {
|
|
54628
54728
|
if (!file.endsWith(".json")) continue;
|
|
54629
|
-
|
|
54729
|
+
fs39.renameSync(path41.join(ownerSrc, file), path41.join(ownerDst, file));
|
|
54630
54730
|
movedVmOwner += 1;
|
|
54631
54731
|
}
|
|
54632
54732
|
rmdirIfEmpty(ownerSrc);
|
|
54633
54733
|
}
|
|
54634
|
-
const listenerSrc =
|
|
54734
|
+
const listenerSrc = path41.join(personaDir, "listener");
|
|
54635
54735
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
54636
|
-
const archiveDst =
|
|
54637
|
-
|
|
54736
|
+
const archiveDst = path41.join(dataDir, ".legacy", `listener-${pid}`);
|
|
54737
|
+
fs39.mkdirSync(archiveDst, { recursive: true });
|
|
54638
54738
|
for (const file of readdirSafe(listenerSrc)) {
|
|
54639
54739
|
if (!file.endsWith(".json")) continue;
|
|
54640
|
-
|
|
54740
|
+
fs39.renameSync(path41.join(listenerSrc, file), path41.join(archiveDst, file));
|
|
54641
54741
|
archivedListener += 1;
|
|
54642
54742
|
}
|
|
54643
54743
|
rmdirIfEmpty(listenerSrc);
|
|
54644
54744
|
}
|
|
54645
54745
|
rmdirIfEmpty(personaDir);
|
|
54646
54746
|
}
|
|
54647
|
-
|
|
54648
|
-
|
|
54747
|
+
fs39.mkdirSync(sessionsDir, { recursive: true });
|
|
54748
|
+
fs39.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
54649
54749
|
return {
|
|
54650
54750
|
skipped: false,
|
|
54651
54751
|
flagWritten: true,
|
|
@@ -54656,7 +54756,7 @@ function migrateFlattenSessions(opts) {
|
|
|
54656
54756
|
}
|
|
54657
54757
|
function existsSync3(p2) {
|
|
54658
54758
|
try {
|
|
54659
|
-
|
|
54759
|
+
fs39.statSync(p2);
|
|
54660
54760
|
return true;
|
|
54661
54761
|
} catch {
|
|
54662
54762
|
return false;
|
|
@@ -54664,31 +54764,31 @@ function existsSync3(p2) {
|
|
|
54664
54764
|
}
|
|
54665
54765
|
function isDir(p2) {
|
|
54666
54766
|
try {
|
|
54667
|
-
return
|
|
54767
|
+
return fs39.statSync(p2).isDirectory();
|
|
54668
54768
|
} catch {
|
|
54669
54769
|
return false;
|
|
54670
54770
|
}
|
|
54671
54771
|
}
|
|
54672
54772
|
function readdirSafe(p2) {
|
|
54673
54773
|
try {
|
|
54674
|
-
return
|
|
54774
|
+
return fs39.readdirSync(p2);
|
|
54675
54775
|
} catch {
|
|
54676
54776
|
return [];
|
|
54677
54777
|
}
|
|
54678
54778
|
}
|
|
54679
54779
|
function rmdirIfEmpty(p2) {
|
|
54680
54780
|
try {
|
|
54681
|
-
|
|
54781
|
+
fs39.rmdirSync(p2);
|
|
54682
54782
|
} catch {
|
|
54683
54783
|
}
|
|
54684
54784
|
}
|
|
54685
54785
|
|
|
54686
54786
|
// src/transport/http-router.ts
|
|
54687
|
-
var
|
|
54688
|
-
var
|
|
54787
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
54788
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
54689
54789
|
|
|
54690
54790
|
// src/attachment/mime.ts
|
|
54691
|
-
var
|
|
54791
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
54692
54792
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
54693
54793
|
var EXT_TO_NATIVE_MIME = {
|
|
54694
54794
|
// 图片
|
|
@@ -54795,7 +54895,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
54795
54895
|
".mk"
|
|
54796
54896
|
]);
|
|
54797
54897
|
function lookupMime(filePathOrName) {
|
|
54798
|
-
const ext =
|
|
54898
|
+
const ext = import_node_path34.default.extname(filePathOrName).toLowerCase();
|
|
54799
54899
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
54800
54900
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
54801
54901
|
return "application/octet-stream";
|
|
@@ -54865,8 +54965,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
54865
54965
|
}
|
|
54866
54966
|
|
|
54867
54967
|
// src/attachment/upload.ts
|
|
54868
|
-
var
|
|
54869
|
-
var
|
|
54968
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
54969
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
54870
54970
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
54871
54971
|
var import_promises3 = require("stream/promises");
|
|
54872
54972
|
var UploadError = class extends Error {
|
|
@@ -54878,22 +54978,22 @@ var UploadError = class extends Error {
|
|
|
54878
54978
|
code;
|
|
54879
54979
|
};
|
|
54880
54980
|
function assertValidFileName(fileName) {
|
|
54881
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
54981
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path35.default.basename(fileName)) {
|
|
54882
54982
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
54883
54983
|
}
|
|
54884
54984
|
}
|
|
54885
54985
|
var HASH_PREFIX_LEN = 16;
|
|
54886
54986
|
async function writeUploadedAttachment(args) {
|
|
54887
54987
|
assertValidFileName(args.fileName);
|
|
54888
|
-
const attachmentsRoot =
|
|
54988
|
+
const attachmentsRoot = import_node_path35.default.join(args.baseDir, ".attachments");
|
|
54889
54989
|
try {
|
|
54890
|
-
|
|
54990
|
+
import_node_fs32.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
54891
54991
|
} catch (err) {
|
|
54892
54992
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
54893
54993
|
}
|
|
54894
54994
|
const hasher = import_node_crypto8.default.createHash("sha256");
|
|
54895
54995
|
let actualSize = 0;
|
|
54896
|
-
const tmpPath =
|
|
54996
|
+
const tmpPath = import_node_path35.default.join(
|
|
54897
54997
|
attachmentsRoot,
|
|
54898
54998
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
|
|
54899
54999
|
);
|
|
@@ -54908,18 +55008,18 @@ async function writeUploadedAttachment(args) {
|
|
|
54908
55008
|
yield buf;
|
|
54909
55009
|
}
|
|
54910
55010
|
},
|
|
54911
|
-
|
|
55011
|
+
import_node_fs32.default.createWriteStream(tmpPath, { mode: 384 })
|
|
54912
55012
|
);
|
|
54913
55013
|
} catch (err) {
|
|
54914
55014
|
try {
|
|
54915
|
-
|
|
55015
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54916
55016
|
} catch {
|
|
54917
55017
|
}
|
|
54918
55018
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
54919
55019
|
}
|
|
54920
55020
|
if (actualSize !== args.contentLength) {
|
|
54921
55021
|
try {
|
|
54922
|
-
|
|
55022
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54923
55023
|
} catch {
|
|
54924
55024
|
}
|
|
54925
55025
|
throw new UploadError(
|
|
@@ -54928,34 +55028,34 @@ async function writeUploadedAttachment(args) {
|
|
|
54928
55028
|
);
|
|
54929
55029
|
}
|
|
54930
55030
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
54931
|
-
const hashDir =
|
|
55031
|
+
const hashDir = import_node_path35.default.join(attachmentsRoot, attachmentId);
|
|
54932
55032
|
let finalFileName;
|
|
54933
55033
|
let hashDirExists = false;
|
|
54934
55034
|
try {
|
|
54935
|
-
hashDirExists =
|
|
55035
|
+
hashDirExists = import_node_fs32.default.statSync(hashDir).isDirectory();
|
|
54936
55036
|
} catch {
|
|
54937
55037
|
}
|
|
54938
55038
|
if (hashDirExists) {
|
|
54939
|
-
const existing =
|
|
55039
|
+
const existing = import_node_fs32.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
54940
55040
|
finalFileName = existing[0] ?? args.fileName;
|
|
54941
55041
|
try {
|
|
54942
|
-
|
|
55042
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54943
55043
|
} catch {
|
|
54944
55044
|
}
|
|
54945
55045
|
} else {
|
|
54946
55046
|
try {
|
|
54947
|
-
|
|
55047
|
+
import_node_fs32.default.mkdirSync(hashDir, { recursive: true });
|
|
54948
55048
|
finalFileName = args.fileName;
|
|
54949
|
-
|
|
55049
|
+
import_node_fs32.default.renameSync(tmpPath, import_node_path35.default.join(hashDir, finalFileName));
|
|
54950
55050
|
} catch (err) {
|
|
54951
55051
|
try {
|
|
54952
|
-
|
|
55052
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54953
55053
|
} catch {
|
|
54954
55054
|
}
|
|
54955
55055
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
54956
55056
|
}
|
|
54957
55057
|
}
|
|
54958
|
-
const absPath =
|
|
55058
|
+
const absPath = import_node_path35.default.join(hashDir, finalFileName);
|
|
54959
55059
|
const relPath = absPath;
|
|
54960
55060
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
54961
55061
|
relPath: absPath,
|
|
@@ -54970,7 +55070,7 @@ async function writeUploadedAttachment(args) {
|
|
|
54970
55070
|
|
|
54971
55071
|
// src/extension/import.ts
|
|
54972
55072
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
54973
|
-
var
|
|
55073
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
54974
55074
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
54975
55075
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
54976
55076
|
var ImportError = class extends Error {
|
|
@@ -54988,7 +55088,7 @@ async function importZip(buf, root) {
|
|
|
54988
55088
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54989
55089
|
}
|
|
54990
55090
|
for (const name of Object.keys(zip.files)) {
|
|
54991
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
55091
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path36.default.isAbsolute(name)) {
|
|
54992
55092
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
54993
55093
|
}
|
|
54994
55094
|
}
|
|
@@ -55021,7 +55121,7 @@ async function importZip(buf, root) {
|
|
|
55021
55121
|
);
|
|
55022
55122
|
}
|
|
55023
55123
|
}
|
|
55024
|
-
const destDir =
|
|
55124
|
+
const destDir = import_node_path36.default.join(root, manifest.id);
|
|
55025
55125
|
let destExists = false;
|
|
55026
55126
|
try {
|
|
55027
55127
|
await import_promises4.default.access(destDir);
|
|
@@ -55031,15 +55131,15 @@ async function importZip(buf, root) {
|
|
|
55031
55131
|
if (destExists) {
|
|
55032
55132
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
55033
55133
|
}
|
|
55034
|
-
const stage = await import_promises4.default.mkdtemp(
|
|
55134
|
+
const stage = await import_promises4.default.mkdtemp(import_node_path36.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
55035
55135
|
try {
|
|
55036
55136
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
55037
|
-
const dest =
|
|
55137
|
+
const dest = import_node_path36.default.join(stage, name);
|
|
55038
55138
|
if (entry.dir) {
|
|
55039
55139
|
await import_promises4.default.mkdir(dest, { recursive: true });
|
|
55040
55140
|
continue;
|
|
55041
55141
|
}
|
|
55042
|
-
await import_promises4.default.mkdir(
|
|
55142
|
+
await import_promises4.default.mkdir(import_node_path36.default.dirname(dest), { recursive: true });
|
|
55043
55143
|
const content = await entry.async("nodebuffer");
|
|
55044
55144
|
await import_promises4.default.writeFile(dest, content);
|
|
55045
55145
|
}
|
|
@@ -55069,7 +55169,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
55069
55169
|
".wasm": "application/wasm"
|
|
55070
55170
|
};
|
|
55071
55171
|
function shareUiAssetMime(filePath) {
|
|
55072
|
-
const ext =
|
|
55172
|
+
const ext = import_node_path37.default.extname(filePath).toLowerCase();
|
|
55073
55173
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
55074
55174
|
}
|
|
55075
55175
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -55168,7 +55268,7 @@ function isValidUploadFileName(fileName) {
|
|
|
55168
55268
|
if (fileName === "." || fileName === "..") return false;
|
|
55169
55269
|
if (fileName.startsWith(".")) return false;
|
|
55170
55270
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
55171
|
-
return fileName ===
|
|
55271
|
+
return fileName === import_node_path37.default.basename(fileName);
|
|
55172
55272
|
}
|
|
55173
55273
|
function createHttpRouter(deps) {
|
|
55174
55274
|
return async (req, res) => {
|
|
@@ -55256,7 +55356,7 @@ function createHttpRouter(deps) {
|
|
|
55256
55356
|
}
|
|
55257
55357
|
let buf;
|
|
55258
55358
|
try {
|
|
55259
|
-
buf = await
|
|
55359
|
+
buf = await import_node_fs33.default.promises.readFile(abs);
|
|
55260
55360
|
} catch {
|
|
55261
55361
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
55262
55362
|
return true;
|
|
@@ -55404,7 +55504,7 @@ function createHttpRouter(deps) {
|
|
|
55404
55504
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
55405
55505
|
return true;
|
|
55406
55506
|
}
|
|
55407
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
55507
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path37.default.basename(r.absPath)));
|
|
55408
55508
|
return true;
|
|
55409
55509
|
}
|
|
55410
55510
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -55525,7 +55625,7 @@ function createHttpRouter(deps) {
|
|
|
55525
55625
|
return true;
|
|
55526
55626
|
}
|
|
55527
55627
|
let absPath;
|
|
55528
|
-
if (
|
|
55628
|
+
if (import_node_path37.default.isAbsolute(pathParam)) {
|
|
55529
55629
|
absPath = pathParam;
|
|
55530
55630
|
} else if (deps.sessionStore) {
|
|
55531
55631
|
const file = deps.sessionStore.read(sid);
|
|
@@ -55533,7 +55633,7 @@ function createHttpRouter(deps) {
|
|
|
55533
55633
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
55534
55634
|
return true;
|
|
55535
55635
|
}
|
|
55536
|
-
absPath =
|
|
55636
|
+
absPath = import_node_path37.default.join(file.cwd, pathParam);
|
|
55537
55637
|
} else {
|
|
55538
55638
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
55539
55639
|
return true;
|
|
@@ -55620,7 +55720,7 @@ function withCtx(ctx, body) {
|
|
|
55620
55720
|
function streamFile(res, absPath, logger) {
|
|
55621
55721
|
let stat;
|
|
55622
55722
|
try {
|
|
55623
|
-
stat =
|
|
55723
|
+
stat = import_node_fs33.default.statSync(absPath);
|
|
55624
55724
|
} catch (err) {
|
|
55625
55725
|
const code = err?.code;
|
|
55626
55726
|
if (code === "ENOENT") {
|
|
@@ -55635,7 +55735,7 @@ function streamFile(res, absPath, logger) {
|
|
|
55635
55735
|
return;
|
|
55636
55736
|
}
|
|
55637
55737
|
const mime = lookupMime(absPath);
|
|
55638
|
-
const basename =
|
|
55738
|
+
const basename = import_node_path37.default.basename(absPath);
|
|
55639
55739
|
res.writeHead(200, {
|
|
55640
55740
|
"Content-Type": mime,
|
|
55641
55741
|
"Content-Length": String(stat.size),
|
|
@@ -55643,7 +55743,7 @@ function streamFile(res, absPath, logger) {
|
|
|
55643
55743
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
55644
55744
|
"X-Content-Type-Options": "nosniff"
|
|
55645
55745
|
});
|
|
55646
|
-
const stream =
|
|
55746
|
+
const stream = import_node_fs33.default.createReadStream(absPath);
|
|
55647
55747
|
stream.on("error", (err) => {
|
|
55648
55748
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
55649
55749
|
res.destroy();
|
|
@@ -55652,8 +55752,8 @@ function streamFile(res, absPath, logger) {
|
|
|
55652
55752
|
}
|
|
55653
55753
|
|
|
55654
55754
|
// src/attachment/gc.ts
|
|
55655
|
-
var
|
|
55656
|
-
var
|
|
55755
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
55756
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
55657
55757
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
55658
55758
|
function runAttachmentGc(args) {
|
|
55659
55759
|
const now = (args.now ?? Date.now)();
|
|
@@ -55662,12 +55762,12 @@ function runAttachmentGc(args) {
|
|
|
55662
55762
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
55663
55763
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
55664
55764
|
if (entry.stale) continue;
|
|
55665
|
-
if (
|
|
55765
|
+
if (import_node_path38.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
55666
55766
|
}
|
|
55667
55767
|
}
|
|
55668
55768
|
const visited = /* @__PURE__ */ new Set();
|
|
55669
55769
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
55670
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
55770
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path38.default.join(
|
|
55671
55771
|
args.dataDir,
|
|
55672
55772
|
"sessions",
|
|
55673
55773
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -55680,28 +55780,28 @@ function runAttachmentGc(args) {
|
|
|
55680
55780
|
return true;
|
|
55681
55781
|
});
|
|
55682
55782
|
for (const rootDir of roots) {
|
|
55683
|
-
const attRoot =
|
|
55783
|
+
const attRoot = import_node_path38.default.join(rootDir, ".attachments");
|
|
55684
55784
|
let hashDirs;
|
|
55685
55785
|
try {
|
|
55686
|
-
hashDirs =
|
|
55786
|
+
hashDirs = import_node_fs34.default.readdirSync(attRoot);
|
|
55687
55787
|
} catch (err) {
|
|
55688
55788
|
if (err.code === "ENOENT") continue;
|
|
55689
55789
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
55690
55790
|
continue;
|
|
55691
55791
|
}
|
|
55692
55792
|
for (const hashDir of hashDirs) {
|
|
55693
|
-
const hashDirAbs =
|
|
55793
|
+
const hashDirAbs = import_node_path38.default.join(attRoot, hashDir);
|
|
55694
55794
|
let files;
|
|
55695
55795
|
try {
|
|
55696
|
-
files =
|
|
55796
|
+
files = import_node_fs34.default.readdirSync(hashDirAbs);
|
|
55697
55797
|
} catch {
|
|
55698
55798
|
continue;
|
|
55699
55799
|
}
|
|
55700
55800
|
for (const name of files) {
|
|
55701
|
-
const file =
|
|
55801
|
+
const file = import_node_path38.default.join(hashDirAbs, name);
|
|
55702
55802
|
let stat;
|
|
55703
55803
|
try {
|
|
55704
|
-
stat =
|
|
55804
|
+
stat = import_node_fs34.default.statSync(file);
|
|
55705
55805
|
} catch {
|
|
55706
55806
|
continue;
|
|
55707
55807
|
}
|
|
@@ -55710,18 +55810,18 @@ function runAttachmentGc(args) {
|
|
|
55710
55810
|
if (age < ttlMs) continue;
|
|
55711
55811
|
if (liveAbs.has(file)) continue;
|
|
55712
55812
|
try {
|
|
55713
|
-
|
|
55813
|
+
import_node_fs34.default.unlinkSync(file);
|
|
55714
55814
|
} catch (err) {
|
|
55715
55815
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
55716
55816
|
}
|
|
55717
55817
|
}
|
|
55718
55818
|
try {
|
|
55719
|
-
if (
|
|
55819
|
+
if (import_node_fs34.default.readdirSync(hashDirAbs).length === 0) import_node_fs34.default.rmdirSync(hashDirAbs);
|
|
55720
55820
|
} catch {
|
|
55721
55821
|
}
|
|
55722
55822
|
}
|
|
55723
55823
|
try {
|
|
55724
|
-
if (
|
|
55824
|
+
if (import_node_fs34.default.readdirSync(attRoot).length === 0) import_node_fs34.default.rmdirSync(attRoot);
|
|
55725
55825
|
} catch {
|
|
55726
55826
|
}
|
|
55727
55827
|
}
|
|
@@ -55729,8 +55829,8 @@ function runAttachmentGc(args) {
|
|
|
55729
55829
|
}
|
|
55730
55830
|
|
|
55731
55831
|
// src/attachment/group.ts
|
|
55732
|
-
var
|
|
55733
|
-
var
|
|
55832
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
55833
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
55734
55834
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
55735
55835
|
init_protocol();
|
|
55736
55836
|
var GroupFileStore = class {
|
|
@@ -55742,11 +55842,11 @@ var GroupFileStore = class {
|
|
|
55742
55842
|
this.logger = opts.logger;
|
|
55743
55843
|
}
|
|
55744
55844
|
rootForScope(scope) {
|
|
55745
|
-
return
|
|
55845
|
+
return import_node_path39.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
55746
55846
|
}
|
|
55747
55847
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
55748
55848
|
filePath(scope, sessionId) {
|
|
55749
|
-
return
|
|
55849
|
+
return import_node_path39.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
55750
55850
|
}
|
|
55751
55851
|
cacheKey(scope, sessionId) {
|
|
55752
55852
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -55755,7 +55855,7 @@ var GroupFileStore = class {
|
|
|
55755
55855
|
readFile(scope, sessionId) {
|
|
55756
55856
|
const file = this.filePath(scope, sessionId);
|
|
55757
55857
|
try {
|
|
55758
|
-
const raw =
|
|
55858
|
+
const raw = import_node_fs35.default.readFileSync(file, "utf8");
|
|
55759
55859
|
const parsed = JSON.parse(raw);
|
|
55760
55860
|
if (!Array.isArray(parsed)) {
|
|
55761
55861
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -55781,10 +55881,10 @@ var GroupFileStore = class {
|
|
|
55781
55881
|
}
|
|
55782
55882
|
writeFile(scope, sessionId, entries) {
|
|
55783
55883
|
const file = this.filePath(scope, sessionId);
|
|
55784
|
-
|
|
55884
|
+
import_node_fs35.default.mkdirSync(import_node_path39.default.dirname(file), { recursive: true });
|
|
55785
55885
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
55786
|
-
|
|
55787
|
-
|
|
55886
|
+
import_node_fs35.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
55887
|
+
import_node_fs35.default.renameSync(tmp, file);
|
|
55788
55888
|
}
|
|
55789
55889
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
55790
55890
|
list(scope, sessionId) {
|
|
@@ -55870,10 +55970,10 @@ var GroupFileStore = class {
|
|
|
55870
55970
|
};
|
|
55871
55971
|
|
|
55872
55972
|
// src/discovery/state-file.ts
|
|
55873
|
-
var
|
|
55874
|
-
var
|
|
55973
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
55974
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
55875
55975
|
function defaultStateFilePath(dataDir) {
|
|
55876
|
-
return
|
|
55976
|
+
return import_node_path40.default.join(dataDir, "state.json");
|
|
55877
55977
|
}
|
|
55878
55978
|
function isPidAlive(pid) {
|
|
55879
55979
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -55895,7 +55995,7 @@ var StateFileManager = class {
|
|
|
55895
55995
|
}
|
|
55896
55996
|
read() {
|
|
55897
55997
|
try {
|
|
55898
|
-
const raw =
|
|
55998
|
+
const raw = import_node_fs36.default.readFileSync(this.file, "utf8");
|
|
55899
55999
|
const parsed = JSON.parse(raw);
|
|
55900
56000
|
return parsed;
|
|
55901
56001
|
} catch {
|
|
@@ -55909,20 +56009,20 @@ var StateFileManager = class {
|
|
|
55909
56009
|
return { status: "stale", existing };
|
|
55910
56010
|
}
|
|
55911
56011
|
write(state) {
|
|
55912
|
-
|
|
56012
|
+
import_node_fs36.default.mkdirSync(import_node_path40.default.dirname(this.file), { recursive: true });
|
|
55913
56013
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
55914
|
-
|
|
55915
|
-
|
|
56014
|
+
import_node_fs36.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
56015
|
+
import_node_fs36.default.renameSync(tmp, this.file);
|
|
55916
56016
|
if (process.platform !== "win32") {
|
|
55917
56017
|
try {
|
|
55918
|
-
|
|
56018
|
+
import_node_fs36.default.chmodSync(this.file, 384);
|
|
55919
56019
|
} catch {
|
|
55920
56020
|
}
|
|
55921
56021
|
}
|
|
55922
56022
|
}
|
|
55923
56023
|
delete() {
|
|
55924
56024
|
try {
|
|
55925
|
-
|
|
56025
|
+
import_node_fs36.default.unlinkSync(this.file);
|
|
55926
56026
|
} catch {
|
|
55927
56027
|
}
|
|
55928
56028
|
}
|
|
@@ -55936,14 +56036,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
55936
56036
|
}
|
|
55937
56037
|
|
|
55938
56038
|
// src/tunnel/tunnel-manager.ts
|
|
55939
|
-
var
|
|
55940
|
-
var
|
|
56039
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
56040
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
55941
56041
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
55942
56042
|
var import_node_child_process9 = require("child_process");
|
|
55943
56043
|
|
|
55944
56044
|
// src/tunnel/tunnel-store.ts
|
|
55945
|
-
var
|
|
55946
|
-
var
|
|
56045
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
56046
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
55947
56047
|
var TunnelStore = class {
|
|
55948
56048
|
constructor(filePath) {
|
|
55949
56049
|
this.filePath = filePath;
|
|
@@ -55951,7 +56051,7 @@ var TunnelStore = class {
|
|
|
55951
56051
|
filePath;
|
|
55952
56052
|
async get() {
|
|
55953
56053
|
try {
|
|
55954
|
-
const raw = await
|
|
56054
|
+
const raw = await import_node_fs37.default.promises.readFile(this.filePath, "utf8");
|
|
55955
56055
|
const obj = JSON.parse(raw);
|
|
55956
56056
|
if (!isPersistedTunnel(obj)) return null;
|
|
55957
56057
|
return obj;
|
|
@@ -55962,22 +56062,22 @@ var TunnelStore = class {
|
|
|
55962
56062
|
}
|
|
55963
56063
|
}
|
|
55964
56064
|
async set(v2) {
|
|
55965
|
-
const dir =
|
|
55966
|
-
await
|
|
56065
|
+
const dir = import_node_path41.default.dirname(this.filePath);
|
|
56066
|
+
await import_node_fs37.default.promises.mkdir(dir, { recursive: true });
|
|
55967
56067
|
const data = JSON.stringify(v2, null, 2);
|
|
55968
56068
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
55969
|
-
await
|
|
56069
|
+
await import_node_fs37.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
55970
56070
|
if (process.platform !== "win32") {
|
|
55971
56071
|
try {
|
|
55972
|
-
await
|
|
56072
|
+
await import_node_fs37.default.promises.chmod(tmp, 384);
|
|
55973
56073
|
} catch {
|
|
55974
56074
|
}
|
|
55975
56075
|
}
|
|
55976
|
-
await
|
|
56076
|
+
await import_node_fs37.default.promises.rename(tmp, this.filePath);
|
|
55977
56077
|
}
|
|
55978
56078
|
async clear() {
|
|
55979
56079
|
try {
|
|
55980
|
-
await
|
|
56080
|
+
await import_node_fs37.default.promises.unlink(this.filePath);
|
|
55981
56081
|
} catch (err) {
|
|
55982
56082
|
const code = err?.code;
|
|
55983
56083
|
if (code !== "ENOENT") throw err;
|
|
@@ -56072,9 +56172,9 @@ function escape(v2) {
|
|
|
56072
56172
|
}
|
|
56073
56173
|
|
|
56074
56174
|
// src/tunnel/frpc-binary.ts
|
|
56075
|
-
var
|
|
56175
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
56076
56176
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
56077
|
-
var
|
|
56177
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
56078
56178
|
var import_node_child_process7 = require("child_process");
|
|
56079
56179
|
var import_node_stream3 = require("stream");
|
|
56080
56180
|
var import_promises5 = require("stream/promises");
|
|
@@ -56106,20 +56206,20 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
56106
56206
|
}
|
|
56107
56207
|
async function ensureFrpcBinary(opts) {
|
|
56108
56208
|
if (opts.override) {
|
|
56109
|
-
if (!
|
|
56209
|
+
if (!import_node_fs38.default.existsSync(opts.override)) {
|
|
56110
56210
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
56111
56211
|
}
|
|
56112
56212
|
return opts.override;
|
|
56113
56213
|
}
|
|
56114
56214
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
56115
56215
|
const platform = opts.platform ?? detectPlatform();
|
|
56116
|
-
const binDir =
|
|
56117
|
-
|
|
56216
|
+
const binDir = import_node_path42.default.join(opts.dataDir, "bin");
|
|
56217
|
+
import_node_fs38.default.mkdirSync(binDir, { recursive: true });
|
|
56118
56218
|
cleanupStaleArtifacts(binDir);
|
|
56119
|
-
const stableBin =
|
|
56120
|
-
if (
|
|
56219
|
+
const stableBin = import_node_path42.default.join(binDir, "frpc");
|
|
56220
|
+
if (import_node_fs38.default.existsSync(stableBin)) return stableBin;
|
|
56121
56221
|
const partialBin = `${stableBin}.partial`;
|
|
56122
|
-
const tarballPath =
|
|
56222
|
+
const tarballPath = import_node_path42.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
56123
56223
|
try {
|
|
56124
56224
|
const url = frpcDownloadUrl(version2, platform);
|
|
56125
56225
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -56128,8 +56228,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
56128
56228
|
} else {
|
|
56129
56229
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
56130
56230
|
}
|
|
56131
|
-
|
|
56132
|
-
|
|
56231
|
+
import_node_fs38.default.chmodSync(partialBin, 493);
|
|
56232
|
+
import_node_fs38.default.renameSync(partialBin, stableBin);
|
|
56133
56233
|
} finally {
|
|
56134
56234
|
safeUnlink(tarballPath);
|
|
56135
56235
|
safeUnlink(partialBin);
|
|
@@ -56139,15 +56239,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
56139
56239
|
function cleanupStaleArtifacts(binDir) {
|
|
56140
56240
|
let entries;
|
|
56141
56241
|
try {
|
|
56142
|
-
entries =
|
|
56242
|
+
entries = import_node_fs38.default.readdirSync(binDir);
|
|
56143
56243
|
} catch {
|
|
56144
56244
|
return;
|
|
56145
56245
|
}
|
|
56146
56246
|
for (const name of entries) {
|
|
56147
56247
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
56148
|
-
const full =
|
|
56248
|
+
const full = import_node_path42.default.join(binDir, name);
|
|
56149
56249
|
try {
|
|
56150
|
-
|
|
56250
|
+
import_node_fs38.default.rmSync(full, { recursive: true, force: true });
|
|
56151
56251
|
} catch {
|
|
56152
56252
|
}
|
|
56153
56253
|
}
|
|
@@ -56155,7 +56255,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
56155
56255
|
}
|
|
56156
56256
|
function safeUnlink(p2) {
|
|
56157
56257
|
try {
|
|
56158
|
-
|
|
56258
|
+
import_node_fs38.default.unlinkSync(p2);
|
|
56159
56259
|
} catch {
|
|
56160
56260
|
}
|
|
56161
56261
|
}
|
|
@@ -56166,13 +56266,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
56166
56266
|
if (!res.ok || !res.body) {
|
|
56167
56267
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
56168
56268
|
}
|
|
56169
|
-
const out =
|
|
56269
|
+
const out = import_node_fs38.default.createWriteStream(dest);
|
|
56170
56270
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
56171
56271
|
await (0, import_promises5.pipeline)(nodeStream, out);
|
|
56172
56272
|
}
|
|
56173
56273
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
56174
|
-
const work =
|
|
56175
|
-
|
|
56274
|
+
const work = import_node_path42.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
56275
|
+
import_node_fs38.default.mkdirSync(work, { recursive: true });
|
|
56176
56276
|
try {
|
|
56177
56277
|
await new Promise((resolve6, reject) => {
|
|
56178
56278
|
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -56180,32 +56280,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
56180
56280
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
56181
56281
|
});
|
|
56182
56282
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
56183
|
-
const src =
|
|
56184
|
-
if (!
|
|
56283
|
+
const src = import_node_path42.default.join(work, dirName, "frpc");
|
|
56284
|
+
if (!import_node_fs38.default.existsSync(src)) {
|
|
56185
56285
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
56186
56286
|
}
|
|
56187
|
-
|
|
56287
|
+
import_node_fs38.default.copyFileSync(src, destBin);
|
|
56188
56288
|
} finally {
|
|
56189
|
-
|
|
56289
|
+
import_node_fs38.default.rmSync(work, { recursive: true, force: true });
|
|
56190
56290
|
}
|
|
56191
56291
|
}
|
|
56192
56292
|
|
|
56193
56293
|
// src/tunnel/frpc-process.ts
|
|
56194
|
-
var
|
|
56195
|
-
var
|
|
56294
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
56295
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
56196
56296
|
var import_node_child_process8 = require("child_process");
|
|
56197
56297
|
function frpcPidFilePath(dataDir) {
|
|
56198
|
-
return
|
|
56298
|
+
return import_node_path43.default.join(dataDir, "frpc.pid");
|
|
56199
56299
|
}
|
|
56200
56300
|
function writeFrpcPid(dataDir, pid) {
|
|
56201
56301
|
try {
|
|
56202
|
-
|
|
56302
|
+
import_node_fs39.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
56203
56303
|
} catch {
|
|
56204
56304
|
}
|
|
56205
56305
|
}
|
|
56206
56306
|
function clearFrpcPid(dataDir) {
|
|
56207
56307
|
try {
|
|
56208
|
-
|
|
56308
|
+
import_node_fs39.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
56209
56309
|
} catch {
|
|
56210
56310
|
}
|
|
56211
56311
|
}
|
|
@@ -56221,7 +56321,7 @@ function defaultIsPidAlive(pid) {
|
|
|
56221
56321
|
}
|
|
56222
56322
|
function defaultReadPidFile(file) {
|
|
56223
56323
|
try {
|
|
56224
|
-
return
|
|
56324
|
+
return import_node_fs39.default.readFileSync(file, "utf8");
|
|
56225
56325
|
} catch {
|
|
56226
56326
|
return null;
|
|
56227
56327
|
}
|
|
@@ -56237,7 +56337,7 @@ function defaultSleep2(ms) {
|
|
|
56237
56337
|
}
|
|
56238
56338
|
async function killStaleFrpc(deps) {
|
|
56239
56339
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
56240
|
-
const tomlPath =
|
|
56340
|
+
const tomlPath = import_node_path43.default.join(deps.dataDir, "frpc.toml");
|
|
56241
56341
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
56242
56342
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
56243
56343
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -56261,7 +56361,7 @@ async function killStaleFrpc(deps) {
|
|
|
56261
56361
|
}
|
|
56262
56362
|
if (victims.size === 0) {
|
|
56263
56363
|
try {
|
|
56264
|
-
|
|
56364
|
+
import_node_fs39.default.unlinkSync(pidFile);
|
|
56265
56365
|
} catch {
|
|
56266
56366
|
}
|
|
56267
56367
|
return;
|
|
@@ -56272,7 +56372,7 @@ async function killStaleFrpc(deps) {
|
|
|
56272
56372
|
}
|
|
56273
56373
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
56274
56374
|
try {
|
|
56275
|
-
|
|
56375
|
+
import_node_fs39.default.unlinkSync(pidFile);
|
|
56276
56376
|
} catch {
|
|
56277
56377
|
}
|
|
56278
56378
|
}
|
|
@@ -56309,7 +56409,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
56309
56409
|
var TunnelManager = class {
|
|
56310
56410
|
constructor(deps) {
|
|
56311
56411
|
this.deps = deps;
|
|
56312
|
-
this.store = deps.store ?? new TunnelStore(
|
|
56412
|
+
this.store = deps.store ?? new TunnelStore(import_node_path44.default.join(deps.dataDir, "tunnel.json"));
|
|
56313
56413
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
56314
56414
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
56315
56415
|
}
|
|
@@ -56436,7 +56536,7 @@ var TunnelManager = class {
|
|
|
56436
56536
|
dataDir: this.deps.dataDir,
|
|
56437
56537
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
56438
56538
|
});
|
|
56439
|
-
const tomlPath =
|
|
56539
|
+
const tomlPath = import_node_path44.default.join(this.deps.dataDir, "frpc.toml");
|
|
56440
56540
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
|
|
56441
56541
|
const toml = buildFrpcToml({
|
|
56442
56542
|
serverAddr: t.frpsHost,
|
|
@@ -56447,14 +56547,14 @@ var TunnelManager = class {
|
|
|
56447
56547
|
localPort,
|
|
56448
56548
|
logLevel: "info"
|
|
56449
56549
|
});
|
|
56450
|
-
await
|
|
56550
|
+
await import_node_fs40.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
56451
56551
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
56452
56552
|
stdio: ["ignore", "pipe", "pipe"]
|
|
56453
56553
|
});
|
|
56454
|
-
const logDir =
|
|
56455
|
-
|
|
56456
|
-
const logFilePath =
|
|
56457
|
-
const logStream =
|
|
56554
|
+
const logDir = import_node_path44.default.join(this.deps.dataDir, "log");
|
|
56555
|
+
import_node_fs40.default.mkdirSync(logDir, { recursive: true });
|
|
56556
|
+
const logFilePath = import_node_path44.default.join(logDir, "frpc.log");
|
|
56557
|
+
const logStream = import_node_fs40.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
56458
56558
|
logStream.on("error", () => {
|
|
56459
56559
|
});
|
|
56460
56560
|
const tee = (chunk) => {
|
|
@@ -56537,27 +56637,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
56537
56637
|
|
|
56538
56638
|
// src/tunnel/device-key.ts
|
|
56539
56639
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
56540
|
-
var
|
|
56640
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
56541
56641
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
56542
56642
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
56543
56643
|
function deriveStableDeviceKey(opts = {}) {
|
|
56544
56644
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
56545
56645
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
56546
56646
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
56547
|
-
const defaultDataDir =
|
|
56548
|
-
const normalizedDataDir = opts.dataDir ?
|
|
56647
|
+
const defaultDataDir = import_node_path45.default.resolve(import_node_path45.default.join(home, ".clawd"));
|
|
56648
|
+
const normalizedDataDir = opts.dataDir ? import_node_path45.default.resolve(opts.dataDir) : null;
|
|
56549
56649
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
56550
56650
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
56551
56651
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
56552
56652
|
}
|
|
56553
56653
|
|
|
56554
56654
|
// src/auth-store.ts
|
|
56555
|
-
var
|
|
56556
|
-
var
|
|
56655
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
56656
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
56557
56657
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
56558
56658
|
var AUTH_FILE_NAME = "auth.json";
|
|
56559
56659
|
function authFilePath(dataDir) {
|
|
56560
|
-
return
|
|
56660
|
+
return import_node_path46.default.join(dataDir, AUTH_FILE_NAME);
|
|
56561
56661
|
}
|
|
56562
56662
|
function loadOrCreateAuthFile(opts) {
|
|
56563
56663
|
const file = authFilePath(opts.dataDir);
|
|
@@ -56589,7 +56689,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
56589
56689
|
}
|
|
56590
56690
|
function readAuthFile(file) {
|
|
56591
56691
|
try {
|
|
56592
|
-
const raw =
|
|
56692
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
56593
56693
|
const parsed = JSON.parse(raw);
|
|
56594
56694
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
56595
56695
|
return null;
|
|
@@ -56609,25 +56709,25 @@ function readAuthFile(file) {
|
|
|
56609
56709
|
}
|
|
56610
56710
|
}
|
|
56611
56711
|
function writeAuthFile(file, content) {
|
|
56612
|
-
|
|
56613
|
-
|
|
56712
|
+
import_node_fs41.default.mkdirSync(import_node_path46.default.dirname(file), { recursive: true });
|
|
56713
|
+
import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
56614
56714
|
try {
|
|
56615
|
-
|
|
56715
|
+
import_node_fs41.default.chmodSync(file, 384);
|
|
56616
56716
|
} catch {
|
|
56617
56717
|
}
|
|
56618
56718
|
}
|
|
56619
56719
|
|
|
56620
56720
|
// src/owner-profile.ts
|
|
56621
|
-
var
|
|
56721
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
56622
56722
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
56623
|
-
var
|
|
56723
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
56624
56724
|
var PROFILE_FILENAME = "profile.json";
|
|
56625
56725
|
function loadOwnerDisplayName(dataDir) {
|
|
56626
56726
|
const fallback = import_node_os15.default.userInfo().username;
|
|
56627
|
-
const profilePath =
|
|
56727
|
+
const profilePath = import_node_path47.default.join(dataDir, PROFILE_FILENAME);
|
|
56628
56728
|
let raw;
|
|
56629
56729
|
try {
|
|
56630
|
-
raw =
|
|
56730
|
+
raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
|
|
56631
56731
|
} catch {
|
|
56632
56732
|
return fallback;
|
|
56633
56733
|
}
|
|
@@ -56650,18 +56750,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
56650
56750
|
}
|
|
56651
56751
|
|
|
56652
56752
|
// src/feishu-auth/owner-identity-store.ts
|
|
56653
|
-
var
|
|
56654
|
-
var
|
|
56753
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
56754
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
56655
56755
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
56656
56756
|
var OwnerIdentityStore = class {
|
|
56657
56757
|
file;
|
|
56658
56758
|
constructor(dataDir) {
|
|
56659
|
-
this.file =
|
|
56759
|
+
this.file = import_node_path48.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
56660
56760
|
}
|
|
56661
56761
|
read() {
|
|
56662
56762
|
let raw;
|
|
56663
56763
|
try {
|
|
56664
|
-
raw =
|
|
56764
|
+
raw = import_node_fs43.default.readFileSync(this.file, "utf8");
|
|
56665
56765
|
} catch {
|
|
56666
56766
|
return null;
|
|
56667
56767
|
}
|
|
@@ -56689,16 +56789,16 @@ var OwnerIdentityStore = class {
|
|
|
56689
56789
|
};
|
|
56690
56790
|
}
|
|
56691
56791
|
write(record) {
|
|
56692
|
-
|
|
56693
|
-
|
|
56792
|
+
import_node_fs43.default.mkdirSync(import_node_path48.default.dirname(this.file), { recursive: true });
|
|
56793
|
+
import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
56694
56794
|
try {
|
|
56695
|
-
|
|
56795
|
+
import_node_fs43.default.chmodSync(this.file, 384);
|
|
56696
56796
|
} catch {
|
|
56697
56797
|
}
|
|
56698
56798
|
}
|
|
56699
56799
|
clear() {
|
|
56700
56800
|
try {
|
|
56701
|
-
|
|
56801
|
+
import_node_fs43.default.unlinkSync(this.file);
|
|
56702
56802
|
} catch (err) {
|
|
56703
56803
|
const code = err?.code;
|
|
56704
56804
|
if (code !== "ENOENT") throw err;
|
|
@@ -56835,9 +56935,9 @@ var CentralClientError = class extends Error {
|
|
|
56835
56935
|
code;
|
|
56836
56936
|
cause;
|
|
56837
56937
|
};
|
|
56838
|
-
async function centralRequest(opts,
|
|
56938
|
+
async function centralRequest(opts, path79, init) {
|
|
56839
56939
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
56840
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
56940
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path79}`;
|
|
56841
56941
|
const ctrl = new AbortController();
|
|
56842
56942
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
56843
56943
|
let res;
|
|
@@ -57031,8 +57131,8 @@ function verifyConnectToken(args) {
|
|
|
57031
57131
|
}
|
|
57032
57132
|
|
|
57033
57133
|
// src/feishu-auth/server-key.ts
|
|
57034
|
-
var
|
|
57035
|
-
var
|
|
57134
|
+
var fs53 = __toESM(require("fs"), 1);
|
|
57135
|
+
var path57 = __toESM(require("path"), 1);
|
|
57036
57136
|
var FILE_NAME2 = "server-signing-key.json";
|
|
57037
57137
|
var ServerKeyStore = class {
|
|
57038
57138
|
constructor(dataDir) {
|
|
@@ -57040,12 +57140,12 @@ var ServerKeyStore = class {
|
|
|
57040
57140
|
}
|
|
57041
57141
|
dataDir;
|
|
57042
57142
|
filePath() {
|
|
57043
|
-
return
|
|
57143
|
+
return path57.join(this.dataDir, FILE_NAME2);
|
|
57044
57144
|
}
|
|
57045
57145
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
57046
57146
|
read() {
|
|
57047
57147
|
try {
|
|
57048
|
-
const raw =
|
|
57148
|
+
const raw = fs53.readFileSync(this.filePath(), "utf8");
|
|
57049
57149
|
const parsed = JSON.parse(raw);
|
|
57050
57150
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
57051
57151
|
return parsed.publicKeyPem;
|
|
@@ -57060,12 +57160,12 @@ var ServerKeyStore = class {
|
|
|
57060
57160
|
publicKeyPem,
|
|
57061
57161
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
57062
57162
|
};
|
|
57063
|
-
|
|
57064
|
-
|
|
57163
|
+
fs53.mkdirSync(this.dataDir, { recursive: true });
|
|
57164
|
+
fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
57065
57165
|
}
|
|
57066
57166
|
clear() {
|
|
57067
57167
|
try {
|
|
57068
|
-
|
|
57168
|
+
fs53.unlinkSync(this.filePath());
|
|
57069
57169
|
} catch {
|
|
57070
57170
|
}
|
|
57071
57171
|
}
|
|
@@ -57078,12 +57178,12 @@ init_protocol();
|
|
|
57078
57178
|
init_protocol();
|
|
57079
57179
|
|
|
57080
57180
|
// src/session/fork.ts
|
|
57081
|
-
var
|
|
57181
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
57082
57182
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
57083
|
-
var
|
|
57183
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
57084
57184
|
init_claude_history();
|
|
57085
57185
|
function readJsonlEntries(file) {
|
|
57086
|
-
const raw =
|
|
57186
|
+
const raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
57087
57187
|
const out = [];
|
|
57088
57188
|
for (const line of raw.split("\n")) {
|
|
57089
57189
|
const t = line.trim();
|
|
@@ -57096,19 +57196,19 @@ function readJsonlEntries(file) {
|
|
|
57096
57196
|
return out;
|
|
57097
57197
|
}
|
|
57098
57198
|
function forkSession(input) {
|
|
57099
|
-
const baseDir = input.baseDir ??
|
|
57100
|
-
let projectDir =
|
|
57101
|
-
let sourceFile =
|
|
57102
|
-
if (!
|
|
57199
|
+
const baseDir = input.baseDir ?? import_node_path49.default.join(import_node_os16.default.homedir(), ".claude");
|
|
57200
|
+
let projectDir = import_node_path49.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
57201
|
+
let sourceFile = import_node_path49.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
57202
|
+
if (!import_node_fs44.default.existsSync(sourceFile)) {
|
|
57103
57203
|
const found = findTranscriptByToolSessionId(
|
|
57104
|
-
|
|
57204
|
+
import_node_path49.default.join(baseDir, "projects"),
|
|
57105
57205
|
input.toolSessionId
|
|
57106
57206
|
);
|
|
57107
57207
|
if (!found) {
|
|
57108
57208
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
57109
57209
|
}
|
|
57110
57210
|
sourceFile = found;
|
|
57111
|
-
projectDir =
|
|
57211
|
+
projectDir = import_node_path49.default.dirname(found);
|
|
57112
57212
|
}
|
|
57113
57213
|
const entries = readJsonlEntries(sourceFile);
|
|
57114
57214
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -57137,10 +57237,10 @@ function forkSession(input) {
|
|
|
57137
57237
|
}
|
|
57138
57238
|
forkedLines.push(JSON.stringify(forked));
|
|
57139
57239
|
}
|
|
57140
|
-
const outDir = input.targetCwd ?
|
|
57141
|
-
const forkedFilePath =
|
|
57142
|
-
|
|
57143
|
-
|
|
57240
|
+
const outDir = input.targetCwd ? import_node_path49.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
57241
|
+
const forkedFilePath = import_node_path49.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
57242
|
+
import_node_fs44.default.mkdirSync(outDir, { recursive: true });
|
|
57243
|
+
import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
57144
57244
|
return { forkedToolSessionId, forkedFilePath };
|
|
57145
57245
|
}
|
|
57146
57246
|
|
|
@@ -57599,7 +57699,7 @@ function buildPermissionHandlers(deps) {
|
|
|
57599
57699
|
}
|
|
57600
57700
|
|
|
57601
57701
|
// src/handlers/history.ts
|
|
57602
|
-
var
|
|
57702
|
+
var path60 = __toESM(require("path"), 1);
|
|
57603
57703
|
init_protocol();
|
|
57604
57704
|
|
|
57605
57705
|
// src/session/recent-dirs.ts
|
|
@@ -57617,7 +57717,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
57617
57717
|
}
|
|
57618
57718
|
|
|
57619
57719
|
// src/permission/persona-paths.ts
|
|
57620
|
-
var
|
|
57720
|
+
var path59 = __toESM(require("path"), 1);
|
|
57621
57721
|
function getAllowedPersonaIds(grants, action) {
|
|
57622
57722
|
const ids = /* @__PURE__ */ new Set();
|
|
57623
57723
|
for (const g2 of grants) {
|
|
@@ -57630,42 +57730,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
57630
57730
|
return ids;
|
|
57631
57731
|
}
|
|
57632
57732
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
57633
|
-
const target =
|
|
57733
|
+
const target = path59.resolve(absPath);
|
|
57634
57734
|
if (userWorkDir) {
|
|
57635
|
-
const u =
|
|
57636
|
-
const usep = u.endsWith(
|
|
57735
|
+
const u = path59.resolve(userWorkDir);
|
|
57736
|
+
const usep = u.endsWith(path59.sep) ? "" : path59.sep;
|
|
57637
57737
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
57638
57738
|
}
|
|
57639
|
-
const root =
|
|
57640
|
-
const sep3 = root.endsWith(
|
|
57739
|
+
const root = path59.resolve(personaRoot);
|
|
57740
|
+
const sep3 = root.endsWith(path59.sep) ? "" : path59.sep;
|
|
57641
57741
|
if (!target.startsWith(root + sep3)) return false;
|
|
57642
|
-
const rel =
|
|
57742
|
+
const rel = path59.relative(root, target);
|
|
57643
57743
|
if (!rel || rel.startsWith("..")) return false;
|
|
57644
|
-
const personaId2 = rel.split(
|
|
57744
|
+
const personaId2 = rel.split(path59.sep)[0];
|
|
57645
57745
|
if (!personaId2) return false;
|
|
57646
57746
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
57647
57747
|
if (allowed === "*") return true;
|
|
57648
57748
|
return allowed.has(personaId2);
|
|
57649
57749
|
}
|
|
57650
57750
|
function personaIdFromPath(absPath, personaRoot) {
|
|
57651
|
-
const root =
|
|
57652
|
-
const target =
|
|
57653
|
-
const sep3 = root.endsWith(
|
|
57751
|
+
const root = path59.resolve(personaRoot);
|
|
57752
|
+
const target = path59.resolve(absPath);
|
|
57753
|
+
const sep3 = root.endsWith(path59.sep) ? "" : path59.sep;
|
|
57654
57754
|
if (!target.startsWith(root + sep3)) return null;
|
|
57655
|
-
const rel =
|
|
57755
|
+
const rel = path59.relative(root, target);
|
|
57656
57756
|
if (!rel || rel.startsWith("..")) return null;
|
|
57657
|
-
const id = rel.split(
|
|
57757
|
+
const id = rel.split(path59.sep)[0];
|
|
57658
57758
|
return id || null;
|
|
57659
57759
|
}
|
|
57660
57760
|
function isPathWithin(dir, absPath) {
|
|
57661
|
-
const d =
|
|
57662
|
-
const t =
|
|
57663
|
-
const sep3 = d.endsWith(
|
|
57761
|
+
const d = path59.resolve(dir);
|
|
57762
|
+
const t = path59.resolve(absPath);
|
|
57763
|
+
const sep3 = d.endsWith(path59.sep) ? "" : path59.sep;
|
|
57664
57764
|
return t === d || t.startsWith(d + sep3);
|
|
57665
57765
|
}
|
|
57666
57766
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
57667
57767
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
57668
|
-
return personaIdFromPath(
|
|
57768
|
+
return personaIdFromPath(path59.resolve(absPath), personaRoot) === personaId2;
|
|
57669
57769
|
}
|
|
57670
57770
|
|
|
57671
57771
|
// src/handlers/history.ts
|
|
@@ -57717,7 +57817,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57717
57817
|
if (!pid) return false;
|
|
57718
57818
|
return isGuestPathAllowed(
|
|
57719
57819
|
ctx.grants,
|
|
57720
|
-
|
|
57820
|
+
path60.join(personaRoot, pid),
|
|
57721
57821
|
personaRoot,
|
|
57722
57822
|
"read",
|
|
57723
57823
|
userWorkDir
|
|
@@ -57729,7 +57829,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57729
57829
|
};
|
|
57730
57830
|
const list = async (frame, _client, ctx) => {
|
|
57731
57831
|
const args = HistoryListArgs.parse(frame);
|
|
57732
|
-
assertGuestPath(ctx,
|
|
57832
|
+
assertGuestPath(ctx, path60.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
57733
57833
|
const sessions = await history.listSessions(args);
|
|
57734
57834
|
return { response: { type: "history:list", sessions } };
|
|
57735
57835
|
};
|
|
@@ -57773,14 +57873,14 @@ function buildHistoryHandlers(deps) {
|
|
|
57773
57873
|
};
|
|
57774
57874
|
const subagents = async (frame, _client, ctx) => {
|
|
57775
57875
|
const args = HistorySubagentsArgs.parse(frame);
|
|
57776
|
-
assertGuestPath(ctx,
|
|
57876
|
+
assertGuestPath(ctx, path60.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
57777
57877
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
57778
57878
|
const subs = await history.listSubagents(args);
|
|
57779
57879
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
57780
57880
|
};
|
|
57781
57881
|
const subagentRead = async (frame, _client, ctx) => {
|
|
57782
57882
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
57783
|
-
assertGuestPath(ctx,
|
|
57883
|
+
assertGuestPath(ctx, path60.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
57784
57884
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
57785
57885
|
const res = await history.readSubagent(args);
|
|
57786
57886
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -57790,7 +57890,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57790
57890
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
57791
57891
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
57792
57892
|
const filtered = dirs.filter(
|
|
57793
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
57893
|
+
(d) => isGuestPathAllowed(ctx.grants, path60.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
57794
57894
|
);
|
|
57795
57895
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
57796
57896
|
}
|
|
@@ -57807,7 +57907,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57807
57907
|
}
|
|
57808
57908
|
|
|
57809
57909
|
// src/handlers/workspace.ts
|
|
57810
|
-
var
|
|
57910
|
+
var path61 = __toESM(require("path"), 1);
|
|
57811
57911
|
var os16 = __toESM(require("os"), 1);
|
|
57812
57912
|
init_protocol();
|
|
57813
57913
|
init_protocol();
|
|
@@ -57849,22 +57949,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57849
57949
|
const args = WorkspaceListArgs.parse(frame);
|
|
57850
57950
|
const isGuest = ctx?.principal.kind === "guest";
|
|
57851
57951
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
57852
|
-
const resolvedCwd =
|
|
57853
|
-
const target = args.path ?
|
|
57952
|
+
const resolvedCwd = path61.resolve(args.cwd ?? fallbackCwd);
|
|
57953
|
+
const target = args.path ? path61.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
57854
57954
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
57855
57955
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
57856
57956
|
return { response: { type: "workspace:list", ...res } };
|
|
57857
57957
|
};
|
|
57858
57958
|
const read = async (frame, _client, ctx) => {
|
|
57859
57959
|
const args = WorkspaceReadArgs.parse(frame);
|
|
57860
|
-
const target =
|
|
57960
|
+
const target = path61.isAbsolute(args.path) ? path61.resolve(args.path) : path61.resolve(args.cwd, args.path);
|
|
57861
57961
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
57862
57962
|
const res = workspace.read(args);
|
|
57863
57963
|
return { response: { type: "workspace:read", ...res } };
|
|
57864
57964
|
};
|
|
57865
57965
|
const skillsList = async (frame, _client, ctx) => {
|
|
57866
57966
|
const args = SkillsListArgs.parse(frame);
|
|
57867
|
-
const cwdAbs =
|
|
57967
|
+
const cwdAbs = path61.resolve(args.cwd);
|
|
57868
57968
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
57869
57969
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
57870
57970
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -57876,7 +57976,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57876
57976
|
};
|
|
57877
57977
|
const agentsList = async (frame, _client, ctx) => {
|
|
57878
57978
|
const args = AgentsListArgs.parse(frame);
|
|
57879
|
-
const cwdAbs =
|
|
57979
|
+
const cwdAbs = path61.resolve(args.cwd);
|
|
57880
57980
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
57881
57981
|
if (args.tool === "codex") {
|
|
57882
57982
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -57898,20 +57998,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57898
57998
|
}
|
|
57899
57999
|
|
|
57900
58000
|
// src/handlers/git.ts
|
|
57901
|
-
var
|
|
58001
|
+
var path63 = __toESM(require("path"), 1);
|
|
57902
58002
|
init_protocol();
|
|
57903
58003
|
init_protocol();
|
|
57904
58004
|
|
|
57905
58005
|
// src/workspace/git.ts
|
|
57906
58006
|
var import_node_child_process10 = require("child_process");
|
|
57907
|
-
var
|
|
57908
|
-
var
|
|
58007
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
58008
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
57909
58009
|
var import_node_util = require("util");
|
|
57910
58010
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
57911
58011
|
function normalizePath(p2) {
|
|
57912
|
-
const resolved =
|
|
58012
|
+
const resolved = import_node_path50.default.resolve(p2);
|
|
57913
58013
|
try {
|
|
57914
|
-
return
|
|
58014
|
+
return import_node_fs45.default.realpathSync(resolved);
|
|
57915
58015
|
} catch {
|
|
57916
58016
|
return resolved;
|
|
57917
58017
|
}
|
|
@@ -57985,7 +58085,7 @@ async function listGitBranches(cwd) {
|
|
|
57985
58085
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
57986
58086
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
57987
58087
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
57988
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
58088
|
+
if (!isGuestPathAllowed(ctx.grants, path63.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
57989
58089
|
throw new ClawdError(
|
|
57990
58090
|
ERROR_CODES.UNAUTHORIZED,
|
|
57991
58091
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -58850,21 +58950,21 @@ function computeMethodAccess(args) {
|
|
|
58850
58950
|
}
|
|
58851
58951
|
|
|
58852
58952
|
// src/version.ts
|
|
58853
|
-
var version = "0.2.
|
|
58953
|
+
var version = "0.2.295".length > 0 ? "0.2.295" : "dev";
|
|
58854
58954
|
|
|
58855
58955
|
// src/cli-probe/probe.ts
|
|
58856
|
-
var
|
|
58857
|
-
var
|
|
58956
|
+
var fs56 = __toESM(require("fs"), 1);
|
|
58957
|
+
var path64 = __toESM(require("path"), 1);
|
|
58858
58958
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
58859
58959
|
var BIN_NAME = "clawd";
|
|
58860
58960
|
var MAX_PARENT_HOPS = 5;
|
|
58861
58961
|
function probeGlobalCli(pathEnv) {
|
|
58862
58962
|
if (!pathEnv) return null;
|
|
58863
|
-
for (const dir of pathEnv.split(
|
|
58963
|
+
for (const dir of pathEnv.split(path64.delimiter)) {
|
|
58864
58964
|
if (!dir) continue;
|
|
58865
58965
|
let real;
|
|
58866
58966
|
try {
|
|
58867
|
-
real =
|
|
58967
|
+
real = fs56.realpathSync(path64.join(dir, BIN_NAME));
|
|
58868
58968
|
} catch {
|
|
58869
58969
|
continue;
|
|
58870
58970
|
}
|
|
@@ -58874,15 +58974,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
58874
58974
|
return null;
|
|
58875
58975
|
}
|
|
58876
58976
|
function readOwnPackageVersion(entryPath) {
|
|
58877
|
-
let dir =
|
|
58977
|
+
let dir = path64.dirname(entryPath);
|
|
58878
58978
|
for (let i = 0; i < MAX_PARENT_HOPS; i++) {
|
|
58879
58979
|
try {
|
|
58880
|
-
const raw =
|
|
58980
|
+
const raw = fs56.readFileSync(path64.join(dir, "package.json"), "utf8");
|
|
58881
58981
|
const pkg = JSON.parse(raw);
|
|
58882
58982
|
if (pkg.name !== PKG_NAME) return null;
|
|
58883
58983
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
58884
58984
|
} catch {
|
|
58885
|
-
const parent =
|
|
58985
|
+
const parent = path64.dirname(dir);
|
|
58886
58986
|
if (parent === dir) return null;
|
|
58887
58987
|
dir = parent;
|
|
58888
58988
|
}
|
|
@@ -59040,7 +59140,7 @@ function buildPersonaHandlers(deps) {
|
|
|
59040
59140
|
}
|
|
59041
59141
|
|
|
59042
59142
|
// src/handlers/attachment.ts
|
|
59043
|
-
var
|
|
59143
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
59044
59144
|
init_protocol();
|
|
59045
59145
|
init_protocol();
|
|
59046
59146
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -59120,12 +59220,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
59120
59220
|
`session ${args.sessionId} scope unresolved`
|
|
59121
59221
|
);
|
|
59122
59222
|
}
|
|
59123
|
-
const cwdAbs =
|
|
59124
|
-
const candidateAbs =
|
|
59223
|
+
const cwdAbs = import_node_path51.default.resolve(sessionFile.cwd);
|
|
59224
|
+
const candidateAbs = import_node_path51.default.isAbsolute(args.relPath) ? import_node_path51.default.resolve(args.relPath) : import_node_path51.default.resolve(cwdAbs, args.relPath);
|
|
59125
59225
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
59126
59226
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
59127
59227
|
const entry = entries.find((e) => {
|
|
59128
|
-
const storedAbs =
|
|
59228
|
+
const storedAbs = import_node_path51.default.isAbsolute(e.relPath) ? import_node_path51.default.resolve(e.relPath) : import_node_path51.default.resolve(cwdAbs, e.relPath);
|
|
59129
59229
|
return storedAbs === candidateAbs && !e.stale;
|
|
59130
59230
|
});
|
|
59131
59231
|
if (!entry) {
|
|
@@ -59150,7 +59250,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
59150
59250
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
59151
59251
|
const f = deps.sessionStore.read(sessionId);
|
|
59152
59252
|
if (!f) return;
|
|
59153
|
-
assertGuestAttachmentPath(ctx,
|
|
59253
|
+
assertGuestAttachmentPath(ctx, import_node_path51.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
59154
59254
|
}
|
|
59155
59255
|
const groupAdd = async (frame, _client, ctx) => {
|
|
59156
59256
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -59165,8 +59265,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
59165
59265
|
if (!scope) {
|
|
59166
59266
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
59167
59267
|
}
|
|
59168
|
-
const cwdAbs =
|
|
59169
|
-
const candidateAbs =
|
|
59268
|
+
const cwdAbs = import_node_path51.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
59269
|
+
const candidateAbs = import_node_path51.default.isAbsolute(args.relPath) ? import_node_path51.default.resolve(args.relPath) : import_node_path51.default.resolve(cwdAbs, args.relPath);
|
|
59170
59270
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
59171
59271
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
59172
59272
|
const size = 0;
|
|
@@ -59225,19 +59325,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
59225
59325
|
|
|
59226
59326
|
// src/handlers/extension.ts
|
|
59227
59327
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
59228
|
-
var
|
|
59328
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
59229
59329
|
init_protocol();
|
|
59230
59330
|
|
|
59231
59331
|
// src/extension/bundle-zip.ts
|
|
59232
59332
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
59233
|
-
var
|
|
59333
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
59234
59334
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
59235
59335
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
59236
59336
|
async function bundleExtensionDir(dir) {
|
|
59237
59337
|
const entries = await listFilesSorted(dir);
|
|
59238
59338
|
const zip = new import_jszip2.default();
|
|
59239
59339
|
for (const rel of entries) {
|
|
59240
|
-
const abs =
|
|
59340
|
+
const abs = import_node_path52.default.join(dir, rel);
|
|
59241
59341
|
const content = await import_promises6.default.readFile(abs);
|
|
59242
59342
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
59243
59343
|
}
|
|
@@ -59258,7 +59358,7 @@ async function listFilesSorted(rootDir) {
|
|
|
59258
59358
|
return out;
|
|
59259
59359
|
}
|
|
59260
59360
|
async function walk(absRoot, relPrefix, out) {
|
|
59261
|
-
const dirAbs =
|
|
59361
|
+
const dirAbs = import_node_path52.default.join(absRoot, relPrefix);
|
|
59262
59362
|
const entries = await import_promises6.default.readdir(dirAbs, { withFileTypes: true });
|
|
59263
59363
|
for (const e of entries) {
|
|
59264
59364
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -59312,25 +59412,25 @@ function computePublishCheck(args) {
|
|
|
59312
59412
|
|
|
59313
59413
|
// src/extension/install-flow.ts
|
|
59314
59414
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
59315
|
-
var
|
|
59415
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
59316
59416
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
59317
59417
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
59318
59418
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
59319
59419
|
|
|
59320
59420
|
// src/extension/paths.ts
|
|
59321
59421
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
59322
|
-
var
|
|
59422
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
59323
59423
|
function clawdHomeRoot(override) {
|
|
59324
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
59424
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path53.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
59325
59425
|
}
|
|
59326
59426
|
function extensionsRoot(override) {
|
|
59327
|
-
return
|
|
59427
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extensions");
|
|
59328
59428
|
}
|
|
59329
59429
|
function publishedChannelsFile(override) {
|
|
59330
|
-
return
|
|
59430
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
59331
59431
|
}
|
|
59332
59432
|
function bundleCacheRoot(override) {
|
|
59333
|
-
return
|
|
59433
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
59334
59434
|
}
|
|
59335
59435
|
|
|
59336
59436
|
// src/extension/install-flow.ts
|
|
@@ -59357,7 +59457,7 @@ async function installFromChannel(args, deps) {
|
|
|
59357
59457
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
59358
59458
|
}
|
|
59359
59459
|
for (const name of Object.keys(zip.files)) {
|
|
59360
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
59460
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path54.default.isAbsolute(name)) {
|
|
59361
59461
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
59362
59462
|
}
|
|
59363
59463
|
}
|
|
@@ -59389,7 +59489,7 @@ async function installFromChannel(args, deps) {
|
|
|
59389
59489
|
);
|
|
59390
59490
|
}
|
|
59391
59491
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
59392
|
-
const destDir =
|
|
59492
|
+
const destDir = import_node_path54.default.join(deps.extensionsRoot, localExtId);
|
|
59393
59493
|
let destExists = false;
|
|
59394
59494
|
try {
|
|
59395
59495
|
await import_promises7.default.access(destDir);
|
|
@@ -59403,16 +59503,16 @@ async function installFromChannel(args, deps) {
|
|
|
59403
59503
|
);
|
|
59404
59504
|
}
|
|
59405
59505
|
const stage = await import_promises7.default.mkdtemp(
|
|
59406
|
-
|
|
59506
|
+
import_node_path54.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
59407
59507
|
);
|
|
59408
59508
|
try {
|
|
59409
59509
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
59410
|
-
const dest =
|
|
59510
|
+
const dest = import_node_path54.default.join(stage, name);
|
|
59411
59511
|
if (entry.dir) {
|
|
59412
59512
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
59413
59513
|
continue;
|
|
59414
59514
|
}
|
|
59415
|
-
await import_promises7.default.mkdir(
|
|
59515
|
+
await import_promises7.default.mkdir(import_node_path54.default.dirname(dest), { recursive: true });
|
|
59416
59516
|
if (name === "manifest.json") {
|
|
59417
59517
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
59418
59518
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -59433,7 +59533,7 @@ async function installFromChannel(args, deps) {
|
|
|
59433
59533
|
|
|
59434
59534
|
// src/extension/update-flow.ts
|
|
59435
59535
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
59436
|
-
var
|
|
59536
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
59437
59537
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
59438
59538
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
59439
59539
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -59450,11 +59550,11 @@ async function updateFromChannel(args, deps) {
|
|
|
59450
59550
|
channelRef.extId,
|
|
59451
59551
|
channelRef.ownerPrincipalId
|
|
59452
59552
|
);
|
|
59453
|
-
const liveDir =
|
|
59553
|
+
const liveDir = import_node_path55.default.join(deps.extensionsRoot, localExtId);
|
|
59454
59554
|
const prevDir = `${liveDir}.prev`;
|
|
59455
59555
|
let existingVersion;
|
|
59456
59556
|
try {
|
|
59457
|
-
const raw = await import_promises8.default.readFile(
|
|
59557
|
+
const raw = await import_promises8.default.readFile(import_node_path55.default.join(liveDir, "manifest.json"), "utf8");
|
|
59458
59558
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
59459
59559
|
if (!parsed2.success) {
|
|
59460
59560
|
throw new UpdateError(
|
|
@@ -59487,7 +59587,7 @@ async function updateFromChannel(args, deps) {
|
|
|
59487
59587
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
59488
59588
|
}
|
|
59489
59589
|
for (const name of Object.keys(zip.files)) {
|
|
59490
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
59590
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path55.default.isAbsolute(name)) {
|
|
59491
59591
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
59492
59592
|
}
|
|
59493
59593
|
}
|
|
@@ -59522,16 +59622,16 @@ async function updateFromChannel(args, deps) {
|
|
|
59522
59622
|
await import_promises8.default.rm(prevDir, { recursive: true, force: true });
|
|
59523
59623
|
await import_promises8.default.rename(liveDir, prevDir);
|
|
59524
59624
|
const stage = await import_promises8.default.mkdtemp(
|
|
59525
|
-
|
|
59625
|
+
import_node_path55.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
59526
59626
|
);
|
|
59527
59627
|
try {
|
|
59528
59628
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
59529
|
-
const dest =
|
|
59629
|
+
const dest = import_node_path55.default.join(stage, name);
|
|
59530
59630
|
if (entry.dir) {
|
|
59531
59631
|
await import_promises8.default.mkdir(dest, { recursive: true });
|
|
59532
59632
|
continue;
|
|
59533
59633
|
}
|
|
59534
|
-
await import_promises8.default.mkdir(
|
|
59634
|
+
await import_promises8.default.mkdir(import_node_path55.default.dirname(dest), { recursive: true });
|
|
59535
59635
|
if (name === "manifest.json") {
|
|
59536
59636
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
59537
59637
|
await import_promises8.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -59598,7 +59698,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
59598
59698
|
);
|
|
59599
59699
|
}
|
|
59600
59700
|
}
|
|
59601
|
-
const manifestPath =
|
|
59701
|
+
const manifestPath = import_node_path56.default.join(root, extId, "manifest.json");
|
|
59602
59702
|
const manifest = await readManifest(root, extId);
|
|
59603
59703
|
const next = { ...manifest, version: newVersion };
|
|
59604
59704
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -59606,7 +59706,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
59606
59706
|
await import_promises9.default.rename(tmp, manifestPath);
|
|
59607
59707
|
}
|
|
59608
59708
|
async function readManifest(root, extId) {
|
|
59609
|
-
const file =
|
|
59709
|
+
const file = import_node_path56.default.join(root, extId, "manifest.json");
|
|
59610
59710
|
let raw;
|
|
59611
59711
|
try {
|
|
59612
59712
|
raw = await import_promises9.default.readFile(file, "utf8");
|
|
@@ -59690,7 +59790,7 @@ function buildExtensionHandlers(deps) {
|
|
|
59690
59790
|
};
|
|
59691
59791
|
async function buildSnapshotMeta(extId) {
|
|
59692
59792
|
const manifest = await readManifest(deps.root, extId);
|
|
59693
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
59793
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path56.default.join(deps.root, extId));
|
|
59694
59794
|
return { manifest, contentHash: sha256, buffer };
|
|
59695
59795
|
}
|
|
59696
59796
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -59865,9 +59965,9 @@ function buildExtensionHandlers(deps) {
|
|
|
59865
59965
|
}
|
|
59866
59966
|
|
|
59867
59967
|
// src/app-builder/project-store.ts
|
|
59868
|
-
var
|
|
59968
|
+
var import_node_fs46 = require("fs");
|
|
59869
59969
|
var import_node_child_process11 = require("child_process");
|
|
59870
|
-
var
|
|
59970
|
+
var import_node_path57 = require("path");
|
|
59871
59971
|
init_protocol();
|
|
59872
59972
|
var PROJECTS_DIR = "projects";
|
|
59873
59973
|
var META_FILE = ".clawd-project.json";
|
|
@@ -59881,19 +59981,19 @@ var ProjectStore = class {
|
|
|
59881
59981
|
root;
|
|
59882
59982
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
59883
59983
|
metaPath(name) {
|
|
59884
|
-
return (0,
|
|
59984
|
+
return (0, import_node_path57.join)(this.projectsRoot(), name, META_FILE);
|
|
59885
59985
|
}
|
|
59886
59986
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
59887
59987
|
projectDir(name) {
|
|
59888
|
-
return (0,
|
|
59988
|
+
return (0, import_node_path57.join)(this.projectsRoot(), name);
|
|
59889
59989
|
}
|
|
59890
59990
|
projectsRoot() {
|
|
59891
|
-
return (0,
|
|
59991
|
+
return (0, import_node_path57.join)(this.root, PROJECTS_DIR);
|
|
59892
59992
|
}
|
|
59893
59993
|
async list() {
|
|
59894
59994
|
let entries;
|
|
59895
59995
|
try {
|
|
59896
|
-
entries = await
|
|
59996
|
+
entries = await import_node_fs46.promises.readdir(this.projectsRoot());
|
|
59897
59997
|
} catch (err) {
|
|
59898
59998
|
if (err.code === "ENOENT") return [];
|
|
59899
59999
|
throw err;
|
|
@@ -59901,7 +60001,7 @@ var ProjectStore = class {
|
|
|
59901
60001
|
const out = [];
|
|
59902
60002
|
for (const name of entries) {
|
|
59903
60003
|
try {
|
|
59904
|
-
const raw = await
|
|
60004
|
+
const raw = await import_node_fs46.promises.readFile(this.metaPath(name), "utf8");
|
|
59905
60005
|
const json = JSON.parse(raw);
|
|
59906
60006
|
let migrated = false;
|
|
59907
60007
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -59912,7 +60012,7 @@ var ProjectStore = class {
|
|
|
59912
60012
|
if (parsed.success) {
|
|
59913
60013
|
out.push(parsed.data);
|
|
59914
60014
|
if (migrated) {
|
|
59915
|
-
void
|
|
60015
|
+
void import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
59916
60016
|
});
|
|
59917
60017
|
}
|
|
59918
60018
|
}
|
|
@@ -59956,8 +60056,8 @@ var ProjectStore = class {
|
|
|
59956
60056
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
59957
60057
|
}
|
|
59958
60058
|
const dir = this.projectDir(name);
|
|
59959
|
-
await
|
|
59960
|
-
await
|
|
60059
|
+
await import_node_fs46.promises.mkdir(dir, { recursive: true });
|
|
60060
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
59961
60061
|
return meta;
|
|
59962
60062
|
}
|
|
59963
60063
|
/**
|
|
@@ -60000,7 +60100,7 @@ var ProjectStore = class {
|
|
|
60000
60100
|
}
|
|
60001
60101
|
async delete(name) {
|
|
60002
60102
|
const dir = this.projectDir(name);
|
|
60003
|
-
await
|
|
60103
|
+
await import_node_fs46.promises.rm(dir, { recursive: true, force: true });
|
|
60004
60104
|
}
|
|
60005
60105
|
async updatePort(name, newPort) {
|
|
60006
60106
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -60016,7 +60116,7 @@ var ProjectStore = class {
|
|
|
60016
60116
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
60017
60117
|
}
|
|
60018
60118
|
const updated = { ...target, port: newPort };
|
|
60019
|
-
await
|
|
60119
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
60020
60120
|
return updated;
|
|
60021
60121
|
}
|
|
60022
60122
|
/**
|
|
@@ -60033,7 +60133,7 @@ var ProjectStore = class {
|
|
|
60033
60133
|
if (!validated.success) {
|
|
60034
60134
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
60035
60135
|
}
|
|
60036
|
-
await
|
|
60136
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60037
60137
|
return validated.data;
|
|
60038
60138
|
}
|
|
60039
60139
|
/**
|
|
@@ -60054,7 +60154,7 @@ var ProjectStore = class {
|
|
|
60054
60154
|
if (!validated.success) {
|
|
60055
60155
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
60056
60156
|
}
|
|
60057
|
-
await
|
|
60157
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60058
60158
|
return validated.data;
|
|
60059
60159
|
}
|
|
60060
60160
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -60069,7 +60169,7 @@ var ProjectStore = class {
|
|
|
60069
60169
|
if (!validated.success) {
|
|
60070
60170
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
60071
60171
|
}
|
|
60072
|
-
await
|
|
60172
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60073
60173
|
return validated.data;
|
|
60074
60174
|
}
|
|
60075
60175
|
};
|
|
@@ -60190,8 +60290,8 @@ var PublishJobRegistry = class {
|
|
|
60190
60290
|
|
|
60191
60291
|
// src/app-builder/publish-job-runner.ts
|
|
60192
60292
|
var import_node_child_process13 = require("child_process");
|
|
60193
|
-
var
|
|
60194
|
-
var
|
|
60293
|
+
var import_node_fs47 = require("fs");
|
|
60294
|
+
var import_node_path58 = require("path");
|
|
60195
60295
|
|
|
60196
60296
|
// src/app-builder/publish-stage-parser.ts
|
|
60197
60297
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -60223,10 +60323,10 @@ async function startPublishJob(deps, args) {
|
|
|
60223
60323
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
60224
60324
|
}
|
|
60225
60325
|
const projDir = projectDir(args.name);
|
|
60226
|
-
const logPath = (0,
|
|
60326
|
+
const logPath = (0, import_node_path58.join)(projDir, ".publish.log");
|
|
60227
60327
|
let logStream = null;
|
|
60228
60328
|
try {
|
|
60229
|
-
logStream = (0,
|
|
60329
|
+
logStream = (0, import_node_fs47.createWriteStream)(logPath, { flags: "w" });
|
|
60230
60330
|
} catch {
|
|
60231
60331
|
logStream = null;
|
|
60232
60332
|
}
|
|
@@ -60483,8 +60583,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
60483
60583
|
|
|
60484
60584
|
// src/handlers/app-builder.ts
|
|
60485
60585
|
init_protocol();
|
|
60486
|
-
var
|
|
60487
|
-
var
|
|
60586
|
+
var import_node_path59 = require("path");
|
|
60587
|
+
var import_node_fs48 = require("fs");
|
|
60488
60588
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
60489
60589
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
60490
60590
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -60565,7 +60665,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60565
60665
|
async function listAllUsersProjects() {
|
|
60566
60666
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
60567
60667
|
const getStore = deps.getStore;
|
|
60568
|
-
const userIds = await
|
|
60668
|
+
const userIds = await import_node_fs48.promises.readdir(deps.usersRoot).catch(() => []);
|
|
60569
60669
|
const perUser = await Promise.all(
|
|
60570
60670
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
60571
60671
|
);
|
|
@@ -60634,8 +60734,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60634
60734
|
const project = await userStore.create(f.name, reservedPorts);
|
|
60635
60735
|
try {
|
|
60636
60736
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
60637
|
-
const templateSrcDir = (0,
|
|
60638
|
-
const scaffoldScript = (0,
|
|
60737
|
+
const templateSrcDir = (0, import_node_path59.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
60738
|
+
const scaffoldScript = (0, import_node_path59.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
60639
60739
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
60640
60740
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
60641
60741
|
name: project.name,
|
|
@@ -60839,7 +60939,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60839
60939
|
await userStore.clearPublishJob(args.name);
|
|
60840
60940
|
}
|
|
60841
60941
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
60842
|
-
const scriptPath = (0,
|
|
60942
|
+
const scriptPath = (0, import_node_path59.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
60843
60943
|
deps.logger?.info("app-builder.publish.start", {
|
|
60844
60944
|
name: args.name,
|
|
60845
60945
|
sessionId: boundSession.sessionId,
|
|
@@ -61015,7 +61115,7 @@ function buildVisitorHandlers(deps) {
|
|
|
61015
61115
|
|
|
61016
61116
|
// src/extension/registry.ts
|
|
61017
61117
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
61018
|
-
var
|
|
61118
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
61019
61119
|
async function loadAll(root) {
|
|
61020
61120
|
let entries;
|
|
61021
61121
|
try {
|
|
@@ -61028,13 +61128,13 @@ async function loadAll(root) {
|
|
|
61028
61128
|
for (const ent of entries) {
|
|
61029
61129
|
if (!ent.isDirectory()) continue;
|
|
61030
61130
|
if (ent.name.startsWith(".")) continue;
|
|
61031
|
-
records.push(await loadOne(
|
|
61131
|
+
records.push(await loadOne(import_node_path60.default.join(root, ent.name), ent.name));
|
|
61032
61132
|
}
|
|
61033
61133
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
61034
61134
|
return records;
|
|
61035
61135
|
}
|
|
61036
61136
|
async function loadOne(dir, dirName) {
|
|
61037
|
-
const manifestPath =
|
|
61137
|
+
const manifestPath = import_node_path60.default.join(dir, "manifest.json");
|
|
61038
61138
|
let raw;
|
|
61039
61139
|
try {
|
|
61040
61140
|
raw = await import_promises10.default.readFile(manifestPath, "utf8");
|
|
@@ -61079,7 +61179,7 @@ async function loadOne(dir, dirName) {
|
|
|
61079
61179
|
|
|
61080
61180
|
// src/extension/uninstall.ts
|
|
61081
61181
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
61082
|
-
var
|
|
61182
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
61083
61183
|
var UninstallError = class extends Error {
|
|
61084
61184
|
constructor(code, message) {
|
|
61085
61185
|
super(message);
|
|
@@ -61088,7 +61188,7 @@ var UninstallError = class extends Error {
|
|
|
61088
61188
|
code;
|
|
61089
61189
|
};
|
|
61090
61190
|
async function uninstall(deps) {
|
|
61091
|
-
const dir =
|
|
61191
|
+
const dir = import_node_path61.default.join(deps.root, deps.extId);
|
|
61092
61192
|
try {
|
|
61093
61193
|
await import_promises11.default.access(dir);
|
|
61094
61194
|
} catch {
|
|
@@ -61618,7 +61718,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
61618
61718
|
|
|
61619
61719
|
// src/extension/runtime.ts
|
|
61620
61720
|
var import_node_child_process16 = require("child_process");
|
|
61621
|
-
var
|
|
61721
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
61622
61722
|
var import_promises12 = require("timers/promises");
|
|
61623
61723
|
|
|
61624
61724
|
// src/extension/port-allocator.ts
|
|
@@ -61719,7 +61819,7 @@ var Runtime = class {
|
|
|
61719
61819
|
/\$CLAWOS_EXT_PORT/g,
|
|
61720
61820
|
String(port)
|
|
61721
61821
|
);
|
|
61722
|
-
const dir =
|
|
61822
|
+
const dir = import_node_path62.default.join(this.root, extId);
|
|
61723
61823
|
const env = {
|
|
61724
61824
|
...process.env,
|
|
61725
61825
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -61831,7 +61931,7 @@ ${handle.stderrTail}`
|
|
|
61831
61931
|
|
|
61832
61932
|
// src/extension/published-channels.ts
|
|
61833
61933
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
61834
|
-
var
|
|
61934
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
61835
61935
|
init_zod();
|
|
61836
61936
|
var PublishedChannelsError = class extends Error {
|
|
61837
61937
|
constructor(code, message) {
|
|
@@ -61930,7 +62030,7 @@ var PublishedChannelStore = class {
|
|
|
61930
62030
|
)
|
|
61931
62031
|
};
|
|
61932
62032
|
const tmp = `${this.filePath}.tmp`;
|
|
61933
|
-
await import_promises13.default.mkdir(
|
|
62033
|
+
await import_promises13.default.mkdir(import_node_path63.default.dirname(this.filePath), { recursive: true });
|
|
61934
62034
|
await import_promises13.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
61935
62035
|
await import_promises13.default.rename(tmp, this.filePath);
|
|
61936
62036
|
}
|
|
@@ -61938,7 +62038,7 @@ var PublishedChannelStore = class {
|
|
|
61938
62038
|
|
|
61939
62039
|
// src/extension/bundle-cache.ts
|
|
61940
62040
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
61941
|
-
var
|
|
62041
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
61942
62042
|
var BundleCache = class {
|
|
61943
62043
|
constructor(rootDir) {
|
|
61944
62044
|
this.rootDir = rootDir;
|
|
@@ -61947,14 +62047,14 @@ var BundleCache = class {
|
|
|
61947
62047
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
61948
62048
|
async write(snapshotHash, buffer) {
|
|
61949
62049
|
await import_promises14.default.mkdir(this.rootDir, { recursive: true });
|
|
61950
|
-
const file =
|
|
62050
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61951
62051
|
const tmp = `${file}.tmp`;
|
|
61952
62052
|
await import_promises14.default.writeFile(tmp, buffer, { mode: 384 });
|
|
61953
62053
|
await import_promises14.default.rename(tmp, file);
|
|
61954
62054
|
}
|
|
61955
62055
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
61956
62056
|
async read(snapshotHash) {
|
|
61957
|
-
const file =
|
|
62057
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61958
62058
|
try {
|
|
61959
62059
|
return await import_promises14.default.readFile(file);
|
|
61960
62060
|
} catch (e) {
|
|
@@ -61964,7 +62064,7 @@ var BundleCache = class {
|
|
|
61964
62064
|
}
|
|
61965
62065
|
/** Idempotent — missing file is not an error. */
|
|
61966
62066
|
async delete(snapshotHash) {
|
|
61967
|
-
const file =
|
|
62067
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61968
62068
|
await import_promises14.default.rm(file, { force: true });
|
|
61969
62069
|
}
|
|
61970
62070
|
};
|
|
@@ -61987,24 +62087,24 @@ async function startDaemon(config) {
|
|
|
61987
62087
|
sampling: logShippingCfg.sampling,
|
|
61988
62088
|
homeDir: import_node_os22.default.homedir()
|
|
61989
62089
|
});
|
|
61990
|
-
const logDir =
|
|
61991
|
-
|
|
62090
|
+
const logDir = import_node_path65.default.join(config.dataDir, "log");
|
|
62091
|
+
import_node_fs49.default.mkdirSync(logDir, { recursive: true });
|
|
61992
62092
|
const logger = createLogger({
|
|
61993
62093
|
level: config.logLevel,
|
|
61994
|
-
file:
|
|
62094
|
+
file: import_node_path65.default.join(logDir, "clawd.log"),
|
|
61995
62095
|
logClient
|
|
61996
62096
|
});
|
|
61997
62097
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
61998
62098
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
61999
|
-
file:
|
|
62099
|
+
file: import_node_path65.default.join(logDir, "screen-idle-probe.log"),
|
|
62000
62100
|
level: "debug"
|
|
62001
62101
|
});
|
|
62002
62102
|
logger.info("screen-idle probe logger enabled", {
|
|
62003
|
-
file:
|
|
62103
|
+
file: import_node_path65.default.join(logDir, "screen-idle-probe.log")
|
|
62004
62104
|
});
|
|
62005
62105
|
const CAP_TARGETS = [
|
|
62006
|
-
|
|
62007
|
-
|
|
62106
|
+
import_node_path65.default.join(logDir, "clawd.log"),
|
|
62107
|
+
import_node_path65.default.join(logDir, "screen-idle-probe.log")
|
|
62008
62108
|
];
|
|
62009
62109
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
62010
62110
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -62100,8 +62200,8 @@ async function startDaemon(config) {
|
|
|
62100
62200
|
const agents = new AgentsScanner();
|
|
62101
62201
|
const history = new ClaudeHistoryReader();
|
|
62102
62202
|
let transport = null;
|
|
62103
|
-
const personaStore = new PersonaStore(
|
|
62104
|
-
const usersRoot =
|
|
62203
|
+
const personaStore = new PersonaStore(import_node_path65.default.join(config.dataDir, "personas"));
|
|
62204
|
+
const usersRoot = import_node_path65.default.join(config.dataDir, "users");
|
|
62105
62205
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
62106
62206
|
if (defaultsRoot) {
|
|
62107
62207
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -62123,7 +62223,7 @@ async function startDaemon(config) {
|
|
|
62123
62223
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
62124
62224
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
62125
62225
|
const dispatchStore = createDispatchStore({
|
|
62126
|
-
filePath:
|
|
62226
|
+
filePath: import_node_path65.default.join(config.dataDir, "dispatch.json"),
|
|
62127
62227
|
now: () => Date.now(),
|
|
62128
62228
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
62129
62229
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -62138,18 +62238,18 @@ async function startDaemon(config) {
|
|
|
62138
62238
|
now: () => Date.now(),
|
|
62139
62239
|
onCompleted: (sid) => deliverPendingRef?.(sid)
|
|
62140
62240
|
});
|
|
62141
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
62241
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path65.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
62142
62242
|
const mcpConfigs = [];
|
|
62143
62243
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
62144
62244
|
const dispatchServerCandidates = [
|
|
62145
|
-
|
|
62245
|
+
import_node_path65.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
62146
62246
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
62147
|
-
|
|
62247
|
+
import_node_path65.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
62148
62248
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
62149
62249
|
];
|
|
62150
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
62250
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62151
62251
|
if (dispatchServerScriptPath) {
|
|
62152
|
-
const dispatchLogPath =
|
|
62252
|
+
const dispatchLogPath = import_node_path65.default.join(logDir, "dispatch-mcp-server.log");
|
|
62153
62253
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
62154
62254
|
dataDir: config.dataDir,
|
|
62155
62255
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -62169,12 +62269,12 @@ async function startDaemon(config) {
|
|
|
62169
62269
|
});
|
|
62170
62270
|
}
|
|
62171
62271
|
const ticketServerCandidates = [
|
|
62172
|
-
|
|
62173
|
-
|
|
62272
|
+
import_node_path65.default.join(here, "ticket", "mcp-server.cjs"),
|
|
62273
|
+
import_node_path65.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
62174
62274
|
];
|
|
62175
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
62275
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62176
62276
|
if (ticketServerScriptPath) {
|
|
62177
|
-
const ticketLogPath =
|
|
62277
|
+
const ticketLogPath = import_node_path65.default.join(logDir, "ticket-mcp-server.log");
|
|
62178
62278
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
62179
62279
|
dataDir: config.dataDir,
|
|
62180
62280
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -62196,12 +62296,12 @@ async function startDaemon(config) {
|
|
|
62196
62296
|
});
|
|
62197
62297
|
}
|
|
62198
62298
|
const shiftServerCandidates = [
|
|
62199
|
-
|
|
62200
|
-
|
|
62299
|
+
import_node_path65.default.join(here, "shift", "mcp-server.cjs"),
|
|
62300
|
+
import_node_path65.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
62201
62301
|
];
|
|
62202
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
62302
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62203
62303
|
if (shiftServerScriptPath) {
|
|
62204
|
-
const shiftLogPath =
|
|
62304
|
+
const shiftLogPath = import_node_path65.default.join(logDir, "shift-mcp-server.log");
|
|
62205
62305
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
62206
62306
|
dataDir: config.dataDir,
|
|
62207
62307
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -62222,12 +62322,12 @@ async function startDaemon(config) {
|
|
|
62222
62322
|
);
|
|
62223
62323
|
}
|
|
62224
62324
|
const inboxServerCandidates = [
|
|
62225
|
-
|
|
62226
|
-
|
|
62325
|
+
import_node_path65.default.join(here, "inbox", "mcp-server.cjs"),
|
|
62326
|
+
import_node_path65.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
62227
62327
|
];
|
|
62228
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
62328
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62229
62329
|
if (inboxServerScriptPath) {
|
|
62230
|
-
const inboxLogPath =
|
|
62330
|
+
const inboxLogPath = import_node_path65.default.join(logDir, "inbox-mcp-server.log");
|
|
62231
62331
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
62232
62332
|
dataDir: config.dataDir,
|
|
62233
62333
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -62248,10 +62348,10 @@ async function startDaemon(config) {
|
|
|
62248
62348
|
);
|
|
62249
62349
|
}
|
|
62250
62350
|
const peerOpsServerCandidates = [
|
|
62251
|
-
|
|
62252
|
-
|
|
62351
|
+
import_node_path65.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
62352
|
+
import_node_path65.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
62253
62353
|
];
|
|
62254
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) =>
|
|
62354
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62255
62355
|
if (peerOpsServerScriptPath) {
|
|
62256
62356
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
62257
62357
|
dataDir: config.dataDir,
|
|
@@ -62271,12 +62371,12 @@ async function startDaemon(config) {
|
|
|
62271
62371
|
);
|
|
62272
62372
|
}
|
|
62273
62373
|
const rpcToolServerCandidates = [
|
|
62274
|
-
|
|
62275
|
-
|
|
62374
|
+
import_node_path65.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
62375
|
+
import_node_path65.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
62276
62376
|
];
|
|
62277
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) =>
|
|
62377
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62278
62378
|
if (rpcToolServerScriptPath) {
|
|
62279
|
-
const rpcToolLogPath =
|
|
62379
|
+
const rpcToolLogPath = import_node_path65.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
62280
62380
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
62281
62381
|
dataDir: config.dataDir,
|
|
62282
62382
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -62297,7 +62397,7 @@ async function startDaemon(config) {
|
|
|
62297
62397
|
);
|
|
62298
62398
|
}
|
|
62299
62399
|
const shiftStore = createShiftStore({
|
|
62300
|
-
filePath:
|
|
62400
|
+
filePath: import_node_path65.default.join(config.dataDir, "shift.json"),
|
|
62301
62401
|
ownerIdProvider: () => ownerPrincipalId,
|
|
62302
62402
|
now: () => Date.now()
|
|
62303
62403
|
});
|
|
@@ -62319,7 +62419,7 @@ async function startDaemon(config) {
|
|
|
62319
62419
|
getAdapter,
|
|
62320
62420
|
historyReader: history,
|
|
62321
62421
|
dataDir: config.dataDir,
|
|
62322
|
-
personaRoot:
|
|
62422
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62323
62423
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
62324
62424
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
62325
62425
|
getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool,
|
|
@@ -62370,10 +62470,10 @@ async function startDaemon(config) {
|
|
|
62370
62470
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
62371
62471
|
attachmentGroup: {
|
|
62372
62472
|
onFileEdit: (input) => {
|
|
62373
|
-
const absPath =
|
|
62473
|
+
const absPath = import_node_path65.default.isAbsolute(input.relPath) ? input.relPath : import_node_path65.default.join(input.cwd, input.relPath);
|
|
62374
62474
|
let size = 0;
|
|
62375
62475
|
try {
|
|
62376
|
-
size =
|
|
62476
|
+
size = import_node_fs49.default.statSync(absPath).size;
|
|
62377
62477
|
} catch (err) {
|
|
62378
62478
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
62379
62479
|
sessionId: input.sessionId,
|
|
@@ -62620,11 +62720,11 @@ async function startDaemon(config) {
|
|
|
62620
62720
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
62621
62721
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
62622
62722
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
62623
|
-
personaRoot:
|
|
62723
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62624
62724
|
usersRoot
|
|
62625
62725
|
},
|
|
62626
62726
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
62627
|
-
personaRoot:
|
|
62727
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62628
62728
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
62629
62729
|
usersRoot,
|
|
62630
62730
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -62750,11 +62850,11 @@ async function startDaemon(config) {
|
|
|
62750
62850
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
62751
62851
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
62752
62852
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
62753
|
-
appBuilderPersonaRoot:
|
|
62853
|
+
appBuilderPersonaRoot: import_node_path65.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
62754
62854
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
62755
|
-
deployKitRoot:
|
|
62855
|
+
deployKitRoot: import_node_path65.default.join(config.dataDir, "deploy-kit"),
|
|
62756
62856
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
62757
|
-
resolvePersonaRoot: (personaId2) =>
|
|
62857
|
+
resolvePersonaRoot: (personaId2) => import_node_path65.default.join(config.dataDir, "personas", personaId2),
|
|
62758
62858
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
62759
62859
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
62760
62860
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -62857,7 +62957,7 @@ async function startDaemon(config) {
|
|
|
62857
62957
|
});
|
|
62858
62958
|
shiftScheduler.start();
|
|
62859
62959
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
62860
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
62960
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path65.default.join(config.dataDir, "personas"));
|
|
62861
62961
|
const larkBotCloud = createLarkBotCloudClient({
|
|
62862
62962
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
62863
62963
|
apiKey: resolveClawdTicketsApiKey(),
|
|
@@ -62868,6 +62968,9 @@ async function startDaemon(config) {
|
|
|
62868
62968
|
manager,
|
|
62869
62969
|
cloud: larkBotCloud,
|
|
62870
62970
|
store: larkBotStore,
|
|
62971
|
+
fetchResource: (appId, messageId, fileKey, maxBytes) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes),
|
|
62972
|
+
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
62973
|
+
mediaRootFor: (chatId) => import_node_path65.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
62871
62974
|
logger: {
|
|
62872
62975
|
warn: (msg) => logger.warn(msg),
|
|
62873
62976
|
info: (msg) => logger.info(msg)
|
|
@@ -63150,8 +63253,8 @@ async function startDaemon(config) {
|
|
|
63150
63253
|
const lines = [
|
|
63151
63254
|
`Tunnel: ${r.url}`,
|
|
63152
63255
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
63153
|
-
`Frpc config: ${
|
|
63154
|
-
`Frpc log: ${
|
|
63256
|
+
`Frpc config: ${import_node_path65.default.join(config.dataDir, "frpc.toml")}`,
|
|
63257
|
+
`Frpc log: ${import_node_path65.default.join(logDir, "frpc.log")}`
|
|
63155
63258
|
];
|
|
63156
63259
|
const width = Math.max(...lines.map((l) => l.length));
|
|
63157
63260
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -63164,8 +63267,8 @@ ${bar}
|
|
|
63164
63267
|
|
|
63165
63268
|
`);
|
|
63166
63269
|
try {
|
|
63167
|
-
const connectPath =
|
|
63168
|
-
|
|
63270
|
+
const connectPath = import_node_path65.default.join(config.dataDir, "connect.txt");
|
|
63271
|
+
import_node_fs49.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
63169
63272
|
} catch {
|
|
63170
63273
|
}
|
|
63171
63274
|
} catch (err) {
|
|
@@ -63239,9 +63342,9 @@ ${bar}
|
|
|
63239
63342
|
};
|
|
63240
63343
|
}
|
|
63241
63344
|
function migrateDropPersonsDir(dataDir) {
|
|
63242
|
-
const dir =
|
|
63345
|
+
const dir = import_node_path65.default.join(dataDir, "persons");
|
|
63243
63346
|
try {
|
|
63244
|
-
|
|
63347
|
+
import_node_fs49.default.rmSync(dir, { recursive: true, force: true });
|
|
63245
63348
|
} catch {
|
|
63246
63349
|
}
|
|
63247
63350
|
}
|