@clawos-dev/clawd 0.2.250 → 0.2.251
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 +767 -605
- package/dist/dispatch/mcp-server.cjs +99 -24
- package/dist/persona-defaults/persona-app-builder/CLAUDE.md +1 -1
- package/dist/persona-defaults/persona-builder/CLAUDE.md +6 -3
- package/dist/persona-defaults/persona-clawd-helper/CLAUDE.md +3 -3
- package/dist/persona-defaults/persona-feishu-assistant/CLAUDE.md +1 -1
- package/dist/share-ui/assets/{guest-BsIuA95-.js → guest-D6RAMr_5.js} +119 -119
- package/dist/share-ui/guest.html +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -751,8 +751,8 @@ var init_parseUtil = __esm({
|
|
|
751
751
|
init_errors2();
|
|
752
752
|
init_en();
|
|
753
753
|
makeIssue = (params) => {
|
|
754
|
-
const { data, path:
|
|
755
|
-
const fullPath = [...
|
|
754
|
+
const { data, path: path74, errorMaps, issueData } = params;
|
|
755
|
+
const fullPath = [...path74, ...issueData.path || []];
|
|
756
756
|
const fullIssue = {
|
|
757
757
|
...issueData,
|
|
758
758
|
path: fullPath
|
|
@@ -1063,11 +1063,11 @@ var init_types = __esm({
|
|
|
1063
1063
|
init_parseUtil();
|
|
1064
1064
|
init_util();
|
|
1065
1065
|
ParseInputLazyPath = class {
|
|
1066
|
-
constructor(parent, value,
|
|
1066
|
+
constructor(parent, value, path74, key) {
|
|
1067
1067
|
this._cachedPath = [];
|
|
1068
1068
|
this.parent = parent;
|
|
1069
1069
|
this.data = value;
|
|
1070
|
-
this._path =
|
|
1070
|
+
this._path = path74;
|
|
1071
1071
|
this._key = key;
|
|
1072
1072
|
}
|
|
1073
1073
|
get path() {
|
|
@@ -6615,8 +6615,8 @@ var require_req = __commonJS({
|
|
|
6615
6615
|
if (req.originalUrl) {
|
|
6616
6616
|
_req.url = req.originalUrl;
|
|
6617
6617
|
} else {
|
|
6618
|
-
const
|
|
6619
|
-
_req.url = typeof
|
|
6618
|
+
const path74 = req.path;
|
|
6619
|
+
_req.url = typeof path74 === "string" ? path74 : req.url ? req.url.path || req.url : void 0;
|
|
6620
6620
|
}
|
|
6621
6621
|
if (req.query) {
|
|
6622
6622
|
_req.query = req.query;
|
|
@@ -6781,14 +6781,14 @@ var require_redact = __commonJS({
|
|
|
6781
6781
|
}
|
|
6782
6782
|
return obj;
|
|
6783
6783
|
}
|
|
6784
|
-
function parsePath(
|
|
6784
|
+
function parsePath(path74) {
|
|
6785
6785
|
const parts = [];
|
|
6786
6786
|
let current = "";
|
|
6787
6787
|
let inBrackets = false;
|
|
6788
6788
|
let inQuotes = false;
|
|
6789
6789
|
let quoteChar = "";
|
|
6790
|
-
for (let i = 0; i <
|
|
6791
|
-
const char =
|
|
6790
|
+
for (let i = 0; i < path74.length; i++) {
|
|
6791
|
+
const char = path74[i];
|
|
6792
6792
|
if (!inBrackets && char === ".") {
|
|
6793
6793
|
if (current) {
|
|
6794
6794
|
parts.push(current);
|
|
@@ -6919,10 +6919,10 @@ var require_redact = __commonJS({
|
|
|
6919
6919
|
return current;
|
|
6920
6920
|
}
|
|
6921
6921
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6922
|
-
for (const
|
|
6923
|
-
const parts = parsePath(
|
|
6922
|
+
for (const path74 of paths) {
|
|
6923
|
+
const parts = parsePath(path74);
|
|
6924
6924
|
if (parts.includes("*")) {
|
|
6925
|
-
redactWildcardPath(obj, parts, censor,
|
|
6925
|
+
redactWildcardPath(obj, parts, censor, path74, remove);
|
|
6926
6926
|
} else {
|
|
6927
6927
|
if (remove) {
|
|
6928
6928
|
removeKey(obj, parts);
|
|
@@ -7007,8 +7007,8 @@ var require_redact = __commonJS({
|
|
|
7007
7007
|
}
|
|
7008
7008
|
} else {
|
|
7009
7009
|
if (afterWildcard.includes("*")) {
|
|
7010
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7011
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
7010
|
+
const wrappedCensor = typeof censor === "function" ? (value, path74) => {
|
|
7011
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path74];
|
|
7012
7012
|
return censor(value, fullPath);
|
|
7013
7013
|
} : censor;
|
|
7014
7014
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -7043,8 +7043,8 @@ var require_redact = __commonJS({
|
|
|
7043
7043
|
return null;
|
|
7044
7044
|
}
|
|
7045
7045
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
7046
|
-
for (const
|
|
7047
|
-
const parts = parsePath(
|
|
7046
|
+
for (const path74 of pathsToClone) {
|
|
7047
|
+
const parts = parsePath(path74);
|
|
7048
7048
|
let current = pathStructure;
|
|
7049
7049
|
for (let i = 0; i < parts.length; i++) {
|
|
7050
7050
|
const part = parts[i];
|
|
@@ -7096,24 +7096,24 @@ var require_redact = __commonJS({
|
|
|
7096
7096
|
}
|
|
7097
7097
|
return cloneSelectively(obj, pathStructure);
|
|
7098
7098
|
}
|
|
7099
|
-
function validatePath(
|
|
7100
|
-
if (typeof
|
|
7099
|
+
function validatePath(path74) {
|
|
7100
|
+
if (typeof path74 !== "string") {
|
|
7101
7101
|
throw new Error("Paths must be (non-empty) strings");
|
|
7102
7102
|
}
|
|
7103
|
-
if (
|
|
7103
|
+
if (path74 === "") {
|
|
7104
7104
|
throw new Error("Invalid redaction path ()");
|
|
7105
7105
|
}
|
|
7106
|
-
if (
|
|
7107
|
-
throw new Error(`Invalid redaction path (${
|
|
7106
|
+
if (path74.includes("..")) {
|
|
7107
|
+
throw new Error(`Invalid redaction path (${path74})`);
|
|
7108
7108
|
}
|
|
7109
|
-
if (
|
|
7110
|
-
throw new Error(`Invalid redaction path (${
|
|
7109
|
+
if (path74.includes(",")) {
|
|
7110
|
+
throw new Error(`Invalid redaction path (${path74})`);
|
|
7111
7111
|
}
|
|
7112
7112
|
let bracketCount = 0;
|
|
7113
7113
|
let inQuotes = false;
|
|
7114
7114
|
let quoteChar = "";
|
|
7115
|
-
for (let i = 0; i <
|
|
7116
|
-
const char =
|
|
7115
|
+
for (let i = 0; i < path74.length; i++) {
|
|
7116
|
+
const char = path74[i];
|
|
7117
7117
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
7118
7118
|
if (!inQuotes) {
|
|
7119
7119
|
inQuotes = true;
|
|
@@ -7127,20 +7127,20 @@ var require_redact = __commonJS({
|
|
|
7127
7127
|
} else if (char === "]" && !inQuotes) {
|
|
7128
7128
|
bracketCount--;
|
|
7129
7129
|
if (bracketCount < 0) {
|
|
7130
|
-
throw new Error(`Invalid redaction path (${
|
|
7130
|
+
throw new Error(`Invalid redaction path (${path74})`);
|
|
7131
7131
|
}
|
|
7132
7132
|
}
|
|
7133
7133
|
}
|
|
7134
7134
|
if (bracketCount !== 0) {
|
|
7135
|
-
throw new Error(`Invalid redaction path (${
|
|
7135
|
+
throw new Error(`Invalid redaction path (${path74})`);
|
|
7136
7136
|
}
|
|
7137
7137
|
}
|
|
7138
7138
|
function validatePaths(paths) {
|
|
7139
7139
|
if (!Array.isArray(paths)) {
|
|
7140
7140
|
throw new TypeError("paths must be an array");
|
|
7141
7141
|
}
|
|
7142
|
-
for (const
|
|
7143
|
-
validatePath(
|
|
7142
|
+
for (const path74 of paths) {
|
|
7143
|
+
validatePath(path74);
|
|
7144
7144
|
}
|
|
7145
7145
|
}
|
|
7146
7146
|
function slowRedact(options = {}) {
|
|
@@ -7308,8 +7308,8 @@ var require_redaction = __commonJS({
|
|
|
7308
7308
|
if (shape[k2] === null) {
|
|
7309
7309
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
7310
7310
|
} else {
|
|
7311
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7312
|
-
return censor(value, [k2, ...
|
|
7311
|
+
const wrappedCensor = typeof censor === "function" ? (value, path74) => {
|
|
7312
|
+
return censor(value, [k2, ...path74]);
|
|
7313
7313
|
} : censor;
|
|
7314
7314
|
o[k2] = Redact({
|
|
7315
7315
|
paths: shape[k2],
|
|
@@ -7527,10 +7527,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
7527
7527
|
var require_sonic_boom = __commonJS({
|
|
7528
7528
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
7529
7529
|
"use strict";
|
|
7530
|
-
var
|
|
7530
|
+
var fs66 = require("fs");
|
|
7531
7531
|
var EventEmitter3 = require("events");
|
|
7532
7532
|
var inherits = require("util").inherits;
|
|
7533
|
-
var
|
|
7533
|
+
var path74 = require("path");
|
|
7534
7534
|
var sleep2 = require_atomic_sleep();
|
|
7535
7535
|
var assert = require("assert");
|
|
7536
7536
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7584,20 +7584,20 @@ var require_sonic_boom = __commonJS({
|
|
|
7584
7584
|
const mode = sonic.mode;
|
|
7585
7585
|
if (sonic.sync) {
|
|
7586
7586
|
try {
|
|
7587
|
-
if (sonic.mkdir)
|
|
7588
|
-
const fd =
|
|
7587
|
+
if (sonic.mkdir) fs66.mkdirSync(path74.dirname(file), { recursive: true });
|
|
7588
|
+
const fd = fs66.openSync(file, flags, mode);
|
|
7589
7589
|
fileOpened(null, fd);
|
|
7590
7590
|
} catch (err) {
|
|
7591
7591
|
fileOpened(err);
|
|
7592
7592
|
throw err;
|
|
7593
7593
|
}
|
|
7594
7594
|
} else if (sonic.mkdir) {
|
|
7595
|
-
|
|
7595
|
+
fs66.mkdir(path74.dirname(file), { recursive: true }, (err) => {
|
|
7596
7596
|
if (err) return fileOpened(err);
|
|
7597
|
-
|
|
7597
|
+
fs66.open(file, flags, mode, fileOpened);
|
|
7598
7598
|
});
|
|
7599
7599
|
} else {
|
|
7600
|
-
|
|
7600
|
+
fs66.open(file, flags, mode, fileOpened);
|
|
7601
7601
|
}
|
|
7602
7602
|
}
|
|
7603
7603
|
function SonicBoom(opts) {
|
|
@@ -7638,8 +7638,8 @@ var require_sonic_boom = __commonJS({
|
|
|
7638
7638
|
this.flush = flushBuffer;
|
|
7639
7639
|
this.flushSync = flushBufferSync;
|
|
7640
7640
|
this._actualWrite = actualWriteBuffer;
|
|
7641
|
-
fsWriteSync = () =>
|
|
7642
|
-
fsWrite = () =>
|
|
7641
|
+
fsWriteSync = () => fs66.writeSync(this.fd, this._writingBuf);
|
|
7642
|
+
fsWrite = () => fs66.write(this.fd, this._writingBuf, this.release);
|
|
7643
7643
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
7644
7644
|
this._writingBuf = "";
|
|
7645
7645
|
this.write = write;
|
|
@@ -7648,15 +7648,15 @@ var require_sonic_boom = __commonJS({
|
|
|
7648
7648
|
this._actualWrite = actualWrite;
|
|
7649
7649
|
fsWriteSync = () => {
|
|
7650
7650
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7651
|
-
return
|
|
7651
|
+
return fs66.writeSync(this.fd, this._writingBuf);
|
|
7652
7652
|
}
|
|
7653
|
-
return
|
|
7653
|
+
return fs66.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7654
7654
|
};
|
|
7655
7655
|
fsWrite = () => {
|
|
7656
7656
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7657
|
-
return
|
|
7657
|
+
return fs66.write(this.fd, this._writingBuf, this.release);
|
|
7658
7658
|
}
|
|
7659
|
-
return
|
|
7659
|
+
return fs66.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
7660
7660
|
};
|
|
7661
7661
|
} else {
|
|
7662
7662
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -7713,7 +7713,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7713
7713
|
}
|
|
7714
7714
|
}
|
|
7715
7715
|
if (this._fsync) {
|
|
7716
|
-
|
|
7716
|
+
fs66.fsyncSync(this.fd);
|
|
7717
7717
|
}
|
|
7718
7718
|
const len = this._len;
|
|
7719
7719
|
if (this._reopening) {
|
|
@@ -7827,7 +7827,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7827
7827
|
const onDrain = () => {
|
|
7828
7828
|
if (!this._fsync) {
|
|
7829
7829
|
try {
|
|
7830
|
-
|
|
7830
|
+
fs66.fsync(this.fd, (err) => {
|
|
7831
7831
|
this._flushPending = false;
|
|
7832
7832
|
cb(err);
|
|
7833
7833
|
});
|
|
@@ -7929,7 +7929,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7929
7929
|
const fd = this.fd;
|
|
7930
7930
|
this.once("ready", () => {
|
|
7931
7931
|
if (fd !== this.fd) {
|
|
7932
|
-
|
|
7932
|
+
fs66.close(fd, (err) => {
|
|
7933
7933
|
if (err) {
|
|
7934
7934
|
return this.emit("error", err);
|
|
7935
7935
|
}
|
|
@@ -7978,7 +7978,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7978
7978
|
buf = this._bufs[0];
|
|
7979
7979
|
}
|
|
7980
7980
|
try {
|
|
7981
|
-
const n = Buffer.isBuffer(buf) ?
|
|
7981
|
+
const n = Buffer.isBuffer(buf) ? fs66.writeSync(this.fd, buf) : fs66.writeSync(this.fd, buf, "utf8");
|
|
7982
7982
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
7983
7983
|
buf = releasedBufObj.writingBuf;
|
|
7984
7984
|
this._len = releasedBufObj.len;
|
|
@@ -7994,7 +7994,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7994
7994
|
}
|
|
7995
7995
|
}
|
|
7996
7996
|
try {
|
|
7997
|
-
|
|
7997
|
+
fs66.fsyncSync(this.fd);
|
|
7998
7998
|
} catch {
|
|
7999
7999
|
}
|
|
8000
8000
|
}
|
|
@@ -8015,7 +8015,7 @@ var require_sonic_boom = __commonJS({
|
|
|
8015
8015
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
8016
8016
|
}
|
|
8017
8017
|
try {
|
|
8018
|
-
const n =
|
|
8018
|
+
const n = fs66.writeSync(this.fd, buf);
|
|
8019
8019
|
buf = buf.subarray(n);
|
|
8020
8020
|
this._len = Math.max(this._len - n, 0);
|
|
8021
8021
|
if (buf.length <= 0) {
|
|
@@ -8043,13 +8043,13 @@ var require_sonic_boom = __commonJS({
|
|
|
8043
8043
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
8044
8044
|
if (this.sync) {
|
|
8045
8045
|
try {
|
|
8046
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
8046
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs66.writeSync(this.fd, this._writingBuf) : fs66.writeSync(this.fd, this._writingBuf, "utf8");
|
|
8047
8047
|
release(null, written);
|
|
8048
8048
|
} catch (err) {
|
|
8049
8049
|
release(err);
|
|
8050
8050
|
}
|
|
8051
8051
|
} else {
|
|
8052
|
-
|
|
8052
|
+
fs66.write(this.fd, this._writingBuf, release);
|
|
8053
8053
|
}
|
|
8054
8054
|
}
|
|
8055
8055
|
function actualWriteBuffer() {
|
|
@@ -8058,7 +8058,7 @@ var require_sonic_boom = __commonJS({
|
|
|
8058
8058
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
8059
8059
|
if (this.sync) {
|
|
8060
8060
|
try {
|
|
8061
|
-
const written =
|
|
8061
|
+
const written = fs66.writeSync(this.fd, this._writingBuf);
|
|
8062
8062
|
release(null, written);
|
|
8063
8063
|
} catch (err) {
|
|
8064
8064
|
release(err);
|
|
@@ -8067,7 +8067,7 @@ var require_sonic_boom = __commonJS({
|
|
|
8067
8067
|
if (kCopyBuffer) {
|
|
8068
8068
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
8069
8069
|
}
|
|
8070
|
-
|
|
8070
|
+
fs66.write(this.fd, this._writingBuf, release);
|
|
8071
8071
|
}
|
|
8072
8072
|
}
|
|
8073
8073
|
function actualClose(sonic) {
|
|
@@ -8083,12 +8083,12 @@ var require_sonic_boom = __commonJS({
|
|
|
8083
8083
|
sonic._lens = [];
|
|
8084
8084
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
8085
8085
|
try {
|
|
8086
|
-
|
|
8086
|
+
fs66.fsync(sonic.fd, closeWrapped);
|
|
8087
8087
|
} catch {
|
|
8088
8088
|
}
|
|
8089
8089
|
function closeWrapped() {
|
|
8090
8090
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
8091
|
-
|
|
8091
|
+
fs66.close(sonic.fd, done);
|
|
8092
8092
|
} else {
|
|
8093
8093
|
done();
|
|
8094
8094
|
}
|
|
@@ -11223,11 +11223,11 @@ var init_lib = __esm({
|
|
|
11223
11223
|
}
|
|
11224
11224
|
}
|
|
11225
11225
|
},
|
|
11226
|
-
addToPath: function addToPath(
|
|
11227
|
-
var last =
|
|
11226
|
+
addToPath: function addToPath(path74, added, removed, oldPosInc, options) {
|
|
11227
|
+
var last = path74.lastComponent;
|
|
11228
11228
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
11229
11229
|
return {
|
|
11230
|
-
oldPos:
|
|
11230
|
+
oldPos: path74.oldPos + oldPosInc,
|
|
11231
11231
|
lastComponent: {
|
|
11232
11232
|
count: last.count + 1,
|
|
11233
11233
|
added,
|
|
@@ -11237,7 +11237,7 @@ var init_lib = __esm({
|
|
|
11237
11237
|
};
|
|
11238
11238
|
} else {
|
|
11239
11239
|
return {
|
|
11240
|
-
oldPos:
|
|
11240
|
+
oldPos: path74.oldPos + oldPosInc,
|
|
11241
11241
|
lastComponent: {
|
|
11242
11242
|
count: 1,
|
|
11243
11243
|
added,
|
|
@@ -11746,10 +11746,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11746
11746
|
const memories = raw.map((m2) => {
|
|
11747
11747
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11748
11748
|
const rec3 = m2;
|
|
11749
|
-
const
|
|
11749
|
+
const path74 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11750
11750
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11751
|
-
if (!
|
|
11752
|
-
const entry = { path:
|
|
11751
|
+
if (!path74 || content == null) return null;
|
|
11752
|
+
const entry = { path: path74, content };
|
|
11753
11753
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11754
11754
|
return entry;
|
|
11755
11755
|
}).filter((m2) => m2 !== null);
|
|
@@ -12552,10 +12552,10 @@ function parseAttachment(obj) {
|
|
|
12552
12552
|
const memories = raw.map((m2) => {
|
|
12553
12553
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12554
12554
|
const rec3 = m2;
|
|
12555
|
-
const
|
|
12555
|
+
const path74 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12556
12556
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12557
|
-
if (!
|
|
12558
|
-
const out = { path:
|
|
12557
|
+
if (!path74 || content == null) return null;
|
|
12558
|
+
const out = { path: path74, content };
|
|
12559
12559
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12560
12560
|
return out;
|
|
12561
12561
|
}).filter((m2) => m2 !== null);
|
|
@@ -33524,8 +33524,8 @@ var require_utils = __commonJS({
|
|
|
33524
33524
|
var result = transform[inputType][outputType](input);
|
|
33525
33525
|
return result;
|
|
33526
33526
|
};
|
|
33527
|
-
exports2.resolve = function(
|
|
33528
|
-
var parts =
|
|
33527
|
+
exports2.resolve = function(path74) {
|
|
33528
|
+
var parts = path74.split("/");
|
|
33529
33529
|
var result = [];
|
|
33530
33530
|
for (var index = 0; index < parts.length; index++) {
|
|
33531
33531
|
var part = parts[index];
|
|
@@ -39378,18 +39378,18 @@ var require_object = __commonJS({
|
|
|
39378
39378
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
39379
39379
|
this.files[name] = object;
|
|
39380
39380
|
};
|
|
39381
|
-
var parentFolder = function(
|
|
39382
|
-
if (
|
|
39383
|
-
|
|
39381
|
+
var parentFolder = function(path74) {
|
|
39382
|
+
if (path74.slice(-1) === "/") {
|
|
39383
|
+
path74 = path74.substring(0, path74.length - 1);
|
|
39384
39384
|
}
|
|
39385
|
-
var lastSlash =
|
|
39386
|
-
return lastSlash > 0 ?
|
|
39385
|
+
var lastSlash = path74.lastIndexOf("/");
|
|
39386
|
+
return lastSlash > 0 ? path74.substring(0, lastSlash) : "";
|
|
39387
39387
|
};
|
|
39388
|
-
var forceTrailingSlash = function(
|
|
39389
|
-
if (
|
|
39390
|
-
|
|
39388
|
+
var forceTrailingSlash = function(path74) {
|
|
39389
|
+
if (path74.slice(-1) !== "/") {
|
|
39390
|
+
path74 += "/";
|
|
39391
39391
|
}
|
|
39392
|
-
return
|
|
39392
|
+
return path74;
|
|
39393
39393
|
};
|
|
39394
39394
|
var folderAdd = function(name, createFolders) {
|
|
39395
39395
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40391,7 +40391,7 @@ var require_lib3 = __commonJS({
|
|
|
40391
40391
|
// src/run-case/recorder.ts
|
|
40392
40392
|
function startRunCaseRecorder(opts) {
|
|
40393
40393
|
const now = opts.now ?? Date.now;
|
|
40394
|
-
const dir =
|
|
40394
|
+
const dir = import_node_path62.default.dirname(opts.recordPath);
|
|
40395
40395
|
let stream = null;
|
|
40396
40396
|
let closing = false;
|
|
40397
40397
|
let closedSettled = false;
|
|
@@ -40405,8 +40405,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40405
40405
|
});
|
|
40406
40406
|
const ensureStream = () => {
|
|
40407
40407
|
if (stream) return stream;
|
|
40408
|
-
|
|
40409
|
-
stream =
|
|
40408
|
+
import_node_fs47.default.mkdirSync(dir, { recursive: true });
|
|
40409
|
+
stream = import_node_fs47.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40410
40410
|
stream.on("close", () => closedResolve());
|
|
40411
40411
|
return stream;
|
|
40412
40412
|
};
|
|
@@ -40431,12 +40431,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40431
40431
|
};
|
|
40432
40432
|
return { tap, close, closed };
|
|
40433
40433
|
}
|
|
40434
|
-
var
|
|
40434
|
+
var import_node_fs47, import_node_path62;
|
|
40435
40435
|
var init_recorder = __esm({
|
|
40436
40436
|
"src/run-case/recorder.ts"() {
|
|
40437
40437
|
"use strict";
|
|
40438
|
-
|
|
40439
|
-
|
|
40438
|
+
import_node_fs47 = __toESM(require("fs"), 1);
|
|
40439
|
+
import_node_path62 = __toESM(require("path"), 1);
|
|
40440
40440
|
}
|
|
40441
40441
|
});
|
|
40442
40442
|
|
|
@@ -40479,7 +40479,7 @@ var init_wire = __esm({
|
|
|
40479
40479
|
// src/run-case/controller.ts
|
|
40480
40480
|
async function runController(opts) {
|
|
40481
40481
|
const now = opts.now ?? Date.now;
|
|
40482
|
-
const cwd = opts.cwd ?? (0,
|
|
40482
|
+
const cwd = opts.cwd ?? (0, import_node_fs48.mkdtempSync)(import_node_path63.default.join(import_node_os23.default.tmpdir(), "clawd-runcase-"));
|
|
40483
40483
|
const ownsCwd = opts.cwd === void 0;
|
|
40484
40484
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40485
40485
|
const spawnCtx = { cwd };
|
|
@@ -40640,19 +40640,19 @@ async function runController(opts) {
|
|
|
40640
40640
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40641
40641
|
if (ownsCwd) {
|
|
40642
40642
|
try {
|
|
40643
|
-
(0,
|
|
40643
|
+
(0, import_node_fs48.rmSync)(cwd, { recursive: true, force: true });
|
|
40644
40644
|
} catch {
|
|
40645
40645
|
}
|
|
40646
40646
|
}
|
|
40647
40647
|
return exitCode ?? 0;
|
|
40648
40648
|
}
|
|
40649
|
-
var
|
|
40649
|
+
var import_node_fs48, import_node_os23, import_node_path63;
|
|
40650
40650
|
var init_controller = __esm({
|
|
40651
40651
|
"src/run-case/controller.ts"() {
|
|
40652
40652
|
"use strict";
|
|
40653
|
-
|
|
40653
|
+
import_node_fs48 = require("fs");
|
|
40654
40654
|
import_node_os23 = __toESM(require("os"), 1);
|
|
40655
|
-
|
|
40655
|
+
import_node_path63 = __toESM(require("path"), 1);
|
|
40656
40656
|
init_claude();
|
|
40657
40657
|
init_stdout_splitter();
|
|
40658
40658
|
init_permission_stdio();
|
|
@@ -40914,8 +40914,8 @@ Env (advanced):
|
|
|
40914
40914
|
`;
|
|
40915
40915
|
|
|
40916
40916
|
// src/index.ts
|
|
40917
|
-
var
|
|
40918
|
-
var
|
|
40917
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
40918
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
40919
40919
|
var import_node_os22 = __toESM(require("os"), 1);
|
|
40920
40920
|
|
|
40921
40921
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -41918,17 +41918,17 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
|
|
|
41918
41918
|
|
|
41919
41919
|
- \`relPath\` \u5FC5\u987B\u4F20**\u7EDD\u5BF9\u8DEF\u5F84**\uFF08\u4F60\u4EA7\u51FA\u6587\u4EF6\u7684\u771F\u5B9E\u8DEF\u5F84\uFF09\uFF0C\u4E0D\u8981\u4F20\u76F8\u5BF9\u8DEF\u5F84\u3002
|
|
41920
41920
|
- \u53EA\u80FD\u5206\u4EAB\u4F60\u81EA\u5DF1\u5DE5\u4F5C\u76EE\u5F55\u5185\u7684\u6587\u4EF6\uFF0C\u8D8A\u754C\u4F1A\u88AB\u62D2\u3002
|
|
41921
|
-
- \u88AB dispatch \u63A5\u5230\u4EFB\u52A1\u3001\u8981\u56DE\u4F20\u4EA7\u7269\u65F6\uFF1A\u628A\u7B7E\u540D URL \u5199\u8FDB \`personaDispatchComplete\` \u7684 \`text\` \u91CC\uFF08\`filePaths\` \u53EA\u662F\u4F60\u672C\u673A\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u8DE8\u8BBE\u5907\u5BF9\u65B9\u6253\u4E0D\u5F00\uFF0CURL \u624D\u80FD\u6253\u5F00\uFF09\u3002`;
|
|
41921
|
+
- \u88AB dispatch \u63A5\u5230\u4EFB\u52A1\u3001\u8981\u56DE\u4F20\u4EA7\u7269\u65F6\uFF1A\u628A\u7B7E\u540D URL \u5199\u8FDB \`personaDispatchComplete\` tool\uFF08\`clawd-dispatch\` MCP\uFF09\u7684 \`text\` \u91CC\uFF08\`filePaths\` \u53EA\u662F\u4F60\u672C\u673A\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u8DE8\u8BBE\u5907\u5BF9\u65B9\u6253\u4E0D\u5F00\uFF0CURL \u624D\u80FD\u6253\u5F00\uFF09\u3002`;
|
|
41922
41922
|
|
|
41923
41923
|
// src/dispatch/system-prompt.ts
|
|
41924
41924
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41925
41925
|
|
|
41926
|
-
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 MCP
|
|
41926
|
+
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 \`clawd-dispatch\` MCP server \u7684 \`personaDispatch\` tool \u59D4\u6D3E\uFF08\u5404 agent \u5BF9 MCP tool \u7684\u5C55\u793A\u540D\u4E0D\u540C\uFF0C\u5982 claude \u663E\u793A\u4E3A \`mcp__clawd-dispatch__personaDispatch\`\uFF1B\u6309\u4F60\u73AF\u5883\u91CC\u5B9E\u9645\u5217\u51FA\u7684\u540D\u5B57\u8C03\u7528\uFF09\uFF0C\u4E0D\u8981\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF1A
|
|
41927
41927
|
|
|
41928
41928
|
- \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
|
|
41929
41929
|
- \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
|
|
41930
41930
|
|
|
41931
|
-
tool \u4F1A**\u7ACB\u5373\u8FD4\u56DE** dispatchId\uFF08\u5F02\u6B65\u59D4\u6D3E\uFF09\uFF0C\u5BF9\u65B9\u4EBA\u683C\u5728\u540E\u53F0\u5E72\u6D3B\u3002\u4F60\u544A\u8BC9\u7528\u6237"\u4EFB\u52A1\u5DF2\u4EA4\u529E"\u5373\u53EF\u7ED3\u675F\u672C\u8F6E\u2014\u2014**\u4E0D\u8981\u7B49\u5F85\u3001\u4E0D\u8981\u8F6E\u8BE2**\u3002\u5BF9\u65B9\u5E72\u5B8C\u540E\uFF0C\u7ED3\u679C\u4F1A\u4F5C\u4E3A\u4E00\u6761\u65B0\u6D88\u606F\u81EA\u52A8\u6CE8\u5165\u56DE\u4F60\u7684 session\uFF0C\u4F60\u5C4A\u65F6\u518D\u7EFC\u5408\u8F6C\u8FBE\u7ED9\u7528\u6237\u3002\u60F3\u67E5\u8FDB\u5C55\u65F6\uFF08\u7528\u6237\u95EE\u8D77\uFF09\u8C03 \`
|
|
41931
|
+
tool \u4F1A**\u7ACB\u5373\u8FD4\u56DE** dispatchId\uFF08\u5F02\u6B65\u59D4\u6D3E\uFF09\uFF0C\u5BF9\u65B9\u4EBA\u683C\u5728\u540E\u53F0\u5E72\u6D3B\u3002\u4F60\u544A\u8BC9\u7528\u6237"\u4EFB\u52A1\u5DF2\u4EA4\u529E"\u5373\u53EF\u7ED3\u675F\u672C\u8F6E\u2014\u2014**\u4E0D\u8981\u7B49\u5F85\u3001\u4E0D\u8981\u8F6E\u8BE2**\u3002\u5BF9\u65B9\u5E72\u5B8C\u540E\uFF0C\u7ED3\u679C\u4F1A\u4F5C\u4E3A\u4E00\u6761\u65B0\u6D88\u606F\u81EA\u52A8\u6CE8\u5165\u56DE\u4F60\u7684 session\uFF0C\u4F60\u5C4A\u65F6\u518D\u7EFC\u5408\u8F6C\u8FBE\u7ED9\u7528\u6237\u3002\u60F3\u67E5\u8FDB\u5C55\u65F6\uFF08\u7528\u6237\u95EE\u8D77\uFF09\u8C03\u540C\u4E00 MCP \u7684 \`personaDispatchList\`\u3002
|
|
41932
41932
|
|
|
41933
41933
|
- **\u4E0D\u8981**\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF08\u4F60\u4E0D\u662F\u90A3\u4E2A persona\uFF09
|
|
41934
41934
|
- **\u4E0D\u8981** in-place \u6A21\u4EFF\u5BF9\u65B9\u4EBA\u683C \u2014\u2014 dispatch \u662F\u771F\u5207\u5230\u53E6\u4E00\u4E2A\u72EC\u7ACB session
|
|
@@ -41953,7 +41953,7 @@ deviceId \u76F4\u63A5\u53D6\u81EA token\uFF0C\u4E0D\u8981\u6539\u5199\u6216\u731
|
|
|
41953
41953
|
|
|
41954
41954
|
- \u4EFB\u52A1\u5728 \`Task:\` \u6BB5
|
|
41955
41955
|
- \u539F\u4F1A\u8BDD\u7684\u5BF9\u8BDD\u5386\u53F2\u5728 \`Source conversation\` \u6BB5\u7ED9\u7684 jsonl \u8DEF\u5F84\u4E0B\uFF1B\u6309\u9700 Read \u5B83\u4E86\u89E3\u4E0A\u4E0B\u6587\uFF08\u4E0D\u5FC5\u8BFB\u5B8C\uFF09
|
|
41956
|
-
- \u5E72\u5B8C\u540E**\u5FC5\u987B**\u8C03 \`
|
|
41956
|
+
- \u5E72\u5B8C\u540E**\u5FC5\u987B**\u8C03 \`clawd-dispatch\` MCP \u7684 \`personaDispatchComplete\` tool \u62A5\u544A\u7ED3\u679C\uFF1A
|
|
41957
41957
|
- \u6210\u529F\uFF1A\`{ text: "\u603B\u7ED3/\u7ED3\u8BBA", filePaths?: ["\u4F60\u4EA7\u51FA/\u6539\u7684\u6587\u4EF6\u7EDD\u5BF9\u8DEF\u5F84"] }\`
|
|
41958
41958
|
- \u5931\u8D25\uFF1A\`{ isFailure: true, reason: "..." }\`
|
|
41959
41959
|
- \u62A5\u544A\u5B8C\u540E\u4F60\u7684 session \u5C31\u7ED3\u675F\u4E86\uFF0C\u4E0D\u8981\u7EE7\u7EED\u8F93\u51FA`;
|
|
@@ -43353,7 +43353,8 @@ Source conversation (jsonl, CC stream-json format, one message per line):
|
|
|
43353
43353
|
${args.sourceJsonlPath}
|
|
43354
43354
|
You may read this file with your Read tool to understand context. You do not have to read it all.
|
|
43355
43355
|
|
|
43356
|
-
When done, call the
|
|
43356
|
+
When done, call the \`personaDispatchComplete\` tool from the \`clawd-dispatch\` MCP server with your result
|
|
43357
|
+
(tool display name varies by agent, e.g. \`mcp__clawd-dispatch__personaDispatchComplete\` in claude):
|
|
43357
43358
|
- Success: { text: "...", filePaths?: ["abs/path", ...] }
|
|
43358
43359
|
- Failure: { isFailure: true, reason: "..." }
|
|
43359
43360
|
|
|
@@ -43658,18 +43659,20 @@ var SessionManager = class {
|
|
|
43658
43659
|
`newRunner: guest session ${file.sessionId} \u7F3A personaRoot/userWorkDir\uFF0C\u65E0\u6CD5\u7269\u5316 OS \u6C99\u7BB1\uFF08\u62D2\u7EDD\u521B\u5EFA\u65E0\u6C99\u7BB1 guest\uFF09`
|
|
43659
43660
|
);
|
|
43660
43661
|
}
|
|
43661
|
-
|
|
43662
|
-
|
|
43663
|
-
|
|
43664
|
-
|
|
43665
|
-
|
|
43666
|
-
|
|
43667
|
-
|
|
43668
|
-
|
|
43669
|
-
|
|
43670
|
-
|
|
43662
|
+
if ((file.tool ?? "claude") === "claude") {
|
|
43663
|
+
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43664
|
+
const sandboxSettings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43665
|
+
const ownerCreds = readOwnerCredentials(import_node_os5.default.homedir(), this.deps.logger);
|
|
43666
|
+
const merged = mergeOwnerCredentials(sandboxSettings, ownerCreds);
|
|
43667
|
+
if (ownerCreds) {
|
|
43668
|
+
this.deps.logger?.info("owner credentials injected into guest spawn", {
|
|
43669
|
+
sessionId: file.sessionId,
|
|
43670
|
+
envKeys: ownerCreds.env ? Object.keys(ownerCreds.env) : [],
|
|
43671
|
+
apiKeyHelper: ownerCreds.apiKeyHelper ? "present" : "absent"
|
|
43672
|
+
});
|
|
43673
|
+
}
|
|
43674
|
+
subSessionMeta.extraSettings = JSON.stringify(merged);
|
|
43671
43675
|
}
|
|
43672
|
-
subSessionMeta.extraSettings = JSON.stringify(merged);
|
|
43673
43676
|
const home = import_node_os5.default.homedir();
|
|
43674
43677
|
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path9.default.join(home, p2.slice(2)) : p2;
|
|
43675
43678
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
@@ -44719,7 +44722,9 @@ var SessionManager = class {
|
|
|
44719
44722
|
const file = {
|
|
44720
44723
|
sessionId,
|
|
44721
44724
|
cwd,
|
|
44722
|
-
tool
|
|
44725
|
+
// dispatch B session 跟随 persona 绑定的 tool(codex persona 用 codex spawn),
|
|
44726
|
+
// 与 UI 手建路径(handlers/session.ts create 的 persona.tool 优先)同语义
|
|
44727
|
+
tool: this.deps.getPersonaTool?.(args.targetPersona) ?? "claude",
|
|
44723
44728
|
ownerPersonaId: args.targetPersona,
|
|
44724
44729
|
dispatchedFromSessionId: args.sourceSessionId,
|
|
44725
44730
|
// 跨设备显示关键(spec §8):creatorPrincipalId = A 的 deviceId,让 A 的
|
|
@@ -44809,7 +44814,8 @@ var SessionManager = class {
|
|
|
44809
44814
|
const file = {
|
|
44810
44815
|
sessionId,
|
|
44811
44816
|
cwd,
|
|
44812
|
-
tool
|
|
44817
|
+
// shift 定时 spawn 同样跟随 persona 绑定 tool(对齐 dispatch B session)
|
|
44818
|
+
tool: this.deps.getPersonaTool?.(args.targetPersona) ?? "claude",
|
|
44813
44819
|
ownerPersonaId: args.targetPersona,
|
|
44814
44820
|
...args.sourceSessionId ? { shiftFiredFromSessionId: args.sourceSessionId } : {},
|
|
44815
44821
|
createdAt: now,
|
|
@@ -46185,6 +46191,9 @@ function refreshDaemonManagedDirs(args) {
|
|
|
46185
46191
|
const dstPath = path14.join(personaDir, relPath);
|
|
46186
46192
|
try {
|
|
46187
46193
|
fs12.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
46194
|
+
if (relPath === "CLAUDE.md") {
|
|
46195
|
+
fs12.cpSync(srcPath, path14.join(personaDir, "AGENTS.md"), { force: true, dereference: true });
|
|
46196
|
+
}
|
|
46188
46197
|
args.logger.info("persona.refresh.synced", {
|
|
46189
46198
|
personaId: entry.personaId,
|
|
46190
46199
|
path: relPath
|
|
@@ -46552,11 +46561,12 @@ function createVisitorStore(opts) {
|
|
|
46552
46561
|
init_claude();
|
|
46553
46562
|
|
|
46554
46563
|
// src/tools/codex.ts
|
|
46555
|
-
var
|
|
46556
|
-
var
|
|
46564
|
+
var import_node_child_process5 = require("child_process");
|
|
46565
|
+
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
46557
46566
|
|
|
46558
46567
|
// src/tools/codex-session.ts
|
|
46559
|
-
var
|
|
46568
|
+
var import_node_child_process4 = require("child_process");
|
|
46569
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
46560
46570
|
|
|
46561
46571
|
// src/tools/codex-app-server-client.ts
|
|
46562
46572
|
var import_node_readline = require("readline");
|
|
@@ -46739,7 +46749,7 @@ function resolveApprovalPolicy(ctx) {
|
|
|
46739
46749
|
if (m2 === "untrusted" || m2 === "on-failure" || m2 === "on-request" || m2 === "never") return m2;
|
|
46740
46750
|
return "on-request";
|
|
46741
46751
|
}
|
|
46742
|
-
function buildCodexGuestConfig(cs) {
|
|
46752
|
+
function buildCodexGuestConfig(cs, opts = {}) {
|
|
46743
46753
|
const filesystem = {};
|
|
46744
46754
|
for (const w2 of cs.writableRoots ?? []) filesystem[w2] = "write";
|
|
46745
46755
|
const deny = cs.denyRead ?? [];
|
|
@@ -46754,7 +46764,7 @@ function buildCodexGuestConfig(cs) {
|
|
|
46754
46764
|
clawos_guest: {
|
|
46755
46765
|
extends: ":workspace",
|
|
46756
46766
|
filesystem,
|
|
46757
|
-
network: cs.network ? { enabled: true, domains: { "*": "allow" } } : { enabled: false }
|
|
46767
|
+
network: cs.network ? { enabled: true, domains: { "*": "allow" } } : opts.loopbackDaemonAccess ? { enabled: true, allowed_domains: [], allow_local_binding: true } : { enabled: false }
|
|
46758
46768
|
}
|
|
46759
46769
|
}
|
|
46760
46770
|
};
|
|
@@ -46768,15 +46778,32 @@ function tomlValue(v2) {
|
|
|
46768
46778
|
}
|
|
46769
46779
|
return JSON.stringify(v2);
|
|
46770
46780
|
}
|
|
46771
|
-
function codexGuestCliArgs(cs) {
|
|
46772
|
-
const cfg = buildCodexGuestConfig(cs);
|
|
46781
|
+
function codexGuestCliArgs(cs, opts = {}) {
|
|
46782
|
+
const cfg = buildCodexGuestConfig(cs, opts);
|
|
46773
46783
|
const profile = cfg.permissions.clawos_guest;
|
|
46774
|
-
|
|
46784
|
+
const args = [
|
|
46775
46785
|
"-c",
|
|
46776
46786
|
`default_permissions=${tomlValue("clawos_guest")}`,
|
|
46777
46787
|
"-c",
|
|
46778
46788
|
`permissions.clawos_guest=${tomlValue(profile)}`
|
|
46779
46789
|
];
|
|
46790
|
+
if (!cs.network && opts.loopbackDaemonAccess) {
|
|
46791
|
+
args.push("-c", "features.network_proxy=true");
|
|
46792
|
+
}
|
|
46793
|
+
return args;
|
|
46794
|
+
}
|
|
46795
|
+
function codexMcpCliArgs(defs) {
|
|
46796
|
+
const out = [];
|
|
46797
|
+
for (const d of defs) {
|
|
46798
|
+
const cfg = {
|
|
46799
|
+
command: d.command,
|
|
46800
|
+
...d.args && d.args.length > 0 ? { args: d.args } : {},
|
|
46801
|
+
...d.env && Object.keys(d.env).length > 0 ? { env: d.env } : {}
|
|
46802
|
+
};
|
|
46803
|
+
const key = /^[A-Za-z0-9_-]+$/.test(d.name) ? d.name : JSON.stringify(d.name);
|
|
46804
|
+
out.push("-c", `mcp_servers.${key}=${tomlValue(cfg)}`);
|
|
46805
|
+
}
|
|
46806
|
+
return out;
|
|
46780
46807
|
}
|
|
46781
46808
|
function threadStartParams(ctx) {
|
|
46782
46809
|
const params = {
|
|
@@ -46801,8 +46828,8 @@ function turnStartInput(text) {
|
|
|
46801
46828
|
const items = [];
|
|
46802
46829
|
let leftover = text;
|
|
46803
46830
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46804
|
-
const [marker, name,
|
|
46805
|
-
items.push({ type: "skill", name, path:
|
|
46831
|
+
const [marker, name, path74] = m2;
|
|
46832
|
+
items.push({ type: "skill", name, path: path74 });
|
|
46806
46833
|
leftover = leftover.replace(marker, "");
|
|
46807
46834
|
}
|
|
46808
46835
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -46817,15 +46844,122 @@ function turnStartInput(text) {
|
|
|
46817
46844
|
return items;
|
|
46818
46845
|
}
|
|
46819
46846
|
|
|
46847
|
+
// src/tools/codex-mcp-config.ts
|
|
46848
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
46849
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
46850
|
+
function loadCodexMcpServerDefs(args) {
|
|
46851
|
+
const out = [];
|
|
46852
|
+
const seen = /* @__PURE__ */ new Set();
|
|
46853
|
+
const sources = [...args.mcpConfigPaths, import_node_path15.default.join(args.cwd, ".mcp.json")];
|
|
46854
|
+
for (const file of sources) {
|
|
46855
|
+
let parsed;
|
|
46856
|
+
try {
|
|
46857
|
+
parsed = JSON.parse(import_node_fs17.default.readFileSync(file, "utf8"));
|
|
46858
|
+
} catch (e) {
|
|
46859
|
+
const code = e.code;
|
|
46860
|
+
if (code !== "ENOENT") {
|
|
46861
|
+
args.logger?.warn("codex mcp config unreadable, skipped", { file, code: code ?? "parse-error" });
|
|
46862
|
+
}
|
|
46863
|
+
continue;
|
|
46864
|
+
}
|
|
46865
|
+
const servers = parsed?.mcpServers;
|
|
46866
|
+
if (!servers || typeof servers !== "object") continue;
|
|
46867
|
+
for (const [name, raw] of Object.entries(servers)) {
|
|
46868
|
+
const def = raw ?? {};
|
|
46869
|
+
const type = typeof def.type === "string" ? def.type : "stdio";
|
|
46870
|
+
if (type !== "stdio") {
|
|
46871
|
+
args.logger?.warn("codex mcp server type unsupported, skipped", { file, name, type });
|
|
46872
|
+
continue;
|
|
46873
|
+
}
|
|
46874
|
+
if (typeof def.command !== "string" || !def.command) {
|
|
46875
|
+
args.logger?.warn("codex mcp server missing command, skipped", { file, name });
|
|
46876
|
+
continue;
|
|
46877
|
+
}
|
|
46878
|
+
if (seen.has(name)) {
|
|
46879
|
+
args.logger?.warn("codex mcp server name collision, first-wins", { file, name });
|
|
46880
|
+
continue;
|
|
46881
|
+
}
|
|
46882
|
+
seen.add(name);
|
|
46883
|
+
const fileEnv = def.env && typeof def.env === "object" ? Object.fromEntries(
|
|
46884
|
+
Object.entries(def.env).filter(
|
|
46885
|
+
(kv) => typeof kv[1] === "string"
|
|
46886
|
+
)
|
|
46887
|
+
) : {};
|
|
46888
|
+
const env = { ...args.baseEnv ?? {}, ...fileEnv };
|
|
46889
|
+
out.push({
|
|
46890
|
+
name,
|
|
46891
|
+
command: def.command,
|
|
46892
|
+
...Array.isArray(def.args) && def.args.every((a) => typeof a === "string") ? { args: def.args } : {},
|
|
46893
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
46894
|
+
});
|
|
46895
|
+
}
|
|
46896
|
+
}
|
|
46897
|
+
return out;
|
|
46898
|
+
}
|
|
46899
|
+
|
|
46900
|
+
// src/tools/codex-features.ts
|
|
46901
|
+
var import_node_child_process3 = require("child_process");
|
|
46902
|
+
var cachedNetworkProxy;
|
|
46903
|
+
function hasNetworkProxyFeature(deps = {}) {
|
|
46904
|
+
if (cachedNetworkProxy !== void 0) return cachedNetworkProxy;
|
|
46905
|
+
try {
|
|
46906
|
+
const out = deps.execOverride ? deps.execOverride() : (0, import_node_child_process3.execFileSync)(process.env.CODEX_BIN ?? "codex", ["features", "list"], {
|
|
46907
|
+
encoding: "utf8",
|
|
46908
|
+
timeout: 3e3
|
|
46909
|
+
});
|
|
46910
|
+
const m2 = /^network_proxy\s+(.+?)\s+(?:true|false)\s*$/m.exec(out);
|
|
46911
|
+
cachedNetworkProxy = m2 !== null && m2[1].trim() !== "removed";
|
|
46912
|
+
} catch {
|
|
46913
|
+
cachedNetworkProxy = false;
|
|
46914
|
+
}
|
|
46915
|
+
return cachedNetworkProxy;
|
|
46916
|
+
}
|
|
46917
|
+
var warming = false;
|
|
46918
|
+
function warmCodexFeatureCache() {
|
|
46919
|
+
if (cachedNetworkProxy !== void 0 || warming) return;
|
|
46920
|
+
warming = true;
|
|
46921
|
+
(0, import_node_child_process3.execFile)(
|
|
46922
|
+
process.env.CODEX_BIN ?? "codex",
|
|
46923
|
+
["features", "list"],
|
|
46924
|
+
{ encoding: "utf8", timeout: 3e3 },
|
|
46925
|
+
(err, stdout) => {
|
|
46926
|
+
warming = false;
|
|
46927
|
+
if (cachedNetworkProxy !== void 0) return;
|
|
46928
|
+
if (err) {
|
|
46929
|
+
cachedNetworkProxy = false;
|
|
46930
|
+
return;
|
|
46931
|
+
}
|
|
46932
|
+
const m2 = /^network_proxy\s+(.+?)\s+(?:true|false)\s*$/m.exec(stdout);
|
|
46933
|
+
cachedNetworkProxy = m2 !== null && m2[1].trim() !== "removed";
|
|
46934
|
+
}
|
|
46935
|
+
);
|
|
46936
|
+
}
|
|
46937
|
+
|
|
46820
46938
|
// src/tools/codex-session.ts
|
|
46821
46939
|
function createCodexSession(ctx, sink, deps = {}) {
|
|
46822
46940
|
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
46823
46941
|
const args = ["app-server", "--listen", "stdio://"];
|
|
46824
46942
|
if (ctx.personaMode === "guest" && ctx.codexSandbox) {
|
|
46825
|
-
|
|
46943
|
+
const loopbackDaemonAccess = deps.hasNetworkProxyOverride ? deps.hasNetworkProxyOverride() : hasNetworkProxyFeature();
|
|
46944
|
+
args.push(...codexGuestCliArgs(ctx.codexSandbox, { loopbackDaemonAccess }));
|
|
46826
46945
|
}
|
|
46946
|
+
const clawdEnv = Object.fromEntries(
|
|
46947
|
+
Object.entries(ctx.env ?? {}).filter(
|
|
46948
|
+
(kv) => kv[0].startsWith("CLAWD_") && typeof kv[1] === "string"
|
|
46949
|
+
)
|
|
46950
|
+
);
|
|
46951
|
+
args.push(
|
|
46952
|
+
...codexMcpCliArgs(
|
|
46953
|
+
loadCodexMcpServerDefs({
|
|
46954
|
+
mcpConfigPaths: (ctx.mcpConfigs ?? []).map((m2) => m2.path),
|
|
46955
|
+
cwd: ctx.cwd,
|
|
46956
|
+
baseEnv: clawdEnv,
|
|
46957
|
+
logger: deps.logger
|
|
46958
|
+
})
|
|
46959
|
+
)
|
|
46960
|
+
);
|
|
46827
46961
|
const env = { ...process.env, ...ctx.env };
|
|
46828
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0,
|
|
46962
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, ctx.cwd, env) : (0, import_node_child_process4.spawn)(cmd, args, { cwd: ctx.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
|
|
46829
46963
|
let threadId = ctx.toolSessionId;
|
|
46830
46964
|
let turnId;
|
|
46831
46965
|
const approvalIds = /* @__PURE__ */ new Map();
|
|
@@ -46882,6 +47016,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
46882
47016
|
capabilities: null
|
|
46883
47017
|
});
|
|
46884
47018
|
client.notify("initialized", {});
|
|
47019
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path16.default.join(ctx.cwd, ".claude", "skills")] }).catch((e) => deps.logger?.warn("codex skills/extraRoots/set failed", { message: e.message }));
|
|
46885
47020
|
if (threadId) {
|
|
46886
47021
|
await client.request("thread/resume", { threadId, ...threadStartParams(ctx) });
|
|
46887
47022
|
} else {
|
|
@@ -46928,6 +47063,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
46928
47063
|
}
|
|
46929
47064
|
|
|
46930
47065
|
// src/tools/codex.ts
|
|
47066
|
+
var CODEX_MODEL_IDS = ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"];
|
|
46931
47067
|
var CODEX_MODELS = [
|
|
46932
47068
|
{ id: "", label: "Default", description: "codex config.toml \u9ED8\u8BA4", contextWindowSize: 258400, default: true },
|
|
46933
47069
|
{ id: "gpt-5.5", label: "GPT-5.5", description: "Frontier model for complex coding", contextWindowSize: 258400 },
|
|
@@ -46986,10 +47122,10 @@ function sanitizeCodexModel(model) {
|
|
|
46986
47122
|
return CODEX_MODELS.some((m2) => m2.id === model) ? model : void 0;
|
|
46987
47123
|
}
|
|
46988
47124
|
async function probeCodex(env = process.env) {
|
|
46989
|
-
if (env.CODEX_BIN &&
|
|
47125
|
+
if (env.CODEX_BIN && import_node_fs18.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
|
|
46990
47126
|
try {
|
|
46991
|
-
const out = (0,
|
|
46992
|
-
if (out &&
|
|
47127
|
+
const out = (0, import_node_child_process5.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
|
|
47128
|
+
if (out && import_node_fs18.default.existsSync(out)) return { available: true, path: out };
|
|
46993
47129
|
} catch {
|
|
46994
47130
|
}
|
|
46995
47131
|
return { available: false };
|
|
@@ -47035,9 +47171,9 @@ var CodexAdapter = class {
|
|
|
47035
47171
|
|
|
47036
47172
|
// src/tools/claude-tui.ts
|
|
47037
47173
|
var import_node_crypto5 = require("crypto");
|
|
47038
|
-
var
|
|
47174
|
+
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
47039
47175
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
47040
|
-
var
|
|
47176
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
47041
47177
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
47042
47178
|
|
|
47043
47179
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -48270,9 +48406,9 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
48270
48406
|
function jsonlExistsForCtx(ctx) {
|
|
48271
48407
|
if (!ctx.toolSessionId) return false;
|
|
48272
48408
|
const home = import_node_os7.default.homedir();
|
|
48273
|
-
const file =
|
|
48409
|
+
const file = import_node_path17.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
48274
48410
|
try {
|
|
48275
|
-
return
|
|
48411
|
+
return import_node_fs19.default.statSync(file).isFile();
|
|
48276
48412
|
} catch {
|
|
48277
48413
|
return false;
|
|
48278
48414
|
}
|
|
@@ -48382,7 +48518,7 @@ var PersonaDispatchManager = class {
|
|
|
48382
48518
|
|
|
48383
48519
|
// src/dispatch/store.ts
|
|
48384
48520
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
48385
|
-
var
|
|
48521
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
48386
48522
|
|
|
48387
48523
|
// src/shift/constants.ts
|
|
48388
48524
|
var MAX_RUNS_PER_SHIFT = 30;
|
|
@@ -48420,7 +48556,7 @@ function createDispatchStore(deps) {
|
|
|
48420
48556
|
flushTimer = null;
|
|
48421
48557
|
}
|
|
48422
48558
|
const content = { version: 1, records };
|
|
48423
|
-
await import_promises.default.mkdir(
|
|
48559
|
+
await import_promises.default.mkdir(import_node_path18.default.dirname(deps.filePath), { recursive: true });
|
|
48424
48560
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
48425
48561
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
48426
48562
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -48482,10 +48618,10 @@ function createDispatchStore(deps) {
|
|
|
48482
48618
|
}
|
|
48483
48619
|
|
|
48484
48620
|
// src/dispatch/mcp-config.ts
|
|
48485
|
-
var
|
|
48486
|
-
var
|
|
48621
|
+
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
48622
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
48487
48623
|
function dispatchMcpConfigPath(dataDir) {
|
|
48488
|
-
return
|
|
48624
|
+
return import_node_path19.default.join(dataDir, "dispatch.mcp.json");
|
|
48489
48625
|
}
|
|
48490
48626
|
function writeDispatchMcpConfig(args) {
|
|
48491
48627
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -48500,16 +48636,16 @@ function writeDispatchMcpConfig(args) {
|
|
|
48500
48636
|
}
|
|
48501
48637
|
}
|
|
48502
48638
|
};
|
|
48503
|
-
|
|
48504
|
-
|
|
48639
|
+
import_node_fs20.default.mkdirSync(args.dataDir, { recursive: true });
|
|
48640
|
+
import_node_fs20.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48505
48641
|
return cfgPath;
|
|
48506
48642
|
}
|
|
48507
48643
|
|
|
48508
48644
|
// src/ticket/mcp-config.ts
|
|
48509
|
-
var
|
|
48510
|
-
var
|
|
48645
|
+
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
48646
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
48511
48647
|
function ticketMcpConfigPath(dataDir) {
|
|
48512
|
-
return
|
|
48648
|
+
return import_node_path20.default.join(dataDir, "ticket.mcp.json");
|
|
48513
48649
|
}
|
|
48514
48650
|
function writeTicketMcpConfig(args) {
|
|
48515
48651
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -48529,16 +48665,16 @@ function writeTicketMcpConfig(args) {
|
|
|
48529
48665
|
}
|
|
48530
48666
|
}
|
|
48531
48667
|
};
|
|
48532
|
-
|
|
48533
|
-
|
|
48668
|
+
import_node_fs21.default.mkdirSync(args.dataDir, { recursive: true });
|
|
48669
|
+
import_node_fs21.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48534
48670
|
return cfgPath;
|
|
48535
48671
|
}
|
|
48536
48672
|
|
|
48537
48673
|
// src/shift/mcp-config.ts
|
|
48538
|
-
var
|
|
48539
|
-
var
|
|
48674
|
+
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
48675
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
48540
48676
|
function shiftMcpConfigPath(dataDir) {
|
|
48541
|
-
return
|
|
48677
|
+
return import_node_path21.default.join(dataDir, "shift.mcp.json");
|
|
48542
48678
|
}
|
|
48543
48679
|
async function writeShiftMcpConfig(args) {
|
|
48544
48680
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -48553,16 +48689,16 @@ async function writeShiftMcpConfig(args) {
|
|
|
48553
48689
|
}
|
|
48554
48690
|
}
|
|
48555
48691
|
};
|
|
48556
|
-
await
|
|
48557
|
-
await
|
|
48692
|
+
await import_node_fs22.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
48693
|
+
await import_node_fs22.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48558
48694
|
return cfgPath;
|
|
48559
48695
|
}
|
|
48560
48696
|
|
|
48561
48697
|
// src/inbox/mcp-config.ts
|
|
48562
|
-
var
|
|
48563
|
-
var
|
|
48698
|
+
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
48699
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
48564
48700
|
function inboxMcpConfigPath(dataDir) {
|
|
48565
|
-
return
|
|
48701
|
+
return import_node_path22.default.join(dataDir, "inbox.mcp.json");
|
|
48566
48702
|
}
|
|
48567
48703
|
async function writeInboxMcpConfig(args) {
|
|
48568
48704
|
const cfgPath = inboxMcpConfigPath(args.dataDir);
|
|
@@ -48577,16 +48713,16 @@ async function writeInboxMcpConfig(args) {
|
|
|
48577
48713
|
}
|
|
48578
48714
|
}
|
|
48579
48715
|
};
|
|
48580
|
-
await
|
|
48581
|
-
await
|
|
48716
|
+
await import_node_fs23.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
48717
|
+
await import_node_fs23.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48582
48718
|
return cfgPath;
|
|
48583
48719
|
}
|
|
48584
48720
|
|
|
48585
48721
|
// src/peer-ops/mcp-config.ts
|
|
48586
|
-
var
|
|
48587
|
-
var
|
|
48722
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
48723
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
48588
48724
|
function peerOpsMcpConfigPath(dataDir) {
|
|
48589
|
-
return
|
|
48725
|
+
return import_node_path23.default.join(dataDir, "peer-ops.mcp.json");
|
|
48590
48726
|
}
|
|
48591
48727
|
function writePeerOpsMcpConfig(args) {
|
|
48592
48728
|
const cfgPath = peerOpsMcpConfigPath(args.dataDir);
|
|
@@ -48599,14 +48735,14 @@ function writePeerOpsMcpConfig(args) {
|
|
|
48599
48735
|
}
|
|
48600
48736
|
}
|
|
48601
48737
|
};
|
|
48602
|
-
|
|
48603
|
-
|
|
48738
|
+
import_node_fs24.default.mkdirSync(args.dataDir, { recursive: true });
|
|
48739
|
+
import_node_fs24.default.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
|
|
48604
48740
|
return cfgPath;
|
|
48605
48741
|
}
|
|
48606
48742
|
|
|
48607
48743
|
// src/shift/store.ts
|
|
48608
48744
|
var import_promises2 = __toESM(require("fs/promises"), 1);
|
|
48609
|
-
var
|
|
48745
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
48610
48746
|
var import_node_crypto6 = require("crypto");
|
|
48611
48747
|
|
|
48612
48748
|
// src/shift/schedule.ts
|
|
@@ -48681,7 +48817,7 @@ function createShiftStore(deps) {
|
|
|
48681
48817
|
flushTimer = null;
|
|
48682
48818
|
}
|
|
48683
48819
|
const content = { version: 1, shifts };
|
|
48684
|
-
await import_promises2.default.mkdir(
|
|
48820
|
+
await import_promises2.default.mkdir(import_node_path24.default.dirname(deps.filePath), { recursive: true });
|
|
48685
48821
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
48686
48822
|
await import_promises2.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
48687
48823
|
await import_promises2.default.rename(tmp, deps.filePath);
|
|
@@ -49114,11 +49250,16 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
49114
49250
|
const { type: _t, requestId: _r, ...rest } = frame;
|
|
49115
49251
|
const sourceSessionId = typeof rest.sessionId === "string" ? rest.sessionId : void 0;
|
|
49116
49252
|
const args = DispatchRunArgsSchema.parse(rest);
|
|
49117
|
-
if (args.model !== void 0
|
|
49118
|
-
|
|
49119
|
-
|
|
49120
|
-
|
|
49121
|
-
)
|
|
49253
|
+
if (args.model !== void 0) {
|
|
49254
|
+
const targetPersona2 = args.targetPersona ?? (args.dispatchId ? deps.store.get(args.dispatchId)?.targetPersonaId : void 0);
|
|
49255
|
+
const targetTool = (targetPersona2 ? deps.getPersonaTool?.(targetPersona2) : void 0) ?? "claude";
|
|
49256
|
+
const allowed = targetTool === "codex" ? CODEX_MODEL_IDS : CLAUDE_MODEL_IDS;
|
|
49257
|
+
if (!allowed.includes(args.model)) {
|
|
49258
|
+
throw new ClawdError(
|
|
49259
|
+
ERROR_CODES.INVALID_PARAM,
|
|
49260
|
+
`model '${args.model}' not supported for tool '${targetTool}'; allowed: ${allowed.join(", ")}`
|
|
49261
|
+
);
|
|
49262
|
+
}
|
|
49122
49263
|
}
|
|
49123
49264
|
if (args.dispatchId) {
|
|
49124
49265
|
if (ctx?.principal.kind === "guest") {
|
|
@@ -49453,7 +49594,7 @@ async function forwardPeerExecToPeer(args) {
|
|
|
49453
49594
|
}
|
|
49454
49595
|
|
|
49455
49596
|
// src/tools/codex-history.ts
|
|
49456
|
-
var
|
|
49597
|
+
var import_node_child_process6 = require("child_process");
|
|
49457
49598
|
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
49458
49599
|
function rec2(v2) {
|
|
49459
49600
|
return v2 && typeof v2 === "object" && !Array.isArray(v2) ? v2 : void 0;
|
|
@@ -49516,7 +49657,7 @@ function threadItemToHistoryMessages(item) {
|
|
|
49516
49657
|
async function queryCodexAppServer(cwd, method, params, deps) {
|
|
49517
49658
|
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
49518
49659
|
const args = ["app-server", "--listen", "stdio://"];
|
|
49519
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0,
|
|
49660
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process6.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
49520
49661
|
const client = new CodexAppServerClient(proc, {});
|
|
49521
49662
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
49522
49663
|
let timer;
|
|
@@ -49622,7 +49763,8 @@ var CodexHistoryReader = class {
|
|
|
49622
49763
|
};
|
|
49623
49764
|
|
|
49624
49765
|
// src/tools/codex-skills.ts
|
|
49625
|
-
var
|
|
49766
|
+
var import_node_child_process7 = require("child_process");
|
|
49767
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
49626
49768
|
var DEFAULT_TIMEOUT_MS3 = 8e3;
|
|
49627
49769
|
function str3(v2) {
|
|
49628
49770
|
return typeof v2 === "string" ? v2 : void 0;
|
|
@@ -49638,13 +49780,13 @@ function mapSkillsListResponse(res) {
|
|
|
49638
49780
|
const r = s ?? {};
|
|
49639
49781
|
const name = str3(r.name);
|
|
49640
49782
|
if (!name) continue;
|
|
49641
|
-
const
|
|
49783
|
+
const path74 = str3(r.path);
|
|
49642
49784
|
const description = str3(r.description);
|
|
49643
49785
|
const isPlugin = name.includes(":");
|
|
49644
49786
|
out.push({
|
|
49645
49787
|
name,
|
|
49646
49788
|
source: isPlugin ? "plugin" : "project",
|
|
49647
|
-
...
|
|
49789
|
+
...path74 ? { path: path74 } : {},
|
|
49648
49790
|
...description ? { description } : {},
|
|
49649
49791
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
49650
49792
|
});
|
|
@@ -49655,7 +49797,7 @@ function mapSkillsListResponse(res) {
|
|
|
49655
49797
|
async function listCodexSkills(cwd, deps = {}) {
|
|
49656
49798
|
const cmd = process.env.CODEX_BIN ?? "codex";
|
|
49657
49799
|
const args = ["app-server", "--listen", "stdio://"];
|
|
49658
|
-
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0,
|
|
49800
|
+
const proc = deps.spawnOverride ? deps.spawnOverride(cmd, args, cwd) : (0, import_node_child_process7.spawn)(cmd, args, { cwd, env: process.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
49659
49801
|
const client = new CodexAppServerClient(proc, {});
|
|
49660
49802
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_TIMEOUT_MS3;
|
|
49661
49803
|
let timer;
|
|
@@ -49674,6 +49816,7 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
49674
49816
|
})(),
|
|
49675
49817
|
timeout
|
|
49676
49818
|
]);
|
|
49819
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path25.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
49677
49820
|
const res = await Promise.race([client.request("skills/list", { cwds: [cwd] }), timeout]);
|
|
49678
49821
|
return mapSkillsListResponse(res);
|
|
49679
49822
|
} finally {
|
|
@@ -49683,23 +49826,23 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
49683
49826
|
}
|
|
49684
49827
|
|
|
49685
49828
|
// src/workspace/browser.ts
|
|
49686
|
-
var
|
|
49829
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
49687
49830
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
49688
|
-
var
|
|
49831
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
49689
49832
|
init_protocol();
|
|
49690
49833
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
49691
49834
|
function resolveInsideCwd(cwd, subpath) {
|
|
49692
|
-
const absCwd =
|
|
49693
|
-
const joined =
|
|
49694
|
-
const rel =
|
|
49695
|
-
if (rel.startsWith("..") ||
|
|
49835
|
+
const absCwd = import_node_path26.default.resolve(cwd);
|
|
49836
|
+
const joined = import_node_path26.default.resolve(absCwd, subpath ?? ".");
|
|
49837
|
+
const rel = import_node_path26.default.relative(absCwd, joined);
|
|
49838
|
+
if (rel.startsWith("..") || import_node_path26.default.isAbsolute(rel)) {
|
|
49696
49839
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
49697
49840
|
}
|
|
49698
49841
|
return joined;
|
|
49699
49842
|
}
|
|
49700
49843
|
function ensureCwd(cwd) {
|
|
49701
49844
|
try {
|
|
49702
|
-
const stat =
|
|
49845
|
+
const stat = import_node_fs25.default.statSync(cwd);
|
|
49703
49846
|
if (!stat.isDirectory()) {
|
|
49704
49847
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
49705
49848
|
}
|
|
@@ -49713,7 +49856,7 @@ var WorkspaceBrowser = class {
|
|
|
49713
49856
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
49714
49857
|
ensureCwd(cwd);
|
|
49715
49858
|
const full = resolveInsideCwd(cwd, args.path);
|
|
49716
|
-
const dirents =
|
|
49859
|
+
const dirents = import_node_fs25.default.readdirSync(full, { withFileTypes: true });
|
|
49717
49860
|
const entries = [];
|
|
49718
49861
|
for (const d of dirents) {
|
|
49719
49862
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -49723,7 +49866,7 @@ var WorkspaceBrowser = class {
|
|
|
49723
49866
|
mtime: ""
|
|
49724
49867
|
};
|
|
49725
49868
|
try {
|
|
49726
|
-
const st =
|
|
49869
|
+
const st = import_node_fs25.default.statSync(import_node_path26.default.join(full, d.name));
|
|
49727
49870
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
49728
49871
|
if (d.isFile()) entry.size = st.size;
|
|
49729
49872
|
} catch {
|
|
@@ -49739,14 +49882,14 @@ var WorkspaceBrowser = class {
|
|
|
49739
49882
|
read(args) {
|
|
49740
49883
|
ensureCwd(args.cwd);
|
|
49741
49884
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
49742
|
-
const st =
|
|
49885
|
+
const st = import_node_fs25.default.statSync(full);
|
|
49743
49886
|
if (!st.isFile()) {
|
|
49744
49887
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
49745
49888
|
}
|
|
49746
49889
|
if (st.size > MAX_FILE_BYTES) {
|
|
49747
49890
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
49748
49891
|
}
|
|
49749
|
-
const buf =
|
|
49892
|
+
const buf = import_node_fs25.default.readFileSync(full);
|
|
49750
49893
|
const isBinary = buf.includes(0);
|
|
49751
49894
|
if (isBinary) {
|
|
49752
49895
|
return {
|
|
@@ -49768,20 +49911,20 @@ var WorkspaceBrowser = class {
|
|
|
49768
49911
|
};
|
|
49769
49912
|
|
|
49770
49913
|
// src/skills/agents-scanner.ts
|
|
49771
|
-
var
|
|
49914
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
49772
49915
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
49773
|
-
var
|
|
49916
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
49774
49917
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
49775
49918
|
function isDirLikeSync2(p2) {
|
|
49776
49919
|
try {
|
|
49777
|
-
return
|
|
49920
|
+
return import_node_fs26.default.statSync(p2).isDirectory();
|
|
49778
49921
|
} catch {
|
|
49779
49922
|
return false;
|
|
49780
49923
|
}
|
|
49781
49924
|
}
|
|
49782
49925
|
function fileExistsSync(p2) {
|
|
49783
49926
|
try {
|
|
49784
|
-
return
|
|
49927
|
+
return import_node_fs26.default.statSync(p2).isFile();
|
|
49785
49928
|
} catch {
|
|
49786
49929
|
return false;
|
|
49787
49930
|
}
|
|
@@ -49789,7 +49932,7 @@ function fileExistsSync(p2) {
|
|
|
49789
49932
|
function parseAgentFile(filePath) {
|
|
49790
49933
|
let content;
|
|
49791
49934
|
try {
|
|
49792
|
-
content =
|
|
49935
|
+
content = import_node_fs26.default.readFileSync(filePath, "utf8");
|
|
49793
49936
|
} catch {
|
|
49794
49937
|
return {};
|
|
49795
49938
|
}
|
|
@@ -49802,16 +49945,16 @@ function parseAgentFile(filePath) {
|
|
|
49802
49945
|
function scanAgentsDir(dir, source, seen, out) {
|
|
49803
49946
|
let entries;
|
|
49804
49947
|
try {
|
|
49805
|
-
entries =
|
|
49948
|
+
entries = import_node_fs26.default.readdirSync(dir, { withFileTypes: true });
|
|
49806
49949
|
} catch {
|
|
49807
49950
|
return;
|
|
49808
49951
|
}
|
|
49809
49952
|
for (const ent of entries) {
|
|
49810
49953
|
if (!ent.name.endsWith(".md")) continue;
|
|
49811
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
49954
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path27.default.join(dir, ent.name)))) {
|
|
49812
49955
|
continue;
|
|
49813
49956
|
}
|
|
49814
|
-
const filePath =
|
|
49957
|
+
const filePath = import_node_path27.default.join(dir, ent.name);
|
|
49815
49958
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
49816
49959
|
if (seen.has(baseName)) continue;
|
|
49817
49960
|
seen.add(baseName);
|
|
@@ -49829,12 +49972,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
49829
49972
|
function walk2(dir, namespaces) {
|
|
49830
49973
|
let entries;
|
|
49831
49974
|
try {
|
|
49832
|
-
entries =
|
|
49975
|
+
entries = import_node_fs26.default.readdirSync(dir, { withFileTypes: true });
|
|
49833
49976
|
} catch {
|
|
49834
49977
|
return;
|
|
49835
49978
|
}
|
|
49836
49979
|
for (const ent of entries) {
|
|
49837
|
-
const childPath =
|
|
49980
|
+
const childPath = import_node_path27.default.join(dir, ent.name);
|
|
49838
49981
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
49839
49982
|
walk2(childPath, [...namespaces, ent.name]);
|
|
49840
49983
|
continue;
|
|
@@ -49859,13 +50002,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
49859
50002
|
walk2(root, []);
|
|
49860
50003
|
}
|
|
49861
50004
|
function readInstalledPlugins2(home) {
|
|
49862
|
-
const pluginsDir =
|
|
49863
|
-
const v2 =
|
|
49864
|
-
const v1 =
|
|
50005
|
+
const pluginsDir = import_node_path27.default.join(home, ".claude", "plugins");
|
|
50006
|
+
const v2 = import_node_path27.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
50007
|
+
const v1 = import_node_path27.default.join(pluginsDir, "installed_plugins.json");
|
|
49865
50008
|
let raw = null;
|
|
49866
50009
|
for (const candidate of [v2, v1]) {
|
|
49867
50010
|
try {
|
|
49868
|
-
raw =
|
|
50011
|
+
raw = import_node_fs26.default.readFileSync(candidate, "utf8");
|
|
49869
50012
|
break;
|
|
49870
50013
|
} catch {
|
|
49871
50014
|
}
|
|
@@ -49890,19 +50033,19 @@ function readInstalledPlugins2(home) {
|
|
|
49890
50033
|
return out;
|
|
49891
50034
|
}
|
|
49892
50035
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
49893
|
-
let cur =
|
|
49894
|
-
const fsRoot =
|
|
50036
|
+
let cur = import_node_path27.default.resolve(startCwd);
|
|
50037
|
+
const fsRoot = import_node_path27.default.parse(cur).root;
|
|
49895
50038
|
while (true) {
|
|
49896
|
-
scanAgentsDir(
|
|
50039
|
+
scanAgentsDir(import_node_path27.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
49897
50040
|
let hasGit = false;
|
|
49898
50041
|
try {
|
|
49899
|
-
hasGit =
|
|
50042
|
+
hasGit = import_node_fs26.default.existsSync(import_node_path27.default.join(cur, ".git"));
|
|
49900
50043
|
} catch {
|
|
49901
50044
|
}
|
|
49902
50045
|
if (hasGit) return;
|
|
49903
50046
|
if (cur === home) return;
|
|
49904
50047
|
if (cur === fsRoot) return;
|
|
49905
|
-
const parent =
|
|
50048
|
+
const parent = import_node_path27.default.dirname(cur);
|
|
49906
50049
|
if (parent === cur) return;
|
|
49907
50050
|
cur = parent;
|
|
49908
50051
|
}
|
|
@@ -49937,7 +50080,7 @@ var AgentsScanner = class {
|
|
|
49937
50080
|
}
|
|
49938
50081
|
const fsBlock = [];
|
|
49939
50082
|
scanAgentsDir(
|
|
49940
|
-
|
|
50083
|
+
import_node_path27.default.join(this.home, ".claude", "agents"),
|
|
49941
50084
|
"global",
|
|
49942
50085
|
seen,
|
|
49943
50086
|
fsBlock
|
|
@@ -49951,7 +50094,7 @@ var AgentsScanner = class {
|
|
|
49951
50094
|
...this.extraPluginRoots
|
|
49952
50095
|
];
|
|
49953
50096
|
for (const { name, root } of plugins) {
|
|
49954
|
-
const agentsRoot =
|
|
50097
|
+
const agentsRoot = import_node_path27.default.join(root, "agents");
|
|
49955
50098
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
49956
50099
|
}
|
|
49957
50100
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -49959,15 +50102,15 @@ var AgentsScanner = class {
|
|
|
49959
50102
|
};
|
|
49960
50103
|
|
|
49961
50104
|
// src/observer/session-observer.ts
|
|
49962
|
-
var
|
|
50105
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
49963
50106
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
49964
|
-
var
|
|
50107
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
49965
50108
|
init_claude_history();
|
|
49966
50109
|
|
|
49967
50110
|
// src/observer/subagent-meta-observer.ts
|
|
49968
|
-
var
|
|
50111
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
49969
50112
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
49970
|
-
var
|
|
50113
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
49971
50114
|
init_claude_history();
|
|
49972
50115
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
49973
50116
|
var SubagentMetaObserver = class {
|
|
@@ -49980,7 +50123,7 @@ var SubagentMetaObserver = class {
|
|
|
49980
50123
|
watches = /* @__PURE__ */ new Map();
|
|
49981
50124
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
49982
50125
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
49983
|
-
return
|
|
50126
|
+
return import_node_path28.default.join(
|
|
49984
50127
|
this.home,
|
|
49985
50128
|
".claude",
|
|
49986
50129
|
"projects",
|
|
@@ -50010,7 +50153,7 @@ var SubagentMetaObserver = class {
|
|
|
50010
50153
|
attachWatcher(w2) {
|
|
50011
50154
|
if (w2.watcher) return;
|
|
50012
50155
|
try {
|
|
50013
|
-
w2.watcher =
|
|
50156
|
+
w2.watcher = import_node_fs27.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
50014
50157
|
if (!name) return;
|
|
50015
50158
|
const m2 = META_RE.exec(String(name));
|
|
50016
50159
|
if (!m2) return;
|
|
@@ -50022,7 +50165,7 @@ var SubagentMetaObserver = class {
|
|
|
50022
50165
|
scan(w2) {
|
|
50023
50166
|
let entries;
|
|
50024
50167
|
try {
|
|
50025
|
-
entries =
|
|
50168
|
+
entries = import_node_fs27.default.readdirSync(w2.dirPath);
|
|
50026
50169
|
} catch {
|
|
50027
50170
|
return;
|
|
50028
50171
|
}
|
|
@@ -50036,10 +50179,10 @@ var SubagentMetaObserver = class {
|
|
|
50036
50179
|
if (!m2) return;
|
|
50037
50180
|
const agentId = m2[1];
|
|
50038
50181
|
if (w2.emitted.has(agentId)) return;
|
|
50039
|
-
const file =
|
|
50182
|
+
const file = import_node_path28.default.join(w2.dirPath, name);
|
|
50040
50183
|
let raw;
|
|
50041
50184
|
try {
|
|
50042
|
-
raw =
|
|
50185
|
+
raw = import_node_fs27.default.readFileSync(file, "utf8");
|
|
50043
50186
|
} catch {
|
|
50044
50187
|
return;
|
|
50045
50188
|
}
|
|
@@ -50096,14 +50239,14 @@ var SessionObserver = class {
|
|
|
50096
50239
|
metaObserver;
|
|
50097
50240
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
50098
50241
|
if (override) return override;
|
|
50099
|
-
return
|
|
50242
|
+
return import_node_path29.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
50100
50243
|
}
|
|
50101
50244
|
start(args) {
|
|
50102
50245
|
this.stop(args.sessionId);
|
|
50103
50246
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
50104
50247
|
let size = 0;
|
|
50105
50248
|
try {
|
|
50106
|
-
size =
|
|
50249
|
+
size = import_node_fs28.default.statSync(filePath).size;
|
|
50107
50250
|
} catch {
|
|
50108
50251
|
}
|
|
50109
50252
|
const w2 = {
|
|
@@ -50116,16 +50259,16 @@ var SessionObserver = class {
|
|
|
50116
50259
|
adapter: args.adapter,
|
|
50117
50260
|
prevIsRejectSentinel: false,
|
|
50118
50261
|
toolSessionId: args.toolSessionId,
|
|
50119
|
-
sawFile:
|
|
50262
|
+
sawFile: import_node_fs28.default.existsSync(filePath),
|
|
50120
50263
|
lastRelocateScanMs: 0,
|
|
50121
50264
|
pendingCwdDerive: false,
|
|
50122
50265
|
lastDeriveMs: 0
|
|
50123
50266
|
};
|
|
50124
50267
|
try {
|
|
50125
|
-
|
|
50268
|
+
import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(filePath), { recursive: true });
|
|
50126
50269
|
} catch {
|
|
50127
50270
|
}
|
|
50128
|
-
w2.watcher =
|
|
50271
|
+
w2.watcher = import_node_fs28.default.watch(import_node_path29.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
50129
50272
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
50130
50273
|
this.poll(w2);
|
|
50131
50274
|
});
|
|
@@ -50148,7 +50291,7 @@ var SessionObserver = class {
|
|
|
50148
50291
|
// 异常静默吞,不阻塞 watcher 启动
|
|
50149
50292
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
50150
50293
|
try {
|
|
50151
|
-
const raw =
|
|
50294
|
+
const raw = import_node_fs28.default.readFileSync(w2.filePath, "utf8");
|
|
50152
50295
|
if (!raw) return;
|
|
50153
50296
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
50154
50297
|
if (allLines.length === 0) return;
|
|
@@ -50172,7 +50315,7 @@ var SessionObserver = class {
|
|
|
50172
50315
|
poll(w2) {
|
|
50173
50316
|
let size = 0;
|
|
50174
50317
|
try {
|
|
50175
|
-
size =
|
|
50318
|
+
size = import_node_fs28.default.statSync(w2.filePath).size;
|
|
50176
50319
|
} catch {
|
|
50177
50320
|
if (w2.sawFile) this.maybeRelocate(w2);
|
|
50178
50321
|
return;
|
|
@@ -50183,11 +50326,11 @@ var SessionObserver = class {
|
|
|
50183
50326
|
w2.buf = "";
|
|
50184
50327
|
}
|
|
50185
50328
|
if (size === w2.lastSize) return;
|
|
50186
|
-
const fd =
|
|
50329
|
+
const fd = import_node_fs28.default.openSync(w2.filePath, "r");
|
|
50187
50330
|
try {
|
|
50188
50331
|
const len = size - w2.lastSize;
|
|
50189
50332
|
const buf = Buffer.alloc(len);
|
|
50190
|
-
|
|
50333
|
+
import_node_fs28.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
50191
50334
|
w2.lastSize = size;
|
|
50192
50335
|
w2.buf += buf.toString("utf8");
|
|
50193
50336
|
let newlineIndex;
|
|
@@ -50210,7 +50353,7 @@ var SessionObserver = class {
|
|
|
50210
50353
|
}
|
|
50211
50354
|
}
|
|
50212
50355
|
} finally {
|
|
50213
|
-
|
|
50356
|
+
import_node_fs28.default.closeSync(fd);
|
|
50214
50357
|
}
|
|
50215
50358
|
if (w2.pendingCwdDerive) this.maybeDeriveCwd(w2);
|
|
50216
50359
|
}
|
|
@@ -50222,7 +50365,7 @@ var SessionObserver = class {
|
|
|
50222
50365
|
const now = Date.now();
|
|
50223
50366
|
if (now - w2.lastRelocateScanMs < 1e3) return;
|
|
50224
50367
|
w2.lastRelocateScanMs = now;
|
|
50225
|
-
const projectsRoot =
|
|
50368
|
+
const projectsRoot = import_node_path29.default.join(this.home, ".claude", "projects");
|
|
50226
50369
|
const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
|
|
50227
50370
|
if (!found || found === w2.filePath) return;
|
|
50228
50371
|
try {
|
|
@@ -50231,7 +50374,7 @@ var SessionObserver = class {
|
|
|
50231
50374
|
}
|
|
50232
50375
|
w2.filePath = found;
|
|
50233
50376
|
try {
|
|
50234
|
-
w2.watcher =
|
|
50377
|
+
w2.watcher = import_node_fs28.default.watch(import_node_path29.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
50235
50378
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
50236
50379
|
this.poll(w2);
|
|
50237
50380
|
});
|
|
@@ -51089,14 +51232,14 @@ async function authenticate(token, deps) {
|
|
|
51089
51232
|
}
|
|
51090
51233
|
|
|
51091
51234
|
// src/permission/capability-store.ts
|
|
51092
|
-
var
|
|
51093
|
-
var
|
|
51235
|
+
var fs33 = __toESM(require("fs"), 1);
|
|
51236
|
+
var path34 = __toESM(require("path"), 1);
|
|
51094
51237
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
51095
51238
|
var FILE_VERSION = 1;
|
|
51096
51239
|
var CapabilityStore = class {
|
|
51097
51240
|
constructor(dataDir) {
|
|
51098
51241
|
this.dataDir = dataDir;
|
|
51099
|
-
|
|
51242
|
+
fs33.mkdirSync(dataDir, { recursive: true });
|
|
51100
51243
|
this.cache = this.readFromDisk();
|
|
51101
51244
|
}
|
|
51102
51245
|
dataDir;
|
|
@@ -51120,13 +51263,13 @@ var CapabilityStore = class {
|
|
|
51120
51263
|
this.flush();
|
|
51121
51264
|
}
|
|
51122
51265
|
filePath() {
|
|
51123
|
-
return
|
|
51266
|
+
return path34.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
51124
51267
|
}
|
|
51125
51268
|
readFromDisk() {
|
|
51126
51269
|
const file = this.filePath();
|
|
51127
51270
|
let raw;
|
|
51128
51271
|
try {
|
|
51129
|
-
raw =
|
|
51272
|
+
raw = fs33.readFileSync(file, "utf8");
|
|
51130
51273
|
} catch (err) {
|
|
51131
51274
|
if (err?.code === "ENOENT") return [];
|
|
51132
51275
|
return [];
|
|
@@ -51154,10 +51297,10 @@ var CapabilityStore = class {
|
|
|
51154
51297
|
}
|
|
51155
51298
|
atomicWrite(file, content) {
|
|
51156
51299
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
51157
|
-
|
|
51158
|
-
|
|
51300
|
+
fs33.writeFileSync(tmp, content, { mode: 384 });
|
|
51301
|
+
fs33.renameSync(tmp, file);
|
|
51159
51302
|
try {
|
|
51160
|
-
|
|
51303
|
+
fs33.chmodSync(file, 384);
|
|
51161
51304
|
} catch {
|
|
51162
51305
|
}
|
|
51163
51306
|
}
|
|
@@ -51250,14 +51393,14 @@ var CapabilityManager = class {
|
|
|
51250
51393
|
};
|
|
51251
51394
|
|
|
51252
51395
|
// src/permission/cleanup.ts
|
|
51253
|
-
var
|
|
51396
|
+
var fs34 = __toESM(require("fs"), 1);
|
|
51254
51397
|
function cleanupGuestSessionsForCapability(cap, factory) {
|
|
51255
51398
|
const removed = [];
|
|
51256
51399
|
for (const g2 of cap.grants) {
|
|
51257
51400
|
if (g2.resource.type !== "persona") continue;
|
|
51258
51401
|
const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
|
|
51259
51402
|
try {
|
|
51260
|
-
|
|
51403
|
+
fs34.rmSync(dir, { recursive: true, force: true });
|
|
51261
51404
|
removed.push(dir);
|
|
51262
51405
|
} catch {
|
|
51263
51406
|
}
|
|
@@ -51266,13 +51409,13 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
51266
51409
|
}
|
|
51267
51410
|
|
|
51268
51411
|
// src/inbox/inbox-store.ts
|
|
51269
|
-
var
|
|
51270
|
-
var
|
|
51412
|
+
var fs35 = __toESM(require("fs"), 1);
|
|
51413
|
+
var path35 = __toESM(require("path"), 1);
|
|
51271
51414
|
var INBOX_SUBDIR = "inbox";
|
|
51272
51415
|
var InboxStore = class {
|
|
51273
51416
|
constructor(dataDir) {
|
|
51274
51417
|
this.dataDir = dataDir;
|
|
51275
|
-
|
|
51418
|
+
fs35.mkdirSync(this.dirPath(), { recursive: true });
|
|
51276
51419
|
}
|
|
51277
51420
|
dataDir;
|
|
51278
51421
|
/**
|
|
@@ -51284,7 +51427,7 @@ var InboxStore = class {
|
|
|
51284
51427
|
const file = this.filePath(peerDeviceId);
|
|
51285
51428
|
let raw;
|
|
51286
51429
|
try {
|
|
51287
|
-
raw =
|
|
51430
|
+
raw = fs35.readFileSync(file, "utf8");
|
|
51288
51431
|
} catch (err) {
|
|
51289
51432
|
if (err?.code === "ENOENT") return [];
|
|
51290
51433
|
return [];
|
|
@@ -51300,7 +51443,7 @@ var InboxStore = class {
|
|
|
51300
51443
|
const dir = this.dirPath();
|
|
51301
51444
|
let entries;
|
|
51302
51445
|
try {
|
|
51303
|
-
entries =
|
|
51446
|
+
entries = fs35.readdirSync(dir);
|
|
51304
51447
|
} catch (err) {
|
|
51305
51448
|
if (err?.code === "ENOENT") return [];
|
|
51306
51449
|
return [];
|
|
@@ -51316,9 +51459,9 @@ var InboxStore = class {
|
|
|
51316
51459
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
51317
51460
|
const file = this.filePath(message.peerDeviceId);
|
|
51318
51461
|
const line = JSON.stringify(message) + "\n";
|
|
51319
|
-
|
|
51462
|
+
fs35.appendFileSync(file, line, { mode: 384 });
|
|
51320
51463
|
try {
|
|
51321
|
-
|
|
51464
|
+
fs35.chmodSync(file, 384);
|
|
51322
51465
|
} catch {
|
|
51323
51466
|
}
|
|
51324
51467
|
}
|
|
@@ -51348,7 +51491,7 @@ var InboxStore = class {
|
|
|
51348
51491
|
removeByPeerDeviceId(peerDeviceId) {
|
|
51349
51492
|
const file = this.filePath(peerDeviceId);
|
|
51350
51493
|
try {
|
|
51351
|
-
|
|
51494
|
+
fs35.unlinkSync(file);
|
|
51352
51495
|
} catch (err) {
|
|
51353
51496
|
if (err?.code === "ENOENT") return;
|
|
51354
51497
|
}
|
|
@@ -51357,18 +51500,18 @@ var InboxStore = class {
|
|
|
51357
51500
|
const file = this.filePath(peerDeviceId);
|
|
51358
51501
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
51359
51502
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
51360
|
-
|
|
51361
|
-
|
|
51503
|
+
fs35.writeFileSync(tmp, content, { mode: 384 });
|
|
51504
|
+
fs35.renameSync(tmp, file);
|
|
51362
51505
|
try {
|
|
51363
|
-
|
|
51506
|
+
fs35.chmodSync(file, 384);
|
|
51364
51507
|
} catch {
|
|
51365
51508
|
}
|
|
51366
51509
|
}
|
|
51367
51510
|
dirPath() {
|
|
51368
|
-
return
|
|
51511
|
+
return path35.join(this.dataDir, INBOX_SUBDIR);
|
|
51369
51512
|
}
|
|
51370
51513
|
filePath(peerDeviceId) {
|
|
51371
|
-
return
|
|
51514
|
+
return path35.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
51372
51515
|
}
|
|
51373
51516
|
};
|
|
51374
51517
|
function parseAllLines(raw) {
|
|
@@ -51456,8 +51599,8 @@ var InboxManager = class {
|
|
|
51456
51599
|
};
|
|
51457
51600
|
|
|
51458
51601
|
// src/state/contact-store.ts
|
|
51459
|
-
var
|
|
51460
|
-
var
|
|
51602
|
+
var fs36 = __toESM(require("fs"), 1);
|
|
51603
|
+
var path36 = __toESM(require("path"), 1);
|
|
51461
51604
|
var FILE_NAME = "contacts.json";
|
|
51462
51605
|
var ContactStore = class {
|
|
51463
51606
|
constructor(dataDir) {
|
|
@@ -51467,10 +51610,10 @@ var ContactStore = class {
|
|
|
51467
51610
|
contacts = /* @__PURE__ */ new Map();
|
|
51468
51611
|
load() {
|
|
51469
51612
|
this.contacts.clear();
|
|
51470
|
-
const file =
|
|
51613
|
+
const file = path36.join(this.dataDir, FILE_NAME);
|
|
51471
51614
|
let raw;
|
|
51472
51615
|
try {
|
|
51473
|
-
raw =
|
|
51616
|
+
raw = fs36.readFileSync(file, "utf8");
|
|
51474
51617
|
} catch (err) {
|
|
51475
51618
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
51476
51619
|
return;
|
|
@@ -51539,20 +51682,20 @@ var ContactStore = class {
|
|
|
51539
51682
|
return true;
|
|
51540
51683
|
}
|
|
51541
51684
|
flush() {
|
|
51542
|
-
const file =
|
|
51685
|
+
const file = path36.join(this.dataDir, FILE_NAME);
|
|
51543
51686
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
51544
51687
|
const content = JSON.stringify(
|
|
51545
51688
|
{ contacts: Array.from(this.contacts.values()) },
|
|
51546
51689
|
null,
|
|
51547
51690
|
2
|
|
51548
51691
|
);
|
|
51549
|
-
|
|
51550
|
-
|
|
51551
|
-
|
|
51692
|
+
fs36.mkdirSync(this.dataDir, { recursive: true });
|
|
51693
|
+
fs36.writeFileSync(tmp, content, { mode: 384 });
|
|
51694
|
+
fs36.renameSync(tmp, file);
|
|
51552
51695
|
}
|
|
51553
51696
|
renameBak(file) {
|
|
51554
51697
|
try {
|
|
51555
|
-
|
|
51698
|
+
fs36.renameSync(file, `${file}.bak`);
|
|
51556
51699
|
} catch {
|
|
51557
51700
|
}
|
|
51558
51701
|
}
|
|
@@ -51705,61 +51848,61 @@ async function autoReverseContact(args) {
|
|
|
51705
51848
|
}
|
|
51706
51849
|
|
|
51707
51850
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
51708
|
-
var
|
|
51709
|
-
var
|
|
51851
|
+
var fs37 = __toESM(require("fs"), 1);
|
|
51852
|
+
var path37 = __toESM(require("path"), 1);
|
|
51710
51853
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
51711
51854
|
function migrateFlattenSessions(opts) {
|
|
51712
51855
|
const dataDir = opts.dataDir;
|
|
51713
51856
|
const now = opts.now ?? Date.now;
|
|
51714
|
-
const sessionsDir =
|
|
51715
|
-
const flagPath =
|
|
51857
|
+
const sessionsDir = path37.join(dataDir, "sessions");
|
|
51858
|
+
const flagPath = path37.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
51716
51859
|
if (existsSync3(flagPath)) {
|
|
51717
51860
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
51718
51861
|
}
|
|
51719
51862
|
let movedBare = 0;
|
|
51720
51863
|
let movedVmOwner = 0;
|
|
51721
51864
|
let archivedListener = 0;
|
|
51722
|
-
const defaultDir =
|
|
51865
|
+
const defaultDir = path37.join(sessionsDir, "default");
|
|
51723
51866
|
if (existsSync3(defaultDir)) {
|
|
51724
51867
|
for (const entry of readdirSafe(defaultDir)) {
|
|
51725
51868
|
if (!entry.endsWith(".json")) continue;
|
|
51726
|
-
const src =
|
|
51727
|
-
const dst =
|
|
51728
|
-
|
|
51869
|
+
const src = path37.join(defaultDir, entry);
|
|
51870
|
+
const dst = path37.join(sessionsDir, entry);
|
|
51871
|
+
fs37.renameSync(src, dst);
|
|
51729
51872
|
movedBare += 1;
|
|
51730
51873
|
}
|
|
51731
51874
|
rmdirIfEmpty(defaultDir);
|
|
51732
51875
|
}
|
|
51733
51876
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
51734
|
-
const personaDir =
|
|
51877
|
+
const personaDir = path37.join(sessionsDir, pid);
|
|
51735
51878
|
if (!isDir(personaDir)) continue;
|
|
51736
51879
|
if (pid === "default") continue;
|
|
51737
|
-
const ownerSrc =
|
|
51880
|
+
const ownerSrc = path37.join(personaDir, "owner");
|
|
51738
51881
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
51739
|
-
const ownerDst =
|
|
51740
|
-
|
|
51882
|
+
const ownerDst = path37.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
51883
|
+
fs37.mkdirSync(ownerDst, { recursive: true });
|
|
51741
51884
|
for (const file of readdirSafe(ownerSrc)) {
|
|
51742
51885
|
if (!file.endsWith(".json")) continue;
|
|
51743
|
-
|
|
51886
|
+
fs37.renameSync(path37.join(ownerSrc, file), path37.join(ownerDst, file));
|
|
51744
51887
|
movedVmOwner += 1;
|
|
51745
51888
|
}
|
|
51746
51889
|
rmdirIfEmpty(ownerSrc);
|
|
51747
51890
|
}
|
|
51748
|
-
const listenerSrc =
|
|
51891
|
+
const listenerSrc = path37.join(personaDir, "listener");
|
|
51749
51892
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
51750
|
-
const archiveDst =
|
|
51751
|
-
|
|
51893
|
+
const archiveDst = path37.join(dataDir, ".legacy", `listener-${pid}`);
|
|
51894
|
+
fs37.mkdirSync(archiveDst, { recursive: true });
|
|
51752
51895
|
for (const file of readdirSafe(listenerSrc)) {
|
|
51753
51896
|
if (!file.endsWith(".json")) continue;
|
|
51754
|
-
|
|
51897
|
+
fs37.renameSync(path37.join(listenerSrc, file), path37.join(archiveDst, file));
|
|
51755
51898
|
archivedListener += 1;
|
|
51756
51899
|
}
|
|
51757
51900
|
rmdirIfEmpty(listenerSrc);
|
|
51758
51901
|
}
|
|
51759
51902
|
rmdirIfEmpty(personaDir);
|
|
51760
51903
|
}
|
|
51761
|
-
|
|
51762
|
-
|
|
51904
|
+
fs37.mkdirSync(sessionsDir, { recursive: true });
|
|
51905
|
+
fs37.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
51763
51906
|
return {
|
|
51764
51907
|
skipped: false,
|
|
51765
51908
|
flagWritten: true,
|
|
@@ -51770,7 +51913,7 @@ function migrateFlattenSessions(opts) {
|
|
|
51770
51913
|
}
|
|
51771
51914
|
function existsSync3(p2) {
|
|
51772
51915
|
try {
|
|
51773
|
-
|
|
51916
|
+
fs37.statSync(p2);
|
|
51774
51917
|
return true;
|
|
51775
51918
|
} catch {
|
|
51776
51919
|
return false;
|
|
@@ -51778,31 +51921,31 @@ function existsSync3(p2) {
|
|
|
51778
51921
|
}
|
|
51779
51922
|
function isDir(p2) {
|
|
51780
51923
|
try {
|
|
51781
|
-
return
|
|
51924
|
+
return fs37.statSync(p2).isDirectory();
|
|
51782
51925
|
} catch {
|
|
51783
51926
|
return false;
|
|
51784
51927
|
}
|
|
51785
51928
|
}
|
|
51786
51929
|
function readdirSafe(p2) {
|
|
51787
51930
|
try {
|
|
51788
|
-
return
|
|
51931
|
+
return fs37.readdirSync(p2);
|
|
51789
51932
|
} catch {
|
|
51790
51933
|
return [];
|
|
51791
51934
|
}
|
|
51792
51935
|
}
|
|
51793
51936
|
function rmdirIfEmpty(p2) {
|
|
51794
51937
|
try {
|
|
51795
|
-
|
|
51938
|
+
fs37.rmdirSync(p2);
|
|
51796
51939
|
} catch {
|
|
51797
51940
|
}
|
|
51798
51941
|
}
|
|
51799
51942
|
|
|
51800
51943
|
// src/transport/http-router.ts
|
|
51801
|
-
var
|
|
51802
|
-
var
|
|
51944
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
51945
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
51803
51946
|
|
|
51804
51947
|
// src/attachment/mime.ts
|
|
51805
|
-
var
|
|
51948
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
51806
51949
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
51807
51950
|
var EXT_TO_NATIVE_MIME = {
|
|
51808
51951
|
// 图片
|
|
@@ -51909,7 +52052,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
51909
52052
|
".mk"
|
|
51910
52053
|
]);
|
|
51911
52054
|
function lookupMime(filePathOrName) {
|
|
51912
|
-
const ext =
|
|
52055
|
+
const ext = import_node_path30.default.extname(filePathOrName).toLowerCase();
|
|
51913
52056
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
51914
52057
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
51915
52058
|
return "application/octet-stream";
|
|
@@ -51978,8 +52121,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
51978
52121
|
}
|
|
51979
52122
|
|
|
51980
52123
|
// src/attachment/upload.ts
|
|
51981
|
-
var
|
|
51982
|
-
var
|
|
52124
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
52125
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
51983
52126
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51984
52127
|
var import_promises3 = require("stream/promises");
|
|
51985
52128
|
var UploadError = class extends Error {
|
|
@@ -51991,22 +52134,22 @@ var UploadError = class extends Error {
|
|
|
51991
52134
|
code;
|
|
51992
52135
|
};
|
|
51993
52136
|
function assertValidFileName(fileName) {
|
|
51994
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
52137
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path31.default.basename(fileName)) {
|
|
51995
52138
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
51996
52139
|
}
|
|
51997
52140
|
}
|
|
51998
52141
|
var HASH_PREFIX_LEN = 16;
|
|
51999
52142
|
async function writeUploadedAttachment(args) {
|
|
52000
52143
|
assertValidFileName(args.fileName);
|
|
52001
|
-
const attachmentsRoot =
|
|
52144
|
+
const attachmentsRoot = import_node_path31.default.join(args.sessionDir, ".attachments");
|
|
52002
52145
|
try {
|
|
52003
|
-
|
|
52146
|
+
import_node_fs29.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
52004
52147
|
} catch (err) {
|
|
52005
52148
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
52006
52149
|
}
|
|
52007
52150
|
const hasher = import_node_crypto8.default.createHash("sha256");
|
|
52008
52151
|
let actualSize = 0;
|
|
52009
|
-
const tmpPath =
|
|
52152
|
+
const tmpPath = import_node_path31.default.join(
|
|
52010
52153
|
attachmentsRoot,
|
|
52011
52154
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
|
|
52012
52155
|
);
|
|
@@ -52021,18 +52164,18 @@ async function writeUploadedAttachment(args) {
|
|
|
52021
52164
|
yield buf;
|
|
52022
52165
|
}
|
|
52023
52166
|
},
|
|
52024
|
-
|
|
52167
|
+
import_node_fs29.default.createWriteStream(tmpPath, { mode: 384 })
|
|
52025
52168
|
);
|
|
52026
52169
|
} catch (err) {
|
|
52027
52170
|
try {
|
|
52028
|
-
|
|
52171
|
+
import_node_fs29.default.unlinkSync(tmpPath);
|
|
52029
52172
|
} catch {
|
|
52030
52173
|
}
|
|
52031
52174
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
52032
52175
|
}
|
|
52033
52176
|
if (actualSize !== args.contentLength) {
|
|
52034
52177
|
try {
|
|
52035
|
-
|
|
52178
|
+
import_node_fs29.default.unlinkSync(tmpPath);
|
|
52036
52179
|
} catch {
|
|
52037
52180
|
}
|
|
52038
52181
|
throw new UploadError(
|
|
@@ -52041,35 +52184,35 @@ async function writeUploadedAttachment(args) {
|
|
|
52041
52184
|
);
|
|
52042
52185
|
}
|
|
52043
52186
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
52044
|
-
const hashDir =
|
|
52187
|
+
const hashDir = import_node_path31.default.join(attachmentsRoot, attachmentId);
|
|
52045
52188
|
let finalFileName;
|
|
52046
52189
|
let hashDirExists = false;
|
|
52047
52190
|
try {
|
|
52048
|
-
hashDirExists =
|
|
52191
|
+
hashDirExists = import_node_fs29.default.statSync(hashDir).isDirectory();
|
|
52049
52192
|
} catch {
|
|
52050
52193
|
}
|
|
52051
52194
|
if (hashDirExists) {
|
|
52052
|
-
const existing =
|
|
52195
|
+
const existing = import_node_fs29.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
52053
52196
|
finalFileName = existing[0] ?? args.fileName;
|
|
52054
52197
|
try {
|
|
52055
|
-
|
|
52198
|
+
import_node_fs29.default.unlinkSync(tmpPath);
|
|
52056
52199
|
} catch {
|
|
52057
52200
|
}
|
|
52058
52201
|
} else {
|
|
52059
52202
|
try {
|
|
52060
|
-
|
|
52203
|
+
import_node_fs29.default.mkdirSync(hashDir, { recursive: true });
|
|
52061
52204
|
finalFileName = args.fileName;
|
|
52062
|
-
|
|
52205
|
+
import_node_fs29.default.renameSync(tmpPath, import_node_path31.default.join(hashDir, finalFileName));
|
|
52063
52206
|
} catch (err) {
|
|
52064
52207
|
try {
|
|
52065
|
-
|
|
52208
|
+
import_node_fs29.default.unlinkSync(tmpPath);
|
|
52066
52209
|
} catch {
|
|
52067
52210
|
}
|
|
52068
52211
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
52069
52212
|
}
|
|
52070
52213
|
}
|
|
52071
|
-
const absPath =
|
|
52072
|
-
const relPath =
|
|
52214
|
+
const absPath = import_node_path31.default.join(hashDir, finalFileName);
|
|
52215
|
+
const relPath = import_node_path31.default.relative(args.sessionDir, absPath);
|
|
52073
52216
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
52074
52217
|
relPath: absPath,
|
|
52075
52218
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -52083,7 +52226,7 @@ async function writeUploadedAttachment(args) {
|
|
|
52083
52226
|
|
|
52084
52227
|
// src/extension/import.ts
|
|
52085
52228
|
var import_promises4 = __toESM(require("fs/promises"), 1);
|
|
52086
|
-
var
|
|
52229
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
52087
52230
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
52088
52231
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
52089
52232
|
var ImportError = class extends Error {
|
|
@@ -52101,7 +52244,7 @@ async function importZip(buf, root) {
|
|
|
52101
52244
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
52102
52245
|
}
|
|
52103
52246
|
for (const name of Object.keys(zip.files)) {
|
|
52104
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
52247
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path32.default.isAbsolute(name)) {
|
|
52105
52248
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
52106
52249
|
}
|
|
52107
52250
|
}
|
|
@@ -52134,7 +52277,7 @@ async function importZip(buf, root) {
|
|
|
52134
52277
|
);
|
|
52135
52278
|
}
|
|
52136
52279
|
}
|
|
52137
|
-
const destDir =
|
|
52280
|
+
const destDir = import_node_path32.default.join(root, manifest.id);
|
|
52138
52281
|
let destExists = false;
|
|
52139
52282
|
try {
|
|
52140
52283
|
await import_promises4.default.access(destDir);
|
|
@@ -52144,15 +52287,15 @@ async function importZip(buf, root) {
|
|
|
52144
52287
|
if (destExists) {
|
|
52145
52288
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
52146
52289
|
}
|
|
52147
|
-
const stage = await import_promises4.default.mkdtemp(
|
|
52290
|
+
const stage = await import_promises4.default.mkdtemp(import_node_path32.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
52148
52291
|
try {
|
|
52149
52292
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
52150
|
-
const dest =
|
|
52293
|
+
const dest = import_node_path32.default.join(stage, name);
|
|
52151
52294
|
if (entry.dir) {
|
|
52152
52295
|
await import_promises4.default.mkdir(dest, { recursive: true });
|
|
52153
52296
|
continue;
|
|
52154
52297
|
}
|
|
52155
|
-
await import_promises4.default.mkdir(
|
|
52298
|
+
await import_promises4.default.mkdir(import_node_path32.default.dirname(dest), { recursive: true });
|
|
52156
52299
|
const content = await entry.async("nodebuffer");
|
|
52157
52300
|
await import_promises4.default.writeFile(dest, content);
|
|
52158
52301
|
}
|
|
@@ -52183,7 +52326,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
52183
52326
|
".wasm": "application/wasm"
|
|
52184
52327
|
};
|
|
52185
52328
|
function shareUiAssetMime(filePath) {
|
|
52186
|
-
const ext =
|
|
52329
|
+
const ext = import_node_path33.default.extname(filePath).toLowerCase();
|
|
52187
52330
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
52188
52331
|
}
|
|
52189
52332
|
var DISPATCH_HEARTBEAT_MS = 25e3;
|
|
@@ -52270,7 +52413,7 @@ function isValidUploadFileName(fileName) {
|
|
|
52270
52413
|
if (fileName === "." || fileName === "..") return false;
|
|
52271
52414
|
if (fileName.startsWith(".")) return false;
|
|
52272
52415
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
52273
|
-
return fileName ===
|
|
52416
|
+
return fileName === import_node_path33.default.basename(fileName);
|
|
52274
52417
|
}
|
|
52275
52418
|
function createHttpRouter(deps) {
|
|
52276
52419
|
return async (req, res) => {
|
|
@@ -52342,7 +52485,7 @@ function createHttpRouter(deps) {
|
|
|
52342
52485
|
}
|
|
52343
52486
|
let buf;
|
|
52344
52487
|
try {
|
|
52345
|
-
buf = await
|
|
52488
|
+
buf = await import_node_fs30.default.promises.readFile(abs);
|
|
52346
52489
|
} catch {
|
|
52347
52490
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
52348
52491
|
return true;
|
|
@@ -52566,7 +52709,7 @@ function createHttpRouter(deps) {
|
|
|
52566
52709
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
52567
52710
|
return true;
|
|
52568
52711
|
}
|
|
52569
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
52712
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path33.default.basename(r.absPath)));
|
|
52570
52713
|
return true;
|
|
52571
52714
|
}
|
|
52572
52715
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -52687,7 +52830,7 @@ function createHttpRouter(deps) {
|
|
|
52687
52830
|
return true;
|
|
52688
52831
|
}
|
|
52689
52832
|
let absPath;
|
|
52690
|
-
if (
|
|
52833
|
+
if (import_node_path33.default.isAbsolute(pathParam)) {
|
|
52691
52834
|
absPath = pathParam;
|
|
52692
52835
|
} else if (deps.sessionStore) {
|
|
52693
52836
|
const file = deps.sessionStore.read(sid);
|
|
@@ -52695,7 +52838,7 @@ function createHttpRouter(deps) {
|
|
|
52695
52838
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
52696
52839
|
return true;
|
|
52697
52840
|
}
|
|
52698
|
-
absPath =
|
|
52841
|
+
absPath = import_node_path33.default.join(file.cwd, pathParam);
|
|
52699
52842
|
} else {
|
|
52700
52843
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
52701
52844
|
return true;
|
|
@@ -52782,7 +52925,7 @@ function withCtx(ctx, body) {
|
|
|
52782
52925
|
function streamFile(res, absPath, logger) {
|
|
52783
52926
|
let stat;
|
|
52784
52927
|
try {
|
|
52785
|
-
stat =
|
|
52928
|
+
stat = import_node_fs30.default.statSync(absPath);
|
|
52786
52929
|
} catch (err) {
|
|
52787
52930
|
const code = err?.code;
|
|
52788
52931
|
if (code === "ENOENT") {
|
|
@@ -52797,7 +52940,7 @@ function streamFile(res, absPath, logger) {
|
|
|
52797
52940
|
return;
|
|
52798
52941
|
}
|
|
52799
52942
|
const mime = lookupMime(absPath);
|
|
52800
|
-
const basename =
|
|
52943
|
+
const basename = import_node_path33.default.basename(absPath);
|
|
52801
52944
|
res.writeHead(200, {
|
|
52802
52945
|
"Content-Type": mime,
|
|
52803
52946
|
"Content-Length": String(stat.size),
|
|
@@ -52805,7 +52948,7 @@ function streamFile(res, absPath, logger) {
|
|
|
52805
52948
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
52806
52949
|
"X-Content-Type-Options": "nosniff"
|
|
52807
52950
|
});
|
|
52808
|
-
const stream =
|
|
52951
|
+
const stream = import_node_fs30.default.createReadStream(absPath);
|
|
52809
52952
|
stream.on("error", (err) => {
|
|
52810
52953
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
52811
52954
|
res.destroy();
|
|
@@ -52814,8 +52957,8 @@ function streamFile(res, absPath, logger) {
|
|
|
52814
52957
|
}
|
|
52815
52958
|
|
|
52816
52959
|
// src/attachment/gc.ts
|
|
52817
|
-
var
|
|
52818
|
-
var
|
|
52960
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
52961
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
52819
52962
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
52820
52963
|
function runAttachmentGc(args) {
|
|
52821
52964
|
const now = (args.now ?? Date.now)();
|
|
@@ -52824,38 +52967,38 @@ function runAttachmentGc(args) {
|
|
|
52824
52967
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
52825
52968
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
52826
52969
|
if (entry.stale) continue;
|
|
52827
|
-
if (
|
|
52970
|
+
if (import_node_path34.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
52828
52971
|
}
|
|
52829
52972
|
}
|
|
52830
52973
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
52831
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
52974
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path34.default.join(
|
|
52832
52975
|
args.dataDir,
|
|
52833
52976
|
"sessions",
|
|
52834
52977
|
...scopeSubPath(scope).map(safeFileName),
|
|
52835
52978
|
safeFileName(sessionId)
|
|
52836
52979
|
);
|
|
52837
|
-
const attRoot =
|
|
52980
|
+
const attRoot = import_node_path34.default.join(sessionDir, ".attachments");
|
|
52838
52981
|
let hashDirs;
|
|
52839
52982
|
try {
|
|
52840
|
-
hashDirs =
|
|
52983
|
+
hashDirs = import_node_fs31.default.readdirSync(attRoot);
|
|
52841
52984
|
} catch (err) {
|
|
52842
52985
|
if (err.code === "ENOENT") continue;
|
|
52843
52986
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
52844
52987
|
continue;
|
|
52845
52988
|
}
|
|
52846
52989
|
for (const hashDir of hashDirs) {
|
|
52847
|
-
const hashDirAbs =
|
|
52990
|
+
const hashDirAbs = import_node_path34.default.join(attRoot, hashDir);
|
|
52848
52991
|
let files;
|
|
52849
52992
|
try {
|
|
52850
|
-
files =
|
|
52993
|
+
files = import_node_fs31.default.readdirSync(hashDirAbs);
|
|
52851
52994
|
} catch {
|
|
52852
52995
|
continue;
|
|
52853
52996
|
}
|
|
52854
52997
|
for (const name of files) {
|
|
52855
|
-
const file =
|
|
52998
|
+
const file = import_node_path34.default.join(hashDirAbs, name);
|
|
52856
52999
|
let stat;
|
|
52857
53000
|
try {
|
|
52858
|
-
stat =
|
|
53001
|
+
stat = import_node_fs31.default.statSync(file);
|
|
52859
53002
|
} catch {
|
|
52860
53003
|
continue;
|
|
52861
53004
|
}
|
|
@@ -52864,26 +53007,26 @@ function runAttachmentGc(args) {
|
|
|
52864
53007
|
if (age < ttlMs) continue;
|
|
52865
53008
|
if (liveAbs.has(file)) continue;
|
|
52866
53009
|
try {
|
|
52867
|
-
|
|
53010
|
+
import_node_fs31.default.unlinkSync(file);
|
|
52868
53011
|
} catch (err) {
|
|
52869
53012
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
52870
53013
|
}
|
|
52871
53014
|
}
|
|
52872
53015
|
try {
|
|
52873
|
-
if (
|
|
53016
|
+
if (import_node_fs31.default.readdirSync(hashDirAbs).length === 0) import_node_fs31.default.rmdirSync(hashDirAbs);
|
|
52874
53017
|
} catch {
|
|
52875
53018
|
}
|
|
52876
53019
|
}
|
|
52877
53020
|
try {
|
|
52878
|
-
if (
|
|
53021
|
+
if (import_node_fs31.default.readdirSync(attRoot).length === 0) import_node_fs31.default.rmdirSync(attRoot);
|
|
52879
53022
|
} catch {
|
|
52880
53023
|
}
|
|
52881
53024
|
}
|
|
52882
53025
|
}
|
|
52883
53026
|
|
|
52884
53027
|
// src/attachment/group.ts
|
|
52885
|
-
var
|
|
52886
|
-
var
|
|
53028
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
53029
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
52887
53030
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
52888
53031
|
init_protocol();
|
|
52889
53032
|
var GroupFileStore = class {
|
|
@@ -52895,11 +53038,11 @@ var GroupFileStore = class {
|
|
|
52895
53038
|
this.logger = opts.logger;
|
|
52896
53039
|
}
|
|
52897
53040
|
rootForScope(scope) {
|
|
52898
|
-
return
|
|
53041
|
+
return import_node_path35.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
52899
53042
|
}
|
|
52900
53043
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
52901
53044
|
filePath(scope, sessionId) {
|
|
52902
|
-
return
|
|
53045
|
+
return import_node_path35.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
52903
53046
|
}
|
|
52904
53047
|
cacheKey(scope, sessionId) {
|
|
52905
53048
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -52908,7 +53051,7 @@ var GroupFileStore = class {
|
|
|
52908
53051
|
readFile(scope, sessionId) {
|
|
52909
53052
|
const file = this.filePath(scope, sessionId);
|
|
52910
53053
|
try {
|
|
52911
|
-
const raw =
|
|
53054
|
+
const raw = import_node_fs32.default.readFileSync(file, "utf8");
|
|
52912
53055
|
const parsed = JSON.parse(raw);
|
|
52913
53056
|
if (!Array.isArray(parsed)) {
|
|
52914
53057
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -52934,10 +53077,10 @@ var GroupFileStore = class {
|
|
|
52934
53077
|
}
|
|
52935
53078
|
writeFile(scope, sessionId, entries) {
|
|
52936
53079
|
const file = this.filePath(scope, sessionId);
|
|
52937
|
-
|
|
53080
|
+
import_node_fs32.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
|
|
52938
53081
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
52939
|
-
|
|
52940
|
-
|
|
53082
|
+
import_node_fs32.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
53083
|
+
import_node_fs32.default.renameSync(tmp, file);
|
|
52941
53084
|
}
|
|
52942
53085
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
52943
53086
|
list(scope, sessionId) {
|
|
@@ -53023,10 +53166,10 @@ var GroupFileStore = class {
|
|
|
53023
53166
|
};
|
|
53024
53167
|
|
|
53025
53168
|
// src/discovery/state-file.ts
|
|
53026
|
-
var
|
|
53027
|
-
var
|
|
53169
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
53170
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
53028
53171
|
function defaultStateFilePath(dataDir) {
|
|
53029
|
-
return
|
|
53172
|
+
return import_node_path36.default.join(dataDir, "state.json");
|
|
53030
53173
|
}
|
|
53031
53174
|
function isPidAlive(pid) {
|
|
53032
53175
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -53048,7 +53191,7 @@ var StateFileManager = class {
|
|
|
53048
53191
|
}
|
|
53049
53192
|
read() {
|
|
53050
53193
|
try {
|
|
53051
|
-
const raw =
|
|
53194
|
+
const raw = import_node_fs33.default.readFileSync(this.file, "utf8");
|
|
53052
53195
|
const parsed = JSON.parse(raw);
|
|
53053
53196
|
return parsed;
|
|
53054
53197
|
} catch {
|
|
@@ -53062,20 +53205,20 @@ var StateFileManager = class {
|
|
|
53062
53205
|
return { status: "stale", existing };
|
|
53063
53206
|
}
|
|
53064
53207
|
write(state) {
|
|
53065
|
-
|
|
53208
|
+
import_node_fs33.default.mkdirSync(import_node_path36.default.dirname(this.file), { recursive: true });
|
|
53066
53209
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
53067
|
-
|
|
53068
|
-
|
|
53210
|
+
import_node_fs33.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
53211
|
+
import_node_fs33.default.renameSync(tmp, this.file);
|
|
53069
53212
|
if (process.platform !== "win32") {
|
|
53070
53213
|
try {
|
|
53071
|
-
|
|
53214
|
+
import_node_fs33.default.chmodSync(this.file, 384);
|
|
53072
53215
|
} catch {
|
|
53073
53216
|
}
|
|
53074
53217
|
}
|
|
53075
53218
|
}
|
|
53076
53219
|
delete() {
|
|
53077
53220
|
try {
|
|
53078
|
-
|
|
53221
|
+
import_node_fs33.default.unlinkSync(this.file);
|
|
53079
53222
|
} catch {
|
|
53080
53223
|
}
|
|
53081
53224
|
}
|
|
@@ -53089,14 +53232,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
53089
53232
|
}
|
|
53090
53233
|
|
|
53091
53234
|
// src/tunnel/tunnel-manager.ts
|
|
53092
|
-
var
|
|
53093
|
-
var
|
|
53235
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53236
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
53094
53237
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
53095
|
-
var
|
|
53238
|
+
var import_node_child_process10 = require("child_process");
|
|
53096
53239
|
|
|
53097
53240
|
// src/tunnel/tunnel-store.ts
|
|
53098
|
-
var
|
|
53099
|
-
var
|
|
53241
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
53242
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
53100
53243
|
var TunnelStore = class {
|
|
53101
53244
|
constructor(filePath) {
|
|
53102
53245
|
this.filePath = filePath;
|
|
@@ -53104,7 +53247,7 @@ var TunnelStore = class {
|
|
|
53104
53247
|
filePath;
|
|
53105
53248
|
async get() {
|
|
53106
53249
|
try {
|
|
53107
|
-
const raw = await
|
|
53250
|
+
const raw = await import_node_fs34.default.promises.readFile(this.filePath, "utf8");
|
|
53108
53251
|
const obj = JSON.parse(raw);
|
|
53109
53252
|
if (!isPersistedTunnel(obj)) return null;
|
|
53110
53253
|
return obj;
|
|
@@ -53115,22 +53258,22 @@ var TunnelStore = class {
|
|
|
53115
53258
|
}
|
|
53116
53259
|
}
|
|
53117
53260
|
async set(v2) {
|
|
53118
|
-
const dir =
|
|
53119
|
-
await
|
|
53261
|
+
const dir = import_node_path37.default.dirname(this.filePath);
|
|
53262
|
+
await import_node_fs34.default.promises.mkdir(dir, { recursive: true });
|
|
53120
53263
|
const data = JSON.stringify(v2, null, 2);
|
|
53121
53264
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
53122
|
-
await
|
|
53265
|
+
await import_node_fs34.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
53123
53266
|
if (process.platform !== "win32") {
|
|
53124
53267
|
try {
|
|
53125
|
-
await
|
|
53268
|
+
await import_node_fs34.default.promises.chmod(tmp, 384);
|
|
53126
53269
|
} catch {
|
|
53127
53270
|
}
|
|
53128
53271
|
}
|
|
53129
|
-
await
|
|
53272
|
+
await import_node_fs34.default.promises.rename(tmp, this.filePath);
|
|
53130
53273
|
}
|
|
53131
53274
|
async clear() {
|
|
53132
53275
|
try {
|
|
53133
|
-
await
|
|
53276
|
+
await import_node_fs34.default.promises.unlink(this.filePath);
|
|
53134
53277
|
} catch (err) {
|
|
53135
53278
|
const code = err?.code;
|
|
53136
53279
|
if (code !== "ENOENT") throw err;
|
|
@@ -53225,10 +53368,10 @@ function escape(v2) {
|
|
|
53225
53368
|
}
|
|
53226
53369
|
|
|
53227
53370
|
// src/tunnel/frpc-binary.ts
|
|
53228
|
-
var
|
|
53371
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
53229
53372
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
53230
|
-
var
|
|
53231
|
-
var
|
|
53373
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
53374
|
+
var import_node_child_process8 = require("child_process");
|
|
53232
53375
|
var import_node_stream3 = require("stream");
|
|
53233
53376
|
var import_promises5 = require("stream/promises");
|
|
53234
53377
|
var FRPC_VERSION = "0.68.0";
|
|
@@ -53259,20 +53402,20 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
53259
53402
|
}
|
|
53260
53403
|
async function ensureFrpcBinary(opts) {
|
|
53261
53404
|
if (opts.override) {
|
|
53262
|
-
if (!
|
|
53405
|
+
if (!import_node_fs35.default.existsSync(opts.override)) {
|
|
53263
53406
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
53264
53407
|
}
|
|
53265
53408
|
return opts.override;
|
|
53266
53409
|
}
|
|
53267
53410
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
53268
53411
|
const platform = opts.platform ?? detectPlatform();
|
|
53269
|
-
const binDir =
|
|
53270
|
-
|
|
53412
|
+
const binDir = import_node_path38.default.join(opts.dataDir, "bin");
|
|
53413
|
+
import_node_fs35.default.mkdirSync(binDir, { recursive: true });
|
|
53271
53414
|
cleanupStaleArtifacts(binDir);
|
|
53272
|
-
const stableBin =
|
|
53273
|
-
if (
|
|
53415
|
+
const stableBin = import_node_path38.default.join(binDir, "frpc");
|
|
53416
|
+
if (import_node_fs35.default.existsSync(stableBin)) return stableBin;
|
|
53274
53417
|
const partialBin = `${stableBin}.partial`;
|
|
53275
|
-
const tarballPath =
|
|
53418
|
+
const tarballPath = import_node_path38.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
53276
53419
|
try {
|
|
53277
53420
|
const url = frpcDownloadUrl(version2, platform);
|
|
53278
53421
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -53281,8 +53424,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
53281
53424
|
} else {
|
|
53282
53425
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
53283
53426
|
}
|
|
53284
|
-
|
|
53285
|
-
|
|
53427
|
+
import_node_fs35.default.chmodSync(partialBin, 493);
|
|
53428
|
+
import_node_fs35.default.renameSync(partialBin, stableBin);
|
|
53286
53429
|
} finally {
|
|
53287
53430
|
safeUnlink(tarballPath);
|
|
53288
53431
|
safeUnlink(partialBin);
|
|
@@ -53292,15 +53435,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
53292
53435
|
function cleanupStaleArtifacts(binDir) {
|
|
53293
53436
|
let entries;
|
|
53294
53437
|
try {
|
|
53295
|
-
entries =
|
|
53438
|
+
entries = import_node_fs35.default.readdirSync(binDir);
|
|
53296
53439
|
} catch {
|
|
53297
53440
|
return;
|
|
53298
53441
|
}
|
|
53299
53442
|
for (const name of entries) {
|
|
53300
53443
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
53301
|
-
const full =
|
|
53444
|
+
const full = import_node_path38.default.join(binDir, name);
|
|
53302
53445
|
try {
|
|
53303
|
-
|
|
53446
|
+
import_node_fs35.default.rmSync(full, { recursive: true, force: true });
|
|
53304
53447
|
} catch {
|
|
53305
53448
|
}
|
|
53306
53449
|
}
|
|
@@ -53308,7 +53451,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
53308
53451
|
}
|
|
53309
53452
|
function safeUnlink(p2) {
|
|
53310
53453
|
try {
|
|
53311
|
-
|
|
53454
|
+
import_node_fs35.default.unlinkSync(p2);
|
|
53312
53455
|
} catch {
|
|
53313
53456
|
}
|
|
53314
53457
|
}
|
|
@@ -53319,46 +53462,46 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
53319
53462
|
if (!res.ok || !res.body) {
|
|
53320
53463
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
53321
53464
|
}
|
|
53322
|
-
const out =
|
|
53465
|
+
const out = import_node_fs35.default.createWriteStream(dest);
|
|
53323
53466
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
53324
53467
|
await (0, import_promises5.pipeline)(nodeStream, out);
|
|
53325
53468
|
}
|
|
53326
53469
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
53327
|
-
const work =
|
|
53328
|
-
|
|
53470
|
+
const work = import_node_path38.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
53471
|
+
import_node_fs35.default.mkdirSync(work, { recursive: true });
|
|
53329
53472
|
try {
|
|
53330
53473
|
await new Promise((resolve6, reject) => {
|
|
53331
|
-
const proc = (0,
|
|
53474
|
+
const proc = (0, import_node_child_process8.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
53332
53475
|
proc.on("error", reject);
|
|
53333
53476
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
53334
53477
|
});
|
|
53335
53478
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
53336
|
-
const src =
|
|
53337
|
-
if (!
|
|
53479
|
+
const src = import_node_path38.default.join(work, dirName, "frpc");
|
|
53480
|
+
if (!import_node_fs35.default.existsSync(src)) {
|
|
53338
53481
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
53339
53482
|
}
|
|
53340
|
-
|
|
53483
|
+
import_node_fs35.default.copyFileSync(src, destBin);
|
|
53341
53484
|
} finally {
|
|
53342
|
-
|
|
53485
|
+
import_node_fs35.default.rmSync(work, { recursive: true, force: true });
|
|
53343
53486
|
}
|
|
53344
53487
|
}
|
|
53345
53488
|
|
|
53346
53489
|
// src/tunnel/frpc-process.ts
|
|
53347
|
-
var
|
|
53348
|
-
var
|
|
53349
|
-
var
|
|
53490
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
53491
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53492
|
+
var import_node_child_process9 = require("child_process");
|
|
53350
53493
|
function frpcPidFilePath(dataDir) {
|
|
53351
|
-
return
|
|
53494
|
+
return import_node_path39.default.join(dataDir, "frpc.pid");
|
|
53352
53495
|
}
|
|
53353
53496
|
function writeFrpcPid(dataDir, pid) {
|
|
53354
53497
|
try {
|
|
53355
|
-
|
|
53498
|
+
import_node_fs36.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
53356
53499
|
} catch {
|
|
53357
53500
|
}
|
|
53358
53501
|
}
|
|
53359
53502
|
function clearFrpcPid(dataDir) {
|
|
53360
53503
|
try {
|
|
53361
|
-
|
|
53504
|
+
import_node_fs36.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
53362
53505
|
} catch {
|
|
53363
53506
|
}
|
|
53364
53507
|
}
|
|
@@ -53374,7 +53517,7 @@ function defaultIsPidAlive(pid) {
|
|
|
53374
53517
|
}
|
|
53375
53518
|
function defaultReadPidFile(file) {
|
|
53376
53519
|
try {
|
|
53377
|
-
return
|
|
53520
|
+
return import_node_fs36.default.readFileSync(file, "utf8");
|
|
53378
53521
|
} catch {
|
|
53379
53522
|
return null;
|
|
53380
53523
|
}
|
|
@@ -53390,7 +53533,7 @@ function defaultSleep(ms) {
|
|
|
53390
53533
|
}
|
|
53391
53534
|
async function killStaleFrpc(deps) {
|
|
53392
53535
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
53393
|
-
const tomlPath =
|
|
53536
|
+
const tomlPath = import_node_path39.default.join(deps.dataDir, "frpc.toml");
|
|
53394
53537
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
53395
53538
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
53396
53539
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -53414,7 +53557,7 @@ async function killStaleFrpc(deps) {
|
|
|
53414
53557
|
}
|
|
53415
53558
|
if (victims.size === 0) {
|
|
53416
53559
|
try {
|
|
53417
|
-
|
|
53560
|
+
import_node_fs36.default.unlinkSync(pidFile);
|
|
53418
53561
|
} catch {
|
|
53419
53562
|
}
|
|
53420
53563
|
return;
|
|
@@ -53425,14 +53568,14 @@ async function killStaleFrpc(deps) {
|
|
|
53425
53568
|
}
|
|
53426
53569
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
53427
53570
|
try {
|
|
53428
|
-
|
|
53571
|
+
import_node_fs36.default.unlinkSync(pidFile);
|
|
53429
53572
|
} catch {
|
|
53430
53573
|
}
|
|
53431
53574
|
}
|
|
53432
53575
|
async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
|
|
53433
53576
|
if (process.platform === "win32") return [];
|
|
53434
53577
|
return new Promise((resolve6) => {
|
|
53435
|
-
const ps = (0,
|
|
53578
|
+
const ps = (0, import_node_child_process9.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
|
|
53436
53579
|
let buf = "";
|
|
53437
53580
|
ps.stdout.on("data", (c) => {
|
|
53438
53581
|
buf += c.toString();
|
|
@@ -53462,7 +53605,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
53462
53605
|
var TunnelManager = class {
|
|
53463
53606
|
constructor(deps) {
|
|
53464
53607
|
this.deps = deps;
|
|
53465
|
-
this.store = deps.store ?? new TunnelStore(
|
|
53608
|
+
this.store = deps.store ?? new TunnelStore(import_node_path40.default.join(deps.dataDir, "tunnel.json"));
|
|
53466
53609
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
53467
53610
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
53468
53611
|
}
|
|
@@ -53589,7 +53732,7 @@ var TunnelManager = class {
|
|
|
53589
53732
|
dataDir: this.deps.dataDir,
|
|
53590
53733
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
53591
53734
|
});
|
|
53592
|
-
const tomlPath =
|
|
53735
|
+
const tomlPath = import_node_path40.default.join(this.deps.dataDir, "frpc.toml");
|
|
53593
53736
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
|
|
53594
53737
|
const toml = buildFrpcToml({
|
|
53595
53738
|
serverAddr: t.frpsHost,
|
|
@@ -53600,14 +53743,14 @@ var TunnelManager = class {
|
|
|
53600
53743
|
localPort,
|
|
53601
53744
|
logLevel: "info"
|
|
53602
53745
|
});
|
|
53603
|
-
await
|
|
53604
|
-
const proc = (this.deps.spawnImpl ??
|
|
53746
|
+
await import_node_fs37.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
53747
|
+
const proc = (this.deps.spawnImpl ?? import_node_child_process10.spawn)(frpcBin, ["-c", tomlPath], {
|
|
53605
53748
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53606
53749
|
});
|
|
53607
|
-
const logDir =
|
|
53608
|
-
|
|
53609
|
-
const logFilePath =
|
|
53610
|
-
const logStream =
|
|
53750
|
+
const logDir = import_node_path40.default.join(this.deps.dataDir, "log");
|
|
53751
|
+
import_node_fs37.default.mkdirSync(logDir, { recursive: true });
|
|
53752
|
+
const logFilePath = import_node_path40.default.join(logDir, "frpc.log");
|
|
53753
|
+
const logStream = import_node_fs37.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
53611
53754
|
logStream.on("error", () => {
|
|
53612
53755
|
});
|
|
53613
53756
|
const tee = (chunk) => {
|
|
@@ -53690,27 +53833,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
53690
53833
|
|
|
53691
53834
|
// src/tunnel/device-key.ts
|
|
53692
53835
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
53693
|
-
var
|
|
53836
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
53694
53837
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
53695
53838
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
53696
53839
|
function deriveStableDeviceKey(opts = {}) {
|
|
53697
53840
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
53698
53841
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
53699
53842
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
53700
|
-
const defaultDataDir =
|
|
53701
|
-
const normalizedDataDir = opts.dataDir ?
|
|
53843
|
+
const defaultDataDir = import_node_path41.default.resolve(import_node_path41.default.join(home, ".clawd"));
|
|
53844
|
+
const normalizedDataDir = opts.dataDir ? import_node_path41.default.resolve(opts.dataDir) : null;
|
|
53702
53845
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
53703
53846
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
53704
53847
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
53705
53848
|
}
|
|
53706
53849
|
|
|
53707
53850
|
// src/auth-store.ts
|
|
53708
|
-
var
|
|
53709
|
-
var
|
|
53851
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53852
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
53710
53853
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
53711
53854
|
var AUTH_FILE_NAME = "auth.json";
|
|
53712
53855
|
function authFilePath(dataDir) {
|
|
53713
|
-
return
|
|
53856
|
+
return import_node_path42.default.join(dataDir, AUTH_FILE_NAME);
|
|
53714
53857
|
}
|
|
53715
53858
|
function loadOrCreateAuthFile(opts) {
|
|
53716
53859
|
const file = authFilePath(opts.dataDir);
|
|
@@ -53746,7 +53889,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
53746
53889
|
}
|
|
53747
53890
|
function readAuthFile(file) {
|
|
53748
53891
|
try {
|
|
53749
|
-
const raw =
|
|
53892
|
+
const raw = import_node_fs38.default.readFileSync(file, "utf8");
|
|
53750
53893
|
const parsed = JSON.parse(raw);
|
|
53751
53894
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
53752
53895
|
return null;
|
|
@@ -53766,25 +53909,25 @@ function readAuthFile(file) {
|
|
|
53766
53909
|
}
|
|
53767
53910
|
}
|
|
53768
53911
|
function writeAuthFile(file, content) {
|
|
53769
|
-
|
|
53770
|
-
|
|
53912
|
+
import_node_fs38.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
|
|
53913
|
+
import_node_fs38.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
53771
53914
|
try {
|
|
53772
|
-
|
|
53915
|
+
import_node_fs38.default.chmodSync(file, 384);
|
|
53773
53916
|
} catch {
|
|
53774
53917
|
}
|
|
53775
53918
|
}
|
|
53776
53919
|
|
|
53777
53920
|
// src/owner-profile.ts
|
|
53778
|
-
var
|
|
53921
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
53779
53922
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
53780
|
-
var
|
|
53923
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
53781
53924
|
var PROFILE_FILENAME = "profile.json";
|
|
53782
53925
|
function loadOwnerDisplayName(dataDir) {
|
|
53783
53926
|
const fallback = import_node_os15.default.userInfo().username;
|
|
53784
|
-
const profilePath =
|
|
53927
|
+
const profilePath = import_node_path43.default.join(dataDir, PROFILE_FILENAME);
|
|
53785
53928
|
let raw;
|
|
53786
53929
|
try {
|
|
53787
|
-
raw =
|
|
53930
|
+
raw = import_node_fs39.default.readFileSync(profilePath, "utf8");
|
|
53788
53931
|
} catch {
|
|
53789
53932
|
return fallback;
|
|
53790
53933
|
}
|
|
@@ -53807,18 +53950,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
53807
53950
|
}
|
|
53808
53951
|
|
|
53809
53952
|
// src/feishu-auth/owner-identity-store.ts
|
|
53810
|
-
var
|
|
53811
|
-
var
|
|
53953
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
53954
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
53812
53955
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
53813
53956
|
var OwnerIdentityStore = class {
|
|
53814
53957
|
file;
|
|
53815
53958
|
constructor(dataDir) {
|
|
53816
|
-
this.file =
|
|
53959
|
+
this.file = import_node_path44.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
53817
53960
|
}
|
|
53818
53961
|
read() {
|
|
53819
53962
|
let raw;
|
|
53820
53963
|
try {
|
|
53821
|
-
raw =
|
|
53964
|
+
raw = import_node_fs40.default.readFileSync(this.file, "utf8");
|
|
53822
53965
|
} catch {
|
|
53823
53966
|
return null;
|
|
53824
53967
|
}
|
|
@@ -53846,16 +53989,16 @@ var OwnerIdentityStore = class {
|
|
|
53846
53989
|
};
|
|
53847
53990
|
}
|
|
53848
53991
|
write(record) {
|
|
53849
|
-
|
|
53850
|
-
|
|
53992
|
+
import_node_fs40.default.mkdirSync(import_node_path44.default.dirname(this.file), { recursive: true });
|
|
53993
|
+
import_node_fs40.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
53851
53994
|
try {
|
|
53852
|
-
|
|
53995
|
+
import_node_fs40.default.chmodSync(this.file, 384);
|
|
53853
53996
|
} catch {
|
|
53854
53997
|
}
|
|
53855
53998
|
}
|
|
53856
53999
|
clear() {
|
|
53857
54000
|
try {
|
|
53858
|
-
|
|
54001
|
+
import_node_fs40.default.unlinkSync(this.file);
|
|
53859
54002
|
} catch (err) {
|
|
53860
54003
|
const code = err?.code;
|
|
53861
54004
|
if (code !== "ENOENT") throw err;
|
|
@@ -53992,9 +54135,9 @@ var CentralClientError = class extends Error {
|
|
|
53992
54135
|
code;
|
|
53993
54136
|
cause;
|
|
53994
54137
|
};
|
|
53995
|
-
async function centralRequest(opts,
|
|
54138
|
+
async function centralRequest(opts, path74, init) {
|
|
53996
54139
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
53997
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
54140
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path74}`;
|
|
53998
54141
|
const ctrl = new AbortController();
|
|
53999
54142
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
54000
54143
|
let res;
|
|
@@ -54188,8 +54331,8 @@ function verifyConnectToken(args) {
|
|
|
54188
54331
|
}
|
|
54189
54332
|
|
|
54190
54333
|
// src/feishu-auth/server-key.ts
|
|
54191
|
-
var
|
|
54192
|
-
var
|
|
54334
|
+
var fs51 = __toESM(require("fs"), 1);
|
|
54335
|
+
var path53 = __toESM(require("path"), 1);
|
|
54193
54336
|
var FILE_NAME2 = "server-signing-key.json";
|
|
54194
54337
|
var ServerKeyStore = class {
|
|
54195
54338
|
constructor(dataDir) {
|
|
@@ -54197,12 +54340,12 @@ var ServerKeyStore = class {
|
|
|
54197
54340
|
}
|
|
54198
54341
|
dataDir;
|
|
54199
54342
|
filePath() {
|
|
54200
|
-
return
|
|
54343
|
+
return path53.join(this.dataDir, FILE_NAME2);
|
|
54201
54344
|
}
|
|
54202
54345
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
54203
54346
|
read() {
|
|
54204
54347
|
try {
|
|
54205
|
-
const raw =
|
|
54348
|
+
const raw = fs51.readFileSync(this.filePath(), "utf8");
|
|
54206
54349
|
const parsed = JSON.parse(raw);
|
|
54207
54350
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
54208
54351
|
return parsed.publicKeyPem;
|
|
@@ -54217,12 +54360,12 @@ var ServerKeyStore = class {
|
|
|
54217
54360
|
publicKeyPem,
|
|
54218
54361
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54219
54362
|
};
|
|
54220
|
-
|
|
54221
|
-
|
|
54363
|
+
fs51.mkdirSync(this.dataDir, { recursive: true });
|
|
54364
|
+
fs51.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
54222
54365
|
}
|
|
54223
54366
|
clear() {
|
|
54224
54367
|
try {
|
|
54225
|
-
|
|
54368
|
+
fs51.unlinkSync(this.filePath());
|
|
54226
54369
|
} catch {
|
|
54227
54370
|
}
|
|
54228
54371
|
}
|
|
@@ -54235,12 +54378,12 @@ init_protocol();
|
|
|
54235
54378
|
init_protocol();
|
|
54236
54379
|
|
|
54237
54380
|
// src/session/fork.ts
|
|
54238
|
-
var
|
|
54381
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
54239
54382
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
54240
|
-
var
|
|
54383
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54241
54384
|
init_claude_history();
|
|
54242
54385
|
function readJsonlEntries(file) {
|
|
54243
|
-
const raw =
|
|
54386
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
54244
54387
|
const out = [];
|
|
54245
54388
|
for (const line of raw.split("\n")) {
|
|
54246
54389
|
const t = line.trim();
|
|
@@ -54253,19 +54396,19 @@ function readJsonlEntries(file) {
|
|
|
54253
54396
|
return out;
|
|
54254
54397
|
}
|
|
54255
54398
|
function forkSession(input) {
|
|
54256
|
-
const baseDir = input.baseDir ??
|
|
54257
|
-
let projectDir =
|
|
54258
|
-
let sourceFile =
|
|
54259
|
-
if (!
|
|
54399
|
+
const baseDir = input.baseDir ?? import_node_path45.default.join(import_node_os16.default.homedir(), ".claude");
|
|
54400
|
+
let projectDir = import_node_path45.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
54401
|
+
let sourceFile = import_node_path45.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
54402
|
+
if (!import_node_fs41.default.existsSync(sourceFile)) {
|
|
54260
54403
|
const found = findTranscriptByToolSessionId(
|
|
54261
|
-
|
|
54404
|
+
import_node_path45.default.join(baseDir, "projects"),
|
|
54262
54405
|
input.toolSessionId
|
|
54263
54406
|
);
|
|
54264
54407
|
if (!found) {
|
|
54265
54408
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
54266
54409
|
}
|
|
54267
54410
|
sourceFile = found;
|
|
54268
|
-
projectDir =
|
|
54411
|
+
projectDir = import_node_path45.default.dirname(found);
|
|
54269
54412
|
}
|
|
54270
54413
|
const entries = readJsonlEntries(sourceFile);
|
|
54271
54414
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -54294,9 +54437,9 @@ function forkSession(input) {
|
|
|
54294
54437
|
}
|
|
54295
54438
|
forkedLines.push(JSON.stringify(forked));
|
|
54296
54439
|
}
|
|
54297
|
-
const forkedFilePath =
|
|
54298
|
-
|
|
54299
|
-
|
|
54440
|
+
const forkedFilePath = import_node_path45.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
54441
|
+
import_node_fs41.default.mkdirSync(projectDir, { recursive: true });
|
|
54442
|
+
import_node_fs41.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
54300
54443
|
return { forkedToolSessionId, forkedFilePath };
|
|
54301
54444
|
}
|
|
54302
54445
|
|
|
@@ -54458,21 +54601,34 @@ function buildSessionHandlers(deps) {
|
|
|
54458
54601
|
const { broadcast } = await manager.interrupt(args);
|
|
54459
54602
|
return { response: { type: "session:interrupt", ok: true }, broadcast };
|
|
54460
54603
|
};
|
|
54604
|
+
const ensureRewindSupported = async (sessionId) => {
|
|
54605
|
+
const file = manager.get({ sessionId }).response;
|
|
54606
|
+
const caps = await getAdapter2(file.tool ?? "claude").capabilities();
|
|
54607
|
+
if (caps.features.rewind === false) {
|
|
54608
|
+
throw new ClawdError(
|
|
54609
|
+
ERROR_CODES.TOOL_NOT_SUPPORTED,
|
|
54610
|
+
`tool ${file.tool ?? "claude"} does not support rewind`
|
|
54611
|
+
);
|
|
54612
|
+
}
|
|
54613
|
+
};
|
|
54461
54614
|
const rewind = async (frame, _client, ctx) => {
|
|
54462
54615
|
const args = SessionRewindArgs.parse(frame);
|
|
54463
54616
|
ensureSessionAccess(ctx, args.sessionId, "send");
|
|
54617
|
+
await ensureRewindSupported(args.sessionId);
|
|
54464
54618
|
const { response, broadcast } = await manager.rewind(args);
|
|
54465
54619
|
return { response: { type: "session:rewind", ...response }, broadcast };
|
|
54466
54620
|
};
|
|
54467
54621
|
const rewindDiff = async (frame, _client, ctx) => {
|
|
54468
54622
|
const args = SessionRewindDiffArgs.parse(frame);
|
|
54469
54623
|
ensureSessionAccess(ctx, args.sessionId, "read");
|
|
54624
|
+
await ensureRewindSupported(args.sessionId);
|
|
54470
54625
|
const { response } = await manager.rewindDiff(args);
|
|
54471
54626
|
return { response: { type: "session:rewind-diff", ...response } };
|
|
54472
54627
|
};
|
|
54473
54628
|
const rewindableMessageIds = async (frame, _client, ctx) => {
|
|
54474
54629
|
const args = SessionRewindableMessageIdsArgs.parse(frame);
|
|
54475
54630
|
ensureSessionAccess(ctx, args.sessionId, "read");
|
|
54631
|
+
await ensureRewindSupported(args.sessionId);
|
|
54476
54632
|
const { response } = manager.rewindableMessageIds(args);
|
|
54477
54633
|
return {
|
|
54478
54634
|
response: { type: "session:rewindable-message-ids", ...response }
|
|
@@ -54695,7 +54851,7 @@ function buildPermissionHandlers(deps) {
|
|
|
54695
54851
|
}
|
|
54696
54852
|
|
|
54697
54853
|
// src/handlers/history.ts
|
|
54698
|
-
var
|
|
54854
|
+
var path56 = __toESM(require("path"), 1);
|
|
54699
54855
|
init_protocol();
|
|
54700
54856
|
|
|
54701
54857
|
// src/session/recent-dirs.ts
|
|
@@ -54713,7 +54869,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
54713
54869
|
}
|
|
54714
54870
|
|
|
54715
54871
|
// src/permission/persona-paths.ts
|
|
54716
|
-
var
|
|
54872
|
+
var path55 = __toESM(require("path"), 1);
|
|
54717
54873
|
function getAllowedPersonaIds(grants, action) {
|
|
54718
54874
|
const ids = /* @__PURE__ */ new Set();
|
|
54719
54875
|
for (const g2 of grants) {
|
|
@@ -54726,42 +54882,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
54726
54882
|
return ids;
|
|
54727
54883
|
}
|
|
54728
54884
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
54729
|
-
const target =
|
|
54885
|
+
const target = path55.resolve(absPath);
|
|
54730
54886
|
if (userWorkDir) {
|
|
54731
|
-
const u =
|
|
54732
|
-
const usep = u.endsWith(
|
|
54887
|
+
const u = path55.resolve(userWorkDir);
|
|
54888
|
+
const usep = u.endsWith(path55.sep) ? "" : path55.sep;
|
|
54733
54889
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
54734
54890
|
}
|
|
54735
|
-
const root =
|
|
54736
|
-
const sep3 = root.endsWith(
|
|
54891
|
+
const root = path55.resolve(personaRoot);
|
|
54892
|
+
const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
|
|
54737
54893
|
if (!target.startsWith(root + sep3)) return false;
|
|
54738
|
-
const rel =
|
|
54894
|
+
const rel = path55.relative(root, target);
|
|
54739
54895
|
if (!rel || rel.startsWith("..")) return false;
|
|
54740
|
-
const personaId = rel.split(
|
|
54896
|
+
const personaId = rel.split(path55.sep)[0];
|
|
54741
54897
|
if (!personaId) return false;
|
|
54742
54898
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54743
54899
|
if (allowed === "*") return true;
|
|
54744
54900
|
return allowed.has(personaId);
|
|
54745
54901
|
}
|
|
54746
54902
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54747
|
-
const root =
|
|
54748
|
-
const target =
|
|
54749
|
-
const sep3 = root.endsWith(
|
|
54903
|
+
const root = path55.resolve(personaRoot);
|
|
54904
|
+
const target = path55.resolve(absPath);
|
|
54905
|
+
const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
|
|
54750
54906
|
if (!target.startsWith(root + sep3)) return null;
|
|
54751
|
-
const rel =
|
|
54907
|
+
const rel = path55.relative(root, target);
|
|
54752
54908
|
if (!rel || rel.startsWith("..")) return null;
|
|
54753
|
-
const id = rel.split(
|
|
54909
|
+
const id = rel.split(path55.sep)[0];
|
|
54754
54910
|
return id || null;
|
|
54755
54911
|
}
|
|
54756
54912
|
function isPathWithin(dir, absPath) {
|
|
54757
|
-
const d =
|
|
54758
|
-
const t =
|
|
54759
|
-
const sep3 = d.endsWith(
|
|
54913
|
+
const d = path55.resolve(dir);
|
|
54914
|
+
const t = path55.resolve(absPath);
|
|
54915
|
+
const sep3 = d.endsWith(path55.sep) ? "" : path55.sep;
|
|
54760
54916
|
return t === d || t.startsWith(d + sep3);
|
|
54761
54917
|
}
|
|
54762
54918
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
54763
54919
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54764
|
-
return personaIdFromPath(
|
|
54920
|
+
return personaIdFromPath(path55.resolve(absPath), personaRoot) === personaId;
|
|
54765
54921
|
}
|
|
54766
54922
|
|
|
54767
54923
|
// src/handlers/history.ts
|
|
@@ -54813,7 +54969,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54813
54969
|
if (!pid) return false;
|
|
54814
54970
|
return isGuestPathAllowed(
|
|
54815
54971
|
ctx.grants,
|
|
54816
|
-
|
|
54972
|
+
path56.join(personaRoot, pid),
|
|
54817
54973
|
personaRoot,
|
|
54818
54974
|
"read",
|
|
54819
54975
|
userWorkDir
|
|
@@ -54825,7 +54981,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54825
54981
|
};
|
|
54826
54982
|
const list = async (frame, _client, ctx) => {
|
|
54827
54983
|
const args = HistoryListArgs.parse(frame);
|
|
54828
|
-
assertGuestPath(ctx,
|
|
54984
|
+
assertGuestPath(ctx, path56.resolve(args.projectPath), personaRoot, "history:list");
|
|
54829
54985
|
const sessions = await history.listSessions(args);
|
|
54830
54986
|
return { response: { type: "history:list", sessions } };
|
|
54831
54987
|
};
|
|
@@ -54858,13 +55014,13 @@ function buildHistoryHandlers(deps) {
|
|
|
54858
55014
|
};
|
|
54859
55015
|
const subagents = async (frame, _client, ctx) => {
|
|
54860
55016
|
const args = HistorySubagentsArgs.parse(frame);
|
|
54861
|
-
assertGuestPath(ctx,
|
|
55017
|
+
assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
54862
55018
|
const subs = await history.listSubagents(args);
|
|
54863
55019
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
54864
55020
|
};
|
|
54865
55021
|
const subagentRead = async (frame, _client, ctx) => {
|
|
54866
55022
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
54867
|
-
assertGuestPath(ctx,
|
|
55023
|
+
assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
54868
55024
|
const res = await history.readSubagent(args);
|
|
54869
55025
|
return { response: { type: "history:subagent-read", ...res } };
|
|
54870
55026
|
};
|
|
@@ -54873,7 +55029,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54873
55029
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54874
55030
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54875
55031
|
const filtered = dirs.filter(
|
|
54876
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
55032
|
+
(d) => isGuestPathAllowed(ctx.grants, path56.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
54877
55033
|
);
|
|
54878
55034
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
54879
55035
|
}
|
|
@@ -54890,7 +55046,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54890
55046
|
}
|
|
54891
55047
|
|
|
54892
55048
|
// src/handlers/workspace.ts
|
|
54893
|
-
var
|
|
55049
|
+
var path57 = __toESM(require("path"), 1);
|
|
54894
55050
|
var os16 = __toESM(require("os"), 1);
|
|
54895
55051
|
init_protocol();
|
|
54896
55052
|
init_protocol();
|
|
@@ -54932,22 +55088,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54932
55088
|
const args = WorkspaceListArgs.parse(frame);
|
|
54933
55089
|
const isGuest = ctx?.principal.kind === "guest";
|
|
54934
55090
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
54935
|
-
const resolvedCwd =
|
|
54936
|
-
const target = args.path ?
|
|
55091
|
+
const resolvedCwd = path57.resolve(args.cwd ?? fallbackCwd);
|
|
55092
|
+
const target = args.path ? path57.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
54937
55093
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
54938
55094
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
54939
55095
|
return { response: { type: "workspace:list", ...res } };
|
|
54940
55096
|
};
|
|
54941
55097
|
const read = async (frame, _client, ctx) => {
|
|
54942
55098
|
const args = WorkspaceReadArgs.parse(frame);
|
|
54943
|
-
const target =
|
|
55099
|
+
const target = path57.isAbsolute(args.path) ? path57.resolve(args.path) : path57.resolve(args.cwd, args.path);
|
|
54944
55100
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
54945
55101
|
const res = workspace.read(args);
|
|
54946
55102
|
return { response: { type: "workspace:read", ...res } };
|
|
54947
55103
|
};
|
|
54948
55104
|
const skillsList = async (frame, _client, ctx) => {
|
|
54949
55105
|
const args = SkillsListArgs.parse(frame);
|
|
54950
|
-
const cwdAbs =
|
|
55106
|
+
const cwdAbs = path57.resolve(args.cwd);
|
|
54951
55107
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
54952
55108
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
54953
55109
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -54959,7 +55115,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54959
55115
|
};
|
|
54960
55116
|
const agentsList = async (frame, _client, ctx) => {
|
|
54961
55117
|
const args = AgentsListArgs.parse(frame);
|
|
54962
|
-
const cwdAbs =
|
|
55118
|
+
const cwdAbs = path57.resolve(args.cwd);
|
|
54963
55119
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
54964
55120
|
if (args.tool === "codex") {
|
|
54965
55121
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -54981,20 +55137,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54981
55137
|
}
|
|
54982
55138
|
|
|
54983
55139
|
// src/handlers/git.ts
|
|
54984
|
-
var
|
|
55140
|
+
var path59 = __toESM(require("path"), 1);
|
|
54985
55141
|
init_protocol();
|
|
54986
55142
|
init_protocol();
|
|
54987
55143
|
|
|
54988
55144
|
// src/workspace/git.ts
|
|
54989
|
-
var
|
|
54990
|
-
var
|
|
54991
|
-
var
|
|
55145
|
+
var import_node_child_process11 = require("child_process");
|
|
55146
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
55147
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54992
55148
|
var import_node_util = require("util");
|
|
54993
|
-
var pexec = (0, import_node_util.promisify)(
|
|
55149
|
+
var pexec = (0, import_node_util.promisify)(import_node_child_process11.execFile);
|
|
54994
55150
|
function normalizePath(p2) {
|
|
54995
|
-
const resolved =
|
|
55151
|
+
const resolved = import_node_path46.default.resolve(p2);
|
|
54996
55152
|
try {
|
|
54997
|
-
return
|
|
55153
|
+
return import_node_fs42.default.realpathSync(resolved);
|
|
54998
55154
|
} catch {
|
|
54999
55155
|
return resolved;
|
|
55000
55156
|
}
|
|
@@ -55068,7 +55224,7 @@ async function listGitBranches(cwd) {
|
|
|
55068
55224
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
55069
55225
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
55070
55226
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
55071
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
55227
|
+
if (!isGuestPathAllowed(ctx.grants, path59.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
55072
55228
|
throw new ClawdError(
|
|
55073
55229
|
ERROR_CODES.UNAUTHORIZED,
|
|
55074
55230
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -55754,7 +55910,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55754
55910
|
}
|
|
55755
55911
|
|
|
55756
55912
|
// src/handlers/attachment.ts
|
|
55757
|
-
var
|
|
55913
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
55758
55914
|
init_protocol();
|
|
55759
55915
|
init_protocol();
|
|
55760
55916
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -55834,12 +55990,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
55834
55990
|
`session ${args.sessionId} scope unresolved`
|
|
55835
55991
|
);
|
|
55836
55992
|
}
|
|
55837
|
-
const cwdAbs =
|
|
55838
|
-
const candidateAbs =
|
|
55993
|
+
const cwdAbs = import_node_path47.default.resolve(sessionFile.cwd);
|
|
55994
|
+
const candidateAbs = import_node_path47.default.isAbsolute(args.relPath) ? import_node_path47.default.resolve(args.relPath) : import_node_path47.default.resolve(cwdAbs, args.relPath);
|
|
55839
55995
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
55840
55996
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
55841
55997
|
const entry = entries.find((e) => {
|
|
55842
|
-
const storedAbs =
|
|
55998
|
+
const storedAbs = import_node_path47.default.isAbsolute(e.relPath) ? import_node_path47.default.resolve(e.relPath) : import_node_path47.default.resolve(cwdAbs, e.relPath);
|
|
55843
55999
|
return storedAbs === candidateAbs && !e.stale;
|
|
55844
56000
|
});
|
|
55845
56001
|
if (!entry) {
|
|
@@ -55864,7 +56020,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
55864
56020
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
55865
56021
|
const f = deps.sessionStore.read(sessionId);
|
|
55866
56022
|
if (!f) return;
|
|
55867
|
-
assertGuestAttachmentPath(ctx,
|
|
56023
|
+
assertGuestAttachmentPath(ctx, import_node_path47.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
55868
56024
|
}
|
|
55869
56025
|
const groupAdd = async (frame, _client, ctx) => {
|
|
55870
56026
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -55879,8 +56035,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
55879
56035
|
if (!scope) {
|
|
55880
56036
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
55881
56037
|
}
|
|
55882
|
-
const cwdAbs =
|
|
55883
|
-
const candidateAbs =
|
|
56038
|
+
const cwdAbs = import_node_path47.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
56039
|
+
const candidateAbs = import_node_path47.default.isAbsolute(args.relPath) ? import_node_path47.default.resolve(args.relPath) : import_node_path47.default.resolve(cwdAbs, args.relPath);
|
|
55884
56040
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
55885
56041
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
55886
56042
|
const size = 0;
|
|
@@ -55939,19 +56095,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
55939
56095
|
|
|
55940
56096
|
// src/handlers/extension.ts
|
|
55941
56097
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
55942
|
-
var
|
|
56098
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
55943
56099
|
init_protocol();
|
|
55944
56100
|
|
|
55945
56101
|
// src/extension/bundle-zip.ts
|
|
55946
56102
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
55947
|
-
var
|
|
56103
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
55948
56104
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
55949
56105
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
55950
56106
|
async function bundleExtensionDir(dir) {
|
|
55951
56107
|
const entries = await listFilesSorted(dir);
|
|
55952
56108
|
const zip = new import_jszip2.default();
|
|
55953
56109
|
for (const rel of entries) {
|
|
55954
|
-
const abs =
|
|
56110
|
+
const abs = import_node_path48.default.join(dir, rel);
|
|
55955
56111
|
const content = await import_promises6.default.readFile(abs);
|
|
55956
56112
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
55957
56113
|
}
|
|
@@ -55972,7 +56128,7 @@ async function listFilesSorted(rootDir) {
|
|
|
55972
56128
|
return out;
|
|
55973
56129
|
}
|
|
55974
56130
|
async function walk(absRoot, relPrefix, out) {
|
|
55975
|
-
const dirAbs =
|
|
56131
|
+
const dirAbs = import_node_path48.default.join(absRoot, relPrefix);
|
|
55976
56132
|
const entries = await import_promises6.default.readdir(dirAbs, { withFileTypes: true });
|
|
55977
56133
|
for (const e of entries) {
|
|
55978
56134
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -56026,25 +56182,25 @@ function computePublishCheck(args) {
|
|
|
56026
56182
|
|
|
56027
56183
|
// src/extension/install-flow.ts
|
|
56028
56184
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
56029
|
-
var
|
|
56185
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56030
56186
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
56031
56187
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
56032
56188
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
56033
56189
|
|
|
56034
56190
|
// src/extension/paths.ts
|
|
56035
56191
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
56036
|
-
var
|
|
56192
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
56037
56193
|
function clawdHomeRoot(override) {
|
|
56038
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
56194
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path49.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
56039
56195
|
}
|
|
56040
56196
|
function extensionsRoot(override) {
|
|
56041
|
-
return
|
|
56197
|
+
return import_node_path49.default.join(clawdHomeRoot(override), "extensions");
|
|
56042
56198
|
}
|
|
56043
56199
|
function publishedChannelsFile(override) {
|
|
56044
|
-
return
|
|
56200
|
+
return import_node_path49.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
56045
56201
|
}
|
|
56046
56202
|
function bundleCacheRoot(override) {
|
|
56047
|
-
return
|
|
56203
|
+
return import_node_path49.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
56048
56204
|
}
|
|
56049
56205
|
|
|
56050
56206
|
// src/extension/install-flow.ts
|
|
@@ -56071,7 +56227,7 @@ async function installFromChannel(args, deps) {
|
|
|
56071
56227
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56072
56228
|
}
|
|
56073
56229
|
for (const name of Object.keys(zip.files)) {
|
|
56074
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56230
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path50.default.isAbsolute(name)) {
|
|
56075
56231
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56076
56232
|
}
|
|
56077
56233
|
}
|
|
@@ -56103,7 +56259,7 @@ async function installFromChannel(args, deps) {
|
|
|
56103
56259
|
);
|
|
56104
56260
|
}
|
|
56105
56261
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
56106
|
-
const destDir =
|
|
56262
|
+
const destDir = import_node_path50.default.join(deps.extensionsRoot, localExtId);
|
|
56107
56263
|
let destExists = false;
|
|
56108
56264
|
try {
|
|
56109
56265
|
await import_promises7.default.access(destDir);
|
|
@@ -56117,16 +56273,16 @@ async function installFromChannel(args, deps) {
|
|
|
56117
56273
|
);
|
|
56118
56274
|
}
|
|
56119
56275
|
const stage = await import_promises7.default.mkdtemp(
|
|
56120
|
-
|
|
56276
|
+
import_node_path50.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
56121
56277
|
);
|
|
56122
56278
|
try {
|
|
56123
56279
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56124
|
-
const dest =
|
|
56280
|
+
const dest = import_node_path50.default.join(stage, name);
|
|
56125
56281
|
if (entry.dir) {
|
|
56126
56282
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
56127
56283
|
continue;
|
|
56128
56284
|
}
|
|
56129
|
-
await import_promises7.default.mkdir(
|
|
56285
|
+
await import_promises7.default.mkdir(import_node_path50.default.dirname(dest), { recursive: true });
|
|
56130
56286
|
if (name === "manifest.json") {
|
|
56131
56287
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56132
56288
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56147,7 +56303,7 @@ async function installFromChannel(args, deps) {
|
|
|
56147
56303
|
|
|
56148
56304
|
// src/extension/update-flow.ts
|
|
56149
56305
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
56150
|
-
var
|
|
56306
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56151
56307
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
56152
56308
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
56153
56309
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -56164,11 +56320,11 @@ async function updateFromChannel(args, deps) {
|
|
|
56164
56320
|
channelRef.extId,
|
|
56165
56321
|
channelRef.ownerPrincipalId
|
|
56166
56322
|
);
|
|
56167
|
-
const liveDir =
|
|
56323
|
+
const liveDir = import_node_path51.default.join(deps.extensionsRoot, localExtId);
|
|
56168
56324
|
const prevDir = `${liveDir}.prev`;
|
|
56169
56325
|
let existingVersion;
|
|
56170
56326
|
try {
|
|
56171
|
-
const raw = await import_promises8.default.readFile(
|
|
56327
|
+
const raw = await import_promises8.default.readFile(import_node_path51.default.join(liveDir, "manifest.json"), "utf8");
|
|
56172
56328
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
56173
56329
|
if (!parsed2.success) {
|
|
56174
56330
|
throw new UpdateError(
|
|
@@ -56201,7 +56357,7 @@ async function updateFromChannel(args, deps) {
|
|
|
56201
56357
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56202
56358
|
}
|
|
56203
56359
|
for (const name of Object.keys(zip.files)) {
|
|
56204
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56360
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
|
|
56205
56361
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56206
56362
|
}
|
|
56207
56363
|
}
|
|
@@ -56236,16 +56392,16 @@ async function updateFromChannel(args, deps) {
|
|
|
56236
56392
|
await import_promises8.default.rm(prevDir, { recursive: true, force: true });
|
|
56237
56393
|
await import_promises8.default.rename(liveDir, prevDir);
|
|
56238
56394
|
const stage = await import_promises8.default.mkdtemp(
|
|
56239
|
-
|
|
56395
|
+
import_node_path51.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
56240
56396
|
);
|
|
56241
56397
|
try {
|
|
56242
56398
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56243
|
-
const dest =
|
|
56399
|
+
const dest = import_node_path51.default.join(stage, name);
|
|
56244
56400
|
if (entry.dir) {
|
|
56245
56401
|
await import_promises8.default.mkdir(dest, { recursive: true });
|
|
56246
56402
|
continue;
|
|
56247
56403
|
}
|
|
56248
|
-
await import_promises8.default.mkdir(
|
|
56404
|
+
await import_promises8.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
|
|
56249
56405
|
if (name === "manifest.json") {
|
|
56250
56406
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56251
56407
|
await import_promises8.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56338,7 +56494,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56338
56494
|
);
|
|
56339
56495
|
}
|
|
56340
56496
|
}
|
|
56341
|
-
const manifestPath =
|
|
56497
|
+
const manifestPath = import_node_path52.default.join(root, extId, "manifest.json");
|
|
56342
56498
|
const manifest = await readManifest(root, extId);
|
|
56343
56499
|
const next = { ...manifest, version: newVersion };
|
|
56344
56500
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -56346,7 +56502,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56346
56502
|
await import_promises9.default.rename(tmp, manifestPath);
|
|
56347
56503
|
}
|
|
56348
56504
|
async function readManifest(root, extId) {
|
|
56349
|
-
const file =
|
|
56505
|
+
const file = import_node_path52.default.join(root, extId, "manifest.json");
|
|
56350
56506
|
let raw;
|
|
56351
56507
|
try {
|
|
56352
56508
|
raw = await import_promises9.default.readFile(file, "utf8");
|
|
@@ -56437,7 +56593,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56437
56593
|
};
|
|
56438
56594
|
async function buildSnapshotMeta(extId) {
|
|
56439
56595
|
const manifest = await readManifest(deps.root, extId);
|
|
56440
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
56596
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path52.default.join(deps.root, extId));
|
|
56441
56597
|
return { manifest, contentHash: sha256, buffer };
|
|
56442
56598
|
}
|
|
56443
56599
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -56618,9 +56774,9 @@ function buildExtensionHandlers(deps) {
|
|
|
56618
56774
|
}
|
|
56619
56775
|
|
|
56620
56776
|
// src/app-builder/project-store.ts
|
|
56621
|
-
var
|
|
56622
|
-
var
|
|
56623
|
-
var
|
|
56777
|
+
var import_node_fs43 = require("fs");
|
|
56778
|
+
var import_node_child_process12 = require("child_process");
|
|
56779
|
+
var import_node_path53 = require("path");
|
|
56624
56780
|
init_protocol();
|
|
56625
56781
|
var PROJECTS_DIR = "projects";
|
|
56626
56782
|
var META_FILE = ".clawd-project.json";
|
|
@@ -56634,19 +56790,19 @@ var ProjectStore = class {
|
|
|
56634
56790
|
root;
|
|
56635
56791
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
56636
56792
|
metaPath(name) {
|
|
56637
|
-
return (0,
|
|
56793
|
+
return (0, import_node_path53.join)(this.projectsRoot(), name, META_FILE);
|
|
56638
56794
|
}
|
|
56639
56795
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
56640
56796
|
projectDir(name) {
|
|
56641
|
-
return (0,
|
|
56797
|
+
return (0, import_node_path53.join)(this.projectsRoot(), name);
|
|
56642
56798
|
}
|
|
56643
56799
|
projectsRoot() {
|
|
56644
|
-
return (0,
|
|
56800
|
+
return (0, import_node_path53.join)(this.root, PROJECTS_DIR);
|
|
56645
56801
|
}
|
|
56646
56802
|
async list() {
|
|
56647
56803
|
let entries;
|
|
56648
56804
|
try {
|
|
56649
|
-
entries = await
|
|
56805
|
+
entries = await import_node_fs43.promises.readdir(this.projectsRoot());
|
|
56650
56806
|
} catch (err) {
|
|
56651
56807
|
if (err.code === "ENOENT") return [];
|
|
56652
56808
|
throw err;
|
|
@@ -56654,7 +56810,7 @@ var ProjectStore = class {
|
|
|
56654
56810
|
const out = [];
|
|
56655
56811
|
for (const name of entries) {
|
|
56656
56812
|
try {
|
|
56657
|
-
const raw = await
|
|
56813
|
+
const raw = await import_node_fs43.promises.readFile(this.metaPath(name), "utf8");
|
|
56658
56814
|
const json = JSON.parse(raw);
|
|
56659
56815
|
let migrated = false;
|
|
56660
56816
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -56665,7 +56821,7 @@ var ProjectStore = class {
|
|
|
56665
56821
|
if (parsed.success) {
|
|
56666
56822
|
out.push(parsed.data);
|
|
56667
56823
|
if (migrated) {
|
|
56668
|
-
void
|
|
56824
|
+
void import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
56669
56825
|
});
|
|
56670
56826
|
}
|
|
56671
56827
|
}
|
|
@@ -56709,8 +56865,8 @@ var ProjectStore = class {
|
|
|
56709
56865
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
56710
56866
|
}
|
|
56711
56867
|
const dir = this.projectDir(name);
|
|
56712
|
-
await
|
|
56713
|
-
await
|
|
56868
|
+
await import_node_fs43.promises.mkdir(dir, { recursive: true });
|
|
56869
|
+
await import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
56714
56870
|
return meta;
|
|
56715
56871
|
}
|
|
56716
56872
|
/**
|
|
@@ -56724,7 +56880,7 @@ var ProjectStore = class {
|
|
|
56724
56880
|
async scaffold(name, templateSrcDir, scaffoldScriptPath) {
|
|
56725
56881
|
const destDir = this.projectDir(name);
|
|
56726
56882
|
return await new Promise((resolve6, reject) => {
|
|
56727
|
-
const child = (0,
|
|
56883
|
+
const child = (0, import_node_child_process12.spawn)("bash", [scaffoldScriptPath, name, templateSrcDir, destDir], {
|
|
56728
56884
|
env: { ...process.env, PATH: process.env.PATH ?? "" },
|
|
56729
56885
|
stdio: ["ignore", "pipe", "pipe"]
|
|
56730
56886
|
});
|
|
@@ -56753,7 +56909,7 @@ var ProjectStore = class {
|
|
|
56753
56909
|
}
|
|
56754
56910
|
async delete(name) {
|
|
56755
56911
|
const dir = this.projectDir(name);
|
|
56756
|
-
await
|
|
56912
|
+
await import_node_fs43.promises.rm(dir, { recursive: true, force: true });
|
|
56757
56913
|
}
|
|
56758
56914
|
async updatePort(name, newPort) {
|
|
56759
56915
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -56769,7 +56925,7 @@ var ProjectStore = class {
|
|
|
56769
56925
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
56770
56926
|
}
|
|
56771
56927
|
const updated = { ...target, port: newPort };
|
|
56772
|
-
await
|
|
56928
|
+
await import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
56773
56929
|
return updated;
|
|
56774
56930
|
}
|
|
56775
56931
|
/**
|
|
@@ -56786,7 +56942,7 @@ var ProjectStore = class {
|
|
|
56786
56942
|
if (!validated.success) {
|
|
56787
56943
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
56788
56944
|
}
|
|
56789
|
-
await
|
|
56945
|
+
await import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56790
56946
|
return validated.data;
|
|
56791
56947
|
}
|
|
56792
56948
|
/**
|
|
@@ -56807,7 +56963,7 @@ var ProjectStore = class {
|
|
|
56807
56963
|
if (!validated.success) {
|
|
56808
56964
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
56809
56965
|
}
|
|
56810
|
-
await
|
|
56966
|
+
await import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56811
56967
|
return validated.data;
|
|
56812
56968
|
}
|
|
56813
56969
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -56822,13 +56978,13 @@ var ProjectStore = class {
|
|
|
56822
56978
|
if (!validated.success) {
|
|
56823
56979
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
56824
56980
|
}
|
|
56825
|
-
await
|
|
56981
|
+
await import_node_fs43.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56826
56982
|
return validated.data;
|
|
56827
56983
|
}
|
|
56828
56984
|
};
|
|
56829
56985
|
|
|
56830
56986
|
// src/app-builder/kill-port.ts
|
|
56831
|
-
var
|
|
56987
|
+
var import_node_child_process13 = require("child_process");
|
|
56832
56988
|
async function killPortOccupants(port, ownedPids, logger) {
|
|
56833
56989
|
let pids;
|
|
56834
56990
|
try {
|
|
@@ -56870,7 +57026,7 @@ async function killPortOccupants(port, ownedPids, logger) {
|
|
|
56870
57026
|
}
|
|
56871
57027
|
function listPidsOnPort(port) {
|
|
56872
57028
|
return new Promise((resolve6, reject) => {
|
|
56873
|
-
(0,
|
|
57029
|
+
(0, import_node_child_process13.execFile)(
|
|
56874
57030
|
"lsof",
|
|
56875
57031
|
["-ti", `:${port}`],
|
|
56876
57032
|
{ timeout: 3e3 },
|
|
@@ -56942,9 +57098,9 @@ var PublishJobRegistry = class {
|
|
|
56942
57098
|
};
|
|
56943
57099
|
|
|
56944
57100
|
// src/app-builder/publish-job-runner.ts
|
|
56945
|
-
var
|
|
56946
|
-
var
|
|
56947
|
-
var
|
|
57101
|
+
var import_node_child_process14 = require("child_process");
|
|
57102
|
+
var import_node_fs44 = require("fs");
|
|
57103
|
+
var import_node_path54 = require("path");
|
|
56948
57104
|
|
|
56949
57105
|
// src/app-builder/publish-stage-parser.ts
|
|
56950
57106
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -56971,15 +57127,15 @@ function tailStderrLines(buf, n) {
|
|
|
56971
57127
|
// src/app-builder/publish-job-runner.ts
|
|
56972
57128
|
async function startPublishJob(deps, args) {
|
|
56973
57129
|
const { registry: registry2, projectDir } = deps;
|
|
56974
|
-
const spawn13 = deps.spawnImpl ??
|
|
57130
|
+
const spawn13 = deps.spawnImpl ?? import_node_child_process14.spawn;
|
|
56975
57131
|
if (registry2.has(args.name)) {
|
|
56976
57132
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
56977
57133
|
}
|
|
56978
57134
|
const projDir = projectDir(args.name);
|
|
56979
|
-
const logPath = (0,
|
|
57135
|
+
const logPath = (0, import_node_path54.join)(projDir, ".publish.log");
|
|
56980
57136
|
let logStream = null;
|
|
56981
57137
|
try {
|
|
56982
|
-
logStream = (0,
|
|
57138
|
+
logStream = (0, import_node_fs44.createWriteStream)(logPath, { flags: "w" });
|
|
56983
57139
|
} catch {
|
|
56984
57140
|
logStream = null;
|
|
56985
57141
|
}
|
|
@@ -57236,8 +57392,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
57236
57392
|
|
|
57237
57393
|
// src/handlers/app-builder.ts
|
|
57238
57394
|
init_protocol();
|
|
57239
|
-
var
|
|
57240
|
-
var
|
|
57395
|
+
var import_node_path55 = require("path");
|
|
57396
|
+
var import_node_fs45 = require("fs");
|
|
57241
57397
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
57242
57398
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
57243
57399
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -57318,7 +57474,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57318
57474
|
async function listAllUsersProjects() {
|
|
57319
57475
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
57320
57476
|
const getStore = deps.getStore;
|
|
57321
|
-
const userIds = await
|
|
57477
|
+
const userIds = await import_node_fs45.promises.readdir(deps.usersRoot).catch(() => []);
|
|
57322
57478
|
const perUser = await Promise.all(
|
|
57323
57479
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
57324
57480
|
);
|
|
@@ -57394,8 +57550,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57394
57550
|
const project = await userStore.create(f.name, reservedPorts);
|
|
57395
57551
|
try {
|
|
57396
57552
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57397
|
-
const templateSrcDir = (0,
|
|
57398
|
-
const scaffoldScript = (0,
|
|
57553
|
+
const templateSrcDir = (0, import_node_path55.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
57554
|
+
const scaffoldScript = (0, import_node_path55.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
57399
57555
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
57400
57556
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
57401
57557
|
name: project.name,
|
|
@@ -57616,7 +57772,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57616
57772
|
await userStore.clearPublishJob(args.name);
|
|
57617
57773
|
}
|
|
57618
57774
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57619
|
-
const scriptPath = (0,
|
|
57775
|
+
const scriptPath = (0, import_node_path55.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
57620
57776
|
deps.logger?.info("app-builder.publish.start", {
|
|
57621
57777
|
name: args.name,
|
|
57622
57778
|
sessionId: boundSession.sessionId,
|
|
@@ -57792,7 +57948,7 @@ function buildVisitorHandlers(deps) {
|
|
|
57792
57948
|
|
|
57793
57949
|
// src/extension/registry.ts
|
|
57794
57950
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
57795
|
-
var
|
|
57951
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
57796
57952
|
async function loadAll(root) {
|
|
57797
57953
|
let entries;
|
|
57798
57954
|
try {
|
|
@@ -57805,13 +57961,13 @@ async function loadAll(root) {
|
|
|
57805
57961
|
for (const ent of entries) {
|
|
57806
57962
|
if (!ent.isDirectory()) continue;
|
|
57807
57963
|
if (ent.name.startsWith(".")) continue;
|
|
57808
|
-
records.push(await loadOne(
|
|
57964
|
+
records.push(await loadOne(import_node_path56.default.join(root, ent.name), ent.name));
|
|
57809
57965
|
}
|
|
57810
57966
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
57811
57967
|
return records;
|
|
57812
57968
|
}
|
|
57813
57969
|
async function loadOne(dir, dirName) {
|
|
57814
|
-
const manifestPath =
|
|
57970
|
+
const manifestPath = import_node_path56.default.join(dir, "manifest.json");
|
|
57815
57971
|
let raw;
|
|
57816
57972
|
try {
|
|
57817
57973
|
raw = await import_promises10.default.readFile(manifestPath, "utf8");
|
|
@@ -57856,7 +58012,7 @@ async function loadOne(dir, dirName) {
|
|
|
57856
58012
|
|
|
57857
58013
|
// src/extension/uninstall.ts
|
|
57858
58014
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
57859
|
-
var
|
|
58015
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
57860
58016
|
var UninstallError = class extends Error {
|
|
57861
58017
|
constructor(code, message) {
|
|
57862
58018
|
super(message);
|
|
@@ -57865,7 +58021,7 @@ var UninstallError = class extends Error {
|
|
|
57865
58021
|
code;
|
|
57866
58022
|
};
|
|
57867
58023
|
async function uninstall(deps) {
|
|
57868
|
-
const dir =
|
|
58024
|
+
const dir = import_node_path57.default.join(deps.root, deps.extId);
|
|
57869
58025
|
try {
|
|
57870
58026
|
await import_promises11.default.access(dir);
|
|
57871
58027
|
} catch {
|
|
@@ -57882,7 +58038,7 @@ var import_node_crypto18 = require("crypto");
|
|
|
57882
58038
|
init_protocol();
|
|
57883
58039
|
|
|
57884
58040
|
// src/peer-ops/run-command.ts
|
|
57885
|
-
var
|
|
58041
|
+
var import_node_child_process15 = require("child_process");
|
|
57886
58042
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
57887
58043
|
var DEFAULT_TIMEOUT_MS5 = 3e4;
|
|
57888
58044
|
var MAX_TIMEOUT_MS = 3e5;
|
|
@@ -57890,7 +58046,7 @@ var MAX_OUTPUT_BYTES = 1048576;
|
|
|
57890
58046
|
function runCommand(command, opts = {}) {
|
|
57891
58047
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS5, MAX_TIMEOUT_MS);
|
|
57892
58048
|
return new Promise((resolve6) => {
|
|
57893
|
-
const child = (0,
|
|
58049
|
+
const child = (0, import_node_child_process15.spawn)("bash", ["-c", command], { cwd: import_node_os21.default.homedir() });
|
|
57894
58050
|
const out = [];
|
|
57895
58051
|
const err = [];
|
|
57896
58052
|
let outBytes = 0;
|
|
@@ -58104,7 +58260,7 @@ function buildMethodHandlers(deps) {
|
|
|
58104
58260
|
}
|
|
58105
58261
|
|
|
58106
58262
|
// src/app-builder/dev-server-supervisor.ts
|
|
58107
|
-
var
|
|
58263
|
+
var import_node_child_process16 = require("child_process");
|
|
58108
58264
|
var import_node_events2 = require("events");
|
|
58109
58265
|
var DEFAULT_READY_PATTERN = /Local:\s+https?:\/\/|Nest application successfully started|server listening on/i;
|
|
58110
58266
|
var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
@@ -58141,7 +58297,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
58141
58297
|
tunnelHost: args.tunnelHost,
|
|
58142
58298
|
devCommand: cmd
|
|
58143
58299
|
});
|
|
58144
|
-
const child = (0,
|
|
58300
|
+
const child = (0, import_node_child_process16.spawn)("sh", ["-c", cmd], {
|
|
58145
58301
|
cwd: args.cwd,
|
|
58146
58302
|
env,
|
|
58147
58303
|
stdio: "pipe",
|
|
@@ -58584,8 +58740,8 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58584
58740
|
}
|
|
58585
58741
|
|
|
58586
58742
|
// src/extension/runtime.ts
|
|
58587
|
-
var
|
|
58588
|
-
var
|
|
58743
|
+
var import_node_child_process17 = require("child_process");
|
|
58744
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
58589
58745
|
var import_promises12 = require("timers/promises");
|
|
58590
58746
|
|
|
58591
58747
|
// src/extension/port-allocator.ts
|
|
@@ -58686,13 +58842,13 @@ var Runtime = class {
|
|
|
58686
58842
|
/\$CLAWOS_EXT_PORT/g,
|
|
58687
58843
|
String(port)
|
|
58688
58844
|
);
|
|
58689
|
-
const dir =
|
|
58845
|
+
const dir = import_node_path58.default.join(this.root, extId);
|
|
58690
58846
|
const env = {
|
|
58691
58847
|
...process.env,
|
|
58692
58848
|
CLAWOS_EXT_PORT: String(port),
|
|
58693
58849
|
CLAWOS_EXT_ID: extId
|
|
58694
58850
|
};
|
|
58695
|
-
const child = (0,
|
|
58851
|
+
const child = (0, import_node_child_process17.spawn)("sh", ["-c", cmd], {
|
|
58696
58852
|
cwd: dir,
|
|
58697
58853
|
env,
|
|
58698
58854
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -58798,7 +58954,7 @@ ${handle.stderrTail}`
|
|
|
58798
58954
|
|
|
58799
58955
|
// src/extension/published-channels.ts
|
|
58800
58956
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
58801
|
-
var
|
|
58957
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
58802
58958
|
init_zod();
|
|
58803
58959
|
var PublishedChannelsError = class extends Error {
|
|
58804
58960
|
constructor(code, message) {
|
|
@@ -58897,7 +59053,7 @@ var PublishedChannelStore = class {
|
|
|
58897
59053
|
)
|
|
58898
59054
|
};
|
|
58899
59055
|
const tmp = `${this.filePath}.tmp`;
|
|
58900
|
-
await import_promises13.default.mkdir(
|
|
59056
|
+
await import_promises13.default.mkdir(import_node_path59.default.dirname(this.filePath), { recursive: true });
|
|
58901
59057
|
await import_promises13.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
58902
59058
|
await import_promises13.default.rename(tmp, this.filePath);
|
|
58903
59059
|
}
|
|
@@ -58905,7 +59061,7 @@ var PublishedChannelStore = class {
|
|
|
58905
59061
|
|
|
58906
59062
|
// src/extension/bundle-cache.ts
|
|
58907
59063
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
58908
|
-
var
|
|
59064
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
58909
59065
|
var BundleCache = class {
|
|
58910
59066
|
constructor(rootDir) {
|
|
58911
59067
|
this.rootDir = rootDir;
|
|
@@ -58914,14 +59070,14 @@ var BundleCache = class {
|
|
|
58914
59070
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
58915
59071
|
async write(snapshotHash, buffer) {
|
|
58916
59072
|
await import_promises14.default.mkdir(this.rootDir, { recursive: true });
|
|
58917
|
-
const file =
|
|
59073
|
+
const file = import_node_path60.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58918
59074
|
const tmp = `${file}.tmp`;
|
|
58919
59075
|
await import_promises14.default.writeFile(tmp, buffer, { mode: 384 });
|
|
58920
59076
|
await import_promises14.default.rename(tmp, file);
|
|
58921
59077
|
}
|
|
58922
59078
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
58923
59079
|
async read(snapshotHash) {
|
|
58924
|
-
const file =
|
|
59080
|
+
const file = import_node_path60.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58925
59081
|
try {
|
|
58926
59082
|
return await import_promises14.default.readFile(file);
|
|
58927
59083
|
} catch (e) {
|
|
@@ -58931,7 +59087,7 @@ var BundleCache = class {
|
|
|
58931
59087
|
}
|
|
58932
59088
|
/** Idempotent — missing file is not an error. */
|
|
58933
59089
|
async delete(snapshotHash) {
|
|
58934
|
-
const file =
|
|
59090
|
+
const file = import_node_path60.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58935
59091
|
await import_promises14.default.rm(file, { force: true });
|
|
58936
59092
|
}
|
|
58937
59093
|
};
|
|
@@ -58954,24 +59110,24 @@ async function startDaemon(config) {
|
|
|
58954
59110
|
sampling: logShippingCfg.sampling,
|
|
58955
59111
|
homeDir: import_node_os22.default.homedir()
|
|
58956
59112
|
});
|
|
58957
|
-
const logDir =
|
|
58958
|
-
|
|
59113
|
+
const logDir = import_node_path61.default.join(config.dataDir, "log");
|
|
59114
|
+
import_node_fs46.default.mkdirSync(logDir, { recursive: true });
|
|
58959
59115
|
const logger = createLogger({
|
|
58960
59116
|
level: config.logLevel,
|
|
58961
|
-
file:
|
|
59117
|
+
file: import_node_path61.default.join(logDir, "clawd.log"),
|
|
58962
59118
|
logClient
|
|
58963
59119
|
});
|
|
58964
59120
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
58965
59121
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
58966
|
-
file:
|
|
59122
|
+
file: import_node_path61.default.join(logDir, "screen-idle-probe.log"),
|
|
58967
59123
|
level: "debug"
|
|
58968
59124
|
});
|
|
58969
59125
|
logger.info("screen-idle probe logger enabled", {
|
|
58970
|
-
file:
|
|
59126
|
+
file: import_node_path61.default.join(logDir, "screen-idle-probe.log")
|
|
58971
59127
|
});
|
|
58972
59128
|
const CAP_TARGETS = [
|
|
58973
|
-
|
|
58974
|
-
|
|
59129
|
+
import_node_path61.default.join(logDir, "clawd.log"),
|
|
59130
|
+
import_node_path61.default.join(logDir, "screen-idle-probe.log")
|
|
58975
59131
|
];
|
|
58976
59132
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
58977
59133
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -59125,8 +59281,8 @@ async function startDaemon(config) {
|
|
|
59125
59281
|
const agents = new AgentsScanner();
|
|
59126
59282
|
const history = new ClaudeHistoryReader();
|
|
59127
59283
|
let transport = null;
|
|
59128
|
-
const personaStore = new PersonaStore(
|
|
59129
|
-
const usersRoot =
|
|
59284
|
+
const personaStore = new PersonaStore(import_node_path61.default.join(config.dataDir, "personas"));
|
|
59285
|
+
const usersRoot = import_node_path61.default.join(config.dataDir, "users");
|
|
59130
59286
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
59131
59287
|
if (defaultsRoot) {
|
|
59132
59288
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -59146,7 +59302,7 @@ async function startDaemon(config) {
|
|
|
59146
59302
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
59147
59303
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
59148
59304
|
const dispatchStore = createDispatchStore({
|
|
59149
|
-
filePath:
|
|
59305
|
+
filePath: import_node_path61.default.join(config.dataDir, "dispatch.json"),
|
|
59150
59306
|
now: () => Date.now(),
|
|
59151
59307
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
59152
59308
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -59161,17 +59317,17 @@ async function startDaemon(config) {
|
|
|
59161
59317
|
now: () => Date.now(),
|
|
59162
59318
|
onCompleted: (sid) => deliverPendingRef?.(sid)
|
|
59163
59319
|
});
|
|
59164
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
59320
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path61.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
59165
59321
|
const mcpConfigs = [];
|
|
59166
59322
|
const dispatchServerCandidates = [
|
|
59167
|
-
|
|
59323
|
+
import_node_path61.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
59168
59324
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
59169
|
-
|
|
59325
|
+
import_node_path61.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
59170
59326
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
59171
59327
|
];
|
|
59172
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
59328
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs46.default.existsSync(p2));
|
|
59173
59329
|
if (dispatchServerScriptPath) {
|
|
59174
|
-
const dispatchLogPath =
|
|
59330
|
+
const dispatchLogPath = import_node_path61.default.join(logDir, "dispatch-mcp-server.log");
|
|
59175
59331
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
59176
59332
|
dataDir: config.dataDir,
|
|
59177
59333
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -59189,12 +59345,12 @@ async function startDaemon(config) {
|
|
|
59189
59345
|
});
|
|
59190
59346
|
}
|
|
59191
59347
|
const ticketServerCandidates = [
|
|
59192
|
-
|
|
59193
|
-
|
|
59348
|
+
import_node_path61.default.join(here, "ticket", "mcp-server.cjs"),
|
|
59349
|
+
import_node_path61.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
59194
59350
|
];
|
|
59195
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
59351
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs46.default.existsSync(p2));
|
|
59196
59352
|
if (ticketServerScriptPath) {
|
|
59197
|
-
const ticketLogPath =
|
|
59353
|
+
const ticketLogPath = import_node_path61.default.join(logDir, "ticket-mcp-server.log");
|
|
59198
59354
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
59199
59355
|
dataDir: config.dataDir,
|
|
59200
59356
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -59214,12 +59370,12 @@ async function startDaemon(config) {
|
|
|
59214
59370
|
});
|
|
59215
59371
|
}
|
|
59216
59372
|
const shiftServerCandidates = [
|
|
59217
|
-
|
|
59218
|
-
|
|
59373
|
+
import_node_path61.default.join(here, "shift", "mcp-server.cjs"),
|
|
59374
|
+
import_node_path61.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
59219
59375
|
];
|
|
59220
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
59376
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs46.default.existsSync(p2));
|
|
59221
59377
|
if (shiftServerScriptPath) {
|
|
59222
|
-
const shiftLogPath =
|
|
59378
|
+
const shiftLogPath = import_node_path61.default.join(logDir, "shift-mcp-server.log");
|
|
59223
59379
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
59224
59380
|
dataDir: config.dataDir,
|
|
59225
59381
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -59238,12 +59394,12 @@ async function startDaemon(config) {
|
|
|
59238
59394
|
);
|
|
59239
59395
|
}
|
|
59240
59396
|
const inboxServerCandidates = [
|
|
59241
|
-
|
|
59242
|
-
|
|
59397
|
+
import_node_path61.default.join(here, "inbox", "mcp-server.cjs"),
|
|
59398
|
+
import_node_path61.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
59243
59399
|
];
|
|
59244
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
59400
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs46.default.existsSync(p2));
|
|
59245
59401
|
if (inboxServerScriptPath) {
|
|
59246
|
-
const inboxLogPath =
|
|
59402
|
+
const inboxLogPath = import_node_path61.default.join(logDir, "inbox-mcp-server.log");
|
|
59247
59403
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
59248
59404
|
dataDir: config.dataDir,
|
|
59249
59405
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -59262,10 +59418,10 @@ async function startDaemon(config) {
|
|
|
59262
59418
|
);
|
|
59263
59419
|
}
|
|
59264
59420
|
const peerOpsServerCandidates = [
|
|
59265
|
-
|
|
59266
|
-
|
|
59421
|
+
import_node_path61.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
59422
|
+
import_node_path61.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
59267
59423
|
];
|
|
59268
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) =>
|
|
59424
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs46.default.existsSync(p2));
|
|
59269
59425
|
if (peerOpsServerScriptPath) {
|
|
59270
59426
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
59271
59427
|
dataDir: config.dataDir,
|
|
@@ -59283,7 +59439,7 @@ async function startDaemon(config) {
|
|
|
59283
59439
|
);
|
|
59284
59440
|
}
|
|
59285
59441
|
const shiftStore = createShiftStore({
|
|
59286
|
-
filePath:
|
|
59442
|
+
filePath: import_node_path61.default.join(config.dataDir, "shift.json"),
|
|
59287
59443
|
ownerIdProvider: () => ownerPrincipalId,
|
|
59288
59444
|
now: () => Date.now()
|
|
59289
59445
|
});
|
|
@@ -59305,7 +59461,10 @@ async function startDaemon(config) {
|
|
|
59305
59461
|
getAdapter,
|
|
59306
59462
|
historyReader: history,
|
|
59307
59463
|
dataDir: config.dataDir,
|
|
59308
|
-
personaRoot:
|
|
59464
|
+
personaRoot: import_node_path61.default.join(config.dataDir, "personas"),
|
|
59465
|
+
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
59466
|
+
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
59467
|
+
getPersonaTool: (personaId) => personaRegistry.get(personaId)?.tool,
|
|
59309
59468
|
usersRoot,
|
|
59310
59469
|
personaStore,
|
|
59311
59470
|
ownerDisplayName,
|
|
@@ -59345,10 +59504,10 @@ async function startDaemon(config) {
|
|
|
59345
59504
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
59346
59505
|
attachmentGroup: {
|
|
59347
59506
|
onFileEdit: (input) => {
|
|
59348
|
-
const absPath =
|
|
59507
|
+
const absPath = import_node_path61.default.isAbsolute(input.relPath) ? input.relPath : import_node_path61.default.join(input.cwd, input.relPath);
|
|
59349
59508
|
let size = 0;
|
|
59350
59509
|
try {
|
|
59351
|
-
size =
|
|
59510
|
+
size = import_node_fs46.default.statSync(absPath).size;
|
|
59352
59511
|
} catch (err) {
|
|
59353
59512
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
59354
59513
|
sessionId: input.sessionId,
|
|
@@ -59431,6 +59590,7 @@ async function startDaemon(config) {
|
|
|
59431
59590
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
59432
59591
|
registerAdapter("claude", claudeAdapter);
|
|
59433
59592
|
registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
|
|
59593
|
+
warmCodexFeatureCache();
|
|
59434
59594
|
const personaRegistry = new PersonaRegistry(personaStore);
|
|
59435
59595
|
const personaManager = new PersonaManager({
|
|
59436
59596
|
store: personaStore,
|
|
@@ -59578,11 +59738,11 @@ async function startDaemon(config) {
|
|
|
59578
59738
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
59579
59739
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
59580
59740
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
59581
|
-
personaRoot:
|
|
59741
|
+
personaRoot: import_node_path61.default.join(config.dataDir, "personas"),
|
|
59582
59742
|
usersRoot
|
|
59583
59743
|
},
|
|
59584
59744
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
59585
|
-
personaRoot:
|
|
59745
|
+
personaRoot: import_node_path61.default.join(config.dataDir, "personas"),
|
|
59586
59746
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
59587
59747
|
usersRoot,
|
|
59588
59748
|
// capability:list / delete handler 依赖
|
|
@@ -59693,11 +59853,11 @@ async function startDaemon(config) {
|
|
|
59693
59853
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
59694
59854
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
59695
59855
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
59696
|
-
appBuilderPersonaRoot:
|
|
59856
|
+
appBuilderPersonaRoot: import_node_path61.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
59697
59857
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59698
|
-
deployKitRoot:
|
|
59858
|
+
deployKitRoot: import_node_path61.default.join(config.dataDir, "deploy-kit"),
|
|
59699
59859
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59700
|
-
resolvePersonaRoot: (personaId) =>
|
|
59860
|
+
resolvePersonaRoot: (personaId) => import_node_path61.default.join(config.dataDir, "personas", personaId),
|
|
59701
59861
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59702
59862
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59703
59863
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59743,7 +59903,7 @@ async function startDaemon(config) {
|
|
|
59743
59903
|
}
|
|
59744
59904
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
59745
59905
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
59746
|
-
sourceJsonlPath =
|
|
59906
|
+
sourceJsonlPath = import_node_path61.default.join(
|
|
59747
59907
|
import_node_os22.default.homedir(),
|
|
59748
59908
|
".claude",
|
|
59749
59909
|
"projects",
|
|
@@ -59789,7 +59949,9 @@ async function startDaemon(config) {
|
|
|
59789
59949
|
});
|
|
59790
59950
|
},
|
|
59791
59951
|
// B 角色:判断 targetPersona 是否 public(跨设备授权边界,private 拒)。
|
|
59792
|
-
getPersonaPublic: (personaId) => personaRegistry.get(personaId)?.public ?? false
|
|
59952
|
+
getPersonaPublic: (personaId) => personaRegistry.get(personaId)?.public ?? false,
|
|
59953
|
+
// model 校验按 target persona 绑定 tool 选表(claude / codex 模型集不同)
|
|
59954
|
+
getPersonaTool: (personaId) => personaRegistry.get(personaId)?.tool
|
|
59793
59955
|
});
|
|
59794
59956
|
handlers = { ...handlers, ...dispatchHandlers };
|
|
59795
59957
|
const shiftHandlers = buildShiftInternalHandlers({
|
|
@@ -60061,8 +60223,8 @@ async function startDaemon(config) {
|
|
|
60061
60223
|
const lines = [
|
|
60062
60224
|
`Tunnel: ${r.url}`,
|
|
60063
60225
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
60064
|
-
`Frpc config: ${
|
|
60065
|
-
`Frpc log: ${
|
|
60226
|
+
`Frpc config: ${import_node_path61.default.join(config.dataDir, "frpc.toml")}`,
|
|
60227
|
+
`Frpc log: ${import_node_path61.default.join(logDir, "frpc.log")}`
|
|
60066
60228
|
];
|
|
60067
60229
|
const width = Math.max(...lines.map((l) => l.length));
|
|
60068
60230
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -60075,8 +60237,8 @@ ${bar}
|
|
|
60075
60237
|
|
|
60076
60238
|
`);
|
|
60077
60239
|
try {
|
|
60078
|
-
const connectPath =
|
|
60079
|
-
|
|
60240
|
+
const connectPath = import_node_path61.default.join(config.dataDir, "connect.txt");
|
|
60241
|
+
import_node_fs46.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
60080
60242
|
} catch {
|
|
60081
60243
|
}
|
|
60082
60244
|
} catch (err) {
|
|
@@ -60148,9 +60310,9 @@ ${bar}
|
|
|
60148
60310
|
};
|
|
60149
60311
|
}
|
|
60150
60312
|
function migrateDropPersonsDir(dataDir) {
|
|
60151
|
-
const dir =
|
|
60313
|
+
const dir = import_node_path61.default.join(dataDir, "persons");
|
|
60152
60314
|
try {
|
|
60153
|
-
|
|
60315
|
+
import_node_fs46.default.rmSync(dir, { recursive: true, force: true });
|
|
60154
60316
|
} catch {
|
|
60155
60317
|
}
|
|
60156
60318
|
}
|