@clawos-dev/clawd 0.2.293 → 0.2.294
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
|
|
|
@@ -47181,8 +47187,9 @@ var SessionManager = class {
|
|
|
47181
47187
|
// guest 三件套:creatorPrincipalId=capId(scopeForFile 回落防线)、
|
|
47182
47188
|
// creatorDisplayName(reducer guest 分支硬性要求,缺则 spawn 抛)
|
|
47183
47189
|
creatorPrincipalId: capId,
|
|
47184
|
-
creatorDisplayName:
|
|
47190
|
+
creatorDisplayName: `${(args.chatType ?? "group") === "p2p" ? "\u98DE\u4E66\u79C1\u804A" : "\u98DE\u4E66\u7FA4"}\xB7${args.chatName ?? args.chatId}`,
|
|
47185
47191
|
larkChatId: args.chatId,
|
|
47192
|
+
larkChatType: args.chatType ?? "group",
|
|
47186
47193
|
...args.chatName ? { larkChatName: args.chatName } : {},
|
|
47187
47194
|
createdAt: now,
|
|
47188
47195
|
updatedAt: now
|
|
@@ -47752,7 +47759,10 @@ var PersonaStore = class {
|
|
|
47752
47759
|
/**
|
|
47753
47760
|
* persona 基线注入:Edit-deny(绝对 '~/<persona>/**')并进 permissions.deny + 剥掉历史相对
|
|
47754
47761
|
* 'Edit(./**)';persona 目录 '~/' 路径 union 进 sandbox.filesystem.allowRead(guest 读权
|
|
47755
|
-
* 落盘即真源,compose 不再运行时注入——spec 2026-08-06-persona-workdir-discipline §1-§2
|
|
47762
|
+
* 落盘即真源,compose 不再运行时注入——spec 2026-08-06-persona-workdir-discipline §1-§2);
|
|
47763
|
+
* `Read(~/<persona>/**)` union 进 permissions.allow——OS 沙箱层可读只放行了 Bash,CC 自带
|
|
47764
|
+
* Read 工具在最严格 base(dontAsk + 无 allow)下仍被拒,工具层与 OS 层必须同构放行
|
|
47765
|
+
* (guest「自由读 persona 目录、只写自己 userWorkDir」,spec 2026-08-06-lark-dm §P10 通用化)。
|
|
47756
47766
|
*/
|
|
47757
47767
|
injectPersonaBaseline(personaId2, settings) {
|
|
47758
47768
|
const dir = this.personaDir(personaId2);
|
|
@@ -47760,6 +47770,9 @@ var PersonaStore = class {
|
|
|
47760
47770
|
const rule = personaEditDeny(dir);
|
|
47761
47771
|
const rawDeny = s.permissions && typeof s.permissions === "object" ? s.permissions.deny : void 0;
|
|
47762
47772
|
const prevDeny = (Array.isArray(rawDeny) ? rawDeny : []).filter((r) => r !== "Edit(./**)" && r !== rule);
|
|
47773
|
+
const readRule = personaReadAllow(dir);
|
|
47774
|
+
const rawAllow = s.permissions && typeof s.permissions === "object" ? s.permissions.allow : void 0;
|
|
47775
|
+
const prevAllow = (Array.isArray(rawAllow) ? rawAllow : []).filter((r) => r !== readRule);
|
|
47763
47776
|
const readPath = tildePath(dir);
|
|
47764
47777
|
const sandbox = s.sandbox && typeof s.sandbox === "object" && !Array.isArray(s.sandbox) ? s.sandbox : {};
|
|
47765
47778
|
const rawFs = sandbox.filesystem;
|
|
@@ -47770,6 +47783,7 @@ var PersonaStore = class {
|
|
|
47770
47783
|
...s,
|
|
47771
47784
|
permissions: {
|
|
47772
47785
|
...s.permissions && typeof s.permissions === "object" ? s.permissions : {},
|
|
47786
|
+
allow: [...prevAllow, readRule],
|
|
47773
47787
|
deny: [...prevDeny, rule]
|
|
47774
47788
|
},
|
|
47775
47789
|
sandbox: { ...sandbox, filesystem: { ...filesystem, allowRead: [...prevRead, readPath] } }
|
|
@@ -48654,7 +48668,10 @@ function migrateSandboxAllowRead(args) {
|
|
|
48654
48668
|
continue;
|
|
48655
48669
|
}
|
|
48656
48670
|
const allowRead = raw.sandbox?.filesystem?.allowRead;
|
|
48657
|
-
|
|
48671
|
+
const permAllow = raw.permissions?.allow;
|
|
48672
|
+
const readRule = personaReadAllow(args.store.personaDirPath(personaId2));
|
|
48673
|
+
if (Array.isArray(allowRead) && allowRead.includes(readPath) && Array.isArray(permAllow) && permAllow.includes(readRule))
|
|
48674
|
+
continue;
|
|
48658
48675
|
args.store.writeSandboxSettings(personaId2, raw);
|
|
48659
48676
|
n++;
|
|
48660
48677
|
args.logger.info("persona.sandbox.allow-read.migrated", { personaId: personaId2 });
|
|
@@ -49301,8 +49318,8 @@ function turnStartInput(text) {
|
|
|
49301
49318
|
const items = [];
|
|
49302
49319
|
let leftover = text;
|
|
49303
49320
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
49304
|
-
const [marker, name,
|
|
49305
|
-
items.push({ type: "skill", name, path:
|
|
49321
|
+
const [marker, name, path79] = m2;
|
|
49322
|
+
items.push({ type: "skill", name, path: path79 });
|
|
49306
49323
|
leftover = leftover.replace(marker, "");
|
|
49307
49324
|
}
|
|
49308
49325
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -51996,14 +52013,62 @@ function createLarkBotCloudClient(opts) {
|
|
|
51996
52013
|
async claimEvents() {
|
|
51997
52014
|
const json = await request("POST", "/api/lark-bot/events/claim");
|
|
51998
52015
|
return json.items ?? [];
|
|
52016
|
+
},
|
|
52017
|
+
async fetchResource(appId, messageId, fileKey, maxBytes) {
|
|
52018
|
+
const ac = new AbortController();
|
|
52019
|
+
const timer = setTimeout(() => ac.abort(), opts.timeoutMs ?? 15e3);
|
|
52020
|
+
const qs = new URLSearchParams({
|
|
52021
|
+
appId,
|
|
52022
|
+
messageId,
|
|
52023
|
+
fileKey,
|
|
52024
|
+
...maxBytes ? { maxBytes: String(maxBytes) } : {}
|
|
52025
|
+
}).toString();
|
|
52026
|
+
let res;
|
|
52027
|
+
try {
|
|
52028
|
+
res = await f(`${base}/api/lark-bot/resource?${qs}`, {
|
|
52029
|
+
method: "GET",
|
|
52030
|
+
signal: ac.signal,
|
|
52031
|
+
headers: {
|
|
52032
|
+
authorization: `Bearer ${opts.apiKey}`,
|
|
52033
|
+
"x-did": encodeURIComponent(opts.deviceId),
|
|
52034
|
+
"x-name": encodeURIComponent(opts.displayName),
|
|
52035
|
+
"x-scene": "daemon"
|
|
52036
|
+
}
|
|
52037
|
+
});
|
|
52038
|
+
} catch (err) {
|
|
52039
|
+
throw new LarkBotCloudError(`lark-bot cloud resource fetch failed: ${err.message}`);
|
|
52040
|
+
} finally {
|
|
52041
|
+
clearTimeout(timer);
|
|
52042
|
+
}
|
|
52043
|
+
if (!res.ok) {
|
|
52044
|
+
throw new LarkBotCloudError(`lark-bot cloud resource: HTTP ${res.status}`, res.status);
|
|
52045
|
+
}
|
|
52046
|
+
const data = Buffer.from(await res.arrayBuffer());
|
|
52047
|
+
const contentType = res.headers.get("content-type") ?? "application/octet-stream";
|
|
52048
|
+
return { data, contentType };
|
|
51999
52049
|
}
|
|
52000
52050
|
};
|
|
52001
52051
|
}
|
|
52002
52052
|
|
|
52003
52053
|
// src/lark-bot-connector/chat-router.ts
|
|
52054
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
52055
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
52004
52056
|
init_protocol();
|
|
52005
52057
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
52006
52058
|
var DEFAULT_TURN_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
52059
|
+
var MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
52060
|
+
var EXT_BY_MIME = {
|
|
52061
|
+
"image/png": "png",
|
|
52062
|
+
"image/jpeg": "jpg",
|
|
52063
|
+
"image/gif": "gif",
|
|
52064
|
+
"image/webp": "webp"
|
|
52065
|
+
};
|
|
52066
|
+
var IMAGE_OVERSIZE_TEXT = "[\u56FE\u7247\u6D88\u606F\uFF0C\u8D85\u51FA\u5927\u5C0F\u9650\u5236]";
|
|
52067
|
+
var IMAGE_UNAVAILABLE_TEXT = "[\u56FE\u7247\u6D88\u606F\uFF0C\u6682\u4E0D\u652F\u6301\u67E5\u770B]";
|
|
52068
|
+
function safeMediaName(raw) {
|
|
52069
|
+
const cleaned = raw.replace(/[^a-zA-Z0-9_\-.]/g, "_").replace(/^\.+/, (d) => "_".repeat(d.length));
|
|
52070
|
+
return (cleaned || "msg").replace(/\.\./g, "__");
|
|
52071
|
+
}
|
|
52007
52072
|
function createLarkChatRouter(deps) {
|
|
52008
52073
|
const timeoutMs = deps.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;
|
|
52009
52074
|
const replyDelays = deps.replyRetryDelaysMs ?? [2e3, 8e3, 3e4];
|
|
@@ -52016,7 +52081,34 @@ function createLarkChatRouter(deps) {
|
|
|
52016
52081
|
return;
|
|
52017
52082
|
}
|
|
52018
52083
|
const speaker = env.senderName || env.senderOpenId || "\u672A\u77E5\u6210\u5458";
|
|
52019
|
-
const
|
|
52084
|
+
const imageLines = [];
|
|
52085
|
+
for (const [i, key] of (env.imageKeys ?? []).entries()) {
|
|
52086
|
+
try {
|
|
52087
|
+
if (!deps.fetchResource || !deps.mediaRootFor) throw new Error("resource pipeline not wired");
|
|
52088
|
+
const r = await deps.fetchResource(env.appId, env.messageId, key, MAX_IMAGE_BYTES);
|
|
52089
|
+
if (r.data.byteLength > MAX_IMAGE_BYTES) {
|
|
52090
|
+
deps.logger?.warn(`larkBot image oversize ${key}: ${r.data.byteLength}B`);
|
|
52091
|
+
imageLines.push(IMAGE_OVERSIZE_TEXT);
|
|
52092
|
+
continue;
|
|
52093
|
+
}
|
|
52094
|
+
const ext = EXT_BY_MIME[r.contentType];
|
|
52095
|
+
if (!ext) {
|
|
52096
|
+
deps.logger?.warn(`larkBot image unsupported mime ${key}: ${r.contentType}`);
|
|
52097
|
+
imageLines.push(IMAGE_UNAVAILABLE_TEXT);
|
|
52098
|
+
continue;
|
|
52099
|
+
}
|
|
52100
|
+
const dir = deps.mediaRootFor(env.chatId);
|
|
52101
|
+
import_node_fs27.default.mkdirSync(dir, { recursive: true });
|
|
52102
|
+
const p2 = import_node_path28.default.join(dir, `${safeMediaName(env.messageId)}-${i}.${ext}`);
|
|
52103
|
+
import_node_fs27.default.writeFileSync(p2, r.data);
|
|
52104
|
+
imageLines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
52105
|
+
} catch (err) {
|
|
52106
|
+
deps.logger?.warn(`larkBot image fetch failed ${key}: ${err.message}`);
|
|
52107
|
+
imageLines.push(IMAGE_UNAVAILABLE_TEXT);
|
|
52108
|
+
}
|
|
52109
|
+
}
|
|
52110
|
+
const rawBody = [env.text?.trim(), ...imageLines].filter(Boolean).join("\n");
|
|
52111
|
+
const body = rawBody || "[\u975E\u6587\u672C\u6D88\u606F]";
|
|
52020
52112
|
const text = `${body}
|
|
52021
52113
|
|
|
52022
52114
|
${formatLarkSpeakerReminder(speaker)}`;
|
|
@@ -52024,6 +52116,7 @@ ${formatLarkSpeakerReminder(speaker)}`;
|
|
|
52024
52116
|
personaId: env.personaId,
|
|
52025
52117
|
chatId: env.chatId,
|
|
52026
52118
|
chatName: env.chatName,
|
|
52119
|
+
chatType: env.chatType ?? "group",
|
|
52027
52120
|
senderOpenId: env.senderOpenId ?? "",
|
|
52028
52121
|
senderName: env.senderName ?? env.senderOpenId ?? "\u672A\u77E5\u6210\u5458",
|
|
52029
52122
|
text
|
|
@@ -52786,7 +52879,7 @@ var CodexHistoryReader = class {
|
|
|
52786
52879
|
};
|
|
52787
52880
|
|
|
52788
52881
|
// src/tools/codex-skills.ts
|
|
52789
|
-
var
|
|
52882
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
52790
52883
|
function str3(v2) {
|
|
52791
52884
|
return typeof v2 === "string" ? v2 : void 0;
|
|
52792
52885
|
}
|
|
@@ -52801,13 +52894,13 @@ function mapSkillsListResponse(res) {
|
|
|
52801
52894
|
const r = s ?? {};
|
|
52802
52895
|
const name = str3(r.name);
|
|
52803
52896
|
if (!name) continue;
|
|
52804
|
-
const
|
|
52897
|
+
const path79 = str3(r.path);
|
|
52805
52898
|
const description = str3(r.description);
|
|
52806
52899
|
const isPlugin = name.includes(":");
|
|
52807
52900
|
out.push({
|
|
52808
52901
|
name,
|
|
52809
52902
|
source: isPlugin ? "plugin" : "project",
|
|
52810
|
-
...
|
|
52903
|
+
...path79 ? { path: path79 } : {},
|
|
52811
52904
|
...description ? { description } : {},
|
|
52812
52905
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
52813
52906
|
});
|
|
@@ -52823,30 +52916,30 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
52823
52916
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
52824
52917
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
52825
52918
|
beforeRequest: (client) => {
|
|
52826
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
52919
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path29.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
52827
52920
|
}
|
|
52828
52921
|
});
|
|
52829
52922
|
return mapSkillsListResponse(res);
|
|
52830
52923
|
}
|
|
52831
52924
|
|
|
52832
52925
|
// src/workspace/browser.ts
|
|
52833
|
-
var
|
|
52926
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
52834
52927
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
52835
|
-
var
|
|
52928
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
52836
52929
|
init_protocol();
|
|
52837
52930
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
52838
52931
|
function resolveInsideCwd(cwd, subpath) {
|
|
52839
|
-
const absCwd =
|
|
52840
|
-
const joined =
|
|
52841
|
-
const rel =
|
|
52842
|
-
if (rel.startsWith("..") ||
|
|
52932
|
+
const absCwd = import_node_path30.default.resolve(cwd);
|
|
52933
|
+
const joined = import_node_path30.default.resolve(absCwd, subpath ?? ".");
|
|
52934
|
+
const rel = import_node_path30.default.relative(absCwd, joined);
|
|
52935
|
+
if (rel.startsWith("..") || import_node_path30.default.isAbsolute(rel)) {
|
|
52843
52936
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
52844
52937
|
}
|
|
52845
52938
|
return joined;
|
|
52846
52939
|
}
|
|
52847
52940
|
function ensureCwd(cwd) {
|
|
52848
52941
|
try {
|
|
52849
|
-
const stat =
|
|
52942
|
+
const stat = import_node_fs28.default.statSync(cwd);
|
|
52850
52943
|
if (!stat.isDirectory()) {
|
|
52851
52944
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
52852
52945
|
}
|
|
@@ -52860,7 +52953,7 @@ var WorkspaceBrowser = class {
|
|
|
52860
52953
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
52861
52954
|
ensureCwd(cwd);
|
|
52862
52955
|
const full = resolveInsideCwd(cwd, args.path);
|
|
52863
|
-
const dirents =
|
|
52956
|
+
const dirents = import_node_fs28.default.readdirSync(full, { withFileTypes: true });
|
|
52864
52957
|
const entries = [];
|
|
52865
52958
|
for (const d of dirents) {
|
|
52866
52959
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -52870,7 +52963,7 @@ var WorkspaceBrowser = class {
|
|
|
52870
52963
|
mtime: ""
|
|
52871
52964
|
};
|
|
52872
52965
|
try {
|
|
52873
|
-
const st =
|
|
52966
|
+
const st = import_node_fs28.default.statSync(import_node_path30.default.join(full, d.name));
|
|
52874
52967
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
52875
52968
|
if (d.isFile()) entry.size = st.size;
|
|
52876
52969
|
} catch {
|
|
@@ -52886,14 +52979,14 @@ var WorkspaceBrowser = class {
|
|
|
52886
52979
|
read(args) {
|
|
52887
52980
|
ensureCwd(args.cwd);
|
|
52888
52981
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
52889
|
-
const st =
|
|
52982
|
+
const st = import_node_fs28.default.statSync(full);
|
|
52890
52983
|
if (!st.isFile()) {
|
|
52891
52984
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
52892
52985
|
}
|
|
52893
52986
|
if (st.size > MAX_FILE_BYTES) {
|
|
52894
52987
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
52895
52988
|
}
|
|
52896
|
-
const buf =
|
|
52989
|
+
const buf = import_node_fs28.default.readFileSync(full);
|
|
52897
52990
|
const isBinary = buf.includes(0);
|
|
52898
52991
|
if (isBinary) {
|
|
52899
52992
|
return {
|
|
@@ -52915,20 +53008,20 @@ var WorkspaceBrowser = class {
|
|
|
52915
53008
|
};
|
|
52916
53009
|
|
|
52917
53010
|
// src/skills/agents-scanner.ts
|
|
52918
|
-
var
|
|
53011
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
52919
53012
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
52920
|
-
var
|
|
53013
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
52921
53014
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
52922
53015
|
function isDirLikeSync2(p2) {
|
|
52923
53016
|
try {
|
|
52924
|
-
return
|
|
53017
|
+
return import_node_fs29.default.statSync(p2).isDirectory();
|
|
52925
53018
|
} catch {
|
|
52926
53019
|
return false;
|
|
52927
53020
|
}
|
|
52928
53021
|
}
|
|
52929
53022
|
function fileExistsSync(p2) {
|
|
52930
53023
|
try {
|
|
52931
|
-
return
|
|
53024
|
+
return import_node_fs29.default.statSync(p2).isFile();
|
|
52932
53025
|
} catch {
|
|
52933
53026
|
return false;
|
|
52934
53027
|
}
|
|
@@ -52936,7 +53029,7 @@ function fileExistsSync(p2) {
|
|
|
52936
53029
|
function parseAgentFile(filePath) {
|
|
52937
53030
|
let content;
|
|
52938
53031
|
try {
|
|
52939
|
-
content =
|
|
53032
|
+
content = import_node_fs29.default.readFileSync(filePath, "utf8");
|
|
52940
53033
|
} catch {
|
|
52941
53034
|
return {};
|
|
52942
53035
|
}
|
|
@@ -52949,16 +53042,16 @@ function parseAgentFile(filePath) {
|
|
|
52949
53042
|
function scanAgentsDir(dir, source, seen, out) {
|
|
52950
53043
|
let entries;
|
|
52951
53044
|
try {
|
|
52952
|
-
entries =
|
|
53045
|
+
entries = import_node_fs29.default.readdirSync(dir, { withFileTypes: true });
|
|
52953
53046
|
} catch {
|
|
52954
53047
|
return;
|
|
52955
53048
|
}
|
|
52956
53049
|
for (const ent of entries) {
|
|
52957
53050
|
if (!ent.name.endsWith(".md")) continue;
|
|
52958
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
53051
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path31.default.join(dir, ent.name)))) {
|
|
52959
53052
|
continue;
|
|
52960
53053
|
}
|
|
52961
|
-
const filePath =
|
|
53054
|
+
const filePath = import_node_path31.default.join(dir, ent.name);
|
|
52962
53055
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
52963
53056
|
if (seen.has(baseName)) continue;
|
|
52964
53057
|
seen.add(baseName);
|
|
@@ -52976,12 +53069,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
52976
53069
|
function walk2(dir, namespaces) {
|
|
52977
53070
|
let entries;
|
|
52978
53071
|
try {
|
|
52979
|
-
entries =
|
|
53072
|
+
entries = import_node_fs29.default.readdirSync(dir, { withFileTypes: true });
|
|
52980
53073
|
} catch {
|
|
52981
53074
|
return;
|
|
52982
53075
|
}
|
|
52983
53076
|
for (const ent of entries) {
|
|
52984
|
-
const childPath =
|
|
53077
|
+
const childPath = import_node_path31.default.join(dir, ent.name);
|
|
52985
53078
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
52986
53079
|
walk2(childPath, [...namespaces, ent.name]);
|
|
52987
53080
|
continue;
|
|
@@ -53006,13 +53099,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
53006
53099
|
walk2(root, []);
|
|
53007
53100
|
}
|
|
53008
53101
|
function readInstalledPlugins2(home) {
|
|
53009
|
-
const pluginsDir =
|
|
53010
|
-
const v2 =
|
|
53011
|
-
const v1 =
|
|
53102
|
+
const pluginsDir = import_node_path31.default.join(home, ".claude", "plugins");
|
|
53103
|
+
const v2 = import_node_path31.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
53104
|
+
const v1 = import_node_path31.default.join(pluginsDir, "installed_plugins.json");
|
|
53012
53105
|
let raw = null;
|
|
53013
53106
|
for (const candidate of [v2, v1]) {
|
|
53014
53107
|
try {
|
|
53015
|
-
raw =
|
|
53108
|
+
raw = import_node_fs29.default.readFileSync(candidate, "utf8");
|
|
53016
53109
|
break;
|
|
53017
53110
|
} catch {
|
|
53018
53111
|
}
|
|
@@ -53037,19 +53130,19 @@ function readInstalledPlugins2(home) {
|
|
|
53037
53130
|
return out;
|
|
53038
53131
|
}
|
|
53039
53132
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
53040
|
-
let cur =
|
|
53041
|
-
const fsRoot =
|
|
53133
|
+
let cur = import_node_path31.default.resolve(startCwd);
|
|
53134
|
+
const fsRoot = import_node_path31.default.parse(cur).root;
|
|
53042
53135
|
while (true) {
|
|
53043
|
-
scanAgentsDir(
|
|
53136
|
+
scanAgentsDir(import_node_path31.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
53044
53137
|
let hasGit = false;
|
|
53045
53138
|
try {
|
|
53046
|
-
hasGit =
|
|
53139
|
+
hasGit = import_node_fs29.default.existsSync(import_node_path31.default.join(cur, ".git"));
|
|
53047
53140
|
} catch {
|
|
53048
53141
|
}
|
|
53049
53142
|
if (hasGit) return;
|
|
53050
53143
|
if (cur === home) return;
|
|
53051
53144
|
if (cur === fsRoot) return;
|
|
53052
|
-
const parent =
|
|
53145
|
+
const parent = import_node_path31.default.dirname(cur);
|
|
53053
53146
|
if (parent === cur) return;
|
|
53054
53147
|
cur = parent;
|
|
53055
53148
|
}
|
|
@@ -53084,7 +53177,7 @@ var AgentsScanner = class {
|
|
|
53084
53177
|
}
|
|
53085
53178
|
const fsBlock = [];
|
|
53086
53179
|
scanAgentsDir(
|
|
53087
|
-
|
|
53180
|
+
import_node_path31.default.join(this.home, ".claude", "agents"),
|
|
53088
53181
|
"global",
|
|
53089
53182
|
seen,
|
|
53090
53183
|
fsBlock
|
|
@@ -53098,7 +53191,7 @@ var AgentsScanner = class {
|
|
|
53098
53191
|
...this.extraPluginRoots
|
|
53099
53192
|
];
|
|
53100
53193
|
for (const { name, root } of plugins) {
|
|
53101
|
-
const agentsRoot =
|
|
53194
|
+
const agentsRoot = import_node_path31.default.join(root, "agents");
|
|
53102
53195
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
53103
53196
|
}
|
|
53104
53197
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -53106,15 +53199,15 @@ var AgentsScanner = class {
|
|
|
53106
53199
|
};
|
|
53107
53200
|
|
|
53108
53201
|
// src/observer/session-observer.ts
|
|
53109
|
-
var
|
|
53202
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
53110
53203
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
53111
|
-
var
|
|
53204
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
53112
53205
|
init_claude_history();
|
|
53113
53206
|
|
|
53114
53207
|
// src/observer/subagent-meta-observer.ts
|
|
53115
|
-
var
|
|
53208
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
53116
53209
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
53117
|
-
var
|
|
53210
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
53118
53211
|
init_claude_history();
|
|
53119
53212
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
53120
53213
|
var SubagentMetaObserver = class {
|
|
@@ -53127,7 +53220,7 @@ var SubagentMetaObserver = class {
|
|
|
53127
53220
|
watches = /* @__PURE__ */ new Map();
|
|
53128
53221
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
53129
53222
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
53130
|
-
return
|
|
53223
|
+
return import_node_path32.default.join(
|
|
53131
53224
|
this.home,
|
|
53132
53225
|
".claude",
|
|
53133
53226
|
"projects",
|
|
@@ -53157,7 +53250,7 @@ var SubagentMetaObserver = class {
|
|
|
53157
53250
|
attachWatcher(w2) {
|
|
53158
53251
|
if (w2.watcher) return;
|
|
53159
53252
|
try {
|
|
53160
|
-
w2.watcher =
|
|
53253
|
+
w2.watcher = import_node_fs30.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
53161
53254
|
if (!name) return;
|
|
53162
53255
|
const m2 = META_RE.exec(String(name));
|
|
53163
53256
|
if (!m2) return;
|
|
@@ -53169,7 +53262,7 @@ var SubagentMetaObserver = class {
|
|
|
53169
53262
|
scan(w2) {
|
|
53170
53263
|
let entries;
|
|
53171
53264
|
try {
|
|
53172
|
-
entries =
|
|
53265
|
+
entries = import_node_fs30.default.readdirSync(w2.dirPath);
|
|
53173
53266
|
} catch {
|
|
53174
53267
|
return;
|
|
53175
53268
|
}
|
|
@@ -53183,10 +53276,10 @@ var SubagentMetaObserver = class {
|
|
|
53183
53276
|
if (!m2) return;
|
|
53184
53277
|
const agentId = m2[1];
|
|
53185
53278
|
if (w2.emitted.has(agentId)) return;
|
|
53186
|
-
const file =
|
|
53279
|
+
const file = import_node_path32.default.join(w2.dirPath, name);
|
|
53187
53280
|
let raw;
|
|
53188
53281
|
try {
|
|
53189
|
-
raw =
|
|
53282
|
+
raw = import_node_fs30.default.readFileSync(file, "utf8");
|
|
53190
53283
|
} catch {
|
|
53191
53284
|
return;
|
|
53192
53285
|
}
|
|
@@ -53243,14 +53336,14 @@ var SessionObserver = class {
|
|
|
53243
53336
|
metaObserver;
|
|
53244
53337
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
53245
53338
|
if (override) return override;
|
|
53246
|
-
return
|
|
53339
|
+
return import_node_path33.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
53247
53340
|
}
|
|
53248
53341
|
start(args) {
|
|
53249
53342
|
this.stop(args.sessionId);
|
|
53250
53343
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
53251
53344
|
let size = 0;
|
|
53252
53345
|
try {
|
|
53253
|
-
size =
|
|
53346
|
+
size = import_node_fs31.default.statSync(filePath).size;
|
|
53254
53347
|
} catch {
|
|
53255
53348
|
}
|
|
53256
53349
|
const w2 = {
|
|
@@ -53263,16 +53356,16 @@ var SessionObserver = class {
|
|
|
53263
53356
|
adapter: args.adapter,
|
|
53264
53357
|
prevIsRejectSentinel: false,
|
|
53265
53358
|
toolSessionId: args.toolSessionId,
|
|
53266
|
-
sawFile:
|
|
53359
|
+
sawFile: import_node_fs31.default.existsSync(filePath),
|
|
53267
53360
|
lastRelocateScanMs: 0,
|
|
53268
53361
|
pendingCwdDerive: false,
|
|
53269
53362
|
lastDeriveMs: 0
|
|
53270
53363
|
};
|
|
53271
53364
|
try {
|
|
53272
|
-
|
|
53365
|
+
import_node_fs31.default.mkdirSync(import_node_path33.default.dirname(filePath), { recursive: true });
|
|
53273
53366
|
} catch {
|
|
53274
53367
|
}
|
|
53275
|
-
w2.watcher =
|
|
53368
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path33.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
53276
53369
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
53277
53370
|
this.poll(w2);
|
|
53278
53371
|
});
|
|
@@ -53295,7 +53388,7 @@ var SessionObserver = class {
|
|
|
53295
53388
|
// 异常静默吞,不阻塞 watcher 启动
|
|
53296
53389
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
53297
53390
|
try {
|
|
53298
|
-
const raw =
|
|
53391
|
+
const raw = import_node_fs31.default.readFileSync(w2.filePath, "utf8");
|
|
53299
53392
|
if (!raw) return;
|
|
53300
53393
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
53301
53394
|
if (allLines.length === 0) return;
|
|
@@ -53319,7 +53412,7 @@ var SessionObserver = class {
|
|
|
53319
53412
|
poll(w2) {
|
|
53320
53413
|
let size = 0;
|
|
53321
53414
|
try {
|
|
53322
|
-
size =
|
|
53415
|
+
size = import_node_fs31.default.statSync(w2.filePath).size;
|
|
53323
53416
|
} catch {
|
|
53324
53417
|
if (w2.sawFile) this.maybeRelocate(w2);
|
|
53325
53418
|
return;
|
|
@@ -53330,11 +53423,11 @@ var SessionObserver = class {
|
|
|
53330
53423
|
w2.buf = "";
|
|
53331
53424
|
}
|
|
53332
53425
|
if (size === w2.lastSize) return;
|
|
53333
|
-
const fd =
|
|
53426
|
+
const fd = import_node_fs31.default.openSync(w2.filePath, "r");
|
|
53334
53427
|
try {
|
|
53335
53428
|
const len = size - w2.lastSize;
|
|
53336
53429
|
const buf = Buffer.alloc(len);
|
|
53337
|
-
|
|
53430
|
+
import_node_fs31.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
53338
53431
|
w2.lastSize = size;
|
|
53339
53432
|
w2.buf += buf.toString("utf8");
|
|
53340
53433
|
let newlineIndex;
|
|
@@ -53357,7 +53450,7 @@ var SessionObserver = class {
|
|
|
53357
53450
|
}
|
|
53358
53451
|
}
|
|
53359
53452
|
} finally {
|
|
53360
|
-
|
|
53453
|
+
import_node_fs31.default.closeSync(fd);
|
|
53361
53454
|
}
|
|
53362
53455
|
if (w2.pendingCwdDerive) this.maybeDeriveCwd(w2);
|
|
53363
53456
|
}
|
|
@@ -53369,7 +53462,7 @@ var SessionObserver = class {
|
|
|
53369
53462
|
const now = Date.now();
|
|
53370
53463
|
if (now - w2.lastRelocateScanMs < 1e3) return;
|
|
53371
53464
|
w2.lastRelocateScanMs = now;
|
|
53372
|
-
const projectsRoot =
|
|
53465
|
+
const projectsRoot = import_node_path33.default.join(this.home, ".claude", "projects");
|
|
53373
53466
|
const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
|
|
53374
53467
|
if (!found || found === w2.filePath) return;
|
|
53375
53468
|
try {
|
|
@@ -53378,7 +53471,7 @@ var SessionObserver = class {
|
|
|
53378
53471
|
}
|
|
53379
53472
|
w2.filePath = found;
|
|
53380
53473
|
try {
|
|
53381
|
-
w2.watcher =
|
|
53474
|
+
w2.watcher = import_node_fs31.default.watch(import_node_path33.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
53382
53475
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
53383
53476
|
this.poll(w2);
|
|
53384
53477
|
});
|
|
@@ -54173,8 +54266,8 @@ async function authenticate(token, deps) {
|
|
|
54173
54266
|
}
|
|
54174
54267
|
|
|
54175
54268
|
// src/legacy-cleanup.ts
|
|
54176
|
-
var
|
|
54177
|
-
var
|
|
54269
|
+
var fs36 = __toESM(require("fs/promises"), 1);
|
|
54270
|
+
var path38 = __toESM(require("path"), 1);
|
|
54178
54271
|
var LEGACY_FILES = [
|
|
54179
54272
|
"personal-capability.json",
|
|
54180
54273
|
"received-capabilities.json",
|
|
@@ -54183,9 +54276,9 @@ var LEGACY_FILES = [
|
|
|
54183
54276
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
54184
54277
|
const removed = [];
|
|
54185
54278
|
for (const name of LEGACY_FILES) {
|
|
54186
|
-
const p2 =
|
|
54279
|
+
const p2 = path38.join(dataDir, name);
|
|
54187
54280
|
try {
|
|
54188
|
-
await
|
|
54281
|
+
await fs36.unlink(p2);
|
|
54189
54282
|
removed.push(name);
|
|
54190
54283
|
logger.debug("legacy capability file removed", { file: name });
|
|
54191
54284
|
} catch (err) {
|
|
@@ -54197,13 +54290,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
54197
54290
|
}
|
|
54198
54291
|
|
|
54199
54292
|
// src/inbox/inbox-store.ts
|
|
54200
|
-
var
|
|
54201
|
-
var
|
|
54293
|
+
var fs37 = __toESM(require("fs"), 1);
|
|
54294
|
+
var path39 = __toESM(require("path"), 1);
|
|
54202
54295
|
var INBOX_SUBDIR = "inbox";
|
|
54203
54296
|
var InboxStore = class {
|
|
54204
54297
|
constructor(dataDir) {
|
|
54205
54298
|
this.dataDir = dataDir;
|
|
54206
|
-
|
|
54299
|
+
fs37.mkdirSync(this.dirPath(), { recursive: true });
|
|
54207
54300
|
}
|
|
54208
54301
|
dataDir;
|
|
54209
54302
|
/**
|
|
@@ -54215,7 +54308,7 @@ var InboxStore = class {
|
|
|
54215
54308
|
const file = this.filePath(peerDeviceId);
|
|
54216
54309
|
let raw;
|
|
54217
54310
|
try {
|
|
54218
|
-
raw =
|
|
54311
|
+
raw = fs37.readFileSync(file, "utf8");
|
|
54219
54312
|
} catch (err) {
|
|
54220
54313
|
if (err?.code === "ENOENT") return [];
|
|
54221
54314
|
return [];
|
|
@@ -54231,7 +54324,7 @@ var InboxStore = class {
|
|
|
54231
54324
|
const dir = this.dirPath();
|
|
54232
54325
|
let entries;
|
|
54233
54326
|
try {
|
|
54234
|
-
entries =
|
|
54327
|
+
entries = fs37.readdirSync(dir);
|
|
54235
54328
|
} catch (err) {
|
|
54236
54329
|
if (err?.code === "ENOENT") return [];
|
|
54237
54330
|
return [];
|
|
@@ -54247,9 +54340,9 @@ var InboxStore = class {
|
|
|
54247
54340
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
54248
54341
|
const file = this.filePath(message.peerDeviceId);
|
|
54249
54342
|
const line = JSON.stringify(message) + "\n";
|
|
54250
|
-
|
|
54343
|
+
fs37.appendFileSync(file, line, { mode: 384 });
|
|
54251
54344
|
try {
|
|
54252
|
-
|
|
54345
|
+
fs37.chmodSync(file, 384);
|
|
54253
54346
|
} catch {
|
|
54254
54347
|
}
|
|
54255
54348
|
}
|
|
@@ -54279,7 +54372,7 @@ var InboxStore = class {
|
|
|
54279
54372
|
removeByPeerDeviceId(peerDeviceId) {
|
|
54280
54373
|
const file = this.filePath(peerDeviceId);
|
|
54281
54374
|
try {
|
|
54282
|
-
|
|
54375
|
+
fs37.unlinkSync(file);
|
|
54283
54376
|
} catch (err) {
|
|
54284
54377
|
if (err?.code === "ENOENT") return;
|
|
54285
54378
|
}
|
|
@@ -54288,18 +54381,18 @@ var InboxStore = class {
|
|
|
54288
54381
|
const file = this.filePath(peerDeviceId);
|
|
54289
54382
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
54290
54383
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
54291
|
-
|
|
54292
|
-
|
|
54384
|
+
fs37.writeFileSync(tmp, content, { mode: 384 });
|
|
54385
|
+
fs37.renameSync(tmp, file);
|
|
54293
54386
|
try {
|
|
54294
|
-
|
|
54387
|
+
fs37.chmodSync(file, 384);
|
|
54295
54388
|
} catch {
|
|
54296
54389
|
}
|
|
54297
54390
|
}
|
|
54298
54391
|
dirPath() {
|
|
54299
|
-
return
|
|
54392
|
+
return path39.join(this.dataDir, INBOX_SUBDIR);
|
|
54300
54393
|
}
|
|
54301
54394
|
filePath(peerDeviceId) {
|
|
54302
|
-
return
|
|
54395
|
+
return path39.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
54303
54396
|
}
|
|
54304
54397
|
};
|
|
54305
54398
|
function parseAllLines(raw) {
|
|
@@ -54387,8 +54480,8 @@ var InboxManager = class {
|
|
|
54387
54480
|
};
|
|
54388
54481
|
|
|
54389
54482
|
// src/state/contact-store.ts
|
|
54390
|
-
var
|
|
54391
|
-
var
|
|
54483
|
+
var fs38 = __toESM(require("fs"), 1);
|
|
54484
|
+
var path40 = __toESM(require("path"), 1);
|
|
54392
54485
|
var FILE_NAME = "contacts.json";
|
|
54393
54486
|
var ContactStore = class {
|
|
54394
54487
|
constructor(dataDir) {
|
|
@@ -54398,10 +54491,10 @@ var ContactStore = class {
|
|
|
54398
54491
|
contacts = /* @__PURE__ */ new Map();
|
|
54399
54492
|
load() {
|
|
54400
54493
|
this.contacts.clear();
|
|
54401
|
-
const file =
|
|
54494
|
+
const file = path40.join(this.dataDir, FILE_NAME);
|
|
54402
54495
|
let raw;
|
|
54403
54496
|
try {
|
|
54404
|
-
raw =
|
|
54497
|
+
raw = fs38.readFileSync(file, "utf8");
|
|
54405
54498
|
} catch (err) {
|
|
54406
54499
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
54407
54500
|
return;
|
|
@@ -54470,20 +54563,20 @@ var ContactStore = class {
|
|
|
54470
54563
|
return true;
|
|
54471
54564
|
}
|
|
54472
54565
|
flush() {
|
|
54473
|
-
const file =
|
|
54566
|
+
const file = path40.join(this.dataDir, FILE_NAME);
|
|
54474
54567
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
54475
54568
|
const content = JSON.stringify(
|
|
54476
54569
|
{ contacts: Array.from(this.contacts.values()) },
|
|
54477
54570
|
null,
|
|
54478
54571
|
2
|
|
54479
54572
|
);
|
|
54480
|
-
|
|
54481
|
-
|
|
54482
|
-
|
|
54573
|
+
fs38.mkdirSync(this.dataDir, { recursive: true });
|
|
54574
|
+
fs38.writeFileSync(tmp, content, { mode: 384 });
|
|
54575
|
+
fs38.renameSync(tmp, file);
|
|
54483
54576
|
}
|
|
54484
54577
|
renameBak(file) {
|
|
54485
54578
|
try {
|
|
54486
|
-
|
|
54579
|
+
fs38.renameSync(file, `${file}.bak`);
|
|
54487
54580
|
} catch {
|
|
54488
54581
|
}
|
|
54489
54582
|
}
|
|
@@ -54591,61 +54684,61 @@ async function connectRemote(args) {
|
|
|
54591
54684
|
}
|
|
54592
54685
|
|
|
54593
54686
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
54594
|
-
var
|
|
54595
|
-
var
|
|
54687
|
+
var fs39 = __toESM(require("fs"), 1);
|
|
54688
|
+
var path41 = __toESM(require("path"), 1);
|
|
54596
54689
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
54597
54690
|
function migrateFlattenSessions(opts) {
|
|
54598
54691
|
const dataDir = opts.dataDir;
|
|
54599
54692
|
const now = opts.now ?? Date.now;
|
|
54600
|
-
const sessionsDir =
|
|
54601
|
-
const flagPath =
|
|
54693
|
+
const sessionsDir = path41.join(dataDir, "sessions");
|
|
54694
|
+
const flagPath = path41.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
54602
54695
|
if (existsSync3(flagPath)) {
|
|
54603
54696
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
54604
54697
|
}
|
|
54605
54698
|
let movedBare = 0;
|
|
54606
54699
|
let movedVmOwner = 0;
|
|
54607
54700
|
let archivedListener = 0;
|
|
54608
|
-
const defaultDir =
|
|
54701
|
+
const defaultDir = path41.join(sessionsDir, "default");
|
|
54609
54702
|
if (existsSync3(defaultDir)) {
|
|
54610
54703
|
for (const entry of readdirSafe(defaultDir)) {
|
|
54611
54704
|
if (!entry.endsWith(".json")) continue;
|
|
54612
|
-
const src =
|
|
54613
|
-
const dst =
|
|
54614
|
-
|
|
54705
|
+
const src = path41.join(defaultDir, entry);
|
|
54706
|
+
const dst = path41.join(sessionsDir, entry);
|
|
54707
|
+
fs39.renameSync(src, dst);
|
|
54615
54708
|
movedBare += 1;
|
|
54616
54709
|
}
|
|
54617
54710
|
rmdirIfEmpty(defaultDir);
|
|
54618
54711
|
}
|
|
54619
54712
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
54620
|
-
const personaDir =
|
|
54713
|
+
const personaDir = path41.join(sessionsDir, pid);
|
|
54621
54714
|
if (!isDir(personaDir)) continue;
|
|
54622
54715
|
if (pid === "default") continue;
|
|
54623
|
-
const ownerSrc =
|
|
54716
|
+
const ownerSrc = path41.join(personaDir, "owner");
|
|
54624
54717
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
54625
|
-
const ownerDst =
|
|
54626
|
-
|
|
54718
|
+
const ownerDst = path41.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
54719
|
+
fs39.mkdirSync(ownerDst, { recursive: true });
|
|
54627
54720
|
for (const file of readdirSafe(ownerSrc)) {
|
|
54628
54721
|
if (!file.endsWith(".json")) continue;
|
|
54629
|
-
|
|
54722
|
+
fs39.renameSync(path41.join(ownerSrc, file), path41.join(ownerDst, file));
|
|
54630
54723
|
movedVmOwner += 1;
|
|
54631
54724
|
}
|
|
54632
54725
|
rmdirIfEmpty(ownerSrc);
|
|
54633
54726
|
}
|
|
54634
|
-
const listenerSrc =
|
|
54727
|
+
const listenerSrc = path41.join(personaDir, "listener");
|
|
54635
54728
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
54636
|
-
const archiveDst =
|
|
54637
|
-
|
|
54729
|
+
const archiveDst = path41.join(dataDir, ".legacy", `listener-${pid}`);
|
|
54730
|
+
fs39.mkdirSync(archiveDst, { recursive: true });
|
|
54638
54731
|
for (const file of readdirSafe(listenerSrc)) {
|
|
54639
54732
|
if (!file.endsWith(".json")) continue;
|
|
54640
|
-
|
|
54733
|
+
fs39.renameSync(path41.join(listenerSrc, file), path41.join(archiveDst, file));
|
|
54641
54734
|
archivedListener += 1;
|
|
54642
54735
|
}
|
|
54643
54736
|
rmdirIfEmpty(listenerSrc);
|
|
54644
54737
|
}
|
|
54645
54738
|
rmdirIfEmpty(personaDir);
|
|
54646
54739
|
}
|
|
54647
|
-
|
|
54648
|
-
|
|
54740
|
+
fs39.mkdirSync(sessionsDir, { recursive: true });
|
|
54741
|
+
fs39.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
54649
54742
|
return {
|
|
54650
54743
|
skipped: false,
|
|
54651
54744
|
flagWritten: true,
|
|
@@ -54656,7 +54749,7 @@ function migrateFlattenSessions(opts) {
|
|
|
54656
54749
|
}
|
|
54657
54750
|
function existsSync3(p2) {
|
|
54658
54751
|
try {
|
|
54659
|
-
|
|
54752
|
+
fs39.statSync(p2);
|
|
54660
54753
|
return true;
|
|
54661
54754
|
} catch {
|
|
54662
54755
|
return false;
|
|
@@ -54664,31 +54757,31 @@ function existsSync3(p2) {
|
|
|
54664
54757
|
}
|
|
54665
54758
|
function isDir(p2) {
|
|
54666
54759
|
try {
|
|
54667
|
-
return
|
|
54760
|
+
return fs39.statSync(p2).isDirectory();
|
|
54668
54761
|
} catch {
|
|
54669
54762
|
return false;
|
|
54670
54763
|
}
|
|
54671
54764
|
}
|
|
54672
54765
|
function readdirSafe(p2) {
|
|
54673
54766
|
try {
|
|
54674
|
-
return
|
|
54767
|
+
return fs39.readdirSync(p2);
|
|
54675
54768
|
} catch {
|
|
54676
54769
|
return [];
|
|
54677
54770
|
}
|
|
54678
54771
|
}
|
|
54679
54772
|
function rmdirIfEmpty(p2) {
|
|
54680
54773
|
try {
|
|
54681
|
-
|
|
54774
|
+
fs39.rmdirSync(p2);
|
|
54682
54775
|
} catch {
|
|
54683
54776
|
}
|
|
54684
54777
|
}
|
|
54685
54778
|
|
|
54686
54779
|
// src/transport/http-router.ts
|
|
54687
|
-
var
|
|
54688
|
-
var
|
|
54780
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
54781
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
54689
54782
|
|
|
54690
54783
|
// src/attachment/mime.ts
|
|
54691
|
-
var
|
|
54784
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
54692
54785
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
54693
54786
|
var EXT_TO_NATIVE_MIME = {
|
|
54694
54787
|
// 图片
|
|
@@ -54795,7 +54888,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
54795
54888
|
".mk"
|
|
54796
54889
|
]);
|
|
54797
54890
|
function lookupMime(filePathOrName) {
|
|
54798
|
-
const ext =
|
|
54891
|
+
const ext = import_node_path34.default.extname(filePathOrName).toLowerCase();
|
|
54799
54892
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
54800
54893
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
54801
54894
|
return "application/octet-stream";
|
|
@@ -54865,8 +54958,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
54865
54958
|
}
|
|
54866
54959
|
|
|
54867
54960
|
// src/attachment/upload.ts
|
|
54868
|
-
var
|
|
54869
|
-
var
|
|
54961
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
54962
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
54870
54963
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
54871
54964
|
var import_promises3 = require("stream/promises");
|
|
54872
54965
|
var UploadError = class extends Error {
|
|
@@ -54878,22 +54971,22 @@ var UploadError = class extends Error {
|
|
|
54878
54971
|
code;
|
|
54879
54972
|
};
|
|
54880
54973
|
function assertValidFileName(fileName) {
|
|
54881
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
54974
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path35.default.basename(fileName)) {
|
|
54882
54975
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
54883
54976
|
}
|
|
54884
54977
|
}
|
|
54885
54978
|
var HASH_PREFIX_LEN = 16;
|
|
54886
54979
|
async function writeUploadedAttachment(args) {
|
|
54887
54980
|
assertValidFileName(args.fileName);
|
|
54888
|
-
const attachmentsRoot =
|
|
54981
|
+
const attachmentsRoot = import_node_path35.default.join(args.baseDir, ".attachments");
|
|
54889
54982
|
try {
|
|
54890
|
-
|
|
54983
|
+
import_node_fs32.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
54891
54984
|
} catch (err) {
|
|
54892
54985
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
54893
54986
|
}
|
|
54894
54987
|
const hasher = import_node_crypto8.default.createHash("sha256");
|
|
54895
54988
|
let actualSize = 0;
|
|
54896
|
-
const tmpPath =
|
|
54989
|
+
const tmpPath = import_node_path35.default.join(
|
|
54897
54990
|
attachmentsRoot,
|
|
54898
54991
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
|
|
54899
54992
|
);
|
|
@@ -54908,18 +55001,18 @@ async function writeUploadedAttachment(args) {
|
|
|
54908
55001
|
yield buf;
|
|
54909
55002
|
}
|
|
54910
55003
|
},
|
|
54911
|
-
|
|
55004
|
+
import_node_fs32.default.createWriteStream(tmpPath, { mode: 384 })
|
|
54912
55005
|
);
|
|
54913
55006
|
} catch (err) {
|
|
54914
55007
|
try {
|
|
54915
|
-
|
|
55008
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54916
55009
|
} catch {
|
|
54917
55010
|
}
|
|
54918
55011
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
54919
55012
|
}
|
|
54920
55013
|
if (actualSize !== args.contentLength) {
|
|
54921
55014
|
try {
|
|
54922
|
-
|
|
55015
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54923
55016
|
} catch {
|
|
54924
55017
|
}
|
|
54925
55018
|
throw new UploadError(
|
|
@@ -54928,34 +55021,34 @@ async function writeUploadedAttachment(args) {
|
|
|
54928
55021
|
);
|
|
54929
55022
|
}
|
|
54930
55023
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
54931
|
-
const hashDir =
|
|
55024
|
+
const hashDir = import_node_path35.default.join(attachmentsRoot, attachmentId);
|
|
54932
55025
|
let finalFileName;
|
|
54933
55026
|
let hashDirExists = false;
|
|
54934
55027
|
try {
|
|
54935
|
-
hashDirExists =
|
|
55028
|
+
hashDirExists = import_node_fs32.default.statSync(hashDir).isDirectory();
|
|
54936
55029
|
} catch {
|
|
54937
55030
|
}
|
|
54938
55031
|
if (hashDirExists) {
|
|
54939
|
-
const existing =
|
|
55032
|
+
const existing = import_node_fs32.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
54940
55033
|
finalFileName = existing[0] ?? args.fileName;
|
|
54941
55034
|
try {
|
|
54942
|
-
|
|
55035
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54943
55036
|
} catch {
|
|
54944
55037
|
}
|
|
54945
55038
|
} else {
|
|
54946
55039
|
try {
|
|
54947
|
-
|
|
55040
|
+
import_node_fs32.default.mkdirSync(hashDir, { recursive: true });
|
|
54948
55041
|
finalFileName = args.fileName;
|
|
54949
|
-
|
|
55042
|
+
import_node_fs32.default.renameSync(tmpPath, import_node_path35.default.join(hashDir, finalFileName));
|
|
54950
55043
|
} catch (err) {
|
|
54951
55044
|
try {
|
|
54952
|
-
|
|
55045
|
+
import_node_fs32.default.unlinkSync(tmpPath);
|
|
54953
55046
|
} catch {
|
|
54954
55047
|
}
|
|
54955
55048
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
54956
55049
|
}
|
|
54957
55050
|
}
|
|
54958
|
-
const absPath =
|
|
55051
|
+
const absPath = import_node_path35.default.join(hashDir, finalFileName);
|
|
54959
55052
|
const relPath = absPath;
|
|
54960
55053
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
54961
55054
|
relPath: absPath,
|
|
@@ -54970,7 +55063,7 @@ async function writeUploadedAttachment(args) {
|
|
|
54970
55063
|
|
|
54971
55064
|
// src/extension/import.ts
|
|
54972
55065
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
54973
|
-
var
|
|
55066
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
54974
55067
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
54975
55068
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
54976
55069
|
var ImportError = class extends Error {
|
|
@@ -54988,7 +55081,7 @@ async function importZip(buf, root) {
|
|
|
54988
55081
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
54989
55082
|
}
|
|
54990
55083
|
for (const name of Object.keys(zip.files)) {
|
|
54991
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
55084
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path36.default.isAbsolute(name)) {
|
|
54992
55085
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
54993
55086
|
}
|
|
54994
55087
|
}
|
|
@@ -55021,7 +55114,7 @@ async function importZip(buf, root) {
|
|
|
55021
55114
|
);
|
|
55022
55115
|
}
|
|
55023
55116
|
}
|
|
55024
|
-
const destDir =
|
|
55117
|
+
const destDir = import_node_path36.default.join(root, manifest.id);
|
|
55025
55118
|
let destExists = false;
|
|
55026
55119
|
try {
|
|
55027
55120
|
await import_promises4.default.access(destDir);
|
|
@@ -55031,15 +55124,15 @@ async function importZip(buf, root) {
|
|
|
55031
55124
|
if (destExists) {
|
|
55032
55125
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
55033
55126
|
}
|
|
55034
|
-
const stage = await import_promises4.default.mkdtemp(
|
|
55127
|
+
const stage = await import_promises4.default.mkdtemp(import_node_path36.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
55035
55128
|
try {
|
|
55036
55129
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
55037
|
-
const dest =
|
|
55130
|
+
const dest = import_node_path36.default.join(stage, name);
|
|
55038
55131
|
if (entry.dir) {
|
|
55039
55132
|
await import_promises4.default.mkdir(dest, { recursive: true });
|
|
55040
55133
|
continue;
|
|
55041
55134
|
}
|
|
55042
|
-
await import_promises4.default.mkdir(
|
|
55135
|
+
await import_promises4.default.mkdir(import_node_path36.default.dirname(dest), { recursive: true });
|
|
55043
55136
|
const content = await entry.async("nodebuffer");
|
|
55044
55137
|
await import_promises4.default.writeFile(dest, content);
|
|
55045
55138
|
}
|
|
@@ -55069,7 +55162,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
55069
55162
|
".wasm": "application/wasm"
|
|
55070
55163
|
};
|
|
55071
55164
|
function shareUiAssetMime(filePath) {
|
|
55072
|
-
const ext =
|
|
55165
|
+
const ext = import_node_path37.default.extname(filePath).toLowerCase();
|
|
55073
55166
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
55074
55167
|
}
|
|
55075
55168
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -55168,7 +55261,7 @@ function isValidUploadFileName(fileName) {
|
|
|
55168
55261
|
if (fileName === "." || fileName === "..") return false;
|
|
55169
55262
|
if (fileName.startsWith(".")) return false;
|
|
55170
55263
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
55171
|
-
return fileName ===
|
|
55264
|
+
return fileName === import_node_path37.default.basename(fileName);
|
|
55172
55265
|
}
|
|
55173
55266
|
function createHttpRouter(deps) {
|
|
55174
55267
|
return async (req, res) => {
|
|
@@ -55256,7 +55349,7 @@ function createHttpRouter(deps) {
|
|
|
55256
55349
|
}
|
|
55257
55350
|
let buf;
|
|
55258
55351
|
try {
|
|
55259
|
-
buf = await
|
|
55352
|
+
buf = await import_node_fs33.default.promises.readFile(abs);
|
|
55260
55353
|
} catch {
|
|
55261
55354
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
55262
55355
|
return true;
|
|
@@ -55404,7 +55497,7 @@ function createHttpRouter(deps) {
|
|
|
55404
55497
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
55405
55498
|
return true;
|
|
55406
55499
|
}
|
|
55407
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
55500
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path37.default.basename(r.absPath)));
|
|
55408
55501
|
return true;
|
|
55409
55502
|
}
|
|
55410
55503
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -55525,7 +55618,7 @@ function createHttpRouter(deps) {
|
|
|
55525
55618
|
return true;
|
|
55526
55619
|
}
|
|
55527
55620
|
let absPath;
|
|
55528
|
-
if (
|
|
55621
|
+
if (import_node_path37.default.isAbsolute(pathParam)) {
|
|
55529
55622
|
absPath = pathParam;
|
|
55530
55623
|
} else if (deps.sessionStore) {
|
|
55531
55624
|
const file = deps.sessionStore.read(sid);
|
|
@@ -55533,7 +55626,7 @@ function createHttpRouter(deps) {
|
|
|
55533
55626
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
55534
55627
|
return true;
|
|
55535
55628
|
}
|
|
55536
|
-
absPath =
|
|
55629
|
+
absPath = import_node_path37.default.join(file.cwd, pathParam);
|
|
55537
55630
|
} else {
|
|
55538
55631
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
55539
55632
|
return true;
|
|
@@ -55620,7 +55713,7 @@ function withCtx(ctx, body) {
|
|
|
55620
55713
|
function streamFile(res, absPath, logger) {
|
|
55621
55714
|
let stat;
|
|
55622
55715
|
try {
|
|
55623
|
-
stat =
|
|
55716
|
+
stat = import_node_fs33.default.statSync(absPath);
|
|
55624
55717
|
} catch (err) {
|
|
55625
55718
|
const code = err?.code;
|
|
55626
55719
|
if (code === "ENOENT") {
|
|
@@ -55635,7 +55728,7 @@ function streamFile(res, absPath, logger) {
|
|
|
55635
55728
|
return;
|
|
55636
55729
|
}
|
|
55637
55730
|
const mime = lookupMime(absPath);
|
|
55638
|
-
const basename =
|
|
55731
|
+
const basename = import_node_path37.default.basename(absPath);
|
|
55639
55732
|
res.writeHead(200, {
|
|
55640
55733
|
"Content-Type": mime,
|
|
55641
55734
|
"Content-Length": String(stat.size),
|
|
@@ -55643,7 +55736,7 @@ function streamFile(res, absPath, logger) {
|
|
|
55643
55736
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
55644
55737
|
"X-Content-Type-Options": "nosniff"
|
|
55645
55738
|
});
|
|
55646
|
-
const stream =
|
|
55739
|
+
const stream = import_node_fs33.default.createReadStream(absPath);
|
|
55647
55740
|
stream.on("error", (err) => {
|
|
55648
55741
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
55649
55742
|
res.destroy();
|
|
@@ -55652,8 +55745,8 @@ function streamFile(res, absPath, logger) {
|
|
|
55652
55745
|
}
|
|
55653
55746
|
|
|
55654
55747
|
// src/attachment/gc.ts
|
|
55655
|
-
var
|
|
55656
|
-
var
|
|
55748
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
55749
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
55657
55750
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
55658
55751
|
function runAttachmentGc(args) {
|
|
55659
55752
|
const now = (args.now ?? Date.now)();
|
|
@@ -55662,12 +55755,12 @@ function runAttachmentGc(args) {
|
|
|
55662
55755
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
55663
55756
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
55664
55757
|
if (entry.stale) continue;
|
|
55665
|
-
if (
|
|
55758
|
+
if (import_node_path38.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
55666
55759
|
}
|
|
55667
55760
|
}
|
|
55668
55761
|
const visited = /* @__PURE__ */ new Set();
|
|
55669
55762
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
55670
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
55763
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path38.default.join(
|
|
55671
55764
|
args.dataDir,
|
|
55672
55765
|
"sessions",
|
|
55673
55766
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -55680,28 +55773,28 @@ function runAttachmentGc(args) {
|
|
|
55680
55773
|
return true;
|
|
55681
55774
|
});
|
|
55682
55775
|
for (const rootDir of roots) {
|
|
55683
|
-
const attRoot =
|
|
55776
|
+
const attRoot = import_node_path38.default.join(rootDir, ".attachments");
|
|
55684
55777
|
let hashDirs;
|
|
55685
55778
|
try {
|
|
55686
|
-
hashDirs =
|
|
55779
|
+
hashDirs = import_node_fs34.default.readdirSync(attRoot);
|
|
55687
55780
|
} catch (err) {
|
|
55688
55781
|
if (err.code === "ENOENT") continue;
|
|
55689
55782
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
55690
55783
|
continue;
|
|
55691
55784
|
}
|
|
55692
55785
|
for (const hashDir of hashDirs) {
|
|
55693
|
-
const hashDirAbs =
|
|
55786
|
+
const hashDirAbs = import_node_path38.default.join(attRoot, hashDir);
|
|
55694
55787
|
let files;
|
|
55695
55788
|
try {
|
|
55696
|
-
files =
|
|
55789
|
+
files = import_node_fs34.default.readdirSync(hashDirAbs);
|
|
55697
55790
|
} catch {
|
|
55698
55791
|
continue;
|
|
55699
55792
|
}
|
|
55700
55793
|
for (const name of files) {
|
|
55701
|
-
const file =
|
|
55794
|
+
const file = import_node_path38.default.join(hashDirAbs, name);
|
|
55702
55795
|
let stat;
|
|
55703
55796
|
try {
|
|
55704
|
-
stat =
|
|
55797
|
+
stat = import_node_fs34.default.statSync(file);
|
|
55705
55798
|
} catch {
|
|
55706
55799
|
continue;
|
|
55707
55800
|
}
|
|
@@ -55710,18 +55803,18 @@ function runAttachmentGc(args) {
|
|
|
55710
55803
|
if (age < ttlMs) continue;
|
|
55711
55804
|
if (liveAbs.has(file)) continue;
|
|
55712
55805
|
try {
|
|
55713
|
-
|
|
55806
|
+
import_node_fs34.default.unlinkSync(file);
|
|
55714
55807
|
} catch (err) {
|
|
55715
55808
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
55716
55809
|
}
|
|
55717
55810
|
}
|
|
55718
55811
|
try {
|
|
55719
|
-
if (
|
|
55812
|
+
if (import_node_fs34.default.readdirSync(hashDirAbs).length === 0) import_node_fs34.default.rmdirSync(hashDirAbs);
|
|
55720
55813
|
} catch {
|
|
55721
55814
|
}
|
|
55722
55815
|
}
|
|
55723
55816
|
try {
|
|
55724
|
-
if (
|
|
55817
|
+
if (import_node_fs34.default.readdirSync(attRoot).length === 0) import_node_fs34.default.rmdirSync(attRoot);
|
|
55725
55818
|
} catch {
|
|
55726
55819
|
}
|
|
55727
55820
|
}
|
|
@@ -55729,8 +55822,8 @@ function runAttachmentGc(args) {
|
|
|
55729
55822
|
}
|
|
55730
55823
|
|
|
55731
55824
|
// src/attachment/group.ts
|
|
55732
|
-
var
|
|
55733
|
-
var
|
|
55825
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
55826
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
55734
55827
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
55735
55828
|
init_protocol();
|
|
55736
55829
|
var GroupFileStore = class {
|
|
@@ -55742,11 +55835,11 @@ var GroupFileStore = class {
|
|
|
55742
55835
|
this.logger = opts.logger;
|
|
55743
55836
|
}
|
|
55744
55837
|
rootForScope(scope) {
|
|
55745
|
-
return
|
|
55838
|
+
return import_node_path39.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
55746
55839
|
}
|
|
55747
55840
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
55748
55841
|
filePath(scope, sessionId) {
|
|
55749
|
-
return
|
|
55842
|
+
return import_node_path39.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
55750
55843
|
}
|
|
55751
55844
|
cacheKey(scope, sessionId) {
|
|
55752
55845
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -55755,7 +55848,7 @@ var GroupFileStore = class {
|
|
|
55755
55848
|
readFile(scope, sessionId) {
|
|
55756
55849
|
const file = this.filePath(scope, sessionId);
|
|
55757
55850
|
try {
|
|
55758
|
-
const raw =
|
|
55851
|
+
const raw = import_node_fs35.default.readFileSync(file, "utf8");
|
|
55759
55852
|
const parsed = JSON.parse(raw);
|
|
55760
55853
|
if (!Array.isArray(parsed)) {
|
|
55761
55854
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -55781,10 +55874,10 @@ var GroupFileStore = class {
|
|
|
55781
55874
|
}
|
|
55782
55875
|
writeFile(scope, sessionId, entries) {
|
|
55783
55876
|
const file = this.filePath(scope, sessionId);
|
|
55784
|
-
|
|
55877
|
+
import_node_fs35.default.mkdirSync(import_node_path39.default.dirname(file), { recursive: true });
|
|
55785
55878
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
55786
|
-
|
|
55787
|
-
|
|
55879
|
+
import_node_fs35.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
55880
|
+
import_node_fs35.default.renameSync(tmp, file);
|
|
55788
55881
|
}
|
|
55789
55882
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
55790
55883
|
list(scope, sessionId) {
|
|
@@ -55870,10 +55963,10 @@ var GroupFileStore = class {
|
|
|
55870
55963
|
};
|
|
55871
55964
|
|
|
55872
55965
|
// src/discovery/state-file.ts
|
|
55873
|
-
var
|
|
55874
|
-
var
|
|
55966
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
55967
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
55875
55968
|
function defaultStateFilePath(dataDir) {
|
|
55876
|
-
return
|
|
55969
|
+
return import_node_path40.default.join(dataDir, "state.json");
|
|
55877
55970
|
}
|
|
55878
55971
|
function isPidAlive(pid) {
|
|
55879
55972
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -55895,7 +55988,7 @@ var StateFileManager = class {
|
|
|
55895
55988
|
}
|
|
55896
55989
|
read() {
|
|
55897
55990
|
try {
|
|
55898
|
-
const raw =
|
|
55991
|
+
const raw = import_node_fs36.default.readFileSync(this.file, "utf8");
|
|
55899
55992
|
const parsed = JSON.parse(raw);
|
|
55900
55993
|
return parsed;
|
|
55901
55994
|
} catch {
|
|
@@ -55909,20 +56002,20 @@ var StateFileManager = class {
|
|
|
55909
56002
|
return { status: "stale", existing };
|
|
55910
56003
|
}
|
|
55911
56004
|
write(state) {
|
|
55912
|
-
|
|
56005
|
+
import_node_fs36.default.mkdirSync(import_node_path40.default.dirname(this.file), { recursive: true });
|
|
55913
56006
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
55914
|
-
|
|
55915
|
-
|
|
56007
|
+
import_node_fs36.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
56008
|
+
import_node_fs36.default.renameSync(tmp, this.file);
|
|
55916
56009
|
if (process.platform !== "win32") {
|
|
55917
56010
|
try {
|
|
55918
|
-
|
|
56011
|
+
import_node_fs36.default.chmodSync(this.file, 384);
|
|
55919
56012
|
} catch {
|
|
55920
56013
|
}
|
|
55921
56014
|
}
|
|
55922
56015
|
}
|
|
55923
56016
|
delete() {
|
|
55924
56017
|
try {
|
|
55925
|
-
|
|
56018
|
+
import_node_fs36.default.unlinkSync(this.file);
|
|
55926
56019
|
} catch {
|
|
55927
56020
|
}
|
|
55928
56021
|
}
|
|
@@ -55936,14 +56029,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
55936
56029
|
}
|
|
55937
56030
|
|
|
55938
56031
|
// src/tunnel/tunnel-manager.ts
|
|
55939
|
-
var
|
|
55940
|
-
var
|
|
56032
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
56033
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
55941
56034
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
55942
56035
|
var import_node_child_process9 = require("child_process");
|
|
55943
56036
|
|
|
55944
56037
|
// src/tunnel/tunnel-store.ts
|
|
55945
|
-
var
|
|
55946
|
-
var
|
|
56038
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
56039
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
55947
56040
|
var TunnelStore = class {
|
|
55948
56041
|
constructor(filePath) {
|
|
55949
56042
|
this.filePath = filePath;
|
|
@@ -55951,7 +56044,7 @@ var TunnelStore = class {
|
|
|
55951
56044
|
filePath;
|
|
55952
56045
|
async get() {
|
|
55953
56046
|
try {
|
|
55954
|
-
const raw = await
|
|
56047
|
+
const raw = await import_node_fs37.default.promises.readFile(this.filePath, "utf8");
|
|
55955
56048
|
const obj = JSON.parse(raw);
|
|
55956
56049
|
if (!isPersistedTunnel(obj)) return null;
|
|
55957
56050
|
return obj;
|
|
@@ -55962,22 +56055,22 @@ var TunnelStore = class {
|
|
|
55962
56055
|
}
|
|
55963
56056
|
}
|
|
55964
56057
|
async set(v2) {
|
|
55965
|
-
const dir =
|
|
55966
|
-
await
|
|
56058
|
+
const dir = import_node_path41.default.dirname(this.filePath);
|
|
56059
|
+
await import_node_fs37.default.promises.mkdir(dir, { recursive: true });
|
|
55967
56060
|
const data = JSON.stringify(v2, null, 2);
|
|
55968
56061
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
55969
|
-
await
|
|
56062
|
+
await import_node_fs37.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
55970
56063
|
if (process.platform !== "win32") {
|
|
55971
56064
|
try {
|
|
55972
|
-
await
|
|
56065
|
+
await import_node_fs37.default.promises.chmod(tmp, 384);
|
|
55973
56066
|
} catch {
|
|
55974
56067
|
}
|
|
55975
56068
|
}
|
|
55976
|
-
await
|
|
56069
|
+
await import_node_fs37.default.promises.rename(tmp, this.filePath);
|
|
55977
56070
|
}
|
|
55978
56071
|
async clear() {
|
|
55979
56072
|
try {
|
|
55980
|
-
await
|
|
56073
|
+
await import_node_fs37.default.promises.unlink(this.filePath);
|
|
55981
56074
|
} catch (err) {
|
|
55982
56075
|
const code = err?.code;
|
|
55983
56076
|
if (code !== "ENOENT") throw err;
|
|
@@ -56072,9 +56165,9 @@ function escape(v2) {
|
|
|
56072
56165
|
}
|
|
56073
56166
|
|
|
56074
56167
|
// src/tunnel/frpc-binary.ts
|
|
56075
|
-
var
|
|
56168
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
56076
56169
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
56077
|
-
var
|
|
56170
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
56078
56171
|
var import_node_child_process7 = require("child_process");
|
|
56079
56172
|
var import_node_stream3 = require("stream");
|
|
56080
56173
|
var import_promises5 = require("stream/promises");
|
|
@@ -56106,20 +56199,20 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
56106
56199
|
}
|
|
56107
56200
|
async function ensureFrpcBinary(opts) {
|
|
56108
56201
|
if (opts.override) {
|
|
56109
|
-
if (!
|
|
56202
|
+
if (!import_node_fs38.default.existsSync(opts.override)) {
|
|
56110
56203
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
56111
56204
|
}
|
|
56112
56205
|
return opts.override;
|
|
56113
56206
|
}
|
|
56114
56207
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
56115
56208
|
const platform = opts.platform ?? detectPlatform();
|
|
56116
|
-
const binDir =
|
|
56117
|
-
|
|
56209
|
+
const binDir = import_node_path42.default.join(opts.dataDir, "bin");
|
|
56210
|
+
import_node_fs38.default.mkdirSync(binDir, { recursive: true });
|
|
56118
56211
|
cleanupStaleArtifacts(binDir);
|
|
56119
|
-
const stableBin =
|
|
56120
|
-
if (
|
|
56212
|
+
const stableBin = import_node_path42.default.join(binDir, "frpc");
|
|
56213
|
+
if (import_node_fs38.default.existsSync(stableBin)) return stableBin;
|
|
56121
56214
|
const partialBin = `${stableBin}.partial`;
|
|
56122
|
-
const tarballPath =
|
|
56215
|
+
const tarballPath = import_node_path42.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
56123
56216
|
try {
|
|
56124
56217
|
const url = frpcDownloadUrl(version2, platform);
|
|
56125
56218
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -56128,8 +56221,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
56128
56221
|
} else {
|
|
56129
56222
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
56130
56223
|
}
|
|
56131
|
-
|
|
56132
|
-
|
|
56224
|
+
import_node_fs38.default.chmodSync(partialBin, 493);
|
|
56225
|
+
import_node_fs38.default.renameSync(partialBin, stableBin);
|
|
56133
56226
|
} finally {
|
|
56134
56227
|
safeUnlink(tarballPath);
|
|
56135
56228
|
safeUnlink(partialBin);
|
|
@@ -56139,15 +56232,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
56139
56232
|
function cleanupStaleArtifacts(binDir) {
|
|
56140
56233
|
let entries;
|
|
56141
56234
|
try {
|
|
56142
|
-
entries =
|
|
56235
|
+
entries = import_node_fs38.default.readdirSync(binDir);
|
|
56143
56236
|
} catch {
|
|
56144
56237
|
return;
|
|
56145
56238
|
}
|
|
56146
56239
|
for (const name of entries) {
|
|
56147
56240
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
56148
|
-
const full =
|
|
56241
|
+
const full = import_node_path42.default.join(binDir, name);
|
|
56149
56242
|
try {
|
|
56150
|
-
|
|
56243
|
+
import_node_fs38.default.rmSync(full, { recursive: true, force: true });
|
|
56151
56244
|
} catch {
|
|
56152
56245
|
}
|
|
56153
56246
|
}
|
|
@@ -56155,7 +56248,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
56155
56248
|
}
|
|
56156
56249
|
function safeUnlink(p2) {
|
|
56157
56250
|
try {
|
|
56158
|
-
|
|
56251
|
+
import_node_fs38.default.unlinkSync(p2);
|
|
56159
56252
|
} catch {
|
|
56160
56253
|
}
|
|
56161
56254
|
}
|
|
@@ -56166,13 +56259,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
56166
56259
|
if (!res.ok || !res.body) {
|
|
56167
56260
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
56168
56261
|
}
|
|
56169
|
-
const out =
|
|
56262
|
+
const out = import_node_fs38.default.createWriteStream(dest);
|
|
56170
56263
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
56171
56264
|
await (0, import_promises5.pipeline)(nodeStream, out);
|
|
56172
56265
|
}
|
|
56173
56266
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
56174
|
-
const work =
|
|
56175
|
-
|
|
56267
|
+
const work = import_node_path42.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
56268
|
+
import_node_fs38.default.mkdirSync(work, { recursive: true });
|
|
56176
56269
|
try {
|
|
56177
56270
|
await new Promise((resolve6, reject) => {
|
|
56178
56271
|
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -56180,32 +56273,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
56180
56273
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
56181
56274
|
});
|
|
56182
56275
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
56183
|
-
const src =
|
|
56184
|
-
if (!
|
|
56276
|
+
const src = import_node_path42.default.join(work, dirName, "frpc");
|
|
56277
|
+
if (!import_node_fs38.default.existsSync(src)) {
|
|
56185
56278
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
56186
56279
|
}
|
|
56187
|
-
|
|
56280
|
+
import_node_fs38.default.copyFileSync(src, destBin);
|
|
56188
56281
|
} finally {
|
|
56189
|
-
|
|
56282
|
+
import_node_fs38.default.rmSync(work, { recursive: true, force: true });
|
|
56190
56283
|
}
|
|
56191
56284
|
}
|
|
56192
56285
|
|
|
56193
56286
|
// src/tunnel/frpc-process.ts
|
|
56194
|
-
var
|
|
56195
|
-
var
|
|
56287
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
56288
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
56196
56289
|
var import_node_child_process8 = require("child_process");
|
|
56197
56290
|
function frpcPidFilePath(dataDir) {
|
|
56198
|
-
return
|
|
56291
|
+
return import_node_path43.default.join(dataDir, "frpc.pid");
|
|
56199
56292
|
}
|
|
56200
56293
|
function writeFrpcPid(dataDir, pid) {
|
|
56201
56294
|
try {
|
|
56202
|
-
|
|
56295
|
+
import_node_fs39.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
56203
56296
|
} catch {
|
|
56204
56297
|
}
|
|
56205
56298
|
}
|
|
56206
56299
|
function clearFrpcPid(dataDir) {
|
|
56207
56300
|
try {
|
|
56208
|
-
|
|
56301
|
+
import_node_fs39.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
56209
56302
|
} catch {
|
|
56210
56303
|
}
|
|
56211
56304
|
}
|
|
@@ -56221,7 +56314,7 @@ function defaultIsPidAlive(pid) {
|
|
|
56221
56314
|
}
|
|
56222
56315
|
function defaultReadPidFile(file) {
|
|
56223
56316
|
try {
|
|
56224
|
-
return
|
|
56317
|
+
return import_node_fs39.default.readFileSync(file, "utf8");
|
|
56225
56318
|
} catch {
|
|
56226
56319
|
return null;
|
|
56227
56320
|
}
|
|
@@ -56237,7 +56330,7 @@ function defaultSleep2(ms) {
|
|
|
56237
56330
|
}
|
|
56238
56331
|
async function killStaleFrpc(deps) {
|
|
56239
56332
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
56240
|
-
const tomlPath =
|
|
56333
|
+
const tomlPath = import_node_path43.default.join(deps.dataDir, "frpc.toml");
|
|
56241
56334
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
56242
56335
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
56243
56336
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -56261,7 +56354,7 @@ async function killStaleFrpc(deps) {
|
|
|
56261
56354
|
}
|
|
56262
56355
|
if (victims.size === 0) {
|
|
56263
56356
|
try {
|
|
56264
|
-
|
|
56357
|
+
import_node_fs39.default.unlinkSync(pidFile);
|
|
56265
56358
|
} catch {
|
|
56266
56359
|
}
|
|
56267
56360
|
return;
|
|
@@ -56272,7 +56365,7 @@ async function killStaleFrpc(deps) {
|
|
|
56272
56365
|
}
|
|
56273
56366
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
56274
56367
|
try {
|
|
56275
|
-
|
|
56368
|
+
import_node_fs39.default.unlinkSync(pidFile);
|
|
56276
56369
|
} catch {
|
|
56277
56370
|
}
|
|
56278
56371
|
}
|
|
@@ -56309,7 +56402,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
56309
56402
|
var TunnelManager = class {
|
|
56310
56403
|
constructor(deps) {
|
|
56311
56404
|
this.deps = deps;
|
|
56312
|
-
this.store = deps.store ?? new TunnelStore(
|
|
56405
|
+
this.store = deps.store ?? new TunnelStore(import_node_path44.default.join(deps.dataDir, "tunnel.json"));
|
|
56313
56406
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
56314
56407
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
56315
56408
|
}
|
|
@@ -56436,7 +56529,7 @@ var TunnelManager = class {
|
|
|
56436
56529
|
dataDir: this.deps.dataDir,
|
|
56437
56530
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
56438
56531
|
});
|
|
56439
|
-
const tomlPath =
|
|
56532
|
+
const tomlPath = import_node_path44.default.join(this.deps.dataDir, "frpc.toml");
|
|
56440
56533
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
|
|
56441
56534
|
const toml = buildFrpcToml({
|
|
56442
56535
|
serverAddr: t.frpsHost,
|
|
@@ -56447,14 +56540,14 @@ var TunnelManager = class {
|
|
|
56447
56540
|
localPort,
|
|
56448
56541
|
logLevel: "info"
|
|
56449
56542
|
});
|
|
56450
|
-
await
|
|
56543
|
+
await import_node_fs40.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
56451
56544
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
56452
56545
|
stdio: ["ignore", "pipe", "pipe"]
|
|
56453
56546
|
});
|
|
56454
|
-
const logDir =
|
|
56455
|
-
|
|
56456
|
-
const logFilePath =
|
|
56457
|
-
const logStream =
|
|
56547
|
+
const logDir = import_node_path44.default.join(this.deps.dataDir, "log");
|
|
56548
|
+
import_node_fs40.default.mkdirSync(logDir, { recursive: true });
|
|
56549
|
+
const logFilePath = import_node_path44.default.join(logDir, "frpc.log");
|
|
56550
|
+
const logStream = import_node_fs40.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
56458
56551
|
logStream.on("error", () => {
|
|
56459
56552
|
});
|
|
56460
56553
|
const tee = (chunk) => {
|
|
@@ -56537,27 +56630,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
56537
56630
|
|
|
56538
56631
|
// src/tunnel/device-key.ts
|
|
56539
56632
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
56540
|
-
var
|
|
56633
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
56541
56634
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
56542
56635
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
56543
56636
|
function deriveStableDeviceKey(opts = {}) {
|
|
56544
56637
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
56545
56638
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
56546
56639
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
56547
|
-
const defaultDataDir =
|
|
56548
|
-
const normalizedDataDir = opts.dataDir ?
|
|
56640
|
+
const defaultDataDir = import_node_path45.default.resolve(import_node_path45.default.join(home, ".clawd"));
|
|
56641
|
+
const normalizedDataDir = opts.dataDir ? import_node_path45.default.resolve(opts.dataDir) : null;
|
|
56549
56642
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
56550
56643
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
56551
56644
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
56552
56645
|
}
|
|
56553
56646
|
|
|
56554
56647
|
// src/auth-store.ts
|
|
56555
|
-
var
|
|
56556
|
-
var
|
|
56648
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
56649
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
56557
56650
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
56558
56651
|
var AUTH_FILE_NAME = "auth.json";
|
|
56559
56652
|
function authFilePath(dataDir) {
|
|
56560
|
-
return
|
|
56653
|
+
return import_node_path46.default.join(dataDir, AUTH_FILE_NAME);
|
|
56561
56654
|
}
|
|
56562
56655
|
function loadOrCreateAuthFile(opts) {
|
|
56563
56656
|
const file = authFilePath(opts.dataDir);
|
|
@@ -56589,7 +56682,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
56589
56682
|
}
|
|
56590
56683
|
function readAuthFile(file) {
|
|
56591
56684
|
try {
|
|
56592
|
-
const raw =
|
|
56685
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
56593
56686
|
const parsed = JSON.parse(raw);
|
|
56594
56687
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
56595
56688
|
return null;
|
|
@@ -56609,25 +56702,25 @@ function readAuthFile(file) {
|
|
|
56609
56702
|
}
|
|
56610
56703
|
}
|
|
56611
56704
|
function writeAuthFile(file, content) {
|
|
56612
|
-
|
|
56613
|
-
|
|
56705
|
+
import_node_fs41.default.mkdirSync(import_node_path46.default.dirname(file), { recursive: true });
|
|
56706
|
+
import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
56614
56707
|
try {
|
|
56615
|
-
|
|
56708
|
+
import_node_fs41.default.chmodSync(file, 384);
|
|
56616
56709
|
} catch {
|
|
56617
56710
|
}
|
|
56618
56711
|
}
|
|
56619
56712
|
|
|
56620
56713
|
// src/owner-profile.ts
|
|
56621
|
-
var
|
|
56714
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
56622
56715
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
56623
|
-
var
|
|
56716
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
56624
56717
|
var PROFILE_FILENAME = "profile.json";
|
|
56625
56718
|
function loadOwnerDisplayName(dataDir) {
|
|
56626
56719
|
const fallback = import_node_os15.default.userInfo().username;
|
|
56627
|
-
const profilePath =
|
|
56720
|
+
const profilePath = import_node_path47.default.join(dataDir, PROFILE_FILENAME);
|
|
56628
56721
|
let raw;
|
|
56629
56722
|
try {
|
|
56630
|
-
raw =
|
|
56723
|
+
raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
|
|
56631
56724
|
} catch {
|
|
56632
56725
|
return fallback;
|
|
56633
56726
|
}
|
|
@@ -56650,18 +56743,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
56650
56743
|
}
|
|
56651
56744
|
|
|
56652
56745
|
// src/feishu-auth/owner-identity-store.ts
|
|
56653
|
-
var
|
|
56654
|
-
var
|
|
56746
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
56747
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
56655
56748
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
56656
56749
|
var OwnerIdentityStore = class {
|
|
56657
56750
|
file;
|
|
56658
56751
|
constructor(dataDir) {
|
|
56659
|
-
this.file =
|
|
56752
|
+
this.file = import_node_path48.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
56660
56753
|
}
|
|
56661
56754
|
read() {
|
|
56662
56755
|
let raw;
|
|
56663
56756
|
try {
|
|
56664
|
-
raw =
|
|
56757
|
+
raw = import_node_fs43.default.readFileSync(this.file, "utf8");
|
|
56665
56758
|
} catch {
|
|
56666
56759
|
return null;
|
|
56667
56760
|
}
|
|
@@ -56689,16 +56782,16 @@ var OwnerIdentityStore = class {
|
|
|
56689
56782
|
};
|
|
56690
56783
|
}
|
|
56691
56784
|
write(record) {
|
|
56692
|
-
|
|
56693
|
-
|
|
56785
|
+
import_node_fs43.default.mkdirSync(import_node_path48.default.dirname(this.file), { recursive: true });
|
|
56786
|
+
import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
56694
56787
|
try {
|
|
56695
|
-
|
|
56788
|
+
import_node_fs43.default.chmodSync(this.file, 384);
|
|
56696
56789
|
} catch {
|
|
56697
56790
|
}
|
|
56698
56791
|
}
|
|
56699
56792
|
clear() {
|
|
56700
56793
|
try {
|
|
56701
|
-
|
|
56794
|
+
import_node_fs43.default.unlinkSync(this.file);
|
|
56702
56795
|
} catch (err) {
|
|
56703
56796
|
const code = err?.code;
|
|
56704
56797
|
if (code !== "ENOENT") throw err;
|
|
@@ -56835,9 +56928,9 @@ var CentralClientError = class extends Error {
|
|
|
56835
56928
|
code;
|
|
56836
56929
|
cause;
|
|
56837
56930
|
};
|
|
56838
|
-
async function centralRequest(opts,
|
|
56931
|
+
async function centralRequest(opts, path79, init) {
|
|
56839
56932
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
56840
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
56933
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path79}`;
|
|
56841
56934
|
const ctrl = new AbortController();
|
|
56842
56935
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
56843
56936
|
let res;
|
|
@@ -57031,8 +57124,8 @@ function verifyConnectToken(args) {
|
|
|
57031
57124
|
}
|
|
57032
57125
|
|
|
57033
57126
|
// src/feishu-auth/server-key.ts
|
|
57034
|
-
var
|
|
57035
|
-
var
|
|
57127
|
+
var fs53 = __toESM(require("fs"), 1);
|
|
57128
|
+
var path57 = __toESM(require("path"), 1);
|
|
57036
57129
|
var FILE_NAME2 = "server-signing-key.json";
|
|
57037
57130
|
var ServerKeyStore = class {
|
|
57038
57131
|
constructor(dataDir) {
|
|
@@ -57040,12 +57133,12 @@ var ServerKeyStore = class {
|
|
|
57040
57133
|
}
|
|
57041
57134
|
dataDir;
|
|
57042
57135
|
filePath() {
|
|
57043
|
-
return
|
|
57136
|
+
return path57.join(this.dataDir, FILE_NAME2);
|
|
57044
57137
|
}
|
|
57045
57138
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
57046
57139
|
read() {
|
|
57047
57140
|
try {
|
|
57048
|
-
const raw =
|
|
57141
|
+
const raw = fs53.readFileSync(this.filePath(), "utf8");
|
|
57049
57142
|
const parsed = JSON.parse(raw);
|
|
57050
57143
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
57051
57144
|
return parsed.publicKeyPem;
|
|
@@ -57060,12 +57153,12 @@ var ServerKeyStore = class {
|
|
|
57060
57153
|
publicKeyPem,
|
|
57061
57154
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
57062
57155
|
};
|
|
57063
|
-
|
|
57064
|
-
|
|
57156
|
+
fs53.mkdirSync(this.dataDir, { recursive: true });
|
|
57157
|
+
fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
57065
57158
|
}
|
|
57066
57159
|
clear() {
|
|
57067
57160
|
try {
|
|
57068
|
-
|
|
57161
|
+
fs53.unlinkSync(this.filePath());
|
|
57069
57162
|
} catch {
|
|
57070
57163
|
}
|
|
57071
57164
|
}
|
|
@@ -57078,12 +57171,12 @@ init_protocol();
|
|
|
57078
57171
|
init_protocol();
|
|
57079
57172
|
|
|
57080
57173
|
// src/session/fork.ts
|
|
57081
|
-
var
|
|
57174
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
57082
57175
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
57083
|
-
var
|
|
57176
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
57084
57177
|
init_claude_history();
|
|
57085
57178
|
function readJsonlEntries(file) {
|
|
57086
|
-
const raw =
|
|
57179
|
+
const raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
57087
57180
|
const out = [];
|
|
57088
57181
|
for (const line of raw.split("\n")) {
|
|
57089
57182
|
const t = line.trim();
|
|
@@ -57096,19 +57189,19 @@ function readJsonlEntries(file) {
|
|
|
57096
57189
|
return out;
|
|
57097
57190
|
}
|
|
57098
57191
|
function forkSession(input) {
|
|
57099
|
-
const baseDir = input.baseDir ??
|
|
57100
|
-
let projectDir =
|
|
57101
|
-
let sourceFile =
|
|
57102
|
-
if (!
|
|
57192
|
+
const baseDir = input.baseDir ?? import_node_path49.default.join(import_node_os16.default.homedir(), ".claude");
|
|
57193
|
+
let projectDir = import_node_path49.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
57194
|
+
let sourceFile = import_node_path49.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
57195
|
+
if (!import_node_fs44.default.existsSync(sourceFile)) {
|
|
57103
57196
|
const found = findTranscriptByToolSessionId(
|
|
57104
|
-
|
|
57197
|
+
import_node_path49.default.join(baseDir, "projects"),
|
|
57105
57198
|
input.toolSessionId
|
|
57106
57199
|
);
|
|
57107
57200
|
if (!found) {
|
|
57108
57201
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
57109
57202
|
}
|
|
57110
57203
|
sourceFile = found;
|
|
57111
|
-
projectDir =
|
|
57204
|
+
projectDir = import_node_path49.default.dirname(found);
|
|
57112
57205
|
}
|
|
57113
57206
|
const entries = readJsonlEntries(sourceFile);
|
|
57114
57207
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -57137,10 +57230,10 @@ function forkSession(input) {
|
|
|
57137
57230
|
}
|
|
57138
57231
|
forkedLines.push(JSON.stringify(forked));
|
|
57139
57232
|
}
|
|
57140
|
-
const outDir = input.targetCwd ?
|
|
57141
|
-
const forkedFilePath =
|
|
57142
|
-
|
|
57143
|
-
|
|
57233
|
+
const outDir = input.targetCwd ? import_node_path49.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
57234
|
+
const forkedFilePath = import_node_path49.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
57235
|
+
import_node_fs44.default.mkdirSync(outDir, { recursive: true });
|
|
57236
|
+
import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
57144
57237
|
return { forkedToolSessionId, forkedFilePath };
|
|
57145
57238
|
}
|
|
57146
57239
|
|
|
@@ -57599,7 +57692,7 @@ function buildPermissionHandlers(deps) {
|
|
|
57599
57692
|
}
|
|
57600
57693
|
|
|
57601
57694
|
// src/handlers/history.ts
|
|
57602
|
-
var
|
|
57695
|
+
var path60 = __toESM(require("path"), 1);
|
|
57603
57696
|
init_protocol();
|
|
57604
57697
|
|
|
57605
57698
|
// src/session/recent-dirs.ts
|
|
@@ -57617,7 +57710,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
57617
57710
|
}
|
|
57618
57711
|
|
|
57619
57712
|
// src/permission/persona-paths.ts
|
|
57620
|
-
var
|
|
57713
|
+
var path59 = __toESM(require("path"), 1);
|
|
57621
57714
|
function getAllowedPersonaIds(grants, action) {
|
|
57622
57715
|
const ids = /* @__PURE__ */ new Set();
|
|
57623
57716
|
for (const g2 of grants) {
|
|
@@ -57630,42 +57723,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
57630
57723
|
return ids;
|
|
57631
57724
|
}
|
|
57632
57725
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
57633
|
-
const target =
|
|
57726
|
+
const target = path59.resolve(absPath);
|
|
57634
57727
|
if (userWorkDir) {
|
|
57635
|
-
const u =
|
|
57636
|
-
const usep = u.endsWith(
|
|
57728
|
+
const u = path59.resolve(userWorkDir);
|
|
57729
|
+
const usep = u.endsWith(path59.sep) ? "" : path59.sep;
|
|
57637
57730
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
57638
57731
|
}
|
|
57639
|
-
const root =
|
|
57640
|
-
const sep3 = root.endsWith(
|
|
57732
|
+
const root = path59.resolve(personaRoot);
|
|
57733
|
+
const sep3 = root.endsWith(path59.sep) ? "" : path59.sep;
|
|
57641
57734
|
if (!target.startsWith(root + sep3)) return false;
|
|
57642
|
-
const rel =
|
|
57735
|
+
const rel = path59.relative(root, target);
|
|
57643
57736
|
if (!rel || rel.startsWith("..")) return false;
|
|
57644
|
-
const personaId2 = rel.split(
|
|
57737
|
+
const personaId2 = rel.split(path59.sep)[0];
|
|
57645
57738
|
if (!personaId2) return false;
|
|
57646
57739
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
57647
57740
|
if (allowed === "*") return true;
|
|
57648
57741
|
return allowed.has(personaId2);
|
|
57649
57742
|
}
|
|
57650
57743
|
function personaIdFromPath(absPath, personaRoot) {
|
|
57651
|
-
const root =
|
|
57652
|
-
const target =
|
|
57653
|
-
const sep3 = root.endsWith(
|
|
57744
|
+
const root = path59.resolve(personaRoot);
|
|
57745
|
+
const target = path59.resolve(absPath);
|
|
57746
|
+
const sep3 = root.endsWith(path59.sep) ? "" : path59.sep;
|
|
57654
57747
|
if (!target.startsWith(root + sep3)) return null;
|
|
57655
|
-
const rel =
|
|
57748
|
+
const rel = path59.relative(root, target);
|
|
57656
57749
|
if (!rel || rel.startsWith("..")) return null;
|
|
57657
|
-
const id = rel.split(
|
|
57750
|
+
const id = rel.split(path59.sep)[0];
|
|
57658
57751
|
return id || null;
|
|
57659
57752
|
}
|
|
57660
57753
|
function isPathWithin(dir, absPath) {
|
|
57661
|
-
const d =
|
|
57662
|
-
const t =
|
|
57663
|
-
const sep3 = d.endsWith(
|
|
57754
|
+
const d = path59.resolve(dir);
|
|
57755
|
+
const t = path59.resolve(absPath);
|
|
57756
|
+
const sep3 = d.endsWith(path59.sep) ? "" : path59.sep;
|
|
57664
57757
|
return t === d || t.startsWith(d + sep3);
|
|
57665
57758
|
}
|
|
57666
57759
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
57667
57760
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
57668
|
-
return personaIdFromPath(
|
|
57761
|
+
return personaIdFromPath(path59.resolve(absPath), personaRoot) === personaId2;
|
|
57669
57762
|
}
|
|
57670
57763
|
|
|
57671
57764
|
// src/handlers/history.ts
|
|
@@ -57717,7 +57810,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57717
57810
|
if (!pid) return false;
|
|
57718
57811
|
return isGuestPathAllowed(
|
|
57719
57812
|
ctx.grants,
|
|
57720
|
-
|
|
57813
|
+
path60.join(personaRoot, pid),
|
|
57721
57814
|
personaRoot,
|
|
57722
57815
|
"read",
|
|
57723
57816
|
userWorkDir
|
|
@@ -57729,7 +57822,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57729
57822
|
};
|
|
57730
57823
|
const list = async (frame, _client, ctx) => {
|
|
57731
57824
|
const args = HistoryListArgs.parse(frame);
|
|
57732
|
-
assertGuestPath(ctx,
|
|
57825
|
+
assertGuestPath(ctx, path60.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
57733
57826
|
const sessions = await history.listSessions(args);
|
|
57734
57827
|
return { response: { type: "history:list", sessions } };
|
|
57735
57828
|
};
|
|
@@ -57773,14 +57866,14 @@ function buildHistoryHandlers(deps) {
|
|
|
57773
57866
|
};
|
|
57774
57867
|
const subagents = async (frame, _client, ctx) => {
|
|
57775
57868
|
const args = HistorySubagentsArgs.parse(frame);
|
|
57776
|
-
assertGuestPath(ctx,
|
|
57869
|
+
assertGuestPath(ctx, path60.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
57777
57870
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
57778
57871
|
const subs = await history.listSubagents(args);
|
|
57779
57872
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
57780
57873
|
};
|
|
57781
57874
|
const subagentRead = async (frame, _client, ctx) => {
|
|
57782
57875
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
57783
|
-
assertGuestPath(ctx,
|
|
57876
|
+
assertGuestPath(ctx, path60.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
57784
57877
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
57785
57878
|
const res = await history.readSubagent(args);
|
|
57786
57879
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -57790,7 +57883,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57790
57883
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
57791
57884
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
57792
57885
|
const filtered = dirs.filter(
|
|
57793
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
57886
|
+
(d) => isGuestPathAllowed(ctx.grants, path60.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
57794
57887
|
);
|
|
57795
57888
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
57796
57889
|
}
|
|
@@ -57807,7 +57900,7 @@ function buildHistoryHandlers(deps) {
|
|
|
57807
57900
|
}
|
|
57808
57901
|
|
|
57809
57902
|
// src/handlers/workspace.ts
|
|
57810
|
-
var
|
|
57903
|
+
var path61 = __toESM(require("path"), 1);
|
|
57811
57904
|
var os16 = __toESM(require("os"), 1);
|
|
57812
57905
|
init_protocol();
|
|
57813
57906
|
init_protocol();
|
|
@@ -57849,22 +57942,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57849
57942
|
const args = WorkspaceListArgs.parse(frame);
|
|
57850
57943
|
const isGuest = ctx?.principal.kind === "guest";
|
|
57851
57944
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
57852
|
-
const resolvedCwd =
|
|
57853
|
-
const target = args.path ?
|
|
57945
|
+
const resolvedCwd = path61.resolve(args.cwd ?? fallbackCwd);
|
|
57946
|
+
const target = args.path ? path61.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
57854
57947
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
57855
57948
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
57856
57949
|
return { response: { type: "workspace:list", ...res } };
|
|
57857
57950
|
};
|
|
57858
57951
|
const read = async (frame, _client, ctx) => {
|
|
57859
57952
|
const args = WorkspaceReadArgs.parse(frame);
|
|
57860
|
-
const target =
|
|
57953
|
+
const target = path61.isAbsolute(args.path) ? path61.resolve(args.path) : path61.resolve(args.cwd, args.path);
|
|
57861
57954
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
57862
57955
|
const res = workspace.read(args);
|
|
57863
57956
|
return { response: { type: "workspace:read", ...res } };
|
|
57864
57957
|
};
|
|
57865
57958
|
const skillsList = async (frame, _client, ctx) => {
|
|
57866
57959
|
const args = SkillsListArgs.parse(frame);
|
|
57867
|
-
const cwdAbs =
|
|
57960
|
+
const cwdAbs = path61.resolve(args.cwd);
|
|
57868
57961
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
57869
57962
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
57870
57963
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -57876,7 +57969,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57876
57969
|
};
|
|
57877
57970
|
const agentsList = async (frame, _client, ctx) => {
|
|
57878
57971
|
const args = AgentsListArgs.parse(frame);
|
|
57879
|
-
const cwdAbs =
|
|
57972
|
+
const cwdAbs = path61.resolve(args.cwd);
|
|
57880
57973
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
57881
57974
|
if (args.tool === "codex") {
|
|
57882
57975
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -57898,20 +57991,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
57898
57991
|
}
|
|
57899
57992
|
|
|
57900
57993
|
// src/handlers/git.ts
|
|
57901
|
-
var
|
|
57994
|
+
var path63 = __toESM(require("path"), 1);
|
|
57902
57995
|
init_protocol();
|
|
57903
57996
|
init_protocol();
|
|
57904
57997
|
|
|
57905
57998
|
// src/workspace/git.ts
|
|
57906
57999
|
var import_node_child_process10 = require("child_process");
|
|
57907
|
-
var
|
|
57908
|
-
var
|
|
58000
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
58001
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
57909
58002
|
var import_node_util = require("util");
|
|
57910
58003
|
var pexec = (0, import_node_util.promisify)(import_node_child_process10.execFile);
|
|
57911
58004
|
function normalizePath(p2) {
|
|
57912
|
-
const resolved =
|
|
58005
|
+
const resolved = import_node_path50.default.resolve(p2);
|
|
57913
58006
|
try {
|
|
57914
|
-
return
|
|
58007
|
+
return import_node_fs45.default.realpathSync(resolved);
|
|
57915
58008
|
} catch {
|
|
57916
58009
|
return resolved;
|
|
57917
58010
|
}
|
|
@@ -57985,7 +58078,7 @@ async function listGitBranches(cwd) {
|
|
|
57985
58078
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
57986
58079
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
57987
58080
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
57988
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
58081
|
+
if (!isGuestPathAllowed(ctx.grants, path63.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
57989
58082
|
throw new ClawdError(
|
|
57990
58083
|
ERROR_CODES.UNAUTHORIZED,
|
|
57991
58084
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -58850,21 +58943,21 @@ function computeMethodAccess(args) {
|
|
|
58850
58943
|
}
|
|
58851
58944
|
|
|
58852
58945
|
// src/version.ts
|
|
58853
|
-
var version = "0.2.
|
|
58946
|
+
var version = "0.2.294".length > 0 ? "0.2.294" : "dev";
|
|
58854
58947
|
|
|
58855
58948
|
// src/cli-probe/probe.ts
|
|
58856
|
-
var
|
|
58857
|
-
var
|
|
58949
|
+
var fs56 = __toESM(require("fs"), 1);
|
|
58950
|
+
var path64 = __toESM(require("path"), 1);
|
|
58858
58951
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
58859
58952
|
var BIN_NAME = "clawd";
|
|
58860
58953
|
var MAX_PARENT_HOPS = 5;
|
|
58861
58954
|
function probeGlobalCli(pathEnv) {
|
|
58862
58955
|
if (!pathEnv) return null;
|
|
58863
|
-
for (const dir of pathEnv.split(
|
|
58956
|
+
for (const dir of pathEnv.split(path64.delimiter)) {
|
|
58864
58957
|
if (!dir) continue;
|
|
58865
58958
|
let real;
|
|
58866
58959
|
try {
|
|
58867
|
-
real =
|
|
58960
|
+
real = fs56.realpathSync(path64.join(dir, BIN_NAME));
|
|
58868
58961
|
} catch {
|
|
58869
58962
|
continue;
|
|
58870
58963
|
}
|
|
@@ -58874,15 +58967,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
58874
58967
|
return null;
|
|
58875
58968
|
}
|
|
58876
58969
|
function readOwnPackageVersion(entryPath) {
|
|
58877
|
-
let dir =
|
|
58970
|
+
let dir = path64.dirname(entryPath);
|
|
58878
58971
|
for (let i = 0; i < MAX_PARENT_HOPS; i++) {
|
|
58879
58972
|
try {
|
|
58880
|
-
const raw =
|
|
58973
|
+
const raw = fs56.readFileSync(path64.join(dir, "package.json"), "utf8");
|
|
58881
58974
|
const pkg = JSON.parse(raw);
|
|
58882
58975
|
if (pkg.name !== PKG_NAME) return null;
|
|
58883
58976
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
58884
58977
|
} catch {
|
|
58885
|
-
const parent =
|
|
58978
|
+
const parent = path64.dirname(dir);
|
|
58886
58979
|
if (parent === dir) return null;
|
|
58887
58980
|
dir = parent;
|
|
58888
58981
|
}
|
|
@@ -59040,7 +59133,7 @@ function buildPersonaHandlers(deps) {
|
|
|
59040
59133
|
}
|
|
59041
59134
|
|
|
59042
59135
|
// src/handlers/attachment.ts
|
|
59043
|
-
var
|
|
59136
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
59044
59137
|
init_protocol();
|
|
59045
59138
|
init_protocol();
|
|
59046
59139
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -59120,12 +59213,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
59120
59213
|
`session ${args.sessionId} scope unresolved`
|
|
59121
59214
|
);
|
|
59122
59215
|
}
|
|
59123
|
-
const cwdAbs =
|
|
59124
|
-
const candidateAbs =
|
|
59216
|
+
const cwdAbs = import_node_path51.default.resolve(sessionFile.cwd);
|
|
59217
|
+
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
59218
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
59126
59219
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
59127
59220
|
const entry = entries.find((e) => {
|
|
59128
|
-
const storedAbs =
|
|
59221
|
+
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
59222
|
return storedAbs === candidateAbs && !e.stale;
|
|
59130
59223
|
});
|
|
59131
59224
|
if (!entry) {
|
|
@@ -59150,7 +59243,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
59150
59243
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
59151
59244
|
const f = deps.sessionStore.read(sessionId);
|
|
59152
59245
|
if (!f) return;
|
|
59153
|
-
assertGuestAttachmentPath(ctx,
|
|
59246
|
+
assertGuestAttachmentPath(ctx, import_node_path51.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
59154
59247
|
}
|
|
59155
59248
|
const groupAdd = async (frame, _client, ctx) => {
|
|
59156
59249
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -59165,8 +59258,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
59165
59258
|
if (!scope) {
|
|
59166
59259
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
59167
59260
|
}
|
|
59168
|
-
const cwdAbs =
|
|
59169
|
-
const candidateAbs =
|
|
59261
|
+
const cwdAbs = import_node_path51.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
59262
|
+
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
59263
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
59171
59264
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
59172
59265
|
const size = 0;
|
|
@@ -59225,19 +59318,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
59225
59318
|
|
|
59226
59319
|
// src/handlers/extension.ts
|
|
59227
59320
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
59228
|
-
var
|
|
59321
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
59229
59322
|
init_protocol();
|
|
59230
59323
|
|
|
59231
59324
|
// src/extension/bundle-zip.ts
|
|
59232
59325
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
59233
|
-
var
|
|
59326
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
59234
59327
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
59235
59328
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
59236
59329
|
async function bundleExtensionDir(dir) {
|
|
59237
59330
|
const entries = await listFilesSorted(dir);
|
|
59238
59331
|
const zip = new import_jszip2.default();
|
|
59239
59332
|
for (const rel of entries) {
|
|
59240
|
-
const abs =
|
|
59333
|
+
const abs = import_node_path52.default.join(dir, rel);
|
|
59241
59334
|
const content = await import_promises6.default.readFile(abs);
|
|
59242
59335
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
59243
59336
|
}
|
|
@@ -59258,7 +59351,7 @@ async function listFilesSorted(rootDir) {
|
|
|
59258
59351
|
return out;
|
|
59259
59352
|
}
|
|
59260
59353
|
async function walk(absRoot, relPrefix, out) {
|
|
59261
|
-
const dirAbs =
|
|
59354
|
+
const dirAbs = import_node_path52.default.join(absRoot, relPrefix);
|
|
59262
59355
|
const entries = await import_promises6.default.readdir(dirAbs, { withFileTypes: true });
|
|
59263
59356
|
for (const e of entries) {
|
|
59264
59357
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -59312,25 +59405,25 @@ function computePublishCheck(args) {
|
|
|
59312
59405
|
|
|
59313
59406
|
// src/extension/install-flow.ts
|
|
59314
59407
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
59315
|
-
var
|
|
59408
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
59316
59409
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
59317
59410
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
59318
59411
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
59319
59412
|
|
|
59320
59413
|
// src/extension/paths.ts
|
|
59321
59414
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
59322
|
-
var
|
|
59415
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
59323
59416
|
function clawdHomeRoot(override) {
|
|
59324
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
59417
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path53.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
59325
59418
|
}
|
|
59326
59419
|
function extensionsRoot(override) {
|
|
59327
|
-
return
|
|
59420
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extensions");
|
|
59328
59421
|
}
|
|
59329
59422
|
function publishedChannelsFile(override) {
|
|
59330
|
-
return
|
|
59423
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
59331
59424
|
}
|
|
59332
59425
|
function bundleCacheRoot(override) {
|
|
59333
|
-
return
|
|
59426
|
+
return import_node_path53.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
59334
59427
|
}
|
|
59335
59428
|
|
|
59336
59429
|
// src/extension/install-flow.ts
|
|
@@ -59357,7 +59450,7 @@ async function installFromChannel(args, deps) {
|
|
|
59357
59450
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
59358
59451
|
}
|
|
59359
59452
|
for (const name of Object.keys(zip.files)) {
|
|
59360
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
59453
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path54.default.isAbsolute(name)) {
|
|
59361
59454
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
59362
59455
|
}
|
|
59363
59456
|
}
|
|
@@ -59389,7 +59482,7 @@ async function installFromChannel(args, deps) {
|
|
|
59389
59482
|
);
|
|
59390
59483
|
}
|
|
59391
59484
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
59392
|
-
const destDir =
|
|
59485
|
+
const destDir = import_node_path54.default.join(deps.extensionsRoot, localExtId);
|
|
59393
59486
|
let destExists = false;
|
|
59394
59487
|
try {
|
|
59395
59488
|
await import_promises7.default.access(destDir);
|
|
@@ -59403,16 +59496,16 @@ async function installFromChannel(args, deps) {
|
|
|
59403
59496
|
);
|
|
59404
59497
|
}
|
|
59405
59498
|
const stage = await import_promises7.default.mkdtemp(
|
|
59406
|
-
|
|
59499
|
+
import_node_path54.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
59407
59500
|
);
|
|
59408
59501
|
try {
|
|
59409
59502
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
59410
|
-
const dest =
|
|
59503
|
+
const dest = import_node_path54.default.join(stage, name);
|
|
59411
59504
|
if (entry.dir) {
|
|
59412
59505
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
59413
59506
|
continue;
|
|
59414
59507
|
}
|
|
59415
|
-
await import_promises7.default.mkdir(
|
|
59508
|
+
await import_promises7.default.mkdir(import_node_path54.default.dirname(dest), { recursive: true });
|
|
59416
59509
|
if (name === "manifest.json") {
|
|
59417
59510
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
59418
59511
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -59433,7 +59526,7 @@ async function installFromChannel(args, deps) {
|
|
|
59433
59526
|
|
|
59434
59527
|
// src/extension/update-flow.ts
|
|
59435
59528
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
59436
|
-
var
|
|
59529
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
59437
59530
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
59438
59531
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
59439
59532
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -59450,11 +59543,11 @@ async function updateFromChannel(args, deps) {
|
|
|
59450
59543
|
channelRef.extId,
|
|
59451
59544
|
channelRef.ownerPrincipalId
|
|
59452
59545
|
);
|
|
59453
|
-
const liveDir =
|
|
59546
|
+
const liveDir = import_node_path55.default.join(deps.extensionsRoot, localExtId);
|
|
59454
59547
|
const prevDir = `${liveDir}.prev`;
|
|
59455
59548
|
let existingVersion;
|
|
59456
59549
|
try {
|
|
59457
|
-
const raw = await import_promises8.default.readFile(
|
|
59550
|
+
const raw = await import_promises8.default.readFile(import_node_path55.default.join(liveDir, "manifest.json"), "utf8");
|
|
59458
59551
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
59459
59552
|
if (!parsed2.success) {
|
|
59460
59553
|
throw new UpdateError(
|
|
@@ -59487,7 +59580,7 @@ async function updateFromChannel(args, deps) {
|
|
|
59487
59580
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
59488
59581
|
}
|
|
59489
59582
|
for (const name of Object.keys(zip.files)) {
|
|
59490
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
59583
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path55.default.isAbsolute(name)) {
|
|
59491
59584
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
59492
59585
|
}
|
|
59493
59586
|
}
|
|
@@ -59522,16 +59615,16 @@ async function updateFromChannel(args, deps) {
|
|
|
59522
59615
|
await import_promises8.default.rm(prevDir, { recursive: true, force: true });
|
|
59523
59616
|
await import_promises8.default.rename(liveDir, prevDir);
|
|
59524
59617
|
const stage = await import_promises8.default.mkdtemp(
|
|
59525
|
-
|
|
59618
|
+
import_node_path55.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
59526
59619
|
);
|
|
59527
59620
|
try {
|
|
59528
59621
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
59529
|
-
const dest =
|
|
59622
|
+
const dest = import_node_path55.default.join(stage, name);
|
|
59530
59623
|
if (entry.dir) {
|
|
59531
59624
|
await import_promises8.default.mkdir(dest, { recursive: true });
|
|
59532
59625
|
continue;
|
|
59533
59626
|
}
|
|
59534
|
-
await import_promises8.default.mkdir(
|
|
59627
|
+
await import_promises8.default.mkdir(import_node_path55.default.dirname(dest), { recursive: true });
|
|
59535
59628
|
if (name === "manifest.json") {
|
|
59536
59629
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
59537
59630
|
await import_promises8.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -59598,7 +59691,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
59598
59691
|
);
|
|
59599
59692
|
}
|
|
59600
59693
|
}
|
|
59601
|
-
const manifestPath =
|
|
59694
|
+
const manifestPath = import_node_path56.default.join(root, extId, "manifest.json");
|
|
59602
59695
|
const manifest = await readManifest(root, extId);
|
|
59603
59696
|
const next = { ...manifest, version: newVersion };
|
|
59604
59697
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -59606,7 +59699,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
59606
59699
|
await import_promises9.default.rename(tmp, manifestPath);
|
|
59607
59700
|
}
|
|
59608
59701
|
async function readManifest(root, extId) {
|
|
59609
|
-
const file =
|
|
59702
|
+
const file = import_node_path56.default.join(root, extId, "manifest.json");
|
|
59610
59703
|
let raw;
|
|
59611
59704
|
try {
|
|
59612
59705
|
raw = await import_promises9.default.readFile(file, "utf8");
|
|
@@ -59690,7 +59783,7 @@ function buildExtensionHandlers(deps) {
|
|
|
59690
59783
|
};
|
|
59691
59784
|
async function buildSnapshotMeta(extId) {
|
|
59692
59785
|
const manifest = await readManifest(deps.root, extId);
|
|
59693
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
59786
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path56.default.join(deps.root, extId));
|
|
59694
59787
|
return { manifest, contentHash: sha256, buffer };
|
|
59695
59788
|
}
|
|
59696
59789
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -59865,9 +59958,9 @@ function buildExtensionHandlers(deps) {
|
|
|
59865
59958
|
}
|
|
59866
59959
|
|
|
59867
59960
|
// src/app-builder/project-store.ts
|
|
59868
|
-
var
|
|
59961
|
+
var import_node_fs46 = require("fs");
|
|
59869
59962
|
var import_node_child_process11 = require("child_process");
|
|
59870
|
-
var
|
|
59963
|
+
var import_node_path57 = require("path");
|
|
59871
59964
|
init_protocol();
|
|
59872
59965
|
var PROJECTS_DIR = "projects";
|
|
59873
59966
|
var META_FILE = ".clawd-project.json";
|
|
@@ -59881,19 +59974,19 @@ var ProjectStore = class {
|
|
|
59881
59974
|
root;
|
|
59882
59975
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
59883
59976
|
metaPath(name) {
|
|
59884
|
-
return (0,
|
|
59977
|
+
return (0, import_node_path57.join)(this.projectsRoot(), name, META_FILE);
|
|
59885
59978
|
}
|
|
59886
59979
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
59887
59980
|
projectDir(name) {
|
|
59888
|
-
return (0,
|
|
59981
|
+
return (0, import_node_path57.join)(this.projectsRoot(), name);
|
|
59889
59982
|
}
|
|
59890
59983
|
projectsRoot() {
|
|
59891
|
-
return (0,
|
|
59984
|
+
return (0, import_node_path57.join)(this.root, PROJECTS_DIR);
|
|
59892
59985
|
}
|
|
59893
59986
|
async list() {
|
|
59894
59987
|
let entries;
|
|
59895
59988
|
try {
|
|
59896
|
-
entries = await
|
|
59989
|
+
entries = await import_node_fs46.promises.readdir(this.projectsRoot());
|
|
59897
59990
|
} catch (err) {
|
|
59898
59991
|
if (err.code === "ENOENT") return [];
|
|
59899
59992
|
throw err;
|
|
@@ -59901,7 +59994,7 @@ var ProjectStore = class {
|
|
|
59901
59994
|
const out = [];
|
|
59902
59995
|
for (const name of entries) {
|
|
59903
59996
|
try {
|
|
59904
|
-
const raw = await
|
|
59997
|
+
const raw = await import_node_fs46.promises.readFile(this.metaPath(name), "utf8");
|
|
59905
59998
|
const json = JSON.parse(raw);
|
|
59906
59999
|
let migrated = false;
|
|
59907
60000
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -59912,7 +60005,7 @@ var ProjectStore = class {
|
|
|
59912
60005
|
if (parsed.success) {
|
|
59913
60006
|
out.push(parsed.data);
|
|
59914
60007
|
if (migrated) {
|
|
59915
|
-
void
|
|
60008
|
+
void import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
59916
60009
|
});
|
|
59917
60010
|
}
|
|
59918
60011
|
}
|
|
@@ -59956,8 +60049,8 @@ var ProjectStore = class {
|
|
|
59956
60049
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
59957
60050
|
}
|
|
59958
60051
|
const dir = this.projectDir(name);
|
|
59959
|
-
await
|
|
59960
|
-
await
|
|
60052
|
+
await import_node_fs46.promises.mkdir(dir, { recursive: true });
|
|
60053
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
59961
60054
|
return meta;
|
|
59962
60055
|
}
|
|
59963
60056
|
/**
|
|
@@ -60000,7 +60093,7 @@ var ProjectStore = class {
|
|
|
60000
60093
|
}
|
|
60001
60094
|
async delete(name) {
|
|
60002
60095
|
const dir = this.projectDir(name);
|
|
60003
|
-
await
|
|
60096
|
+
await import_node_fs46.promises.rm(dir, { recursive: true, force: true });
|
|
60004
60097
|
}
|
|
60005
60098
|
async updatePort(name, newPort) {
|
|
60006
60099
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -60016,7 +60109,7 @@ var ProjectStore = class {
|
|
|
60016
60109
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
60017
60110
|
}
|
|
60018
60111
|
const updated = { ...target, port: newPort };
|
|
60019
|
-
await
|
|
60112
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
60020
60113
|
return updated;
|
|
60021
60114
|
}
|
|
60022
60115
|
/**
|
|
@@ -60033,7 +60126,7 @@ var ProjectStore = class {
|
|
|
60033
60126
|
if (!validated.success) {
|
|
60034
60127
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
60035
60128
|
}
|
|
60036
|
-
await
|
|
60129
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60037
60130
|
return validated.data;
|
|
60038
60131
|
}
|
|
60039
60132
|
/**
|
|
@@ -60054,7 +60147,7 @@ var ProjectStore = class {
|
|
|
60054
60147
|
if (!validated.success) {
|
|
60055
60148
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
60056
60149
|
}
|
|
60057
|
-
await
|
|
60150
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60058
60151
|
return validated.data;
|
|
60059
60152
|
}
|
|
60060
60153
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -60069,7 +60162,7 @@ var ProjectStore = class {
|
|
|
60069
60162
|
if (!validated.success) {
|
|
60070
60163
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
60071
60164
|
}
|
|
60072
|
-
await
|
|
60165
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
60073
60166
|
return validated.data;
|
|
60074
60167
|
}
|
|
60075
60168
|
};
|
|
@@ -60190,8 +60283,8 @@ var PublishJobRegistry = class {
|
|
|
60190
60283
|
|
|
60191
60284
|
// src/app-builder/publish-job-runner.ts
|
|
60192
60285
|
var import_node_child_process13 = require("child_process");
|
|
60193
|
-
var
|
|
60194
|
-
var
|
|
60286
|
+
var import_node_fs47 = require("fs");
|
|
60287
|
+
var import_node_path58 = require("path");
|
|
60195
60288
|
|
|
60196
60289
|
// src/app-builder/publish-stage-parser.ts
|
|
60197
60290
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -60223,10 +60316,10 @@ async function startPublishJob(deps, args) {
|
|
|
60223
60316
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
60224
60317
|
}
|
|
60225
60318
|
const projDir = projectDir(args.name);
|
|
60226
|
-
const logPath = (0,
|
|
60319
|
+
const logPath = (0, import_node_path58.join)(projDir, ".publish.log");
|
|
60227
60320
|
let logStream = null;
|
|
60228
60321
|
try {
|
|
60229
|
-
logStream = (0,
|
|
60322
|
+
logStream = (0, import_node_fs47.createWriteStream)(logPath, { flags: "w" });
|
|
60230
60323
|
} catch {
|
|
60231
60324
|
logStream = null;
|
|
60232
60325
|
}
|
|
@@ -60483,8 +60576,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
60483
60576
|
|
|
60484
60577
|
// src/handlers/app-builder.ts
|
|
60485
60578
|
init_protocol();
|
|
60486
|
-
var
|
|
60487
|
-
var
|
|
60579
|
+
var import_node_path59 = require("path");
|
|
60580
|
+
var import_node_fs48 = require("fs");
|
|
60488
60581
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
60489
60582
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
60490
60583
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -60565,7 +60658,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60565
60658
|
async function listAllUsersProjects() {
|
|
60566
60659
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
60567
60660
|
const getStore = deps.getStore;
|
|
60568
|
-
const userIds = await
|
|
60661
|
+
const userIds = await import_node_fs48.promises.readdir(deps.usersRoot).catch(() => []);
|
|
60569
60662
|
const perUser = await Promise.all(
|
|
60570
60663
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
60571
60664
|
);
|
|
@@ -60634,8 +60727,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60634
60727
|
const project = await userStore.create(f.name, reservedPorts);
|
|
60635
60728
|
try {
|
|
60636
60729
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
60637
|
-
const templateSrcDir = (0,
|
|
60638
|
-
const scaffoldScript = (0,
|
|
60730
|
+
const templateSrcDir = (0, import_node_path59.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
60731
|
+
const scaffoldScript = (0, import_node_path59.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
60639
60732
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
60640
60733
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
60641
60734
|
name: project.name,
|
|
@@ -60839,7 +60932,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
60839
60932
|
await userStore.clearPublishJob(args.name);
|
|
60840
60933
|
}
|
|
60841
60934
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
60842
|
-
const scriptPath = (0,
|
|
60935
|
+
const scriptPath = (0, import_node_path59.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
60843
60936
|
deps.logger?.info("app-builder.publish.start", {
|
|
60844
60937
|
name: args.name,
|
|
60845
60938
|
sessionId: boundSession.sessionId,
|
|
@@ -61015,7 +61108,7 @@ function buildVisitorHandlers(deps) {
|
|
|
61015
61108
|
|
|
61016
61109
|
// src/extension/registry.ts
|
|
61017
61110
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
61018
|
-
var
|
|
61111
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
61019
61112
|
async function loadAll(root) {
|
|
61020
61113
|
let entries;
|
|
61021
61114
|
try {
|
|
@@ -61028,13 +61121,13 @@ async function loadAll(root) {
|
|
|
61028
61121
|
for (const ent of entries) {
|
|
61029
61122
|
if (!ent.isDirectory()) continue;
|
|
61030
61123
|
if (ent.name.startsWith(".")) continue;
|
|
61031
|
-
records.push(await loadOne(
|
|
61124
|
+
records.push(await loadOne(import_node_path60.default.join(root, ent.name), ent.name));
|
|
61032
61125
|
}
|
|
61033
61126
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
61034
61127
|
return records;
|
|
61035
61128
|
}
|
|
61036
61129
|
async function loadOne(dir, dirName) {
|
|
61037
|
-
const manifestPath =
|
|
61130
|
+
const manifestPath = import_node_path60.default.join(dir, "manifest.json");
|
|
61038
61131
|
let raw;
|
|
61039
61132
|
try {
|
|
61040
61133
|
raw = await import_promises10.default.readFile(manifestPath, "utf8");
|
|
@@ -61079,7 +61172,7 @@ async function loadOne(dir, dirName) {
|
|
|
61079
61172
|
|
|
61080
61173
|
// src/extension/uninstall.ts
|
|
61081
61174
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
61082
|
-
var
|
|
61175
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
61083
61176
|
var UninstallError = class extends Error {
|
|
61084
61177
|
constructor(code, message) {
|
|
61085
61178
|
super(message);
|
|
@@ -61088,7 +61181,7 @@ var UninstallError = class extends Error {
|
|
|
61088
61181
|
code;
|
|
61089
61182
|
};
|
|
61090
61183
|
async function uninstall(deps) {
|
|
61091
|
-
const dir =
|
|
61184
|
+
const dir = import_node_path61.default.join(deps.root, deps.extId);
|
|
61092
61185
|
try {
|
|
61093
61186
|
await import_promises11.default.access(dir);
|
|
61094
61187
|
} catch {
|
|
@@ -61618,7 +61711,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
61618
61711
|
|
|
61619
61712
|
// src/extension/runtime.ts
|
|
61620
61713
|
var import_node_child_process16 = require("child_process");
|
|
61621
|
-
var
|
|
61714
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
61622
61715
|
var import_promises12 = require("timers/promises");
|
|
61623
61716
|
|
|
61624
61717
|
// src/extension/port-allocator.ts
|
|
@@ -61719,7 +61812,7 @@ var Runtime = class {
|
|
|
61719
61812
|
/\$CLAWOS_EXT_PORT/g,
|
|
61720
61813
|
String(port)
|
|
61721
61814
|
);
|
|
61722
|
-
const dir =
|
|
61815
|
+
const dir = import_node_path62.default.join(this.root, extId);
|
|
61723
61816
|
const env = {
|
|
61724
61817
|
...process.env,
|
|
61725
61818
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -61831,7 +61924,7 @@ ${handle.stderrTail}`
|
|
|
61831
61924
|
|
|
61832
61925
|
// src/extension/published-channels.ts
|
|
61833
61926
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
61834
|
-
var
|
|
61927
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
61835
61928
|
init_zod();
|
|
61836
61929
|
var PublishedChannelsError = class extends Error {
|
|
61837
61930
|
constructor(code, message) {
|
|
@@ -61930,7 +62023,7 @@ var PublishedChannelStore = class {
|
|
|
61930
62023
|
)
|
|
61931
62024
|
};
|
|
61932
62025
|
const tmp = `${this.filePath}.tmp`;
|
|
61933
|
-
await import_promises13.default.mkdir(
|
|
62026
|
+
await import_promises13.default.mkdir(import_node_path63.default.dirname(this.filePath), { recursive: true });
|
|
61934
62027
|
await import_promises13.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
61935
62028
|
await import_promises13.default.rename(tmp, this.filePath);
|
|
61936
62029
|
}
|
|
@@ -61938,7 +62031,7 @@ var PublishedChannelStore = class {
|
|
|
61938
62031
|
|
|
61939
62032
|
// src/extension/bundle-cache.ts
|
|
61940
62033
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
61941
|
-
var
|
|
62034
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
61942
62035
|
var BundleCache = class {
|
|
61943
62036
|
constructor(rootDir) {
|
|
61944
62037
|
this.rootDir = rootDir;
|
|
@@ -61947,14 +62040,14 @@ var BundleCache = class {
|
|
|
61947
62040
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
61948
62041
|
async write(snapshotHash, buffer) {
|
|
61949
62042
|
await import_promises14.default.mkdir(this.rootDir, { recursive: true });
|
|
61950
|
-
const file =
|
|
62043
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61951
62044
|
const tmp = `${file}.tmp`;
|
|
61952
62045
|
await import_promises14.default.writeFile(tmp, buffer, { mode: 384 });
|
|
61953
62046
|
await import_promises14.default.rename(tmp, file);
|
|
61954
62047
|
}
|
|
61955
62048
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
61956
62049
|
async read(snapshotHash) {
|
|
61957
|
-
const file =
|
|
62050
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61958
62051
|
try {
|
|
61959
62052
|
return await import_promises14.default.readFile(file);
|
|
61960
62053
|
} catch (e) {
|
|
@@ -61964,7 +62057,7 @@ var BundleCache = class {
|
|
|
61964
62057
|
}
|
|
61965
62058
|
/** Idempotent — missing file is not an error. */
|
|
61966
62059
|
async delete(snapshotHash) {
|
|
61967
|
-
const file =
|
|
62060
|
+
const file = import_node_path64.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
61968
62061
|
await import_promises14.default.rm(file, { force: true });
|
|
61969
62062
|
}
|
|
61970
62063
|
};
|
|
@@ -61987,24 +62080,24 @@ async function startDaemon(config) {
|
|
|
61987
62080
|
sampling: logShippingCfg.sampling,
|
|
61988
62081
|
homeDir: import_node_os22.default.homedir()
|
|
61989
62082
|
});
|
|
61990
|
-
const logDir =
|
|
61991
|
-
|
|
62083
|
+
const logDir = import_node_path65.default.join(config.dataDir, "log");
|
|
62084
|
+
import_node_fs49.default.mkdirSync(logDir, { recursive: true });
|
|
61992
62085
|
const logger = createLogger({
|
|
61993
62086
|
level: config.logLevel,
|
|
61994
|
-
file:
|
|
62087
|
+
file: import_node_path65.default.join(logDir, "clawd.log"),
|
|
61995
62088
|
logClient
|
|
61996
62089
|
});
|
|
61997
62090
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
61998
62091
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
61999
|
-
file:
|
|
62092
|
+
file: import_node_path65.default.join(logDir, "screen-idle-probe.log"),
|
|
62000
62093
|
level: "debug"
|
|
62001
62094
|
});
|
|
62002
62095
|
logger.info("screen-idle probe logger enabled", {
|
|
62003
|
-
file:
|
|
62096
|
+
file: import_node_path65.default.join(logDir, "screen-idle-probe.log")
|
|
62004
62097
|
});
|
|
62005
62098
|
const CAP_TARGETS = [
|
|
62006
|
-
|
|
62007
|
-
|
|
62099
|
+
import_node_path65.default.join(logDir, "clawd.log"),
|
|
62100
|
+
import_node_path65.default.join(logDir, "screen-idle-probe.log")
|
|
62008
62101
|
];
|
|
62009
62102
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
62010
62103
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -62100,8 +62193,8 @@ async function startDaemon(config) {
|
|
|
62100
62193
|
const agents = new AgentsScanner();
|
|
62101
62194
|
const history = new ClaudeHistoryReader();
|
|
62102
62195
|
let transport = null;
|
|
62103
|
-
const personaStore = new PersonaStore(
|
|
62104
|
-
const usersRoot =
|
|
62196
|
+
const personaStore = new PersonaStore(import_node_path65.default.join(config.dataDir, "personas"));
|
|
62197
|
+
const usersRoot = import_node_path65.default.join(config.dataDir, "users");
|
|
62105
62198
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
62106
62199
|
if (defaultsRoot) {
|
|
62107
62200
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -62123,7 +62216,7 @@ async function startDaemon(config) {
|
|
|
62123
62216
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
62124
62217
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
62125
62218
|
const dispatchStore = createDispatchStore({
|
|
62126
|
-
filePath:
|
|
62219
|
+
filePath: import_node_path65.default.join(config.dataDir, "dispatch.json"),
|
|
62127
62220
|
now: () => Date.now(),
|
|
62128
62221
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
62129
62222
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -62138,18 +62231,18 @@ async function startDaemon(config) {
|
|
|
62138
62231
|
now: () => Date.now(),
|
|
62139
62232
|
onCompleted: (sid) => deliverPendingRef?.(sid)
|
|
62140
62233
|
});
|
|
62141
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
62234
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path65.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
62142
62235
|
const mcpConfigs = [];
|
|
62143
62236
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
62144
62237
|
const dispatchServerCandidates = [
|
|
62145
|
-
|
|
62238
|
+
import_node_path65.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
62146
62239
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
62147
|
-
|
|
62240
|
+
import_node_path65.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
62148
62241
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
62149
62242
|
];
|
|
62150
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
62243
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62151
62244
|
if (dispatchServerScriptPath) {
|
|
62152
|
-
const dispatchLogPath =
|
|
62245
|
+
const dispatchLogPath = import_node_path65.default.join(logDir, "dispatch-mcp-server.log");
|
|
62153
62246
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
62154
62247
|
dataDir: config.dataDir,
|
|
62155
62248
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -62169,12 +62262,12 @@ async function startDaemon(config) {
|
|
|
62169
62262
|
});
|
|
62170
62263
|
}
|
|
62171
62264
|
const ticketServerCandidates = [
|
|
62172
|
-
|
|
62173
|
-
|
|
62265
|
+
import_node_path65.default.join(here, "ticket", "mcp-server.cjs"),
|
|
62266
|
+
import_node_path65.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
62174
62267
|
];
|
|
62175
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
62268
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62176
62269
|
if (ticketServerScriptPath) {
|
|
62177
|
-
const ticketLogPath =
|
|
62270
|
+
const ticketLogPath = import_node_path65.default.join(logDir, "ticket-mcp-server.log");
|
|
62178
62271
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
62179
62272
|
dataDir: config.dataDir,
|
|
62180
62273
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -62196,12 +62289,12 @@ async function startDaemon(config) {
|
|
|
62196
62289
|
});
|
|
62197
62290
|
}
|
|
62198
62291
|
const shiftServerCandidates = [
|
|
62199
|
-
|
|
62200
|
-
|
|
62292
|
+
import_node_path65.default.join(here, "shift", "mcp-server.cjs"),
|
|
62293
|
+
import_node_path65.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
62201
62294
|
];
|
|
62202
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
62295
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62203
62296
|
if (shiftServerScriptPath) {
|
|
62204
|
-
const shiftLogPath =
|
|
62297
|
+
const shiftLogPath = import_node_path65.default.join(logDir, "shift-mcp-server.log");
|
|
62205
62298
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
62206
62299
|
dataDir: config.dataDir,
|
|
62207
62300
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -62222,12 +62315,12 @@ async function startDaemon(config) {
|
|
|
62222
62315
|
);
|
|
62223
62316
|
}
|
|
62224
62317
|
const inboxServerCandidates = [
|
|
62225
|
-
|
|
62226
|
-
|
|
62318
|
+
import_node_path65.default.join(here, "inbox", "mcp-server.cjs"),
|
|
62319
|
+
import_node_path65.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
62227
62320
|
];
|
|
62228
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
62321
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62229
62322
|
if (inboxServerScriptPath) {
|
|
62230
|
-
const inboxLogPath =
|
|
62323
|
+
const inboxLogPath = import_node_path65.default.join(logDir, "inbox-mcp-server.log");
|
|
62231
62324
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
62232
62325
|
dataDir: config.dataDir,
|
|
62233
62326
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -62248,10 +62341,10 @@ async function startDaemon(config) {
|
|
|
62248
62341
|
);
|
|
62249
62342
|
}
|
|
62250
62343
|
const peerOpsServerCandidates = [
|
|
62251
|
-
|
|
62252
|
-
|
|
62344
|
+
import_node_path65.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
62345
|
+
import_node_path65.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
62253
62346
|
];
|
|
62254
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) =>
|
|
62347
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62255
62348
|
if (peerOpsServerScriptPath) {
|
|
62256
62349
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
62257
62350
|
dataDir: config.dataDir,
|
|
@@ -62271,12 +62364,12 @@ async function startDaemon(config) {
|
|
|
62271
62364
|
);
|
|
62272
62365
|
}
|
|
62273
62366
|
const rpcToolServerCandidates = [
|
|
62274
|
-
|
|
62275
|
-
|
|
62367
|
+
import_node_path65.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
62368
|
+
import_node_path65.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
62276
62369
|
];
|
|
62277
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) =>
|
|
62370
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
62278
62371
|
if (rpcToolServerScriptPath) {
|
|
62279
|
-
const rpcToolLogPath =
|
|
62372
|
+
const rpcToolLogPath = import_node_path65.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
62280
62373
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
62281
62374
|
dataDir: config.dataDir,
|
|
62282
62375
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -62297,7 +62390,7 @@ async function startDaemon(config) {
|
|
|
62297
62390
|
);
|
|
62298
62391
|
}
|
|
62299
62392
|
const shiftStore = createShiftStore({
|
|
62300
|
-
filePath:
|
|
62393
|
+
filePath: import_node_path65.default.join(config.dataDir, "shift.json"),
|
|
62301
62394
|
ownerIdProvider: () => ownerPrincipalId,
|
|
62302
62395
|
now: () => Date.now()
|
|
62303
62396
|
});
|
|
@@ -62319,7 +62412,7 @@ async function startDaemon(config) {
|
|
|
62319
62412
|
getAdapter,
|
|
62320
62413
|
historyReader: history,
|
|
62321
62414
|
dataDir: config.dataDir,
|
|
62322
|
-
personaRoot:
|
|
62415
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62323
62416
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
62324
62417
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
62325
62418
|
getPersonaTool: (personaId2) => personaRegistry.get(personaId2)?.tool,
|
|
@@ -62370,10 +62463,10 @@ async function startDaemon(config) {
|
|
|
62370
62463
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
62371
62464
|
attachmentGroup: {
|
|
62372
62465
|
onFileEdit: (input) => {
|
|
62373
|
-
const absPath =
|
|
62466
|
+
const absPath = import_node_path65.default.isAbsolute(input.relPath) ? input.relPath : import_node_path65.default.join(input.cwd, input.relPath);
|
|
62374
62467
|
let size = 0;
|
|
62375
62468
|
try {
|
|
62376
|
-
size =
|
|
62469
|
+
size = import_node_fs49.default.statSync(absPath).size;
|
|
62377
62470
|
} catch (err) {
|
|
62378
62471
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
62379
62472
|
sessionId: input.sessionId,
|
|
@@ -62620,11 +62713,11 @@ async function startDaemon(config) {
|
|
|
62620
62713
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
62621
62714
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
62622
62715
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
62623
|
-
personaRoot:
|
|
62716
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62624
62717
|
usersRoot
|
|
62625
62718
|
},
|
|
62626
62719
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
62627
|
-
personaRoot:
|
|
62720
|
+
personaRoot: import_node_path65.default.join(config.dataDir, "personas"),
|
|
62628
62721
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
62629
62722
|
usersRoot,
|
|
62630
62723
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -62750,11 +62843,11 @@ async function startDaemon(config) {
|
|
|
62750
62843
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
62751
62844
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
62752
62845
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
62753
|
-
appBuilderPersonaRoot:
|
|
62846
|
+
appBuilderPersonaRoot: import_node_path65.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
62754
62847
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
62755
|
-
deployKitRoot:
|
|
62848
|
+
deployKitRoot: import_node_path65.default.join(config.dataDir, "deploy-kit"),
|
|
62756
62849
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
62757
|
-
resolvePersonaRoot: (personaId2) =>
|
|
62850
|
+
resolvePersonaRoot: (personaId2) => import_node_path65.default.join(config.dataDir, "personas", personaId2),
|
|
62758
62851
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
62759
62852
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
62760
62853
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -62857,7 +62950,7 @@ async function startDaemon(config) {
|
|
|
62857
62950
|
});
|
|
62858
62951
|
shiftScheduler.start();
|
|
62859
62952
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
62860
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
62953
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path65.default.join(config.dataDir, "personas"));
|
|
62861
62954
|
const larkBotCloud = createLarkBotCloudClient({
|
|
62862
62955
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
62863
62956
|
apiKey: resolveClawdTicketsApiKey(),
|
|
@@ -62868,6 +62961,9 @@ async function startDaemon(config) {
|
|
|
62868
62961
|
manager,
|
|
62869
62962
|
cloud: larkBotCloud,
|
|
62870
62963
|
store: larkBotStore,
|
|
62964
|
+
fetchResource: (appId, messageId, fileKey, maxBytes) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes),
|
|
62965
|
+
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
62966
|
+
mediaRootFor: (chatId) => import_node_path65.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
62871
62967
|
logger: {
|
|
62872
62968
|
warn: (msg) => logger.warn(msg),
|
|
62873
62969
|
info: (msg) => logger.info(msg)
|
|
@@ -63150,8 +63246,8 @@ async function startDaemon(config) {
|
|
|
63150
63246
|
const lines = [
|
|
63151
63247
|
`Tunnel: ${r.url}`,
|
|
63152
63248
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
63153
|
-
`Frpc config: ${
|
|
63154
|
-
`Frpc log: ${
|
|
63249
|
+
`Frpc config: ${import_node_path65.default.join(config.dataDir, "frpc.toml")}`,
|
|
63250
|
+
`Frpc log: ${import_node_path65.default.join(logDir, "frpc.log")}`
|
|
63155
63251
|
];
|
|
63156
63252
|
const width = Math.max(...lines.map((l) => l.length));
|
|
63157
63253
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -63164,8 +63260,8 @@ ${bar}
|
|
|
63164
63260
|
|
|
63165
63261
|
`);
|
|
63166
63262
|
try {
|
|
63167
|
-
const connectPath =
|
|
63168
|
-
|
|
63263
|
+
const connectPath = import_node_path65.default.join(config.dataDir, "connect.txt");
|
|
63264
|
+
import_node_fs49.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
63169
63265
|
} catch {
|
|
63170
63266
|
}
|
|
63171
63267
|
} catch (err) {
|
|
@@ -63239,9 +63335,9 @@ ${bar}
|
|
|
63239
63335
|
};
|
|
63240
63336
|
}
|
|
63241
63337
|
function migrateDropPersonsDir(dataDir) {
|
|
63242
|
-
const dir =
|
|
63338
|
+
const dir = import_node_path65.default.join(dataDir, "persons");
|
|
63243
63339
|
try {
|
|
63244
|
-
|
|
63340
|
+
import_node_fs49.default.rmSync(dir, { recursive: true, force: true });
|
|
63245
63341
|
} catch {
|
|
63246
63342
|
}
|
|
63247
63343
|
}
|