@clawos-dev/clawd 0.2.204 → 0.2.205-beta.409.d6f7a21
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 +372 -441
- 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: path76, errorMaps, issueData } = params;
|
|
746
|
+
const fullPath = [...path76, ...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, path76, key) {
|
|
1058
1058
|
this._cachedPath = [];
|
|
1059
1059
|
this.parent = parent;
|
|
1060
1060
|
this.data = value;
|
|
1061
|
-
this._path =
|
|
1061
|
+
this._path = path76;
|
|
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 path76 = req.path;
|
|
6453
|
+
_req.url = typeof path76 === "string" ? path76 : 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(path76) {
|
|
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 < path76.length; i++) {
|
|
6625
|
+
const char = path76[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 path76 of paths) {
|
|
6757
|
+
const parts = parsePath(path76);
|
|
6758
6758
|
if (parts.includes("*")) {
|
|
6759
|
-
redactWildcardPath(obj, parts, censor,
|
|
6759
|
+
redactWildcardPath(obj, parts, censor, path76, 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, path76) => {
|
|
6845
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path76];
|
|
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 path76 of pathsToClone) {
|
|
6881
|
+
const parts = parsePath(path76);
|
|
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(path76) {
|
|
6934
|
+
if (typeof path76 !== "string") {
|
|
6935
6935
|
throw new Error("Paths must be (non-empty) strings");
|
|
6936
6936
|
}
|
|
6937
|
-
if (
|
|
6937
|
+
if (path76 === "") {
|
|
6938
6938
|
throw new Error("Invalid redaction path ()");
|
|
6939
6939
|
}
|
|
6940
|
-
if (
|
|
6941
|
-
throw new Error(`Invalid redaction path (${
|
|
6940
|
+
if (path76.includes("..")) {
|
|
6941
|
+
throw new Error(`Invalid redaction path (${path76})`);
|
|
6942
6942
|
}
|
|
6943
|
-
if (
|
|
6944
|
-
throw new Error(`Invalid redaction path (${
|
|
6943
|
+
if (path76.includes(",")) {
|
|
6944
|
+
throw new Error(`Invalid redaction path (${path76})`);
|
|
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 < path76.length; i++) {
|
|
6950
|
+
const char = path76[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 (${path76})`);
|
|
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 (${path76})`);
|
|
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 path76 of paths) {
|
|
6977
|
+
validatePath(path76);
|
|
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, path76) => {
|
|
7146
|
+
return censor(value, [k2, ...path76]);
|
|
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 fs69 = require("fs");
|
|
7365
7365
|
var EventEmitter3 = require("events");
|
|
7366
7366
|
var inherits = require("util").inherits;
|
|
7367
|
-
var
|
|
7367
|
+
var path76 = 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) fs69.mkdirSync(path76.dirname(file), { recursive: true });
|
|
7422
|
+
const fd = fs69.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
|
+
fs69.mkdir(path76.dirname(file), { recursive: true }, (err) => {
|
|
7430
7430
|
if (err) return fileOpened(err);
|
|
7431
|
-
|
|
7431
|
+
fs69.open(file, flags, mode, fileOpened);
|
|
7432
7432
|
});
|
|
7433
7433
|
} else {
|
|
7434
|
-
|
|
7434
|
+
fs69.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 = () => fs69.writeSync(this.fd, this._writingBuf);
|
|
7476
|
+
fsWrite = () => fs69.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 fs69.writeSync(this.fd, this._writingBuf);
|
|
7486
7486
|
}
|
|
7487
|
-
return
|
|
7487
|
+
return fs69.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7488
7488
|
};
|
|
7489
7489
|
fsWrite = () => {
|
|
7490
7490
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7491
|
-
return
|
|
7491
|
+
return fs69.write(this.fd, this._writingBuf, this.release);
|
|
7492
7492
|
}
|
|
7493
|
-
return
|
|
7493
|
+
return fs69.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
|
+
fs69.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
|
+
fs69.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
|
+
fs69.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) ? fs69.writeSync(this.fd, buf) : fs69.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
|
+
fs69.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 = fs69.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) ? fs69.writeSync(this.fd, this._writingBuf) : fs69.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
|
+
fs69.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 = fs69.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
|
+
fs69.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
|
+
fs69.fsync(sonic.fd, closeWrapped);
|
|
7921
7921
|
} catch {
|
|
7922
7922
|
}
|
|
7923
7923
|
function closeWrapped() {
|
|
7924
7924
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
7925
|
-
|
|
7925
|
+
fs69.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(path76, added, removed, oldPosInc, options) {
|
|
11061
|
+
var last = path76.lastComponent;
|
|
11062
11062
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
11063
11063
|
return {
|
|
11064
|
-
oldPos:
|
|
11064
|
+
oldPos: path76.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: path76.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 path76 = 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 (!path76 || content == null) return null;
|
|
11543
|
+
const entry = { path: path76, 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 path76 = 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 (!path76 || content == null) return null;
|
|
12366
|
+
const out = { path: path76, 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(path76) {
|
|
33464
|
+
var parts = path76.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(path76) {
|
|
39318
|
+
if (path76.slice(-1) === "/") {
|
|
39319
|
+
path76 = path76.substring(0, path76.length - 1);
|
|
39320
39320
|
}
|
|
39321
|
-
var lastSlash =
|
|
39322
|
-
return lastSlash > 0 ?
|
|
39321
|
+
var lastSlash = path76.lastIndexOf("/");
|
|
39322
|
+
return lastSlash > 0 ? path76.substring(0, lastSlash) : "";
|
|
39323
39323
|
};
|
|
39324
|
-
var forceTrailingSlash = function(
|
|
39325
|
-
if (
|
|
39326
|
-
|
|
39324
|
+
var forceTrailingSlash = function(path76) {
|
|
39325
|
+
if (path76.slice(-1) !== "/") {
|
|
39326
|
+
path76 += "/";
|
|
39327
39327
|
}
|
|
39328
|
-
return
|
|
39328
|
+
return path76;
|
|
39329
39329
|
};
|
|
39330
39330
|
var folderAdd = function(name, createFolders) {
|
|
39331
39331
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40324,53 +40324,10 @@ 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
|
-
|
|
40370
40327
|
// src/run-case/recorder.ts
|
|
40371
40328
|
function startRunCaseRecorder(opts) {
|
|
40372
40329
|
const now = opts.now ?? Date.now;
|
|
40373
|
-
const dir =
|
|
40330
|
+
const dir = import_node_path63.default.dirname(opts.recordPath);
|
|
40374
40331
|
let stream = null;
|
|
40375
40332
|
let closing = false;
|
|
40376
40333
|
let closedSettled = false;
|
|
@@ -40384,8 +40341,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40384
40341
|
});
|
|
40385
40342
|
const ensureStream = () => {
|
|
40386
40343
|
if (stream) return stream;
|
|
40387
|
-
|
|
40388
|
-
stream =
|
|
40344
|
+
import_node_fs50.default.mkdirSync(dir, { recursive: true });
|
|
40345
|
+
stream = import_node_fs50.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40389
40346
|
stream.on("close", () => closedResolve());
|
|
40390
40347
|
return stream;
|
|
40391
40348
|
};
|
|
@@ -40410,12 +40367,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40410
40367
|
};
|
|
40411
40368
|
return { tap, close, closed };
|
|
40412
40369
|
}
|
|
40413
|
-
var
|
|
40370
|
+
var import_node_fs50, import_node_path63;
|
|
40414
40371
|
var init_recorder = __esm({
|
|
40415
40372
|
"src/run-case/recorder.ts"() {
|
|
40416
40373
|
"use strict";
|
|
40417
|
-
|
|
40418
|
-
|
|
40374
|
+
import_node_fs50 = __toESM(require("fs"), 1);
|
|
40375
|
+
import_node_path63 = __toESM(require("path"), 1);
|
|
40419
40376
|
}
|
|
40420
40377
|
});
|
|
40421
40378
|
|
|
@@ -40458,7 +40415,7 @@ var init_wire = __esm({
|
|
|
40458
40415
|
// src/run-case/controller.ts
|
|
40459
40416
|
async function runController(opts) {
|
|
40460
40417
|
const now = opts.now ?? Date.now;
|
|
40461
|
-
const cwd = opts.cwd ?? (0,
|
|
40418
|
+
const cwd = opts.cwd ?? (0, import_node_fs51.mkdtempSync)(import_node_path64.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
|
|
40462
40419
|
const ownsCwd = opts.cwd === void 0;
|
|
40463
40420
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40464
40421
|
const spawnCtx = { cwd };
|
|
@@ -40619,19 +40576,19 @@ async function runController(opts) {
|
|
|
40619
40576
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40620
40577
|
if (ownsCwd) {
|
|
40621
40578
|
try {
|
|
40622
|
-
(0,
|
|
40579
|
+
(0, import_node_fs51.rmSync)(cwd, { recursive: true, force: true });
|
|
40623
40580
|
} catch {
|
|
40624
40581
|
}
|
|
40625
40582
|
}
|
|
40626
40583
|
return exitCode ?? 0;
|
|
40627
40584
|
}
|
|
40628
|
-
var
|
|
40585
|
+
var import_node_fs51, import_node_os22, import_node_path64;
|
|
40629
40586
|
var init_controller = __esm({
|
|
40630
40587
|
"src/run-case/controller.ts"() {
|
|
40631
40588
|
"use strict";
|
|
40632
|
-
|
|
40589
|
+
import_node_fs51 = require("fs");
|
|
40633
40590
|
import_node_os22 = __toESM(require("os"), 1);
|
|
40634
|
-
|
|
40591
|
+
import_node_path64 = __toESM(require("path"), 1);
|
|
40635
40592
|
init_claude();
|
|
40636
40593
|
init_stdout_splitter();
|
|
40637
40594
|
init_permission_stdio();
|
|
@@ -40742,23 +40699,14 @@ async function sshRelay(argv) {
|
|
|
40742
40699
|
process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
|
|
40743
40700
|
return 2;
|
|
40744
40701
|
}
|
|
40745
|
-
const dataDir = args.dataDir ??
|
|
40746
|
-
const sshLog = createContactSshLog(dataDir);
|
|
40702
|
+
const dataDir = args.dataDir ?? import_node_path65.default.join(import_node_os23.default.homedir(), ".clawd");
|
|
40747
40703
|
const contact = findContact(dataDir, args.peerDeviceId);
|
|
40748
40704
|
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
|
-
});
|
|
40753
40705
|
process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
|
|
40754
40706
|
`);
|
|
40755
40707
|
return 2;
|
|
40756
40708
|
}
|
|
40757
40709
|
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
|
-
});
|
|
40762
40710
|
process.stderr.write(
|
|
40763
40711
|
`clawd ssh-relay: contact ${args.peerDeviceId} has no connectToken (auto-reverse \u672A\u6362\u7968)
|
|
40764
40712
|
`
|
|
@@ -40768,11 +40716,6 @@ async function sshRelay(argv) {
|
|
|
40768
40716
|
const baseHttp = wsUrlToHttp(contact.remoteUrl).replace(/\/+$/, "");
|
|
40769
40717
|
const wsBase = baseHttp.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
40770
40718
|
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
|
-
});
|
|
40776
40719
|
return new Promise((resolve6) => {
|
|
40777
40720
|
const ws = new import_websocket.default(url, {
|
|
40778
40721
|
headers: {
|
|
@@ -40792,9 +40735,6 @@ async function sshRelay(argv) {
|
|
|
40792
40735
|
resolve6(exitCode);
|
|
40793
40736
|
};
|
|
40794
40737
|
ws.on("open", () => {
|
|
40795
|
-
sshLog.info("relay.dial-open", "ws open\uFF0C\u8FDB\u5165 stdio \u2194 ws \u4E2D\u7EE7", {
|
|
40796
|
-
peerDeviceId: args.peerDeviceId
|
|
40797
|
-
});
|
|
40798
40738
|
process.stdin.on("data", (chunk) => {
|
|
40799
40739
|
if (ws.readyState === ws.OPEN) {
|
|
40800
40740
|
ws.send(chunk, { binary: true });
|
|
@@ -40819,25 +40759,9 @@ async function sshRelay(argv) {
|
|
|
40819
40759
|
}
|
|
40820
40760
|
});
|
|
40821
40761
|
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
|
-
}
|
|
40833
40762
|
settle(code === 1e3 ? 0 : 1);
|
|
40834
40763
|
});
|
|
40835
40764
|
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
|
-
});
|
|
40841
40765
|
process.stderr.write(`clawd ssh-relay: ws error ${err.message}
|
|
40842
40766
|
`);
|
|
40843
40767
|
settle(1);
|
|
@@ -40869,10 +40793,10 @@ function parseSshRelayArgs(argv) {
|
|
|
40869
40793
|
return out;
|
|
40870
40794
|
}
|
|
40871
40795
|
function findContact(dataDir, deviceId) {
|
|
40872
|
-
const file =
|
|
40796
|
+
const file = import_node_path65.default.join(dataDir, "contacts.json");
|
|
40873
40797
|
let raw;
|
|
40874
40798
|
try {
|
|
40875
|
-
raw =
|
|
40799
|
+
raw = import_node_fs52.default.readFileSync(file, "utf8");
|
|
40876
40800
|
} catch {
|
|
40877
40801
|
return null;
|
|
40878
40802
|
}
|
|
@@ -40890,17 +40814,16 @@ function findContact(dataDir, deviceId) {
|
|
|
40890
40814
|
}
|
|
40891
40815
|
return null;
|
|
40892
40816
|
}
|
|
40893
|
-
var
|
|
40817
|
+
var import_node_fs52, import_node_os23, import_node_path65, SSH_RELAY_HELP;
|
|
40894
40818
|
var init_sshd_cli_relay = __esm({
|
|
40895
40819
|
"src/sshd/sshd-cli-relay.ts"() {
|
|
40896
40820
|
"use strict";
|
|
40897
|
-
|
|
40821
|
+
import_node_fs52 = __toESM(require("fs"), 1);
|
|
40898
40822
|
import_node_os23 = __toESM(require("os"), 1);
|
|
40899
|
-
|
|
40823
|
+
import_node_path65 = __toESM(require("path"), 1);
|
|
40900
40824
|
init_wrapper();
|
|
40901
40825
|
init_src();
|
|
40902
40826
|
init_peer_forward();
|
|
40903
|
-
init_contact_ssh_log();
|
|
40904
40827
|
SSH_RELAY_HELP = `clawd ssh-relay <peer-device-id> [options]
|
|
40905
40828
|
|
|
40906
40829
|
WebSocket relay to a peer daemon's /rpc/ssh-tunnel, exposing raw SSH bytes on
|
|
@@ -41100,8 +41023,8 @@ Env (advanced):
|
|
|
41100
41023
|
`;
|
|
41101
41024
|
|
|
41102
41025
|
// src/index.ts
|
|
41103
|
-
var
|
|
41104
|
-
var
|
|
41026
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
41027
|
+
var import_node_fs49 = __toESM(require("fs"), 1);
|
|
41105
41028
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
41106
41029
|
|
|
41107
41030
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -41815,7 +41738,9 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
41815
41738
|
fsv.allowRead = unionArr(fsv.allowRead, [
|
|
41816
41739
|
"~/.clawd/contact-ssh-keys",
|
|
41817
41740
|
"~/.clawd/contacts.json",
|
|
41818
|
-
"
|
|
41741
|
+
"~/Library/Application Support/@clawos/clawd-desktop/ota-bundles",
|
|
41742
|
+
"~/.clawd/config.json",
|
|
41743
|
+
"~/.clawd/auth.json"
|
|
41819
41744
|
]);
|
|
41820
41745
|
return s;
|
|
41821
41746
|
}
|
|
@@ -41966,14 +41891,12 @@ var CONTACT_SSH_SYSTEM_PROMPT_HINT = `## \u8DE8\u8BBE\u5907\u6587\u4EF6\u8BBF\u9
|
|
|
41966
41891
|
\uFF08\u6BCF\u4E2A \`<deviceId>.ed25519\` \u5C31\u662F\u4E00\u628A privkey\uFF0C\u53BB\u6389\u540E\u7F00\u5C31\u662F deviceId\uFF09
|
|
41967
41892
|
2. \u7528 SSH \u62E8\u53F7\uFF08\u628A \`<A>\` \u6362\u6210\u5B9E\u9645 deviceId\uFF09\uFF1A
|
|
41968
41893
|
\`\`\`bash
|
|
41969
|
-
ssh -o ProxyCommand='
|
|
41894
|
+
ssh -o ProxyCommand='clawd ssh-relay <A>' \\
|
|
41970
41895
|
-i ~/.clawd/contact-ssh-keys/<A>.ed25519 \\
|
|
41971
41896
|
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \\
|
|
41972
41897
|
$USER@127.0.0.1 <command>
|
|
41973
41898
|
# \u4F8B\u5982\uFF1A... $USER@127.0.0.1 cat /Users/xxx/some/file.md
|
|
41974
41899
|
# ... $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
|
|
41977
41900
|
\`\`\`
|
|
41978
41901
|
|
|
41979
41902
|
**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
|
|
@@ -46643,8 +46566,8 @@ function turnStartInput(text) {
|
|
|
46643
46566
|
const items = [];
|
|
46644
46567
|
let leftover = text;
|
|
46645
46568
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46646
|
-
const [marker, name,
|
|
46647
|
-
items.push({ type: "skill", name, path:
|
|
46569
|
+
const [marker, name, path76] = m2;
|
|
46570
|
+
items.push({ type: "skill", name, path: path76 });
|
|
46648
46571
|
leftover = leftover.replace(marker, "");
|
|
46649
46572
|
}
|
|
46650
46573
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -49098,13 +49021,13 @@ function mapSkillsListResponse(res) {
|
|
|
49098
49021
|
const r = s ?? {};
|
|
49099
49022
|
const name = str3(r.name);
|
|
49100
49023
|
if (!name) continue;
|
|
49101
|
-
const
|
|
49024
|
+
const path76 = str3(r.path);
|
|
49102
49025
|
const description = str3(r.description);
|
|
49103
49026
|
const isPlugin = name.includes(":");
|
|
49104
49027
|
out.push({
|
|
49105
49028
|
name,
|
|
49106
49029
|
source: isPlugin ? "plugin" : "project",
|
|
49107
|
-
...
|
|
49030
|
+
...path76 ? { path: path76 } : {},
|
|
49108
49031
|
...description ? { description } : {},
|
|
49109
49032
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
49110
49033
|
});
|
|
@@ -53076,8 +52999,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
53076
52999
|
}
|
|
53077
53000
|
|
|
53078
53001
|
// src/sshd/sshd-manager.ts
|
|
53079
|
-
var
|
|
53080
|
-
var
|
|
53002
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
53003
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
53081
53004
|
var import_node_child_process11 = require("child_process");
|
|
53082
53005
|
|
|
53083
53006
|
// src/sshd/sshd-config.ts
|
|
@@ -53360,35 +53283,11 @@ function ensureJailScript(dataDir) {
|
|
|
53360
53283
|
return target;
|
|
53361
53284
|
}
|
|
53362
53285
|
|
|
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
|
-
|
|
53387
53286
|
// src/sshd/sshd-manager.ts
|
|
53388
53287
|
var SshdManager = class {
|
|
53389
53288
|
constructor(deps) {
|
|
53390
53289
|
this.deps = deps;
|
|
53391
|
-
this.sshdDir =
|
|
53290
|
+
this.sshdDir = import_node_path37.default.join(deps.dataDir, "sshd");
|
|
53392
53291
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
53393
53292
|
}
|
|
53394
53293
|
deps;
|
|
@@ -53407,32 +53306,31 @@ var SshdManager = class {
|
|
|
53407
53306
|
ownPid: process.pid,
|
|
53408
53307
|
logger
|
|
53409
53308
|
});
|
|
53410
|
-
|
|
53411
|
-
|
|
53309
|
+
import_node_fs36.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
|
|
53310
|
+
import_node_fs36.default.mkdirSync(import_node_path37.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
|
|
53412
53311
|
ensureJailScript(this.deps.dataDir);
|
|
53413
|
-
|
|
53414
|
-
|
|
53415
|
-
if (!import_node_fs37.default.existsSync(hostKeyPath)) {
|
|
53312
|
+
const hostKeyPath = import_node_path37.default.join(this.sshdDir, "host_key");
|
|
53313
|
+
if (!import_node_fs36.default.existsSync(hostKeyPath)) {
|
|
53416
53314
|
await this.generateHostKey(hostKeyPath);
|
|
53417
53315
|
}
|
|
53418
|
-
const akFile =
|
|
53419
|
-
if (!
|
|
53420
|
-
|
|
53316
|
+
const akFile = import_node_path37.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
|
|
53317
|
+
if (!import_node_fs36.default.existsSync(akFile)) {
|
|
53318
|
+
import_node_fs36.default.writeFileSync(akFile, "", { mode: 384 });
|
|
53421
53319
|
}
|
|
53422
|
-
const configPath =
|
|
53320
|
+
const configPath = import_node_path37.default.join(this.sshdDir, "sshd_config");
|
|
53423
53321
|
const config = buildSshdConfig({
|
|
53424
53322
|
listenAddress: "127.0.0.1",
|
|
53425
53323
|
port: this.deps.port,
|
|
53426
53324
|
hostKeyPath,
|
|
53427
53325
|
authorizedKeysFile: akFile,
|
|
53428
|
-
pidFilePath:
|
|
53326
|
+
pidFilePath: import_node_path37.default.join(this.sshdDir, "sshd.pid")
|
|
53429
53327
|
});
|
|
53430
|
-
|
|
53328
|
+
import_node_fs36.default.writeFileSync(configPath, config, { mode: 384 });
|
|
53431
53329
|
const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
|
|
53432
53330
|
const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
|
|
53433
53331
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53434
53332
|
});
|
|
53435
|
-
const logStream =
|
|
53333
|
+
const logStream = import_node_fs36.default.createWriteStream(import_node_path37.default.join(this.sshdDir, "sshd.log"), {
|
|
53436
53334
|
flags: "a",
|
|
53437
53335
|
mode: 384
|
|
53438
53336
|
});
|
|
@@ -53525,7 +53423,7 @@ ${tail}` : ready.error;
|
|
|
53525
53423
|
p2.on("error", reject);
|
|
53526
53424
|
});
|
|
53527
53425
|
try {
|
|
53528
|
-
|
|
53426
|
+
import_node_fs36.default.chmodSync(hostKeyPath, 384);
|
|
53529
53427
|
} catch {
|
|
53530
53428
|
}
|
|
53531
53429
|
}
|
|
@@ -53568,17 +53466,17 @@ async function waitForSshdReady(proc, timeoutMs) {
|
|
|
53568
53466
|
}
|
|
53569
53467
|
|
|
53570
53468
|
// src/sshd/authorized-keys.ts
|
|
53571
|
-
var
|
|
53572
|
-
var
|
|
53469
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53470
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
53573
53471
|
var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
|
|
53574
53472
|
var AUTHORIZED_KEYS_FILE = "clawd-contacts";
|
|
53575
53473
|
function jailBinPath() {
|
|
53576
|
-
return process.env[JAIL_BIN_PATH_ENV] ??
|
|
53474
|
+
return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path38.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
|
|
53577
53475
|
}
|
|
53578
53476
|
function rebuildAuthorizedKeys(store, sshdDir) {
|
|
53579
|
-
const akDir =
|
|
53580
|
-
const target =
|
|
53581
|
-
|
|
53477
|
+
const akDir = import_node_path38.default.join(sshdDir, "authorized_keys.d");
|
|
53478
|
+
const target = import_node_path38.default.join(akDir, AUTHORIZED_KEYS_FILE);
|
|
53479
|
+
import_node_fs37.default.mkdirSync(akDir, { recursive: true, mode: 448 });
|
|
53582
53480
|
const lines = ["# managed by clawd; do not edit", ""];
|
|
53583
53481
|
for (const c of store.list()) {
|
|
53584
53482
|
if (!c.sshAllowed) continue;
|
|
@@ -53592,28 +53490,66 @@ function rebuildAuthorizedKeys(store, sshdDir) {
|
|
|
53592
53490
|
}
|
|
53593
53491
|
const body = lines.join("\n") + "\n";
|
|
53594
53492
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
53595
|
-
|
|
53596
|
-
|
|
53493
|
+
import_node_fs37.default.writeFileSync(tmp, body, { mode: 384 });
|
|
53494
|
+
import_node_fs37.default.renameSync(tmp, target);
|
|
53597
53495
|
}
|
|
53598
53496
|
function readIssuedPubkey(sshdDir, deviceId) {
|
|
53599
53497
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53600
|
-
const p2 =
|
|
53498
|
+
const p2 = import_node_path38.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
|
|
53601
53499
|
try {
|
|
53602
|
-
return
|
|
53500
|
+
return import_node_fs37.default.readFileSync(p2, "utf8");
|
|
53603
53501
|
} catch {
|
|
53604
53502
|
return null;
|
|
53605
53503
|
}
|
|
53606
53504
|
}
|
|
53607
53505
|
|
|
53608
53506
|
// src/sshd/contact-key-puller.ts
|
|
53609
|
-
var
|
|
53610
|
-
var
|
|
53507
|
+
var import_node_fs39 = __toESM(require("fs"), 1);
|
|
53508
|
+
var import_node_path40 = __toESM(require("path"), 1);
|
|
53611
53509
|
init_peer_forward();
|
|
53612
|
-
|
|
53510
|
+
|
|
53511
|
+
// src/sshd/contact-ssh-log.ts
|
|
53512
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53513
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53514
|
+
function createContactSshLog(dataDir) {
|
|
53515
|
+
const file = import_node_path39.default.join(dataDir, "contact-ssh.log");
|
|
53516
|
+
function append(level, tag, message, meta) {
|
|
53517
|
+
const time = (/* @__PURE__ */ new Date()).toISOString();
|
|
53518
|
+
let line = `[${time}] [${level}] [${tag}] ${message}`;
|
|
53519
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
53520
|
+
try {
|
|
53521
|
+
line += " " + JSON.stringify(meta);
|
|
53522
|
+
} catch {
|
|
53523
|
+
line += " [meta-serialize-failed]";
|
|
53524
|
+
}
|
|
53525
|
+
}
|
|
53526
|
+
line += "\n";
|
|
53527
|
+
try {
|
|
53528
|
+
import_node_fs38.default.mkdirSync(import_node_path39.default.dirname(file), { recursive: true });
|
|
53529
|
+
import_node_fs38.default.appendFileSync(file, line, { mode: 384 });
|
|
53530
|
+
} catch {
|
|
53531
|
+
}
|
|
53532
|
+
}
|
|
53533
|
+
return {
|
|
53534
|
+
info: (tag, message, meta) => append("INFO", tag, message, meta),
|
|
53535
|
+
warn: (tag, message, meta) => append("WARN", tag, message, meta),
|
|
53536
|
+
error: (tag, message, meta) => append("ERROR", tag, message, meta)
|
|
53537
|
+
};
|
|
53538
|
+
}
|
|
53539
|
+
var nullContactSshLog = {
|
|
53540
|
+
info: () => {
|
|
53541
|
+
},
|
|
53542
|
+
warn: () => {
|
|
53543
|
+
},
|
|
53544
|
+
error: () => {
|
|
53545
|
+
}
|
|
53546
|
+
};
|
|
53547
|
+
|
|
53548
|
+
// src/sshd/contact-key-puller.ts
|
|
53613
53549
|
var CONTACT_KEYS_DIR = "contact-ssh-keys";
|
|
53614
53550
|
function safeContactKeyPath(dataDir, deviceId) {
|
|
53615
53551
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53616
|
-
return
|
|
53552
|
+
return import_node_path40.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
|
|
53617
53553
|
}
|
|
53618
53554
|
async function pullContactSshKeyOnce(deps) {
|
|
53619
53555
|
const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
|
|
@@ -53679,12 +53615,12 @@ async function pullContactSshKeyOnce(deps) {
|
|
|
53679
53615
|
}
|
|
53680
53616
|
function writeKeyFile(dataDir, deviceId, pem) {
|
|
53681
53617
|
const p2 = safeContactKeyPath(dataDir, deviceId);
|
|
53682
|
-
|
|
53683
|
-
|
|
53618
|
+
import_node_fs39.default.mkdirSync(import_node_path40.default.dirname(p2), { recursive: true, mode: 448 });
|
|
53619
|
+
import_node_fs39.default.writeFileSync(p2, pem, { mode: 384 });
|
|
53684
53620
|
}
|
|
53685
53621
|
function removeKeyFile(dataDir, deviceId) {
|
|
53686
53622
|
try {
|
|
53687
|
-
|
|
53623
|
+
import_node_fs39.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
|
|
53688
53624
|
return true;
|
|
53689
53625
|
} catch {
|
|
53690
53626
|
return false;
|
|
@@ -53721,7 +53657,6 @@ var ContactKeyPuller = class {
|
|
|
53721
53657
|
|
|
53722
53658
|
// src/sshd/ssh-tunnel-relay.ts
|
|
53723
53659
|
var import_node_net2 = __toESM(require("net"), 1);
|
|
53724
|
-
init_contact_ssh_log();
|
|
53725
53660
|
async function handleSshTunnelUpgrade(req, socket, head, deps) {
|
|
53726
53661
|
const sshLog = deps.sshLog ?? nullContactSshLog;
|
|
53727
53662
|
const clientAddr = (req.socket && "remoteAddress" in req.socket ? req.socket.remoteAddress : null) ?? "unknown";
|
|
@@ -53829,32 +53764,29 @@ function pumpWsToSshd(ws, deps, clientAddr) {
|
|
|
53829
53764
|
});
|
|
53830
53765
|
}
|
|
53831
53766
|
|
|
53832
|
-
// src/index.ts
|
|
53833
|
-
init_contact_ssh_log();
|
|
53834
|
-
|
|
53835
53767
|
// src/tunnel/device-key.ts
|
|
53836
53768
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
53837
|
-
var
|
|
53769
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
53838
53770
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
53839
53771
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
53840
53772
|
function deriveStableDeviceKey(opts = {}) {
|
|
53841
53773
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
53842
53774
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
53843
53775
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
53844
|
-
const defaultDataDir =
|
|
53845
|
-
const normalizedDataDir = opts.dataDir ?
|
|
53776
|
+
const defaultDataDir = import_node_path41.default.resolve(import_node_path41.default.join(home, ".clawd"));
|
|
53777
|
+
const normalizedDataDir = opts.dataDir ? import_node_path41.default.resolve(opts.dataDir) : null;
|
|
53846
53778
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
53847
53779
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
53848
53780
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
53849
53781
|
}
|
|
53850
53782
|
|
|
53851
53783
|
// src/auth-store.ts
|
|
53852
|
-
var
|
|
53853
|
-
var
|
|
53784
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
53785
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
53854
53786
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
53855
53787
|
var AUTH_FILE_NAME = "auth.json";
|
|
53856
53788
|
function authFilePath(dataDir) {
|
|
53857
|
-
return
|
|
53789
|
+
return import_node_path42.default.join(dataDir, AUTH_FILE_NAME);
|
|
53858
53790
|
}
|
|
53859
53791
|
function loadOrCreateAuthFile(opts) {
|
|
53860
53792
|
const file = authFilePath(opts.dataDir);
|
|
@@ -53890,7 +53822,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
53890
53822
|
}
|
|
53891
53823
|
function readAuthFile(file) {
|
|
53892
53824
|
try {
|
|
53893
|
-
const raw =
|
|
53825
|
+
const raw = import_node_fs40.default.readFileSync(file, "utf8");
|
|
53894
53826
|
const parsed = JSON.parse(raw);
|
|
53895
53827
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
53896
53828
|
return null;
|
|
@@ -53910,25 +53842,25 @@ function readAuthFile(file) {
|
|
|
53910
53842
|
}
|
|
53911
53843
|
}
|
|
53912
53844
|
function writeAuthFile(file, content) {
|
|
53913
|
-
|
|
53914
|
-
|
|
53845
|
+
import_node_fs40.default.mkdirSync(import_node_path42.default.dirname(file), { recursive: true });
|
|
53846
|
+
import_node_fs40.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
53915
53847
|
try {
|
|
53916
|
-
|
|
53848
|
+
import_node_fs40.default.chmodSync(file, 384);
|
|
53917
53849
|
} catch {
|
|
53918
53850
|
}
|
|
53919
53851
|
}
|
|
53920
53852
|
|
|
53921
53853
|
// src/owner-profile.ts
|
|
53922
|
-
var
|
|
53854
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
53923
53855
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
53924
|
-
var
|
|
53856
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
53925
53857
|
var PROFILE_FILENAME = "profile.json";
|
|
53926
53858
|
function loadOwnerDisplayName(dataDir) {
|
|
53927
53859
|
const fallback = import_node_os15.default.userInfo().username;
|
|
53928
|
-
const profilePath =
|
|
53860
|
+
const profilePath = import_node_path43.default.join(dataDir, PROFILE_FILENAME);
|
|
53929
53861
|
let raw;
|
|
53930
53862
|
try {
|
|
53931
|
-
raw =
|
|
53863
|
+
raw = import_node_fs41.default.readFileSync(profilePath, "utf8");
|
|
53932
53864
|
} catch {
|
|
53933
53865
|
return fallback;
|
|
53934
53866
|
}
|
|
@@ -53951,18 +53883,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
53951
53883
|
}
|
|
53952
53884
|
|
|
53953
53885
|
// src/feishu-auth/owner-identity-store.ts
|
|
53954
|
-
var
|
|
53955
|
-
var
|
|
53886
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
53887
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
53956
53888
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
53957
53889
|
var OwnerIdentityStore = class {
|
|
53958
53890
|
file;
|
|
53959
53891
|
constructor(dataDir) {
|
|
53960
|
-
this.file =
|
|
53892
|
+
this.file = import_node_path44.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
53961
53893
|
}
|
|
53962
53894
|
read() {
|
|
53963
53895
|
let raw;
|
|
53964
53896
|
try {
|
|
53965
|
-
raw =
|
|
53897
|
+
raw = import_node_fs42.default.readFileSync(this.file, "utf8");
|
|
53966
53898
|
} catch {
|
|
53967
53899
|
return null;
|
|
53968
53900
|
}
|
|
@@ -53990,16 +53922,16 @@ var OwnerIdentityStore = class {
|
|
|
53990
53922
|
};
|
|
53991
53923
|
}
|
|
53992
53924
|
write(record) {
|
|
53993
|
-
|
|
53994
|
-
|
|
53925
|
+
import_node_fs42.default.mkdirSync(import_node_path44.default.dirname(this.file), { recursive: true });
|
|
53926
|
+
import_node_fs42.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
53995
53927
|
try {
|
|
53996
|
-
|
|
53928
|
+
import_node_fs42.default.chmodSync(this.file, 384);
|
|
53997
53929
|
} catch {
|
|
53998
53930
|
}
|
|
53999
53931
|
}
|
|
54000
53932
|
clear() {
|
|
54001
53933
|
try {
|
|
54002
|
-
|
|
53934
|
+
import_node_fs42.default.unlinkSync(this.file);
|
|
54003
53935
|
} catch (err) {
|
|
54004
53936
|
const code = err?.code;
|
|
54005
53937
|
if (code !== "ENOENT") throw err;
|
|
@@ -54120,9 +54052,9 @@ var CentralClientError = class extends Error {
|
|
|
54120
54052
|
code;
|
|
54121
54053
|
cause;
|
|
54122
54054
|
};
|
|
54123
|
-
async function centralRequest(opts,
|
|
54055
|
+
async function centralRequest(opts, path76, init) {
|
|
54124
54056
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
54125
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
54057
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path76}`;
|
|
54126
54058
|
const ctrl = new AbortController();
|
|
54127
54059
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
54128
54060
|
let res;
|
|
@@ -54264,8 +54196,8 @@ function verifyConnectToken(args) {
|
|
|
54264
54196
|
}
|
|
54265
54197
|
|
|
54266
54198
|
// src/feishu-auth/server-key.ts
|
|
54267
|
-
var
|
|
54268
|
-
var
|
|
54199
|
+
var fs52 = __toESM(require("fs"), 1);
|
|
54200
|
+
var path53 = __toESM(require("path"), 1);
|
|
54269
54201
|
var FILE_NAME2 = "server-signing-key.json";
|
|
54270
54202
|
var ServerKeyStore = class {
|
|
54271
54203
|
constructor(dataDir) {
|
|
@@ -54273,12 +54205,12 @@ var ServerKeyStore = class {
|
|
|
54273
54205
|
}
|
|
54274
54206
|
dataDir;
|
|
54275
54207
|
filePath() {
|
|
54276
|
-
return
|
|
54208
|
+
return path53.join(this.dataDir, FILE_NAME2);
|
|
54277
54209
|
}
|
|
54278
54210
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
54279
54211
|
read() {
|
|
54280
54212
|
try {
|
|
54281
|
-
const raw =
|
|
54213
|
+
const raw = fs52.readFileSync(this.filePath(), "utf8");
|
|
54282
54214
|
const parsed = JSON.parse(raw);
|
|
54283
54215
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
54284
54216
|
return parsed.publicKeyPem;
|
|
@@ -54293,12 +54225,12 @@ var ServerKeyStore = class {
|
|
|
54293
54225
|
publicKeyPem,
|
|
54294
54226
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54295
54227
|
};
|
|
54296
|
-
|
|
54297
|
-
|
|
54228
|
+
fs52.mkdirSync(this.dataDir, { recursive: true });
|
|
54229
|
+
fs52.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
54298
54230
|
}
|
|
54299
54231
|
clear() {
|
|
54300
54232
|
try {
|
|
54301
|
-
|
|
54233
|
+
fs52.unlinkSync(this.filePath());
|
|
54302
54234
|
} catch {
|
|
54303
54235
|
}
|
|
54304
54236
|
}
|
|
@@ -54311,12 +54243,12 @@ init_protocol();
|
|
|
54311
54243
|
init_protocol();
|
|
54312
54244
|
|
|
54313
54245
|
// src/session/fork.ts
|
|
54314
|
-
var
|
|
54246
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
54315
54247
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
54316
|
-
var
|
|
54248
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54317
54249
|
init_claude_history();
|
|
54318
54250
|
function readJsonlEntries(file) {
|
|
54319
|
-
const raw =
|
|
54251
|
+
const raw = import_node_fs43.default.readFileSync(file, "utf8");
|
|
54320
54252
|
const out = [];
|
|
54321
54253
|
for (const line of raw.split("\n")) {
|
|
54322
54254
|
const t = line.trim();
|
|
@@ -54329,10 +54261,10 @@ function readJsonlEntries(file) {
|
|
|
54329
54261
|
return out;
|
|
54330
54262
|
}
|
|
54331
54263
|
function forkSession(input) {
|
|
54332
|
-
const baseDir = input.baseDir ??
|
|
54333
|
-
const projectDir =
|
|
54334
|
-
const sourceFile =
|
|
54335
|
-
if (!
|
|
54264
|
+
const baseDir = input.baseDir ?? import_node_path45.default.join(import_node_os16.default.homedir(), ".claude");
|
|
54265
|
+
const projectDir = import_node_path45.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
54266
|
+
const sourceFile = import_node_path45.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
54267
|
+
if (!import_node_fs43.default.existsSync(sourceFile)) {
|
|
54336
54268
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
54337
54269
|
}
|
|
54338
54270
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -54362,9 +54294,9 @@ function forkSession(input) {
|
|
|
54362
54294
|
}
|
|
54363
54295
|
forkedLines.push(JSON.stringify(forked));
|
|
54364
54296
|
}
|
|
54365
|
-
const forkedFilePath =
|
|
54366
|
-
|
|
54367
|
-
|
|
54297
|
+
const forkedFilePath = import_node_path45.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
54298
|
+
import_node_fs43.default.mkdirSync(projectDir, { recursive: true });
|
|
54299
|
+
import_node_fs43.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
54368
54300
|
return { forkedToolSessionId, forkedFilePath };
|
|
54369
54301
|
}
|
|
54370
54302
|
|
|
@@ -54716,7 +54648,7 @@ function buildPermissionHandlers(deps) {
|
|
|
54716
54648
|
}
|
|
54717
54649
|
|
|
54718
54650
|
// src/handlers/history.ts
|
|
54719
|
-
var
|
|
54651
|
+
var path56 = __toESM(require("path"), 1);
|
|
54720
54652
|
init_protocol();
|
|
54721
54653
|
|
|
54722
54654
|
// src/session/recent-dirs.ts
|
|
@@ -54734,7 +54666,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
54734
54666
|
}
|
|
54735
54667
|
|
|
54736
54668
|
// src/permission/persona-paths.ts
|
|
54737
|
-
var
|
|
54669
|
+
var path55 = __toESM(require("path"), 1);
|
|
54738
54670
|
function getAllowedPersonaIds(grants, action) {
|
|
54739
54671
|
const ids = /* @__PURE__ */ new Set();
|
|
54740
54672
|
for (const g2 of grants) {
|
|
@@ -54747,42 +54679,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
54747
54679
|
return ids;
|
|
54748
54680
|
}
|
|
54749
54681
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
54750
|
-
const target =
|
|
54682
|
+
const target = path55.resolve(absPath);
|
|
54751
54683
|
if (userWorkDir) {
|
|
54752
|
-
const u =
|
|
54753
|
-
const usep = u.endsWith(
|
|
54684
|
+
const u = path55.resolve(userWorkDir);
|
|
54685
|
+
const usep = u.endsWith(path55.sep) ? "" : path55.sep;
|
|
54754
54686
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
54755
54687
|
}
|
|
54756
|
-
const root =
|
|
54757
|
-
const sep3 = root.endsWith(
|
|
54688
|
+
const root = path55.resolve(personaRoot);
|
|
54689
|
+
const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
|
|
54758
54690
|
if (!target.startsWith(root + sep3)) return false;
|
|
54759
|
-
const rel =
|
|
54691
|
+
const rel = path55.relative(root, target);
|
|
54760
54692
|
if (!rel || rel.startsWith("..")) return false;
|
|
54761
|
-
const personaId = rel.split(
|
|
54693
|
+
const personaId = rel.split(path55.sep)[0];
|
|
54762
54694
|
if (!personaId) return false;
|
|
54763
54695
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54764
54696
|
if (allowed === "*") return true;
|
|
54765
54697
|
return allowed.has(personaId);
|
|
54766
54698
|
}
|
|
54767
54699
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54768
|
-
const root =
|
|
54769
|
-
const target =
|
|
54770
|
-
const sep3 = root.endsWith(
|
|
54700
|
+
const root = path55.resolve(personaRoot);
|
|
54701
|
+
const target = path55.resolve(absPath);
|
|
54702
|
+
const sep3 = root.endsWith(path55.sep) ? "" : path55.sep;
|
|
54771
54703
|
if (!target.startsWith(root + sep3)) return null;
|
|
54772
|
-
const rel =
|
|
54704
|
+
const rel = path55.relative(root, target);
|
|
54773
54705
|
if (!rel || rel.startsWith("..")) return null;
|
|
54774
|
-
const id = rel.split(
|
|
54706
|
+
const id = rel.split(path55.sep)[0];
|
|
54775
54707
|
return id || null;
|
|
54776
54708
|
}
|
|
54777
54709
|
function isPathWithin(dir, absPath) {
|
|
54778
|
-
const d =
|
|
54779
|
-
const t =
|
|
54780
|
-
const sep3 = d.endsWith(
|
|
54710
|
+
const d = path55.resolve(dir);
|
|
54711
|
+
const t = path55.resolve(absPath);
|
|
54712
|
+
const sep3 = d.endsWith(path55.sep) ? "" : path55.sep;
|
|
54781
54713
|
return t === d || t.startsWith(d + sep3);
|
|
54782
54714
|
}
|
|
54783
54715
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
54784
54716
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54785
|
-
return personaIdFromPath(
|
|
54717
|
+
return personaIdFromPath(path55.resolve(absPath), personaRoot) === personaId;
|
|
54786
54718
|
}
|
|
54787
54719
|
|
|
54788
54720
|
// src/handlers/history.ts
|
|
@@ -54808,7 +54740,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54808
54740
|
if (!pid) return false;
|
|
54809
54741
|
return isGuestPathAllowed(
|
|
54810
54742
|
ctx.grants,
|
|
54811
|
-
|
|
54743
|
+
path56.join(personaRoot, pid),
|
|
54812
54744
|
personaRoot,
|
|
54813
54745
|
"read",
|
|
54814
54746
|
userWorkDir
|
|
@@ -54820,7 +54752,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54820
54752
|
};
|
|
54821
54753
|
const list = async (frame, _client, ctx) => {
|
|
54822
54754
|
const args = HistoryListArgs.parse(frame);
|
|
54823
|
-
assertGuestPath(ctx,
|
|
54755
|
+
assertGuestPath(ctx, path56.resolve(args.projectPath), personaRoot, "history:list");
|
|
54824
54756
|
const sessions = await history.listSessions(args);
|
|
54825
54757
|
return { response: { type: "history:list", sessions } };
|
|
54826
54758
|
};
|
|
@@ -54852,13 +54784,13 @@ function buildHistoryHandlers(deps) {
|
|
|
54852
54784
|
};
|
|
54853
54785
|
const subagents = async (frame, _client, ctx) => {
|
|
54854
54786
|
const args = HistorySubagentsArgs.parse(frame);
|
|
54855
|
-
assertGuestPath(ctx,
|
|
54787
|
+
assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
54856
54788
|
const subs = await history.listSubagents(args);
|
|
54857
54789
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
54858
54790
|
};
|
|
54859
54791
|
const subagentRead = async (frame, _client, ctx) => {
|
|
54860
54792
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
54861
|
-
assertGuestPath(ctx,
|
|
54793
|
+
assertGuestPath(ctx, path56.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
54862
54794
|
const res = await history.readSubagent(args);
|
|
54863
54795
|
return { response: { type: "history:subagent-read", ...res } };
|
|
54864
54796
|
};
|
|
@@ -54867,7 +54799,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54867
54799
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54868
54800
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54869
54801
|
const filtered = dirs.filter(
|
|
54870
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
54802
|
+
(d) => isGuestPathAllowed(ctx.grants, path56.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
54871
54803
|
);
|
|
54872
54804
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
54873
54805
|
}
|
|
@@ -54884,7 +54816,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54884
54816
|
}
|
|
54885
54817
|
|
|
54886
54818
|
// src/handlers/workspace.ts
|
|
54887
|
-
var
|
|
54819
|
+
var path57 = __toESM(require("path"), 1);
|
|
54888
54820
|
var os16 = __toESM(require("os"), 1);
|
|
54889
54821
|
init_protocol();
|
|
54890
54822
|
init_protocol();
|
|
@@ -54926,22 +54858,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54926
54858
|
const args = WorkspaceListArgs.parse(frame);
|
|
54927
54859
|
const isGuest = ctx?.principal.kind === "guest";
|
|
54928
54860
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
54929
|
-
const resolvedCwd =
|
|
54930
|
-
const target = args.path ?
|
|
54861
|
+
const resolvedCwd = path57.resolve(args.cwd ?? fallbackCwd);
|
|
54862
|
+
const target = args.path ? path57.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
54931
54863
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
54932
54864
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
54933
54865
|
return { response: { type: "workspace:list", ...res } };
|
|
54934
54866
|
};
|
|
54935
54867
|
const read = async (frame, _client, ctx) => {
|
|
54936
54868
|
const args = WorkspaceReadArgs.parse(frame);
|
|
54937
|
-
const target =
|
|
54869
|
+
const target = path57.isAbsolute(args.path) ? path57.resolve(args.path) : path57.resolve(args.cwd, args.path);
|
|
54938
54870
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
54939
54871
|
const res = workspace.read(args);
|
|
54940
54872
|
return { response: { type: "workspace:read", ...res } };
|
|
54941
54873
|
};
|
|
54942
54874
|
const skillsList = async (frame, _client, ctx) => {
|
|
54943
54875
|
const args = SkillsListArgs.parse(frame);
|
|
54944
|
-
const cwdAbs =
|
|
54876
|
+
const cwdAbs = path57.resolve(args.cwd);
|
|
54945
54877
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
54946
54878
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
54947
54879
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -54953,7 +54885,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54953
54885
|
};
|
|
54954
54886
|
const agentsList = async (frame, _client, ctx) => {
|
|
54955
54887
|
const args = AgentsListArgs.parse(frame);
|
|
54956
|
-
const cwdAbs =
|
|
54888
|
+
const cwdAbs = path57.resolve(args.cwd);
|
|
54957
54889
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
54958
54890
|
if (args.tool === "codex") {
|
|
54959
54891
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -54975,20 +54907,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54975
54907
|
}
|
|
54976
54908
|
|
|
54977
54909
|
// src/handlers/git.ts
|
|
54978
|
-
var
|
|
54910
|
+
var path59 = __toESM(require("path"), 1);
|
|
54979
54911
|
init_protocol();
|
|
54980
54912
|
init_protocol();
|
|
54981
54913
|
|
|
54982
54914
|
// src/workspace/git.ts
|
|
54983
54915
|
var import_node_child_process12 = require("child_process");
|
|
54984
|
-
var
|
|
54985
|
-
var
|
|
54916
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
54917
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54986
54918
|
var import_node_util = require("util");
|
|
54987
54919
|
var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
|
|
54988
54920
|
function normalizePath(p2) {
|
|
54989
|
-
const resolved =
|
|
54921
|
+
const resolved = import_node_path46.default.resolve(p2);
|
|
54990
54922
|
try {
|
|
54991
|
-
return
|
|
54923
|
+
return import_node_fs44.default.realpathSync(resolved);
|
|
54992
54924
|
} catch {
|
|
54993
54925
|
return resolved;
|
|
54994
54926
|
}
|
|
@@ -55062,7 +54994,7 @@ async function listGitBranches(cwd) {
|
|
|
55062
54994
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
55063
54995
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
55064
54996
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
55065
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
54997
|
+
if (!isGuestPathAllowed(ctx.grants, path59.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
55066
54998
|
throw new ClawdError(
|
|
55067
54999
|
ERROR_CODES.UNAUTHORIZED,
|
|
55068
55000
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -55403,22 +55335,22 @@ init_src();
|
|
|
55403
55335
|
init_protocol();
|
|
55404
55336
|
|
|
55405
55337
|
// src/sshd/key-issue.ts
|
|
55406
|
-
var
|
|
55407
|
-
var
|
|
55338
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
55339
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
55408
55340
|
var import_node_child_process13 = require("child_process");
|
|
55409
55341
|
function safeDeviceId(deviceId) {
|
|
55410
55342
|
return deviceId.replace(/[\/\\]/g, "_");
|
|
55411
55343
|
}
|
|
55412
55344
|
async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
55413
55345
|
const safeId = safeDeviceId(deviceId);
|
|
55414
|
-
const keysDir =
|
|
55415
|
-
|
|
55416
|
-
const privPath =
|
|
55346
|
+
const keysDir = import_node_path47.default.join(sshdDir, "keys");
|
|
55347
|
+
import_node_fs45.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
|
|
55348
|
+
const privPath = import_node_path47.default.join(keysDir, `${safeId}.ed25519`);
|
|
55417
55349
|
const pubPath = `${privPath}.pub`;
|
|
55418
|
-
if (
|
|
55350
|
+
if (import_node_fs45.default.existsSync(privPath) && import_node_fs45.default.existsSync(pubPath)) {
|
|
55419
55351
|
return {
|
|
55420
|
-
privateKeyPem:
|
|
55421
|
-
publicKeyLine:
|
|
55352
|
+
privateKeyPem: import_node_fs45.default.readFileSync(privPath, "utf8"),
|
|
55353
|
+
publicKeyLine: import_node_fs45.default.readFileSync(pubPath, "utf8").trim()
|
|
55422
55354
|
};
|
|
55423
55355
|
}
|
|
55424
55356
|
const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
|
|
@@ -55432,21 +55364,20 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
|
55432
55364
|
p2.on("error", reject);
|
|
55433
55365
|
});
|
|
55434
55366
|
try {
|
|
55435
|
-
|
|
55367
|
+
import_node_fs45.default.chmodSync(privPath, 384);
|
|
55436
55368
|
} catch {
|
|
55437
55369
|
}
|
|
55438
55370
|
try {
|
|
55439
|
-
|
|
55371
|
+
import_node_fs45.default.chmodSync(pubPath, 420);
|
|
55440
55372
|
} catch {
|
|
55441
55373
|
}
|
|
55442
55374
|
return {
|
|
55443
|
-
privateKeyPem:
|
|
55444
|
-
publicKeyLine:
|
|
55375
|
+
privateKeyPem: import_node_fs45.default.readFileSync(privPath, "utf8"),
|
|
55376
|
+
publicKeyLine: import_node_fs45.default.readFileSync(pubPath, "utf8").trim()
|
|
55445
55377
|
};
|
|
55446
55378
|
}
|
|
55447
55379
|
|
|
55448
55380
|
// src/handlers/contact-ssh.ts
|
|
55449
|
-
init_contact_ssh_log();
|
|
55450
55381
|
function ensureOwner2(ctx) {
|
|
55451
55382
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
55452
55383
|
throw new ClawdError(
|
|
@@ -55861,7 +55792,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55861
55792
|
}
|
|
55862
55793
|
|
|
55863
55794
|
// src/handlers/attachment.ts
|
|
55864
|
-
var
|
|
55795
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
55865
55796
|
init_protocol();
|
|
55866
55797
|
init_protocol();
|
|
55867
55798
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -55941,12 +55872,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
55941
55872
|
`session ${args.sessionId} scope unresolved`
|
|
55942
55873
|
);
|
|
55943
55874
|
}
|
|
55944
|
-
const cwdAbs =
|
|
55945
|
-
const candidateAbs =
|
|
55875
|
+
const cwdAbs = import_node_path48.default.resolve(sessionFile.cwd);
|
|
55876
|
+
const candidateAbs = import_node_path48.default.isAbsolute(args.relPath) ? import_node_path48.default.resolve(args.relPath) : import_node_path48.default.resolve(cwdAbs, args.relPath);
|
|
55946
55877
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
55947
55878
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
55948
55879
|
const entry = entries.find((e) => {
|
|
55949
|
-
const storedAbs =
|
|
55880
|
+
const storedAbs = import_node_path48.default.isAbsolute(e.relPath) ? import_node_path48.default.resolve(e.relPath) : import_node_path48.default.resolve(cwdAbs, e.relPath);
|
|
55950
55881
|
return storedAbs === candidateAbs && !e.stale;
|
|
55951
55882
|
});
|
|
55952
55883
|
if (!entry) {
|
|
@@ -55971,7 +55902,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
55971
55902
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
55972
55903
|
const f = deps.sessionStore.read(sessionId);
|
|
55973
55904
|
if (!f) return;
|
|
55974
|
-
assertGuestAttachmentPath(ctx,
|
|
55905
|
+
assertGuestAttachmentPath(ctx, import_node_path48.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
55975
55906
|
}
|
|
55976
55907
|
const groupAdd = async (frame, _client, ctx) => {
|
|
55977
55908
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -55986,8 +55917,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
55986
55917
|
if (!scope) {
|
|
55987
55918
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
55988
55919
|
}
|
|
55989
|
-
const cwdAbs =
|
|
55990
|
-
const candidateAbs =
|
|
55920
|
+
const cwdAbs = import_node_path48.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
55921
|
+
const candidateAbs = import_node_path48.default.isAbsolute(args.relPath) ? import_node_path48.default.resolve(args.relPath) : import_node_path48.default.resolve(cwdAbs, args.relPath);
|
|
55991
55922
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
55992
55923
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
55993
55924
|
const size = 0;
|
|
@@ -56046,20 +55977,20 @@ function buildAttachmentHandlers(deps) {
|
|
|
56046
55977
|
|
|
56047
55978
|
// src/handlers/extension.ts
|
|
56048
55979
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
56049
|
-
var
|
|
55980
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
56050
55981
|
init_protocol();
|
|
56051
55982
|
init_src();
|
|
56052
55983
|
|
|
56053
55984
|
// src/extension/bundle-zip.ts
|
|
56054
55985
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
56055
|
-
var
|
|
55986
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
56056
55987
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
56057
55988
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
56058
55989
|
async function bundleExtensionDir(dir) {
|
|
56059
55990
|
const entries = await listFilesSorted(dir);
|
|
56060
55991
|
const zip = new import_jszip2.default();
|
|
56061
55992
|
for (const rel of entries) {
|
|
56062
|
-
const abs =
|
|
55993
|
+
const abs = import_node_path49.default.join(dir, rel);
|
|
56063
55994
|
const content = await import_promises5.default.readFile(abs);
|
|
56064
55995
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
56065
55996
|
}
|
|
@@ -56080,7 +56011,7 @@ async function listFilesSorted(rootDir) {
|
|
|
56080
56011
|
return out;
|
|
56081
56012
|
}
|
|
56082
56013
|
async function walk(absRoot, relPrefix, out) {
|
|
56083
|
-
const dirAbs =
|
|
56014
|
+
const dirAbs = import_node_path49.default.join(absRoot, relPrefix);
|
|
56084
56015
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
56085
56016
|
for (const e of entries) {
|
|
56086
56017
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -56136,7 +56067,7 @@ function computePublishCheck(args) {
|
|
|
56136
56067
|
|
|
56137
56068
|
// src/extension/install-flow.ts
|
|
56138
56069
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
56139
|
-
var
|
|
56070
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56140
56071
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
56141
56072
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
56142
56073
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
@@ -56144,19 +56075,19 @@ init_src();
|
|
|
56144
56075
|
|
|
56145
56076
|
// src/extension/paths.ts
|
|
56146
56077
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
56147
|
-
var
|
|
56078
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56148
56079
|
init_src();
|
|
56149
56080
|
function clawdHomeRoot(override) {
|
|
56150
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
56081
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path50.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
56151
56082
|
}
|
|
56152
56083
|
function extensionsRoot(override) {
|
|
56153
|
-
return
|
|
56084
|
+
return import_node_path50.default.join(clawdHomeRoot(override), "extensions");
|
|
56154
56085
|
}
|
|
56155
56086
|
function publishedChannelsFile(override) {
|
|
56156
|
-
return
|
|
56087
|
+
return import_node_path50.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
56157
56088
|
}
|
|
56158
56089
|
function bundleCacheRoot(override) {
|
|
56159
|
-
return
|
|
56090
|
+
return import_node_path50.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
56160
56091
|
}
|
|
56161
56092
|
|
|
56162
56093
|
// src/extension/install-flow.ts
|
|
@@ -56183,7 +56114,7 @@ async function installFromChannel(args, deps) {
|
|
|
56183
56114
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56184
56115
|
}
|
|
56185
56116
|
for (const name of Object.keys(zip.files)) {
|
|
56186
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56117
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path51.default.isAbsolute(name)) {
|
|
56187
56118
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56188
56119
|
}
|
|
56189
56120
|
}
|
|
@@ -56215,7 +56146,7 @@ async function installFromChannel(args, deps) {
|
|
|
56215
56146
|
);
|
|
56216
56147
|
}
|
|
56217
56148
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
56218
|
-
const destDir =
|
|
56149
|
+
const destDir = import_node_path51.default.join(deps.extensionsRoot, localExtId);
|
|
56219
56150
|
let destExists = false;
|
|
56220
56151
|
try {
|
|
56221
56152
|
await import_promises6.default.access(destDir);
|
|
@@ -56229,16 +56160,16 @@ async function installFromChannel(args, deps) {
|
|
|
56229
56160
|
);
|
|
56230
56161
|
}
|
|
56231
56162
|
const stage = await import_promises6.default.mkdtemp(
|
|
56232
|
-
|
|
56163
|
+
import_node_path51.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
56233
56164
|
);
|
|
56234
56165
|
try {
|
|
56235
56166
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56236
|
-
const dest =
|
|
56167
|
+
const dest = import_node_path51.default.join(stage, name);
|
|
56237
56168
|
if (entry.dir) {
|
|
56238
56169
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
56239
56170
|
continue;
|
|
56240
56171
|
}
|
|
56241
|
-
await import_promises6.default.mkdir(
|
|
56172
|
+
await import_promises6.default.mkdir(import_node_path51.default.dirname(dest), { recursive: true });
|
|
56242
56173
|
if (name === "manifest.json") {
|
|
56243
56174
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56244
56175
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56259,7 +56190,7 @@ async function installFromChannel(args, deps) {
|
|
|
56259
56190
|
|
|
56260
56191
|
// src/extension/update-flow.ts
|
|
56261
56192
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
56262
|
-
var
|
|
56193
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56263
56194
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
56264
56195
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
56265
56196
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -56277,11 +56208,11 @@ async function updateFromChannel(args, deps) {
|
|
|
56277
56208
|
channelRef.extId,
|
|
56278
56209
|
channelRef.ownerPrincipalId
|
|
56279
56210
|
);
|
|
56280
|
-
const liveDir =
|
|
56211
|
+
const liveDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
|
|
56281
56212
|
const prevDir = `${liveDir}.prev`;
|
|
56282
56213
|
let existingVersion;
|
|
56283
56214
|
try {
|
|
56284
|
-
const raw = await import_promises7.default.readFile(
|
|
56215
|
+
const raw = await import_promises7.default.readFile(import_node_path52.default.join(liveDir, "manifest.json"), "utf8");
|
|
56285
56216
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
56286
56217
|
if (!parsed2.success) {
|
|
56287
56218
|
throw new UpdateError(
|
|
@@ -56314,7 +56245,7 @@ async function updateFromChannel(args, deps) {
|
|
|
56314
56245
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56315
56246
|
}
|
|
56316
56247
|
for (const name of Object.keys(zip.files)) {
|
|
56317
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56248
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
|
|
56318
56249
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56319
56250
|
}
|
|
56320
56251
|
}
|
|
@@ -56349,16 +56280,16 @@ async function updateFromChannel(args, deps) {
|
|
|
56349
56280
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
56350
56281
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
56351
56282
|
const stage = await import_promises7.default.mkdtemp(
|
|
56352
|
-
|
|
56283
|
+
import_node_path52.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
56353
56284
|
);
|
|
56354
56285
|
try {
|
|
56355
56286
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56356
|
-
const dest =
|
|
56287
|
+
const dest = import_node_path52.default.join(stage, name);
|
|
56357
56288
|
if (entry.dir) {
|
|
56358
56289
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
56359
56290
|
continue;
|
|
56360
56291
|
}
|
|
56361
|
-
await import_promises7.default.mkdir(
|
|
56292
|
+
await import_promises7.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
|
|
56362
56293
|
if (name === "manifest.json") {
|
|
56363
56294
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56364
56295
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56452,7 +56383,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56452
56383
|
);
|
|
56453
56384
|
}
|
|
56454
56385
|
}
|
|
56455
|
-
const manifestPath =
|
|
56386
|
+
const manifestPath = import_node_path53.default.join(root, extId, "manifest.json");
|
|
56456
56387
|
const manifest = await readManifest(root, extId);
|
|
56457
56388
|
const next = { ...manifest, version: newVersion };
|
|
56458
56389
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -56460,7 +56391,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56460
56391
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
56461
56392
|
}
|
|
56462
56393
|
async function readManifest(root, extId) {
|
|
56463
|
-
const file =
|
|
56394
|
+
const file = import_node_path53.default.join(root, extId, "manifest.json");
|
|
56464
56395
|
let raw;
|
|
56465
56396
|
try {
|
|
56466
56397
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -56551,7 +56482,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56551
56482
|
};
|
|
56552
56483
|
async function buildSnapshotMeta(extId) {
|
|
56553
56484
|
const manifest = await readManifest(deps.root, extId);
|
|
56554
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
56485
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path53.default.join(deps.root, extId));
|
|
56555
56486
|
return { manifest, contentHash: sha256, buffer };
|
|
56556
56487
|
}
|
|
56557
56488
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -56732,9 +56663,9 @@ function buildExtensionHandlers(deps) {
|
|
|
56732
56663
|
}
|
|
56733
56664
|
|
|
56734
56665
|
// src/app-builder/project-store.ts
|
|
56735
|
-
var
|
|
56666
|
+
var import_node_fs46 = require("fs");
|
|
56736
56667
|
var import_node_child_process14 = require("child_process");
|
|
56737
|
-
var
|
|
56668
|
+
var import_node_path54 = require("path");
|
|
56738
56669
|
init_protocol();
|
|
56739
56670
|
var PROJECTS_DIR = "projects";
|
|
56740
56671
|
var META_FILE = ".clawd-project.json";
|
|
@@ -56748,19 +56679,19 @@ var ProjectStore = class {
|
|
|
56748
56679
|
root;
|
|
56749
56680
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
56750
56681
|
metaPath(name) {
|
|
56751
|
-
return (0,
|
|
56682
|
+
return (0, import_node_path54.join)(this.projectsRoot(), name, META_FILE);
|
|
56752
56683
|
}
|
|
56753
56684
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
56754
56685
|
projectDir(name) {
|
|
56755
|
-
return (0,
|
|
56686
|
+
return (0, import_node_path54.join)(this.projectsRoot(), name);
|
|
56756
56687
|
}
|
|
56757
56688
|
projectsRoot() {
|
|
56758
|
-
return (0,
|
|
56689
|
+
return (0, import_node_path54.join)(this.root, PROJECTS_DIR);
|
|
56759
56690
|
}
|
|
56760
56691
|
async list() {
|
|
56761
56692
|
let entries;
|
|
56762
56693
|
try {
|
|
56763
|
-
entries = await
|
|
56694
|
+
entries = await import_node_fs46.promises.readdir(this.projectsRoot());
|
|
56764
56695
|
} catch (err) {
|
|
56765
56696
|
if (err.code === "ENOENT") return [];
|
|
56766
56697
|
throw err;
|
|
@@ -56768,7 +56699,7 @@ var ProjectStore = class {
|
|
|
56768
56699
|
const out = [];
|
|
56769
56700
|
for (const name of entries) {
|
|
56770
56701
|
try {
|
|
56771
|
-
const raw = await
|
|
56702
|
+
const raw = await import_node_fs46.promises.readFile(this.metaPath(name), "utf8");
|
|
56772
56703
|
const json = JSON.parse(raw);
|
|
56773
56704
|
let migrated = false;
|
|
56774
56705
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -56779,7 +56710,7 @@ var ProjectStore = class {
|
|
|
56779
56710
|
if (parsed.success) {
|
|
56780
56711
|
out.push(parsed.data);
|
|
56781
56712
|
if (migrated) {
|
|
56782
|
-
void
|
|
56713
|
+
void import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
56783
56714
|
});
|
|
56784
56715
|
}
|
|
56785
56716
|
}
|
|
@@ -56823,8 +56754,8 @@ var ProjectStore = class {
|
|
|
56823
56754
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
56824
56755
|
}
|
|
56825
56756
|
const dir = this.projectDir(name);
|
|
56826
|
-
await
|
|
56827
|
-
await
|
|
56757
|
+
await import_node_fs46.promises.mkdir(dir, { recursive: true });
|
|
56758
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
56828
56759
|
return meta;
|
|
56829
56760
|
}
|
|
56830
56761
|
/**
|
|
@@ -56867,7 +56798,7 @@ var ProjectStore = class {
|
|
|
56867
56798
|
}
|
|
56868
56799
|
async delete(name) {
|
|
56869
56800
|
const dir = this.projectDir(name);
|
|
56870
|
-
await
|
|
56801
|
+
await import_node_fs46.promises.rm(dir, { recursive: true, force: true });
|
|
56871
56802
|
}
|
|
56872
56803
|
async updatePort(name, newPort) {
|
|
56873
56804
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -56883,7 +56814,7 @@ var ProjectStore = class {
|
|
|
56883
56814
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
56884
56815
|
}
|
|
56885
56816
|
const updated = { ...target, port: newPort };
|
|
56886
|
-
await
|
|
56817
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
56887
56818
|
return updated;
|
|
56888
56819
|
}
|
|
56889
56820
|
/**
|
|
@@ -56900,7 +56831,7 @@ var ProjectStore = class {
|
|
|
56900
56831
|
if (!validated.success) {
|
|
56901
56832
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
56902
56833
|
}
|
|
56903
|
-
await
|
|
56834
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56904
56835
|
return validated.data;
|
|
56905
56836
|
}
|
|
56906
56837
|
/**
|
|
@@ -56921,7 +56852,7 @@ var ProjectStore = class {
|
|
|
56921
56852
|
if (!validated.success) {
|
|
56922
56853
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
56923
56854
|
}
|
|
56924
|
-
await
|
|
56855
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56925
56856
|
return validated.data;
|
|
56926
56857
|
}
|
|
56927
56858
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -56936,7 +56867,7 @@ var ProjectStore = class {
|
|
|
56936
56867
|
if (!validated.success) {
|
|
56937
56868
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
56938
56869
|
}
|
|
56939
|
-
await
|
|
56870
|
+
await import_node_fs46.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56940
56871
|
return validated.data;
|
|
56941
56872
|
}
|
|
56942
56873
|
};
|
|
@@ -57057,8 +56988,8 @@ var PublishJobRegistry = class {
|
|
|
57057
56988
|
|
|
57058
56989
|
// src/app-builder/publish-job-runner.ts
|
|
57059
56990
|
var import_node_child_process16 = require("child_process");
|
|
57060
|
-
var
|
|
57061
|
-
var
|
|
56991
|
+
var import_node_fs47 = require("fs");
|
|
56992
|
+
var import_node_path55 = require("path");
|
|
57062
56993
|
|
|
57063
56994
|
// src/app-builder/publish-stage-parser.ts
|
|
57064
56995
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -57090,10 +57021,10 @@ async function startPublishJob(deps, args) {
|
|
|
57090
57021
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
57091
57022
|
}
|
|
57092
57023
|
const projDir = projectDir(args.name);
|
|
57093
|
-
const logPath = (0,
|
|
57024
|
+
const logPath = (0, import_node_path55.join)(projDir, ".publish.log");
|
|
57094
57025
|
let logStream = null;
|
|
57095
57026
|
try {
|
|
57096
|
-
logStream = (0,
|
|
57027
|
+
logStream = (0, import_node_fs47.createWriteStream)(logPath, { flags: "w" });
|
|
57097
57028
|
} catch {
|
|
57098
57029
|
logStream = null;
|
|
57099
57030
|
}
|
|
@@ -57350,8 +57281,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
57350
57281
|
|
|
57351
57282
|
// src/handlers/app-builder.ts
|
|
57352
57283
|
init_protocol();
|
|
57353
|
-
var
|
|
57354
|
-
var
|
|
57284
|
+
var import_node_path56 = require("path");
|
|
57285
|
+
var import_node_fs48 = require("fs");
|
|
57355
57286
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
57356
57287
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
57357
57288
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -57432,7 +57363,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57432
57363
|
async function listAllUsersProjects() {
|
|
57433
57364
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
57434
57365
|
const getStore = deps.getStore;
|
|
57435
|
-
const userIds = await
|
|
57366
|
+
const userIds = await import_node_fs48.promises.readdir(deps.usersRoot).catch(() => []);
|
|
57436
57367
|
const perUser = await Promise.all(
|
|
57437
57368
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
57438
57369
|
);
|
|
@@ -57508,8 +57439,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57508
57439
|
const project = await userStore.create(f.name, reservedPorts);
|
|
57509
57440
|
try {
|
|
57510
57441
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57511
|
-
const templateSrcDir = (0,
|
|
57512
|
-
const scaffoldScript = (0,
|
|
57442
|
+
const templateSrcDir = (0, import_node_path56.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
57443
|
+
const scaffoldScript = (0, import_node_path56.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
57513
57444
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
57514
57445
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
57515
57446
|
name: project.name,
|
|
@@ -57730,7 +57661,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57730
57661
|
await userStore.clearPublishJob(args.name);
|
|
57731
57662
|
}
|
|
57732
57663
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57733
|
-
const scriptPath = (0,
|
|
57664
|
+
const scriptPath = (0, import_node_path56.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
57734
57665
|
deps.logger?.info("app-builder.publish.start", {
|
|
57735
57666
|
name: args.name,
|
|
57736
57667
|
sessionId: boundSession.sessionId,
|
|
@@ -57899,7 +57830,7 @@ function buildVisitorHandlers(deps) {
|
|
|
57899
57830
|
|
|
57900
57831
|
// src/extension/registry.ts
|
|
57901
57832
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
57902
|
-
var
|
|
57833
|
+
var import_node_path57 = __toESM(require("path"), 1);
|
|
57903
57834
|
init_src();
|
|
57904
57835
|
async function loadAll(root) {
|
|
57905
57836
|
let entries;
|
|
@@ -57913,13 +57844,13 @@ async function loadAll(root) {
|
|
|
57913
57844
|
for (const ent of entries) {
|
|
57914
57845
|
if (!ent.isDirectory()) continue;
|
|
57915
57846
|
if (ent.name.startsWith(".")) continue;
|
|
57916
|
-
records.push(await loadOne(
|
|
57847
|
+
records.push(await loadOne(import_node_path57.default.join(root, ent.name), ent.name));
|
|
57917
57848
|
}
|
|
57918
57849
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
57919
57850
|
return records;
|
|
57920
57851
|
}
|
|
57921
57852
|
async function loadOne(dir, dirName) {
|
|
57922
|
-
const manifestPath =
|
|
57853
|
+
const manifestPath = import_node_path57.default.join(dir, "manifest.json");
|
|
57923
57854
|
let raw;
|
|
57924
57855
|
try {
|
|
57925
57856
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -57964,7 +57895,7 @@ async function loadOne(dir, dirName) {
|
|
|
57964
57895
|
|
|
57965
57896
|
// src/extension/uninstall.ts
|
|
57966
57897
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
57967
|
-
var
|
|
57898
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
57968
57899
|
var UninstallError = class extends Error {
|
|
57969
57900
|
constructor(code, message) {
|
|
57970
57901
|
super(message);
|
|
@@ -57973,7 +57904,7 @@ var UninstallError = class extends Error {
|
|
|
57973
57904
|
code;
|
|
57974
57905
|
};
|
|
57975
57906
|
async function uninstall(deps) {
|
|
57976
|
-
const dir =
|
|
57907
|
+
const dir = import_node_path58.default.join(deps.root, deps.extId);
|
|
57977
57908
|
try {
|
|
57978
57909
|
await import_promises10.default.access(dir);
|
|
57979
57910
|
} catch {
|
|
@@ -58557,7 +58488,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58557
58488
|
|
|
58558
58489
|
// src/extension/runtime.ts
|
|
58559
58490
|
var import_node_child_process18 = require("child_process");
|
|
58560
|
-
var
|
|
58491
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
58561
58492
|
var import_promises11 = require("timers/promises");
|
|
58562
58493
|
init_src();
|
|
58563
58494
|
|
|
@@ -58659,7 +58590,7 @@ var Runtime = class {
|
|
|
58659
58590
|
/\$CLAWOS_EXT_PORT/g,
|
|
58660
58591
|
String(port)
|
|
58661
58592
|
);
|
|
58662
|
-
const dir =
|
|
58593
|
+
const dir = import_node_path59.default.join(this.root, extId);
|
|
58663
58594
|
const env = {
|
|
58664
58595
|
...process.env,
|
|
58665
58596
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -58771,7 +58702,7 @@ ${handle.stderrTail}`
|
|
|
58771
58702
|
|
|
58772
58703
|
// src/extension/published-channels.ts
|
|
58773
58704
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
58774
|
-
var
|
|
58705
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
58775
58706
|
init_src();
|
|
58776
58707
|
init_zod();
|
|
58777
58708
|
var PublishedChannelsError = class extends Error {
|
|
@@ -58871,7 +58802,7 @@ var PublishedChannelStore = class {
|
|
|
58871
58802
|
)
|
|
58872
58803
|
};
|
|
58873
58804
|
const tmp = `${this.filePath}.tmp`;
|
|
58874
|
-
await import_promises12.default.mkdir(
|
|
58805
|
+
await import_promises12.default.mkdir(import_node_path60.default.dirname(this.filePath), { recursive: true });
|
|
58875
58806
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
58876
58807
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
58877
58808
|
}
|
|
@@ -58879,7 +58810,7 @@ var PublishedChannelStore = class {
|
|
|
58879
58810
|
|
|
58880
58811
|
// src/extension/bundle-cache.ts
|
|
58881
58812
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
58882
|
-
var
|
|
58813
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
58883
58814
|
var BundleCache = class {
|
|
58884
58815
|
constructor(rootDir) {
|
|
58885
58816
|
this.rootDir = rootDir;
|
|
@@ -58888,14 +58819,14 @@ var BundleCache = class {
|
|
|
58888
58819
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
58889
58820
|
async write(snapshotHash, buffer) {
|
|
58890
58821
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
58891
|
-
const file =
|
|
58822
|
+
const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58892
58823
|
const tmp = `${file}.tmp`;
|
|
58893
58824
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
58894
58825
|
await import_promises13.default.rename(tmp, file);
|
|
58895
58826
|
}
|
|
58896
58827
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
58897
58828
|
async read(snapshotHash) {
|
|
58898
|
-
const file =
|
|
58829
|
+
const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58899
58830
|
try {
|
|
58900
58831
|
return await import_promises13.default.readFile(file);
|
|
58901
58832
|
} catch (e) {
|
|
@@ -58905,7 +58836,7 @@ var BundleCache = class {
|
|
|
58905
58836
|
}
|
|
58906
58837
|
/** Idempotent — missing file is not an error. */
|
|
58907
58838
|
async delete(snapshotHash) {
|
|
58908
|
-
const file =
|
|
58839
|
+
const file = import_node_path61.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58909
58840
|
await import_promises13.default.rm(file, { force: true });
|
|
58910
58841
|
}
|
|
58911
58842
|
};
|
|
@@ -58930,16 +58861,16 @@ async function startDaemon(config) {
|
|
|
58930
58861
|
});
|
|
58931
58862
|
const logger = createLogger({
|
|
58932
58863
|
level: config.logLevel,
|
|
58933
|
-
file:
|
|
58864
|
+
file: import_node_path62.default.join(config.dataDir, "clawd.log"),
|
|
58934
58865
|
logClient
|
|
58935
58866
|
});
|
|
58936
58867
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
58937
58868
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
58938
|
-
file:
|
|
58869
|
+
file: import_node_path62.default.join(config.dataDir, "screen-idle-probe.log"),
|
|
58939
58870
|
level: "debug"
|
|
58940
58871
|
});
|
|
58941
58872
|
logger.info("screen-idle probe logger enabled", {
|
|
58942
|
-
file:
|
|
58873
|
+
file: import_node_path62.default.join(config.dataDir, "screen-idle-probe.log")
|
|
58943
58874
|
});
|
|
58944
58875
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
58945
58876
|
const pre = stateMgr.preflight();
|
|
@@ -59077,8 +59008,8 @@ async function startDaemon(config) {
|
|
|
59077
59008
|
const agents = new AgentsScanner();
|
|
59078
59009
|
const history = new ClaudeHistoryReader();
|
|
59079
59010
|
let transport = null;
|
|
59080
|
-
const personaStore = new PersonaStore(
|
|
59081
|
-
const usersRoot =
|
|
59011
|
+
const personaStore = new PersonaStore(import_node_path62.default.join(config.dataDir, "personas"));
|
|
59012
|
+
const usersRoot = import_node_path62.default.join(config.dataDir, "users");
|
|
59082
59013
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
59083
59014
|
if (defaultsRoot) {
|
|
59084
59015
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -59098,17 +59029,17 @@ async function startDaemon(config) {
|
|
|
59098
59029
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
59099
59030
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
59100
59031
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
59101
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
59032
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path62.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
59102
59033
|
const dispatchServerCandidates = [
|
|
59103
|
-
|
|
59034
|
+
import_node_path62.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
59104
59035
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
59105
|
-
|
|
59036
|
+
import_node_path62.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
59106
59037
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
59107
59038
|
];
|
|
59108
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
59039
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
59109
59040
|
let dispatchMcpConfigPath2;
|
|
59110
59041
|
if (dispatchServerScriptPath) {
|
|
59111
|
-
const dispatchLogPath =
|
|
59042
|
+
const dispatchLogPath = import_node_path62.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
59112
59043
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
59113
59044
|
dataDir: config.dataDir,
|
|
59114
59045
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -59125,15 +59056,15 @@ async function startDaemon(config) {
|
|
|
59125
59056
|
});
|
|
59126
59057
|
}
|
|
59127
59058
|
const ticketServerCandidates = [
|
|
59128
|
-
|
|
59129
|
-
|
|
59059
|
+
import_node_path62.default.join(here, "ticket", "mcp-server.cjs"),
|
|
59060
|
+
import_node_path62.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
59130
59061
|
];
|
|
59131
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
59062
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
59132
59063
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
59133
59064
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
59134
59065
|
let ticketMcpConfigPath2;
|
|
59135
59066
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
59136
|
-
const ticketLogPath =
|
|
59067
|
+
const ticketLogPath = import_node_path62.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
59137
59068
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
59138
59069
|
dataDir: config.dataDir,
|
|
59139
59070
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -59154,13 +59085,13 @@ async function startDaemon(config) {
|
|
|
59154
59085
|
});
|
|
59155
59086
|
}
|
|
59156
59087
|
const shiftServerCandidates = [
|
|
59157
|
-
|
|
59158
|
-
|
|
59088
|
+
import_node_path62.default.join(here, "shift", "mcp-server.cjs"),
|
|
59089
|
+
import_node_path62.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
59159
59090
|
];
|
|
59160
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
59091
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
59161
59092
|
let shiftMcpConfigPath2;
|
|
59162
59093
|
if (shiftServerScriptPath) {
|
|
59163
|
-
const shiftLogPath =
|
|
59094
|
+
const shiftLogPath = import_node_path62.default.join(config.dataDir, "shift-mcp-server.log");
|
|
59164
59095
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
59165
59096
|
dataDir: config.dataDir,
|
|
59166
59097
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -59178,13 +59109,13 @@ async function startDaemon(config) {
|
|
|
59178
59109
|
);
|
|
59179
59110
|
}
|
|
59180
59111
|
const inboxServerCandidates = [
|
|
59181
|
-
|
|
59182
|
-
|
|
59112
|
+
import_node_path62.default.join(here, "inbox", "mcp-server.cjs"),
|
|
59113
|
+
import_node_path62.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
59183
59114
|
];
|
|
59184
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
59115
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs49.default.existsSync(p2));
|
|
59185
59116
|
let inboxMcpConfigPath2;
|
|
59186
59117
|
if (inboxServerScriptPath) {
|
|
59187
|
-
const inboxLogPath =
|
|
59118
|
+
const inboxLogPath = import_node_path62.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
59188
59119
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
59189
59120
|
dataDir: config.dataDir,
|
|
59190
59121
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -59202,7 +59133,7 @@ async function startDaemon(config) {
|
|
|
59202
59133
|
);
|
|
59203
59134
|
}
|
|
59204
59135
|
const shiftStore = createShiftStore({
|
|
59205
|
-
filePath:
|
|
59136
|
+
filePath: import_node_path62.default.join(config.dataDir, "shift.json"),
|
|
59206
59137
|
ownerIdProvider: () => ownerPrincipalId,
|
|
59207
59138
|
now: () => Date.now()
|
|
59208
59139
|
});
|
|
@@ -59224,7 +59155,7 @@ async function startDaemon(config) {
|
|
|
59224
59155
|
getAdapter,
|
|
59225
59156
|
historyReader: history,
|
|
59226
59157
|
dataDir: config.dataDir,
|
|
59227
|
-
personaRoot:
|
|
59158
|
+
personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
|
|
59228
59159
|
usersRoot,
|
|
59229
59160
|
personaStore,
|
|
59230
59161
|
ownerDisplayName,
|
|
@@ -59267,10 +59198,10 @@ async function startDaemon(config) {
|
|
|
59267
59198
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
59268
59199
|
attachmentGroup: {
|
|
59269
59200
|
onFileEdit: (input) => {
|
|
59270
|
-
const absPath =
|
|
59201
|
+
const absPath = import_node_path62.default.isAbsolute(input.relPath) ? input.relPath : import_node_path62.default.join(input.cwd, input.relPath);
|
|
59271
59202
|
let size = 0;
|
|
59272
59203
|
try {
|
|
59273
|
-
size =
|
|
59204
|
+
size = import_node_fs49.default.statSync(absPath).size;
|
|
59274
59205
|
} catch (err) {
|
|
59275
59206
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
59276
59207
|
sessionId: input.sessionId,
|
|
@@ -59469,11 +59400,11 @@ async function startDaemon(config) {
|
|
|
59469
59400
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
59470
59401
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
59471
59402
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
59472
|
-
personaRoot:
|
|
59403
|
+
personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
|
|
59473
59404
|
usersRoot
|
|
59474
59405
|
},
|
|
59475
59406
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
59476
|
-
personaRoot:
|
|
59407
|
+
personaRoot: import_node_path62.default.join(config.dataDir, "personas"),
|
|
59477
59408
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
59478
59409
|
usersRoot,
|
|
59479
59410
|
// capability:list / delete handler 依赖
|
|
@@ -59495,7 +59426,7 @@ async function startDaemon(config) {
|
|
|
59495
59426
|
contactStore,
|
|
59496
59427
|
// <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
|
|
59497
59428
|
// Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
|
|
59498
|
-
sshdDir:
|
|
59429
|
+
sshdDir: import_node_path62.default.join(config.dataDir, "sshd"),
|
|
59499
59430
|
contactSshLog: sshLog,
|
|
59500
59431
|
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
59501
59432
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
@@ -59586,11 +59517,11 @@ async function startDaemon(config) {
|
|
|
59586
59517
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
59587
59518
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
59588
59519
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
59589
|
-
appBuilderPersonaRoot:
|
|
59520
|
+
appBuilderPersonaRoot: import_node_path62.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
59590
59521
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59591
|
-
deployKitRoot:
|
|
59522
|
+
deployKitRoot: import_node_path62.default.join(config.dataDir, "deploy-kit"),
|
|
59592
59523
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59593
|
-
resolvePersonaRoot: (personaId) =>
|
|
59524
|
+
resolvePersonaRoot: (personaId) => import_node_path62.default.join(config.dataDir, "personas", personaId),
|
|
59594
59525
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59595
59526
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59596
59527
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59633,7 +59564,7 @@ async function startDaemon(config) {
|
|
|
59633
59564
|
}
|
|
59634
59565
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
59635
59566
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
59636
|
-
sourceJsonlPath =
|
|
59567
|
+
sourceJsonlPath = import_node_path62.default.join(
|
|
59637
59568
|
import_node_os21.default.homedir(),
|
|
59638
59569
|
".claude",
|
|
59639
59570
|
"projects",
|
|
@@ -59963,8 +59894,8 @@ async function startDaemon(config) {
|
|
|
59963
59894
|
const lines = [
|
|
59964
59895
|
`Tunnel: ${r.url}`,
|
|
59965
59896
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
59966
|
-
`Frpc config: ${
|
|
59967
|
-
`Frpc log: ${
|
|
59897
|
+
`Frpc config: ${import_node_path62.default.join(config.dataDir, "frpc.toml")}`,
|
|
59898
|
+
`Frpc log: ${import_node_path62.default.join(config.dataDir, "frpc.log")}`
|
|
59968
59899
|
];
|
|
59969
59900
|
const width = Math.max(...lines.map((l) => l.length));
|
|
59970
59901
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -59977,8 +59908,8 @@ ${bar}
|
|
|
59977
59908
|
|
|
59978
59909
|
`);
|
|
59979
59910
|
try {
|
|
59980
|
-
const connectPath =
|
|
59981
|
-
|
|
59911
|
+
const connectPath = import_node_path62.default.join(config.dataDir, "connect.txt");
|
|
59912
|
+
import_node_fs49.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
59982
59913
|
} catch {
|
|
59983
59914
|
}
|
|
59984
59915
|
} catch (err) {
|
|
@@ -60012,7 +59943,7 @@ ${bar}
|
|
|
60012
59943
|
});
|
|
60013
59944
|
try {
|
|
60014
59945
|
await sshdMgr.start();
|
|
60015
|
-
rebuildAuthorizedKeys(contactStore,
|
|
59946
|
+
rebuildAuthorizedKeys(contactStore, import_node_path62.default.join(config.dataDir, "sshd"));
|
|
60016
59947
|
logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
|
|
60017
59948
|
} catch (err) {
|
|
60018
59949
|
logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
|
|
@@ -60080,9 +60011,9 @@ ${bar}
|
|
|
60080
60011
|
};
|
|
60081
60012
|
}
|
|
60082
60013
|
function migrateDropPersonsDir(dataDir) {
|
|
60083
|
-
const dir =
|
|
60014
|
+
const dir = import_node_path62.default.join(dataDir, "persons");
|
|
60084
60015
|
try {
|
|
60085
|
-
|
|
60016
|
+
import_node_fs49.default.rmSync(dir, { recursive: true, force: true });
|
|
60086
60017
|
} catch {
|
|
60087
60018
|
}
|
|
60088
60019
|
}
|