@clawos-dev/clawd 0.2.464 → 0.2.466
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 +1155 -687
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/guest-Cv9BgWuD.css +32 -0
- package/dist/share-ui/assets/{guest-BbYD5I0i.js → guest-piimtn8y.js} +134 -132
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/share-ui/assets/guest-DW6_DI9v.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -450,8 +450,8 @@ var init_parseUtil = __esm({
|
|
|
450
450
|
init_errors();
|
|
451
451
|
init_en();
|
|
452
452
|
makeIssue = (params) => {
|
|
453
|
-
const { data, path:
|
|
454
|
-
const fullPath = [...
|
|
453
|
+
const { data, path: path99, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path99, ...issueData.path || []];
|
|
455
455
|
const fullIssue = {
|
|
456
456
|
...issueData,
|
|
457
457
|
path: fullPath
|
|
@@ -762,11 +762,11 @@ var init_types = __esm({
|
|
|
762
762
|
init_parseUtil();
|
|
763
763
|
init_util();
|
|
764
764
|
ParseInputLazyPath = class {
|
|
765
|
-
constructor(parent, value,
|
|
765
|
+
constructor(parent, value, path99, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path99;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -9905,8 +9905,8 @@ var require_req = __commonJS({
|
|
|
9905
9905
|
if (req.originalUrl) {
|
|
9906
9906
|
_req.url = req.originalUrl;
|
|
9907
9907
|
} else {
|
|
9908
|
-
const
|
|
9909
|
-
_req.url = typeof
|
|
9908
|
+
const path99 = req.path;
|
|
9909
|
+
_req.url = typeof path99 === "string" ? path99 : req.url ? req.url.path || req.url : void 0;
|
|
9910
9910
|
}
|
|
9911
9911
|
if (req.query) {
|
|
9912
9912
|
_req.query = req.query;
|
|
@@ -10071,14 +10071,14 @@ var require_redact = __commonJS({
|
|
|
10071
10071
|
}
|
|
10072
10072
|
return obj;
|
|
10073
10073
|
}
|
|
10074
|
-
function parsePath(
|
|
10074
|
+
function parsePath(path99) {
|
|
10075
10075
|
const parts = [];
|
|
10076
10076
|
let current = "";
|
|
10077
10077
|
let inBrackets = false;
|
|
10078
10078
|
let inQuotes = false;
|
|
10079
10079
|
let quoteChar = "";
|
|
10080
|
-
for (let i = 0; i <
|
|
10081
|
-
const char =
|
|
10080
|
+
for (let i = 0; i < path99.length; i++) {
|
|
10081
|
+
const char = path99[i];
|
|
10082
10082
|
if (!inBrackets && char === ".") {
|
|
10083
10083
|
if (current) {
|
|
10084
10084
|
parts.push(current);
|
|
@@ -10209,10 +10209,10 @@ var require_redact = __commonJS({
|
|
|
10209
10209
|
return current;
|
|
10210
10210
|
}
|
|
10211
10211
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
10212
|
-
for (const
|
|
10213
|
-
const parts = parsePath(
|
|
10212
|
+
for (const path99 of paths) {
|
|
10213
|
+
const parts = parsePath(path99);
|
|
10214
10214
|
if (parts.includes("*")) {
|
|
10215
|
-
redactWildcardPath(obj, parts, censor,
|
|
10215
|
+
redactWildcardPath(obj, parts, censor, path99, remove);
|
|
10216
10216
|
} else {
|
|
10217
10217
|
if (remove) {
|
|
10218
10218
|
removeKey(obj, parts);
|
|
@@ -10297,8 +10297,8 @@ var require_redact = __commonJS({
|
|
|
10297
10297
|
}
|
|
10298
10298
|
} else {
|
|
10299
10299
|
if (afterWildcard.includes("*")) {
|
|
10300
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10301
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10300
|
+
const wrappedCensor = typeof censor === "function" ? (value, path99) => {
|
|
10301
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path99];
|
|
10302
10302
|
return censor(value, fullPath);
|
|
10303
10303
|
} : censor;
|
|
10304
10304
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10333,8 +10333,8 @@ var require_redact = __commonJS({
|
|
|
10333
10333
|
return null;
|
|
10334
10334
|
}
|
|
10335
10335
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10336
|
-
for (const
|
|
10337
|
-
const parts = parsePath(
|
|
10336
|
+
for (const path99 of pathsToClone) {
|
|
10337
|
+
const parts = parsePath(path99);
|
|
10338
10338
|
let current = pathStructure;
|
|
10339
10339
|
for (let i = 0; i < parts.length; i++) {
|
|
10340
10340
|
const part = parts[i];
|
|
@@ -10386,24 +10386,24 @@ var require_redact = __commonJS({
|
|
|
10386
10386
|
}
|
|
10387
10387
|
return cloneSelectively(obj, pathStructure);
|
|
10388
10388
|
}
|
|
10389
|
-
function validatePath(
|
|
10390
|
-
if (typeof
|
|
10389
|
+
function validatePath(path99) {
|
|
10390
|
+
if (typeof path99 !== "string") {
|
|
10391
10391
|
throw new Error("Paths must be (non-empty) strings");
|
|
10392
10392
|
}
|
|
10393
|
-
if (
|
|
10393
|
+
if (path99 === "") {
|
|
10394
10394
|
throw new Error("Invalid redaction path ()");
|
|
10395
10395
|
}
|
|
10396
|
-
if (
|
|
10397
|
-
throw new Error(`Invalid redaction path (${
|
|
10396
|
+
if (path99.includes("..")) {
|
|
10397
|
+
throw new Error(`Invalid redaction path (${path99})`);
|
|
10398
10398
|
}
|
|
10399
|
-
if (
|
|
10400
|
-
throw new Error(`Invalid redaction path (${
|
|
10399
|
+
if (path99.includes(",")) {
|
|
10400
|
+
throw new Error(`Invalid redaction path (${path99})`);
|
|
10401
10401
|
}
|
|
10402
10402
|
let bracketCount = 0;
|
|
10403
10403
|
let inQuotes = false;
|
|
10404
10404
|
let quoteChar = "";
|
|
10405
|
-
for (let i = 0; i <
|
|
10406
|
-
const char =
|
|
10405
|
+
for (let i = 0; i < path99.length; i++) {
|
|
10406
|
+
const char = path99[i];
|
|
10407
10407
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10408
10408
|
if (!inQuotes) {
|
|
10409
10409
|
inQuotes = true;
|
|
@@ -10417,20 +10417,20 @@ var require_redact = __commonJS({
|
|
|
10417
10417
|
} else if (char === "]" && !inQuotes) {
|
|
10418
10418
|
bracketCount--;
|
|
10419
10419
|
if (bracketCount < 0) {
|
|
10420
|
-
throw new Error(`Invalid redaction path (${
|
|
10420
|
+
throw new Error(`Invalid redaction path (${path99})`);
|
|
10421
10421
|
}
|
|
10422
10422
|
}
|
|
10423
10423
|
}
|
|
10424
10424
|
if (bracketCount !== 0) {
|
|
10425
|
-
throw new Error(`Invalid redaction path (${
|
|
10425
|
+
throw new Error(`Invalid redaction path (${path99})`);
|
|
10426
10426
|
}
|
|
10427
10427
|
}
|
|
10428
10428
|
function validatePaths(paths) {
|
|
10429
10429
|
if (!Array.isArray(paths)) {
|
|
10430
10430
|
throw new TypeError("paths must be an array");
|
|
10431
10431
|
}
|
|
10432
|
-
for (const
|
|
10433
|
-
validatePath(
|
|
10432
|
+
for (const path99 of paths) {
|
|
10433
|
+
validatePath(path99);
|
|
10434
10434
|
}
|
|
10435
10435
|
}
|
|
10436
10436
|
function slowRedact(options = {}) {
|
|
@@ -10598,8 +10598,8 @@ var require_redaction = __commonJS({
|
|
|
10598
10598
|
if (shape[k2] === null) {
|
|
10599
10599
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
10600
10600
|
} else {
|
|
10601
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10602
|
-
return censor(value, [k2, ...
|
|
10601
|
+
const wrappedCensor = typeof censor === "function" ? (value, path99) => {
|
|
10602
|
+
return censor(value, [k2, ...path99]);
|
|
10603
10603
|
} : censor;
|
|
10604
10604
|
o[k2] = Redact({
|
|
10605
10605
|
paths: shape[k2],
|
|
@@ -10817,10 +10817,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
10817
10817
|
var require_sonic_boom = __commonJS({
|
|
10818
10818
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
10819
10819
|
"use strict";
|
|
10820
|
-
var
|
|
10820
|
+
var fs88 = require("fs");
|
|
10821
10821
|
var EventEmitter3 = require("events");
|
|
10822
10822
|
var inherits = require("util").inherits;
|
|
10823
|
-
var
|
|
10823
|
+
var path99 = require("path");
|
|
10824
10824
|
var sleep2 = require_atomic_sleep();
|
|
10825
10825
|
var assert = require("assert");
|
|
10826
10826
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -10874,20 +10874,20 @@ var require_sonic_boom = __commonJS({
|
|
|
10874
10874
|
const mode = sonic.mode;
|
|
10875
10875
|
if (sonic.sync) {
|
|
10876
10876
|
try {
|
|
10877
|
-
if (sonic.mkdir)
|
|
10878
|
-
const fd =
|
|
10877
|
+
if (sonic.mkdir) fs88.mkdirSync(path99.dirname(file), { recursive: true });
|
|
10878
|
+
const fd = fs88.openSync(file, flags, mode);
|
|
10879
10879
|
fileOpened(null, fd);
|
|
10880
10880
|
} catch (err) {
|
|
10881
10881
|
fileOpened(err);
|
|
10882
10882
|
throw err;
|
|
10883
10883
|
}
|
|
10884
10884
|
} else if (sonic.mkdir) {
|
|
10885
|
-
|
|
10885
|
+
fs88.mkdir(path99.dirname(file), { recursive: true }, (err) => {
|
|
10886
10886
|
if (err) return fileOpened(err);
|
|
10887
|
-
|
|
10887
|
+
fs88.open(file, flags, mode, fileOpened);
|
|
10888
10888
|
});
|
|
10889
10889
|
} else {
|
|
10890
|
-
|
|
10890
|
+
fs88.open(file, flags, mode, fileOpened);
|
|
10891
10891
|
}
|
|
10892
10892
|
}
|
|
10893
10893
|
function SonicBoom(opts) {
|
|
@@ -10928,8 +10928,8 @@ var require_sonic_boom = __commonJS({
|
|
|
10928
10928
|
this.flush = flushBuffer;
|
|
10929
10929
|
this.flushSync = flushBufferSync;
|
|
10930
10930
|
this._actualWrite = actualWriteBuffer;
|
|
10931
|
-
fsWriteSync = () =>
|
|
10932
|
-
fsWrite = () =>
|
|
10931
|
+
fsWriteSync = () => fs88.writeSync(this.fd, this._writingBuf);
|
|
10932
|
+
fsWrite = () => fs88.write(this.fd, this._writingBuf, this.release);
|
|
10933
10933
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
10934
10934
|
this._writingBuf = "";
|
|
10935
10935
|
this.write = write;
|
|
@@ -10938,15 +10938,15 @@ var require_sonic_boom = __commonJS({
|
|
|
10938
10938
|
this._actualWrite = actualWrite;
|
|
10939
10939
|
fsWriteSync = () => {
|
|
10940
10940
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
10941
|
-
return
|
|
10941
|
+
return fs88.writeSync(this.fd, this._writingBuf);
|
|
10942
10942
|
}
|
|
10943
|
-
return
|
|
10943
|
+
return fs88.writeSync(this.fd, this._writingBuf, "utf8");
|
|
10944
10944
|
};
|
|
10945
10945
|
fsWrite = () => {
|
|
10946
10946
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
10947
|
-
return
|
|
10947
|
+
return fs88.write(this.fd, this._writingBuf, this.release);
|
|
10948
10948
|
}
|
|
10949
|
-
return
|
|
10949
|
+
return fs88.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
10950
10950
|
};
|
|
10951
10951
|
} else {
|
|
10952
10952
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -11003,7 +11003,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11003
11003
|
}
|
|
11004
11004
|
}
|
|
11005
11005
|
if (this._fsync) {
|
|
11006
|
-
|
|
11006
|
+
fs88.fsyncSync(this.fd);
|
|
11007
11007
|
}
|
|
11008
11008
|
const len = this._len;
|
|
11009
11009
|
if (this._reopening) {
|
|
@@ -11117,7 +11117,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11117
11117
|
const onDrain = () => {
|
|
11118
11118
|
if (!this._fsync) {
|
|
11119
11119
|
try {
|
|
11120
|
-
|
|
11120
|
+
fs88.fsync(this.fd, (err) => {
|
|
11121
11121
|
this._flushPending = false;
|
|
11122
11122
|
cb(err);
|
|
11123
11123
|
});
|
|
@@ -11219,7 +11219,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11219
11219
|
const fd = this.fd;
|
|
11220
11220
|
this.once("ready", () => {
|
|
11221
11221
|
if (fd !== this.fd) {
|
|
11222
|
-
|
|
11222
|
+
fs88.close(fd, (err) => {
|
|
11223
11223
|
if (err) {
|
|
11224
11224
|
return this.emit("error", err);
|
|
11225
11225
|
}
|
|
@@ -11268,7 +11268,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11268
11268
|
buf = this._bufs[0];
|
|
11269
11269
|
}
|
|
11270
11270
|
try {
|
|
11271
|
-
const n = Buffer.isBuffer(buf) ?
|
|
11271
|
+
const n = Buffer.isBuffer(buf) ? fs88.writeSync(this.fd, buf) : fs88.writeSync(this.fd, buf, "utf8");
|
|
11272
11272
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
11273
11273
|
buf = releasedBufObj.writingBuf;
|
|
11274
11274
|
this._len = releasedBufObj.len;
|
|
@@ -11284,7 +11284,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11284
11284
|
}
|
|
11285
11285
|
}
|
|
11286
11286
|
try {
|
|
11287
|
-
|
|
11287
|
+
fs88.fsyncSync(this.fd);
|
|
11288
11288
|
} catch {
|
|
11289
11289
|
}
|
|
11290
11290
|
}
|
|
@@ -11305,7 +11305,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11305
11305
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
11306
11306
|
}
|
|
11307
11307
|
try {
|
|
11308
|
-
const n =
|
|
11308
|
+
const n = fs88.writeSync(this.fd, buf);
|
|
11309
11309
|
buf = buf.subarray(n);
|
|
11310
11310
|
this._len = Math.max(this._len - n, 0);
|
|
11311
11311
|
if (buf.length <= 0) {
|
|
@@ -11333,13 +11333,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11333
11333
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11334
11334
|
if (this.sync) {
|
|
11335
11335
|
try {
|
|
11336
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11336
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs88.writeSync(this.fd, this._writingBuf) : fs88.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11337
11337
|
release(null, written);
|
|
11338
11338
|
} catch (err) {
|
|
11339
11339
|
release(err);
|
|
11340
11340
|
}
|
|
11341
11341
|
} else {
|
|
11342
|
-
|
|
11342
|
+
fs88.write(this.fd, this._writingBuf, release);
|
|
11343
11343
|
}
|
|
11344
11344
|
}
|
|
11345
11345
|
function actualWriteBuffer() {
|
|
@@ -11348,7 +11348,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11348
11348
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11349
11349
|
if (this.sync) {
|
|
11350
11350
|
try {
|
|
11351
|
-
const written =
|
|
11351
|
+
const written = fs88.writeSync(this.fd, this._writingBuf);
|
|
11352
11352
|
release(null, written);
|
|
11353
11353
|
} catch (err) {
|
|
11354
11354
|
release(err);
|
|
@@ -11357,7 +11357,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11357
11357
|
if (kCopyBuffer) {
|
|
11358
11358
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11359
11359
|
}
|
|
11360
|
-
|
|
11360
|
+
fs88.write(this.fd, this._writingBuf, release);
|
|
11361
11361
|
}
|
|
11362
11362
|
}
|
|
11363
11363
|
function actualClose(sonic) {
|
|
@@ -11373,12 +11373,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11373
11373
|
sonic._lens = [];
|
|
11374
11374
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11375
11375
|
try {
|
|
11376
|
-
|
|
11376
|
+
fs88.fsync(sonic.fd, closeWrapped);
|
|
11377
11377
|
} catch {
|
|
11378
11378
|
}
|
|
11379
11379
|
function closeWrapped() {
|
|
11380
11380
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11381
|
-
|
|
11381
|
+
fs88.close(sonic.fd, done);
|
|
11382
11382
|
} else {
|
|
11383
11383
|
done();
|
|
11384
11384
|
}
|
|
@@ -13742,7 +13742,7 @@ var require_multistream = __commonJS({
|
|
|
13742
13742
|
var require_pino = __commonJS({
|
|
13743
13743
|
"../node_modules/.pnpm/pino@9.14.0/node_modules/pino/pino.js"(exports2, module2) {
|
|
13744
13744
|
"use strict";
|
|
13745
|
-
var
|
|
13745
|
+
var os33 = require("os");
|
|
13746
13746
|
var stdSerializers = require_pino_std_serializers();
|
|
13747
13747
|
var caller = require_caller();
|
|
13748
13748
|
var redaction = require_redaction();
|
|
@@ -13789,7 +13789,7 @@ var require_pino = __commonJS({
|
|
|
13789
13789
|
} = symbols;
|
|
13790
13790
|
var { epochTime, nullTime } = time;
|
|
13791
13791
|
var { pid } = process;
|
|
13792
|
-
var hostname =
|
|
13792
|
+
var hostname = os33.hostname();
|
|
13793
13793
|
var defaultErrorSerializer = stdSerializers.err;
|
|
13794
13794
|
var defaultOptions2 = {
|
|
13795
13795
|
level: "info",
|
|
@@ -14513,11 +14513,11 @@ var init_lib = __esm({
|
|
|
14513
14513
|
}
|
|
14514
14514
|
}
|
|
14515
14515
|
},
|
|
14516
|
-
addToPath: function addToPath(
|
|
14517
|
-
var last =
|
|
14516
|
+
addToPath: function addToPath(path99, added, removed, oldPosInc, options) {
|
|
14517
|
+
var last = path99.lastComponent;
|
|
14518
14518
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14519
14519
|
return {
|
|
14520
|
-
oldPos:
|
|
14520
|
+
oldPos: path99.oldPos + oldPosInc,
|
|
14521
14521
|
lastComponent: {
|
|
14522
14522
|
count: last.count + 1,
|
|
14523
14523
|
added,
|
|
@@ -14527,7 +14527,7 @@ var init_lib = __esm({
|
|
|
14527
14527
|
};
|
|
14528
14528
|
} else {
|
|
14529
14529
|
return {
|
|
14530
|
-
oldPos:
|
|
14530
|
+
oldPos: path99.oldPos + oldPosInc,
|
|
14531
14531
|
lastComponent: {
|
|
14532
14532
|
count: 1,
|
|
14533
14533
|
added,
|
|
@@ -15109,10 +15109,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
15109
15109
|
const memories = raw.map((m2) => {
|
|
15110
15110
|
if (!m2 || typeof m2 !== "object") return null;
|
|
15111
15111
|
const rec4 = m2;
|
|
15112
|
-
const
|
|
15112
|
+
const path99 = typeof rec4.path === "string" ? rec4.path : null;
|
|
15113
15113
|
const content = typeof rec4.content === "string" ? rec4.content : null;
|
|
15114
|
-
if (!
|
|
15115
|
-
const entry = { path:
|
|
15114
|
+
if (!path99 || content == null) return null;
|
|
15115
|
+
const entry = { path: path99, content };
|
|
15116
15116
|
if (typeof rec4.mtimeMs === "number") entry.mtimeMs = rec4.mtimeMs;
|
|
15117
15117
|
return entry;
|
|
15118
15118
|
}).filter((m2) => m2 !== null);
|
|
@@ -15978,10 +15978,10 @@ function parseAttachment(obj) {
|
|
|
15978
15978
|
const memories = raw.map((m2) => {
|
|
15979
15979
|
if (!m2 || typeof m2 !== "object") return null;
|
|
15980
15980
|
const rec4 = m2;
|
|
15981
|
-
const
|
|
15981
|
+
const path99 = typeof rec4.path === "string" ? rec4.path : null;
|
|
15982
15982
|
const content = typeof rec4.content === "string" ? rec4.content : null;
|
|
15983
|
-
if (!
|
|
15984
|
-
const out = { path:
|
|
15983
|
+
if (!path99 || content == null) return null;
|
|
15984
|
+
const out = { path: path99, content };
|
|
15985
15985
|
if (typeof rec4.mtimeMs === "number") out.mtimeMs = rec4.mtimeMs;
|
|
15986
15986
|
return out;
|
|
15987
15987
|
}).filter((m2) => m2 !== null);
|
|
@@ -23490,14 +23490,14 @@ var require_luxon = __commonJS({
|
|
|
23490
23490
|
return normalized;
|
|
23491
23491
|
}
|
|
23492
23492
|
function formatOffset(offset2, format) {
|
|
23493
|
-
const hours = Math.trunc(Math.abs(offset2 / 60)), minutes = Math.trunc(Math.abs(offset2 % 60)),
|
|
23493
|
+
const hours = Math.trunc(Math.abs(offset2 / 60)), minutes = Math.trunc(Math.abs(offset2 % 60)), sign2 = offset2 >= 0 ? "+" : "-";
|
|
23494
23494
|
switch (format) {
|
|
23495
23495
|
case "short":
|
|
23496
|
-
return `${
|
|
23496
|
+
return `${sign2}${padStart(hours, 2)}:${padStart(minutes, 2)}`;
|
|
23497
23497
|
case "narrow":
|
|
23498
|
-
return `${
|
|
23498
|
+
return `${sign2}${hours}${minutes > 0 ? `:${minutes}` : ""}`;
|
|
23499
23499
|
case "techie":
|
|
23500
|
-
return `${
|
|
23500
|
+
return `${sign2}${padStart(hours, 2)}${padStart(minutes, 2)}`;
|
|
23501
23501
|
default:
|
|
23502
23502
|
throw new RangeError(`Value format ${format} is out of range for property format`);
|
|
23503
23503
|
}
|
|
@@ -36955,8 +36955,8 @@ var require_utils = __commonJS({
|
|
|
36955
36955
|
var result = transform[inputType][outputType](input);
|
|
36956
36956
|
return result;
|
|
36957
36957
|
};
|
|
36958
|
-
exports2.resolve = function(
|
|
36959
|
-
var parts =
|
|
36958
|
+
exports2.resolve = function(path99) {
|
|
36959
|
+
var parts = path99.split("/");
|
|
36960
36960
|
var result = [];
|
|
36961
36961
|
for (var index = 0; index < parts.length; index++) {
|
|
36962
36962
|
var part = parts[index];
|
|
@@ -42809,18 +42809,18 @@ var require_object = __commonJS({
|
|
|
42809
42809
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
42810
42810
|
this.files[name] = object;
|
|
42811
42811
|
};
|
|
42812
|
-
var parentFolder = function(
|
|
42813
|
-
if (
|
|
42814
|
-
|
|
42812
|
+
var parentFolder = function(path99) {
|
|
42813
|
+
if (path99.slice(-1) === "/") {
|
|
42814
|
+
path99 = path99.substring(0, path99.length - 1);
|
|
42815
42815
|
}
|
|
42816
|
-
var lastSlash =
|
|
42817
|
-
return lastSlash > 0 ?
|
|
42816
|
+
var lastSlash = path99.lastIndexOf("/");
|
|
42817
|
+
return lastSlash > 0 ? path99.substring(0, lastSlash) : "";
|
|
42818
42818
|
};
|
|
42819
|
-
var forceTrailingSlash = function(
|
|
42820
|
-
if (
|
|
42821
|
-
|
|
42819
|
+
var forceTrailingSlash = function(path99) {
|
|
42820
|
+
if (path99.slice(-1) !== "/") {
|
|
42821
|
+
path99 += "/";
|
|
42822
42822
|
}
|
|
42823
|
-
return
|
|
42823
|
+
return path99;
|
|
42824
42824
|
};
|
|
42825
42825
|
var folderAdd = function(name, createFolders) {
|
|
42826
42826
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -43822,7 +43822,7 @@ var require_lib3 = __commonJS({
|
|
|
43822
43822
|
// src/run-case/recorder.ts
|
|
43823
43823
|
function startRunCaseRecorder(opts) {
|
|
43824
43824
|
const now = opts.now ?? Date.now;
|
|
43825
|
-
const dir =
|
|
43825
|
+
const dir = import_node_path81.default.dirname(opts.recordPath);
|
|
43826
43826
|
let stream = null;
|
|
43827
43827
|
let closing = false;
|
|
43828
43828
|
let closedSettled = false;
|
|
@@ -43862,12 +43862,12 @@ function startRunCaseRecorder(opts) {
|
|
|
43862
43862
|
};
|
|
43863
43863
|
return { tap, close, closed };
|
|
43864
43864
|
}
|
|
43865
|
-
var import_node_fs57,
|
|
43865
|
+
var import_node_fs57, import_node_path81;
|
|
43866
43866
|
var init_recorder = __esm({
|
|
43867
43867
|
"src/run-case/recorder.ts"() {
|
|
43868
43868
|
"use strict";
|
|
43869
43869
|
import_node_fs57 = __toESM(require("fs"), 1);
|
|
43870
|
-
|
|
43870
|
+
import_node_path81 = __toESM(require("path"), 1);
|
|
43871
43871
|
}
|
|
43872
43872
|
});
|
|
43873
43873
|
|
|
@@ -43910,7 +43910,7 @@ var init_wire = __esm({
|
|
|
43910
43910
|
// src/run-case/controller.ts
|
|
43911
43911
|
async function runController(opts) {
|
|
43912
43912
|
const now = opts.now ?? Date.now;
|
|
43913
|
-
const cwd = opts.cwd ?? (0, import_node_fs58.mkdtempSync)(
|
|
43913
|
+
const cwd = opts.cwd ?? (0, import_node_fs58.mkdtempSync)(import_node_path82.default.join(import_node_os29.default.tmpdir(), "clawd-runcase-"));
|
|
43914
43914
|
const ownsCwd = opts.cwd === void 0;
|
|
43915
43915
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
43916
43916
|
const spawnCtx = { cwd };
|
|
@@ -44077,13 +44077,13 @@ async function runController(opts) {
|
|
|
44077
44077
|
}
|
|
44078
44078
|
return exitCode ?? 0;
|
|
44079
44079
|
}
|
|
44080
|
-
var import_node_fs58,
|
|
44080
|
+
var import_node_fs58, import_node_os29, import_node_path82;
|
|
44081
44081
|
var init_controller = __esm({
|
|
44082
44082
|
"src/run-case/controller.ts"() {
|
|
44083
44083
|
"use strict";
|
|
44084
44084
|
import_node_fs58 = require("fs");
|
|
44085
|
-
|
|
44086
|
-
|
|
44085
|
+
import_node_os29 = __toESM(require("os"), 1);
|
|
44086
|
+
import_node_path82 = __toESM(require("path"), 1);
|
|
44087
44087
|
init_claude();
|
|
44088
44088
|
init_stdout_splitter();
|
|
44089
44089
|
init_permission_stdio();
|
|
@@ -44358,10 +44358,10 @@ Env (advanced):
|
|
|
44358
44358
|
`;
|
|
44359
44359
|
|
|
44360
44360
|
// src/index.ts
|
|
44361
|
-
var
|
|
44361
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
44362
44362
|
var import_node_fs56 = __toESM(require("fs"), 1);
|
|
44363
|
-
var
|
|
44364
|
-
var
|
|
44363
|
+
var import_node_os28 = __toESM(require("os"), 1);
|
|
44364
|
+
var import_node_crypto23 = require("crypto");
|
|
44365
44365
|
var import_node_url5 = require("url");
|
|
44366
44366
|
|
|
44367
44367
|
// src/logger.ts
|
|
@@ -51616,8 +51616,8 @@ function turnStartInput(text) {
|
|
|
51616
51616
|
const items = [];
|
|
51617
51617
|
let leftover = text;
|
|
51618
51618
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
51619
|
-
const [marker, name,
|
|
51620
|
-
items.push({ type: "skill", name, path:
|
|
51619
|
+
const [marker, name, path99] = m2;
|
|
51620
|
+
items.push({ type: "skill", name, path: path99 });
|
|
51621
51621
|
leftover = leftover.replace(marker, "");
|
|
51622
51622
|
}
|
|
51623
51623
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -55169,9 +55169,87 @@ function createSecretStore(deps) {
|
|
|
55169
55169
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
55170
55170
|
var import_node_path32 = __toESM(require("path"), 1);
|
|
55171
55171
|
var CLOUD_HOST_CONFIG_FILE = "cloud-host.json";
|
|
55172
|
-
var REQUIRED = ["provisionDir", "gatewayUrl", "gatewayAdminKey", "gatewayApiKey"
|
|
55172
|
+
var REQUIRED = ["provisionDir", "gatewayUrl", "gatewayAdminKey", "gatewayApiKey"];
|
|
55173
55173
|
var CloudHostConfigError = class extends Error {
|
|
55174
55174
|
};
|
|
55175
|
+
var looksLikeRegistryRef = (s) => {
|
|
55176
|
+
const head = s.split("/")[0] ?? "";
|
|
55177
|
+
return s.includes("/") && (head.includes(".") || head.includes(":"));
|
|
55178
|
+
};
|
|
55179
|
+
var EXAMPLE_FILE = "cloud-host/deploy/cloud-host.json.example";
|
|
55180
|
+
function ghaGaps(parsed, imageRepo) {
|
|
55181
|
+
const gaps = [];
|
|
55182
|
+
if (!parsed.baseImage) {
|
|
55183
|
+
gaps.push({
|
|
55184
|
+
field: "baseImage",
|
|
55185
|
+
why: "persona \u5C42\u8981 FROM \u4E00\u4E2A\u5E95\u5EA7\u955C\u50CF\u3002\u5FC5\u987B\u662F\u4E0D\u53EF\u53D8\u7684 sha tag\uFF0C\u4E14\u7528**\u516C\u7F51**\u5730\u5740\u2014\u2014\u6784\u5EFA\u8DD1\u5728\u5883\u5916\u7684 runner \u4E0A\uFF0CVPC \u5730\u5740\u5B83\u89E3\u6790\u4E0D\u4E86",
|
|
55186
|
+
example: "registry.cn-hangzhou.aliyuncs.com/ttc-prod/clawd-persona-cloud:base-<40 \u4F4D sha>",
|
|
55187
|
+
where: "GitHub Actions \u91CC\u300CBuild persona-cloud base image\u300D\u6700\u8FD1\u4E00\u6B21\u6210\u529F run \u7684 Summary\uFF0C\u90A3\u5F20\u8868\u91CC\u76F4\u63A5\u7ED9\u4E86\u8FD9\u4E00\u884C"
|
|
55188
|
+
});
|
|
55189
|
+
}
|
|
55190
|
+
const gh2 = parsed.github;
|
|
55191
|
+
if (!gh2?.repo) {
|
|
55192
|
+
gaps.push({
|
|
55193
|
+
field: "github.repo",
|
|
55194
|
+
why: "\u5F80\u54EA\u4E2A\u4ED3\u5E93\u89E6\u53D1\u6784\u5EFA",
|
|
55195
|
+
example: "ottin4ttc/clawos",
|
|
55196
|
+
where: "\u5C31\u662F\u653E workflow \u7684\u90A3\u4E2A\u4ED3\u5E93"
|
|
55197
|
+
});
|
|
55198
|
+
}
|
|
55199
|
+
if (!gh2?.token) {
|
|
55200
|
+
gaps.push({
|
|
55201
|
+
field: "github.token",
|
|
55202
|
+
why: "\u89E6\u53D1 workflow_dispatch\u3001\u8F6E\u8BE2 run\u3001\u5931\u8D25\u65F6\u8BFB job \u65E5\u5FD7",
|
|
55203
|
+
example: "ghp_\u2026 / github_pat_\u2026",
|
|
55204
|
+
where: "`gh auth token`\uFF08classic token \u7684 `repo` scope \u5C31\u591F\uFF0C\u5DF2\u5B9E\u6D4B\u53EF\u89E6\u53D1\uFF09\uFF1B\u6216\u5EFA\u4E00\u4E2A fine-grained PAT\uFF0C\u5BF9\u8BE5\u4ED3\u5E93\u7ED9 **Actions: read and write** + **Contents: read**"
|
|
55205
|
+
});
|
|
55206
|
+
}
|
|
55207
|
+
const store = parsed.bundleStore;
|
|
55208
|
+
if (!store?.bucket || !store?.endpoint) {
|
|
55209
|
+
gaps.push({
|
|
55210
|
+
field: "bundleStore.bucket / bundleStore.endpoint",
|
|
55211
|
+
why: "persona \u76EE\u5F55\u7ECF\u8FD9\u4E2A\u79C1\u6709\u6876\u4E2D\u8F6C\u7ED9 runner\uFF08\u4E0D\u8D70 workflow inputs\uFF1A\u90A3\u513F\u6709 64KB \u4E0A\u9650\uFF0C\u800C\u4E14\u5165\u53C2\u4F1A\u957F\u671F\u663E\u793A\u5728 run \u9875\u9762\u4E0A\uFF09",
|
|
55212
|
+
example: '"bucket": "clawd-persona-bundle", "endpoint": "oss-cn-hangzhou.aliyuncs.com"',
|
|
55213
|
+
where: "endpoint \u7528**\u516C\u7F51**\u5730\u5740\uFF08\u4E0B\u8F7D\u65B9\u662F\u5883\u5916\u7684 runner\uFF0C\u5185\u7F51\u5730\u5740\u5B83\u8FDE\u4E0D\u4E0A\uFF09\u3002\u6876\u8981\u662F\u79C1\u6709\u7684\uFF0C\u5EFA\u8BAE\u7ED9\u4E2D\u8F6C\u524D\u7F00\u6302\u4E00\u6761\u300CN \u5929\u81EA\u52A8\u8FC7\u671F\u300D\u7684\u751F\u547D\u5468\u671F\u89C4\u5219\u515C\u5E95"
|
|
55214
|
+
});
|
|
55215
|
+
}
|
|
55216
|
+
if (!store?.accessKeyId || !store?.accessKeySecret) {
|
|
55217
|
+
gaps.push({
|
|
55218
|
+
field: "bundleStore.accessKeyId / bundleStore.accessKeySecret",
|
|
55219
|
+
why: "\u5F80\u90A3\u4E2A\u6876\u4F20\u5BF9\u8C61\u3001\u7B7E URL\u3001\u7528\u5B8C\u5220\u5BF9\u8C61",
|
|
55220
|
+
example: '"accessKeyId": "LTAI\u2026", "accessKeySecret": "\u2026"',
|
|
55221
|
+
where: "\u5EFA\u6876\u90A3\u4E2A\u963F\u91CC\u4E91\u8D26\u53F7\u4E0B\u7684 AccessKey\uFF08`~/.aliyun/config.json` \u91CC\u5C31\u6709\uFF09\u3002\u53EA\u9700\u8981\u5BF9\u8FD9\u4E00\u4E2A\u6876\u53EF\u8BFB\u5199"
|
|
55222
|
+
});
|
|
55223
|
+
}
|
|
55224
|
+
if (!looksLikeRegistryRef(imageRepo)) {
|
|
55225
|
+
gaps.push({
|
|
55226
|
+
field: "imageRepo",
|
|
55227
|
+
why: `\u73B0\u5728\u662F \`${imageRepo}\`\uFF0C\u6CA1\u6709 registry \u524D\u7F00\u3002\u8FD9\u4E2A\u503C\u4F1A**\u539F\u6837\u8FDB\u90E8\u7F72\u767B\u8BB0\u8868**\uFF0Ckubelet \u7167\u5B83\u53BB\u62C9\uFF1B\u6CA1\u524D\u7F00\u4F1A\u88AB\u89E3\u6790\u6210 \`docker.io/library/\u2026\`\uFF0C\u62A5\u51FA\u6765\u662F\u300C\u8FDE\u4E0D\u4E0A Docker Hub\u300D\u800C\u4E0D\u662F\u300C\u8282\u70B9\u4E0A\u6CA1\u8FD9\u4E2A\u955C\u50CF\u300D`,
|
|
55228
|
+
example: "registry-vpc.cn-hangzhou.aliyuncs.com/ttc-prod/clawd-persona-cloud",
|
|
55229
|
+
where: "\u8DDF baseImage \u662F**\u540C\u4E00\u4E2A ACR \u4ED3\u5E93**\uFF0C\u4F46\u8FD9\u91CC\u8981 **VPC \u5185\u7F51**\u5730\u5740\uFF08\u4E91\u5BBF\u4E3B\u6309\u5B83\u62C9\uFF09\uFF0CbaseImage \u90A3\u8FB9\u8981\u516C\u7F51\u5730\u5740\uFF08runner \u6309\u5B83\u62C9\uFF09\u3002\u522B\u5199\u53CD"
|
|
55230
|
+
});
|
|
55231
|
+
}
|
|
55232
|
+
return gaps;
|
|
55233
|
+
}
|
|
55234
|
+
function formatGaps(file, gaps, hasLocalCoords) {
|
|
55235
|
+
const lines = [
|
|
55236
|
+
`${file} \u8FD8\u5DEE ${gaps.length} \u9879\u624D\u80FD\u7528 buildHost=gha \u8DD1\u8BD5\u88C5\uFF08\u955C\u50CF\u5207\u6210\u300C\u5E95\u5EA7 + persona \u5C42\u300D\u4E4B\u540E\u65B0\u589E\u7684\uFF0C\u65E7\u914D\u7F6E\u5347\u4E0A\u6765\u90FD\u4F1A\u7F3A\uFF09\uFF1A`,
|
|
55237
|
+
""
|
|
55238
|
+
];
|
|
55239
|
+
for (const g2 of gaps) {
|
|
55240
|
+
lines.push(` \xB7 ${g2.field} \u2014\u2014 ${g2.why}`);
|
|
55241
|
+
lines.push(` \u793A\u4F8B\uFF1A${g2.example}`);
|
|
55242
|
+
lines.push(` \u4ECE\u54EA\u62FF\uFF1A${g2.where}`);
|
|
55243
|
+
lines.push("");
|
|
55244
|
+
}
|
|
55245
|
+
lines.push(`\u5B8C\u6574\u793A\u4F8B\u89C1 ${EXAMPLE_FILE}\u3002`);
|
|
55246
|
+
if (hasLocalCoords) {
|
|
55247
|
+
lines.push(
|
|
55248
|
+
'\u4E0D\u60F3\u73B0\u5728\u914D\u8FD9\u4E9B\u7684\u8BDD\uFF1A\u8FD9\u4EFD\u914D\u7F6E\u91CC\u5DF2\u7ECF\u6709 k3sHost / k3sKeyPath \u4E86\uFF0C\u52A0\u4E00\u884C `"buildHost": "local"` \u5C31\u9000\u56DE\u672C\u673A docker \u6784\u5EFA + \u4FA7\u8F7D\u90A3\u6761\u8DEF\uFF08\u8981\u672C\u673A\u6709 docker\uFF09\u3002'
|
|
55249
|
+
);
|
|
55250
|
+
}
|
|
55251
|
+
return lines.join("\n");
|
|
55252
|
+
}
|
|
55175
55253
|
async function loadCloudHostConfig(dataDir) {
|
|
55176
55254
|
const file = import_node_path32.default.join(dataDir, CLOUD_HOST_CONFIG_FILE);
|
|
55177
55255
|
let raw;
|
|
@@ -55180,7 +55258,7 @@ async function loadCloudHostConfig(dataDir) {
|
|
|
55180
55258
|
} catch (err) {
|
|
55181
55259
|
if (err.code === "ENOENT") {
|
|
55182
55260
|
throw new CloudHostConfigError(
|
|
55183
|
-
`\u8FD8\u6CA1\u914D ${file}\u3002\u8BD5\u88C5\u8981\u77E5\u9053\
|
|
55261
|
+
`\u8FD8\u6CA1\u914D ${file}\u3002\u8BD5\u88C5\u8981\u77E5\u9053\u955C\u50CF\u5728\u54EA\u513F\u6784\u3001\u8DDF\u54EA\u4E2A gateway \u8BF4\u8BDD\uFF0C\u5B57\u6BB5\u89C1 specs/2026-09-04-persona-cloud-base-image-design.md\u3002`
|
|
55184
55262
|
);
|
|
55185
55263
|
}
|
|
55186
55264
|
throw err;
|
|
@@ -55195,24 +55273,284 @@ async function loadCloudHostConfig(dataDir) {
|
|
|
55195
55273
|
if (missing.length > 0) {
|
|
55196
55274
|
throw new CloudHostConfigError(`${file} \u7F3A\u5B57\u6BB5\uFF1A${missing.join(" / ")}`);
|
|
55197
55275
|
}
|
|
55276
|
+
const buildHost = parsed.buildHost === "local" ? "local" : "gha";
|
|
55277
|
+
const imageRepo = parsed.imageRepo ?? "clawd-persona-cloud";
|
|
55278
|
+
if (buildHost === "local") {
|
|
55279
|
+
const need = ["k3sHost", "k3sKeyPath"].filter((k2) => !parsed[k2]);
|
|
55280
|
+
if (need.length > 0) {
|
|
55281
|
+
throw new CloudHostConfigError(`${file} \u7684 buildHost \u662F local\uFF0C\u8FD8\u7F3A\uFF1A${need.join(" / ")}`);
|
|
55282
|
+
}
|
|
55283
|
+
} else {
|
|
55284
|
+
const gaps = ghaGaps(parsed, imageRepo);
|
|
55285
|
+
if (gaps.length > 0) {
|
|
55286
|
+
throw new CloudHostConfigError(
|
|
55287
|
+
formatGaps(file, gaps, Boolean(parsed.k3sHost && parsed.k3sKeyPath))
|
|
55288
|
+
);
|
|
55289
|
+
}
|
|
55290
|
+
}
|
|
55198
55291
|
return {
|
|
55199
55292
|
provisionDir: parsed.provisionDir,
|
|
55200
55293
|
gatewayUrl: parsed.gatewayUrl.replace(/\/+$/, ""),
|
|
55201
55294
|
gatewayAdminKey: parsed.gatewayAdminKey,
|
|
55202
55295
|
gatewayApiKey: parsed.gatewayApiKey,
|
|
55203
|
-
|
|
55204
|
-
|
|
55205
|
-
|
|
55296
|
+
buildHost,
|
|
55297
|
+
imageRepo,
|
|
55298
|
+
...parsed.baseImage ? { baseImage: parsed.baseImage } : {},
|
|
55299
|
+
...parsed.github ? {
|
|
55300
|
+
github: {
|
|
55301
|
+
repo: parsed.github.repo,
|
|
55302
|
+
token: parsed.github.token,
|
|
55303
|
+
ref: parsed.github.ref ?? "release",
|
|
55304
|
+
workflow: parsed.github.workflow ?? "build-persona-deploy-image.yml"
|
|
55305
|
+
}
|
|
55306
|
+
} : {},
|
|
55307
|
+
...parsed.bundleStore ? {
|
|
55308
|
+
bundleStore: {
|
|
55309
|
+
endpoint: parsed.bundleStore.endpoint,
|
|
55310
|
+
bucket: parsed.bundleStore.bucket,
|
|
55311
|
+
accessKeyId: parsed.bundleStore.accessKeyId,
|
|
55312
|
+
accessKeySecret: parsed.bundleStore.accessKeySecret,
|
|
55313
|
+
prefix: parsed.bundleStore.prefix ?? "persona-bundles/"
|
|
55314
|
+
}
|
|
55315
|
+
} : {},
|
|
55316
|
+
...parsed.k3sHost ? { k3sHost: parsed.k3sHost } : {},
|
|
55317
|
+
...parsed.k3sKeyPath ? { k3sKeyPath: parsed.k3sKeyPath } : {},
|
|
55206
55318
|
trialTimeoutMs: parsed.trialTimeoutMs ?? 45 * 6e4
|
|
55207
55319
|
};
|
|
55208
55320
|
}
|
|
55209
55321
|
|
|
55210
55322
|
// src/deploy/trial-runner.ts
|
|
55323
|
+
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
55324
|
+
var import_node_os9 = __toESM(require("os"), 1);
|
|
55325
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
55326
|
+
|
|
55327
|
+
// src/deploy/bundle-store.ts
|
|
55328
|
+
var import_node_crypto7 = __toESM(require("crypto"), 1);
|
|
55211
55329
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
55212
55330
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
55213
55331
|
var import_node_path33 = __toESM(require("path"), 1);
|
|
55332
|
+
var import_node_child_process8 = require("child_process");
|
|
55333
|
+
var BUNDLE_URL_TTL_SEC = 30 * 60;
|
|
55334
|
+
var RUNTIME_STATE = /* @__PURE__ */ new Set(["projects", ".attachments", ".clawd/sessions"]);
|
|
55335
|
+
var NEVER_PERSONA = /* @__PURE__ */ new Set(["node_modules", ".git"]);
|
|
55336
|
+
async function stagePersonaDir(personaDir) {
|
|
55337
|
+
const stage = await import_promises7.default.mkdtemp(import_node_path33.default.join(import_node_os8.default.tmpdir(), "clawd-bundle-"));
|
|
55338
|
+
const root = import_node_path33.default.resolve(personaDir);
|
|
55339
|
+
await import_promises7.default.cp(root, import_node_path33.default.join(stage, "persona"), {
|
|
55340
|
+
recursive: true,
|
|
55341
|
+
dereference: true,
|
|
55342
|
+
filter: (src) => {
|
|
55343
|
+
const rel = import_node_path33.default.relative(root, import_node_path33.default.resolve(src));
|
|
55344
|
+
if (!rel) return true;
|
|
55345
|
+
return !RUNTIME_STATE.has(rel) && !NEVER_PERSONA.has(import_node_path33.default.basename(rel));
|
|
55346
|
+
}
|
|
55347
|
+
});
|
|
55348
|
+
return { dir: stage, cleanup: () => import_promises7.default.rm(stage, { recursive: true, force: true }) };
|
|
55349
|
+
}
|
|
55350
|
+
async function packPersonaBundle(personaDir) {
|
|
55351
|
+
const { dir: stage, cleanup } = await stagePersonaDir(personaDir);
|
|
55352
|
+
const file = import_node_path33.default.join(stage, "bundle.tgz");
|
|
55353
|
+
await new Promise((resolve9, reject) => {
|
|
55354
|
+
const child = (0, import_node_child_process8.spawn)("tar", ["-czf", file, "-C", stage, "persona"], { stdio: ["ignore", "ignore", "pipe"] });
|
|
55355
|
+
let err = "";
|
|
55356
|
+
child.stderr.on("data", (d) => {
|
|
55357
|
+
err += d.toString("utf8");
|
|
55358
|
+
});
|
|
55359
|
+
child.on("error", (e) => reject(new Error(`\u6253\u5305 persona \u76EE\u5F55\u8D77\u4E0D\u6765 tar\uFF1A${e.message}`)));
|
|
55360
|
+
child.on("close", (code) => code === 0 ? resolve9() : reject(new Error(`tar \u9000\u51FA\u7801 ${code}\uFF1A${err.slice(-500)}`)));
|
|
55361
|
+
});
|
|
55362
|
+
return { file, cleanup };
|
|
55363
|
+
}
|
|
55364
|
+
function sign(cfg, args) {
|
|
55365
|
+
const canonical = [
|
|
55366
|
+
args.method,
|
|
55367
|
+
args.contentMd5 ?? "",
|
|
55368
|
+
args.contentType ?? "",
|
|
55369
|
+
args.dateOrExpires,
|
|
55370
|
+
`/${cfg.bucket}/${args.key}`
|
|
55371
|
+
].join("\n");
|
|
55372
|
+
return import_node_crypto7.default.createHmac("sha1", cfg.accessKeySecret).update(canonical).digest("base64");
|
|
55373
|
+
}
|
|
55374
|
+
var objectUrl = (cfg, key) => `https://${cfg.bucket}.${cfg.endpoint}/${key.split("/").map(encodeURIComponent).join("/")}`;
|
|
55375
|
+
async function putBundle(cfg, key, body, fetchImpl = fetch, now = () => Date.now()) {
|
|
55376
|
+
const date = new Date(now()).toUTCString();
|
|
55377
|
+
const contentType = "application/gzip";
|
|
55378
|
+
const contentMd5 = import_node_crypto7.default.createHash("md5").update(body).digest("base64");
|
|
55379
|
+
const res = await fetchImpl(objectUrl(cfg, key), {
|
|
55380
|
+
method: "PUT",
|
|
55381
|
+
headers: {
|
|
55382
|
+
Date: date,
|
|
55383
|
+
"Content-Type": contentType,
|
|
55384
|
+
"Content-MD5": contentMd5,
|
|
55385
|
+
Authorization: `OSS ${cfg.accessKeyId}:${sign(cfg, { method: "PUT", key, dateOrExpires: date, contentMd5, contentType })}`
|
|
55386
|
+
},
|
|
55387
|
+
body: new Uint8Array(body)
|
|
55388
|
+
});
|
|
55389
|
+
if (!res.ok) {
|
|
55390
|
+
const text = await res.text().catch(() => "");
|
|
55391
|
+
throw new Error(`bundle \u4F20\u4E0D\u4E0A OSS\uFF08HTTP ${res.status}\uFF09\uFF1A${text.slice(0, 400)}`);
|
|
55392
|
+
}
|
|
55393
|
+
const expires = String(Math.floor(now() / 1e3) + BUNDLE_URL_TTL_SEC);
|
|
55394
|
+
const sig = sign(cfg, { method: "GET", key, dateOrExpires: expires });
|
|
55395
|
+
const q = new URLSearchParams({
|
|
55396
|
+
OSSAccessKeyId: cfg.accessKeyId,
|
|
55397
|
+
Expires: expires,
|
|
55398
|
+
Signature: sig
|
|
55399
|
+
});
|
|
55400
|
+
return { key, url: `${objectUrl(cfg, key)}?${q.toString()}`, bytes: body.length };
|
|
55401
|
+
}
|
|
55402
|
+
async function removeBundle(cfg, key, fetchImpl = fetch, now = () => Date.now()) {
|
|
55403
|
+
const date = new Date(now()).toUTCString();
|
|
55404
|
+
try {
|
|
55405
|
+
const res = await fetchImpl(objectUrl(cfg, key), {
|
|
55406
|
+
method: "DELETE",
|
|
55407
|
+
headers: {
|
|
55408
|
+
Date: date,
|
|
55409
|
+
Authorization: `OSS ${cfg.accessKeyId}:${sign(cfg, { method: "DELETE", key, dateOrExpires: date })}`
|
|
55410
|
+
}
|
|
55411
|
+
});
|
|
55412
|
+
return res.ok || res.status === 404;
|
|
55413
|
+
} catch {
|
|
55414
|
+
return false;
|
|
55415
|
+
}
|
|
55416
|
+
}
|
|
55417
|
+
|
|
55418
|
+
// src/deploy/gha-build.ts
|
|
55419
|
+
var POLL_MS = 5e3;
|
|
55420
|
+
var CLAIM_TIMEOUT_MS = 12e4;
|
|
55421
|
+
var LOG_TAIL_CHARS = 4e3;
|
|
55422
|
+
var GAP_MARKER = "::clawd-build-gaps::";
|
|
55423
|
+
function gapsFromRunnerLog(log) {
|
|
55424
|
+
const i = log.lastIndexOf(GAP_MARKER);
|
|
55425
|
+
if (i === -1) return [];
|
|
55426
|
+
const line = log.slice(i + GAP_MARKER.length).split("\n")[0].trim();
|
|
55427
|
+
try {
|
|
55428
|
+
const parsed = JSON.parse(line);
|
|
55429
|
+
if (!Array.isArray(parsed)) return [];
|
|
55430
|
+
return parsed.filter((g2) => g2 && typeof g2.errorText === "string" && g2.errorText.length > 0).map((g2) => ({
|
|
55431
|
+
errorText: g2.errorText,
|
|
55432
|
+
...g2.raw ? { raw: g2.raw } : {},
|
|
55433
|
+
...g2.suggest ? { suggest: g2.suggest } : {}
|
|
55434
|
+
}));
|
|
55435
|
+
} catch {
|
|
55436
|
+
return [];
|
|
55437
|
+
}
|
|
55438
|
+
}
|
|
55439
|
+
async function gh(deps, url, init) {
|
|
55440
|
+
const res = await deps.fetchImpl(`https://api.github.com${url}`, {
|
|
55441
|
+
...init,
|
|
55442
|
+
headers: {
|
|
55443
|
+
accept: "application/vnd.github+json",
|
|
55444
|
+
authorization: `Bearer ${deps.github.token}`,
|
|
55445
|
+
"x-github-api-version": "2022-11-28",
|
|
55446
|
+
...init?.body ? { "content-type": "application/json" } : {},
|
|
55447
|
+
...init?.headers
|
|
55448
|
+
}
|
|
55449
|
+
});
|
|
55450
|
+
if (!res.ok) {
|
|
55451
|
+
const text = await res.text().catch(() => "");
|
|
55452
|
+
throw new Error(`GitHub ${init?.method ?? "GET"} ${url} \u2192 HTTP ${res.status}\uFF1A${text.slice(0, 400)}`);
|
|
55453
|
+
}
|
|
55454
|
+
if (res.status === 204) return void 0;
|
|
55455
|
+
return await res.json();
|
|
55456
|
+
}
|
|
55457
|
+
async function claimRun(deps, tag) {
|
|
55458
|
+
const { repo: repo2, workflow } = deps.github;
|
|
55459
|
+
const deadline = deps.now() + CLAIM_TIMEOUT_MS;
|
|
55460
|
+
for (; ; ) {
|
|
55461
|
+
const list = await gh(
|
|
55462
|
+
deps,
|
|
55463
|
+
`/repos/${repo2}/actions/workflows/${encodeURIComponent(workflow)}/runs?event=workflow_dispatch&per_page=30`
|
|
55464
|
+
);
|
|
55465
|
+
const hit = list.workflow_runs.find((r) => [r.name, r.display_title].some((n) => typeof n === "string" && n.includes(tag)));
|
|
55466
|
+
if (hit) return hit;
|
|
55467
|
+
if (deps.now() > deadline) {
|
|
55468
|
+
throw new Error(
|
|
55469
|
+
`\u89E6\u53D1\u4E4B\u540E ${Math.round(CLAIM_TIMEOUT_MS / 1e3)}s \u6CA1\u5728 ${repo2} \u7684 ${workflow} \u91CC\u627E\u5230 run-name \u5E26 \`${tag}\` \u7684 run\u3002workflow \u6587\u4EF6\u5728\u76EE\u6807 ref \u4E0A\u5B58\u5728\u5417\uFF1F\u5B83\u7684 run-name \u91CC\u5E26 inputs.tag \u5417\uFF1F`
|
|
55470
|
+
);
|
|
55471
|
+
}
|
|
55472
|
+
await deps.sleep(POLL_MS);
|
|
55473
|
+
}
|
|
55474
|
+
}
|
|
55475
|
+
async function failureDetail(deps, run) {
|
|
55476
|
+
const { repo: repo2 } = deps.github;
|
|
55477
|
+
try {
|
|
55478
|
+
const jobs = await gh(
|
|
55479
|
+
deps,
|
|
55480
|
+
`/repos/${repo2}/actions/runs/${run.id}/jobs`
|
|
55481
|
+
);
|
|
55482
|
+
const failed = jobs.jobs.find((j) => j.conclusion && j.conclusion !== "success");
|
|
55483
|
+
if (!failed) return { raw: "", gaps: [] };
|
|
55484
|
+
const step = failed.steps?.find((s) => s.conclusion && s.conclusion !== "success");
|
|
55485
|
+
const res = await deps.fetchImpl(`https://api.github.com/repos/${repo2}/actions/jobs/${failed.id}/logs`, {
|
|
55486
|
+
headers: { authorization: `Bearer ${deps.github.token}`, "x-github-api-version": "2022-11-28" }
|
|
55487
|
+
});
|
|
55488
|
+
const log = res.ok ? await res.text() : "";
|
|
55489
|
+
return {
|
|
55490
|
+
gaps: gapsFromRunnerLog(log),
|
|
55491
|
+
raw: [
|
|
55492
|
+
`\u5931\u8D25\u7684\u6B65\u9AA4\uFF1A${failed.name}${step ? ` / ${step.name}` : ""}`,
|
|
55493
|
+
log ? log.slice(-LOG_TAIL_CHARS) : "\uFF08\u65E5\u5FD7\u53D6\u4E0D\u5230\uFF09"
|
|
55494
|
+
].join("\n")
|
|
55495
|
+
};
|
|
55496
|
+
} catch (err) {
|
|
55497
|
+
return { raw: `\uFF08\u53D6\u5931\u8D25\u8BE6\u60C5\u65F6\u53C8\u51FA\u9519\u4E86\uFF1A${String(err)}\uFF09`, gaps: [] };
|
|
55498
|
+
}
|
|
55499
|
+
}
|
|
55500
|
+
async function buildOnGha(deps, args) {
|
|
55501
|
+
const { repo: repo2, ref, workflow } = deps.github;
|
|
55502
|
+
const started = deps.now();
|
|
55503
|
+
try {
|
|
55504
|
+
deps.onStage("\u5728 GitHub \u4E0A\u6392\u4E00\u6B21\u955C\u50CF\u6784\u5EFA");
|
|
55505
|
+
await gh(deps, `/repos/${repo2}/actions/workflows/${encodeURIComponent(workflow)}/dispatches`, {
|
|
55506
|
+
method: "POST",
|
|
55507
|
+
body: JSON.stringify({ ref, inputs: args.inputs })
|
|
55508
|
+
});
|
|
55509
|
+
} catch (err) {
|
|
55510
|
+
return { ok: false, errorText: `\u89E6\u53D1\u4E0D\u4E86 ${repo2} \u7684 ${workflow}\uFF1A${String(err)}` };
|
|
55511
|
+
}
|
|
55512
|
+
let run;
|
|
55513
|
+
try {
|
|
55514
|
+
run = await claimRun(deps, args.inputs.tag);
|
|
55515
|
+
} catch (err) {
|
|
55516
|
+
return { ok: false, errorText: String(err) };
|
|
55517
|
+
}
|
|
55518
|
+
deps.onStage(`\u955C\u50CF\u6784\u5EFA\u8DD1\u8D77\u6765\u4E86\uFF1A${run.html_url}`);
|
|
55519
|
+
const deadline = started + args.timeoutMs;
|
|
55520
|
+
for (; ; ) {
|
|
55521
|
+
if (deps.now() > deadline) {
|
|
55522
|
+
return {
|
|
55523
|
+
ok: false,
|
|
55524
|
+
runUrl: run.html_url,
|
|
55525
|
+
errorText: `\u7B49\u4E86 ${Math.round(args.timeoutMs / 6e4)} \u5206\u949F\uFF0C\u955C\u50CF\u8FD8\u6CA1\u6784\u5B8C\uFF1A${run.html_url}`
|
|
55526
|
+
};
|
|
55527
|
+
}
|
|
55528
|
+
await deps.sleep(POLL_MS);
|
|
55529
|
+
let cur;
|
|
55530
|
+
try {
|
|
55531
|
+
cur = await gh(deps, `/repos/${repo2}/actions/runs/${run.id}`);
|
|
55532
|
+
} catch (err) {
|
|
55533
|
+
deps.onStage(`\u95EE GitHub \u6784\u5EFA\u8FDB\u5C55\u6CA1\u95EE\u7740\uFF08\u4F1A\u91CD\u8BD5\uFF09\uFF1A${String(err).slice(0, 120)}`);
|
|
55534
|
+
continue;
|
|
55535
|
+
}
|
|
55536
|
+
if (cur.status !== "completed") continue;
|
|
55537
|
+
const seconds = Math.round((deps.now() - started) / 1e3);
|
|
55538
|
+
if (cur.conclusion === "success") return { ok: true, runUrl: cur.html_url, seconds };
|
|
55539
|
+
const detail = await failureDetail(deps, cur);
|
|
55540
|
+
return {
|
|
55541
|
+
ok: false,
|
|
55542
|
+
runUrl: cur.html_url,
|
|
55543
|
+
errorText: `\u955C\u50CF\u6CA1\u6784\u6210\uFF08${cur.conclusion}\uFF09\uFF1A${cur.html_url}`,
|
|
55544
|
+
raw: detail.raw,
|
|
55545
|
+
...detail.gaps.length > 0 ? { gaps: detail.gaps } : {}
|
|
55546
|
+
};
|
|
55547
|
+
}
|
|
55548
|
+
}
|
|
55549
|
+
|
|
55550
|
+
// src/deploy/trial-runner.ts
|
|
55214
55551
|
var RAW_TAIL_CHARS = 2e3;
|
|
55215
55552
|
var GATEWAY_ADMIN_TIMEOUT_MS = 3e4;
|
|
55553
|
+
var MAX_BUNDLE_BYTES = 64 * 1024 * 1024;
|
|
55216
55554
|
var trialStamp = (nowMs) => Math.floor(nowMs / 1e3).toString(36);
|
|
55217
55555
|
var trialImageTag = (repo2, deployId, round, stamp) => `${repo2}:${trialDeployId(deployId, round, stamp)}`;
|
|
55218
55556
|
var trialDeployId = (deployId, round, stamp) => `${deployId}-t${round}-${stamp}`;
|
|
@@ -55371,8 +55709,8 @@ async function* sseLines(res) {
|
|
|
55371
55709
|
}
|
|
55372
55710
|
if (buf.trim()) yield buf.trim();
|
|
55373
55711
|
}
|
|
55374
|
-
async function gatewayAdmin(deps,
|
|
55375
|
-
const res = await deps.fetchImpl(`${deps.cloudHost.gatewayUrl}${
|
|
55712
|
+
async function gatewayAdmin(deps, path99, body) {
|
|
55713
|
+
const res = await deps.fetchImpl(`${deps.cloudHost.gatewayUrl}${path99}`, {
|
|
55376
55714
|
method: "POST",
|
|
55377
55715
|
headers: {
|
|
55378
55716
|
"content-type": "application/json",
|
|
@@ -55385,11 +55723,11 @@ async function gatewayAdmin(deps, path98, body) {
|
|
|
55385
55723
|
signal: AbortSignal.timeout(GATEWAY_ADMIN_TIMEOUT_MS)
|
|
55386
55724
|
});
|
|
55387
55725
|
const text = await res.text();
|
|
55388
|
-
if (!res.ok) throw new Error(`gateway ${
|
|
55726
|
+
if (!res.ok) throw new Error(`gateway ${path99} \u56DE\u4E86 HTTP ${res.status}\uFF1A${text.slice(0, 300)}`);
|
|
55389
55727
|
try {
|
|
55390
55728
|
return JSON.parse(text);
|
|
55391
55729
|
} catch {
|
|
55392
|
-
throw new Error(`gateway ${
|
|
55730
|
+
throw new Error(`gateway ${path99} \u56DE\u7684\u4E0D\u662F JSON\uFF1A${text.slice(0, 300)}`);
|
|
55393
55731
|
}
|
|
55394
55732
|
}
|
|
55395
55733
|
async function registerOfficialDeployment(deps, receipt, deployerSecrets) {
|
|
@@ -55414,41 +55752,168 @@ async function registerOfficialDeployment(deps, receipt, deployerSecrets) {
|
|
|
55414
55752
|
deployedAt: deps.now()
|
|
55415
55753
|
};
|
|
55416
55754
|
}
|
|
55417
|
-
async function
|
|
55418
|
-
const { receipt, round } = args;
|
|
55755
|
+
async function buildViaGha(deps, args) {
|
|
55419
55756
|
const { cloudHost } = deps;
|
|
55420
|
-
const
|
|
55421
|
-
const
|
|
55422
|
-
const
|
|
55423
|
-
|
|
55424
|
-
|
|
55425
|
-
|
|
55757
|
+
const store = cloudHost.bundleStore;
|
|
55758
|
+
const github = cloudHost.github;
|
|
55759
|
+
const baseImage = cloudHost.baseImage;
|
|
55760
|
+
if (!store || !github || !baseImage) {
|
|
55761
|
+
return { ok: false, gaps: [gap(
|
|
55762
|
+
`cloud-host.json \u7684 buildHost \u662F gha\uFF0C\u4F46\u7F3A ${[
|
|
55763
|
+
!github && "github",
|
|
55764
|
+
!store && "bundleStore",
|
|
55765
|
+
!baseImage && "baseImage"
|
|
55766
|
+
].filter(Boolean).join(" / ")}\u3002`
|
|
55767
|
+
)] };
|
|
55768
|
+
}
|
|
55769
|
+
const key = `${store.prefix}${args.tag}.tgz`;
|
|
55770
|
+
deps.onStage("\u5728\u6253\u5305 persona \u76EE\u5F55");
|
|
55771
|
+
let packed;
|
|
55772
|
+
try {
|
|
55773
|
+
packed = await packPersonaBundle(args.personaDir);
|
|
55774
|
+
} catch (err) {
|
|
55775
|
+
return { ok: false, gaps: [gap(`\u6253\u4E0D\u51FA persona \u76EE\u5F55\u7684\u5305\uFF1A${String(err)}`)] };
|
|
55776
|
+
}
|
|
55777
|
+
try {
|
|
55778
|
+
const body = await import_promises8.default.readFile(packed.file);
|
|
55779
|
+
if (body.length > MAX_BUNDLE_BYTES) {
|
|
55780
|
+
return { ok: false, gaps: [gap(
|
|
55781
|
+
`persona \u76EE\u5F55\u6253\u5B8C\u5305\u8FD8\u6709 ${Math.round(body.length / 1e6)} MB\uFF0C\u8D85\u8FC7 ${MAX_BUNDLE_BYTES / 1e6} MB \u5C31\u4E0D\u4F20\u4E86\u3002\u955C\u50CF\u91CC\u53EA\u8BE5\u6709\u4EBA\u683C\uFF0C\u9879\u76EE / \u4F1A\u8BDD\u8BB0\u5F55 / \u9644\u4EF6\u8FD9\u4E9B\u8FD0\u884C\u671F\u72B6\u6001\u5728\u4E91\u4E0A\u662F\u6302\u8F7D\u5377\u3002`,
|
|
55782
|
+
args.personaDir
|
|
55783
|
+
)] };
|
|
55784
|
+
}
|
|
55785
|
+
let ref;
|
|
55786
|
+
try {
|
|
55787
|
+
ref = await putBundle(store, key, body, deps.fetchImpl, deps.now);
|
|
55788
|
+
} catch (err) {
|
|
55789
|
+
return { ok: false, gaps: [gap(`persona \u76EE\u5F55\u4F20\u4E0D\u4E0A\u4E2D\u8F6C\u4ED3\u5E93\uFF1A${String(err)}`)] };
|
|
55790
|
+
}
|
|
55791
|
+
deps.onStage(`persona \u76EE\u5F55\u9001\u4E0A\u53BB\u4E86\uFF08${Math.round(ref.bytes / 1024)} KB\uFF09`);
|
|
55792
|
+
const built = await buildOnGha(
|
|
55793
|
+
{
|
|
55794
|
+
github,
|
|
55795
|
+
fetchImpl: deps.fetchImpl,
|
|
55796
|
+
now: deps.now,
|
|
55797
|
+
sleep: deps.sleep,
|
|
55798
|
+
onStage: deps.onStage
|
|
55799
|
+
},
|
|
55800
|
+
{
|
|
55801
|
+
timeoutMs: args.timeoutMs,
|
|
55802
|
+
inputs: {
|
|
55803
|
+
tag: args.tag,
|
|
55804
|
+
base_image: baseImage,
|
|
55805
|
+
bundle_url: ref.url,
|
|
55806
|
+
manifest_b64: Buffer.from(JSON.stringify({ manifest: args.manifest })).toString("base64")
|
|
55807
|
+
}
|
|
55808
|
+
}
|
|
55809
|
+
);
|
|
55810
|
+
if (!built.ok) {
|
|
55811
|
+
return {
|
|
55812
|
+
ok: false,
|
|
55813
|
+
gaps: built.gaps?.length ? built.gaps.map((g2) => gap(g2.errorText, g2.raw ?? built.raw, g2.suggest)) : [gap(built.errorText, built.raw)]
|
|
55814
|
+
};
|
|
55815
|
+
}
|
|
55816
|
+
deps.logger?.info("deploy.trial.image-built", { tag: args.tag, seconds: built.seconds, run: built.runUrl });
|
|
55817
|
+
return { ok: true };
|
|
55818
|
+
} catch (err) {
|
|
55819
|
+
return { ok: false, gaps: [gap(`\u6784\u955C\u50CF\u8FD9\u4E00\u6B65\u8D77\u4E0D\u6765\uFF1A${String(err)}`)] };
|
|
55820
|
+
} finally {
|
|
55821
|
+
await packed.cleanup().catch(() => {
|
|
55822
|
+
});
|
|
55823
|
+
const gone = await removeBundle(store, key, deps.fetchImpl, deps.now);
|
|
55824
|
+
if (!gone) deps.logger?.warn("deploy.trial.bundle-not-removed", { key });
|
|
55825
|
+
}
|
|
55826
|
+
}
|
|
55827
|
+
async function buildLocally(deps, args) {
|
|
55828
|
+
const { cloudHost } = deps;
|
|
55829
|
+
const baseTag = `${cloudHost.imageRepo}:base-local`;
|
|
55830
|
+
const deadline = deps.now() + args.timeoutMs;
|
|
55426
55831
|
const left = () => Math.max(3e4, deadline - deps.now());
|
|
55427
|
-
deps.onStage("\u5728\
|
|
55428
|
-
const
|
|
55832
|
+
deps.onStage("\u5728\u672C\u673A\u6784\u5E95\u5EA7");
|
|
55833
|
+
const base = await deps.runNode(
|
|
55834
|
+
`${cloudHost.provisionDir}/build-image.mjs`,
|
|
55835
|
+
[
|
|
55836
|
+
"--base",
|
|
55837
|
+
"--manifest",
|
|
55838
|
+
`${cloudHost.provisionDir}/manifests/base.json`,
|
|
55839
|
+
"--tag",
|
|
55840
|
+
baseTag,
|
|
55841
|
+
"--platform",
|
|
55842
|
+
"linux/amd64",
|
|
55843
|
+
"--context",
|
|
55844
|
+
`${cloudHost.provisionDir}/build-context-base`
|
|
55845
|
+
],
|
|
55846
|
+
{ timeoutMs: left() }
|
|
55847
|
+
);
|
|
55848
|
+
if (base.code !== 0) return { ok: false, gaps: gapsFromBuildOutput(base) };
|
|
55849
|
+
deps.onStage("\u5728\u6309\u6E05\u5355\u6784 persona \u5C42");
|
|
55850
|
+
const manifestFile = import_node_path34.default.join(import_node_os9.default.tmpdir(), `clawd-trial-${args.tmpKey}.json`);
|
|
55429
55851
|
let built;
|
|
55852
|
+
let staged;
|
|
55853
|
+
try {
|
|
55854
|
+
staged = await stagePersonaDir(args.personaDir);
|
|
55855
|
+
} catch (err) {
|
|
55856
|
+
return { ok: false, gaps: [gap(`\u7406\u4E0D\u51FA\u8981\u6253\u8FDB\u955C\u50CF\u7684 persona \u76EE\u5F55\uFF1A${String(err)}`)] };
|
|
55857
|
+
}
|
|
55430
55858
|
try {
|
|
55431
|
-
await
|
|
55859
|
+
await import_promises8.default.writeFile(manifestFile, JSON.stringify({ manifest: args.manifest }, null, 2), { mode: 384 });
|
|
55432
55860
|
built = await deps.runNode(
|
|
55433
55861
|
`${cloudHost.provisionDir}/build-image.mjs`,
|
|
55434
|
-
[
|
|
55862
|
+
[
|
|
55863
|
+
"--manifest",
|
|
55864
|
+
manifestFile,
|
|
55865
|
+
"--from",
|
|
55866
|
+
baseTag,
|
|
55867
|
+
"--persona-dir",
|
|
55868
|
+
import_node_path34.default.join(staged.dir, "persona"),
|
|
55869
|
+
"--tag",
|
|
55870
|
+
args.image,
|
|
55871
|
+
"--platform",
|
|
55872
|
+
"linux/amd64"
|
|
55873
|
+
],
|
|
55435
55874
|
{ timeoutMs: left() }
|
|
55436
55875
|
);
|
|
55437
|
-
await
|
|
55876
|
+
await import_promises8.default.rm(manifestFile, { force: true });
|
|
55438
55877
|
} catch (err) {
|
|
55439
|
-
return { ok: false,
|
|
55878
|
+
return { ok: false, gaps: [gap(`\u6784\u955C\u50CF\u8FD9\u4E00\u6B65\u8D77\u4E0D\u6765\uFF1A${String(err)}`)] };
|
|
55879
|
+
} finally {
|
|
55880
|
+
await staged.cleanup().catch(() => {
|
|
55881
|
+
});
|
|
55440
55882
|
}
|
|
55441
|
-
if (built.code !== 0) return { ok: false,
|
|
55883
|
+
if (built.code !== 0) return { ok: false, gaps: gapsFromBuildOutput(built) };
|
|
55442
55884
|
deps.onStage("\u628A\u955C\u50CF\u63A8\u5230\u4E91\u4E0A\u90A3\u53F0\u673A\u5668");
|
|
55885
|
+
if (!cloudHost.k3sHost || !cloudHost.k3sKeyPath) {
|
|
55886
|
+
return { ok: false, gaps: [gap("cloud-host.json \u7684 buildHost \u662F local\uFF0C\u4F46\u7F3A k3sHost / k3sKeyPath\u3002")] };
|
|
55887
|
+
}
|
|
55443
55888
|
const pushed = await deps.runNode(
|
|
55444
55889
|
`${cloudHost.provisionDir}/push-to-k3s.mjs`,
|
|
55445
|
-
["--host", cloudHost.k3sHost, "--key", cloudHost.k3sKeyPath, "--image", image],
|
|
55890
|
+
["--host", cloudHost.k3sHost, "--key", cloudHost.k3sKeyPath, "--image", args.image],
|
|
55446
55891
|
{ timeoutMs: left() }
|
|
55447
55892
|
);
|
|
55448
55893
|
if (pushed.code !== 0) {
|
|
55449
|
-
return { ok: false,
|
|
55894
|
+
return { ok: false, gaps: [gap(`\u955C\u50CF\u63A8\u4E0D\u4E0A\u53BB\uFF08\u9000\u51FA\u7801 ${pushed.code}\uFF09\u3002`, `${pushed.stdout}
|
|
55450
55895
|
${pushed.stderr}`)] };
|
|
55451
55896
|
}
|
|
55897
|
+
return { ok: true };
|
|
55898
|
+
}
|
|
55899
|
+
async function runTrial(deps, args) {
|
|
55900
|
+
const { receipt, round } = args;
|
|
55901
|
+
const { cloudHost } = deps;
|
|
55902
|
+
const manifest = receipt.manifest;
|
|
55903
|
+
const stamp = trialStamp(deps.now());
|
|
55904
|
+
const trialId = trialDeployId(receipt.deployId, round, stamp);
|
|
55905
|
+
const image = trialImageTag(cloudHost.imageRepo, receipt.deployId, round, stamp);
|
|
55906
|
+
const appName = trialAppName(receipt.deployId);
|
|
55907
|
+
const deadline = deps.now() + cloudHost.trialTimeoutMs;
|
|
55908
|
+
const left = () => Math.max(3e4, deadline - deps.now());
|
|
55909
|
+
const buildOutcome = cloudHost.buildHost === "local" ? await buildLocally(deps, {
|
|
55910
|
+
manifest,
|
|
55911
|
+
personaDir: args.personaDir,
|
|
55912
|
+
image,
|
|
55913
|
+
timeoutMs: left(),
|
|
55914
|
+
tmpKey: `${receipt.deployId}-t${round}-${stamp}`
|
|
55915
|
+
}) : await buildViaGha(deps, { manifest, personaDir: args.personaDir, tag: trialId, timeoutMs: left() });
|
|
55916
|
+
if (!buildOutcome.ok) return { ok: false, spent: false, gaps: buildOutcome.gaps };
|
|
55452
55917
|
deps.onStage("\u5728\u4E91\u4E0A\u767B\u8BB0\u8FD9\u6B21\u8BD5\u88C5");
|
|
55453
55918
|
try {
|
|
55454
55919
|
await gatewayAdmin(deps, "/admin/deployments", {
|
|
@@ -55514,10 +55979,10 @@ ${pushed.stderr}`)] };
|
|
|
55514
55979
|
}
|
|
55515
55980
|
|
|
55516
55981
|
// src/deploy/run-node.ts
|
|
55517
|
-
var
|
|
55982
|
+
var import_node_child_process9 = require("child_process");
|
|
55518
55983
|
async function runNodeScript(script, args, timeoutMs) {
|
|
55519
55984
|
return await new Promise((resolve9, reject) => {
|
|
55520
|
-
const child = (0,
|
|
55985
|
+
const child = (0, import_node_child_process9.spawn)(process.execPath, [script, ...args], { stdio: ["ignore", "pipe", "pipe"] });
|
|
55521
55986
|
let stdout = "";
|
|
55522
55987
|
let stderr = "";
|
|
55523
55988
|
child.stdout.on("data", (d) => {
|
|
@@ -55960,9 +56425,9 @@ async function refreshTunnelUrlOnStartup(deps) {
|
|
|
55960
56425
|
|
|
55961
56426
|
// src/lark-bot-connector/binding-store.ts
|
|
55962
56427
|
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
55963
|
-
var
|
|
56428
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
55964
56429
|
function createLarkBotBindingStore(personaRoot) {
|
|
55965
|
-
const filePath = (personaId2) =>
|
|
56430
|
+
const filePath = (personaId2) => import_node_path35.default.join(personaRoot, safeFileName(personaId2), ".clawd", "lark-bot.json");
|
|
55966
56431
|
const read = (personaId2) => {
|
|
55967
56432
|
const file = filePath(personaId2);
|
|
55968
56433
|
if (!import_node_fs28.default.existsSync(file)) return null;
|
|
@@ -55976,7 +56441,7 @@ function createLarkBotBindingStore(personaRoot) {
|
|
|
55976
56441
|
};
|
|
55977
56442
|
const write = (personaId2, meta) => {
|
|
55978
56443
|
const file = filePath(personaId2);
|
|
55979
|
-
import_node_fs28.default.mkdirSync(
|
|
56444
|
+
import_node_fs28.default.mkdirSync(import_node_path35.default.dirname(file), { recursive: true });
|
|
55980
56445
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
55981
56446
|
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(meta, null, 2), { mode: 384 });
|
|
55982
56447
|
import_node_fs28.default.renameSync(tmp, file);
|
|
@@ -56144,7 +56609,7 @@ function createLarkBotCloudClient(opts) {
|
|
|
56144
56609
|
|
|
56145
56610
|
// src/lark-bot-connector/chat-router.ts
|
|
56146
56611
|
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
56147
|
-
var
|
|
56612
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
56148
56613
|
init_protocol();
|
|
56149
56614
|
var ERROR_REPLY_TEXT = "\u5904\u7406\u51FA\u9519\u4E86\uFF0C\u8BF7\u91CD\u8BD5";
|
|
56150
56615
|
var LOCAL_TURN_RETRIES = 2;
|
|
@@ -56211,7 +56676,7 @@ function createLarkChatRouter(deps) {
|
|
|
56211
56676
|
}
|
|
56212
56677
|
const dir = deps.mediaRootFor(env.chatId);
|
|
56213
56678
|
import_node_fs29.default.mkdirSync(dir, { recursive: true });
|
|
56214
|
-
const p2 =
|
|
56679
|
+
const p2 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}.${ext}`);
|
|
56215
56680
|
import_node_fs29.default.writeFileSync(p2, r.data);
|
|
56216
56681
|
lines.push(`[\u56FE\u7247: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
56217
56682
|
} catch (err) {
|
|
@@ -56234,7 +56699,7 @@ function createLarkChatRouter(deps) {
|
|
|
56234
56699
|
}
|
|
56235
56700
|
const dir = deps.mediaRootFor(env.chatId);
|
|
56236
56701
|
import_node_fs29.default.mkdirSync(dir, { recursive: true });
|
|
56237
|
-
const p2 =
|
|
56702
|
+
const p2 = import_node_path36.default.join(dir, `${safeMediaName(ownerMessageId)}-${i}-${safeAttachmentName(f.name)}`);
|
|
56238
56703
|
import_node_fs29.default.writeFileSync(p2, r.data);
|
|
56239
56704
|
lines.push(`[\u6587\u4EF6: ${p2}]\uFF08\u7528 Read \u5DE5\u5177\u67E5\u770B\uFF09`);
|
|
56240
56705
|
} catch (err) {
|
|
@@ -56430,7 +56895,7 @@ ${formatLarkSpeakerReminder(speaker)}`
|
|
|
56430
56895
|
}
|
|
56431
56896
|
|
|
56432
56897
|
// src/lark-bot-connector/envelope.ts
|
|
56433
|
-
var
|
|
56898
|
+
var import_node_crypto8 = require("crypto");
|
|
56434
56899
|
var LARK_ENVELOPE_PREFIX = "clawdlbe1";
|
|
56435
56900
|
function verifyLarkEventEnvelope(args) {
|
|
56436
56901
|
const { token, publicKeyPem } = args;
|
|
@@ -56449,7 +56914,7 @@ function verifyLarkEventEnvelope(args) {
|
|
|
56449
56914
|
const data = Buffer.from(`${prefix}.${payloadB64}`, "utf8");
|
|
56450
56915
|
let sigOk = false;
|
|
56451
56916
|
try {
|
|
56452
|
-
sigOk = (0,
|
|
56917
|
+
sigOk = (0, import_node_crypto8.verify)(null, data, publicKeyPem, Buffer.from(sigB64, "base64url"));
|
|
56453
56918
|
} catch {
|
|
56454
56919
|
sigOk = false;
|
|
56455
56920
|
}
|
|
@@ -57324,7 +57789,7 @@ var CodexHistoryReader = class {
|
|
|
57324
57789
|
};
|
|
57325
57790
|
|
|
57326
57791
|
// src/tools/codex-skills.ts
|
|
57327
|
-
var
|
|
57792
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
57328
57793
|
function str3(v2) {
|
|
57329
57794
|
return typeof v2 === "string" ? v2 : void 0;
|
|
57330
57795
|
}
|
|
@@ -57339,13 +57804,13 @@ function mapSkillsListResponse(res) {
|
|
|
57339
57804
|
const r = s ?? {};
|
|
57340
57805
|
const name = str3(r.name);
|
|
57341
57806
|
if (!name) continue;
|
|
57342
|
-
const
|
|
57807
|
+
const path99 = str3(r.path);
|
|
57343
57808
|
const description = str3(r.description);
|
|
57344
57809
|
const isPlugin = name.includes(":");
|
|
57345
57810
|
out.push({
|
|
57346
57811
|
name,
|
|
57347
57812
|
source: isPlugin ? "plugin" : "project",
|
|
57348
|
-
...
|
|
57813
|
+
...path99 ? { path: path99 } : {},
|
|
57349
57814
|
...description ? { description } : {},
|
|
57350
57815
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
57351
57816
|
});
|
|
@@ -57361,14 +57826,14 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
57361
57826
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
57362
57827
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
57363
57828
|
beforeRequest: (client) => {
|
|
57364
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
57829
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path37.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
57365
57830
|
}
|
|
57366
57831
|
});
|
|
57367
57832
|
return mapSkillsListResponse(res);
|
|
57368
57833
|
}
|
|
57369
57834
|
|
|
57370
57835
|
// src/tools/codex-turn-context.ts
|
|
57371
|
-
var
|
|
57836
|
+
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
57372
57837
|
function parseTurnContextFromRollout(raw) {
|
|
57373
57838
|
const lines = raw.split("\n");
|
|
57374
57839
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
@@ -57403,7 +57868,7 @@ async function readCodexTurnContext(args, deps = {}) {
|
|
|
57403
57868
|
);
|
|
57404
57869
|
const rolloutPath = str4(rec3(res?.thread)?.path);
|
|
57405
57870
|
if (!rolloutPath) return null;
|
|
57406
|
-
return parseTurnContextFromRollout(await
|
|
57871
|
+
return parseTurnContextFromRollout(await import_promises9.default.readFile(rolloutPath, "utf8"));
|
|
57407
57872
|
}
|
|
57408
57873
|
function createCodexResolvedMetaHydrator(deps) {
|
|
57409
57874
|
const fetchedThreadIds = /* @__PURE__ */ new Set();
|
|
@@ -57447,15 +57912,15 @@ function str4(v2) {
|
|
|
57447
57912
|
|
|
57448
57913
|
// src/workspace/browser.ts
|
|
57449
57914
|
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
57450
|
-
var
|
|
57451
|
-
var
|
|
57915
|
+
var import_node_os10 = __toESM(require("os"), 1);
|
|
57916
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
57452
57917
|
init_protocol();
|
|
57453
57918
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
57454
57919
|
function resolveInsideCwd(cwd, subpath) {
|
|
57455
|
-
const absCwd =
|
|
57456
|
-
const joined =
|
|
57457
|
-
const rel =
|
|
57458
|
-
if (rel.startsWith("..") ||
|
|
57920
|
+
const absCwd = import_node_path38.default.resolve(cwd);
|
|
57921
|
+
const joined = import_node_path38.default.resolve(absCwd, subpath ?? ".");
|
|
57922
|
+
const rel = import_node_path38.default.relative(absCwd, joined);
|
|
57923
|
+
if (rel.startsWith("..") || import_node_path38.default.isAbsolute(rel)) {
|
|
57459
57924
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
57460
57925
|
}
|
|
57461
57926
|
return joined;
|
|
@@ -57473,7 +57938,7 @@ function ensureCwd(cwd) {
|
|
|
57473
57938
|
}
|
|
57474
57939
|
var WorkspaceBrowser = class {
|
|
57475
57940
|
list(args) {
|
|
57476
|
-
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd :
|
|
57941
|
+
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os10.default.homedir();
|
|
57477
57942
|
ensureCwd(cwd);
|
|
57478
57943
|
const full = resolveInsideCwd(cwd, args.path);
|
|
57479
57944
|
const dirents = import_node_fs30.default.readdirSync(full, { withFileTypes: true });
|
|
@@ -57486,7 +57951,7 @@ var WorkspaceBrowser = class {
|
|
|
57486
57951
|
mtime: ""
|
|
57487
57952
|
};
|
|
57488
57953
|
try {
|
|
57489
|
-
const st = import_node_fs30.default.statSync(
|
|
57954
|
+
const st = import_node_fs30.default.statSync(import_node_path38.default.join(full, d.name));
|
|
57490
57955
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
57491
57956
|
if (d.isFile()) entry.size = st.size;
|
|
57492
57957
|
} catch {
|
|
@@ -57532,8 +57997,8 @@ var WorkspaceBrowser = class {
|
|
|
57532
57997
|
|
|
57533
57998
|
// src/skills/agents-scanner.ts
|
|
57534
57999
|
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
57535
|
-
var
|
|
57536
|
-
var
|
|
58000
|
+
var import_node_os11 = __toESM(require("os"), 1);
|
|
58001
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
57537
58002
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
57538
58003
|
function isDirLikeSync2(p2) {
|
|
57539
58004
|
try {
|
|
@@ -57571,10 +58036,10 @@ function scanAgentsDir(dir, source, seen, out) {
|
|
|
57571
58036
|
}
|
|
57572
58037
|
for (const ent of entries) {
|
|
57573
58038
|
if (!ent.name.endsWith(".md")) continue;
|
|
57574
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
58039
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path39.default.join(dir, ent.name)))) {
|
|
57575
58040
|
continue;
|
|
57576
58041
|
}
|
|
57577
|
-
const filePath =
|
|
58042
|
+
const filePath = import_node_path39.default.join(dir, ent.name);
|
|
57578
58043
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
57579
58044
|
if (seen.has(baseName)) continue;
|
|
57580
58045
|
seen.add(baseName);
|
|
@@ -57597,7 +58062,7 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
57597
58062
|
return;
|
|
57598
58063
|
}
|
|
57599
58064
|
for (const ent of entries) {
|
|
57600
|
-
const childPath =
|
|
58065
|
+
const childPath = import_node_path39.default.join(dir, ent.name);
|
|
57601
58066
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
57602
58067
|
walk2(childPath, [...namespaces, ent.name]);
|
|
57603
58068
|
continue;
|
|
@@ -57622,9 +58087,9 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
57622
58087
|
walk2(root, []);
|
|
57623
58088
|
}
|
|
57624
58089
|
function readInstalledPlugins2(home) {
|
|
57625
|
-
const pluginsDir =
|
|
57626
|
-
const v2 =
|
|
57627
|
-
const v1 =
|
|
58090
|
+
const pluginsDir = import_node_path39.default.join(home, ".claude", "plugins");
|
|
58091
|
+
const v2 = import_node_path39.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
58092
|
+
const v1 = import_node_path39.default.join(pluginsDir, "installed_plugins.json");
|
|
57628
58093
|
let raw = null;
|
|
57629
58094
|
for (const candidate of [v2, v1]) {
|
|
57630
58095
|
try {
|
|
@@ -57653,19 +58118,19 @@ function readInstalledPlugins2(home) {
|
|
|
57653
58118
|
return out;
|
|
57654
58119
|
}
|
|
57655
58120
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
57656
|
-
let cur =
|
|
57657
|
-
const fsRoot =
|
|
58121
|
+
let cur = import_node_path39.default.resolve(startCwd);
|
|
58122
|
+
const fsRoot = import_node_path39.default.parse(cur).root;
|
|
57658
58123
|
while (true) {
|
|
57659
|
-
scanAgentsDir(
|
|
58124
|
+
scanAgentsDir(import_node_path39.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
57660
58125
|
let hasGit = false;
|
|
57661
58126
|
try {
|
|
57662
|
-
hasGit = import_node_fs31.default.existsSync(
|
|
58127
|
+
hasGit = import_node_fs31.default.existsSync(import_node_path39.default.join(cur, ".git"));
|
|
57663
58128
|
} catch {
|
|
57664
58129
|
}
|
|
57665
58130
|
if (hasGit) return;
|
|
57666
58131
|
if (cur === home) return;
|
|
57667
58132
|
if (cur === fsRoot) return;
|
|
57668
|
-
const parent =
|
|
58133
|
+
const parent = import_node_path39.default.dirname(cur);
|
|
57669
58134
|
if (parent === cur) return;
|
|
57670
58135
|
cur = parent;
|
|
57671
58136
|
}
|
|
@@ -57675,7 +58140,7 @@ var AgentsScanner = class {
|
|
|
57675
58140
|
extraPluginRoots;
|
|
57676
58141
|
policyDir;
|
|
57677
58142
|
constructor(opts = {}) {
|
|
57678
|
-
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ??
|
|
58143
|
+
this.home = opts.home ?? process.env.CLAUDE_CONFIG_DIR ?? import_node_os11.default.homedir();
|
|
57679
58144
|
this.extraPluginRoots = opts.extraPluginRoots ?? [];
|
|
57680
58145
|
if (opts.policyDir !== void 0) {
|
|
57681
58146
|
this.policyDir = opts.policyDir;
|
|
@@ -57700,7 +58165,7 @@ var AgentsScanner = class {
|
|
|
57700
58165
|
}
|
|
57701
58166
|
const fsBlock = [];
|
|
57702
58167
|
scanAgentsDir(
|
|
57703
|
-
|
|
58168
|
+
import_node_path39.default.join(this.home, ".claude", "agents"),
|
|
57704
58169
|
"global",
|
|
57705
58170
|
seen,
|
|
57706
58171
|
fsBlock
|
|
@@ -57714,7 +58179,7 @@ var AgentsScanner = class {
|
|
|
57714
58179
|
...this.extraPluginRoots
|
|
57715
58180
|
];
|
|
57716
58181
|
for (const { name, root } of plugins) {
|
|
57717
|
-
const agentsRoot =
|
|
58182
|
+
const agentsRoot = import_node_path39.default.join(root, "agents");
|
|
57718
58183
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
57719
58184
|
}
|
|
57720
58185
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -57723,27 +58188,27 @@ var AgentsScanner = class {
|
|
|
57723
58188
|
|
|
57724
58189
|
// src/observer/session-observer.ts
|
|
57725
58190
|
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
57726
|
-
var
|
|
57727
|
-
var
|
|
58191
|
+
var import_node_os13 = __toESM(require("os"), 1);
|
|
58192
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
57728
58193
|
init_claude_history();
|
|
57729
58194
|
|
|
57730
58195
|
// src/observer/subagent-meta-observer.ts
|
|
57731
58196
|
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
57732
|
-
var
|
|
57733
|
-
var
|
|
58197
|
+
var import_node_os12 = __toESM(require("os"), 1);
|
|
58198
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
57734
58199
|
init_claude_history();
|
|
57735
58200
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
57736
58201
|
var SubagentMetaObserver = class {
|
|
57737
58202
|
constructor(opts) {
|
|
57738
58203
|
this.opts = opts;
|
|
57739
|
-
this.home = opts.home ??
|
|
58204
|
+
this.home = opts.home ?? import_node_os12.default.homedir();
|
|
57740
58205
|
}
|
|
57741
58206
|
opts;
|
|
57742
58207
|
home;
|
|
57743
58208
|
watches = /* @__PURE__ */ new Map();
|
|
57744
58209
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
57745
58210
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
57746
|
-
return
|
|
58211
|
+
return import_node_path40.default.join(
|
|
57747
58212
|
this.home,
|
|
57748
58213
|
".claude",
|
|
57749
58214
|
"projects",
|
|
@@ -57799,7 +58264,7 @@ var SubagentMetaObserver = class {
|
|
|
57799
58264
|
if (!m2) return;
|
|
57800
58265
|
const agentId = m2[1];
|
|
57801
58266
|
if (w2.emitted.has(agentId)) return;
|
|
57802
|
-
const file =
|
|
58267
|
+
const file = import_node_path40.default.join(w2.dirPath, name);
|
|
57803
58268
|
let raw;
|
|
57804
58269
|
try {
|
|
57805
58270
|
raw = import_node_fs32.default.readFileSync(file, "utf8");
|
|
@@ -57847,7 +58312,7 @@ var SubagentMetaObserver = class {
|
|
|
57847
58312
|
var SessionObserver = class {
|
|
57848
58313
|
constructor(opts) {
|
|
57849
58314
|
this.opts = opts;
|
|
57850
|
-
this.home = opts.home ??
|
|
58315
|
+
this.home = opts.home ?? import_node_os13.default.homedir();
|
|
57851
58316
|
this.metaObserver = opts.enableSubagentMetaObserver ? new SubagentMetaObserver({ home: this.home, onEvent: opts.onEvent }) : null;
|
|
57852
58317
|
}
|
|
57853
58318
|
opts;
|
|
@@ -57859,7 +58324,7 @@ var SessionObserver = class {
|
|
|
57859
58324
|
metaObserver;
|
|
57860
58325
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
57861
58326
|
if (override) return override;
|
|
57862
|
-
return
|
|
58327
|
+
return import_node_path41.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
57863
58328
|
}
|
|
57864
58329
|
start(args) {
|
|
57865
58330
|
this.stop(args.sessionId);
|
|
@@ -57885,10 +58350,10 @@ var SessionObserver = class {
|
|
|
57885
58350
|
lastDeriveMs: 0
|
|
57886
58351
|
};
|
|
57887
58352
|
try {
|
|
57888
|
-
import_node_fs33.default.mkdirSync(
|
|
58353
|
+
import_node_fs33.default.mkdirSync(import_node_path41.default.dirname(filePath), { recursive: true });
|
|
57889
58354
|
} catch {
|
|
57890
58355
|
}
|
|
57891
|
-
w2.watcher = import_node_fs33.default.watch(
|
|
58356
|
+
w2.watcher = import_node_fs33.default.watch(import_node_path41.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
57892
58357
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
57893
58358
|
this.poll(w2);
|
|
57894
58359
|
});
|
|
@@ -57985,7 +58450,7 @@ var SessionObserver = class {
|
|
|
57985
58450
|
const now = Date.now();
|
|
57986
58451
|
if (now - w2.lastRelocateScanMs < 1e3) return;
|
|
57987
58452
|
w2.lastRelocateScanMs = now;
|
|
57988
|
-
const projectsRoot =
|
|
58453
|
+
const projectsRoot = import_node_path41.default.join(this.home, ".claude", "projects");
|
|
57989
58454
|
const found = findTranscriptByToolSessionId(projectsRoot, w2.toolSessionId);
|
|
57990
58455
|
if (!found || found === w2.filePath) return;
|
|
57991
58456
|
try {
|
|
@@ -57994,7 +58459,7 @@ var SessionObserver = class {
|
|
|
57994
58459
|
}
|
|
57995
58460
|
w2.filePath = found;
|
|
57996
58461
|
try {
|
|
57997
|
-
w2.watcher = import_node_fs33.default.watch(
|
|
58462
|
+
w2.watcher = import_node_fs33.default.watch(import_node_path41.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
57998
58463
|
if (!changedName || !w2.filePath.endsWith(changedName)) return;
|
|
57999
58464
|
this.poll(w2);
|
|
58000
58465
|
});
|
|
@@ -58114,10 +58579,10 @@ function listRegistered() {
|
|
|
58114
58579
|
}
|
|
58115
58580
|
|
|
58116
58581
|
// src/tools/title-generator.ts
|
|
58117
|
-
var
|
|
58582
|
+
var import_node_child_process10 = require("child_process");
|
|
58118
58583
|
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
58119
|
-
var
|
|
58120
|
-
var
|
|
58584
|
+
var import_node_os14 = __toESM(require("os"), 1);
|
|
58585
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
58121
58586
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
58122
58587
|
var TITLE_MODEL_BY_TOOL = {
|
|
58123
58588
|
claude: "haiku",
|
|
@@ -58188,7 +58653,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
58188
58653
|
if (!text) return null;
|
|
58189
58654
|
let workDir;
|
|
58190
58655
|
try {
|
|
58191
|
-
workDir = import_node_fs34.default.mkdtempSync(
|
|
58656
|
+
workDir = import_node_fs34.default.mkdtempSync(import_node_path42.default.join(import_node_os14.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
58192
58657
|
} catch {
|
|
58193
58658
|
return null;
|
|
58194
58659
|
}
|
|
@@ -58198,8 +58663,8 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
58198
58663
|
} catch {
|
|
58199
58664
|
}
|
|
58200
58665
|
};
|
|
58201
|
-
const outFile =
|
|
58202
|
-
const schemaFile =
|
|
58666
|
+
const outFile = import_node_path42.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
58667
|
+
const schemaFile = import_node_path42.default.join(workDir, "title-schema.json");
|
|
58203
58668
|
if (tool === "codex") {
|
|
58204
58669
|
try {
|
|
58205
58670
|
import_node_fs34.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
@@ -58210,7 +58675,7 @@ async function generateSessionTitle(tool, firstMessage, deps = {}) {
|
|
|
58210
58675
|
}
|
|
58211
58676
|
const cmd = tool === "claude" ? process.env.CLAUDE_BIN ?? "claude" : process.env.CODEX_BIN ?? "codex";
|
|
58212
58677
|
const args = tool === "claude" ? buildClaudeTitleArgs(buildClaudeTitlePrompt(text)) : buildCodexTitleArgs(buildTitlePrompt(text), outFile, schemaFile);
|
|
58213
|
-
const doSpawn = deps.spawnOverride ?? ((c, a, o) => (0,
|
|
58678
|
+
const doSpawn = deps.spawnOverride ?? ((c, a, o) => (0, import_node_child_process10.spawn)(c, a, { ...o, stdio: ["ignore", "pipe", "pipe"] }));
|
|
58214
58679
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_TITLE_GEN_TIMEOUT_MS;
|
|
58215
58680
|
return await new Promise((resolve9) => {
|
|
58216
58681
|
let proc;
|
|
@@ -58274,7 +58739,7 @@ var wrapper_default = import_websocket.default;
|
|
|
58274
58739
|
|
|
58275
58740
|
// src/transport/local-ws-server.ts
|
|
58276
58741
|
var import_node_http2 = __toESM(require("http"), 1);
|
|
58277
|
-
var
|
|
58742
|
+
var import_node_crypto9 = require("crypto");
|
|
58278
58743
|
|
|
58279
58744
|
// src/transport/preview-proxy.ts
|
|
58280
58745
|
var import_node_http = __toESM(require("http"), 1);
|
|
@@ -58558,7 +59023,7 @@ var LocalWsServer = class {
|
|
|
58558
59023
|
}
|
|
58559
59024
|
}
|
|
58560
59025
|
onConnection(socket, remoteAddress) {
|
|
58561
|
-
const id = (0,
|
|
59026
|
+
const id = (0, import_node_crypto9.randomUUID)();
|
|
58562
59027
|
const subscribedSessions = /* @__PURE__ */ new Map();
|
|
58563
59028
|
const handle = {
|
|
58564
59029
|
id,
|
|
@@ -58961,8 +59426,8 @@ async function authenticate(token, deps) {
|
|
|
58961
59426
|
}
|
|
58962
59427
|
|
|
58963
59428
|
// src/legacy-cleanup.ts
|
|
58964
|
-
var
|
|
58965
|
-
var
|
|
59429
|
+
var fs48 = __toESM(require("fs/promises"), 1);
|
|
59430
|
+
var path50 = __toESM(require("path"), 1);
|
|
58966
59431
|
var LEGACY_FILES = [
|
|
58967
59432
|
"personal-capability.json",
|
|
58968
59433
|
"received-capabilities.json",
|
|
@@ -58971,9 +59436,9 @@ var LEGACY_FILES = [
|
|
|
58971
59436
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
58972
59437
|
const removed = [];
|
|
58973
59438
|
for (const name of LEGACY_FILES) {
|
|
58974
|
-
const p2 =
|
|
59439
|
+
const p2 = path50.join(dataDir, name);
|
|
58975
59440
|
try {
|
|
58976
|
-
await
|
|
59441
|
+
await fs48.unlink(p2);
|
|
58977
59442
|
removed.push(name);
|
|
58978
59443
|
logger.debug("legacy capability file removed", { file: name });
|
|
58979
59444
|
} catch (err) {
|
|
@@ -58985,13 +59450,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
58985
59450
|
}
|
|
58986
59451
|
|
|
58987
59452
|
// src/inbox/inbox-store.ts
|
|
58988
|
-
var
|
|
58989
|
-
var
|
|
59453
|
+
var fs49 = __toESM(require("fs"), 1);
|
|
59454
|
+
var path51 = __toESM(require("path"), 1);
|
|
58990
59455
|
var INBOX_SUBDIR = "inbox";
|
|
58991
59456
|
var InboxStore = class {
|
|
58992
59457
|
constructor(dataDir) {
|
|
58993
59458
|
this.dataDir = dataDir;
|
|
58994
|
-
|
|
59459
|
+
fs49.mkdirSync(this.dirPath(), { recursive: true });
|
|
58995
59460
|
}
|
|
58996
59461
|
dataDir;
|
|
58997
59462
|
/**
|
|
@@ -59003,7 +59468,7 @@ var InboxStore = class {
|
|
|
59003
59468
|
const file = this.filePath(peerDeviceId);
|
|
59004
59469
|
let raw;
|
|
59005
59470
|
try {
|
|
59006
|
-
raw =
|
|
59471
|
+
raw = fs49.readFileSync(file, "utf8");
|
|
59007
59472
|
} catch (err) {
|
|
59008
59473
|
if (err?.code === "ENOENT") return [];
|
|
59009
59474
|
return [];
|
|
@@ -59019,7 +59484,7 @@ var InboxStore = class {
|
|
|
59019
59484
|
const dir = this.dirPath();
|
|
59020
59485
|
let entries;
|
|
59021
59486
|
try {
|
|
59022
|
-
entries =
|
|
59487
|
+
entries = fs49.readdirSync(dir);
|
|
59023
59488
|
} catch (err) {
|
|
59024
59489
|
if (err?.code === "ENOENT") return [];
|
|
59025
59490
|
return [];
|
|
@@ -59035,9 +59500,9 @@ var InboxStore = class {
|
|
|
59035
59500
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
59036
59501
|
const file = this.filePath(message.peerDeviceId);
|
|
59037
59502
|
const line = JSON.stringify(message) + "\n";
|
|
59038
|
-
|
|
59503
|
+
fs49.appendFileSync(file, line, { mode: 384 });
|
|
59039
59504
|
try {
|
|
59040
|
-
|
|
59505
|
+
fs49.chmodSync(file, 384);
|
|
59041
59506
|
} catch {
|
|
59042
59507
|
}
|
|
59043
59508
|
}
|
|
@@ -59067,7 +59532,7 @@ var InboxStore = class {
|
|
|
59067
59532
|
removeByPeerDeviceId(peerDeviceId) {
|
|
59068
59533
|
const file = this.filePath(peerDeviceId);
|
|
59069
59534
|
try {
|
|
59070
|
-
|
|
59535
|
+
fs49.unlinkSync(file);
|
|
59071
59536
|
} catch (err) {
|
|
59072
59537
|
if (err?.code === "ENOENT") return;
|
|
59073
59538
|
}
|
|
@@ -59076,18 +59541,18 @@ var InboxStore = class {
|
|
|
59076
59541
|
const file = this.filePath(peerDeviceId);
|
|
59077
59542
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
59078
59543
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
59079
|
-
|
|
59080
|
-
|
|
59544
|
+
fs49.writeFileSync(tmp, content, { mode: 384 });
|
|
59545
|
+
fs49.renameSync(tmp, file);
|
|
59081
59546
|
try {
|
|
59082
|
-
|
|
59547
|
+
fs49.chmodSync(file, 384);
|
|
59083
59548
|
} catch {
|
|
59084
59549
|
}
|
|
59085
59550
|
}
|
|
59086
59551
|
dirPath() {
|
|
59087
|
-
return
|
|
59552
|
+
return path51.join(this.dataDir, INBOX_SUBDIR);
|
|
59088
59553
|
}
|
|
59089
59554
|
filePath(peerDeviceId) {
|
|
59090
|
-
return
|
|
59555
|
+
return path51.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
59091
59556
|
}
|
|
59092
59557
|
};
|
|
59093
59558
|
function parseAllLines(raw) {
|
|
@@ -59175,8 +59640,8 @@ var InboxManager = class {
|
|
|
59175
59640
|
};
|
|
59176
59641
|
|
|
59177
59642
|
// src/state/contact-store.ts
|
|
59178
|
-
var
|
|
59179
|
-
var
|
|
59643
|
+
var fs50 = __toESM(require("fs"), 1);
|
|
59644
|
+
var path52 = __toESM(require("path"), 1);
|
|
59180
59645
|
var FILE_NAME = "contacts.json";
|
|
59181
59646
|
var ContactStore = class {
|
|
59182
59647
|
constructor(dataDir) {
|
|
@@ -59186,10 +59651,10 @@ var ContactStore = class {
|
|
|
59186
59651
|
contacts = /* @__PURE__ */ new Map();
|
|
59187
59652
|
load() {
|
|
59188
59653
|
this.contacts.clear();
|
|
59189
|
-
const file =
|
|
59654
|
+
const file = path52.join(this.dataDir, FILE_NAME);
|
|
59190
59655
|
let raw;
|
|
59191
59656
|
try {
|
|
59192
|
-
raw =
|
|
59657
|
+
raw = fs50.readFileSync(file, "utf8");
|
|
59193
59658
|
} catch (err) {
|
|
59194
59659
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
59195
59660
|
return;
|
|
@@ -59270,27 +59735,27 @@ var ContactStore = class {
|
|
|
59270
59735
|
return true;
|
|
59271
59736
|
}
|
|
59272
59737
|
flush() {
|
|
59273
|
-
const file =
|
|
59738
|
+
const file = path52.join(this.dataDir, FILE_NAME);
|
|
59274
59739
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
59275
59740
|
const content = JSON.stringify(
|
|
59276
59741
|
{ contacts: Array.from(this.contacts.values()) },
|
|
59277
59742
|
null,
|
|
59278
59743
|
2
|
|
59279
59744
|
);
|
|
59280
|
-
|
|
59281
|
-
|
|
59282
|
-
|
|
59745
|
+
fs50.mkdirSync(this.dataDir, { recursive: true });
|
|
59746
|
+
fs50.writeFileSync(tmp, content, { mode: 384 });
|
|
59747
|
+
fs50.renameSync(tmp, file);
|
|
59283
59748
|
}
|
|
59284
59749
|
renameBak(file) {
|
|
59285
59750
|
try {
|
|
59286
|
-
|
|
59751
|
+
fs50.renameSync(file, `${file}.bak`);
|
|
59287
59752
|
} catch {
|
|
59288
59753
|
}
|
|
59289
59754
|
}
|
|
59290
59755
|
};
|
|
59291
59756
|
|
|
59292
59757
|
// src/contact/connect-remote.ts
|
|
59293
|
-
var
|
|
59758
|
+
var crypto4 = __toESM(require("crypto"), 1);
|
|
59294
59759
|
init_protocol();
|
|
59295
59760
|
var HANDSHAKE_TIMEOUT_MS = 5e3;
|
|
59296
59761
|
var RPC_TIMEOUT_MS = 5e3;
|
|
@@ -59345,7 +59810,7 @@ async function connectRemote(args) {
|
|
|
59345
59810
|
ws.once("close", onClose);
|
|
59346
59811
|
});
|
|
59347
59812
|
function call(method, payload) {
|
|
59348
|
-
const requestId =
|
|
59813
|
+
const requestId = crypto4.randomUUID();
|
|
59349
59814
|
return new Promise((resolve9, reject) => {
|
|
59350
59815
|
const onMessage = (raw) => {
|
|
59351
59816
|
let f;
|
|
@@ -59391,61 +59856,61 @@ async function connectRemote(args) {
|
|
|
59391
59856
|
}
|
|
59392
59857
|
|
|
59393
59858
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
59394
|
-
var
|
|
59395
|
-
var
|
|
59859
|
+
var fs51 = __toESM(require("fs"), 1);
|
|
59860
|
+
var path53 = __toESM(require("path"), 1);
|
|
59396
59861
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
59397
59862
|
function migrateFlattenSessions(opts) {
|
|
59398
59863
|
const dataDir = opts.dataDir;
|
|
59399
59864
|
const now = opts.now ?? Date.now;
|
|
59400
|
-
const sessionsDir =
|
|
59401
|
-
const flagPath =
|
|
59865
|
+
const sessionsDir = path53.join(dataDir, "sessions");
|
|
59866
|
+
const flagPath = path53.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
59402
59867
|
if (existsSync3(flagPath)) {
|
|
59403
59868
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
59404
59869
|
}
|
|
59405
59870
|
let movedBare = 0;
|
|
59406
59871
|
let movedVmOwner = 0;
|
|
59407
59872
|
let archivedListener = 0;
|
|
59408
|
-
const defaultDir =
|
|
59873
|
+
const defaultDir = path53.join(sessionsDir, "default");
|
|
59409
59874
|
if (existsSync3(defaultDir)) {
|
|
59410
59875
|
for (const entry of readdirSafe(defaultDir)) {
|
|
59411
59876
|
if (!entry.endsWith(".json")) continue;
|
|
59412
|
-
const src =
|
|
59413
|
-
const dst =
|
|
59414
|
-
|
|
59877
|
+
const src = path53.join(defaultDir, entry);
|
|
59878
|
+
const dst = path53.join(sessionsDir, entry);
|
|
59879
|
+
fs51.renameSync(src, dst);
|
|
59415
59880
|
movedBare += 1;
|
|
59416
59881
|
}
|
|
59417
59882
|
rmdirIfEmpty(defaultDir);
|
|
59418
59883
|
}
|
|
59419
59884
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
59420
|
-
const personaDir =
|
|
59885
|
+
const personaDir = path53.join(sessionsDir, pid);
|
|
59421
59886
|
if (!isDir(personaDir)) continue;
|
|
59422
59887
|
if (pid === "default") continue;
|
|
59423
|
-
const ownerSrc =
|
|
59888
|
+
const ownerSrc = path53.join(personaDir, "owner");
|
|
59424
59889
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
59425
|
-
const ownerDst =
|
|
59426
|
-
|
|
59890
|
+
const ownerDst = path53.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
59891
|
+
fs51.mkdirSync(ownerDst, { recursive: true });
|
|
59427
59892
|
for (const file of readdirSafe(ownerSrc)) {
|
|
59428
59893
|
if (!file.endsWith(".json")) continue;
|
|
59429
|
-
|
|
59894
|
+
fs51.renameSync(path53.join(ownerSrc, file), path53.join(ownerDst, file));
|
|
59430
59895
|
movedVmOwner += 1;
|
|
59431
59896
|
}
|
|
59432
59897
|
rmdirIfEmpty(ownerSrc);
|
|
59433
59898
|
}
|
|
59434
|
-
const listenerSrc =
|
|
59899
|
+
const listenerSrc = path53.join(personaDir, "listener");
|
|
59435
59900
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
59436
|
-
const archiveDst =
|
|
59437
|
-
|
|
59901
|
+
const archiveDst = path53.join(dataDir, ".legacy", `listener-${pid}`);
|
|
59902
|
+
fs51.mkdirSync(archiveDst, { recursive: true });
|
|
59438
59903
|
for (const file of readdirSafe(listenerSrc)) {
|
|
59439
59904
|
if (!file.endsWith(".json")) continue;
|
|
59440
|
-
|
|
59905
|
+
fs51.renameSync(path53.join(listenerSrc, file), path53.join(archiveDst, file));
|
|
59441
59906
|
archivedListener += 1;
|
|
59442
59907
|
}
|
|
59443
59908
|
rmdirIfEmpty(listenerSrc);
|
|
59444
59909
|
}
|
|
59445
59910
|
rmdirIfEmpty(personaDir);
|
|
59446
59911
|
}
|
|
59447
|
-
|
|
59448
|
-
|
|
59912
|
+
fs51.mkdirSync(sessionsDir, { recursive: true });
|
|
59913
|
+
fs51.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
59449
59914
|
return {
|
|
59450
59915
|
skipped: false,
|
|
59451
59916
|
flagWritten: true,
|
|
@@ -59456,7 +59921,7 @@ function migrateFlattenSessions(opts) {
|
|
|
59456
59921
|
}
|
|
59457
59922
|
function existsSync3(p2) {
|
|
59458
59923
|
try {
|
|
59459
|
-
|
|
59924
|
+
fs51.statSync(p2);
|
|
59460
59925
|
return true;
|
|
59461
59926
|
} catch {
|
|
59462
59927
|
return false;
|
|
@@ -59464,61 +59929,61 @@ function existsSync3(p2) {
|
|
|
59464
59929
|
}
|
|
59465
59930
|
function isDir(p2) {
|
|
59466
59931
|
try {
|
|
59467
|
-
return
|
|
59932
|
+
return fs51.statSync(p2).isDirectory();
|
|
59468
59933
|
} catch {
|
|
59469
59934
|
return false;
|
|
59470
59935
|
}
|
|
59471
59936
|
}
|
|
59472
59937
|
function readdirSafe(p2) {
|
|
59473
59938
|
try {
|
|
59474
|
-
return
|
|
59939
|
+
return fs51.readdirSync(p2);
|
|
59475
59940
|
} catch {
|
|
59476
59941
|
return [];
|
|
59477
59942
|
}
|
|
59478
59943
|
}
|
|
59479
59944
|
function rmdirIfEmpty(p2) {
|
|
59480
59945
|
try {
|
|
59481
|
-
|
|
59946
|
+
fs51.rmdirSync(p2);
|
|
59482
59947
|
} catch {
|
|
59483
59948
|
}
|
|
59484
59949
|
}
|
|
59485
59950
|
|
|
59486
59951
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
59487
|
-
var
|
|
59488
|
-
var
|
|
59952
|
+
var fs52 = __toESM(require("fs"), 1);
|
|
59953
|
+
var path54 = __toESM(require("path"), 1);
|
|
59489
59954
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
59490
59955
|
function dropSeededProjects(opts) {
|
|
59491
|
-
|
|
59492
|
-
const flag =
|
|
59493
|
-
if (
|
|
59494
|
-
const file =
|
|
59956
|
+
fs52.mkdirSync(opts.dataDir, { recursive: true });
|
|
59957
|
+
const flag = path54.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
59958
|
+
if (fs52.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
59959
|
+
const file = path54.join(opts.dataDir, "projects.json");
|
|
59495
59960
|
let raw = null;
|
|
59496
59961
|
let dropped = 0;
|
|
59497
59962
|
try {
|
|
59498
|
-
raw =
|
|
59963
|
+
raw = fs52.readFileSync(file, "utf8");
|
|
59499
59964
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
59500
59965
|
} catch {
|
|
59501
59966
|
}
|
|
59502
59967
|
let backup = null;
|
|
59503
59968
|
if (raw != null && dropped > 0) {
|
|
59504
|
-
const dir =
|
|
59505
|
-
|
|
59506
|
-
backup =
|
|
59507
|
-
|
|
59969
|
+
const dir = path54.join(opts.dataDir, "backups");
|
|
59970
|
+
fs52.mkdirSync(dir, { recursive: true });
|
|
59971
|
+
backup = path54.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
59972
|
+
fs52.writeFileSync(backup, raw);
|
|
59508
59973
|
}
|
|
59509
59974
|
if (raw != null || dropped > 0) {
|
|
59510
|
-
|
|
59975
|
+
fs52.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
59511
59976
|
}
|
|
59512
|
-
|
|
59977
|
+
fs52.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
59513
59978
|
return { skipped: false, dropped, backup };
|
|
59514
59979
|
}
|
|
59515
59980
|
|
|
59516
59981
|
// src/transport/http-router.ts
|
|
59517
59982
|
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
59518
|
-
var
|
|
59983
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
59519
59984
|
|
|
59520
59985
|
// src/attachment/mime.ts
|
|
59521
|
-
var
|
|
59986
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
59522
59987
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
59523
59988
|
var EXT_TO_NATIVE_MIME = {
|
|
59524
59989
|
// 图片
|
|
@@ -59625,14 +60090,14 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
59625
60090
|
".mk"
|
|
59626
60091
|
]);
|
|
59627
60092
|
function lookupMime(filePathOrName) {
|
|
59628
|
-
const ext =
|
|
60093
|
+
const ext = import_node_path43.default.extname(filePathOrName).toLowerCase();
|
|
59629
60094
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
59630
60095
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
59631
60096
|
return "application/octet-stream";
|
|
59632
60097
|
}
|
|
59633
60098
|
|
|
59634
60099
|
// src/attachment/sign-url.ts
|
|
59635
|
-
var
|
|
60100
|
+
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
59636
60101
|
var HMAC_ALGO = "sha256";
|
|
59637
60102
|
function base64urlEncode(buf) {
|
|
59638
60103
|
const b2 = typeof buf === "string" ? Buffer.from(buf, "utf8") : buf;
|
|
@@ -59650,7 +60115,7 @@ function decodeAbsPathFromUrl(encoded) {
|
|
|
59650
60115
|
var DOMAIN_PREFIX2 = "clawd-attach-v1|";
|
|
59651
60116
|
function computeSig(secret, absPath, e) {
|
|
59652
60117
|
const msg = e === null ? `${DOMAIN_PREFIX2}${absPath}` : `${DOMAIN_PREFIX2}${absPath}|${e}`;
|
|
59653
|
-
return
|
|
60118
|
+
return import_node_crypto10.default.createHmac(HMAC_ALGO, secret).update(msg).digest();
|
|
59654
60119
|
}
|
|
59655
60120
|
function signUrlParts(secret, absPath, ttlSeconds, now = Date.now) {
|
|
59656
60121
|
const e = ttlSeconds === null ? null : Math.floor(now() / 1e3) + ttlSeconds;
|
|
@@ -59685,7 +60150,7 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
59685
60150
|
if (provided.length !== expected.length) {
|
|
59686
60151
|
return { ok: false, code: "BAD_SIG" };
|
|
59687
60152
|
}
|
|
59688
|
-
if (!
|
|
60153
|
+
if (!import_node_crypto10.default.timingSafeEqual(provided, expected)) {
|
|
59689
60154
|
return { ok: false, code: "BAD_SIG" };
|
|
59690
60155
|
}
|
|
59691
60156
|
if (e !== null && now() / 1e3 > e) {
|
|
@@ -59696,9 +60161,9 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
59696
60161
|
|
|
59697
60162
|
// src/attachment/upload.ts
|
|
59698
60163
|
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
59699
|
-
var
|
|
59700
|
-
var
|
|
59701
|
-
var
|
|
60164
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
60165
|
+
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
60166
|
+
var import_promises10 = require("stream/promises");
|
|
59702
60167
|
var UploadError = class extends Error {
|
|
59703
60168
|
constructor(code, message) {
|
|
59704
60169
|
super(message);
|
|
@@ -59708,27 +60173,27 @@ var UploadError = class extends Error {
|
|
|
59708
60173
|
code;
|
|
59709
60174
|
};
|
|
59710
60175
|
function assertValidFileName(fileName) {
|
|
59711
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
60176
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path44.default.basename(fileName)) {
|
|
59712
60177
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
59713
60178
|
}
|
|
59714
60179
|
}
|
|
59715
60180
|
var HASH_PREFIX_LEN = 16;
|
|
59716
60181
|
async function writeUploadedAttachment(args) {
|
|
59717
60182
|
assertValidFileName(args.fileName);
|
|
59718
|
-
const attachmentsRoot =
|
|
60183
|
+
const attachmentsRoot = import_node_path44.default.join(args.baseDir, ".attachments");
|
|
59719
60184
|
try {
|
|
59720
60185
|
import_node_fs35.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
59721
60186
|
} catch (err) {
|
|
59722
60187
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
59723
60188
|
}
|
|
59724
|
-
const hasher =
|
|
60189
|
+
const hasher = import_node_crypto11.default.createHash("sha256");
|
|
59725
60190
|
let actualSize = 0;
|
|
59726
|
-
const tmpPath =
|
|
60191
|
+
const tmpPath = import_node_path44.default.join(
|
|
59727
60192
|
attachmentsRoot,
|
|
59728
|
-
`.upload-${process.pid}-${Date.now()}-${
|
|
60193
|
+
`.upload-${process.pid}-${Date.now()}-${import_node_crypto11.default.randomBytes(4).toString("hex")}`
|
|
59729
60194
|
);
|
|
59730
60195
|
try {
|
|
59731
|
-
await (0,
|
|
60196
|
+
await (0, import_promises10.pipeline)(
|
|
59732
60197
|
args.body,
|
|
59733
60198
|
async function* (source) {
|
|
59734
60199
|
for await (const chunk of source) {
|
|
@@ -59758,7 +60223,7 @@ async function writeUploadedAttachment(args) {
|
|
|
59758
60223
|
);
|
|
59759
60224
|
}
|
|
59760
60225
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
59761
|
-
const hashDir =
|
|
60226
|
+
const hashDir = import_node_path44.default.join(attachmentsRoot, attachmentId);
|
|
59762
60227
|
let finalFileName;
|
|
59763
60228
|
let hashDirExists = false;
|
|
59764
60229
|
try {
|
|
@@ -59776,7 +60241,7 @@ async function writeUploadedAttachment(args) {
|
|
|
59776
60241
|
try {
|
|
59777
60242
|
import_node_fs35.default.mkdirSync(hashDir, { recursive: true });
|
|
59778
60243
|
finalFileName = args.fileName;
|
|
59779
|
-
import_node_fs35.default.renameSync(tmpPath,
|
|
60244
|
+
import_node_fs35.default.renameSync(tmpPath, import_node_path44.default.join(hashDir, finalFileName));
|
|
59780
60245
|
} catch (err) {
|
|
59781
60246
|
try {
|
|
59782
60247
|
import_node_fs35.default.unlinkSync(tmpPath);
|
|
@@ -59785,7 +60250,7 @@ async function writeUploadedAttachment(args) {
|
|
|
59785
60250
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
59786
60251
|
}
|
|
59787
60252
|
}
|
|
59788
|
-
const absPath =
|
|
60253
|
+
const absPath = import_node_path44.default.join(hashDir, finalFileName);
|
|
59789
60254
|
const relPath = absPath;
|
|
59790
60255
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
59791
60256
|
relPath: absPath,
|
|
@@ -59799,9 +60264,9 @@ async function writeUploadedAttachment(args) {
|
|
|
59799
60264
|
}
|
|
59800
60265
|
|
|
59801
60266
|
// src/extension/import.ts
|
|
59802
|
-
var
|
|
59803
|
-
var
|
|
59804
|
-
var
|
|
60267
|
+
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
60268
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
60269
|
+
var import_node_os15 = __toESM(require("os"), 1);
|
|
59805
60270
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
59806
60271
|
var ImportError = class extends Error {
|
|
59807
60272
|
constructor(code, message) {
|
|
@@ -59818,7 +60283,7 @@ async function importZip(buf, root) {
|
|
|
59818
60283
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
59819
60284
|
}
|
|
59820
60285
|
for (const name of Object.keys(zip.files)) {
|
|
59821
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
60286
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path45.default.isAbsolute(name)) {
|
|
59822
60287
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
59823
60288
|
}
|
|
59824
60289
|
}
|
|
@@ -59851,33 +60316,33 @@ async function importZip(buf, root) {
|
|
|
59851
60316
|
);
|
|
59852
60317
|
}
|
|
59853
60318
|
}
|
|
59854
|
-
const destDir =
|
|
60319
|
+
const destDir = import_node_path45.default.join(root, manifest.id);
|
|
59855
60320
|
let destExists = false;
|
|
59856
60321
|
try {
|
|
59857
|
-
await
|
|
60322
|
+
await import_promises11.default.access(destDir);
|
|
59858
60323
|
destExists = true;
|
|
59859
60324
|
} catch {
|
|
59860
60325
|
}
|
|
59861
60326
|
if (destExists) {
|
|
59862
60327
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
59863
60328
|
}
|
|
59864
|
-
const stage = await
|
|
60329
|
+
const stage = await import_promises11.default.mkdtemp(import_node_path45.default.join(import_node_os15.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
59865
60330
|
try {
|
|
59866
60331
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
59867
|
-
const dest =
|
|
60332
|
+
const dest = import_node_path45.default.join(stage, name);
|
|
59868
60333
|
if (entry.dir) {
|
|
59869
|
-
await
|
|
60334
|
+
await import_promises11.default.mkdir(dest, { recursive: true });
|
|
59870
60335
|
continue;
|
|
59871
60336
|
}
|
|
59872
|
-
await
|
|
60337
|
+
await import_promises11.default.mkdir(import_node_path45.default.dirname(dest), { recursive: true });
|
|
59873
60338
|
const content = await entry.async("nodebuffer");
|
|
59874
|
-
await
|
|
60339
|
+
await import_promises11.default.writeFile(dest, content);
|
|
59875
60340
|
}
|
|
59876
|
-
await
|
|
59877
|
-
await
|
|
60341
|
+
await import_promises11.default.mkdir(root, { recursive: true });
|
|
60342
|
+
await import_promises11.default.rename(stage, destDir);
|
|
59878
60343
|
return { extId: manifest.id };
|
|
59879
60344
|
} catch (e) {
|
|
59880
|
-
await
|
|
60345
|
+
await import_promises11.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
59881
60346
|
});
|
|
59882
60347
|
throw e;
|
|
59883
60348
|
}
|
|
@@ -59899,7 +60364,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
59899
60364
|
".wasm": "application/wasm"
|
|
59900
60365
|
};
|
|
59901
60366
|
function shareUiAssetMime(filePath) {
|
|
59902
|
-
const ext =
|
|
60367
|
+
const ext = import_node_path46.default.extname(filePath).toLowerCase();
|
|
59903
60368
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
59904
60369
|
}
|
|
59905
60370
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -59998,7 +60463,7 @@ function isValidUploadFileName(fileName) {
|
|
|
59998
60463
|
if (fileName === "." || fileName === "..") return false;
|
|
59999
60464
|
if (fileName.startsWith(".")) return false;
|
|
60000
60465
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
60001
|
-
return fileName ===
|
|
60466
|
+
return fileName === import_node_path46.default.basename(fileName);
|
|
60002
60467
|
}
|
|
60003
60468
|
function createHttpRouter(deps) {
|
|
60004
60469
|
return async (req, res) => {
|
|
@@ -60234,7 +60699,7 @@ function createHttpRouter(deps) {
|
|
|
60234
60699
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
60235
60700
|
return true;
|
|
60236
60701
|
}
|
|
60237
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
60702
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path46.default.basename(r.absPath)));
|
|
60238
60703
|
return true;
|
|
60239
60704
|
}
|
|
60240
60705
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -60355,7 +60820,7 @@ function createHttpRouter(deps) {
|
|
|
60355
60820
|
return true;
|
|
60356
60821
|
}
|
|
60357
60822
|
let absPath;
|
|
60358
|
-
if (
|
|
60823
|
+
if (import_node_path46.default.isAbsolute(pathParam)) {
|
|
60359
60824
|
absPath = pathParam;
|
|
60360
60825
|
} else if (deps.sessionStore) {
|
|
60361
60826
|
const file = deps.sessionStore.read(sid);
|
|
@@ -60363,7 +60828,7 @@ function createHttpRouter(deps) {
|
|
|
60363
60828
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
60364
60829
|
return true;
|
|
60365
60830
|
}
|
|
60366
|
-
absPath =
|
|
60831
|
+
absPath = import_node_path46.default.join(file.cwd, pathParam);
|
|
60367
60832
|
} else {
|
|
60368
60833
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
60369
60834
|
return true;
|
|
@@ -60465,7 +60930,7 @@ function streamFile(res, absPath, logger) {
|
|
|
60465
60930
|
return;
|
|
60466
60931
|
}
|
|
60467
60932
|
const mime = lookupMime(absPath);
|
|
60468
|
-
const basename2 =
|
|
60933
|
+
const basename2 = import_node_path46.default.basename(absPath);
|
|
60469
60934
|
res.writeHead(200, {
|
|
60470
60935
|
"Content-Type": mime,
|
|
60471
60936
|
"Content-Length": String(stat.size),
|
|
@@ -60483,7 +60948,7 @@ function streamFile(res, absPath, logger) {
|
|
|
60483
60948
|
|
|
60484
60949
|
// src/attachment/gc.ts
|
|
60485
60950
|
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
60486
|
-
var
|
|
60951
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
60487
60952
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
60488
60953
|
function runAttachmentGc(args) {
|
|
60489
60954
|
const now = (args.now ?? Date.now)();
|
|
@@ -60492,12 +60957,12 @@ function runAttachmentGc(args) {
|
|
|
60492
60957
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
60493
60958
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
60494
60959
|
if (entry.stale) continue;
|
|
60495
|
-
if (
|
|
60960
|
+
if (import_node_path47.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
60496
60961
|
}
|
|
60497
60962
|
}
|
|
60498
60963
|
const visited = /* @__PURE__ */ new Set();
|
|
60499
60964
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
60500
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
60965
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path47.default.join(
|
|
60501
60966
|
args.dataDir,
|
|
60502
60967
|
"sessions",
|
|
60503
60968
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -60510,7 +60975,7 @@ function runAttachmentGc(args) {
|
|
|
60510
60975
|
return true;
|
|
60511
60976
|
});
|
|
60512
60977
|
for (const rootDir of roots) {
|
|
60513
|
-
const attRoot =
|
|
60978
|
+
const attRoot = import_node_path47.default.join(rootDir, ".attachments");
|
|
60514
60979
|
let hashDirs;
|
|
60515
60980
|
try {
|
|
60516
60981
|
hashDirs = import_node_fs37.default.readdirSync(attRoot);
|
|
@@ -60520,7 +60985,7 @@ function runAttachmentGc(args) {
|
|
|
60520
60985
|
continue;
|
|
60521
60986
|
}
|
|
60522
60987
|
for (const hashDir of hashDirs) {
|
|
60523
|
-
const hashDirAbs =
|
|
60988
|
+
const hashDirAbs = import_node_path47.default.join(attRoot, hashDir);
|
|
60524
60989
|
let files;
|
|
60525
60990
|
try {
|
|
60526
60991
|
files = import_node_fs37.default.readdirSync(hashDirAbs);
|
|
@@ -60528,7 +60993,7 @@ function runAttachmentGc(args) {
|
|
|
60528
60993
|
continue;
|
|
60529
60994
|
}
|
|
60530
60995
|
for (const name of files) {
|
|
60531
|
-
const file =
|
|
60996
|
+
const file = import_node_path47.default.join(hashDirAbs, name);
|
|
60532
60997
|
let stat;
|
|
60533
60998
|
try {
|
|
60534
60999
|
stat = import_node_fs37.default.statSync(file);
|
|
@@ -60560,8 +61025,8 @@ function runAttachmentGc(args) {
|
|
|
60560
61025
|
|
|
60561
61026
|
// src/attachment/group.ts
|
|
60562
61027
|
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
60563
|
-
var
|
|
60564
|
-
var
|
|
61028
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
61029
|
+
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
60565
61030
|
init_protocol();
|
|
60566
61031
|
var GroupFileStore = class {
|
|
60567
61032
|
dataDir;
|
|
@@ -60572,11 +61037,11 @@ var GroupFileStore = class {
|
|
|
60572
61037
|
this.logger = opts.logger;
|
|
60573
61038
|
}
|
|
60574
61039
|
rootForScope(scope) {
|
|
60575
|
-
return
|
|
61040
|
+
return import_node_path48.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
60576
61041
|
}
|
|
60577
61042
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
60578
61043
|
filePath(scope, sessionId) {
|
|
60579
|
-
return
|
|
61044
|
+
return import_node_path48.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
60580
61045
|
}
|
|
60581
61046
|
cacheKey(scope, sessionId) {
|
|
60582
61047
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -60611,7 +61076,7 @@ var GroupFileStore = class {
|
|
|
60611
61076
|
}
|
|
60612
61077
|
writeFile(scope, sessionId, entries) {
|
|
60613
61078
|
const file = this.filePath(scope, sessionId);
|
|
60614
|
-
import_node_fs38.default.mkdirSync(
|
|
61079
|
+
import_node_fs38.default.mkdirSync(import_node_path48.default.dirname(file), { recursive: true });
|
|
60615
61080
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
60616
61081
|
import_node_fs38.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
60617
61082
|
import_node_fs38.default.renameSync(tmp, file);
|
|
@@ -60650,7 +61115,7 @@ var GroupFileStore = class {
|
|
|
60650
61115
|
entries[idx] = next;
|
|
60651
61116
|
} else {
|
|
60652
61117
|
next = {
|
|
60653
|
-
id: `gf-${
|
|
61118
|
+
id: `gf-${import_node_crypto12.default.randomBytes(6).toString("base64url")}`,
|
|
60654
61119
|
relPath: input.relPath,
|
|
60655
61120
|
from: input.from,
|
|
60656
61121
|
label: input.label,
|
|
@@ -60701,9 +61166,9 @@ var GroupFileStore = class {
|
|
|
60701
61166
|
|
|
60702
61167
|
// src/discovery/state-file.ts
|
|
60703
61168
|
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
60704
|
-
var
|
|
61169
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
60705
61170
|
function defaultStateFilePath(dataDir) {
|
|
60706
|
-
return
|
|
61171
|
+
return import_node_path49.default.join(dataDir, "state.json");
|
|
60707
61172
|
}
|
|
60708
61173
|
function isPidAlive(pid) {
|
|
60709
61174
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -60739,7 +61204,7 @@ var StateFileManager = class {
|
|
|
60739
61204
|
return { status: "stale", existing };
|
|
60740
61205
|
}
|
|
60741
61206
|
write(state) {
|
|
60742
|
-
import_node_fs39.default.mkdirSync(
|
|
61207
|
+
import_node_fs39.default.mkdirSync(import_node_path49.default.dirname(this.file), { recursive: true });
|
|
60743
61208
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
60744
61209
|
import_node_fs39.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
60745
61210
|
import_node_fs39.default.renameSync(tmp, this.file);
|
|
@@ -60767,13 +61232,13 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
60767
61232
|
|
|
60768
61233
|
// src/tunnel/tunnel-manager.ts
|
|
60769
61234
|
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
60770
|
-
var
|
|
60771
|
-
var
|
|
60772
|
-
var
|
|
61235
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
61236
|
+
var import_node_crypto13 = __toESM(require("crypto"), 1);
|
|
61237
|
+
var import_node_child_process13 = require("child_process");
|
|
60773
61238
|
|
|
60774
61239
|
// src/tunnel/tunnel-store.ts
|
|
60775
61240
|
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
60776
|
-
var
|
|
61241
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
60777
61242
|
var TunnelStore = class {
|
|
60778
61243
|
constructor(filePath) {
|
|
60779
61244
|
this.filePath = filePath;
|
|
@@ -60792,7 +61257,7 @@ var TunnelStore = class {
|
|
|
60792
61257
|
}
|
|
60793
61258
|
}
|
|
60794
61259
|
async set(v2) {
|
|
60795
|
-
const dir =
|
|
61260
|
+
const dir = import_node_path50.default.dirname(this.filePath);
|
|
60796
61261
|
await import_node_fs40.default.promises.mkdir(dir, { recursive: true });
|
|
60797
61262
|
const data = JSON.stringify(v2, null, 2);
|
|
60798
61263
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
@@ -60903,11 +61368,11 @@ function escape(v2) {
|
|
|
60903
61368
|
|
|
60904
61369
|
// src/tunnel/frpc-binary.ts
|
|
60905
61370
|
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
60906
|
-
var
|
|
60907
|
-
var
|
|
60908
|
-
var
|
|
61371
|
+
var import_node_os16 = __toESM(require("os"), 1);
|
|
61372
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
61373
|
+
var import_node_child_process11 = require("child_process");
|
|
60909
61374
|
var import_node_stream3 = require("stream");
|
|
60910
|
-
var
|
|
61375
|
+
var import_promises12 = require("stream/promises");
|
|
60911
61376
|
var FRPC_VERSION = "0.68.0";
|
|
60912
61377
|
var UnsupportedPlatformError = class extends Error {
|
|
60913
61378
|
constructor(platform, arch) {
|
|
@@ -60943,13 +61408,13 @@ async function ensureFrpcBinary(opts) {
|
|
|
60943
61408
|
}
|
|
60944
61409
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
60945
61410
|
const platform = opts.platform ?? detectPlatform();
|
|
60946
|
-
const binDir =
|
|
61411
|
+
const binDir = import_node_path51.default.join(opts.dataDir, "bin");
|
|
60947
61412
|
import_node_fs41.default.mkdirSync(binDir, { recursive: true });
|
|
60948
61413
|
cleanupStaleArtifacts(binDir);
|
|
60949
|
-
const stableBin =
|
|
61414
|
+
const stableBin = import_node_path51.default.join(binDir, "frpc");
|
|
60950
61415
|
if (import_node_fs41.default.existsSync(stableBin)) return stableBin;
|
|
60951
61416
|
const partialBin = `${stableBin}.partial`;
|
|
60952
|
-
const tarballPath =
|
|
61417
|
+
const tarballPath = import_node_path51.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
60953
61418
|
try {
|
|
60954
61419
|
const url = frpcDownloadUrl(version2, platform);
|
|
60955
61420
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -60975,7 +61440,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
60975
61440
|
}
|
|
60976
61441
|
for (const name of entries) {
|
|
60977
61442
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
60978
|
-
const full =
|
|
61443
|
+
const full = import_node_path51.default.join(binDir, name);
|
|
60979
61444
|
try {
|
|
60980
61445
|
import_node_fs41.default.rmSync(full, { recursive: true, force: true });
|
|
60981
61446
|
} catch {
|
|
@@ -60998,19 +61463,19 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
60998
61463
|
}
|
|
60999
61464
|
const out = import_node_fs41.default.createWriteStream(dest);
|
|
61000
61465
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
61001
|
-
await (0,
|
|
61466
|
+
await (0, import_promises12.pipeline)(nodeStream, out);
|
|
61002
61467
|
}
|
|
61003
61468
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
61004
|
-
const work =
|
|
61469
|
+
const work = import_node_path51.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
61005
61470
|
import_node_fs41.default.mkdirSync(work, { recursive: true });
|
|
61006
61471
|
try {
|
|
61007
61472
|
await new Promise((resolve9, reject) => {
|
|
61008
|
-
const proc = (0,
|
|
61473
|
+
const proc = (0, import_node_child_process11.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
61009
61474
|
proc.on("error", reject);
|
|
61010
61475
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
61011
61476
|
});
|
|
61012
61477
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
61013
|
-
const src =
|
|
61478
|
+
const src = import_node_path51.default.join(work, dirName, "frpc");
|
|
61014
61479
|
if (!import_node_fs41.default.existsSync(src)) {
|
|
61015
61480
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
61016
61481
|
}
|
|
@@ -61022,10 +61487,10 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
61022
61487
|
|
|
61023
61488
|
// src/tunnel/frpc-process.ts
|
|
61024
61489
|
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
61025
|
-
var
|
|
61026
|
-
var
|
|
61490
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
61491
|
+
var import_node_child_process12 = require("child_process");
|
|
61027
61492
|
function frpcPidFilePath(dataDir) {
|
|
61028
|
-
return
|
|
61493
|
+
return import_node_path52.default.join(dataDir, "frpc.pid");
|
|
61029
61494
|
}
|
|
61030
61495
|
function writeFrpcPid(dataDir, pid) {
|
|
61031
61496
|
try {
|
|
@@ -61067,7 +61532,7 @@ function defaultSleep2(ms) {
|
|
|
61067
61532
|
}
|
|
61068
61533
|
async function killStaleFrpc(deps) {
|
|
61069
61534
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
61070
|
-
const tomlPath =
|
|
61535
|
+
const tomlPath = import_node_path52.default.join(deps.dataDir, "frpc.toml");
|
|
61071
61536
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
61072
61537
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
61073
61538
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -61109,7 +61574,7 @@ async function killStaleFrpc(deps) {
|
|
|
61109
61574
|
async function defaultScanFrpcPidsByCmdline(tomlPath, logger) {
|
|
61110
61575
|
if (process.platform === "win32") return [];
|
|
61111
61576
|
return new Promise((resolve9) => {
|
|
61112
|
-
const ps = (0,
|
|
61577
|
+
const ps = (0, import_node_child_process12.spawn)("ps", ["-axo", "pid=,command="], { stdio: ["ignore", "pipe", "ignore"] });
|
|
61113
61578
|
let buf = "";
|
|
61114
61579
|
ps.stdout.on("data", (c) => {
|
|
61115
61580
|
buf += c.toString();
|
|
@@ -61139,7 +61604,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
61139
61604
|
var TunnelManager = class {
|
|
61140
61605
|
constructor(deps) {
|
|
61141
61606
|
this.deps = deps;
|
|
61142
|
-
this.store = deps.store ?? new TunnelStore(
|
|
61607
|
+
this.store = deps.store ?? new TunnelStore(import_node_path53.default.join(deps.dataDir, "tunnel.json"));
|
|
61143
61608
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
61144
61609
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
61145
61610
|
}
|
|
@@ -61266,8 +61731,8 @@ var TunnelManager = class {
|
|
|
61266
61731
|
dataDir: this.deps.dataDir,
|
|
61267
61732
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
61268
61733
|
});
|
|
61269
|
-
const tomlPath =
|
|
61270
|
-
const proxyName = `clawd-${t.subdomain}-${localPort}-${
|
|
61734
|
+
const tomlPath = import_node_path53.default.join(this.deps.dataDir, "frpc.toml");
|
|
61735
|
+
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto13.default.randomBytes(3).toString("hex")}`;
|
|
61271
61736
|
const toml = buildFrpcToml({
|
|
61272
61737
|
serverAddr: t.frpsHost,
|
|
61273
61738
|
serverPort: t.frpsPort,
|
|
@@ -61278,12 +61743,12 @@ var TunnelManager = class {
|
|
|
61278
61743
|
logLevel: "info"
|
|
61279
61744
|
});
|
|
61280
61745
|
await import_node_fs43.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
61281
|
-
const proc = (this.deps.spawnImpl ??
|
|
61746
|
+
const proc = (this.deps.spawnImpl ?? import_node_child_process13.spawn)(frpcBin, ["-c", tomlPath], {
|
|
61282
61747
|
stdio: ["ignore", "pipe", "pipe"]
|
|
61283
61748
|
});
|
|
61284
|
-
const logDir =
|
|
61749
|
+
const logDir = import_node_path53.default.join(this.deps.dataDir, "log");
|
|
61285
61750
|
import_node_fs43.default.mkdirSync(logDir, { recursive: true });
|
|
61286
|
-
const logFilePath =
|
|
61751
|
+
const logFilePath = import_node_path53.default.join(logDir, "frpc.log");
|
|
61287
61752
|
const logStream = import_node_fs43.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
61288
61753
|
logStream.on("error", () => {
|
|
61289
61754
|
});
|
|
@@ -61366,28 +61831,28 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
61366
61831
|
}
|
|
61367
61832
|
|
|
61368
61833
|
// src/tunnel/device-key.ts
|
|
61369
|
-
var
|
|
61370
|
-
var
|
|
61371
|
-
var
|
|
61834
|
+
var import_node_os17 = __toESM(require("os"), 1);
|
|
61835
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
61836
|
+
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
61372
61837
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
61373
61838
|
function deriveStableDeviceKey(opts = {}) {
|
|
61374
|
-
const hostname = opts.hostname ??
|
|
61375
|
-
const uid = opts.uid ?? (typeof
|
|
61376
|
-
const home = opts.home ??
|
|
61377
|
-
const defaultDataDir =
|
|
61378
|
-
const normalizedDataDir = opts.dataDir ?
|
|
61839
|
+
const hostname = opts.hostname ?? import_node_os17.default.hostname();
|
|
61840
|
+
const uid = opts.uid ?? (typeof import_node_os17.default.userInfo === "function" ? import_node_os17.default.userInfo().uid : 0);
|
|
61841
|
+
const home = opts.home ?? import_node_os17.default.homedir();
|
|
61842
|
+
const defaultDataDir = import_node_path54.default.resolve(import_node_path54.default.join(home, ".clawd"));
|
|
61843
|
+
const normalizedDataDir = opts.dataDir ? import_node_path54.default.resolve(opts.dataDir) : null;
|
|
61379
61844
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
61380
61845
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
61381
|
-
return
|
|
61846
|
+
return import_node_crypto14.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
61382
61847
|
}
|
|
61383
61848
|
|
|
61384
61849
|
// src/auth-store.ts
|
|
61385
61850
|
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
61386
|
-
var
|
|
61387
|
-
var
|
|
61851
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
61852
|
+
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
61388
61853
|
var AUTH_FILE_NAME = "auth.json";
|
|
61389
61854
|
function authFilePath(dataDir) {
|
|
61390
|
-
return
|
|
61855
|
+
return import_node_path55.default.join(dataDir, AUTH_FILE_NAME);
|
|
61391
61856
|
}
|
|
61392
61857
|
function loadOrCreateAuthFile(opts) {
|
|
61393
61858
|
const file = authFilePath(opts.dataDir);
|
|
@@ -61412,10 +61877,10 @@ function loadOrCreateAuthFile(opts) {
|
|
|
61412
61877
|
return next;
|
|
61413
61878
|
}
|
|
61414
61879
|
function defaultGenerateToken() {
|
|
61415
|
-
return
|
|
61880
|
+
return import_node_crypto15.default.randomBytes(32).toString("base64url");
|
|
61416
61881
|
}
|
|
61417
61882
|
function defaultGenerateOwnerPrincipalId() {
|
|
61418
|
-
return `owner-${
|
|
61883
|
+
return `owner-${import_node_crypto15.default.randomUUID()}`;
|
|
61419
61884
|
}
|
|
61420
61885
|
function readAuthFile(file) {
|
|
61421
61886
|
try {
|
|
@@ -61439,7 +61904,7 @@ function readAuthFile(file) {
|
|
|
61439
61904
|
}
|
|
61440
61905
|
}
|
|
61441
61906
|
function writeAuthFile(file, content) {
|
|
61442
|
-
import_node_fs44.default.mkdirSync(
|
|
61907
|
+
import_node_fs44.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
|
|
61443
61908
|
import_node_fs44.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
61444
61909
|
try {
|
|
61445
61910
|
import_node_fs44.default.chmodSync(file, 384);
|
|
@@ -61449,11 +61914,11 @@ function writeAuthFile(file, content) {
|
|
|
61449
61914
|
|
|
61450
61915
|
// src/owner-profile.ts
|
|
61451
61916
|
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
61452
|
-
var
|
|
61453
|
-
var
|
|
61917
|
+
var import_node_os18 = __toESM(require("os"), 1);
|
|
61918
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
61454
61919
|
var PROFILE_FILENAME = "profile.json";
|
|
61455
61920
|
function profilePath(dataDir) {
|
|
61456
|
-
return
|
|
61921
|
+
return import_node_path56.default.join(dataDir, PROFILE_FILENAME);
|
|
61457
61922
|
}
|
|
61458
61923
|
function loadOwnerProfile(dataDir) {
|
|
61459
61924
|
let raw;
|
|
@@ -61478,7 +61943,7 @@ function patchOwnerProfile(dataDir, patch) {
|
|
|
61478
61943
|
return merged;
|
|
61479
61944
|
}
|
|
61480
61945
|
function loadOwnerDisplayName(dataDir) {
|
|
61481
|
-
const fallback =
|
|
61946
|
+
const fallback = import_node_os18.default.userInfo().username;
|
|
61482
61947
|
const displayName = loadOwnerProfile(dataDir).displayName;
|
|
61483
61948
|
if (typeof displayName !== "string" || displayName.length === 0) {
|
|
61484
61949
|
if (displayName !== void 0) {
|
|
@@ -61491,12 +61956,12 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
61491
61956
|
|
|
61492
61957
|
// src/feishu-auth/owner-identity-store.ts
|
|
61493
61958
|
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
61494
|
-
var
|
|
61959
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
61495
61960
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
61496
61961
|
var OwnerIdentityStore = class {
|
|
61497
61962
|
file;
|
|
61498
61963
|
constructor(dataDir) {
|
|
61499
|
-
this.file =
|
|
61964
|
+
this.file = import_node_path57.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
61500
61965
|
}
|
|
61501
61966
|
read() {
|
|
61502
61967
|
let raw;
|
|
@@ -61529,7 +61994,7 @@ var OwnerIdentityStore = class {
|
|
|
61529
61994
|
};
|
|
61530
61995
|
}
|
|
61531
61996
|
write(record3) {
|
|
61532
|
-
import_node_fs46.default.mkdirSync(
|
|
61997
|
+
import_node_fs46.default.mkdirSync(import_node_path57.default.dirname(this.file), { recursive: true });
|
|
61533
61998
|
import_node_fs46.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
|
|
61534
61999
|
try {
|
|
61535
62000
|
import_node_fs46.default.chmodSync(this.file, 384);
|
|
@@ -61547,7 +62012,7 @@ var OwnerIdentityStore = class {
|
|
|
61547
62012
|
};
|
|
61548
62013
|
|
|
61549
62014
|
// src/feishu-auth/login-flow.ts
|
|
61550
|
-
var
|
|
62015
|
+
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
61551
62016
|
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
61552
62017
|
var LoginFlow = class {
|
|
61553
62018
|
constructor(deps) {
|
|
@@ -61556,7 +62021,7 @@ var LoginFlow = class {
|
|
|
61556
62021
|
deps;
|
|
61557
62022
|
pendingStates = /* @__PURE__ */ new Map();
|
|
61558
62023
|
start() {
|
|
61559
|
-
const state =
|
|
62024
|
+
const state = import_node_crypto16.default.randomBytes(16).toString("base64url");
|
|
61560
62025
|
const now = (this.deps.now ?? Date.now)();
|
|
61561
62026
|
this.pendingStates.set(state, now);
|
|
61562
62027
|
this.gcExpired(now);
|
|
@@ -61675,9 +62140,9 @@ var CentralClientError = class extends Error {
|
|
|
61675
62140
|
code;
|
|
61676
62141
|
cause;
|
|
61677
62142
|
};
|
|
61678
|
-
async function centralRequest(opts,
|
|
62143
|
+
async function centralRequest(opts, path99, init) {
|
|
61679
62144
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
61680
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
62145
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path99}`;
|
|
61681
62146
|
const ctrl = new AbortController();
|
|
61682
62147
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
61683
62148
|
let res;
|
|
@@ -62065,7 +62530,7 @@ function buildDeviceHandlers(deps) {
|
|
|
62065
62530
|
}
|
|
62066
62531
|
|
|
62067
62532
|
// src/feishu-auth/verify-token.ts
|
|
62068
|
-
var
|
|
62533
|
+
var crypto12 = __toESM(require("crypto"), 1);
|
|
62069
62534
|
var CONNECT_TOKEN_PREFIX = "clawdtk1";
|
|
62070
62535
|
function verifyConnectToken(args) {
|
|
62071
62536
|
const now = args.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
@@ -62077,7 +62542,7 @@ function verifyConnectToken(args) {
|
|
|
62077
62542
|
const data = `${prefix}.${payloadB64}`;
|
|
62078
62543
|
let signatureValid = false;
|
|
62079
62544
|
try {
|
|
62080
|
-
signatureValid =
|
|
62545
|
+
signatureValid = crypto12.verify(
|
|
62081
62546
|
null,
|
|
62082
62547
|
Buffer.from(data, "utf8"),
|
|
62083
62548
|
args.publicKeyPem,
|
|
@@ -62114,8 +62579,8 @@ function verifyConnectToken(args) {
|
|
|
62114
62579
|
}
|
|
62115
62580
|
|
|
62116
62581
|
// src/feishu-auth/server-key.ts
|
|
62117
|
-
var
|
|
62118
|
-
var
|
|
62582
|
+
var fs66 = __toESM(require("fs"), 1);
|
|
62583
|
+
var path70 = __toESM(require("path"), 1);
|
|
62119
62584
|
var FILE_NAME2 = "server-signing-key.json";
|
|
62120
62585
|
var ServerKeyStore = class {
|
|
62121
62586
|
constructor(dataDir) {
|
|
@@ -62123,12 +62588,12 @@ var ServerKeyStore = class {
|
|
|
62123
62588
|
}
|
|
62124
62589
|
dataDir;
|
|
62125
62590
|
filePath() {
|
|
62126
|
-
return
|
|
62591
|
+
return path70.join(this.dataDir, FILE_NAME2);
|
|
62127
62592
|
}
|
|
62128
62593
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
62129
62594
|
read() {
|
|
62130
62595
|
try {
|
|
62131
|
-
const raw =
|
|
62596
|
+
const raw = fs66.readFileSync(this.filePath(), "utf8");
|
|
62132
62597
|
const parsed = JSON.parse(raw);
|
|
62133
62598
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
62134
62599
|
return parsed.publicKeyPem;
|
|
@@ -62143,12 +62608,12 @@ var ServerKeyStore = class {
|
|
|
62143
62608
|
publicKeyPem,
|
|
62144
62609
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
62145
62610
|
};
|
|
62146
|
-
|
|
62147
|
-
|
|
62611
|
+
fs66.mkdirSync(this.dataDir, { recursive: true });
|
|
62612
|
+
fs66.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
62148
62613
|
}
|
|
62149
62614
|
clear() {
|
|
62150
62615
|
try {
|
|
62151
|
-
|
|
62616
|
+
fs66.unlinkSync(this.filePath());
|
|
62152
62617
|
} catch {
|
|
62153
62618
|
}
|
|
62154
62619
|
}
|
|
@@ -62158,16 +62623,16 @@ var ServerKeyStore = class {
|
|
|
62158
62623
|
init_protocol();
|
|
62159
62624
|
|
|
62160
62625
|
// src/handlers/index.ts
|
|
62161
|
-
var
|
|
62626
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
62162
62627
|
|
|
62163
62628
|
// src/handlers/session.ts
|
|
62164
62629
|
init_protocol();
|
|
62165
62630
|
|
|
62166
62631
|
// src/session/fork.ts
|
|
62167
62632
|
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
62168
|
-
var
|
|
62169
|
-
var
|
|
62170
|
-
var
|
|
62633
|
+
var import_node_os19 = __toESM(require("os"), 1);
|
|
62634
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
62635
|
+
var import_node_crypto17 = require("crypto");
|
|
62171
62636
|
init_claude_history();
|
|
62172
62637
|
function readJsonlEntries(file) {
|
|
62173
62638
|
const raw = import_node_fs47.default.readFileSync(file, "utf8");
|
|
@@ -62183,19 +62648,19 @@ function readJsonlEntries(file) {
|
|
|
62183
62648
|
return out;
|
|
62184
62649
|
}
|
|
62185
62650
|
function forkSession(input) {
|
|
62186
|
-
const baseDir = input.baseDir ??
|
|
62187
|
-
let projectDir =
|
|
62188
|
-
let sourceFile =
|
|
62651
|
+
const baseDir = input.baseDir ?? import_node_path58.default.join(import_node_os19.default.homedir(), ".claude");
|
|
62652
|
+
let projectDir = import_node_path58.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
62653
|
+
let sourceFile = import_node_path58.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
62189
62654
|
if (!import_node_fs47.default.existsSync(sourceFile)) {
|
|
62190
62655
|
const found = findTranscriptByToolSessionId(
|
|
62191
|
-
|
|
62656
|
+
import_node_path58.default.join(baseDir, "projects"),
|
|
62192
62657
|
input.toolSessionId
|
|
62193
62658
|
);
|
|
62194
62659
|
if (!found) {
|
|
62195
62660
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
62196
62661
|
}
|
|
62197
62662
|
sourceFile = found;
|
|
62198
|
-
projectDir =
|
|
62663
|
+
projectDir = import_node_path58.default.dirname(found);
|
|
62199
62664
|
}
|
|
62200
62665
|
const entries = readJsonlEntries(sourceFile);
|
|
62201
62666
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -62204,7 +62669,7 @@ function forkSession(input) {
|
|
|
62204
62669
|
throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
|
|
62205
62670
|
}
|
|
62206
62671
|
const sliced = mainEntries.slice(0, targetIdx + 1);
|
|
62207
|
-
const forkedToolSessionId = (0,
|
|
62672
|
+
const forkedToolSessionId = (0, import_node_crypto17.randomUUID)();
|
|
62208
62673
|
let parentUuid = null;
|
|
62209
62674
|
const forkedLines = [];
|
|
62210
62675
|
for (const entry of sliced) {
|
|
@@ -62224,8 +62689,8 @@ function forkSession(input) {
|
|
|
62224
62689
|
}
|
|
62225
62690
|
forkedLines.push(JSON.stringify(forked));
|
|
62226
62691
|
}
|
|
62227
|
-
const outDir = input.targetCwd ?
|
|
62228
|
-
const forkedFilePath =
|
|
62692
|
+
const outDir = input.targetCwd ? import_node_path58.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
62693
|
+
const forkedFilePath = import_node_path58.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
62229
62694
|
import_node_fs47.default.mkdirSync(outDir, { recursive: true });
|
|
62230
62695
|
import_node_fs47.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
62231
62696
|
return { forkedToolSessionId, forkedFilePath };
|
|
@@ -62233,18 +62698,18 @@ function forkSession(input) {
|
|
|
62233
62698
|
|
|
62234
62699
|
// src/session/external-scan.ts
|
|
62235
62700
|
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
62236
|
-
var
|
|
62237
|
-
var
|
|
62238
|
-
var
|
|
62701
|
+
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
62702
|
+
var import_node_os20 = __toESM(require("os"), 1);
|
|
62703
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
62239
62704
|
var import_node_module = require("module");
|
|
62240
|
-
var
|
|
62705
|
+
var import_node_child_process14 = require("child_process");
|
|
62241
62706
|
var import_meta5 = {};
|
|
62242
62707
|
function defaultRoots() {
|
|
62243
|
-
const home =
|
|
62708
|
+
const home = import_node_os20.default.homedir();
|
|
62244
62709
|
return {
|
|
62245
|
-
claudeProjectsDir:
|
|
62246
|
-
codexDir:
|
|
62247
|
-
clawdDir:
|
|
62710
|
+
claudeProjectsDir: import_node_path59.default.join(home, ".claude", "projects"),
|
|
62711
|
+
codexDir: import_node_path59.default.join(home, ".codex"),
|
|
62712
|
+
clawdDir: import_node_path59.default.join(home, ".clawd")
|
|
62248
62713
|
};
|
|
62249
62714
|
}
|
|
62250
62715
|
function width(s) {
|
|
@@ -62272,7 +62737,7 @@ function toMs(v2) {
|
|
|
62272
62737
|
async function* jsonLines(file) {
|
|
62273
62738
|
let raw;
|
|
62274
62739
|
try {
|
|
62275
|
-
raw = await
|
|
62740
|
+
raw = await import_promises13.default.readFile(file, "utf8");
|
|
62276
62741
|
} catch {
|
|
62277
62742
|
return;
|
|
62278
62743
|
}
|
|
@@ -62312,13 +62777,13 @@ async function scanClaude(roots) {
|
|
|
62312
62777
|
if (!d.isDirectory()) continue;
|
|
62313
62778
|
let files;
|
|
62314
62779
|
try {
|
|
62315
|
-
files = import_node_fs48.default.readdirSync(
|
|
62780
|
+
files = import_node_fs48.default.readdirSync(import_node_path59.default.join(roots.claudeProjectsDir, d.name));
|
|
62316
62781
|
} catch {
|
|
62317
62782
|
continue;
|
|
62318
62783
|
}
|
|
62319
62784
|
for (const name of files) {
|
|
62320
62785
|
if (!name.endsWith(".jsonl")) continue;
|
|
62321
|
-
const file =
|
|
62786
|
+
const file = import_node_path59.default.join(roots.claudeProjectsDir, d.name, name);
|
|
62322
62787
|
let st;
|
|
62323
62788
|
try {
|
|
62324
62789
|
st = import_node_fs48.default.statSync(file);
|
|
@@ -62405,14 +62870,14 @@ function readCodexThreads(db) {
|
|
|
62405
62870
|
} catch {
|
|
62406
62871
|
}
|
|
62407
62872
|
try {
|
|
62408
|
-
const info = (0,
|
|
62873
|
+
const info = (0, import_node_child_process14.spawnSync)("sqlite3", [db, "PRAGMA table_info(threads);"], { encoding: "utf8" });
|
|
62409
62874
|
if (info.status !== 0) return null;
|
|
62410
62875
|
const have = new Set(
|
|
62411
62876
|
info.stdout.split("\n").map((l) => l.split("|")[1]).filter(Boolean)
|
|
62412
62877
|
);
|
|
62413
62878
|
if (!["id", "cwd", "updated_at", "thread_source"].every((c) => have.has(c))) return null;
|
|
62414
62879
|
const sel = COLS.map((c) => have.has(c) ? c : `NULL AS ${c}`).join(", ");
|
|
62415
|
-
const res = (0,
|
|
62880
|
+
const res = (0, import_node_child_process14.spawnSync)("sqlite3", ["-json", db, `SELECT ${sel} FROM threads;`], {
|
|
62416
62881
|
encoding: "utf8",
|
|
62417
62882
|
maxBuffer: 64 * 1024 * 1024
|
|
62418
62883
|
});
|
|
@@ -62448,7 +62913,7 @@ async function codexFromRows(rows) {
|
|
|
62448
62913
|
async function scanCodex(roots) {
|
|
62449
62914
|
let dbs = [];
|
|
62450
62915
|
try {
|
|
62451
|
-
dbs = import_node_fs48.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) =>
|
|
62916
|
+
dbs = import_node_fs48.default.readdirSync(roots.codexDir).filter((n) => /^state_.*\.sqlite$/.test(n)).sort().map((n) => import_node_path59.default.join(roots.codexDir, n));
|
|
62452
62917
|
} catch {
|
|
62453
62918
|
}
|
|
62454
62919
|
if (!dbs.length) return [];
|
|
@@ -62457,14 +62922,14 @@ async function scanCodex(roots) {
|
|
|
62457
62922
|
}
|
|
62458
62923
|
async function scanExternalSessions(rootsIn) {
|
|
62459
62924
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
62460
|
-
const personaRoot =
|
|
62925
|
+
const personaRoot = import_node_path59.default.join(roots.clawdDir, "personas");
|
|
62461
62926
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
62462
62927
|
const out = [];
|
|
62463
62928
|
for (const c of all) {
|
|
62464
62929
|
if (c.skip) continue;
|
|
62465
62930
|
if (c.turns < 1) continue;
|
|
62466
62931
|
if (!c.cwd || !isDir2(c.cwd)) continue;
|
|
62467
|
-
if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot +
|
|
62932
|
+
if (c.cwd === roots.clawdDir || c.cwd === personaRoot || c.cwd.startsWith(personaRoot + import_node_path59.default.sep) || c.cwd.startsWith(roots.clawdDir + import_node_path59.default.sep)) {
|
|
62468
62933
|
continue;
|
|
62469
62934
|
}
|
|
62470
62935
|
out.push({
|
|
@@ -62482,12 +62947,12 @@ async function scanExternalSessions(rootsIn) {
|
|
|
62482
62947
|
|
|
62483
62948
|
// src/session/import-ledger.ts
|
|
62484
62949
|
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
62485
|
-
var
|
|
62950
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
62486
62951
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
62487
62952
|
function readImportLedger(dataDir) {
|
|
62488
62953
|
try {
|
|
62489
62954
|
const parsed = JSON.parse(
|
|
62490
|
-
import_node_fs49.default.readFileSync(
|
|
62955
|
+
import_node_fs49.default.readFileSync(import_node_path60.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
62491
62956
|
);
|
|
62492
62957
|
return Array.isArray(parsed) ? parsed : [];
|
|
62493
62958
|
} catch {
|
|
@@ -62495,7 +62960,7 @@ function readImportLedger(dataDir) {
|
|
|
62495
62960
|
}
|
|
62496
62961
|
}
|
|
62497
62962
|
function appendImportLedger(dataDir, entry) {
|
|
62498
|
-
const file =
|
|
62963
|
+
const file = import_node_path60.default.join(dataDir, LEDGER_FILENAME);
|
|
62499
62964
|
const entries = readImportLedger(dataDir);
|
|
62500
62965
|
entries.push(entry);
|
|
62501
62966
|
import_node_fs49.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
@@ -62503,7 +62968,7 @@ function appendImportLedger(dataDir, entry) {
|
|
|
62503
62968
|
|
|
62504
62969
|
// src/tools/transcript-search.ts
|
|
62505
62970
|
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
62506
|
-
var
|
|
62971
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
62507
62972
|
var SNIPPET_PAD = 60;
|
|
62508
62973
|
var INJECTED_ENVELOPE_RE = /^<(system-reminder|command-name|command-message|command-args|local-command-stdout|local-command-stderr|task-notification|user-prompt-submit-hook|environment_context|user_instructions)\b/;
|
|
62509
62974
|
var CODEX_WRAPPER_RE = /<(related-dir|environment_context|user_instructions)>[\s\S]*?<\/\1>/g;
|
|
@@ -62596,7 +63061,7 @@ function createCodexRolloutLocator(roots) {
|
|
|
62596
63061
|
return;
|
|
62597
63062
|
}
|
|
62598
63063
|
for (const entry of entries) {
|
|
62599
|
-
const full =
|
|
63064
|
+
const full = import_node_path61.default.join(dir, entry.name);
|
|
62600
63065
|
if (entry.isDirectory()) {
|
|
62601
63066
|
walk2(full, into);
|
|
62602
63067
|
continue;
|
|
@@ -62616,16 +63081,16 @@ function createCodexRolloutLocator(roots) {
|
|
|
62616
63081
|
|
|
62617
63082
|
// src/handlers/session.ts
|
|
62618
63083
|
init_protocol();
|
|
62619
|
-
var
|
|
62620
|
-
var
|
|
63084
|
+
var import_node_os21 = __toESM(require("os"), 1);
|
|
63085
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
62621
63086
|
function canReadSearchHit(ctx, file) {
|
|
62622
63087
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
62623
63088
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
62624
63089
|
}
|
|
62625
63090
|
var DEFAULT_SEARCH_LIMIT = 9;
|
|
62626
63091
|
function codexRolloutRoots(dataDir) {
|
|
62627
|
-
const roots = [
|
|
62628
|
-
if (dataDir) roots.push(
|
|
63092
|
+
const roots = [import_node_path62.default.join(import_node_os21.default.homedir(), ".codex", "sessions")];
|
|
63093
|
+
if (dataDir) roots.push(import_node_path62.default.join(dataDir, "codex-home", "sessions"));
|
|
62629
63094
|
return roots;
|
|
62630
63095
|
}
|
|
62631
63096
|
function buildSessionHandlers(deps) {
|
|
@@ -63174,7 +63639,7 @@ function buildPermissionHandlers(deps) {
|
|
|
63174
63639
|
}
|
|
63175
63640
|
|
|
63176
63641
|
// src/handlers/history.ts
|
|
63177
|
-
var
|
|
63642
|
+
var path77 = __toESM(require("path"), 1);
|
|
63178
63643
|
init_protocol();
|
|
63179
63644
|
|
|
63180
63645
|
// src/session/recent-dirs.ts
|
|
@@ -63192,7 +63657,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
63192
63657
|
}
|
|
63193
63658
|
|
|
63194
63659
|
// src/permission/persona-paths.ts
|
|
63195
|
-
var
|
|
63660
|
+
var path76 = __toESM(require("path"), 1);
|
|
63196
63661
|
function getAllowedPersonaIds(grants, action) {
|
|
63197
63662
|
const ids = /* @__PURE__ */ new Set();
|
|
63198
63663
|
for (const g2 of grants) {
|
|
@@ -63205,42 +63670,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
63205
63670
|
return ids;
|
|
63206
63671
|
}
|
|
63207
63672
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
63208
|
-
const target =
|
|
63673
|
+
const target = path76.resolve(absPath);
|
|
63209
63674
|
if (userWorkDir) {
|
|
63210
|
-
const u =
|
|
63211
|
-
const usep = u.endsWith(
|
|
63675
|
+
const u = path76.resolve(userWorkDir);
|
|
63676
|
+
const usep = u.endsWith(path76.sep) ? "" : path76.sep;
|
|
63212
63677
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
63213
63678
|
}
|
|
63214
|
-
const root =
|
|
63215
|
-
const sep4 = root.endsWith(
|
|
63679
|
+
const root = path76.resolve(personaRoot);
|
|
63680
|
+
const sep4 = root.endsWith(path76.sep) ? "" : path76.sep;
|
|
63216
63681
|
if (!target.startsWith(root + sep4)) return false;
|
|
63217
|
-
const rel =
|
|
63682
|
+
const rel = path76.relative(root, target);
|
|
63218
63683
|
if (!rel || rel.startsWith("..")) return false;
|
|
63219
|
-
const personaId2 = rel.split(
|
|
63684
|
+
const personaId2 = rel.split(path76.sep)[0];
|
|
63220
63685
|
if (!personaId2) return false;
|
|
63221
63686
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
63222
63687
|
if (allowed === "*") return true;
|
|
63223
63688
|
return allowed.has(personaId2);
|
|
63224
63689
|
}
|
|
63225
63690
|
function personaIdFromPath(absPath, personaRoot) {
|
|
63226
|
-
const root =
|
|
63227
|
-
const target =
|
|
63228
|
-
const sep4 = root.endsWith(
|
|
63691
|
+
const root = path76.resolve(personaRoot);
|
|
63692
|
+
const target = path76.resolve(absPath);
|
|
63693
|
+
const sep4 = root.endsWith(path76.sep) ? "" : path76.sep;
|
|
63229
63694
|
if (!target.startsWith(root + sep4)) return null;
|
|
63230
|
-
const rel =
|
|
63695
|
+
const rel = path76.relative(root, target);
|
|
63231
63696
|
if (!rel || rel.startsWith("..")) return null;
|
|
63232
|
-
const id = rel.split(
|
|
63697
|
+
const id = rel.split(path76.sep)[0];
|
|
63233
63698
|
return id || null;
|
|
63234
63699
|
}
|
|
63235
63700
|
function isPathWithin(dir, absPath) {
|
|
63236
|
-
const d =
|
|
63237
|
-
const t =
|
|
63238
|
-
const sep4 = d.endsWith(
|
|
63701
|
+
const d = path76.resolve(dir);
|
|
63702
|
+
const t = path76.resolve(absPath);
|
|
63703
|
+
const sep4 = d.endsWith(path76.sep) ? "" : path76.sep;
|
|
63239
63704
|
return t === d || t.startsWith(d + sep4);
|
|
63240
63705
|
}
|
|
63241
63706
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
63242
63707
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
63243
|
-
return personaIdFromPath(
|
|
63708
|
+
return personaIdFromPath(path76.resolve(absPath), personaRoot) === personaId2;
|
|
63244
63709
|
}
|
|
63245
63710
|
|
|
63246
63711
|
// src/handlers/history.ts
|
|
@@ -63293,7 +63758,7 @@ function buildHistoryHandlers(deps) {
|
|
|
63293
63758
|
if (!pid) return false;
|
|
63294
63759
|
return isGuestPathAllowed(
|
|
63295
63760
|
ctx.grants,
|
|
63296
|
-
|
|
63761
|
+
path77.join(personaRoot, pid),
|
|
63297
63762
|
personaRoot,
|
|
63298
63763
|
"read",
|
|
63299
63764
|
userWorkDir
|
|
@@ -63305,7 +63770,7 @@ function buildHistoryHandlers(deps) {
|
|
|
63305
63770
|
};
|
|
63306
63771
|
const list = async (frame, _client, ctx) => {
|
|
63307
63772
|
const args = HistoryListArgs.parse(frame);
|
|
63308
|
-
assertGuestPath(ctx,
|
|
63773
|
+
assertGuestPath(ctx, path77.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
63309
63774
|
const sessions = await history.listSessions(args);
|
|
63310
63775
|
return { response: { type: "history:list", sessions } };
|
|
63311
63776
|
};
|
|
@@ -63353,14 +63818,14 @@ function buildHistoryHandlers(deps) {
|
|
|
63353
63818
|
};
|
|
63354
63819
|
const subagents = async (frame, _client, ctx) => {
|
|
63355
63820
|
const args = HistorySubagentsArgs.parse(frame);
|
|
63356
|
-
assertGuestPath(ctx,
|
|
63821
|
+
assertGuestPath(ctx, path77.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
63357
63822
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
63358
63823
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
63359
63824
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
63360
63825
|
};
|
|
63361
63826
|
const subagentRead = async (frame, _client, ctx) => {
|
|
63362
63827
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
63363
|
-
assertGuestPath(ctx,
|
|
63828
|
+
assertGuestPath(ctx, path77.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
63364
63829
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
63365
63830
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
63366
63831
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -63370,7 +63835,7 @@ function buildHistoryHandlers(deps) {
|
|
|
63370
63835
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
63371
63836
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
63372
63837
|
const filtered = dirs.filter(
|
|
63373
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
63838
|
+
(d) => isGuestPathAllowed(ctx.grants, path77.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
63374
63839
|
);
|
|
63375
63840
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
63376
63841
|
}
|
|
@@ -63387,17 +63852,17 @@ function buildHistoryHandlers(deps) {
|
|
|
63387
63852
|
}
|
|
63388
63853
|
|
|
63389
63854
|
// src/handlers/projects.ts
|
|
63390
|
-
var
|
|
63391
|
-
var
|
|
63392
|
-
var
|
|
63393
|
-
var
|
|
63855
|
+
var fs71 = __toESM(require("fs"), 1);
|
|
63856
|
+
var os23 = __toESM(require("os"), 1);
|
|
63857
|
+
var path78 = __toESM(require("path"), 1);
|
|
63858
|
+
var import_node_child_process15 = require("child_process");
|
|
63394
63859
|
init_protocol();
|
|
63395
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
63860
|
+
var DEFAULT_PROJECTS_ROOT = path78.join(os23.homedir(), "Documents", "ChatGPT");
|
|
63396
63861
|
function allocateDir(root, name) {
|
|
63397
|
-
let candidate =
|
|
63862
|
+
let candidate = path78.join(root, name);
|
|
63398
63863
|
let n = 2;
|
|
63399
|
-
while (
|
|
63400
|
-
candidate =
|
|
63864
|
+
while (fs71.existsSync(candidate)) {
|
|
63865
|
+
candidate = path78.join(root, `${name} ${n}`);
|
|
63401
63866
|
n += 1;
|
|
63402
63867
|
}
|
|
63403
63868
|
return candidate;
|
|
@@ -63425,11 +63890,11 @@ function buildProjectHandlers(deps) {
|
|
|
63425
63890
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
63426
63891
|
}
|
|
63427
63892
|
try {
|
|
63428
|
-
if (!
|
|
63893
|
+
if (!fs71.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
63429
63894
|
} catch {
|
|
63430
63895
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
63431
63896
|
}
|
|
63432
|
-
const r = (0,
|
|
63897
|
+
const r = (0, import_node_child_process15.spawnSync)("open", ["-R", args.path], { stdio: "ignore" });
|
|
63433
63898
|
if (r.status !== 0) {
|
|
63434
63899
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `open -R \u5931\u8D25: exit ${r.status}`);
|
|
63435
63900
|
}
|
|
@@ -63441,7 +63906,7 @@ function buildProjectHandlers(deps) {
|
|
|
63441
63906
|
let target;
|
|
63442
63907
|
if (args.path) {
|
|
63443
63908
|
try {
|
|
63444
|
-
if (!
|
|
63909
|
+
if (!fs71.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
63445
63910
|
} catch {
|
|
63446
63911
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
63447
63912
|
}
|
|
@@ -63449,15 +63914,15 @@ function buildProjectHandlers(deps) {
|
|
|
63449
63914
|
} else {
|
|
63450
63915
|
const name = args.name;
|
|
63451
63916
|
try {
|
|
63452
|
-
|
|
63917
|
+
fs71.mkdirSync(root, { recursive: true });
|
|
63453
63918
|
target = allocateDir(root, name);
|
|
63454
|
-
|
|
63919
|
+
fs71.mkdirSync(target);
|
|
63455
63920
|
} catch (err) {
|
|
63456
63921
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
63457
63922
|
}
|
|
63458
|
-
const git = (0,
|
|
63923
|
+
const git = (0, import_node_child_process15.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
63459
63924
|
if (git.status !== 0) {
|
|
63460
|
-
|
|
63925
|
+
fs71.rmSync(target, { recursive: true, force: true });
|
|
63461
63926
|
throw new ClawdError(
|
|
63462
63927
|
ERROR_CODES.INVALID_CWD,
|
|
63463
63928
|
`git init \u5931\u8D25\uFF08${git.error ? String(git.error) : `exit ${git.status}`}\uFF09: ${target}`
|
|
@@ -63482,8 +63947,8 @@ function buildProjectHandlers(deps) {
|
|
|
63482
63947
|
}
|
|
63483
63948
|
|
|
63484
63949
|
// src/handlers/workspace.ts
|
|
63485
|
-
var
|
|
63486
|
-
var
|
|
63950
|
+
var path79 = __toESM(require("path"), 1);
|
|
63951
|
+
var os24 = __toESM(require("os"), 1);
|
|
63487
63952
|
init_protocol();
|
|
63488
63953
|
init_protocol();
|
|
63489
63954
|
function buildEnabledPluginNames(personaManager, personaId2) {
|
|
@@ -63523,23 +63988,23 @@ function buildWorkspaceHandlers(deps) {
|
|
|
63523
63988
|
const list = async (frame, _client, ctx) => {
|
|
63524
63989
|
const args = WorkspaceListArgs.parse(frame);
|
|
63525
63990
|
const isGuest = ctx?.principal.kind === "guest";
|
|
63526
|
-
const fallbackCwd = isGuest && personaRoot ? personaRoot :
|
|
63527
|
-
const resolvedCwd =
|
|
63528
|
-
const target = args.path ?
|
|
63991
|
+
const fallbackCwd = isGuest && personaRoot ? personaRoot : os24.homedir();
|
|
63992
|
+
const resolvedCwd = path79.resolve(args.cwd ?? fallbackCwd);
|
|
63993
|
+
const target = args.path ? path79.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
63529
63994
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
63530
63995
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
63531
63996
|
return { response: { type: "workspace:list", ...res } };
|
|
63532
63997
|
};
|
|
63533
63998
|
const read = async (frame, _client, ctx) => {
|
|
63534
63999
|
const args = WorkspaceReadArgs.parse(frame);
|
|
63535
|
-
const target =
|
|
64000
|
+
const target = path79.isAbsolute(args.path) ? path79.resolve(args.path) : path79.resolve(args.cwd, args.path);
|
|
63536
64001
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
63537
64002
|
const res = workspace.read(args);
|
|
63538
64003
|
return { response: { type: "workspace:read", ...res } };
|
|
63539
64004
|
};
|
|
63540
64005
|
const skillsList = async (frame, _client, ctx) => {
|
|
63541
64006
|
const args = SkillsListArgs.parse(frame);
|
|
63542
|
-
const cwdAbs =
|
|
64007
|
+
const cwdAbs = path79.resolve(args.cwd);
|
|
63543
64008
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
63544
64009
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
63545
64010
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -63551,7 +64016,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
63551
64016
|
};
|
|
63552
64017
|
const agentsList = async (frame, _client, ctx) => {
|
|
63553
64018
|
const args = AgentsListArgs.parse(frame);
|
|
63554
|
-
const cwdAbs =
|
|
64019
|
+
const cwdAbs = path79.resolve(args.cwd);
|
|
63555
64020
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
63556
64021
|
if (args.tool === "codex") {
|
|
63557
64022
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -63573,18 +64038,18 @@ function buildWorkspaceHandlers(deps) {
|
|
|
63573
64038
|
}
|
|
63574
64039
|
|
|
63575
64040
|
// src/handlers/git.ts
|
|
63576
|
-
var
|
|
64041
|
+
var path81 = __toESM(require("path"), 1);
|
|
63577
64042
|
init_protocol();
|
|
63578
64043
|
init_protocol();
|
|
63579
64044
|
|
|
63580
64045
|
// src/workspace/git.ts
|
|
63581
|
-
var
|
|
64046
|
+
var import_node_child_process16 = require("child_process");
|
|
63582
64047
|
var import_node_fs51 = __toESM(require("fs"), 1);
|
|
63583
|
-
var
|
|
64048
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
63584
64049
|
var import_node_util = require("util");
|
|
63585
|
-
var pexec = (0, import_node_util.promisify)(
|
|
64050
|
+
var pexec = (0, import_node_util.promisify)(import_node_child_process16.execFile);
|
|
63586
64051
|
function normalizePath(p2) {
|
|
63587
|
-
const resolved =
|
|
64052
|
+
const resolved = import_node_path63.default.resolve(p2);
|
|
63588
64053
|
try {
|
|
63589
64054
|
return import_node_fs51.default.realpathSync(resolved);
|
|
63590
64055
|
} catch {
|
|
@@ -63660,7 +64125,7 @@ async function listGitBranches(cwd) {
|
|
|
63660
64125
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
63661
64126
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
63662
64127
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
63663
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
64128
|
+
if (!isGuestPathAllowed(ctx.grants, path81.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
63664
64129
|
throw new ClawdError(
|
|
63665
64130
|
ERROR_CODES.UNAUTHORIZED,
|
|
63666
64131
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -64205,7 +64670,7 @@ function buildFeishuAuthHandlers(deps) {
|
|
|
64205
64670
|
}
|
|
64206
64671
|
|
|
64207
64672
|
// src/handlers/meta.ts
|
|
64208
|
-
var
|
|
64673
|
+
var import_node_os22 = __toESM(require("os"), 1);
|
|
64209
64674
|
init_protocol();
|
|
64210
64675
|
|
|
64211
64676
|
// src/handlers/method-grants.ts
|
|
@@ -64508,21 +64973,21 @@ function computeMethodAccess(args) {
|
|
|
64508
64973
|
}
|
|
64509
64974
|
|
|
64510
64975
|
// src/version.ts
|
|
64511
|
-
var version = "0.2.
|
|
64976
|
+
var version = "0.2.466".length > 0 ? "0.2.466" : "dev";
|
|
64512
64977
|
|
|
64513
64978
|
// src/cli-probe/probe.ts
|
|
64514
|
-
var
|
|
64515
|
-
var
|
|
64979
|
+
var fs73 = __toESM(require("fs"), 1);
|
|
64980
|
+
var path82 = __toESM(require("path"), 1);
|
|
64516
64981
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
64517
64982
|
var BIN_NAME = "clawd";
|
|
64518
64983
|
var MAX_PARENT_HOPS = 5;
|
|
64519
64984
|
function probeGlobalCli(pathEnv) {
|
|
64520
64985
|
if (!pathEnv) return null;
|
|
64521
|
-
for (const dir of pathEnv.split(
|
|
64986
|
+
for (const dir of pathEnv.split(path82.delimiter)) {
|
|
64522
64987
|
if (!dir) continue;
|
|
64523
64988
|
let real;
|
|
64524
64989
|
try {
|
|
64525
|
-
real =
|
|
64990
|
+
real = fs73.realpathSync(path82.join(dir, BIN_NAME));
|
|
64526
64991
|
} catch {
|
|
64527
64992
|
continue;
|
|
64528
64993
|
}
|
|
@@ -64532,15 +64997,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
64532
64997
|
return null;
|
|
64533
64998
|
}
|
|
64534
64999
|
function readOwnPackageVersion(entryPath) {
|
|
64535
|
-
let dir =
|
|
65000
|
+
let dir = path82.dirname(entryPath);
|
|
64536
65001
|
for (let i = 0; i < MAX_PARENT_HOPS; i++) {
|
|
64537
65002
|
try {
|
|
64538
|
-
const raw =
|
|
65003
|
+
const raw = fs73.readFileSync(path82.join(dir, "package.json"), "utf8");
|
|
64539
65004
|
const pkg = JSON.parse(raw);
|
|
64540
65005
|
if (pkg.name !== PKG_NAME) return null;
|
|
64541
65006
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
64542
65007
|
} catch {
|
|
64543
|
-
const parent =
|
|
65008
|
+
const parent = path82.dirname(dir);
|
|
64544
65009
|
if (parent === dir) return null;
|
|
64545
65010
|
dir = parent;
|
|
64546
65011
|
}
|
|
@@ -64576,7 +65041,7 @@ function buildReadyFrame(deps, client) {
|
|
|
64576
65041
|
return {
|
|
64577
65042
|
version,
|
|
64578
65043
|
protocolVersion: PROTOCOL_VERSION,
|
|
64579
|
-
hostname:
|
|
65044
|
+
hostname: import_node_os22.default.hostname(),
|
|
64580
65045
|
os: process.platform,
|
|
64581
65046
|
tools,
|
|
64582
65047
|
runningSessions: info.runningSessions,
|
|
@@ -64712,7 +65177,7 @@ function buildPersonaHandlers(deps) {
|
|
|
64712
65177
|
}
|
|
64713
65178
|
|
|
64714
65179
|
// src/handlers/attachment.ts
|
|
64715
|
-
var
|
|
65180
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
64716
65181
|
init_protocol();
|
|
64717
65182
|
init_protocol();
|
|
64718
65183
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -64792,12 +65257,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
64792
65257
|
`session ${args.sessionId} scope unresolved`
|
|
64793
65258
|
);
|
|
64794
65259
|
}
|
|
64795
|
-
const cwdAbs =
|
|
64796
|
-
const candidateAbs =
|
|
65260
|
+
const cwdAbs = import_node_path64.default.resolve(sessionFile.cwd);
|
|
65261
|
+
const candidateAbs = import_node_path64.default.isAbsolute(args.relPath) ? import_node_path64.default.resolve(args.relPath) : import_node_path64.default.resolve(cwdAbs, args.relPath);
|
|
64797
65262
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
64798
65263
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
64799
65264
|
const entry = entries.find((e) => {
|
|
64800
|
-
const storedAbs =
|
|
65265
|
+
const storedAbs = import_node_path64.default.isAbsolute(e.relPath) ? import_node_path64.default.resolve(e.relPath) : import_node_path64.default.resolve(cwdAbs, e.relPath);
|
|
64801
65266
|
return storedAbs === candidateAbs && !e.stale;
|
|
64802
65267
|
});
|
|
64803
65268
|
if (!entry) {
|
|
@@ -64822,7 +65287,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
64822
65287
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
64823
65288
|
const f = deps.sessionStore.read(sessionId);
|
|
64824
65289
|
if (!f) return;
|
|
64825
|
-
assertGuestAttachmentPath(ctx,
|
|
65290
|
+
assertGuestAttachmentPath(ctx, import_node_path64.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
64826
65291
|
}
|
|
64827
65292
|
const groupAdd = async (frame, _client, ctx) => {
|
|
64828
65293
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -64837,8 +65302,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
64837
65302
|
if (!scope) {
|
|
64838
65303
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
64839
65304
|
}
|
|
64840
|
-
const cwdAbs =
|
|
64841
|
-
const candidateAbs =
|
|
65305
|
+
const cwdAbs = import_node_path64.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
65306
|
+
const candidateAbs = import_node_path64.default.isAbsolute(args.relPath) ? import_node_path64.default.resolve(args.relPath) : import_node_path64.default.resolve(cwdAbs, args.relPath);
|
|
64842
65307
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
64843
65308
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
64844
65309
|
const size = 0;
|
|
@@ -64896,21 +65361,21 @@ function buildAttachmentHandlers(deps) {
|
|
|
64896
65361
|
}
|
|
64897
65362
|
|
|
64898
65363
|
// src/handlers/extension.ts
|
|
64899
|
-
var
|
|
64900
|
-
var
|
|
65364
|
+
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
65365
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
64901
65366
|
init_protocol();
|
|
64902
65367
|
|
|
64903
65368
|
// src/extension/bundle-zip.ts
|
|
64904
|
-
var
|
|
64905
|
-
var
|
|
64906
|
-
var
|
|
65369
|
+
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
65370
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
65371
|
+
var import_node_crypto18 = __toESM(require("crypto"), 1);
|
|
64907
65372
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
64908
65373
|
async function bundleExtensionDir(dir) {
|
|
64909
65374
|
const entries = await listFilesSorted(dir);
|
|
64910
65375
|
const zip = new import_jszip2.default();
|
|
64911
65376
|
for (const rel of entries) {
|
|
64912
|
-
const abs =
|
|
64913
|
-
const content = await
|
|
65377
|
+
const abs = import_node_path65.default.join(dir, rel);
|
|
65378
|
+
const content = await import_promises14.default.readFile(abs);
|
|
64914
65379
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
64915
65380
|
}
|
|
64916
65381
|
const buffer = await zip.generateAsync({
|
|
@@ -64918,7 +65383,7 @@ async function bundleExtensionDir(dir) {
|
|
|
64918
65383
|
compression: "DEFLATE",
|
|
64919
65384
|
compressionOptions: { level: 6 }
|
|
64920
65385
|
});
|
|
64921
|
-
const sha256 =
|
|
65386
|
+
const sha256 = import_node_crypto18.default.createHash("sha256").update(buffer).digest("hex");
|
|
64922
65387
|
return { buffer, sha256 };
|
|
64923
65388
|
}
|
|
64924
65389
|
var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
@@ -64930,8 +65395,8 @@ async function listFilesSorted(rootDir) {
|
|
|
64930
65395
|
return out;
|
|
64931
65396
|
}
|
|
64932
65397
|
async function walk(absRoot, relPrefix, out) {
|
|
64933
|
-
const dirAbs =
|
|
64934
|
-
const entries = await
|
|
65398
|
+
const dirAbs = import_node_path65.default.join(absRoot, relPrefix);
|
|
65399
|
+
const entries = await import_promises14.default.readdir(dirAbs, { withFileTypes: true });
|
|
64935
65400
|
for (const e of entries) {
|
|
64936
65401
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
64937
65402
|
const rel = relPrefix ? `${relPrefix}/${e.name}` : e.name;
|
|
@@ -64983,26 +65448,26 @@ function computePublishCheck(args) {
|
|
|
64983
65448
|
}
|
|
64984
65449
|
|
|
64985
65450
|
// src/extension/install-flow.ts
|
|
64986
|
-
var
|
|
64987
|
-
var
|
|
64988
|
-
var
|
|
64989
|
-
var
|
|
65451
|
+
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
65452
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
65453
|
+
var import_node_os24 = __toESM(require("os"), 1);
|
|
65454
|
+
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
64990
65455
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
64991
65456
|
|
|
64992
65457
|
// src/extension/paths.ts
|
|
64993
|
-
var
|
|
64994
|
-
var
|
|
65458
|
+
var import_node_os23 = __toESM(require("os"), 1);
|
|
65459
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
64995
65460
|
function clawdHomeRoot(override) {
|
|
64996
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
65461
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
|
|
64997
65462
|
}
|
|
64998
65463
|
function extensionsRoot(override) {
|
|
64999
|
-
return
|
|
65464
|
+
return import_node_path66.default.join(clawdHomeRoot(override), "extensions");
|
|
65000
65465
|
}
|
|
65001
65466
|
function publishedChannelsFile(override) {
|
|
65002
|
-
return
|
|
65467
|
+
return import_node_path66.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
65003
65468
|
}
|
|
65004
65469
|
function bundleCacheRoot(override) {
|
|
65005
|
-
return
|
|
65470
|
+
return import_node_path66.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
65006
65471
|
}
|
|
65007
65472
|
|
|
65008
65473
|
// src/extension/install-flow.ts
|
|
@@ -65015,7 +65480,7 @@ var InstallError = class extends Error {
|
|
|
65015
65480
|
};
|
|
65016
65481
|
async function installFromChannel(args, deps) {
|
|
65017
65482
|
const { channelRef, snapshotHash, bundleZip } = args;
|
|
65018
|
-
const computed =
|
|
65483
|
+
const computed = import_node_crypto19.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
65019
65484
|
if (computed !== snapshotHash) {
|
|
65020
65485
|
throw new InstallError(
|
|
65021
65486
|
"HASH_MISMATCH",
|
|
@@ -65029,7 +65494,7 @@ async function installFromChannel(args, deps) {
|
|
|
65029
65494
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
65030
65495
|
}
|
|
65031
65496
|
for (const name of Object.keys(zip.files)) {
|
|
65032
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
65497
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path67.default.isAbsolute(name)) {
|
|
65033
65498
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
65034
65499
|
}
|
|
65035
65500
|
}
|
|
@@ -65061,10 +65526,10 @@ async function installFromChannel(args, deps) {
|
|
|
65061
65526
|
);
|
|
65062
65527
|
}
|
|
65063
65528
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
65064
|
-
const destDir =
|
|
65529
|
+
const destDir = import_node_path67.default.join(deps.extensionsRoot, localExtId);
|
|
65065
65530
|
let destExists = false;
|
|
65066
65531
|
try {
|
|
65067
|
-
await
|
|
65532
|
+
await import_promises15.default.access(destDir);
|
|
65068
65533
|
destExists = true;
|
|
65069
65534
|
} catch {
|
|
65070
65535
|
}
|
|
@@ -65074,28 +65539,28 @@ async function installFromChannel(args, deps) {
|
|
|
65074
65539
|
`extension ${localExtId} already installed locally (from owner ${channelRef.ownerPrincipalId})`
|
|
65075
65540
|
);
|
|
65076
65541
|
}
|
|
65077
|
-
const stage = await
|
|
65078
|
-
|
|
65542
|
+
const stage = await import_promises15.default.mkdtemp(
|
|
65543
|
+
import_node_path67.default.join(import_node_os24.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
65079
65544
|
);
|
|
65080
65545
|
try {
|
|
65081
65546
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
65082
|
-
const dest =
|
|
65547
|
+
const dest = import_node_path67.default.join(stage, name);
|
|
65083
65548
|
if (entry.dir) {
|
|
65084
|
-
await
|
|
65549
|
+
await import_promises15.default.mkdir(dest, { recursive: true });
|
|
65085
65550
|
continue;
|
|
65086
65551
|
}
|
|
65087
|
-
await
|
|
65552
|
+
await import_promises15.default.mkdir(import_node_path67.default.dirname(dest), { recursive: true });
|
|
65088
65553
|
if (name === "manifest.json") {
|
|
65089
65554
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
65090
|
-
await
|
|
65555
|
+
await import_promises15.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
65091
65556
|
} else {
|
|
65092
|
-
await
|
|
65557
|
+
await import_promises15.default.writeFile(dest, await entry.async("nodebuffer"));
|
|
65093
65558
|
}
|
|
65094
65559
|
}
|
|
65095
|
-
await
|
|
65096
|
-
await
|
|
65560
|
+
await import_promises15.default.mkdir(deps.extensionsRoot, { recursive: true });
|
|
65561
|
+
await import_promises15.default.rename(stage, destDir);
|
|
65097
65562
|
} catch (e) {
|
|
65098
|
-
await
|
|
65563
|
+
await import_promises15.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
65099
65564
|
});
|
|
65100
65565
|
throw e;
|
|
65101
65566
|
}
|
|
@@ -65104,10 +65569,10 @@ async function installFromChannel(args, deps) {
|
|
|
65104
65569
|
}
|
|
65105
65570
|
|
|
65106
65571
|
// src/extension/update-flow.ts
|
|
65107
|
-
var
|
|
65108
|
-
var
|
|
65109
|
-
var
|
|
65110
|
-
var
|
|
65572
|
+
var import_promises16 = __toESM(require("fs/promises"), 1);
|
|
65573
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
65574
|
+
var import_node_os25 = __toESM(require("os"), 1);
|
|
65575
|
+
var import_node_crypto20 = __toESM(require("crypto"), 1);
|
|
65111
65576
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
65112
65577
|
var UpdateError = class extends Error {
|
|
65113
65578
|
constructor(code, message) {
|
|
@@ -65122,11 +65587,11 @@ async function updateFromChannel(args, deps) {
|
|
|
65122
65587
|
channelRef.extId,
|
|
65123
65588
|
channelRef.ownerPrincipalId
|
|
65124
65589
|
);
|
|
65125
|
-
const liveDir =
|
|
65590
|
+
const liveDir = import_node_path68.default.join(deps.extensionsRoot, localExtId);
|
|
65126
65591
|
const prevDir = `${liveDir}.prev`;
|
|
65127
65592
|
let existingVersion;
|
|
65128
65593
|
try {
|
|
65129
|
-
const raw = await
|
|
65594
|
+
const raw = await import_promises16.default.readFile(import_node_path68.default.join(liveDir, "manifest.json"), "utf8");
|
|
65130
65595
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
65131
65596
|
if (!parsed2.success) {
|
|
65132
65597
|
throw new UpdateError(
|
|
@@ -65145,7 +65610,7 @@ async function updateFromChannel(args, deps) {
|
|
|
65145
65610
|
if (e instanceof UpdateError) throw e;
|
|
65146
65611
|
throw e;
|
|
65147
65612
|
}
|
|
65148
|
-
const computed =
|
|
65613
|
+
const computed = import_node_crypto20.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
65149
65614
|
if (computed !== snapshotHash) {
|
|
65150
65615
|
throw new UpdateError(
|
|
65151
65616
|
"HASH_MISMATCH",
|
|
@@ -65159,7 +65624,7 @@ async function updateFromChannel(args, deps) {
|
|
|
65159
65624
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
65160
65625
|
}
|
|
65161
65626
|
for (const name of Object.keys(zip.files)) {
|
|
65162
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
65627
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path68.default.isAbsolute(name)) {
|
|
65163
65628
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
65164
65629
|
}
|
|
65165
65630
|
}
|
|
@@ -65191,31 +65656,31 @@ async function updateFromChannel(args, deps) {
|
|
|
65191
65656
|
);
|
|
65192
65657
|
}
|
|
65193
65658
|
await deps.runtime.close(localExtId);
|
|
65194
|
-
await
|
|
65195
|
-
await
|
|
65196
|
-
const stage = await
|
|
65197
|
-
|
|
65659
|
+
await import_promises16.default.rm(prevDir, { recursive: true, force: true });
|
|
65660
|
+
await import_promises16.default.rename(liveDir, prevDir);
|
|
65661
|
+
const stage = await import_promises16.default.mkdtemp(
|
|
65662
|
+
import_node_path68.default.join(import_node_os25.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
65198
65663
|
);
|
|
65199
65664
|
try {
|
|
65200
65665
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
65201
|
-
const dest =
|
|
65666
|
+
const dest = import_node_path68.default.join(stage, name);
|
|
65202
65667
|
if (entry.dir) {
|
|
65203
|
-
await
|
|
65668
|
+
await import_promises16.default.mkdir(dest, { recursive: true });
|
|
65204
65669
|
continue;
|
|
65205
65670
|
}
|
|
65206
|
-
await
|
|
65671
|
+
await import_promises16.default.mkdir(import_node_path68.default.dirname(dest), { recursive: true });
|
|
65207
65672
|
if (name === "manifest.json") {
|
|
65208
65673
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
65209
|
-
await
|
|
65674
|
+
await import_promises16.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
65210
65675
|
} else {
|
|
65211
|
-
await
|
|
65676
|
+
await import_promises16.default.writeFile(dest, await entry.async("nodebuffer"));
|
|
65212
65677
|
}
|
|
65213
65678
|
}
|
|
65214
|
-
await
|
|
65679
|
+
await import_promises16.default.rename(stage, liveDir);
|
|
65215
65680
|
} catch (e) {
|
|
65216
|
-
await
|
|
65681
|
+
await import_promises16.default.rm(stage, { recursive: true, force: true }).catch(() => {
|
|
65217
65682
|
});
|
|
65218
|
-
await
|
|
65683
|
+
await import_promises16.default.rename(prevDir, liveDir).catch(() => {
|
|
65219
65684
|
});
|
|
65220
65685
|
await deps.runtime.open(localExtId).catch(() => {
|
|
65221
65686
|
});
|
|
@@ -65237,7 +65702,7 @@ async function updateFromChannel(args, deps) {
|
|
|
65237
65702
|
reason: e.message
|
|
65238
65703
|
};
|
|
65239
65704
|
}
|
|
65240
|
-
await
|
|
65705
|
+
await import_promises16.default.rm(prevDir, { recursive: true, force: true });
|
|
65241
65706
|
return {
|
|
65242
65707
|
kind: "updated",
|
|
65243
65708
|
extId: localExtId,
|
|
@@ -65245,9 +65710,9 @@ async function updateFromChannel(args, deps) {
|
|
|
65245
65710
|
};
|
|
65246
65711
|
}
|
|
65247
65712
|
async function rollback(deps, localExtId, liveDir, prevDir) {
|
|
65248
|
-
await
|
|
65713
|
+
await import_promises16.default.rm(liveDir, { recursive: true, force: true }).catch(() => {
|
|
65249
65714
|
});
|
|
65250
|
-
await
|
|
65715
|
+
await import_promises16.default.rename(prevDir, liveDir).catch(() => {
|
|
65251
65716
|
});
|
|
65252
65717
|
await deps.runtime.open(localExtId).catch(() => {
|
|
65253
65718
|
});
|
|
@@ -65270,18 +65735,18 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
65270
65735
|
);
|
|
65271
65736
|
}
|
|
65272
65737
|
}
|
|
65273
|
-
const manifestPath =
|
|
65738
|
+
const manifestPath = import_node_path69.default.join(root, extId, "manifest.json");
|
|
65274
65739
|
const manifest = await readManifest(root, extId);
|
|
65275
65740
|
const next = { ...manifest, version: newVersion };
|
|
65276
65741
|
const tmp = `${manifestPath}.tmp`;
|
|
65277
|
-
await
|
|
65278
|
-
await
|
|
65742
|
+
await import_promises17.default.writeFile(tmp, JSON.stringify(next, null, 2));
|
|
65743
|
+
await import_promises17.default.rename(tmp, manifestPath);
|
|
65279
65744
|
}
|
|
65280
65745
|
async function readManifest(root, extId) {
|
|
65281
|
-
const file =
|
|
65746
|
+
const file = import_node_path69.default.join(root, extId, "manifest.json");
|
|
65282
65747
|
let raw;
|
|
65283
65748
|
try {
|
|
65284
|
-
raw = await
|
|
65749
|
+
raw = await import_promises17.default.readFile(file, "utf8");
|
|
65285
65750
|
} catch (e) {
|
|
65286
65751
|
if (e.code === "ENOENT") {
|
|
65287
65752
|
throw new ClawdError(ERROR_CODES.INVALID_PARAM, `extension ${extId} not installed`);
|
|
@@ -65362,7 +65827,7 @@ function buildExtensionHandlers(deps) {
|
|
|
65362
65827
|
};
|
|
65363
65828
|
async function buildSnapshotMeta(extId) {
|
|
65364
65829
|
const manifest = await readManifest(deps.root, extId);
|
|
65365
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
65830
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path69.default.join(deps.root, extId));
|
|
65366
65831
|
return { manifest, contentHash: sha256, buffer };
|
|
65367
65832
|
}
|
|
65368
65833
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -65537,7 +66002,7 @@ function buildExtensionHandlers(deps) {
|
|
|
65537
66002
|
}
|
|
65538
66003
|
|
|
65539
66004
|
// src/app-builder/kill-port.ts
|
|
65540
|
-
var
|
|
66005
|
+
var import_node_child_process17 = require("child_process");
|
|
65541
66006
|
async function killPortOccupants(port, ownedPids, logger) {
|
|
65542
66007
|
let pids;
|
|
65543
66008
|
try {
|
|
@@ -65579,7 +66044,7 @@ async function killPortOccupants(port, ownedPids, logger) {
|
|
|
65579
66044
|
}
|
|
65580
66045
|
function listPidsOnPort(port) {
|
|
65581
66046
|
return new Promise((resolve9, reject) => {
|
|
65582
|
-
(0,
|
|
66047
|
+
(0, import_node_child_process17.execFile)(
|
|
65583
66048
|
"lsof",
|
|
65584
66049
|
["-ti", `:${port}`],
|
|
65585
66050
|
{ timeout: 3e3 },
|
|
@@ -65605,7 +66070,7 @@ var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
|
65605
66070
|
|
|
65606
66071
|
// src/handlers/app-builder.ts
|
|
65607
66072
|
init_protocol();
|
|
65608
|
-
var
|
|
66073
|
+
var import_node_path70 = require("path");
|
|
65609
66074
|
var import_node_fs52 = require("fs");
|
|
65610
66075
|
var DEFAULT_TEMPLATE = "nestjs-react";
|
|
65611
66076
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
@@ -65752,13 +66217,13 @@ function buildAppBuilderHandlers(deps) {
|
|
|
65752
66217
|
const created = await deps.createProjectOnDisk({
|
|
65753
66218
|
store: userStore,
|
|
65754
66219
|
name: f.name,
|
|
65755
|
-
templateSrcDir: (0,
|
|
65756
|
-
scaffoldScript: (0,
|
|
66220
|
+
templateSrcDir: (0, import_node_path70.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE),
|
|
66221
|
+
scaffoldScript: (0, import_node_path70.join)(deps.deployKitRoot, "scripts", "new-extension.sh"),
|
|
65757
66222
|
reservedPorts,
|
|
65758
66223
|
// 凭据只进 scaffold 子进程的 env,且**只给这个 persona 的 kit 模板声明要的那几个变量**
|
|
65759
66224
|
// (M1b Step 5)。整表塞进去粒度只到「进程」——那会把 service-role key 交给一个用不到
|
|
65760
66225
|
// 它的脚本。new-extension.sh 用它把模板的 `${VAR}` 渲成项目可跑的 server/.env。
|
|
65761
|
-
extraEnv: secretsForKit(deps.readSecrets?.(), (0,
|
|
66226
|
+
extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path70.join)(personaRoot, "extension-kit")),
|
|
65762
66227
|
...deps.logger ? { logger: deps.logger } : {}
|
|
65763
66228
|
});
|
|
65764
66229
|
project = created.project;
|
|
@@ -65957,7 +66422,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
65957
66422
|
await userStore.clearPublishJob(args.name);
|
|
65958
66423
|
}
|
|
65959
66424
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
65960
|
-
const scriptPath = (0,
|
|
66425
|
+
const scriptPath = (0, import_node_path70.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
65961
66426
|
deps.logger?.info("app-builder.publish.start", {
|
|
65962
66427
|
name: args.name,
|
|
65963
66428
|
sessionId: boundSession.sessionId,
|
|
@@ -65973,7 +66438,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
65973
66438
|
// 凭据只进 publish.sh 这个子进程的 env,且只给它的 kit 模板声明要的那几个变量
|
|
65974
66439
|
// (M1b Step 5)。那个进程里跑着 `eval "$BUILD_CMD"`——项目自带的构建命令会继承这份
|
|
65975
66440
|
// env,多给一个变量就是多交一个凭据给它。personaRoot 上面已按绑定 session 的 persona 解析。
|
|
65976
|
-
extraEnv: secretsForKit(deps.readSecrets?.(), (0,
|
|
66441
|
+
extraEnv: secretsForKit(deps.readSecrets?.(), (0, import_node_path70.join)(personaRoot, "extension-kit")),
|
|
65977
66442
|
hooks: {
|
|
65978
66443
|
// 元数据每次写盘(publishJob 起落 / prodUrl 回填)后重推一帧:UI 渲染 PublishProgress
|
|
65979
66444
|
// 三段 checklist 依赖 project.publishJob.status==='in-flight',而 publishJob 字段只有
|
|
@@ -66381,7 +66846,7 @@ function buildTopicHandlers(deps) {
|
|
|
66381
66846
|
init_protocol();
|
|
66382
66847
|
|
|
66383
66848
|
// src/channel/authority.ts
|
|
66384
|
-
var
|
|
66849
|
+
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
66385
66850
|
init_protocol();
|
|
66386
66851
|
var DEFAULT_AUTHORITY_RULES = [
|
|
66387
66852
|
{ id: "outbound-message", desc: "\u4EE5\u8001\u677F\u540D\u4E49\u7ED9\u5176\u4ED6\u4EBA\u53D1\u6D88\u606F\uFF08IM/\u90AE\u4EF6\uFF09", action: "ask" },
|
|
@@ -66399,7 +66864,7 @@ async function resolveAuthority(args) {
|
|
|
66399
66864
|
let source;
|
|
66400
66865
|
let raw = null;
|
|
66401
66866
|
try {
|
|
66402
|
-
raw = await
|
|
66867
|
+
raw = await import_promises18.default.readFile(args.tablePath, "utf8");
|
|
66403
66868
|
} catch (e) {
|
|
66404
66869
|
if (e.code !== "ENOENT") {
|
|
66405
66870
|
return askBecause(`\u6388\u6743\u8BBE\u5B9A\u8BFB\u4E0D\u51FA\u6765\uFF08${args.tablePath}\uFF09\uFF1A${e.message}`);
|
|
@@ -66579,11 +67044,11 @@ function parsePrDetailResponse(json, repoRef) {
|
|
|
66579
67044
|
// src/handlers/github.ts
|
|
66580
67045
|
var HOSTNAME = "github.com";
|
|
66581
67046
|
function buildGithubHandlers(deps) {
|
|
66582
|
-
const { gh } = deps;
|
|
67047
|
+
const { gh: gh2 } = deps;
|
|
66583
67048
|
return {
|
|
66584
67049
|
"github:status": async () => {
|
|
66585
67050
|
try {
|
|
66586
|
-
await
|
|
67051
|
+
await gh2.run(["--version"]);
|
|
66587
67052
|
} catch (err) {
|
|
66588
67053
|
if (err instanceof GhError && err.kind === "gh-missing") {
|
|
66589
67054
|
return { response: { installed: false, authenticated: false } };
|
|
@@ -66591,17 +67056,17 @@ function buildGithubHandlers(deps) {
|
|
|
66591
67056
|
throw err;
|
|
66592
67057
|
}
|
|
66593
67058
|
try {
|
|
66594
|
-
await
|
|
67059
|
+
await gh2.run(["auth", "status", "--active", "--hostname", HOSTNAME]);
|
|
66595
67060
|
} catch {
|
|
66596
67061
|
return { response: { installed: true, authenticated: false } };
|
|
66597
67062
|
}
|
|
66598
|
-
const login = (await
|
|
67063
|
+
const login = (await gh2.run(["api", "user", "--jq", ".login"])).trim();
|
|
66599
67064
|
const response = { installed: true, authenticated: true, login };
|
|
66600
67065
|
return { response };
|
|
66601
67066
|
},
|
|
66602
67067
|
"github:prList": async (frame) => {
|
|
66603
67068
|
const { role } = GithubPrListArgs.parse(frame);
|
|
66604
|
-
const stdout = await
|
|
67069
|
+
const stdout = await gh2.run([
|
|
66605
67070
|
"api",
|
|
66606
67071
|
"graphql",
|
|
66607
67072
|
"-f",
|
|
@@ -66617,7 +67082,7 @@ function buildGithubHandlers(deps) {
|
|
|
66617
67082
|
},
|
|
66618
67083
|
"github:prDetail": async (frame) => {
|
|
66619
67084
|
const { owner: owner2, repo: repo2, number: number2 } = GithubPrDetailArgs.parse(frame);
|
|
66620
|
-
const stdout = await
|
|
67085
|
+
const stdout = await gh2.run([
|
|
66621
67086
|
"api",
|
|
66622
67087
|
"graphql",
|
|
66623
67088
|
"-f",
|
|
@@ -66635,7 +67100,7 @@ function buildGithubHandlers(deps) {
|
|
|
66635
67100
|
"github:prMerge": async (frame) => {
|
|
66636
67101
|
const { owner: owner2, repo: repo2, number: number2, expectedHeadSha } = GithubPrMergeArgs.parse(frame);
|
|
66637
67102
|
try {
|
|
66638
|
-
await
|
|
67103
|
+
await gh2.run([
|
|
66639
67104
|
"pr",
|
|
66640
67105
|
"merge",
|
|
66641
67106
|
String(number2),
|
|
@@ -66655,19 +67120,19 @@ function buildGithubHandlers(deps) {
|
|
|
66655
67120
|
},
|
|
66656
67121
|
"github:prComment": async (frame) => {
|
|
66657
67122
|
const { owner: owner2, repo: repo2, number: number2, body } = GithubPrCommentArgs.parse(frame);
|
|
66658
|
-
await
|
|
67123
|
+
await gh2.run(["api", `repos/${owner2}/${repo2}/issues/${number2}/comments`, "-f", `body=${body}`]);
|
|
66659
67124
|
return { response: { posted: true } };
|
|
66660
67125
|
},
|
|
66661
67126
|
"github:prSetReady": async (frame) => {
|
|
66662
67127
|
const { owner: owner2, repo: repo2, number: number2, ready } = GithubPrSetReadyArgs.parse(frame);
|
|
66663
67128
|
const args = ["pr", "ready", String(number2), "--repo", `${owner2}/${repo2}`];
|
|
66664
67129
|
if (!ready) args.push("--undo");
|
|
66665
|
-
await
|
|
67130
|
+
await gh2.run(args);
|
|
66666
67131
|
return { response: { updated: true } };
|
|
66667
67132
|
},
|
|
66668
67133
|
"github:collaborators": async (frame) => {
|
|
66669
67134
|
const { owner: owner2, repo: repo2 } = GithubCollaboratorsArgs.parse(frame);
|
|
66670
|
-
const stdout = await
|
|
67135
|
+
const stdout = await gh2.run(["api", `repos/${owner2}/${repo2}/collaborators?per_page=100`]);
|
|
66671
67136
|
const arr = JSON.parse(stdout);
|
|
66672
67137
|
const logins = arr.map((c) => String(c.login ?? "")).filter((s) => s !== "");
|
|
66673
67138
|
return { response: { logins } };
|
|
@@ -66676,7 +67141,7 @@ function buildGithubHandlers(deps) {
|
|
|
66676
67141
|
const { owner: owner2, repo: repo2, number: number2, reviewers } = GithubPrRequestReviewersArgs.parse(frame);
|
|
66677
67142
|
const args = ["api", "-X", "POST", `repos/${owner2}/${repo2}/pulls/${number2}/requested_reviewers`];
|
|
66678
67143
|
for (const r of reviewers) args.push("-f", `reviewers[]=${r}`);
|
|
66679
|
-
await
|
|
67144
|
+
await gh2.run(args);
|
|
66680
67145
|
return { response: { requested: true } };
|
|
66681
67146
|
}
|
|
66682
67147
|
};
|
|
@@ -66708,12 +67173,12 @@ function buildVisitorHandlers(deps) {
|
|
|
66708
67173
|
}
|
|
66709
67174
|
|
|
66710
67175
|
// src/extension/registry.ts
|
|
66711
|
-
var
|
|
66712
|
-
var
|
|
67176
|
+
var import_promises19 = __toESM(require("fs/promises"), 1);
|
|
67177
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
66713
67178
|
async function loadAll(root) {
|
|
66714
67179
|
let entries;
|
|
66715
67180
|
try {
|
|
66716
|
-
entries = await
|
|
67181
|
+
entries = await import_promises19.default.readdir(root, { withFileTypes: true });
|
|
66717
67182
|
} catch (e) {
|
|
66718
67183
|
if (e.code === "ENOENT") return [];
|
|
66719
67184
|
throw e;
|
|
@@ -66722,16 +67187,16 @@ async function loadAll(root) {
|
|
|
66722
67187
|
for (const ent of entries) {
|
|
66723
67188
|
if (!ent.isDirectory()) continue;
|
|
66724
67189
|
if (ent.name.startsWith(".")) continue;
|
|
66725
|
-
records.push(await loadOne(
|
|
67190
|
+
records.push(await loadOne(import_node_path71.default.join(root, ent.name), ent.name));
|
|
66726
67191
|
}
|
|
66727
67192
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
66728
67193
|
return records;
|
|
66729
67194
|
}
|
|
66730
67195
|
async function loadOne(dir, dirName) {
|
|
66731
|
-
const manifestPath =
|
|
67196
|
+
const manifestPath = import_node_path71.default.join(dir, "manifest.json");
|
|
66732
67197
|
let raw;
|
|
66733
67198
|
try {
|
|
66734
|
-
raw = await
|
|
67199
|
+
raw = await import_promises19.default.readFile(manifestPath, "utf8");
|
|
66735
67200
|
} catch {
|
|
66736
67201
|
return {
|
|
66737
67202
|
extId: dirName,
|
|
@@ -66772,8 +67237,8 @@ async function loadOne(dir, dirName) {
|
|
|
66772
67237
|
}
|
|
66773
67238
|
|
|
66774
67239
|
// src/extension/uninstall.ts
|
|
66775
|
-
var
|
|
66776
|
-
var
|
|
67240
|
+
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
67241
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
66777
67242
|
var UninstallError = class extends Error {
|
|
66778
67243
|
constructor(code, message) {
|
|
66779
67244
|
super(message);
|
|
@@ -66782,32 +67247,32 @@ var UninstallError = class extends Error {
|
|
|
66782
67247
|
code;
|
|
66783
67248
|
};
|
|
66784
67249
|
async function uninstall(deps) {
|
|
66785
|
-
const dir =
|
|
67250
|
+
const dir = import_node_path72.default.join(deps.root, deps.extId);
|
|
66786
67251
|
try {
|
|
66787
|
-
await
|
|
67252
|
+
await import_promises20.default.access(dir);
|
|
66788
67253
|
} catch {
|
|
66789
67254
|
throw new UninstallError("NOT_FOUND", `extension ${deps.extId} not installed`);
|
|
66790
67255
|
}
|
|
66791
67256
|
await deps.runtime.close(deps.extId);
|
|
66792
|
-
await
|
|
67257
|
+
await import_promises20.default.rm(dir, { recursive: true, force: true });
|
|
66793
67258
|
}
|
|
66794
67259
|
|
|
66795
67260
|
// src/handlers/index.ts
|
|
66796
|
-
var
|
|
67261
|
+
var import_node_crypto21 = require("crypto");
|
|
66797
67262
|
|
|
66798
67263
|
// src/handlers/peer-exec.ts
|
|
66799
67264
|
init_protocol();
|
|
66800
67265
|
|
|
66801
67266
|
// src/peer-ops/run-command.ts
|
|
66802
|
-
var
|
|
66803
|
-
var
|
|
67267
|
+
var import_node_child_process18 = require("child_process");
|
|
67268
|
+
var import_node_os26 = __toESM(require("os"), 1);
|
|
66804
67269
|
var DEFAULT_TIMEOUT_MS5 = 3e4;
|
|
66805
67270
|
var MAX_TIMEOUT_MS = 3e5;
|
|
66806
67271
|
var MAX_OUTPUT_BYTES = 1048576;
|
|
66807
67272
|
function runCommand(command, opts = {}) {
|
|
66808
67273
|
const timeoutMs = Math.min(opts.timeoutMs ?? DEFAULT_TIMEOUT_MS5, MAX_TIMEOUT_MS);
|
|
66809
67274
|
return new Promise((resolve9) => {
|
|
66810
|
-
const child = (0,
|
|
67275
|
+
const child = (0, import_node_child_process18.spawn)("bash", ["-c", command], { cwd: import_node_os26.default.homedir() });
|
|
66811
67276
|
const out = [];
|
|
66812
67277
|
const err = [];
|
|
66813
67278
|
let outBytes = 0;
|
|
@@ -66949,7 +67414,7 @@ function buildMethodHandlers(deps) {
|
|
|
66949
67414
|
const c = deps.contactStore.get(deviceId);
|
|
66950
67415
|
return c ? { deviceId: c.deviceId, remoteUrl: c.remoteUrl, connectToken: c.connectToken } : null;
|
|
66951
67416
|
},
|
|
66952
|
-
genId: () => (0,
|
|
67417
|
+
genId: () => (0, import_node_crypto21.randomUUID)(),
|
|
66953
67418
|
now: () => Date.now(),
|
|
66954
67419
|
forwardInboxPostToPeer,
|
|
66955
67420
|
logger: deps.logger
|
|
@@ -67018,7 +67483,7 @@ function buildMethodHandlers(deps) {
|
|
|
67018
67483
|
broadcast: deps.broadcastToOwners
|
|
67019
67484
|
}),
|
|
67020
67485
|
...buildMasterHandlers({
|
|
67021
|
-
authorityTablePath:
|
|
67486
|
+
authorityTablePath: import_node_path73.default.join(deps.masterDataDir, "master-authority.json")
|
|
67022
67487
|
}),
|
|
67023
67488
|
...buildTopicHandlers({
|
|
67024
67489
|
topicStore: deps.topicStore,
|
|
@@ -67049,23 +67514,23 @@ function buildMethodHandlers(deps) {
|
|
|
67049
67514
|
init_protocol();
|
|
67050
67515
|
|
|
67051
67516
|
// src/tools/version-probe.ts
|
|
67052
|
-
var
|
|
67517
|
+
var import_node_child_process20 = require("child_process");
|
|
67053
67518
|
init_claude();
|
|
67054
67519
|
|
|
67055
67520
|
// src/tools/shell-path.ts
|
|
67056
|
-
var
|
|
67057
|
-
var
|
|
67521
|
+
var import_node_child_process19 = require("child_process");
|
|
67522
|
+
var import_node_os27 = __toESM(require("os"), 1);
|
|
67058
67523
|
function refreshPathFromLoginShell() {
|
|
67059
67524
|
if (process.platform === "win32") return;
|
|
67060
|
-
const shell = process.env.SHELL ??
|
|
67525
|
+
const shell = process.env.SHELL ?? import_node_os27.default.userInfo().shell ?? "/bin/zsh";
|
|
67061
67526
|
try {
|
|
67062
|
-
const out = (0,
|
|
67527
|
+
const out = (0, import_node_child_process19.execFileSync)(shell, ["-ilc", 'command echo -n "$PATH"'], {
|
|
67063
67528
|
encoding: "utf8",
|
|
67064
67529
|
timeout: 3e3,
|
|
67065
67530
|
stdio: ["ignore", "pipe", "ignore"]
|
|
67066
67531
|
});
|
|
67067
|
-
const
|
|
67068
|
-
if (
|
|
67532
|
+
const path99 = out.trim();
|
|
67533
|
+
if (path99) process.env.PATH = path99;
|
|
67069
67534
|
} catch {
|
|
67070
67535
|
}
|
|
67071
67536
|
}
|
|
@@ -67076,7 +67541,7 @@ function parseVersionOutput(out) {
|
|
|
67076
67541
|
}
|
|
67077
67542
|
function execVersion(bin) {
|
|
67078
67543
|
return new Promise((resolve9, reject) => {
|
|
67079
|
-
(0,
|
|
67544
|
+
(0, import_node_child_process20.execFile)(bin, ["--version"], { timeout: 5e3 }, (err, stdout) => {
|
|
67080
67545
|
if (err) reject(err);
|
|
67081
67546
|
else resolve9(String(stdout));
|
|
67082
67547
|
});
|
|
@@ -67190,8 +67655,8 @@ function buildOnboardingHandlers(deps) {
|
|
|
67190
67655
|
|
|
67191
67656
|
// src/app-builder-plugin/project-store.ts
|
|
67192
67657
|
var import_node_fs53 = require("fs");
|
|
67193
|
-
var
|
|
67194
|
-
var
|
|
67658
|
+
var import_node_child_process21 = require("child_process");
|
|
67659
|
+
var import_node_path74 = require("path");
|
|
67195
67660
|
init_protocol();
|
|
67196
67661
|
var PROJECTS_DIR = "projects";
|
|
67197
67662
|
var META_FILE = ".clawd-project.json";
|
|
@@ -67221,14 +67686,14 @@ var ProjectStore = class {
|
|
|
67221
67686
|
}
|
|
67222
67687
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
67223
67688
|
metaPath(name) {
|
|
67224
|
-
return (0,
|
|
67689
|
+
return (0, import_node_path74.join)(this.projectsRoot(), name, META_FILE);
|
|
67225
67690
|
}
|
|
67226
67691
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
67227
67692
|
projectDir(name) {
|
|
67228
|
-
return (0,
|
|
67693
|
+
return (0, import_node_path74.join)(this.projectsRoot(), name);
|
|
67229
67694
|
}
|
|
67230
67695
|
projectsRoot() {
|
|
67231
|
-
return (0,
|
|
67696
|
+
return (0, import_node_path74.join)(this.root, PROJECTS_DIR);
|
|
67232
67697
|
}
|
|
67233
67698
|
async list() {
|
|
67234
67699
|
let entries;
|
|
@@ -67311,7 +67776,7 @@ var ProjectStore = class {
|
|
|
67311
67776
|
async scaffold(name, templateSrcDir, scaffoldScriptPath, extraEnv) {
|
|
67312
67777
|
const destDir = this.projectDir(name);
|
|
67313
67778
|
return await new Promise((resolve9, reject) => {
|
|
67314
|
-
const child = (0,
|
|
67779
|
+
const child = (0, import_node_child_process21.spawn)("bash", [scaffoldScriptPath, name, templateSrcDir, destDir], {
|
|
67315
67780
|
// extraEnv 排在 PATH **之前**:凭据表里若混进一条名叫 PATH 的条目,顶掉 PATH 会让
|
|
67316
67781
|
// 脚本以「命令找不到」的形态崩在离现场很远的地方。
|
|
67317
67782
|
env: { ...process.env, ...extraEnv ?? {}, PATH: process.env.PATH ?? "" },
|
|
@@ -67425,7 +67890,7 @@ var ProjectStore = class {
|
|
|
67425
67890
|
};
|
|
67426
67891
|
|
|
67427
67892
|
// src/app-builder/dev-server-supervisor.ts
|
|
67428
|
-
var
|
|
67893
|
+
var import_node_child_process22 = require("child_process");
|
|
67429
67894
|
var import_node_events2 = require("events");
|
|
67430
67895
|
var DEFAULT_READY_PATTERN = /Local:\s+https?:\/\/|Nest application successfully started|server listening on/i;
|
|
67431
67896
|
var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
@@ -67462,7 +67927,7 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
67462
67927
|
tunnelHost: args.tunnelHost,
|
|
67463
67928
|
devCommand: cmd
|
|
67464
67929
|
});
|
|
67465
|
-
const child = (0,
|
|
67930
|
+
const child = (0, import_node_child_process22.spawn)("sh", ["-c", cmd], {
|
|
67466
67931
|
cwd: args.cwd,
|
|
67467
67932
|
env,
|
|
67468
67933
|
stdio: "pipe",
|
|
@@ -67679,10 +68144,10 @@ var DevServerSupervisor = class extends import_node_events2.EventEmitter {
|
|
|
67679
68144
|
};
|
|
67680
68145
|
|
|
67681
68146
|
// src/app-builder-plugin/core.ts
|
|
67682
|
-
var
|
|
68147
|
+
var import_node_child_process24 = require("child_process");
|
|
67683
68148
|
|
|
67684
68149
|
// src/app-builder-plugin/publish-registry.ts
|
|
67685
|
-
var
|
|
68150
|
+
var import_node_crypto22 = require("crypto");
|
|
67686
68151
|
var PublishJobRegistry = class {
|
|
67687
68152
|
jobs = /* @__PURE__ */ new Map();
|
|
67688
68153
|
has(name) {
|
|
@@ -67699,7 +68164,7 @@ var PublishJobRegistry = class {
|
|
|
67699
68164
|
if (this.jobs.has(args.name)) {
|
|
67700
68165
|
throw new Error(`already publishing: ${args.name}`);
|
|
67701
68166
|
}
|
|
67702
|
-
const jobId = args.jobId ?? `job-${(0,
|
|
68167
|
+
const jobId = args.jobId ?? `job-${(0, import_node_crypto22.randomUUID)()}`;
|
|
67703
68168
|
this.jobs.set(args.name, {
|
|
67704
68169
|
jobId,
|
|
67705
68170
|
name: args.name,
|
|
@@ -67732,9 +68197,9 @@ var PublishJobRegistry = class {
|
|
|
67732
68197
|
};
|
|
67733
68198
|
|
|
67734
68199
|
// src/app-builder-plugin/publish-job-runner.ts
|
|
67735
|
-
var
|
|
68200
|
+
var import_node_child_process23 = require("child_process");
|
|
67736
68201
|
var import_node_fs54 = require("fs");
|
|
67737
|
-
var
|
|
68202
|
+
var import_node_path75 = require("path");
|
|
67738
68203
|
|
|
67739
68204
|
// src/app-builder-plugin/publish-stage-parser.ts
|
|
67740
68205
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -67761,19 +68226,19 @@ function tailStderrLines(buf, n) {
|
|
|
67761
68226
|
// src/app-builder-plugin/publish-job-runner.ts
|
|
67762
68227
|
async function startPublishJob(deps, args) {
|
|
67763
68228
|
const { registry: registry2, projectDir } = deps;
|
|
67764
|
-
const
|
|
68229
|
+
const spawn15 = deps.spawnImpl ?? import_node_child_process23.spawn;
|
|
67765
68230
|
if (registry2.has(args.name)) {
|
|
67766
68231
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
67767
68232
|
}
|
|
67768
68233
|
const projDir = projectDir(args.name);
|
|
67769
|
-
const logPath = (0,
|
|
68234
|
+
const logPath = (0, import_node_path75.join)(projDir, ".publish.log");
|
|
67770
68235
|
let logStream = null;
|
|
67771
68236
|
try {
|
|
67772
68237
|
logStream = (0, import_node_fs54.createWriteStream)(logPath, { flags: "w" });
|
|
67773
68238
|
} catch {
|
|
67774
68239
|
logStream = null;
|
|
67775
68240
|
}
|
|
67776
|
-
const child =
|
|
68241
|
+
const child = spawn15("bash", [args.scriptPath, projDir, args.personaRoot ?? ""], {
|
|
67777
68242
|
cwd: projDir,
|
|
67778
68243
|
// 宿主给的 env 覆盖在 process.env 之上:daemon 进程本身没有这些变量(它们只在这一个
|
|
67779
68244
|
// 子进程里活着)。云上宿主不传 extraEnv,凭据本来就在容器 env 里。
|
|
@@ -68113,9 +68578,9 @@ async function recoverInterruptedPublishJobs(store, logger) {
|
|
|
68113
68578
|
|
|
68114
68579
|
// src/app-builder-plugin/mcp-config.ts
|
|
68115
68580
|
var import_node_fs55 = __toESM(require("fs"), 1);
|
|
68116
|
-
var
|
|
68581
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
68117
68582
|
function appBuilderMcpConfigPath(dataDir) {
|
|
68118
|
-
return
|
|
68583
|
+
return import_node_path76.default.join(dataDir, "app-builder.mcp.json");
|
|
68119
68584
|
}
|
|
68120
68585
|
function writeAppBuilderMcpConfig(args) {
|
|
68121
68586
|
const cfgPath = appBuilderMcpConfigPath(args.dataDir);
|
|
@@ -68129,8 +68594,8 @@ function writeAppBuilderMcpConfig(args) {
|
|
|
68129
68594
|
env: {
|
|
68130
68595
|
CLAWD_DAEMON_TOKEN: args.daemonToken,
|
|
68131
68596
|
CLAWD_DAEMON_URL: args.daemonUrl,
|
|
68132
|
-
CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT:
|
|
68133
|
-
CLAWD_APP_BUILDER_PUBLISH_SCRIPT:
|
|
68597
|
+
CLAWD_APP_BUILDER_SCAFFOLD_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "new-extension.sh"),
|
|
68598
|
+
CLAWD_APP_BUILDER_PUBLISH_SCRIPT: import_node_path76.default.join(args.deployKitScriptsDir, "publish.sh"),
|
|
68134
68599
|
...args.logPath ? { CLAWD_APP_BUILDER_LOG: args.logPath } : {}
|
|
68135
68600
|
}
|
|
68136
68601
|
}
|
|
@@ -68177,9 +68642,9 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
68177
68642
|
}
|
|
68178
68643
|
|
|
68179
68644
|
// src/extension/runtime.ts
|
|
68180
|
-
var
|
|
68181
|
-
var
|
|
68182
|
-
var
|
|
68645
|
+
var import_node_child_process25 = require("child_process");
|
|
68646
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
68647
|
+
var import_promises21 = require("timers/promises");
|
|
68183
68648
|
|
|
68184
68649
|
// src/extension/port-allocator.ts
|
|
68185
68650
|
var import_node_net2 = __toESM(require("net"), 1);
|
|
@@ -68279,13 +68744,13 @@ var Runtime = class {
|
|
|
68279
68744
|
/\$CLAWOS_EXT_PORT/g,
|
|
68280
68745
|
String(port)
|
|
68281
68746
|
);
|
|
68282
|
-
const dir =
|
|
68747
|
+
const dir = import_node_path77.default.join(this.root, extId);
|
|
68283
68748
|
const env = {
|
|
68284
68749
|
...process.env,
|
|
68285
68750
|
CLAWOS_EXT_PORT: String(port),
|
|
68286
68751
|
CLAWOS_EXT_ID: extId
|
|
68287
68752
|
};
|
|
68288
|
-
const child = (0,
|
|
68753
|
+
const child = (0, import_node_child_process25.spawn)("sh", ["-c", cmd], {
|
|
68289
68754
|
cwd: dir,
|
|
68290
68755
|
env,
|
|
68291
68756
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -68355,7 +68820,7 @@ ${handle.stderrTail}`
|
|
|
68355
68820
|
if (res.ok) return;
|
|
68356
68821
|
} catch {
|
|
68357
68822
|
}
|
|
68358
|
-
await (0,
|
|
68823
|
+
await (0, import_promises21.setTimeout)(this.healthzIntervalMs);
|
|
68359
68824
|
}
|
|
68360
68825
|
throw new RuntimeError(
|
|
68361
68826
|
"HEALTHZ_FAILED",
|
|
@@ -68380,7 +68845,7 @@ ${handle.stderrTail}`
|
|
|
68380
68845
|
};
|
|
68381
68846
|
killGroup("SIGTERM");
|
|
68382
68847
|
const exited = new Promise((resolve9) => child.once("exit", () => resolve9()));
|
|
68383
|
-
const timed = (0,
|
|
68848
|
+
const timed = (0, import_promises21.setTimeout)(5e3).then(() => "timeout");
|
|
68384
68849
|
const winner = await Promise.race([exited.then(() => "exited"), timed]);
|
|
68385
68850
|
if (winner === "timeout" && child.exitCode === null) {
|
|
68386
68851
|
killGroup("SIGKILL");
|
|
@@ -68390,8 +68855,8 @@ ${handle.stderrTail}`
|
|
|
68390
68855
|
};
|
|
68391
68856
|
|
|
68392
68857
|
// src/extension/published-channels.ts
|
|
68393
|
-
var
|
|
68394
|
-
var
|
|
68858
|
+
var import_promises22 = __toESM(require("fs/promises"), 1);
|
|
68859
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
68395
68860
|
init_zod();
|
|
68396
68861
|
var PublishedChannelsError = class extends Error {
|
|
68397
68862
|
constructor(code, message) {
|
|
@@ -68421,7 +68886,7 @@ var PublishedChannelStore = class {
|
|
|
68421
68886
|
this.channels.clear();
|
|
68422
68887
|
let raw;
|
|
68423
68888
|
try {
|
|
68424
|
-
raw = await
|
|
68889
|
+
raw = await import_promises22.default.readFile(this.filePath, "utf8");
|
|
68425
68890
|
} catch (e) {
|
|
68426
68891
|
if (e.code === "ENOENT") {
|
|
68427
68892
|
this.loaded = true;
|
|
@@ -68490,15 +68955,15 @@ var PublishedChannelStore = class {
|
|
|
68490
68955
|
)
|
|
68491
68956
|
};
|
|
68492
68957
|
const tmp = `${this.filePath}.tmp`;
|
|
68493
|
-
await
|
|
68494
|
-
await
|
|
68495
|
-
await
|
|
68958
|
+
await import_promises22.default.mkdir(import_node_path78.default.dirname(this.filePath), { recursive: true });
|
|
68959
|
+
await import_promises22.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
68960
|
+
await import_promises22.default.rename(tmp, this.filePath);
|
|
68496
68961
|
}
|
|
68497
68962
|
};
|
|
68498
68963
|
|
|
68499
68964
|
// src/extension/bundle-cache.ts
|
|
68500
|
-
var
|
|
68501
|
-
var
|
|
68965
|
+
var import_promises23 = __toESM(require("fs/promises"), 1);
|
|
68966
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
68502
68967
|
var BundleCache = class {
|
|
68503
68968
|
constructor(rootDir) {
|
|
68504
68969
|
this.rootDir = rootDir;
|
|
@@ -68506,17 +68971,17 @@ var BundleCache = class {
|
|
|
68506
68971
|
rootDir;
|
|
68507
68972
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
68508
68973
|
async write(snapshotHash, buffer) {
|
|
68509
|
-
await
|
|
68510
|
-
const file =
|
|
68974
|
+
await import_promises23.default.mkdir(this.rootDir, { recursive: true });
|
|
68975
|
+
const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
68511
68976
|
const tmp = `${file}.tmp`;
|
|
68512
|
-
await
|
|
68513
|
-
await
|
|
68977
|
+
await import_promises23.default.writeFile(tmp, buffer, { mode: 384 });
|
|
68978
|
+
await import_promises23.default.rename(tmp, file);
|
|
68514
68979
|
}
|
|
68515
68980
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
68516
68981
|
async read(snapshotHash) {
|
|
68517
|
-
const file =
|
|
68982
|
+
const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
68518
68983
|
try {
|
|
68519
|
-
return await
|
|
68984
|
+
return await import_promises23.default.readFile(file);
|
|
68520
68985
|
} catch (e) {
|
|
68521
68986
|
if (e.code === "ENOENT") return null;
|
|
68522
68987
|
throw e;
|
|
@@ -68524,8 +68989,8 @@ var BundleCache = class {
|
|
|
68524
68989
|
}
|
|
68525
68990
|
/** Idempotent — missing file is not an error. */
|
|
68526
68991
|
async delete(snapshotHash) {
|
|
68527
|
-
const file =
|
|
68528
|
-
await
|
|
68992
|
+
const file = import_node_path79.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
68993
|
+
await import_promises23.default.rm(file, { force: true });
|
|
68529
68994
|
}
|
|
68530
68995
|
};
|
|
68531
68996
|
|
|
@@ -68545,26 +69010,26 @@ async function startDaemon(config) {
|
|
|
68545
69010
|
},
|
|
68546
69011
|
source: "daemon",
|
|
68547
69012
|
sampling: logShippingCfg.sampling,
|
|
68548
|
-
homeDir:
|
|
69013
|
+
homeDir: import_node_os28.default.homedir()
|
|
68549
69014
|
});
|
|
68550
|
-
const logDir =
|
|
69015
|
+
const logDir = import_node_path80.default.join(config.dataDir, "log");
|
|
68551
69016
|
import_node_fs56.default.mkdirSync(logDir, { recursive: true });
|
|
68552
69017
|
const logger = createLogger({
|
|
68553
69018
|
level: config.logLevel,
|
|
68554
|
-
file:
|
|
69019
|
+
file: import_node_path80.default.join(logDir, "clawd.log"),
|
|
68555
69020
|
logClient
|
|
68556
69021
|
});
|
|
68557
69022
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
68558
69023
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
68559
|
-
file:
|
|
69024
|
+
file: import_node_path80.default.join(logDir, "screen-idle-probe.log"),
|
|
68560
69025
|
level: "debug"
|
|
68561
69026
|
});
|
|
68562
69027
|
logger.info("screen-idle probe logger enabled", {
|
|
68563
|
-
file:
|
|
69028
|
+
file: import_node_path80.default.join(logDir, "screen-idle-probe.log")
|
|
68564
69029
|
});
|
|
68565
69030
|
const CAP_TARGETS = [
|
|
68566
|
-
|
|
68567
|
-
|
|
69031
|
+
import_node_path80.default.join(logDir, "clawd.log"),
|
|
69032
|
+
import_node_path80.default.join(logDir, "screen-idle-probe.log")
|
|
68568
69033
|
];
|
|
68569
69034
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
68570
69035
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -68686,8 +69151,8 @@ async function startDaemon(config) {
|
|
|
68686
69151
|
const agents = new AgentsScanner();
|
|
68687
69152
|
const history = new ClaudeHistoryReader();
|
|
68688
69153
|
let transport = null;
|
|
68689
|
-
const personaStore = new PersonaStore(
|
|
68690
|
-
const usersRoot =
|
|
69154
|
+
const personaStore = new PersonaStore(import_node_path80.default.join(config.dataDir, "personas"));
|
|
69155
|
+
const usersRoot = import_node_path80.default.join(config.dataDir, "users");
|
|
68691
69156
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
68692
69157
|
if (defaultsRoot) {
|
|
68693
69158
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -68711,7 +69176,7 @@ async function startDaemon(config) {
|
|
|
68711
69176
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
68712
69177
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
68713
69178
|
const dispatchStore = createDispatchStore({
|
|
68714
|
-
filePath:
|
|
69179
|
+
filePath: import_node_path80.default.join(config.dataDir, "dispatch.json"),
|
|
68715
69180
|
now: () => Date.now(),
|
|
68716
69181
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
68717
69182
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -68720,18 +69185,18 @@ async function startDaemon(config) {
|
|
|
68720
69185
|
await dispatchStore.load();
|
|
68721
69186
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
68722
69187
|
const channelStore = createChannelStore({
|
|
68723
|
-
filePath:
|
|
69188
|
+
filePath: import_node_path80.default.join(config.dataDir, "channels.json"),
|
|
68724
69189
|
now: () => Date.now(),
|
|
68725
|
-
genId: () => `ch-${(0,
|
|
69190
|
+
genId: () => `ch-${(0, import_node_crypto23.randomUUID)().slice(0, 8)}`,
|
|
68726
69191
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
68727
69192
|
reason: err instanceof Error ? err.message : String(err)
|
|
68728
69193
|
})
|
|
68729
69194
|
});
|
|
68730
69195
|
await channelStore.load();
|
|
68731
69196
|
const topicStore = createTopicStore({
|
|
68732
|
-
filePath:
|
|
69197
|
+
filePath: import_node_path80.default.join(config.dataDir, "topics.json"),
|
|
68733
69198
|
now: () => Date.now(),
|
|
68734
|
-
genId: () => `tp-${(0,
|
|
69199
|
+
genId: () => `tp-${(0, import_node_crypto23.randomUUID)().slice(0, 8)}`,
|
|
68735
69200
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
68736
69201
|
reason: err instanceof Error ? err.message : String(err)
|
|
68737
69202
|
})
|
|
@@ -68739,7 +69204,7 @@ async function startDaemon(config) {
|
|
|
68739
69204
|
await topicStore.load();
|
|
68740
69205
|
let deliverPendingRef;
|
|
68741
69206
|
const personaDispatchManager = new PersonaDispatchManager({
|
|
68742
|
-
genId: () => (0,
|
|
69207
|
+
genId: () => (0, import_node_crypto23.randomUUID)(),
|
|
68743
69208
|
store: dispatchStore,
|
|
68744
69209
|
now: () => Date.now(),
|
|
68745
69210
|
onCompleted: (sid) => deliverPendingRef?.(sid),
|
|
@@ -68756,28 +69221,28 @@ async function startDaemon(config) {
|
|
|
68756
69221
|
});
|
|
68757
69222
|
}
|
|
68758
69223
|
});
|
|
68759
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
69224
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path80.default.dirname((0, import_node_url5.fileURLToPath)(import_meta8.url));
|
|
68760
69225
|
const mcpConfigs = [];
|
|
68761
69226
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
68762
|
-
const localSecretsDir =
|
|
69227
|
+
const localSecretsDir = import_node_path80.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
68763
69228
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
68764
69229
|
const resolvePersonaMcpConfig = (personaId2) => renderPersonaMcpSecrets({
|
|
68765
69230
|
personaId: personaId2,
|
|
68766
|
-
personaDir:
|
|
69231
|
+
personaDir: import_node_path80.default.join(config.dataDir, "personas", personaId2),
|
|
68767
69232
|
secrets: readSecrets(),
|
|
68768
|
-
outDir:
|
|
69233
|
+
outDir: import_node_path80.default.join(config.dataDir, "persona-mcp"),
|
|
68769
69234
|
logger
|
|
68770
69235
|
});
|
|
68771
69236
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
68772
69237
|
const dispatchServerCandidates = [
|
|
68773
|
-
|
|
69238
|
+
import_node_path80.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
68774
69239
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
68775
|
-
|
|
69240
|
+
import_node_path80.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
68776
69241
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
68777
69242
|
];
|
|
68778
69243
|
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68779
69244
|
if (dispatchServerScriptPath) {
|
|
68780
|
-
const dispatchLogPath =
|
|
69245
|
+
const dispatchLogPath = import_node_path80.default.join(logDir, "dispatch-mcp-server.log");
|
|
68781
69246
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
68782
69247
|
dataDir: config.dataDir,
|
|
68783
69248
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -68797,12 +69262,12 @@ async function startDaemon(config) {
|
|
|
68797
69262
|
});
|
|
68798
69263
|
}
|
|
68799
69264
|
const ticketServerCandidates = [
|
|
68800
|
-
|
|
68801
|
-
|
|
69265
|
+
import_node_path80.default.join(here, "ticket", "mcp-server.cjs"),
|
|
69266
|
+
import_node_path80.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
68802
69267
|
];
|
|
68803
69268
|
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68804
69269
|
if (ticketServerScriptPath) {
|
|
68805
|
-
const ticketLogPath =
|
|
69270
|
+
const ticketLogPath = import_node_path80.default.join(logDir, "ticket-mcp-server.log");
|
|
68806
69271
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
68807
69272
|
dataDir: config.dataDir,
|
|
68808
69273
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -68824,12 +69289,12 @@ async function startDaemon(config) {
|
|
|
68824
69289
|
});
|
|
68825
69290
|
}
|
|
68826
69291
|
const shiftServerCandidates = [
|
|
68827
|
-
|
|
68828
|
-
|
|
69292
|
+
import_node_path80.default.join(here, "shift", "mcp-server.cjs"),
|
|
69293
|
+
import_node_path80.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
68829
69294
|
];
|
|
68830
69295
|
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68831
69296
|
if (shiftServerScriptPath) {
|
|
68832
|
-
const shiftLogPath =
|
|
69297
|
+
const shiftLogPath = import_node_path80.default.join(logDir, "shift-mcp-server.log");
|
|
68833
69298
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
68834
69299
|
dataDir: config.dataDir,
|
|
68835
69300
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -68850,12 +69315,12 @@ async function startDaemon(config) {
|
|
|
68850
69315
|
);
|
|
68851
69316
|
}
|
|
68852
69317
|
const inboxServerCandidates = [
|
|
68853
|
-
|
|
68854
|
-
|
|
69318
|
+
import_node_path80.default.join(here, "inbox", "mcp-server.cjs"),
|
|
69319
|
+
import_node_path80.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
68855
69320
|
];
|
|
68856
69321
|
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68857
69322
|
if (inboxServerScriptPath) {
|
|
68858
|
-
const inboxLogPath =
|
|
69323
|
+
const inboxLogPath = import_node_path80.default.join(logDir, "inbox-mcp-server.log");
|
|
68859
69324
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
68860
69325
|
dataDir: config.dataDir,
|
|
68861
69326
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -68876,8 +69341,8 @@ async function startDaemon(config) {
|
|
|
68876
69341
|
);
|
|
68877
69342
|
}
|
|
68878
69343
|
const peerOpsServerCandidates = [
|
|
68879
|
-
|
|
68880
|
-
|
|
69344
|
+
import_node_path80.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
69345
|
+
import_node_path80.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
68881
69346
|
];
|
|
68882
69347
|
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68883
69348
|
if (peerOpsServerScriptPath) {
|
|
@@ -68899,12 +69364,12 @@ async function startDaemon(config) {
|
|
|
68899
69364
|
);
|
|
68900
69365
|
}
|
|
68901
69366
|
const rpcToolServerCandidates = [
|
|
68902
|
-
|
|
68903
|
-
|
|
69367
|
+
import_node_path80.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
69368
|
+
import_node_path80.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
68904
69369
|
];
|
|
68905
69370
|
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68906
69371
|
if (rpcToolServerScriptPath) {
|
|
68907
|
-
const rpcToolLogPath =
|
|
69372
|
+
const rpcToolLogPath = import_node_path80.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
68908
69373
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
68909
69374
|
dataDir: config.dataDir,
|
|
68910
69375
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -68925,18 +69390,18 @@ async function startDaemon(config) {
|
|
|
68925
69390
|
);
|
|
68926
69391
|
}
|
|
68927
69392
|
const appBuilderServerCandidates = [
|
|
68928
|
-
|
|
68929
|
-
|
|
69393
|
+
import_node_path80.default.join(here, "app-builder-plugin", "mcp-server.cjs"),
|
|
69394
|
+
import_node_path80.default.join(here, "..", "dist", "app-builder-plugin", "mcp-server.cjs")
|
|
68930
69395
|
];
|
|
68931
69396
|
const appBuilderServerScriptPath = appBuilderServerCandidates.find((p2) => import_node_fs56.default.existsSync(p2));
|
|
68932
69397
|
if (appBuilderServerScriptPath) {
|
|
68933
|
-
const appBuilderLogPath =
|
|
69398
|
+
const appBuilderLogPath = import_node_path80.default.join(logDir, "app-builder-mcp-server.log");
|
|
68934
69399
|
const appBuilderCfgPath = writeAppBuilderMcpConfig({
|
|
68935
69400
|
dataDir: config.dataDir,
|
|
68936
69401
|
serverScriptPath: appBuilderServerScriptPath,
|
|
68937
69402
|
daemonToken: resolvedAuthToken,
|
|
68938
69403
|
daemonUrl: mcpDaemonUrl,
|
|
68939
|
-
deployKitScriptsDir:
|
|
69404
|
+
deployKitScriptsDir: import_node_path80.default.join(config.dataDir, "deploy-kit", "scripts"),
|
|
68940
69405
|
logPath: appBuilderLogPath
|
|
68941
69406
|
});
|
|
68942
69407
|
mcpConfigs.push({ id: "app-builder", path: appBuilderCfgPath, personas: APP_BUILDER_PERSONAS });
|
|
@@ -68952,7 +69417,7 @@ async function startDaemon(config) {
|
|
|
68952
69417
|
);
|
|
68953
69418
|
}
|
|
68954
69419
|
const shiftStore = createShiftStore({
|
|
68955
|
-
filePath:
|
|
69420
|
+
filePath: import_node_path80.default.join(config.dataDir, "shift.json"),
|
|
68956
69421
|
ownerIdProvider: () => ownerPrincipalId,
|
|
68957
69422
|
now: () => Date.now()
|
|
68958
69423
|
});
|
|
@@ -68974,7 +69439,7 @@ async function startDaemon(config) {
|
|
|
68974
69439
|
getAdapter,
|
|
68975
69440
|
historyReader: history,
|
|
68976
69441
|
dataDir: config.dataDir,
|
|
68977
|
-
personaRoot:
|
|
69442
|
+
personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
|
|
68978
69443
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
68979
69444
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
68980
69445
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -69031,7 +69496,7 @@ async function startDaemon(config) {
|
|
|
69031
69496
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
69032
69497
|
attachmentGroup: {
|
|
69033
69498
|
onFileEdit: (input) => {
|
|
69034
|
-
const absPath =
|
|
69499
|
+
const absPath = import_node_path80.default.isAbsolute(input.relPath) ? input.relPath : import_node_path80.default.join(input.cwd, input.relPath);
|
|
69035
69500
|
let size = 0;
|
|
69036
69501
|
try {
|
|
69037
69502
|
size = import_node_fs56.default.statSync(absPath).size;
|
|
@@ -69064,9 +69529,9 @@ async function startDaemon(config) {
|
|
|
69064
69529
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
69065
69530
|
}
|
|
69066
69531
|
const projectsStore = new ProjectsStore({
|
|
69067
|
-
file:
|
|
69532
|
+
file: import_node_path80.default.join(config.dataDir, "projects.json"),
|
|
69068
69533
|
clawdDir: config.dataDir,
|
|
69069
|
-
codexStateFile:
|
|
69534
|
+
codexStateFile: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
69070
69535
|
logger
|
|
69071
69536
|
});
|
|
69072
69537
|
const observer = new SessionObserver({
|
|
@@ -69126,12 +69591,12 @@ async function startDaemon(config) {
|
|
|
69126
69591
|
screenIdleProbeLogger
|
|
69127
69592
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
69128
69593
|
registerAdapter("claude", claudeAdapter);
|
|
69129
|
-
const codexIsolatedHome =
|
|
69594
|
+
const codexIsolatedHome = import_node_path80.default.join(config.dataDir, "codex-home");
|
|
69130
69595
|
try {
|
|
69131
69596
|
import_node_fs56.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
69132
69597
|
for (const f of ["auth.json", "config.toml"]) {
|
|
69133
|
-
const link =
|
|
69134
|
-
const target =
|
|
69598
|
+
const link = import_node_path80.default.join(codexIsolatedHome, f);
|
|
69599
|
+
const target = import_node_path80.default.join(import_node_os28.default.homedir(), ".codex", f);
|
|
69135
69600
|
if (!import_node_fs56.default.existsSync(link) && import_node_fs56.default.existsSync(target)) import_node_fs56.default.symlinkSync(target, link);
|
|
69136
69601
|
}
|
|
69137
69602
|
} catch (err) {
|
|
@@ -69145,11 +69610,11 @@ async function startDaemon(config) {
|
|
|
69145
69610
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
69146
69611
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
69147
69612
|
cwd,
|
|
69148
|
-
personaRoot:
|
|
69613
|
+
personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
|
|
69149
69614
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
69150
69615
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
69151
69616
|
projectPaths: projectsStore.listMerged().map((x) => x.path),
|
|
69152
|
-
sharedHome:
|
|
69617
|
+
sharedHome: import_node_path80.default.join(import_node_os28.default.homedir(), ".codex"),
|
|
69153
69618
|
isolatedHome: codexIsolatedHome
|
|
69154
69619
|
})
|
|
69155
69620
|
})
|
|
@@ -69434,11 +69899,11 @@ async function startDaemon(config) {
|
|
|
69434
69899
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
69435
69900
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
69436
69901
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
69437
|
-
personaRoot:
|
|
69902
|
+
personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
|
|
69438
69903
|
usersRoot
|
|
69439
69904
|
},
|
|
69440
69905
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
69441
|
-
personaRoot:
|
|
69906
|
+
personaRoot: import_node_path80.default.join(config.dataDir, "personas"),
|
|
69442
69907
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
69443
69908
|
usersRoot,
|
|
69444
69909
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -69539,11 +70004,11 @@ async function startDaemon(config) {
|
|
|
69539
70004
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
69540
70005
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
69541
70006
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
69542
|
-
appBuilderPersonaRoot:
|
|
70007
|
+
appBuilderPersonaRoot: import_node_path80.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
69543
70008
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
69544
|
-
deployKitRoot:
|
|
70009
|
+
deployKitRoot: import_node_path80.default.join(config.dataDir, "deploy-kit"),
|
|
69545
70010
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
69546
|
-
resolvePersonaRoot: (personaId2) =>
|
|
70011
|
+
resolvePersonaRoot: (personaId2) => import_node_path80.default.join(config.dataDir, "personas", personaId2),
|
|
69547
70012
|
// 凭据表(M1b Step 5):与 MCP 那条同一张表、同一个来源,只是交付给另一个子进程。
|
|
69548
70013
|
readSecrets,
|
|
69549
70014
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
@@ -69600,7 +70065,7 @@ async function startDaemon(config) {
|
|
|
69600
70065
|
sourceSessionId: args.sourceSessionId
|
|
69601
70066
|
});
|
|
69602
70067
|
const sourceFile = manager.findOwnedSession(args.sourceSessionId);
|
|
69603
|
-
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile,
|
|
70068
|
+
const sourceJsonlPath = resolveSourceJsonlPath(sourceFile, import_node_os28.default.homedir());
|
|
69604
70069
|
logger.info("dispatch.spawnB.source-resolved", {
|
|
69605
70070
|
dispatchId: args.dispatchId,
|
|
69606
70071
|
sourceJsonlPath,
|
|
@@ -69658,12 +70123,12 @@ async function startDaemon(config) {
|
|
|
69658
70123
|
});
|
|
69659
70124
|
Object.assign(handlers, shiftHandlers);
|
|
69660
70125
|
const deployReceipts = createReceiptStore({
|
|
69661
|
-
filePath:
|
|
70126
|
+
filePath: import_node_path80.default.join(config.dataDir, "deploy.json"),
|
|
69662
70127
|
now: () => Date.now(),
|
|
69663
70128
|
onFlushError: (err) => logger.error("deploy receipts flush failed", { error: String(err) })
|
|
69664
70129
|
});
|
|
69665
70130
|
const deploySecrets = createSecretStore({
|
|
69666
|
-
filePath:
|
|
70131
|
+
filePath: import_node_path80.default.join(config.dataDir, "deploy-secrets.json"),
|
|
69667
70132
|
now: () => Date.now(),
|
|
69668
70133
|
onFlushError: (err) => logger.error("deploy secrets flush failed", { error: String(err) })
|
|
69669
70134
|
});
|
|
@@ -69694,6 +70159,7 @@ async function startDaemon(config) {
|
|
|
69694
70159
|
runNode: (script, args, opts) => runNodeScript(script, args, opts.timeoutMs),
|
|
69695
70160
|
fetchImpl: fetch,
|
|
69696
70161
|
now: () => Date.now(),
|
|
70162
|
+
sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
|
|
69697
70163
|
onStage: (stage) => {
|
|
69698
70164
|
deployReceipts.update(deployId, { trialStage: stage });
|
|
69699
70165
|
},
|
|
@@ -69706,6 +70172,8 @@ async function startDaemon(config) {
|
|
|
69706
70172
|
receipt,
|
|
69707
70173
|
// 试装带全量(含使用者自带那几条的临时垫付值)——它要真跑一次发布
|
|
69708
70174
|
secretTable: secretTableFor(receipt, deploySecrets.resolve(deployId), "all"),
|
|
70175
|
+
// persona 目录由 daemon 给:构建器不认识任何 persona 的名字(见 RunTrialArgs.personaDir)
|
|
70176
|
+
personaDir: personaStore.personaDirPath(receipt.personaId),
|
|
69709
70177
|
round: receipt.trialRound
|
|
69710
70178
|
}
|
|
69711
70179
|
);
|
|
@@ -69736,7 +70204,7 @@ async function startDaemon(config) {
|
|
|
69736
70204
|
hasPersona: (personaId2) => personaStore.has(personaId2),
|
|
69737
70205
|
startScan: (deployId, personaId2) => {
|
|
69738
70206
|
const assetLines = SCANNABLE_ASSETS.map(
|
|
69739
|
-
(name) => ` - ${name}\uFF1A${
|
|
70207
|
+
(name) => ` - ${name}\uFF1A${import_node_path80.default.join(config.dataDir, name)}`
|
|
69740
70208
|
).join("\n");
|
|
69741
70209
|
const prompt = [
|
|
69742
70210
|
`\u626B\u63CF persona\u300C${personaId2}\u300D\u7684\u90E8\u7F72\u73AF\u5883\uFF0CdeployId=${deployId}\u3002`,
|
|
@@ -69788,7 +70256,7 @@ async function startDaemon(config) {
|
|
|
69788
70256
|
const cloudHost = await loadCloudHostConfig(config.dataDir);
|
|
69789
70257
|
await gatewayAdmin({ cloudHost, fetchImpl: fetch }, "/admin/deployments:remove", { deployId });
|
|
69790
70258
|
},
|
|
69791
|
-
genId: () => `dp-${(0,
|
|
70259
|
+
genId: () => `dp-${(0, import_node_crypto23.randomUUID)().slice(0, 8)}`,
|
|
69792
70260
|
now: () => Date.now()
|
|
69793
70261
|
});
|
|
69794
70262
|
Object.assign(handlers, deployHandlers);
|
|
@@ -69801,7 +70269,7 @@ async function startDaemon(config) {
|
|
|
69801
70269
|
});
|
|
69802
70270
|
shiftScheduler.start();
|
|
69803
70271
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
69804
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
70272
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path80.default.join(config.dataDir, "personas"));
|
|
69805
70273
|
const larkBotCloud = createLarkBotCloudClient({
|
|
69806
70274
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
69807
70275
|
apiKey: resolveClawdTicketsApiKey(),
|
|
@@ -69815,7 +70283,7 @@ async function startDaemon(config) {
|
|
|
69815
70283
|
store: larkBotStore,
|
|
69816
70284
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
69817
70285
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
69818
|
-
mediaRootFor: (chatId) =>
|
|
70286
|
+
mediaRootFor: (chatId) => import_node_path80.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
69819
70287
|
isShuttingDown: () => larkDraining,
|
|
69820
70288
|
logger: {
|
|
69821
70289
|
warn: (msg) => logger.warn(msg),
|
|
@@ -70120,8 +70588,8 @@ async function startDaemon(config) {
|
|
|
70120
70588
|
const lines = [
|
|
70121
70589
|
`Tunnel: ${r.url}`,
|
|
70122
70590
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
70123
|
-
`Frpc config: ${
|
|
70124
|
-
`Frpc log: ${
|
|
70591
|
+
`Frpc config: ${import_node_path80.default.join(config.dataDir, "frpc.toml")}`,
|
|
70592
|
+
`Frpc log: ${import_node_path80.default.join(logDir, "frpc.log")}`
|
|
70125
70593
|
];
|
|
70126
70594
|
const width2 = Math.max(...lines.map((l) => l.length));
|
|
70127
70595
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -70134,7 +70602,7 @@ ${bar}
|
|
|
70134
70602
|
|
|
70135
70603
|
`);
|
|
70136
70604
|
try {
|
|
70137
|
-
const connectPath =
|
|
70605
|
+
const connectPath = import_node_path80.default.join(config.dataDir, "connect.txt");
|
|
70138
70606
|
import_node_fs56.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
70139
70607
|
} catch {
|
|
70140
70608
|
}
|
|
@@ -70224,7 +70692,7 @@ ${bar}
|
|
|
70224
70692
|
};
|
|
70225
70693
|
}
|
|
70226
70694
|
function migrateDropPersonsDir(dataDir) {
|
|
70227
|
-
const dir =
|
|
70695
|
+
const dir = import_node_path80.default.join(dataDir, "persons");
|
|
70228
70696
|
try {
|
|
70229
70697
|
import_node_fs56.default.rmSync(dir, { recursive: true, force: true });
|
|
70230
70698
|
} catch {
|