@clawos-dev/clawd 0.2.203 → 0.2.204
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 +445 -370
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -742,8 +742,8 @@ var init_parseUtil = __esm({
|
|
|
742
742
|
init_errors2();
|
|
743
743
|
init_en();
|
|
744
744
|
makeIssue = (params) => {
|
|
745
|
-
const { data, path:
|
|
746
|
-
const fullPath = [...
|
|
745
|
+
const { data, path: path77, errorMaps, issueData } = params;
|
|
746
|
+
const fullPath = [...path77, ...issueData.path || []];
|
|
747
747
|
const fullIssue = {
|
|
748
748
|
...issueData,
|
|
749
749
|
path: fullPath
|
|
@@ -1054,11 +1054,11 @@ var init_types = __esm({
|
|
|
1054
1054
|
init_parseUtil();
|
|
1055
1055
|
init_util();
|
|
1056
1056
|
ParseInputLazyPath = class {
|
|
1057
|
-
constructor(parent, value,
|
|
1057
|
+
constructor(parent, value, path77, key) {
|
|
1058
1058
|
this._cachedPath = [];
|
|
1059
1059
|
this.parent = parent;
|
|
1060
1060
|
this.data = value;
|
|
1061
|
-
this._path =
|
|
1061
|
+
this._path = path77;
|
|
1062
1062
|
this._key = key;
|
|
1063
1063
|
}
|
|
1064
1064
|
get path() {
|
|
@@ -6449,8 +6449,8 @@ var require_req = __commonJS({
|
|
|
6449
6449
|
if (req.originalUrl) {
|
|
6450
6450
|
_req.url = req.originalUrl;
|
|
6451
6451
|
} else {
|
|
6452
|
-
const
|
|
6453
|
-
_req.url = typeof
|
|
6452
|
+
const path77 = req.path;
|
|
6453
|
+
_req.url = typeof path77 === "string" ? path77 : req.url ? req.url.path || req.url : void 0;
|
|
6454
6454
|
}
|
|
6455
6455
|
if (req.query) {
|
|
6456
6456
|
_req.query = req.query;
|
|
@@ -6615,14 +6615,14 @@ var require_redact = __commonJS({
|
|
|
6615
6615
|
}
|
|
6616
6616
|
return obj;
|
|
6617
6617
|
}
|
|
6618
|
-
function parsePath(
|
|
6618
|
+
function parsePath(path77) {
|
|
6619
6619
|
const parts = [];
|
|
6620
6620
|
let current = "";
|
|
6621
6621
|
let inBrackets = false;
|
|
6622
6622
|
let inQuotes = false;
|
|
6623
6623
|
let quoteChar = "";
|
|
6624
|
-
for (let i = 0; i <
|
|
6625
|
-
const char =
|
|
6624
|
+
for (let i = 0; i < path77.length; i++) {
|
|
6625
|
+
const char = path77[i];
|
|
6626
6626
|
if (!inBrackets && char === ".") {
|
|
6627
6627
|
if (current) {
|
|
6628
6628
|
parts.push(current);
|
|
@@ -6753,10 +6753,10 @@ var require_redact = __commonJS({
|
|
|
6753
6753
|
return current;
|
|
6754
6754
|
}
|
|
6755
6755
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6756
|
-
for (const
|
|
6757
|
-
const parts = parsePath(
|
|
6756
|
+
for (const path77 of paths) {
|
|
6757
|
+
const parts = parsePath(path77);
|
|
6758
6758
|
if (parts.includes("*")) {
|
|
6759
|
-
redactWildcardPath(obj, parts, censor,
|
|
6759
|
+
redactWildcardPath(obj, parts, censor, path77, remove);
|
|
6760
6760
|
} else {
|
|
6761
6761
|
if (remove) {
|
|
6762
6762
|
removeKey(obj, parts);
|
|
@@ -6841,8 +6841,8 @@ var require_redact = __commonJS({
|
|
|
6841
6841
|
}
|
|
6842
6842
|
} else {
|
|
6843
6843
|
if (afterWildcard.includes("*")) {
|
|
6844
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6845
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6844
|
+
const wrappedCensor = typeof censor === "function" ? (value, path77) => {
|
|
6845
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path77];
|
|
6846
6846
|
return censor(value, fullPath);
|
|
6847
6847
|
} : censor;
|
|
6848
6848
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6877,8 +6877,8 @@ var require_redact = __commonJS({
|
|
|
6877
6877
|
return null;
|
|
6878
6878
|
}
|
|
6879
6879
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6880
|
-
for (const
|
|
6881
|
-
const parts = parsePath(
|
|
6880
|
+
for (const path77 of pathsToClone) {
|
|
6881
|
+
const parts = parsePath(path77);
|
|
6882
6882
|
let current = pathStructure;
|
|
6883
6883
|
for (let i = 0; i < parts.length; i++) {
|
|
6884
6884
|
const part = parts[i];
|
|
@@ -6930,24 +6930,24 @@ var require_redact = __commonJS({
|
|
|
6930
6930
|
}
|
|
6931
6931
|
return cloneSelectively(obj, pathStructure);
|
|
6932
6932
|
}
|
|
6933
|
-
function validatePath(
|
|
6934
|
-
if (typeof
|
|
6933
|
+
function validatePath(path77) {
|
|
6934
|
+
if (typeof path77 !== "string") {
|
|
6935
6935
|
throw new Error("Paths must be (non-empty) strings");
|
|
6936
6936
|
}
|
|
6937
|
-
if (
|
|
6937
|
+
if (path77 === "") {
|
|
6938
6938
|
throw new Error("Invalid redaction path ()");
|
|
6939
6939
|
}
|
|
6940
|
-
if (
|
|
6941
|
-
throw new Error(`Invalid redaction path (${
|
|
6940
|
+
if (path77.includes("..")) {
|
|
6941
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6942
6942
|
}
|
|
6943
|
-
if (
|
|
6944
|
-
throw new Error(`Invalid redaction path (${
|
|
6943
|
+
if (path77.includes(",")) {
|
|
6944
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6945
6945
|
}
|
|
6946
6946
|
let bracketCount = 0;
|
|
6947
6947
|
let inQuotes = false;
|
|
6948
6948
|
let quoteChar = "";
|
|
6949
|
-
for (let i = 0; i <
|
|
6950
|
-
const char =
|
|
6949
|
+
for (let i = 0; i < path77.length; i++) {
|
|
6950
|
+
const char = path77[i];
|
|
6951
6951
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6952
6952
|
if (!inQuotes) {
|
|
6953
6953
|
inQuotes = true;
|
|
@@ -6961,20 +6961,20 @@ var require_redact = __commonJS({
|
|
|
6961
6961
|
} else if (char === "]" && !inQuotes) {
|
|
6962
6962
|
bracketCount--;
|
|
6963
6963
|
if (bracketCount < 0) {
|
|
6964
|
-
throw new Error(`Invalid redaction path (${
|
|
6964
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6965
6965
|
}
|
|
6966
6966
|
}
|
|
6967
6967
|
}
|
|
6968
6968
|
if (bracketCount !== 0) {
|
|
6969
|
-
throw new Error(`Invalid redaction path (${
|
|
6969
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6970
6970
|
}
|
|
6971
6971
|
}
|
|
6972
6972
|
function validatePaths(paths) {
|
|
6973
6973
|
if (!Array.isArray(paths)) {
|
|
6974
6974
|
throw new TypeError("paths must be an array");
|
|
6975
6975
|
}
|
|
6976
|
-
for (const
|
|
6977
|
-
validatePath(
|
|
6976
|
+
for (const path77 of paths) {
|
|
6977
|
+
validatePath(path77);
|
|
6978
6978
|
}
|
|
6979
6979
|
}
|
|
6980
6980
|
function slowRedact(options = {}) {
|
|
@@ -7142,8 +7142,8 @@ var require_redaction = __commonJS({
|
|
|
7142
7142
|
if (shape[k2] === null) {
|
|
7143
7143
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
7144
7144
|
} else {
|
|
7145
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7146
|
-
return censor(value, [k2, ...
|
|
7145
|
+
const wrappedCensor = typeof censor === "function" ? (value, path77) => {
|
|
7146
|
+
return censor(value, [k2, ...path77]);
|
|
7147
7147
|
} : censor;
|
|
7148
7148
|
o[k2] = Redact({
|
|
7149
7149
|
paths: shape[k2],
|
|
@@ -7361,10 +7361,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
7361
7361
|
var require_sonic_boom = __commonJS({
|
|
7362
7362
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
7363
7363
|
"use strict";
|
|
7364
|
-
var
|
|
7364
|
+
var fs70 = require("fs");
|
|
7365
7365
|
var EventEmitter3 = require("events");
|
|
7366
7366
|
var inherits = require("util").inherits;
|
|
7367
|
-
var
|
|
7367
|
+
var path77 = require("path");
|
|
7368
7368
|
var sleep2 = require_atomic_sleep();
|
|
7369
7369
|
var assert = require("assert");
|
|
7370
7370
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7418,20 +7418,20 @@ var require_sonic_boom = __commonJS({
|
|
|
7418
7418
|
const mode = sonic.mode;
|
|
7419
7419
|
if (sonic.sync) {
|
|
7420
7420
|
try {
|
|
7421
|
-
if (sonic.mkdir)
|
|
7422
|
-
const fd =
|
|
7421
|
+
if (sonic.mkdir) fs70.mkdirSync(path77.dirname(file), { recursive: true });
|
|
7422
|
+
const fd = fs70.openSync(file, flags, mode);
|
|
7423
7423
|
fileOpened(null, fd);
|
|
7424
7424
|
} catch (err) {
|
|
7425
7425
|
fileOpened(err);
|
|
7426
7426
|
throw err;
|
|
7427
7427
|
}
|
|
7428
7428
|
} else if (sonic.mkdir) {
|
|
7429
|
-
|
|
7429
|
+
fs70.mkdir(path77.dirname(file), { recursive: true }, (err) => {
|
|
7430
7430
|
if (err) return fileOpened(err);
|
|
7431
|
-
|
|
7431
|
+
fs70.open(file, flags, mode, fileOpened);
|
|
7432
7432
|
});
|
|
7433
7433
|
} else {
|
|
7434
|
-
|
|
7434
|
+
fs70.open(file, flags, mode, fileOpened);
|
|
7435
7435
|
}
|
|
7436
7436
|
}
|
|
7437
7437
|
function SonicBoom(opts) {
|
|
@@ -7472,8 +7472,8 @@ var require_sonic_boom = __commonJS({
|
|
|
7472
7472
|
this.flush = flushBuffer;
|
|
7473
7473
|
this.flushSync = flushBufferSync;
|
|
7474
7474
|
this._actualWrite = actualWriteBuffer;
|
|
7475
|
-
fsWriteSync = () =>
|
|
7476
|
-
fsWrite = () =>
|
|
7475
|
+
fsWriteSync = () => fs70.writeSync(this.fd, this._writingBuf);
|
|
7476
|
+
fsWrite = () => fs70.write(this.fd, this._writingBuf, this.release);
|
|
7477
7477
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
7478
7478
|
this._writingBuf = "";
|
|
7479
7479
|
this.write = write;
|
|
@@ -7482,15 +7482,15 @@ var require_sonic_boom = __commonJS({
|
|
|
7482
7482
|
this._actualWrite = actualWrite;
|
|
7483
7483
|
fsWriteSync = () => {
|
|
7484
7484
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7485
|
-
return
|
|
7485
|
+
return fs70.writeSync(this.fd, this._writingBuf);
|
|
7486
7486
|
}
|
|
7487
|
-
return
|
|
7487
|
+
return fs70.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7488
7488
|
};
|
|
7489
7489
|
fsWrite = () => {
|
|
7490
7490
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7491
|
-
return
|
|
7491
|
+
return fs70.write(this.fd, this._writingBuf, this.release);
|
|
7492
7492
|
}
|
|
7493
|
-
return
|
|
7493
|
+
return fs70.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
7494
7494
|
};
|
|
7495
7495
|
} else {
|
|
7496
7496
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -7547,7 +7547,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7547
7547
|
}
|
|
7548
7548
|
}
|
|
7549
7549
|
if (this._fsync) {
|
|
7550
|
-
|
|
7550
|
+
fs70.fsyncSync(this.fd);
|
|
7551
7551
|
}
|
|
7552
7552
|
const len = this._len;
|
|
7553
7553
|
if (this._reopening) {
|
|
@@ -7661,7 +7661,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7661
7661
|
const onDrain = () => {
|
|
7662
7662
|
if (!this._fsync) {
|
|
7663
7663
|
try {
|
|
7664
|
-
|
|
7664
|
+
fs70.fsync(this.fd, (err) => {
|
|
7665
7665
|
this._flushPending = false;
|
|
7666
7666
|
cb(err);
|
|
7667
7667
|
});
|
|
@@ -7763,7 +7763,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7763
7763
|
const fd = this.fd;
|
|
7764
7764
|
this.once("ready", () => {
|
|
7765
7765
|
if (fd !== this.fd) {
|
|
7766
|
-
|
|
7766
|
+
fs70.close(fd, (err) => {
|
|
7767
7767
|
if (err) {
|
|
7768
7768
|
return this.emit("error", err);
|
|
7769
7769
|
}
|
|
@@ -7812,7 +7812,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7812
7812
|
buf = this._bufs[0];
|
|
7813
7813
|
}
|
|
7814
7814
|
try {
|
|
7815
|
-
const n = Buffer.isBuffer(buf) ?
|
|
7815
|
+
const n = Buffer.isBuffer(buf) ? fs70.writeSync(this.fd, buf) : fs70.writeSync(this.fd, buf, "utf8");
|
|
7816
7816
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
7817
7817
|
buf = releasedBufObj.writingBuf;
|
|
7818
7818
|
this._len = releasedBufObj.len;
|
|
@@ -7828,7 +7828,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7828
7828
|
}
|
|
7829
7829
|
}
|
|
7830
7830
|
try {
|
|
7831
|
-
|
|
7831
|
+
fs70.fsyncSync(this.fd);
|
|
7832
7832
|
} catch {
|
|
7833
7833
|
}
|
|
7834
7834
|
}
|
|
@@ -7849,7 +7849,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7849
7849
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
7850
7850
|
}
|
|
7851
7851
|
try {
|
|
7852
|
-
const n =
|
|
7852
|
+
const n = fs70.writeSync(this.fd, buf);
|
|
7853
7853
|
buf = buf.subarray(n);
|
|
7854
7854
|
this._len = Math.max(this._len - n, 0);
|
|
7855
7855
|
if (buf.length <= 0) {
|
|
@@ -7877,13 +7877,13 @@ var require_sonic_boom = __commonJS({
|
|
|
7877
7877
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
7878
7878
|
if (this.sync) {
|
|
7879
7879
|
try {
|
|
7880
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
7880
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs70.writeSync(this.fd, this._writingBuf) : fs70.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7881
7881
|
release(null, written);
|
|
7882
7882
|
} catch (err) {
|
|
7883
7883
|
release(err);
|
|
7884
7884
|
}
|
|
7885
7885
|
} else {
|
|
7886
|
-
|
|
7886
|
+
fs70.write(this.fd, this._writingBuf, release);
|
|
7887
7887
|
}
|
|
7888
7888
|
}
|
|
7889
7889
|
function actualWriteBuffer() {
|
|
@@ -7892,7 +7892,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7892
7892
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
7893
7893
|
if (this.sync) {
|
|
7894
7894
|
try {
|
|
7895
|
-
const written =
|
|
7895
|
+
const written = fs70.writeSync(this.fd, this._writingBuf);
|
|
7896
7896
|
release(null, written);
|
|
7897
7897
|
} catch (err) {
|
|
7898
7898
|
release(err);
|
|
@@ -7901,7 +7901,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7901
7901
|
if (kCopyBuffer) {
|
|
7902
7902
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
7903
7903
|
}
|
|
7904
|
-
|
|
7904
|
+
fs70.write(this.fd, this._writingBuf, release);
|
|
7905
7905
|
}
|
|
7906
7906
|
}
|
|
7907
7907
|
function actualClose(sonic) {
|
|
@@ -7917,12 +7917,12 @@ var require_sonic_boom = __commonJS({
|
|
|
7917
7917
|
sonic._lens = [];
|
|
7918
7918
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
7919
7919
|
try {
|
|
7920
|
-
|
|
7920
|
+
fs70.fsync(sonic.fd, closeWrapped);
|
|
7921
7921
|
} catch {
|
|
7922
7922
|
}
|
|
7923
7923
|
function closeWrapped() {
|
|
7924
7924
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
7925
|
-
|
|
7925
|
+
fs70.close(sonic.fd, done);
|
|
7926
7926
|
} else {
|
|
7927
7927
|
done();
|
|
7928
7928
|
}
|
|
@@ -11057,11 +11057,11 @@ var init_lib = __esm({
|
|
|
11057
11057
|
}
|
|
11058
11058
|
}
|
|
11059
11059
|
},
|
|
11060
|
-
addToPath: function addToPath(
|
|
11061
|
-
var last =
|
|
11060
|
+
addToPath: function addToPath(path77, added, removed, oldPosInc, options) {
|
|
11061
|
+
var last = path77.lastComponent;
|
|
11062
11062
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
11063
11063
|
return {
|
|
11064
|
-
oldPos:
|
|
11064
|
+
oldPos: path77.oldPos + oldPosInc,
|
|
11065
11065
|
lastComponent: {
|
|
11066
11066
|
count: last.count + 1,
|
|
11067
11067
|
added,
|
|
@@ -11071,7 +11071,7 @@ var init_lib = __esm({
|
|
|
11071
11071
|
};
|
|
11072
11072
|
} else {
|
|
11073
11073
|
return {
|
|
11074
|
-
oldPos:
|
|
11074
|
+
oldPos: path77.oldPos + oldPosInc,
|
|
11075
11075
|
lastComponent: {
|
|
11076
11076
|
count: 1,
|
|
11077
11077
|
added,
|
|
@@ -11537,10 +11537,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11537
11537
|
const memories = raw.map((m2) => {
|
|
11538
11538
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11539
11539
|
const rec3 = m2;
|
|
11540
|
-
const
|
|
11540
|
+
const path77 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11541
11541
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11542
|
-
if (!
|
|
11543
|
-
const entry = { path:
|
|
11542
|
+
if (!path77 || content == null) return null;
|
|
11543
|
+
const entry = { path: path77, content };
|
|
11544
11544
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11545
11545
|
return entry;
|
|
11546
11546
|
}).filter((m2) => m2 !== null);
|
|
@@ -12360,10 +12360,10 @@ function parseAttachment(obj) {
|
|
|
12360
12360
|
const memories = raw.map((m2) => {
|
|
12361
12361
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12362
12362
|
const rec3 = m2;
|
|
12363
|
-
const
|
|
12363
|
+
const path77 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12364
12364
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12365
|
-
if (!
|
|
12366
|
-
const out = { path:
|
|
12365
|
+
if (!path77 || content == null) return null;
|
|
12366
|
+
const out = { path: path77, content };
|
|
12367
12367
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12368
12368
|
return out;
|
|
12369
12369
|
}).filter((m2) => m2 !== null);
|
|
@@ -33460,8 +33460,8 @@ var require_utils = __commonJS({
|
|
|
33460
33460
|
var result = transform[inputType][outputType](input);
|
|
33461
33461
|
return result;
|
|
33462
33462
|
};
|
|
33463
|
-
exports2.resolve = function(
|
|
33464
|
-
var parts =
|
|
33463
|
+
exports2.resolve = function(path77) {
|
|
33464
|
+
var parts = path77.split("/");
|
|
33465
33465
|
var result = [];
|
|
33466
33466
|
for (var index = 0; index < parts.length; index++) {
|
|
33467
33467
|
var part = parts[index];
|
|
@@ -39314,18 +39314,18 @@ var require_object = __commonJS({
|
|
|
39314
39314
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
39315
39315
|
this.files[name] = object;
|
|
39316
39316
|
};
|
|
39317
|
-
var parentFolder = function(
|
|
39318
|
-
if (
|
|
39319
|
-
|
|
39317
|
+
var parentFolder = function(path77) {
|
|
39318
|
+
if (path77.slice(-1) === "/") {
|
|
39319
|
+
path77 = path77.substring(0, path77.length - 1);
|
|
39320
39320
|
}
|
|
39321
|
-
var lastSlash =
|
|
39322
|
-
return lastSlash > 0 ?
|
|
39321
|
+
var lastSlash = path77.lastIndexOf("/");
|
|
39322
|
+
return lastSlash > 0 ? path77.substring(0, lastSlash) : "";
|
|
39323
39323
|
};
|
|
39324
|
-
var forceTrailingSlash = function(
|
|
39325
|
-
if (
|
|
39326
|
-
|
|
39324
|
+
var forceTrailingSlash = function(path77) {
|
|
39325
|
+
if (path77.slice(-1) !== "/") {
|
|
39326
|
+
path77 += "/";
|
|
39327
39327
|
}
|
|
39328
|
-
return
|
|
39328
|
+
return path77;
|
|
39329
39329
|
};
|
|
39330
39330
|
var folderAdd = function(name, createFolders) {
|
|
39331
39331
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40324,10 +40324,53 @@ var require_lib3 = __commonJS({
|
|
|
40324
40324
|
}
|
|
40325
40325
|
});
|
|
40326
40326
|
|
|
40327
|
+
// src/sshd/contact-ssh-log.ts
|
|
40328
|
+
function createContactSshLog(dataDir) {
|
|
40329
|
+
const file = import_node_path40.default.join(dataDir, "contact-ssh.log");
|
|
40330
|
+
function append(level, tag, message, meta) {
|
|
40331
|
+
const time = (/* @__PURE__ */ new Date()).toISOString();
|
|
40332
|
+
let line = `[${time}] [${level}] [${tag}] ${message}`;
|
|
40333
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
40334
|
+
try {
|
|
40335
|
+
line += " " + JSON.stringify(meta);
|
|
40336
|
+
} catch {
|
|
40337
|
+
line += " [meta-serialize-failed]";
|
|
40338
|
+
}
|
|
40339
|
+
}
|
|
40340
|
+
line += "\n";
|
|
40341
|
+
try {
|
|
40342
|
+
import_node_fs39.default.mkdirSync(import_node_path40.default.dirname(file), { recursive: true });
|
|
40343
|
+
import_node_fs39.default.appendFileSync(file, line, { mode: 384 });
|
|
40344
|
+
} catch {
|
|
40345
|
+
}
|
|
40346
|
+
}
|
|
40347
|
+
return {
|
|
40348
|
+
info: (tag, message, meta) => append("INFO", tag, message, meta),
|
|
40349
|
+
warn: (tag, message, meta) => append("WARN", tag, message, meta),
|
|
40350
|
+
error: (tag, message, meta) => append("ERROR", tag, message, meta)
|
|
40351
|
+
};
|
|
40352
|
+
}
|
|
40353
|
+
var import_node_fs39, import_node_path40, nullContactSshLog;
|
|
40354
|
+
var init_contact_ssh_log = __esm({
|
|
40355
|
+
"src/sshd/contact-ssh-log.ts"() {
|
|
40356
|
+
"use strict";
|
|
40357
|
+
import_node_fs39 = __toESM(require("fs"), 1);
|
|
40358
|
+
import_node_path40 = __toESM(require("path"), 1);
|
|
40359
|
+
nullContactSshLog = {
|
|
40360
|
+
info: () => {
|
|
40361
|
+
},
|
|
40362
|
+
warn: () => {
|
|
40363
|
+
},
|
|
40364
|
+
error: () => {
|
|
40365
|
+
}
|
|
40366
|
+
};
|
|
40367
|
+
}
|
|
40368
|
+
});
|
|
40369
|
+
|
|
40327
40370
|
// src/run-case/recorder.ts
|
|
40328
40371
|
function startRunCaseRecorder(opts) {
|
|
40329
40372
|
const now = opts.now ?? Date.now;
|
|
40330
|
-
const dir =
|
|
40373
|
+
const dir = import_node_path64.default.dirname(opts.recordPath);
|
|
40331
40374
|
let stream = null;
|
|
40332
40375
|
let closing = false;
|
|
40333
40376
|
let closedSettled = false;
|
|
@@ -40341,8 +40384,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40341
40384
|
});
|
|
40342
40385
|
const ensureStream = () => {
|
|
40343
40386
|
if (stream) return stream;
|
|
40344
|
-
|
|
40345
|
-
stream =
|
|
40387
|
+
import_node_fs51.default.mkdirSync(dir, { recursive: true });
|
|
40388
|
+
stream = import_node_fs51.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40346
40389
|
stream.on("close", () => closedResolve());
|
|
40347
40390
|
return stream;
|
|
40348
40391
|
};
|
|
@@ -40367,12 +40410,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40367
40410
|
};
|
|
40368
40411
|
return { tap, close, closed };
|
|
40369
40412
|
}
|
|
40370
|
-
var
|
|
40413
|
+
var import_node_fs51, import_node_path64;
|
|
40371
40414
|
var init_recorder = __esm({
|
|
40372
40415
|
"src/run-case/recorder.ts"() {
|
|
40373
40416
|
"use strict";
|
|
40374
|
-
|
|
40375
|
-
|
|
40417
|
+
import_node_fs51 = __toESM(require("fs"), 1);
|
|
40418
|
+
import_node_path64 = __toESM(require("path"), 1);
|
|
40376
40419
|
}
|
|
40377
40420
|
});
|
|
40378
40421
|
|
|
@@ -40415,7 +40458,7 @@ var init_wire = __esm({
|
|
|
40415
40458
|
// src/run-case/controller.ts
|
|
40416
40459
|
async function runController(opts) {
|
|
40417
40460
|
const now = opts.now ?? Date.now;
|
|
40418
|
-
const cwd = opts.cwd ?? (0,
|
|
40461
|
+
const cwd = opts.cwd ?? (0, import_node_fs52.mkdtempSync)(import_node_path65.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
|
|
40419
40462
|
const ownsCwd = opts.cwd === void 0;
|
|
40420
40463
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40421
40464
|
const spawnCtx = { cwd };
|
|
@@ -40576,19 +40619,19 @@ async function runController(opts) {
|
|
|
40576
40619
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40577
40620
|
if (ownsCwd) {
|
|
40578
40621
|
try {
|
|
40579
|
-
(0,
|
|
40622
|
+
(0, import_node_fs52.rmSync)(cwd, { recursive: true, force: true });
|
|
40580
40623
|
} catch {
|
|
40581
40624
|
}
|
|
40582
40625
|
}
|
|
40583
40626
|
return exitCode ?? 0;
|
|
40584
40627
|
}
|
|
40585
|
-
var
|
|
40628
|
+
var import_node_fs52, import_node_os22, import_node_path65;
|
|
40586
40629
|
var init_controller = __esm({
|
|
40587
40630
|
"src/run-case/controller.ts"() {
|
|
40588
40631
|
"use strict";
|
|
40589
|
-
|
|
40632
|
+
import_node_fs52 = require("fs");
|
|
40590
40633
|
import_node_os22 = __toESM(require("os"), 1);
|
|
40591
|
-
|
|
40634
|
+
import_node_path65 = __toESM(require("path"), 1);
|
|
40592
40635
|
init_claude();
|
|
40593
40636
|
init_stdout_splitter();
|
|
40594
40637
|
init_permission_stdio();
|
|
@@ -40699,14 +40742,23 @@ async function sshRelay(argv) {
|
|
|
40699
40742
|
process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
|
|
40700
40743
|
return 2;
|
|
40701
40744
|
}
|
|
40702
|
-
const dataDir = args.dataDir ??
|
|
40745
|
+
const dataDir = args.dataDir ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
|
|
40746
|
+
const sshLog = createContactSshLog(dataDir);
|
|
40703
40747
|
const contact = findContact(dataDir, args.peerDeviceId);
|
|
40704
40748
|
if (!contact) {
|
|
40749
|
+
sshLog.error("relay.contact-not-found", "ssh-relay \u627E\u4E0D\u5230 peer contact", {
|
|
40750
|
+
peerDeviceId: args.peerDeviceId,
|
|
40751
|
+
contactsPath: import_node_path66.default.join(dataDir, "contacts.json")
|
|
40752
|
+
});
|
|
40705
40753
|
process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
|
|
40706
40754
|
`);
|
|
40707
40755
|
return 2;
|
|
40708
40756
|
}
|
|
40709
40757
|
if (!contact.connectToken) {
|
|
40758
|
+
sshLog.error("relay.token-missing", "contact \u6709\u8BB0\u5F55\u4F46\u7F3A connectToken\uFF08auto-reverse \u672A\u6362\u7968\uFF09", {
|
|
40759
|
+
peerDeviceId: args.peerDeviceId,
|
|
40760
|
+
peerDisplayName: contact.displayName
|
|
40761
|
+
});
|
|
40710
40762
|
process.stderr.write(
|
|
40711
40763
|
`clawd ssh-relay: contact ${args.peerDeviceId} has no connectToken (auto-reverse \u672A\u6362\u7968)
|
|
40712
40764
|
`
|
|
@@ -40716,6 +40768,11 @@ async function sshRelay(argv) {
|
|
|
40716
40768
|
const baseHttp = wsUrlToHttp(contact.remoteUrl).replace(/\/+$/, "");
|
|
40717
40769
|
const wsBase = baseHttp.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
40718
40770
|
const url = `${wsBase}/rpc/ssh-tunnel`;
|
|
40771
|
+
sshLog.info("relay.dial", "\u5F00\u59CB\u62E8 A \u4FA7 /rpc/ssh-tunnel", {
|
|
40772
|
+
peerDeviceId: args.peerDeviceId,
|
|
40773
|
+
peerDisplayName: contact.displayName,
|
|
40774
|
+
url
|
|
40775
|
+
});
|
|
40719
40776
|
return new Promise((resolve6) => {
|
|
40720
40777
|
const ws = new import_websocket.default(url, {
|
|
40721
40778
|
headers: {
|
|
@@ -40735,6 +40792,9 @@ async function sshRelay(argv) {
|
|
|
40735
40792
|
resolve6(exitCode);
|
|
40736
40793
|
};
|
|
40737
40794
|
ws.on("open", () => {
|
|
40795
|
+
sshLog.info("relay.dial-open", "ws open\uFF0C\u8FDB\u5165 stdio \u2194 ws \u4E2D\u7EE7", {
|
|
40796
|
+
peerDeviceId: args.peerDeviceId
|
|
40797
|
+
});
|
|
40738
40798
|
process.stdin.on("data", (chunk) => {
|
|
40739
40799
|
if (ws.readyState === ws.OPEN) {
|
|
40740
40800
|
ws.send(chunk, { binary: true });
|
|
@@ -40759,9 +40819,25 @@ async function sshRelay(argv) {
|
|
|
40759
40819
|
}
|
|
40760
40820
|
});
|
|
40761
40821
|
ws.on("close", (code) => {
|
|
40822
|
+
if (code === 1e3) {
|
|
40823
|
+
sshLog.info("relay.dial-close", "ws \u6B63\u5E38\u5173\u95ED", {
|
|
40824
|
+
peerDeviceId: args.peerDeviceId,
|
|
40825
|
+
code
|
|
40826
|
+
});
|
|
40827
|
+
} else {
|
|
40828
|
+
sshLog.warn("relay.dial-close-abnormal", "ws \u975E\u6B63\u5E38\u5173\u95ED\uFF08A \u4FA7\u62D2 auth / \u7F51\u7EDC\u65AD / peer \u5D29\uFF09", {
|
|
40829
|
+
peerDeviceId: args.peerDeviceId,
|
|
40830
|
+
code
|
|
40831
|
+
});
|
|
40832
|
+
}
|
|
40762
40833
|
settle(code === 1e3 ? 0 : 1);
|
|
40763
40834
|
});
|
|
40764
40835
|
ws.on("error", (err) => {
|
|
40836
|
+
sshLog.error("relay.dial-error", "ws \u8FDE\u63A5\u9519\u8BEF\uFF08peer \u4E0D\u53EF\u8FBE / \u7AEF\u53E3\u4E0D\u901A / TLS \u5931\u8D25\uFF09", {
|
|
40837
|
+
peerDeviceId: args.peerDeviceId,
|
|
40838
|
+
url,
|
|
40839
|
+
message: err.message
|
|
40840
|
+
});
|
|
40765
40841
|
process.stderr.write(`clawd ssh-relay: ws error ${err.message}
|
|
40766
40842
|
`);
|
|
40767
40843
|
settle(1);
|
|
@@ -40793,10 +40869,10 @@ function parseSshRelayArgs(argv) {
|
|
|
40793
40869
|
return out;
|
|
40794
40870
|
}
|
|
40795
40871
|
function findContact(dataDir, deviceId) {
|
|
40796
|
-
const file =
|
|
40872
|
+
const file = import_node_path66.default.join(dataDir, "contacts.json");
|
|
40797
40873
|
let raw;
|
|
40798
40874
|
try {
|
|
40799
|
-
raw =
|
|
40875
|
+
raw = import_node_fs53.default.readFileSync(file, "utf8");
|
|
40800
40876
|
} catch {
|
|
40801
40877
|
return null;
|
|
40802
40878
|
}
|
|
@@ -40814,16 +40890,17 @@ function findContact(dataDir, deviceId) {
|
|
|
40814
40890
|
}
|
|
40815
40891
|
return null;
|
|
40816
40892
|
}
|
|
40817
|
-
var
|
|
40893
|
+
var import_node_fs53, import_node_os23, import_node_path66, SSH_RELAY_HELP;
|
|
40818
40894
|
var init_sshd_cli_relay = __esm({
|
|
40819
40895
|
"src/sshd/sshd-cli-relay.ts"() {
|
|
40820
40896
|
"use strict";
|
|
40821
|
-
|
|
40897
|
+
import_node_fs53 = __toESM(require("fs"), 1);
|
|
40822
40898
|
import_node_os23 = __toESM(require("os"), 1);
|
|
40823
|
-
|
|
40899
|
+
import_node_path66 = __toESM(require("path"), 1);
|
|
40824
40900
|
init_wrapper();
|
|
40825
40901
|
init_src();
|
|
40826
40902
|
init_peer_forward();
|
|
40903
|
+
init_contact_ssh_log();
|
|
40827
40904
|
SSH_RELAY_HELP = `clawd ssh-relay <peer-device-id> [options]
|
|
40828
40905
|
|
|
40829
40906
|
WebSocket relay to a peer daemon's /rpc/ssh-tunnel, exposing raw SSH bytes on
|
|
@@ -41023,8 +41100,8 @@ Env (advanced):
|
|
|
41023
41100
|
`;
|
|
41024
41101
|
|
|
41025
41102
|
// src/index.ts
|
|
41026
|
-
var
|
|
41027
|
-
var
|
|
41103
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
41104
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
41028
41105
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
41029
41106
|
|
|
41030
41107
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -41735,7 +41812,11 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
41735
41812
|
fsv.denyWrite = unionArr((fsv.denyWrite ?? []).filter((p2) => p2 !== "~/"), [spawnCwd]);
|
|
41736
41813
|
fsv.allowRead = unionArr(fsv.allowRead, [userWorkDir]);
|
|
41737
41814
|
fsv.allowWrite = unionArr(fsv.allowWrite, [userWorkDir]);
|
|
41738
|
-
fsv.allowRead = unionArr(fsv.allowRead, [
|
|
41815
|
+
fsv.allowRead = unionArr(fsv.allowRead, [
|
|
41816
|
+
"~/.clawd/contact-ssh-keys",
|
|
41817
|
+
"~/.clawd/contacts.json",
|
|
41818
|
+
"~/.clawd/bin"
|
|
41819
|
+
]);
|
|
41739
41820
|
return s;
|
|
41740
41821
|
}
|
|
41741
41822
|
|
|
@@ -41885,12 +41966,14 @@ var CONTACT_SSH_SYSTEM_PROMPT_HINT = `## \u8DE8\u8BBE\u5907\u6587\u4EF6\u8BBF\u9
|
|
|
41885
41966
|
\uFF08\u6BCF\u4E2A \`<deviceId>.ed25519\` \u5C31\u662F\u4E00\u628A privkey\uFF0C\u53BB\u6389\u540E\u7F00\u5C31\u662F deviceId\uFF09
|
|
41886
41967
|
2. \u7528 SSH \u62E8\u53F7\uFF08\u628A \`<A>\` \u6362\u6210\u5B9E\u9645 deviceId\uFF09\uFF1A
|
|
41887
41968
|
\`\`\`bash
|
|
41888
|
-
ssh -o ProxyCommand='clawd ssh-relay <A>' \\
|
|
41969
|
+
ssh -o ProxyCommand='~/.clawd/bin/clawd ssh-relay <A>' \\
|
|
41889
41970
|
-i ~/.clawd/contact-ssh-keys/<A>.ed25519 \\
|
|
41890
41971
|
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \\
|
|
41891
41972
|
$USER@127.0.0.1 <command>
|
|
41892
41973
|
# \u4F8B\u5982\uFF1A... $USER@127.0.0.1 cat /Users/xxx/some/file.md
|
|
41893
41974
|
# ... $USER@127.0.0.1 ls -la /Users/xxx/proj
|
|
41975
|
+
# \u8BF4\u660E\uFF1A\`~/.clawd/bin/clawd\` \u662F daemon \u542F\u52A8\u65F6 seed \u7684 shim\uFF0C\u786C\u7F16\u7801\u5F53\u524D daemon \u7684
|
|
41976
|
+
# execPath+cliPath\uFF0C\u4FDD\u8BC1 relay \u8DDF daemon \u7248\u672C\u540C\u6B65\u3002\u4E0D\u8981\u7528\u88F8 \`clawd\`\uFF08\u8D70 $PATH \u4F1A\u6F02\uFF09\u3002
|
|
41894
41977
|
\`\`\`
|
|
41895
41978
|
|
|
41896
41979
|
**A \u6388\u6743\u54EA\u4E9B\u76EE\u5F55\u4E0D\u7528\u4F60\u63D0\u524D\u8BB0**\uFF1AA \u4FA7\u7684 sshd \u62E8\u53F7\u4F1A\u5F3A\u5236\u8D70 sandbox jail\uFF0C\u8FDB\u6C99\u7BB1\u524D\u4F1A\u628A\u6388\u6743\u76EE\u5F55\u5217\u8868\u5199\u5230 stderr\uFF08\u683C\u5F0F \`[clawd-ssh-jail] Access allowed to these directories: ...\`\uFF09\u3002\u4F60\u5373\u4F7F\u731C\u9519\u8DEF\u5F84\u4E5F\u4F1A\u88AB sandbox deny\uFF0C\u4F46 stderr \u91CC\u5C31\u81EA\u5E26\u7B54\u6848\uFF0C\u8BD5\u9519\u4E00\u6B21\u5C31\u5B66\u5230 A \u6388\u6743\u4E86\u54EA\u4E9B\u76EE\u5F55\uFF0C\u4E0B\u6B21\u76F4\u63A5\u7528\u5BF9\u7684\u8DEF\u5F84\u3002
|
|
@@ -46560,8 +46643,8 @@ function turnStartInput(text) {
|
|
|
46560
46643
|
const items = [];
|
|
46561
46644
|
let leftover = text;
|
|
46562
46645
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46563
|
-
const [marker, name,
|
|
46564
|
-
items.push({ type: "skill", name, path:
|
|
46646
|
+
const [marker, name, path77] = m2;
|
|
46647
|
+
items.push({ type: "skill", name, path: path77 });
|
|
46565
46648
|
leftover = leftover.replace(marker, "");
|
|
46566
46649
|
}
|
|
46567
46650
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -49015,13 +49098,13 @@ function mapSkillsListResponse(res) {
|
|
|
49015
49098
|
const r = s ?? {};
|
|
49016
49099
|
const name = str3(r.name);
|
|
49017
49100
|
if (!name) continue;
|
|
49018
|
-
const
|
|
49101
|
+
const path77 = str3(r.path);
|
|
49019
49102
|
const description = str3(r.description);
|
|
49020
49103
|
const isPlugin = name.includes(":");
|
|
49021
49104
|
out.push({
|
|
49022
49105
|
name,
|
|
49023
49106
|
source: isPlugin ? "plugin" : "project",
|
|
49024
|
-
...
|
|
49107
|
+
...path77 ? { path: path77 } : {},
|
|
49025
49108
|
...description ? { description } : {},
|
|
49026
49109
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
49027
49110
|
});
|
|
@@ -52993,8 +53076,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52993
53076
|
}
|
|
52994
53077
|
|
|
52995
53078
|
// src/sshd/sshd-manager.ts
|
|
52996
|
-
var
|
|
52997
|
-
var
|
|
53079
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53080
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
52998
53081
|
var import_node_child_process11 = require("child_process");
|
|
52999
53082
|
|
|
53000
53083
|
// src/sshd/sshd-config.ts
|
|
@@ -53277,11 +53360,35 @@ function ensureJailScript(dataDir) {
|
|
|
53277
53360
|
return target;
|
|
53278
53361
|
}
|
|
53279
53362
|
|
|
53363
|
+
// src/sshd/clawd-shim.ts
|
|
53364
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
53365
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
53366
|
+
function shellQuote(s) {
|
|
53367
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
53368
|
+
}
|
|
53369
|
+
function buildClawdShim(execPath, cliPath) {
|
|
53370
|
+
return `#!/usr/bin/env bash
|
|
53371
|
+
# clawd shim (managed by clawd; do not edit)
|
|
53372
|
+
#
|
|
53373
|
+
# \u786C\u7F16\u7801\u672C daemon \u542F\u52A8\u65F6\u7528\u7684 execPath + cliPath\uFF1Bdaemon \u91CD\u542F\u4F1A\u8986\u5199\u672C\u6587\u4EF6\uFF08\u5E42\u7B49 seed\uFF09\u3002
|
|
53374
|
+
# guest CC \u7528 SSH ProxyCommand \u8D70 ~/.clawd/bin/clawd ssh-relay \u65F6\u4F1A\u547D\u4E2D\u672C shim\uFF0C\u4FDD\u8BC1
|
|
53375
|
+
# relay \u4E8C\u8FDB\u5236\u8DDF\u5F53\u524D\u8DD1\u7740\u7684 daemon \u540C\u6E90\u540C\u7248\u672C\u3002
|
|
53376
|
+
exec ${shellQuote(execPath)} ${shellQuote(cliPath)} "$@"
|
|
53377
|
+
`;
|
|
53378
|
+
}
|
|
53379
|
+
function ensureClawdShim(dataDir, execPath, cliPath) {
|
|
53380
|
+
const binDir = import_node_path37.default.join(dataDir, "bin");
|
|
53381
|
+
import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
|
|
53382
|
+
const target = import_node_path37.default.join(binDir, "clawd");
|
|
53383
|
+
import_node_fs36.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
|
|
53384
|
+
return target;
|
|
53385
|
+
}
|
|
53386
|
+
|
|
53280
53387
|
// src/sshd/sshd-manager.ts
|
|
53281
53388
|
var SshdManager = class {
|
|
53282
53389
|
constructor(deps) {
|
|
53283
53390
|
this.deps = deps;
|
|
53284
|
-
this.sshdDir =
|
|
53391
|
+
this.sshdDir = import_node_path38.default.join(deps.dataDir, "sshd");
|
|
53285
53392
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
53286
53393
|
}
|
|
53287
53394
|
deps;
|
|
@@ -53300,31 +53407,32 @@ var SshdManager = class {
|
|
|
53300
53407
|
ownPid: process.pid,
|
|
53301
53408
|
logger
|
|
53302
53409
|
});
|
|
53303
|
-
|
|
53304
|
-
|
|
53410
|
+
import_node_fs37.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
|
|
53411
|
+
import_node_fs37.default.mkdirSync(import_node_path38.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
|
|
53305
53412
|
ensureJailScript(this.deps.dataDir);
|
|
53306
|
-
|
|
53307
|
-
|
|
53413
|
+
ensureClawdShim(this.deps.dataDir, process.execPath, process.argv[1] ?? "");
|
|
53414
|
+
const hostKeyPath = import_node_path38.default.join(this.sshdDir, "host_key");
|
|
53415
|
+
if (!import_node_fs37.default.existsSync(hostKeyPath)) {
|
|
53308
53416
|
await this.generateHostKey(hostKeyPath);
|
|
53309
53417
|
}
|
|
53310
|
-
const akFile =
|
|
53311
|
-
if (!
|
|
53312
|
-
|
|
53418
|
+
const akFile = import_node_path38.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
|
|
53419
|
+
if (!import_node_fs37.default.existsSync(akFile)) {
|
|
53420
|
+
import_node_fs37.default.writeFileSync(akFile, "", { mode: 384 });
|
|
53313
53421
|
}
|
|
53314
|
-
const configPath =
|
|
53422
|
+
const configPath = import_node_path38.default.join(this.sshdDir, "sshd_config");
|
|
53315
53423
|
const config = buildSshdConfig({
|
|
53316
53424
|
listenAddress: "127.0.0.1",
|
|
53317
53425
|
port: this.deps.port,
|
|
53318
53426
|
hostKeyPath,
|
|
53319
53427
|
authorizedKeysFile: akFile,
|
|
53320
|
-
pidFilePath:
|
|
53428
|
+
pidFilePath: import_node_path38.default.join(this.sshdDir, "sshd.pid")
|
|
53321
53429
|
});
|
|
53322
|
-
|
|
53430
|
+
import_node_fs37.default.writeFileSync(configPath, config, { mode: 384 });
|
|
53323
53431
|
const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
|
|
53324
53432
|
const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
|
|
53325
53433
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53326
53434
|
});
|
|
53327
|
-
const logStream =
|
|
53435
|
+
const logStream = import_node_fs37.default.createWriteStream(import_node_path38.default.join(this.sshdDir, "sshd.log"), {
|
|
53328
53436
|
flags: "a",
|
|
53329
53437
|
mode: 384
|
|
53330
53438
|
});
|
|
@@ -53417,7 +53525,7 @@ ${tail}` : ready.error;
|
|
|
53417
53525
|
p2.on("error", reject);
|
|
53418
53526
|
});
|
|
53419
53527
|
try {
|
|
53420
|
-
|
|
53528
|
+
import_node_fs37.default.chmodSync(hostKeyPath, 384);
|
|
53421
53529
|
} catch {
|
|
53422
53530
|
}
|
|
53423
53531
|
}
|
|
@@ -53460,17 +53568,17 @@ async function waitForSshdReady(proc, timeoutMs) {
|
|
|
53460
53568
|
}
|
|
53461
53569
|
|
|
53462
53570
|
// src/sshd/authorized-keys.ts
|
|
53463
|
-
var
|
|
53464
|
-
var
|
|
53571
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53572
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53465
53573
|
var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
|
|
53466
53574
|
var AUTHORIZED_KEYS_FILE = "clawd-contacts";
|
|
53467
53575
|
function jailBinPath() {
|
|
53468
|
-
return process.env[JAIL_BIN_PATH_ENV] ??
|
|
53576
|
+
return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path39.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
|
|
53469
53577
|
}
|
|
53470
53578
|
function rebuildAuthorizedKeys(store, sshdDir) {
|
|
53471
|
-
const akDir =
|
|
53472
|
-
const target =
|
|
53473
|
-
|
|
53579
|
+
const akDir = import_node_path39.default.join(sshdDir, "authorized_keys.d");
|
|
53580
|
+
const target = import_node_path39.default.join(akDir, AUTHORIZED_KEYS_FILE);
|
|
53581
|
+
import_node_fs38.default.mkdirSync(akDir, { recursive: true, mode: 448 });
|
|
53474
53582
|
const lines = ["# managed by clawd; do not edit", ""];
|
|
53475
53583
|
for (const c of store.list()) {
|
|
53476
53584
|
if (!c.sshAllowed) continue;
|
|
@@ -53484,66 +53592,28 @@ function rebuildAuthorizedKeys(store, sshdDir) {
|
|
|
53484
53592
|
}
|
|
53485
53593
|
const body = lines.join("\n") + "\n";
|
|
53486
53594
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
53487
|
-
|
|
53488
|
-
|
|
53595
|
+
import_node_fs38.default.writeFileSync(tmp, body, { mode: 384 });
|
|
53596
|
+
import_node_fs38.default.renameSync(tmp, target);
|
|
53489
53597
|
}
|
|
53490
53598
|
function readIssuedPubkey(sshdDir, deviceId) {
|
|
53491
53599
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53492
|
-
const p2 =
|
|
53600
|
+
const p2 = import_node_path39.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
|
|
53493
53601
|
try {
|
|
53494
|
-
return
|
|
53602
|
+
return import_node_fs38.default.readFileSync(p2, "utf8");
|
|
53495
53603
|
} catch {
|
|
53496
53604
|
return null;
|
|
53497
53605
|
}
|
|
53498
53606
|
}
|
|
53499
53607
|
|
|
53500
53608
|
// src/sshd/contact-key-puller.ts
|
|
53501
|
-
var
|
|
53502
|
-
var
|
|
53609
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
53610
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
53503
53611
|
init_peer_forward();
|
|
53504
|
-
|
|
53505
|
-
// src/sshd/contact-ssh-log.ts
|
|
53506
|
-
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53507
|
-
var import_node_path39 = __toESM(require("path"), 1);
|
|
53508
|
-
function createContactSshLog(dataDir) {
|
|
53509
|
-
const file = import_node_path39.default.join(dataDir, "contact-ssh.log");
|
|
53510
|
-
function append(level, tag, message, meta) {
|
|
53511
|
-
const time = (/* @__PURE__ */ new Date()).toISOString();
|
|
53512
|
-
let line = `[${time}] [${level}] [${tag}] ${message}`;
|
|
53513
|
-
if (meta && Object.keys(meta).length > 0) {
|
|
53514
|
-
try {
|
|
53515
|
-
line += " " + JSON.stringify(meta);
|
|
53516
|
-
} catch {
|
|
53517
|
-
line += " [meta-serialize-failed]";
|
|
53518
|
-
}
|
|
53519
|
-
}
|
|
53520
|
-
line += "\n";
|
|
53521
|
-
try {
|
|
53522
|
-
import_node_fs38.default.mkdirSync(import_node_path39.default.dirname(file), { recursive: true });
|
|
53523
|
-
import_node_fs38.default.appendFileSync(file, line, { mode: 384 });
|
|
53524
|
-
} catch {
|
|
53525
|
-
}
|
|
53526
|
-
}
|
|
53527
|
-
return {
|
|
53528
|
-
info: (tag, message, meta) => append("INFO", tag, message, meta),
|
|
53529
|
-
warn: (tag, message, meta) => append("WARN", tag, message, meta),
|
|
53530
|
-
error: (tag, message, meta) => append("ERROR", tag, message, meta)
|
|
53531
|
-
};
|
|
53532
|
-
}
|
|
53533
|
-
var nullContactSshLog = {
|
|
53534
|
-
info: () => {
|
|
53535
|
-
},
|
|
53536
|
-
warn: () => {
|
|
53537
|
-
},
|
|
53538
|
-
error: () => {
|
|
53539
|
-
}
|
|
53540
|
-
};
|
|
53541
|
-
|
|
53542
|
-
// src/sshd/contact-key-puller.ts
|
|
53612
|
+
init_contact_ssh_log();
|
|
53543
53613
|
var CONTACT_KEYS_DIR = "contact-ssh-keys";
|
|
53544
53614
|
function safeContactKeyPath(dataDir, deviceId) {
|
|
53545
53615
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53546
|
-
return
|
|
53616
|
+
return import_node_path41.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
|
|
53547
53617
|
}
|
|
53548
53618
|
async function pullContactSshKeyOnce(deps) {
|
|
53549
53619
|
const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
|
|
@@ -53609,12 +53679,12 @@ async function pullContactSshKeyOnce(deps) {
|
|
|
53609
53679
|
}
|
|
53610
53680
|
function writeKeyFile(dataDir, deviceId, pem) {
|
|
53611
53681
|
const p2 = safeContactKeyPath(dataDir, deviceId);
|
|
53612
|
-
|
|
53613
|
-
|
|
53682
|
+
import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(p2), { recursive: true, mode: 448 });
|
|
53683
|
+
import_node_fs40.default.writeFileSync(p2, pem, { mode: 384 });
|
|
53614
53684
|
}
|
|
53615
53685
|
function removeKeyFile(dataDir, deviceId) {
|
|
53616
53686
|
try {
|
|
53617
|
-
|
|
53687
|
+
import_node_fs40.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
|
|
53618
53688
|
return true;
|
|
53619
53689
|
} catch {
|
|
53620
53690
|
return false;
|
|
@@ -53651,6 +53721,7 @@ var ContactKeyPuller = class {
|
|
|
53651
53721
|
|
|
53652
53722
|
// src/sshd/ssh-tunnel-relay.ts
|
|
53653
53723
|
var import_node_net2 = __toESM(require("net"), 1);
|
|
53724
|
+
init_contact_ssh_log();
|
|
53654
53725
|
async function handleSshTunnelUpgrade(req, socket, head, deps) {
|
|
53655
53726
|
const sshLog = deps.sshLog ?? nullContactSshLog;
|
|
53656
53727
|
const clientAddr = (req.socket && "remoteAddress" in req.socket ? req.socket.remoteAddress : null) ?? "unknown";
|
|
@@ -53758,29 +53829,32 @@ function pumpWsToSshd(ws, deps, clientAddr) {
|
|
|
53758
53829
|
});
|
|
53759
53830
|
}
|
|
53760
53831
|
|
|
53832
|
+
// src/index.ts
|
|
53833
|
+
init_contact_ssh_log();
|
|
53834
|
+
|
|
53761
53835
|
// src/tunnel/device-key.ts
|
|
53762
53836
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
53763
|
-
var
|
|
53837
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
53764
53838
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
53765
53839
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
53766
53840
|
function deriveStableDeviceKey(opts = {}) {
|
|
53767
53841
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
53768
53842
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
53769
53843
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
53770
|
-
const defaultDataDir =
|
|
53771
|
-
const normalizedDataDir = opts.dataDir ?
|
|
53844
|
+
const defaultDataDir = import_node_path42.default.resolve(import_node_path42.default.join(home, ".clawd"));
|
|
53845
|
+
const normalizedDataDir = opts.dataDir ? import_node_path42.default.resolve(opts.dataDir) : null;
|
|
53772
53846
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
53773
53847
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
53774
53848
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
53775
53849
|
}
|
|
53776
53850
|
|
|
53777
53851
|
// src/auth-store.ts
|
|
53778
|
-
var
|
|
53779
|
-
var
|
|
53852
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
53853
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
53780
53854
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
53781
53855
|
var AUTH_FILE_NAME = "auth.json";
|
|
53782
53856
|
function authFilePath(dataDir) {
|
|
53783
|
-
return
|
|
53857
|
+
return import_node_path43.default.join(dataDir, AUTH_FILE_NAME);
|
|
53784
53858
|
}
|
|
53785
53859
|
function loadOrCreateAuthFile(opts) {
|
|
53786
53860
|
const file = authFilePath(opts.dataDir);
|
|
@@ -53816,7 +53890,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
53816
53890
|
}
|
|
53817
53891
|
function readAuthFile(file) {
|
|
53818
53892
|
try {
|
|
53819
|
-
const raw =
|
|
53893
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
53820
53894
|
const parsed = JSON.parse(raw);
|
|
53821
53895
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
53822
53896
|
return null;
|
|
@@ -53836,25 +53910,25 @@ function readAuthFile(file) {
|
|
|
53836
53910
|
}
|
|
53837
53911
|
}
|
|
53838
53912
|
function writeAuthFile(file, content) {
|
|
53839
|
-
|
|
53840
|
-
|
|
53913
|
+
import_node_fs41.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
|
|
53914
|
+
import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
53841
53915
|
try {
|
|
53842
|
-
|
|
53916
|
+
import_node_fs41.default.chmodSync(file, 384);
|
|
53843
53917
|
} catch {
|
|
53844
53918
|
}
|
|
53845
53919
|
}
|
|
53846
53920
|
|
|
53847
53921
|
// src/owner-profile.ts
|
|
53848
|
-
var
|
|
53922
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
53849
53923
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
53850
|
-
var
|
|
53924
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
53851
53925
|
var PROFILE_FILENAME = "profile.json";
|
|
53852
53926
|
function loadOwnerDisplayName(dataDir) {
|
|
53853
53927
|
const fallback = import_node_os15.default.userInfo().username;
|
|
53854
|
-
const profilePath =
|
|
53928
|
+
const profilePath = import_node_path44.default.join(dataDir, PROFILE_FILENAME);
|
|
53855
53929
|
let raw;
|
|
53856
53930
|
try {
|
|
53857
|
-
raw =
|
|
53931
|
+
raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
|
|
53858
53932
|
} catch {
|
|
53859
53933
|
return fallback;
|
|
53860
53934
|
}
|
|
@@ -53877,18 +53951,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
53877
53951
|
}
|
|
53878
53952
|
|
|
53879
53953
|
// src/feishu-auth/owner-identity-store.ts
|
|
53880
|
-
var
|
|
53881
|
-
var
|
|
53954
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
53955
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
53882
53956
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
53883
53957
|
var OwnerIdentityStore = class {
|
|
53884
53958
|
file;
|
|
53885
53959
|
constructor(dataDir) {
|
|
53886
|
-
this.file =
|
|
53960
|
+
this.file = import_node_path45.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
53887
53961
|
}
|
|
53888
53962
|
read() {
|
|
53889
53963
|
let raw;
|
|
53890
53964
|
try {
|
|
53891
|
-
raw =
|
|
53965
|
+
raw = import_node_fs43.default.readFileSync(this.file, "utf8");
|
|
53892
53966
|
} catch {
|
|
53893
53967
|
return null;
|
|
53894
53968
|
}
|
|
@@ -53916,16 +53990,16 @@ var OwnerIdentityStore = class {
|
|
|
53916
53990
|
};
|
|
53917
53991
|
}
|
|
53918
53992
|
write(record) {
|
|
53919
|
-
|
|
53920
|
-
|
|
53993
|
+
import_node_fs43.default.mkdirSync(import_node_path45.default.dirname(this.file), { recursive: true });
|
|
53994
|
+
import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
53921
53995
|
try {
|
|
53922
|
-
|
|
53996
|
+
import_node_fs43.default.chmodSync(this.file, 384);
|
|
53923
53997
|
} catch {
|
|
53924
53998
|
}
|
|
53925
53999
|
}
|
|
53926
54000
|
clear() {
|
|
53927
54001
|
try {
|
|
53928
|
-
|
|
54002
|
+
import_node_fs43.default.unlinkSync(this.file);
|
|
53929
54003
|
} catch (err) {
|
|
53930
54004
|
const code = err?.code;
|
|
53931
54005
|
if (code !== "ENOENT") throw err;
|
|
@@ -54046,9 +54120,9 @@ var CentralClientError = class extends Error {
|
|
|
54046
54120
|
code;
|
|
54047
54121
|
cause;
|
|
54048
54122
|
};
|
|
54049
|
-
async function centralRequest(opts,
|
|
54123
|
+
async function centralRequest(opts, path77, init) {
|
|
54050
54124
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
54051
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
54125
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path77}`;
|
|
54052
54126
|
const ctrl = new AbortController();
|
|
54053
54127
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
54054
54128
|
let res;
|
|
@@ -54190,8 +54264,8 @@ function verifyConnectToken(args) {
|
|
|
54190
54264
|
}
|
|
54191
54265
|
|
|
54192
54266
|
// src/feishu-auth/server-key.ts
|
|
54193
|
-
var
|
|
54194
|
-
var
|
|
54267
|
+
var fs53 = __toESM(require("fs"), 1);
|
|
54268
|
+
var path54 = __toESM(require("path"), 1);
|
|
54195
54269
|
var FILE_NAME2 = "server-signing-key.json";
|
|
54196
54270
|
var ServerKeyStore = class {
|
|
54197
54271
|
constructor(dataDir) {
|
|
@@ -54199,12 +54273,12 @@ var ServerKeyStore = class {
|
|
|
54199
54273
|
}
|
|
54200
54274
|
dataDir;
|
|
54201
54275
|
filePath() {
|
|
54202
|
-
return
|
|
54276
|
+
return path54.join(this.dataDir, FILE_NAME2);
|
|
54203
54277
|
}
|
|
54204
54278
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
54205
54279
|
read() {
|
|
54206
54280
|
try {
|
|
54207
|
-
const raw =
|
|
54281
|
+
const raw = fs53.readFileSync(this.filePath(), "utf8");
|
|
54208
54282
|
const parsed = JSON.parse(raw);
|
|
54209
54283
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
54210
54284
|
return parsed.publicKeyPem;
|
|
@@ -54219,12 +54293,12 @@ var ServerKeyStore = class {
|
|
|
54219
54293
|
publicKeyPem,
|
|
54220
54294
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54221
54295
|
};
|
|
54222
|
-
|
|
54223
|
-
|
|
54296
|
+
fs53.mkdirSync(this.dataDir, { recursive: true });
|
|
54297
|
+
fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
54224
54298
|
}
|
|
54225
54299
|
clear() {
|
|
54226
54300
|
try {
|
|
54227
|
-
|
|
54301
|
+
fs53.unlinkSync(this.filePath());
|
|
54228
54302
|
} catch {
|
|
54229
54303
|
}
|
|
54230
54304
|
}
|
|
@@ -54237,12 +54311,12 @@ init_protocol();
|
|
|
54237
54311
|
init_protocol();
|
|
54238
54312
|
|
|
54239
54313
|
// src/session/fork.ts
|
|
54240
|
-
var
|
|
54314
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
54241
54315
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
54242
|
-
var
|
|
54316
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54243
54317
|
init_claude_history();
|
|
54244
54318
|
function readJsonlEntries(file) {
|
|
54245
|
-
const raw =
|
|
54319
|
+
const raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
54246
54320
|
const out = [];
|
|
54247
54321
|
for (const line of raw.split("\n")) {
|
|
54248
54322
|
const t = line.trim();
|
|
@@ -54255,10 +54329,10 @@ function readJsonlEntries(file) {
|
|
|
54255
54329
|
return out;
|
|
54256
54330
|
}
|
|
54257
54331
|
function forkSession(input) {
|
|
54258
|
-
const baseDir = input.baseDir ??
|
|
54259
|
-
const projectDir =
|
|
54260
|
-
const sourceFile =
|
|
54261
|
-
if (!
|
|
54332
|
+
const baseDir = input.baseDir ?? import_node_path46.default.join(import_node_os16.default.homedir(), ".claude");
|
|
54333
|
+
const projectDir = import_node_path46.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
54334
|
+
const sourceFile = import_node_path46.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
54335
|
+
if (!import_node_fs44.default.existsSync(sourceFile)) {
|
|
54262
54336
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
54263
54337
|
}
|
|
54264
54338
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -54288,9 +54362,9 @@ function forkSession(input) {
|
|
|
54288
54362
|
}
|
|
54289
54363
|
forkedLines.push(JSON.stringify(forked));
|
|
54290
54364
|
}
|
|
54291
|
-
const forkedFilePath =
|
|
54292
|
-
|
|
54293
|
-
|
|
54365
|
+
const forkedFilePath = import_node_path46.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
54366
|
+
import_node_fs44.default.mkdirSync(projectDir, { recursive: true });
|
|
54367
|
+
import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
54294
54368
|
return { forkedToolSessionId, forkedFilePath };
|
|
54295
54369
|
}
|
|
54296
54370
|
|
|
@@ -54642,7 +54716,7 @@ function buildPermissionHandlers(deps) {
|
|
|
54642
54716
|
}
|
|
54643
54717
|
|
|
54644
54718
|
// src/handlers/history.ts
|
|
54645
|
-
var
|
|
54719
|
+
var path57 = __toESM(require("path"), 1);
|
|
54646
54720
|
init_protocol();
|
|
54647
54721
|
|
|
54648
54722
|
// src/session/recent-dirs.ts
|
|
@@ -54660,7 +54734,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
54660
54734
|
}
|
|
54661
54735
|
|
|
54662
54736
|
// src/permission/persona-paths.ts
|
|
54663
|
-
var
|
|
54737
|
+
var path56 = __toESM(require("path"), 1);
|
|
54664
54738
|
function getAllowedPersonaIds(grants, action) {
|
|
54665
54739
|
const ids = /* @__PURE__ */ new Set();
|
|
54666
54740
|
for (const g2 of grants) {
|
|
@@ -54673,42 +54747,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
54673
54747
|
return ids;
|
|
54674
54748
|
}
|
|
54675
54749
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
54676
|
-
const target =
|
|
54750
|
+
const target = path56.resolve(absPath);
|
|
54677
54751
|
if (userWorkDir) {
|
|
54678
|
-
const u =
|
|
54679
|
-
const usep = u.endsWith(
|
|
54752
|
+
const u = path56.resolve(userWorkDir);
|
|
54753
|
+
const usep = u.endsWith(path56.sep) ? "" : path56.sep;
|
|
54680
54754
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
54681
54755
|
}
|
|
54682
|
-
const root =
|
|
54683
|
-
const sep3 = root.endsWith(
|
|
54756
|
+
const root = path56.resolve(personaRoot);
|
|
54757
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54684
54758
|
if (!target.startsWith(root + sep3)) return false;
|
|
54685
|
-
const rel =
|
|
54759
|
+
const rel = path56.relative(root, target);
|
|
54686
54760
|
if (!rel || rel.startsWith("..")) return false;
|
|
54687
|
-
const personaId = rel.split(
|
|
54761
|
+
const personaId = rel.split(path56.sep)[0];
|
|
54688
54762
|
if (!personaId) return false;
|
|
54689
54763
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54690
54764
|
if (allowed === "*") return true;
|
|
54691
54765
|
return allowed.has(personaId);
|
|
54692
54766
|
}
|
|
54693
54767
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54694
|
-
const root =
|
|
54695
|
-
const target =
|
|
54696
|
-
const sep3 = root.endsWith(
|
|
54768
|
+
const root = path56.resolve(personaRoot);
|
|
54769
|
+
const target = path56.resolve(absPath);
|
|
54770
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54697
54771
|
if (!target.startsWith(root + sep3)) return null;
|
|
54698
|
-
const rel =
|
|
54772
|
+
const rel = path56.relative(root, target);
|
|
54699
54773
|
if (!rel || rel.startsWith("..")) return null;
|
|
54700
|
-
const id = rel.split(
|
|
54774
|
+
const id = rel.split(path56.sep)[0];
|
|
54701
54775
|
return id || null;
|
|
54702
54776
|
}
|
|
54703
54777
|
function isPathWithin(dir, absPath) {
|
|
54704
|
-
const d =
|
|
54705
|
-
const t =
|
|
54706
|
-
const sep3 = d.endsWith(
|
|
54778
|
+
const d = path56.resolve(dir);
|
|
54779
|
+
const t = path56.resolve(absPath);
|
|
54780
|
+
const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
|
|
54707
54781
|
return t === d || t.startsWith(d + sep3);
|
|
54708
54782
|
}
|
|
54709
54783
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
54710
54784
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54711
|
-
return personaIdFromPath(
|
|
54785
|
+
return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId;
|
|
54712
54786
|
}
|
|
54713
54787
|
|
|
54714
54788
|
// src/handlers/history.ts
|
|
@@ -54734,7 +54808,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54734
54808
|
if (!pid) return false;
|
|
54735
54809
|
return isGuestPathAllowed(
|
|
54736
54810
|
ctx.grants,
|
|
54737
|
-
|
|
54811
|
+
path57.join(personaRoot, pid),
|
|
54738
54812
|
personaRoot,
|
|
54739
54813
|
"read",
|
|
54740
54814
|
userWorkDir
|
|
@@ -54746,7 +54820,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54746
54820
|
};
|
|
54747
54821
|
const list = async (frame, _client, ctx) => {
|
|
54748
54822
|
const args = HistoryListArgs.parse(frame);
|
|
54749
|
-
assertGuestPath(ctx,
|
|
54823
|
+
assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
|
|
54750
54824
|
const sessions = await history.listSessions(args);
|
|
54751
54825
|
return { response: { type: "history:list", sessions } };
|
|
54752
54826
|
};
|
|
@@ -54778,13 +54852,13 @@ function buildHistoryHandlers(deps) {
|
|
|
54778
54852
|
};
|
|
54779
54853
|
const subagents = async (frame, _client, ctx) => {
|
|
54780
54854
|
const args = HistorySubagentsArgs.parse(frame);
|
|
54781
|
-
assertGuestPath(ctx,
|
|
54855
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
54782
54856
|
const subs = await history.listSubagents(args);
|
|
54783
54857
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
54784
54858
|
};
|
|
54785
54859
|
const subagentRead = async (frame, _client, ctx) => {
|
|
54786
54860
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
54787
|
-
assertGuestPath(ctx,
|
|
54861
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
54788
54862
|
const res = await history.readSubagent(args);
|
|
54789
54863
|
return { response: { type: "history:subagent-read", ...res } };
|
|
54790
54864
|
};
|
|
@@ -54793,7 +54867,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54793
54867
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54794
54868
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54795
54869
|
const filtered = dirs.filter(
|
|
54796
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
54870
|
+
(d) => isGuestPathAllowed(ctx.grants, path57.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
54797
54871
|
);
|
|
54798
54872
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
54799
54873
|
}
|
|
@@ -54810,7 +54884,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54810
54884
|
}
|
|
54811
54885
|
|
|
54812
54886
|
// src/handlers/workspace.ts
|
|
54813
|
-
var
|
|
54887
|
+
var path58 = __toESM(require("path"), 1);
|
|
54814
54888
|
var os16 = __toESM(require("os"), 1);
|
|
54815
54889
|
init_protocol();
|
|
54816
54890
|
init_protocol();
|
|
@@ -54852,22 +54926,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54852
54926
|
const args = WorkspaceListArgs.parse(frame);
|
|
54853
54927
|
const isGuest = ctx?.principal.kind === "guest";
|
|
54854
54928
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
54855
|
-
const resolvedCwd =
|
|
54856
|
-
const target = args.path ?
|
|
54929
|
+
const resolvedCwd = path58.resolve(args.cwd ?? fallbackCwd);
|
|
54930
|
+
const target = args.path ? path58.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
54857
54931
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
54858
54932
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
54859
54933
|
return { response: { type: "workspace:list", ...res } };
|
|
54860
54934
|
};
|
|
54861
54935
|
const read = async (frame, _client, ctx) => {
|
|
54862
54936
|
const args = WorkspaceReadArgs.parse(frame);
|
|
54863
|
-
const target =
|
|
54937
|
+
const target = path58.isAbsolute(args.path) ? path58.resolve(args.path) : path58.resolve(args.cwd, args.path);
|
|
54864
54938
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
54865
54939
|
const res = workspace.read(args);
|
|
54866
54940
|
return { response: { type: "workspace:read", ...res } };
|
|
54867
54941
|
};
|
|
54868
54942
|
const skillsList = async (frame, _client, ctx) => {
|
|
54869
54943
|
const args = SkillsListArgs.parse(frame);
|
|
54870
|
-
const cwdAbs =
|
|
54944
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
54871
54945
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
54872
54946
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
54873
54947
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -54879,7 +54953,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54879
54953
|
};
|
|
54880
54954
|
const agentsList = async (frame, _client, ctx) => {
|
|
54881
54955
|
const args = AgentsListArgs.parse(frame);
|
|
54882
|
-
const cwdAbs =
|
|
54956
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
54883
54957
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
54884
54958
|
if (args.tool === "codex") {
|
|
54885
54959
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -54901,20 +54975,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54901
54975
|
}
|
|
54902
54976
|
|
|
54903
54977
|
// src/handlers/git.ts
|
|
54904
|
-
var
|
|
54978
|
+
var path60 = __toESM(require("path"), 1);
|
|
54905
54979
|
init_protocol();
|
|
54906
54980
|
init_protocol();
|
|
54907
54981
|
|
|
54908
54982
|
// src/workspace/git.ts
|
|
54909
54983
|
var import_node_child_process12 = require("child_process");
|
|
54910
|
-
var
|
|
54911
|
-
var
|
|
54984
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
54985
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
54912
54986
|
var import_node_util = require("util");
|
|
54913
54987
|
var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
|
|
54914
54988
|
function normalizePath(p2) {
|
|
54915
|
-
const resolved =
|
|
54989
|
+
const resolved = import_node_path47.default.resolve(p2);
|
|
54916
54990
|
try {
|
|
54917
|
-
return
|
|
54991
|
+
return import_node_fs45.default.realpathSync(resolved);
|
|
54918
54992
|
} catch {
|
|
54919
54993
|
return resolved;
|
|
54920
54994
|
}
|
|
@@ -54988,7 +55062,7 @@ async function listGitBranches(cwd) {
|
|
|
54988
55062
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
54989
55063
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
54990
55064
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54991
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
55065
|
+
if (!isGuestPathAllowed(ctx.grants, path60.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
54992
55066
|
throw new ClawdError(
|
|
54993
55067
|
ERROR_CODES.UNAUTHORIZED,
|
|
54994
55068
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -55329,22 +55403,22 @@ init_src();
|
|
|
55329
55403
|
init_protocol();
|
|
55330
55404
|
|
|
55331
55405
|
// src/sshd/key-issue.ts
|
|
55332
|
-
var
|
|
55333
|
-
var
|
|
55406
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
55407
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
55334
55408
|
var import_node_child_process13 = require("child_process");
|
|
55335
55409
|
function safeDeviceId(deviceId) {
|
|
55336
55410
|
return deviceId.replace(/[\/\\]/g, "_");
|
|
55337
55411
|
}
|
|
55338
55412
|
async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
55339
55413
|
const safeId = safeDeviceId(deviceId);
|
|
55340
|
-
const keysDir =
|
|
55341
|
-
|
|
55342
|
-
const privPath =
|
|
55414
|
+
const keysDir = import_node_path48.default.join(sshdDir, "keys");
|
|
55415
|
+
import_node_fs46.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
|
|
55416
|
+
const privPath = import_node_path48.default.join(keysDir, `${safeId}.ed25519`);
|
|
55343
55417
|
const pubPath = `${privPath}.pub`;
|
|
55344
|
-
if (
|
|
55418
|
+
if (import_node_fs46.default.existsSync(privPath) && import_node_fs46.default.existsSync(pubPath)) {
|
|
55345
55419
|
return {
|
|
55346
|
-
privateKeyPem:
|
|
55347
|
-
publicKeyLine:
|
|
55420
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55421
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55348
55422
|
};
|
|
55349
55423
|
}
|
|
55350
55424
|
const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
|
|
@@ -55358,20 +55432,21 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
|
55358
55432
|
p2.on("error", reject);
|
|
55359
55433
|
});
|
|
55360
55434
|
try {
|
|
55361
|
-
|
|
55435
|
+
import_node_fs46.default.chmodSync(privPath, 384);
|
|
55362
55436
|
} catch {
|
|
55363
55437
|
}
|
|
55364
55438
|
try {
|
|
55365
|
-
|
|
55439
|
+
import_node_fs46.default.chmodSync(pubPath, 420);
|
|
55366
55440
|
} catch {
|
|
55367
55441
|
}
|
|
55368
55442
|
return {
|
|
55369
|
-
privateKeyPem:
|
|
55370
|
-
publicKeyLine:
|
|
55443
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55444
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55371
55445
|
};
|
|
55372
55446
|
}
|
|
55373
55447
|
|
|
55374
55448
|
// src/handlers/contact-ssh.ts
|
|
55449
|
+
init_contact_ssh_log();
|
|
55375
55450
|
function ensureOwner2(ctx) {
|
|
55376
55451
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
55377
55452
|
throw new ClawdError(
|
|
@@ -55786,7 +55861,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55786
55861
|
}
|
|
55787
55862
|
|
|
55788
55863
|
// src/handlers/attachment.ts
|
|
55789
|
-
var
|
|
55864
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
55790
55865
|
init_protocol();
|
|
55791
55866
|
init_protocol();
|
|
55792
55867
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -55866,12 +55941,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
55866
55941
|
`session ${args.sessionId} scope unresolved`
|
|
55867
55942
|
);
|
|
55868
55943
|
}
|
|
55869
|
-
const cwdAbs =
|
|
55870
|
-
const candidateAbs =
|
|
55944
|
+
const cwdAbs = import_node_path49.default.resolve(sessionFile.cwd);
|
|
55945
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
55871
55946
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
55872
55947
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
55873
55948
|
const entry = entries.find((e) => {
|
|
55874
|
-
const storedAbs =
|
|
55949
|
+
const storedAbs = import_node_path49.default.isAbsolute(e.relPath) ? import_node_path49.default.resolve(e.relPath) : import_node_path49.default.resolve(cwdAbs, e.relPath);
|
|
55875
55950
|
return storedAbs === candidateAbs && !e.stale;
|
|
55876
55951
|
});
|
|
55877
55952
|
if (!entry) {
|
|
@@ -55896,7 +55971,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
55896
55971
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
55897
55972
|
const f = deps.sessionStore.read(sessionId);
|
|
55898
55973
|
if (!f) return;
|
|
55899
|
-
assertGuestAttachmentPath(ctx,
|
|
55974
|
+
assertGuestAttachmentPath(ctx, import_node_path49.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
55900
55975
|
}
|
|
55901
55976
|
const groupAdd = async (frame, _client, ctx) => {
|
|
55902
55977
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -55911,8 +55986,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
55911
55986
|
if (!scope) {
|
|
55912
55987
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
55913
55988
|
}
|
|
55914
|
-
const cwdAbs =
|
|
55915
|
-
const candidateAbs =
|
|
55989
|
+
const cwdAbs = import_node_path49.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
55990
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
55916
55991
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
55917
55992
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
55918
55993
|
const size = 0;
|
|
@@ -55971,20 +56046,20 @@ function buildAttachmentHandlers(deps) {
|
|
|
55971
56046
|
|
|
55972
56047
|
// src/handlers/extension.ts
|
|
55973
56048
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
55974
|
-
var
|
|
56049
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
55975
56050
|
init_protocol();
|
|
55976
56051
|
init_src();
|
|
55977
56052
|
|
|
55978
56053
|
// src/extension/bundle-zip.ts
|
|
55979
56054
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
55980
|
-
var
|
|
56055
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
55981
56056
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
55982
56057
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
55983
56058
|
async function bundleExtensionDir(dir) {
|
|
55984
56059
|
const entries = await listFilesSorted(dir);
|
|
55985
56060
|
const zip = new import_jszip2.default();
|
|
55986
56061
|
for (const rel of entries) {
|
|
55987
|
-
const abs =
|
|
56062
|
+
const abs = import_node_path50.default.join(dir, rel);
|
|
55988
56063
|
const content = await import_promises5.default.readFile(abs);
|
|
55989
56064
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
55990
56065
|
}
|
|
@@ -56005,7 +56080,7 @@ async function listFilesSorted(rootDir) {
|
|
|
56005
56080
|
return out;
|
|
56006
56081
|
}
|
|
56007
56082
|
async function walk(absRoot, relPrefix, out) {
|
|
56008
|
-
const dirAbs =
|
|
56083
|
+
const dirAbs = import_node_path50.default.join(absRoot, relPrefix);
|
|
56009
56084
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
56010
56085
|
for (const e of entries) {
|
|
56011
56086
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -56061,7 +56136,7 @@ function computePublishCheck(args) {
|
|
|
56061
56136
|
|
|
56062
56137
|
// src/extension/install-flow.ts
|
|
56063
56138
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
56064
|
-
var
|
|
56139
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56065
56140
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
56066
56141
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
56067
56142
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
@@ -56069,19 +56144,19 @@ init_src();
|
|
|
56069
56144
|
|
|
56070
56145
|
// src/extension/paths.ts
|
|
56071
56146
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
56072
|
-
var
|
|
56147
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56073
56148
|
init_src();
|
|
56074
56149
|
function clawdHomeRoot(override) {
|
|
56075
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
56150
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path51.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
56076
56151
|
}
|
|
56077
56152
|
function extensionsRoot(override) {
|
|
56078
|
-
return
|
|
56153
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions");
|
|
56079
56154
|
}
|
|
56080
56155
|
function publishedChannelsFile(override) {
|
|
56081
|
-
return
|
|
56156
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
56082
56157
|
}
|
|
56083
56158
|
function bundleCacheRoot(override) {
|
|
56084
|
-
return
|
|
56159
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
56085
56160
|
}
|
|
56086
56161
|
|
|
56087
56162
|
// src/extension/install-flow.ts
|
|
@@ -56108,7 +56183,7 @@ async function installFromChannel(args, deps) {
|
|
|
56108
56183
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56109
56184
|
}
|
|
56110
56185
|
for (const name of Object.keys(zip.files)) {
|
|
56111
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56186
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
|
|
56112
56187
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56113
56188
|
}
|
|
56114
56189
|
}
|
|
@@ -56140,7 +56215,7 @@ async function installFromChannel(args, deps) {
|
|
|
56140
56215
|
);
|
|
56141
56216
|
}
|
|
56142
56217
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
56143
|
-
const destDir =
|
|
56218
|
+
const destDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
|
|
56144
56219
|
let destExists = false;
|
|
56145
56220
|
try {
|
|
56146
56221
|
await import_promises6.default.access(destDir);
|
|
@@ -56154,16 +56229,16 @@ async function installFromChannel(args, deps) {
|
|
|
56154
56229
|
);
|
|
56155
56230
|
}
|
|
56156
56231
|
const stage = await import_promises6.default.mkdtemp(
|
|
56157
|
-
|
|
56232
|
+
import_node_path52.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
56158
56233
|
);
|
|
56159
56234
|
try {
|
|
56160
56235
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56161
|
-
const dest =
|
|
56236
|
+
const dest = import_node_path52.default.join(stage, name);
|
|
56162
56237
|
if (entry.dir) {
|
|
56163
56238
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
56164
56239
|
continue;
|
|
56165
56240
|
}
|
|
56166
|
-
await import_promises6.default.mkdir(
|
|
56241
|
+
await import_promises6.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
|
|
56167
56242
|
if (name === "manifest.json") {
|
|
56168
56243
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56169
56244
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56184,7 +56259,7 @@ async function installFromChannel(args, deps) {
|
|
|
56184
56259
|
|
|
56185
56260
|
// src/extension/update-flow.ts
|
|
56186
56261
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
56187
|
-
var
|
|
56262
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
56188
56263
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
56189
56264
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
56190
56265
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -56202,11 +56277,11 @@ async function updateFromChannel(args, deps) {
|
|
|
56202
56277
|
channelRef.extId,
|
|
56203
56278
|
channelRef.ownerPrincipalId
|
|
56204
56279
|
);
|
|
56205
|
-
const liveDir =
|
|
56280
|
+
const liveDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
|
|
56206
56281
|
const prevDir = `${liveDir}.prev`;
|
|
56207
56282
|
let existingVersion;
|
|
56208
56283
|
try {
|
|
56209
|
-
const raw = await import_promises7.default.readFile(
|
|
56284
|
+
const raw = await import_promises7.default.readFile(import_node_path53.default.join(liveDir, "manifest.json"), "utf8");
|
|
56210
56285
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
56211
56286
|
if (!parsed2.success) {
|
|
56212
56287
|
throw new UpdateError(
|
|
@@ -56239,7 +56314,7 @@ async function updateFromChannel(args, deps) {
|
|
|
56239
56314
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56240
56315
|
}
|
|
56241
56316
|
for (const name of Object.keys(zip.files)) {
|
|
56242
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56317
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
|
|
56243
56318
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56244
56319
|
}
|
|
56245
56320
|
}
|
|
@@ -56274,16 +56349,16 @@ async function updateFromChannel(args, deps) {
|
|
|
56274
56349
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
56275
56350
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
56276
56351
|
const stage = await import_promises7.default.mkdtemp(
|
|
56277
|
-
|
|
56352
|
+
import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
56278
56353
|
);
|
|
56279
56354
|
try {
|
|
56280
56355
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56281
|
-
const dest =
|
|
56356
|
+
const dest = import_node_path53.default.join(stage, name);
|
|
56282
56357
|
if (entry.dir) {
|
|
56283
56358
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
56284
56359
|
continue;
|
|
56285
56360
|
}
|
|
56286
|
-
await import_promises7.default.mkdir(
|
|
56361
|
+
await import_promises7.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
|
|
56287
56362
|
if (name === "manifest.json") {
|
|
56288
56363
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56289
56364
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56377,7 +56452,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56377
56452
|
);
|
|
56378
56453
|
}
|
|
56379
56454
|
}
|
|
56380
|
-
const manifestPath =
|
|
56455
|
+
const manifestPath = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56381
56456
|
const manifest = await readManifest(root, extId);
|
|
56382
56457
|
const next = { ...manifest, version: newVersion };
|
|
56383
56458
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -56385,7 +56460,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56385
56460
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
56386
56461
|
}
|
|
56387
56462
|
async function readManifest(root, extId) {
|
|
56388
|
-
const file =
|
|
56463
|
+
const file = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56389
56464
|
let raw;
|
|
56390
56465
|
try {
|
|
56391
56466
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -56476,7 +56551,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56476
56551
|
};
|
|
56477
56552
|
async function buildSnapshotMeta(extId) {
|
|
56478
56553
|
const manifest = await readManifest(deps.root, extId);
|
|
56479
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
56554
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path54.default.join(deps.root, extId));
|
|
56480
56555
|
return { manifest, contentHash: sha256, buffer };
|
|
56481
56556
|
}
|
|
56482
56557
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -56657,9 +56732,9 @@ function buildExtensionHandlers(deps) {
|
|
|
56657
56732
|
}
|
|
56658
56733
|
|
|
56659
56734
|
// src/app-builder/project-store.ts
|
|
56660
|
-
var
|
|
56735
|
+
var import_node_fs47 = require("fs");
|
|
56661
56736
|
var import_node_child_process14 = require("child_process");
|
|
56662
|
-
var
|
|
56737
|
+
var import_node_path55 = require("path");
|
|
56663
56738
|
init_protocol();
|
|
56664
56739
|
var PROJECTS_DIR = "projects";
|
|
56665
56740
|
var META_FILE = ".clawd-project.json";
|
|
@@ -56673,19 +56748,19 @@ var ProjectStore = class {
|
|
|
56673
56748
|
root;
|
|
56674
56749
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
56675
56750
|
metaPath(name) {
|
|
56676
|
-
return (0,
|
|
56751
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name, META_FILE);
|
|
56677
56752
|
}
|
|
56678
56753
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
56679
56754
|
projectDir(name) {
|
|
56680
|
-
return (0,
|
|
56755
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name);
|
|
56681
56756
|
}
|
|
56682
56757
|
projectsRoot() {
|
|
56683
|
-
return (0,
|
|
56758
|
+
return (0, import_node_path55.join)(this.root, PROJECTS_DIR);
|
|
56684
56759
|
}
|
|
56685
56760
|
async list() {
|
|
56686
56761
|
let entries;
|
|
56687
56762
|
try {
|
|
56688
|
-
entries = await
|
|
56763
|
+
entries = await import_node_fs47.promises.readdir(this.projectsRoot());
|
|
56689
56764
|
} catch (err) {
|
|
56690
56765
|
if (err.code === "ENOENT") return [];
|
|
56691
56766
|
throw err;
|
|
@@ -56693,7 +56768,7 @@ var ProjectStore = class {
|
|
|
56693
56768
|
const out = [];
|
|
56694
56769
|
for (const name of entries) {
|
|
56695
56770
|
try {
|
|
56696
|
-
const raw = await
|
|
56771
|
+
const raw = await import_node_fs47.promises.readFile(this.metaPath(name), "utf8");
|
|
56697
56772
|
const json = JSON.parse(raw);
|
|
56698
56773
|
let migrated = false;
|
|
56699
56774
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -56704,7 +56779,7 @@ var ProjectStore = class {
|
|
|
56704
56779
|
if (parsed.success) {
|
|
56705
56780
|
out.push(parsed.data);
|
|
56706
56781
|
if (migrated) {
|
|
56707
|
-
void
|
|
56782
|
+
void import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
56708
56783
|
});
|
|
56709
56784
|
}
|
|
56710
56785
|
}
|
|
@@ -56748,8 +56823,8 @@ var ProjectStore = class {
|
|
|
56748
56823
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
56749
56824
|
}
|
|
56750
56825
|
const dir = this.projectDir(name);
|
|
56751
|
-
await
|
|
56752
|
-
await
|
|
56826
|
+
await import_node_fs47.promises.mkdir(dir, { recursive: true });
|
|
56827
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
56753
56828
|
return meta;
|
|
56754
56829
|
}
|
|
56755
56830
|
/**
|
|
@@ -56792,7 +56867,7 @@ var ProjectStore = class {
|
|
|
56792
56867
|
}
|
|
56793
56868
|
async delete(name) {
|
|
56794
56869
|
const dir = this.projectDir(name);
|
|
56795
|
-
await
|
|
56870
|
+
await import_node_fs47.promises.rm(dir, { recursive: true, force: true });
|
|
56796
56871
|
}
|
|
56797
56872
|
async updatePort(name, newPort) {
|
|
56798
56873
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -56808,7 +56883,7 @@ var ProjectStore = class {
|
|
|
56808
56883
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
56809
56884
|
}
|
|
56810
56885
|
const updated = { ...target, port: newPort };
|
|
56811
|
-
await
|
|
56886
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
56812
56887
|
return updated;
|
|
56813
56888
|
}
|
|
56814
56889
|
/**
|
|
@@ -56825,7 +56900,7 @@ var ProjectStore = class {
|
|
|
56825
56900
|
if (!validated.success) {
|
|
56826
56901
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
56827
56902
|
}
|
|
56828
|
-
await
|
|
56903
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56829
56904
|
return validated.data;
|
|
56830
56905
|
}
|
|
56831
56906
|
/**
|
|
@@ -56846,7 +56921,7 @@ var ProjectStore = class {
|
|
|
56846
56921
|
if (!validated.success) {
|
|
56847
56922
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
56848
56923
|
}
|
|
56849
|
-
await
|
|
56924
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56850
56925
|
return validated.data;
|
|
56851
56926
|
}
|
|
56852
56927
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -56861,7 +56936,7 @@ var ProjectStore = class {
|
|
|
56861
56936
|
if (!validated.success) {
|
|
56862
56937
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
56863
56938
|
}
|
|
56864
|
-
await
|
|
56939
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56865
56940
|
return validated.data;
|
|
56866
56941
|
}
|
|
56867
56942
|
};
|
|
@@ -56982,8 +57057,8 @@ var PublishJobRegistry = class {
|
|
|
56982
57057
|
|
|
56983
57058
|
// src/app-builder/publish-job-runner.ts
|
|
56984
57059
|
var import_node_child_process16 = require("child_process");
|
|
56985
|
-
var
|
|
56986
|
-
var
|
|
57060
|
+
var import_node_fs48 = require("fs");
|
|
57061
|
+
var import_node_path56 = require("path");
|
|
56987
57062
|
|
|
56988
57063
|
// src/app-builder/publish-stage-parser.ts
|
|
56989
57064
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -57015,10 +57090,10 @@ async function startPublishJob(deps, args) {
|
|
|
57015
57090
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
57016
57091
|
}
|
|
57017
57092
|
const projDir = projectDir(args.name);
|
|
57018
|
-
const logPath = (0,
|
|
57093
|
+
const logPath = (0, import_node_path56.join)(projDir, ".publish.log");
|
|
57019
57094
|
let logStream = null;
|
|
57020
57095
|
try {
|
|
57021
|
-
logStream = (0,
|
|
57096
|
+
logStream = (0, import_node_fs48.createWriteStream)(logPath, { flags: "w" });
|
|
57022
57097
|
} catch {
|
|
57023
57098
|
logStream = null;
|
|
57024
57099
|
}
|
|
@@ -57275,8 +57350,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
57275
57350
|
|
|
57276
57351
|
// src/handlers/app-builder.ts
|
|
57277
57352
|
init_protocol();
|
|
57278
|
-
var
|
|
57279
|
-
var
|
|
57353
|
+
var import_node_path57 = require("path");
|
|
57354
|
+
var import_node_fs49 = require("fs");
|
|
57280
57355
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
57281
57356
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
57282
57357
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -57357,7 +57432,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57357
57432
|
async function listAllUsersProjects() {
|
|
57358
57433
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
57359
57434
|
const getStore = deps.getStore;
|
|
57360
|
-
const userIds = await
|
|
57435
|
+
const userIds = await import_node_fs49.promises.readdir(deps.usersRoot).catch(() => []);
|
|
57361
57436
|
const perUser = await Promise.all(
|
|
57362
57437
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
57363
57438
|
);
|
|
@@ -57433,8 +57508,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57433
57508
|
const project = await userStore.create(f.name, reservedPorts);
|
|
57434
57509
|
try {
|
|
57435
57510
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57436
|
-
const templateSrcDir = (0,
|
|
57437
|
-
const scaffoldScript = (0,
|
|
57511
|
+
const templateSrcDir = (0, import_node_path57.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
57512
|
+
const scaffoldScript = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
57438
57513
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
57439
57514
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
57440
57515
|
name: project.name,
|
|
@@ -57655,7 +57730,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57655
57730
|
await userStore.clearPublishJob(args.name);
|
|
57656
57731
|
}
|
|
57657
57732
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57658
|
-
const scriptPath = (0,
|
|
57733
|
+
const scriptPath = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
57659
57734
|
deps.logger?.info("app-builder.publish.start", {
|
|
57660
57735
|
name: args.name,
|
|
57661
57736
|
sessionId: boundSession.sessionId,
|
|
@@ -57824,7 +57899,7 @@ function buildVisitorHandlers(deps) {
|
|
|
57824
57899
|
|
|
57825
57900
|
// src/extension/registry.ts
|
|
57826
57901
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
57827
|
-
var
|
|
57902
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
57828
57903
|
init_src();
|
|
57829
57904
|
async function loadAll(root) {
|
|
57830
57905
|
let entries;
|
|
@@ -57838,13 +57913,13 @@ async function loadAll(root) {
|
|
|
57838
57913
|
for (const ent of entries) {
|
|
57839
57914
|
if (!ent.isDirectory()) continue;
|
|
57840
57915
|
if (ent.name.startsWith(".")) continue;
|
|
57841
|
-
records.push(await loadOne(
|
|
57916
|
+
records.push(await loadOne(import_node_path58.default.join(root, ent.name), ent.name));
|
|
57842
57917
|
}
|
|
57843
57918
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
57844
57919
|
return records;
|
|
57845
57920
|
}
|
|
57846
57921
|
async function loadOne(dir, dirName) {
|
|
57847
|
-
const manifestPath =
|
|
57922
|
+
const manifestPath = import_node_path58.default.join(dir, "manifest.json");
|
|
57848
57923
|
let raw;
|
|
57849
57924
|
try {
|
|
57850
57925
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -57889,7 +57964,7 @@ async function loadOne(dir, dirName) {
|
|
|
57889
57964
|
|
|
57890
57965
|
// src/extension/uninstall.ts
|
|
57891
57966
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
57892
|
-
var
|
|
57967
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
57893
57968
|
var UninstallError = class extends Error {
|
|
57894
57969
|
constructor(code, message) {
|
|
57895
57970
|
super(message);
|
|
@@ -57898,7 +57973,7 @@ var UninstallError = class extends Error {
|
|
|
57898
57973
|
code;
|
|
57899
57974
|
};
|
|
57900
57975
|
async function uninstall(deps) {
|
|
57901
|
-
const dir =
|
|
57976
|
+
const dir = import_node_path59.default.join(deps.root, deps.extId);
|
|
57902
57977
|
try {
|
|
57903
57978
|
await import_promises10.default.access(dir);
|
|
57904
57979
|
} catch {
|
|
@@ -58482,7 +58557,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58482
58557
|
|
|
58483
58558
|
// src/extension/runtime.ts
|
|
58484
58559
|
var import_node_child_process18 = require("child_process");
|
|
58485
|
-
var
|
|
58560
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
58486
58561
|
var import_promises11 = require("timers/promises");
|
|
58487
58562
|
init_src();
|
|
58488
58563
|
|
|
@@ -58584,7 +58659,7 @@ var Runtime = class {
|
|
|
58584
58659
|
/\$CLAWOS_EXT_PORT/g,
|
|
58585
58660
|
String(port)
|
|
58586
58661
|
);
|
|
58587
|
-
const dir =
|
|
58662
|
+
const dir = import_node_path60.default.join(this.root, extId);
|
|
58588
58663
|
const env = {
|
|
58589
58664
|
...process.env,
|
|
58590
58665
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -58696,7 +58771,7 @@ ${handle.stderrTail}`
|
|
|
58696
58771
|
|
|
58697
58772
|
// src/extension/published-channels.ts
|
|
58698
58773
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
58699
|
-
var
|
|
58774
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
58700
58775
|
init_src();
|
|
58701
58776
|
init_zod();
|
|
58702
58777
|
var PublishedChannelsError = class extends Error {
|
|
@@ -58796,7 +58871,7 @@ var PublishedChannelStore = class {
|
|
|
58796
58871
|
)
|
|
58797
58872
|
};
|
|
58798
58873
|
const tmp = `${this.filePath}.tmp`;
|
|
58799
|
-
await import_promises12.default.mkdir(
|
|
58874
|
+
await import_promises12.default.mkdir(import_node_path61.default.dirname(this.filePath), { recursive: true });
|
|
58800
58875
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
58801
58876
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
58802
58877
|
}
|
|
@@ -58804,7 +58879,7 @@ var PublishedChannelStore = class {
|
|
|
58804
58879
|
|
|
58805
58880
|
// src/extension/bundle-cache.ts
|
|
58806
58881
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
58807
|
-
var
|
|
58882
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
58808
58883
|
var BundleCache = class {
|
|
58809
58884
|
constructor(rootDir) {
|
|
58810
58885
|
this.rootDir = rootDir;
|
|
@@ -58813,14 +58888,14 @@ var BundleCache = class {
|
|
|
58813
58888
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
58814
58889
|
async write(snapshotHash, buffer) {
|
|
58815
58890
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
58816
|
-
const file =
|
|
58891
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58817
58892
|
const tmp = `${file}.tmp`;
|
|
58818
58893
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
58819
58894
|
await import_promises13.default.rename(tmp, file);
|
|
58820
58895
|
}
|
|
58821
58896
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
58822
58897
|
async read(snapshotHash) {
|
|
58823
|
-
const file =
|
|
58898
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58824
58899
|
try {
|
|
58825
58900
|
return await import_promises13.default.readFile(file);
|
|
58826
58901
|
} catch (e) {
|
|
@@ -58830,7 +58905,7 @@ var BundleCache = class {
|
|
|
58830
58905
|
}
|
|
58831
58906
|
/** Idempotent — missing file is not an error. */
|
|
58832
58907
|
async delete(snapshotHash) {
|
|
58833
|
-
const file =
|
|
58908
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58834
58909
|
await import_promises13.default.rm(file, { force: true });
|
|
58835
58910
|
}
|
|
58836
58911
|
};
|
|
@@ -58855,16 +58930,16 @@ async function startDaemon(config) {
|
|
|
58855
58930
|
});
|
|
58856
58931
|
const logger = createLogger({
|
|
58857
58932
|
level: config.logLevel,
|
|
58858
|
-
file:
|
|
58933
|
+
file: import_node_path63.default.join(config.dataDir, "clawd.log"),
|
|
58859
58934
|
logClient
|
|
58860
58935
|
});
|
|
58861
58936
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
58862
58937
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
58863
|
-
file:
|
|
58938
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log"),
|
|
58864
58939
|
level: "debug"
|
|
58865
58940
|
});
|
|
58866
58941
|
logger.info("screen-idle probe logger enabled", {
|
|
58867
|
-
file:
|
|
58942
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log")
|
|
58868
58943
|
});
|
|
58869
58944
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
58870
58945
|
const pre = stateMgr.preflight();
|
|
@@ -59002,8 +59077,8 @@ async function startDaemon(config) {
|
|
|
59002
59077
|
const agents = new AgentsScanner();
|
|
59003
59078
|
const history = new ClaudeHistoryReader();
|
|
59004
59079
|
let transport = null;
|
|
59005
|
-
const personaStore = new PersonaStore(
|
|
59006
|
-
const usersRoot =
|
|
59080
|
+
const personaStore = new PersonaStore(import_node_path63.default.join(config.dataDir, "personas"));
|
|
59081
|
+
const usersRoot = import_node_path63.default.join(config.dataDir, "users");
|
|
59007
59082
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
59008
59083
|
if (defaultsRoot) {
|
|
59009
59084
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -59023,17 +59098,17 @@ async function startDaemon(config) {
|
|
|
59023
59098
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
59024
59099
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
59025
59100
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
59026
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
59101
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path63.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
59027
59102
|
const dispatchServerCandidates = [
|
|
59028
|
-
|
|
59103
|
+
import_node_path63.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
59029
59104
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
59030
|
-
|
|
59105
|
+
import_node_path63.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
59031
59106
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
59032
59107
|
];
|
|
59033
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
59108
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59034
59109
|
let dispatchMcpConfigPath2;
|
|
59035
59110
|
if (dispatchServerScriptPath) {
|
|
59036
|
-
const dispatchLogPath =
|
|
59111
|
+
const dispatchLogPath = import_node_path63.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
59037
59112
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
59038
59113
|
dataDir: config.dataDir,
|
|
59039
59114
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -59050,15 +59125,15 @@ async function startDaemon(config) {
|
|
|
59050
59125
|
});
|
|
59051
59126
|
}
|
|
59052
59127
|
const ticketServerCandidates = [
|
|
59053
|
-
|
|
59054
|
-
|
|
59128
|
+
import_node_path63.default.join(here, "ticket", "mcp-server.cjs"),
|
|
59129
|
+
import_node_path63.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
59055
59130
|
];
|
|
59056
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
59131
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59057
59132
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
59058
59133
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
59059
59134
|
let ticketMcpConfigPath2;
|
|
59060
59135
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
59061
|
-
const ticketLogPath =
|
|
59136
|
+
const ticketLogPath = import_node_path63.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
59062
59137
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
59063
59138
|
dataDir: config.dataDir,
|
|
59064
59139
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -59079,13 +59154,13 @@ async function startDaemon(config) {
|
|
|
59079
59154
|
});
|
|
59080
59155
|
}
|
|
59081
59156
|
const shiftServerCandidates = [
|
|
59082
|
-
|
|
59083
|
-
|
|
59157
|
+
import_node_path63.default.join(here, "shift", "mcp-server.cjs"),
|
|
59158
|
+
import_node_path63.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
59084
59159
|
];
|
|
59085
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
59160
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59086
59161
|
let shiftMcpConfigPath2;
|
|
59087
59162
|
if (shiftServerScriptPath) {
|
|
59088
|
-
const shiftLogPath =
|
|
59163
|
+
const shiftLogPath = import_node_path63.default.join(config.dataDir, "shift-mcp-server.log");
|
|
59089
59164
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
59090
59165
|
dataDir: config.dataDir,
|
|
59091
59166
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -59103,13 +59178,13 @@ async function startDaemon(config) {
|
|
|
59103
59178
|
);
|
|
59104
59179
|
}
|
|
59105
59180
|
const inboxServerCandidates = [
|
|
59106
|
-
|
|
59107
|
-
|
|
59181
|
+
import_node_path63.default.join(here, "inbox", "mcp-server.cjs"),
|
|
59182
|
+
import_node_path63.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
59108
59183
|
];
|
|
59109
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
59184
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59110
59185
|
let inboxMcpConfigPath2;
|
|
59111
59186
|
if (inboxServerScriptPath) {
|
|
59112
|
-
const inboxLogPath =
|
|
59187
|
+
const inboxLogPath = import_node_path63.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
59113
59188
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
59114
59189
|
dataDir: config.dataDir,
|
|
59115
59190
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -59127,7 +59202,7 @@ async function startDaemon(config) {
|
|
|
59127
59202
|
);
|
|
59128
59203
|
}
|
|
59129
59204
|
const shiftStore = createShiftStore({
|
|
59130
|
-
filePath:
|
|
59205
|
+
filePath: import_node_path63.default.join(config.dataDir, "shift.json"),
|
|
59131
59206
|
ownerIdProvider: () => ownerPrincipalId,
|
|
59132
59207
|
now: () => Date.now()
|
|
59133
59208
|
});
|
|
@@ -59149,7 +59224,7 @@ async function startDaemon(config) {
|
|
|
59149
59224
|
getAdapter,
|
|
59150
59225
|
historyReader: history,
|
|
59151
59226
|
dataDir: config.dataDir,
|
|
59152
|
-
personaRoot:
|
|
59227
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59153
59228
|
usersRoot,
|
|
59154
59229
|
personaStore,
|
|
59155
59230
|
ownerDisplayName,
|
|
@@ -59192,10 +59267,10 @@ async function startDaemon(config) {
|
|
|
59192
59267
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
59193
59268
|
attachmentGroup: {
|
|
59194
59269
|
onFileEdit: (input) => {
|
|
59195
|
-
const absPath =
|
|
59270
|
+
const absPath = import_node_path63.default.isAbsolute(input.relPath) ? input.relPath : import_node_path63.default.join(input.cwd, input.relPath);
|
|
59196
59271
|
let size = 0;
|
|
59197
59272
|
try {
|
|
59198
|
-
size =
|
|
59273
|
+
size = import_node_fs50.default.statSync(absPath).size;
|
|
59199
59274
|
} catch (err) {
|
|
59200
59275
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
59201
59276
|
sessionId: input.sessionId,
|
|
@@ -59394,11 +59469,11 @@ async function startDaemon(config) {
|
|
|
59394
59469
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
59395
59470
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
59396
59471
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
59397
|
-
personaRoot:
|
|
59472
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59398
59473
|
usersRoot
|
|
59399
59474
|
},
|
|
59400
59475
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
59401
|
-
personaRoot:
|
|
59476
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59402
59477
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
59403
59478
|
usersRoot,
|
|
59404
59479
|
// capability:list / delete handler 依赖
|
|
@@ -59420,7 +59495,7 @@ async function startDaemon(config) {
|
|
|
59420
59495
|
contactStore,
|
|
59421
59496
|
// <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
|
|
59422
59497
|
// Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
|
|
59423
|
-
sshdDir:
|
|
59498
|
+
sshdDir: import_node_path63.default.join(config.dataDir, "sshd"),
|
|
59424
59499
|
contactSshLog: sshLog,
|
|
59425
59500
|
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
59426
59501
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
@@ -59511,11 +59586,11 @@ async function startDaemon(config) {
|
|
|
59511
59586
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
59512
59587
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
59513
59588
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
59514
|
-
appBuilderPersonaRoot:
|
|
59589
|
+
appBuilderPersonaRoot: import_node_path63.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
59515
59590
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59516
|
-
deployKitRoot:
|
|
59591
|
+
deployKitRoot: import_node_path63.default.join(config.dataDir, "deploy-kit"),
|
|
59517
59592
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59518
|
-
resolvePersonaRoot: (personaId) =>
|
|
59593
|
+
resolvePersonaRoot: (personaId) => import_node_path63.default.join(config.dataDir, "personas", personaId),
|
|
59519
59594
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59520
59595
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59521
59596
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59558,7 +59633,7 @@ async function startDaemon(config) {
|
|
|
59558
59633
|
}
|
|
59559
59634
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
59560
59635
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
59561
|
-
sourceJsonlPath =
|
|
59636
|
+
sourceJsonlPath = import_node_path63.default.join(
|
|
59562
59637
|
import_node_os21.default.homedir(),
|
|
59563
59638
|
".claude",
|
|
59564
59639
|
"projects",
|
|
@@ -59888,8 +59963,8 @@ async function startDaemon(config) {
|
|
|
59888
59963
|
const lines = [
|
|
59889
59964
|
`Tunnel: ${r.url}`,
|
|
59890
59965
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
59891
|
-
`Frpc config: ${
|
|
59892
|
-
`Frpc log: ${
|
|
59966
|
+
`Frpc config: ${import_node_path63.default.join(config.dataDir, "frpc.toml")}`,
|
|
59967
|
+
`Frpc log: ${import_node_path63.default.join(config.dataDir, "frpc.log")}`
|
|
59893
59968
|
];
|
|
59894
59969
|
const width = Math.max(...lines.map((l) => l.length));
|
|
59895
59970
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -59902,8 +59977,8 @@ ${bar}
|
|
|
59902
59977
|
|
|
59903
59978
|
`);
|
|
59904
59979
|
try {
|
|
59905
|
-
const connectPath =
|
|
59906
|
-
|
|
59980
|
+
const connectPath = import_node_path63.default.join(config.dataDir, "connect.txt");
|
|
59981
|
+
import_node_fs50.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
59907
59982
|
} catch {
|
|
59908
59983
|
}
|
|
59909
59984
|
} catch (err) {
|
|
@@ -59937,7 +60012,7 @@ ${bar}
|
|
|
59937
60012
|
});
|
|
59938
60013
|
try {
|
|
59939
60014
|
await sshdMgr.start();
|
|
59940
|
-
rebuildAuthorizedKeys(contactStore,
|
|
60015
|
+
rebuildAuthorizedKeys(contactStore, import_node_path63.default.join(config.dataDir, "sshd"));
|
|
59941
60016
|
logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
|
|
59942
60017
|
} catch (err) {
|
|
59943
60018
|
logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
|
|
@@ -60005,9 +60080,9 @@ ${bar}
|
|
|
60005
60080
|
};
|
|
60006
60081
|
}
|
|
60007
60082
|
function migrateDropPersonsDir(dataDir) {
|
|
60008
|
-
const dir =
|
|
60083
|
+
const dir = import_node_path63.default.join(dataDir, "persons");
|
|
60009
60084
|
try {
|
|
60010
|
-
|
|
60085
|
+
import_node_fs50.default.rmSync(dir, { recursive: true, force: true });
|
|
60011
60086
|
} catch {
|
|
60012
60087
|
}
|
|
60013
60088
|
}
|