@clawos-dev/clawd 0.2.614 → 0.2.615
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 +659 -1468
- package/package.json +1 -1
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: path106, errorMaps, issueData } = params;
|
|
454
|
+
const fullPath = [...path106, ...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, path106, key) {
|
|
766
766
|
this._cachedPath = [];
|
|
767
767
|
this.parent = parent;
|
|
768
768
|
this.data = value;
|
|
769
|
-
this._path =
|
|
769
|
+
this._path = path106;
|
|
770
770
|
this._key = key;
|
|
771
771
|
}
|
|
772
772
|
get path() {
|
|
@@ -10356,8 +10356,8 @@ var require_req = __commonJS({
|
|
|
10356
10356
|
if (req.originalUrl) {
|
|
10357
10357
|
_req.url = req.originalUrl;
|
|
10358
10358
|
} else {
|
|
10359
|
-
const
|
|
10360
|
-
_req.url = typeof
|
|
10359
|
+
const path106 = req.path;
|
|
10360
|
+
_req.url = typeof path106 === "string" ? path106 : req.url ? req.url.path || req.url : void 0;
|
|
10361
10361
|
}
|
|
10362
10362
|
if (req.query) {
|
|
10363
10363
|
_req.query = req.query;
|
|
@@ -10522,14 +10522,14 @@ var require_redact = __commonJS({
|
|
|
10522
10522
|
}
|
|
10523
10523
|
return obj;
|
|
10524
10524
|
}
|
|
10525
|
-
function parsePath(
|
|
10525
|
+
function parsePath(path106) {
|
|
10526
10526
|
const parts = [];
|
|
10527
10527
|
let current = "";
|
|
10528
10528
|
let inBrackets = false;
|
|
10529
10529
|
let inQuotes = false;
|
|
10530
10530
|
let quoteChar = "";
|
|
10531
|
-
for (let i2 = 0; i2 <
|
|
10532
|
-
const char =
|
|
10531
|
+
for (let i2 = 0; i2 < path106.length; i2++) {
|
|
10532
|
+
const char = path106[i2];
|
|
10533
10533
|
if (!inBrackets && char === ".") {
|
|
10534
10534
|
if (current) {
|
|
10535
10535
|
parts.push(current);
|
|
@@ -10660,10 +10660,10 @@ var require_redact = __commonJS({
|
|
|
10660
10660
|
return current;
|
|
10661
10661
|
}
|
|
10662
10662
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
10663
|
-
for (const
|
|
10664
|
-
const parts = parsePath(
|
|
10663
|
+
for (const path106 of paths) {
|
|
10664
|
+
const parts = parsePath(path106);
|
|
10665
10665
|
if (parts.includes("*")) {
|
|
10666
|
-
redactWildcardPath(obj, parts, censor,
|
|
10666
|
+
redactWildcardPath(obj, parts, censor, path106, remove);
|
|
10667
10667
|
} else {
|
|
10668
10668
|
if (remove) {
|
|
10669
10669
|
removeKey(obj, parts);
|
|
@@ -10748,8 +10748,8 @@ var require_redact = __commonJS({
|
|
|
10748
10748
|
}
|
|
10749
10749
|
} else {
|
|
10750
10750
|
if (afterWildcard.includes("*")) {
|
|
10751
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
10752
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
10751
|
+
const wrappedCensor = typeof censor === "function" ? (value, path106) => {
|
|
10752
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path106];
|
|
10753
10753
|
return censor(value, fullPath);
|
|
10754
10754
|
} : censor;
|
|
10755
10755
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -10784,8 +10784,8 @@ var require_redact = __commonJS({
|
|
|
10784
10784
|
return null;
|
|
10785
10785
|
}
|
|
10786
10786
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
10787
|
-
for (const
|
|
10788
|
-
const parts = parsePath(
|
|
10787
|
+
for (const path106 of pathsToClone) {
|
|
10788
|
+
const parts = parsePath(path106);
|
|
10789
10789
|
let current = pathStructure;
|
|
10790
10790
|
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
10791
10791
|
const part = parts[i2];
|
|
@@ -10837,24 +10837,24 @@ var require_redact = __commonJS({
|
|
|
10837
10837
|
}
|
|
10838
10838
|
return cloneSelectively(obj, pathStructure);
|
|
10839
10839
|
}
|
|
10840
|
-
function validatePath(
|
|
10841
|
-
if (typeof
|
|
10840
|
+
function validatePath(path106) {
|
|
10841
|
+
if (typeof path106 !== "string") {
|
|
10842
10842
|
throw new Error("Paths must be (non-empty) strings");
|
|
10843
10843
|
}
|
|
10844
|
-
if (
|
|
10844
|
+
if (path106 === "") {
|
|
10845
10845
|
throw new Error("Invalid redaction path ()");
|
|
10846
10846
|
}
|
|
10847
|
-
if (
|
|
10848
|
-
throw new Error(`Invalid redaction path (${
|
|
10847
|
+
if (path106.includes("..")) {
|
|
10848
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10849
10849
|
}
|
|
10850
|
-
if (
|
|
10851
|
-
throw new Error(`Invalid redaction path (${
|
|
10850
|
+
if (path106.includes(",")) {
|
|
10851
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10852
10852
|
}
|
|
10853
10853
|
let bracketCount = 0;
|
|
10854
10854
|
let inQuotes = false;
|
|
10855
10855
|
let quoteChar = "";
|
|
10856
|
-
for (let i2 = 0; i2 <
|
|
10857
|
-
const char =
|
|
10856
|
+
for (let i2 = 0; i2 < path106.length; i2++) {
|
|
10857
|
+
const char = path106[i2];
|
|
10858
10858
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
10859
10859
|
if (!inQuotes) {
|
|
10860
10860
|
inQuotes = true;
|
|
@@ -10868,20 +10868,20 @@ var require_redact = __commonJS({
|
|
|
10868
10868
|
} else if (char === "]" && !inQuotes) {
|
|
10869
10869
|
bracketCount--;
|
|
10870
10870
|
if (bracketCount < 0) {
|
|
10871
|
-
throw new Error(`Invalid redaction path (${
|
|
10871
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10872
10872
|
}
|
|
10873
10873
|
}
|
|
10874
10874
|
}
|
|
10875
10875
|
if (bracketCount !== 0) {
|
|
10876
|
-
throw new Error(`Invalid redaction path (${
|
|
10876
|
+
throw new Error(`Invalid redaction path (${path106})`);
|
|
10877
10877
|
}
|
|
10878
10878
|
}
|
|
10879
10879
|
function validatePaths(paths) {
|
|
10880
10880
|
if (!Array.isArray(paths)) {
|
|
10881
10881
|
throw new TypeError("paths must be an array");
|
|
10882
10882
|
}
|
|
10883
|
-
for (const
|
|
10884
|
-
validatePath(
|
|
10883
|
+
for (const path106 of paths) {
|
|
10884
|
+
validatePath(path106);
|
|
10885
10885
|
}
|
|
10886
10886
|
}
|
|
10887
10887
|
function slowRedact(options = {}) {
|
|
@@ -11049,8 +11049,8 @@ var require_redaction = __commonJS({
|
|
|
11049
11049
|
if (shape[k3] === null) {
|
|
11050
11050
|
o2[k3] = (value) => topCensor(value, [k3]);
|
|
11051
11051
|
} else {
|
|
11052
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
11053
|
-
return censor(value, [k3, ...
|
|
11052
|
+
const wrappedCensor = typeof censor === "function" ? (value, path106) => {
|
|
11053
|
+
return censor(value, [k3, ...path106]);
|
|
11054
11054
|
} : censor;
|
|
11055
11055
|
o2[k3] = Redact({
|
|
11056
11056
|
paths: shape[k3],
|
|
@@ -11268,10 +11268,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
11268
11268
|
var require_sonic_boom = __commonJS({
|
|
11269
11269
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
11270
11270
|
"use strict";
|
|
11271
|
-
var
|
|
11271
|
+
var fs95 = require("fs");
|
|
11272
11272
|
var EventEmitter2 = require("events");
|
|
11273
11273
|
var inherits = require("util").inherits;
|
|
11274
|
-
var
|
|
11274
|
+
var path106 = require("path");
|
|
11275
11275
|
var sleep2 = require_atomic_sleep();
|
|
11276
11276
|
var assert = require("assert");
|
|
11277
11277
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -11325,20 +11325,20 @@ var require_sonic_boom = __commonJS({
|
|
|
11325
11325
|
const mode = sonic.mode;
|
|
11326
11326
|
if (sonic.sync) {
|
|
11327
11327
|
try {
|
|
11328
|
-
if (sonic.mkdir)
|
|
11329
|
-
const fd =
|
|
11328
|
+
if (sonic.mkdir) fs95.mkdirSync(path106.dirname(file), { recursive: true });
|
|
11329
|
+
const fd = fs95.openSync(file, flags, mode);
|
|
11330
11330
|
fileOpened(null, fd);
|
|
11331
11331
|
} catch (err) {
|
|
11332
11332
|
fileOpened(err);
|
|
11333
11333
|
throw err;
|
|
11334
11334
|
}
|
|
11335
11335
|
} else if (sonic.mkdir) {
|
|
11336
|
-
|
|
11336
|
+
fs95.mkdir(path106.dirname(file), { recursive: true }, (err) => {
|
|
11337
11337
|
if (err) return fileOpened(err);
|
|
11338
|
-
|
|
11338
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11339
11339
|
});
|
|
11340
11340
|
} else {
|
|
11341
|
-
|
|
11341
|
+
fs95.open(file, flags, mode, fileOpened);
|
|
11342
11342
|
}
|
|
11343
11343
|
}
|
|
11344
11344
|
function SonicBoom(opts) {
|
|
@@ -11379,8 +11379,8 @@ var require_sonic_boom = __commonJS({
|
|
|
11379
11379
|
this.flush = flushBuffer;
|
|
11380
11380
|
this.flushSync = flushBufferSync;
|
|
11381
11381
|
this._actualWrite = actualWriteBuffer;
|
|
11382
|
-
fsWriteSync = () =>
|
|
11383
|
-
fsWrite = () =>
|
|
11382
|
+
fsWriteSync = () => fs95.writeSync(this.fd, this._writingBuf);
|
|
11383
|
+
fsWrite = () => fs95.write(this.fd, this._writingBuf, this.release);
|
|
11384
11384
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
11385
11385
|
this._writingBuf = "";
|
|
11386
11386
|
this.write = write;
|
|
@@ -11389,15 +11389,15 @@ var require_sonic_boom = __commonJS({
|
|
|
11389
11389
|
this._actualWrite = actualWrite;
|
|
11390
11390
|
fsWriteSync = () => {
|
|
11391
11391
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11392
|
-
return
|
|
11392
|
+
return fs95.writeSync(this.fd, this._writingBuf);
|
|
11393
11393
|
}
|
|
11394
|
-
return
|
|
11394
|
+
return fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11395
11395
|
};
|
|
11396
11396
|
fsWrite = () => {
|
|
11397
11397
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
11398
|
-
return
|
|
11398
|
+
return fs95.write(this.fd, this._writingBuf, this.release);
|
|
11399
11399
|
}
|
|
11400
|
-
return
|
|
11400
|
+
return fs95.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
11401
11401
|
};
|
|
11402
11402
|
} else {
|
|
11403
11403
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -11454,7 +11454,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11454
11454
|
}
|
|
11455
11455
|
}
|
|
11456
11456
|
if (this._fsync) {
|
|
11457
|
-
|
|
11457
|
+
fs95.fsyncSync(this.fd);
|
|
11458
11458
|
}
|
|
11459
11459
|
const len = this._len;
|
|
11460
11460
|
if (this._reopening) {
|
|
@@ -11568,7 +11568,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11568
11568
|
const onDrain = () => {
|
|
11569
11569
|
if (!this._fsync) {
|
|
11570
11570
|
try {
|
|
11571
|
-
|
|
11571
|
+
fs95.fsync(this.fd, (err) => {
|
|
11572
11572
|
this._flushPending = false;
|
|
11573
11573
|
cb(err);
|
|
11574
11574
|
});
|
|
@@ -11670,7 +11670,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11670
11670
|
const fd = this.fd;
|
|
11671
11671
|
this.once("ready", () => {
|
|
11672
11672
|
if (fd !== this.fd) {
|
|
11673
|
-
|
|
11673
|
+
fs95.close(fd, (err) => {
|
|
11674
11674
|
if (err) {
|
|
11675
11675
|
return this.emit("error", err);
|
|
11676
11676
|
}
|
|
@@ -11719,7 +11719,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11719
11719
|
buf = this._bufs[0];
|
|
11720
11720
|
}
|
|
11721
11721
|
try {
|
|
11722
|
-
const n2 = Buffer.isBuffer(buf) ?
|
|
11722
|
+
const n2 = Buffer.isBuffer(buf) ? fs95.writeSync(this.fd, buf) : fs95.writeSync(this.fd, buf, "utf8");
|
|
11723
11723
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n2);
|
|
11724
11724
|
buf = releasedBufObj.writingBuf;
|
|
11725
11725
|
this._len = releasedBufObj.len;
|
|
@@ -11735,7 +11735,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11735
11735
|
}
|
|
11736
11736
|
}
|
|
11737
11737
|
try {
|
|
11738
|
-
|
|
11738
|
+
fs95.fsyncSync(this.fd);
|
|
11739
11739
|
} catch {
|
|
11740
11740
|
}
|
|
11741
11741
|
}
|
|
@@ -11756,7 +11756,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11756
11756
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
11757
11757
|
}
|
|
11758
11758
|
try {
|
|
11759
|
-
const n2 =
|
|
11759
|
+
const n2 = fs95.writeSync(this.fd, buf);
|
|
11760
11760
|
buf = buf.subarray(n2);
|
|
11761
11761
|
this._len = Math.max(this._len - n2, 0);
|
|
11762
11762
|
if (buf.length <= 0) {
|
|
@@ -11784,13 +11784,13 @@ var require_sonic_boom = __commonJS({
|
|
|
11784
11784
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
11785
11785
|
if (this.sync) {
|
|
11786
11786
|
try {
|
|
11787
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
11787
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs95.writeSync(this.fd, this._writingBuf) : fs95.writeSync(this.fd, this._writingBuf, "utf8");
|
|
11788
11788
|
release2(null, written);
|
|
11789
11789
|
} catch (err) {
|
|
11790
11790
|
release2(err);
|
|
11791
11791
|
}
|
|
11792
11792
|
} else {
|
|
11793
|
-
|
|
11793
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11794
11794
|
}
|
|
11795
11795
|
}
|
|
11796
11796
|
function actualWriteBuffer() {
|
|
@@ -11799,7 +11799,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11799
11799
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
11800
11800
|
if (this.sync) {
|
|
11801
11801
|
try {
|
|
11802
|
-
const written =
|
|
11802
|
+
const written = fs95.writeSync(this.fd, this._writingBuf);
|
|
11803
11803
|
release2(null, written);
|
|
11804
11804
|
} catch (err) {
|
|
11805
11805
|
release2(err);
|
|
@@ -11808,7 +11808,7 @@ var require_sonic_boom = __commonJS({
|
|
|
11808
11808
|
if (kCopyBuffer) {
|
|
11809
11809
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
11810
11810
|
}
|
|
11811
|
-
|
|
11811
|
+
fs95.write(this.fd, this._writingBuf, release2);
|
|
11812
11812
|
}
|
|
11813
11813
|
}
|
|
11814
11814
|
function actualClose(sonic) {
|
|
@@ -11824,12 +11824,12 @@ var require_sonic_boom = __commonJS({
|
|
|
11824
11824
|
sonic._lens = [];
|
|
11825
11825
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
11826
11826
|
try {
|
|
11827
|
-
|
|
11827
|
+
fs95.fsync(sonic.fd, closeWrapped);
|
|
11828
11828
|
} catch {
|
|
11829
11829
|
}
|
|
11830
11830
|
function closeWrapped() {
|
|
11831
11831
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
11832
|
-
|
|
11832
|
+
fs95.close(sonic.fd, done);
|
|
11833
11833
|
} else {
|
|
11834
11834
|
done();
|
|
11835
11835
|
}
|
|
@@ -14964,11 +14964,11 @@ var init_lib = __esm({
|
|
|
14964
14964
|
}
|
|
14965
14965
|
}
|
|
14966
14966
|
},
|
|
14967
|
-
addToPath: function addToPath(
|
|
14968
|
-
var last =
|
|
14967
|
+
addToPath: function addToPath(path106, added, removed, oldPosInc, options) {
|
|
14968
|
+
var last = path106.lastComponent;
|
|
14969
14969
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
14970
14970
|
return {
|
|
14971
|
-
oldPos:
|
|
14971
|
+
oldPos: path106.oldPos + oldPosInc,
|
|
14972
14972
|
lastComponent: {
|
|
14973
14973
|
count: last.count + 1,
|
|
14974
14974
|
added,
|
|
@@ -14978,7 +14978,7 @@ var init_lib = __esm({
|
|
|
14978
14978
|
};
|
|
14979
14979
|
} else {
|
|
14980
14980
|
return {
|
|
14981
|
-
oldPos:
|
|
14981
|
+
oldPos: path106.oldPos + oldPosInc,
|
|
14982
14982
|
lastComponent: {
|
|
14983
14983
|
count: 1,
|
|
14984
14984
|
added,
|
|
@@ -15560,10 +15560,10 @@ function attachmentToHistoryMessage(o2, ts) {
|
|
|
15560
15560
|
const memories = raw.map((m3) => {
|
|
15561
15561
|
if (!m3 || typeof m3 !== "object") return null;
|
|
15562
15562
|
const rec6 = m3;
|
|
15563
|
-
const
|
|
15563
|
+
const path106 = typeof rec6.path === "string" ? rec6.path : null;
|
|
15564
15564
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
15565
|
-
if (!
|
|
15566
|
-
const entry = { path:
|
|
15565
|
+
if (!path106 || content == null) return null;
|
|
15566
|
+
const entry = { path: path106, content };
|
|
15567
15567
|
if (typeof rec6.mtimeMs === "number") entry.mtimeMs = rec6.mtimeMs;
|
|
15568
15568
|
return entry;
|
|
15569
15569
|
}).filter((m3) => m3 !== null);
|
|
@@ -16429,10 +16429,10 @@ function parseAttachment(obj) {
|
|
|
16429
16429
|
const memories = raw.map((m3) => {
|
|
16430
16430
|
if (!m3 || typeof m3 !== "object") return null;
|
|
16431
16431
|
const rec6 = m3;
|
|
16432
|
-
const
|
|
16432
|
+
const path106 = typeof rec6.path === "string" ? rec6.path : null;
|
|
16433
16433
|
const content = typeof rec6.content === "string" ? rec6.content : null;
|
|
16434
|
-
if (!
|
|
16435
|
-
const out = { path:
|
|
16434
|
+
if (!path106 || content == null) return null;
|
|
16435
|
+
const out = { path: path106, content };
|
|
16436
16436
|
if (typeof rec6.mtimeMs === "number") out.mtimeMs = rec6.mtimeMs;
|
|
16437
16437
|
return out;
|
|
16438
16438
|
}).filter((m3) => m3 !== null);
|
|
@@ -37406,8 +37406,8 @@ var require_utils = __commonJS({
|
|
|
37406
37406
|
var result = transform[inputType][outputType](input);
|
|
37407
37407
|
return result;
|
|
37408
37408
|
};
|
|
37409
|
-
exports2.resolve = function(
|
|
37410
|
-
var parts =
|
|
37409
|
+
exports2.resolve = function(path106) {
|
|
37410
|
+
var parts = path106.split("/");
|
|
37411
37411
|
var result = [];
|
|
37412
37412
|
for (var index = 0; index < parts.length; index++) {
|
|
37413
37413
|
var part = parts[index];
|
|
@@ -43260,18 +43260,18 @@ var require_object = __commonJS({
|
|
|
43260
43260
|
var object = new ZipObject(name, zipObjectContent, o2);
|
|
43261
43261
|
this.files[name] = object;
|
|
43262
43262
|
};
|
|
43263
|
-
var parentFolder = function(
|
|
43264
|
-
if (
|
|
43265
|
-
|
|
43263
|
+
var parentFolder = function(path106) {
|
|
43264
|
+
if (path106.slice(-1) === "/") {
|
|
43265
|
+
path106 = path106.substring(0, path106.length - 1);
|
|
43266
43266
|
}
|
|
43267
|
-
var lastSlash =
|
|
43268
|
-
return lastSlash > 0 ?
|
|
43267
|
+
var lastSlash = path106.lastIndexOf("/");
|
|
43268
|
+
return lastSlash > 0 ? path106.substring(0, lastSlash) : "";
|
|
43269
43269
|
};
|
|
43270
|
-
var forceTrailingSlash = function(
|
|
43271
|
-
if (
|
|
43272
|
-
|
|
43270
|
+
var forceTrailingSlash = function(path106) {
|
|
43271
|
+
if (path106.slice(-1) !== "/") {
|
|
43272
|
+
path106 += "/";
|
|
43273
43273
|
}
|
|
43274
|
-
return
|
|
43274
|
+
return path106;
|
|
43275
43275
|
};
|
|
43276
43276
|
var folderAdd = function(name, createFolders) {
|
|
43277
43277
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -44273,7 +44273,7 @@ var require_lib3 = __commonJS({
|
|
|
44273
44273
|
// src/run-case/recorder.ts
|
|
44274
44274
|
function startRunCaseRecorder(opts) {
|
|
44275
44275
|
const now = opts.now ?? Date.now;
|
|
44276
|
-
const dir =
|
|
44276
|
+
const dir = import_node_path85.default.dirname(opts.recordPath);
|
|
44277
44277
|
let stream = null;
|
|
44278
44278
|
let closing = false;
|
|
44279
44279
|
let closedSettled = false;
|
|
@@ -44287,8 +44287,8 @@ function startRunCaseRecorder(opts) {
|
|
|
44287
44287
|
});
|
|
44288
44288
|
const ensureStream = () => {
|
|
44289
44289
|
if (stream) return stream;
|
|
44290
|
-
|
|
44291
|
-
stream =
|
|
44290
|
+
import_node_fs66.default.mkdirSync(dir, { recursive: true });
|
|
44291
|
+
stream = import_node_fs66.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
44292
44292
|
stream.on("close", () => closedResolve());
|
|
44293
44293
|
return stream;
|
|
44294
44294
|
};
|
|
@@ -44313,12 +44313,12 @@ function startRunCaseRecorder(opts) {
|
|
|
44313
44313
|
};
|
|
44314
44314
|
return { tap, close, closed };
|
|
44315
44315
|
}
|
|
44316
|
-
var
|
|
44316
|
+
var import_node_fs66, import_node_path85;
|
|
44317
44317
|
var init_recorder = __esm({
|
|
44318
44318
|
"src/run-case/recorder.ts"() {
|
|
44319
44319
|
"use strict";
|
|
44320
|
-
|
|
44321
|
-
|
|
44320
|
+
import_node_fs66 = __toESM(require("fs"), 1);
|
|
44321
|
+
import_node_path85 = __toESM(require("path"), 1);
|
|
44322
44322
|
}
|
|
44323
44323
|
});
|
|
44324
44324
|
|
|
@@ -44361,7 +44361,7 @@ var init_wire = __esm({
|
|
|
44361
44361
|
// src/run-case/controller.ts
|
|
44362
44362
|
async function runController(opts) {
|
|
44363
44363
|
const now = opts.now ?? Date.now;
|
|
44364
|
-
const cwd = opts.cwd ?? (0,
|
|
44364
|
+
const cwd = opts.cwd ?? (0, import_node_fs67.mkdtempSync)(import_node_path86.default.join(import_node_os32.default.tmpdir(), "clawd-runcase-"));
|
|
44365
44365
|
const ownsCwd = opts.cwd === void 0;
|
|
44366
44366
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
44367
44367
|
const spawnCtx = { cwd };
|
|
@@ -44522,19 +44522,19 @@ async function runController(opts) {
|
|
|
44522
44522
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
44523
44523
|
if (ownsCwd) {
|
|
44524
44524
|
try {
|
|
44525
|
-
(0,
|
|
44525
|
+
(0, import_node_fs67.rmSync)(cwd, { recursive: true, force: true });
|
|
44526
44526
|
} catch {
|
|
44527
44527
|
}
|
|
44528
44528
|
}
|
|
44529
44529
|
return exitCode ?? 0;
|
|
44530
44530
|
}
|
|
44531
|
-
var
|
|
44531
|
+
var import_node_fs67, import_node_os32, import_node_path86;
|
|
44532
44532
|
var init_controller = __esm({
|
|
44533
44533
|
"src/run-case/controller.ts"() {
|
|
44534
44534
|
"use strict";
|
|
44535
|
-
|
|
44535
|
+
import_node_fs67 = require("fs");
|
|
44536
44536
|
import_node_os32 = __toESM(require("os"), 1);
|
|
44537
|
-
|
|
44537
|
+
import_node_path86 = __toESM(require("path"), 1);
|
|
44538
44538
|
init_claude();
|
|
44539
44539
|
init_stdout_splitter();
|
|
44540
44540
|
init_permission_stdio();
|
|
@@ -44806,10 +44806,10 @@ Env (advanced):
|
|
|
44806
44806
|
`;
|
|
44807
44807
|
|
|
44808
44808
|
// src/index.ts
|
|
44809
|
-
var
|
|
44810
|
-
var
|
|
44809
|
+
var import_node_path84 = __toESM(require("path"), 1);
|
|
44810
|
+
var import_node_fs65 = __toESM(require("fs"), 1);
|
|
44811
44811
|
var import_node_os31 = __toESM(require("os"), 1);
|
|
44812
|
-
var
|
|
44812
|
+
var import_node_crypto27 = require("crypto");
|
|
44813
44813
|
var import_node_url6 = require("url");
|
|
44814
44814
|
|
|
44815
44815
|
// src/logger.ts
|
|
@@ -46672,7 +46672,6 @@ function applyCommand(state, command, deps) {
|
|
|
46672
46672
|
void _titleGeneratedAt;
|
|
46673
46673
|
const nextFile = {
|
|
46674
46674
|
...rest,
|
|
46675
|
-
...command.nextCloudExecutionId ? { cloudExecutionId: command.nextCloudExecutionId } : {},
|
|
46676
46675
|
...command.nextToolSessionId ? { toolSessionId: command.nextToolSessionId } : {},
|
|
46677
46676
|
updatedAt: nowIso(deps)
|
|
46678
46677
|
};
|
|
@@ -46735,18 +46734,6 @@ function reduceSessionInner(state, input, deps) {
|
|
|
46735
46734
|
case "inject-events": {
|
|
46736
46735
|
return applyEventBatch(state, input.events, deps);
|
|
46737
46736
|
}
|
|
46738
|
-
case "cloud-recovery-absent": {
|
|
46739
|
-
if (!state.file.cloudPendingCommand) return { state, effects: [] };
|
|
46740
|
-
const next = cloneState(state);
|
|
46741
|
-
next.file = { ...next.file, cloudPendingCommand: void 0, cloudGatewaySessionId: void 0 };
|
|
46742
|
-
return { state: next, effects: [{ kind: "persist-file", file: next.file }, sessionInfoFrame(next.file)] };
|
|
46743
|
-
}
|
|
46744
|
-
case "cloud-gateway-ready": {
|
|
46745
|
-
if (state.file.cloudGatewaySessionId === input.gatewaySessionId) return { state, effects: [] };
|
|
46746
|
-
const next = cloneState(state);
|
|
46747
|
-
next.file = { ...next.file, cloudGatewaySessionId: input.gatewaySessionId };
|
|
46748
|
-
return { state: next, effects: [{ kind: "persist-file", file: next.file }] };
|
|
46749
|
-
}
|
|
46750
46737
|
case "cloud-command-prepared": {
|
|
46751
46738
|
const pending = state.file.cloudPendingCommand;
|
|
46752
46739
|
const turn = state.file.cloudPendingTurns?.find((item) => item.id === input.commandId);
|
|
@@ -47452,7 +47439,7 @@ var SessionRunner = class {
|
|
|
47452
47439
|
applyEffect(effect) {
|
|
47453
47440
|
switch (effect.kind) {
|
|
47454
47441
|
case "spawn":
|
|
47455
|
-
this.doSpawn(
|
|
47442
|
+
this.doSpawn(effect.ctx);
|
|
47456
47443
|
break;
|
|
47457
47444
|
case "kill":
|
|
47458
47445
|
if (this.session) {
|
|
@@ -47601,15 +47588,6 @@ var SessionRunner = class {
|
|
|
47601
47588
|
kind: CLOUD_HISTORY_REFRESH_KIND,
|
|
47602
47589
|
synchronized
|
|
47603
47590
|
}, "broadcast"),
|
|
47604
|
-
onRecoveryAbsent: () => {
|
|
47605
|
-
this.input({ kind: "cloud-recovery-absent" });
|
|
47606
|
-
this.hooks.broadcastFrame({ type: "session:control", sessionId: this.state.file.sessionId, kind: CLOUD_HISTORY_REFRESH_KIND, synchronized: true }, "broadcast");
|
|
47607
|
-
},
|
|
47608
|
-
onGatewayReady: (gatewaySessionId) => {
|
|
47609
|
-
if (this.state.file.cloudGatewaySessionId === gatewaySessionId) return;
|
|
47610
|
-
this.hooks.store.write({ ...this.state.file, cloudGatewaySessionId: gatewaySessionId });
|
|
47611
|
-
this.input({ kind: "cloud-gateway-ready", gatewaySessionId });
|
|
47612
|
-
},
|
|
47613
47591
|
onCommandPrepared: (commandId, text, prepared) => {
|
|
47614
47592
|
const pending = this.state.file.cloudPendingTurns?.find((turn) => turn.id === commandId) ?? this.state.file.cloudPendingCommand;
|
|
47615
47593
|
if (!pending || pending.id !== commandId || prepared && pending.text !== text) return false;
|
|
@@ -49012,7 +48990,7 @@ var SessionManager = class {
|
|
|
49012
48990
|
}
|
|
49013
48991
|
return { response: normalized, broadcast };
|
|
49014
48992
|
}
|
|
49015
|
-
newSession(args
|
|
48993
|
+
newSession(args) {
|
|
49016
48994
|
const existingFile = this.getFile(args.sessionId);
|
|
49017
48995
|
this.titleGenPending.get(args.sessionId)?.abort();
|
|
49018
48996
|
this.titleGenPending.delete(args.sessionId);
|
|
@@ -49023,7 +49001,7 @@ var SessionManager = class {
|
|
|
49023
49001
|
const { value, broadcast } = this.withCollector(() => {
|
|
49024
49002
|
runner.input({
|
|
49025
49003
|
kind: "command",
|
|
49026
|
-
command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {}
|
|
49004
|
+
command: { kind: "new", ...nextToolSessionId ? { nextToolSessionId } : {} }
|
|
49027
49005
|
});
|
|
49028
49006
|
return runner.getState().file;
|
|
49029
49007
|
});
|
|
@@ -49059,7 +49037,6 @@ var SessionManager = class {
|
|
|
49059
49037
|
void _titleGeneratedAt;
|
|
49060
49038
|
const updated = {
|
|
49061
49039
|
...rest,
|
|
49062
|
-
...nextCloudExecutionId ? { cloudExecutionId: nextCloudExecutionId } : {},
|
|
49063
49040
|
...nextToolSessionId ? { toolSessionId: nextToolSessionId } : {},
|
|
49064
49041
|
updatedAt: nowIso2(this.deps)
|
|
49065
49042
|
};
|
|
@@ -49073,7 +49050,7 @@ var SessionManager = class {
|
|
|
49073
49050
|
if (!this.cloudCancel) throw new Error("cloud canceller is not configured");
|
|
49074
49051
|
await this.cloudCancel(file, runner);
|
|
49075
49052
|
} else runner?.confirmCloudCancelled();
|
|
49076
|
-
return this.newSession(args
|
|
49053
|
+
return this.newSession(args);
|
|
49077
49054
|
}
|
|
49078
49055
|
return this.newSession(args);
|
|
49079
49056
|
}
|
|
@@ -52928,9 +52905,9 @@ var CentralClientError = class extends Error {
|
|
|
52928
52905
|
cause;
|
|
52929
52906
|
status;
|
|
52930
52907
|
};
|
|
52931
|
-
async function centralRequest(opts,
|
|
52908
|
+
async function centralRequest(opts, path106, init) {
|
|
52932
52909
|
const f2 = opts.fetchImpl ?? globalThis.fetch;
|
|
52933
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
52910
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path106}`;
|
|
52934
52911
|
const ctrl = new AbortController();
|
|
52935
52912
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
52936
52913
|
let res;
|
|
@@ -53966,8 +53943,8 @@ function turnStartInput(text, resolveImage) {
|
|
|
53966
53943
|
const items = [];
|
|
53967
53944
|
let leftover = text;
|
|
53968
53945
|
for (const m3 of text.matchAll(SKILL_RE)) {
|
|
53969
|
-
const [marker, name,
|
|
53970
|
-
items.push({ type: "skill", name, path:
|
|
53946
|
+
const [marker, name, path106] = m3;
|
|
53947
|
+
items.push({ type: "skill", name, path: path106 });
|
|
53971
53948
|
leftover = leftover.replace(marker, "");
|
|
53972
53949
|
}
|
|
53973
53950
|
for (const m3 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -61342,10 +61319,10 @@ function createGithubApi(args) {
|
|
|
61342
61319
|
const doFetch = args.fetch ?? fetch;
|
|
61343
61320
|
const seal = args.seal ?? sealWithSodium;
|
|
61344
61321
|
const timeoutMs = args.timeoutMs ?? TIMEOUT_MS;
|
|
61345
|
-
async function request(method,
|
|
61322
|
+
async function request(method, path106, body) {
|
|
61346
61323
|
let res;
|
|
61347
61324
|
try {
|
|
61348
|
-
res = await doFetch(`${API}${
|
|
61325
|
+
res = await doFetch(`${API}${path106}`, {
|
|
61349
61326
|
method,
|
|
61350
61327
|
headers: {
|
|
61351
61328
|
Authorization: `Bearer ${args.token}`,
|
|
@@ -61370,8 +61347,8 @@ function createGithubApi(args) {
|
|
|
61370
61347
|
}
|
|
61371
61348
|
return { status: res.status, json };
|
|
61372
61349
|
}
|
|
61373
|
-
async function must(method,
|
|
61374
|
-
const r2 = await request(method,
|
|
61350
|
+
async function must(method, path106, what, body) {
|
|
61351
|
+
const r2 = await request(method, path106, body);
|
|
61375
61352
|
if (r2.status < 200 || r2.status >= 300) throw new GithubApiError(r2.status, explain(r2.status, what, r2.json));
|
|
61376
61353
|
return r2.json;
|
|
61377
61354
|
}
|
|
@@ -61416,9 +61393,9 @@ function createGithubApi(args) {
|
|
|
61416
61393
|
return { env: x2.name, ...Number.isFinite(at3) ? { setAt: at3 } : {} };
|
|
61417
61394
|
});
|
|
61418
61395
|
},
|
|
61419
|
-
async getJson(
|
|
61396
|
+
async getJson(path106) {
|
|
61420
61397
|
try {
|
|
61421
|
-
const r2 = await request("GET",
|
|
61398
|
+
const r2 = await request("GET", path106);
|
|
61422
61399
|
return r2.status >= 200 && r2.status < 300 ? r2.json : void 0;
|
|
61423
61400
|
} catch {
|
|
61424
61401
|
return void 0;
|
|
@@ -62970,8 +62947,8 @@ function refreshPathFromLoginShell() {
|
|
|
62970
62947
|
timeout: 3e3,
|
|
62971
62948
|
stdio: ["ignore", "pipe", "ignore"]
|
|
62972
62949
|
});
|
|
62973
|
-
const
|
|
62974
|
-
if (
|
|
62950
|
+
const path106 = out.trim();
|
|
62951
|
+
if (path106) process.env.PATH = path106;
|
|
62975
62952
|
} catch {
|
|
62976
62953
|
}
|
|
62977
62954
|
}
|
|
@@ -63773,10 +63750,10 @@ function createCloudPersonaBotClient(opts) {
|
|
|
63773
63750
|
const f2 = opts.fetchImpl ?? fetch;
|
|
63774
63751
|
const base = opts.api.replace(/\/+$/, "");
|
|
63775
63752
|
const route = (personaId2) => `/api/lark-bot/cloud/${encodeURIComponent(personaId2)}`;
|
|
63776
|
-
async function request(method,
|
|
63753
|
+
async function request(method, path106, body) {
|
|
63777
63754
|
const pass = opts.getLoginPass();
|
|
63778
63755
|
if (!pass) throw new LarkBotCloudError("\u98DE\u4E66\u767B\u5F55\u540E\u624D\u80FD\u7BA1\u7406\u4E91 Persona \u7684 Bot", 401);
|
|
63779
|
-
const response = await f2(base +
|
|
63756
|
+
const response = await f2(base + path106, {
|
|
63780
63757
|
method,
|
|
63781
63758
|
headers: { authorization: `Bearer ${pass}`, "content-type": "application/json" },
|
|
63782
63759
|
...body ? { body: JSON.stringify(body) } : {},
|
|
@@ -63785,7 +63762,7 @@ function createCloudPersonaBotClient(opts) {
|
|
|
63785
63762
|
const json = await response.json().catch(() => ({}));
|
|
63786
63763
|
if (!response.ok) {
|
|
63787
63764
|
const detail = typeof json.message === "string" ? json.message : `HTTP ${response.status}`;
|
|
63788
|
-
throw new LarkBotCloudError(`cloud bot ${method} ${
|
|
63765
|
+
throw new LarkBotCloudError(`cloud bot ${method} ${path106}: ${detail}`, response.status);
|
|
63789
63766
|
}
|
|
63790
63767
|
return json;
|
|
63791
63768
|
}
|
|
@@ -64771,16 +64748,8 @@ async function forwardPeerExecToPeer(args) {
|
|
|
64771
64748
|
init_protocol();
|
|
64772
64749
|
init_protocol();
|
|
64773
64750
|
var CLOUD_WORKSPACE_SLOT = "{{WORKSPACE}}";
|
|
64774
|
-
var CLOUD_TURN_HEADER = "x-clawd-turn";
|
|
64775
|
-
var CLOUD_TURN_HEADER_START = "start";
|
|
64776
64751
|
var GATEWAY_ROUTES = {
|
|
64777
64752
|
healthz: () => "/healthz",
|
|
64778
|
-
session: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session`,
|
|
64779
|
-
sessionSend: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/${encodeURIComponent(sessionId)}`,
|
|
64780
|
-
sessionMirror: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/${encodeURIComponent(sessionId)}/mirror`,
|
|
64781
|
-
eventSession: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session/events`,
|
|
64782
|
-
eventCancel: (personaId2) => `/p/${encodeURIComponent(personaId2)}/session/events:cancel`,
|
|
64783
|
-
eventSend: (personaId2, sessionId) => `/p/${encodeURIComponent(personaId2)}/session/events/${encodeURIComponent(sessionId)}`,
|
|
64784
64753
|
turn: (personaId2) => `/p/${encodeURIComponent(personaId2)}/v1/chat/completions`,
|
|
64785
64754
|
turnCommand: (personaId2, turnId) => `/p/${encodeURIComponent(personaId2)}/turns/${encodeURIComponent(turnId)}/commands`,
|
|
64786
64755
|
conversationCancel: (personaId2, conversationId) => `/p/${encodeURIComponent(personaId2)}/conversations/${encodeURIComponent(conversationId)}:cancel`,
|
|
@@ -64882,49 +64851,6 @@ var CloudGatewayClient = class {
|
|
|
64882
64851
|
const list = await this.fetchDeployments(trimSlash(gatewayUrl));
|
|
64883
64852
|
return list.find((p3) => p3.personaId === gatewayPersonaId)?.connectors ?? [];
|
|
64884
64853
|
}
|
|
64885
|
-
/**
|
|
64886
|
-
* 会话通道。返回的行流在 Pod 就绪前就能 write:写入先攒着,收到 `ready` 控制行后按序 POST 出去——
|
|
64887
|
-
* 编排那头一构造就发 initialize,不用知道 Pod 还在起。
|
|
64888
|
-
* `toolSessionId`:调用方预分配的引擎会话 id(pi 的 --session-id;codex 的 thread id 是协议内的、不传),进 open 的 body `engineSessionId`
|
|
64889
|
-
* (契约 2026-09-18 §3.2)。`instructions`:会话级指令(pi-cloud 的连接 intro,工作目录写 CLOUD_WORKSPACE_SLOT),进 body `instructions`,
|
|
64890
|
-
* gateway 落成 Pod 里的 /run/agent/instructions.md(契约 §3.1);codex-cloud 不发(走协议内 developerInstructions)。
|
|
64891
|
-
* `expectedEngine` 是 session 创建时的引擎;gateway 在起 Pod 前与当前发布核对。
|
|
64892
|
-
*/
|
|
64893
|
-
async openSession(personaId2, opts = {}) {
|
|
64894
|
-
const { apiKey, gatewayUrl } = await this.credentials();
|
|
64895
|
-
return openHttpLineStream({
|
|
64896
|
-
fetchImpl: this.fetchImpl,
|
|
64897
|
-
gatewayUrl,
|
|
64898
|
-
apiKey,
|
|
64899
|
-
personaId: personaId2,
|
|
64900
|
-
...opts.toolSessionId ? { engineSessionId: opts.toolSessionId } : {},
|
|
64901
|
-
...opts.instructions ? { instructions: opts.instructions } : {},
|
|
64902
|
-
...opts.purpose ? { purpose: opts.purpose } : {},
|
|
64903
|
-
...opts.expectedEngine ? { expectedEngine: opts.expectedEngine } : {},
|
|
64904
|
-
logger: this.deps.logger
|
|
64905
|
-
});
|
|
64906
|
-
}
|
|
64907
|
-
async openEventSession(personaId2, opts) {
|
|
64908
|
-
const { apiKey, gatewayUrl } = await this.credentials();
|
|
64909
|
-
const health = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.healthz());
|
|
64910
|
-
if (!health.ok || (await health.json()).sessionProtocolVersion !== 2) throw new Error("\u4E91 gateway \u7684\u4F1A\u8BDD\u534F\u8BAE\u7248\u672C\u4E0D\u5339\u914D\uFF0C\u8BF7\u5148\u5347\u7EA7 gateway");
|
|
64911
|
-
return openHttpEventSession({
|
|
64912
|
-
fetchImpl: this.fetchImpl,
|
|
64913
|
-
gatewayUrl,
|
|
64914
|
-
apiKey,
|
|
64915
|
-
personaId: personaId2,
|
|
64916
|
-
clientSessionId: opts.clientSessionId,
|
|
64917
|
-
gatewaySessionId: opts.gatewaySessionId,
|
|
64918
|
-
engineSessionId: opts.toolSessionId,
|
|
64919
|
-
instructions: opts.instructions,
|
|
64920
|
-
purpose: opts.purpose,
|
|
64921
|
-
expectedEngine: opts.expectedEngine,
|
|
64922
|
-
effort: opts.effort,
|
|
64923
|
-
personaMode: opts.personaMode,
|
|
64924
|
-
attachOnly: opts.attachOnly,
|
|
64925
|
-
logger: this.deps.logger
|
|
64926
|
-
});
|
|
64927
|
-
}
|
|
64928
64854
|
async openTurn(personaId2, opts) {
|
|
64929
64855
|
const { apiKey, gatewayUrl } = await this.credentials();
|
|
64930
64856
|
const health = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.healthz());
|
|
@@ -64951,23 +64877,6 @@ var CloudGatewayClient = class {
|
|
|
64951
64877
|
});
|
|
64952
64878
|
if (!res.ok) throw new Error(`gateway conversation cancel returned ${res.status}`);
|
|
64953
64879
|
}
|
|
64954
|
-
async cancelEventSession(personaId2, clientSessionId, gatewaySessionId) {
|
|
64955
|
-
const { apiKey, gatewayUrl } = await this.credentials();
|
|
64956
|
-
const res = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventCancel(personaId2), {
|
|
64957
|
-
method: "POST",
|
|
64958
|
-
headers: { authorization: `Bearer ${apiKey}`, "content-type": "application/json" },
|
|
64959
|
-
body: JSON.stringify({ protocolVersion: 2, clientSessionId, gatewaySessionId })
|
|
64960
|
-
});
|
|
64961
|
-
if (!res.ok) {
|
|
64962
|
-
let message = `gateway \u56DE ${res.status}`;
|
|
64963
|
-
try {
|
|
64964
|
-
const body = await res.json();
|
|
64965
|
-
if (typeof body.message === "string") message = body.message;
|
|
64966
|
-
} catch {
|
|
64967
|
-
}
|
|
64968
|
-
throw new Error(message);
|
|
64969
|
-
}
|
|
64970
|
-
}
|
|
64971
64880
|
/**
|
|
64972
64881
|
* 看板数据(design 2026-09-23-cloud-persona-metrics §3.8):GET /metrics/<persona>?window&entry,**原样回**状态码与 body——
|
|
64973
64882
|
* 形状真源在 gateway 的 cloud-persona-metrics,daemon 只是替浏览器拿本机 api key 转一跳。拿不到 key / 连不上 / 超时 → 抛(路由折成 502)。
|
|
@@ -65024,7 +64933,7 @@ var CloudGatewayClient = class {
|
|
|
65024
64933
|
}
|
|
65025
64934
|
};
|
|
65026
64935
|
function openHttpTurn(opts) {
|
|
65027
|
-
const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, logger } = opts;
|
|
64936
|
+
const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, conversationId, turnId, text, expectedEngine, engineSessionId, instructions, effort, personaMode, purpose, logger } = opts;
|
|
65028
64937
|
const body = JSON.stringify({
|
|
65029
64938
|
messages: [{ role: "user", content: text }],
|
|
65030
64939
|
stream: true,
|
|
@@ -65033,6 +64942,7 @@ function openHttpTurn(opts) {
|
|
|
65033
64942
|
conversationId,
|
|
65034
64943
|
turnId,
|
|
65035
64944
|
expectedEngine,
|
|
64945
|
+
...purpose ? { purpose } : {},
|
|
65036
64946
|
...engineSessionId ? { engineSessionId } : {},
|
|
65037
64947
|
...instructions ? { instructions } : {},
|
|
65038
64948
|
...effort ? { effort } : {},
|
|
@@ -65169,525 +65079,12 @@ function openHttpTurn(opts) {
|
|
|
65169
65079
|
close: finish
|
|
65170
65080
|
};
|
|
65171
65081
|
}
|
|
65172
|
-
function openHttpEventSession(opts) {
|
|
65173
|
-
const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, clientSessionId, gatewaySessionId, engineSessionId, instructions, purpose, effort, personaMode, attachOnly, expectedEngine, logger } = opts;
|
|
65174
|
-
const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
|
|
65175
|
-
let abort = new AbortController();
|
|
65176
|
-
const eventCbs = [];
|
|
65177
|
-
const controlCbs = [];
|
|
65178
|
-
const closeCbs = [];
|
|
65179
|
-
const earlyEvents = [];
|
|
65180
|
-
const earlyControls = [];
|
|
65181
|
-
let closed = false;
|
|
65182
|
-
let readyControl = null;
|
|
65183
|
-
let errorControl = null;
|
|
65184
|
-
let sessionId = gatewaySessionId ?? null;
|
|
65185
|
-
let lastSeq = 0;
|
|
65186
|
-
let everReady = false;
|
|
65187
|
-
let connected = false;
|
|
65188
|
-
const attachWaiters = [];
|
|
65189
|
-
let resolveReady;
|
|
65190
|
-
let rejectReady;
|
|
65191
|
-
const ready = new Promise((resolve9, reject) => {
|
|
65192
|
-
resolveReady = resolve9;
|
|
65193
|
-
rejectReady = reject;
|
|
65194
|
-
});
|
|
65195
|
-
void ready.catch(() => {
|
|
65196
|
-
});
|
|
65197
|
-
let sendChain = Promise.resolve();
|
|
65198
|
-
const emitControl = (control) => {
|
|
65199
|
-
if (control.kind === "ready") readyControl = control;
|
|
65200
|
-
if (control.kind === "error") errorControl = control;
|
|
65201
|
-
if (!controlCbs.length) earlyControls.push(control);
|
|
65202
|
-
for (const cb of controlCbs) cb(control);
|
|
65203
|
-
};
|
|
65204
|
-
const finish = (message) => {
|
|
65205
|
-
if (closed) return;
|
|
65206
|
-
if (message) emitControl({ kind: "error", message });
|
|
65207
|
-
closed = true;
|
|
65208
|
-
rejectReady(new Error(message ?? "event session closed"));
|
|
65209
|
-
abort.abort();
|
|
65210
|
-
for (const resolve9 of attachWaiters.splice(0)) resolve9();
|
|
65211
|
-
for (const cb of closeCbs) cb();
|
|
65212
|
-
};
|
|
65213
|
-
const waitForAttach = () => connected ? Promise.resolve() : new Promise((resolve9) => {
|
|
65214
|
-
attachWaiters.push(resolve9);
|
|
65215
|
-
});
|
|
65216
|
-
const retryWait = () => new Promise((resolve9) => {
|
|
65217
|
-
const timer = setTimeout(resolve9, 250);
|
|
65218
|
-
timer.unref?.();
|
|
65219
|
-
abort.signal.addEventListener("abort", () => {
|
|
65220
|
-
clearTimeout(timer);
|
|
65221
|
-
resolve9();
|
|
65222
|
-
}, { once: true });
|
|
65223
|
-
});
|
|
65224
|
-
void (async () => {
|
|
65225
|
-
while (!closed) {
|
|
65226
|
-
abort = new AbortController();
|
|
65227
|
-
let fatal = false;
|
|
65228
|
-
try {
|
|
65229
|
-
const res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventSession(personaId2), {
|
|
65230
|
-
method: "POST",
|
|
65231
|
-
headers,
|
|
65232
|
-
body: JSON.stringify({ protocolVersion: 2, clientSessionId, afterSeq: lastSeq, ...sessionId ? { gatewaySessionId: sessionId } : {}, expectedEngine, ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {}, ...effort ? { effort } : {}, ...personaMode ? { personaMode } : {}, ...attachOnly ? { attachOnly: true } : {} }),
|
|
65233
|
-
signal: abort.signal
|
|
65234
|
-
});
|
|
65235
|
-
if (!res.ok || !res.body) {
|
|
65236
|
-
let message = `gateway \u56DE ${res.status}`;
|
|
65237
|
-
let code;
|
|
65238
|
-
try {
|
|
65239
|
-
const body = await res.json();
|
|
65240
|
-
if (typeof body.message === "string") message = body.message;
|
|
65241
|
-
code = body.error;
|
|
65242
|
-
if (body.error === "SESSION_VERSION_EXPIRED" && !message.includes("SESSION_VERSION_EXPIRED")) message = `SESSION_VERSION_EXPIRED: ${message}`;
|
|
65243
|
-
} catch {
|
|
65244
|
-
}
|
|
65245
|
-
if ((attachOnly || sessionId) && res.status === 404 && code === "SESSION_NOT_FOUND") {
|
|
65246
|
-
emitControl({ kind: "closed", reason: "not-found" });
|
|
65247
|
-
finish();
|
|
65248
|
-
return;
|
|
65249
|
-
}
|
|
65250
|
-
if (res.status === 426 || res.status === 400 || res.status === 401 || res.status === 403 || res.status === 409 || res.status === 410 || code === "CLIENT_UPGRADE_REQUIRED") {
|
|
65251
|
-
fatal = true;
|
|
65252
|
-
finish(message);
|
|
65253
|
-
return;
|
|
65254
|
-
}
|
|
65255
|
-
throw new Error(message);
|
|
65256
|
-
}
|
|
65257
|
-
connected = true;
|
|
65258
|
-
for (const resolve9 of attachWaiters.splice(0)) resolve9();
|
|
65259
|
-
const reader = res.body.getReader();
|
|
65260
|
-
const decoder = new TextDecoder();
|
|
65261
|
-
let pending = "";
|
|
65262
|
-
for (; ; ) {
|
|
65263
|
-
const { value, done } = await reader.read();
|
|
65264
|
-
if (done) break;
|
|
65265
|
-
pending += decoder.decode(value, { stream: true });
|
|
65266
|
-
const lines = pending.split("\n");
|
|
65267
|
-
pending = lines.pop() ?? "";
|
|
65268
|
-
for (const line of lines) {
|
|
65269
|
-
if (!line.trim()) continue;
|
|
65270
|
-
const data = JSON.parse(line);
|
|
65271
|
-
if (data.clawd === "events") {
|
|
65272
|
-
if (typeof data.seq === "number") {
|
|
65273
|
-
if (data.seq <= lastSeq) continue;
|
|
65274
|
-
lastSeq = data.seq;
|
|
65275
|
-
}
|
|
65276
|
-
const events = ParsedEventSchema.array().parse(data.events);
|
|
65277
|
-
if (!eventCbs.length) earlyEvents.push(events);
|
|
65278
|
-
for (const cb of eventCbs) cb(events);
|
|
65279
|
-
continue;
|
|
65280
|
-
}
|
|
65281
|
-
const control = parseControlLine(line);
|
|
65282
|
-
if (!control) throw new Error("gateway event stream contains an unknown line");
|
|
65283
|
-
if (control.kind === "ready") {
|
|
65284
|
-
if (!control.session) throw new Error("gateway ready line has no session id");
|
|
65285
|
-
if (control.engine !== expectedEngine) {
|
|
65286
|
-
finish(control.engine ? `SESSION_VERSION_EXPIRED: \u5F53\u524D Pod \u662F ${control.engine}\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u9700\u8981 ${expectedEngine}` : "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 engine\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway");
|
|
65287
|
-
return;
|
|
65288
|
-
}
|
|
65289
|
-
sessionId = control.session;
|
|
65290
|
-
everReady = true;
|
|
65291
|
-
resolveReady();
|
|
65292
|
-
}
|
|
65293
|
-
emitControl(control);
|
|
65294
|
-
if (control.kind === "error") {
|
|
65295
|
-
finish();
|
|
65296
|
-
return;
|
|
65297
|
-
}
|
|
65298
|
-
if (control.kind === "closed") {
|
|
65299
|
-
finish();
|
|
65300
|
-
return;
|
|
65301
|
-
}
|
|
65302
|
-
}
|
|
65303
|
-
}
|
|
65304
|
-
connected = false;
|
|
65305
|
-
} catch (e) {
|
|
65306
|
-
if (!closed) {
|
|
65307
|
-
if (e instanceof SyntaxError || e.name === "ZodError") {
|
|
65308
|
-
finish("gateway event stream contains invalid data");
|
|
65309
|
-
return;
|
|
65310
|
-
}
|
|
65311
|
-
connected = false;
|
|
65312
|
-
logger?.warn("cloud event stream failed; reconnecting", { code: e.code, name: e.name, ready: everReady });
|
|
65313
|
-
}
|
|
65314
|
-
}
|
|
65315
|
-
if (!closed && !fatal) await retryWait();
|
|
65316
|
-
}
|
|
65317
|
-
})();
|
|
65318
|
-
return {
|
|
65319
|
-
send(command) {
|
|
65320
|
-
const next = sendChain.then(async () => {
|
|
65321
|
-
await ready;
|
|
65322
|
-
while (!closed) {
|
|
65323
|
-
await waitForAttach();
|
|
65324
|
-
if (!sessionId) continue;
|
|
65325
|
-
let res;
|
|
65326
|
-
try {
|
|
65327
|
-
res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.eventSend(personaId2, sessionId), { method: "POST", headers, body: JSON.stringify(command) });
|
|
65328
|
-
} catch {
|
|
65329
|
-
connected = false;
|
|
65330
|
-
abort.abort();
|
|
65331
|
-
await retryWait();
|
|
65332
|
-
continue;
|
|
65333
|
-
}
|
|
65334
|
-
if (res.ok) return;
|
|
65335
|
-
if (res.status === 404 || res.status >= 500) {
|
|
65336
|
-
connected = false;
|
|
65337
|
-
abort.abort();
|
|
65338
|
-
await retryWait();
|
|
65339
|
-
continue;
|
|
65340
|
-
}
|
|
65341
|
-
let message = `gateway \u56DE ${res.status}`;
|
|
65342
|
-
try {
|
|
65343
|
-
const body = await res.json();
|
|
65344
|
-
if (typeof body.message === "string") message = body.message;
|
|
65345
|
-
} catch {
|
|
65346
|
-
}
|
|
65347
|
-
throw new Error(message);
|
|
65348
|
-
}
|
|
65349
|
-
throw new Error("event session closed");
|
|
65350
|
-
});
|
|
65351
|
-
sendChain = next.catch(() => {
|
|
65352
|
-
});
|
|
65353
|
-
return next;
|
|
65354
|
-
},
|
|
65355
|
-
onEvents(cb) {
|
|
65356
|
-
const first = !eventCbs.length;
|
|
65357
|
-
eventCbs.push(cb);
|
|
65358
|
-
if (first) for (const events of earlyEvents.splice(0)) cb(events);
|
|
65359
|
-
},
|
|
65360
|
-
onControl(cb) {
|
|
65361
|
-
const first = !controlCbs.length;
|
|
65362
|
-
controlCbs.push(cb);
|
|
65363
|
-
if (first) for (const control of earlyControls.splice(0)) cb(control);
|
|
65364
|
-
else {
|
|
65365
|
-
if (readyControl) cb(readyControl);
|
|
65366
|
-
if (errorControl) cb(errorControl);
|
|
65367
|
-
}
|
|
65368
|
-
},
|
|
65369
|
-
onClose(cb) {
|
|
65370
|
-
closeCbs.push(cb);
|
|
65371
|
-
if (closed) cb();
|
|
65372
|
-
},
|
|
65373
|
-
close() {
|
|
65374
|
-
finish();
|
|
65375
|
-
}
|
|
65376
|
-
};
|
|
65377
|
-
}
|
|
65378
|
-
function parseControlLine(line) {
|
|
65379
|
-
let o2;
|
|
65380
|
-
try {
|
|
65381
|
-
o2 = JSON.parse(line);
|
|
65382
|
-
} catch {
|
|
65383
|
-
return null;
|
|
65384
|
-
}
|
|
65385
|
-
if (!o2 || typeof o2 !== "object" || !("clawd" in o2)) return null;
|
|
65386
|
-
const r2 = o2;
|
|
65387
|
-
switch (r2.clawd) {
|
|
65388
|
-
case "queued":
|
|
65389
|
-
return { kind: "queued", running: typeof r2.running === "number" ? r2.running : 0 };
|
|
65390
|
-
case "ready":
|
|
65391
|
-
return {
|
|
65392
|
-
kind: "ready",
|
|
65393
|
-
session: typeof r2.session === "string" ? r2.session : "",
|
|
65394
|
-
personaDir: typeof r2.personaDir === "string" ? r2.personaDir : "",
|
|
65395
|
-
workDir: typeof r2.workDir === "string" ? r2.workDir : "",
|
|
65396
|
-
...typeof r2.model === "string" ? { model: r2.model } : {},
|
|
65397
|
-
...typeof r2.engine === "string" ? { engine: r2.engine } : {},
|
|
65398
|
-
...typeof r2.replayGap === "boolean" ? { replayGap: r2.replayGap } : {},
|
|
65399
|
-
...typeof r2.historySynchronized === "boolean" ? { historySynchronized: r2.historySynchronized } : {},
|
|
65400
|
-
...typeof r2.activeTurn === "boolean" ? { activeTurn: r2.activeTurn } : {}
|
|
65401
|
-
};
|
|
65402
|
-
case "error":
|
|
65403
|
-
return { kind: "error", message: typeof r2.message === "string" ? r2.message : "gateway error" };
|
|
65404
|
-
case "closed":
|
|
65405
|
-
return { kind: "closed", reason: typeof r2.reason === "string" ? r2.reason : "unknown" };
|
|
65406
|
-
case "history":
|
|
65407
|
-
return { kind: "history", synchronized: r2.synchronized === true };
|
|
65408
|
-
default:
|
|
65409
|
-
return { kind: "ping" };
|
|
65410
|
-
}
|
|
65411
|
-
}
|
|
65412
|
-
function openHttpLineStream(opts) {
|
|
65413
|
-
const { fetchImpl, gatewayUrl, apiKey, personaId: personaId2, engineSessionId, instructions, purpose, expectedEngine, logger } = opts;
|
|
65414
|
-
const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json" };
|
|
65415
|
-
const ac = new AbortController();
|
|
65416
|
-
const lineCbs = [];
|
|
65417
|
-
const closeCbs = [];
|
|
65418
|
-
const controlCbs = [];
|
|
65419
|
-
let sessionId = null;
|
|
65420
|
-
let closed = false;
|
|
65421
|
-
let closedWith = null;
|
|
65422
|
-
let readyWith = null;
|
|
65423
|
-
const pending = [];
|
|
65424
|
-
let nextIsTurnStart = false;
|
|
65425
|
-
let sendChain = Promise.resolve();
|
|
65426
|
-
const finish = () => {
|
|
65427
|
-
if (closed) return;
|
|
65428
|
-
closed = true;
|
|
65429
|
-
for (const cb of closeCbs) cb();
|
|
65430
|
-
};
|
|
65431
|
-
const emitControl = (c2) => {
|
|
65432
|
-
if (c2.kind === "error") closedWith = c2;
|
|
65433
|
-
if (c2.kind === "ready") readyWith = c2;
|
|
65434
|
-
for (const cb of controlCbs) cb(c2);
|
|
65435
|
-
};
|
|
65436
|
-
const fail = (message) => {
|
|
65437
|
-
if (closed) return;
|
|
65438
|
-
emitControl({ kind: "error", message });
|
|
65439
|
-
ac.abort();
|
|
65440
|
-
finish();
|
|
65441
|
-
};
|
|
65442
|
-
const post = (line, turnStart) => {
|
|
65443
|
-
if (closed || !sessionId) return Promise.resolve();
|
|
65444
|
-
const url = gatewayUrl + GATEWAY_ROUTES.sessionSend(personaId2, sessionId);
|
|
65445
|
-
return fetchImpl(url, { method: "POST", headers: turnStart ? { ...headers, [CLOUD_TURN_HEADER]: CLOUD_TURN_HEADER_START } : headers, body: line + "\n" }).then((res) => {
|
|
65446
|
-
if (res.status === 404) {
|
|
65447
|
-
finish();
|
|
65448
|
-
return;
|
|
65449
|
-
}
|
|
65450
|
-
if (!res.ok) {
|
|
65451
|
-
logger?.warn("cloud session send failed", { status: res.status });
|
|
65452
|
-
fail(
|
|
65453
|
-
res.status === 401 ? "\u8C03\u7528 key \u5DF2\u5931\u6548\uFF08\u64A4\u9500\u6216\u91CD\u65B0\u751F\u6210\u8FC7\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86\u3002\u5230\u300C\u8BBE\u7F6E \u2192 \u8D26\u53F7\u300D\u6216\u8FD9\u4E2A persona \u7684\u5361\u7247\u4E0A\u751F\u6210\u4E00\u628A\uFF0C\u518D\u5F00\u65B0\u4F1A\u8BDD" : `\u4E0A\u884C\u53D1\u4E0D\u51FA\u53BB\uFF08gateway \u56DE ${res.status}\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86`
|
|
65454
|
-
);
|
|
65455
|
-
}
|
|
65456
|
-
}).catch((e) => {
|
|
65457
|
-
if (closed) return;
|
|
65458
|
-
logger?.warn("cloud session send error", { message: e.message });
|
|
65459
|
-
fail(`\u4E0A\u884C\u53D1\u4E0D\u51FA\u53BB\uFF08${e.message}\uFF09\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u65AD\u4E86`);
|
|
65460
|
-
});
|
|
65461
|
-
};
|
|
65462
|
-
const postMirror = async (turn) => {
|
|
65463
|
-
if (closed || !sessionId) return;
|
|
65464
|
-
const url = gatewayUrl + GATEWAY_ROUTES.sessionMirror(personaId2, sessionId);
|
|
65465
|
-
try {
|
|
65466
|
-
const res = await fetchImpl(url, { method: "POST", headers, body: turn ? JSON.stringify({ turn: { outcome: turn.outcome, ...turn.afterFirstByteMs !== void 0 ? { afterFirstByteMs: turn.afterFirstByteMs } : {} } }) : "" });
|
|
65467
|
-
if (!res.ok) logger?.warn("cloud session mirror failed", { status: res.status });
|
|
65468
|
-
} catch (e) {
|
|
65469
|
-
if (!closed) logger?.warn("cloud session mirror error", { message: e.message });
|
|
65470
|
-
}
|
|
65471
|
-
};
|
|
65472
|
-
const flush = () => {
|
|
65473
|
-
for (const { line, turnStart } of pending.splice(0)) sendChain = sendChain.then(() => post(line, turnStart));
|
|
65474
|
-
};
|
|
65475
|
-
void (async () => {
|
|
65476
|
-
let res;
|
|
65477
|
-
try {
|
|
65478
|
-
res = await fetchImpl(gatewayUrl + GATEWAY_ROUTES.session(personaId2), {
|
|
65479
|
-
method: "POST",
|
|
65480
|
-
headers,
|
|
65481
|
-
body: JSON.stringify({ ...engineSessionId ? { engineSessionId } : {}, ...instructions ? { instructions } : {}, ...purpose ? { purpose } : {}, ...expectedEngine ? { expectedEngine } : {} }),
|
|
65482
|
-
signal: ac.signal
|
|
65483
|
-
});
|
|
65484
|
-
} catch (e) {
|
|
65485
|
-
if (!closed) emitControl({ kind: "error", message: `\u8FDE\u4E0D\u4E0A gateway\uFF1A${e.message}` });
|
|
65486
|
-
finish();
|
|
65487
|
-
return;
|
|
65488
|
-
}
|
|
65489
|
-
if (!res.ok || !res.body) {
|
|
65490
|
-
let message = `gateway \u56DE ${res.status}`;
|
|
65491
|
-
try {
|
|
65492
|
-
const body = await res.json();
|
|
65493
|
-
if (typeof body.message === "string") message = body.message;
|
|
65494
|
-
else if (typeof body.error === "string") message = body.error;
|
|
65495
|
-
if (body.error === "SESSION_VERSION_EXPIRED" && !message.includes("SESSION_VERSION_EXPIRED")) message = `SESSION_VERSION_EXPIRED: ${message}`;
|
|
65496
|
-
} catch {
|
|
65497
|
-
}
|
|
65498
|
-
emitControl({ kind: "error", message });
|
|
65499
|
-
finish();
|
|
65500
|
-
return;
|
|
65501
|
-
}
|
|
65502
|
-
const reader = res.body.getReader();
|
|
65503
|
-
const decoder = new TextDecoder();
|
|
65504
|
-
let buf = "";
|
|
65505
|
-
let stop = false;
|
|
65506
|
-
try {
|
|
65507
|
-
for (; ; ) {
|
|
65508
|
-
if (stop) break;
|
|
65509
|
-
const { value, done } = await reader.read();
|
|
65510
|
-
if (done) break;
|
|
65511
|
-
buf += decoder.decode(value, { stream: true });
|
|
65512
|
-
const lines = buf.split("\n");
|
|
65513
|
-
buf = lines.pop() ?? "";
|
|
65514
|
-
for (const raw of lines) {
|
|
65515
|
-
const line = raw.trim();
|
|
65516
|
-
if (!line) continue;
|
|
65517
|
-
const control = parseControlLine(line);
|
|
65518
|
-
if (control) {
|
|
65519
|
-
if (control.kind === "ready") {
|
|
65520
|
-
if (!control.session) {
|
|
65521
|
-
emitControl({ kind: "error", message: "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 session id" });
|
|
65522
|
-
stop = true;
|
|
65523
|
-
ac.abort();
|
|
65524
|
-
void reader.cancel().catch(() => {
|
|
65525
|
-
});
|
|
65526
|
-
break;
|
|
65527
|
-
}
|
|
65528
|
-
if (!control.personaDir || !control.workDir) {
|
|
65529
|
-
emitControl({ kind: "error", message: "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 Pod \u8DEF\u5F84\uFF08personaDir / workDir\uFF09\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway" });
|
|
65530
|
-
stop = true;
|
|
65531
|
-
ac.abort();
|
|
65532
|
-
void reader.cancel().catch(() => {
|
|
65533
|
-
});
|
|
65534
|
-
break;
|
|
65535
|
-
}
|
|
65536
|
-
if (expectedEngine && control.engine !== expectedEngine) {
|
|
65537
|
-
emitControl({ kind: "error", message: control.engine ? `SESSION_VERSION_EXPIRED: \u5F53\u524D Pod \u662F ${control.engine}\uFF0C\u8FD9\u6761\u4F1A\u8BDD\u9700\u8981 ${expectedEngine}` : "gateway \u7684 ready \u63A7\u5236\u884C\u6CA1\u5E26 engine\uFF0Cgateway \u592A\u8001\uFF0C\u5148\u5347 gateway" });
|
|
65538
|
-
stop = true;
|
|
65539
|
-
ac.abort();
|
|
65540
|
-
void reader.cancel().catch(() => {
|
|
65541
|
-
});
|
|
65542
|
-
break;
|
|
65543
|
-
}
|
|
65544
|
-
sessionId = control.session;
|
|
65545
|
-
flush();
|
|
65546
|
-
}
|
|
65547
|
-
emitControl(control);
|
|
65548
|
-
if (control.kind === "error") {
|
|
65549
|
-
stop = true;
|
|
65550
|
-
ac.abort();
|
|
65551
|
-
void reader.cancel().catch(() => {
|
|
65552
|
-
});
|
|
65553
|
-
break;
|
|
65554
|
-
}
|
|
65555
|
-
continue;
|
|
65556
|
-
}
|
|
65557
|
-
for (const cb of lineCbs) cb(line);
|
|
65558
|
-
}
|
|
65559
|
-
}
|
|
65560
|
-
} catch (e) {
|
|
65561
|
-
if (!closed && !ac.signal.aborted) logger?.warn("cloud session stream broke", { message: e.message });
|
|
65562
|
-
}
|
|
65563
|
-
finish();
|
|
65564
|
-
})();
|
|
65565
|
-
return {
|
|
65566
|
-
write: (line) => {
|
|
65567
|
-
if (closed) return;
|
|
65568
|
-
pending.push({ line, turnStart: nextIsTurnStart });
|
|
65569
|
-
nextIsTurnStart = false;
|
|
65570
|
-
if (sessionId) flush();
|
|
65571
|
-
},
|
|
65572
|
-
markNextLineTurnStart: () => {
|
|
65573
|
-
nextIsTurnStart = true;
|
|
65574
|
-
},
|
|
65575
|
-
onLine: (cb) => {
|
|
65576
|
-
lineCbs.push(cb);
|
|
65577
|
-
},
|
|
65578
|
-
onClose: (cb) => {
|
|
65579
|
-
closeCbs.push(cb);
|
|
65580
|
-
if (closed) cb();
|
|
65581
|
-
},
|
|
65582
|
-
onControl: (cb) => {
|
|
65583
|
-
controlCbs.push(cb);
|
|
65584
|
-
if (readyWith) cb(readyWith);
|
|
65585
|
-
if (closedWith) cb(closedWith);
|
|
65586
|
-
},
|
|
65587
|
-
close: () => {
|
|
65588
|
-
ac.abort();
|
|
65589
|
-
finish();
|
|
65590
|
-
},
|
|
65591
|
-
mirror: (turn) => {
|
|
65592
|
-
if (closed || !sessionId) return Promise.resolve();
|
|
65593
|
-
const p3 = sendChain.then(() => postMirror(turn));
|
|
65594
|
-
sendChain = p3;
|
|
65595
|
-
return p3;
|
|
65596
|
-
}
|
|
65597
|
-
};
|
|
65598
|
-
}
|
|
65599
|
-
|
|
65600
|
-
// src/cloud/cancel-outbox.ts
|
|
65601
|
-
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
65602
|
-
var import_node_path44 = __toESM(require("path"), 1);
|
|
65603
|
-
var CloudCancelOutbox = class {
|
|
65604
|
-
constructor(dir, send2, logger) {
|
|
65605
|
-
this.dir = dir;
|
|
65606
|
-
this.send = send2;
|
|
65607
|
-
this.logger = logger;
|
|
65608
|
-
}
|
|
65609
|
-
dir;
|
|
65610
|
-
send;
|
|
65611
|
-
logger;
|
|
65612
|
-
timer = null;
|
|
65613
|
-
inFlight = /* @__PURE__ */ new Set();
|
|
65614
|
-
record(clientSessionId, personaId2, gatewaySessionId) {
|
|
65615
|
-
if (!clientSessionId || !personaId2 || !gatewaySessionId) throw new Error("cloud cancel requires client, gateway and persona IDs");
|
|
65616
|
-
import_node_fs39.default.mkdirSync(this.dir, { recursive: true, mode: 448 });
|
|
65617
|
-
const target = this.pathFor(clientSessionId);
|
|
65618
|
-
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
65619
|
-
import_node_fs39.default.writeFileSync(temporary, JSON.stringify({ clientSessionId, personaId: personaId2, gatewaySessionId }), { mode: 384 });
|
|
65620
|
-
import_node_fs39.default.renameSync(temporary, target);
|
|
65621
|
-
this.inFlight.add(clientSessionId);
|
|
65622
|
-
}
|
|
65623
|
-
confirm(clientSessionId) {
|
|
65624
|
-
import_node_fs39.default.rmSync(this.pathFor(clientSessionId), { force: true });
|
|
65625
|
-
this.inFlight.delete(clientSessionId);
|
|
65626
|
-
}
|
|
65627
|
-
release(clientSessionId) {
|
|
65628
|
-
this.inFlight.delete(clientSessionId);
|
|
65629
|
-
}
|
|
65630
|
-
async request(clientSessionId, personaId2, gatewaySessionId) {
|
|
65631
|
-
this.record(clientSessionId, personaId2, gatewaySessionId);
|
|
65632
|
-
try {
|
|
65633
|
-
await this.send(personaId2, clientSessionId, gatewaySessionId);
|
|
65634
|
-
this.confirm(clientSessionId);
|
|
65635
|
-
} catch (e) {
|
|
65636
|
-
this.release(clientSessionId);
|
|
65637
|
-
throw e;
|
|
65638
|
-
}
|
|
65639
|
-
}
|
|
65640
|
-
async flush() {
|
|
65641
|
-
let names;
|
|
65642
|
-
try {
|
|
65643
|
-
names = import_node_fs39.default.readdirSync(this.dir).filter((name) => name.endsWith(".json"));
|
|
65644
|
-
} catch (e) {
|
|
65645
|
-
if (e.code === "ENOENT") return;
|
|
65646
|
-
throw e;
|
|
65647
|
-
}
|
|
65648
|
-
for (const name of names) {
|
|
65649
|
-
const target = import_node_path44.default.join(this.dir, name);
|
|
65650
|
-
let pending;
|
|
65651
|
-
try {
|
|
65652
|
-
pending = JSON.parse(import_node_fs39.default.readFileSync(target, "utf8"));
|
|
65653
|
-
} catch {
|
|
65654
|
-
continue;
|
|
65655
|
-
}
|
|
65656
|
-
if (!pending.clientSessionId || !pending.personaId || !pending.gatewaySessionId || this.pathFor(pending.clientSessionId) !== target) continue;
|
|
65657
|
-
if (this.inFlight.has(pending.clientSessionId)) continue;
|
|
65658
|
-
this.inFlight.add(pending.clientSessionId);
|
|
65659
|
-
try {
|
|
65660
|
-
await this.send(pending.personaId, pending.clientSessionId, pending.gatewaySessionId);
|
|
65661
|
-
import_node_fs39.default.rmSync(target, { force: true });
|
|
65662
|
-
} catch (e) {
|
|
65663
|
-
this.logger?.warn("cloud cancel pending", { sessionId: pending.clientSessionId, error: e.message });
|
|
65664
|
-
} finally {
|
|
65665
|
-
this.inFlight.delete(pending.clientSessionId);
|
|
65666
|
-
}
|
|
65667
|
-
}
|
|
65668
|
-
}
|
|
65669
|
-
start() {
|
|
65670
|
-
if (this.timer) return;
|
|
65671
|
-
const retry = () => void this.flush().catch((e) => this.logger?.warn("cloud cancel outbox flush failed", { error: e.message }));
|
|
65672
|
-
retry();
|
|
65673
|
-
this.timer = setInterval(retry, 3e4);
|
|
65674
|
-
this.timer.unref?.();
|
|
65675
|
-
}
|
|
65676
|
-
stop() {
|
|
65677
|
-
if (this.timer) clearInterval(this.timer);
|
|
65678
|
-
this.timer = null;
|
|
65679
|
-
}
|
|
65680
|
-
pathFor(clientSessionId) {
|
|
65681
|
-
return import_node_path44.default.join(this.dir, `${safeFileName(clientSessionId)}.json`);
|
|
65682
|
-
}
|
|
65683
|
-
};
|
|
65684
65082
|
|
|
65685
65083
|
// src/tools/codex-cloud.ts
|
|
65686
65084
|
init_protocol();
|
|
65687
65085
|
|
|
65688
65086
|
// src/tools/codex-cloud-session.ts
|
|
65689
|
-
var
|
|
65690
|
-
var import_node_crypto14 = require("crypto");
|
|
65087
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
65691
65088
|
|
|
65692
65089
|
// src/tools/cloud-portable-input.ts
|
|
65693
65090
|
async function portableCloudInput(text, resolvers) {
|
|
@@ -65746,10 +65143,11 @@ function createCloudTurnSession(args) {
|
|
|
65746
65143
|
turnId: commandId,
|
|
65747
65144
|
text: portable,
|
|
65748
65145
|
expectedEngine: engine,
|
|
65749
|
-
...engine === "pi" ? { engineSessionId: engineSessionId ?? conversationId } : {},
|
|
65146
|
+
...engine === "pi" && !ctx.titleOnly ? { engineSessionId: engineSessionId ?? conversationId } : {},
|
|
65750
65147
|
...instructions ? { instructions } : {},
|
|
65751
65148
|
...ctx.effort ? { effort: ctx.effort } : {},
|
|
65752
|
-
...ctx.personaMode ? { personaMode: ctx.personaMode } : {}
|
|
65149
|
+
...ctx.personaMode ? { personaMode: ctx.personaMode } : {},
|
|
65150
|
+
...ctx.titleOnly ? { purpose: "title" } : {}
|
|
65753
65151
|
});
|
|
65754
65152
|
if (closed) {
|
|
65755
65153
|
stream.close();
|
|
@@ -65826,7 +65224,7 @@ function cloudImageInput(deps) {
|
|
|
65826
65224
|
const mime = lookupMime(p3);
|
|
65827
65225
|
if (!mime.startsWith("image/")) return null;
|
|
65828
65226
|
try {
|
|
65829
|
-
const bytes = (deps.readFile ??
|
|
65227
|
+
const bytes = (deps.readFile ?? import_node_fs39.default.readFileSync)(p3);
|
|
65830
65228
|
return { type: "image", url: `data:${mime};base64,${bytes.toString("base64")}` };
|
|
65831
65229
|
} catch (e) {
|
|
65832
65230
|
deps.logger?.warn("cloud image attachment unreadable", { path: p3, message: e.message });
|
|
@@ -65836,34 +65234,10 @@ function cloudImageInput(deps) {
|
|
|
65836
65234
|
}
|
|
65837
65235
|
function createCloudCodexSession(ctx, sink, deps) {
|
|
65838
65236
|
const personaId2 = personaIdFromCloudCwd(ctx.cwd);
|
|
65839
|
-
if (personaId2
|
|
65840
|
-
return createCloudTurnSession({
|
|
65841
|
-
ctx,
|
|
65842
|
-
sink,
|
|
65843
|
-
client: deps.client,
|
|
65844
|
-
personaId: personaId2,
|
|
65845
|
-
engine: "codex",
|
|
65846
|
-
instructions: ctx.extraSystemPrompt,
|
|
65847
|
-
prepare: (text) => portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) })
|
|
65848
|
-
});
|
|
65849
|
-
}
|
|
65850
|
-
const clientSessionId = ctx.titleOnly ? (0, import_node_crypto14.randomUUID)() : ctx.cloudExecutionId ?? ctx.env?.CLAWD_SESSION_ID;
|
|
65851
|
-
let channel = null;
|
|
65852
|
-
let closed = false;
|
|
65853
|
-
let detached = false;
|
|
65854
|
-
let stopping = null;
|
|
65855
|
-
let exited = false;
|
|
65856
|
-
let ready = false;
|
|
65857
|
-
const exit = () => {
|
|
65858
|
-
if (!exited) {
|
|
65859
|
-
exited = true;
|
|
65860
|
-
sink.onExit(null);
|
|
65861
|
-
}
|
|
65862
|
-
};
|
|
65863
|
-
if (!personaId2 || !clientSessionId) {
|
|
65237
|
+
if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
|
|
65864
65238
|
queueMicrotask(() => {
|
|
65865
|
-
sink.onError(
|
|
65866
|
-
|
|
65239
|
+
sink.onError(personaId2 ? "\u65E7\u4E91\u4F1A\u8BDD\u534F\u8BAE\u5DF2\u505C\u7528\uFF0C\u8BF7\u5347\u7EA7\u5BA2\u6237\u7AEF\u5E76\u65B0\u5F00\u4F1A\u8BDD" : "cloud session is missing persona id");
|
|
65240
|
+
sink.onExit(null);
|
|
65867
65241
|
});
|
|
65868
65242
|
return { startTurn() {
|
|
65869
65243
|
}, respondPermission() {
|
|
@@ -65871,90 +65245,15 @@ function createCloudCodexSession(ctx, sink, deps) {
|
|
|
65871
65245
|
}, async stop() {
|
|
65872
65246
|
} };
|
|
65873
65247
|
}
|
|
65874
|
-
|
|
65875
|
-
|
|
65876
|
-
|
|
65877
|
-
|
|
65878
|
-
|
|
65879
|
-
|
|
65880
|
-
|
|
65881
|
-
|
|
65882
|
-
...ctx.titleOnly ? { purpose: "title" } : {},
|
|
65883
|
-
...ctx.cloudAttachOnly ? { attachOnly: true } : {}
|
|
65884
|
-
}).then(
|
|
65885
|
-
(opened2) => {
|
|
65886
|
-
channel = opened2;
|
|
65887
|
-
channel.onEvents((events) => sink.pushEvents(events));
|
|
65888
|
-
channel.onControl((c2) => {
|
|
65889
|
-
if (c2.kind === "ready") {
|
|
65890
|
-
ready = true;
|
|
65891
|
-
sink.onGatewayReady?.(c2.session);
|
|
65892
|
-
if (c2.replayGap || c2.historySynchronized === false) sink.onHistoryGap?.(c2.historySynchronized === true);
|
|
65893
|
-
} else if (c2.kind === "queued") {
|
|
65894
|
-
sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
|
|
65895
|
-
} else if (c2.kind === "history") {
|
|
65896
|
-
sink.onHistoryGap?.(c2.synchronized);
|
|
65897
|
-
} else if (c2.kind === "error") {
|
|
65898
|
-
sink.onError(`${ready ? "\u4E91\u4E0A\u6267\u884C\u5931\u8D25" : "\u4E91\u4E0A persona \u8D77\u4E0D\u6765"}\uFF1A${c2.message}`);
|
|
65899
|
-
} else if (c2.kind === "closed" && c2.reason === "not-found") {
|
|
65900
|
-
sink.onRecoveryAbsent?.();
|
|
65901
|
-
}
|
|
65902
|
-
});
|
|
65903
|
-
channel.onClose(() => {
|
|
65904
|
-
if (!detached) exit();
|
|
65905
|
-
});
|
|
65906
|
-
if (closed) channel.close();
|
|
65907
|
-
return channel;
|
|
65908
|
-
},
|
|
65909
|
-
(e) => {
|
|
65910
|
-
sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
|
|
65911
|
-
exit();
|
|
65912
|
-
throw e;
|
|
65913
|
-
}
|
|
65914
|
-
);
|
|
65915
|
-
void opened.catch(() => {
|
|
65248
|
+
return createCloudTurnSession({
|
|
65249
|
+
ctx,
|
|
65250
|
+
sink,
|
|
65251
|
+
client: deps.client,
|
|
65252
|
+
personaId: personaId2,
|
|
65253
|
+
engine: "codex",
|
|
65254
|
+
instructions: ctx.titleOnly ? void 0 : ctx.extraSystemPrompt,
|
|
65255
|
+
prepare: (text) => portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) })
|
|
65916
65256
|
});
|
|
65917
|
-
let sendChain = Promise.resolve();
|
|
65918
|
-
const send2 = (command) => {
|
|
65919
|
-
sendChain = sendChain.then(command).catch((e) => {
|
|
65920
|
-
if (!closed && !exited) sink.onError(`\u4E91\u4E0A\u4F1A\u8BDD\u4E0A\u884C\u5931\u8D25\uFF1A${e.message}`);
|
|
65921
|
-
});
|
|
65922
|
-
};
|
|
65923
|
-
return {
|
|
65924
|
-
startTurn(text, commandId = (0, import_node_crypto14.randomUUID)(), prepared = false) {
|
|
65925
|
-
send2(async () => {
|
|
65926
|
-
const ch = await opened;
|
|
65927
|
-
if (closed) return;
|
|
65928
|
-
const portable = prepared ? text : await portableCloudInput(text, { resolveCodexImage: cloudImageInput(deps) });
|
|
65929
|
-
if (sink.onCommandPrepared?.(commandId, portable, prepared) === false) return;
|
|
65930
|
-
await ch.send({ command: "turn", text: portable, commandId });
|
|
65931
|
-
});
|
|
65932
|
-
},
|
|
65933
|
-
respondPermission(requestId, allow) {
|
|
65934
|
-
send2(async () => (await opened).send({ command: "permission", requestId, allow }));
|
|
65935
|
-
},
|
|
65936
|
-
interrupt() {
|
|
65937
|
-
send2(async () => (await opened).send({ command: "interrupt" }));
|
|
65938
|
-
},
|
|
65939
|
-
detach() {
|
|
65940
|
-
detached = true;
|
|
65941
|
-
closed = true;
|
|
65942
|
-
channel?.close();
|
|
65943
|
-
},
|
|
65944
|
-
stop() {
|
|
65945
|
-
if (stopping) return stopping;
|
|
65946
|
-
closed = true;
|
|
65947
|
-
stopping = (async () => {
|
|
65948
|
-
const ch = await opened.catch(() => null);
|
|
65949
|
-
if (ch) {
|
|
65950
|
-
await ch.send({ command: "cancel" });
|
|
65951
|
-
ch.close();
|
|
65952
|
-
}
|
|
65953
|
-
exit();
|
|
65954
|
-
})();
|
|
65955
|
-
return stopping;
|
|
65956
|
-
}
|
|
65957
|
-
};
|
|
65958
65257
|
}
|
|
65959
65258
|
|
|
65960
65259
|
// src/tools/codex-cloud.ts
|
|
@@ -66025,7 +65324,7 @@ init_protocol();
|
|
|
66025
65324
|
|
|
66026
65325
|
// src/tools/pi.ts
|
|
66027
65326
|
var import_node_child_process12 = require("child_process");
|
|
66028
|
-
var
|
|
65327
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
66029
65328
|
init_protocol();
|
|
66030
65329
|
|
|
66031
65330
|
// src/tools/pi-rpc-client.ts
|
|
@@ -66125,9 +65424,9 @@ var PiRpcClient = class {
|
|
|
66125
65424
|
|
|
66126
65425
|
// src/tools/pi-session.ts
|
|
66127
65426
|
var import_node_child_process11 = require("child_process");
|
|
66128
|
-
var
|
|
66129
|
-
var
|
|
66130
|
-
var
|
|
65427
|
+
var import_node_crypto14 = require("crypto");
|
|
65428
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
65429
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
66131
65430
|
|
|
66132
65431
|
// src/tools/pi-events.ts
|
|
66133
65432
|
init_protocol();
|
|
@@ -66398,9 +65697,9 @@ ${dirs.map((d2) => `- ${d2}`).join("\n")}`;
|
|
|
66398
65697
|
}
|
|
66399
65698
|
function createPiSession(ctx, sink, deps = {}) {
|
|
66400
65699
|
const cmd = process.env.PI_BIN ?? "pi";
|
|
66401
|
-
const sessionId = ctx.toolSessionId ?? (0,
|
|
66402
|
-
const skillsDir =
|
|
66403
|
-
const exists = deps.skillsDirExists ?? ((d2) =>
|
|
65700
|
+
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto14.randomUUID)();
|
|
65701
|
+
const skillsDir = import_node_path44.default.join(ctx.cwd, ".claude", "skills");
|
|
65702
|
+
const exists = deps.skillsDirExists ?? ((d2) => import_node_fs40.default.existsSync(d2));
|
|
66404
65703
|
const args = buildPiArgs(ctx, {
|
|
66405
65704
|
sessionId,
|
|
66406
65705
|
skillsDir: exists(skillsDir) ? skillsDir : void 0,
|
|
@@ -66462,10 +65761,10 @@ var PI_DEFAULT_MODEL_ENTRY = {
|
|
|
66462
65761
|
};
|
|
66463
65762
|
var PI_FULL_ACCESS = { id: "never", label: "Full Access", description: "pi \u65E0\u5BA1\u6279\uFF1A\u4ECE\u4E0D\u8BE2\u95EE\uFF0C\u81EA\u4E3B\u6267\u884C" };
|
|
66464
65763
|
async function probePi(env = process.env) {
|
|
66465
|
-
if (env.PI_BIN &&
|
|
65764
|
+
if (env.PI_BIN && import_node_fs41.default.existsSync(env.PI_BIN)) return { available: true, path: env.PI_BIN };
|
|
66466
65765
|
try {
|
|
66467
65766
|
const out = (0, import_node_child_process12.execFileSync)("which", ["pi"], { encoding: "utf8" }).trim();
|
|
66468
|
-
if (out &&
|
|
65767
|
+
if (out && import_node_fs41.default.existsSync(out)) return { available: true, path: out };
|
|
66469
65768
|
} catch {
|
|
66470
65769
|
}
|
|
66471
65770
|
return { available: false };
|
|
@@ -66635,42 +65934,15 @@ var PiAdapter = class {
|
|
|
66635
65934
|
};
|
|
66636
65935
|
|
|
66637
65936
|
// src/tools/pi-cloud-session.ts
|
|
66638
|
-
var import_node_crypto16 = require("crypto");
|
|
66639
65937
|
function cloudPiInstructions(ctx) {
|
|
66640
65938
|
return [ctx.extraSystemPrompt, workDirPrompt(CLOUD_WORKSPACE_SLOT, ctx.personaMode ?? "owner")].filter((x2) => Boolean(x2)).join("\n\n");
|
|
66641
65939
|
}
|
|
66642
65940
|
function createCloudPiSession(ctx, sink, deps) {
|
|
66643
65941
|
const personaId2 = personaIdFromCloudCwd(ctx.cwd);
|
|
66644
|
-
if (personaId2
|
|
66645
|
-
return createCloudTurnSession({
|
|
66646
|
-
ctx,
|
|
66647
|
-
sink,
|
|
66648
|
-
client: deps.client,
|
|
66649
|
-
personaId: personaId2,
|
|
66650
|
-
engine: "pi",
|
|
66651
|
-
engineSessionId: ctx.toolSessionId,
|
|
66652
|
-
instructions: cloudPiInstructions(ctx),
|
|
66653
|
-
prepare: (text) => portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() })
|
|
66654
|
-
});
|
|
66655
|
-
}
|
|
66656
|
-
const clientSessionId = ctx.titleOnly ? (0, import_node_crypto16.randomUUID)() : ctx.cloudExecutionId ?? ctx.env?.CLAWD_SESSION_ID;
|
|
66657
|
-
const sessionId = ctx.toolSessionId ?? (0, import_node_crypto16.randomUUID)();
|
|
66658
|
-
let channel = null;
|
|
66659
|
-
let closed = false;
|
|
66660
|
-
let detached = false;
|
|
66661
|
-
let stopping = null;
|
|
66662
|
-
let exited = false;
|
|
66663
|
-
let ready = false;
|
|
66664
|
-
const exit = () => {
|
|
66665
|
-
if (!exited) {
|
|
66666
|
-
exited = true;
|
|
66667
|
-
sink.onExit(null);
|
|
66668
|
-
}
|
|
66669
|
-
};
|
|
66670
|
-
if (!personaId2 || !clientSessionId) {
|
|
65942
|
+
if (!personaId2 || ctx.cloudGatewaySessionId || ctx.cloudLegacyPendingCommand) {
|
|
66671
65943
|
queueMicrotask(() => {
|
|
66672
|
-
sink.onError(
|
|
66673
|
-
|
|
65944
|
+
sink.onError(personaId2 ? "\u65E7\u4E91\u4F1A\u8BDD\u534F\u8BAE\u5DF2\u505C\u7528\uFF0C\u8BF7\u5347\u7EA7\u5BA2\u6237\u7AEF\u5E76\u65B0\u5F00\u4F1A\u8BDD" : "cloud session is missing persona id");
|
|
65945
|
+
sink.onExit(null);
|
|
66674
65946
|
});
|
|
66675
65947
|
return { startTurn() {
|
|
66676
65948
|
}, respondPermission() {
|
|
@@ -66678,80 +65950,16 @@ function createCloudPiSession(ctx, sink, deps) {
|
|
|
66678
65950
|
}, async stop() {
|
|
66679
65951
|
} };
|
|
66680
65952
|
}
|
|
66681
|
-
|
|
66682
|
-
|
|
66683
|
-
|
|
66684
|
-
|
|
66685
|
-
|
|
66686
|
-
|
|
66687
|
-
|
|
66688
|
-
|
|
66689
|
-
|
|
66690
|
-
} else if (c2.kind === "queued") {
|
|
66691
|
-
sink.pushEvents([{ kind: "meta-text", text: `\u4E91\u4E0A\u673A\u5668\u6709 ${c2.running} \u4E2A\u4EFB\u52A1\u5728\u8DD1\uFF0C\u7B49\u4E00\u4E2A\u7ED3\u675F\u5C31\u8F6E\u5230\u4F60` }]);
|
|
66692
|
-
} else if (c2.kind === "history") {
|
|
66693
|
-
sink.onHistoryGap?.(c2.synchronized);
|
|
66694
|
-
} else if (c2.kind === "error") {
|
|
66695
|
-
sink.onError(`${ready ? "\u4E91\u4E0A\u6267\u884C\u5931\u8D25" : "\u4E91\u4E0A persona \u8D77\u4E0D\u6765"}\uFF1A${c2.message}`);
|
|
66696
|
-
} else if (c2.kind === "closed" && c2.reason === "not-found") {
|
|
66697
|
-
sink.onRecoveryAbsent?.();
|
|
66698
|
-
}
|
|
66699
|
-
});
|
|
66700
|
-
channel.onClose(() => {
|
|
66701
|
-
if (!detached) exit();
|
|
66702
|
-
});
|
|
66703
|
-
if (closed) channel.close();
|
|
66704
|
-
return channel;
|
|
66705
|
-
},
|
|
66706
|
-
(e) => {
|
|
66707
|
-
sink.onError(e instanceof CloudApiKeyRequiredError ? e.message : `\u8FDE\u4E0D\u4E0A\u4E91 gateway\uFF1A${e.message}`);
|
|
66708
|
-
exit();
|
|
66709
|
-
throw e;
|
|
66710
|
-
}
|
|
66711
|
-
);
|
|
66712
|
-
void opened.catch(() => {
|
|
65953
|
+
return createCloudTurnSession({
|
|
65954
|
+
ctx,
|
|
65955
|
+
sink,
|
|
65956
|
+
client: deps.client,
|
|
65957
|
+
personaId: personaId2,
|
|
65958
|
+
engine: "pi",
|
|
65959
|
+
engineSessionId: ctx.toolSessionId,
|
|
65960
|
+
instructions: ctx.titleOnly ? void 0 : cloudPiInstructions(ctx),
|
|
65961
|
+
prepare: (text) => portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() })
|
|
66713
65962
|
});
|
|
66714
|
-
let sendChain = Promise.resolve();
|
|
66715
|
-
const send2 = (command) => {
|
|
66716
|
-
sendChain = sendChain.then(command).catch((e) => {
|
|
66717
|
-
if (!closed && !exited) sink.onError(`\u4E91\u4E0A\u4F1A\u8BDD\u4E0A\u884C\u5931\u8D25\uFF1A${e.message}`);
|
|
66718
|
-
});
|
|
66719
|
-
};
|
|
66720
|
-
return {
|
|
66721
|
-
startTurn(text, commandId = (0, import_node_crypto16.randomUUID)(), prepared = false) {
|
|
66722
|
-
send2(async () => {
|
|
66723
|
-
const ch = await opened;
|
|
66724
|
-
if (closed) return;
|
|
66725
|
-
const portable = prepared ? text : await portableCloudInput(text, { fetchPiImage: deps.fetchImage ?? makeImageFetcher() });
|
|
66726
|
-
if (sink.onCommandPrepared?.(commandId, portable, prepared) === false) return;
|
|
66727
|
-
await ch.send({ command: "turn", text: portable, commandId });
|
|
66728
|
-
});
|
|
66729
|
-
},
|
|
66730
|
-
respondPermission(requestId, allow) {
|
|
66731
|
-
send2(async () => (await opened).send({ command: "permission", requestId, allow }));
|
|
66732
|
-
},
|
|
66733
|
-
interrupt() {
|
|
66734
|
-
send2(async () => (await opened).send({ command: "interrupt" }));
|
|
66735
|
-
},
|
|
66736
|
-
detach() {
|
|
66737
|
-
detached = true;
|
|
66738
|
-
closed = true;
|
|
66739
|
-
channel?.close();
|
|
66740
|
-
},
|
|
66741
|
-
stop() {
|
|
66742
|
-
if (stopping) return stopping;
|
|
66743
|
-
closed = true;
|
|
66744
|
-
stopping = (async () => {
|
|
66745
|
-
const ch = await opened.catch(() => null);
|
|
66746
|
-
if (ch) {
|
|
66747
|
-
await ch.send({ command: "cancel" });
|
|
66748
|
-
ch.close();
|
|
66749
|
-
}
|
|
66750
|
-
exit();
|
|
66751
|
-
})();
|
|
66752
|
-
return stopping;
|
|
66753
|
-
}
|
|
66754
|
-
};
|
|
66755
65963
|
}
|
|
66756
65964
|
|
|
66757
65965
|
// src/tools/pi-cloud.ts
|
|
@@ -66821,7 +66029,7 @@ var CloudPiAdapter = class {
|
|
|
66821
66029
|
init_protocol();
|
|
66822
66030
|
|
|
66823
66031
|
// src/tools/codex-skills.ts
|
|
66824
|
-
var
|
|
66032
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
66825
66033
|
function str4(v3) {
|
|
66826
66034
|
return typeof v3 === "string" ? v3 : void 0;
|
|
66827
66035
|
}
|
|
@@ -66836,13 +66044,13 @@ function mapSkillsListResponse(res) {
|
|
|
66836
66044
|
const r2 = s2 ?? {};
|
|
66837
66045
|
const name = str4(r2.name);
|
|
66838
66046
|
if (!name) continue;
|
|
66839
|
-
const
|
|
66047
|
+
const path106 = str4(r2.path);
|
|
66840
66048
|
const description = str4(r2.description);
|
|
66841
66049
|
const isPlugin = name.includes(":");
|
|
66842
66050
|
out.push({
|
|
66843
66051
|
name,
|
|
66844
66052
|
source: isPlugin ? "plugin" : "project",
|
|
66845
|
-
...
|
|
66053
|
+
...path106 ? { path: path106 } : {},
|
|
66846
66054
|
...description ? { description } : {},
|
|
66847
66055
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
66848
66056
|
});
|
|
@@ -66858,7 +66066,7 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
66858
66066
|
// 先写 extraRoots 再写 list(stdio 按写入顺序处理,fire-and-forget 不 await 回包;
|
|
66859
66067
|
// codex-session.ts ready 序列同款,两处保持一致)。失败不阻塞 list。
|
|
66860
66068
|
beforeRequest: (client) => {
|
|
66861
|
-
void client.request("skills/extraRoots/set", { extraRoots: [
|
|
66069
|
+
void client.request("skills/extraRoots/set", { extraRoots: [import_node_path45.default.join(cwd, ".claude", "skills")] }).catch(() => void 0);
|
|
66862
66070
|
}
|
|
66863
66071
|
});
|
|
66864
66072
|
return mapSkillsListResponse(res);
|
|
@@ -66932,23 +66140,23 @@ function rec4(v3) {
|
|
|
66932
66140
|
}
|
|
66933
66141
|
|
|
66934
66142
|
// src/workspace/browser.ts
|
|
66935
|
-
var
|
|
66143
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
66936
66144
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
66937
|
-
var
|
|
66145
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
66938
66146
|
init_protocol();
|
|
66939
66147
|
var MAX_FILE_BYTES2 = 2 * 1024 * 1024;
|
|
66940
66148
|
function resolveInsideCwd(cwd, subpath) {
|
|
66941
|
-
const absCwd =
|
|
66942
|
-
const joined =
|
|
66943
|
-
const rel =
|
|
66944
|
-
if (rel.startsWith("..") ||
|
|
66149
|
+
const absCwd = import_node_path46.default.resolve(cwd);
|
|
66150
|
+
const joined = import_node_path46.default.resolve(absCwd, subpath ?? ".");
|
|
66151
|
+
const rel = import_node_path46.default.relative(absCwd, joined);
|
|
66152
|
+
if (rel.startsWith("..") || import_node_path46.default.isAbsolute(rel)) {
|
|
66945
66153
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
66946
66154
|
}
|
|
66947
66155
|
return joined;
|
|
66948
66156
|
}
|
|
66949
66157
|
function ensureCwd(cwd) {
|
|
66950
66158
|
try {
|
|
66951
|
-
const stat =
|
|
66159
|
+
const stat = import_node_fs42.default.statSync(cwd);
|
|
66952
66160
|
if (!stat.isDirectory()) {
|
|
66953
66161
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
66954
66162
|
}
|
|
@@ -66962,7 +66170,7 @@ var WorkspaceBrowser = class {
|
|
|
66962
66170
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os15.default.homedir();
|
|
66963
66171
|
ensureCwd(cwd);
|
|
66964
66172
|
const full = resolveInsideCwd(cwd, args.path);
|
|
66965
|
-
const dirents =
|
|
66173
|
+
const dirents = import_node_fs42.default.readdirSync(full, { withFileTypes: true });
|
|
66966
66174
|
const entries = [];
|
|
66967
66175
|
for (const d2 of dirents) {
|
|
66968
66176
|
if (!args.showHidden && d2.name.startsWith(".")) continue;
|
|
@@ -66972,7 +66180,7 @@ var WorkspaceBrowser = class {
|
|
|
66972
66180
|
mtime: ""
|
|
66973
66181
|
};
|
|
66974
66182
|
try {
|
|
66975
|
-
const st2 =
|
|
66183
|
+
const st2 = import_node_fs42.default.statSync(import_node_path46.default.join(full, d2.name));
|
|
66976
66184
|
entry.mtime = new Date(st2.mtimeMs).toISOString();
|
|
66977
66185
|
if (d2.isFile()) entry.size = st2.size;
|
|
66978
66186
|
} catch {
|
|
@@ -66988,14 +66196,14 @@ var WorkspaceBrowser = class {
|
|
|
66988
66196
|
read(args) {
|
|
66989
66197
|
ensureCwd(args.cwd);
|
|
66990
66198
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
66991
|
-
const st2 =
|
|
66199
|
+
const st2 = import_node_fs42.default.statSync(full);
|
|
66992
66200
|
if (!st2.isFile()) {
|
|
66993
66201
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
66994
66202
|
}
|
|
66995
66203
|
if (st2.size > MAX_FILE_BYTES2) {
|
|
66996
66204
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES2} bytes`);
|
|
66997
66205
|
}
|
|
66998
|
-
const buf =
|
|
66206
|
+
const buf = import_node_fs42.default.readFileSync(full);
|
|
66999
66207
|
const isBinary = buf.includes(0);
|
|
67000
66208
|
if (isBinary) {
|
|
67001
66209
|
return {
|
|
@@ -67017,20 +66225,20 @@ var WorkspaceBrowser = class {
|
|
|
67017
66225
|
};
|
|
67018
66226
|
|
|
67019
66227
|
// src/skills/agents-scanner.ts
|
|
67020
|
-
var
|
|
66228
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
67021
66229
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
67022
|
-
var
|
|
66230
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
67023
66231
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
67024
66232
|
function isDirLikeSync2(p3) {
|
|
67025
66233
|
try {
|
|
67026
|
-
return
|
|
66234
|
+
return import_node_fs43.default.statSync(p3).isDirectory();
|
|
67027
66235
|
} catch {
|
|
67028
66236
|
return false;
|
|
67029
66237
|
}
|
|
67030
66238
|
}
|
|
67031
66239
|
function fileExistsSync(p3) {
|
|
67032
66240
|
try {
|
|
67033
|
-
return
|
|
66241
|
+
return import_node_fs43.default.statSync(p3).isFile();
|
|
67034
66242
|
} catch {
|
|
67035
66243
|
return false;
|
|
67036
66244
|
}
|
|
@@ -67038,7 +66246,7 @@ function fileExistsSync(p3) {
|
|
|
67038
66246
|
function parseAgentFile(filePath) {
|
|
67039
66247
|
let content;
|
|
67040
66248
|
try {
|
|
67041
|
-
content =
|
|
66249
|
+
content = import_node_fs43.default.readFileSync(filePath, "utf8");
|
|
67042
66250
|
} catch {
|
|
67043
66251
|
return {};
|
|
67044
66252
|
}
|
|
@@ -67051,16 +66259,16 @@ function parseAgentFile(filePath) {
|
|
|
67051
66259
|
function scanAgentsDir(dir, source, seen, out) {
|
|
67052
66260
|
let entries;
|
|
67053
66261
|
try {
|
|
67054
|
-
entries =
|
|
66262
|
+
entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
|
|
67055
66263
|
} catch {
|
|
67056
66264
|
return;
|
|
67057
66265
|
}
|
|
67058
66266
|
for (const ent of entries) {
|
|
67059
66267
|
if (!ent.name.endsWith(".md")) continue;
|
|
67060
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
66268
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path47.default.join(dir, ent.name)))) {
|
|
67061
66269
|
continue;
|
|
67062
66270
|
}
|
|
67063
|
-
const filePath =
|
|
66271
|
+
const filePath = import_node_path47.default.join(dir, ent.name);
|
|
67064
66272
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
67065
66273
|
if (seen.has(baseName)) continue;
|
|
67066
66274
|
seen.add(baseName);
|
|
@@ -67078,12 +66286,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
67078
66286
|
function walk2(dir, namespaces) {
|
|
67079
66287
|
let entries;
|
|
67080
66288
|
try {
|
|
67081
|
-
entries =
|
|
66289
|
+
entries = import_node_fs43.default.readdirSync(dir, { withFileTypes: true });
|
|
67082
66290
|
} catch {
|
|
67083
66291
|
return;
|
|
67084
66292
|
}
|
|
67085
66293
|
for (const ent of entries) {
|
|
67086
|
-
const childPath =
|
|
66294
|
+
const childPath = import_node_path47.default.join(dir, ent.name);
|
|
67087
66295
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
67088
66296
|
walk2(childPath, [...namespaces, ent.name]);
|
|
67089
66297
|
continue;
|
|
@@ -67108,13 +66316,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
67108
66316
|
walk2(root, []);
|
|
67109
66317
|
}
|
|
67110
66318
|
function readInstalledPlugins2(home) {
|
|
67111
|
-
const pluginsDir =
|
|
67112
|
-
const v22 =
|
|
67113
|
-
const v1 =
|
|
66319
|
+
const pluginsDir = import_node_path47.default.join(home, ".claude", "plugins");
|
|
66320
|
+
const v22 = import_node_path47.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
66321
|
+
const v1 = import_node_path47.default.join(pluginsDir, "installed_plugins.json");
|
|
67114
66322
|
let raw = null;
|
|
67115
66323
|
for (const candidate of [v22, v1]) {
|
|
67116
66324
|
try {
|
|
67117
|
-
raw =
|
|
66325
|
+
raw = import_node_fs43.default.readFileSync(candidate, "utf8");
|
|
67118
66326
|
break;
|
|
67119
66327
|
} catch {
|
|
67120
66328
|
}
|
|
@@ -67139,19 +66347,19 @@ function readInstalledPlugins2(home) {
|
|
|
67139
66347
|
return out;
|
|
67140
66348
|
}
|
|
67141
66349
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
67142
|
-
let cur =
|
|
67143
|
-
const fsRoot =
|
|
66350
|
+
let cur = import_node_path47.default.resolve(startCwd);
|
|
66351
|
+
const fsRoot = import_node_path47.default.parse(cur).root;
|
|
67144
66352
|
while (true) {
|
|
67145
|
-
scanAgentsDir(
|
|
66353
|
+
scanAgentsDir(import_node_path47.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
67146
66354
|
let hasGit = false;
|
|
67147
66355
|
try {
|
|
67148
|
-
hasGit =
|
|
66356
|
+
hasGit = import_node_fs43.default.existsSync(import_node_path47.default.join(cur, ".git"));
|
|
67149
66357
|
} catch {
|
|
67150
66358
|
}
|
|
67151
66359
|
if (hasGit) return;
|
|
67152
66360
|
if (cur === home) return;
|
|
67153
66361
|
if (cur === fsRoot) return;
|
|
67154
|
-
const parent =
|
|
66362
|
+
const parent = import_node_path47.default.dirname(cur);
|
|
67155
66363
|
if (parent === cur) return;
|
|
67156
66364
|
cur = parent;
|
|
67157
66365
|
}
|
|
@@ -67186,7 +66394,7 @@ var AgentsScanner = class {
|
|
|
67186
66394
|
}
|
|
67187
66395
|
const fsBlock = [];
|
|
67188
66396
|
scanAgentsDir(
|
|
67189
|
-
|
|
66397
|
+
import_node_path47.default.join(this.home, ".claude", "agents"),
|
|
67190
66398
|
"global",
|
|
67191
66399
|
seen,
|
|
67192
66400
|
fsBlock
|
|
@@ -67200,7 +66408,7 @@ var AgentsScanner = class {
|
|
|
67200
66408
|
...this.extraPluginRoots
|
|
67201
66409
|
];
|
|
67202
66410
|
for (const { name, root } of plugins) {
|
|
67203
|
-
const agentsRoot =
|
|
66411
|
+
const agentsRoot = import_node_path47.default.join(root, "agents");
|
|
67204
66412
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
67205
66413
|
}
|
|
67206
66414
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -67208,15 +66416,15 @@ var AgentsScanner = class {
|
|
|
67208
66416
|
};
|
|
67209
66417
|
|
|
67210
66418
|
// src/observer/session-observer.ts
|
|
67211
|
-
var
|
|
66419
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
67212
66420
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
67213
|
-
var
|
|
66421
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
67214
66422
|
init_claude_history();
|
|
67215
66423
|
|
|
67216
66424
|
// src/observer/subagent-meta-observer.ts
|
|
67217
|
-
var
|
|
66425
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
67218
66426
|
var import_node_os17 = __toESM(require("os"), 1);
|
|
67219
|
-
var
|
|
66427
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
67220
66428
|
init_claude_history();
|
|
67221
66429
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
67222
66430
|
var SubagentMetaObserver = class {
|
|
@@ -67229,7 +66437,7 @@ var SubagentMetaObserver = class {
|
|
|
67229
66437
|
watches = /* @__PURE__ */ new Map();
|
|
67230
66438
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
67231
66439
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
67232
|
-
return
|
|
66440
|
+
return import_node_path48.default.join(
|
|
67233
66441
|
this.home,
|
|
67234
66442
|
".claude",
|
|
67235
66443
|
"projects",
|
|
@@ -67259,7 +66467,7 @@ var SubagentMetaObserver = class {
|
|
|
67259
66467
|
attachWatcher(w3) {
|
|
67260
66468
|
if (w3.watcher) return;
|
|
67261
66469
|
try {
|
|
67262
|
-
w3.watcher =
|
|
66470
|
+
w3.watcher = import_node_fs44.default.watch(w3.dirPath, { persistent: false }, (_evt, name) => {
|
|
67263
66471
|
if (!name) return;
|
|
67264
66472
|
const m3 = META_RE.exec(String(name));
|
|
67265
66473
|
if (!m3) return;
|
|
@@ -67271,7 +66479,7 @@ var SubagentMetaObserver = class {
|
|
|
67271
66479
|
scan(w3) {
|
|
67272
66480
|
let entries;
|
|
67273
66481
|
try {
|
|
67274
|
-
entries =
|
|
66482
|
+
entries = import_node_fs44.default.readdirSync(w3.dirPath);
|
|
67275
66483
|
} catch {
|
|
67276
66484
|
return;
|
|
67277
66485
|
}
|
|
@@ -67285,10 +66493,10 @@ var SubagentMetaObserver = class {
|
|
|
67285
66493
|
if (!m3) return;
|
|
67286
66494
|
const agentId = m3[1];
|
|
67287
66495
|
if (w3.emitted.has(agentId)) return;
|
|
67288
|
-
const file =
|
|
66496
|
+
const file = import_node_path48.default.join(w3.dirPath, name);
|
|
67289
66497
|
let raw;
|
|
67290
66498
|
try {
|
|
67291
|
-
raw =
|
|
66499
|
+
raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
67292
66500
|
} catch {
|
|
67293
66501
|
return;
|
|
67294
66502
|
}
|
|
@@ -67345,14 +66553,14 @@ var SessionObserver = class {
|
|
|
67345
66553
|
metaObserver;
|
|
67346
66554
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
67347
66555
|
if (override) return override;
|
|
67348
|
-
return
|
|
66556
|
+
return import_node_path49.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
67349
66557
|
}
|
|
67350
66558
|
start(args) {
|
|
67351
66559
|
this.stop(args.sessionId);
|
|
67352
66560
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
67353
66561
|
let size = 0;
|
|
67354
66562
|
try {
|
|
67355
|
-
size =
|
|
66563
|
+
size = import_node_fs45.default.statSync(filePath).size;
|
|
67356
66564
|
} catch {
|
|
67357
66565
|
}
|
|
67358
66566
|
const w3 = {
|
|
@@ -67365,16 +66573,16 @@ var SessionObserver = class {
|
|
|
67365
66573
|
adapter: args.adapter,
|
|
67366
66574
|
prevIsRejectSentinel: false,
|
|
67367
66575
|
toolSessionId: args.toolSessionId,
|
|
67368
|
-
sawFile:
|
|
66576
|
+
sawFile: import_node_fs45.default.existsSync(filePath),
|
|
67369
66577
|
lastRelocateScanMs: 0,
|
|
67370
66578
|
pendingCwdDerive: false,
|
|
67371
66579
|
lastDeriveMs: 0
|
|
67372
66580
|
};
|
|
67373
66581
|
try {
|
|
67374
|
-
|
|
66582
|
+
import_node_fs45.default.mkdirSync(import_node_path49.default.dirname(filePath), { recursive: true });
|
|
67375
66583
|
} catch {
|
|
67376
66584
|
}
|
|
67377
|
-
w3.watcher =
|
|
66585
|
+
w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
67378
66586
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
67379
66587
|
this.poll(w3);
|
|
67380
66588
|
});
|
|
@@ -67397,7 +66605,7 @@ var SessionObserver = class {
|
|
|
67397
66605
|
// 异常静默吞,不阻塞 watcher 启动
|
|
67398
66606
|
hydrateMetaTail(w3, maxLines = 200) {
|
|
67399
66607
|
try {
|
|
67400
|
-
const raw =
|
|
66608
|
+
const raw = import_node_fs45.default.readFileSync(w3.filePath, "utf8");
|
|
67401
66609
|
if (!raw) return;
|
|
67402
66610
|
const allLines = raw.split("\n").filter((l2) => l2.trim().length > 0);
|
|
67403
66611
|
if (allLines.length === 0) return;
|
|
@@ -67421,7 +66629,7 @@ var SessionObserver = class {
|
|
|
67421
66629
|
poll(w3) {
|
|
67422
66630
|
let size = 0;
|
|
67423
66631
|
try {
|
|
67424
|
-
size =
|
|
66632
|
+
size = import_node_fs45.default.statSync(w3.filePath).size;
|
|
67425
66633
|
} catch {
|
|
67426
66634
|
if (w3.sawFile) this.maybeRelocate(w3);
|
|
67427
66635
|
return;
|
|
@@ -67432,11 +66640,11 @@ var SessionObserver = class {
|
|
|
67432
66640
|
w3.buf = "";
|
|
67433
66641
|
}
|
|
67434
66642
|
if (size === w3.lastSize) return;
|
|
67435
|
-
const fd =
|
|
66643
|
+
const fd = import_node_fs45.default.openSync(w3.filePath, "r");
|
|
67436
66644
|
try {
|
|
67437
66645
|
const len = size - w3.lastSize;
|
|
67438
66646
|
const buf = Buffer.alloc(len);
|
|
67439
|
-
|
|
66647
|
+
import_node_fs45.default.readSync(fd, buf, 0, len, w3.lastSize);
|
|
67440
66648
|
w3.lastSize = size;
|
|
67441
66649
|
w3.buf += buf.toString("utf8");
|
|
67442
66650
|
let newlineIndex;
|
|
@@ -67459,7 +66667,7 @@ var SessionObserver = class {
|
|
|
67459
66667
|
}
|
|
67460
66668
|
}
|
|
67461
66669
|
} finally {
|
|
67462
|
-
|
|
66670
|
+
import_node_fs45.default.closeSync(fd);
|
|
67463
66671
|
}
|
|
67464
66672
|
if (w3.pendingCwdDerive) this.maybeDeriveCwd(w3);
|
|
67465
66673
|
}
|
|
@@ -67471,7 +66679,7 @@ var SessionObserver = class {
|
|
|
67471
66679
|
const now = Date.now();
|
|
67472
66680
|
if (now - w3.lastRelocateScanMs < 1e3) return;
|
|
67473
66681
|
w3.lastRelocateScanMs = now;
|
|
67474
|
-
const projectsRoot =
|
|
66682
|
+
const projectsRoot = import_node_path49.default.join(this.home, ".claude", "projects");
|
|
67475
66683
|
const found = findTranscriptByToolSessionId(projectsRoot, w3.toolSessionId);
|
|
67476
66684
|
if (!found || found === w3.filePath) return;
|
|
67477
66685
|
try {
|
|
@@ -67480,7 +66688,7 @@ var SessionObserver = class {
|
|
|
67480
66688
|
}
|
|
67481
66689
|
w3.filePath = found;
|
|
67482
66690
|
try {
|
|
67483
|
-
w3.watcher =
|
|
66691
|
+
w3.watcher = import_node_fs45.default.watch(import_node_path49.default.dirname(found), { persistent: false }, (_event, changedName) => {
|
|
67484
66692
|
if (!changedName || !w3.filePath.endsWith(changedName)) return;
|
|
67485
66693
|
this.poll(w3);
|
|
67486
66694
|
});
|
|
@@ -67602,9 +66810,9 @@ function listRegistered() {
|
|
|
67602
66810
|
// src/tools/title-generator.ts
|
|
67603
66811
|
var import_node_child_process13 = require("child_process");
|
|
67604
66812
|
init_protocol();
|
|
67605
|
-
var
|
|
66813
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
67606
66814
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
67607
|
-
var
|
|
66815
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
67608
66816
|
var TITLE_GEN_DIR_PREFIX = "clawd-title-";
|
|
67609
66817
|
var TITLE_INPUT_MAX_CHARS = 400;
|
|
67610
66818
|
var DEFAULT_TITLE_GEN_TIMEOUT_MS = 45e3;
|
|
@@ -67695,21 +66903,21 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
|
|
|
67695
66903
|
}
|
|
67696
66904
|
let workDir;
|
|
67697
66905
|
try {
|
|
67698
|
-
workDir =
|
|
66906
|
+
workDir = import_node_fs46.default.mkdtempSync(import_node_path50.default.join(import_node_os19.default.tmpdir(), TITLE_GEN_DIR_PREFIX));
|
|
67699
66907
|
} catch {
|
|
67700
66908
|
return null;
|
|
67701
66909
|
}
|
|
67702
66910
|
const cleanupWorkDir = () => {
|
|
67703
66911
|
try {
|
|
67704
|
-
|
|
66912
|
+
import_node_fs46.default.rmSync(workDir, { recursive: true, force: true });
|
|
67705
66913
|
} catch {
|
|
67706
66914
|
}
|
|
67707
66915
|
};
|
|
67708
|
-
const outFile =
|
|
67709
|
-
const schemaFile =
|
|
66916
|
+
const outFile = import_node_path50.default.join(workDir, `codex-title-${process.pid}-${++outFileSeq}-${Date.now()}.txt`);
|
|
66917
|
+
const schemaFile = import_node_path50.default.join(workDir, "title-schema.json");
|
|
67710
66918
|
if (tool === "codex") {
|
|
67711
66919
|
try {
|
|
67712
|
-
|
|
66920
|
+
import_node_fs46.default.writeFileSync(schemaFile, CODEX_TITLE_SCHEMA);
|
|
67713
66921
|
} catch {
|
|
67714
66922
|
cleanupWorkDir();
|
|
67715
66923
|
return null;
|
|
@@ -67764,7 +66972,7 @@ async function generateSessionTitle(file, firstMessage, deps = {}) {
|
|
|
67764
66972
|
if (tool === "claude" || tool === "pi") return finish(parseTitleJson(stdout));
|
|
67765
66973
|
let fileText = "";
|
|
67766
66974
|
try {
|
|
67767
|
-
fileText =
|
|
66975
|
+
fileText = import_node_fs46.default.readFileSync(outFile, "utf8");
|
|
67768
66976
|
} catch {
|
|
67769
66977
|
return finish(null);
|
|
67770
66978
|
}
|
|
@@ -67837,7 +67045,7 @@ var wrapper_default = import_websocket.default;
|
|
|
67837
67045
|
|
|
67838
67046
|
// src/transport/local-ws-server.ts
|
|
67839
67047
|
var import_node_http = __toESM(require("http"), 1);
|
|
67840
|
-
var
|
|
67048
|
+
var import_node_crypto15 = require("crypto");
|
|
67841
67049
|
var LocalWsServer = class {
|
|
67842
67050
|
constructor(opts) {
|
|
67843
67051
|
this.opts = opts;
|
|
@@ -68054,7 +67262,7 @@ var LocalWsServer = class {
|
|
|
68054
67262
|
}
|
|
68055
67263
|
}
|
|
68056
67264
|
onConnection(socket, remoteAddress) {
|
|
68057
|
-
const id = (0,
|
|
67265
|
+
const id = (0, import_node_crypto15.randomUUID)();
|
|
68058
67266
|
const subscribedSessions = /* @__PURE__ */ new Map();
|
|
68059
67267
|
const handle = {
|
|
68060
67268
|
id,
|
|
@@ -68460,8 +67668,8 @@ async function authenticate(token, deps) {
|
|
|
68460
67668
|
}
|
|
68461
67669
|
|
|
68462
67670
|
// src/legacy-cleanup.ts
|
|
68463
|
-
var
|
|
68464
|
-
var
|
|
67671
|
+
var fs57 = __toESM(require("fs/promises"), 1);
|
|
67672
|
+
var path58 = __toESM(require("path"), 1);
|
|
68465
67673
|
var LEGACY_FILES = [
|
|
68466
67674
|
"personal-capability.json",
|
|
68467
67675
|
"received-capabilities.json",
|
|
@@ -68470,9 +67678,9 @@ var LEGACY_FILES = [
|
|
|
68470
67678
|
async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
68471
67679
|
const removed = [];
|
|
68472
67680
|
for (const name of LEGACY_FILES) {
|
|
68473
|
-
const p3 =
|
|
67681
|
+
const p3 = path58.join(dataDir, name);
|
|
68474
67682
|
try {
|
|
68475
|
-
await
|
|
67683
|
+
await fs57.unlink(p3);
|
|
68476
67684
|
removed.push(name);
|
|
68477
67685
|
logger.debug("legacy capability file removed", { file: name });
|
|
68478
67686
|
} catch (err) {
|
|
@@ -68484,13 +67692,13 @@ async function cleanupLegacyCapabilityFiles(dataDir, logger) {
|
|
|
68484
67692
|
}
|
|
68485
67693
|
|
|
68486
67694
|
// src/inbox/inbox-store.ts
|
|
68487
|
-
var
|
|
68488
|
-
var
|
|
67695
|
+
var fs58 = __toESM(require("fs"), 1);
|
|
67696
|
+
var path59 = __toESM(require("path"), 1);
|
|
68489
67697
|
var INBOX_SUBDIR = "inbox";
|
|
68490
67698
|
var InboxStore = class {
|
|
68491
67699
|
constructor(dataDir) {
|
|
68492
67700
|
this.dataDir = dataDir;
|
|
68493
|
-
|
|
67701
|
+
fs58.mkdirSync(this.dirPath(), { recursive: true });
|
|
68494
67702
|
}
|
|
68495
67703
|
dataDir;
|
|
68496
67704
|
/**
|
|
@@ -68502,7 +67710,7 @@ var InboxStore = class {
|
|
|
68502
67710
|
const file = this.filePath(peerDeviceId);
|
|
68503
67711
|
let raw;
|
|
68504
67712
|
try {
|
|
68505
|
-
raw =
|
|
67713
|
+
raw = fs58.readFileSync(file, "utf8");
|
|
68506
67714
|
} catch (err) {
|
|
68507
67715
|
if (err?.code === "ENOENT") return [];
|
|
68508
67716
|
return [];
|
|
@@ -68518,7 +67726,7 @@ var InboxStore = class {
|
|
|
68518
67726
|
const dir = this.dirPath();
|
|
68519
67727
|
let entries;
|
|
68520
67728
|
try {
|
|
68521
|
-
entries =
|
|
67729
|
+
entries = fs58.readdirSync(dir);
|
|
68522
67730
|
} catch (err) {
|
|
68523
67731
|
if (err?.code === "ENOENT") return [];
|
|
68524
67732
|
return [];
|
|
@@ -68534,9 +67742,9 @@ var InboxStore = class {
|
|
|
68534
67742
|
if (existing.some((m3) => m3.id === message.id)) return;
|
|
68535
67743
|
const file = this.filePath(message.peerDeviceId);
|
|
68536
67744
|
const line = JSON.stringify(message) + "\n";
|
|
68537
|
-
|
|
67745
|
+
fs58.appendFileSync(file, line, { mode: 384 });
|
|
68538
67746
|
try {
|
|
68539
|
-
|
|
67747
|
+
fs58.chmodSync(file, 384);
|
|
68540
67748
|
} catch {
|
|
68541
67749
|
}
|
|
68542
67750
|
}
|
|
@@ -68566,7 +67774,7 @@ var InboxStore = class {
|
|
|
68566
67774
|
removeByPeerDeviceId(peerDeviceId) {
|
|
68567
67775
|
const file = this.filePath(peerDeviceId);
|
|
68568
67776
|
try {
|
|
68569
|
-
|
|
67777
|
+
fs58.unlinkSync(file);
|
|
68570
67778
|
} catch (err) {
|
|
68571
67779
|
if (err?.code === "ENOENT") return;
|
|
68572
67780
|
}
|
|
@@ -68575,18 +67783,18 @@ var InboxStore = class {
|
|
|
68575
67783
|
const file = this.filePath(peerDeviceId);
|
|
68576
67784
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
68577
67785
|
const content = messages.map((m3) => JSON.stringify(m3)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
68578
|
-
|
|
68579
|
-
|
|
67786
|
+
fs58.writeFileSync(tmp, content, { mode: 384 });
|
|
67787
|
+
fs58.renameSync(tmp, file);
|
|
68580
67788
|
try {
|
|
68581
|
-
|
|
67789
|
+
fs58.chmodSync(file, 384);
|
|
68582
67790
|
} catch {
|
|
68583
67791
|
}
|
|
68584
67792
|
}
|
|
68585
67793
|
dirPath() {
|
|
68586
|
-
return
|
|
67794
|
+
return path59.join(this.dataDir, INBOX_SUBDIR);
|
|
68587
67795
|
}
|
|
68588
67796
|
filePath(peerDeviceId) {
|
|
68589
|
-
return
|
|
67797
|
+
return path59.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
68590
67798
|
}
|
|
68591
67799
|
};
|
|
68592
67800
|
function parseAllLines(raw) {
|
|
@@ -68674,8 +67882,8 @@ var InboxManager = class {
|
|
|
68674
67882
|
};
|
|
68675
67883
|
|
|
68676
67884
|
// src/state/contact-store.ts
|
|
68677
|
-
var
|
|
68678
|
-
var
|
|
67885
|
+
var fs59 = __toESM(require("fs"), 1);
|
|
67886
|
+
var path60 = __toESM(require("path"), 1);
|
|
68679
67887
|
var FILE_NAME = "contacts.json";
|
|
68680
67888
|
var ContactStore = class {
|
|
68681
67889
|
constructor(dataDir) {
|
|
@@ -68685,10 +67893,10 @@ var ContactStore = class {
|
|
|
68685
67893
|
contacts = /* @__PURE__ */ new Map();
|
|
68686
67894
|
load() {
|
|
68687
67895
|
this.contacts.clear();
|
|
68688
|
-
const file =
|
|
67896
|
+
const file = path60.join(this.dataDir, FILE_NAME);
|
|
68689
67897
|
let raw;
|
|
68690
67898
|
try {
|
|
68691
|
-
raw =
|
|
67899
|
+
raw = fs59.readFileSync(file, "utf8");
|
|
68692
67900
|
} catch (err) {
|
|
68693
67901
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
68694
67902
|
return;
|
|
@@ -68769,20 +67977,20 @@ var ContactStore = class {
|
|
|
68769
67977
|
return true;
|
|
68770
67978
|
}
|
|
68771
67979
|
flush() {
|
|
68772
|
-
const file =
|
|
67980
|
+
const file = path60.join(this.dataDir, FILE_NAME);
|
|
68773
67981
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
68774
67982
|
const content = JSON.stringify(
|
|
68775
67983
|
{ contacts: Array.from(this.contacts.values()) },
|
|
68776
67984
|
null,
|
|
68777
67985
|
2
|
|
68778
67986
|
);
|
|
68779
|
-
|
|
68780
|
-
|
|
68781
|
-
|
|
67987
|
+
fs59.mkdirSync(this.dataDir, { recursive: true });
|
|
67988
|
+
fs59.writeFileSync(tmp, content, { mode: 384 });
|
|
67989
|
+
fs59.renameSync(tmp, file);
|
|
68782
67990
|
}
|
|
68783
67991
|
renameBak(file) {
|
|
68784
67992
|
try {
|
|
68785
|
-
|
|
67993
|
+
fs59.renameSync(file, `${file}.bak`);
|
|
68786
67994
|
} catch {
|
|
68787
67995
|
}
|
|
68788
67996
|
}
|
|
@@ -68890,61 +68098,61 @@ async function connectRemote(args) {
|
|
|
68890
68098
|
}
|
|
68891
68099
|
|
|
68892
68100
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
68893
|
-
var
|
|
68894
|
-
var
|
|
68101
|
+
var fs60 = __toESM(require("fs"), 1);
|
|
68102
|
+
var path61 = __toESM(require("path"), 1);
|
|
68895
68103
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
68896
68104
|
function migrateFlattenSessions(opts) {
|
|
68897
68105
|
const dataDir = opts.dataDir;
|
|
68898
68106
|
const now = opts.now ?? Date.now;
|
|
68899
|
-
const sessionsDir =
|
|
68900
|
-
const flagPath =
|
|
68107
|
+
const sessionsDir = path61.join(dataDir, "sessions");
|
|
68108
|
+
const flagPath = path61.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
68901
68109
|
if (existsSync3(flagPath)) {
|
|
68902
68110
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
68903
68111
|
}
|
|
68904
68112
|
let movedBare = 0;
|
|
68905
68113
|
let movedVmOwner = 0;
|
|
68906
68114
|
let archivedListener = 0;
|
|
68907
|
-
const defaultDir =
|
|
68115
|
+
const defaultDir = path61.join(sessionsDir, "default");
|
|
68908
68116
|
if (existsSync3(defaultDir)) {
|
|
68909
68117
|
for (const entry of readdirSafe(defaultDir)) {
|
|
68910
68118
|
if (!entry.endsWith(".json")) continue;
|
|
68911
|
-
const src =
|
|
68912
|
-
const dst =
|
|
68913
|
-
|
|
68119
|
+
const src = path61.join(defaultDir, entry);
|
|
68120
|
+
const dst = path61.join(sessionsDir, entry);
|
|
68121
|
+
fs60.renameSync(src, dst);
|
|
68914
68122
|
movedBare += 1;
|
|
68915
68123
|
}
|
|
68916
68124
|
rmdirIfEmpty(defaultDir);
|
|
68917
68125
|
}
|
|
68918
68126
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
68919
|
-
const personaDir =
|
|
68127
|
+
const personaDir = path61.join(sessionsDir, pid);
|
|
68920
68128
|
if (!isDir(personaDir)) continue;
|
|
68921
68129
|
if (pid === "default") continue;
|
|
68922
|
-
const ownerSrc =
|
|
68130
|
+
const ownerSrc = path61.join(personaDir, "owner");
|
|
68923
68131
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
68924
|
-
const ownerDst =
|
|
68925
|
-
|
|
68132
|
+
const ownerDst = path61.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
68133
|
+
fs60.mkdirSync(ownerDst, { recursive: true });
|
|
68926
68134
|
for (const file of readdirSafe(ownerSrc)) {
|
|
68927
68135
|
if (!file.endsWith(".json")) continue;
|
|
68928
|
-
|
|
68136
|
+
fs60.renameSync(path61.join(ownerSrc, file), path61.join(ownerDst, file));
|
|
68929
68137
|
movedVmOwner += 1;
|
|
68930
68138
|
}
|
|
68931
68139
|
rmdirIfEmpty(ownerSrc);
|
|
68932
68140
|
}
|
|
68933
|
-
const listenerSrc =
|
|
68141
|
+
const listenerSrc = path61.join(personaDir, "listener");
|
|
68934
68142
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
68935
|
-
const archiveDst =
|
|
68936
|
-
|
|
68143
|
+
const archiveDst = path61.join(dataDir, ".legacy", `listener-${pid}`);
|
|
68144
|
+
fs60.mkdirSync(archiveDst, { recursive: true });
|
|
68937
68145
|
for (const file of readdirSafe(listenerSrc)) {
|
|
68938
68146
|
if (!file.endsWith(".json")) continue;
|
|
68939
|
-
|
|
68147
|
+
fs60.renameSync(path61.join(listenerSrc, file), path61.join(archiveDst, file));
|
|
68940
68148
|
archivedListener += 1;
|
|
68941
68149
|
}
|
|
68942
68150
|
rmdirIfEmpty(listenerSrc);
|
|
68943
68151
|
}
|
|
68944
68152
|
rmdirIfEmpty(personaDir);
|
|
68945
68153
|
}
|
|
68946
|
-
|
|
68947
|
-
|
|
68154
|
+
fs60.mkdirSync(sessionsDir, { recursive: true });
|
|
68155
|
+
fs60.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
68948
68156
|
return {
|
|
68949
68157
|
skipped: false,
|
|
68950
68158
|
flagWritten: true,
|
|
@@ -68955,7 +68163,7 @@ function migrateFlattenSessions(opts) {
|
|
|
68955
68163
|
}
|
|
68956
68164
|
function existsSync3(p3) {
|
|
68957
68165
|
try {
|
|
68958
|
-
|
|
68166
|
+
fs60.statSync(p3);
|
|
68959
68167
|
return true;
|
|
68960
68168
|
} catch {
|
|
68961
68169
|
return false;
|
|
@@ -68963,63 +68171,63 @@ function existsSync3(p3) {
|
|
|
68963
68171
|
}
|
|
68964
68172
|
function isDir(p3) {
|
|
68965
68173
|
try {
|
|
68966
|
-
return
|
|
68174
|
+
return fs60.statSync(p3).isDirectory();
|
|
68967
68175
|
} catch {
|
|
68968
68176
|
return false;
|
|
68969
68177
|
}
|
|
68970
68178
|
}
|
|
68971
68179
|
function readdirSafe(p3) {
|
|
68972
68180
|
try {
|
|
68973
|
-
return
|
|
68181
|
+
return fs60.readdirSync(p3);
|
|
68974
68182
|
} catch {
|
|
68975
68183
|
return [];
|
|
68976
68184
|
}
|
|
68977
68185
|
}
|
|
68978
68186
|
function rmdirIfEmpty(p3) {
|
|
68979
68187
|
try {
|
|
68980
|
-
|
|
68188
|
+
fs60.rmdirSync(p3);
|
|
68981
68189
|
} catch {
|
|
68982
68190
|
}
|
|
68983
68191
|
}
|
|
68984
68192
|
|
|
68985
68193
|
// src/migrations/2026-08-18-drop-seeded-projects.ts
|
|
68986
|
-
var
|
|
68987
|
-
var
|
|
68194
|
+
var fs61 = __toESM(require("fs"), 1);
|
|
68195
|
+
var path62 = __toESM(require("path"), 1);
|
|
68988
68196
|
var DROP_SEEDED_PROJECTS_FLAG = ".projects-seed-dropped.v1.done";
|
|
68989
68197
|
function dropSeededProjects(opts) {
|
|
68990
|
-
|
|
68991
|
-
const flag =
|
|
68992
|
-
if (
|
|
68993
|
-
const file =
|
|
68198
|
+
fs61.mkdirSync(opts.dataDir, { recursive: true });
|
|
68199
|
+
const flag = path62.join(opts.dataDir, DROP_SEEDED_PROJECTS_FLAG);
|
|
68200
|
+
if (fs61.existsSync(flag)) return { skipped: true, dropped: 0, backup: null };
|
|
68201
|
+
const file = path62.join(opts.dataDir, "projects.json");
|
|
68994
68202
|
let raw = null;
|
|
68995
68203
|
let dropped = 0;
|
|
68996
68204
|
try {
|
|
68997
|
-
raw =
|
|
68205
|
+
raw = fs61.readFileSync(file, "utf8");
|
|
68998
68206
|
dropped = JSON.parse(raw).projects?.length ?? 0;
|
|
68999
68207
|
} catch {
|
|
69000
68208
|
}
|
|
69001
68209
|
let backup = null;
|
|
69002
68210
|
if (raw != null && dropped > 0) {
|
|
69003
|
-
const dir =
|
|
69004
|
-
|
|
69005
|
-
backup =
|
|
69006
|
-
|
|
68211
|
+
const dir = path62.join(opts.dataDir, "backups");
|
|
68212
|
+
fs61.mkdirSync(dir, { recursive: true });
|
|
68213
|
+
backup = path62.join(dir, `projects.seed-dropped.${(opts.now ?? Date.now)()}.json`);
|
|
68214
|
+
fs61.writeFileSync(backup, raw);
|
|
69007
68215
|
}
|
|
69008
68216
|
if (raw != null || dropped > 0) {
|
|
69009
|
-
|
|
68217
|
+
fs61.writeFileSync(file, JSON.stringify({ projects: [] }, null, 2));
|
|
69010
68218
|
}
|
|
69011
|
-
|
|
68219
|
+
fs61.writeFileSync(flag, (/* @__PURE__ */ new Date()).toISOString());
|
|
69012
68220
|
return { skipped: false, dropped, backup };
|
|
69013
68221
|
}
|
|
69014
68222
|
|
|
69015
68223
|
// src/transport/http-router.ts
|
|
69016
|
-
var
|
|
69017
|
-
var
|
|
68224
|
+
var import_node_fs48 = __toESM(require("fs"), 1);
|
|
68225
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
69018
68226
|
|
|
69019
68227
|
// src/attachment/upload.ts
|
|
69020
|
-
var
|
|
69021
|
-
var
|
|
69022
|
-
var
|
|
68228
|
+
var import_node_fs47 = __toESM(require("fs"), 1);
|
|
68229
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
68230
|
+
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
69023
68231
|
var import_promises8 = require("stream/promises");
|
|
69024
68232
|
var UploadError = class extends Error {
|
|
69025
68233
|
constructor(code, message) {
|
|
@@ -69030,24 +68238,24 @@ var UploadError = class extends Error {
|
|
|
69030
68238
|
code;
|
|
69031
68239
|
};
|
|
69032
68240
|
function assertValidFileName(fileName) {
|
|
69033
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
68241
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path51.default.basename(fileName)) {
|
|
69034
68242
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
69035
68243
|
}
|
|
69036
68244
|
}
|
|
69037
68245
|
var HASH_PREFIX_LEN = 16;
|
|
69038
68246
|
async function writeUploadedAttachment(args) {
|
|
69039
68247
|
assertValidFileName(args.fileName);
|
|
69040
|
-
const attachmentsRoot =
|
|
68248
|
+
const attachmentsRoot = import_node_path51.default.join(args.baseDir, ".attachments");
|
|
69041
68249
|
try {
|
|
69042
|
-
|
|
68250
|
+
import_node_fs47.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
69043
68251
|
} catch (err) {
|
|
69044
68252
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
69045
68253
|
}
|
|
69046
|
-
const hasher =
|
|
68254
|
+
const hasher = import_node_crypto16.default.createHash("sha256");
|
|
69047
68255
|
let actualSize = 0;
|
|
69048
|
-
const tmpPath =
|
|
68256
|
+
const tmpPath = import_node_path51.default.join(
|
|
69049
68257
|
attachmentsRoot,
|
|
69050
|
-
`.upload-${process.pid}-${Date.now()}-${
|
|
68258
|
+
`.upload-${process.pid}-${Date.now()}-${import_node_crypto16.default.randomBytes(4).toString("hex")}`
|
|
69051
68259
|
);
|
|
69052
68260
|
try {
|
|
69053
68261
|
await (0, import_promises8.pipeline)(
|
|
@@ -69060,18 +68268,18 @@ async function writeUploadedAttachment(args) {
|
|
|
69060
68268
|
yield buf;
|
|
69061
68269
|
}
|
|
69062
68270
|
},
|
|
69063
|
-
|
|
68271
|
+
import_node_fs47.default.createWriteStream(tmpPath, { mode: 384 })
|
|
69064
68272
|
);
|
|
69065
68273
|
} catch (err) {
|
|
69066
68274
|
try {
|
|
69067
|
-
|
|
68275
|
+
import_node_fs47.default.unlinkSync(tmpPath);
|
|
69068
68276
|
} catch {
|
|
69069
68277
|
}
|
|
69070
68278
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
69071
68279
|
}
|
|
69072
68280
|
if (actualSize !== args.contentLength) {
|
|
69073
68281
|
try {
|
|
69074
|
-
|
|
68282
|
+
import_node_fs47.default.unlinkSync(tmpPath);
|
|
69075
68283
|
} catch {
|
|
69076
68284
|
}
|
|
69077
68285
|
throw new UploadError(
|
|
@@ -69080,34 +68288,34 @@ async function writeUploadedAttachment(args) {
|
|
|
69080
68288
|
);
|
|
69081
68289
|
}
|
|
69082
68290
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
69083
|
-
const hashDir =
|
|
68291
|
+
const hashDir = import_node_path51.default.join(attachmentsRoot, attachmentId);
|
|
69084
68292
|
let finalFileName;
|
|
69085
68293
|
let hashDirExists = false;
|
|
69086
68294
|
try {
|
|
69087
|
-
hashDirExists =
|
|
68295
|
+
hashDirExists = import_node_fs47.default.statSync(hashDir).isDirectory();
|
|
69088
68296
|
} catch {
|
|
69089
68297
|
}
|
|
69090
68298
|
if (hashDirExists) {
|
|
69091
|
-
const existing =
|
|
68299
|
+
const existing = import_node_fs47.default.readdirSync(hashDir).filter((n2) => !n2.startsWith("."));
|
|
69092
68300
|
finalFileName = existing[0] ?? args.fileName;
|
|
69093
68301
|
try {
|
|
69094
|
-
|
|
68302
|
+
import_node_fs47.default.unlinkSync(tmpPath);
|
|
69095
68303
|
} catch {
|
|
69096
68304
|
}
|
|
69097
68305
|
} else {
|
|
69098
68306
|
try {
|
|
69099
|
-
|
|
68307
|
+
import_node_fs47.default.mkdirSync(hashDir, { recursive: true });
|
|
69100
68308
|
finalFileName = args.fileName;
|
|
69101
|
-
|
|
68309
|
+
import_node_fs47.default.renameSync(tmpPath, import_node_path51.default.join(hashDir, finalFileName));
|
|
69102
68310
|
} catch (err) {
|
|
69103
68311
|
try {
|
|
69104
|
-
|
|
68312
|
+
import_node_fs47.default.unlinkSync(tmpPath);
|
|
69105
68313
|
} catch {
|
|
69106
68314
|
}
|
|
69107
68315
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
69108
68316
|
}
|
|
69109
68317
|
}
|
|
69110
|
-
const absPath =
|
|
68318
|
+
const absPath = import_node_path51.default.join(hashDir, finalFileName);
|
|
69111
68319
|
const relPath = absPath;
|
|
69112
68320
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
69113
68321
|
relPath: absPath,
|
|
@@ -69122,7 +68330,7 @@ async function writeUploadedAttachment(args) {
|
|
|
69122
68330
|
|
|
69123
68331
|
// src/extension/import.ts
|
|
69124
68332
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
69125
|
-
var
|
|
68333
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
69126
68334
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
69127
68335
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
69128
68336
|
var ImportError = class extends Error {
|
|
@@ -69140,7 +68348,7 @@ async function importZip(buf, root) {
|
|
|
69140
68348
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
69141
68349
|
}
|
|
69142
68350
|
for (const name of Object.keys(zip.files)) {
|
|
69143
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
68351
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
|
|
69144
68352
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
69145
68353
|
}
|
|
69146
68354
|
}
|
|
@@ -69173,7 +68381,7 @@ async function importZip(buf, root) {
|
|
|
69173
68381
|
);
|
|
69174
68382
|
}
|
|
69175
68383
|
}
|
|
69176
|
-
const destDir =
|
|
68384
|
+
const destDir = import_node_path52.default.join(root, manifest.id);
|
|
69177
68385
|
let destExists = false;
|
|
69178
68386
|
try {
|
|
69179
68387
|
await import_promises9.default.access(destDir);
|
|
@@ -69183,15 +68391,15 @@ async function importZip(buf, root) {
|
|
|
69183
68391
|
if (destExists) {
|
|
69184
68392
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
69185
68393
|
}
|
|
69186
|
-
const stage = await import_promises9.default.mkdtemp(
|
|
68394
|
+
const stage = await import_promises9.default.mkdtemp(import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
69187
68395
|
try {
|
|
69188
68396
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
69189
|
-
const dest =
|
|
68397
|
+
const dest = import_node_path52.default.join(stage, name);
|
|
69190
68398
|
if (entry.dir) {
|
|
69191
68399
|
await import_promises9.default.mkdir(dest, { recursive: true });
|
|
69192
68400
|
continue;
|
|
69193
68401
|
}
|
|
69194
|
-
await import_promises9.default.mkdir(
|
|
68402
|
+
await import_promises9.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
|
|
69195
68403
|
const content = await entry.async("nodebuffer");
|
|
69196
68404
|
await import_promises9.default.writeFile(dest, content);
|
|
69197
68405
|
}
|
|
@@ -69245,7 +68453,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
69245
68453
|
".wasm": "application/wasm"
|
|
69246
68454
|
};
|
|
69247
68455
|
function shareUiAssetMime(filePath) {
|
|
69248
|
-
const ext =
|
|
68456
|
+
const ext = import_node_path53.default.extname(filePath).toLowerCase();
|
|
69249
68457
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
69250
68458
|
}
|
|
69251
68459
|
var AUTHED_RPC_ROUTE_PREFIX = "/rpc/";
|
|
@@ -69344,7 +68552,7 @@ function isValidUploadFileName(fileName) {
|
|
|
69344
68552
|
if (fileName === "." || fileName === "..") return false;
|
|
69345
68553
|
if (fileName.startsWith(".")) return false;
|
|
69346
68554
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
69347
|
-
return fileName ===
|
|
68555
|
+
return fileName === import_node_path53.default.basename(fileName);
|
|
69348
68556
|
}
|
|
69349
68557
|
function createHttpRouter(deps) {
|
|
69350
68558
|
return async (req, res) => {
|
|
@@ -69428,7 +68636,7 @@ function createHttpRouter(deps) {
|
|
|
69428
68636
|
}
|
|
69429
68637
|
let buf;
|
|
69430
68638
|
try {
|
|
69431
|
-
buf = await
|
|
68639
|
+
buf = await import_node_fs48.default.promises.readFile(abs);
|
|
69432
68640
|
} catch {
|
|
69433
68641
|
sendJson2(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
69434
68642
|
return true;
|
|
@@ -69574,7 +68782,7 @@ function createHttpRouter(deps) {
|
|
|
69574
68782
|
sendHtml(res, statusByCode[r2.code], loader.renderErrorHtml(r2.code, msgByCode[r2.code]));
|
|
69575
68783
|
return true;
|
|
69576
68784
|
}
|
|
69577
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
68785
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path53.default.basename(r2.absPath)));
|
|
69578
68786
|
return true;
|
|
69579
68787
|
}
|
|
69580
68788
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -69695,7 +68903,7 @@ function createHttpRouter(deps) {
|
|
|
69695
68903
|
return true;
|
|
69696
68904
|
}
|
|
69697
68905
|
let absPath;
|
|
69698
|
-
if (
|
|
68906
|
+
if (import_node_path53.default.isAbsolute(pathParam)) {
|
|
69699
68907
|
absPath = pathParam;
|
|
69700
68908
|
} else if (deps.sessionStore) {
|
|
69701
68909
|
const file = deps.sessionStore.read(sid);
|
|
@@ -69703,7 +68911,7 @@ function createHttpRouter(deps) {
|
|
|
69703
68911
|
sendJson2(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
69704
68912
|
return true;
|
|
69705
68913
|
}
|
|
69706
|
-
absPath =
|
|
68914
|
+
absPath = import_node_path53.default.join(file.cwd, pathParam);
|
|
69707
68915
|
} else {
|
|
69708
68916
|
sendJson2(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
69709
68917
|
return true;
|
|
@@ -69787,7 +68995,7 @@ function withCtx(ctx, body) {
|
|
|
69787
68995
|
function streamFile(res, absPath, logger) {
|
|
69788
68996
|
let stat;
|
|
69789
68997
|
try {
|
|
69790
|
-
stat =
|
|
68998
|
+
stat = import_node_fs48.default.statSync(absPath);
|
|
69791
68999
|
} catch (err) {
|
|
69792
69000
|
const code = err?.code;
|
|
69793
69001
|
if (code === "ENOENT") {
|
|
@@ -69802,7 +69010,7 @@ function streamFile(res, absPath, logger) {
|
|
|
69802
69010
|
return;
|
|
69803
69011
|
}
|
|
69804
69012
|
const mime = lookupMime(absPath);
|
|
69805
|
-
const basename2 =
|
|
69013
|
+
const basename2 = import_node_path53.default.basename(absPath);
|
|
69806
69014
|
res.writeHead(200, {
|
|
69807
69015
|
"Content-Type": mime,
|
|
69808
69016
|
"Content-Length": String(stat.size),
|
|
@@ -69810,7 +69018,7 @@ function streamFile(res, absPath, logger) {
|
|
|
69810
69018
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
69811
69019
|
"X-Content-Type-Options": "nosniff"
|
|
69812
69020
|
});
|
|
69813
|
-
const stream =
|
|
69021
|
+
const stream = import_node_fs48.default.createReadStream(absPath);
|
|
69814
69022
|
stream.on("error", (err) => {
|
|
69815
69023
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
69816
69024
|
res.destroy();
|
|
@@ -69819,8 +69027,8 @@ function streamFile(res, absPath, logger) {
|
|
|
69819
69027
|
}
|
|
69820
69028
|
|
|
69821
69029
|
// src/attachment/gc.ts
|
|
69822
|
-
var
|
|
69823
|
-
var
|
|
69030
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
69031
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
69824
69032
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
69825
69033
|
function runAttachmentGc(args) {
|
|
69826
69034
|
const now = (args.now ?? Date.now)();
|
|
@@ -69829,12 +69037,12 @@ function runAttachmentGc(args) {
|
|
|
69829
69037
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
69830
69038
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
69831
69039
|
if (entry.stale) continue;
|
|
69832
|
-
if (
|
|
69040
|
+
if (import_node_path54.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
69833
69041
|
}
|
|
69834
69042
|
}
|
|
69835
69043
|
const visited = /* @__PURE__ */ new Set();
|
|
69836
69044
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
69837
|
-
const legacyDir = args.getSessionCwd?.(sessionId) ??
|
|
69045
|
+
const legacyDir = args.getSessionCwd?.(sessionId) ?? import_node_path54.default.join(
|
|
69838
69046
|
args.dataDir,
|
|
69839
69047
|
"sessions",
|
|
69840
69048
|
...scopeSubPath(scope).map(safeFileName),
|
|
@@ -69847,28 +69055,28 @@ function runAttachmentGc(args) {
|
|
|
69847
69055
|
return true;
|
|
69848
69056
|
});
|
|
69849
69057
|
for (const rootDir of roots) {
|
|
69850
|
-
const attRoot =
|
|
69058
|
+
const attRoot = import_node_path54.default.join(rootDir, ".attachments");
|
|
69851
69059
|
let hashDirs;
|
|
69852
69060
|
try {
|
|
69853
|
-
hashDirs =
|
|
69061
|
+
hashDirs = import_node_fs49.default.readdirSync(attRoot);
|
|
69854
69062
|
} catch (err) {
|
|
69855
69063
|
if (err.code === "ENOENT") continue;
|
|
69856
69064
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
69857
69065
|
continue;
|
|
69858
69066
|
}
|
|
69859
69067
|
for (const hashDir of hashDirs) {
|
|
69860
|
-
const hashDirAbs =
|
|
69068
|
+
const hashDirAbs = import_node_path54.default.join(attRoot, hashDir);
|
|
69861
69069
|
let files;
|
|
69862
69070
|
try {
|
|
69863
|
-
files =
|
|
69071
|
+
files = import_node_fs49.default.readdirSync(hashDirAbs);
|
|
69864
69072
|
} catch {
|
|
69865
69073
|
continue;
|
|
69866
69074
|
}
|
|
69867
69075
|
for (const name of files) {
|
|
69868
|
-
const file =
|
|
69076
|
+
const file = import_node_path54.default.join(hashDirAbs, name);
|
|
69869
69077
|
let stat;
|
|
69870
69078
|
try {
|
|
69871
|
-
stat =
|
|
69079
|
+
stat = import_node_fs49.default.statSync(file);
|
|
69872
69080
|
} catch {
|
|
69873
69081
|
continue;
|
|
69874
69082
|
}
|
|
@@ -69877,18 +69085,18 @@ function runAttachmentGc(args) {
|
|
|
69877
69085
|
if (age < ttlMs) continue;
|
|
69878
69086
|
if (liveAbs.has(file)) continue;
|
|
69879
69087
|
try {
|
|
69880
|
-
|
|
69088
|
+
import_node_fs49.default.unlinkSync(file);
|
|
69881
69089
|
} catch (err) {
|
|
69882
69090
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
69883
69091
|
}
|
|
69884
69092
|
}
|
|
69885
69093
|
try {
|
|
69886
|
-
if (
|
|
69094
|
+
if (import_node_fs49.default.readdirSync(hashDirAbs).length === 0) import_node_fs49.default.rmdirSync(hashDirAbs);
|
|
69887
69095
|
} catch {
|
|
69888
69096
|
}
|
|
69889
69097
|
}
|
|
69890
69098
|
try {
|
|
69891
|
-
if (
|
|
69099
|
+
if (import_node_fs49.default.readdirSync(attRoot).length === 0) import_node_fs49.default.rmdirSync(attRoot);
|
|
69892
69100
|
} catch {
|
|
69893
69101
|
}
|
|
69894
69102
|
}
|
|
@@ -69896,9 +69104,9 @@ function runAttachmentGc(args) {
|
|
|
69896
69104
|
}
|
|
69897
69105
|
|
|
69898
69106
|
// src/attachment/group.ts
|
|
69899
|
-
var
|
|
69900
|
-
var
|
|
69901
|
-
var
|
|
69107
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
69108
|
+
var import_node_path55 = __toESM(require("path"), 1);
|
|
69109
|
+
var import_node_crypto17 = __toESM(require("crypto"), 1);
|
|
69902
69110
|
init_protocol();
|
|
69903
69111
|
var GroupFileStore = class {
|
|
69904
69112
|
dataDir;
|
|
@@ -69909,11 +69117,11 @@ var GroupFileStore = class {
|
|
|
69909
69117
|
this.logger = opts.logger;
|
|
69910
69118
|
}
|
|
69911
69119
|
rootForScope(scope) {
|
|
69912
|
-
return
|
|
69120
|
+
return import_node_path55.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
69913
69121
|
}
|
|
69914
69122
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
69915
69123
|
filePath(scope, sessionId) {
|
|
69916
|
-
return
|
|
69124
|
+
return import_node_path55.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
69917
69125
|
}
|
|
69918
69126
|
cacheKey(scope, sessionId) {
|
|
69919
69127
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -69922,7 +69130,7 @@ var GroupFileStore = class {
|
|
|
69922
69130
|
readFile(scope, sessionId) {
|
|
69923
69131
|
const file = this.filePath(scope, sessionId);
|
|
69924
69132
|
try {
|
|
69925
|
-
const raw =
|
|
69133
|
+
const raw = import_node_fs50.default.readFileSync(file, "utf8");
|
|
69926
69134
|
const parsed = JSON.parse(raw);
|
|
69927
69135
|
if (!Array.isArray(parsed)) {
|
|
69928
69136
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -69948,10 +69156,10 @@ var GroupFileStore = class {
|
|
|
69948
69156
|
}
|
|
69949
69157
|
writeFile(scope, sessionId, entries) {
|
|
69950
69158
|
const file = this.filePath(scope, sessionId);
|
|
69951
|
-
|
|
69159
|
+
import_node_fs50.default.mkdirSync(import_node_path55.default.dirname(file), { recursive: true });
|
|
69952
69160
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
69953
|
-
|
|
69954
|
-
|
|
69161
|
+
import_node_fs50.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
69162
|
+
import_node_fs50.default.renameSync(tmp, file);
|
|
69955
69163
|
}
|
|
69956
69164
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
69957
69165
|
list(scope, sessionId) {
|
|
@@ -69987,7 +69195,7 @@ var GroupFileStore = class {
|
|
|
69987
69195
|
entries[idx] = next;
|
|
69988
69196
|
} else {
|
|
69989
69197
|
next = {
|
|
69990
|
-
id: `gf-${
|
|
69198
|
+
id: `gf-${import_node_crypto17.default.randomBytes(6).toString("base64url")}`,
|
|
69991
69199
|
relPath: input.relPath,
|
|
69992
69200
|
from: input.from,
|
|
69993
69201
|
label: input.label,
|
|
@@ -70043,7 +69251,7 @@ var GroupFileStore = class {
|
|
|
70043
69251
|
*/
|
|
70044
69252
|
deleteSession(scope, sessionId) {
|
|
70045
69253
|
try {
|
|
70046
|
-
|
|
69254
|
+
import_node_fs50.default.unlinkSync(this.filePath(scope, sessionId));
|
|
70047
69255
|
} catch (err) {
|
|
70048
69256
|
if (err?.code !== "ENOENT") throw err;
|
|
70049
69257
|
}
|
|
@@ -70056,7 +69264,7 @@ var GroupFileStore = class {
|
|
|
70056
69264
|
* 不在 persona 目录里(见文件头的路径约定)。没树的 persona 是 noop。
|
|
70057
69265
|
*/
|
|
70058
69266
|
deletePersona(personaId2) {
|
|
70059
|
-
|
|
69267
|
+
import_node_fs50.default.rmSync(import_node_path55.default.join(this.dataDir, "sessions", safeFileName(personaId2)), { recursive: true, force: true });
|
|
70060
69268
|
const prefix = `persona:${personaId2}:`;
|
|
70061
69269
|
for (const key of this.cache.keys()) {
|
|
70062
69270
|
if (key.startsWith(prefix)) this.cache.delete(key);
|
|
@@ -70065,10 +69273,10 @@ var GroupFileStore = class {
|
|
|
70065
69273
|
};
|
|
70066
69274
|
|
|
70067
69275
|
// src/discovery/state-file.ts
|
|
70068
|
-
var
|
|
70069
|
-
var
|
|
69276
|
+
var import_node_fs51 = __toESM(require("fs"), 1);
|
|
69277
|
+
var import_node_path56 = __toESM(require("path"), 1);
|
|
70070
69278
|
function defaultStateFilePath(dataDir) {
|
|
70071
|
-
return
|
|
69279
|
+
return import_node_path56.default.join(dataDir, "state.json");
|
|
70072
69280
|
}
|
|
70073
69281
|
function isPidAlive(pid) {
|
|
70074
69282
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -70090,7 +69298,7 @@ var StateFileManager = class {
|
|
|
70090
69298
|
}
|
|
70091
69299
|
read() {
|
|
70092
69300
|
try {
|
|
70093
|
-
const raw =
|
|
69301
|
+
const raw = import_node_fs51.default.readFileSync(this.file, "utf8");
|
|
70094
69302
|
const parsed = JSON.parse(raw);
|
|
70095
69303
|
return parsed;
|
|
70096
69304
|
} catch {
|
|
@@ -70104,20 +69312,20 @@ var StateFileManager = class {
|
|
|
70104
69312
|
return { status: "stale", existing };
|
|
70105
69313
|
}
|
|
70106
69314
|
write(state) {
|
|
70107
|
-
|
|
69315
|
+
import_node_fs51.default.mkdirSync(import_node_path56.default.dirname(this.file), { recursive: true });
|
|
70108
69316
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
70109
|
-
|
|
70110
|
-
|
|
69317
|
+
import_node_fs51.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
69318
|
+
import_node_fs51.default.renameSync(tmp, this.file);
|
|
70111
69319
|
if (process.platform !== "win32") {
|
|
70112
69320
|
try {
|
|
70113
|
-
|
|
69321
|
+
import_node_fs51.default.chmodSync(this.file, 384);
|
|
70114
69322
|
} catch {
|
|
70115
69323
|
}
|
|
70116
69324
|
}
|
|
70117
69325
|
}
|
|
70118
69326
|
delete() {
|
|
70119
69327
|
try {
|
|
70120
|
-
|
|
69328
|
+
import_node_fs51.default.unlinkSync(this.file);
|
|
70121
69329
|
} catch {
|
|
70122
69330
|
}
|
|
70123
69331
|
}
|
|
@@ -70131,14 +69339,14 @@ function readSpawnedByDesktopFromEnv(env = process.env) {
|
|
|
70131
69339
|
}
|
|
70132
69340
|
|
|
70133
69341
|
// src/tunnel/tunnel-manager.ts
|
|
70134
|
-
var
|
|
70135
|
-
var
|
|
70136
|
-
var
|
|
69342
|
+
var import_node_fs55 = __toESM(require("fs"), 1);
|
|
69343
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
69344
|
+
var import_node_crypto18 = __toESM(require("crypto"), 1);
|
|
70137
69345
|
var import_node_child_process16 = require("child_process");
|
|
70138
69346
|
|
|
70139
69347
|
// src/tunnel/tunnel-store.ts
|
|
70140
|
-
var
|
|
70141
|
-
var
|
|
69348
|
+
var import_node_fs52 = __toESM(require("fs"), 1);
|
|
69349
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
70142
69350
|
var TunnelStore = class {
|
|
70143
69351
|
constructor(filePath) {
|
|
70144
69352
|
this.filePath = filePath;
|
|
@@ -70146,7 +69354,7 @@ var TunnelStore = class {
|
|
|
70146
69354
|
filePath;
|
|
70147
69355
|
async get() {
|
|
70148
69356
|
try {
|
|
70149
|
-
const raw = await
|
|
69357
|
+
const raw = await import_node_fs52.default.promises.readFile(this.filePath, "utf8");
|
|
70150
69358
|
const obj = JSON.parse(raw);
|
|
70151
69359
|
if (!isPersistedTunnel(obj)) return null;
|
|
70152
69360
|
return obj;
|
|
@@ -70157,22 +69365,22 @@ var TunnelStore = class {
|
|
|
70157
69365
|
}
|
|
70158
69366
|
}
|
|
70159
69367
|
async set(v3) {
|
|
70160
|
-
const dir =
|
|
70161
|
-
await
|
|
69368
|
+
const dir = import_node_path57.default.dirname(this.filePath);
|
|
69369
|
+
await import_node_fs52.default.promises.mkdir(dir, { recursive: true });
|
|
70162
69370
|
const data = JSON.stringify(v3, null, 2);
|
|
70163
69371
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
70164
|
-
await
|
|
69372
|
+
await import_node_fs52.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
70165
69373
|
if (process.platform !== "win32") {
|
|
70166
69374
|
try {
|
|
70167
|
-
await
|
|
69375
|
+
await import_node_fs52.default.promises.chmod(tmp, 384);
|
|
70168
69376
|
} catch {
|
|
70169
69377
|
}
|
|
70170
69378
|
}
|
|
70171
|
-
await
|
|
69379
|
+
await import_node_fs52.default.promises.rename(tmp, this.filePath);
|
|
70172
69380
|
}
|
|
70173
69381
|
async clear() {
|
|
70174
69382
|
try {
|
|
70175
|
-
await
|
|
69383
|
+
await import_node_fs52.default.promises.unlink(this.filePath);
|
|
70176
69384
|
} catch (err) {
|
|
70177
69385
|
const code = err?.code;
|
|
70178
69386
|
if (code !== "ENOENT") throw err;
|
|
@@ -70267,9 +69475,9 @@ function escape2(v3) {
|
|
|
70267
69475
|
}
|
|
70268
69476
|
|
|
70269
69477
|
// src/tunnel/frpc-binary.ts
|
|
70270
|
-
var
|
|
69478
|
+
var import_node_fs53 = __toESM(require("fs"), 1);
|
|
70271
69479
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
70272
|
-
var
|
|
69480
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
70273
69481
|
var import_node_child_process14 = require("child_process");
|
|
70274
69482
|
var import_node_stream4 = require("stream");
|
|
70275
69483
|
var import_promises10 = require("stream/promises");
|
|
@@ -70301,20 +69509,20 @@ function frpcDownloadUrl(version2, p3) {
|
|
|
70301
69509
|
}
|
|
70302
69510
|
async function ensureFrpcBinary(opts) {
|
|
70303
69511
|
if (opts.override) {
|
|
70304
|
-
if (!
|
|
69512
|
+
if (!import_node_fs53.default.existsSync(opts.override)) {
|
|
70305
69513
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
70306
69514
|
}
|
|
70307
69515
|
return opts.override;
|
|
70308
69516
|
}
|
|
70309
69517
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
70310
69518
|
const platform = opts.platform ?? detectPlatform();
|
|
70311
|
-
const binDir =
|
|
70312
|
-
|
|
69519
|
+
const binDir = import_node_path58.default.join(opts.dataDir, "bin");
|
|
69520
|
+
import_node_fs53.default.mkdirSync(binDir, { recursive: true });
|
|
70313
69521
|
cleanupStaleArtifacts(binDir);
|
|
70314
|
-
const stableBin =
|
|
70315
|
-
if (
|
|
69522
|
+
const stableBin = import_node_path58.default.join(binDir, "frpc");
|
|
69523
|
+
if (import_node_fs53.default.existsSync(stableBin)) return stableBin;
|
|
70316
69524
|
const partialBin = `${stableBin}.partial`;
|
|
70317
|
-
const tarballPath =
|
|
69525
|
+
const tarballPath = import_node_path58.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
70318
69526
|
try {
|
|
70319
69527
|
const url = frpcDownloadUrl(version2, platform);
|
|
70320
69528
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -70323,8 +69531,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
70323
69531
|
} else {
|
|
70324
69532
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
70325
69533
|
}
|
|
70326
|
-
|
|
70327
|
-
|
|
69534
|
+
import_node_fs53.default.chmodSync(partialBin, 493);
|
|
69535
|
+
import_node_fs53.default.renameSync(partialBin, stableBin);
|
|
70328
69536
|
} finally {
|
|
70329
69537
|
safeUnlink(tarballPath);
|
|
70330
69538
|
safeUnlink(partialBin);
|
|
@@ -70334,15 +69542,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
70334
69542
|
function cleanupStaleArtifacts(binDir) {
|
|
70335
69543
|
let entries;
|
|
70336
69544
|
try {
|
|
70337
|
-
entries =
|
|
69545
|
+
entries = import_node_fs53.default.readdirSync(binDir);
|
|
70338
69546
|
} catch {
|
|
70339
69547
|
return;
|
|
70340
69548
|
}
|
|
70341
69549
|
for (const name of entries) {
|
|
70342
69550
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
70343
|
-
const full =
|
|
69551
|
+
const full = import_node_path58.default.join(binDir, name);
|
|
70344
69552
|
try {
|
|
70345
|
-
|
|
69553
|
+
import_node_fs53.default.rmSync(full, { recursive: true, force: true });
|
|
70346
69554
|
} catch {
|
|
70347
69555
|
}
|
|
70348
69556
|
}
|
|
@@ -70350,7 +69558,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
70350
69558
|
}
|
|
70351
69559
|
function safeUnlink(p3) {
|
|
70352
69560
|
try {
|
|
70353
|
-
|
|
69561
|
+
import_node_fs53.default.unlinkSync(p3);
|
|
70354
69562
|
} catch {
|
|
70355
69563
|
}
|
|
70356
69564
|
}
|
|
@@ -70361,13 +69569,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
70361
69569
|
if (!res.ok || !res.body) {
|
|
70362
69570
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
70363
69571
|
}
|
|
70364
|
-
const out =
|
|
69572
|
+
const out = import_node_fs53.default.createWriteStream(dest);
|
|
70365
69573
|
const nodeStream = import_node_stream4.Readable.fromWeb(res.body);
|
|
70366
69574
|
await (0, import_promises10.pipeline)(nodeStream, out);
|
|
70367
69575
|
}
|
|
70368
69576
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
70369
|
-
const work =
|
|
70370
|
-
|
|
69577
|
+
const work = import_node_path58.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
69578
|
+
import_node_fs53.default.mkdirSync(work, { recursive: true });
|
|
70371
69579
|
try {
|
|
70372
69580
|
await new Promise((resolve9, reject) => {
|
|
70373
69581
|
const proc = (0, import_node_child_process14.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -70375,32 +69583,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
70375
69583
|
proc.on("exit", (code) => code === 0 ? resolve9() : reject(new Error(`tar exited ${code}`)));
|
|
70376
69584
|
});
|
|
70377
69585
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
70378
|
-
const src =
|
|
70379
|
-
if (!
|
|
69586
|
+
const src = import_node_path58.default.join(work, dirName, "frpc");
|
|
69587
|
+
if (!import_node_fs53.default.existsSync(src)) {
|
|
70380
69588
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
70381
69589
|
}
|
|
70382
|
-
|
|
69590
|
+
import_node_fs53.default.copyFileSync(src, destBin);
|
|
70383
69591
|
} finally {
|
|
70384
|
-
|
|
69592
|
+
import_node_fs53.default.rmSync(work, { recursive: true, force: true });
|
|
70385
69593
|
}
|
|
70386
69594
|
}
|
|
70387
69595
|
|
|
70388
69596
|
// src/tunnel/frpc-process.ts
|
|
70389
|
-
var
|
|
70390
|
-
var
|
|
69597
|
+
var import_node_fs54 = __toESM(require("fs"), 1);
|
|
69598
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
70391
69599
|
var import_node_child_process15 = require("child_process");
|
|
70392
69600
|
function frpcPidFilePath(dataDir) {
|
|
70393
|
-
return
|
|
69601
|
+
return import_node_path59.default.join(dataDir, "frpc.pid");
|
|
70394
69602
|
}
|
|
70395
69603
|
function writeFrpcPid(dataDir, pid) {
|
|
70396
69604
|
try {
|
|
70397
|
-
|
|
69605
|
+
import_node_fs54.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
70398
69606
|
} catch {
|
|
70399
69607
|
}
|
|
70400
69608
|
}
|
|
70401
69609
|
function clearFrpcPid(dataDir) {
|
|
70402
69610
|
try {
|
|
70403
|
-
|
|
69611
|
+
import_node_fs54.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
70404
69612
|
} catch {
|
|
70405
69613
|
}
|
|
70406
69614
|
}
|
|
@@ -70416,7 +69624,7 @@ function defaultIsPidAlive(pid) {
|
|
|
70416
69624
|
}
|
|
70417
69625
|
function defaultReadPidFile(file) {
|
|
70418
69626
|
try {
|
|
70419
|
-
return
|
|
69627
|
+
return import_node_fs54.default.readFileSync(file, "utf8");
|
|
70420
69628
|
} catch {
|
|
70421
69629
|
return null;
|
|
70422
69630
|
}
|
|
@@ -70432,7 +69640,7 @@ function defaultSleep2(ms) {
|
|
|
70432
69640
|
}
|
|
70433
69641
|
async function killStaleFrpc(deps) {
|
|
70434
69642
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
70435
|
-
const tomlPath =
|
|
69643
|
+
const tomlPath = import_node_path59.default.join(deps.dataDir, "frpc.toml");
|
|
70436
69644
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
70437
69645
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
70438
69646
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -70456,7 +69664,7 @@ async function killStaleFrpc(deps) {
|
|
|
70456
69664
|
}
|
|
70457
69665
|
if (victims.size === 0) {
|
|
70458
69666
|
try {
|
|
70459
|
-
|
|
69667
|
+
import_node_fs54.default.unlinkSync(pidFile);
|
|
70460
69668
|
} catch {
|
|
70461
69669
|
}
|
|
70462
69670
|
return;
|
|
@@ -70467,7 +69675,7 @@ async function killStaleFrpc(deps) {
|
|
|
70467
69675
|
}
|
|
70468
69676
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
70469
69677
|
try {
|
|
70470
|
-
|
|
69678
|
+
import_node_fs54.default.unlinkSync(pidFile);
|
|
70471
69679
|
} catch {
|
|
70472
69680
|
}
|
|
70473
69681
|
}
|
|
@@ -70504,7 +69712,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
70504
69712
|
var TunnelManager = class {
|
|
70505
69713
|
constructor(deps) {
|
|
70506
69714
|
this.deps = deps;
|
|
70507
|
-
this.store = deps.store ?? new TunnelStore(
|
|
69715
|
+
this.store = deps.store ?? new TunnelStore(import_node_path60.default.join(deps.dataDir, "tunnel.json"));
|
|
70508
69716
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
70509
69717
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
70510
69718
|
}
|
|
@@ -70631,8 +69839,8 @@ var TunnelManager = class {
|
|
|
70631
69839
|
dataDir: this.deps.dataDir,
|
|
70632
69840
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
70633
69841
|
});
|
|
70634
|
-
const tomlPath =
|
|
70635
|
-
const proxyName = `clawd-${t2.subdomain}-${localPort}-${
|
|
69842
|
+
const tomlPath = import_node_path60.default.join(this.deps.dataDir, "frpc.toml");
|
|
69843
|
+
const proxyName = `clawd-${t2.subdomain}-${localPort}-${import_node_crypto18.default.randomBytes(3).toString("hex")}`;
|
|
70636
69844
|
const toml = buildFrpcToml({
|
|
70637
69845
|
serverAddr: t2.frpsHost,
|
|
70638
69846
|
serverPort: t2.frpsPort,
|
|
@@ -70642,14 +69850,14 @@ var TunnelManager = class {
|
|
|
70642
69850
|
localPort,
|
|
70643
69851
|
logLevel: "info"
|
|
70644
69852
|
});
|
|
70645
|
-
await
|
|
69853
|
+
await import_node_fs55.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
70646
69854
|
const proc = (this.deps.spawnImpl ?? import_node_child_process16.spawn)(frpcBin, ["-c", tomlPath], {
|
|
70647
69855
|
stdio: ["ignore", "pipe", "pipe"]
|
|
70648
69856
|
});
|
|
70649
|
-
const logDir =
|
|
70650
|
-
|
|
70651
|
-
const logFilePath =
|
|
70652
|
-
const logStream =
|
|
69857
|
+
const logDir = import_node_path60.default.join(this.deps.dataDir, "log");
|
|
69858
|
+
import_node_fs55.default.mkdirSync(logDir, { recursive: true });
|
|
69859
|
+
const logFilePath = import_node_path60.default.join(logDir, "frpc.log");
|
|
69860
|
+
const logStream = import_node_fs55.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
70653
69861
|
logStream.on("error", () => {
|
|
70654
69862
|
});
|
|
70655
69863
|
const tee = (chunk) => {
|
|
@@ -70732,27 +69940,27 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
70732
69940
|
|
|
70733
69941
|
// src/tunnel/device-key.ts
|
|
70734
69942
|
var import_node_os22 = __toESM(require("os"), 1);
|
|
70735
|
-
var
|
|
70736
|
-
var
|
|
69943
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
69944
|
+
var import_node_crypto19 = __toESM(require("crypto"), 1);
|
|
70737
69945
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
70738
69946
|
function deriveStableDeviceKey(opts = {}) {
|
|
70739
69947
|
const hostname = opts.hostname ?? import_node_os22.default.hostname();
|
|
70740
69948
|
const uid = opts.uid ?? (typeof import_node_os22.default.userInfo === "function" ? import_node_os22.default.userInfo().uid : 0);
|
|
70741
69949
|
const home = opts.home ?? import_node_os22.default.homedir();
|
|
70742
|
-
const defaultDataDir =
|
|
70743
|
-
const normalizedDataDir = opts.dataDir ?
|
|
69950
|
+
const defaultDataDir = import_node_path61.default.resolve(import_node_path61.default.join(home, ".clawd"));
|
|
69951
|
+
const normalizedDataDir = opts.dataDir ? import_node_path61.default.resolve(opts.dataDir) : null;
|
|
70744
69952
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
70745
69953
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
70746
|
-
return
|
|
69954
|
+
return import_node_crypto19.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
70747
69955
|
}
|
|
70748
69956
|
|
|
70749
69957
|
// src/auth-store.ts
|
|
70750
|
-
var
|
|
70751
|
-
var
|
|
70752
|
-
var
|
|
69958
|
+
var import_node_fs56 = __toESM(require("fs"), 1);
|
|
69959
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
69960
|
+
var import_node_crypto20 = __toESM(require("crypto"), 1);
|
|
70753
69961
|
var AUTH_FILE_NAME = "auth.json";
|
|
70754
69962
|
function authFilePath(dataDir) {
|
|
70755
|
-
return
|
|
69963
|
+
return import_node_path62.default.join(dataDir, AUTH_FILE_NAME);
|
|
70756
69964
|
}
|
|
70757
69965
|
function loadOrCreateAuthFile(opts) {
|
|
70758
69966
|
const file = authFilePath(opts.dataDir);
|
|
@@ -70786,14 +69994,14 @@ function loadOrCreateTunnelDeviceKey(opts) {
|
|
|
70786
69994
|
return tunnelDeviceKey;
|
|
70787
69995
|
}
|
|
70788
69996
|
function defaultGenerateToken() {
|
|
70789
|
-
return
|
|
69997
|
+
return import_node_crypto20.default.randomBytes(32).toString("base64url");
|
|
70790
69998
|
}
|
|
70791
69999
|
function defaultGenerateOwnerPrincipalId() {
|
|
70792
|
-
return `owner-${
|
|
70000
|
+
return `owner-${import_node_crypto20.default.randomUUID()}`;
|
|
70793
70001
|
}
|
|
70794
70002
|
function readAuthFile(file) {
|
|
70795
70003
|
try {
|
|
70796
|
-
const raw =
|
|
70004
|
+
const raw = import_node_fs56.default.readFileSync(file, "utf8");
|
|
70797
70005
|
const parsed = JSON.parse(raw);
|
|
70798
70006
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
70799
70007
|
return null;
|
|
@@ -70814,26 +70022,26 @@ function readAuthFile(file) {
|
|
|
70814
70022
|
}
|
|
70815
70023
|
}
|
|
70816
70024
|
function writeAuthFile(file, content) {
|
|
70817
|
-
|
|
70818
|
-
|
|
70025
|
+
import_node_fs56.default.mkdirSync(import_node_path62.default.dirname(file), { recursive: true });
|
|
70026
|
+
import_node_fs56.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
70819
70027
|
try {
|
|
70820
|
-
|
|
70028
|
+
import_node_fs56.default.chmodSync(file, 384);
|
|
70821
70029
|
} catch {
|
|
70822
70030
|
}
|
|
70823
70031
|
}
|
|
70824
70032
|
|
|
70825
70033
|
// src/owner-profile.ts
|
|
70826
|
-
var
|
|
70034
|
+
var import_node_fs57 = __toESM(require("fs"), 1);
|
|
70827
70035
|
var import_node_os23 = __toESM(require("os"), 1);
|
|
70828
|
-
var
|
|
70036
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
70829
70037
|
var PROFILE_FILENAME = "profile.json";
|
|
70830
70038
|
function profilePath(dataDir) {
|
|
70831
|
-
return
|
|
70039
|
+
return import_node_path63.default.join(dataDir, PROFILE_FILENAME);
|
|
70832
70040
|
}
|
|
70833
70041
|
function loadOwnerProfile(dataDir) {
|
|
70834
70042
|
let raw;
|
|
70835
70043
|
try {
|
|
70836
|
-
raw =
|
|
70044
|
+
raw = import_node_fs57.default.readFileSync(profilePath(dataDir), "utf8");
|
|
70837
70045
|
} catch {
|
|
70838
70046
|
return {};
|
|
70839
70047
|
}
|
|
@@ -70849,7 +70057,7 @@ function loadOwnerProfile(dataDir) {
|
|
|
70849
70057
|
}
|
|
70850
70058
|
function patchOwnerProfile(dataDir, patch) {
|
|
70851
70059
|
const merged = { ...loadOwnerProfile(dataDir), ...patch };
|
|
70852
|
-
|
|
70060
|
+
import_node_fs57.default.writeFileSync(profilePath(dataDir), JSON.stringify(merged, null, 2), { encoding: "utf8", mode: 384 });
|
|
70853
70061
|
return merged;
|
|
70854
70062
|
}
|
|
70855
70063
|
function loadOwnerDisplayName(dataDir) {
|
|
@@ -70865,18 +70073,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
70865
70073
|
}
|
|
70866
70074
|
|
|
70867
70075
|
// src/feishu-auth/owner-identity-store.ts
|
|
70868
|
-
var
|
|
70869
|
-
var
|
|
70076
|
+
var import_node_fs58 = __toESM(require("fs"), 1);
|
|
70077
|
+
var import_node_path64 = __toESM(require("path"), 1);
|
|
70870
70078
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
70871
70079
|
var OwnerIdentityStore = class {
|
|
70872
70080
|
file;
|
|
70873
70081
|
constructor(dataDir) {
|
|
70874
|
-
this.file =
|
|
70082
|
+
this.file = import_node_path64.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
70875
70083
|
}
|
|
70876
70084
|
read() {
|
|
70877
70085
|
let raw;
|
|
70878
70086
|
try {
|
|
70879
|
-
raw =
|
|
70087
|
+
raw = import_node_fs58.default.readFileSync(this.file, "utf8");
|
|
70880
70088
|
} catch {
|
|
70881
70089
|
return null;
|
|
70882
70090
|
}
|
|
@@ -70903,16 +70111,16 @@ var OwnerIdentityStore = class {
|
|
|
70903
70111
|
};
|
|
70904
70112
|
}
|
|
70905
70113
|
write(record4) {
|
|
70906
|
-
|
|
70907
|
-
|
|
70114
|
+
import_node_fs58.default.mkdirSync(import_node_path64.default.dirname(this.file), { recursive: true });
|
|
70115
|
+
import_node_fs58.default.writeFileSync(this.file, JSON.stringify(record4, null, 2), { mode: 384 });
|
|
70908
70116
|
try {
|
|
70909
|
-
|
|
70117
|
+
import_node_fs58.default.chmodSync(this.file, 384);
|
|
70910
70118
|
} catch {
|
|
70911
70119
|
}
|
|
70912
70120
|
}
|
|
70913
70121
|
clear() {
|
|
70914
70122
|
try {
|
|
70915
|
-
|
|
70123
|
+
import_node_fs58.default.unlinkSync(this.file);
|
|
70916
70124
|
} catch (err) {
|
|
70917
70125
|
const code = err?.code;
|
|
70918
70126
|
if (code !== "ENOENT") throw err;
|
|
@@ -70921,7 +70129,7 @@ var OwnerIdentityStore = class {
|
|
|
70921
70129
|
};
|
|
70922
70130
|
|
|
70923
70131
|
// src/feishu-auth/login-flow.ts
|
|
70924
|
-
var
|
|
70132
|
+
var import_node_crypto21 = __toESM(require("crypto"), 1);
|
|
70925
70133
|
var STATE_TTL_MS = 5 * 60 * 1e3;
|
|
70926
70134
|
var LoginFlow = class {
|
|
70927
70135
|
constructor(deps) {
|
|
@@ -70930,7 +70138,7 @@ var LoginFlow = class {
|
|
|
70930
70138
|
deps;
|
|
70931
70139
|
pendingStates = /* @__PURE__ */ new Map();
|
|
70932
70140
|
start() {
|
|
70933
|
-
const state =
|
|
70141
|
+
const state = import_node_crypto21.default.randomBytes(16).toString("base64url");
|
|
70934
70142
|
const now = (this.deps.now ?? Date.now)();
|
|
70935
70143
|
this.pendingStates.set(state, now);
|
|
70936
70144
|
this.gcExpired(now);
|
|
@@ -71408,8 +70616,8 @@ function verifyConnectToken(args) {
|
|
|
71408
70616
|
}
|
|
71409
70617
|
|
|
71410
70618
|
// src/feishu-auth/server-key.ts
|
|
71411
|
-
var
|
|
71412
|
-
var
|
|
70619
|
+
var fs75 = __toESM(require("fs"), 1);
|
|
70620
|
+
var path77 = __toESM(require("path"), 1);
|
|
71413
70621
|
var FILE_NAME2 = "server-signing-key.json";
|
|
71414
70622
|
var ServerKeyStore = class {
|
|
71415
70623
|
constructor(dataDir) {
|
|
@@ -71417,12 +70625,12 @@ var ServerKeyStore = class {
|
|
|
71417
70625
|
}
|
|
71418
70626
|
dataDir;
|
|
71419
70627
|
filePath() {
|
|
71420
|
-
return
|
|
70628
|
+
return path77.join(this.dataDir, FILE_NAME2);
|
|
71421
70629
|
}
|
|
71422
70630
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
71423
70631
|
read() {
|
|
71424
70632
|
try {
|
|
71425
|
-
const raw =
|
|
70633
|
+
const raw = fs75.readFileSync(this.filePath(), "utf8");
|
|
71426
70634
|
const parsed = JSON.parse(raw);
|
|
71427
70635
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
71428
70636
|
return parsed.publicKeyPem;
|
|
@@ -71437,12 +70645,12 @@ var ServerKeyStore = class {
|
|
|
71437
70645
|
publicKeyPem,
|
|
71438
70646
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
71439
70647
|
};
|
|
71440
|
-
|
|
71441
|
-
|
|
70648
|
+
fs75.mkdirSync(this.dataDir, { recursive: true });
|
|
70649
|
+
fs75.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
71442
70650
|
}
|
|
71443
70651
|
clear() {
|
|
71444
70652
|
try {
|
|
71445
|
-
|
|
70653
|
+
fs75.unlinkSync(this.filePath());
|
|
71446
70654
|
} catch {
|
|
71447
70655
|
}
|
|
71448
70656
|
}
|
|
@@ -71452,19 +70660,19 @@ var ServerKeyStore = class {
|
|
|
71452
70660
|
init_protocol();
|
|
71453
70661
|
|
|
71454
70662
|
// src/handlers/index.ts
|
|
71455
|
-
var
|
|
70663
|
+
var import_node_path80 = __toESM(require("path"), 1);
|
|
71456
70664
|
|
|
71457
70665
|
// src/handlers/session.ts
|
|
71458
70666
|
init_protocol();
|
|
71459
70667
|
|
|
71460
70668
|
// src/session/fork.ts
|
|
71461
|
-
var
|
|
70669
|
+
var import_node_fs59 = __toESM(require("fs"), 1);
|
|
71462
70670
|
var import_node_os24 = __toESM(require("os"), 1);
|
|
71463
|
-
var
|
|
71464
|
-
var
|
|
70671
|
+
var import_node_path65 = __toESM(require("path"), 1);
|
|
70672
|
+
var import_node_crypto22 = require("crypto");
|
|
71465
70673
|
init_claude_history();
|
|
71466
70674
|
function readJsonlEntries(file) {
|
|
71467
|
-
const raw =
|
|
70675
|
+
const raw = import_node_fs59.default.readFileSync(file, "utf8");
|
|
71468
70676
|
const out = [];
|
|
71469
70677
|
for (const line of raw.split("\n")) {
|
|
71470
70678
|
const t2 = line.trim();
|
|
@@ -71477,19 +70685,19 @@ function readJsonlEntries(file) {
|
|
|
71477
70685
|
return out;
|
|
71478
70686
|
}
|
|
71479
70687
|
function forkSession(input) {
|
|
71480
|
-
const baseDir = input.baseDir ??
|
|
71481
|
-
let projectDir =
|
|
71482
|
-
let sourceFile =
|
|
71483
|
-
if (!
|
|
70688
|
+
const baseDir = input.baseDir ?? import_node_path65.default.join(import_node_os24.default.homedir(), ".claude");
|
|
70689
|
+
let projectDir = import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
70690
|
+
let sourceFile = import_node_path65.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
70691
|
+
if (!import_node_fs59.default.existsSync(sourceFile)) {
|
|
71484
70692
|
const found = findTranscriptByToolSessionId(
|
|
71485
|
-
|
|
70693
|
+
import_node_path65.default.join(baseDir, "projects"),
|
|
71486
70694
|
input.toolSessionId
|
|
71487
70695
|
);
|
|
71488
70696
|
if (!found) {
|
|
71489
70697
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
71490
70698
|
}
|
|
71491
70699
|
sourceFile = found;
|
|
71492
|
-
projectDir =
|
|
70700
|
+
projectDir = import_node_path65.default.dirname(found);
|
|
71493
70701
|
}
|
|
71494
70702
|
const entries = readJsonlEntries(sourceFile);
|
|
71495
70703
|
const mainEntries = entries.filter((e) => e.isSidechain !== true);
|
|
@@ -71498,7 +70706,7 @@ function forkSession(input) {
|
|
|
71498
70706
|
throw new Error(`fork: messageUuid not found in transcript: ${input.messageUuid}`);
|
|
71499
70707
|
}
|
|
71500
70708
|
const sliced = mainEntries.slice(0, targetIdx + 1);
|
|
71501
|
-
const forkedToolSessionId = (0,
|
|
70709
|
+
const forkedToolSessionId = (0, import_node_crypto22.randomUUID)();
|
|
71502
70710
|
let parentUuid = null;
|
|
71503
70711
|
const forkedLines = [];
|
|
71504
70712
|
for (const entry of sliced) {
|
|
@@ -71518,17 +70726,17 @@ function forkSession(input) {
|
|
|
71518
70726
|
}
|
|
71519
70727
|
forkedLines.push(JSON.stringify(forked));
|
|
71520
70728
|
}
|
|
71521
|
-
const outDir = input.targetCwd ?
|
|
71522
|
-
const forkedFilePath =
|
|
71523
|
-
|
|
71524
|
-
|
|
70729
|
+
const outDir = input.targetCwd ? import_node_path65.default.join(baseDir, "projects", cwdToHashDir(input.targetCwd)) : projectDir;
|
|
70730
|
+
const forkedFilePath = import_node_path65.default.join(outDir, `${forkedToolSessionId}.jsonl`);
|
|
70731
|
+
import_node_fs59.default.mkdirSync(outDir, { recursive: true });
|
|
70732
|
+
import_node_fs59.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
71525
70733
|
return { forkedToolSessionId, forkedFilePath };
|
|
71526
70734
|
}
|
|
71527
70735
|
|
|
71528
70736
|
// src/tools/codex-fork.ts
|
|
71529
70737
|
var import_node_child_process17 = require("child_process");
|
|
71530
|
-
var
|
|
71531
|
-
var
|
|
70738
|
+
var import_node_fs60 = __toESM(require("fs"), 1);
|
|
70739
|
+
var import_node_path66 = __toESM(require("path"), 1);
|
|
71532
70740
|
function openCodexAppServer(home, cwd) {
|
|
71533
70741
|
const proc = (0, import_node_child_process17.spawn)(process.env.CODEX_BIN ?? "codex", ["app-server", "--listen", "stdio://"], {
|
|
71534
70742
|
cwd,
|
|
@@ -71548,7 +70756,7 @@ function openCodexAppServer(home, cwd) {
|
|
|
71548
70756
|
async function forkCodexThread(input, deps = {}) {
|
|
71549
70757
|
const source = locateCodexThread(input.roots, input.sourceThreadId);
|
|
71550
70758
|
if (!source) throw new Error(`codex fork: source thread not found: ${input.sourceThreadId}`);
|
|
71551
|
-
const rollout = parseCodexRollout(
|
|
70759
|
+
const rollout = parseCodexRollout(import_node_fs60.default.readFileSync(source.file, "utf8"));
|
|
71552
70760
|
if (rollout.meta?.threadId.toLowerCase() !== input.sourceThreadId.toLowerCase()) {
|
|
71553
70761
|
throw new Error(`codex fork: source thread metadata does not match ${input.sourceThreadId}`);
|
|
71554
70762
|
}
|
|
@@ -71578,7 +70786,7 @@ async function forkCodexThread(input, deps = {}) {
|
|
|
71578
70786
|
if (typeof forkedToolSessionId !== "string" || !forkedToolSessionId) {
|
|
71579
70787
|
throw new Error("codex fork: app-server returned no thread id");
|
|
71580
70788
|
}
|
|
71581
|
-
const forked = locateCodexThread([
|
|
70789
|
+
const forked = locateCodexThread([import_node_path66.default.join(source.home, "sessions")], forkedToolSessionId);
|
|
71582
70790
|
if (!forked) throw new Error(`codex fork: rollout not found for forked thread ${forkedToolSessionId}`);
|
|
71583
70791
|
return { forkedToolSessionId, forkedFilePath: forked.file };
|
|
71584
70792
|
})()]);
|
|
@@ -71589,19 +70797,19 @@ async function forkCodexThread(input, deps = {}) {
|
|
|
71589
70797
|
}
|
|
71590
70798
|
|
|
71591
70799
|
// src/session/external-scan.ts
|
|
71592
|
-
var
|
|
70800
|
+
var import_node_fs61 = __toESM(require("fs"), 1);
|
|
71593
70801
|
var import_promises11 = __toESM(require("fs/promises"), 1);
|
|
71594
70802
|
var import_node_os25 = __toESM(require("os"), 1);
|
|
71595
|
-
var
|
|
70803
|
+
var import_node_path67 = __toESM(require("path"), 1);
|
|
71596
70804
|
var import_node_module = require("module");
|
|
71597
70805
|
var import_node_child_process18 = require("child_process");
|
|
71598
70806
|
var import_meta7 = {};
|
|
71599
70807
|
function defaultRoots() {
|
|
71600
70808
|
const home = import_node_os25.default.homedir();
|
|
71601
70809
|
return {
|
|
71602
|
-
claudeProjectsDir:
|
|
71603
|
-
codexDir:
|
|
71604
|
-
clawdDir:
|
|
70810
|
+
claudeProjectsDir: import_node_path67.default.join(home, ".claude", "projects"),
|
|
70811
|
+
codexDir: import_node_path67.default.join(home, ".codex"),
|
|
70812
|
+
clawdDir: import_node_path67.default.join(home, ".clawd")
|
|
71605
70813
|
};
|
|
71606
70814
|
}
|
|
71607
70815
|
function width(s2) {
|
|
@@ -71652,7 +70860,7 @@ function userText(msg) {
|
|
|
71652
70860
|
}
|
|
71653
70861
|
function isDir2(p3) {
|
|
71654
70862
|
try {
|
|
71655
|
-
return
|
|
70863
|
+
return import_node_fs61.default.statSync(p3).isDirectory();
|
|
71656
70864
|
} catch {
|
|
71657
70865
|
return false;
|
|
71658
70866
|
}
|
|
@@ -71661,7 +70869,7 @@ async function scanClaude(roots) {
|
|
|
71661
70869
|
const out = [];
|
|
71662
70870
|
let dirs;
|
|
71663
70871
|
try {
|
|
71664
|
-
dirs =
|
|
70872
|
+
dirs = import_node_fs61.default.readdirSync(roots.claudeProjectsDir, { withFileTypes: true });
|
|
71665
70873
|
} catch {
|
|
71666
70874
|
return out;
|
|
71667
70875
|
}
|
|
@@ -71669,16 +70877,16 @@ async function scanClaude(roots) {
|
|
|
71669
70877
|
if (!d2.isDirectory()) continue;
|
|
71670
70878
|
let files;
|
|
71671
70879
|
try {
|
|
71672
|
-
files =
|
|
70880
|
+
files = import_node_fs61.default.readdirSync(import_node_path67.default.join(roots.claudeProjectsDir, d2.name));
|
|
71673
70881
|
} catch {
|
|
71674
70882
|
continue;
|
|
71675
70883
|
}
|
|
71676
70884
|
for (const name of files) {
|
|
71677
70885
|
if (!name.endsWith(".jsonl")) continue;
|
|
71678
|
-
const file =
|
|
70886
|
+
const file = import_node_path67.default.join(roots.claudeProjectsDir, d2.name, name);
|
|
71679
70887
|
let st2;
|
|
71680
70888
|
try {
|
|
71681
|
-
st2 =
|
|
70889
|
+
st2 = import_node_fs61.default.statSync(file);
|
|
71682
70890
|
} catch {
|
|
71683
70891
|
continue;
|
|
71684
70892
|
}
|
|
@@ -71731,7 +70939,7 @@ async function scanClaude(roots) {
|
|
|
71731
70939
|
return out;
|
|
71732
70940
|
}
|
|
71733
70941
|
async function countCodexTurns(rolloutPath) {
|
|
71734
|
-
if (!rolloutPath || !
|
|
70942
|
+
if (!rolloutPath || !import_node_fs61.default.existsSync(rolloutPath)) return { turns: 0, first: "" };
|
|
71735
70943
|
let turns = 0;
|
|
71736
70944
|
let first = "";
|
|
71737
70945
|
for await (const rec6 of jsonLines(rolloutPath)) {
|
|
@@ -71805,7 +71013,7 @@ async function codexFromRows(rows) {
|
|
|
71805
71013
|
async function scanCodex(roots) {
|
|
71806
71014
|
let dbs = [];
|
|
71807
71015
|
try {
|
|
71808
|
-
dbs =
|
|
71016
|
+
dbs = import_node_fs61.default.readdirSync(roots.codexDir).filter((n2) => /^state_.*\.sqlite$/.test(n2)).sort().map((n2) => import_node_path67.default.join(roots.codexDir, n2));
|
|
71809
71017
|
} catch {
|
|
71810
71018
|
}
|
|
71811
71019
|
if (!dbs.length) return [];
|
|
@@ -71814,14 +71022,14 @@ async function scanCodex(roots) {
|
|
|
71814
71022
|
}
|
|
71815
71023
|
async function scanExternalSessions(rootsIn) {
|
|
71816
71024
|
const roots = { ...defaultRoots(), ...rootsIn };
|
|
71817
|
-
const personaRoot =
|
|
71025
|
+
const personaRoot = import_node_path67.default.join(roots.clawdDir, "personas");
|
|
71818
71026
|
const all = [...await scanClaude(roots), ...await scanCodex(roots)];
|
|
71819
71027
|
const out = [];
|
|
71820
71028
|
for (const c2 of all) {
|
|
71821
71029
|
if (c2.skip) continue;
|
|
71822
71030
|
if (c2.turns < 1) continue;
|
|
71823
71031
|
if (!c2.cwd || !isDir2(c2.cwd)) continue;
|
|
71824
|
-
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot +
|
|
71032
|
+
if (c2.cwd === roots.clawdDir || c2.cwd === personaRoot || c2.cwd.startsWith(personaRoot + import_node_path67.default.sep) || c2.cwd.startsWith(roots.clawdDir + import_node_path67.default.sep)) {
|
|
71825
71033
|
continue;
|
|
71826
71034
|
}
|
|
71827
71035
|
out.push({
|
|
@@ -71838,13 +71046,13 @@ async function scanExternalSessions(rootsIn) {
|
|
|
71838
71046
|
}
|
|
71839
71047
|
|
|
71840
71048
|
// src/session/import-ledger.ts
|
|
71841
|
-
var
|
|
71842
|
-
var
|
|
71049
|
+
var import_node_fs62 = __toESM(require("fs"), 1);
|
|
71050
|
+
var import_node_path68 = __toESM(require("path"), 1);
|
|
71843
71051
|
var LEDGER_FILENAME = "session-import-ledger.json";
|
|
71844
71052
|
function readImportLedger(dataDir) {
|
|
71845
71053
|
try {
|
|
71846
71054
|
const parsed = JSON.parse(
|
|
71847
|
-
|
|
71055
|
+
import_node_fs62.default.readFileSync(import_node_path68.default.join(dataDir, LEDGER_FILENAME), "utf8")
|
|
71848
71056
|
);
|
|
71849
71057
|
return Array.isArray(parsed) ? parsed : [];
|
|
71850
71058
|
} catch {
|
|
@@ -71852,15 +71060,15 @@ function readImportLedger(dataDir) {
|
|
|
71852
71060
|
}
|
|
71853
71061
|
}
|
|
71854
71062
|
function appendImportLedger(dataDir, entry) {
|
|
71855
|
-
const file =
|
|
71063
|
+
const file = import_node_path68.default.join(dataDir, LEDGER_FILENAME);
|
|
71856
71064
|
const entries = readImportLedger(dataDir);
|
|
71857
71065
|
entries.push(entry);
|
|
71858
|
-
|
|
71066
|
+
import_node_fs62.default.writeFileSync(file, JSON.stringify(entries, null, 2), { encoding: "utf8", mode: 384 });
|
|
71859
71067
|
}
|
|
71860
71068
|
|
|
71861
71069
|
// src/handlers/session.ts
|
|
71862
71070
|
init_protocol();
|
|
71863
|
-
var
|
|
71071
|
+
var import_node_path69 = __toESM(require("path"), 1);
|
|
71864
71072
|
function canReadSearchHit(ctx, file) {
|
|
71865
71073
|
if (!ctx || ctx.principal.kind === "owner") return true;
|
|
71866
71074
|
return canAccessPersona(ctx.grants, file.ownerPersonaId, "read") && file.creatorPrincipalId === ctx.principal.id;
|
|
@@ -72141,7 +71349,7 @@ ${attribution}` } : args;
|
|
|
72141
71349
|
`principal guest:${ctx.principal.id} cannot fork tool session ${args.toolSessionId}`
|
|
72142
71350
|
);
|
|
72143
71351
|
}
|
|
72144
|
-
if (source?.tool === "codex" && args.targetCwd &&
|
|
71352
|
+
if (source?.tool === "codex" && args.targetCwd && import_node_path69.default.resolve(args.targetCwd) !== import_node_path69.default.resolve(source.cwd)) {
|
|
72145
71353
|
throw new ClawdError(ERROR_CODES.FORBIDDEN, "fork: guest targetCwd must match source cwd");
|
|
72146
71354
|
}
|
|
72147
71355
|
}
|
|
@@ -72418,7 +71626,7 @@ function buildPermissionHandlers(deps) {
|
|
|
72418
71626
|
}
|
|
72419
71627
|
|
|
72420
71628
|
// src/handlers/history.ts
|
|
72421
|
-
var
|
|
71629
|
+
var path84 = __toESM(require("path"), 1);
|
|
72422
71630
|
init_protocol();
|
|
72423
71631
|
|
|
72424
71632
|
// src/session/recent-dirs.ts
|
|
@@ -72436,7 +71644,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
72436
71644
|
}
|
|
72437
71645
|
|
|
72438
71646
|
// src/permission/persona-paths.ts
|
|
72439
|
-
var
|
|
71647
|
+
var path83 = __toESM(require("path"), 1);
|
|
72440
71648
|
function getAllowedPersonaIds(grants, action) {
|
|
72441
71649
|
const ids = /* @__PURE__ */ new Set();
|
|
72442
71650
|
for (const g3 of grants) {
|
|
@@ -72449,42 +71657,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
72449
71657
|
return ids;
|
|
72450
71658
|
}
|
|
72451
71659
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
72452
|
-
const target =
|
|
71660
|
+
const target = path83.resolve(absPath);
|
|
72453
71661
|
if (userWorkDir) {
|
|
72454
|
-
const u2 =
|
|
72455
|
-
const usep = u2.endsWith(
|
|
71662
|
+
const u2 = path83.resolve(userWorkDir);
|
|
71663
|
+
const usep = u2.endsWith(path83.sep) ? "" : path83.sep;
|
|
72456
71664
|
if (target === u2 || target.startsWith(u2 + usep)) return true;
|
|
72457
71665
|
}
|
|
72458
|
-
const root =
|
|
72459
|
-
const sep4 = root.endsWith(
|
|
71666
|
+
const root = path83.resolve(personaRoot);
|
|
71667
|
+
const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
|
|
72460
71668
|
if (!target.startsWith(root + sep4)) return false;
|
|
72461
|
-
const rel =
|
|
71669
|
+
const rel = path83.relative(root, target);
|
|
72462
71670
|
if (!rel || rel.startsWith("..")) return false;
|
|
72463
|
-
const personaId2 = rel.split(
|
|
71671
|
+
const personaId2 = rel.split(path83.sep)[0];
|
|
72464
71672
|
if (!personaId2) return false;
|
|
72465
71673
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
72466
71674
|
if (allowed === "*") return true;
|
|
72467
71675
|
return allowed.has(personaId2);
|
|
72468
71676
|
}
|
|
72469
71677
|
function personaIdFromPath(absPath, personaRoot) {
|
|
72470
|
-
const root =
|
|
72471
|
-
const target =
|
|
72472
|
-
const sep4 = root.endsWith(
|
|
71678
|
+
const root = path83.resolve(personaRoot);
|
|
71679
|
+
const target = path83.resolve(absPath);
|
|
71680
|
+
const sep4 = root.endsWith(path83.sep) ? "" : path83.sep;
|
|
72473
71681
|
if (!target.startsWith(root + sep4)) return null;
|
|
72474
|
-
const rel =
|
|
71682
|
+
const rel = path83.relative(root, target);
|
|
72475
71683
|
if (!rel || rel.startsWith("..")) return null;
|
|
72476
|
-
const id = rel.split(
|
|
71684
|
+
const id = rel.split(path83.sep)[0];
|
|
72477
71685
|
return id || null;
|
|
72478
71686
|
}
|
|
72479
71687
|
function isPathWithin(dir, absPath) {
|
|
72480
|
-
const d2 =
|
|
72481
|
-
const t2 =
|
|
72482
|
-
const sep4 = d2.endsWith(
|
|
71688
|
+
const d2 = path83.resolve(dir);
|
|
71689
|
+
const t2 = path83.resolve(absPath);
|
|
71690
|
+
const sep4 = d2.endsWith(path83.sep) ? "" : path83.sep;
|
|
72483
71691
|
return t2 === d2 || t2.startsWith(d2 + sep4);
|
|
72484
71692
|
}
|
|
72485
71693
|
function isPathInGuestBoundary(personaRoot, personaId2, userWorkDir, absPath) {
|
|
72486
71694
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
72487
|
-
return personaIdFromPath(
|
|
71695
|
+
return personaIdFromPath(path83.resolve(absPath), personaRoot) === personaId2;
|
|
72488
71696
|
}
|
|
72489
71697
|
|
|
72490
71698
|
// src/handlers/history.ts
|
|
@@ -72538,7 +71746,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72538
71746
|
if (!pid) return false;
|
|
72539
71747
|
return isGuestPathAllowed(
|
|
72540
71748
|
ctx.grants,
|
|
72541
|
-
|
|
71749
|
+
path84.join(personaRoot, pid),
|
|
72542
71750
|
personaRoot,
|
|
72543
71751
|
"read",
|
|
72544
71752
|
userWorkDir
|
|
@@ -72550,7 +71758,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72550
71758
|
};
|
|
72551
71759
|
const list = async (frame, _client, ctx) => {
|
|
72552
71760
|
const args = HistoryListArgs.parse(frame);
|
|
72553
|
-
assertGuestPath(ctx,
|
|
71761
|
+
assertGuestPath(ctx, path84.resolve(args.projectPath), personaRoot, "history:list", usersRoot);
|
|
72554
71762
|
const sessions = await history.listSessions(args);
|
|
72555
71763
|
return { response: { type: "history:list", sessions } };
|
|
72556
71764
|
};
|
|
@@ -72625,14 +71833,14 @@ function buildHistoryHandlers(deps) {
|
|
|
72625
71833
|
};
|
|
72626
71834
|
const subagents = async (frame, _client, ctx) => {
|
|
72627
71835
|
const args = HistorySubagentsArgs.parse(frame);
|
|
72628
|
-
assertGuestPath(ctx,
|
|
71836
|
+
assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
72629
71837
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
72630
71838
|
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
72631
71839
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
72632
71840
|
};
|
|
72633
71841
|
const subagentRead = async (frame, _client, ctx) => {
|
|
72634
71842
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
72635
|
-
assertGuestPath(ctx,
|
|
71843
|
+
assertGuestPath(ctx, path84.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
72636
71844
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
72637
71845
|
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
72638
71846
|
return { response: { type: "history:subagent-read", ...res } };
|
|
@@ -72642,7 +71850,7 @@ function buildHistoryHandlers(deps) {
|
|
|
72642
71850
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
72643
71851
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
72644
71852
|
const filtered = dirs.filter(
|
|
72645
|
-
(d2) => isGuestPathAllowed(ctx.grants,
|
|
71853
|
+
(d2) => isGuestPathAllowed(ctx.grants, path84.resolve(d2.cwd), personaRoot, "read", userWorkDir)
|
|
72646
71854
|
);
|
|
72647
71855
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
72648
71856
|
}
|
|
@@ -72659,17 +71867,17 @@ function buildHistoryHandlers(deps) {
|
|
|
72659
71867
|
}
|
|
72660
71868
|
|
|
72661
71869
|
// src/handlers/projects.ts
|
|
72662
|
-
var
|
|
71870
|
+
var fs80 = __toESM(require("fs"), 1);
|
|
72663
71871
|
var os27 = __toESM(require("os"), 1);
|
|
72664
|
-
var
|
|
71872
|
+
var path85 = __toESM(require("path"), 1);
|
|
72665
71873
|
var import_node_child_process19 = require("child_process");
|
|
72666
71874
|
init_protocol();
|
|
72667
|
-
var DEFAULT_PROJECTS_ROOT =
|
|
71875
|
+
var DEFAULT_PROJECTS_ROOT = path85.join(os27.homedir(), "Documents", "ChatGPT");
|
|
72668
71876
|
function allocateDir(root, name) {
|
|
72669
|
-
let candidate =
|
|
71877
|
+
let candidate = path85.join(root, name);
|
|
72670
71878
|
let n2 = 2;
|
|
72671
|
-
while (
|
|
72672
|
-
candidate =
|
|
71879
|
+
while (fs80.existsSync(candidate)) {
|
|
71880
|
+
candidate = path85.join(root, `${name} ${n2}`);
|
|
72673
71881
|
n2 += 1;
|
|
72674
71882
|
}
|
|
72675
71883
|
return candidate;
|
|
@@ -72697,7 +71905,7 @@ function buildProjectHandlers(deps) {
|
|
|
72697
71905
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "project:reveal \u4EC5\u652F\u6301 macOS");
|
|
72698
71906
|
}
|
|
72699
71907
|
try {
|
|
72700
|
-
if (!
|
|
71908
|
+
if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
72701
71909
|
} catch {
|
|
72702
71910
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
72703
71911
|
}
|
|
@@ -72713,7 +71921,7 @@ function buildProjectHandlers(deps) {
|
|
|
72713
71921
|
let target;
|
|
72714
71922
|
if (args.path) {
|
|
72715
71923
|
try {
|
|
72716
|
-
if (!
|
|
71924
|
+
if (!fs80.statSync(args.path).isDirectory()) throw new Error("not dir");
|
|
72717
71925
|
} catch {
|
|
72718
71926
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${args.path}`);
|
|
72719
71927
|
}
|
|
@@ -72721,15 +71929,15 @@ function buildProjectHandlers(deps) {
|
|
|
72721
71929
|
} else {
|
|
72722
71930
|
const name = args.name;
|
|
72723
71931
|
try {
|
|
72724
|
-
|
|
71932
|
+
fs80.mkdirSync(root, { recursive: true });
|
|
72725
71933
|
target = allocateDir(root, name);
|
|
72726
|
-
|
|
71934
|
+
fs80.mkdirSync(target);
|
|
72727
71935
|
} catch (err) {
|
|
72728
71936
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `\u521B\u5EFA\u9879\u76EE\u76EE\u5F55\u5931\u8D25: ${String(err)}`);
|
|
72729
71937
|
}
|
|
72730
71938
|
const git2 = (0, import_node_child_process19.spawnSync)("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
72731
71939
|
if (git2.status !== 0) {
|
|
72732
|
-
|
|
71940
|
+
fs80.rmSync(target, { recursive: true, force: true });
|
|
72733
71941
|
throw new ClawdError(
|
|
72734
71942
|
ERROR_CODES.INVALID_CWD,
|
|
72735
71943
|
`git init \u5931\u8D25\uFF08${git2.error ? String(git2.error) : `exit ${git2.status}`}\uFF09: ${target}`
|
|
@@ -72754,7 +71962,7 @@ function buildProjectHandlers(deps) {
|
|
|
72754
71962
|
}
|
|
72755
71963
|
|
|
72756
71964
|
// src/handlers/workspace.ts
|
|
72757
|
-
var
|
|
71965
|
+
var path86 = __toESM(require("path"), 1);
|
|
72758
71966
|
init_protocol();
|
|
72759
71967
|
var os28 = __toESM(require("os"), 1);
|
|
72760
71968
|
init_protocol();
|
|
@@ -72797,22 +72005,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72797
72005
|
const args = WorkspaceListArgs.parse(frame);
|
|
72798
72006
|
const isGuest = ctx?.principal.kind === "guest";
|
|
72799
72007
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os28.homedir();
|
|
72800
|
-
const resolvedCwd =
|
|
72801
|
-
const target = args.path ?
|
|
72008
|
+
const resolvedCwd = path86.resolve(args.cwd ?? fallbackCwd);
|
|
72009
|
+
const target = args.path ? path86.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
72802
72010
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
72803
72011
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
72804
72012
|
return { response: { type: "workspace:list", ...res } };
|
|
72805
72013
|
};
|
|
72806
72014
|
const read = async (frame, _client, ctx) => {
|
|
72807
72015
|
const args = WorkspaceReadArgs.parse(frame);
|
|
72808
|
-
const target =
|
|
72016
|
+
const target = path86.isAbsolute(args.path) ? path86.resolve(args.path) : path86.resolve(args.cwd, args.path);
|
|
72809
72017
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
72810
72018
|
const res = workspace.read(args);
|
|
72811
72019
|
return { response: { type: "workspace:read", ...res } };
|
|
72812
72020
|
};
|
|
72813
72021
|
const skillsList = async (frame, _client, ctx) => {
|
|
72814
72022
|
const args = SkillsListArgs.parse(frame);
|
|
72815
|
-
const cwdAbs =
|
|
72023
|
+
const cwdAbs = path86.resolve(args.cwd);
|
|
72816
72024
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
72817
72025
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
72818
72026
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -72824,7 +72032,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72824
72032
|
};
|
|
72825
72033
|
const agentsList = async (frame, _client, ctx) => {
|
|
72826
72034
|
const args = AgentsListArgs.parse(frame);
|
|
72827
|
-
const cwdAbs =
|
|
72035
|
+
const cwdAbs = path86.resolve(args.cwd);
|
|
72828
72036
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
72829
72037
|
if (isCodexFamily(args.tool) || isPiFamily(args.tool)) {
|
|
72830
72038
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -72846,20 +72054,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
72846
72054
|
}
|
|
72847
72055
|
|
|
72848
72056
|
// src/handlers/git.ts
|
|
72849
|
-
var
|
|
72057
|
+
var path88 = __toESM(require("path"), 1);
|
|
72850
72058
|
init_protocol();
|
|
72851
72059
|
init_protocol();
|
|
72852
72060
|
|
|
72853
72061
|
// src/workspace/git.ts
|
|
72854
72062
|
var import_node_child_process20 = require("child_process");
|
|
72855
|
-
var
|
|
72856
|
-
var
|
|
72063
|
+
var import_node_fs63 = __toESM(require("fs"), 1);
|
|
72064
|
+
var import_node_path70 = __toESM(require("path"), 1);
|
|
72857
72065
|
var import_node_util2 = require("util");
|
|
72858
72066
|
var pexec = (0, import_node_util2.promisify)(import_node_child_process20.execFile);
|
|
72859
72067
|
function normalizePath(p3) {
|
|
72860
|
-
const resolved =
|
|
72068
|
+
const resolved = import_node_path70.default.resolve(p3);
|
|
72861
72069
|
try {
|
|
72862
|
-
return
|
|
72070
|
+
return import_node_fs63.default.realpathSync(resolved);
|
|
72863
72071
|
} catch {
|
|
72864
72072
|
return resolved;
|
|
72865
72073
|
}
|
|
@@ -72933,7 +72141,7 @@ async function listGitBranches(cwd) {
|
|
|
72933
72141
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
72934
72142
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
72935
72143
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
72936
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
72144
|
+
if (!isGuestPathAllowed(ctx.grants, path88.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
72937
72145
|
throw new ClawdError(
|
|
72938
72146
|
ERROR_CODES.UNAUTHORIZED,
|
|
72939
72147
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -73190,12 +72398,12 @@ async function queryCodexAccount(deps = {}) {
|
|
|
73190
72398
|
}
|
|
73191
72399
|
|
|
73192
72400
|
// src/tools/pi-account.ts
|
|
73193
|
-
var
|
|
73194
|
-
var
|
|
72401
|
+
var import_node_fs64 = __toESM(require("fs"), 1);
|
|
72402
|
+
var import_node_path71 = __toESM(require("path"), 1);
|
|
73195
72403
|
function readPiCredentials(agentDir) {
|
|
73196
72404
|
let raw;
|
|
73197
72405
|
try {
|
|
73198
|
-
raw = JSON.parse(
|
|
72406
|
+
raw = JSON.parse(import_node_fs64.default.readFileSync(import_node_path71.default.join(agentDir, "auth.json"), "utf8"));
|
|
73199
72407
|
} catch {
|
|
73200
72408
|
return {};
|
|
73201
72409
|
}
|
|
@@ -74286,21 +73494,21 @@ function computeMethodAccess(args) {
|
|
|
74286
73494
|
}
|
|
74287
73495
|
|
|
74288
73496
|
// src/version.ts
|
|
74289
|
-
var version = "0.2.
|
|
73497
|
+
var version = "0.2.615".length > 0 ? "0.2.615" : "dev";
|
|
74290
73498
|
|
|
74291
73499
|
// src/cli-probe/probe.ts
|
|
74292
|
-
var
|
|
74293
|
-
var
|
|
73500
|
+
var fs83 = __toESM(require("fs"), 1);
|
|
73501
|
+
var path90 = __toESM(require("path"), 1);
|
|
74294
73502
|
var PKG_NAME = "@clawos-dev/clawd";
|
|
74295
73503
|
var BIN_NAME = "clawd";
|
|
74296
73504
|
var MAX_PARENT_HOPS = 5;
|
|
74297
73505
|
function probeGlobalCli(pathEnv) {
|
|
74298
73506
|
if (!pathEnv) return null;
|
|
74299
|
-
for (const dir of pathEnv.split(
|
|
73507
|
+
for (const dir of pathEnv.split(path90.delimiter)) {
|
|
74300
73508
|
if (!dir) continue;
|
|
74301
73509
|
let real;
|
|
74302
73510
|
try {
|
|
74303
|
-
real =
|
|
73511
|
+
real = fs83.realpathSync(path90.join(dir, BIN_NAME));
|
|
74304
73512
|
} catch {
|
|
74305
73513
|
continue;
|
|
74306
73514
|
}
|
|
@@ -74310,15 +73518,15 @@ function probeGlobalCli(pathEnv) {
|
|
|
74310
73518
|
return null;
|
|
74311
73519
|
}
|
|
74312
73520
|
function readOwnPackageVersion(entryPath) {
|
|
74313
|
-
let dir =
|
|
73521
|
+
let dir = path90.dirname(entryPath);
|
|
74314
73522
|
for (let i2 = 0; i2 < MAX_PARENT_HOPS; i2++) {
|
|
74315
73523
|
try {
|
|
74316
|
-
const raw =
|
|
73524
|
+
const raw = fs83.readFileSync(path90.join(dir, "package.json"), "utf8");
|
|
74317
73525
|
const pkg = JSON.parse(raw);
|
|
74318
73526
|
if (pkg.name !== PKG_NAME) return null;
|
|
74319
73527
|
return typeof pkg.version === "string" && pkg.version ? pkg.version : null;
|
|
74320
73528
|
} catch {
|
|
74321
|
-
const parent =
|
|
73529
|
+
const parent = path90.dirname(dir);
|
|
74322
73530
|
if (parent === dir) return null;
|
|
74323
73531
|
dir = parent;
|
|
74324
73532
|
}
|
|
@@ -74494,7 +73702,7 @@ function buildPersonaHandlers(deps) {
|
|
|
74494
73702
|
}
|
|
74495
73703
|
|
|
74496
73704
|
// src/handlers/attachment.ts
|
|
74497
|
-
var
|
|
73705
|
+
var import_node_path72 = __toESM(require("path"), 1);
|
|
74498
73706
|
init_protocol();
|
|
74499
73707
|
init_protocol();
|
|
74500
73708
|
function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot) {
|
|
@@ -74573,12 +73781,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
74573
73781
|
`session ${args.sessionId} scope unresolved`
|
|
74574
73782
|
);
|
|
74575
73783
|
}
|
|
74576
|
-
const cwdAbs =
|
|
74577
|
-
const candidateAbs =
|
|
73784
|
+
const cwdAbs = import_node_path72.default.resolve(sessionFile.cwd);
|
|
73785
|
+
const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
|
|
74578
73786
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
74579
73787
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
74580
73788
|
const entry = entries.find((e) => {
|
|
74581
|
-
const storedAbs =
|
|
73789
|
+
const storedAbs = import_node_path72.default.isAbsolute(e.relPath) ? import_node_path72.default.resolve(e.relPath) : import_node_path72.default.resolve(cwdAbs, e.relPath);
|
|
74582
73790
|
return storedAbs === candidateAbs && !e.stale;
|
|
74583
73791
|
});
|
|
74584
73792
|
if (!entry) {
|
|
@@ -74602,7 +73810,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
74602
73810
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
74603
73811
|
const f2 = deps.sessionStore.read(sessionId);
|
|
74604
73812
|
if (!f2) return;
|
|
74605
|
-
assertGuestAttachmentPath(ctx,
|
|
73813
|
+
assertGuestAttachmentPath(ctx, import_node_path72.default.resolve(f2.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
74606
73814
|
}
|
|
74607
73815
|
const groupAdd = async (frame, _client, ctx) => {
|
|
74608
73816
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -74617,8 +73825,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
74617
73825
|
if (!scope) {
|
|
74618
73826
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
74619
73827
|
}
|
|
74620
|
-
const cwdAbs =
|
|
74621
|
-
const candidateAbs =
|
|
73828
|
+
const cwdAbs = import_node_path72.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
73829
|
+
const candidateAbs = import_node_path72.default.isAbsolute(args.relPath) ? import_node_path72.default.resolve(args.relPath) : import_node_path72.default.resolve(cwdAbs, args.relPath);
|
|
74622
73830
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
74623
73831
|
const from = args.origin === "agent" ? "agent" : ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
74624
73832
|
const size = 0;
|
|
@@ -74677,19 +73885,19 @@ function buildAttachmentHandlers(deps) {
|
|
|
74677
73885
|
|
|
74678
73886
|
// src/handlers/extension.ts
|
|
74679
73887
|
var import_promises15 = __toESM(require("fs/promises"), 1);
|
|
74680
|
-
var
|
|
73888
|
+
var import_node_path77 = __toESM(require("path"), 1);
|
|
74681
73889
|
init_protocol();
|
|
74682
73890
|
|
|
74683
73891
|
// src/extension/bundle-zip.ts
|
|
74684
73892
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
74685
|
-
var
|
|
74686
|
-
var
|
|
73893
|
+
var import_node_path73 = __toESM(require("path"), 1);
|
|
73894
|
+
var import_node_crypto23 = __toESM(require("crypto"), 1);
|
|
74687
73895
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
74688
73896
|
async function bundleExtensionDir(dir) {
|
|
74689
73897
|
const entries = await listFilesSorted(dir);
|
|
74690
73898
|
const zip = new import_jszip2.default();
|
|
74691
73899
|
for (const rel of entries) {
|
|
74692
|
-
const abs =
|
|
73900
|
+
const abs = import_node_path73.default.join(dir, rel);
|
|
74693
73901
|
const content = await import_promises12.default.readFile(abs);
|
|
74694
73902
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
74695
73903
|
}
|
|
@@ -74698,7 +73906,7 @@ async function bundleExtensionDir(dir) {
|
|
|
74698
73906
|
compression: "DEFLATE",
|
|
74699
73907
|
compressionOptions: { level: 6 }
|
|
74700
73908
|
});
|
|
74701
|
-
const sha256 =
|
|
73909
|
+
const sha256 = import_node_crypto23.default.createHash("sha256").update(buffer).digest("hex");
|
|
74702
73910
|
return { buffer, sha256 };
|
|
74703
73911
|
}
|
|
74704
73912
|
var FIXED_DATE = /* @__PURE__ */ new Date("2020-01-01T00:00:00.000Z");
|
|
@@ -74710,7 +73918,7 @@ async function listFilesSorted(rootDir) {
|
|
|
74710
73918
|
return out;
|
|
74711
73919
|
}
|
|
74712
73920
|
async function walk(absRoot, relPrefix, out) {
|
|
74713
|
-
const dirAbs =
|
|
73921
|
+
const dirAbs = import_node_path73.default.join(absRoot, relPrefix);
|
|
74714
73922
|
const entries = await import_promises12.default.readdir(dirAbs, { withFileTypes: true });
|
|
74715
73923
|
for (const e of entries) {
|
|
74716
73924
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -74764,25 +73972,25 @@ function computePublishCheck(args) {
|
|
|
74764
73972
|
|
|
74765
73973
|
// src/extension/install-flow.ts
|
|
74766
73974
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
74767
|
-
var
|
|
73975
|
+
var import_node_path75 = __toESM(require("path"), 1);
|
|
74768
73976
|
var import_node_os28 = __toESM(require("os"), 1);
|
|
74769
|
-
var
|
|
73977
|
+
var import_node_crypto24 = __toESM(require("crypto"), 1);
|
|
74770
73978
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
74771
73979
|
|
|
74772
73980
|
// src/extension/paths.ts
|
|
74773
73981
|
var import_node_os27 = __toESM(require("os"), 1);
|
|
74774
|
-
var
|
|
73982
|
+
var import_node_path74 = __toESM(require("path"), 1);
|
|
74775
73983
|
function clawdHomeRoot(override) {
|
|
74776
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
73984
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path74.default.join(import_node_os27.default.homedir(), ".clawd");
|
|
74777
73985
|
}
|
|
74778
73986
|
function extensionsRoot(override) {
|
|
74779
|
-
return
|
|
73987
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions");
|
|
74780
73988
|
}
|
|
74781
73989
|
function publishedChannelsFile(override) {
|
|
74782
|
-
return
|
|
73990
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
74783
73991
|
}
|
|
74784
73992
|
function bundleCacheRoot(override) {
|
|
74785
|
-
return
|
|
73993
|
+
return import_node_path74.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
74786
73994
|
}
|
|
74787
73995
|
|
|
74788
73996
|
// src/extension/install-flow.ts
|
|
@@ -74795,7 +74003,7 @@ var InstallError = class extends Error {
|
|
|
74795
74003
|
};
|
|
74796
74004
|
async function installFromChannel(args, deps) {
|
|
74797
74005
|
const { channelRef, snapshotHash, bundleZip } = args;
|
|
74798
|
-
const computed =
|
|
74006
|
+
const computed = import_node_crypto24.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
74799
74007
|
if (computed !== snapshotHash) {
|
|
74800
74008
|
throw new InstallError(
|
|
74801
74009
|
"HASH_MISMATCH",
|
|
@@ -74809,7 +74017,7 @@ async function installFromChannel(args, deps) {
|
|
|
74809
74017
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
74810
74018
|
}
|
|
74811
74019
|
for (const name of Object.keys(zip.files)) {
|
|
74812
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
74020
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path75.default.isAbsolute(name)) {
|
|
74813
74021
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
74814
74022
|
}
|
|
74815
74023
|
}
|
|
@@ -74841,7 +74049,7 @@ async function installFromChannel(args, deps) {
|
|
|
74841
74049
|
);
|
|
74842
74050
|
}
|
|
74843
74051
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
74844
|
-
const destDir =
|
|
74052
|
+
const destDir = import_node_path75.default.join(deps.extensionsRoot, localExtId);
|
|
74845
74053
|
let destExists = false;
|
|
74846
74054
|
try {
|
|
74847
74055
|
await import_promises13.default.access(destDir);
|
|
@@ -74855,16 +74063,16 @@ async function installFromChannel(args, deps) {
|
|
|
74855
74063
|
);
|
|
74856
74064
|
}
|
|
74857
74065
|
const stage = await import_promises13.default.mkdtemp(
|
|
74858
|
-
|
|
74066
|
+
import_node_path75.default.join(import_node_os28.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
74859
74067
|
);
|
|
74860
74068
|
try {
|
|
74861
74069
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
74862
|
-
const dest =
|
|
74070
|
+
const dest = import_node_path75.default.join(stage, name);
|
|
74863
74071
|
if (entry.dir) {
|
|
74864
74072
|
await import_promises13.default.mkdir(dest, { recursive: true });
|
|
74865
74073
|
continue;
|
|
74866
74074
|
}
|
|
74867
|
-
await import_promises13.default.mkdir(
|
|
74075
|
+
await import_promises13.default.mkdir(import_node_path75.default.dirname(dest), { recursive: true });
|
|
74868
74076
|
if (name === "manifest.json") {
|
|
74869
74077
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
74870
74078
|
await import_promises13.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -74885,9 +74093,9 @@ async function installFromChannel(args, deps) {
|
|
|
74885
74093
|
|
|
74886
74094
|
// src/extension/update-flow.ts
|
|
74887
74095
|
var import_promises14 = __toESM(require("fs/promises"), 1);
|
|
74888
|
-
var
|
|
74096
|
+
var import_node_path76 = __toESM(require("path"), 1);
|
|
74889
74097
|
var import_node_os29 = __toESM(require("os"), 1);
|
|
74890
|
-
var
|
|
74098
|
+
var import_node_crypto25 = __toESM(require("crypto"), 1);
|
|
74891
74099
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
74892
74100
|
var UpdateError = class extends Error {
|
|
74893
74101
|
constructor(code, message) {
|
|
@@ -74902,11 +74110,11 @@ async function updateFromChannel(args, deps) {
|
|
|
74902
74110
|
channelRef.extId,
|
|
74903
74111
|
channelRef.ownerPrincipalId
|
|
74904
74112
|
);
|
|
74905
|
-
const liveDir =
|
|
74113
|
+
const liveDir = import_node_path76.default.join(deps.extensionsRoot, localExtId);
|
|
74906
74114
|
const prevDir = `${liveDir}.prev`;
|
|
74907
74115
|
let existingVersion;
|
|
74908
74116
|
try {
|
|
74909
|
-
const raw = await import_promises14.default.readFile(
|
|
74117
|
+
const raw = await import_promises14.default.readFile(import_node_path76.default.join(liveDir, "manifest.json"), "utf8");
|
|
74910
74118
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
74911
74119
|
if (!parsed2.success) {
|
|
74912
74120
|
throw new UpdateError(
|
|
@@ -74925,7 +74133,7 @@ async function updateFromChannel(args, deps) {
|
|
|
74925
74133
|
if (e instanceof UpdateError) throw e;
|
|
74926
74134
|
throw e;
|
|
74927
74135
|
}
|
|
74928
|
-
const computed =
|
|
74136
|
+
const computed = import_node_crypto25.default.createHash("sha256").update(bundleZip).digest("hex");
|
|
74929
74137
|
if (computed !== snapshotHash) {
|
|
74930
74138
|
throw new UpdateError(
|
|
74931
74139
|
"HASH_MISMATCH",
|
|
@@ -74939,7 +74147,7 @@ async function updateFromChannel(args, deps) {
|
|
|
74939
74147
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
74940
74148
|
}
|
|
74941
74149
|
for (const name of Object.keys(zip.files)) {
|
|
74942
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
74150
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path76.default.isAbsolute(name)) {
|
|
74943
74151
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
74944
74152
|
}
|
|
74945
74153
|
}
|
|
@@ -74974,16 +74182,16 @@ async function updateFromChannel(args, deps) {
|
|
|
74974
74182
|
await import_promises14.default.rm(prevDir, { recursive: true, force: true });
|
|
74975
74183
|
await import_promises14.default.rename(liveDir, prevDir);
|
|
74976
74184
|
const stage = await import_promises14.default.mkdtemp(
|
|
74977
|
-
|
|
74185
|
+
import_node_path76.default.join(import_node_os29.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
74978
74186
|
);
|
|
74979
74187
|
try {
|
|
74980
74188
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
74981
|
-
const dest =
|
|
74189
|
+
const dest = import_node_path76.default.join(stage, name);
|
|
74982
74190
|
if (entry.dir) {
|
|
74983
74191
|
await import_promises14.default.mkdir(dest, { recursive: true });
|
|
74984
74192
|
continue;
|
|
74985
74193
|
}
|
|
74986
|
-
await import_promises14.default.mkdir(
|
|
74194
|
+
await import_promises14.default.mkdir(import_node_path76.default.dirname(dest), { recursive: true });
|
|
74987
74195
|
if (name === "manifest.json") {
|
|
74988
74196
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
74989
74197
|
await import_promises14.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -75050,7 +74258,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
75050
74258
|
);
|
|
75051
74259
|
}
|
|
75052
74260
|
}
|
|
75053
|
-
const manifestPath =
|
|
74261
|
+
const manifestPath = import_node_path77.default.join(root, extId, "manifest.json");
|
|
75054
74262
|
const manifest = await readManifest(root, extId);
|
|
75055
74263
|
const next = { ...manifest, version: newVersion };
|
|
75056
74264
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -75058,7 +74266,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
75058
74266
|
await import_promises15.default.rename(tmp, manifestPath);
|
|
75059
74267
|
}
|
|
75060
74268
|
async function readManifest(root, extId) {
|
|
75061
|
-
const file =
|
|
74269
|
+
const file = import_node_path77.default.join(root, extId, "manifest.json");
|
|
75062
74270
|
let raw;
|
|
75063
74271
|
try {
|
|
75064
74272
|
raw = await import_promises15.default.readFile(file, "utf8");
|
|
@@ -75142,7 +74350,7 @@ function buildExtensionHandlers(deps) {
|
|
|
75142
74350
|
};
|
|
75143
74351
|
async function buildSnapshotMeta(extId) {
|
|
75144
74352
|
const manifest = await readManifest(deps.root, extId);
|
|
75145
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
74353
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path77.default.join(deps.root, extId));
|
|
75146
74354
|
return { manifest, contentHash: sha256, buffer };
|
|
75147
74355
|
}
|
|
75148
74356
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -75970,7 +75178,7 @@ function buildVisitorHandlers(deps) {
|
|
|
75970
75178
|
|
|
75971
75179
|
// src/extension/registry.ts
|
|
75972
75180
|
var import_promises17 = __toESM(require("fs/promises"), 1);
|
|
75973
|
-
var
|
|
75181
|
+
var import_node_path78 = __toESM(require("path"), 1);
|
|
75974
75182
|
async function loadAll(root) {
|
|
75975
75183
|
let entries;
|
|
75976
75184
|
try {
|
|
@@ -75983,13 +75191,13 @@ async function loadAll(root) {
|
|
|
75983
75191
|
for (const ent of entries) {
|
|
75984
75192
|
if (!ent.isDirectory()) continue;
|
|
75985
75193
|
if (ent.name.startsWith(".")) continue;
|
|
75986
|
-
records.push(await loadOne(
|
|
75194
|
+
records.push(await loadOne(import_node_path78.default.join(root, ent.name), ent.name));
|
|
75987
75195
|
}
|
|
75988
75196
|
records.sort((a2, b3) => a2.extId < b3.extId ? -1 : a2.extId > b3.extId ? 1 : 0);
|
|
75989
75197
|
return records;
|
|
75990
75198
|
}
|
|
75991
75199
|
async function loadOne(dir, dirName) {
|
|
75992
|
-
const manifestPath =
|
|
75200
|
+
const manifestPath = import_node_path78.default.join(dir, "manifest.json");
|
|
75993
75201
|
let raw;
|
|
75994
75202
|
try {
|
|
75995
75203
|
raw = await import_promises17.default.readFile(manifestPath, "utf8");
|
|
@@ -76034,7 +75242,7 @@ async function loadOne(dir, dirName) {
|
|
|
76034
75242
|
|
|
76035
75243
|
// src/extension/uninstall.ts
|
|
76036
75244
|
var import_promises18 = __toESM(require("fs/promises"), 1);
|
|
76037
|
-
var
|
|
75245
|
+
var import_node_path79 = __toESM(require("path"), 1);
|
|
76038
75246
|
var UninstallError = class extends Error {
|
|
76039
75247
|
constructor(code, message) {
|
|
76040
75248
|
super(message);
|
|
@@ -76043,7 +75251,7 @@ var UninstallError = class extends Error {
|
|
|
76043
75251
|
code;
|
|
76044
75252
|
};
|
|
76045
75253
|
async function uninstall(deps) {
|
|
76046
|
-
const dir =
|
|
75254
|
+
const dir = import_node_path79.default.join(deps.root, deps.extId);
|
|
76047
75255
|
try {
|
|
76048
75256
|
await import_promises18.default.access(dir);
|
|
76049
75257
|
} catch {
|
|
@@ -76054,7 +75262,7 @@ async function uninstall(deps) {
|
|
|
76054
75262
|
}
|
|
76055
75263
|
|
|
76056
75264
|
// src/handlers/index.ts
|
|
76057
|
-
var
|
|
75265
|
+
var import_node_crypto26 = require("crypto");
|
|
76058
75266
|
|
|
76059
75267
|
// src/handlers/peer-exec.ts
|
|
76060
75268
|
init_protocol();
|
|
@@ -76211,7 +75419,7 @@ function buildMethodHandlers(deps) {
|
|
|
76211
75419
|
const c2 = deps.contactStore.get(deviceId);
|
|
76212
75420
|
return c2 ? { deviceId: c2.deviceId, remoteUrl: c2.remoteUrl, connectToken: c2.connectToken } : null;
|
|
76213
75421
|
},
|
|
76214
|
-
genId: () => (0,
|
|
75422
|
+
genId: () => (0, import_node_crypto26.randomUUID)(),
|
|
76215
75423
|
now: () => Date.now(),
|
|
76216
75424
|
forwardInboxPostToPeer,
|
|
76217
75425
|
logger: deps.logger
|
|
@@ -76261,7 +75469,7 @@ function buildMethodHandlers(deps) {
|
|
|
76261
75469
|
broadcast: deps.broadcastToOwners
|
|
76262
75470
|
}),
|
|
76263
75471
|
...buildMasterHandlers({
|
|
76264
|
-
authorityTablePath:
|
|
75472
|
+
authorityTablePath: import_node_path80.default.join(deps.masterDataDir, "master-authority.json")
|
|
76265
75473
|
}),
|
|
76266
75474
|
...buildTopicHandlers({
|
|
76267
75475
|
topicStore: deps.topicStore,
|
|
@@ -76404,7 +75612,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
76404
75612
|
|
|
76405
75613
|
// src/extension/runtime.ts
|
|
76406
75614
|
var import_node_child_process25 = require("child_process");
|
|
76407
|
-
var
|
|
75615
|
+
var import_node_path81 = __toESM(require("path"), 1);
|
|
76408
75616
|
var import_promises19 = require("timers/promises");
|
|
76409
75617
|
|
|
76410
75618
|
// src/extension/port-allocator.ts
|
|
@@ -76505,7 +75713,7 @@ var Runtime = class {
|
|
|
76505
75713
|
/\$CLAWOS_EXT_PORT/g,
|
|
76506
75714
|
String(port)
|
|
76507
75715
|
);
|
|
76508
|
-
const dir =
|
|
75716
|
+
const dir = import_node_path81.default.join(this.root, extId);
|
|
76509
75717
|
const env = {
|
|
76510
75718
|
...process.env,
|
|
76511
75719
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -76617,7 +75825,7 @@ ${handle.stderrTail}`
|
|
|
76617
75825
|
|
|
76618
75826
|
// src/extension/published-channels.ts
|
|
76619
75827
|
var import_promises20 = __toESM(require("fs/promises"), 1);
|
|
76620
|
-
var
|
|
75828
|
+
var import_node_path82 = __toESM(require("path"), 1);
|
|
76621
75829
|
init_zod();
|
|
76622
75830
|
var PublishedChannelsError = class extends Error {
|
|
76623
75831
|
constructor(code, message) {
|
|
@@ -76716,7 +75924,7 @@ var PublishedChannelStore = class {
|
|
|
76716
75924
|
)
|
|
76717
75925
|
};
|
|
76718
75926
|
const tmp = `${this.filePath}.tmp`;
|
|
76719
|
-
await import_promises20.default.mkdir(
|
|
75927
|
+
await import_promises20.default.mkdir(import_node_path82.default.dirname(this.filePath), { recursive: true });
|
|
76720
75928
|
await import_promises20.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
76721
75929
|
await import_promises20.default.rename(tmp, this.filePath);
|
|
76722
75930
|
}
|
|
@@ -76724,7 +75932,7 @@ var PublishedChannelStore = class {
|
|
|
76724
75932
|
|
|
76725
75933
|
// src/extension/bundle-cache.ts
|
|
76726
75934
|
var import_promises21 = __toESM(require("fs/promises"), 1);
|
|
76727
|
-
var
|
|
75935
|
+
var import_node_path83 = __toESM(require("path"), 1);
|
|
76728
75936
|
var BundleCache = class {
|
|
76729
75937
|
constructor(rootDir) {
|
|
76730
75938
|
this.rootDir = rootDir;
|
|
@@ -76733,14 +75941,14 @@ var BundleCache = class {
|
|
|
76733
75941
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
76734
75942
|
async write(snapshotHash, buffer) {
|
|
76735
75943
|
await import_promises21.default.mkdir(this.rootDir, { recursive: true });
|
|
76736
|
-
const file =
|
|
75944
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76737
75945
|
const tmp = `${file}.tmp`;
|
|
76738
75946
|
await import_promises21.default.writeFile(tmp, buffer, { mode: 384 });
|
|
76739
75947
|
await import_promises21.default.rename(tmp, file);
|
|
76740
75948
|
}
|
|
76741
75949
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
76742
75950
|
async read(snapshotHash) {
|
|
76743
|
-
const file =
|
|
75951
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76744
75952
|
try {
|
|
76745
75953
|
return await import_promises21.default.readFile(file);
|
|
76746
75954
|
} catch (e) {
|
|
@@ -76750,7 +75958,7 @@ var BundleCache = class {
|
|
|
76750
75958
|
}
|
|
76751
75959
|
/** Idempotent — missing file is not an error. */
|
|
76752
75960
|
async delete(snapshotHash) {
|
|
76753
|
-
const file =
|
|
75961
|
+
const file = import_node_path83.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
76754
75962
|
await import_promises21.default.rm(file, { force: true });
|
|
76755
75963
|
}
|
|
76756
75964
|
};
|
|
@@ -76773,24 +75981,24 @@ async function startDaemon(config) {
|
|
|
76773
75981
|
sampling: logShippingCfg.sampling,
|
|
76774
75982
|
homeDir: import_node_os31.default.homedir()
|
|
76775
75983
|
});
|
|
76776
|
-
const logDir =
|
|
76777
|
-
|
|
75984
|
+
const logDir = import_node_path84.default.join(config.dataDir, "log");
|
|
75985
|
+
import_node_fs65.default.mkdirSync(logDir, { recursive: true });
|
|
76778
75986
|
const logger = createLogger({
|
|
76779
75987
|
level: config.logLevel,
|
|
76780
|
-
file:
|
|
75988
|
+
file: import_node_path84.default.join(logDir, "clawd.log"),
|
|
76781
75989
|
logClient
|
|
76782
75990
|
});
|
|
76783
75991
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
76784
75992
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
76785
|
-
file:
|
|
75993
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log"),
|
|
76786
75994
|
level: "debug"
|
|
76787
75995
|
});
|
|
76788
75996
|
logger.info("screen-idle probe logger enabled", {
|
|
76789
|
-
file:
|
|
75997
|
+
file: import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
76790
75998
|
});
|
|
76791
75999
|
const CAP_TARGETS = [
|
|
76792
|
-
|
|
76793
|
-
|
|
76000
|
+
import_node_path84.default.join(logDir, "clawd.log"),
|
|
76001
|
+
import_node_path84.default.join(logDir, "screen-idle-probe.log")
|
|
76794
76002
|
];
|
|
76795
76003
|
const LOG_CAP_MAX_BYTES = 10 * 1024 * 1024;
|
|
76796
76004
|
const LOG_CAP_KEEP_BYTES = 5 * 1024 * 1024;
|
|
@@ -76912,11 +76120,11 @@ async function startDaemon(config) {
|
|
|
76912
76120
|
const agents = new AgentsScanner();
|
|
76913
76121
|
const history = new ClaudeHistoryReader();
|
|
76914
76122
|
let transport = null;
|
|
76915
|
-
const personaStore = new PersonaStore(
|
|
76123
|
+
const personaStore = new PersonaStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
76916
76124
|
const subscriptionChannelStore = new SubscriptionChannelStore({ dataDir: config.dataDir });
|
|
76917
76125
|
const activeSubscriptionChannel = subscriptionChannelStore.getActive();
|
|
76918
76126
|
if (activeSubscriptionChannel) applyPiSubscriptionChannel({ channel: activeSubscriptionChannel });
|
|
76919
|
-
const usersRoot =
|
|
76127
|
+
const usersRoot = import_node_path84.default.join(config.dataDir, "users");
|
|
76920
76128
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
76921
76129
|
if (defaultsRoot) {
|
|
76922
76130
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -76933,7 +76141,7 @@ async function startDaemon(config) {
|
|
|
76933
76141
|
retirePersonaBuilder({ store: personaStore, logger });
|
|
76934
76142
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
76935
76143
|
const dispatchStore = createDispatchStore({
|
|
76936
|
-
filePath:
|
|
76144
|
+
filePath: import_node_path84.default.join(config.dataDir, "dispatch.json"),
|
|
76937
76145
|
now: () => Date.now(),
|
|
76938
76146
|
onFlushError: (err) => logger.error("dispatch store flush failed", {
|
|
76939
76147
|
reason: err instanceof Error ? err.message : String(err)
|
|
@@ -76942,18 +76150,18 @@ async function startDaemon(config) {
|
|
|
76942
76150
|
await dispatchStore.load();
|
|
76943
76151
|
dispatchStore.markInterruptedAsFailed((/* @__PURE__ */ new Date()).toISOString());
|
|
76944
76152
|
const channelStore = createChannelStore({
|
|
76945
|
-
filePath:
|
|
76153
|
+
filePath: import_node_path84.default.join(config.dataDir, "channels.json"),
|
|
76946
76154
|
now: () => Date.now(),
|
|
76947
|
-
genId: () => `ch-${(0,
|
|
76155
|
+
genId: () => `ch-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
|
|
76948
76156
|
onFlushError: (err) => logger.error("channel store flush failed", {
|
|
76949
76157
|
reason: err instanceof Error ? err.message : String(err)
|
|
76950
76158
|
})
|
|
76951
76159
|
});
|
|
76952
76160
|
await channelStore.load();
|
|
76953
76161
|
const topicStore = createTopicStore({
|
|
76954
|
-
filePath:
|
|
76162
|
+
filePath: import_node_path84.default.join(config.dataDir, "topics.json"),
|
|
76955
76163
|
now: () => Date.now(),
|
|
76956
|
-
genId: () => `tp-${(0,
|
|
76164
|
+
genId: () => `tp-${(0, import_node_crypto27.randomUUID)().slice(0, 8)}`,
|
|
76957
76165
|
onFlushError: (err) => logger.error("topic store flush failed", {
|
|
76958
76166
|
reason: err instanceof Error ? err.message : String(err)
|
|
76959
76167
|
})
|
|
@@ -76961,7 +76169,7 @@ async function startDaemon(config) {
|
|
|
76961
76169
|
await topicStore.load();
|
|
76962
76170
|
let deliverPendingRef;
|
|
76963
76171
|
const personaDispatchManager = new PersonaDispatchManager({
|
|
76964
|
-
genId: () => (0,
|
|
76172
|
+
genId: () => (0, import_node_crypto27.randomUUID)(),
|
|
76965
76173
|
store: dispatchStore,
|
|
76966
76174
|
now: () => Date.now(),
|
|
76967
76175
|
onCompleted: (sid) => deliverPendingRef?.(sid),
|
|
@@ -76978,12 +76186,12 @@ async function startDaemon(config) {
|
|
|
76978
76186
|
});
|
|
76979
76187
|
}
|
|
76980
76188
|
});
|
|
76981
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
76189
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path84.default.dirname((0, import_node_url6.fileURLToPath)(import_meta10.url));
|
|
76982
76190
|
const mcpConfigs = [];
|
|
76983
76191
|
const secretsBundleRoot = findSecretsBundleRoot(logger);
|
|
76984
|
-
const localSecretsDir =
|
|
76192
|
+
const localSecretsDir = import_node_path84.default.join(config.dataDir, LOCAL_SECRETS_DIRNAME);
|
|
76985
76193
|
const readSecrets = () => readSecretTable({ bundleRoot: secretsBundleRoot, overrideDir: localSecretsDir, logger });
|
|
76986
|
-
const githubTokenFile =
|
|
76194
|
+
const githubTokenFile = import_node_path84.default.join(localSecretsDir, GITHUB_TOKEN_FILE);
|
|
76987
76195
|
const githubIdentity = createGithubIdentity({
|
|
76988
76196
|
resolve: () => resolveGithubAuth({ exec: runCommand, fileToken: () => readEnvFileVar(githubTokenFile, GITHUB_TOKEN_VAR) }),
|
|
76989
76197
|
store: (token) => storeGithubAuth({
|
|
@@ -77021,22 +76229,22 @@ async function startDaemon(config) {
|
|
|
77021
76229
|
void githubIdentity.refresh();
|
|
77022
76230
|
return renderPersonaMcpSecrets({
|
|
77023
76231
|
personaId: personaId2,
|
|
77024
|
-
personaDir:
|
|
76232
|
+
personaDir: import_node_path84.default.join(config.dataDir, "personas", personaId2),
|
|
77025
76233
|
secrets,
|
|
77026
|
-
outDir:
|
|
76234
|
+
outDir: import_node_path84.default.join(config.dataDir, "persona-mcp"),
|
|
77027
76235
|
logger
|
|
77028
76236
|
});
|
|
77029
76237
|
};
|
|
77030
76238
|
const mcpDaemonUrl = `http://127.0.0.1:${config.port}`;
|
|
77031
76239
|
const dispatchServerCandidates = [
|
|
77032
|
-
|
|
76240
|
+
import_node_path84.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
77033
76241
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
77034
|
-
|
|
76242
|
+
import_node_path84.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
77035
76243
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
77036
76244
|
];
|
|
77037
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) =>
|
|
76245
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77038
76246
|
if (dispatchServerScriptPath) {
|
|
77039
|
-
const dispatchLogPath =
|
|
76247
|
+
const dispatchLogPath = import_node_path84.default.join(logDir, "dispatch-mcp-server.log");
|
|
77040
76248
|
const dispatchCfgPath = writeDispatchMcpConfig({
|
|
77041
76249
|
dataDir: config.dataDir,
|
|
77042
76250
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -77056,12 +76264,12 @@ async function startDaemon(config) {
|
|
|
77056
76264
|
});
|
|
77057
76265
|
}
|
|
77058
76266
|
const ticketServerCandidates = [
|
|
77059
|
-
|
|
77060
|
-
|
|
76267
|
+
import_node_path84.default.join(here, "ticket", "mcp-server.cjs"),
|
|
76268
|
+
import_node_path84.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
77061
76269
|
];
|
|
77062
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p3) =>
|
|
76270
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77063
76271
|
if (ticketServerScriptPath) {
|
|
77064
|
-
const ticketLogPath =
|
|
76272
|
+
const ticketLogPath = import_node_path84.default.join(logDir, "ticket-mcp-server.log");
|
|
77065
76273
|
const ticketCfgPath = writeTicketMcpConfig({
|
|
77066
76274
|
dataDir: config.dataDir,
|
|
77067
76275
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -77083,12 +76291,12 @@ async function startDaemon(config) {
|
|
|
77083
76291
|
});
|
|
77084
76292
|
}
|
|
77085
76293
|
const shiftServerCandidates = [
|
|
77086
|
-
|
|
77087
|
-
|
|
76294
|
+
import_node_path84.default.join(here, "shift", "mcp-server.cjs"),
|
|
76295
|
+
import_node_path84.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
77088
76296
|
];
|
|
77089
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p3) =>
|
|
76297
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77090
76298
|
if (shiftServerScriptPath) {
|
|
77091
|
-
const shiftLogPath =
|
|
76299
|
+
const shiftLogPath = import_node_path84.default.join(logDir, "shift-mcp-server.log");
|
|
77092
76300
|
const shiftCfgPath = await writeShiftMcpConfig({
|
|
77093
76301
|
dataDir: config.dataDir,
|
|
77094
76302
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -77109,12 +76317,12 @@ async function startDaemon(config) {
|
|
|
77109
76317
|
);
|
|
77110
76318
|
}
|
|
77111
76319
|
const inboxServerCandidates = [
|
|
77112
|
-
|
|
77113
|
-
|
|
76320
|
+
import_node_path84.default.join(here, "inbox", "mcp-server.cjs"),
|
|
76321
|
+
import_node_path84.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
77114
76322
|
];
|
|
77115
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p3) =>
|
|
76323
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77116
76324
|
if (inboxServerScriptPath) {
|
|
77117
|
-
const inboxLogPath =
|
|
76325
|
+
const inboxLogPath = import_node_path84.default.join(logDir, "inbox-mcp-server.log");
|
|
77118
76326
|
const inboxCfgPath = await writeInboxMcpConfig({
|
|
77119
76327
|
dataDir: config.dataDir,
|
|
77120
76328
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -77135,10 +76343,10 @@ async function startDaemon(config) {
|
|
|
77135
76343
|
);
|
|
77136
76344
|
}
|
|
77137
76345
|
const peerOpsServerCandidates = [
|
|
77138
|
-
|
|
77139
|
-
|
|
76346
|
+
import_node_path84.default.join(here, "peer-ops", "mcp-server.cjs"),
|
|
76347
|
+
import_node_path84.default.join(here, "..", "dist", "peer-ops", "mcp-server.cjs")
|
|
77140
76348
|
];
|
|
77141
|
-
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) =>
|
|
76349
|
+
const peerOpsServerScriptPath = peerOpsServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77142
76350
|
if (peerOpsServerScriptPath) {
|
|
77143
76351
|
const peerOpsCfgPath = writePeerOpsMcpConfig({
|
|
77144
76352
|
dataDir: config.dataDir,
|
|
@@ -77158,12 +76366,12 @@ async function startDaemon(config) {
|
|
|
77158
76366
|
);
|
|
77159
76367
|
}
|
|
77160
76368
|
const rpcToolServerCandidates = [
|
|
77161
|
-
|
|
77162
|
-
|
|
76369
|
+
import_node_path84.default.join(here, "rpc-tool", "mcp-server.cjs"),
|
|
76370
|
+
import_node_path84.default.join(here, "..", "dist", "rpc-tool", "mcp-server.cjs")
|
|
77163
76371
|
];
|
|
77164
|
-
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) =>
|
|
76372
|
+
const rpcToolServerScriptPath = rpcToolServerCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77165
76373
|
if (rpcToolServerScriptPath) {
|
|
77166
|
-
const rpcToolLogPath =
|
|
76374
|
+
const rpcToolLogPath = import_node_path84.default.join(logDir, "rpc-tool-mcp-server.log");
|
|
77167
76375
|
const rpcToolCfgPath = writeRpcToolMcpConfig({
|
|
77168
76376
|
dataDir: config.dataDir,
|
|
77169
76377
|
serverScriptPath: rpcToolServerScriptPath,
|
|
@@ -77184,7 +76392,7 @@ async function startDaemon(config) {
|
|
|
77184
76392
|
);
|
|
77185
76393
|
}
|
|
77186
76394
|
const shiftStore = createShiftStore({
|
|
77187
|
-
filePath:
|
|
76395
|
+
filePath: import_node_path84.default.join(config.dataDir, "shift.json"),
|
|
77188
76396
|
ownerIdProvider: () => ownerPrincipalId,
|
|
77189
76397
|
now: () => Date.now()
|
|
77190
76398
|
});
|
|
@@ -77206,7 +76414,7 @@ async function startDaemon(config) {
|
|
|
77206
76414
|
getAdapter,
|
|
77207
76415
|
historyReader: history,
|
|
77208
76416
|
dataDir: config.dataDir,
|
|
77209
|
-
personaRoot:
|
|
76417
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
77210
76418
|
// dispatch / shift 自动化 spawn 按 persona 绑定 tool 起 B session(codex persona 用 codex)。
|
|
77211
76419
|
// personaRegistry 声明在 manager 之后(同作用域 const,调用时机在启动完成后,无 TDZ 风险)。
|
|
77212
76420
|
getPersonaDefaults: (personaId2) => personaRegistry.get(personaId2),
|
|
@@ -77267,10 +76475,10 @@ async function startDaemon(config) {
|
|
|
77267
76475
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
77268
76476
|
attachmentGroup: {
|
|
77269
76477
|
onFileEdit: (input) => {
|
|
77270
|
-
const absPath =
|
|
76478
|
+
const absPath = import_node_path84.default.isAbsolute(input.relPath) ? input.relPath : import_node_path84.default.join(input.cwd, input.relPath);
|
|
77271
76479
|
let size = 0;
|
|
77272
76480
|
try {
|
|
77273
|
-
size =
|
|
76481
|
+
size = import_node_fs65.default.statSync(absPath).size;
|
|
77274
76482
|
} catch (err) {
|
|
77275
76483
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
77276
76484
|
sessionId: input.sessionId,
|
|
@@ -77311,9 +76519,9 @@ async function startDaemon(config) {
|
|
|
77311
76519
|
logger.info("projects.seed-dropped", { dropped: droppedSeed.dropped, backup: droppedSeed.backup });
|
|
77312
76520
|
}
|
|
77313
76521
|
const projectsStore = new ProjectsStore({
|
|
77314
|
-
file:
|
|
76522
|
+
file: import_node_path84.default.join(config.dataDir, "projects.json"),
|
|
77315
76523
|
clawdDir: config.dataDir,
|
|
77316
|
-
codexStateFile:
|
|
76524
|
+
codexStateFile: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", ".codex-global-state.json"),
|
|
77317
76525
|
logger
|
|
77318
76526
|
});
|
|
77319
76527
|
const observer = new SessionObserver({
|
|
@@ -77377,11 +76585,6 @@ async function startDaemon(config) {
|
|
|
77377
76585
|
centralApi: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
77378
76586
|
logger
|
|
77379
76587
|
});
|
|
77380
|
-
const cloudCancelOutbox = new CloudCancelOutbox(
|
|
77381
|
-
import_node_path85.default.join(config.dataDir, "cloud-cancel-outbox"),
|
|
77382
|
-
(personaId2, clientSessionId, gatewaySessionId) => cloudGateway.cancelEventSession(personaId2, clientSessionId, gatewaySessionId),
|
|
77383
|
-
logger
|
|
77384
|
-
);
|
|
77385
76588
|
manager.setCloudCanceller(async (file, runner) => {
|
|
77386
76589
|
const personaId2 = personaIdFromCloudCwd(file.cwd);
|
|
77387
76590
|
if (!personaId2) throw new Error(`\u4E91\u4F1A\u8BDD ${file.sessionId} \u7F3A\u5C11 gateway persona ID`);
|
|
@@ -77390,27 +76593,16 @@ async function startDaemon(config) {
|
|
|
77390
76593
|
runner?.confirmCloudCancelled();
|
|
77391
76594
|
return;
|
|
77392
76595
|
}
|
|
77393
|
-
|
|
77394
|
-
if (!file.cloudGatewaySessionId) throw new Error(`\u4E91\u4F1A\u8BDD ${file.sessionId} \u5C1A\u672A\u6536\u5230 gateway ready`);
|
|
77395
|
-
cloudCancelOutbox.record(executionId, personaId2, file.cloudGatewaySessionId);
|
|
77396
|
-
try {
|
|
77397
|
-
await cloudGateway.cancelEventSession(personaId2, executionId, file.cloudGatewaySessionId);
|
|
77398
|
-
cloudCancelOutbox.confirm(executionId);
|
|
77399
|
-
runner?.confirmCloudCancelled();
|
|
77400
|
-
} catch (e) {
|
|
77401
|
-
cloudCancelOutbox.release(executionId);
|
|
77402
|
-
throw e;
|
|
77403
|
-
}
|
|
76596
|
+
runner?.confirmCloudCancelled();
|
|
77404
76597
|
});
|
|
77405
|
-
cloudCancelOutbox.start();
|
|
77406
76598
|
registerAdapter("claude", claudeAdapter);
|
|
77407
|
-
const codexIsolatedHome =
|
|
76599
|
+
const codexIsolatedHome = import_node_path84.default.join(config.dataDir, "codex-home");
|
|
77408
76600
|
try {
|
|
77409
|
-
|
|
76601
|
+
import_node_fs65.default.mkdirSync(codexIsolatedHome, { recursive: true });
|
|
77410
76602
|
for (const f2 of ["auth.json", "config.toml"]) {
|
|
77411
|
-
const link =
|
|
77412
|
-
const target =
|
|
77413
|
-
if (!
|
|
76603
|
+
const link = import_node_path84.default.join(codexIsolatedHome, f2);
|
|
76604
|
+
const target = import_node_path84.default.join(import_node_os31.default.homedir(), ".codex", f2);
|
|
76605
|
+
if (!import_node_fs65.default.existsSync(link) && import_node_fs65.default.existsSync(target)) import_node_fs65.default.symlinkSync(target, link);
|
|
77414
76606
|
}
|
|
77415
76607
|
} catch (err) {
|
|
77416
76608
|
logger.warn("codex isolated home setup failed", { err: String(err) });
|
|
@@ -77421,17 +76613,17 @@ async function startDaemon(config) {
|
|
|
77421
76613
|
logger,
|
|
77422
76614
|
historyReader: new CodexHistoryReader({
|
|
77423
76615
|
roots: codexRolloutRoots(config.dataDir),
|
|
77424
|
-
sharedHome:
|
|
76616
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
77425
76617
|
logger
|
|
77426
76618
|
}),
|
|
77427
76619
|
// projectPaths 每次调用现取 —— 用户新建 project 后立即生效,不用重启 daemon
|
|
77428
76620
|
codexHomeFor: (cwd) => resolveCodexHome({
|
|
77429
76621
|
cwd,
|
|
77430
|
-
personaRoot:
|
|
76622
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
77431
76623
|
// 必须用 listMerged(Codex registry ∪ 叠加层):只用本地 list() 的话,用户在
|
|
77432
76624
|
// Codex 里建的 project 不在表里,在它下面开的会话会被误判成隔离 → Codex 侧看不到
|
|
77433
76625
|
projectPaths: projectsStore.listMerged().map((x2) => x2.path),
|
|
77434
|
-
sharedHome:
|
|
76626
|
+
sharedHome: import_node_path84.default.join(import_node_os31.default.homedir(), ".codex"),
|
|
77435
76627
|
isolatedHome: codexIsolatedHome
|
|
77436
76628
|
}),
|
|
77437
76629
|
codexHomeForThread: (threadId) => locateCodexThread(codexRolloutRoots(config.dataDir), threadId)?.home,
|
|
@@ -77457,10 +76649,10 @@ async function startDaemon(config) {
|
|
|
77457
76649
|
);
|
|
77458
76650
|
registerAdapter(PI_CLOUD_TOOL_ID, new CloudPiAdapter({ client: cloudGateway, history: cloudHistorySource, logger }));
|
|
77459
76651
|
const piMcpBridgeCandidates = [
|
|
77460
|
-
|
|
77461
|
-
|
|
76652
|
+
import_node_path84.default.join(here, "pi-mcp-bridge", "extension.cjs"),
|
|
76653
|
+
import_node_path84.default.join(here, "..", "dist", "pi-mcp-bridge", "extension.cjs")
|
|
77462
76654
|
];
|
|
77463
|
-
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) =>
|
|
76655
|
+
const piMcpBridgePath = piMcpBridgeCandidates.find((p3) => import_node_fs65.default.existsSync(p3));
|
|
77464
76656
|
if (piMcpBridgePath) {
|
|
77465
76657
|
logger.info("pi-mcp-bridge extension resolved", { path: piMcpBridgePath });
|
|
77466
76658
|
} else {
|
|
@@ -77766,11 +76958,11 @@ async function startDaemon(config) {
|
|
|
77766
76958
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
77767
76959
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
77768
76960
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
77769
|
-
personaRoot:
|
|
76961
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
77770
76962
|
usersRoot
|
|
77771
76963
|
},
|
|
77772
76964
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
77773
|
-
personaRoot:
|
|
76965
|
+
personaRoot: import_node_path84.default.join(config.dataDir, "personas"),
|
|
77774
76966
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
77775
76967
|
usersRoot,
|
|
77776
76968
|
// v2 Phase 6: whoami handler 装在 owner principal.displayName + persona 解析
|
|
@@ -78076,7 +77268,7 @@ async function startDaemon(config) {
|
|
|
78076
77268
|
});
|
|
78077
77269
|
shiftScheduler.start();
|
|
78078
77270
|
logger.info("shift scheduler started", { shiftCount: shiftStore.list().length });
|
|
78079
|
-
const larkBotStore = createLarkBotBindingStore(
|
|
77271
|
+
const larkBotStore = createLarkBotBindingStore(import_node_path84.default.join(config.dataDir, "personas"));
|
|
78080
77272
|
const larkBotCloud = createLarkBotCloudClient({
|
|
78081
77273
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
78082
77274
|
getLoginPass: () => ownerIdentityStore.read()?.loginPass ?? null
|
|
@@ -78088,7 +77280,7 @@ async function startDaemon(config) {
|
|
|
78088
77280
|
store: larkBotStore,
|
|
78089
77281
|
fetchResource: (appId, messageId, fileKey, maxBytes, type) => larkBotCloud.fetchResource(appId, messageId, fileKey, maxBytes, type),
|
|
78090
77282
|
// 图片落 guest userWorkDir 下(capId = lark-<chat_id>):CC 经 --add-dir + allowRead carve 可 Read
|
|
78091
|
-
mediaRootFor: (chatId) =>
|
|
77283
|
+
mediaRootFor: (chatId) => import_node_path84.default.join(deriveUserWorkDir(`lark-${chatId}`, usersRoot), "lark-media"),
|
|
78092
77284
|
isShuttingDown: () => larkDraining,
|
|
78093
77285
|
logger: {
|
|
78094
77286
|
warn: (msg) => logger.warn(msg),
|
|
@@ -78401,8 +77593,8 @@ async function startDaemon(config) {
|
|
|
78401
77593
|
const lines = [
|
|
78402
77594
|
`Tunnel: ${r2.url}`,
|
|
78403
77595
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
78404
|
-
`Frpc config: ${
|
|
78405
|
-
`Frpc log: ${
|
|
77596
|
+
`Frpc config: ${import_node_path84.default.join(config.dataDir, "frpc.toml")}`,
|
|
77597
|
+
`Frpc log: ${import_node_path84.default.join(logDir, "frpc.log")}`
|
|
78406
77598
|
];
|
|
78407
77599
|
const width2 = Math.max(...lines.map((l2) => l2.length));
|
|
78408
77600
|
const bar = "\u2550".repeat(width2 + 4);
|
|
@@ -78415,8 +77607,8 @@ ${bar}
|
|
|
78415
77607
|
|
|
78416
77608
|
`);
|
|
78417
77609
|
try {
|
|
78418
|
-
const connectPath =
|
|
78419
|
-
|
|
77610
|
+
const connectPath = import_node_path84.default.join(config.dataDir, "connect.txt");
|
|
77611
|
+
import_node_fs65.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
78420
77612
|
} catch {
|
|
78421
77613
|
}
|
|
78422
77614
|
} catch (err) {
|
|
@@ -78485,7 +77677,6 @@ ${bar}
|
|
|
78485
77677
|
larkDraining = true;
|
|
78486
77678
|
clearInterval(attachmentGcInterval);
|
|
78487
77679
|
clearInterval(cloudRecoveryInterval);
|
|
78488
|
-
cloudCancelOutbox.stop();
|
|
78489
77680
|
observer.stopAll();
|
|
78490
77681
|
manager.stopAll();
|
|
78491
77682
|
await extensionRuntime.stopAll();
|
|
@@ -78516,9 +77707,9 @@ ${bar}
|
|
|
78516
77707
|
};
|
|
78517
77708
|
}
|
|
78518
77709
|
function migrateDropPersonsDir(dataDir) {
|
|
78519
|
-
const dir =
|
|
77710
|
+
const dir = import_node_path84.default.join(dataDir, "persons");
|
|
78520
77711
|
try {
|
|
78521
|
-
|
|
77712
|
+
import_node_fs65.default.rmSync(dir, { recursive: true, force: true });
|
|
78522
77713
|
} catch {
|
|
78523
77714
|
}
|
|
78524
77715
|
}
|