@clawos-dev/clawd 0.2.205-beta.409.d6f7a21 → 0.2.205-beta.410.e49bc1f
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 +441 -369
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -742,8 +742,8 @@ var init_parseUtil = __esm({
|
|
|
742
742
|
init_errors2();
|
|
743
743
|
init_en();
|
|
744
744
|
makeIssue = (params) => {
|
|
745
|
-
const { data, path:
|
|
746
|
-
const fullPath = [...
|
|
745
|
+
const { data, path: path77, errorMaps, issueData } = params;
|
|
746
|
+
const fullPath = [...path77, ...issueData.path || []];
|
|
747
747
|
const fullIssue = {
|
|
748
748
|
...issueData,
|
|
749
749
|
path: fullPath
|
|
@@ -1054,11 +1054,11 @@ var init_types = __esm({
|
|
|
1054
1054
|
init_parseUtil();
|
|
1055
1055
|
init_util();
|
|
1056
1056
|
ParseInputLazyPath = class {
|
|
1057
|
-
constructor(parent, value,
|
|
1057
|
+
constructor(parent, value, path77, key) {
|
|
1058
1058
|
this._cachedPath = [];
|
|
1059
1059
|
this.parent = parent;
|
|
1060
1060
|
this.data = value;
|
|
1061
|
-
this._path =
|
|
1061
|
+
this._path = path77;
|
|
1062
1062
|
this._key = key;
|
|
1063
1063
|
}
|
|
1064
1064
|
get path() {
|
|
@@ -6449,8 +6449,8 @@ var require_req = __commonJS({
|
|
|
6449
6449
|
if (req.originalUrl) {
|
|
6450
6450
|
_req.url = req.originalUrl;
|
|
6451
6451
|
} else {
|
|
6452
|
-
const
|
|
6453
|
-
_req.url = typeof
|
|
6452
|
+
const path77 = req.path;
|
|
6453
|
+
_req.url = typeof path77 === "string" ? path77 : req.url ? req.url.path || req.url : void 0;
|
|
6454
6454
|
}
|
|
6455
6455
|
if (req.query) {
|
|
6456
6456
|
_req.query = req.query;
|
|
@@ -6615,14 +6615,14 @@ var require_redact = __commonJS({
|
|
|
6615
6615
|
}
|
|
6616
6616
|
return obj;
|
|
6617
6617
|
}
|
|
6618
|
-
function parsePath(
|
|
6618
|
+
function parsePath(path77) {
|
|
6619
6619
|
const parts = [];
|
|
6620
6620
|
let current = "";
|
|
6621
6621
|
let inBrackets = false;
|
|
6622
6622
|
let inQuotes = false;
|
|
6623
6623
|
let quoteChar = "";
|
|
6624
|
-
for (let i = 0; i <
|
|
6625
|
-
const char =
|
|
6624
|
+
for (let i = 0; i < path77.length; i++) {
|
|
6625
|
+
const char = path77[i];
|
|
6626
6626
|
if (!inBrackets && char === ".") {
|
|
6627
6627
|
if (current) {
|
|
6628
6628
|
parts.push(current);
|
|
@@ -6753,10 +6753,10 @@ var require_redact = __commonJS({
|
|
|
6753
6753
|
return current;
|
|
6754
6754
|
}
|
|
6755
6755
|
function redactPaths(obj, paths, censor, remove = false) {
|
|
6756
|
-
for (const
|
|
6757
|
-
const parts = parsePath(
|
|
6756
|
+
for (const path77 of paths) {
|
|
6757
|
+
const parts = parsePath(path77);
|
|
6758
6758
|
if (parts.includes("*")) {
|
|
6759
|
-
redactWildcardPath(obj, parts, censor,
|
|
6759
|
+
redactWildcardPath(obj, parts, censor, path77, remove);
|
|
6760
6760
|
} else {
|
|
6761
6761
|
if (remove) {
|
|
6762
6762
|
removeKey(obj, parts);
|
|
@@ -6841,8 +6841,8 @@ var require_redact = __commonJS({
|
|
|
6841
6841
|
}
|
|
6842
6842
|
} else {
|
|
6843
6843
|
if (afterWildcard.includes("*")) {
|
|
6844
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
6845
|
-
const fullPath = [...pathArray.slice(0, pathLength), ...
|
|
6844
|
+
const wrappedCensor = typeof censor === "function" ? (value, path77) => {
|
|
6845
|
+
const fullPath = [...pathArray.slice(0, pathLength), ...path77];
|
|
6846
6846
|
return censor(value, fullPath);
|
|
6847
6847
|
} : censor;
|
|
6848
6848
|
redactWildcardPath(current, afterWildcard, wrappedCensor, originalPath, remove);
|
|
@@ -6877,8 +6877,8 @@ var require_redact = __commonJS({
|
|
|
6877
6877
|
return null;
|
|
6878
6878
|
}
|
|
6879
6879
|
const pathStructure = /* @__PURE__ */ new Map();
|
|
6880
|
-
for (const
|
|
6881
|
-
const parts = parsePath(
|
|
6880
|
+
for (const path77 of pathsToClone) {
|
|
6881
|
+
const parts = parsePath(path77);
|
|
6882
6882
|
let current = pathStructure;
|
|
6883
6883
|
for (let i = 0; i < parts.length; i++) {
|
|
6884
6884
|
const part = parts[i];
|
|
@@ -6930,24 +6930,24 @@ var require_redact = __commonJS({
|
|
|
6930
6930
|
}
|
|
6931
6931
|
return cloneSelectively(obj, pathStructure);
|
|
6932
6932
|
}
|
|
6933
|
-
function validatePath(
|
|
6934
|
-
if (typeof
|
|
6933
|
+
function validatePath(path77) {
|
|
6934
|
+
if (typeof path77 !== "string") {
|
|
6935
6935
|
throw new Error("Paths must be (non-empty) strings");
|
|
6936
6936
|
}
|
|
6937
|
-
if (
|
|
6937
|
+
if (path77 === "") {
|
|
6938
6938
|
throw new Error("Invalid redaction path ()");
|
|
6939
6939
|
}
|
|
6940
|
-
if (
|
|
6941
|
-
throw new Error(`Invalid redaction path (${
|
|
6940
|
+
if (path77.includes("..")) {
|
|
6941
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6942
6942
|
}
|
|
6943
|
-
if (
|
|
6944
|
-
throw new Error(`Invalid redaction path (${
|
|
6943
|
+
if (path77.includes(",")) {
|
|
6944
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6945
6945
|
}
|
|
6946
6946
|
let bracketCount = 0;
|
|
6947
6947
|
let inQuotes = false;
|
|
6948
6948
|
let quoteChar = "";
|
|
6949
|
-
for (let i = 0; i <
|
|
6950
|
-
const char =
|
|
6949
|
+
for (let i = 0; i < path77.length; i++) {
|
|
6950
|
+
const char = path77[i];
|
|
6951
6951
|
if ((char === '"' || char === "'") && bracketCount > 0) {
|
|
6952
6952
|
if (!inQuotes) {
|
|
6953
6953
|
inQuotes = true;
|
|
@@ -6961,20 +6961,20 @@ var require_redact = __commonJS({
|
|
|
6961
6961
|
} else if (char === "]" && !inQuotes) {
|
|
6962
6962
|
bracketCount--;
|
|
6963
6963
|
if (bracketCount < 0) {
|
|
6964
|
-
throw new Error(`Invalid redaction path (${
|
|
6964
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6965
6965
|
}
|
|
6966
6966
|
}
|
|
6967
6967
|
}
|
|
6968
6968
|
if (bracketCount !== 0) {
|
|
6969
|
-
throw new Error(`Invalid redaction path (${
|
|
6969
|
+
throw new Error(`Invalid redaction path (${path77})`);
|
|
6970
6970
|
}
|
|
6971
6971
|
}
|
|
6972
6972
|
function validatePaths(paths) {
|
|
6973
6973
|
if (!Array.isArray(paths)) {
|
|
6974
6974
|
throw new TypeError("paths must be an array");
|
|
6975
6975
|
}
|
|
6976
|
-
for (const
|
|
6977
|
-
validatePath(
|
|
6976
|
+
for (const path77 of paths) {
|
|
6977
|
+
validatePath(path77);
|
|
6978
6978
|
}
|
|
6979
6979
|
}
|
|
6980
6980
|
function slowRedact(options = {}) {
|
|
@@ -7142,8 +7142,8 @@ var require_redaction = __commonJS({
|
|
|
7142
7142
|
if (shape[k2] === null) {
|
|
7143
7143
|
o[k2] = (value) => topCensor(value, [k2]);
|
|
7144
7144
|
} else {
|
|
7145
|
-
const wrappedCensor = typeof censor === "function" ? (value,
|
|
7146
|
-
return censor(value, [k2, ...
|
|
7145
|
+
const wrappedCensor = typeof censor === "function" ? (value, path77) => {
|
|
7146
|
+
return censor(value, [k2, ...path77]);
|
|
7147
7147
|
} : censor;
|
|
7148
7148
|
o[k2] = Redact({
|
|
7149
7149
|
paths: shape[k2],
|
|
@@ -7361,10 +7361,10 @@ var require_atomic_sleep = __commonJS({
|
|
|
7361
7361
|
var require_sonic_boom = __commonJS({
|
|
7362
7362
|
"../node_modules/.pnpm/sonic-boom@4.2.1/node_modules/sonic-boom/index.js"(exports2, module2) {
|
|
7363
7363
|
"use strict";
|
|
7364
|
-
var
|
|
7364
|
+
var fs70 = require("fs");
|
|
7365
7365
|
var EventEmitter3 = require("events");
|
|
7366
7366
|
var inherits = require("util").inherits;
|
|
7367
|
-
var
|
|
7367
|
+
var path77 = require("path");
|
|
7368
7368
|
var sleep2 = require_atomic_sleep();
|
|
7369
7369
|
var assert = require("assert");
|
|
7370
7370
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
@@ -7418,20 +7418,20 @@ var require_sonic_boom = __commonJS({
|
|
|
7418
7418
|
const mode = sonic.mode;
|
|
7419
7419
|
if (sonic.sync) {
|
|
7420
7420
|
try {
|
|
7421
|
-
if (sonic.mkdir)
|
|
7422
|
-
const fd =
|
|
7421
|
+
if (sonic.mkdir) fs70.mkdirSync(path77.dirname(file), { recursive: true });
|
|
7422
|
+
const fd = fs70.openSync(file, flags, mode);
|
|
7423
7423
|
fileOpened(null, fd);
|
|
7424
7424
|
} catch (err) {
|
|
7425
7425
|
fileOpened(err);
|
|
7426
7426
|
throw err;
|
|
7427
7427
|
}
|
|
7428
7428
|
} else if (sonic.mkdir) {
|
|
7429
|
-
|
|
7429
|
+
fs70.mkdir(path77.dirname(file), { recursive: true }, (err) => {
|
|
7430
7430
|
if (err) return fileOpened(err);
|
|
7431
|
-
|
|
7431
|
+
fs70.open(file, flags, mode, fileOpened);
|
|
7432
7432
|
});
|
|
7433
7433
|
} else {
|
|
7434
|
-
|
|
7434
|
+
fs70.open(file, flags, mode, fileOpened);
|
|
7435
7435
|
}
|
|
7436
7436
|
}
|
|
7437
7437
|
function SonicBoom(opts) {
|
|
@@ -7472,8 +7472,8 @@ var require_sonic_boom = __commonJS({
|
|
|
7472
7472
|
this.flush = flushBuffer;
|
|
7473
7473
|
this.flushSync = flushBufferSync;
|
|
7474
7474
|
this._actualWrite = actualWriteBuffer;
|
|
7475
|
-
fsWriteSync = () =>
|
|
7476
|
-
fsWrite = () =>
|
|
7475
|
+
fsWriteSync = () => fs70.writeSync(this.fd, this._writingBuf);
|
|
7476
|
+
fsWrite = () => fs70.write(this.fd, this._writingBuf, this.release);
|
|
7477
7477
|
} else if (contentMode === void 0 || contentMode === kContentModeUtf8) {
|
|
7478
7478
|
this._writingBuf = "";
|
|
7479
7479
|
this.write = write;
|
|
@@ -7482,15 +7482,15 @@ var require_sonic_boom = __commonJS({
|
|
|
7482
7482
|
this._actualWrite = actualWrite;
|
|
7483
7483
|
fsWriteSync = () => {
|
|
7484
7484
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7485
|
-
return
|
|
7485
|
+
return fs70.writeSync(this.fd, this._writingBuf);
|
|
7486
7486
|
}
|
|
7487
|
-
return
|
|
7487
|
+
return fs70.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7488
7488
|
};
|
|
7489
7489
|
fsWrite = () => {
|
|
7490
7490
|
if (Buffer.isBuffer(this._writingBuf)) {
|
|
7491
|
-
return
|
|
7491
|
+
return fs70.write(this.fd, this._writingBuf, this.release);
|
|
7492
7492
|
}
|
|
7493
|
-
return
|
|
7493
|
+
return fs70.write(this.fd, this._writingBuf, "utf8", this.release);
|
|
7494
7494
|
};
|
|
7495
7495
|
} else {
|
|
7496
7496
|
throw new Error(`SonicBoom supports "${kContentModeUtf8}" and "${kContentModeBuffer}", but passed ${contentMode}`);
|
|
@@ -7547,7 +7547,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7547
7547
|
}
|
|
7548
7548
|
}
|
|
7549
7549
|
if (this._fsync) {
|
|
7550
|
-
|
|
7550
|
+
fs70.fsyncSync(this.fd);
|
|
7551
7551
|
}
|
|
7552
7552
|
const len = this._len;
|
|
7553
7553
|
if (this._reopening) {
|
|
@@ -7661,7 +7661,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7661
7661
|
const onDrain = () => {
|
|
7662
7662
|
if (!this._fsync) {
|
|
7663
7663
|
try {
|
|
7664
|
-
|
|
7664
|
+
fs70.fsync(this.fd, (err) => {
|
|
7665
7665
|
this._flushPending = false;
|
|
7666
7666
|
cb(err);
|
|
7667
7667
|
});
|
|
@@ -7763,7 +7763,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7763
7763
|
const fd = this.fd;
|
|
7764
7764
|
this.once("ready", () => {
|
|
7765
7765
|
if (fd !== this.fd) {
|
|
7766
|
-
|
|
7766
|
+
fs70.close(fd, (err) => {
|
|
7767
7767
|
if (err) {
|
|
7768
7768
|
return this.emit("error", err);
|
|
7769
7769
|
}
|
|
@@ -7812,7 +7812,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7812
7812
|
buf = this._bufs[0];
|
|
7813
7813
|
}
|
|
7814
7814
|
try {
|
|
7815
|
-
const n = Buffer.isBuffer(buf) ?
|
|
7815
|
+
const n = Buffer.isBuffer(buf) ? fs70.writeSync(this.fd, buf) : fs70.writeSync(this.fd, buf, "utf8");
|
|
7816
7816
|
const releasedBufObj = releaseWritingBuf(buf, this._len, n);
|
|
7817
7817
|
buf = releasedBufObj.writingBuf;
|
|
7818
7818
|
this._len = releasedBufObj.len;
|
|
@@ -7828,7 +7828,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7828
7828
|
}
|
|
7829
7829
|
}
|
|
7830
7830
|
try {
|
|
7831
|
-
|
|
7831
|
+
fs70.fsyncSync(this.fd);
|
|
7832
7832
|
} catch {
|
|
7833
7833
|
}
|
|
7834
7834
|
}
|
|
@@ -7849,7 +7849,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7849
7849
|
buf = mergeBuf(this._bufs[0], this._lens[0]);
|
|
7850
7850
|
}
|
|
7851
7851
|
try {
|
|
7852
|
-
const n =
|
|
7852
|
+
const n = fs70.writeSync(this.fd, buf);
|
|
7853
7853
|
buf = buf.subarray(n);
|
|
7854
7854
|
this._len = Math.max(this._len - n, 0);
|
|
7855
7855
|
if (buf.length <= 0) {
|
|
@@ -7877,13 +7877,13 @@ var require_sonic_boom = __commonJS({
|
|
|
7877
7877
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : this._bufs.shift() || "";
|
|
7878
7878
|
if (this.sync) {
|
|
7879
7879
|
try {
|
|
7880
|
-
const written = Buffer.isBuffer(this._writingBuf) ?
|
|
7880
|
+
const written = Buffer.isBuffer(this._writingBuf) ? fs70.writeSync(this.fd, this._writingBuf) : fs70.writeSync(this.fd, this._writingBuf, "utf8");
|
|
7881
7881
|
release(null, written);
|
|
7882
7882
|
} catch (err) {
|
|
7883
7883
|
release(err);
|
|
7884
7884
|
}
|
|
7885
7885
|
} else {
|
|
7886
|
-
|
|
7886
|
+
fs70.write(this.fd, this._writingBuf, release);
|
|
7887
7887
|
}
|
|
7888
7888
|
}
|
|
7889
7889
|
function actualWriteBuffer() {
|
|
@@ -7892,7 +7892,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7892
7892
|
this._writingBuf = this._writingBuf.length ? this._writingBuf : mergeBuf(this._bufs.shift(), this._lens.shift());
|
|
7893
7893
|
if (this.sync) {
|
|
7894
7894
|
try {
|
|
7895
|
-
const written =
|
|
7895
|
+
const written = fs70.writeSync(this.fd, this._writingBuf);
|
|
7896
7896
|
release(null, written);
|
|
7897
7897
|
} catch (err) {
|
|
7898
7898
|
release(err);
|
|
@@ -7901,7 +7901,7 @@ var require_sonic_boom = __commonJS({
|
|
|
7901
7901
|
if (kCopyBuffer) {
|
|
7902
7902
|
this._writingBuf = Buffer.from(this._writingBuf);
|
|
7903
7903
|
}
|
|
7904
|
-
|
|
7904
|
+
fs70.write(this.fd, this._writingBuf, release);
|
|
7905
7905
|
}
|
|
7906
7906
|
}
|
|
7907
7907
|
function actualClose(sonic) {
|
|
@@ -7917,12 +7917,12 @@ var require_sonic_boom = __commonJS({
|
|
|
7917
7917
|
sonic._lens = [];
|
|
7918
7918
|
assert(typeof sonic.fd === "number", `sonic.fd must be a number, got ${typeof sonic.fd}`);
|
|
7919
7919
|
try {
|
|
7920
|
-
|
|
7920
|
+
fs70.fsync(sonic.fd, closeWrapped);
|
|
7921
7921
|
} catch {
|
|
7922
7922
|
}
|
|
7923
7923
|
function closeWrapped() {
|
|
7924
7924
|
if (sonic.fd !== 1 && sonic.fd !== 2) {
|
|
7925
|
-
|
|
7925
|
+
fs70.close(sonic.fd, done);
|
|
7926
7926
|
} else {
|
|
7927
7927
|
done();
|
|
7928
7928
|
}
|
|
@@ -11057,11 +11057,11 @@ var init_lib = __esm({
|
|
|
11057
11057
|
}
|
|
11058
11058
|
}
|
|
11059
11059
|
},
|
|
11060
|
-
addToPath: function addToPath(
|
|
11061
|
-
var last =
|
|
11060
|
+
addToPath: function addToPath(path77, added, removed, oldPosInc, options) {
|
|
11061
|
+
var last = path77.lastComponent;
|
|
11062
11062
|
if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
|
|
11063
11063
|
return {
|
|
11064
|
-
oldPos:
|
|
11064
|
+
oldPos: path77.oldPos + oldPosInc,
|
|
11065
11065
|
lastComponent: {
|
|
11066
11066
|
count: last.count + 1,
|
|
11067
11067
|
added,
|
|
@@ -11071,7 +11071,7 @@ var init_lib = __esm({
|
|
|
11071
11071
|
};
|
|
11072
11072
|
} else {
|
|
11073
11073
|
return {
|
|
11074
|
-
oldPos:
|
|
11074
|
+
oldPos: path77.oldPos + oldPosInc,
|
|
11075
11075
|
lastComponent: {
|
|
11076
11076
|
count: 1,
|
|
11077
11077
|
added,
|
|
@@ -11537,10 +11537,10 @@ function attachmentToHistoryMessage(o, ts) {
|
|
|
11537
11537
|
const memories = raw.map((m2) => {
|
|
11538
11538
|
if (!m2 || typeof m2 !== "object") return null;
|
|
11539
11539
|
const rec3 = m2;
|
|
11540
|
-
const
|
|
11540
|
+
const path77 = typeof rec3.path === "string" ? rec3.path : null;
|
|
11541
11541
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
11542
|
-
if (!
|
|
11543
|
-
const entry = { path:
|
|
11542
|
+
if (!path77 || content == null) return null;
|
|
11543
|
+
const entry = { path: path77, content };
|
|
11544
11544
|
if (typeof rec3.mtimeMs === "number") entry.mtimeMs = rec3.mtimeMs;
|
|
11545
11545
|
return entry;
|
|
11546
11546
|
}).filter((m2) => m2 !== null);
|
|
@@ -12360,10 +12360,10 @@ function parseAttachment(obj) {
|
|
|
12360
12360
|
const memories = raw.map((m2) => {
|
|
12361
12361
|
if (!m2 || typeof m2 !== "object") return null;
|
|
12362
12362
|
const rec3 = m2;
|
|
12363
|
-
const
|
|
12363
|
+
const path77 = typeof rec3.path === "string" ? rec3.path : null;
|
|
12364
12364
|
const content = typeof rec3.content === "string" ? rec3.content : null;
|
|
12365
|
-
if (!
|
|
12366
|
-
const out = { path:
|
|
12365
|
+
if (!path77 || content == null) return null;
|
|
12366
|
+
const out = { path: path77, content };
|
|
12367
12367
|
if (typeof rec3.mtimeMs === "number") out.mtimeMs = rec3.mtimeMs;
|
|
12368
12368
|
return out;
|
|
12369
12369
|
}).filter((m2) => m2 !== null);
|
|
@@ -33460,8 +33460,8 @@ var require_utils = __commonJS({
|
|
|
33460
33460
|
var result = transform[inputType][outputType](input);
|
|
33461
33461
|
return result;
|
|
33462
33462
|
};
|
|
33463
|
-
exports2.resolve = function(
|
|
33464
|
-
var parts =
|
|
33463
|
+
exports2.resolve = function(path77) {
|
|
33464
|
+
var parts = path77.split("/");
|
|
33465
33465
|
var result = [];
|
|
33466
33466
|
for (var index = 0; index < parts.length; index++) {
|
|
33467
33467
|
var part = parts[index];
|
|
@@ -39314,18 +39314,18 @@ var require_object = __commonJS({
|
|
|
39314
39314
|
var object = new ZipObject(name, zipObjectContent, o);
|
|
39315
39315
|
this.files[name] = object;
|
|
39316
39316
|
};
|
|
39317
|
-
var parentFolder = function(
|
|
39318
|
-
if (
|
|
39319
|
-
|
|
39317
|
+
var parentFolder = function(path77) {
|
|
39318
|
+
if (path77.slice(-1) === "/") {
|
|
39319
|
+
path77 = path77.substring(0, path77.length - 1);
|
|
39320
39320
|
}
|
|
39321
|
-
var lastSlash =
|
|
39322
|
-
return lastSlash > 0 ?
|
|
39321
|
+
var lastSlash = path77.lastIndexOf("/");
|
|
39322
|
+
return lastSlash > 0 ? path77.substring(0, lastSlash) : "";
|
|
39323
39323
|
};
|
|
39324
|
-
var forceTrailingSlash = function(
|
|
39325
|
-
if (
|
|
39326
|
-
|
|
39324
|
+
var forceTrailingSlash = function(path77) {
|
|
39325
|
+
if (path77.slice(-1) !== "/") {
|
|
39326
|
+
path77 += "/";
|
|
39327
39327
|
}
|
|
39328
|
-
return
|
|
39328
|
+
return path77;
|
|
39329
39329
|
};
|
|
39330
39330
|
var folderAdd = function(name, createFolders) {
|
|
39331
39331
|
createFolders = typeof createFolders !== "undefined" ? createFolders : defaults.createFolders;
|
|
@@ -40324,10 +40324,53 @@ var require_lib3 = __commonJS({
|
|
|
40324
40324
|
}
|
|
40325
40325
|
});
|
|
40326
40326
|
|
|
40327
|
+
// src/sshd/contact-ssh-log.ts
|
|
40328
|
+
function createContactSshLog(dataDir) {
|
|
40329
|
+
const file = import_node_path40.default.join(dataDir, "contact-ssh.log");
|
|
40330
|
+
function append(level, tag, message, meta) {
|
|
40331
|
+
const time = (/* @__PURE__ */ new Date()).toISOString();
|
|
40332
|
+
let line = `[${time}] [${level}] [${tag}] ${message}`;
|
|
40333
|
+
if (meta && Object.keys(meta).length > 0) {
|
|
40334
|
+
try {
|
|
40335
|
+
line += " " + JSON.stringify(meta);
|
|
40336
|
+
} catch {
|
|
40337
|
+
line += " [meta-serialize-failed]";
|
|
40338
|
+
}
|
|
40339
|
+
}
|
|
40340
|
+
line += "\n";
|
|
40341
|
+
try {
|
|
40342
|
+
import_node_fs39.default.mkdirSync(import_node_path40.default.dirname(file), { recursive: true });
|
|
40343
|
+
import_node_fs39.default.appendFileSync(file, line, { mode: 384 });
|
|
40344
|
+
} catch {
|
|
40345
|
+
}
|
|
40346
|
+
}
|
|
40347
|
+
return {
|
|
40348
|
+
info: (tag, message, meta) => append("INFO", tag, message, meta),
|
|
40349
|
+
warn: (tag, message, meta) => append("WARN", tag, message, meta),
|
|
40350
|
+
error: (tag, message, meta) => append("ERROR", tag, message, meta)
|
|
40351
|
+
};
|
|
40352
|
+
}
|
|
40353
|
+
var import_node_fs39, import_node_path40, nullContactSshLog;
|
|
40354
|
+
var init_contact_ssh_log = __esm({
|
|
40355
|
+
"src/sshd/contact-ssh-log.ts"() {
|
|
40356
|
+
"use strict";
|
|
40357
|
+
import_node_fs39 = __toESM(require("fs"), 1);
|
|
40358
|
+
import_node_path40 = __toESM(require("path"), 1);
|
|
40359
|
+
nullContactSshLog = {
|
|
40360
|
+
info: () => {
|
|
40361
|
+
},
|
|
40362
|
+
warn: () => {
|
|
40363
|
+
},
|
|
40364
|
+
error: () => {
|
|
40365
|
+
}
|
|
40366
|
+
};
|
|
40367
|
+
}
|
|
40368
|
+
});
|
|
40369
|
+
|
|
40327
40370
|
// src/run-case/recorder.ts
|
|
40328
40371
|
function startRunCaseRecorder(opts) {
|
|
40329
40372
|
const now = opts.now ?? Date.now;
|
|
40330
|
-
const dir =
|
|
40373
|
+
const dir = import_node_path64.default.dirname(opts.recordPath);
|
|
40331
40374
|
let stream = null;
|
|
40332
40375
|
let closing = false;
|
|
40333
40376
|
let closedSettled = false;
|
|
@@ -40341,8 +40384,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40341
40384
|
});
|
|
40342
40385
|
const ensureStream = () => {
|
|
40343
40386
|
if (stream) return stream;
|
|
40344
|
-
|
|
40345
|
-
stream =
|
|
40387
|
+
import_node_fs51.default.mkdirSync(dir, { recursive: true });
|
|
40388
|
+
stream = import_node_fs51.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40346
40389
|
stream.on("close", () => closedResolve());
|
|
40347
40390
|
return stream;
|
|
40348
40391
|
};
|
|
@@ -40367,12 +40410,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40367
40410
|
};
|
|
40368
40411
|
return { tap, close, closed };
|
|
40369
40412
|
}
|
|
40370
|
-
var
|
|
40413
|
+
var import_node_fs51, import_node_path64;
|
|
40371
40414
|
var init_recorder = __esm({
|
|
40372
40415
|
"src/run-case/recorder.ts"() {
|
|
40373
40416
|
"use strict";
|
|
40374
|
-
|
|
40375
|
-
|
|
40417
|
+
import_node_fs51 = __toESM(require("fs"), 1);
|
|
40418
|
+
import_node_path64 = __toESM(require("path"), 1);
|
|
40376
40419
|
}
|
|
40377
40420
|
});
|
|
40378
40421
|
|
|
@@ -40415,7 +40458,7 @@ var init_wire = __esm({
|
|
|
40415
40458
|
// src/run-case/controller.ts
|
|
40416
40459
|
async function runController(opts) {
|
|
40417
40460
|
const now = opts.now ?? Date.now;
|
|
40418
|
-
const cwd = opts.cwd ?? (0,
|
|
40461
|
+
const cwd = opts.cwd ?? (0, import_node_fs52.mkdtempSync)(import_node_path65.default.join(import_node_os22.default.tmpdir(), "clawd-runcase-"));
|
|
40419
40462
|
const ownsCwd = opts.cwd === void 0;
|
|
40420
40463
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40421
40464
|
const spawnCtx = { cwd };
|
|
@@ -40576,19 +40619,19 @@ async function runController(opts) {
|
|
|
40576
40619
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40577
40620
|
if (ownsCwd) {
|
|
40578
40621
|
try {
|
|
40579
|
-
(0,
|
|
40622
|
+
(0, import_node_fs52.rmSync)(cwd, { recursive: true, force: true });
|
|
40580
40623
|
} catch {
|
|
40581
40624
|
}
|
|
40582
40625
|
}
|
|
40583
40626
|
return exitCode ?? 0;
|
|
40584
40627
|
}
|
|
40585
|
-
var
|
|
40628
|
+
var import_node_fs52, import_node_os22, import_node_path65;
|
|
40586
40629
|
var init_controller = __esm({
|
|
40587
40630
|
"src/run-case/controller.ts"() {
|
|
40588
40631
|
"use strict";
|
|
40589
|
-
|
|
40632
|
+
import_node_fs52 = require("fs");
|
|
40590
40633
|
import_node_os22 = __toESM(require("os"), 1);
|
|
40591
|
-
|
|
40634
|
+
import_node_path65 = __toESM(require("path"), 1);
|
|
40592
40635
|
init_claude();
|
|
40593
40636
|
init_stdout_splitter();
|
|
40594
40637
|
init_permission_stdio();
|
|
@@ -40699,14 +40742,23 @@ async function sshRelay(argv) {
|
|
|
40699
40742
|
process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
|
|
40700
40743
|
return 2;
|
|
40701
40744
|
}
|
|
40702
|
-
const dataDir = args.dataDir ??
|
|
40745
|
+
const dataDir = args.dataDir ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
|
|
40746
|
+
const sshLog = createContactSshLog(dataDir);
|
|
40703
40747
|
const contact = findContact(dataDir, args.peerDeviceId);
|
|
40704
40748
|
if (!contact) {
|
|
40749
|
+
sshLog.error("relay.contact-not-found", "ssh-relay \u627E\u4E0D\u5230 peer contact", {
|
|
40750
|
+
peerDeviceId: args.peerDeviceId,
|
|
40751
|
+
contactsPath: import_node_path66.default.join(dataDir, "contacts.json")
|
|
40752
|
+
});
|
|
40705
40753
|
process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
|
|
40706
40754
|
`);
|
|
40707
40755
|
return 2;
|
|
40708
40756
|
}
|
|
40709
40757
|
if (!contact.connectToken) {
|
|
40758
|
+
sshLog.error("relay.token-missing", "contact \u6709\u8BB0\u5F55\u4F46\u7F3A connectToken\uFF08auto-reverse \u672A\u6362\u7968\uFF09", {
|
|
40759
|
+
peerDeviceId: args.peerDeviceId,
|
|
40760
|
+
peerDisplayName: contact.displayName
|
|
40761
|
+
});
|
|
40710
40762
|
process.stderr.write(
|
|
40711
40763
|
`clawd ssh-relay: contact ${args.peerDeviceId} has no connectToken (auto-reverse \u672A\u6362\u7968)
|
|
40712
40764
|
`
|
|
@@ -40716,6 +40768,11 @@ async function sshRelay(argv) {
|
|
|
40716
40768
|
const baseHttp = wsUrlToHttp(contact.remoteUrl).replace(/\/+$/, "");
|
|
40717
40769
|
const wsBase = baseHttp.replace(/^http:/, "ws:").replace(/^https:/, "wss:");
|
|
40718
40770
|
const url = `${wsBase}/rpc/ssh-tunnel`;
|
|
40771
|
+
sshLog.info("relay.dial", "\u5F00\u59CB\u62E8 A \u4FA7 /rpc/ssh-tunnel", {
|
|
40772
|
+
peerDeviceId: args.peerDeviceId,
|
|
40773
|
+
peerDisplayName: contact.displayName,
|
|
40774
|
+
url
|
|
40775
|
+
});
|
|
40719
40776
|
return new Promise((resolve6) => {
|
|
40720
40777
|
const ws = new import_websocket.default(url, {
|
|
40721
40778
|
headers: {
|
|
@@ -40735,6 +40792,9 @@ async function sshRelay(argv) {
|
|
|
40735
40792
|
resolve6(exitCode);
|
|
40736
40793
|
};
|
|
40737
40794
|
ws.on("open", () => {
|
|
40795
|
+
sshLog.info("relay.dial-open", "ws open\uFF0C\u8FDB\u5165 stdio \u2194 ws \u4E2D\u7EE7", {
|
|
40796
|
+
peerDeviceId: args.peerDeviceId
|
|
40797
|
+
});
|
|
40738
40798
|
process.stdin.on("data", (chunk) => {
|
|
40739
40799
|
if (ws.readyState === ws.OPEN) {
|
|
40740
40800
|
ws.send(chunk, { binary: true });
|
|
@@ -40759,9 +40819,25 @@ async function sshRelay(argv) {
|
|
|
40759
40819
|
}
|
|
40760
40820
|
});
|
|
40761
40821
|
ws.on("close", (code) => {
|
|
40822
|
+
if (code === 1e3) {
|
|
40823
|
+
sshLog.info("relay.dial-close", "ws \u6B63\u5E38\u5173\u95ED", {
|
|
40824
|
+
peerDeviceId: args.peerDeviceId,
|
|
40825
|
+
code
|
|
40826
|
+
});
|
|
40827
|
+
} else {
|
|
40828
|
+
sshLog.warn("relay.dial-close-abnormal", "ws \u975E\u6B63\u5E38\u5173\u95ED\uFF08A \u4FA7\u62D2 auth / \u7F51\u7EDC\u65AD / peer \u5D29\uFF09", {
|
|
40829
|
+
peerDeviceId: args.peerDeviceId,
|
|
40830
|
+
code
|
|
40831
|
+
});
|
|
40832
|
+
}
|
|
40762
40833
|
settle(code === 1e3 ? 0 : 1);
|
|
40763
40834
|
});
|
|
40764
40835
|
ws.on("error", (err) => {
|
|
40836
|
+
sshLog.error("relay.dial-error", "ws \u8FDE\u63A5\u9519\u8BEF\uFF08peer \u4E0D\u53EF\u8FBE / \u7AEF\u53E3\u4E0D\u901A / TLS \u5931\u8D25\uFF09", {
|
|
40837
|
+
peerDeviceId: args.peerDeviceId,
|
|
40838
|
+
url,
|
|
40839
|
+
message: err.message
|
|
40840
|
+
});
|
|
40765
40841
|
process.stderr.write(`clawd ssh-relay: ws error ${err.message}
|
|
40766
40842
|
`);
|
|
40767
40843
|
settle(1);
|
|
@@ -40793,10 +40869,10 @@ function parseSshRelayArgs(argv) {
|
|
|
40793
40869
|
return out;
|
|
40794
40870
|
}
|
|
40795
40871
|
function findContact(dataDir, deviceId) {
|
|
40796
|
-
const file =
|
|
40872
|
+
const file = import_node_path66.default.join(dataDir, "contacts.json");
|
|
40797
40873
|
let raw;
|
|
40798
40874
|
try {
|
|
40799
|
-
raw =
|
|
40875
|
+
raw = import_node_fs53.default.readFileSync(file, "utf8");
|
|
40800
40876
|
} catch {
|
|
40801
40877
|
return null;
|
|
40802
40878
|
}
|
|
@@ -40814,16 +40890,17 @@ function findContact(dataDir, deviceId) {
|
|
|
40814
40890
|
}
|
|
40815
40891
|
return null;
|
|
40816
40892
|
}
|
|
40817
|
-
var
|
|
40893
|
+
var import_node_fs53, import_node_os23, import_node_path66, SSH_RELAY_HELP;
|
|
40818
40894
|
var init_sshd_cli_relay = __esm({
|
|
40819
40895
|
"src/sshd/sshd-cli-relay.ts"() {
|
|
40820
40896
|
"use strict";
|
|
40821
|
-
|
|
40897
|
+
import_node_fs53 = __toESM(require("fs"), 1);
|
|
40822
40898
|
import_node_os23 = __toESM(require("os"), 1);
|
|
40823
|
-
|
|
40899
|
+
import_node_path66 = __toESM(require("path"), 1);
|
|
40824
40900
|
init_wrapper();
|
|
40825
40901
|
init_src();
|
|
40826
40902
|
init_peer_forward();
|
|
40903
|
+
init_contact_ssh_log();
|
|
40827
40904
|
SSH_RELAY_HELP = `clawd ssh-relay <peer-device-id> [options]
|
|
40828
40905
|
|
|
40829
40906
|
WebSocket relay to a peer daemon's /rpc/ssh-tunnel, exposing raw SSH bytes on
|
|
@@ -41023,8 +41100,8 @@ Env (advanced):
|
|
|
41023
41100
|
`;
|
|
41024
41101
|
|
|
41025
41102
|
// src/index.ts
|
|
41026
|
-
var
|
|
41027
|
-
var
|
|
41103
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
41104
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
41028
41105
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
41029
41106
|
|
|
41030
41107
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -41738,6 +41815,7 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
41738
41815
|
fsv.allowRead = unionArr(fsv.allowRead, [
|
|
41739
41816
|
"~/.clawd/contact-ssh-keys",
|
|
41740
41817
|
"~/.clawd/contacts.json",
|
|
41818
|
+
"~/.clawd/bin",
|
|
41741
41819
|
"~/Library/Application Support/@clawos/clawd-desktop/ota-bundles",
|
|
41742
41820
|
"~/.clawd/config.json",
|
|
41743
41821
|
"~/.clawd/auth.json"
|
|
@@ -41891,12 +41969,14 @@ var CONTACT_SSH_SYSTEM_PROMPT_HINT = `## \u8DE8\u8BBE\u5907\u6587\u4EF6\u8BBF\u9
|
|
|
41891
41969
|
\uFF08\u6BCF\u4E2A \`<deviceId>.ed25519\` \u5C31\u662F\u4E00\u628A privkey\uFF0C\u53BB\u6389\u540E\u7F00\u5C31\u662F deviceId\uFF09
|
|
41892
41970
|
2. \u7528 SSH \u62E8\u53F7\uFF08\u628A \`<A>\` \u6362\u6210\u5B9E\u9645 deviceId\uFF09\uFF1A
|
|
41893
41971
|
\`\`\`bash
|
|
41894
|
-
ssh -o ProxyCommand='clawd ssh-relay <A>' \\
|
|
41972
|
+
ssh -o ProxyCommand='~/.clawd/bin/clawd ssh-relay <A>' \\
|
|
41895
41973
|
-i ~/.clawd/contact-ssh-keys/<A>.ed25519 \\
|
|
41896
41974
|
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \\
|
|
41897
41975
|
$USER@127.0.0.1 <command>
|
|
41898
41976
|
# \u4F8B\u5982\uFF1A... $USER@127.0.0.1 cat /Users/xxx/some/file.md
|
|
41899
41977
|
# ... $USER@127.0.0.1 ls -la /Users/xxx/proj
|
|
41978
|
+
# \u8BF4\u660E\uFF1A\`~/.clawd/bin/clawd\` \u662F daemon \u542F\u52A8\u65F6 seed \u7684 shim\uFF0C\u786C\u7F16\u7801\u5F53\u524D daemon \u7684
|
|
41979
|
+
# 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
|
|
41900
41980
|
\`\`\`
|
|
41901
41981
|
|
|
41902
41982
|
**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
|
|
@@ -46566,8 +46646,8 @@ function turnStartInput(text) {
|
|
|
46566
46646
|
const items = [];
|
|
46567
46647
|
let leftover = text;
|
|
46568
46648
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46569
|
-
const [marker, name,
|
|
46570
|
-
items.push({ type: "skill", name, path:
|
|
46649
|
+
const [marker, name, path77] = m2;
|
|
46650
|
+
items.push({ type: "skill", name, path: path77 });
|
|
46571
46651
|
leftover = leftover.replace(marker, "");
|
|
46572
46652
|
}
|
|
46573
46653
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -49021,13 +49101,13 @@ function mapSkillsListResponse(res) {
|
|
|
49021
49101
|
const r = s ?? {};
|
|
49022
49102
|
const name = str3(r.name);
|
|
49023
49103
|
if (!name) continue;
|
|
49024
|
-
const
|
|
49104
|
+
const path77 = str3(r.path);
|
|
49025
49105
|
const description = str3(r.description);
|
|
49026
49106
|
const isPlugin = name.includes(":");
|
|
49027
49107
|
out.push({
|
|
49028
49108
|
name,
|
|
49029
49109
|
source: isPlugin ? "plugin" : "project",
|
|
49030
|
-
...
|
|
49110
|
+
...path77 ? { path: path77 } : {},
|
|
49031
49111
|
...description ? { description } : {},
|
|
49032
49112
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
49033
49113
|
});
|
|
@@ -52999,8 +53079,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
52999
53079
|
}
|
|
53000
53080
|
|
|
53001
53081
|
// src/sshd/sshd-manager.ts
|
|
53002
|
-
var
|
|
53003
|
-
var
|
|
53082
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53083
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
53004
53084
|
var import_node_child_process11 = require("child_process");
|
|
53005
53085
|
|
|
53006
53086
|
// src/sshd/sshd-config.ts
|
|
@@ -53283,11 +53363,35 @@ function ensureJailScript(dataDir) {
|
|
|
53283
53363
|
return target;
|
|
53284
53364
|
}
|
|
53285
53365
|
|
|
53366
|
+
// src/sshd/clawd-shim.ts
|
|
53367
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
53368
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
53369
|
+
function shellQuote(s) {
|
|
53370
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
53371
|
+
}
|
|
53372
|
+
function buildClawdShim(execPath, cliPath) {
|
|
53373
|
+
return `#!/usr/bin/env bash
|
|
53374
|
+
# clawd shim (managed by clawd; do not edit)
|
|
53375
|
+
#
|
|
53376
|
+
# \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
|
|
53377
|
+
# guest CC \u7528 SSH ProxyCommand \u8D70 ~/.clawd/bin/clawd ssh-relay \u65F6\u4F1A\u547D\u4E2D\u672C shim\uFF0C\u4FDD\u8BC1
|
|
53378
|
+
# relay \u4E8C\u8FDB\u5236\u8DDF\u5F53\u524D\u8DD1\u7740\u7684 daemon \u540C\u6E90\u540C\u7248\u672C\u3002
|
|
53379
|
+
exec ${shellQuote(execPath)} ${shellQuote(cliPath)} "$@"
|
|
53380
|
+
`;
|
|
53381
|
+
}
|
|
53382
|
+
function ensureClawdShim(dataDir, execPath, cliPath) {
|
|
53383
|
+
const binDir = import_node_path37.default.join(dataDir, "bin");
|
|
53384
|
+
import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
|
|
53385
|
+
const target = import_node_path37.default.join(binDir, "clawd");
|
|
53386
|
+
import_node_fs36.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
|
|
53387
|
+
return target;
|
|
53388
|
+
}
|
|
53389
|
+
|
|
53286
53390
|
// src/sshd/sshd-manager.ts
|
|
53287
53391
|
var SshdManager = class {
|
|
53288
53392
|
constructor(deps) {
|
|
53289
53393
|
this.deps = deps;
|
|
53290
|
-
this.sshdDir =
|
|
53394
|
+
this.sshdDir = import_node_path38.default.join(deps.dataDir, "sshd");
|
|
53291
53395
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
53292
53396
|
}
|
|
53293
53397
|
deps;
|
|
@@ -53306,31 +53410,32 @@ var SshdManager = class {
|
|
|
53306
53410
|
ownPid: process.pid,
|
|
53307
53411
|
logger
|
|
53308
53412
|
});
|
|
53309
|
-
|
|
53310
|
-
|
|
53413
|
+
import_node_fs37.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
|
|
53414
|
+
import_node_fs37.default.mkdirSync(import_node_path38.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
|
|
53311
53415
|
ensureJailScript(this.deps.dataDir);
|
|
53312
|
-
|
|
53313
|
-
|
|
53416
|
+
ensureClawdShim(this.deps.dataDir, process.execPath, process.argv[1] ?? "");
|
|
53417
|
+
const hostKeyPath = import_node_path38.default.join(this.sshdDir, "host_key");
|
|
53418
|
+
if (!import_node_fs37.default.existsSync(hostKeyPath)) {
|
|
53314
53419
|
await this.generateHostKey(hostKeyPath);
|
|
53315
53420
|
}
|
|
53316
|
-
const akFile =
|
|
53317
|
-
if (!
|
|
53318
|
-
|
|
53421
|
+
const akFile = import_node_path38.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
|
|
53422
|
+
if (!import_node_fs37.default.existsSync(akFile)) {
|
|
53423
|
+
import_node_fs37.default.writeFileSync(akFile, "", { mode: 384 });
|
|
53319
53424
|
}
|
|
53320
|
-
const configPath =
|
|
53425
|
+
const configPath = import_node_path38.default.join(this.sshdDir, "sshd_config");
|
|
53321
53426
|
const config = buildSshdConfig({
|
|
53322
53427
|
listenAddress: "127.0.0.1",
|
|
53323
53428
|
port: this.deps.port,
|
|
53324
53429
|
hostKeyPath,
|
|
53325
53430
|
authorizedKeysFile: akFile,
|
|
53326
|
-
pidFilePath:
|
|
53431
|
+
pidFilePath: import_node_path38.default.join(this.sshdDir, "sshd.pid")
|
|
53327
53432
|
});
|
|
53328
|
-
|
|
53433
|
+
import_node_fs37.default.writeFileSync(configPath, config, { mode: 384 });
|
|
53329
53434
|
const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
|
|
53330
53435
|
const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
|
|
53331
53436
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53332
53437
|
});
|
|
53333
|
-
const logStream =
|
|
53438
|
+
const logStream = import_node_fs37.default.createWriteStream(import_node_path38.default.join(this.sshdDir, "sshd.log"), {
|
|
53334
53439
|
flags: "a",
|
|
53335
53440
|
mode: 384
|
|
53336
53441
|
});
|
|
@@ -53423,7 +53528,7 @@ ${tail}` : ready.error;
|
|
|
53423
53528
|
p2.on("error", reject);
|
|
53424
53529
|
});
|
|
53425
53530
|
try {
|
|
53426
|
-
|
|
53531
|
+
import_node_fs37.default.chmodSync(hostKeyPath, 384);
|
|
53427
53532
|
} catch {
|
|
53428
53533
|
}
|
|
53429
53534
|
}
|
|
@@ -53466,17 +53571,17 @@ async function waitForSshdReady(proc, timeoutMs) {
|
|
|
53466
53571
|
}
|
|
53467
53572
|
|
|
53468
53573
|
// src/sshd/authorized-keys.ts
|
|
53469
|
-
var
|
|
53470
|
-
var
|
|
53574
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53575
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53471
53576
|
var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
|
|
53472
53577
|
var AUTHORIZED_KEYS_FILE = "clawd-contacts";
|
|
53473
53578
|
function jailBinPath() {
|
|
53474
|
-
return process.env[JAIL_BIN_PATH_ENV] ??
|
|
53579
|
+
return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path39.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
|
|
53475
53580
|
}
|
|
53476
53581
|
function rebuildAuthorizedKeys(store, sshdDir) {
|
|
53477
|
-
const akDir =
|
|
53478
|
-
const target =
|
|
53479
|
-
|
|
53582
|
+
const akDir = import_node_path39.default.join(sshdDir, "authorized_keys.d");
|
|
53583
|
+
const target = import_node_path39.default.join(akDir, AUTHORIZED_KEYS_FILE);
|
|
53584
|
+
import_node_fs38.default.mkdirSync(akDir, { recursive: true, mode: 448 });
|
|
53480
53585
|
const lines = ["# managed by clawd; do not edit", ""];
|
|
53481
53586
|
for (const c of store.list()) {
|
|
53482
53587
|
if (!c.sshAllowed) continue;
|
|
@@ -53490,66 +53595,28 @@ function rebuildAuthorizedKeys(store, sshdDir) {
|
|
|
53490
53595
|
}
|
|
53491
53596
|
const body = lines.join("\n") + "\n";
|
|
53492
53597
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
53493
|
-
|
|
53494
|
-
|
|
53598
|
+
import_node_fs38.default.writeFileSync(tmp, body, { mode: 384 });
|
|
53599
|
+
import_node_fs38.default.renameSync(tmp, target);
|
|
53495
53600
|
}
|
|
53496
53601
|
function readIssuedPubkey(sshdDir, deviceId) {
|
|
53497
53602
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53498
|
-
const p2 =
|
|
53603
|
+
const p2 = import_node_path39.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
|
|
53499
53604
|
try {
|
|
53500
|
-
return
|
|
53605
|
+
return import_node_fs38.default.readFileSync(p2, "utf8");
|
|
53501
53606
|
} catch {
|
|
53502
53607
|
return null;
|
|
53503
53608
|
}
|
|
53504
53609
|
}
|
|
53505
53610
|
|
|
53506
53611
|
// src/sshd/contact-key-puller.ts
|
|
53507
|
-
var
|
|
53508
|
-
var
|
|
53612
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
53613
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
53509
53614
|
init_peer_forward();
|
|
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
|
|
53615
|
+
init_contact_ssh_log();
|
|
53549
53616
|
var CONTACT_KEYS_DIR = "contact-ssh-keys";
|
|
53550
53617
|
function safeContactKeyPath(dataDir, deviceId) {
|
|
53551
53618
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53552
|
-
return
|
|
53619
|
+
return import_node_path41.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
|
|
53553
53620
|
}
|
|
53554
53621
|
async function pullContactSshKeyOnce(deps) {
|
|
53555
53622
|
const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
|
|
@@ -53615,12 +53682,12 @@ async function pullContactSshKeyOnce(deps) {
|
|
|
53615
53682
|
}
|
|
53616
53683
|
function writeKeyFile(dataDir, deviceId, pem) {
|
|
53617
53684
|
const p2 = safeContactKeyPath(dataDir, deviceId);
|
|
53618
|
-
|
|
53619
|
-
|
|
53685
|
+
import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(p2), { recursive: true, mode: 448 });
|
|
53686
|
+
import_node_fs40.default.writeFileSync(p2, pem, { mode: 384 });
|
|
53620
53687
|
}
|
|
53621
53688
|
function removeKeyFile(dataDir, deviceId) {
|
|
53622
53689
|
try {
|
|
53623
|
-
|
|
53690
|
+
import_node_fs40.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
|
|
53624
53691
|
return true;
|
|
53625
53692
|
} catch {
|
|
53626
53693
|
return false;
|
|
@@ -53657,6 +53724,7 @@ var ContactKeyPuller = class {
|
|
|
53657
53724
|
|
|
53658
53725
|
// src/sshd/ssh-tunnel-relay.ts
|
|
53659
53726
|
var import_node_net2 = __toESM(require("net"), 1);
|
|
53727
|
+
init_contact_ssh_log();
|
|
53660
53728
|
async function handleSshTunnelUpgrade(req, socket, head, deps) {
|
|
53661
53729
|
const sshLog = deps.sshLog ?? nullContactSshLog;
|
|
53662
53730
|
const clientAddr = (req.socket && "remoteAddress" in req.socket ? req.socket.remoteAddress : null) ?? "unknown";
|
|
@@ -53764,29 +53832,32 @@ function pumpWsToSshd(ws, deps, clientAddr) {
|
|
|
53764
53832
|
});
|
|
53765
53833
|
}
|
|
53766
53834
|
|
|
53835
|
+
// src/index.ts
|
|
53836
|
+
init_contact_ssh_log();
|
|
53837
|
+
|
|
53767
53838
|
// src/tunnel/device-key.ts
|
|
53768
53839
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
53769
|
-
var
|
|
53840
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
53770
53841
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
53771
53842
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
53772
53843
|
function deriveStableDeviceKey(opts = {}) {
|
|
53773
53844
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
53774
53845
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
53775
53846
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
53776
|
-
const defaultDataDir =
|
|
53777
|
-
const normalizedDataDir = opts.dataDir ?
|
|
53847
|
+
const defaultDataDir = import_node_path42.default.resolve(import_node_path42.default.join(home, ".clawd"));
|
|
53848
|
+
const normalizedDataDir = opts.dataDir ? import_node_path42.default.resolve(opts.dataDir) : null;
|
|
53778
53849
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
53779
53850
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
53780
53851
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
53781
53852
|
}
|
|
53782
53853
|
|
|
53783
53854
|
// src/auth-store.ts
|
|
53784
|
-
var
|
|
53785
|
-
var
|
|
53855
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
53856
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
53786
53857
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
53787
53858
|
var AUTH_FILE_NAME = "auth.json";
|
|
53788
53859
|
function authFilePath(dataDir) {
|
|
53789
|
-
return
|
|
53860
|
+
return import_node_path43.default.join(dataDir, AUTH_FILE_NAME);
|
|
53790
53861
|
}
|
|
53791
53862
|
function loadOrCreateAuthFile(opts) {
|
|
53792
53863
|
const file = authFilePath(opts.dataDir);
|
|
@@ -53822,7 +53893,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
53822
53893
|
}
|
|
53823
53894
|
function readAuthFile(file) {
|
|
53824
53895
|
try {
|
|
53825
|
-
const raw =
|
|
53896
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
53826
53897
|
const parsed = JSON.parse(raw);
|
|
53827
53898
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
53828
53899
|
return null;
|
|
@@ -53842,25 +53913,25 @@ function readAuthFile(file) {
|
|
|
53842
53913
|
}
|
|
53843
53914
|
}
|
|
53844
53915
|
function writeAuthFile(file, content) {
|
|
53845
|
-
|
|
53846
|
-
|
|
53916
|
+
import_node_fs41.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
|
|
53917
|
+
import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
53847
53918
|
try {
|
|
53848
|
-
|
|
53919
|
+
import_node_fs41.default.chmodSync(file, 384);
|
|
53849
53920
|
} catch {
|
|
53850
53921
|
}
|
|
53851
53922
|
}
|
|
53852
53923
|
|
|
53853
53924
|
// src/owner-profile.ts
|
|
53854
|
-
var
|
|
53925
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
53855
53926
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
53856
|
-
var
|
|
53927
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
53857
53928
|
var PROFILE_FILENAME = "profile.json";
|
|
53858
53929
|
function loadOwnerDisplayName(dataDir) {
|
|
53859
53930
|
const fallback = import_node_os15.default.userInfo().username;
|
|
53860
|
-
const profilePath =
|
|
53931
|
+
const profilePath = import_node_path44.default.join(dataDir, PROFILE_FILENAME);
|
|
53861
53932
|
let raw;
|
|
53862
53933
|
try {
|
|
53863
|
-
raw =
|
|
53934
|
+
raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
|
|
53864
53935
|
} catch {
|
|
53865
53936
|
return fallback;
|
|
53866
53937
|
}
|
|
@@ -53883,18 +53954,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
53883
53954
|
}
|
|
53884
53955
|
|
|
53885
53956
|
// src/feishu-auth/owner-identity-store.ts
|
|
53886
|
-
var
|
|
53887
|
-
var
|
|
53957
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
53958
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
53888
53959
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
53889
53960
|
var OwnerIdentityStore = class {
|
|
53890
53961
|
file;
|
|
53891
53962
|
constructor(dataDir) {
|
|
53892
|
-
this.file =
|
|
53963
|
+
this.file = import_node_path45.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
53893
53964
|
}
|
|
53894
53965
|
read() {
|
|
53895
53966
|
let raw;
|
|
53896
53967
|
try {
|
|
53897
|
-
raw =
|
|
53968
|
+
raw = import_node_fs43.default.readFileSync(this.file, "utf8");
|
|
53898
53969
|
} catch {
|
|
53899
53970
|
return null;
|
|
53900
53971
|
}
|
|
@@ -53922,16 +53993,16 @@ var OwnerIdentityStore = class {
|
|
|
53922
53993
|
};
|
|
53923
53994
|
}
|
|
53924
53995
|
write(record) {
|
|
53925
|
-
|
|
53926
|
-
|
|
53996
|
+
import_node_fs43.default.mkdirSync(import_node_path45.default.dirname(this.file), { recursive: true });
|
|
53997
|
+
import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
53927
53998
|
try {
|
|
53928
|
-
|
|
53999
|
+
import_node_fs43.default.chmodSync(this.file, 384);
|
|
53929
54000
|
} catch {
|
|
53930
54001
|
}
|
|
53931
54002
|
}
|
|
53932
54003
|
clear() {
|
|
53933
54004
|
try {
|
|
53934
|
-
|
|
54005
|
+
import_node_fs43.default.unlinkSync(this.file);
|
|
53935
54006
|
} catch (err) {
|
|
53936
54007
|
const code = err?.code;
|
|
53937
54008
|
if (code !== "ENOENT") throw err;
|
|
@@ -54052,9 +54123,9 @@ var CentralClientError = class extends Error {
|
|
|
54052
54123
|
code;
|
|
54053
54124
|
cause;
|
|
54054
54125
|
};
|
|
54055
|
-
async function centralRequest(opts,
|
|
54126
|
+
async function centralRequest(opts, path77, init) {
|
|
54056
54127
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
54057
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
54128
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path77}`;
|
|
54058
54129
|
const ctrl = new AbortController();
|
|
54059
54130
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
54060
54131
|
let res;
|
|
@@ -54196,8 +54267,8 @@ function verifyConnectToken(args) {
|
|
|
54196
54267
|
}
|
|
54197
54268
|
|
|
54198
54269
|
// src/feishu-auth/server-key.ts
|
|
54199
|
-
var
|
|
54200
|
-
var
|
|
54270
|
+
var fs53 = __toESM(require("fs"), 1);
|
|
54271
|
+
var path54 = __toESM(require("path"), 1);
|
|
54201
54272
|
var FILE_NAME2 = "server-signing-key.json";
|
|
54202
54273
|
var ServerKeyStore = class {
|
|
54203
54274
|
constructor(dataDir) {
|
|
@@ -54205,12 +54276,12 @@ var ServerKeyStore = class {
|
|
|
54205
54276
|
}
|
|
54206
54277
|
dataDir;
|
|
54207
54278
|
filePath() {
|
|
54208
|
-
return
|
|
54279
|
+
return path54.join(this.dataDir, FILE_NAME2);
|
|
54209
54280
|
}
|
|
54210
54281
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
54211
54282
|
read() {
|
|
54212
54283
|
try {
|
|
54213
|
-
const raw =
|
|
54284
|
+
const raw = fs53.readFileSync(this.filePath(), "utf8");
|
|
54214
54285
|
const parsed = JSON.parse(raw);
|
|
54215
54286
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
54216
54287
|
return parsed.publicKeyPem;
|
|
@@ -54225,12 +54296,12 @@ var ServerKeyStore = class {
|
|
|
54225
54296
|
publicKeyPem,
|
|
54226
54297
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54227
54298
|
};
|
|
54228
|
-
|
|
54229
|
-
|
|
54299
|
+
fs53.mkdirSync(this.dataDir, { recursive: true });
|
|
54300
|
+
fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
54230
54301
|
}
|
|
54231
54302
|
clear() {
|
|
54232
54303
|
try {
|
|
54233
|
-
|
|
54304
|
+
fs53.unlinkSync(this.filePath());
|
|
54234
54305
|
} catch {
|
|
54235
54306
|
}
|
|
54236
54307
|
}
|
|
@@ -54243,12 +54314,12 @@ init_protocol();
|
|
|
54243
54314
|
init_protocol();
|
|
54244
54315
|
|
|
54245
54316
|
// src/session/fork.ts
|
|
54246
|
-
var
|
|
54317
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
54247
54318
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
54248
|
-
var
|
|
54319
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54249
54320
|
init_claude_history();
|
|
54250
54321
|
function readJsonlEntries(file) {
|
|
54251
|
-
const raw =
|
|
54322
|
+
const raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
54252
54323
|
const out = [];
|
|
54253
54324
|
for (const line of raw.split("\n")) {
|
|
54254
54325
|
const t = line.trim();
|
|
@@ -54261,10 +54332,10 @@ function readJsonlEntries(file) {
|
|
|
54261
54332
|
return out;
|
|
54262
54333
|
}
|
|
54263
54334
|
function forkSession(input) {
|
|
54264
|
-
const baseDir = input.baseDir ??
|
|
54265
|
-
const projectDir =
|
|
54266
|
-
const sourceFile =
|
|
54267
|
-
if (!
|
|
54335
|
+
const baseDir = input.baseDir ?? import_node_path46.default.join(import_node_os16.default.homedir(), ".claude");
|
|
54336
|
+
const projectDir = import_node_path46.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
54337
|
+
const sourceFile = import_node_path46.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
54338
|
+
if (!import_node_fs44.default.existsSync(sourceFile)) {
|
|
54268
54339
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
54269
54340
|
}
|
|
54270
54341
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -54294,9 +54365,9 @@ function forkSession(input) {
|
|
|
54294
54365
|
}
|
|
54295
54366
|
forkedLines.push(JSON.stringify(forked));
|
|
54296
54367
|
}
|
|
54297
|
-
const forkedFilePath =
|
|
54298
|
-
|
|
54299
|
-
|
|
54368
|
+
const forkedFilePath = import_node_path46.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
54369
|
+
import_node_fs44.default.mkdirSync(projectDir, { recursive: true });
|
|
54370
|
+
import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
54300
54371
|
return { forkedToolSessionId, forkedFilePath };
|
|
54301
54372
|
}
|
|
54302
54373
|
|
|
@@ -54648,7 +54719,7 @@ function buildPermissionHandlers(deps) {
|
|
|
54648
54719
|
}
|
|
54649
54720
|
|
|
54650
54721
|
// src/handlers/history.ts
|
|
54651
|
-
var
|
|
54722
|
+
var path57 = __toESM(require("path"), 1);
|
|
54652
54723
|
init_protocol();
|
|
54653
54724
|
|
|
54654
54725
|
// src/session/recent-dirs.ts
|
|
@@ -54666,7 +54737,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
54666
54737
|
}
|
|
54667
54738
|
|
|
54668
54739
|
// src/permission/persona-paths.ts
|
|
54669
|
-
var
|
|
54740
|
+
var path56 = __toESM(require("path"), 1);
|
|
54670
54741
|
function getAllowedPersonaIds(grants, action) {
|
|
54671
54742
|
const ids = /* @__PURE__ */ new Set();
|
|
54672
54743
|
for (const g2 of grants) {
|
|
@@ -54679,42 +54750,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
54679
54750
|
return ids;
|
|
54680
54751
|
}
|
|
54681
54752
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
54682
|
-
const target =
|
|
54753
|
+
const target = path56.resolve(absPath);
|
|
54683
54754
|
if (userWorkDir) {
|
|
54684
|
-
const u =
|
|
54685
|
-
const usep = u.endsWith(
|
|
54755
|
+
const u = path56.resolve(userWorkDir);
|
|
54756
|
+
const usep = u.endsWith(path56.sep) ? "" : path56.sep;
|
|
54686
54757
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
54687
54758
|
}
|
|
54688
|
-
const root =
|
|
54689
|
-
const sep3 = root.endsWith(
|
|
54759
|
+
const root = path56.resolve(personaRoot);
|
|
54760
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54690
54761
|
if (!target.startsWith(root + sep3)) return false;
|
|
54691
|
-
const rel =
|
|
54762
|
+
const rel = path56.relative(root, target);
|
|
54692
54763
|
if (!rel || rel.startsWith("..")) return false;
|
|
54693
|
-
const personaId = rel.split(
|
|
54764
|
+
const personaId = rel.split(path56.sep)[0];
|
|
54694
54765
|
if (!personaId) return false;
|
|
54695
54766
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54696
54767
|
if (allowed === "*") return true;
|
|
54697
54768
|
return allowed.has(personaId);
|
|
54698
54769
|
}
|
|
54699
54770
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54700
|
-
const root =
|
|
54701
|
-
const target =
|
|
54702
|
-
const sep3 = root.endsWith(
|
|
54771
|
+
const root = path56.resolve(personaRoot);
|
|
54772
|
+
const target = path56.resolve(absPath);
|
|
54773
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54703
54774
|
if (!target.startsWith(root + sep3)) return null;
|
|
54704
|
-
const rel =
|
|
54775
|
+
const rel = path56.relative(root, target);
|
|
54705
54776
|
if (!rel || rel.startsWith("..")) return null;
|
|
54706
|
-
const id = rel.split(
|
|
54777
|
+
const id = rel.split(path56.sep)[0];
|
|
54707
54778
|
return id || null;
|
|
54708
54779
|
}
|
|
54709
54780
|
function isPathWithin(dir, absPath) {
|
|
54710
|
-
const d =
|
|
54711
|
-
const t =
|
|
54712
|
-
const sep3 = d.endsWith(
|
|
54781
|
+
const d = path56.resolve(dir);
|
|
54782
|
+
const t = path56.resolve(absPath);
|
|
54783
|
+
const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
|
|
54713
54784
|
return t === d || t.startsWith(d + sep3);
|
|
54714
54785
|
}
|
|
54715
54786
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
54716
54787
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54717
|
-
return personaIdFromPath(
|
|
54788
|
+
return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId;
|
|
54718
54789
|
}
|
|
54719
54790
|
|
|
54720
54791
|
// src/handlers/history.ts
|
|
@@ -54740,7 +54811,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54740
54811
|
if (!pid) return false;
|
|
54741
54812
|
return isGuestPathAllowed(
|
|
54742
54813
|
ctx.grants,
|
|
54743
|
-
|
|
54814
|
+
path57.join(personaRoot, pid),
|
|
54744
54815
|
personaRoot,
|
|
54745
54816
|
"read",
|
|
54746
54817
|
userWorkDir
|
|
@@ -54752,7 +54823,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54752
54823
|
};
|
|
54753
54824
|
const list = async (frame, _client, ctx) => {
|
|
54754
54825
|
const args = HistoryListArgs.parse(frame);
|
|
54755
|
-
assertGuestPath(ctx,
|
|
54826
|
+
assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
|
|
54756
54827
|
const sessions = await history.listSessions(args);
|
|
54757
54828
|
return { response: { type: "history:list", sessions } };
|
|
54758
54829
|
};
|
|
@@ -54784,13 +54855,13 @@ function buildHistoryHandlers(deps) {
|
|
|
54784
54855
|
};
|
|
54785
54856
|
const subagents = async (frame, _client, ctx) => {
|
|
54786
54857
|
const args = HistorySubagentsArgs.parse(frame);
|
|
54787
|
-
assertGuestPath(ctx,
|
|
54858
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
54788
54859
|
const subs = await history.listSubagents(args);
|
|
54789
54860
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
54790
54861
|
};
|
|
54791
54862
|
const subagentRead = async (frame, _client, ctx) => {
|
|
54792
54863
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
54793
|
-
assertGuestPath(ctx,
|
|
54864
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
54794
54865
|
const res = await history.readSubagent(args);
|
|
54795
54866
|
return { response: { type: "history:subagent-read", ...res } };
|
|
54796
54867
|
};
|
|
@@ -54799,7 +54870,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54799
54870
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54800
54871
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54801
54872
|
const filtered = dirs.filter(
|
|
54802
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
54873
|
+
(d) => isGuestPathAllowed(ctx.grants, path57.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
54803
54874
|
);
|
|
54804
54875
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
54805
54876
|
}
|
|
@@ -54816,7 +54887,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54816
54887
|
}
|
|
54817
54888
|
|
|
54818
54889
|
// src/handlers/workspace.ts
|
|
54819
|
-
var
|
|
54890
|
+
var path58 = __toESM(require("path"), 1);
|
|
54820
54891
|
var os16 = __toESM(require("os"), 1);
|
|
54821
54892
|
init_protocol();
|
|
54822
54893
|
init_protocol();
|
|
@@ -54858,22 +54929,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54858
54929
|
const args = WorkspaceListArgs.parse(frame);
|
|
54859
54930
|
const isGuest = ctx?.principal.kind === "guest";
|
|
54860
54931
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
54861
|
-
const resolvedCwd =
|
|
54862
|
-
const target = args.path ?
|
|
54932
|
+
const resolvedCwd = path58.resolve(args.cwd ?? fallbackCwd);
|
|
54933
|
+
const target = args.path ? path58.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
54863
54934
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
54864
54935
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
54865
54936
|
return { response: { type: "workspace:list", ...res } };
|
|
54866
54937
|
};
|
|
54867
54938
|
const read = async (frame, _client, ctx) => {
|
|
54868
54939
|
const args = WorkspaceReadArgs.parse(frame);
|
|
54869
|
-
const target =
|
|
54940
|
+
const target = path58.isAbsolute(args.path) ? path58.resolve(args.path) : path58.resolve(args.cwd, args.path);
|
|
54870
54941
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
54871
54942
|
const res = workspace.read(args);
|
|
54872
54943
|
return { response: { type: "workspace:read", ...res } };
|
|
54873
54944
|
};
|
|
54874
54945
|
const skillsList = async (frame, _client, ctx) => {
|
|
54875
54946
|
const args = SkillsListArgs.parse(frame);
|
|
54876
|
-
const cwdAbs =
|
|
54947
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
54877
54948
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
54878
54949
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
54879
54950
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -54885,7 +54956,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54885
54956
|
};
|
|
54886
54957
|
const agentsList = async (frame, _client, ctx) => {
|
|
54887
54958
|
const args = AgentsListArgs.parse(frame);
|
|
54888
|
-
const cwdAbs =
|
|
54959
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
54889
54960
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
54890
54961
|
if (args.tool === "codex") {
|
|
54891
54962
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -54907,20 +54978,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54907
54978
|
}
|
|
54908
54979
|
|
|
54909
54980
|
// src/handlers/git.ts
|
|
54910
|
-
var
|
|
54981
|
+
var path60 = __toESM(require("path"), 1);
|
|
54911
54982
|
init_protocol();
|
|
54912
54983
|
init_protocol();
|
|
54913
54984
|
|
|
54914
54985
|
// src/workspace/git.ts
|
|
54915
54986
|
var import_node_child_process12 = require("child_process");
|
|
54916
|
-
var
|
|
54917
|
-
var
|
|
54987
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
54988
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
54918
54989
|
var import_node_util = require("util");
|
|
54919
54990
|
var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
|
|
54920
54991
|
function normalizePath(p2) {
|
|
54921
|
-
const resolved =
|
|
54992
|
+
const resolved = import_node_path47.default.resolve(p2);
|
|
54922
54993
|
try {
|
|
54923
|
-
return
|
|
54994
|
+
return import_node_fs45.default.realpathSync(resolved);
|
|
54924
54995
|
} catch {
|
|
54925
54996
|
return resolved;
|
|
54926
54997
|
}
|
|
@@ -54994,7 +55065,7 @@ async function listGitBranches(cwd) {
|
|
|
54994
55065
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
54995
55066
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
54996
55067
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54997
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
55068
|
+
if (!isGuestPathAllowed(ctx.grants, path60.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
54998
55069
|
throw new ClawdError(
|
|
54999
55070
|
ERROR_CODES.UNAUTHORIZED,
|
|
55000
55071
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -55335,22 +55406,22 @@ init_src();
|
|
|
55335
55406
|
init_protocol();
|
|
55336
55407
|
|
|
55337
55408
|
// src/sshd/key-issue.ts
|
|
55338
|
-
var
|
|
55339
|
-
var
|
|
55409
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
55410
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
55340
55411
|
var import_node_child_process13 = require("child_process");
|
|
55341
55412
|
function safeDeviceId(deviceId) {
|
|
55342
55413
|
return deviceId.replace(/[\/\\]/g, "_");
|
|
55343
55414
|
}
|
|
55344
55415
|
async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
55345
55416
|
const safeId = safeDeviceId(deviceId);
|
|
55346
|
-
const keysDir =
|
|
55347
|
-
|
|
55348
|
-
const privPath =
|
|
55417
|
+
const keysDir = import_node_path48.default.join(sshdDir, "keys");
|
|
55418
|
+
import_node_fs46.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
|
|
55419
|
+
const privPath = import_node_path48.default.join(keysDir, `${safeId}.ed25519`);
|
|
55349
55420
|
const pubPath = `${privPath}.pub`;
|
|
55350
|
-
if (
|
|
55421
|
+
if (import_node_fs46.default.existsSync(privPath) && import_node_fs46.default.existsSync(pubPath)) {
|
|
55351
55422
|
return {
|
|
55352
|
-
privateKeyPem:
|
|
55353
|
-
publicKeyLine:
|
|
55423
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55424
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55354
55425
|
};
|
|
55355
55426
|
}
|
|
55356
55427
|
const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
|
|
@@ -55364,20 +55435,21 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
|
55364
55435
|
p2.on("error", reject);
|
|
55365
55436
|
});
|
|
55366
55437
|
try {
|
|
55367
|
-
|
|
55438
|
+
import_node_fs46.default.chmodSync(privPath, 384);
|
|
55368
55439
|
} catch {
|
|
55369
55440
|
}
|
|
55370
55441
|
try {
|
|
55371
|
-
|
|
55442
|
+
import_node_fs46.default.chmodSync(pubPath, 420);
|
|
55372
55443
|
} catch {
|
|
55373
55444
|
}
|
|
55374
55445
|
return {
|
|
55375
|
-
privateKeyPem:
|
|
55376
|
-
publicKeyLine:
|
|
55446
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55447
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55377
55448
|
};
|
|
55378
55449
|
}
|
|
55379
55450
|
|
|
55380
55451
|
// src/handlers/contact-ssh.ts
|
|
55452
|
+
init_contact_ssh_log();
|
|
55381
55453
|
function ensureOwner2(ctx) {
|
|
55382
55454
|
if (!ctx || ctx.principal.kind !== "owner") {
|
|
55383
55455
|
throw new ClawdError(
|
|
@@ -55792,7 +55864,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55792
55864
|
}
|
|
55793
55865
|
|
|
55794
55866
|
// src/handlers/attachment.ts
|
|
55795
|
-
var
|
|
55867
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
55796
55868
|
init_protocol();
|
|
55797
55869
|
init_protocol();
|
|
55798
55870
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -55872,12 +55944,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
55872
55944
|
`session ${args.sessionId} scope unresolved`
|
|
55873
55945
|
);
|
|
55874
55946
|
}
|
|
55875
|
-
const cwdAbs =
|
|
55876
|
-
const candidateAbs =
|
|
55947
|
+
const cwdAbs = import_node_path49.default.resolve(sessionFile.cwd);
|
|
55948
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
55877
55949
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
55878
55950
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
55879
55951
|
const entry = entries.find((e) => {
|
|
55880
|
-
const storedAbs =
|
|
55952
|
+
const storedAbs = import_node_path49.default.isAbsolute(e.relPath) ? import_node_path49.default.resolve(e.relPath) : import_node_path49.default.resolve(cwdAbs, e.relPath);
|
|
55881
55953
|
return storedAbs === candidateAbs && !e.stale;
|
|
55882
55954
|
});
|
|
55883
55955
|
if (!entry) {
|
|
@@ -55902,7 +55974,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
55902
55974
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
55903
55975
|
const f = deps.sessionStore.read(sessionId);
|
|
55904
55976
|
if (!f) return;
|
|
55905
|
-
assertGuestAttachmentPath(ctx,
|
|
55977
|
+
assertGuestAttachmentPath(ctx, import_node_path49.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
55906
55978
|
}
|
|
55907
55979
|
const groupAdd = async (frame, _client, ctx) => {
|
|
55908
55980
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -55917,8 +55989,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
55917
55989
|
if (!scope) {
|
|
55918
55990
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
55919
55991
|
}
|
|
55920
|
-
const cwdAbs =
|
|
55921
|
-
const candidateAbs =
|
|
55992
|
+
const cwdAbs = import_node_path49.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
55993
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
55922
55994
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
55923
55995
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
55924
55996
|
const size = 0;
|
|
@@ -55977,20 +56049,20 @@ function buildAttachmentHandlers(deps) {
|
|
|
55977
56049
|
|
|
55978
56050
|
// src/handlers/extension.ts
|
|
55979
56051
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
55980
|
-
var
|
|
56052
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
55981
56053
|
init_protocol();
|
|
55982
56054
|
init_src();
|
|
55983
56055
|
|
|
55984
56056
|
// src/extension/bundle-zip.ts
|
|
55985
56057
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
55986
|
-
var
|
|
56058
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
55987
56059
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
55988
56060
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
55989
56061
|
async function bundleExtensionDir(dir) {
|
|
55990
56062
|
const entries = await listFilesSorted(dir);
|
|
55991
56063
|
const zip = new import_jszip2.default();
|
|
55992
56064
|
for (const rel of entries) {
|
|
55993
|
-
const abs =
|
|
56065
|
+
const abs = import_node_path50.default.join(dir, rel);
|
|
55994
56066
|
const content = await import_promises5.default.readFile(abs);
|
|
55995
56067
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
55996
56068
|
}
|
|
@@ -56011,7 +56083,7 @@ async function listFilesSorted(rootDir) {
|
|
|
56011
56083
|
return out;
|
|
56012
56084
|
}
|
|
56013
56085
|
async function walk(absRoot, relPrefix, out) {
|
|
56014
|
-
const dirAbs =
|
|
56086
|
+
const dirAbs = import_node_path50.default.join(absRoot, relPrefix);
|
|
56015
56087
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
56016
56088
|
for (const e of entries) {
|
|
56017
56089
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -56067,7 +56139,7 @@ function computePublishCheck(args) {
|
|
|
56067
56139
|
|
|
56068
56140
|
// src/extension/install-flow.ts
|
|
56069
56141
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
56070
|
-
var
|
|
56142
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56071
56143
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
56072
56144
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
56073
56145
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
@@ -56075,19 +56147,19 @@ init_src();
|
|
|
56075
56147
|
|
|
56076
56148
|
// src/extension/paths.ts
|
|
56077
56149
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
56078
|
-
var
|
|
56150
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56079
56151
|
init_src();
|
|
56080
56152
|
function clawdHomeRoot(override) {
|
|
56081
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
56153
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path51.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
56082
56154
|
}
|
|
56083
56155
|
function extensionsRoot(override) {
|
|
56084
|
-
return
|
|
56156
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions");
|
|
56085
56157
|
}
|
|
56086
56158
|
function publishedChannelsFile(override) {
|
|
56087
|
-
return
|
|
56159
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
56088
56160
|
}
|
|
56089
56161
|
function bundleCacheRoot(override) {
|
|
56090
|
-
return
|
|
56162
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
56091
56163
|
}
|
|
56092
56164
|
|
|
56093
56165
|
// src/extension/install-flow.ts
|
|
@@ -56114,7 +56186,7 @@ async function installFromChannel(args, deps) {
|
|
|
56114
56186
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56115
56187
|
}
|
|
56116
56188
|
for (const name of Object.keys(zip.files)) {
|
|
56117
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56189
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
|
|
56118
56190
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56119
56191
|
}
|
|
56120
56192
|
}
|
|
@@ -56146,7 +56218,7 @@ async function installFromChannel(args, deps) {
|
|
|
56146
56218
|
);
|
|
56147
56219
|
}
|
|
56148
56220
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
56149
|
-
const destDir =
|
|
56221
|
+
const destDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
|
|
56150
56222
|
let destExists = false;
|
|
56151
56223
|
try {
|
|
56152
56224
|
await import_promises6.default.access(destDir);
|
|
@@ -56160,16 +56232,16 @@ async function installFromChannel(args, deps) {
|
|
|
56160
56232
|
);
|
|
56161
56233
|
}
|
|
56162
56234
|
const stage = await import_promises6.default.mkdtemp(
|
|
56163
|
-
|
|
56235
|
+
import_node_path52.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
56164
56236
|
);
|
|
56165
56237
|
try {
|
|
56166
56238
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56167
|
-
const dest =
|
|
56239
|
+
const dest = import_node_path52.default.join(stage, name);
|
|
56168
56240
|
if (entry.dir) {
|
|
56169
56241
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
56170
56242
|
continue;
|
|
56171
56243
|
}
|
|
56172
|
-
await import_promises6.default.mkdir(
|
|
56244
|
+
await import_promises6.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
|
|
56173
56245
|
if (name === "manifest.json") {
|
|
56174
56246
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56175
56247
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56190,7 +56262,7 @@ async function installFromChannel(args, deps) {
|
|
|
56190
56262
|
|
|
56191
56263
|
// src/extension/update-flow.ts
|
|
56192
56264
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
56193
|
-
var
|
|
56265
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
56194
56266
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
56195
56267
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
56196
56268
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -56208,11 +56280,11 @@ async function updateFromChannel(args, deps) {
|
|
|
56208
56280
|
channelRef.extId,
|
|
56209
56281
|
channelRef.ownerPrincipalId
|
|
56210
56282
|
);
|
|
56211
|
-
const liveDir =
|
|
56283
|
+
const liveDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
|
|
56212
56284
|
const prevDir = `${liveDir}.prev`;
|
|
56213
56285
|
let existingVersion;
|
|
56214
56286
|
try {
|
|
56215
|
-
const raw = await import_promises7.default.readFile(
|
|
56287
|
+
const raw = await import_promises7.default.readFile(import_node_path53.default.join(liveDir, "manifest.json"), "utf8");
|
|
56216
56288
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
56217
56289
|
if (!parsed2.success) {
|
|
56218
56290
|
throw new UpdateError(
|
|
@@ -56245,7 +56317,7 @@ async function updateFromChannel(args, deps) {
|
|
|
56245
56317
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56246
56318
|
}
|
|
56247
56319
|
for (const name of Object.keys(zip.files)) {
|
|
56248
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56320
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
|
|
56249
56321
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56250
56322
|
}
|
|
56251
56323
|
}
|
|
@@ -56280,16 +56352,16 @@ async function updateFromChannel(args, deps) {
|
|
|
56280
56352
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
56281
56353
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
56282
56354
|
const stage = await import_promises7.default.mkdtemp(
|
|
56283
|
-
|
|
56355
|
+
import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
56284
56356
|
);
|
|
56285
56357
|
try {
|
|
56286
56358
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56287
|
-
const dest =
|
|
56359
|
+
const dest = import_node_path53.default.join(stage, name);
|
|
56288
56360
|
if (entry.dir) {
|
|
56289
56361
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
56290
56362
|
continue;
|
|
56291
56363
|
}
|
|
56292
|
-
await import_promises7.default.mkdir(
|
|
56364
|
+
await import_promises7.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
|
|
56293
56365
|
if (name === "manifest.json") {
|
|
56294
56366
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56295
56367
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56383,7 +56455,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56383
56455
|
);
|
|
56384
56456
|
}
|
|
56385
56457
|
}
|
|
56386
|
-
const manifestPath =
|
|
56458
|
+
const manifestPath = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56387
56459
|
const manifest = await readManifest(root, extId);
|
|
56388
56460
|
const next = { ...manifest, version: newVersion };
|
|
56389
56461
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -56391,7 +56463,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56391
56463
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
56392
56464
|
}
|
|
56393
56465
|
async function readManifest(root, extId) {
|
|
56394
|
-
const file =
|
|
56466
|
+
const file = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56395
56467
|
let raw;
|
|
56396
56468
|
try {
|
|
56397
56469
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -56482,7 +56554,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56482
56554
|
};
|
|
56483
56555
|
async function buildSnapshotMeta(extId) {
|
|
56484
56556
|
const manifest = await readManifest(deps.root, extId);
|
|
56485
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
56557
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path54.default.join(deps.root, extId));
|
|
56486
56558
|
return { manifest, contentHash: sha256, buffer };
|
|
56487
56559
|
}
|
|
56488
56560
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -56663,9 +56735,9 @@ function buildExtensionHandlers(deps) {
|
|
|
56663
56735
|
}
|
|
56664
56736
|
|
|
56665
56737
|
// src/app-builder/project-store.ts
|
|
56666
|
-
var
|
|
56738
|
+
var import_node_fs47 = require("fs");
|
|
56667
56739
|
var import_node_child_process14 = require("child_process");
|
|
56668
|
-
var
|
|
56740
|
+
var import_node_path55 = require("path");
|
|
56669
56741
|
init_protocol();
|
|
56670
56742
|
var PROJECTS_DIR = "projects";
|
|
56671
56743
|
var META_FILE = ".clawd-project.json";
|
|
@@ -56679,19 +56751,19 @@ var ProjectStore = class {
|
|
|
56679
56751
|
root;
|
|
56680
56752
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
56681
56753
|
metaPath(name) {
|
|
56682
|
-
return (0,
|
|
56754
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name, META_FILE);
|
|
56683
56755
|
}
|
|
56684
56756
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
56685
56757
|
projectDir(name) {
|
|
56686
|
-
return (0,
|
|
56758
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name);
|
|
56687
56759
|
}
|
|
56688
56760
|
projectsRoot() {
|
|
56689
|
-
return (0,
|
|
56761
|
+
return (0, import_node_path55.join)(this.root, PROJECTS_DIR);
|
|
56690
56762
|
}
|
|
56691
56763
|
async list() {
|
|
56692
56764
|
let entries;
|
|
56693
56765
|
try {
|
|
56694
|
-
entries = await
|
|
56766
|
+
entries = await import_node_fs47.promises.readdir(this.projectsRoot());
|
|
56695
56767
|
} catch (err) {
|
|
56696
56768
|
if (err.code === "ENOENT") return [];
|
|
56697
56769
|
throw err;
|
|
@@ -56699,7 +56771,7 @@ var ProjectStore = class {
|
|
|
56699
56771
|
const out = [];
|
|
56700
56772
|
for (const name of entries) {
|
|
56701
56773
|
try {
|
|
56702
|
-
const raw = await
|
|
56774
|
+
const raw = await import_node_fs47.promises.readFile(this.metaPath(name), "utf8");
|
|
56703
56775
|
const json = JSON.parse(raw);
|
|
56704
56776
|
let migrated = false;
|
|
56705
56777
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -56710,7 +56782,7 @@ var ProjectStore = class {
|
|
|
56710
56782
|
if (parsed.success) {
|
|
56711
56783
|
out.push(parsed.data);
|
|
56712
56784
|
if (migrated) {
|
|
56713
|
-
void
|
|
56785
|
+
void import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
56714
56786
|
});
|
|
56715
56787
|
}
|
|
56716
56788
|
}
|
|
@@ -56754,8 +56826,8 @@ var ProjectStore = class {
|
|
|
56754
56826
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
56755
56827
|
}
|
|
56756
56828
|
const dir = this.projectDir(name);
|
|
56757
|
-
await
|
|
56758
|
-
await
|
|
56829
|
+
await import_node_fs47.promises.mkdir(dir, { recursive: true });
|
|
56830
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
56759
56831
|
return meta;
|
|
56760
56832
|
}
|
|
56761
56833
|
/**
|
|
@@ -56798,7 +56870,7 @@ var ProjectStore = class {
|
|
|
56798
56870
|
}
|
|
56799
56871
|
async delete(name) {
|
|
56800
56872
|
const dir = this.projectDir(name);
|
|
56801
|
-
await
|
|
56873
|
+
await import_node_fs47.promises.rm(dir, { recursive: true, force: true });
|
|
56802
56874
|
}
|
|
56803
56875
|
async updatePort(name, newPort) {
|
|
56804
56876
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -56814,7 +56886,7 @@ var ProjectStore = class {
|
|
|
56814
56886
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
56815
56887
|
}
|
|
56816
56888
|
const updated = { ...target, port: newPort };
|
|
56817
|
-
await
|
|
56889
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
56818
56890
|
return updated;
|
|
56819
56891
|
}
|
|
56820
56892
|
/**
|
|
@@ -56831,7 +56903,7 @@ var ProjectStore = class {
|
|
|
56831
56903
|
if (!validated.success) {
|
|
56832
56904
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
56833
56905
|
}
|
|
56834
|
-
await
|
|
56906
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56835
56907
|
return validated.data;
|
|
56836
56908
|
}
|
|
56837
56909
|
/**
|
|
@@ -56852,7 +56924,7 @@ var ProjectStore = class {
|
|
|
56852
56924
|
if (!validated.success) {
|
|
56853
56925
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
56854
56926
|
}
|
|
56855
|
-
await
|
|
56927
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56856
56928
|
return validated.data;
|
|
56857
56929
|
}
|
|
56858
56930
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -56867,7 +56939,7 @@ var ProjectStore = class {
|
|
|
56867
56939
|
if (!validated.success) {
|
|
56868
56940
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
56869
56941
|
}
|
|
56870
|
-
await
|
|
56942
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56871
56943
|
return validated.data;
|
|
56872
56944
|
}
|
|
56873
56945
|
};
|
|
@@ -56988,8 +57060,8 @@ var PublishJobRegistry = class {
|
|
|
56988
57060
|
|
|
56989
57061
|
// src/app-builder/publish-job-runner.ts
|
|
56990
57062
|
var import_node_child_process16 = require("child_process");
|
|
56991
|
-
var
|
|
56992
|
-
var
|
|
57063
|
+
var import_node_fs48 = require("fs");
|
|
57064
|
+
var import_node_path56 = require("path");
|
|
56993
57065
|
|
|
56994
57066
|
// src/app-builder/publish-stage-parser.ts
|
|
56995
57067
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -57021,10 +57093,10 @@ async function startPublishJob(deps, args) {
|
|
|
57021
57093
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
57022
57094
|
}
|
|
57023
57095
|
const projDir = projectDir(args.name);
|
|
57024
|
-
const logPath = (0,
|
|
57096
|
+
const logPath = (0, import_node_path56.join)(projDir, ".publish.log");
|
|
57025
57097
|
let logStream = null;
|
|
57026
57098
|
try {
|
|
57027
|
-
logStream = (0,
|
|
57099
|
+
logStream = (0, import_node_fs48.createWriteStream)(logPath, { flags: "w" });
|
|
57028
57100
|
} catch {
|
|
57029
57101
|
logStream = null;
|
|
57030
57102
|
}
|
|
@@ -57281,8 +57353,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
57281
57353
|
|
|
57282
57354
|
// src/handlers/app-builder.ts
|
|
57283
57355
|
init_protocol();
|
|
57284
|
-
var
|
|
57285
|
-
var
|
|
57356
|
+
var import_node_path57 = require("path");
|
|
57357
|
+
var import_node_fs49 = require("fs");
|
|
57286
57358
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
57287
57359
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
57288
57360
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -57363,7 +57435,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57363
57435
|
async function listAllUsersProjects() {
|
|
57364
57436
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
57365
57437
|
const getStore = deps.getStore;
|
|
57366
|
-
const userIds = await
|
|
57438
|
+
const userIds = await import_node_fs49.promises.readdir(deps.usersRoot).catch(() => []);
|
|
57367
57439
|
const perUser = await Promise.all(
|
|
57368
57440
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
57369
57441
|
);
|
|
@@ -57439,8 +57511,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57439
57511
|
const project = await userStore.create(f.name, reservedPorts);
|
|
57440
57512
|
try {
|
|
57441
57513
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57442
|
-
const templateSrcDir = (0,
|
|
57443
|
-
const scaffoldScript = (0,
|
|
57514
|
+
const templateSrcDir = (0, import_node_path57.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
57515
|
+
const scaffoldScript = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
57444
57516
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
57445
57517
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
57446
57518
|
name: project.name,
|
|
@@ -57661,7 +57733,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57661
57733
|
await userStore.clearPublishJob(args.name);
|
|
57662
57734
|
}
|
|
57663
57735
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57664
|
-
const scriptPath = (0,
|
|
57736
|
+
const scriptPath = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
57665
57737
|
deps.logger?.info("app-builder.publish.start", {
|
|
57666
57738
|
name: args.name,
|
|
57667
57739
|
sessionId: boundSession.sessionId,
|
|
@@ -57830,7 +57902,7 @@ function buildVisitorHandlers(deps) {
|
|
|
57830
57902
|
|
|
57831
57903
|
// src/extension/registry.ts
|
|
57832
57904
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
57833
|
-
var
|
|
57905
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
57834
57906
|
init_src();
|
|
57835
57907
|
async function loadAll(root) {
|
|
57836
57908
|
let entries;
|
|
@@ -57844,13 +57916,13 @@ async function loadAll(root) {
|
|
|
57844
57916
|
for (const ent of entries) {
|
|
57845
57917
|
if (!ent.isDirectory()) continue;
|
|
57846
57918
|
if (ent.name.startsWith(".")) continue;
|
|
57847
|
-
records.push(await loadOne(
|
|
57919
|
+
records.push(await loadOne(import_node_path58.default.join(root, ent.name), ent.name));
|
|
57848
57920
|
}
|
|
57849
57921
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
57850
57922
|
return records;
|
|
57851
57923
|
}
|
|
57852
57924
|
async function loadOne(dir, dirName) {
|
|
57853
|
-
const manifestPath =
|
|
57925
|
+
const manifestPath = import_node_path58.default.join(dir, "manifest.json");
|
|
57854
57926
|
let raw;
|
|
57855
57927
|
try {
|
|
57856
57928
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -57895,7 +57967,7 @@ async function loadOne(dir, dirName) {
|
|
|
57895
57967
|
|
|
57896
57968
|
// src/extension/uninstall.ts
|
|
57897
57969
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
57898
|
-
var
|
|
57970
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
57899
57971
|
var UninstallError = class extends Error {
|
|
57900
57972
|
constructor(code, message) {
|
|
57901
57973
|
super(message);
|
|
@@ -57904,7 +57976,7 @@ var UninstallError = class extends Error {
|
|
|
57904
57976
|
code;
|
|
57905
57977
|
};
|
|
57906
57978
|
async function uninstall(deps) {
|
|
57907
|
-
const dir =
|
|
57979
|
+
const dir = import_node_path59.default.join(deps.root, deps.extId);
|
|
57908
57980
|
try {
|
|
57909
57981
|
await import_promises10.default.access(dir);
|
|
57910
57982
|
} catch {
|
|
@@ -58488,7 +58560,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58488
58560
|
|
|
58489
58561
|
// src/extension/runtime.ts
|
|
58490
58562
|
var import_node_child_process18 = require("child_process");
|
|
58491
|
-
var
|
|
58563
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
58492
58564
|
var import_promises11 = require("timers/promises");
|
|
58493
58565
|
init_src();
|
|
58494
58566
|
|
|
@@ -58590,7 +58662,7 @@ var Runtime = class {
|
|
|
58590
58662
|
/\$CLAWOS_EXT_PORT/g,
|
|
58591
58663
|
String(port)
|
|
58592
58664
|
);
|
|
58593
|
-
const dir =
|
|
58665
|
+
const dir = import_node_path60.default.join(this.root, extId);
|
|
58594
58666
|
const env = {
|
|
58595
58667
|
...process.env,
|
|
58596
58668
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -58702,7 +58774,7 @@ ${handle.stderrTail}`
|
|
|
58702
58774
|
|
|
58703
58775
|
// src/extension/published-channels.ts
|
|
58704
58776
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
58705
|
-
var
|
|
58777
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
58706
58778
|
init_src();
|
|
58707
58779
|
init_zod();
|
|
58708
58780
|
var PublishedChannelsError = class extends Error {
|
|
@@ -58802,7 +58874,7 @@ var PublishedChannelStore = class {
|
|
|
58802
58874
|
)
|
|
58803
58875
|
};
|
|
58804
58876
|
const tmp = `${this.filePath}.tmp`;
|
|
58805
|
-
await import_promises12.default.mkdir(
|
|
58877
|
+
await import_promises12.default.mkdir(import_node_path61.default.dirname(this.filePath), { recursive: true });
|
|
58806
58878
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
58807
58879
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
58808
58880
|
}
|
|
@@ -58810,7 +58882,7 @@ var PublishedChannelStore = class {
|
|
|
58810
58882
|
|
|
58811
58883
|
// src/extension/bundle-cache.ts
|
|
58812
58884
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
58813
|
-
var
|
|
58885
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
58814
58886
|
var BundleCache = class {
|
|
58815
58887
|
constructor(rootDir) {
|
|
58816
58888
|
this.rootDir = rootDir;
|
|
@@ -58819,14 +58891,14 @@ var BundleCache = class {
|
|
|
58819
58891
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
58820
58892
|
async write(snapshotHash, buffer) {
|
|
58821
58893
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
58822
|
-
const file =
|
|
58894
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58823
58895
|
const tmp = `${file}.tmp`;
|
|
58824
58896
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
58825
58897
|
await import_promises13.default.rename(tmp, file);
|
|
58826
58898
|
}
|
|
58827
58899
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
58828
58900
|
async read(snapshotHash) {
|
|
58829
|
-
const file =
|
|
58901
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58830
58902
|
try {
|
|
58831
58903
|
return await import_promises13.default.readFile(file);
|
|
58832
58904
|
} catch (e) {
|
|
@@ -58836,7 +58908,7 @@ var BundleCache = class {
|
|
|
58836
58908
|
}
|
|
58837
58909
|
/** Idempotent — missing file is not an error. */
|
|
58838
58910
|
async delete(snapshotHash) {
|
|
58839
|
-
const file =
|
|
58911
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58840
58912
|
await import_promises13.default.rm(file, { force: true });
|
|
58841
58913
|
}
|
|
58842
58914
|
};
|
|
@@ -58861,16 +58933,16 @@ async function startDaemon(config) {
|
|
|
58861
58933
|
});
|
|
58862
58934
|
const logger = createLogger({
|
|
58863
58935
|
level: config.logLevel,
|
|
58864
|
-
file:
|
|
58936
|
+
file: import_node_path63.default.join(config.dataDir, "clawd.log"),
|
|
58865
58937
|
logClient
|
|
58866
58938
|
});
|
|
58867
58939
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
58868
58940
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
58869
|
-
file:
|
|
58941
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log"),
|
|
58870
58942
|
level: "debug"
|
|
58871
58943
|
});
|
|
58872
58944
|
logger.info("screen-idle probe logger enabled", {
|
|
58873
|
-
file:
|
|
58945
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log")
|
|
58874
58946
|
});
|
|
58875
58947
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
58876
58948
|
const pre = stateMgr.preflight();
|
|
@@ -59008,8 +59080,8 @@ async function startDaemon(config) {
|
|
|
59008
59080
|
const agents = new AgentsScanner();
|
|
59009
59081
|
const history = new ClaudeHistoryReader();
|
|
59010
59082
|
let transport = null;
|
|
59011
|
-
const personaStore = new PersonaStore(
|
|
59012
|
-
const usersRoot =
|
|
59083
|
+
const personaStore = new PersonaStore(import_node_path63.default.join(config.dataDir, "personas"));
|
|
59084
|
+
const usersRoot = import_node_path63.default.join(config.dataDir, "users");
|
|
59013
59085
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
59014
59086
|
if (defaultsRoot) {
|
|
59015
59087
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -59029,17 +59101,17 @@ async function startDaemon(config) {
|
|
|
59029
59101
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
59030
59102
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
59031
59103
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
59032
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
59104
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path63.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
59033
59105
|
const dispatchServerCandidates = [
|
|
59034
|
-
|
|
59106
|
+
import_node_path63.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
59035
59107
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
59036
|
-
|
|
59108
|
+
import_node_path63.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
59037
59109
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
59038
59110
|
];
|
|
59039
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
59111
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59040
59112
|
let dispatchMcpConfigPath2;
|
|
59041
59113
|
if (dispatchServerScriptPath) {
|
|
59042
|
-
const dispatchLogPath =
|
|
59114
|
+
const dispatchLogPath = import_node_path63.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
59043
59115
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
59044
59116
|
dataDir: config.dataDir,
|
|
59045
59117
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -59056,15 +59128,15 @@ async function startDaemon(config) {
|
|
|
59056
59128
|
});
|
|
59057
59129
|
}
|
|
59058
59130
|
const ticketServerCandidates = [
|
|
59059
|
-
|
|
59060
|
-
|
|
59131
|
+
import_node_path63.default.join(here, "ticket", "mcp-server.cjs"),
|
|
59132
|
+
import_node_path63.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
59061
59133
|
];
|
|
59062
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
59134
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59063
59135
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
59064
59136
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
59065
59137
|
let ticketMcpConfigPath2;
|
|
59066
59138
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
59067
|
-
const ticketLogPath =
|
|
59139
|
+
const ticketLogPath = import_node_path63.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
59068
59140
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
59069
59141
|
dataDir: config.dataDir,
|
|
59070
59142
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -59085,13 +59157,13 @@ async function startDaemon(config) {
|
|
|
59085
59157
|
});
|
|
59086
59158
|
}
|
|
59087
59159
|
const shiftServerCandidates = [
|
|
59088
|
-
|
|
59089
|
-
|
|
59160
|
+
import_node_path63.default.join(here, "shift", "mcp-server.cjs"),
|
|
59161
|
+
import_node_path63.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
59090
59162
|
];
|
|
59091
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
59163
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59092
59164
|
let shiftMcpConfigPath2;
|
|
59093
59165
|
if (shiftServerScriptPath) {
|
|
59094
|
-
const shiftLogPath =
|
|
59166
|
+
const shiftLogPath = import_node_path63.default.join(config.dataDir, "shift-mcp-server.log");
|
|
59095
59167
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
59096
59168
|
dataDir: config.dataDir,
|
|
59097
59169
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -59109,13 +59181,13 @@ async function startDaemon(config) {
|
|
|
59109
59181
|
);
|
|
59110
59182
|
}
|
|
59111
59183
|
const inboxServerCandidates = [
|
|
59112
|
-
|
|
59113
|
-
|
|
59184
|
+
import_node_path63.default.join(here, "inbox", "mcp-server.cjs"),
|
|
59185
|
+
import_node_path63.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
59114
59186
|
];
|
|
59115
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
59187
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59116
59188
|
let inboxMcpConfigPath2;
|
|
59117
59189
|
if (inboxServerScriptPath) {
|
|
59118
|
-
const inboxLogPath =
|
|
59190
|
+
const inboxLogPath = import_node_path63.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
59119
59191
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
59120
59192
|
dataDir: config.dataDir,
|
|
59121
59193
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -59133,7 +59205,7 @@ async function startDaemon(config) {
|
|
|
59133
59205
|
);
|
|
59134
59206
|
}
|
|
59135
59207
|
const shiftStore = createShiftStore({
|
|
59136
|
-
filePath:
|
|
59208
|
+
filePath: import_node_path63.default.join(config.dataDir, "shift.json"),
|
|
59137
59209
|
ownerIdProvider: () => ownerPrincipalId,
|
|
59138
59210
|
now: () => Date.now()
|
|
59139
59211
|
});
|
|
@@ -59155,7 +59227,7 @@ async function startDaemon(config) {
|
|
|
59155
59227
|
getAdapter,
|
|
59156
59228
|
historyReader: history,
|
|
59157
59229
|
dataDir: config.dataDir,
|
|
59158
|
-
personaRoot:
|
|
59230
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59159
59231
|
usersRoot,
|
|
59160
59232
|
personaStore,
|
|
59161
59233
|
ownerDisplayName,
|
|
@@ -59198,10 +59270,10 @@ async function startDaemon(config) {
|
|
|
59198
59270
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
59199
59271
|
attachmentGroup: {
|
|
59200
59272
|
onFileEdit: (input) => {
|
|
59201
|
-
const absPath =
|
|
59273
|
+
const absPath = import_node_path63.default.isAbsolute(input.relPath) ? input.relPath : import_node_path63.default.join(input.cwd, input.relPath);
|
|
59202
59274
|
let size = 0;
|
|
59203
59275
|
try {
|
|
59204
|
-
size =
|
|
59276
|
+
size = import_node_fs50.default.statSync(absPath).size;
|
|
59205
59277
|
} catch (err) {
|
|
59206
59278
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
59207
59279
|
sessionId: input.sessionId,
|
|
@@ -59400,11 +59472,11 @@ async function startDaemon(config) {
|
|
|
59400
59472
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
59401
59473
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
59402
59474
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
59403
|
-
personaRoot:
|
|
59475
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59404
59476
|
usersRoot
|
|
59405
59477
|
},
|
|
59406
59478
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
59407
|
-
personaRoot:
|
|
59479
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59408
59480
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
59409
59481
|
usersRoot,
|
|
59410
59482
|
// capability:list / delete handler 依赖
|
|
@@ -59426,7 +59498,7 @@ async function startDaemon(config) {
|
|
|
59426
59498
|
contactStore,
|
|
59427
59499
|
// <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
|
|
59428
59500
|
// Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
|
|
59429
|
-
sshdDir:
|
|
59501
|
+
sshdDir: import_node_path63.default.join(config.dataDir, "sshd"),
|
|
59430
59502
|
contactSshLog: sshLog,
|
|
59431
59503
|
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
59432
59504
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
@@ -59517,11 +59589,11 @@ async function startDaemon(config) {
|
|
|
59517
59589
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
59518
59590
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
59519
59591
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
59520
|
-
appBuilderPersonaRoot:
|
|
59592
|
+
appBuilderPersonaRoot: import_node_path63.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
59521
59593
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59522
|
-
deployKitRoot:
|
|
59594
|
+
deployKitRoot: import_node_path63.default.join(config.dataDir, "deploy-kit"),
|
|
59523
59595
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59524
|
-
resolvePersonaRoot: (personaId) =>
|
|
59596
|
+
resolvePersonaRoot: (personaId) => import_node_path63.default.join(config.dataDir, "personas", personaId),
|
|
59525
59597
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59526
59598
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59527
59599
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59564,7 +59636,7 @@ async function startDaemon(config) {
|
|
|
59564
59636
|
}
|
|
59565
59637
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
59566
59638
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
59567
|
-
sourceJsonlPath =
|
|
59639
|
+
sourceJsonlPath = import_node_path63.default.join(
|
|
59568
59640
|
import_node_os21.default.homedir(),
|
|
59569
59641
|
".claude",
|
|
59570
59642
|
"projects",
|
|
@@ -59894,8 +59966,8 @@ async function startDaemon(config) {
|
|
|
59894
59966
|
const lines = [
|
|
59895
59967
|
`Tunnel: ${r.url}`,
|
|
59896
59968
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
59897
|
-
`Frpc config: ${
|
|
59898
|
-
`Frpc log: ${
|
|
59969
|
+
`Frpc config: ${import_node_path63.default.join(config.dataDir, "frpc.toml")}`,
|
|
59970
|
+
`Frpc log: ${import_node_path63.default.join(config.dataDir, "frpc.log")}`
|
|
59899
59971
|
];
|
|
59900
59972
|
const width = Math.max(...lines.map((l) => l.length));
|
|
59901
59973
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -59908,8 +59980,8 @@ ${bar}
|
|
|
59908
59980
|
|
|
59909
59981
|
`);
|
|
59910
59982
|
try {
|
|
59911
|
-
const connectPath =
|
|
59912
|
-
|
|
59983
|
+
const connectPath = import_node_path63.default.join(config.dataDir, "connect.txt");
|
|
59984
|
+
import_node_fs50.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
59913
59985
|
} catch {
|
|
59914
59986
|
}
|
|
59915
59987
|
} catch (err) {
|
|
@@ -59943,7 +60015,7 @@ ${bar}
|
|
|
59943
60015
|
});
|
|
59944
60016
|
try {
|
|
59945
60017
|
await sshdMgr.start();
|
|
59946
|
-
rebuildAuthorizedKeys(contactStore,
|
|
60018
|
+
rebuildAuthorizedKeys(contactStore, import_node_path63.default.join(config.dataDir, "sshd"));
|
|
59947
60019
|
logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
|
|
59948
60020
|
} catch (err) {
|
|
59949
60021
|
logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
|
|
@@ -60011,9 +60083,9 @@ ${bar}
|
|
|
60011
60083
|
};
|
|
60012
60084
|
}
|
|
60013
60085
|
function migrateDropPersonsDir(dataDir) {
|
|
60014
|
-
const dir =
|
|
60086
|
+
const dir = import_node_path63.default.join(dataDir, "persons");
|
|
60015
60087
|
try {
|
|
60016
|
-
|
|
60088
|
+
import_node_fs50.default.rmSync(dir, { recursive: true, force: true });
|
|
60017
60089
|
} catch {
|
|
60018
60090
|
}
|
|
60019
60091
|
}
|