@clawos-dev/clawd 0.2.207 → 0.2.209-beta.415.57f6599
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 +806 -867
- package/dist/deploy-kit/.secrets/aliyun.env +2 -2
- package/dist/persona-defaults/persona-app-builder/.mcp.json +4 -5
- package/dist/persona-defaults/persona-app-builder/CLAUDE.md +3 -3
- package/dist/persona-defaults/persona-app-builder/extension-kit/config.env +7 -8
- 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,
|
|
@@ -11312,10 +11312,10 @@ function cwdToHashDir(cwd) {
|
|
|
11312
11312
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
11313
11313
|
}
|
|
11314
11314
|
function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
|
|
11315
|
-
const dir =
|
|
11315
|
+
const dir = import_node_path4.default.join(projectsRoot, cwdToHashDir(cwd), toolSessionId, "subagents");
|
|
11316
11316
|
let entries;
|
|
11317
11317
|
try {
|
|
11318
|
-
entries =
|
|
11318
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11319
11319
|
} catch {
|
|
11320
11320
|
return null;
|
|
11321
11321
|
}
|
|
@@ -11324,7 +11324,7 @@ function newestSubagentMtimeMs(projectsRoot, cwd, toolSessionId) {
|
|
|
11324
11324
|
if (!e.isFile()) continue;
|
|
11325
11325
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11326
11326
|
try {
|
|
11327
|
-
const m2 =
|
|
11327
|
+
const m2 = import_node_fs4.default.statSync(import_node_path4.default.join(dir, e.name)).mtimeMs;
|
|
11328
11328
|
if (newest === null || m2 > newest) newest = m2;
|
|
11329
11329
|
} catch {
|
|
11330
11330
|
}
|
|
@@ -11337,7 +11337,7 @@ function hashDirToCwd(hash) {
|
|
|
11337
11337
|
}
|
|
11338
11338
|
function safeStatMtime(p2) {
|
|
11339
11339
|
try {
|
|
11340
|
-
return
|
|
11340
|
+
return import_node_fs4.default.statSync(p2).mtimeMs;
|
|
11341
11341
|
} catch {
|
|
11342
11342
|
return 0;
|
|
11343
11343
|
}
|
|
@@ -11345,7 +11345,7 @@ function safeStatMtime(p2) {
|
|
|
11345
11345
|
function readJsonlLines(file) {
|
|
11346
11346
|
let raw;
|
|
11347
11347
|
try {
|
|
11348
|
-
raw =
|
|
11348
|
+
raw = import_node_fs4.default.readFileSync(file, "utf8");
|
|
11349
11349
|
} catch (err) {
|
|
11350
11350
|
if (err.code === "ENOENT") return [];
|
|
11351
11351
|
throw err;
|
|
@@ -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);
|
|
@@ -11576,8 +11576,8 @@ function attachmentDeferredToolsText(a) {
|
|
|
11576
11576
|
function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
11577
11577
|
if (backupFileName === null) return null;
|
|
11578
11578
|
try {
|
|
11579
|
-
return
|
|
11580
|
-
|
|
11579
|
+
return import_node_fs4.default.readFileSync(
|
|
11580
|
+
import_node_path4.default.join(fileHistoryRoot, toolSessionId, backupFileName),
|
|
11581
11581
|
"utf8"
|
|
11582
11582
|
);
|
|
11583
11583
|
} catch {
|
|
@@ -11586,19 +11586,19 @@ function readBackupContent(fileHistoryRoot, toolSessionId, backupFileName) {
|
|
|
11586
11586
|
}
|
|
11587
11587
|
function readCurrentContent(filePath) {
|
|
11588
11588
|
try {
|
|
11589
|
-
return
|
|
11589
|
+
return import_node_fs4.default.readFileSync(filePath, "utf8");
|
|
11590
11590
|
} catch (err) {
|
|
11591
11591
|
if (err.code === "ENOENT") return null;
|
|
11592
11592
|
return null;
|
|
11593
11593
|
}
|
|
11594
11594
|
}
|
|
11595
|
-
var
|
|
11595
|
+
var import_node_fs4, import_node_os3, import_node_path4, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
|
|
11596
11596
|
var init_claude_history = __esm({
|
|
11597
11597
|
"src/tools/claude-history.ts"() {
|
|
11598
11598
|
"use strict";
|
|
11599
|
-
|
|
11599
|
+
import_node_fs4 = __toESM(require("fs"), 1);
|
|
11600
11600
|
import_node_os3 = __toESM(require("os"), 1);
|
|
11601
|
-
|
|
11601
|
+
import_node_path4 = __toESM(require("path"), 1);
|
|
11602
11602
|
init_lib();
|
|
11603
11603
|
init_tool_result_extra();
|
|
11604
11604
|
TASK_NOTIFICATION_RE = /<task-notification\b[\s\S]*?<\/task-notification>/i;
|
|
@@ -11622,14 +11622,14 @@ var init_claude_history = __esm({
|
|
|
11622
11622
|
// 每次 user 提交前 trackEdit 拷一份,作为 rewind 回退目标
|
|
11623
11623
|
fileHistoryRoot;
|
|
11624
11624
|
constructor(opts = {}) {
|
|
11625
|
-
const base = opts.baseDir ??
|
|
11626
|
-
this.projectsRoot =
|
|
11627
|
-
this.fileHistoryRoot =
|
|
11625
|
+
const base = opts.baseDir ?? import_node_path4.default.join(import_node_os3.default.homedir(), ".claude");
|
|
11626
|
+
this.projectsRoot = import_node_path4.default.join(base, "projects");
|
|
11627
|
+
this.fileHistoryRoot = import_node_path4.default.join(base, "file-history");
|
|
11628
11628
|
}
|
|
11629
11629
|
async listProjects() {
|
|
11630
11630
|
let entries;
|
|
11631
11631
|
try {
|
|
11632
|
-
entries =
|
|
11632
|
+
entries = import_node_fs4.default.readdirSync(this.projectsRoot, { withFileTypes: true });
|
|
11633
11633
|
} catch (err) {
|
|
11634
11634
|
if (err.code === "ENOENT") return [];
|
|
11635
11635
|
throw err;
|
|
@@ -11637,9 +11637,9 @@ var init_claude_history = __esm({
|
|
|
11637
11637
|
const out = [];
|
|
11638
11638
|
for (const ent of entries) {
|
|
11639
11639
|
if (!ent.isDirectory()) continue;
|
|
11640
|
-
const dir =
|
|
11641
|
-
const files =
|
|
11642
|
-
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(
|
|
11640
|
+
const dir = import_node_path4.default.join(this.projectsRoot, ent.name);
|
|
11641
|
+
const files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11642
|
+
const updatedAtMs = files.reduce((m2, f) => Math.max(m2, safeStatMtime(import_node_path4.default.join(dir, f))), 0);
|
|
11643
11643
|
out.push({
|
|
11644
11644
|
projectPath: hashDirToCwd(ent.name),
|
|
11645
11645
|
hashDir: ent.name,
|
|
@@ -11651,17 +11651,17 @@ var init_claude_history = __esm({
|
|
|
11651
11651
|
return out;
|
|
11652
11652
|
}
|
|
11653
11653
|
async listSessions(args) {
|
|
11654
|
-
const dir =
|
|
11654
|
+
const dir = import_node_path4.default.join(this.projectsRoot, cwdToHashDir(args.projectPath));
|
|
11655
11655
|
let files;
|
|
11656
11656
|
try {
|
|
11657
|
-
files =
|
|
11657
|
+
files = import_node_fs4.default.readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
11658
11658
|
} catch (err) {
|
|
11659
11659
|
if (err.code === "ENOENT") return [];
|
|
11660
11660
|
throw err;
|
|
11661
11661
|
}
|
|
11662
11662
|
const out = [];
|
|
11663
11663
|
for (const f of files) {
|
|
11664
|
-
const full =
|
|
11664
|
+
const full = import_node_path4.default.join(dir, f);
|
|
11665
11665
|
const toolSessionId = f.slice(0, -".jsonl".length);
|
|
11666
11666
|
const lines = readJsonlLines(full);
|
|
11667
11667
|
let summary = "";
|
|
@@ -11716,7 +11716,7 @@ var init_claude_history = __esm({
|
|
|
11716
11716
|
return out;
|
|
11717
11717
|
}
|
|
11718
11718
|
async read(args) {
|
|
11719
|
-
const file =
|
|
11719
|
+
const file = import_node_path4.default.join(
|
|
11720
11720
|
this.projectsRoot,
|
|
11721
11721
|
cwdToHashDir(args.cwd),
|
|
11722
11722
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11753,7 +11753,7 @@ var init_claude_history = __esm({
|
|
|
11753
11753
|
// 独立目录路径:<projectsRoot>/<cwdHash>/<toolSessionId>/subagents/*.jsonl
|
|
11754
11754
|
// 返回 null 表示目录不存在(调用方回退旧实现);返回空数组表示目录存在但无 jsonl
|
|
11755
11755
|
listSubagentsFromDirectory(cwd, toolSessionId) {
|
|
11756
|
-
const dir =
|
|
11756
|
+
const dir = import_node_path4.default.join(
|
|
11757
11757
|
this.projectsRoot,
|
|
11758
11758
|
cwdToHashDir(cwd),
|
|
11759
11759
|
toolSessionId,
|
|
@@ -11761,7 +11761,7 @@ var init_claude_history = __esm({
|
|
|
11761
11761
|
);
|
|
11762
11762
|
let entries;
|
|
11763
11763
|
try {
|
|
11764
|
-
entries =
|
|
11764
|
+
entries = import_node_fs4.default.readdirSync(dir, { withFileTypes: true });
|
|
11765
11765
|
} catch (err) {
|
|
11766
11766
|
if (err.code === "ENOENT") return null;
|
|
11767
11767
|
return null;
|
|
@@ -11771,7 +11771,7 @@ var init_claude_history = __esm({
|
|
|
11771
11771
|
if (!e.isFile()) continue;
|
|
11772
11772
|
if (!e.name.startsWith("agent-") || !e.name.endsWith(".jsonl")) continue;
|
|
11773
11773
|
const subagentId = e.name.slice("agent-".length, -".jsonl".length);
|
|
11774
|
-
const filePath =
|
|
11774
|
+
const filePath = import_node_path4.default.join(dir, e.name);
|
|
11775
11775
|
const lines = readJsonlLines(filePath);
|
|
11776
11776
|
let firstText = "";
|
|
11777
11777
|
let messageCount = 0;
|
|
@@ -11788,7 +11788,7 @@ var init_claude_history = __esm({
|
|
|
11788
11788
|
return out;
|
|
11789
11789
|
}
|
|
11790
11790
|
listSubagentsFromMainJsonl(cwd, toolSessionId) {
|
|
11791
|
-
const file =
|
|
11791
|
+
const file = import_node_path4.default.join(
|
|
11792
11792
|
this.projectsRoot,
|
|
11793
11793
|
cwdToHashDir(cwd),
|
|
11794
11794
|
`${toolSessionId}.jsonl`
|
|
@@ -11823,7 +11823,7 @@ var init_claude_history = __esm({
|
|
|
11823
11823
|
}
|
|
11824
11824
|
// 独立文件路径:agent-<subagentId>.jsonl;文件不存在返回 null 让调用方回退旧实现
|
|
11825
11825
|
readSubagentFromFile(cwd, toolSessionId, subagentId) {
|
|
11826
|
-
const file =
|
|
11826
|
+
const file = import_node_path4.default.join(
|
|
11827
11827
|
this.projectsRoot,
|
|
11828
11828
|
cwdToHashDir(cwd),
|
|
11829
11829
|
toolSessionId,
|
|
@@ -11832,7 +11832,7 @@ var init_claude_history = __esm({
|
|
|
11832
11832
|
);
|
|
11833
11833
|
let exists = false;
|
|
11834
11834
|
try {
|
|
11835
|
-
exists =
|
|
11835
|
+
exists = import_node_fs4.default.statSync(file).isFile();
|
|
11836
11836
|
} catch {
|
|
11837
11837
|
return null;
|
|
11838
11838
|
}
|
|
@@ -11851,7 +11851,7 @@ var init_claude_history = __esm({
|
|
|
11851
11851
|
* "那一刻每个 tracked 文件对应的 backup 文件名"
|
|
11852
11852
|
*/
|
|
11853
11853
|
readFileHistorySnapshots(args) {
|
|
11854
|
-
const file =
|
|
11854
|
+
const file = import_node_path4.default.join(
|
|
11855
11855
|
this.projectsRoot,
|
|
11856
11856
|
cwdToHashDir(args.cwd),
|
|
11857
11857
|
`${args.toolSessionId}.jsonl`
|
|
@@ -11896,7 +11896,7 @@ var init_claude_history = __esm({
|
|
|
11896
11896
|
for (const [anchorId, target] of snapshots) {
|
|
11897
11897
|
let hasAny = false;
|
|
11898
11898
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11899
|
-
const absPath =
|
|
11899
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11900
11900
|
const backupContent = readBackupContent(
|
|
11901
11901
|
this.fileHistoryRoot,
|
|
11902
11902
|
args.toolSessionId,
|
|
@@ -11936,7 +11936,7 @@ var init_claude_history = __esm({
|
|
|
11936
11936
|
let totalInsertions = 0;
|
|
11937
11937
|
let totalDeletions = 0;
|
|
11938
11938
|
for (const [rawPath, backup] of Object.entries(target)) {
|
|
11939
|
-
const absPath =
|
|
11939
|
+
const absPath = import_node_path4.default.isAbsolute(rawPath) ? rawPath : import_node_path4.default.join(args.cwd, rawPath);
|
|
11940
11940
|
const backupContent = readBackupContent(
|
|
11941
11941
|
this.fileHistoryRoot,
|
|
11942
11942
|
args.toolSessionId,
|
|
@@ -11983,7 +11983,7 @@ var init_claude_history = __esm({
|
|
|
11983
11983
|
};
|
|
11984
11984
|
}
|
|
11985
11985
|
readSubagentFromMainJsonl(cwd, toolSessionId, subagentId) {
|
|
11986
|
-
const file =
|
|
11986
|
+
const file = import_node_path4.default.join(
|
|
11987
11987
|
this.projectsRoot,
|
|
11988
11988
|
cwdToHashDir(cwd),
|
|
11989
11989
|
`${toolSessionId}.jsonl`
|
|
@@ -12016,13 +12016,13 @@ var init_src = __esm({
|
|
|
12016
12016
|
function probeViaWhich() {
|
|
12017
12017
|
try {
|
|
12018
12018
|
const out = (0, import_node_child_process2.execFileSync)("which", ["claude"], { encoding: "utf8" }).trim();
|
|
12019
|
-
if (out &&
|
|
12019
|
+
if (out && import_node_fs14.default.existsSync(out)) return out;
|
|
12020
12020
|
} catch {
|
|
12021
12021
|
}
|
|
12022
12022
|
return null;
|
|
12023
12023
|
}
|
|
12024
12024
|
async function probeClaude(env = process.env) {
|
|
12025
|
-
if (env.CLAUDE_BIN &&
|
|
12025
|
+
if (env.CLAUDE_BIN && import_node_fs14.default.existsSync(env.CLAUDE_BIN)) {
|
|
12026
12026
|
return { available: true, path: env.CLAUDE_BIN };
|
|
12027
12027
|
}
|
|
12028
12028
|
const w2 = probeViaWhich();
|
|
@@ -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);
|
|
@@ -12467,13 +12467,13 @@ function encodeClaudeStdin(text) {
|
|
|
12467
12467
|
};
|
|
12468
12468
|
return JSON.stringify(frame) + "\n";
|
|
12469
12469
|
}
|
|
12470
|
-
var import_node_child_process, import_node_child_process2,
|
|
12470
|
+
var import_node_child_process, import_node_child_process2, import_node_fs14, ATTACHMENT_SILENT_SUBTYPES2, unknownTypeHandler, ATTACHMENT_RE, IMAGE_EXT_MIME, CLAUDE_MODELS, CLAUDE_PERMISSION_MODES, CLAUDE_CAPABILITIES, ClaudeAdapter;
|
|
12471
12471
|
var init_claude = __esm({
|
|
12472
12472
|
"src/tools/claude.ts"() {
|
|
12473
12473
|
"use strict";
|
|
12474
12474
|
import_node_child_process = require("child_process");
|
|
12475
12475
|
import_node_child_process2 = require("child_process");
|
|
12476
|
-
|
|
12476
|
+
import_node_fs14 = __toESM(require("fs"), 1);
|
|
12477
12477
|
init_protocol();
|
|
12478
12478
|
init_claude_history();
|
|
12479
12479
|
init_tool_result_extra();
|
|
@@ -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;
|
|
@@ -40326,7 +40326,7 @@ var require_lib3 = __commonJS({
|
|
|
40326
40326
|
|
|
40327
40327
|
// src/sshd/contact-ssh-log.ts
|
|
40328
40328
|
function createContactSshLog(dataDir) {
|
|
40329
|
-
const file =
|
|
40329
|
+
const file = import_node_path40.default.join(dataDir, "contact-ssh.log");
|
|
40330
40330
|
function append(level, tag, message, meta) {
|
|
40331
40331
|
const time = (/* @__PURE__ */ new Date()).toISOString();
|
|
40332
40332
|
let line = `[${time}] [${level}] [${tag}] ${message}`;
|
|
@@ -40339,8 +40339,8 @@ function createContactSshLog(dataDir) {
|
|
|
40339
40339
|
}
|
|
40340
40340
|
line += "\n";
|
|
40341
40341
|
try {
|
|
40342
|
-
|
|
40343
|
-
|
|
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
40344
|
} catch {
|
|
40345
40345
|
}
|
|
40346
40346
|
}
|
|
@@ -40350,12 +40350,12 @@ function createContactSshLog(dataDir) {
|
|
|
40350
40350
|
error: (tag, message, meta) => append("ERROR", tag, message, meta)
|
|
40351
40351
|
};
|
|
40352
40352
|
}
|
|
40353
|
-
var
|
|
40353
|
+
var import_node_fs39, import_node_path40, nullContactSshLog;
|
|
40354
40354
|
var init_contact_ssh_log = __esm({
|
|
40355
40355
|
"src/sshd/contact-ssh-log.ts"() {
|
|
40356
40356
|
"use strict";
|
|
40357
|
-
|
|
40358
|
-
|
|
40357
|
+
import_node_fs39 = __toESM(require("fs"), 1);
|
|
40358
|
+
import_node_path40 = __toESM(require("path"), 1);
|
|
40359
40359
|
nullContactSshLog = {
|
|
40360
40360
|
info: () => {
|
|
40361
40361
|
},
|
|
@@ -40370,7 +40370,7 @@ var init_contact_ssh_log = __esm({
|
|
|
40370
40370
|
// src/run-case/recorder.ts
|
|
40371
40371
|
function startRunCaseRecorder(opts) {
|
|
40372
40372
|
const now = opts.now ?? Date.now;
|
|
40373
|
-
const dir =
|
|
40373
|
+
const dir = import_node_path64.default.dirname(opts.recordPath);
|
|
40374
40374
|
let stream = null;
|
|
40375
40375
|
let closing = false;
|
|
40376
40376
|
let closedSettled = false;
|
|
@@ -40384,8 +40384,8 @@ function startRunCaseRecorder(opts) {
|
|
|
40384
40384
|
});
|
|
40385
40385
|
const ensureStream = () => {
|
|
40386
40386
|
if (stream) return stream;
|
|
40387
|
-
|
|
40388
|
-
stream =
|
|
40387
|
+
import_node_fs51.default.mkdirSync(dir, { recursive: true });
|
|
40388
|
+
stream = import_node_fs51.default.createWriteStream(opts.recordPath, { flags: "a" });
|
|
40389
40389
|
stream.on("close", () => closedResolve());
|
|
40390
40390
|
return stream;
|
|
40391
40391
|
};
|
|
@@ -40410,12 +40410,12 @@ function startRunCaseRecorder(opts) {
|
|
|
40410
40410
|
};
|
|
40411
40411
|
return { tap, close, closed };
|
|
40412
40412
|
}
|
|
40413
|
-
var
|
|
40413
|
+
var import_node_fs51, import_node_path64;
|
|
40414
40414
|
var init_recorder = __esm({
|
|
40415
40415
|
"src/run-case/recorder.ts"() {
|
|
40416
40416
|
"use strict";
|
|
40417
|
-
|
|
40418
|
-
|
|
40417
|
+
import_node_fs51 = __toESM(require("fs"), 1);
|
|
40418
|
+
import_node_path64 = __toESM(require("path"), 1);
|
|
40419
40419
|
}
|
|
40420
40420
|
});
|
|
40421
40421
|
|
|
@@ -40458,7 +40458,7 @@ var init_wire = __esm({
|
|
|
40458
40458
|
// src/run-case/controller.ts
|
|
40459
40459
|
async function runController(opts) {
|
|
40460
40460
|
const now = opts.now ?? Date.now;
|
|
40461
|
-
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-"));
|
|
40462
40462
|
const ownsCwd = opts.cwd === void 0;
|
|
40463
40463
|
const recorder = startRunCaseRecorder({ recordPath: opts.record, now });
|
|
40464
40464
|
const spawnCtx = { cwd };
|
|
@@ -40619,19 +40619,19 @@ async function runController(opts) {
|
|
|
40619
40619
|
if (sigintHandler) process.off("SIGINT", sigintHandler);
|
|
40620
40620
|
if (ownsCwd) {
|
|
40621
40621
|
try {
|
|
40622
|
-
(0,
|
|
40622
|
+
(0, import_node_fs52.rmSync)(cwd, { recursive: true, force: true });
|
|
40623
40623
|
} catch {
|
|
40624
40624
|
}
|
|
40625
40625
|
}
|
|
40626
40626
|
return exitCode ?? 0;
|
|
40627
40627
|
}
|
|
40628
|
-
var
|
|
40628
|
+
var import_node_fs52, import_node_os22, import_node_path65;
|
|
40629
40629
|
var init_controller = __esm({
|
|
40630
40630
|
"src/run-case/controller.ts"() {
|
|
40631
40631
|
"use strict";
|
|
40632
|
-
|
|
40632
|
+
import_node_fs52 = require("fs");
|
|
40633
40633
|
import_node_os22 = __toESM(require("os"), 1);
|
|
40634
|
-
|
|
40634
|
+
import_node_path65 = __toESM(require("path"), 1);
|
|
40635
40635
|
init_claude();
|
|
40636
40636
|
init_stdout_splitter();
|
|
40637
40637
|
init_permission_stdio();
|
|
@@ -40742,13 +40742,13 @@ async function sshRelay(argv) {
|
|
|
40742
40742
|
process.stderr.write("clawd ssh-relay: missing <peer-device-id>\n" + SSH_RELAY_HELP);
|
|
40743
40743
|
return 2;
|
|
40744
40744
|
}
|
|
40745
|
-
const dataDir = args.dataDir ??
|
|
40745
|
+
const dataDir = args.dataDir ?? import_node_path66.default.join(import_node_os23.default.homedir(), ".clawd");
|
|
40746
40746
|
const sshLog = createContactSshLog(dataDir);
|
|
40747
40747
|
const contact = findContact(dataDir, args.peerDeviceId);
|
|
40748
40748
|
if (!contact) {
|
|
40749
40749
|
sshLog.error("relay.contact-not-found", "ssh-relay \u627E\u4E0D\u5230 peer contact", {
|
|
40750
40750
|
peerDeviceId: args.peerDeviceId,
|
|
40751
|
-
contactsPath:
|
|
40751
|
+
contactsPath: import_node_path66.default.join(dataDir, "contacts.json")
|
|
40752
40752
|
});
|
|
40753
40753
|
process.stderr.write(`clawd ssh-relay: contact ${args.peerDeviceId} not found in ${dataDir}/contacts.json
|
|
40754
40754
|
`);
|
|
@@ -40869,10 +40869,10 @@ function parseSshRelayArgs(argv) {
|
|
|
40869
40869
|
return out;
|
|
40870
40870
|
}
|
|
40871
40871
|
function findContact(dataDir, deviceId) {
|
|
40872
|
-
const file =
|
|
40872
|
+
const file = import_node_path66.default.join(dataDir, "contacts.json");
|
|
40873
40873
|
let raw;
|
|
40874
40874
|
try {
|
|
40875
|
-
raw =
|
|
40875
|
+
raw = import_node_fs53.default.readFileSync(file, "utf8");
|
|
40876
40876
|
} catch {
|
|
40877
40877
|
return null;
|
|
40878
40878
|
}
|
|
@@ -40890,13 +40890,13 @@ function findContact(dataDir, deviceId) {
|
|
|
40890
40890
|
}
|
|
40891
40891
|
return null;
|
|
40892
40892
|
}
|
|
40893
|
-
var
|
|
40893
|
+
var import_node_fs53, import_node_os23, import_node_path66, SSH_RELAY_HELP;
|
|
40894
40894
|
var init_sshd_cli_relay = __esm({
|
|
40895
40895
|
"src/sshd/sshd-cli-relay.ts"() {
|
|
40896
40896
|
"use strict";
|
|
40897
|
-
|
|
40897
|
+
import_node_fs53 = __toESM(require("fs"), 1);
|
|
40898
40898
|
import_node_os23 = __toESM(require("os"), 1);
|
|
40899
|
-
|
|
40899
|
+
import_node_path66 = __toESM(require("path"), 1);
|
|
40900
40900
|
init_wrapper();
|
|
40901
40901
|
init_src();
|
|
40902
40902
|
init_peer_forward();
|
|
@@ -41100,8 +41100,8 @@ Env (advanced):
|
|
|
41100
41100
|
`;
|
|
41101
41101
|
|
|
41102
41102
|
// src/index.ts
|
|
41103
|
-
var
|
|
41104
|
-
var
|
|
41103
|
+
var import_node_path63 = __toESM(require("path"), 1);
|
|
41104
|
+
var import_node_fs50 = __toESM(require("fs"), 1);
|
|
41105
41105
|
var import_node_os21 = __toESM(require("os"), 1);
|
|
41106
41106
|
|
|
41107
41107
|
// ../node_modules/.pnpm/uuid@10.0.0/node_modules/uuid/dist/esm-node/stringify.js
|
|
@@ -41731,8 +41731,8 @@ var SessionStoreFactory = class {
|
|
|
41731
41731
|
};
|
|
41732
41732
|
|
|
41733
41733
|
// src/session/manager.ts
|
|
41734
|
-
var
|
|
41735
|
-
var
|
|
41734
|
+
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
41735
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
41736
41736
|
var import_node_os5 = __toESM(require("os"), 1);
|
|
41737
41737
|
init_protocol();
|
|
41738
41738
|
|
|
@@ -41820,63 +41820,11 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
|
|
|
41820
41820
|
"~/.clawd/config.json",
|
|
41821
41821
|
"~/.clawd/auth.json"
|
|
41822
41822
|
]);
|
|
41823
|
+
const netv = s.sandbox.network ?? (s.sandbox.network = {});
|
|
41824
|
+
netv.allowedDomains = unionArr(netv.allowedDomains, ["*.tunnel.clawos.chat"]);
|
|
41823
41825
|
return s;
|
|
41824
41826
|
}
|
|
41825
41827
|
|
|
41826
|
-
// src/tools/owner-credentials.ts
|
|
41827
|
-
var import_node_fs4 = __toESM(require("fs"), 1);
|
|
41828
|
-
var import_node_path4 = __toESM(require("path"), 1);
|
|
41829
|
-
function readOwnerCredentials(homeDir, logger) {
|
|
41830
|
-
const settingsPath = import_node_path4.default.join(homeDir, ".claude", "settings.json");
|
|
41831
|
-
let raw;
|
|
41832
|
-
try {
|
|
41833
|
-
raw = import_node_fs4.default.readFileSync(settingsPath, "utf8");
|
|
41834
|
-
} catch (err) {
|
|
41835
|
-
const code = err.code;
|
|
41836
|
-
if (code === "ENOENT") return null;
|
|
41837
|
-
logger?.warn("owner ~/.claude/settings.json read failed", { code });
|
|
41838
|
-
return null;
|
|
41839
|
-
}
|
|
41840
|
-
let parsed;
|
|
41841
|
-
try {
|
|
41842
|
-
parsed = JSON.parse(raw);
|
|
41843
|
-
} catch {
|
|
41844
|
-
logger?.warn("owner ~/.claude/settings.json malformed JSON");
|
|
41845
|
-
return null;
|
|
41846
|
-
}
|
|
41847
|
-
if (!parsed || typeof parsed !== "object") return null;
|
|
41848
|
-
const obj = parsed;
|
|
41849
|
-
const bundle = {};
|
|
41850
|
-
const envRaw = obj.env;
|
|
41851
|
-
if (envRaw && typeof envRaw === "object" && !Array.isArray(envRaw)) {
|
|
41852
|
-
const filtered = {};
|
|
41853
|
-
for (const [k2, v2] of Object.entries(envRaw)) {
|
|
41854
|
-
if (k2.startsWith("ANTHROPIC_") && typeof v2 === "string") filtered[k2] = v2;
|
|
41855
|
-
}
|
|
41856
|
-
if (Object.keys(filtered).length > 0) bundle.env = filtered;
|
|
41857
|
-
}
|
|
41858
|
-
const helperRaw = obj.apiKeyHelper;
|
|
41859
|
-
if (typeof helperRaw === "string" && helperRaw.length > 0) {
|
|
41860
|
-
if (!import_node_path4.default.isAbsolute(helperRaw)) {
|
|
41861
|
-
logger?.warn(
|
|
41862
|
-
"owner apiKeyHelper is not absolute; cc will resolve against guest cwd (persona dir), likely EXEC not found",
|
|
41863
|
-
{ basename: import_node_path4.default.basename(helperRaw) }
|
|
41864
|
-
);
|
|
41865
|
-
}
|
|
41866
|
-
bundle.apiKeyHelper = helperRaw;
|
|
41867
|
-
}
|
|
41868
|
-
if (!bundle.env && !bundle.apiKeyHelper) return null;
|
|
41869
|
-
return bundle;
|
|
41870
|
-
}
|
|
41871
|
-
function mergeOwnerCredentials(guestSandbox, bundle) {
|
|
41872
|
-
if (!bundle) return guestSandbox;
|
|
41873
|
-
return {
|
|
41874
|
-
...guestSandbox,
|
|
41875
|
-
...bundle.env ? { env: bundle.env } : {},
|
|
41876
|
-
...bundle.apiKeyHelper ? { apiKeyHelper: bundle.apiKeyHelper } : {}
|
|
41877
|
-
};
|
|
41878
|
-
}
|
|
41879
|
-
|
|
41880
41828
|
// src/shift/wrap.ts
|
|
41881
41829
|
function wrapShiftFirePrompt(args) {
|
|
41882
41830
|
return [
|
|
@@ -41895,7 +41843,7 @@ function escapeAttr(v2) {
|
|
|
41895
41843
|
|
|
41896
41844
|
// src/session/runner.ts
|
|
41897
41845
|
var import_node_os4 = __toESM(require("os"), 1);
|
|
41898
|
-
var
|
|
41846
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
41899
41847
|
|
|
41900
41848
|
// src/session/reducer.ts
|
|
41901
41849
|
init_runtime();
|
|
@@ -42823,8 +42771,8 @@ init_permission_stdio();
|
|
|
42823
42771
|
init_claude_history();
|
|
42824
42772
|
|
|
42825
42773
|
// src/ipc-recorder.ts
|
|
42826
|
-
var
|
|
42827
|
-
var
|
|
42774
|
+
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
42775
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
42828
42776
|
function tsForFilename(ms) {
|
|
42829
42777
|
return new Date(ms).toISOString().replace(/[:.]/g, "-");
|
|
42830
42778
|
}
|
|
@@ -42835,8 +42783,8 @@ function startRecorder(opts) {
|
|
|
42835
42783
|
return null;
|
|
42836
42784
|
}
|
|
42837
42785
|
const now = opts.now ?? Date.now;
|
|
42838
|
-
const dir =
|
|
42839
|
-
const filePath =
|
|
42786
|
+
const dir = import_node_path5.default.join(opts.dataDir, "ipc-recordings", opts.sessionId);
|
|
42787
|
+
const filePath = import_node_path5.default.join(dir, `${tsForFilename(now())}.jsonl`);
|
|
42840
42788
|
let stream = null;
|
|
42841
42789
|
let closedResolve;
|
|
42842
42790
|
const closed = new Promise((resolve6) => {
|
|
@@ -42845,8 +42793,8 @@ function startRecorder(opts) {
|
|
|
42845
42793
|
let exited = false;
|
|
42846
42794
|
const ensureStream = () => {
|
|
42847
42795
|
if (stream) return stream;
|
|
42848
|
-
|
|
42849
|
-
stream =
|
|
42796
|
+
import_node_fs5.default.mkdirSync(dir, { recursive: true });
|
|
42797
|
+
stream = import_node_fs5.default.createWriteStream(filePath, { flags: "a" });
|
|
42850
42798
|
stream.on("close", () => closedResolve());
|
|
42851
42799
|
return stream;
|
|
42852
42800
|
};
|
|
@@ -43226,7 +43174,7 @@ var SessionRunner = class {
|
|
|
43226
43174
|
isSubagentActive() {
|
|
43227
43175
|
const toolSessionId = this.state.file.toolSessionId;
|
|
43228
43176
|
if (!toolSessionId) return false;
|
|
43229
|
-
const projectsRoot =
|
|
43177
|
+
const projectsRoot = import_node_path6.default.join(this.hooks.home ?? import_node_os4.default.homedir(), ".claude", "projects");
|
|
43230
43178
|
const mtime = newestSubagentMtimeMs(projectsRoot, this.state.file.cwd, toolSessionId);
|
|
43231
43179
|
if (mtime === null) return false;
|
|
43232
43180
|
const now = (this.hooks.now ?? Date.now)();
|
|
@@ -43314,15 +43262,15 @@ function extractEditPath(input) {
|
|
|
43314
43262
|
}
|
|
43315
43263
|
|
|
43316
43264
|
// src/debug/pty-probe.ts
|
|
43317
|
-
var
|
|
43318
|
-
var
|
|
43265
|
+
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
43266
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
43319
43267
|
var PROBE_DIR = "/tmp/clawd-probe";
|
|
43320
|
-
var EVENTS_FILE =
|
|
43268
|
+
var EVENTS_FILE = import_node_path7.default.join(PROBE_DIR, "events.jsonl");
|
|
43321
43269
|
var inited = false;
|
|
43322
43270
|
function ensureDir() {
|
|
43323
43271
|
if (inited) return true;
|
|
43324
43272
|
try {
|
|
43325
|
-
|
|
43273
|
+
import_node_fs6.default.mkdirSync(PROBE_DIR, { recursive: true });
|
|
43326
43274
|
inited = true;
|
|
43327
43275
|
return true;
|
|
43328
43276
|
} catch {
|
|
@@ -43333,15 +43281,15 @@ function probeEvent(event, data = {}) {
|
|
|
43333
43281
|
try {
|
|
43334
43282
|
if (!ensureDir()) return;
|
|
43335
43283
|
const line = JSON.stringify({ ts: Date.now(), event, ...data }) + "\n";
|
|
43336
|
-
|
|
43284
|
+
import_node_fs6.default.appendFileSync(EVENTS_FILE, line);
|
|
43337
43285
|
} catch {
|
|
43338
43286
|
}
|
|
43339
43287
|
}
|
|
43340
43288
|
function probeDumpReplay(sessionId, payload) {
|
|
43341
43289
|
try {
|
|
43342
43290
|
if (!ensureDir()) return "";
|
|
43343
|
-
const file =
|
|
43344
|
-
|
|
43291
|
+
const file = import_node_path7.default.join(PROBE_DIR, `replay-${sessionId}-${Date.now()}.ans`);
|
|
43292
|
+
import_node_fs6.default.writeFileSync(file, payload, "utf8");
|
|
43345
43293
|
return file;
|
|
43346
43294
|
} catch {
|
|
43347
43295
|
return "";
|
|
@@ -43450,7 +43398,7 @@ function derivePersonaSpawnCwd(file, personaRoot) {
|
|
|
43450
43398
|
`derivePersonaSpawnCwd: personaRoot missing for owner session ${file.sessionId} (ownerPersonaId=${personaId})`
|
|
43451
43399
|
);
|
|
43452
43400
|
}
|
|
43453
|
-
return
|
|
43401
|
+
return import_node_path8.default.join(personaRoot, safeFileName(personaId));
|
|
43454
43402
|
}
|
|
43455
43403
|
function makeInitialState(file, subSessionMeta) {
|
|
43456
43404
|
return {
|
|
@@ -43584,10 +43532,10 @@ var SessionManager = class {
|
|
|
43584
43532
|
// <dataDir>/sessions/ 列子目录 (排除 'default').
|
|
43585
43533
|
listPersonaIdsOnDisk() {
|
|
43586
43534
|
if (!this.deps.dataDir) return [];
|
|
43587
|
-
const root = this.deps.storeFactory ?
|
|
43535
|
+
const root = this.deps.storeFactory ? import_node_path8.default.join(this.deps.dataDir, "personas") : import_node_path8.default.join(this.deps.dataDir, "sessions");
|
|
43588
43536
|
let entries;
|
|
43589
43537
|
try {
|
|
43590
|
-
entries =
|
|
43538
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
43591
43539
|
} catch (err) {
|
|
43592
43540
|
const code = err?.code;
|
|
43593
43541
|
if (code === "ENOENT") return [];
|
|
@@ -43600,7 +43548,7 @@ var SessionManager = class {
|
|
|
43600
43548
|
// 只在 storeFactory 注入 (新布局) 下生效, 老布局无 guest 目录.
|
|
43601
43549
|
listGuestCapIdsForPersona(personaId) {
|
|
43602
43550
|
if (!this.deps.dataDir || !this.deps.storeFactory) return [];
|
|
43603
|
-
const root =
|
|
43551
|
+
const root = import_node_path8.default.join(
|
|
43604
43552
|
this.deps.dataDir,
|
|
43605
43553
|
"personas",
|
|
43606
43554
|
personaId,
|
|
@@ -43610,7 +43558,7 @@ var SessionManager = class {
|
|
|
43610
43558
|
);
|
|
43611
43559
|
let entries;
|
|
43612
43560
|
try {
|
|
43613
|
-
entries =
|
|
43561
|
+
entries = import_node_fs7.default.readdirSync(root, { withFileTypes: true });
|
|
43614
43562
|
} catch (err) {
|
|
43615
43563
|
const code = err?.code;
|
|
43616
43564
|
if (code === "ENOENT") return [];
|
|
@@ -43729,7 +43677,7 @@ var SessionManager = class {
|
|
|
43729
43677
|
callerDisplayName
|
|
43730
43678
|
);
|
|
43731
43679
|
if (subSessionMeta?.userWorkDir) {
|
|
43732
|
-
|
|
43680
|
+
import_node_fs7.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
43733
43681
|
}
|
|
43734
43682
|
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
43735
43683
|
if (!this.deps.personaRoot || !subSessionMeta?.userWorkDir) {
|
|
@@ -43738,19 +43686,10 @@ var SessionManager = class {
|
|
|
43738
43686
|
);
|
|
43739
43687
|
}
|
|
43740
43688
|
const base = this.deps.personaStore?.readSandboxSettings(scope.personaId) ?? null;
|
|
43741
|
-
const
|
|
43742
|
-
|
|
43743
|
-
const merged = mergeOwnerCredentials(sandboxSettings, ownerCreds);
|
|
43744
|
-
if (ownerCreds) {
|
|
43745
|
-
this.deps.logger?.info("owner credentials injected into guest spawn", {
|
|
43746
|
-
sessionId: file.sessionId,
|
|
43747
|
-
envKeys: ownerCreds.env ? Object.keys(ownerCreds.env) : [],
|
|
43748
|
-
apiKeyHelper: ownerCreds.apiKeyHelper ? "present" : "absent"
|
|
43749
|
-
});
|
|
43750
|
-
}
|
|
43751
|
-
subSessionMeta.extraSettings = JSON.stringify(merged);
|
|
43689
|
+
const settings = composeGuestSandbox(base, subSessionMeta.userWorkDir, file.cwd);
|
|
43690
|
+
subSessionMeta.extraSettings = JSON.stringify(settings);
|
|
43752
43691
|
const home = import_node_os5.default.homedir();
|
|
43753
|
-
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ?
|
|
43692
|
+
const expand = (p2) => p2 === "~" ? home : p2.startsWith("~/") ? import_node_path8.default.join(home, p2.slice(2)) : p2;
|
|
43754
43693
|
const codexCfg = this.deps.personaStore?.readCodexSandboxSettings(scope.personaId) ?? null;
|
|
43755
43694
|
subSessionMeta.codexSandbox = {
|
|
43756
43695
|
writableRoots: [subSessionMeta.userWorkDir, ...(codexCfg?.writableRoots ?? []).map(expand)],
|
|
@@ -43911,7 +43850,7 @@ var SessionManager = class {
|
|
|
43911
43850
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, "cwd required when ownerPersonaId is absent");
|
|
43912
43851
|
}
|
|
43913
43852
|
try {
|
|
43914
|
-
const stat =
|
|
43853
|
+
const stat = import_node_fs7.default.statSync(cwd);
|
|
43915
43854
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
43916
43855
|
} catch {
|
|
43917
43856
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${cwd}`);
|
|
@@ -44445,7 +44384,7 @@ var SessionManager = class {
|
|
|
44445
44384
|
*/
|
|
44446
44385
|
createForScope(args) {
|
|
44447
44386
|
try {
|
|
44448
|
-
const stat =
|
|
44387
|
+
const stat = import_node_fs7.default.statSync(args.cwd);
|
|
44449
44388
|
if (!stat.isDirectory()) throw new Error("not dir");
|
|
44450
44389
|
} catch {
|
|
44451
44390
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `cwd not a directory: ${args.cwd}`);
|
|
@@ -44661,7 +44600,7 @@ var SessionManager = class {
|
|
|
44661
44600
|
personaId: args.targetPersona,
|
|
44662
44601
|
mode: "owner"
|
|
44663
44602
|
};
|
|
44664
|
-
const cwd =
|
|
44603
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44665
44604
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44666
44605
|
const file = {
|
|
44667
44606
|
sessionId,
|
|
@@ -44726,7 +44665,7 @@ var SessionManager = class {
|
|
|
44726
44665
|
personaId: args.targetPersona,
|
|
44727
44666
|
mode: "owner"
|
|
44728
44667
|
};
|
|
44729
|
-
const cwd =
|
|
44668
|
+
const cwd = import_node_path8.default.join(this.deps.personaRoot, safeFileName(args.targetPersona));
|
|
44730
44669
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
44731
44670
|
const file = {
|
|
44732
44671
|
sessionId,
|
|
@@ -45214,28 +45153,28 @@ var SessionManager = class {
|
|
|
45214
45153
|
};
|
|
45215
45154
|
|
|
45216
45155
|
// src/persona/store.ts
|
|
45217
|
-
var
|
|
45218
|
-
var
|
|
45156
|
+
var fs8 = __toESM(require("fs"), 1);
|
|
45157
|
+
var path11 = __toESM(require("path"), 1);
|
|
45219
45158
|
init_protocol();
|
|
45220
45159
|
var PersonaStore = class {
|
|
45221
45160
|
constructor(root) {
|
|
45222
45161
|
this.root = root;
|
|
45223
|
-
|
|
45162
|
+
fs8.mkdirSync(root, { recursive: true });
|
|
45224
45163
|
}
|
|
45225
45164
|
root;
|
|
45226
45165
|
personaDir(personaId) {
|
|
45227
|
-
return
|
|
45166
|
+
return path11.join(this.root, safeFileName(personaId));
|
|
45228
45167
|
}
|
|
45229
45168
|
metaPath(personaId) {
|
|
45230
|
-
return
|
|
45169
|
+
return path11.join(this.personaDir(personaId), ".clawd", "persona.json");
|
|
45231
45170
|
}
|
|
45232
45171
|
claudeMdPath(personaId) {
|
|
45233
|
-
return
|
|
45172
|
+
return path11.join(this.personaDir(personaId), "CLAUDE.md");
|
|
45234
45173
|
}
|
|
45235
45174
|
// codex 原生读 cwd 的 AGENTS.md。人格双写镜像:claude 读 CLAUDE.md、codex 读 AGENTS.md,
|
|
45236
45175
|
// 两份内容恒一致,persona 切 tool 零迁移。
|
|
45237
45176
|
agentsMdPath(personaId) {
|
|
45238
|
-
return
|
|
45177
|
+
return path11.join(this.personaDir(personaId), "AGENTS.md");
|
|
45239
45178
|
}
|
|
45240
45179
|
/**
|
|
45241
45180
|
* persona 级 sandbox base 落盘路径 —— 故意放 `.clawd/` 而非 `.claude/`,让 CC 的 project
|
|
@@ -45244,11 +45183,11 @@ var PersonaStore = class {
|
|
|
45244
45183
|
* spawn 前 per-guest 动态拼到各自 session 目录的那份(base + 强制底座 + 本 guest userWorkDir carve)。
|
|
45245
45184
|
*/
|
|
45246
45185
|
sandboxSettingsPath(personaId) {
|
|
45247
|
-
return
|
|
45186
|
+
return path11.join(this.personaDir(personaId), ".clawd", "sandbox-settings.json");
|
|
45248
45187
|
}
|
|
45249
45188
|
write(persona, personality) {
|
|
45250
45189
|
const dir = this.personaDir(persona.personaId);
|
|
45251
|
-
|
|
45190
|
+
fs8.mkdirSync(path11.join(dir, ".clawd"), { recursive: true });
|
|
45252
45191
|
this.atomicWrite(this.claudeMdPath(persona.personaId), personality);
|
|
45253
45192
|
this.atomicWrite(this.agentsMdPath(persona.personaId), personality);
|
|
45254
45193
|
this.writeSandboxSettings(persona.personaId, buildGuestSettingsV1());
|
|
@@ -45267,9 +45206,9 @@ var PersonaStore = class {
|
|
|
45267
45206
|
ensureAgentsMirror(personaId) {
|
|
45268
45207
|
const claudeMd = this.claudeMdPath(personaId);
|
|
45269
45208
|
const agentsMd = this.agentsMdPath(personaId);
|
|
45270
|
-
if (!
|
|
45271
|
-
if (
|
|
45272
|
-
this.atomicWrite(agentsMd,
|
|
45209
|
+
if (!fs8.existsSync(claudeMd)) return false;
|
|
45210
|
+
if (fs8.existsSync(agentsMd)) return false;
|
|
45211
|
+
this.atomicWrite(agentsMd, fs8.readFileSync(claudeMd, "utf8"));
|
|
45273
45212
|
return true;
|
|
45274
45213
|
}
|
|
45275
45214
|
/**
|
|
@@ -45293,22 +45232,22 @@ var PersonaStore = class {
|
|
|
45293
45232
|
return { ...s, permissions: { ...s.permissions ?? {}, deny: [...prev, rule] } };
|
|
45294
45233
|
}
|
|
45295
45234
|
codexSandboxSettingsPath(personaId) {
|
|
45296
|
-
return
|
|
45235
|
+
return path11.join(this.personaDir(personaId), ".clawd", "codex-sandbox.json");
|
|
45297
45236
|
}
|
|
45298
45237
|
/** 读 codex-sandbox.json;不存在/损坏 → null。 */
|
|
45299
45238
|
readCodexSandboxSettings(personaId) {
|
|
45300
45239
|
const p2 = this.codexSandboxSettingsPath(personaId);
|
|
45301
|
-
if (!
|
|
45240
|
+
if (!fs8.existsSync(p2)) return null;
|
|
45302
45241
|
try {
|
|
45303
|
-
return CodexSandboxSettingsSchema.parse(JSON.parse(
|
|
45242
|
+
return CodexSandboxSettingsSchema.parse(JSON.parse(fs8.readFileSync(p2, "utf8")));
|
|
45304
45243
|
} catch {
|
|
45305
45244
|
return null;
|
|
45306
45245
|
}
|
|
45307
45246
|
}
|
|
45308
45247
|
/** 覆盖写 codex-sandbox.json(seed/migrate 用)。 */
|
|
45309
45248
|
writeCodexSandboxSettings(personaId, settings) {
|
|
45310
|
-
const dir =
|
|
45311
|
-
|
|
45249
|
+
const dir = path11.join(this.personaDir(personaId), ".clawd");
|
|
45250
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
45312
45251
|
this.atomicWrite(this.codexSandboxSettingsPath(personaId), JSON.stringify(settings, null, 2));
|
|
45313
45252
|
}
|
|
45314
45253
|
writeMeta(persona) {
|
|
@@ -45316,8 +45255,8 @@ var PersonaStore = class {
|
|
|
45316
45255
|
}
|
|
45317
45256
|
read(personaId) {
|
|
45318
45257
|
const p2 = this.metaPath(personaId);
|
|
45319
|
-
if (!
|
|
45320
|
-
const raw = JSON.parse(
|
|
45258
|
+
if (!fs8.existsSync(p2)) return null;
|
|
45259
|
+
const raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
45321
45260
|
if (raw && typeof raw === "object" && "tokenMap" in raw) {
|
|
45322
45261
|
delete raw.tokenMap;
|
|
45323
45262
|
this.atomicWrite(p2, JSON.stringify(raw, null, 2));
|
|
@@ -45325,13 +45264,13 @@ var PersonaStore = class {
|
|
|
45325
45264
|
return PersonaFileSchema.parse(raw);
|
|
45326
45265
|
}
|
|
45327
45266
|
has(personaId) {
|
|
45328
|
-
return
|
|
45267
|
+
return fs8.existsSync(this.metaPath(personaId));
|
|
45329
45268
|
}
|
|
45330
45269
|
readPersonality(personaId) {
|
|
45331
45270
|
const claudeMd = this.claudeMdPath(personaId);
|
|
45332
|
-
if (
|
|
45271
|
+
if (fs8.existsSync(claudeMd)) return fs8.readFileSync(claudeMd, "utf8");
|
|
45333
45272
|
const agentsMd = this.agentsMdPath(personaId);
|
|
45334
|
-
if (
|
|
45273
|
+
if (fs8.existsSync(agentsMd)) return fs8.readFileSync(agentsMd, "utf8");
|
|
45335
45274
|
return null;
|
|
45336
45275
|
}
|
|
45337
45276
|
/**
|
|
@@ -45340,23 +45279,23 @@ var PersonaStore = class {
|
|
|
45340
45279
|
*/
|
|
45341
45280
|
readSandboxSettings(personaId) {
|
|
45342
45281
|
const p2 = this.sandboxSettingsPath(personaId);
|
|
45343
|
-
if (!
|
|
45282
|
+
if (!fs8.existsSync(p2)) return null;
|
|
45344
45283
|
try {
|
|
45345
|
-
return JSON.parse(
|
|
45284
|
+
return JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
45346
45285
|
} catch {
|
|
45347
45286
|
return null;
|
|
45348
45287
|
}
|
|
45349
45288
|
}
|
|
45350
45289
|
/** Persona 私有 skills 目录路径:<personaDir>/.claude/skills */
|
|
45351
45290
|
skillsDir(personaId) {
|
|
45352
|
-
return
|
|
45291
|
+
return path11.join(this.personaDir(personaId), ".claude", "skills");
|
|
45353
45292
|
}
|
|
45354
45293
|
/**
|
|
45355
45294
|
* Claude Code 项目级 settings 路径:`<personaDir>/.claude/settings.json`。
|
|
45356
45295
|
* 这里只读 `enabledPlugins` 字段,由 owner 通过 CC `/plugin` 之类命令维护,daemon 不写。
|
|
45357
45296
|
*/
|
|
45358
45297
|
claudeSettingsPath(personaId) {
|
|
45359
|
-
return
|
|
45298
|
+
return path11.join(this.personaDir(personaId), ".claude", "settings.json");
|
|
45360
45299
|
}
|
|
45361
45300
|
/**
|
|
45362
45301
|
* 读取 persona 的 `.claude/settings.json` 中 `enabledPlugins` map,把 value === true
|
|
@@ -45371,10 +45310,10 @@ var PersonaStore = class {
|
|
|
45371
45310
|
*/
|
|
45372
45311
|
readEnabledPlugins(personaId) {
|
|
45373
45312
|
const p2 = this.claudeSettingsPath(personaId);
|
|
45374
|
-
if (!
|
|
45313
|
+
if (!fs8.existsSync(p2)) return [];
|
|
45375
45314
|
let raw;
|
|
45376
45315
|
try {
|
|
45377
|
-
raw = JSON.parse(
|
|
45316
|
+
raw = JSON.parse(fs8.readFileSync(p2, "utf8"));
|
|
45378
45317
|
} catch {
|
|
45379
45318
|
return [];
|
|
45380
45319
|
}
|
|
@@ -45388,22 +45327,22 @@ var PersonaStore = class {
|
|
|
45388
45327
|
return out;
|
|
45389
45328
|
}
|
|
45390
45329
|
list() {
|
|
45391
|
-
if (!
|
|
45392
|
-
return
|
|
45393
|
-
return
|
|
45330
|
+
if (!fs8.existsSync(this.root)) return [];
|
|
45331
|
+
return fs8.readdirSync(this.root).filter((name) => {
|
|
45332
|
+
return fs8.existsSync(path11.join(this.root, name, ".clawd", "persona.json"));
|
|
45394
45333
|
});
|
|
45395
45334
|
}
|
|
45396
45335
|
remove(personaId) {
|
|
45397
45336
|
const dir = this.personaDir(personaId);
|
|
45398
|
-
if (
|
|
45337
|
+
if (fs8.existsSync(dir)) fs8.rmSync(dir, { recursive: true, force: true });
|
|
45399
45338
|
}
|
|
45400
45339
|
personaDirPath(personaId) {
|
|
45401
45340
|
return this.personaDir(personaId);
|
|
45402
45341
|
}
|
|
45403
45342
|
atomicWrite(file, content) {
|
|
45404
45343
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
45405
|
-
|
|
45406
|
-
|
|
45344
|
+
fs8.writeFileSync(tmp, content, { mode: 384 });
|
|
45345
|
+
fs8.renameSync(tmp, file);
|
|
45407
45346
|
}
|
|
45408
45347
|
};
|
|
45409
45348
|
|
|
@@ -45449,9 +45388,9 @@ var PersonaRegistry = class {
|
|
|
45449
45388
|
var import_node_crypto3 = __toESM(require("crypto"), 1);
|
|
45450
45389
|
|
|
45451
45390
|
// src/skills/scanner.ts
|
|
45452
|
-
var
|
|
45391
|
+
var import_node_fs8 = __toESM(require("fs"), 1);
|
|
45453
45392
|
var import_node_os6 = __toESM(require("os"), 1);
|
|
45454
|
-
var
|
|
45393
|
+
var import_node_path9 = __toESM(require("path"), 1);
|
|
45455
45394
|
|
|
45456
45395
|
// src/skills/frontmatter.ts
|
|
45457
45396
|
var STRIP_QUOTES = /^["']|["']$/g;
|
|
@@ -45560,7 +45499,7 @@ function parseDescription(content) {
|
|
|
45560
45499
|
}
|
|
45561
45500
|
function isDirLikeSync(p2) {
|
|
45562
45501
|
try {
|
|
45563
|
-
return
|
|
45502
|
+
return import_node_fs8.default.statSync(p2).isDirectory();
|
|
45564
45503
|
} catch {
|
|
45565
45504
|
return false;
|
|
45566
45505
|
}
|
|
@@ -45568,19 +45507,19 @@ function isDirLikeSync(p2) {
|
|
|
45568
45507
|
function scanSkillDir(dir, source, seen, out, pluginName) {
|
|
45569
45508
|
let entries;
|
|
45570
45509
|
try {
|
|
45571
|
-
entries =
|
|
45510
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
45572
45511
|
} catch {
|
|
45573
45512
|
return;
|
|
45574
45513
|
}
|
|
45575
45514
|
for (const ent of entries) {
|
|
45576
|
-
const entryPath =
|
|
45515
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
45577
45516
|
if (!ent.isDirectory() && !(ent.isSymbolicLink() && isDirLikeSync(entryPath))) continue;
|
|
45578
45517
|
let content;
|
|
45579
45518
|
try {
|
|
45580
|
-
content =
|
|
45519
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "SKILL.md"), "utf8");
|
|
45581
45520
|
} catch {
|
|
45582
45521
|
try {
|
|
45583
|
-
content =
|
|
45522
|
+
content = import_node_fs8.default.readFileSync(import_node_path9.default.join(entryPath, "skill.md"), "utf8");
|
|
45584
45523
|
} catch {
|
|
45585
45524
|
continue;
|
|
45586
45525
|
}
|
|
@@ -45604,26 +45543,26 @@ function listSkillsForDir(dir, source) {
|
|
|
45604
45543
|
function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
45605
45544
|
let entries;
|
|
45606
45545
|
try {
|
|
45607
|
-
entries =
|
|
45546
|
+
entries = import_node_fs8.default.readdirSync(dir, { withFileTypes: true });
|
|
45608
45547
|
} catch {
|
|
45609
45548
|
return;
|
|
45610
45549
|
}
|
|
45611
45550
|
for (const ent of entries) {
|
|
45612
|
-
const entryPath =
|
|
45551
|
+
const entryPath = import_node_path9.default.join(dir, ent.name);
|
|
45613
45552
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync(entryPath)) {
|
|
45614
45553
|
const ns = ent.name;
|
|
45615
45554
|
let subEntries;
|
|
45616
45555
|
try {
|
|
45617
|
-
subEntries =
|
|
45556
|
+
subEntries = import_node_fs8.default.readdirSync(entryPath, { withFileTypes: true });
|
|
45618
45557
|
} catch {
|
|
45619
45558
|
continue;
|
|
45620
45559
|
}
|
|
45621
45560
|
for (const se of subEntries) {
|
|
45622
45561
|
if (!se.name.endsWith(".md")) continue;
|
|
45623
|
-
const sePath =
|
|
45562
|
+
const sePath = import_node_path9.default.join(entryPath, se.name);
|
|
45624
45563
|
let content;
|
|
45625
45564
|
try {
|
|
45626
|
-
content =
|
|
45565
|
+
content = import_node_fs8.default.readFileSync(sePath, "utf8");
|
|
45627
45566
|
} catch {
|
|
45628
45567
|
continue;
|
|
45629
45568
|
}
|
|
@@ -45640,7 +45579,7 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45640
45579
|
} else if (ent.name.endsWith(".md")) {
|
|
45641
45580
|
let content;
|
|
45642
45581
|
try {
|
|
45643
|
-
content =
|
|
45582
|
+
content = import_node_fs8.default.readFileSync(entryPath, "utf8");
|
|
45644
45583
|
} catch {
|
|
45645
45584
|
continue;
|
|
45646
45585
|
}
|
|
@@ -45656,10 +45595,10 @@ function scanCommandDir(dir, source, seen, out, pluginName) {
|
|
|
45656
45595
|
}
|
|
45657
45596
|
}
|
|
45658
45597
|
function readInstalledPlugins(home) {
|
|
45659
|
-
const file =
|
|
45598
|
+
const file = import_node_path9.default.join(home, ".claude", "plugins", "installed_plugins.json");
|
|
45660
45599
|
let raw;
|
|
45661
45600
|
try {
|
|
45662
|
-
raw =
|
|
45601
|
+
raw = import_node_fs8.default.readFileSync(file, "utf8");
|
|
45663
45602
|
} catch {
|
|
45664
45603
|
return [];
|
|
45665
45604
|
}
|
|
@@ -45707,14 +45646,14 @@ var SkillsScanner = class {
|
|
|
45707
45646
|
});
|
|
45708
45647
|
}
|
|
45709
45648
|
const fsBlock = [];
|
|
45710
|
-
scanSkillDir(
|
|
45711
|
-
scanCommandDir(
|
|
45712
|
-
scanSkillDir(
|
|
45713
|
-
scanCommandDir(
|
|
45649
|
+
scanSkillDir(import_node_path9.default.join(this.home, ".claude", "skills"), "global", seen, fsBlock);
|
|
45650
|
+
scanCommandDir(import_node_path9.default.join(this.home, ".claude", "commands"), "global", seen, fsBlock);
|
|
45651
|
+
scanSkillDir(import_node_path9.default.join(args.cwd, ".claude", "skills"), "project", seen, fsBlock);
|
|
45652
|
+
scanCommandDir(import_node_path9.default.join(args.cwd, ".claude", "commands"), "project", seen, fsBlock);
|
|
45714
45653
|
const plugins = [...readInstalledPlugins(this.home), ...this.extraPluginRoots];
|
|
45715
45654
|
for (const { name, root } of plugins) {
|
|
45716
|
-
scanSkillDir(
|
|
45717
|
-
scanCommandDir(
|
|
45655
|
+
scanSkillDir(import_node_path9.default.join(root, "skills"), "plugin", seen, fsBlock, name);
|
|
45656
|
+
scanCommandDir(import_node_path9.default.join(root, "commands"), "plugin", seen, fsBlock, name);
|
|
45718
45657
|
}
|
|
45719
45658
|
fsBlock.sort((a, b2) => a.name < b2.name ? -1 : a.name > b2.name ? 1 : 0);
|
|
45720
45659
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -45820,8 +45759,8 @@ var PersonaManager = class {
|
|
|
45820
45759
|
};
|
|
45821
45760
|
|
|
45822
45761
|
// src/persona/seed.ts
|
|
45823
|
-
var
|
|
45824
|
-
var
|
|
45762
|
+
var fs10 = __toESM(require("fs"), 1);
|
|
45763
|
+
var path13 = __toESM(require("path"), 1);
|
|
45825
45764
|
var import_node_url = require("url");
|
|
45826
45765
|
var import_meta = {};
|
|
45827
45766
|
var DEFAULT_BYPASS_PROFILE = {
|
|
@@ -45991,24 +45930,24 @@ function bundleSiblingFromArgv(argv1, sibling) {
|
|
|
45991
45930
|
if (!argv1) return null;
|
|
45992
45931
|
let real = argv1;
|
|
45993
45932
|
try {
|
|
45994
|
-
real =
|
|
45933
|
+
real = fs10.realpathSync(argv1);
|
|
45995
45934
|
} catch {
|
|
45996
45935
|
}
|
|
45997
|
-
return
|
|
45936
|
+
return path13.resolve(path13.dirname(real), sibling);
|
|
45998
45937
|
}
|
|
45999
45938
|
function findDefaultsRoot(logger) {
|
|
46000
45939
|
const candidates = [];
|
|
46001
45940
|
try {
|
|
46002
|
-
const here =
|
|
46003
|
-
candidates.push(
|
|
46004
|
-
candidates.push(
|
|
45941
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
45942
|
+
candidates.push(path13.resolve(here, "defaults"));
|
|
45943
|
+
candidates.push(path13.resolve(here, "persona-defaults"));
|
|
46005
45944
|
} catch {
|
|
46006
45945
|
}
|
|
46007
45946
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "persona-defaults");
|
|
46008
45947
|
if (fromArgv) candidates.push(fromArgv);
|
|
46009
45948
|
for (const c of candidates) {
|
|
46010
45949
|
try {
|
|
46011
|
-
if (
|
|
45950
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
46012
45951
|
logger?.info("persona.defaults-root.resolved", { root: c });
|
|
46013
45952
|
return c;
|
|
46014
45953
|
}
|
|
@@ -46025,8 +45964,8 @@ function seedDefaultPersonas(args) {
|
|
|
46025
45964
|
args.logger.info("persona.seed.skip", { personaId: entry.personaId, reason: "exists" });
|
|
46026
45965
|
continue;
|
|
46027
45966
|
}
|
|
46028
|
-
const bundleDir =
|
|
46029
|
-
if (!
|
|
45967
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
45968
|
+
if (!fs10.existsSync(bundleDir)) {
|
|
46030
45969
|
args.logger.warn("persona.seed.skip", {
|
|
46031
45970
|
personaId: entry.personaId,
|
|
46032
45971
|
reason: "bundle-missing",
|
|
@@ -46034,8 +45973,8 @@ function seedDefaultPersonas(args) {
|
|
|
46034
45973
|
});
|
|
46035
45974
|
continue;
|
|
46036
45975
|
}
|
|
46037
|
-
const claudeMdPath =
|
|
46038
|
-
if (!
|
|
45976
|
+
const claudeMdPath = path13.join(bundleDir, "CLAUDE.md");
|
|
45977
|
+
if (!fs10.existsSync(claudeMdPath)) {
|
|
46039
45978
|
args.logger.warn("persona.seed.skip", {
|
|
46040
45979
|
personaId: entry.personaId,
|
|
46041
45980
|
reason: "no-CLAUDE.md",
|
|
@@ -46043,7 +45982,7 @@ function seedDefaultPersonas(args) {
|
|
|
46043
45982
|
});
|
|
46044
45983
|
continue;
|
|
46045
45984
|
}
|
|
46046
|
-
const personality =
|
|
45985
|
+
const personality = fs10.readFileSync(claudeMdPath, "utf8");
|
|
46047
45986
|
const now = Date.now();
|
|
46048
45987
|
const persona = {
|
|
46049
45988
|
personaId: entry.personaId,
|
|
@@ -46069,17 +46008,17 @@ function seedDefaultPersonas(args) {
|
|
|
46069
46008
|
}
|
|
46070
46009
|
}
|
|
46071
46010
|
function skipNodeModulesUnder(srcRoot) {
|
|
46072
|
-
return (src) => !
|
|
46011
|
+
return (src) => !path13.relative(srcRoot, src).split(path13.sep).includes("node_modules");
|
|
46073
46012
|
}
|
|
46074
46013
|
function copyBundleExtras(srcDir, dstDir) {
|
|
46075
|
-
for (const entry of
|
|
46014
|
+
for (const entry of fs10.readdirSync(srcDir, { withFileTypes: true })) {
|
|
46076
46015
|
if (entry.name === "CLAUDE.md" || entry.name === ".clawd") continue;
|
|
46077
|
-
const srcPath =
|
|
46078
|
-
const dstPath =
|
|
46016
|
+
const srcPath = path13.join(srcDir, entry.name);
|
|
46017
|
+
const dstPath = path13.join(dstDir, entry.name);
|
|
46079
46018
|
if (entry.isDirectory()) {
|
|
46080
|
-
|
|
46019
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
46081
46020
|
} else if (entry.isFile()) {
|
|
46082
|
-
|
|
46021
|
+
fs10.copyFileSync(srcPath, dstPath);
|
|
46083
46022
|
}
|
|
46084
46023
|
}
|
|
46085
46024
|
}
|
|
@@ -46087,16 +46026,16 @@ var DAEMON_MANAGED_PATHS = ["extension-kit", "CLAUDE.md", ".mcp.json"];
|
|
|
46087
46026
|
function refreshDaemonManagedDirs(args) {
|
|
46088
46027
|
const entries = args.entries ?? DEFAULT_PERSONAS;
|
|
46089
46028
|
for (const entry of entries) {
|
|
46090
|
-
const bundleDir =
|
|
46091
|
-
if (!
|
|
46029
|
+
const bundleDir = path13.join(args.defaultsRoot, entry.personaId);
|
|
46030
|
+
if (!fs10.existsSync(bundleDir)) continue;
|
|
46092
46031
|
const personaDir = args.store.personaDirPath(entry.personaId);
|
|
46093
|
-
if (!
|
|
46032
|
+
if (!fs10.existsSync(personaDir)) continue;
|
|
46094
46033
|
for (const relPath of DAEMON_MANAGED_PATHS) {
|
|
46095
|
-
const srcPath =
|
|
46096
|
-
if (!
|
|
46097
|
-
const dstPath =
|
|
46034
|
+
const srcPath = path13.join(bundleDir, relPath);
|
|
46035
|
+
if (!fs10.existsSync(srcPath)) continue;
|
|
46036
|
+
const dstPath = path13.join(personaDir, relPath);
|
|
46098
46037
|
try {
|
|
46099
|
-
|
|
46038
|
+
fs10.cpSync(srcPath, dstPath, { recursive: true, force: true, dereference: true, filter: skipNodeModulesUnder(srcPath) });
|
|
46100
46039
|
args.logger.info("persona.refresh.synced", {
|
|
46101
46040
|
personaId: entry.personaId,
|
|
46102
46041
|
path: relPath
|
|
@@ -46156,15 +46095,15 @@ function migrateCodexSandbox(args) {
|
|
|
46156
46095
|
function findDeployKitRoot(logger) {
|
|
46157
46096
|
const candidates = [];
|
|
46158
46097
|
try {
|
|
46159
|
-
const here =
|
|
46160
|
-
candidates.push(
|
|
46098
|
+
const here = path13.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
46099
|
+
candidates.push(path13.resolve(here, "..", "deploy-kit"));
|
|
46161
46100
|
} catch {
|
|
46162
46101
|
}
|
|
46163
46102
|
const fromArgv = bundleSiblingFromArgv(process.argv[1], "deploy-kit");
|
|
46164
46103
|
if (fromArgv) candidates.push(fromArgv);
|
|
46165
46104
|
for (const c of candidates) {
|
|
46166
46105
|
try {
|
|
46167
|
-
if (
|
|
46106
|
+
if (fs10.statSync(c).isDirectory()) {
|
|
46168
46107
|
logger?.info("persona.deploy-kit-root.resolved", { root: c });
|
|
46169
46108
|
return c;
|
|
46170
46109
|
}
|
|
@@ -46175,8 +46114,8 @@ function findDeployKitRoot(logger) {
|
|
|
46175
46114
|
return null;
|
|
46176
46115
|
}
|
|
46177
46116
|
function seedDeployKit(args) {
|
|
46178
|
-
const dst =
|
|
46179
|
-
|
|
46117
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
46118
|
+
fs10.cpSync(args.deployKitBundleRoot, dst, {
|
|
46180
46119
|
recursive: true,
|
|
46181
46120
|
dereference: true,
|
|
46182
46121
|
force: false,
|
|
@@ -46185,35 +46124,35 @@ function seedDeployKit(args) {
|
|
|
46185
46124
|
args.logger.info("deploy-kit.seed.done", { dst });
|
|
46186
46125
|
}
|
|
46187
46126
|
function refreshDeployKit(args) {
|
|
46188
|
-
const dst =
|
|
46189
|
-
if (!
|
|
46127
|
+
const dst = path13.join(args.dataDir, "deploy-kit");
|
|
46128
|
+
if (!fs10.existsSync(dst)) {
|
|
46190
46129
|
seedDeployKit(args);
|
|
46191
46130
|
return;
|
|
46192
46131
|
}
|
|
46193
46132
|
for (const sub of ["scripts", "contract"]) {
|
|
46194
|
-
const s =
|
|
46195
|
-
if (
|
|
46196
|
-
|
|
46133
|
+
const s = path13.join(args.deployKitBundleRoot, sub);
|
|
46134
|
+
if (fs10.existsSync(s)) {
|
|
46135
|
+
fs10.cpSync(s, path13.join(dst, sub), { recursive: true, force: true, dereference: true });
|
|
46197
46136
|
}
|
|
46198
46137
|
}
|
|
46199
|
-
const secretsSrc =
|
|
46200
|
-
if (
|
|
46201
|
-
|
|
46202
|
-
for (const f of
|
|
46138
|
+
const secretsSrc = path13.join(args.deployKitBundleRoot, ".secrets");
|
|
46139
|
+
if (fs10.existsSync(secretsSrc)) {
|
|
46140
|
+
fs10.mkdirSync(path13.join(dst, ".secrets"), { recursive: true });
|
|
46141
|
+
for (const f of fs10.readdirSync(secretsSrc)) {
|
|
46203
46142
|
if (!f.endsWith(".example")) continue;
|
|
46204
|
-
|
|
46143
|
+
fs10.copyFileSync(path13.join(secretsSrc, f), path13.join(dst, ".secrets", f));
|
|
46205
46144
|
}
|
|
46206
46145
|
}
|
|
46207
46146
|
args.logger.info("deploy-kit.refresh.done", { dst });
|
|
46208
46147
|
}
|
|
46209
46148
|
|
|
46210
46149
|
// src/share-md-viewer/load.ts
|
|
46211
|
-
var
|
|
46212
|
-
var
|
|
46150
|
+
var import_node_fs10 = __toESM(require("fs"), 1);
|
|
46151
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
46213
46152
|
var import_node_url2 = require("url");
|
|
46214
46153
|
|
|
46215
46154
|
// src/share-md-viewer/asset-loader.ts
|
|
46216
|
-
var
|
|
46155
|
+
var import_node_fs9 = __toESM(require("fs"), 1);
|
|
46217
46156
|
function htmlEscape(s) {
|
|
46218
46157
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
46219
46158
|
}
|
|
@@ -46221,12 +46160,12 @@ function createViewerAssetLoader(opts) {
|
|
|
46221
46160
|
let viewerTemplate;
|
|
46222
46161
|
let errorTemplate;
|
|
46223
46162
|
try {
|
|
46224
|
-
viewerTemplate =
|
|
46163
|
+
viewerTemplate = import_node_fs9.default.readFileSync(opts.viewerHtmlPath, "utf8");
|
|
46225
46164
|
} catch (err) {
|
|
46226
46165
|
throw new Error(`viewer asset not found at ${opts.viewerHtmlPath}: ${err.message}`);
|
|
46227
46166
|
}
|
|
46228
46167
|
try {
|
|
46229
|
-
errorTemplate =
|
|
46168
|
+
errorTemplate = import_node_fs9.default.readFileSync(opts.errorHtmlPath, "utf8");
|
|
46230
46169
|
} catch (err) {
|
|
46231
46170
|
throw new Error(`viewer error asset not found at ${opts.errorHtmlPath}: ${err.message}`);
|
|
46232
46171
|
}
|
|
@@ -46245,25 +46184,25 @@ var import_meta2 = {};
|
|
|
46245
46184
|
function tryLoadViewerAssets(logger) {
|
|
46246
46185
|
const candidates = [];
|
|
46247
46186
|
try {
|
|
46248
|
-
const here =
|
|
46187
|
+
const here = import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
|
|
46249
46188
|
candidates.push(here);
|
|
46250
|
-
candidates.push(
|
|
46251
|
-
candidates.push(
|
|
46189
|
+
candidates.push(import_node_path10.default.resolve(here, ".."));
|
|
46190
|
+
candidates.push(import_node_path10.default.resolve(here, "..", "..", "dist"));
|
|
46252
46191
|
} catch {
|
|
46253
46192
|
}
|
|
46254
46193
|
if (process.argv[1]) {
|
|
46255
46194
|
let real = process.argv[1];
|
|
46256
46195
|
try {
|
|
46257
|
-
real =
|
|
46196
|
+
real = import_node_fs10.default.realpathSync(process.argv[1]);
|
|
46258
46197
|
} catch {
|
|
46259
46198
|
}
|
|
46260
|
-
candidates.push(
|
|
46199
|
+
candidates.push(import_node_path10.default.dirname(real));
|
|
46261
46200
|
}
|
|
46262
46201
|
for (const root of candidates) {
|
|
46263
|
-
const viewerHtmlPath =
|
|
46264
|
-
const errorHtmlPath =
|
|
46202
|
+
const viewerHtmlPath = import_node_path10.default.join(root, "share-md-viewer.html");
|
|
46203
|
+
const errorHtmlPath = import_node_path10.default.join(root, "share-md-viewer-error.html");
|
|
46265
46204
|
try {
|
|
46266
|
-
if (
|
|
46205
|
+
if (import_node_fs10.default.statSync(viewerHtmlPath).isFile() && import_node_fs10.default.statSync(errorHtmlPath).isFile()) {
|
|
46267
46206
|
logger?.info("share-md-viewer.assets-root.resolved", { root });
|
|
46268
46207
|
return createViewerAssetLoader({ viewerHtmlPath, errorHtmlPath });
|
|
46269
46208
|
}
|
|
@@ -46278,30 +46217,30 @@ function tryLoadViewerAssets(logger) {
|
|
|
46278
46217
|
}
|
|
46279
46218
|
|
|
46280
46219
|
// src/share-ui/load.ts
|
|
46281
|
-
var
|
|
46282
|
-
var
|
|
46220
|
+
var import_node_fs12 = __toESM(require("fs"), 1);
|
|
46221
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
46283
46222
|
var import_node_url3 = require("url");
|
|
46284
46223
|
|
|
46285
46224
|
// src/share-ui/asset-loader.ts
|
|
46286
|
-
var
|
|
46287
|
-
var
|
|
46225
|
+
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
46226
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
46288
46227
|
function createShareUiAssetLoader(opts) {
|
|
46289
46228
|
let indexHtml;
|
|
46290
46229
|
try {
|
|
46291
|
-
indexHtml =
|
|
46230
|
+
indexHtml = import_node_fs11.default.readFileSync(opts.indexHtmlPath, "utf8");
|
|
46292
46231
|
} catch (err) {
|
|
46293
46232
|
throw new Error(`share-ui index.html not found at ${opts.indexHtmlPath}: ${err.message}`);
|
|
46294
46233
|
}
|
|
46295
|
-
const assetsDir =
|
|
46234
|
+
const assetsDir = import_node_path11.default.resolve(opts.assetsDir);
|
|
46296
46235
|
return {
|
|
46297
46236
|
renderIndexHtml() {
|
|
46298
46237
|
return indexHtml;
|
|
46299
46238
|
},
|
|
46300
46239
|
resolveAssetPath(rel) {
|
|
46301
|
-
const resolved =
|
|
46302
|
-
if (resolved !== assetsDir && !resolved.startsWith(assetsDir +
|
|
46240
|
+
const resolved = import_node_path11.default.resolve(assetsDir, rel);
|
|
46241
|
+
if (resolved !== assetsDir && !resolved.startsWith(assetsDir + import_node_path11.default.sep)) return null;
|
|
46303
46242
|
try {
|
|
46304
|
-
if (
|
|
46243
|
+
if (import_node_fs11.default.statSync(resolved).isFile()) return resolved;
|
|
46305
46244
|
} catch {
|
|
46306
46245
|
}
|
|
46307
46246
|
return null;
|
|
@@ -46315,28 +46254,28 @@ function bundleDirFromArgv(argv1) {
|
|
|
46315
46254
|
if (!argv1) return null;
|
|
46316
46255
|
let real = argv1;
|
|
46317
46256
|
try {
|
|
46318
|
-
real =
|
|
46257
|
+
real = import_node_fs12.default.realpathSync(argv1);
|
|
46319
46258
|
} catch {
|
|
46320
46259
|
}
|
|
46321
|
-
return
|
|
46260
|
+
return import_node_path12.default.dirname(real);
|
|
46322
46261
|
}
|
|
46323
46262
|
function tryLoadShareUi(logger) {
|
|
46324
46263
|
const candidates = [];
|
|
46325
46264
|
try {
|
|
46326
|
-
const here =
|
|
46265
|
+
const here = import_node_path12.default.dirname((0, import_node_url3.fileURLToPath)(import_meta3.url));
|
|
46327
46266
|
candidates.push(here);
|
|
46328
|
-
candidates.push(
|
|
46329
|
-
candidates.push(
|
|
46267
|
+
candidates.push(import_node_path12.default.resolve(here, ".."));
|
|
46268
|
+
candidates.push(import_node_path12.default.resolve(here, "..", "..", "dist"));
|
|
46330
46269
|
} catch {
|
|
46331
46270
|
}
|
|
46332
46271
|
const argvDir = bundleDirFromArgv(process.argv[1]);
|
|
46333
46272
|
if (argvDir) candidates.push(argvDir);
|
|
46334
46273
|
for (const root of candidates) {
|
|
46335
|
-
const shareUiDir =
|
|
46336
|
-
const indexHtmlPath =
|
|
46337
|
-
const assetsDir =
|
|
46274
|
+
const shareUiDir = import_node_path12.default.join(root, "share-ui");
|
|
46275
|
+
const indexHtmlPath = import_node_path12.default.join(shareUiDir, "guest.html");
|
|
46276
|
+
const assetsDir = import_node_path12.default.join(shareUiDir, "assets");
|
|
46338
46277
|
try {
|
|
46339
|
-
if (
|
|
46278
|
+
if (import_node_fs12.default.statSync(indexHtmlPath).isFile() && import_node_fs12.default.statSync(assetsDir).isDirectory()) {
|
|
46340
46279
|
logger?.info("share-ui.assets-root.resolved", { root: shareUiDir });
|
|
46341
46280
|
return createShareUiAssetLoader({ indexHtmlPath, assetsDir });
|
|
46342
46281
|
}
|
|
@@ -46414,20 +46353,20 @@ function buildVisitorLogin(deps) {
|
|
|
46414
46353
|
}
|
|
46415
46354
|
|
|
46416
46355
|
// src/visitor/visitor-store.ts
|
|
46417
|
-
var
|
|
46418
|
-
var
|
|
46356
|
+
var import_node_fs13 = __toESM(require("fs"), 1);
|
|
46357
|
+
var import_node_path13 = __toESM(require("path"), 1);
|
|
46419
46358
|
function createVisitorStore(opts) {
|
|
46420
|
-
const file =
|
|
46359
|
+
const file = import_node_path13.default.join(opts.dir, "visitors.json");
|
|
46421
46360
|
const read = () => {
|
|
46422
46361
|
try {
|
|
46423
|
-
return JSON.parse(
|
|
46362
|
+
return JSON.parse(import_node_fs13.default.readFileSync(file, "utf8"));
|
|
46424
46363
|
} catch {
|
|
46425
46364
|
return [];
|
|
46426
46365
|
}
|
|
46427
46366
|
};
|
|
46428
46367
|
const write = (rows) => {
|
|
46429
|
-
|
|
46430
|
-
|
|
46368
|
+
import_node_fs13.default.mkdirSync(opts.dir, { recursive: true });
|
|
46369
|
+
import_node_fs13.default.writeFileSync(file, JSON.stringify(rows, null, 2));
|
|
46431
46370
|
};
|
|
46432
46371
|
return {
|
|
46433
46372
|
upsert(r) {
|
|
@@ -46461,7 +46400,7 @@ init_claude();
|
|
|
46461
46400
|
|
|
46462
46401
|
// src/tools/codex.ts
|
|
46463
46402
|
var import_node_child_process4 = require("child_process");
|
|
46464
|
-
var
|
|
46403
|
+
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
46465
46404
|
|
|
46466
46405
|
// src/tools/codex-session.ts
|
|
46467
46406
|
var import_node_child_process3 = require("child_process");
|
|
@@ -46709,8 +46648,8 @@ function turnStartInput(text) {
|
|
|
46709
46648
|
const items = [];
|
|
46710
46649
|
let leftover = text;
|
|
46711
46650
|
for (const m2 of text.matchAll(SKILL_RE)) {
|
|
46712
|
-
const [marker, name,
|
|
46713
|
-
items.push({ type: "skill", name, path:
|
|
46651
|
+
const [marker, name, path77] = m2;
|
|
46652
|
+
items.push({ type: "skill", name, path: path77 });
|
|
46714
46653
|
leftover = leftover.replace(marker, "");
|
|
46715
46654
|
}
|
|
46716
46655
|
for (const m2 of text.matchAll(ATTACHMENT_RE2)) {
|
|
@@ -46894,10 +46833,10 @@ function sanitizeCodexModel(model) {
|
|
|
46894
46833
|
return CODEX_MODELS.some((m2) => m2.id === model) ? model : void 0;
|
|
46895
46834
|
}
|
|
46896
46835
|
async function probeCodex(env = process.env) {
|
|
46897
|
-
if (env.CODEX_BIN &&
|
|
46836
|
+
if (env.CODEX_BIN && import_node_fs15.default.existsSync(env.CODEX_BIN)) return { available: true, path: env.CODEX_BIN };
|
|
46898
46837
|
try {
|
|
46899
46838
|
const out = (0, import_node_child_process4.execFileSync)("which", ["codex"], { encoding: "utf8" }).trim();
|
|
46900
|
-
if (out &&
|
|
46839
|
+
if (out && import_node_fs15.default.existsSync(out)) return { available: true, path: out };
|
|
46901
46840
|
} catch {
|
|
46902
46841
|
}
|
|
46903
46842
|
return { available: false };
|
|
@@ -46943,9 +46882,9 @@ var CodexAdapter = class {
|
|
|
46943
46882
|
|
|
46944
46883
|
// src/tools/claude-tui.ts
|
|
46945
46884
|
var import_node_crypto5 = require("crypto");
|
|
46946
|
-
var
|
|
46885
|
+
var import_node_fs16 = __toESM(require("fs"), 1);
|
|
46947
46886
|
var import_node_os7 = __toESM(require("os"), 1);
|
|
46948
|
-
var
|
|
46887
|
+
var import_node_path14 = __toESM(require("path"), 1);
|
|
46949
46888
|
var import_headless = __toESM(require_xterm_headless(), 1);
|
|
46950
46889
|
|
|
46951
46890
|
// ../node_modules/.pnpm/@xterm+addon-serialize@0.14.0/node_modules/@xterm/addon-serialize/lib/addon-serialize.mjs
|
|
@@ -48187,9 +48126,9 @@ function buildTuiSpawnArgs(ctx, isResume = false) {
|
|
|
48187
48126
|
function jsonlExistsForCtx(ctx) {
|
|
48188
48127
|
if (!ctx.toolSessionId) return false;
|
|
48189
48128
|
const home = import_node_os7.default.homedir();
|
|
48190
|
-
const file =
|
|
48129
|
+
const file = import_node_path14.default.join(home, ".claude", "projects", cwdToHashDir(ctx.cwd), `${ctx.toolSessionId}.jsonl`);
|
|
48191
48130
|
try {
|
|
48192
|
-
return
|
|
48131
|
+
return import_node_fs16.default.statSync(file).isFile();
|
|
48193
48132
|
} catch {
|
|
48194
48133
|
return false;
|
|
48195
48134
|
}
|
|
@@ -48258,10 +48197,10 @@ var PersonaDispatchManager = class {
|
|
|
48258
48197
|
};
|
|
48259
48198
|
|
|
48260
48199
|
// src/dispatch/mcp-config.ts
|
|
48261
|
-
var
|
|
48262
|
-
var
|
|
48200
|
+
var import_node_fs17 = __toESM(require("fs"), 1);
|
|
48201
|
+
var import_node_path15 = __toESM(require("path"), 1);
|
|
48263
48202
|
function dispatchMcpConfigPath(dataDir) {
|
|
48264
|
-
return
|
|
48203
|
+
return import_node_path15.default.join(dataDir, "dispatch.mcp.json");
|
|
48265
48204
|
}
|
|
48266
48205
|
function writeDispatchMcpConfig(args) {
|
|
48267
48206
|
const cfgPath = dispatchMcpConfigPath(args.dataDir);
|
|
@@ -48276,16 +48215,16 @@ function writeDispatchMcpConfig(args) {
|
|
|
48276
48215
|
}
|
|
48277
48216
|
}
|
|
48278
48217
|
};
|
|
48279
|
-
|
|
48280
|
-
|
|
48218
|
+
import_node_fs17.default.mkdirSync(args.dataDir, { recursive: true });
|
|
48219
|
+
import_node_fs17.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48281
48220
|
return cfgPath;
|
|
48282
48221
|
}
|
|
48283
48222
|
|
|
48284
48223
|
// src/ticket/mcp-config.ts
|
|
48285
|
-
var
|
|
48286
|
-
var
|
|
48224
|
+
var import_node_fs18 = __toESM(require("fs"), 1);
|
|
48225
|
+
var import_node_path16 = __toESM(require("path"), 1);
|
|
48287
48226
|
function ticketMcpConfigPath(dataDir) {
|
|
48288
|
-
return
|
|
48227
|
+
return import_node_path16.default.join(dataDir, "ticket.mcp.json");
|
|
48289
48228
|
}
|
|
48290
48229
|
function writeTicketMcpConfig(args) {
|
|
48291
48230
|
const cfgPath = ticketMcpConfigPath(args.dataDir);
|
|
@@ -48306,16 +48245,16 @@ function writeTicketMcpConfig(args) {
|
|
|
48306
48245
|
}
|
|
48307
48246
|
}
|
|
48308
48247
|
};
|
|
48309
|
-
|
|
48310
|
-
|
|
48248
|
+
import_node_fs18.default.mkdirSync(args.dataDir, { recursive: true });
|
|
48249
|
+
import_node_fs18.default.writeFileSync(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48311
48250
|
return cfgPath;
|
|
48312
48251
|
}
|
|
48313
48252
|
|
|
48314
48253
|
// src/shift/mcp-config.ts
|
|
48315
|
-
var
|
|
48316
|
-
var
|
|
48254
|
+
var import_node_fs19 = __toESM(require("fs"), 1);
|
|
48255
|
+
var import_node_path17 = __toESM(require("path"), 1);
|
|
48317
48256
|
function shiftMcpConfigPath(dataDir) {
|
|
48318
|
-
return
|
|
48257
|
+
return import_node_path17.default.join(dataDir, "shift.mcp.json");
|
|
48319
48258
|
}
|
|
48320
48259
|
async function writeShiftMcpConfig(args) {
|
|
48321
48260
|
const cfgPath = shiftMcpConfigPath(args.dataDir);
|
|
@@ -48330,16 +48269,16 @@ async function writeShiftMcpConfig(args) {
|
|
|
48330
48269
|
}
|
|
48331
48270
|
}
|
|
48332
48271
|
};
|
|
48333
|
-
await
|
|
48334
|
-
await
|
|
48272
|
+
await import_node_fs19.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
48273
|
+
await import_node_fs19.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48335
48274
|
return cfgPath;
|
|
48336
48275
|
}
|
|
48337
48276
|
|
|
48338
48277
|
// src/inbox/mcp-config.ts
|
|
48339
|
-
var
|
|
48340
|
-
var
|
|
48278
|
+
var import_node_fs20 = __toESM(require("fs"), 1);
|
|
48279
|
+
var import_node_path18 = __toESM(require("path"), 1);
|
|
48341
48280
|
function inboxMcpConfigPath(dataDir) {
|
|
48342
|
-
return
|
|
48281
|
+
return import_node_path18.default.join(dataDir, "inbox.mcp.json");
|
|
48343
48282
|
}
|
|
48344
48283
|
async function writeInboxMcpConfig(args) {
|
|
48345
48284
|
const cfgPath = inboxMcpConfigPath(args.dataDir);
|
|
@@ -48354,14 +48293,14 @@ async function writeInboxMcpConfig(args) {
|
|
|
48354
48293
|
}
|
|
48355
48294
|
}
|
|
48356
48295
|
};
|
|
48357
|
-
await
|
|
48358
|
-
await
|
|
48296
|
+
await import_node_fs20.default.promises.mkdir(args.dataDir, { recursive: true });
|
|
48297
|
+
await import_node_fs20.default.promises.writeFile(cfgPath, JSON.stringify(content, null, 2), "utf8");
|
|
48359
48298
|
return cfgPath;
|
|
48360
48299
|
}
|
|
48361
48300
|
|
|
48362
48301
|
// src/shift/store.ts
|
|
48363
48302
|
var import_promises = __toESM(require("fs/promises"), 1);
|
|
48364
|
-
var
|
|
48303
|
+
var import_node_path19 = __toESM(require("path"), 1);
|
|
48365
48304
|
var import_node_crypto6 = require("crypto");
|
|
48366
48305
|
|
|
48367
48306
|
// src/shift/constants.ts
|
|
@@ -48430,7 +48369,7 @@ function createShiftStore(deps) {
|
|
|
48430
48369
|
flushTimer = null;
|
|
48431
48370
|
}
|
|
48432
48371
|
const content = { version: 1, shifts };
|
|
48433
|
-
await import_promises.default.mkdir(
|
|
48372
|
+
await import_promises.default.mkdir(import_node_path19.default.dirname(deps.filePath), { recursive: true });
|
|
48434
48373
|
const tmp = `${deps.filePath}.tmp-${deps.now()}-${Math.floor(Math.random() * 1e6)}`;
|
|
48435
48374
|
await import_promises.default.writeFile(tmp, JSON.stringify(content, null, 2), "utf8");
|
|
48436
48375
|
await import_promises.default.rename(tmp, deps.filePath);
|
|
@@ -49164,13 +49103,13 @@ function mapSkillsListResponse(res) {
|
|
|
49164
49103
|
const r = s ?? {};
|
|
49165
49104
|
const name = str3(r.name);
|
|
49166
49105
|
if (!name) continue;
|
|
49167
|
-
const
|
|
49106
|
+
const path77 = str3(r.path);
|
|
49168
49107
|
const description = str3(r.description);
|
|
49169
49108
|
const isPlugin = name.includes(":");
|
|
49170
49109
|
out.push({
|
|
49171
49110
|
name,
|
|
49172
49111
|
source: isPlugin ? "plugin" : "project",
|
|
49173
|
-
...
|
|
49112
|
+
...path77 ? { path: path77 } : {},
|
|
49174
49113
|
...description ? { description } : {},
|
|
49175
49114
|
...isPlugin ? { plugin: name.split(":")[0] } : {}
|
|
49176
49115
|
});
|
|
@@ -49209,23 +49148,23 @@ async function listCodexSkills(cwd, deps = {}) {
|
|
|
49209
49148
|
}
|
|
49210
49149
|
|
|
49211
49150
|
// src/workspace/browser.ts
|
|
49212
|
-
var
|
|
49151
|
+
var import_node_fs21 = __toESM(require("fs"), 1);
|
|
49213
49152
|
var import_node_os8 = __toESM(require("os"), 1);
|
|
49214
|
-
var
|
|
49153
|
+
var import_node_path20 = __toESM(require("path"), 1);
|
|
49215
49154
|
init_protocol();
|
|
49216
49155
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
49217
49156
|
function resolveInsideCwd(cwd, subpath) {
|
|
49218
|
-
const absCwd =
|
|
49219
|
-
const joined =
|
|
49220
|
-
const rel =
|
|
49221
|
-
if (rel.startsWith("..") ||
|
|
49157
|
+
const absCwd = import_node_path20.default.resolve(cwd);
|
|
49158
|
+
const joined = import_node_path20.default.resolve(absCwd, subpath ?? ".");
|
|
49159
|
+
const rel = import_node_path20.default.relative(absCwd, joined);
|
|
49160
|
+
if (rel.startsWith("..") || import_node_path20.default.isAbsolute(rel)) {
|
|
49222
49161
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `path escapes cwd: ${subpath}`);
|
|
49223
49162
|
}
|
|
49224
49163
|
return joined;
|
|
49225
49164
|
}
|
|
49226
49165
|
function ensureCwd(cwd) {
|
|
49227
49166
|
try {
|
|
49228
|
-
const stat =
|
|
49167
|
+
const stat = import_node_fs21.default.statSync(cwd);
|
|
49229
49168
|
if (!stat.isDirectory()) {
|
|
49230
49169
|
throw new ClawdError(ERROR_CODES.INVALID_CWD, `not a directory: ${cwd}`);
|
|
49231
49170
|
}
|
|
@@ -49239,7 +49178,7 @@ var WorkspaceBrowser = class {
|
|
|
49239
49178
|
const cwd = args.cwd && args.cwd.length > 0 ? args.cwd : import_node_os8.default.homedir();
|
|
49240
49179
|
ensureCwd(cwd);
|
|
49241
49180
|
const full = resolveInsideCwd(cwd, args.path);
|
|
49242
|
-
const dirents =
|
|
49181
|
+
const dirents = import_node_fs21.default.readdirSync(full, { withFileTypes: true });
|
|
49243
49182
|
const entries = [];
|
|
49244
49183
|
for (const d of dirents) {
|
|
49245
49184
|
if (!args.showHidden && d.name.startsWith(".")) continue;
|
|
@@ -49249,7 +49188,7 @@ var WorkspaceBrowser = class {
|
|
|
49249
49188
|
mtime: ""
|
|
49250
49189
|
};
|
|
49251
49190
|
try {
|
|
49252
|
-
const st =
|
|
49191
|
+
const st = import_node_fs21.default.statSync(import_node_path20.default.join(full, d.name));
|
|
49253
49192
|
entry.mtime = new Date(st.mtimeMs).toISOString();
|
|
49254
49193
|
if (d.isFile()) entry.size = st.size;
|
|
49255
49194
|
} catch {
|
|
@@ -49265,14 +49204,14 @@ var WorkspaceBrowser = class {
|
|
|
49265
49204
|
read(args) {
|
|
49266
49205
|
ensureCwd(args.cwd);
|
|
49267
49206
|
const full = resolveInsideCwd(args.cwd, args.path);
|
|
49268
|
-
const st =
|
|
49207
|
+
const st = import_node_fs21.default.statSync(full);
|
|
49269
49208
|
if (!st.isFile()) {
|
|
49270
49209
|
throw new ClawdError(ERROR_CODES.INVALID_PATH, `not a file: ${args.path}`);
|
|
49271
49210
|
}
|
|
49272
49211
|
if (st.size > MAX_FILE_BYTES) {
|
|
49273
49212
|
throw new ClawdError(ERROR_CODES.FILE_TOO_LARGE, `file > ${MAX_FILE_BYTES} bytes`);
|
|
49274
49213
|
}
|
|
49275
|
-
const buf =
|
|
49214
|
+
const buf = import_node_fs21.default.readFileSync(full);
|
|
49276
49215
|
const isBinary = buf.includes(0);
|
|
49277
49216
|
if (isBinary) {
|
|
49278
49217
|
return {
|
|
@@ -49294,20 +49233,20 @@ var WorkspaceBrowser = class {
|
|
|
49294
49233
|
};
|
|
49295
49234
|
|
|
49296
49235
|
// src/skills/agents-scanner.ts
|
|
49297
|
-
var
|
|
49236
|
+
var import_node_fs22 = __toESM(require("fs"), 1);
|
|
49298
49237
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
49299
|
-
var
|
|
49238
|
+
var import_node_path21 = __toESM(require("path"), 1);
|
|
49300
49239
|
var DEFAULT_POLICY_DIR_DARWIN = "/Library/Application Support/ClaudeCode/.claude/agents";
|
|
49301
49240
|
function isDirLikeSync2(p2) {
|
|
49302
49241
|
try {
|
|
49303
|
-
return
|
|
49242
|
+
return import_node_fs22.default.statSync(p2).isDirectory();
|
|
49304
49243
|
} catch {
|
|
49305
49244
|
return false;
|
|
49306
49245
|
}
|
|
49307
49246
|
}
|
|
49308
49247
|
function fileExistsSync(p2) {
|
|
49309
49248
|
try {
|
|
49310
|
-
return
|
|
49249
|
+
return import_node_fs22.default.statSync(p2).isFile();
|
|
49311
49250
|
} catch {
|
|
49312
49251
|
return false;
|
|
49313
49252
|
}
|
|
@@ -49315,7 +49254,7 @@ function fileExistsSync(p2) {
|
|
|
49315
49254
|
function parseAgentFile(filePath) {
|
|
49316
49255
|
let content;
|
|
49317
49256
|
try {
|
|
49318
|
-
content =
|
|
49257
|
+
content = import_node_fs22.default.readFileSync(filePath, "utf8");
|
|
49319
49258
|
} catch {
|
|
49320
49259
|
return {};
|
|
49321
49260
|
}
|
|
@@ -49328,16 +49267,16 @@ function parseAgentFile(filePath) {
|
|
|
49328
49267
|
function scanAgentsDir(dir, source, seen, out) {
|
|
49329
49268
|
let entries;
|
|
49330
49269
|
try {
|
|
49331
|
-
entries =
|
|
49270
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
49332
49271
|
} catch {
|
|
49333
49272
|
return;
|
|
49334
49273
|
}
|
|
49335
49274
|
for (const ent of entries) {
|
|
49336
49275
|
if (!ent.name.endsWith(".md")) continue;
|
|
49337
|
-
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(
|
|
49276
|
+
if (!ent.isFile() && !(ent.isSymbolicLink() && fileExistsSync(import_node_path21.default.join(dir, ent.name)))) {
|
|
49338
49277
|
continue;
|
|
49339
49278
|
}
|
|
49340
|
-
const filePath =
|
|
49279
|
+
const filePath = import_node_path21.default.join(dir, ent.name);
|
|
49341
49280
|
const baseName = ent.name.replace(/\.md$/, "");
|
|
49342
49281
|
if (seen.has(baseName)) continue;
|
|
49343
49282
|
seen.add(baseName);
|
|
@@ -49355,12 +49294,12 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
49355
49294
|
function walk2(dir, namespaces) {
|
|
49356
49295
|
let entries;
|
|
49357
49296
|
try {
|
|
49358
|
-
entries =
|
|
49297
|
+
entries = import_node_fs22.default.readdirSync(dir, { withFileTypes: true });
|
|
49359
49298
|
} catch {
|
|
49360
49299
|
return;
|
|
49361
49300
|
}
|
|
49362
49301
|
for (const ent of entries) {
|
|
49363
|
-
const childPath =
|
|
49302
|
+
const childPath = import_node_path21.default.join(dir, ent.name);
|
|
49364
49303
|
if (ent.isDirectory() || ent.isSymbolicLink() && isDirLikeSync2(childPath)) {
|
|
49365
49304
|
walk2(childPath, [...namespaces, ent.name]);
|
|
49366
49305
|
continue;
|
|
@@ -49385,13 +49324,13 @@ function scanPluginAgentsTree(root, pluginName, seen, out) {
|
|
|
49385
49324
|
walk2(root, []);
|
|
49386
49325
|
}
|
|
49387
49326
|
function readInstalledPlugins2(home) {
|
|
49388
|
-
const pluginsDir =
|
|
49389
|
-
const v2 =
|
|
49390
|
-
const v1 =
|
|
49327
|
+
const pluginsDir = import_node_path21.default.join(home, ".claude", "plugins");
|
|
49328
|
+
const v2 = import_node_path21.default.join(pluginsDir, "installed_plugins_v2.json");
|
|
49329
|
+
const v1 = import_node_path21.default.join(pluginsDir, "installed_plugins.json");
|
|
49391
49330
|
let raw = null;
|
|
49392
49331
|
for (const candidate of [v2, v1]) {
|
|
49393
49332
|
try {
|
|
49394
|
-
raw =
|
|
49333
|
+
raw = import_node_fs22.default.readFileSync(candidate, "utf8");
|
|
49395
49334
|
break;
|
|
49396
49335
|
} catch {
|
|
49397
49336
|
}
|
|
@@ -49416,19 +49355,19 @@ function readInstalledPlugins2(home) {
|
|
|
49416
49355
|
return out;
|
|
49417
49356
|
}
|
|
49418
49357
|
function walkUpProjectAgentsDirs(startCwd, home, seen, out) {
|
|
49419
|
-
let cur =
|
|
49420
|
-
const fsRoot =
|
|
49358
|
+
let cur = import_node_path21.default.resolve(startCwd);
|
|
49359
|
+
const fsRoot = import_node_path21.default.parse(cur).root;
|
|
49421
49360
|
while (true) {
|
|
49422
|
-
scanAgentsDir(
|
|
49361
|
+
scanAgentsDir(import_node_path21.default.join(cur, ".claude", "agents"), "project", seen, out);
|
|
49423
49362
|
let hasGit = false;
|
|
49424
49363
|
try {
|
|
49425
|
-
hasGit =
|
|
49364
|
+
hasGit = import_node_fs22.default.existsSync(import_node_path21.default.join(cur, ".git"));
|
|
49426
49365
|
} catch {
|
|
49427
49366
|
}
|
|
49428
49367
|
if (hasGit) return;
|
|
49429
49368
|
if (cur === home) return;
|
|
49430
49369
|
if (cur === fsRoot) return;
|
|
49431
|
-
const parent =
|
|
49370
|
+
const parent = import_node_path21.default.dirname(cur);
|
|
49432
49371
|
if (parent === cur) return;
|
|
49433
49372
|
cur = parent;
|
|
49434
49373
|
}
|
|
@@ -49463,7 +49402,7 @@ var AgentsScanner = class {
|
|
|
49463
49402
|
}
|
|
49464
49403
|
const fsBlock = [];
|
|
49465
49404
|
scanAgentsDir(
|
|
49466
|
-
|
|
49405
|
+
import_node_path21.default.join(this.home, ".claude", "agents"),
|
|
49467
49406
|
"global",
|
|
49468
49407
|
seen,
|
|
49469
49408
|
fsBlock
|
|
@@ -49477,7 +49416,7 @@ var AgentsScanner = class {
|
|
|
49477
49416
|
...this.extraPluginRoots
|
|
49478
49417
|
];
|
|
49479
49418
|
for (const { name, root } of plugins) {
|
|
49480
|
-
const agentsRoot =
|
|
49419
|
+
const agentsRoot = import_node_path21.default.join(root, "agents");
|
|
49481
49420
|
scanPluginAgentsTree(agentsRoot, name, seen, fsBlock);
|
|
49482
49421
|
}
|
|
49483
49422
|
return [...builtinBlock, ...fsBlock];
|
|
@@ -49485,15 +49424,15 @@ var AgentsScanner = class {
|
|
|
49485
49424
|
};
|
|
49486
49425
|
|
|
49487
49426
|
// src/observer/session-observer.ts
|
|
49488
|
-
var
|
|
49427
|
+
var import_node_fs24 = __toESM(require("fs"), 1);
|
|
49489
49428
|
var import_node_os11 = __toESM(require("os"), 1);
|
|
49490
|
-
var
|
|
49429
|
+
var import_node_path23 = __toESM(require("path"), 1);
|
|
49491
49430
|
init_claude_history();
|
|
49492
49431
|
|
|
49493
49432
|
// src/observer/subagent-meta-observer.ts
|
|
49494
|
-
var
|
|
49433
|
+
var import_node_fs23 = __toESM(require("fs"), 1);
|
|
49495
49434
|
var import_node_os10 = __toESM(require("os"), 1);
|
|
49496
|
-
var
|
|
49435
|
+
var import_node_path22 = __toESM(require("path"), 1);
|
|
49497
49436
|
init_claude_history();
|
|
49498
49437
|
var META_RE = /^agent-([A-Za-z0-9_-]+)\.meta\.json$/;
|
|
49499
49438
|
var SubagentMetaObserver = class {
|
|
@@ -49506,7 +49445,7 @@ var SubagentMetaObserver = class {
|
|
|
49506
49445
|
watches = /* @__PURE__ */ new Map();
|
|
49507
49446
|
// public for spec only:测试直接拼路径写假 meta.json;生产 start() 内部自己解析
|
|
49508
49447
|
resolveSubagentDir(cwd, toolSessionId) {
|
|
49509
|
-
return
|
|
49448
|
+
return import_node_path22.default.join(
|
|
49510
49449
|
this.home,
|
|
49511
49450
|
".claude",
|
|
49512
49451
|
"projects",
|
|
@@ -49536,7 +49475,7 @@ var SubagentMetaObserver = class {
|
|
|
49536
49475
|
attachWatcher(w2) {
|
|
49537
49476
|
if (w2.watcher) return;
|
|
49538
49477
|
try {
|
|
49539
|
-
w2.watcher =
|
|
49478
|
+
w2.watcher = import_node_fs23.default.watch(w2.dirPath, { persistent: false }, (_evt, name) => {
|
|
49540
49479
|
if (!name) return;
|
|
49541
49480
|
const m2 = META_RE.exec(String(name));
|
|
49542
49481
|
if (!m2) return;
|
|
@@ -49548,7 +49487,7 @@ var SubagentMetaObserver = class {
|
|
|
49548
49487
|
scan(w2) {
|
|
49549
49488
|
let entries;
|
|
49550
49489
|
try {
|
|
49551
|
-
entries =
|
|
49490
|
+
entries = import_node_fs23.default.readdirSync(w2.dirPath);
|
|
49552
49491
|
} catch {
|
|
49553
49492
|
return;
|
|
49554
49493
|
}
|
|
@@ -49562,10 +49501,10 @@ var SubagentMetaObserver = class {
|
|
|
49562
49501
|
if (!m2) return;
|
|
49563
49502
|
const agentId = m2[1];
|
|
49564
49503
|
if (w2.emitted.has(agentId)) return;
|
|
49565
|
-
const file =
|
|
49504
|
+
const file = import_node_path22.default.join(w2.dirPath, name);
|
|
49566
49505
|
let raw;
|
|
49567
49506
|
try {
|
|
49568
|
-
raw =
|
|
49507
|
+
raw = import_node_fs23.default.readFileSync(file, "utf8");
|
|
49569
49508
|
} catch {
|
|
49570
49509
|
return;
|
|
49571
49510
|
}
|
|
@@ -49622,14 +49561,14 @@ var SessionObserver = class {
|
|
|
49622
49561
|
metaObserver;
|
|
49623
49562
|
resolveJsonlPath(cwd, toolSessionId, override) {
|
|
49624
49563
|
if (override) return override;
|
|
49625
|
-
return
|
|
49564
|
+
return import_node_path23.default.join(this.home, ".claude", "projects", cwdToHashDir(cwd), `${toolSessionId}.jsonl`);
|
|
49626
49565
|
}
|
|
49627
49566
|
start(args) {
|
|
49628
49567
|
this.stop(args.sessionId);
|
|
49629
49568
|
const filePath = this.resolveJsonlPath(args.cwd, args.toolSessionId, args.jsonlPath);
|
|
49630
49569
|
let size = 0;
|
|
49631
49570
|
try {
|
|
49632
|
-
size =
|
|
49571
|
+
size = import_node_fs24.default.statSync(filePath).size;
|
|
49633
49572
|
} catch {
|
|
49634
49573
|
}
|
|
49635
49574
|
const w2 = {
|
|
@@ -49643,10 +49582,10 @@ var SessionObserver = class {
|
|
|
49643
49582
|
prevIsRejectSentinel: false
|
|
49644
49583
|
};
|
|
49645
49584
|
try {
|
|
49646
|
-
|
|
49585
|
+
import_node_fs24.default.mkdirSync(import_node_path23.default.dirname(filePath), { recursive: true });
|
|
49647
49586
|
} catch {
|
|
49648
49587
|
}
|
|
49649
|
-
w2.watcher =
|
|
49588
|
+
w2.watcher = import_node_fs24.default.watch(import_node_path23.default.dirname(filePath), { persistent: false }, (_event, changedName) => {
|
|
49650
49589
|
if (!changedName || !filePath.endsWith(changedName)) return;
|
|
49651
49590
|
this.poll(w2);
|
|
49652
49591
|
});
|
|
@@ -49669,7 +49608,7 @@ var SessionObserver = class {
|
|
|
49669
49608
|
// 异常静默吞,不阻塞 watcher 启动
|
|
49670
49609
|
hydrateMetaTail(w2, maxLines = 200) {
|
|
49671
49610
|
try {
|
|
49672
|
-
const raw =
|
|
49611
|
+
const raw = import_node_fs24.default.readFileSync(w2.filePath, "utf8");
|
|
49673
49612
|
if (!raw) return;
|
|
49674
49613
|
const allLines = raw.split("\n").filter((l) => l.trim().length > 0);
|
|
49675
49614
|
if (allLines.length === 0) return;
|
|
@@ -49693,7 +49632,7 @@ var SessionObserver = class {
|
|
|
49693
49632
|
poll(w2) {
|
|
49694
49633
|
let size = 0;
|
|
49695
49634
|
try {
|
|
49696
|
-
size =
|
|
49635
|
+
size = import_node_fs24.default.statSync(w2.filePath).size;
|
|
49697
49636
|
} catch {
|
|
49698
49637
|
return;
|
|
49699
49638
|
}
|
|
@@ -49702,11 +49641,11 @@ var SessionObserver = class {
|
|
|
49702
49641
|
w2.buf = "";
|
|
49703
49642
|
}
|
|
49704
49643
|
if (size === w2.lastSize) return;
|
|
49705
|
-
const fd =
|
|
49644
|
+
const fd = import_node_fs24.default.openSync(w2.filePath, "r");
|
|
49706
49645
|
try {
|
|
49707
49646
|
const len = size - w2.lastSize;
|
|
49708
49647
|
const buf = Buffer.alloc(len);
|
|
49709
|
-
|
|
49648
|
+
import_node_fs24.default.readSync(fd, buf, 0, len, w2.lastSize);
|
|
49710
49649
|
w2.lastSize = size;
|
|
49711
49650
|
w2.buf += buf.toString("utf8");
|
|
49712
49651
|
let newlineIndex;
|
|
@@ -49729,7 +49668,7 @@ var SessionObserver = class {
|
|
|
49729
49668
|
}
|
|
49730
49669
|
}
|
|
49731
49670
|
} finally {
|
|
49732
|
-
|
|
49671
|
+
import_node_fs24.default.closeSync(fd);
|
|
49733
49672
|
}
|
|
49734
49673
|
}
|
|
49735
49674
|
// 解析 JSONL 单行:仅当是主链 user 文本行(非 sidechain / 非 sub-agent / message.role='user'
|
|
@@ -50532,15 +50471,15 @@ async function authenticate(token, deps) {
|
|
|
50532
50471
|
}
|
|
50533
50472
|
|
|
50534
50473
|
// src/permission/capability-store.ts
|
|
50535
|
-
var
|
|
50536
|
-
var
|
|
50474
|
+
var fs28 = __toESM(require("fs"), 1);
|
|
50475
|
+
var path28 = __toESM(require("path"), 1);
|
|
50537
50476
|
init_src();
|
|
50538
50477
|
var CAPABILITIES_FILE_NAME = "capabilities.json";
|
|
50539
50478
|
var FILE_VERSION = 1;
|
|
50540
50479
|
var CapabilityStore = class {
|
|
50541
50480
|
constructor(dataDir) {
|
|
50542
50481
|
this.dataDir = dataDir;
|
|
50543
|
-
|
|
50482
|
+
fs28.mkdirSync(dataDir, { recursive: true });
|
|
50544
50483
|
this.cache = this.readFromDisk();
|
|
50545
50484
|
}
|
|
50546
50485
|
dataDir;
|
|
@@ -50564,13 +50503,13 @@ var CapabilityStore = class {
|
|
|
50564
50503
|
this.flush();
|
|
50565
50504
|
}
|
|
50566
50505
|
filePath() {
|
|
50567
|
-
return
|
|
50506
|
+
return path28.join(this.dataDir, CAPABILITIES_FILE_NAME);
|
|
50568
50507
|
}
|
|
50569
50508
|
readFromDisk() {
|
|
50570
50509
|
const file = this.filePath();
|
|
50571
50510
|
let raw;
|
|
50572
50511
|
try {
|
|
50573
|
-
raw =
|
|
50512
|
+
raw = fs28.readFileSync(file, "utf8");
|
|
50574
50513
|
} catch (err) {
|
|
50575
50514
|
if (err?.code === "ENOENT") return [];
|
|
50576
50515
|
return [];
|
|
@@ -50598,10 +50537,10 @@ var CapabilityStore = class {
|
|
|
50598
50537
|
}
|
|
50599
50538
|
atomicWrite(file, content) {
|
|
50600
50539
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
50601
|
-
|
|
50602
|
-
|
|
50540
|
+
fs28.writeFileSync(tmp, content, { mode: 384 });
|
|
50541
|
+
fs28.renameSync(tmp, file);
|
|
50603
50542
|
try {
|
|
50604
|
-
|
|
50543
|
+
fs28.chmodSync(file, 384);
|
|
50605
50544
|
} catch {
|
|
50606
50545
|
}
|
|
50607
50546
|
}
|
|
@@ -50694,14 +50633,14 @@ var CapabilityManager = class {
|
|
|
50694
50633
|
};
|
|
50695
50634
|
|
|
50696
50635
|
// src/permission/cleanup.ts
|
|
50697
|
-
var
|
|
50636
|
+
var fs29 = __toESM(require("fs"), 1);
|
|
50698
50637
|
function cleanupGuestSessionsForCapability(cap, factory) {
|
|
50699
50638
|
const removed = [];
|
|
50700
50639
|
for (const g2 of cap.grants) {
|
|
50701
50640
|
if (g2.resource.type !== "persona") continue;
|
|
50702
50641
|
const dir = factory.vmGuestRoot(g2.resource.id, cap.id);
|
|
50703
50642
|
try {
|
|
50704
|
-
|
|
50643
|
+
fs29.rmSync(dir, { recursive: true, force: true });
|
|
50705
50644
|
removed.push(dir);
|
|
50706
50645
|
} catch {
|
|
50707
50646
|
}
|
|
@@ -50710,14 +50649,14 @@ function cleanupGuestSessionsForCapability(cap, factory) {
|
|
|
50710
50649
|
}
|
|
50711
50650
|
|
|
50712
50651
|
// src/inbox/inbox-store.ts
|
|
50713
|
-
var
|
|
50714
|
-
var
|
|
50652
|
+
var fs30 = __toESM(require("fs"), 1);
|
|
50653
|
+
var path29 = __toESM(require("path"), 1);
|
|
50715
50654
|
init_src();
|
|
50716
50655
|
var INBOX_SUBDIR = "inbox";
|
|
50717
50656
|
var InboxStore = class {
|
|
50718
50657
|
constructor(dataDir) {
|
|
50719
50658
|
this.dataDir = dataDir;
|
|
50720
|
-
|
|
50659
|
+
fs30.mkdirSync(this.dirPath(), { recursive: true });
|
|
50721
50660
|
}
|
|
50722
50661
|
dataDir;
|
|
50723
50662
|
/**
|
|
@@ -50729,7 +50668,7 @@ var InboxStore = class {
|
|
|
50729
50668
|
const file = this.filePath(peerDeviceId);
|
|
50730
50669
|
let raw;
|
|
50731
50670
|
try {
|
|
50732
|
-
raw =
|
|
50671
|
+
raw = fs30.readFileSync(file, "utf8");
|
|
50733
50672
|
} catch (err) {
|
|
50734
50673
|
if (err?.code === "ENOENT") return [];
|
|
50735
50674
|
return [];
|
|
@@ -50745,7 +50684,7 @@ var InboxStore = class {
|
|
|
50745
50684
|
const dir = this.dirPath();
|
|
50746
50685
|
let entries;
|
|
50747
50686
|
try {
|
|
50748
|
-
entries =
|
|
50687
|
+
entries = fs30.readdirSync(dir);
|
|
50749
50688
|
} catch (err) {
|
|
50750
50689
|
if (err?.code === "ENOENT") return [];
|
|
50751
50690
|
return [];
|
|
@@ -50761,9 +50700,9 @@ var InboxStore = class {
|
|
|
50761
50700
|
if (existing.some((m2) => m2.id === message.id)) return;
|
|
50762
50701
|
const file = this.filePath(message.peerDeviceId);
|
|
50763
50702
|
const line = JSON.stringify(message) + "\n";
|
|
50764
|
-
|
|
50703
|
+
fs30.appendFileSync(file, line, { mode: 384 });
|
|
50765
50704
|
try {
|
|
50766
|
-
|
|
50705
|
+
fs30.chmodSync(file, 384);
|
|
50767
50706
|
} catch {
|
|
50768
50707
|
}
|
|
50769
50708
|
}
|
|
@@ -50793,7 +50732,7 @@ var InboxStore = class {
|
|
|
50793
50732
|
removeByPeerDeviceId(peerDeviceId) {
|
|
50794
50733
|
const file = this.filePath(peerDeviceId);
|
|
50795
50734
|
try {
|
|
50796
|
-
|
|
50735
|
+
fs30.unlinkSync(file);
|
|
50797
50736
|
} catch (err) {
|
|
50798
50737
|
if (err?.code === "ENOENT") return;
|
|
50799
50738
|
}
|
|
@@ -50802,18 +50741,18 @@ var InboxStore = class {
|
|
|
50802
50741
|
const file = this.filePath(peerDeviceId);
|
|
50803
50742
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
50804
50743
|
const content = messages.map((m2) => JSON.stringify(m2)).join("\n") + (messages.length > 0 ? "\n" : "");
|
|
50805
|
-
|
|
50806
|
-
|
|
50744
|
+
fs30.writeFileSync(tmp, content, { mode: 384 });
|
|
50745
|
+
fs30.renameSync(tmp, file);
|
|
50807
50746
|
try {
|
|
50808
|
-
|
|
50747
|
+
fs30.chmodSync(file, 384);
|
|
50809
50748
|
} catch {
|
|
50810
50749
|
}
|
|
50811
50750
|
}
|
|
50812
50751
|
dirPath() {
|
|
50813
|
-
return
|
|
50752
|
+
return path29.join(this.dataDir, INBOX_SUBDIR);
|
|
50814
50753
|
}
|
|
50815
50754
|
filePath(peerDeviceId) {
|
|
50816
|
-
return
|
|
50755
|
+
return path29.join(this.dirPath(), `${peerDeviceId}.jsonl`);
|
|
50817
50756
|
}
|
|
50818
50757
|
};
|
|
50819
50758
|
function parseAllLines(raw) {
|
|
@@ -50901,8 +50840,8 @@ var InboxManager = class {
|
|
|
50901
50840
|
};
|
|
50902
50841
|
|
|
50903
50842
|
// src/state/contact-store.ts
|
|
50904
|
-
var
|
|
50905
|
-
var
|
|
50843
|
+
var fs31 = __toESM(require("fs"), 1);
|
|
50844
|
+
var path30 = __toESM(require("path"), 1);
|
|
50906
50845
|
init_src();
|
|
50907
50846
|
var FILE_NAME = "contacts.json";
|
|
50908
50847
|
var ContactStore = class {
|
|
@@ -50913,10 +50852,10 @@ var ContactStore = class {
|
|
|
50913
50852
|
contacts = /* @__PURE__ */ new Map();
|
|
50914
50853
|
load() {
|
|
50915
50854
|
this.contacts.clear();
|
|
50916
|
-
const file =
|
|
50855
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50917
50856
|
let raw;
|
|
50918
50857
|
try {
|
|
50919
|
-
raw =
|
|
50858
|
+
raw = fs31.readFileSync(file, "utf8");
|
|
50920
50859
|
} catch (err) {
|
|
50921
50860
|
if (err?.code !== "ENOENT") this.renameBak(file);
|
|
50922
50861
|
return;
|
|
@@ -50988,20 +50927,20 @@ var ContactStore = class {
|
|
|
50988
50927
|
return true;
|
|
50989
50928
|
}
|
|
50990
50929
|
flush() {
|
|
50991
|
-
const file =
|
|
50930
|
+
const file = path30.join(this.dataDir, FILE_NAME);
|
|
50992
50931
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
50993
50932
|
const content = JSON.stringify(
|
|
50994
50933
|
{ contacts: Array.from(this.contacts.values()) },
|
|
50995
50934
|
null,
|
|
50996
50935
|
2
|
|
50997
50936
|
);
|
|
50998
|
-
|
|
50999
|
-
|
|
51000
|
-
|
|
50937
|
+
fs31.mkdirSync(this.dataDir, { recursive: true });
|
|
50938
|
+
fs31.writeFileSync(tmp, content, { mode: 384 });
|
|
50939
|
+
fs31.renameSync(tmp, file);
|
|
51001
50940
|
}
|
|
51002
50941
|
renameBak(file) {
|
|
51003
50942
|
try {
|
|
51004
|
-
|
|
50943
|
+
fs31.renameSync(file, `${file}.bak`);
|
|
51005
50944
|
} catch {
|
|
51006
50945
|
}
|
|
51007
50946
|
}
|
|
@@ -51158,61 +51097,61 @@ async function autoReverseContact(args) {
|
|
|
51158
51097
|
init_src();
|
|
51159
51098
|
|
|
51160
51099
|
// src/migrations/2026-05-20-flatten-sessions.ts
|
|
51161
|
-
var
|
|
51162
|
-
var
|
|
51100
|
+
var fs32 = __toESM(require("fs"), 1);
|
|
51101
|
+
var path31 = __toESM(require("path"), 1);
|
|
51163
51102
|
var MIGRATION_FLAG_NAME = ".migration.v1.done";
|
|
51164
51103
|
function migrateFlattenSessions(opts) {
|
|
51165
51104
|
const dataDir = opts.dataDir;
|
|
51166
51105
|
const now = opts.now ?? Date.now;
|
|
51167
|
-
const sessionsDir =
|
|
51168
|
-
const flagPath =
|
|
51106
|
+
const sessionsDir = path31.join(dataDir, "sessions");
|
|
51107
|
+
const flagPath = path31.join(sessionsDir, MIGRATION_FLAG_NAME);
|
|
51169
51108
|
if (existsSync3(flagPath)) {
|
|
51170
51109
|
return { skipped: true, flagWritten: false, movedBare: 0, movedVmOwner: 0, archivedListener: 0 };
|
|
51171
51110
|
}
|
|
51172
51111
|
let movedBare = 0;
|
|
51173
51112
|
let movedVmOwner = 0;
|
|
51174
51113
|
let archivedListener = 0;
|
|
51175
|
-
const defaultDir =
|
|
51114
|
+
const defaultDir = path31.join(sessionsDir, "default");
|
|
51176
51115
|
if (existsSync3(defaultDir)) {
|
|
51177
51116
|
for (const entry of readdirSafe(defaultDir)) {
|
|
51178
51117
|
if (!entry.endsWith(".json")) continue;
|
|
51179
|
-
const src =
|
|
51180
|
-
const dst =
|
|
51181
|
-
|
|
51118
|
+
const src = path31.join(defaultDir, entry);
|
|
51119
|
+
const dst = path31.join(sessionsDir, entry);
|
|
51120
|
+
fs32.renameSync(src, dst);
|
|
51182
51121
|
movedBare += 1;
|
|
51183
51122
|
}
|
|
51184
51123
|
rmdirIfEmpty(defaultDir);
|
|
51185
51124
|
}
|
|
51186
51125
|
for (const pid of readdirSafe(sessionsDir)) {
|
|
51187
|
-
const personaDir =
|
|
51126
|
+
const personaDir = path31.join(sessionsDir, pid);
|
|
51188
51127
|
if (!isDir(personaDir)) continue;
|
|
51189
51128
|
if (pid === "default") continue;
|
|
51190
|
-
const ownerSrc =
|
|
51129
|
+
const ownerSrc = path31.join(personaDir, "owner");
|
|
51191
51130
|
if (existsSync3(ownerSrc) && isDir(ownerSrc)) {
|
|
51192
|
-
const ownerDst =
|
|
51193
|
-
|
|
51131
|
+
const ownerDst = path31.join(dataDir, "personas", pid, ".clawd", "sessions", "owner");
|
|
51132
|
+
fs32.mkdirSync(ownerDst, { recursive: true });
|
|
51194
51133
|
for (const file of readdirSafe(ownerSrc)) {
|
|
51195
51134
|
if (!file.endsWith(".json")) continue;
|
|
51196
|
-
|
|
51135
|
+
fs32.renameSync(path31.join(ownerSrc, file), path31.join(ownerDst, file));
|
|
51197
51136
|
movedVmOwner += 1;
|
|
51198
51137
|
}
|
|
51199
51138
|
rmdirIfEmpty(ownerSrc);
|
|
51200
51139
|
}
|
|
51201
|
-
const listenerSrc =
|
|
51140
|
+
const listenerSrc = path31.join(personaDir, "listener");
|
|
51202
51141
|
if (existsSync3(listenerSrc) && isDir(listenerSrc)) {
|
|
51203
|
-
const archiveDst =
|
|
51204
|
-
|
|
51142
|
+
const archiveDst = path31.join(dataDir, ".legacy", `listener-${pid}`);
|
|
51143
|
+
fs32.mkdirSync(archiveDst, { recursive: true });
|
|
51205
51144
|
for (const file of readdirSafe(listenerSrc)) {
|
|
51206
51145
|
if (!file.endsWith(".json")) continue;
|
|
51207
|
-
|
|
51146
|
+
fs32.renameSync(path31.join(listenerSrc, file), path31.join(archiveDst, file));
|
|
51208
51147
|
archivedListener += 1;
|
|
51209
51148
|
}
|
|
51210
51149
|
rmdirIfEmpty(listenerSrc);
|
|
51211
51150
|
}
|
|
51212
51151
|
rmdirIfEmpty(personaDir);
|
|
51213
51152
|
}
|
|
51214
|
-
|
|
51215
|
-
|
|
51153
|
+
fs32.mkdirSync(sessionsDir, { recursive: true });
|
|
51154
|
+
fs32.writeFileSync(flagPath, JSON.stringify({ migratedAt: now() }, null, 2));
|
|
51216
51155
|
return {
|
|
51217
51156
|
skipped: false,
|
|
51218
51157
|
flagWritten: true,
|
|
@@ -51223,7 +51162,7 @@ function migrateFlattenSessions(opts) {
|
|
|
51223
51162
|
}
|
|
51224
51163
|
function existsSync3(p2) {
|
|
51225
51164
|
try {
|
|
51226
|
-
|
|
51165
|
+
fs32.statSync(p2);
|
|
51227
51166
|
return true;
|
|
51228
51167
|
} catch {
|
|
51229
51168
|
return false;
|
|
@@ -51231,31 +51170,31 @@ function existsSync3(p2) {
|
|
|
51231
51170
|
}
|
|
51232
51171
|
function isDir(p2) {
|
|
51233
51172
|
try {
|
|
51234
|
-
return
|
|
51173
|
+
return fs32.statSync(p2).isDirectory();
|
|
51235
51174
|
} catch {
|
|
51236
51175
|
return false;
|
|
51237
51176
|
}
|
|
51238
51177
|
}
|
|
51239
51178
|
function readdirSafe(p2) {
|
|
51240
51179
|
try {
|
|
51241
|
-
return
|
|
51180
|
+
return fs32.readdirSync(p2);
|
|
51242
51181
|
} catch {
|
|
51243
51182
|
return [];
|
|
51244
51183
|
}
|
|
51245
51184
|
}
|
|
51246
51185
|
function rmdirIfEmpty(p2) {
|
|
51247
51186
|
try {
|
|
51248
|
-
|
|
51187
|
+
fs32.rmdirSync(p2);
|
|
51249
51188
|
} catch {
|
|
51250
51189
|
}
|
|
51251
51190
|
}
|
|
51252
51191
|
|
|
51253
51192
|
// src/transport/http-router.ts
|
|
51254
|
-
var
|
|
51255
|
-
var
|
|
51193
|
+
var import_node_fs26 = __toESM(require("fs"), 1);
|
|
51194
|
+
var import_node_path27 = __toESM(require("path"), 1);
|
|
51256
51195
|
|
|
51257
51196
|
// src/attachment/mime.ts
|
|
51258
|
-
var
|
|
51197
|
+
var import_node_path24 = __toESM(require("path"), 1);
|
|
51259
51198
|
var TEXT_PLAIN = "text/plain; charset=utf-8";
|
|
51260
51199
|
var EXT_TO_NATIVE_MIME = {
|
|
51261
51200
|
// 图片
|
|
@@ -51362,7 +51301,7 @@ var TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
51362
51301
|
".mk"
|
|
51363
51302
|
]);
|
|
51364
51303
|
function lookupMime(filePathOrName) {
|
|
51365
|
-
const ext =
|
|
51304
|
+
const ext = import_node_path24.default.extname(filePathOrName).toLowerCase();
|
|
51366
51305
|
if (EXT_TO_NATIVE_MIME[ext]) return EXT_TO_NATIVE_MIME[ext];
|
|
51367
51306
|
if (TEXT_EXTENSIONS.has(ext)) return TEXT_PLAIN;
|
|
51368
51307
|
return "application/octet-stream";
|
|
@@ -51431,8 +51370,8 @@ function verifySignedUrl(secret, absPath, eRaw, s, now = Date.now) {
|
|
|
51431
51370
|
}
|
|
51432
51371
|
|
|
51433
51372
|
// src/attachment/upload.ts
|
|
51434
|
-
var
|
|
51435
|
-
var
|
|
51373
|
+
var import_node_fs25 = __toESM(require("fs"), 1);
|
|
51374
|
+
var import_node_path25 = __toESM(require("path"), 1);
|
|
51436
51375
|
var import_node_crypto8 = __toESM(require("crypto"), 1);
|
|
51437
51376
|
var import_promises2 = require("stream/promises");
|
|
51438
51377
|
var UploadError = class extends Error {
|
|
@@ -51444,22 +51383,22 @@ var UploadError = class extends Error {
|
|
|
51444
51383
|
code;
|
|
51445
51384
|
};
|
|
51446
51385
|
function assertValidFileName(fileName) {
|
|
51447
|
-
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !==
|
|
51386
|
+
if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.startsWith(".") || fileName.includes("/") || fileName.includes("\\") || fileName !== import_node_path25.default.basename(fileName)) {
|
|
51448
51387
|
throw new UploadError("INVALID_FILENAME", `fileName must be a plain basename, got: ${fileName}`);
|
|
51449
51388
|
}
|
|
51450
51389
|
}
|
|
51451
51390
|
var HASH_PREFIX_LEN = 16;
|
|
51452
51391
|
async function writeUploadedAttachment(args) {
|
|
51453
51392
|
assertValidFileName(args.fileName);
|
|
51454
|
-
const attachmentsRoot =
|
|
51393
|
+
const attachmentsRoot = import_node_path25.default.join(args.sessionDir, ".attachments");
|
|
51455
51394
|
try {
|
|
51456
|
-
|
|
51395
|
+
import_node_fs25.default.mkdirSync(attachmentsRoot, { recursive: true });
|
|
51457
51396
|
} catch (err) {
|
|
51458
51397
|
throw new UploadError("STORAGE_ERROR", `mkdir failed: ${err.message}`);
|
|
51459
51398
|
}
|
|
51460
51399
|
const hasher = import_node_crypto8.default.createHash("sha256");
|
|
51461
51400
|
let actualSize = 0;
|
|
51462
|
-
const tmpPath =
|
|
51401
|
+
const tmpPath = import_node_path25.default.join(
|
|
51463
51402
|
attachmentsRoot,
|
|
51464
51403
|
`.upload-${process.pid}-${Date.now()}-${import_node_crypto8.default.randomBytes(4).toString("hex")}`
|
|
51465
51404
|
);
|
|
@@ -51474,18 +51413,18 @@ async function writeUploadedAttachment(args) {
|
|
|
51474
51413
|
yield buf;
|
|
51475
51414
|
}
|
|
51476
51415
|
},
|
|
51477
|
-
|
|
51416
|
+
import_node_fs25.default.createWriteStream(tmpPath, { mode: 384 })
|
|
51478
51417
|
);
|
|
51479
51418
|
} catch (err) {
|
|
51480
51419
|
try {
|
|
51481
|
-
|
|
51420
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
51482
51421
|
} catch {
|
|
51483
51422
|
}
|
|
51484
51423
|
throw new UploadError("STORAGE_ERROR", `write failed: ${err.message}`);
|
|
51485
51424
|
}
|
|
51486
51425
|
if (actualSize !== args.contentLength) {
|
|
51487
51426
|
try {
|
|
51488
|
-
|
|
51427
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
51489
51428
|
} catch {
|
|
51490
51429
|
}
|
|
51491
51430
|
throw new UploadError(
|
|
@@ -51494,35 +51433,35 @@ async function writeUploadedAttachment(args) {
|
|
|
51494
51433
|
);
|
|
51495
51434
|
}
|
|
51496
51435
|
const attachmentId = hasher.digest("hex").slice(0, HASH_PREFIX_LEN);
|
|
51497
|
-
const hashDir =
|
|
51436
|
+
const hashDir = import_node_path25.default.join(attachmentsRoot, attachmentId);
|
|
51498
51437
|
let finalFileName;
|
|
51499
51438
|
let hashDirExists = false;
|
|
51500
51439
|
try {
|
|
51501
|
-
hashDirExists =
|
|
51440
|
+
hashDirExists = import_node_fs25.default.statSync(hashDir).isDirectory();
|
|
51502
51441
|
} catch {
|
|
51503
51442
|
}
|
|
51504
51443
|
if (hashDirExists) {
|
|
51505
|
-
const existing =
|
|
51444
|
+
const existing = import_node_fs25.default.readdirSync(hashDir).filter((n) => !n.startsWith("."));
|
|
51506
51445
|
finalFileName = existing[0] ?? args.fileName;
|
|
51507
51446
|
try {
|
|
51508
|
-
|
|
51447
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
51509
51448
|
} catch {
|
|
51510
51449
|
}
|
|
51511
51450
|
} else {
|
|
51512
51451
|
try {
|
|
51513
|
-
|
|
51452
|
+
import_node_fs25.default.mkdirSync(hashDir, { recursive: true });
|
|
51514
51453
|
finalFileName = args.fileName;
|
|
51515
|
-
|
|
51454
|
+
import_node_fs25.default.renameSync(tmpPath, import_node_path25.default.join(hashDir, finalFileName));
|
|
51516
51455
|
} catch (err) {
|
|
51517
51456
|
try {
|
|
51518
|
-
|
|
51457
|
+
import_node_fs25.default.unlinkSync(tmpPath);
|
|
51519
51458
|
} catch {
|
|
51520
51459
|
}
|
|
51521
51460
|
throw new UploadError("STORAGE_ERROR", `rename failed: ${err.message}`);
|
|
51522
51461
|
}
|
|
51523
51462
|
}
|
|
51524
|
-
const absPath =
|
|
51525
|
-
const relPath =
|
|
51463
|
+
const absPath = import_node_path25.default.join(hashDir, finalFileName);
|
|
51464
|
+
const relPath = import_node_path25.default.relative(args.sessionDir, absPath);
|
|
51526
51465
|
args.groupFileStore.upsert(args.scope, args.sessionId, {
|
|
51527
51466
|
relPath: absPath,
|
|
51528
51467
|
// 存绝对路径,与现有 agent 入清单的形态一致(attachment.ts:144 双形态兼容)
|
|
@@ -51536,7 +51475,7 @@ async function writeUploadedAttachment(args) {
|
|
|
51536
51475
|
|
|
51537
51476
|
// src/extension/import.ts
|
|
51538
51477
|
var import_promises3 = __toESM(require("fs/promises"), 1);
|
|
51539
|
-
var
|
|
51478
|
+
var import_node_path26 = __toESM(require("path"), 1);
|
|
51540
51479
|
var import_node_os12 = __toESM(require("os"), 1);
|
|
51541
51480
|
var import_jszip = __toESM(require_lib3(), 1);
|
|
51542
51481
|
init_src();
|
|
@@ -51555,7 +51494,7 @@ async function importZip(buf, root) {
|
|
|
51555
51494
|
throw new ImportError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
51556
51495
|
}
|
|
51557
51496
|
for (const name of Object.keys(zip.files)) {
|
|
51558
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
51497
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path26.default.isAbsolute(name)) {
|
|
51559
51498
|
throw new ImportError("ZIP_INVALID", `unsafe zip entry path: ${name}`);
|
|
51560
51499
|
}
|
|
51561
51500
|
}
|
|
@@ -51588,7 +51527,7 @@ async function importZip(buf, root) {
|
|
|
51588
51527
|
);
|
|
51589
51528
|
}
|
|
51590
51529
|
}
|
|
51591
|
-
const destDir =
|
|
51530
|
+
const destDir = import_node_path26.default.join(root, manifest.id);
|
|
51592
51531
|
let destExists = false;
|
|
51593
51532
|
try {
|
|
51594
51533
|
await import_promises3.default.access(destDir);
|
|
@@ -51598,15 +51537,15 @@ async function importZip(buf, root) {
|
|
|
51598
51537
|
if (destExists) {
|
|
51599
51538
|
throw new ImportError("ALREADY_EXISTS", `extension ${manifest.id} already installed`);
|
|
51600
51539
|
}
|
|
51601
|
-
const stage = await import_promises3.default.mkdtemp(
|
|
51540
|
+
const stage = await import_promises3.default.mkdtemp(import_node_path26.default.join(import_node_os12.default.tmpdir(), `clawd-ext-stage-${manifest.id}-`));
|
|
51602
51541
|
try {
|
|
51603
51542
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
51604
|
-
const dest =
|
|
51543
|
+
const dest = import_node_path26.default.join(stage, name);
|
|
51605
51544
|
if (entry.dir) {
|
|
51606
51545
|
await import_promises3.default.mkdir(dest, { recursive: true });
|
|
51607
51546
|
continue;
|
|
51608
51547
|
}
|
|
51609
|
-
await import_promises3.default.mkdir(
|
|
51548
|
+
await import_promises3.default.mkdir(import_node_path26.default.dirname(dest), { recursive: true });
|
|
51610
51549
|
const content = await entry.async("nodebuffer");
|
|
51611
51550
|
await import_promises3.default.writeFile(dest, content);
|
|
51612
51551
|
}
|
|
@@ -51637,7 +51576,7 @@ var SHARE_UI_ASSET_MIME = {
|
|
|
51637
51576
|
".wasm": "application/wasm"
|
|
51638
51577
|
};
|
|
51639
51578
|
function shareUiAssetMime(filePath) {
|
|
51640
|
-
const ext =
|
|
51579
|
+
const ext = import_node_path27.default.extname(filePath).toLowerCase();
|
|
51641
51580
|
return SHARE_UI_ASSET_MIME[ext] ?? lookupMime(filePath);
|
|
51642
51581
|
}
|
|
51643
51582
|
var DISPATCH_HEARTBEAT_MS = 25e3;
|
|
@@ -51724,7 +51663,7 @@ function isValidUploadFileName(fileName) {
|
|
|
51724
51663
|
if (fileName === "." || fileName === "..") return false;
|
|
51725
51664
|
if (fileName.startsWith(".")) return false;
|
|
51726
51665
|
if (fileName.includes("/") || fileName.includes("\\")) return false;
|
|
51727
|
-
return fileName ===
|
|
51666
|
+
return fileName === import_node_path27.default.basename(fileName);
|
|
51728
51667
|
}
|
|
51729
51668
|
function createHttpRouter(deps) {
|
|
51730
51669
|
return async (req, res) => {
|
|
@@ -51796,7 +51735,7 @@ function createHttpRouter(deps) {
|
|
|
51796
51735
|
}
|
|
51797
51736
|
let buf;
|
|
51798
51737
|
try {
|
|
51799
|
-
buf = await
|
|
51738
|
+
buf = await import_node_fs26.default.promises.readFile(abs);
|
|
51800
51739
|
} catch {
|
|
51801
51740
|
sendJson(res, 404, { code: "NOT_FOUND", message: "asset not found" });
|
|
51802
51741
|
return true;
|
|
@@ -52020,7 +51959,7 @@ function createHttpRouter(deps) {
|
|
|
52020
51959
|
sendHtml(res, statusByCode[r.code], loader.renderErrorHtml(r.code, msgByCode[r.code]));
|
|
52021
51960
|
return true;
|
|
52022
51961
|
}
|
|
52023
|
-
sendHtml(res, 200, loader.renderViewerHtml(
|
|
51962
|
+
sendHtml(res, 200, loader.renderViewerHtml(import_node_path27.default.basename(r.absPath)));
|
|
52024
51963
|
return true;
|
|
52025
51964
|
}
|
|
52026
51965
|
const ctx = deps.authResolver.resolveFromHeader(
|
|
@@ -52141,7 +52080,7 @@ function createHttpRouter(deps) {
|
|
|
52141
52080
|
return true;
|
|
52142
52081
|
}
|
|
52143
52082
|
let absPath;
|
|
52144
|
-
if (
|
|
52083
|
+
if (import_node_path27.default.isAbsolute(pathParam)) {
|
|
52145
52084
|
absPath = pathParam;
|
|
52146
52085
|
} else if (deps.sessionStore) {
|
|
52147
52086
|
const file = deps.sessionStore.read(sid);
|
|
@@ -52149,7 +52088,7 @@ function createHttpRouter(deps) {
|
|
|
52149
52088
|
sendJson(res, 404, { code: "NOT_FOUND", message: `session ${sid} not found` });
|
|
52150
52089
|
return true;
|
|
52151
52090
|
}
|
|
52152
|
-
absPath =
|
|
52091
|
+
absPath = import_node_path27.default.join(file.cwd, pathParam);
|
|
52153
52092
|
} else {
|
|
52154
52093
|
sendJson(res, 501, withCtx(ctx, { code: "NOT_IMPLEMENTED", message: "sessionStore not wired" }));
|
|
52155
52094
|
return true;
|
|
@@ -52236,7 +52175,7 @@ function withCtx(ctx, body) {
|
|
|
52236
52175
|
function streamFile(res, absPath, logger) {
|
|
52237
52176
|
let stat;
|
|
52238
52177
|
try {
|
|
52239
|
-
stat =
|
|
52178
|
+
stat = import_node_fs26.default.statSync(absPath);
|
|
52240
52179
|
} catch (err) {
|
|
52241
52180
|
const code = err?.code;
|
|
52242
52181
|
if (code === "ENOENT") {
|
|
@@ -52251,7 +52190,7 @@ function streamFile(res, absPath, logger) {
|
|
|
52251
52190
|
return;
|
|
52252
52191
|
}
|
|
52253
52192
|
const mime = lookupMime(absPath);
|
|
52254
|
-
const basename =
|
|
52193
|
+
const basename = import_node_path27.default.basename(absPath);
|
|
52255
52194
|
res.writeHead(200, {
|
|
52256
52195
|
"Content-Type": mime,
|
|
52257
52196
|
"Content-Length": String(stat.size),
|
|
@@ -52259,7 +52198,7 @@ function streamFile(res, absPath, logger) {
|
|
|
52259
52198
|
// 防止浏览器把任意 mime 当 html 渲染
|
|
52260
52199
|
"X-Content-Type-Options": "nosniff"
|
|
52261
52200
|
});
|
|
52262
|
-
const stream =
|
|
52201
|
+
const stream = import_node_fs26.default.createReadStream(absPath);
|
|
52263
52202
|
stream.on("error", (err) => {
|
|
52264
52203
|
logger?.warn("streamFile read error", { absPath, err: err.message });
|
|
52265
52204
|
res.destroy();
|
|
@@ -52268,8 +52207,8 @@ function streamFile(res, absPath, logger) {
|
|
|
52268
52207
|
}
|
|
52269
52208
|
|
|
52270
52209
|
// src/attachment/gc.ts
|
|
52271
|
-
var
|
|
52272
|
-
var
|
|
52210
|
+
var import_node_fs27 = __toESM(require("fs"), 1);
|
|
52211
|
+
var import_node_path28 = __toESM(require("path"), 1);
|
|
52273
52212
|
var DEFAULT_TTL_MS = 30 * 24 * 3600 * 1e3;
|
|
52274
52213
|
function runAttachmentGc(args) {
|
|
52275
52214
|
const now = (args.now ?? Date.now)();
|
|
@@ -52278,38 +52217,38 @@ function runAttachmentGc(args) {
|
|
|
52278
52217
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
52279
52218
|
for (const entry of args.groupFileStore.list(scope, sessionId)) {
|
|
52280
52219
|
if (entry.stale) continue;
|
|
52281
|
-
if (
|
|
52220
|
+
if (import_node_path28.default.isAbsolute(entry.relPath)) liveAbs.add(entry.relPath);
|
|
52282
52221
|
}
|
|
52283
52222
|
}
|
|
52284
52223
|
for (const { scope, sessionId } of args.sessionScopes) {
|
|
52285
|
-
const sessionDir = args.getSessionCwd?.(sessionId) ??
|
|
52224
|
+
const sessionDir = args.getSessionCwd?.(sessionId) ?? import_node_path28.default.join(
|
|
52286
52225
|
args.dataDir,
|
|
52287
52226
|
"sessions",
|
|
52288
52227
|
...scopeSubPath(scope).map(safeFileName),
|
|
52289
52228
|
safeFileName(sessionId)
|
|
52290
52229
|
);
|
|
52291
|
-
const attRoot =
|
|
52230
|
+
const attRoot = import_node_path28.default.join(sessionDir, ".attachments");
|
|
52292
52231
|
let hashDirs;
|
|
52293
52232
|
try {
|
|
52294
|
-
hashDirs =
|
|
52233
|
+
hashDirs = import_node_fs27.default.readdirSync(attRoot);
|
|
52295
52234
|
} catch (err) {
|
|
52296
52235
|
if (err.code === "ENOENT") continue;
|
|
52297
52236
|
args.logger?.warn("attachment gc: readdir failed", { attRoot, err: err.message });
|
|
52298
52237
|
continue;
|
|
52299
52238
|
}
|
|
52300
52239
|
for (const hashDir of hashDirs) {
|
|
52301
|
-
const hashDirAbs =
|
|
52240
|
+
const hashDirAbs = import_node_path28.default.join(attRoot, hashDir);
|
|
52302
52241
|
let files;
|
|
52303
52242
|
try {
|
|
52304
|
-
files =
|
|
52243
|
+
files = import_node_fs27.default.readdirSync(hashDirAbs);
|
|
52305
52244
|
} catch {
|
|
52306
52245
|
continue;
|
|
52307
52246
|
}
|
|
52308
52247
|
for (const name of files) {
|
|
52309
|
-
const file =
|
|
52248
|
+
const file = import_node_path28.default.join(hashDirAbs, name);
|
|
52310
52249
|
let stat;
|
|
52311
52250
|
try {
|
|
52312
|
-
stat =
|
|
52251
|
+
stat = import_node_fs27.default.statSync(file);
|
|
52313
52252
|
} catch {
|
|
52314
52253
|
continue;
|
|
52315
52254
|
}
|
|
@@ -52318,26 +52257,26 @@ function runAttachmentGc(args) {
|
|
|
52318
52257
|
if (age < ttlMs) continue;
|
|
52319
52258
|
if (liveAbs.has(file)) continue;
|
|
52320
52259
|
try {
|
|
52321
|
-
|
|
52260
|
+
import_node_fs27.default.unlinkSync(file);
|
|
52322
52261
|
} catch (err) {
|
|
52323
52262
|
args.logger?.warn("attachment gc: unlink failed", { file, err: err.message });
|
|
52324
52263
|
}
|
|
52325
52264
|
}
|
|
52326
52265
|
try {
|
|
52327
|
-
if (
|
|
52266
|
+
if (import_node_fs27.default.readdirSync(hashDirAbs).length === 0) import_node_fs27.default.rmdirSync(hashDirAbs);
|
|
52328
52267
|
} catch {
|
|
52329
52268
|
}
|
|
52330
52269
|
}
|
|
52331
52270
|
try {
|
|
52332
|
-
if (
|
|
52271
|
+
if (import_node_fs27.default.readdirSync(attRoot).length === 0) import_node_fs27.default.rmdirSync(attRoot);
|
|
52333
52272
|
} catch {
|
|
52334
52273
|
}
|
|
52335
52274
|
}
|
|
52336
52275
|
}
|
|
52337
52276
|
|
|
52338
52277
|
// src/attachment/group.ts
|
|
52339
|
-
var
|
|
52340
|
-
var
|
|
52278
|
+
var import_node_fs28 = __toESM(require("fs"), 1);
|
|
52279
|
+
var import_node_path29 = __toESM(require("path"), 1);
|
|
52341
52280
|
var import_node_crypto9 = __toESM(require("crypto"), 1);
|
|
52342
52281
|
init_protocol();
|
|
52343
52282
|
var GroupFileStore = class {
|
|
@@ -52349,11 +52288,11 @@ var GroupFileStore = class {
|
|
|
52349
52288
|
this.logger = opts.logger;
|
|
52350
52289
|
}
|
|
52351
52290
|
rootForScope(scope) {
|
|
52352
|
-
return
|
|
52291
|
+
return import_node_path29.default.join(this.dataDir, "sessions", ...scopeSubPath(scope).map(safeFileName));
|
|
52353
52292
|
}
|
|
52354
52293
|
/** 与 SessionStore.filePath 平级,扩展名 .group-files.json */
|
|
52355
52294
|
filePath(scope, sessionId) {
|
|
52356
|
-
return
|
|
52295
|
+
return import_node_path29.default.join(this.rootForScope(scope), `${safeFileName(sessionId)}.group-files.json`);
|
|
52357
52296
|
}
|
|
52358
52297
|
cacheKey(scope, sessionId) {
|
|
52359
52298
|
return scope.kind === "default" ? `default::${sessionId}` : `persona:${scope.personaId}:${scope.mode}::${sessionId}`;
|
|
@@ -52362,7 +52301,7 @@ var GroupFileStore = class {
|
|
|
52362
52301
|
readFile(scope, sessionId) {
|
|
52363
52302
|
const file = this.filePath(scope, sessionId);
|
|
52364
52303
|
try {
|
|
52365
|
-
const raw =
|
|
52304
|
+
const raw = import_node_fs28.default.readFileSync(file, "utf8");
|
|
52366
52305
|
const parsed = JSON.parse(raw);
|
|
52367
52306
|
if (!Array.isArray(parsed)) {
|
|
52368
52307
|
this.logger?.warn("GroupFileStore.readFile: not an array; resetting session entries", {
|
|
@@ -52388,10 +52327,10 @@ var GroupFileStore = class {
|
|
|
52388
52327
|
}
|
|
52389
52328
|
writeFile(scope, sessionId, entries) {
|
|
52390
52329
|
const file = this.filePath(scope, sessionId);
|
|
52391
|
-
|
|
52330
|
+
import_node_fs28.default.mkdirSync(import_node_path29.default.dirname(file), { recursive: true });
|
|
52392
52331
|
const tmp = `${file}.tmp-${process.pid}-${Date.now()}`;
|
|
52393
|
-
|
|
52394
|
-
|
|
52332
|
+
import_node_fs28.default.writeFileSync(tmp, JSON.stringify(entries, null, 2), { mode: 384 });
|
|
52333
|
+
import_node_fs28.default.renameSync(tmp, file);
|
|
52395
52334
|
}
|
|
52396
52335
|
/** 拉一份当前 session 的清单。读盘 → cache;之后调用复用 cache */
|
|
52397
52336
|
list(scope, sessionId) {
|
|
@@ -52477,10 +52416,10 @@ var GroupFileStore = class {
|
|
|
52477
52416
|
};
|
|
52478
52417
|
|
|
52479
52418
|
// src/discovery/state-file.ts
|
|
52480
|
-
var
|
|
52481
|
-
var
|
|
52419
|
+
var import_node_fs29 = __toESM(require("fs"), 1);
|
|
52420
|
+
var import_node_path30 = __toESM(require("path"), 1);
|
|
52482
52421
|
function defaultStateFilePath(dataDir) {
|
|
52483
|
-
return
|
|
52422
|
+
return import_node_path30.default.join(dataDir, "state.json");
|
|
52484
52423
|
}
|
|
52485
52424
|
function isPidAlive(pid) {
|
|
52486
52425
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
@@ -52502,7 +52441,7 @@ var StateFileManager = class {
|
|
|
52502
52441
|
}
|
|
52503
52442
|
read() {
|
|
52504
52443
|
try {
|
|
52505
|
-
const raw =
|
|
52444
|
+
const raw = import_node_fs29.default.readFileSync(this.file, "utf8");
|
|
52506
52445
|
const parsed = JSON.parse(raw);
|
|
52507
52446
|
return parsed;
|
|
52508
52447
|
} catch {
|
|
@@ -52516,20 +52455,20 @@ var StateFileManager = class {
|
|
|
52516
52455
|
return { status: "stale", existing };
|
|
52517
52456
|
}
|
|
52518
52457
|
write(state) {
|
|
52519
|
-
|
|
52458
|
+
import_node_fs29.default.mkdirSync(import_node_path30.default.dirname(this.file), { recursive: true });
|
|
52520
52459
|
const tmp = `${this.file}.tmp.${process.pid}.${Date.now()}`;
|
|
52521
|
-
|
|
52522
|
-
|
|
52460
|
+
import_node_fs29.default.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
52461
|
+
import_node_fs29.default.renameSync(tmp, this.file);
|
|
52523
52462
|
if (process.platform !== "win32") {
|
|
52524
52463
|
try {
|
|
52525
|
-
|
|
52464
|
+
import_node_fs29.default.chmodSync(this.file, 384);
|
|
52526
52465
|
} catch {
|
|
52527
52466
|
}
|
|
52528
52467
|
}
|
|
52529
52468
|
}
|
|
52530
52469
|
delete() {
|
|
52531
52470
|
try {
|
|
52532
|
-
|
|
52471
|
+
import_node_fs29.default.unlinkSync(this.file);
|
|
52533
52472
|
} catch {
|
|
52534
52473
|
}
|
|
52535
52474
|
}
|
|
@@ -52544,14 +52483,14 @@ function readDaemonSourceFromEnv(env = process.env) {
|
|
|
52544
52483
|
}
|
|
52545
52484
|
|
|
52546
52485
|
// src/tunnel/tunnel-manager.ts
|
|
52547
|
-
var
|
|
52548
|
-
var
|
|
52486
|
+
var import_node_fs33 = __toESM(require("fs"), 1);
|
|
52487
|
+
var import_node_path34 = __toESM(require("path"), 1);
|
|
52549
52488
|
var import_node_crypto10 = __toESM(require("crypto"), 1);
|
|
52550
52489
|
var import_node_child_process9 = require("child_process");
|
|
52551
52490
|
|
|
52552
52491
|
// src/tunnel/tunnel-store.ts
|
|
52553
|
-
var
|
|
52554
|
-
var
|
|
52492
|
+
var import_node_fs30 = __toESM(require("fs"), 1);
|
|
52493
|
+
var import_node_path31 = __toESM(require("path"), 1);
|
|
52555
52494
|
var TunnelStore = class {
|
|
52556
52495
|
constructor(filePath) {
|
|
52557
52496
|
this.filePath = filePath;
|
|
@@ -52559,7 +52498,7 @@ var TunnelStore = class {
|
|
|
52559
52498
|
filePath;
|
|
52560
52499
|
async get() {
|
|
52561
52500
|
try {
|
|
52562
|
-
const raw = await
|
|
52501
|
+
const raw = await import_node_fs30.default.promises.readFile(this.filePath, "utf8");
|
|
52563
52502
|
const obj = JSON.parse(raw);
|
|
52564
52503
|
if (!isPersistedTunnel(obj)) return null;
|
|
52565
52504
|
return obj;
|
|
@@ -52570,22 +52509,22 @@ var TunnelStore = class {
|
|
|
52570
52509
|
}
|
|
52571
52510
|
}
|
|
52572
52511
|
async set(v2) {
|
|
52573
|
-
const dir =
|
|
52574
|
-
await
|
|
52512
|
+
const dir = import_node_path31.default.dirname(this.filePath);
|
|
52513
|
+
await import_node_fs30.default.promises.mkdir(dir, { recursive: true });
|
|
52575
52514
|
const data = JSON.stringify(v2, null, 2);
|
|
52576
52515
|
const tmp = `${this.filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
52577
|
-
await
|
|
52516
|
+
await import_node_fs30.default.promises.writeFile(tmp, data, { mode: 384 });
|
|
52578
52517
|
if (process.platform !== "win32") {
|
|
52579
52518
|
try {
|
|
52580
|
-
await
|
|
52519
|
+
await import_node_fs30.default.promises.chmod(tmp, 384);
|
|
52581
52520
|
} catch {
|
|
52582
52521
|
}
|
|
52583
52522
|
}
|
|
52584
|
-
await
|
|
52523
|
+
await import_node_fs30.default.promises.rename(tmp, this.filePath);
|
|
52585
52524
|
}
|
|
52586
52525
|
async clear() {
|
|
52587
52526
|
try {
|
|
52588
|
-
await
|
|
52527
|
+
await import_node_fs30.default.promises.unlink(this.filePath);
|
|
52589
52528
|
} catch (err) {
|
|
52590
52529
|
const code = err?.code;
|
|
52591
52530
|
if (code !== "ENOENT") throw err;
|
|
@@ -52680,9 +52619,9 @@ function escape(v2) {
|
|
|
52680
52619
|
}
|
|
52681
52620
|
|
|
52682
52621
|
// src/tunnel/frpc-binary.ts
|
|
52683
|
-
var
|
|
52622
|
+
var import_node_fs31 = __toESM(require("fs"), 1);
|
|
52684
52623
|
var import_node_os13 = __toESM(require("os"), 1);
|
|
52685
|
-
var
|
|
52624
|
+
var import_node_path32 = __toESM(require("path"), 1);
|
|
52686
52625
|
var import_node_child_process7 = require("child_process");
|
|
52687
52626
|
var import_node_stream3 = require("stream");
|
|
52688
52627
|
var import_promises4 = require("stream/promises");
|
|
@@ -52714,20 +52653,20 @@ function frpcDownloadUrl(version2, p2) {
|
|
|
52714
52653
|
}
|
|
52715
52654
|
async function ensureFrpcBinary(opts) {
|
|
52716
52655
|
if (opts.override) {
|
|
52717
|
-
if (!
|
|
52656
|
+
if (!import_node_fs31.default.existsSync(opts.override)) {
|
|
52718
52657
|
throw new Error(`frpc binary not found at override path: ${opts.override}`);
|
|
52719
52658
|
}
|
|
52720
52659
|
return opts.override;
|
|
52721
52660
|
}
|
|
52722
52661
|
const version2 = opts.version ?? FRPC_VERSION;
|
|
52723
52662
|
const platform = opts.platform ?? detectPlatform();
|
|
52724
|
-
const binDir =
|
|
52725
|
-
|
|
52663
|
+
const binDir = import_node_path32.default.join(opts.dataDir, "bin");
|
|
52664
|
+
import_node_fs31.default.mkdirSync(binDir, { recursive: true });
|
|
52726
52665
|
cleanupStaleArtifacts(binDir);
|
|
52727
|
-
const stableBin =
|
|
52728
|
-
if (
|
|
52666
|
+
const stableBin = import_node_path32.default.join(binDir, "frpc");
|
|
52667
|
+
if (import_node_fs31.default.existsSync(stableBin)) return stableBin;
|
|
52729
52668
|
const partialBin = `${stableBin}.partial`;
|
|
52730
|
-
const tarballPath =
|
|
52669
|
+
const tarballPath = import_node_path32.default.join(binDir, `frp_${version2}_${platform.os}_${platform.arch}.tar.gz.partial`);
|
|
52731
52670
|
try {
|
|
52732
52671
|
const url = frpcDownloadUrl(version2, platform);
|
|
52733
52672
|
await downloadToFile(url, tarballPath, opts.fetchImpl);
|
|
@@ -52736,8 +52675,8 @@ async function ensureFrpcBinary(opts) {
|
|
|
52736
52675
|
} else {
|
|
52737
52676
|
await extractFrpcFromTarball(tarballPath, binDir, version2, platform, partialBin);
|
|
52738
52677
|
}
|
|
52739
|
-
|
|
52740
|
-
|
|
52678
|
+
import_node_fs31.default.chmodSync(partialBin, 493);
|
|
52679
|
+
import_node_fs31.default.renameSync(partialBin, stableBin);
|
|
52741
52680
|
} finally {
|
|
52742
52681
|
safeUnlink(tarballPath);
|
|
52743
52682
|
safeUnlink(partialBin);
|
|
@@ -52747,15 +52686,15 @@ async function ensureFrpcBinary(opts) {
|
|
|
52747
52686
|
function cleanupStaleArtifacts(binDir) {
|
|
52748
52687
|
let entries;
|
|
52749
52688
|
try {
|
|
52750
|
-
entries =
|
|
52689
|
+
entries = import_node_fs31.default.readdirSync(binDir);
|
|
52751
52690
|
} catch {
|
|
52752
52691
|
return;
|
|
52753
52692
|
}
|
|
52754
52693
|
for (const name of entries) {
|
|
52755
52694
|
if (name.endsWith(".partial") || name.startsWith("extract-")) {
|
|
52756
|
-
const full =
|
|
52695
|
+
const full = import_node_path32.default.join(binDir, name);
|
|
52757
52696
|
try {
|
|
52758
|
-
|
|
52697
|
+
import_node_fs31.default.rmSync(full, { recursive: true, force: true });
|
|
52759
52698
|
} catch {
|
|
52760
52699
|
}
|
|
52761
52700
|
}
|
|
@@ -52763,7 +52702,7 @@ function cleanupStaleArtifacts(binDir) {
|
|
|
52763
52702
|
}
|
|
52764
52703
|
function safeUnlink(p2) {
|
|
52765
52704
|
try {
|
|
52766
|
-
|
|
52705
|
+
import_node_fs31.default.unlinkSync(p2);
|
|
52767
52706
|
} catch {
|
|
52768
52707
|
}
|
|
52769
52708
|
}
|
|
@@ -52774,13 +52713,13 @@ async function downloadToFile(url, dest, fetchImpl) {
|
|
|
52774
52713
|
if (!res.ok || !res.body) {
|
|
52775
52714
|
throw new Error(`download failed: ${res.status} ${res.statusText}`);
|
|
52776
52715
|
}
|
|
52777
|
-
const out =
|
|
52716
|
+
const out = import_node_fs31.default.createWriteStream(dest);
|
|
52778
52717
|
const nodeStream = import_node_stream3.Readable.fromWeb(res.body);
|
|
52779
52718
|
await (0, import_promises4.pipeline)(nodeStream, out);
|
|
52780
52719
|
}
|
|
52781
52720
|
async function extractFrpcFromTarball(tarball, binDir, version2, platform, destBin) {
|
|
52782
|
-
const work =
|
|
52783
|
-
|
|
52721
|
+
const work = import_node_path32.default.join(binDir, `extract-${process.pid}-${Date.now()}`);
|
|
52722
|
+
import_node_fs31.default.mkdirSync(work, { recursive: true });
|
|
52784
52723
|
try {
|
|
52785
52724
|
await new Promise((resolve6, reject) => {
|
|
52786
52725
|
const proc = (0, import_node_child_process7.spawn)("tar", ["xzf", tarball, "-C", work], { stdio: "pipe" });
|
|
@@ -52788,32 +52727,32 @@ async function extractFrpcFromTarball(tarball, binDir, version2, platform, destB
|
|
|
52788
52727
|
proc.on("exit", (code) => code === 0 ? resolve6() : reject(new Error(`tar exited ${code}`)));
|
|
52789
52728
|
});
|
|
52790
52729
|
const dirName = `frp_${version2}_${platform.os}_${platform.arch}`;
|
|
52791
|
-
const src =
|
|
52792
|
-
if (!
|
|
52730
|
+
const src = import_node_path32.default.join(work, dirName, "frpc");
|
|
52731
|
+
if (!import_node_fs31.default.existsSync(src)) {
|
|
52793
52732
|
throw new Error(`frpc not found inside tarball at ${src}`);
|
|
52794
52733
|
}
|
|
52795
|
-
|
|
52734
|
+
import_node_fs31.default.copyFileSync(src, destBin);
|
|
52796
52735
|
} finally {
|
|
52797
|
-
|
|
52736
|
+
import_node_fs31.default.rmSync(work, { recursive: true, force: true });
|
|
52798
52737
|
}
|
|
52799
52738
|
}
|
|
52800
52739
|
|
|
52801
52740
|
// src/tunnel/frpc-process.ts
|
|
52802
|
-
var
|
|
52803
|
-
var
|
|
52741
|
+
var import_node_fs32 = __toESM(require("fs"), 1);
|
|
52742
|
+
var import_node_path33 = __toESM(require("path"), 1);
|
|
52804
52743
|
var import_node_child_process8 = require("child_process");
|
|
52805
52744
|
function frpcPidFilePath(dataDir) {
|
|
52806
|
-
return
|
|
52745
|
+
return import_node_path33.default.join(dataDir, "frpc.pid");
|
|
52807
52746
|
}
|
|
52808
52747
|
function writeFrpcPid(dataDir, pid) {
|
|
52809
52748
|
try {
|
|
52810
|
-
|
|
52749
|
+
import_node_fs32.default.writeFileSync(frpcPidFilePath(dataDir), String(pid), { mode: 384 });
|
|
52811
52750
|
} catch {
|
|
52812
52751
|
}
|
|
52813
52752
|
}
|
|
52814
52753
|
function clearFrpcPid(dataDir) {
|
|
52815
52754
|
try {
|
|
52816
|
-
|
|
52755
|
+
import_node_fs32.default.unlinkSync(frpcPidFilePath(dataDir));
|
|
52817
52756
|
} catch {
|
|
52818
52757
|
}
|
|
52819
52758
|
}
|
|
@@ -52829,7 +52768,7 @@ function defaultIsPidAlive(pid) {
|
|
|
52829
52768
|
}
|
|
52830
52769
|
function defaultReadPidFile(file) {
|
|
52831
52770
|
try {
|
|
52832
|
-
return
|
|
52771
|
+
return import_node_fs32.default.readFileSync(file, "utf8");
|
|
52833
52772
|
} catch {
|
|
52834
52773
|
return null;
|
|
52835
52774
|
}
|
|
@@ -52845,7 +52784,7 @@ function defaultSleep(ms) {
|
|
|
52845
52784
|
}
|
|
52846
52785
|
async function killStaleFrpc(deps) {
|
|
52847
52786
|
const pidFile = frpcPidFilePath(deps.dataDir);
|
|
52848
|
-
const tomlPath =
|
|
52787
|
+
const tomlPath = import_node_path33.default.join(deps.dataDir, "frpc.toml");
|
|
52849
52788
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile;
|
|
52850
52789
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive;
|
|
52851
52790
|
const killPid = deps.killPidImpl ?? defaultKillPid;
|
|
@@ -52869,7 +52808,7 @@ async function killStaleFrpc(deps) {
|
|
|
52869
52808
|
}
|
|
52870
52809
|
if (victims.size === 0) {
|
|
52871
52810
|
try {
|
|
52872
|
-
|
|
52811
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52873
52812
|
} catch {
|
|
52874
52813
|
}
|
|
52875
52814
|
return;
|
|
@@ -52880,7 +52819,7 @@ async function killStaleFrpc(deps) {
|
|
|
52880
52819
|
}
|
|
52881
52820
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
52882
52821
|
try {
|
|
52883
|
-
|
|
52822
|
+
import_node_fs32.default.unlinkSync(pidFile);
|
|
52884
52823
|
} catch {
|
|
52885
52824
|
}
|
|
52886
52825
|
}
|
|
@@ -52917,7 +52856,7 @@ var DEFAULT_TUNNEL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
52917
52856
|
var TunnelManager = class {
|
|
52918
52857
|
constructor(deps) {
|
|
52919
52858
|
this.deps = deps;
|
|
52920
|
-
this.store = deps.store ?? new TunnelStore(
|
|
52859
|
+
this.store = deps.store ?? new TunnelStore(import_node_path34.default.join(deps.dataDir, "tunnel.json"));
|
|
52921
52860
|
this.ttlMs = deps.ttlMs ?? DEFAULT_TUNNEL_TTL_MS;
|
|
52922
52861
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
52923
52862
|
}
|
|
@@ -53044,7 +52983,7 @@ var TunnelManager = class {
|
|
|
53044
52983
|
dataDir: this.deps.dataDir,
|
|
53045
52984
|
override: this.deps.frpcBinaryOverride ?? void 0
|
|
53046
52985
|
});
|
|
53047
|
-
const tomlPath =
|
|
52986
|
+
const tomlPath = import_node_path34.default.join(this.deps.dataDir, "frpc.toml");
|
|
53048
52987
|
const proxyName = `clawd-${t.subdomain}-${localPort}-${import_node_crypto10.default.randomBytes(3).toString("hex")}`;
|
|
53049
52988
|
const toml = buildFrpcToml({
|
|
53050
52989
|
serverAddr: t.frpsHost,
|
|
@@ -53055,12 +52994,12 @@ var TunnelManager = class {
|
|
|
53055
52994
|
localPort,
|
|
53056
52995
|
logLevel: "info"
|
|
53057
52996
|
});
|
|
53058
|
-
await
|
|
52997
|
+
await import_node_fs33.default.promises.writeFile(tomlPath, toml, { mode: 384 });
|
|
53059
52998
|
const proc = (this.deps.spawnImpl ?? import_node_child_process9.spawn)(frpcBin, ["-c", tomlPath], {
|
|
53060
52999
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53061
53000
|
});
|
|
53062
|
-
const logFilePath =
|
|
53063
|
-
const logStream =
|
|
53001
|
+
const logFilePath = import_node_path34.default.join(this.deps.dataDir, "frpc.log");
|
|
53002
|
+
const logStream = import_node_fs33.default.createWriteStream(logFilePath, { flags: "a", mode: 384 });
|
|
53064
53003
|
logStream.on("error", () => {
|
|
53065
53004
|
});
|
|
53066
53005
|
const tee = (chunk) => {
|
|
@@ -53142,8 +53081,8 @@ async function waitForFrpcReady(proc, timeoutMs) {
|
|
|
53142
53081
|
}
|
|
53143
53082
|
|
|
53144
53083
|
// src/sshd/sshd-manager.ts
|
|
53145
|
-
var
|
|
53146
|
-
var
|
|
53084
|
+
var import_node_fs37 = __toESM(require("fs"), 1);
|
|
53085
|
+
var import_node_path38 = __toESM(require("path"), 1);
|
|
53147
53086
|
var import_node_child_process11 = require("child_process");
|
|
53148
53087
|
|
|
53149
53088
|
// src/sshd/sshd-config.ts
|
|
@@ -53168,23 +53107,23 @@ function buildSshdConfig(input) {
|
|
|
53168
53107
|
}
|
|
53169
53108
|
|
|
53170
53109
|
// src/sshd/sshd-process.ts
|
|
53171
|
-
var
|
|
53172
|
-
var
|
|
53110
|
+
var import_node_fs34 = __toESM(require("fs"), 1);
|
|
53111
|
+
var import_node_path35 = __toESM(require("path"), 1);
|
|
53173
53112
|
var import_node_child_process10 = require("child_process");
|
|
53174
53113
|
function sshdPidFilePath(dataDir) {
|
|
53175
|
-
return
|
|
53114
|
+
return import_node_path35.default.join(dataDir, "sshd", "sshd.pid");
|
|
53176
53115
|
}
|
|
53177
53116
|
function writeSshdPid(dataDir, pid) {
|
|
53178
53117
|
try {
|
|
53179
53118
|
const p2 = sshdPidFilePath(dataDir);
|
|
53180
|
-
|
|
53181
|
-
|
|
53119
|
+
import_node_fs34.default.mkdirSync(import_node_path35.default.dirname(p2), { recursive: true, mode: 448 });
|
|
53120
|
+
import_node_fs34.default.writeFileSync(p2, String(pid), { mode: 384 });
|
|
53182
53121
|
} catch {
|
|
53183
53122
|
}
|
|
53184
53123
|
}
|
|
53185
53124
|
function clearSshdPid(dataDir) {
|
|
53186
53125
|
try {
|
|
53187
|
-
|
|
53126
|
+
import_node_fs34.default.unlinkSync(sshdPidFilePath(dataDir));
|
|
53188
53127
|
} catch {
|
|
53189
53128
|
}
|
|
53190
53129
|
}
|
|
@@ -53200,7 +53139,7 @@ function defaultIsPidAlive2(pid) {
|
|
|
53200
53139
|
}
|
|
53201
53140
|
function defaultReadPidFile2(file) {
|
|
53202
53141
|
try {
|
|
53203
|
-
return
|
|
53142
|
+
return import_node_fs34.default.readFileSync(file, "utf8");
|
|
53204
53143
|
} catch {
|
|
53205
53144
|
return null;
|
|
53206
53145
|
}
|
|
@@ -53216,7 +53155,7 @@ function defaultSleep2(ms) {
|
|
|
53216
53155
|
}
|
|
53217
53156
|
async function killStaleSshd(deps) {
|
|
53218
53157
|
const pidFile = sshdPidFilePath(deps.dataDir);
|
|
53219
|
-
const configPath =
|
|
53158
|
+
const configPath = import_node_path35.default.join(deps.dataDir, "sshd", "sshd_config");
|
|
53220
53159
|
const readPidFile = deps.readPidFileImpl ?? defaultReadPidFile2;
|
|
53221
53160
|
const isAlive = deps.isPidAliveImpl ?? defaultIsPidAlive2;
|
|
53222
53161
|
const killPid = deps.killPidImpl ?? defaultKillPid2;
|
|
@@ -53240,7 +53179,7 @@ async function killStaleSshd(deps) {
|
|
|
53240
53179
|
}
|
|
53241
53180
|
if (victims.size === 0) {
|
|
53242
53181
|
try {
|
|
53243
|
-
|
|
53182
|
+
import_node_fs34.default.unlinkSync(pidFile);
|
|
53244
53183
|
} catch {
|
|
53245
53184
|
}
|
|
53246
53185
|
return;
|
|
@@ -53251,7 +53190,7 @@ async function killStaleSshd(deps) {
|
|
|
53251
53190
|
}
|
|
53252
53191
|
await sleep2(deps.reapWaitMs ?? 300);
|
|
53253
53192
|
try {
|
|
53254
|
-
|
|
53193
|
+
import_node_fs34.default.unlinkSync(pidFile);
|
|
53255
53194
|
} catch {
|
|
53256
53195
|
}
|
|
53257
53196
|
}
|
|
@@ -53284,8 +53223,8 @@ async function defaultScanSshdPidsByCmdline(configPath, logger) {
|
|
|
53284
53223
|
}
|
|
53285
53224
|
|
|
53286
53225
|
// src/sshd/jail-script.ts
|
|
53287
|
-
var
|
|
53288
|
-
var
|
|
53226
|
+
var import_node_fs35 = __toESM(require("fs"), 1);
|
|
53227
|
+
var import_node_path36 = __toESM(require("path"), 1);
|
|
53289
53228
|
var CLAWD_SSH_JAIL_SCRIPT = String.raw`#!/usr/bin/env bash
|
|
53290
53229
|
# clawd-ssh-jail — SSH reverse access sandbox wrapper (managed by clawd; do not edit)
|
|
53291
53230
|
#
|
|
@@ -53419,16 +53358,16 @@ case "$(uname -s)" in
|
|
|
53419
53358
|
esac
|
|
53420
53359
|
`;
|
|
53421
53360
|
function ensureJailScript(dataDir) {
|
|
53422
|
-
const binDir =
|
|
53423
|
-
|
|
53424
|
-
const target =
|
|
53425
|
-
|
|
53361
|
+
const binDir = import_node_path36.default.join(dataDir, "bin");
|
|
53362
|
+
import_node_fs35.default.mkdirSync(binDir, { recursive: true, mode: 493 });
|
|
53363
|
+
const target = import_node_path36.default.join(binDir, "clawd-ssh-jail");
|
|
53364
|
+
import_node_fs35.default.writeFileSync(target, CLAWD_SSH_JAIL_SCRIPT, { mode: 493 });
|
|
53426
53365
|
return target;
|
|
53427
53366
|
}
|
|
53428
53367
|
|
|
53429
53368
|
// src/sshd/clawd-shim.ts
|
|
53430
|
-
var
|
|
53431
|
-
var
|
|
53369
|
+
var import_node_fs36 = __toESM(require("fs"), 1);
|
|
53370
|
+
var import_node_path37 = __toESM(require("path"), 1);
|
|
53432
53371
|
function shellQuote(s) {
|
|
53433
53372
|
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
53434
53373
|
}
|
|
@@ -53443,10 +53382,10 @@ exec ${shellQuote(execPath)} ${shellQuote(cliPath)} "$@"
|
|
|
53443
53382
|
`;
|
|
53444
53383
|
}
|
|
53445
53384
|
function ensureClawdShim(dataDir, execPath, cliPath) {
|
|
53446
|
-
const binDir =
|
|
53447
|
-
|
|
53448
|
-
const target =
|
|
53449
|
-
|
|
53385
|
+
const binDir = import_node_path37.default.join(dataDir, "bin");
|
|
53386
|
+
import_node_fs36.default.mkdirSync(binDir, { recursive: true, mode: 493 });
|
|
53387
|
+
const target = import_node_path37.default.join(binDir, "clawd");
|
|
53388
|
+
import_node_fs36.default.writeFileSync(target, buildClawdShim(execPath, cliPath), { mode: 493 });
|
|
53450
53389
|
return target;
|
|
53451
53390
|
}
|
|
53452
53391
|
|
|
@@ -53454,7 +53393,7 @@ function ensureClawdShim(dataDir, execPath, cliPath) {
|
|
|
53454
53393
|
var SshdManager = class {
|
|
53455
53394
|
constructor(deps) {
|
|
53456
53395
|
this.deps = deps;
|
|
53457
|
-
this.sshdDir =
|
|
53396
|
+
this.sshdDir = import_node_path38.default.join(deps.dataDir, "sshd");
|
|
53458
53397
|
this.startupTimeoutMs = deps.startupTimeoutMs ?? 15e3;
|
|
53459
53398
|
}
|
|
53460
53399
|
deps;
|
|
@@ -53473,32 +53412,32 @@ var SshdManager = class {
|
|
|
53473
53412
|
ownPid: process.pid,
|
|
53474
53413
|
logger
|
|
53475
53414
|
});
|
|
53476
|
-
|
|
53477
|
-
|
|
53415
|
+
import_node_fs37.default.mkdirSync(this.sshdDir, { recursive: true, mode: 448 });
|
|
53416
|
+
import_node_fs37.default.mkdirSync(import_node_path38.default.join(this.sshdDir, "authorized_keys.d"), { recursive: true, mode: 448 });
|
|
53478
53417
|
ensureJailScript(this.deps.dataDir);
|
|
53479
53418
|
ensureClawdShim(this.deps.dataDir, process.execPath, process.argv[1] ?? "");
|
|
53480
|
-
const hostKeyPath =
|
|
53481
|
-
if (!
|
|
53419
|
+
const hostKeyPath = import_node_path38.default.join(this.sshdDir, "host_key");
|
|
53420
|
+
if (!import_node_fs37.default.existsSync(hostKeyPath)) {
|
|
53482
53421
|
await this.generateHostKey(hostKeyPath);
|
|
53483
53422
|
}
|
|
53484
|
-
const akFile =
|
|
53485
|
-
if (!
|
|
53486
|
-
|
|
53423
|
+
const akFile = import_node_path38.default.join(this.sshdDir, "authorized_keys.d", "clawd-contacts");
|
|
53424
|
+
if (!import_node_fs37.default.existsSync(akFile)) {
|
|
53425
|
+
import_node_fs37.default.writeFileSync(akFile, "", { mode: 384 });
|
|
53487
53426
|
}
|
|
53488
|
-
const configPath =
|
|
53427
|
+
const configPath = import_node_path38.default.join(this.sshdDir, "sshd_config");
|
|
53489
53428
|
const config = buildSshdConfig({
|
|
53490
53429
|
listenAddress: "127.0.0.1",
|
|
53491
53430
|
port: this.deps.port,
|
|
53492
53431
|
hostKeyPath,
|
|
53493
53432
|
authorizedKeysFile: akFile,
|
|
53494
|
-
pidFilePath:
|
|
53433
|
+
pidFilePath: import_node_path38.default.join(this.sshdDir, "sshd.pid")
|
|
53495
53434
|
});
|
|
53496
|
-
|
|
53435
|
+
import_node_fs37.default.writeFileSync(configPath, config, { mode: 384 });
|
|
53497
53436
|
const sshdBin = this.deps.sshdBin ?? "/usr/sbin/sshd";
|
|
53498
53437
|
const proc = (this.deps.spawnImpl ?? import_node_child_process11.spawn)(sshdBin, ["-D", "-e", "-f", configPath], {
|
|
53499
53438
|
stdio: ["ignore", "pipe", "pipe"]
|
|
53500
53439
|
});
|
|
53501
|
-
const logStream =
|
|
53440
|
+
const logStream = import_node_fs37.default.createWriteStream(import_node_path38.default.join(this.sshdDir, "sshd.log"), {
|
|
53502
53441
|
flags: "a",
|
|
53503
53442
|
mode: 384
|
|
53504
53443
|
});
|
|
@@ -53591,7 +53530,7 @@ ${tail}` : ready.error;
|
|
|
53591
53530
|
p2.on("error", reject);
|
|
53592
53531
|
});
|
|
53593
53532
|
try {
|
|
53594
|
-
|
|
53533
|
+
import_node_fs37.default.chmodSync(hostKeyPath, 384);
|
|
53595
53534
|
} catch {
|
|
53596
53535
|
}
|
|
53597
53536
|
}
|
|
@@ -53634,17 +53573,17 @@ async function waitForSshdReady(proc, timeoutMs) {
|
|
|
53634
53573
|
}
|
|
53635
53574
|
|
|
53636
53575
|
// src/sshd/authorized-keys.ts
|
|
53637
|
-
var
|
|
53638
|
-
var
|
|
53576
|
+
var import_node_fs38 = __toESM(require("fs"), 1);
|
|
53577
|
+
var import_node_path39 = __toESM(require("path"), 1);
|
|
53639
53578
|
var JAIL_BIN_PATH_ENV = "CLAWD_JAIL_BIN_PATH";
|
|
53640
53579
|
var AUTHORIZED_KEYS_FILE = "clawd-contacts";
|
|
53641
53580
|
function jailBinPath() {
|
|
53642
|
-
return process.env[JAIL_BIN_PATH_ENV] ??
|
|
53581
|
+
return process.env[JAIL_BIN_PATH_ENV] ?? import_node_path39.default.join(process.env.HOME ?? "", ".clawd", "bin", "clawd-ssh-jail");
|
|
53643
53582
|
}
|
|
53644
53583
|
function rebuildAuthorizedKeys(store, sshdDir) {
|
|
53645
|
-
const akDir =
|
|
53646
|
-
const target =
|
|
53647
|
-
|
|
53584
|
+
const akDir = import_node_path39.default.join(sshdDir, "authorized_keys.d");
|
|
53585
|
+
const target = import_node_path39.default.join(akDir, AUTHORIZED_KEYS_FILE);
|
|
53586
|
+
import_node_fs38.default.mkdirSync(akDir, { recursive: true, mode: 448 });
|
|
53648
53587
|
const lines = ["# managed by clawd; do not edit", ""];
|
|
53649
53588
|
for (const c of store.list()) {
|
|
53650
53589
|
if (!c.sshAllowed) continue;
|
|
@@ -53658,28 +53597,28 @@ function rebuildAuthorizedKeys(store, sshdDir) {
|
|
|
53658
53597
|
}
|
|
53659
53598
|
const body = lines.join("\n") + "\n";
|
|
53660
53599
|
const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
53661
|
-
|
|
53662
|
-
|
|
53600
|
+
import_node_fs38.default.writeFileSync(tmp, body, { mode: 384 });
|
|
53601
|
+
import_node_fs38.default.renameSync(tmp, target);
|
|
53663
53602
|
}
|
|
53664
53603
|
function readIssuedPubkey(sshdDir, deviceId) {
|
|
53665
53604
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53666
|
-
const p2 =
|
|
53605
|
+
const p2 = import_node_path39.default.join(sshdDir, "keys", `${safeId}.ed25519.pub`);
|
|
53667
53606
|
try {
|
|
53668
|
-
return
|
|
53607
|
+
return import_node_fs38.default.readFileSync(p2, "utf8");
|
|
53669
53608
|
} catch {
|
|
53670
53609
|
return null;
|
|
53671
53610
|
}
|
|
53672
53611
|
}
|
|
53673
53612
|
|
|
53674
53613
|
// src/sshd/contact-key-puller.ts
|
|
53675
|
-
var
|
|
53676
|
-
var
|
|
53614
|
+
var import_node_fs40 = __toESM(require("fs"), 1);
|
|
53615
|
+
var import_node_path41 = __toESM(require("path"), 1);
|
|
53677
53616
|
init_peer_forward();
|
|
53678
53617
|
init_contact_ssh_log();
|
|
53679
53618
|
var CONTACT_KEYS_DIR = "contact-ssh-keys";
|
|
53680
53619
|
function safeContactKeyPath(dataDir, deviceId) {
|
|
53681
53620
|
const safeId = deviceId.replace(/[\/\\]/g, "_");
|
|
53682
|
-
return
|
|
53621
|
+
return import_node_path41.default.join(dataDir, CONTACT_KEYS_DIR, `${safeId}.ed25519`);
|
|
53683
53622
|
}
|
|
53684
53623
|
async function pullContactSshKeyOnce(deps) {
|
|
53685
53624
|
const forward = deps.forwardImpl ?? ((c) => forwardContactSshKeyIssueToPeer({
|
|
@@ -53745,12 +53684,12 @@ async function pullContactSshKeyOnce(deps) {
|
|
|
53745
53684
|
}
|
|
53746
53685
|
function writeKeyFile(dataDir, deviceId, pem) {
|
|
53747
53686
|
const p2 = safeContactKeyPath(dataDir, deviceId);
|
|
53748
|
-
|
|
53749
|
-
|
|
53687
|
+
import_node_fs40.default.mkdirSync(import_node_path41.default.dirname(p2), { recursive: true, mode: 448 });
|
|
53688
|
+
import_node_fs40.default.writeFileSync(p2, pem, { mode: 384 });
|
|
53750
53689
|
}
|
|
53751
53690
|
function removeKeyFile(dataDir, deviceId) {
|
|
53752
53691
|
try {
|
|
53753
|
-
|
|
53692
|
+
import_node_fs40.default.unlinkSync(safeContactKeyPath(dataDir, deviceId));
|
|
53754
53693
|
return true;
|
|
53755
53694
|
} catch {
|
|
53756
53695
|
return false;
|
|
@@ -53900,27 +53839,27 @@ init_contact_ssh_log();
|
|
|
53900
53839
|
|
|
53901
53840
|
// src/tunnel/device-key.ts
|
|
53902
53841
|
var import_node_os14 = __toESM(require("os"), 1);
|
|
53903
|
-
var
|
|
53842
|
+
var import_node_path42 = __toESM(require("path"), 1);
|
|
53904
53843
|
var import_node_crypto11 = __toESM(require("crypto"), 1);
|
|
53905
53844
|
var DERIVE_SALT = "clawd-tunnel-device-v1";
|
|
53906
53845
|
function deriveStableDeviceKey(opts = {}) {
|
|
53907
53846
|
const hostname = opts.hostname ?? import_node_os14.default.hostname();
|
|
53908
53847
|
const uid = opts.uid ?? (typeof import_node_os14.default.userInfo === "function" ? import_node_os14.default.userInfo().uid : 0);
|
|
53909
53848
|
const home = opts.home ?? import_node_os14.default.homedir();
|
|
53910
|
-
const defaultDataDir =
|
|
53911
|
-
const normalizedDataDir = opts.dataDir ?
|
|
53849
|
+
const defaultDataDir = import_node_path42.default.resolve(import_node_path42.default.join(home, ".clawd"));
|
|
53850
|
+
const normalizedDataDir = opts.dataDir ? import_node_path42.default.resolve(opts.dataDir) : null;
|
|
53912
53851
|
const isDefaultDir = normalizedDataDir == null || normalizedDataDir === defaultDataDir;
|
|
53913
53852
|
const input = isDefaultDir ? `${hostname}::${uid}` : `${hostname}::${uid}::${normalizedDataDir}`;
|
|
53914
53853
|
return import_node_crypto11.default.createHmac("sha256", DERIVE_SALT).update(input).digest("hex").slice(0, 32);
|
|
53915
53854
|
}
|
|
53916
53855
|
|
|
53917
53856
|
// src/auth-store.ts
|
|
53918
|
-
var
|
|
53919
|
-
var
|
|
53857
|
+
var import_node_fs41 = __toESM(require("fs"), 1);
|
|
53858
|
+
var import_node_path43 = __toESM(require("path"), 1);
|
|
53920
53859
|
var import_node_crypto12 = __toESM(require("crypto"), 1);
|
|
53921
53860
|
var AUTH_FILE_NAME = "auth.json";
|
|
53922
53861
|
function authFilePath(dataDir) {
|
|
53923
|
-
return
|
|
53862
|
+
return import_node_path43.default.join(dataDir, AUTH_FILE_NAME);
|
|
53924
53863
|
}
|
|
53925
53864
|
function loadOrCreateAuthFile(opts) {
|
|
53926
53865
|
const file = authFilePath(opts.dataDir);
|
|
@@ -53956,7 +53895,7 @@ function defaultGenerateOwnerPrincipalId() {
|
|
|
53956
53895
|
}
|
|
53957
53896
|
function readAuthFile(file) {
|
|
53958
53897
|
try {
|
|
53959
|
-
const raw =
|
|
53898
|
+
const raw = import_node_fs41.default.readFileSync(file, "utf8");
|
|
53960
53899
|
const parsed = JSON.parse(raw);
|
|
53961
53900
|
if (typeof parsed?.token !== "string" || parsed.token.length === 0) {
|
|
53962
53901
|
return null;
|
|
@@ -53976,25 +53915,25 @@ function readAuthFile(file) {
|
|
|
53976
53915
|
}
|
|
53977
53916
|
}
|
|
53978
53917
|
function writeAuthFile(file, content) {
|
|
53979
|
-
|
|
53980
|
-
|
|
53918
|
+
import_node_fs41.default.mkdirSync(import_node_path43.default.dirname(file), { recursive: true });
|
|
53919
|
+
import_node_fs41.default.writeFileSync(file, JSON.stringify(content, null, 2), { mode: 384 });
|
|
53981
53920
|
try {
|
|
53982
|
-
|
|
53921
|
+
import_node_fs41.default.chmodSync(file, 384);
|
|
53983
53922
|
} catch {
|
|
53984
53923
|
}
|
|
53985
53924
|
}
|
|
53986
53925
|
|
|
53987
53926
|
// src/owner-profile.ts
|
|
53988
|
-
var
|
|
53927
|
+
var import_node_fs42 = __toESM(require("fs"), 1);
|
|
53989
53928
|
var import_node_os15 = __toESM(require("os"), 1);
|
|
53990
|
-
var
|
|
53929
|
+
var import_node_path44 = __toESM(require("path"), 1);
|
|
53991
53930
|
var PROFILE_FILENAME = "profile.json";
|
|
53992
53931
|
function loadOwnerDisplayName(dataDir) {
|
|
53993
53932
|
const fallback = import_node_os15.default.userInfo().username;
|
|
53994
|
-
const profilePath =
|
|
53933
|
+
const profilePath = import_node_path44.default.join(dataDir, PROFILE_FILENAME);
|
|
53995
53934
|
let raw;
|
|
53996
53935
|
try {
|
|
53997
|
-
raw =
|
|
53936
|
+
raw = import_node_fs42.default.readFileSync(profilePath, "utf8");
|
|
53998
53937
|
} catch {
|
|
53999
53938
|
return fallback;
|
|
54000
53939
|
}
|
|
@@ -54017,18 +53956,18 @@ function loadOwnerDisplayName(dataDir) {
|
|
|
54017
53956
|
}
|
|
54018
53957
|
|
|
54019
53958
|
// src/feishu-auth/owner-identity-store.ts
|
|
54020
|
-
var
|
|
54021
|
-
var
|
|
53959
|
+
var import_node_fs43 = __toESM(require("fs"), 1);
|
|
53960
|
+
var import_node_path45 = __toESM(require("path"), 1);
|
|
54022
53961
|
var OWNER_IDENTITY_FILE_NAME = "owner-identity.json";
|
|
54023
53962
|
var OwnerIdentityStore = class {
|
|
54024
53963
|
file;
|
|
54025
53964
|
constructor(dataDir) {
|
|
54026
|
-
this.file =
|
|
53965
|
+
this.file = import_node_path45.default.join(dataDir, OWNER_IDENTITY_FILE_NAME);
|
|
54027
53966
|
}
|
|
54028
53967
|
read() {
|
|
54029
53968
|
let raw;
|
|
54030
53969
|
try {
|
|
54031
|
-
raw =
|
|
53970
|
+
raw = import_node_fs43.default.readFileSync(this.file, "utf8");
|
|
54032
53971
|
} catch {
|
|
54033
53972
|
return null;
|
|
54034
53973
|
}
|
|
@@ -54056,16 +53995,16 @@ var OwnerIdentityStore = class {
|
|
|
54056
53995
|
};
|
|
54057
53996
|
}
|
|
54058
53997
|
write(record) {
|
|
54059
|
-
|
|
54060
|
-
|
|
53998
|
+
import_node_fs43.default.mkdirSync(import_node_path45.default.dirname(this.file), { recursive: true });
|
|
53999
|
+
import_node_fs43.default.writeFileSync(this.file, JSON.stringify(record, null, 2), { mode: 384 });
|
|
54061
54000
|
try {
|
|
54062
|
-
|
|
54001
|
+
import_node_fs43.default.chmodSync(this.file, 384);
|
|
54063
54002
|
} catch {
|
|
54064
54003
|
}
|
|
54065
54004
|
}
|
|
54066
54005
|
clear() {
|
|
54067
54006
|
try {
|
|
54068
|
-
|
|
54007
|
+
import_node_fs43.default.unlinkSync(this.file);
|
|
54069
54008
|
} catch (err) {
|
|
54070
54009
|
const code = err?.code;
|
|
54071
54010
|
if (code !== "ENOENT") throw err;
|
|
@@ -54186,9 +54125,9 @@ var CentralClientError = class extends Error {
|
|
|
54186
54125
|
code;
|
|
54187
54126
|
cause;
|
|
54188
54127
|
};
|
|
54189
|
-
async function centralRequest(opts,
|
|
54128
|
+
async function centralRequest(opts, path77, init) {
|
|
54190
54129
|
const f = opts.fetchImpl ?? globalThis.fetch;
|
|
54191
|
-
const url = `${opts.api.replace(/\/+$/, "")}${
|
|
54130
|
+
const url = `${opts.api.replace(/\/+$/, "")}${path77}`;
|
|
54192
54131
|
const ctrl = new AbortController();
|
|
54193
54132
|
const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 15e3);
|
|
54194
54133
|
let res;
|
|
@@ -54330,8 +54269,8 @@ function verifyConnectToken(args) {
|
|
|
54330
54269
|
}
|
|
54331
54270
|
|
|
54332
54271
|
// src/feishu-auth/server-key.ts
|
|
54333
|
-
var
|
|
54334
|
-
var
|
|
54272
|
+
var fs53 = __toESM(require("fs"), 1);
|
|
54273
|
+
var path54 = __toESM(require("path"), 1);
|
|
54335
54274
|
var FILE_NAME2 = "server-signing-key.json";
|
|
54336
54275
|
var ServerKeyStore = class {
|
|
54337
54276
|
constructor(dataDir) {
|
|
@@ -54339,12 +54278,12 @@ var ServerKeyStore = class {
|
|
|
54339
54278
|
}
|
|
54340
54279
|
dataDir;
|
|
54341
54280
|
filePath() {
|
|
54342
|
-
return
|
|
54281
|
+
return path54.join(this.dataDir, FILE_NAME2);
|
|
54343
54282
|
}
|
|
54344
54283
|
/** 读缓存的公钥;无缓存 / 损坏 → null(调用方决定是否触发拉取) */
|
|
54345
54284
|
read() {
|
|
54346
54285
|
try {
|
|
54347
|
-
const raw =
|
|
54286
|
+
const raw = fs53.readFileSync(this.filePath(), "utf8");
|
|
54348
54287
|
const parsed = JSON.parse(raw);
|
|
54349
54288
|
if (typeof parsed.publicKeyPem === "string" && parsed.publicKeyPem.includes("PUBLIC KEY")) {
|
|
54350
54289
|
return parsed.publicKeyPem;
|
|
@@ -54359,12 +54298,12 @@ var ServerKeyStore = class {
|
|
|
54359
54298
|
publicKeyPem,
|
|
54360
54299
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
54361
54300
|
};
|
|
54362
|
-
|
|
54363
|
-
|
|
54301
|
+
fs53.mkdirSync(this.dataDir, { recursive: true });
|
|
54302
|
+
fs53.writeFileSync(this.filePath(), JSON.stringify(content, null, 2), { mode: 384 });
|
|
54364
54303
|
}
|
|
54365
54304
|
clear() {
|
|
54366
54305
|
try {
|
|
54367
|
-
|
|
54306
|
+
fs53.unlinkSync(this.filePath());
|
|
54368
54307
|
} catch {
|
|
54369
54308
|
}
|
|
54370
54309
|
}
|
|
@@ -54377,12 +54316,12 @@ init_protocol();
|
|
|
54377
54316
|
init_protocol();
|
|
54378
54317
|
|
|
54379
54318
|
// src/session/fork.ts
|
|
54380
|
-
var
|
|
54319
|
+
var import_node_fs44 = __toESM(require("fs"), 1);
|
|
54381
54320
|
var import_node_os16 = __toESM(require("os"), 1);
|
|
54382
|
-
var
|
|
54321
|
+
var import_node_path46 = __toESM(require("path"), 1);
|
|
54383
54322
|
init_claude_history();
|
|
54384
54323
|
function readJsonlEntries(file) {
|
|
54385
|
-
const raw =
|
|
54324
|
+
const raw = import_node_fs44.default.readFileSync(file, "utf8");
|
|
54386
54325
|
const out = [];
|
|
54387
54326
|
for (const line of raw.split("\n")) {
|
|
54388
54327
|
const t = line.trim();
|
|
@@ -54395,10 +54334,10 @@ function readJsonlEntries(file) {
|
|
|
54395
54334
|
return out;
|
|
54396
54335
|
}
|
|
54397
54336
|
function forkSession(input) {
|
|
54398
|
-
const baseDir = input.baseDir ??
|
|
54399
|
-
const projectDir =
|
|
54400
|
-
const sourceFile =
|
|
54401
|
-
if (!
|
|
54337
|
+
const baseDir = input.baseDir ?? import_node_path46.default.join(import_node_os16.default.homedir(), ".claude");
|
|
54338
|
+
const projectDir = import_node_path46.default.join(baseDir, "projects", cwdToHashDir(input.cwd));
|
|
54339
|
+
const sourceFile = import_node_path46.default.join(projectDir, `${input.toolSessionId}.jsonl`);
|
|
54340
|
+
if (!import_node_fs44.default.existsSync(sourceFile)) {
|
|
54402
54341
|
throw new Error(`fork: source transcript not found: ${sourceFile}`);
|
|
54403
54342
|
}
|
|
54404
54343
|
const entries = readJsonlEntries(sourceFile);
|
|
@@ -54428,9 +54367,9 @@ function forkSession(input) {
|
|
|
54428
54367
|
}
|
|
54429
54368
|
forkedLines.push(JSON.stringify(forked));
|
|
54430
54369
|
}
|
|
54431
|
-
const forkedFilePath =
|
|
54432
|
-
|
|
54433
|
-
|
|
54370
|
+
const forkedFilePath = import_node_path46.default.join(projectDir, `${forkedToolSessionId}.jsonl`);
|
|
54371
|
+
import_node_fs44.default.mkdirSync(projectDir, { recursive: true });
|
|
54372
|
+
import_node_fs44.default.writeFileSync(forkedFilePath, forkedLines.join("\n") + "\n", { mode: 384 });
|
|
54434
54373
|
return { forkedToolSessionId, forkedFilePath };
|
|
54435
54374
|
}
|
|
54436
54375
|
|
|
@@ -54782,7 +54721,7 @@ function buildPermissionHandlers(deps) {
|
|
|
54782
54721
|
}
|
|
54783
54722
|
|
|
54784
54723
|
// src/handlers/history.ts
|
|
54785
|
-
var
|
|
54724
|
+
var path57 = __toESM(require("path"), 1);
|
|
54786
54725
|
init_protocol();
|
|
54787
54726
|
|
|
54788
54727
|
// src/session/recent-dirs.ts
|
|
@@ -54800,7 +54739,7 @@ function listRecentDirs(store, limit = 50) {
|
|
|
54800
54739
|
}
|
|
54801
54740
|
|
|
54802
54741
|
// src/permission/persona-paths.ts
|
|
54803
|
-
var
|
|
54742
|
+
var path56 = __toESM(require("path"), 1);
|
|
54804
54743
|
function getAllowedPersonaIds(grants, action) {
|
|
54805
54744
|
const ids = /* @__PURE__ */ new Set();
|
|
54806
54745
|
for (const g2 of grants) {
|
|
@@ -54813,42 +54752,42 @@ function getAllowedPersonaIds(grants, action) {
|
|
|
54813
54752
|
return ids;
|
|
54814
54753
|
}
|
|
54815
54754
|
function isGuestPathAllowed(grants, absPath, personaRoot, action = "read", userWorkDir) {
|
|
54816
|
-
const target =
|
|
54755
|
+
const target = path56.resolve(absPath);
|
|
54817
54756
|
if (userWorkDir) {
|
|
54818
|
-
const u =
|
|
54819
|
-
const usep = u.endsWith(
|
|
54757
|
+
const u = path56.resolve(userWorkDir);
|
|
54758
|
+
const usep = u.endsWith(path56.sep) ? "" : path56.sep;
|
|
54820
54759
|
if (target === u || target.startsWith(u + usep)) return true;
|
|
54821
54760
|
}
|
|
54822
|
-
const root =
|
|
54823
|
-
const sep3 = root.endsWith(
|
|
54761
|
+
const root = path56.resolve(personaRoot);
|
|
54762
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54824
54763
|
if (!target.startsWith(root + sep3)) return false;
|
|
54825
|
-
const rel =
|
|
54764
|
+
const rel = path56.relative(root, target);
|
|
54826
54765
|
if (!rel || rel.startsWith("..")) return false;
|
|
54827
|
-
const personaId = rel.split(
|
|
54766
|
+
const personaId = rel.split(path56.sep)[0];
|
|
54828
54767
|
if (!personaId) return false;
|
|
54829
54768
|
const allowed = getAllowedPersonaIds(grants, action);
|
|
54830
54769
|
if (allowed === "*") return true;
|
|
54831
54770
|
return allowed.has(personaId);
|
|
54832
54771
|
}
|
|
54833
54772
|
function personaIdFromPath(absPath, personaRoot) {
|
|
54834
|
-
const root =
|
|
54835
|
-
const target =
|
|
54836
|
-
const sep3 = root.endsWith(
|
|
54773
|
+
const root = path56.resolve(personaRoot);
|
|
54774
|
+
const target = path56.resolve(absPath);
|
|
54775
|
+
const sep3 = root.endsWith(path56.sep) ? "" : path56.sep;
|
|
54837
54776
|
if (!target.startsWith(root + sep3)) return null;
|
|
54838
|
-
const rel =
|
|
54777
|
+
const rel = path56.relative(root, target);
|
|
54839
54778
|
if (!rel || rel.startsWith("..")) return null;
|
|
54840
|
-
const id = rel.split(
|
|
54779
|
+
const id = rel.split(path56.sep)[0];
|
|
54841
54780
|
return id || null;
|
|
54842
54781
|
}
|
|
54843
54782
|
function isPathWithin(dir, absPath) {
|
|
54844
|
-
const d =
|
|
54845
|
-
const t =
|
|
54846
|
-
const sep3 = d.endsWith(
|
|
54783
|
+
const d = path56.resolve(dir);
|
|
54784
|
+
const t = path56.resolve(absPath);
|
|
54785
|
+
const sep3 = d.endsWith(path56.sep) ? "" : path56.sep;
|
|
54847
54786
|
return t === d || t.startsWith(d + sep3);
|
|
54848
54787
|
}
|
|
54849
54788
|
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
54850
54789
|
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
54851
|
-
return personaIdFromPath(
|
|
54790
|
+
return personaIdFromPath(path56.resolve(absPath), personaRoot) === personaId;
|
|
54852
54791
|
}
|
|
54853
54792
|
|
|
54854
54793
|
// src/handlers/history.ts
|
|
@@ -54874,7 +54813,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54874
54813
|
if (!pid) return false;
|
|
54875
54814
|
return isGuestPathAllowed(
|
|
54876
54815
|
ctx.grants,
|
|
54877
|
-
|
|
54816
|
+
path57.join(personaRoot, pid),
|
|
54878
54817
|
personaRoot,
|
|
54879
54818
|
"read",
|
|
54880
54819
|
userWorkDir
|
|
@@ -54886,7 +54825,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54886
54825
|
};
|
|
54887
54826
|
const list = async (frame, _client, ctx) => {
|
|
54888
54827
|
const args = HistoryListArgs.parse(frame);
|
|
54889
|
-
assertGuestPath(ctx,
|
|
54828
|
+
assertGuestPath(ctx, path57.resolve(args.projectPath), personaRoot, "history:list");
|
|
54890
54829
|
const sessions = await history.listSessions(args);
|
|
54891
54830
|
return { response: { type: "history:list", sessions } };
|
|
54892
54831
|
};
|
|
@@ -54918,13 +54857,13 @@ function buildHistoryHandlers(deps) {
|
|
|
54918
54857
|
};
|
|
54919
54858
|
const subagents = async (frame, _client, ctx) => {
|
|
54920
54859
|
const args = HistorySubagentsArgs.parse(frame);
|
|
54921
|
-
assertGuestPath(ctx,
|
|
54860
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
54922
54861
|
const subs = await history.listSubagents(args);
|
|
54923
54862
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
54924
54863
|
};
|
|
54925
54864
|
const subagentRead = async (frame, _client, ctx) => {
|
|
54926
54865
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
54927
|
-
assertGuestPath(ctx,
|
|
54866
|
+
assertGuestPath(ctx, path57.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
54928
54867
|
const res = await history.readSubagent(args);
|
|
54929
54868
|
return { response: { type: "history:subagent-read", ...res } };
|
|
54930
54869
|
};
|
|
@@ -54933,7 +54872,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54933
54872
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
54934
54873
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
54935
54874
|
const filtered = dirs.filter(
|
|
54936
|
-
(d) => isGuestPathAllowed(ctx.grants,
|
|
54875
|
+
(d) => isGuestPathAllowed(ctx.grants, path57.resolve(d.cwd), personaRoot, "read", userWorkDir)
|
|
54937
54876
|
);
|
|
54938
54877
|
return { response: { type: "history:recentDirs", dirs: filtered } };
|
|
54939
54878
|
}
|
|
@@ -54950,7 +54889,7 @@ function buildHistoryHandlers(deps) {
|
|
|
54950
54889
|
}
|
|
54951
54890
|
|
|
54952
54891
|
// src/handlers/workspace.ts
|
|
54953
|
-
var
|
|
54892
|
+
var path58 = __toESM(require("path"), 1);
|
|
54954
54893
|
var os16 = __toESM(require("os"), 1);
|
|
54955
54894
|
init_protocol();
|
|
54956
54895
|
init_protocol();
|
|
@@ -54992,22 +54931,22 @@ function buildWorkspaceHandlers(deps) {
|
|
|
54992
54931
|
const args = WorkspaceListArgs.parse(frame);
|
|
54993
54932
|
const isGuest = ctx?.principal.kind === "guest";
|
|
54994
54933
|
const fallbackCwd = isGuest && personaRoot ? personaRoot : os16.homedir();
|
|
54995
|
-
const resolvedCwd =
|
|
54996
|
-
const target = args.path ?
|
|
54934
|
+
const resolvedCwd = path58.resolve(args.cwd ?? fallbackCwd);
|
|
54935
|
+
const target = args.path ? path58.resolve(resolvedCwd, args.path) : resolvedCwd;
|
|
54997
54936
|
assertGuestPath2(ctx, target, personaRoot, "workspace:list", usersRoot);
|
|
54998
54937
|
const res = workspace.list({ ...args, cwd: resolvedCwd });
|
|
54999
54938
|
return { response: { type: "workspace:list", ...res } };
|
|
55000
54939
|
};
|
|
55001
54940
|
const read = async (frame, _client, ctx) => {
|
|
55002
54941
|
const args = WorkspaceReadArgs.parse(frame);
|
|
55003
|
-
const target =
|
|
54942
|
+
const target = path58.isAbsolute(args.path) ? path58.resolve(args.path) : path58.resolve(args.cwd, args.path);
|
|
55004
54943
|
assertGuestPath2(ctx, target, personaRoot, "workspace:read", usersRoot);
|
|
55005
54944
|
const res = workspace.read(args);
|
|
55006
54945
|
return { response: { type: "workspace:read", ...res } };
|
|
55007
54946
|
};
|
|
55008
54947
|
const skillsList = async (frame, _client, ctx) => {
|
|
55009
54948
|
const args = SkillsListArgs.parse(frame);
|
|
55010
|
-
const cwdAbs =
|
|
54949
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
55011
54950
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "skills:list", usersRoot);
|
|
55012
54951
|
const list2 = await getSkillsForTool(args.tool ?? "claude", cwdAbs);
|
|
55013
54952
|
if (ctx?.principal.kind === "guest" && personaRoot) {
|
|
@@ -55019,7 +54958,7 @@ function buildWorkspaceHandlers(deps) {
|
|
|
55019
54958
|
};
|
|
55020
54959
|
const agentsList = async (frame, _client, ctx) => {
|
|
55021
54960
|
const args = AgentsListArgs.parse(frame);
|
|
55022
|
-
const cwdAbs =
|
|
54961
|
+
const cwdAbs = path58.resolve(args.cwd);
|
|
55023
54962
|
assertGuestPath2(ctx, cwdAbs, personaRoot, "agents:list", usersRoot);
|
|
55024
54963
|
if (args.tool === "codex") {
|
|
55025
54964
|
return { response: { type: "agents:list", agents: [] } };
|
|
@@ -55041,20 +54980,20 @@ function buildWorkspaceHandlers(deps) {
|
|
|
55041
54980
|
}
|
|
55042
54981
|
|
|
55043
54982
|
// src/handlers/git.ts
|
|
55044
|
-
var
|
|
54983
|
+
var path60 = __toESM(require("path"), 1);
|
|
55045
54984
|
init_protocol();
|
|
55046
54985
|
init_protocol();
|
|
55047
54986
|
|
|
55048
54987
|
// src/workspace/git.ts
|
|
55049
54988
|
var import_node_child_process12 = require("child_process");
|
|
55050
|
-
var
|
|
55051
|
-
var
|
|
54989
|
+
var import_node_fs45 = __toESM(require("fs"), 1);
|
|
54990
|
+
var import_node_path47 = __toESM(require("path"), 1);
|
|
55052
54991
|
var import_node_util = require("util");
|
|
55053
54992
|
var pexec = (0, import_node_util.promisify)(import_node_child_process12.execFile);
|
|
55054
54993
|
function normalizePath(p2) {
|
|
55055
|
-
const resolved =
|
|
54994
|
+
const resolved = import_node_path47.default.resolve(p2);
|
|
55056
54995
|
try {
|
|
55057
|
-
return
|
|
54996
|
+
return import_node_fs45.default.realpathSync(resolved);
|
|
55058
54997
|
} catch {
|
|
55059
54998
|
return resolved;
|
|
55060
54999
|
}
|
|
@@ -55128,7 +55067,7 @@ async function listGitBranches(cwd) {
|
|
|
55128
55067
|
function assertGuestCwd(ctx, cwd, personaRoot, method, usersRoot) {
|
|
55129
55068
|
if (!ctx || ctx.principal.kind !== "guest" || !personaRoot) return;
|
|
55130
55069
|
const userWorkDir = usersRoot ? deriveUserWorkDir(ctx.principal.id, usersRoot) : void 0;
|
|
55131
|
-
if (!isGuestPathAllowed(ctx.grants,
|
|
55070
|
+
if (!isGuestPathAllowed(ctx.grants, path60.resolve(cwd), personaRoot, "read", userWorkDir)) {
|
|
55132
55071
|
throw new ClawdError(
|
|
55133
55072
|
ERROR_CODES.UNAUTHORIZED,
|
|
55134
55073
|
`guest ${ctx.principal.id} cannot ${method} cwd ${cwd}`
|
|
@@ -55469,22 +55408,22 @@ init_src();
|
|
|
55469
55408
|
init_protocol();
|
|
55470
55409
|
|
|
55471
55410
|
// src/sshd/key-issue.ts
|
|
55472
|
-
var
|
|
55473
|
-
var
|
|
55411
|
+
var import_node_fs46 = __toESM(require("fs"), 1);
|
|
55412
|
+
var import_node_path48 = __toESM(require("path"), 1);
|
|
55474
55413
|
var import_node_child_process13 = require("child_process");
|
|
55475
55414
|
function safeDeviceId(deviceId) {
|
|
55476
55415
|
return deviceId.replace(/[\/\\]/g, "_");
|
|
55477
55416
|
}
|
|
55478
55417
|
async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
55479
55418
|
const safeId = safeDeviceId(deviceId);
|
|
55480
|
-
const keysDir =
|
|
55481
|
-
|
|
55482
|
-
const privPath =
|
|
55419
|
+
const keysDir = import_node_path48.default.join(sshdDir, "keys");
|
|
55420
|
+
import_node_fs46.default.mkdirSync(keysDir, { recursive: true, mode: 448 });
|
|
55421
|
+
const privPath = import_node_path48.default.join(keysDir, `${safeId}.ed25519`);
|
|
55483
55422
|
const pubPath = `${privPath}.pub`;
|
|
55484
|
-
if (
|
|
55423
|
+
if (import_node_fs46.default.existsSync(privPath) && import_node_fs46.default.existsSync(pubPath)) {
|
|
55485
55424
|
return {
|
|
55486
|
-
privateKeyPem:
|
|
55487
|
-
publicKeyLine:
|
|
55425
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55426
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55488
55427
|
};
|
|
55489
55428
|
}
|
|
55490
55429
|
const bin = opts.keygenBin ?? "/usr/bin/ssh-keygen";
|
|
@@ -55498,16 +55437,16 @@ async function issueContactSshKey(deviceId, sshdDir, opts = {}) {
|
|
|
55498
55437
|
p2.on("error", reject);
|
|
55499
55438
|
});
|
|
55500
55439
|
try {
|
|
55501
|
-
|
|
55440
|
+
import_node_fs46.default.chmodSync(privPath, 384);
|
|
55502
55441
|
} catch {
|
|
55503
55442
|
}
|
|
55504
55443
|
try {
|
|
55505
|
-
|
|
55444
|
+
import_node_fs46.default.chmodSync(pubPath, 420);
|
|
55506
55445
|
} catch {
|
|
55507
55446
|
}
|
|
55508
55447
|
return {
|
|
55509
|
-
privateKeyPem:
|
|
55510
|
-
publicKeyLine:
|
|
55448
|
+
privateKeyPem: import_node_fs46.default.readFileSync(privPath, "utf8"),
|
|
55449
|
+
publicKeyLine: import_node_fs46.default.readFileSync(pubPath, "utf8").trim()
|
|
55511
55450
|
};
|
|
55512
55451
|
}
|
|
55513
55452
|
|
|
@@ -55927,7 +55866,7 @@ function buildPersonaHandlers(deps) {
|
|
|
55927
55866
|
}
|
|
55928
55867
|
|
|
55929
55868
|
// src/handlers/attachment.ts
|
|
55930
|
-
var
|
|
55869
|
+
var import_node_path49 = __toESM(require("path"), 1);
|
|
55931
55870
|
init_protocol();
|
|
55932
55871
|
init_protocol();
|
|
55933
55872
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
@@ -56007,12 +55946,12 @@ function buildAttachmentHandlers(deps) {
|
|
|
56007
55946
|
`session ${args.sessionId} scope unresolved`
|
|
56008
55947
|
);
|
|
56009
55948
|
}
|
|
56010
|
-
const cwdAbs =
|
|
56011
|
-
const candidateAbs =
|
|
55949
|
+
const cwdAbs = import_node_path49.default.resolve(sessionFile.cwd);
|
|
55950
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
56012
55951
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
56013
55952
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
56014
55953
|
const entry = entries.find((e) => {
|
|
56015
|
-
const storedAbs =
|
|
55954
|
+
const storedAbs = import_node_path49.default.isAbsolute(e.relPath) ? import_node_path49.default.resolve(e.relPath) : import_node_path49.default.resolve(cwdAbs, e.relPath);
|
|
56016
55955
|
return storedAbs === candidateAbs && !e.stale;
|
|
56017
55956
|
});
|
|
56018
55957
|
if (!entry) {
|
|
@@ -56037,7 +55976,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
56037
55976
|
if (!ctx || ctx.principal.kind !== "guest" || !deps.personaRoot || !deps.sessionStore) return;
|
|
56038
55977
|
const f = deps.sessionStore.read(sessionId);
|
|
56039
55978
|
if (!f) return;
|
|
56040
|
-
assertGuestAttachmentPath(ctx,
|
|
55979
|
+
assertGuestAttachmentPath(ctx, import_node_path49.default.resolve(f.cwd), deps.personaRoot, method, deps.usersRoot);
|
|
56041
55980
|
}
|
|
56042
55981
|
const groupAdd = async (frame, _client, ctx) => {
|
|
56043
55982
|
if (!deps.groupFileStore || !deps.getSessionScope) {
|
|
@@ -56052,8 +55991,8 @@ function buildAttachmentHandlers(deps) {
|
|
|
56052
55991
|
if (!scope) {
|
|
56053
55992
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
56054
55993
|
}
|
|
56055
|
-
const cwdAbs =
|
|
56056
|
-
const candidateAbs =
|
|
55994
|
+
const cwdAbs = import_node_path49.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
55995
|
+
const candidateAbs = import_node_path49.default.isAbsolute(args.relPath) ? import_node_path49.default.resolve(args.relPath) : import_node_path49.default.resolve(cwdAbs, args.relPath);
|
|
56057
55996
|
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
56058
55997
|
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
56059
55998
|
const size = 0;
|
|
@@ -56112,20 +56051,20 @@ function buildAttachmentHandlers(deps) {
|
|
|
56112
56051
|
|
|
56113
56052
|
// src/handlers/extension.ts
|
|
56114
56053
|
var import_promises8 = __toESM(require("fs/promises"), 1);
|
|
56115
|
-
var
|
|
56054
|
+
var import_node_path54 = __toESM(require("path"), 1);
|
|
56116
56055
|
init_protocol();
|
|
56117
56056
|
init_src();
|
|
56118
56057
|
|
|
56119
56058
|
// src/extension/bundle-zip.ts
|
|
56120
56059
|
var import_promises5 = __toESM(require("fs/promises"), 1);
|
|
56121
|
-
var
|
|
56060
|
+
var import_node_path50 = __toESM(require("path"), 1);
|
|
56122
56061
|
var import_node_crypto14 = __toESM(require("crypto"), 1);
|
|
56123
56062
|
var import_jszip2 = __toESM(require_lib3(), 1);
|
|
56124
56063
|
async function bundleExtensionDir(dir) {
|
|
56125
56064
|
const entries = await listFilesSorted(dir);
|
|
56126
56065
|
const zip = new import_jszip2.default();
|
|
56127
56066
|
for (const rel of entries) {
|
|
56128
|
-
const abs =
|
|
56067
|
+
const abs = import_node_path50.default.join(dir, rel);
|
|
56129
56068
|
const content = await import_promises5.default.readFile(abs);
|
|
56130
56069
|
zip.file(rel, content, { date: FIXED_DATE });
|
|
56131
56070
|
}
|
|
@@ -56146,7 +56085,7 @@ async function listFilesSorted(rootDir) {
|
|
|
56146
56085
|
return out;
|
|
56147
56086
|
}
|
|
56148
56087
|
async function walk(absRoot, relPrefix, out) {
|
|
56149
|
-
const dirAbs =
|
|
56088
|
+
const dirAbs = import_node_path50.default.join(absRoot, relPrefix);
|
|
56150
56089
|
const entries = await import_promises5.default.readdir(dirAbs, { withFileTypes: true });
|
|
56151
56090
|
for (const e of entries) {
|
|
56152
56091
|
if (IGNORE_BASENAMES.has(e.name)) continue;
|
|
@@ -56202,7 +56141,7 @@ function computePublishCheck(args) {
|
|
|
56202
56141
|
|
|
56203
56142
|
// src/extension/install-flow.ts
|
|
56204
56143
|
var import_promises6 = __toESM(require("fs/promises"), 1);
|
|
56205
|
-
var
|
|
56144
|
+
var import_node_path52 = __toESM(require("path"), 1);
|
|
56206
56145
|
var import_node_os19 = __toESM(require("os"), 1);
|
|
56207
56146
|
var import_node_crypto15 = __toESM(require("crypto"), 1);
|
|
56208
56147
|
var import_jszip3 = __toESM(require_lib3(), 1);
|
|
@@ -56210,19 +56149,19 @@ init_src();
|
|
|
56210
56149
|
|
|
56211
56150
|
// src/extension/paths.ts
|
|
56212
56151
|
var import_node_os18 = __toESM(require("os"), 1);
|
|
56213
|
-
var
|
|
56152
|
+
var import_node_path51 = __toESM(require("path"), 1);
|
|
56214
56153
|
init_src();
|
|
56215
56154
|
function clawdHomeRoot(override) {
|
|
56216
|
-
return override ?? process.env.CLAWD_HOME ??
|
|
56155
|
+
return override ?? process.env.CLAWD_HOME ?? import_node_path51.default.join(import_node_os18.default.homedir(), ".clawd");
|
|
56217
56156
|
}
|
|
56218
56157
|
function extensionsRoot(override) {
|
|
56219
|
-
return
|
|
56158
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions");
|
|
56220
56159
|
}
|
|
56221
56160
|
function publishedChannelsFile(override) {
|
|
56222
|
-
return
|
|
56161
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extensions-published.json");
|
|
56223
56162
|
}
|
|
56224
56163
|
function bundleCacheRoot(override) {
|
|
56225
|
-
return
|
|
56164
|
+
return import_node_path51.default.join(clawdHomeRoot(override), "extension-bundles");
|
|
56226
56165
|
}
|
|
56227
56166
|
|
|
56228
56167
|
// src/extension/install-flow.ts
|
|
@@ -56249,7 +56188,7 @@ async function installFromChannel(args, deps) {
|
|
|
56249
56188
|
throw new InstallError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56250
56189
|
}
|
|
56251
56190
|
for (const name of Object.keys(zip.files)) {
|
|
56252
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56191
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path52.default.isAbsolute(name)) {
|
|
56253
56192
|
throw new InstallError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56254
56193
|
}
|
|
56255
56194
|
}
|
|
@@ -56281,7 +56220,7 @@ async function installFromChannel(args, deps) {
|
|
|
56281
56220
|
);
|
|
56282
56221
|
}
|
|
56283
56222
|
const localExtId = namespacedExtId(ownerSlug, channelRef.ownerPrincipalId);
|
|
56284
|
-
const destDir =
|
|
56223
|
+
const destDir = import_node_path52.default.join(deps.extensionsRoot, localExtId);
|
|
56285
56224
|
let destExists = false;
|
|
56286
56225
|
try {
|
|
56287
56226
|
await import_promises6.default.access(destDir);
|
|
@@ -56295,16 +56234,16 @@ async function installFromChannel(args, deps) {
|
|
|
56295
56234
|
);
|
|
56296
56235
|
}
|
|
56297
56236
|
const stage = await import_promises6.default.mkdtemp(
|
|
56298
|
-
|
|
56237
|
+
import_node_path52.default.join(import_node_os19.default.tmpdir(), `clawd-ext-install-${localExtId}-`)
|
|
56299
56238
|
);
|
|
56300
56239
|
try {
|
|
56301
56240
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56302
|
-
const dest =
|
|
56241
|
+
const dest = import_node_path52.default.join(stage, name);
|
|
56303
56242
|
if (entry.dir) {
|
|
56304
56243
|
await import_promises6.default.mkdir(dest, { recursive: true });
|
|
56305
56244
|
continue;
|
|
56306
56245
|
}
|
|
56307
|
-
await import_promises6.default.mkdir(
|
|
56246
|
+
await import_promises6.default.mkdir(import_node_path52.default.dirname(dest), { recursive: true });
|
|
56308
56247
|
if (name === "manifest.json") {
|
|
56309
56248
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56310
56249
|
await import_promises6.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56325,7 +56264,7 @@ async function installFromChannel(args, deps) {
|
|
|
56325
56264
|
|
|
56326
56265
|
// src/extension/update-flow.ts
|
|
56327
56266
|
var import_promises7 = __toESM(require("fs/promises"), 1);
|
|
56328
|
-
var
|
|
56267
|
+
var import_node_path53 = __toESM(require("path"), 1);
|
|
56329
56268
|
var import_node_os20 = __toESM(require("os"), 1);
|
|
56330
56269
|
var import_node_crypto16 = __toESM(require("crypto"), 1);
|
|
56331
56270
|
var import_jszip4 = __toESM(require_lib3(), 1);
|
|
@@ -56343,11 +56282,11 @@ async function updateFromChannel(args, deps) {
|
|
|
56343
56282
|
channelRef.extId,
|
|
56344
56283
|
channelRef.ownerPrincipalId
|
|
56345
56284
|
);
|
|
56346
|
-
const liveDir =
|
|
56285
|
+
const liveDir = import_node_path53.default.join(deps.extensionsRoot, localExtId);
|
|
56347
56286
|
const prevDir = `${liveDir}.prev`;
|
|
56348
56287
|
let existingVersion;
|
|
56349
56288
|
try {
|
|
56350
|
-
const raw = await import_promises7.default.readFile(
|
|
56289
|
+
const raw = await import_promises7.default.readFile(import_node_path53.default.join(liveDir, "manifest.json"), "utf8");
|
|
56351
56290
|
const parsed2 = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
56352
56291
|
if (!parsed2.success) {
|
|
56353
56292
|
throw new UpdateError(
|
|
@@ -56380,7 +56319,7 @@ async function updateFromChannel(args, deps) {
|
|
|
56380
56319
|
throw new UpdateError("ZIP_INVALID", `failed to load zip: ${e.message}`);
|
|
56381
56320
|
}
|
|
56382
56321
|
for (const name of Object.keys(zip.files)) {
|
|
56383
|
-
if (name.includes("..") || name.startsWith("/") ||
|
|
56322
|
+
if (name.includes("..") || name.startsWith("/") || import_node_path53.default.isAbsolute(name)) {
|
|
56384
56323
|
throw new UpdateError("ZIP_INVALID", `unsafe zip entry: ${name}`);
|
|
56385
56324
|
}
|
|
56386
56325
|
}
|
|
@@ -56415,16 +56354,16 @@ async function updateFromChannel(args, deps) {
|
|
|
56415
56354
|
await import_promises7.default.rm(prevDir, { recursive: true, force: true });
|
|
56416
56355
|
await import_promises7.default.rename(liveDir, prevDir);
|
|
56417
56356
|
const stage = await import_promises7.default.mkdtemp(
|
|
56418
|
-
|
|
56357
|
+
import_node_path53.default.join(import_node_os20.default.tmpdir(), `clawd-ext-update-${localExtId}-`)
|
|
56419
56358
|
);
|
|
56420
56359
|
try {
|
|
56421
56360
|
for (const [name, entry] of Object.entries(zip.files)) {
|
|
56422
|
-
const dest =
|
|
56361
|
+
const dest = import_node_path53.default.join(stage, name);
|
|
56423
56362
|
if (entry.dir) {
|
|
56424
56363
|
await import_promises7.default.mkdir(dest, { recursive: true });
|
|
56425
56364
|
continue;
|
|
56426
56365
|
}
|
|
56427
|
-
await import_promises7.default.mkdir(
|
|
56366
|
+
await import_promises7.default.mkdir(import_node_path53.default.dirname(dest), { recursive: true });
|
|
56428
56367
|
if (name === "manifest.json") {
|
|
56429
56368
|
const rewritten = { ...parsed.data, id: localExtId };
|
|
56430
56369
|
await import_promises7.default.writeFile(dest, JSON.stringify(rewritten, null, 2));
|
|
@@ -56518,7 +56457,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56518
56457
|
);
|
|
56519
56458
|
}
|
|
56520
56459
|
}
|
|
56521
|
-
const manifestPath =
|
|
56460
|
+
const manifestPath = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56522
56461
|
const manifest = await readManifest(root, extId);
|
|
56523
56462
|
const next = { ...manifest, version: newVersion };
|
|
56524
56463
|
const tmp = `${manifestPath}.tmp`;
|
|
@@ -56526,7 +56465,7 @@ async function rewriteManifestVersion(root, extId, newVersion, previousPublished
|
|
|
56526
56465
|
await import_promises8.default.rename(tmp, manifestPath);
|
|
56527
56466
|
}
|
|
56528
56467
|
async function readManifest(root, extId) {
|
|
56529
|
-
const file =
|
|
56468
|
+
const file = import_node_path54.default.join(root, extId, "manifest.json");
|
|
56530
56469
|
let raw;
|
|
56531
56470
|
try {
|
|
56532
56471
|
raw = await import_promises8.default.readFile(file, "utf8");
|
|
@@ -56617,7 +56556,7 @@ function buildExtensionHandlers(deps) {
|
|
|
56617
56556
|
};
|
|
56618
56557
|
async function buildSnapshotMeta(extId) {
|
|
56619
56558
|
const manifest = await readManifest(deps.root, extId);
|
|
56620
|
-
const { sha256, buffer } = await bundleExtensionDir(
|
|
56559
|
+
const { sha256, buffer } = await bundleExtensionDir(import_node_path54.default.join(deps.root, extId));
|
|
56621
56560
|
return { manifest, contentHash: sha256, buffer };
|
|
56622
56561
|
}
|
|
56623
56562
|
const publish = async (frame, _client, ctx) => {
|
|
@@ -56798,9 +56737,9 @@ function buildExtensionHandlers(deps) {
|
|
|
56798
56737
|
}
|
|
56799
56738
|
|
|
56800
56739
|
// src/app-builder/project-store.ts
|
|
56801
|
-
var
|
|
56740
|
+
var import_node_fs47 = require("fs");
|
|
56802
56741
|
var import_node_child_process14 = require("child_process");
|
|
56803
|
-
var
|
|
56742
|
+
var import_node_path55 = require("path");
|
|
56804
56743
|
init_protocol();
|
|
56805
56744
|
var PROJECTS_DIR = "projects";
|
|
56806
56745
|
var META_FILE = ".clawd-project.json";
|
|
@@ -56814,19 +56753,19 @@ var ProjectStore = class {
|
|
|
56814
56753
|
root;
|
|
56815
56754
|
/** projects/<name>/.clawd-project.json 路径 */
|
|
56816
56755
|
metaPath(name) {
|
|
56817
|
-
return (0,
|
|
56756
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name, META_FILE);
|
|
56818
56757
|
}
|
|
56819
56758
|
/** projects/<name>/ 目录路径(cwd 用) */
|
|
56820
56759
|
projectDir(name) {
|
|
56821
|
-
return (0,
|
|
56760
|
+
return (0, import_node_path55.join)(this.projectsRoot(), name);
|
|
56822
56761
|
}
|
|
56823
56762
|
projectsRoot() {
|
|
56824
|
-
return (0,
|
|
56763
|
+
return (0, import_node_path55.join)(this.root, PROJECTS_DIR);
|
|
56825
56764
|
}
|
|
56826
56765
|
async list() {
|
|
56827
56766
|
let entries;
|
|
56828
56767
|
try {
|
|
56829
|
-
entries = await
|
|
56768
|
+
entries = await import_node_fs47.promises.readdir(this.projectsRoot());
|
|
56830
56769
|
} catch (err) {
|
|
56831
56770
|
if (err.code === "ENOENT") return [];
|
|
56832
56771
|
throw err;
|
|
@@ -56834,7 +56773,7 @@ var ProjectStore = class {
|
|
|
56834
56773
|
const out = [];
|
|
56835
56774
|
for (const name of entries) {
|
|
56836
56775
|
try {
|
|
56837
|
-
const raw = await
|
|
56776
|
+
const raw = await import_node_fs47.promises.readFile(this.metaPath(name), "utf8");
|
|
56838
56777
|
const json = JSON.parse(raw);
|
|
56839
56778
|
let migrated = false;
|
|
56840
56779
|
if (typeof json.devCommand !== "string" || json.devCommand.length === 0) {
|
|
@@ -56845,7 +56784,7 @@ var ProjectStore = class {
|
|
|
56845
56784
|
if (parsed.success) {
|
|
56846
56785
|
out.push(parsed.data);
|
|
56847
56786
|
if (migrated) {
|
|
56848
|
-
void
|
|
56787
|
+
void import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(parsed.data, null, 2) + "\n", "utf8").catch(() => {
|
|
56849
56788
|
});
|
|
56850
56789
|
}
|
|
56851
56790
|
}
|
|
@@ -56889,8 +56828,8 @@ var ProjectStore = class {
|
|
|
56889
56828
|
throw new Error(`invalid name "${name}": ${validated.error.message}`);
|
|
56890
56829
|
}
|
|
56891
56830
|
const dir = this.projectDir(name);
|
|
56892
|
-
await
|
|
56893
|
-
await
|
|
56831
|
+
await import_node_fs47.promises.mkdir(dir, { recursive: true });
|
|
56832
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(meta, null, 2) + "\n", "utf8");
|
|
56894
56833
|
return meta;
|
|
56895
56834
|
}
|
|
56896
56835
|
/**
|
|
@@ -56933,7 +56872,7 @@ var ProjectStore = class {
|
|
|
56933
56872
|
}
|
|
56934
56873
|
async delete(name) {
|
|
56935
56874
|
const dir = this.projectDir(name);
|
|
56936
|
-
await
|
|
56875
|
+
await import_node_fs47.promises.rm(dir, { recursive: true, force: true });
|
|
56937
56876
|
}
|
|
56938
56877
|
async updatePort(name, newPort) {
|
|
56939
56878
|
if (newPort < PROJECT_PORT_MIN || newPort > PROJECT_PORT_MAX) {
|
|
@@ -56949,7 +56888,7 @@ var ProjectStore = class {
|
|
|
56949
56888
|
throw new Error(`port ${newPort} already used / \u5DF2\u88AB project "${conflict.name}" \u5360\u7528`);
|
|
56950
56889
|
}
|
|
56951
56890
|
const updated = { ...target, port: newPort };
|
|
56952
|
-
await
|
|
56891
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
56953
56892
|
return updated;
|
|
56954
56893
|
}
|
|
56955
56894
|
/**
|
|
@@ -56966,7 +56905,7 @@ var ProjectStore = class {
|
|
|
56966
56905
|
if (!validated.success) {
|
|
56967
56906
|
throw new Error(`invalid prodUrl "${url}": ${validated.error.message}`);
|
|
56968
56907
|
}
|
|
56969
|
-
await
|
|
56908
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56970
56909
|
return validated.data;
|
|
56971
56910
|
}
|
|
56972
56911
|
/**
|
|
@@ -56987,7 +56926,7 @@ var ProjectStore = class {
|
|
|
56987
56926
|
if (!validated.success) {
|
|
56988
56927
|
throw new Error(`invalid publishJob: ${validated.error.message}`);
|
|
56989
56928
|
}
|
|
56990
|
-
await
|
|
56929
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
56991
56930
|
return validated.data;
|
|
56992
56931
|
}
|
|
56993
56932
|
/** 清掉 .clawd-project.json.publishJob 字段。其他字段保持原样。 */
|
|
@@ -57002,7 +56941,7 @@ var ProjectStore = class {
|
|
|
57002
56941
|
if (!validated.success) {
|
|
57003
56942
|
throw new Error(`failed to clear publishJob: ${validated.error.message}`);
|
|
57004
56943
|
}
|
|
57005
|
-
await
|
|
56944
|
+
await import_node_fs47.promises.writeFile(this.metaPath(name), JSON.stringify(validated.data, null, 2) + "\n", "utf8");
|
|
57006
56945
|
return validated.data;
|
|
57007
56946
|
}
|
|
57008
56947
|
};
|
|
@@ -57123,8 +57062,8 @@ var PublishJobRegistry = class {
|
|
|
57123
57062
|
|
|
57124
57063
|
// src/app-builder/publish-job-runner.ts
|
|
57125
57064
|
var import_node_child_process16 = require("child_process");
|
|
57126
|
-
var
|
|
57127
|
-
var
|
|
57065
|
+
var import_node_fs48 = require("fs");
|
|
57066
|
+
var import_node_path56 = require("path");
|
|
57128
57067
|
|
|
57129
57068
|
// src/app-builder/publish-stage-parser.ts
|
|
57130
57069
|
var STAGE_RE = /^\s*::stage::(build|deploy|verify)\s*$/;
|
|
@@ -57156,10 +57095,10 @@ async function startPublishJob(deps, args) {
|
|
|
57156
57095
|
return { jobId: registry2.get(args.name).jobId, status: "already-publishing" };
|
|
57157
57096
|
}
|
|
57158
57097
|
const projDir = projectDir(args.name);
|
|
57159
|
-
const logPath = (0,
|
|
57098
|
+
const logPath = (0, import_node_path56.join)(projDir, ".publish.log");
|
|
57160
57099
|
let logStream = null;
|
|
57161
57100
|
try {
|
|
57162
|
-
logStream = (0,
|
|
57101
|
+
logStream = (0, import_node_fs48.createWriteStream)(logPath, { flags: "w" });
|
|
57163
57102
|
} catch {
|
|
57164
57103
|
logStream = null;
|
|
57165
57104
|
}
|
|
@@ -57416,8 +57355,8 @@ async function recoverInterruptedJobs(deps) {
|
|
|
57416
57355
|
|
|
57417
57356
|
// src/handlers/app-builder.ts
|
|
57418
57357
|
init_protocol();
|
|
57419
|
-
var
|
|
57420
|
-
var
|
|
57358
|
+
var import_node_path57 = require("path");
|
|
57359
|
+
var import_node_fs49 = require("fs");
|
|
57421
57360
|
var APP_BUILDER_PERSONAS = ["persona-app-builder", "persona-dataclaw-builder"];
|
|
57422
57361
|
var DEV_SERVER_READY_TIMEOUT_MS = 3e4;
|
|
57423
57362
|
async function recoverInterruptedPublishJobs(store, logger) {
|
|
@@ -57498,7 +57437,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57498
57437
|
async function listAllUsersProjects() {
|
|
57499
57438
|
if (!deps.usersRoot || !deps.getStore) return [];
|
|
57500
57439
|
const getStore = deps.getStore;
|
|
57501
|
-
const userIds = await
|
|
57440
|
+
const userIds = await import_node_fs49.promises.readdir(deps.usersRoot).catch(() => []);
|
|
57502
57441
|
const perUser = await Promise.all(
|
|
57503
57442
|
userIds.map((uid) => getStore(uid).list().catch(() => []))
|
|
57504
57443
|
);
|
|
@@ -57574,8 +57513,8 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57574
57513
|
const project = await userStore.create(f.name, reservedPorts);
|
|
57575
57514
|
try {
|
|
57576
57515
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(session.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57577
|
-
const templateSrcDir = (0,
|
|
57578
|
-
const scaffoldScript = (0,
|
|
57516
|
+
const templateSrcDir = (0, import_node_path57.join)(personaRoot, "extension-kit", "examples", DEFAULT_TEMPLATE);
|
|
57517
|
+
const scaffoldScript = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "new-extension.sh");
|
|
57579
57518
|
const scaffoldResult = await userStore.scaffold(project.name, templateSrcDir, scaffoldScript);
|
|
57580
57519
|
deps.logger?.info("app-builder.scaffold.done", {
|
|
57581
57520
|
name: project.name,
|
|
@@ -57796,7 +57735,7 @@ function buildAppBuilderHandlers(deps) {
|
|
|
57796
57735
|
await userStore.clearPublishJob(args.name);
|
|
57797
57736
|
}
|
|
57798
57737
|
const personaRoot = deps.resolvePersonaRoot ? deps.resolvePersonaRoot(boundSession.ownerPersonaId ?? "") : deps.personaRoot;
|
|
57799
|
-
const scriptPath = (0,
|
|
57738
|
+
const scriptPath = (0, import_node_path57.join)(deps.deployKitRoot, "scripts", "publish.sh");
|
|
57800
57739
|
deps.logger?.info("app-builder.publish.start", {
|
|
57801
57740
|
name: args.name,
|
|
57802
57741
|
sessionId: boundSession.sessionId,
|
|
@@ -57965,7 +57904,7 @@ function buildVisitorHandlers(deps) {
|
|
|
57965
57904
|
|
|
57966
57905
|
// src/extension/registry.ts
|
|
57967
57906
|
var import_promises9 = __toESM(require("fs/promises"), 1);
|
|
57968
|
-
var
|
|
57907
|
+
var import_node_path58 = __toESM(require("path"), 1);
|
|
57969
57908
|
init_src();
|
|
57970
57909
|
async function loadAll(root) {
|
|
57971
57910
|
let entries;
|
|
@@ -57979,13 +57918,13 @@ async function loadAll(root) {
|
|
|
57979
57918
|
for (const ent of entries) {
|
|
57980
57919
|
if (!ent.isDirectory()) continue;
|
|
57981
57920
|
if (ent.name.startsWith(".")) continue;
|
|
57982
|
-
records.push(await loadOne(
|
|
57921
|
+
records.push(await loadOne(import_node_path58.default.join(root, ent.name), ent.name));
|
|
57983
57922
|
}
|
|
57984
57923
|
records.sort((a, b2) => a.extId < b2.extId ? -1 : a.extId > b2.extId ? 1 : 0);
|
|
57985
57924
|
return records;
|
|
57986
57925
|
}
|
|
57987
57926
|
async function loadOne(dir, dirName) {
|
|
57988
|
-
const manifestPath =
|
|
57927
|
+
const manifestPath = import_node_path58.default.join(dir, "manifest.json");
|
|
57989
57928
|
let raw;
|
|
57990
57929
|
try {
|
|
57991
57930
|
raw = await import_promises9.default.readFile(manifestPath, "utf8");
|
|
@@ -58030,7 +57969,7 @@ async function loadOne(dir, dirName) {
|
|
|
58030
57969
|
|
|
58031
57970
|
// src/extension/uninstall.ts
|
|
58032
57971
|
var import_promises10 = __toESM(require("fs/promises"), 1);
|
|
58033
|
-
var
|
|
57972
|
+
var import_node_path59 = __toESM(require("path"), 1);
|
|
58034
57973
|
var UninstallError = class extends Error {
|
|
58035
57974
|
constructor(code, message) {
|
|
58036
57975
|
super(message);
|
|
@@ -58039,7 +57978,7 @@ var UninstallError = class extends Error {
|
|
|
58039
57978
|
code;
|
|
58040
57979
|
};
|
|
58041
57980
|
async function uninstall(deps) {
|
|
58042
|
-
const dir =
|
|
57981
|
+
const dir = import_node_path59.default.join(deps.root, deps.extId);
|
|
58043
57982
|
try {
|
|
58044
57983
|
await import_promises10.default.access(dir);
|
|
58045
57984
|
} catch {
|
|
@@ -58623,7 +58562,7 @@ async function dispatchRpc(method, frame, client, ctx, deps) {
|
|
|
58623
58562
|
|
|
58624
58563
|
// src/extension/runtime.ts
|
|
58625
58564
|
var import_node_child_process18 = require("child_process");
|
|
58626
|
-
var
|
|
58565
|
+
var import_node_path60 = __toESM(require("path"), 1);
|
|
58627
58566
|
var import_promises11 = require("timers/promises");
|
|
58628
58567
|
init_src();
|
|
58629
58568
|
|
|
@@ -58725,7 +58664,7 @@ var Runtime = class {
|
|
|
58725
58664
|
/\$CLAWOS_EXT_PORT/g,
|
|
58726
58665
|
String(port)
|
|
58727
58666
|
);
|
|
58728
|
-
const dir =
|
|
58667
|
+
const dir = import_node_path60.default.join(this.root, extId);
|
|
58729
58668
|
const env = {
|
|
58730
58669
|
...process.env,
|
|
58731
58670
|
CLAWOS_EXT_PORT: String(port),
|
|
@@ -58837,7 +58776,7 @@ ${handle.stderrTail}`
|
|
|
58837
58776
|
|
|
58838
58777
|
// src/extension/published-channels.ts
|
|
58839
58778
|
var import_promises12 = __toESM(require("fs/promises"), 1);
|
|
58840
|
-
var
|
|
58779
|
+
var import_node_path61 = __toESM(require("path"), 1);
|
|
58841
58780
|
init_src();
|
|
58842
58781
|
init_zod();
|
|
58843
58782
|
var PublishedChannelsError = class extends Error {
|
|
@@ -58937,7 +58876,7 @@ var PublishedChannelStore = class {
|
|
|
58937
58876
|
)
|
|
58938
58877
|
};
|
|
58939
58878
|
const tmp = `${this.filePath}.tmp`;
|
|
58940
|
-
await import_promises12.default.mkdir(
|
|
58879
|
+
await import_promises12.default.mkdir(import_node_path61.default.dirname(this.filePath), { recursive: true });
|
|
58941
58880
|
await import_promises12.default.writeFile(tmp, JSON.stringify(data, null, 2), { mode: 384 });
|
|
58942
58881
|
await import_promises12.default.rename(tmp, this.filePath);
|
|
58943
58882
|
}
|
|
@@ -58945,7 +58884,7 @@ var PublishedChannelStore = class {
|
|
|
58945
58884
|
|
|
58946
58885
|
// src/extension/bundle-cache.ts
|
|
58947
58886
|
var import_promises13 = __toESM(require("fs/promises"), 1);
|
|
58948
|
-
var
|
|
58887
|
+
var import_node_path62 = __toESM(require("path"), 1);
|
|
58949
58888
|
var BundleCache = class {
|
|
58950
58889
|
constructor(rootDir) {
|
|
58951
58890
|
this.rootDir = rootDir;
|
|
@@ -58954,14 +58893,14 @@ var BundleCache = class {
|
|
|
58954
58893
|
/** Atomic write: stage tmp → rename. Caller passes the hex sha256. */
|
|
58955
58894
|
async write(snapshotHash, buffer) {
|
|
58956
58895
|
await import_promises13.default.mkdir(this.rootDir, { recursive: true });
|
|
58957
|
-
const file =
|
|
58896
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58958
58897
|
const tmp = `${file}.tmp`;
|
|
58959
58898
|
await import_promises13.default.writeFile(tmp, buffer, { mode: 384 });
|
|
58960
58899
|
await import_promises13.default.rename(tmp, file);
|
|
58961
58900
|
}
|
|
58962
58901
|
/** Returns the bundle bytes, or null when the file doesn't exist. */
|
|
58963
58902
|
async read(snapshotHash) {
|
|
58964
|
-
const file =
|
|
58903
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58965
58904
|
try {
|
|
58966
58905
|
return await import_promises13.default.readFile(file);
|
|
58967
58906
|
} catch (e) {
|
|
@@ -58971,7 +58910,7 @@ var BundleCache = class {
|
|
|
58971
58910
|
}
|
|
58972
58911
|
/** Idempotent — missing file is not an error. */
|
|
58973
58912
|
async delete(snapshotHash) {
|
|
58974
|
-
const file =
|
|
58913
|
+
const file = import_node_path62.default.join(this.rootDir, `${snapshotHash}.zip`);
|
|
58975
58914
|
await import_promises13.default.rm(file, { force: true });
|
|
58976
58915
|
}
|
|
58977
58916
|
};
|
|
@@ -58996,16 +58935,16 @@ async function startDaemon(config) {
|
|
|
58996
58935
|
});
|
|
58997
58936
|
const logger = createLogger({
|
|
58998
58937
|
level: config.logLevel,
|
|
58999
|
-
file:
|
|
58938
|
+
file: import_node_path63.default.join(config.dataDir, "clawd.log"),
|
|
59000
58939
|
logClient
|
|
59001
58940
|
});
|
|
59002
58941
|
logger.info("starting clawd", { version, config: { port: config.port, host: config.host, dataDir: config.dataDir } });
|
|
59003
58942
|
const screenIdleProbeLogger = createFileOnlyLogger({
|
|
59004
|
-
file:
|
|
58943
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log"),
|
|
59005
58944
|
level: "debug"
|
|
59006
58945
|
});
|
|
59007
58946
|
logger.info("screen-idle probe logger enabled", {
|
|
59008
|
-
file:
|
|
58947
|
+
file: import_node_path63.default.join(config.dataDir, "screen-idle-probe.log")
|
|
59009
58948
|
});
|
|
59010
58949
|
const stateMgr = new StateFileManager({ dataDir: config.dataDir });
|
|
59011
58950
|
const pre = stateMgr.preflight();
|
|
@@ -59143,8 +59082,8 @@ async function startDaemon(config) {
|
|
|
59143
59082
|
const agents = new AgentsScanner();
|
|
59144
59083
|
const history = new ClaudeHistoryReader();
|
|
59145
59084
|
let transport = null;
|
|
59146
|
-
const personaStore = new PersonaStore(
|
|
59147
|
-
const usersRoot =
|
|
59085
|
+
const personaStore = new PersonaStore(import_node_path63.default.join(config.dataDir, "personas"));
|
|
59086
|
+
const usersRoot = import_node_path63.default.join(config.dataDir, "users");
|
|
59148
59087
|
const defaultsRoot = findDefaultsRoot(logger);
|
|
59149
59088
|
if (defaultsRoot) {
|
|
59150
59089
|
seedDefaultPersonas({ store: personaStore, defaultsRoot, logger });
|
|
@@ -59164,17 +59103,17 @@ async function startDaemon(config) {
|
|
|
59164
59103
|
migrateCodexSandbox({ store: personaStore, logger });
|
|
59165
59104
|
const groupFileStore = new GroupFileStore({ dataDir: config.dataDir, logger });
|
|
59166
59105
|
const personaDispatchManager = new PersonaDispatchManager({ genId: () => v4_default() });
|
|
59167
|
-
const here = typeof __dirname === "string" ? __dirname :
|
|
59106
|
+
const here = typeof __dirname === "string" ? __dirname : import_node_path63.default.dirname((0, import_node_url4.fileURLToPath)(import_meta6.url));
|
|
59168
59107
|
const dispatchServerCandidates = [
|
|
59169
|
-
|
|
59108
|
+
import_node_path63.default.join(here, "dispatch", "mcp-server.cjs"),
|
|
59170
59109
|
// 生产 dist/index → dist/dispatch/mcp-server.cjs
|
|
59171
|
-
|
|
59110
|
+
import_node_path63.default.join(here, "..", "dist", "dispatch", "mcp-server.cjs")
|
|
59172
59111
|
// dev tsx src/index → ../dist/dispatch/mcp-server.cjs
|
|
59173
59112
|
];
|
|
59174
|
-
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) =>
|
|
59113
|
+
const dispatchServerScriptPath = dispatchServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59175
59114
|
let dispatchMcpConfigPath2;
|
|
59176
59115
|
if (dispatchServerScriptPath) {
|
|
59177
|
-
const dispatchLogPath =
|
|
59116
|
+
const dispatchLogPath = import_node_path63.default.join(config.dataDir, "dispatch-mcp-server.log");
|
|
59178
59117
|
dispatchMcpConfigPath2 = writeDispatchMcpConfig({
|
|
59179
59118
|
dataDir: config.dataDir,
|
|
59180
59119
|
serverScriptPath: dispatchServerScriptPath,
|
|
@@ -59191,15 +59130,15 @@ async function startDaemon(config) {
|
|
|
59191
59130
|
});
|
|
59192
59131
|
}
|
|
59193
59132
|
const ticketServerCandidates = [
|
|
59194
|
-
|
|
59195
|
-
|
|
59133
|
+
import_node_path63.default.join(here, "ticket", "mcp-server.cjs"),
|
|
59134
|
+
import_node_path63.default.join(here, "..", "dist", "ticket", "mcp-server.cjs")
|
|
59196
59135
|
];
|
|
59197
|
-
const ticketServerScriptPath = ticketServerCandidates.find((p2) =>
|
|
59136
|
+
const ticketServerScriptPath = ticketServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59198
59137
|
const ticketOwnerUnionId = feishuIdentity?.identity.unionId ?? "";
|
|
59199
59138
|
const ticketOwnerName = feishuIdentity?.identity.displayName ?? "";
|
|
59200
59139
|
let ticketMcpConfigPath2;
|
|
59201
59140
|
if (ticketServerScriptPath && ticketOwnerUnionId) {
|
|
59202
|
-
const ticketLogPath =
|
|
59141
|
+
const ticketLogPath = import_node_path63.default.join(config.dataDir, "ticket-mcp-server.log");
|
|
59203
59142
|
ticketMcpConfigPath2 = writeTicketMcpConfig({
|
|
59204
59143
|
dataDir: config.dataDir,
|
|
59205
59144
|
serverScriptPath: ticketServerScriptPath,
|
|
@@ -59220,13 +59159,13 @@ async function startDaemon(config) {
|
|
|
59220
59159
|
});
|
|
59221
59160
|
}
|
|
59222
59161
|
const shiftServerCandidates = [
|
|
59223
|
-
|
|
59224
|
-
|
|
59162
|
+
import_node_path63.default.join(here, "shift", "mcp-server.cjs"),
|
|
59163
|
+
import_node_path63.default.join(here, "..", "dist", "shift", "mcp-server.cjs")
|
|
59225
59164
|
];
|
|
59226
|
-
const shiftServerScriptPath = shiftServerCandidates.find((p2) =>
|
|
59165
|
+
const shiftServerScriptPath = shiftServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59227
59166
|
let shiftMcpConfigPath2;
|
|
59228
59167
|
if (shiftServerScriptPath) {
|
|
59229
|
-
const shiftLogPath =
|
|
59168
|
+
const shiftLogPath = import_node_path63.default.join(config.dataDir, "shift-mcp-server.log");
|
|
59230
59169
|
shiftMcpConfigPath2 = await writeShiftMcpConfig({
|
|
59231
59170
|
dataDir: config.dataDir,
|
|
59232
59171
|
serverScriptPath: shiftServerScriptPath,
|
|
@@ -59244,13 +59183,13 @@ async function startDaemon(config) {
|
|
|
59244
59183
|
);
|
|
59245
59184
|
}
|
|
59246
59185
|
const inboxServerCandidates = [
|
|
59247
|
-
|
|
59248
|
-
|
|
59186
|
+
import_node_path63.default.join(here, "inbox", "mcp-server.cjs"),
|
|
59187
|
+
import_node_path63.default.join(here, "..", "dist", "inbox", "mcp-server.cjs")
|
|
59249
59188
|
];
|
|
59250
|
-
const inboxServerScriptPath = inboxServerCandidates.find((p2) =>
|
|
59189
|
+
const inboxServerScriptPath = inboxServerCandidates.find((p2) => import_node_fs50.default.existsSync(p2));
|
|
59251
59190
|
let inboxMcpConfigPath2;
|
|
59252
59191
|
if (inboxServerScriptPath) {
|
|
59253
|
-
const inboxLogPath =
|
|
59192
|
+
const inboxLogPath = import_node_path63.default.join(config.dataDir, "inbox-mcp-server.log");
|
|
59254
59193
|
inboxMcpConfigPath2 = await writeInboxMcpConfig({
|
|
59255
59194
|
dataDir: config.dataDir,
|
|
59256
59195
|
serverScriptPath: inboxServerScriptPath,
|
|
@@ -59268,7 +59207,7 @@ async function startDaemon(config) {
|
|
|
59268
59207
|
);
|
|
59269
59208
|
}
|
|
59270
59209
|
const shiftStore = createShiftStore({
|
|
59271
|
-
filePath:
|
|
59210
|
+
filePath: import_node_path63.default.join(config.dataDir, "shift.json"),
|
|
59272
59211
|
ownerIdProvider: () => ownerPrincipalId,
|
|
59273
59212
|
now: () => Date.now()
|
|
59274
59213
|
});
|
|
@@ -59290,7 +59229,7 @@ async function startDaemon(config) {
|
|
|
59290
59229
|
getAdapter,
|
|
59291
59230
|
historyReader: history,
|
|
59292
59231
|
dataDir: config.dataDir,
|
|
59293
|
-
personaRoot:
|
|
59232
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59294
59233
|
usersRoot,
|
|
59295
59234
|
personaStore,
|
|
59296
59235
|
ownerDisplayName,
|
|
@@ -59333,10 +59272,10 @@ async function startDaemon(config) {
|
|
|
59333
59272
|
// 文件可能 agent 写完又被自己删(罕见),用 size=0 / fallback mime 兜底。
|
|
59334
59273
|
attachmentGroup: {
|
|
59335
59274
|
onFileEdit: (input) => {
|
|
59336
|
-
const absPath =
|
|
59275
|
+
const absPath = import_node_path63.default.isAbsolute(input.relPath) ? input.relPath : import_node_path63.default.join(input.cwd, input.relPath);
|
|
59337
59276
|
let size = 0;
|
|
59338
59277
|
try {
|
|
59339
|
-
size =
|
|
59278
|
+
size = import_node_fs50.default.statSync(absPath).size;
|
|
59340
59279
|
} catch (err) {
|
|
59341
59280
|
logger.warn("attachment.onFileEdit stat failed", {
|
|
59342
59281
|
sessionId: input.sessionId,
|
|
@@ -59535,11 +59474,11 @@ async function startDaemon(config) {
|
|
|
59535
59474
|
// 'persona/<pid>/owner',default 走 'default'。
|
|
59536
59475
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
59537
59476
|
// guest path guard:candidate 必须在 personaRoot 子树或调用者自己的 user-dir 下
|
|
59538
|
-
personaRoot:
|
|
59477
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59539
59478
|
usersRoot
|
|
59540
59479
|
},
|
|
59541
59480
|
// workspace/git/history/skills/agents handler 共用的 guest path guard 锚点
|
|
59542
|
-
personaRoot:
|
|
59481
|
+
personaRoot: import_node_path63.default.join(config.dataDir, "personas"),
|
|
59543
59482
|
// v2 多人 persona 隔离:handler 派生 guest user-dir 放行
|
|
59544
59483
|
usersRoot,
|
|
59545
59484
|
// capability:list / delete handler 依赖
|
|
@@ -59561,7 +59500,7 @@ async function startDaemon(config) {
|
|
|
59561
59500
|
contactStore,
|
|
59562
59501
|
// <dataDir>/sshd 绝对路径 —— contact-ssh handlers 用它拼 authorized_keys / keys/ 子路径
|
|
59563
59502
|
// Task 10 会加 SshdManager 起 sshd;handlers wire 提前挂 sshdDir 让 typecheck 过
|
|
59564
|
-
sshdDir:
|
|
59503
|
+
sshdDir: import_node_path63.default.join(config.dataDir, "sshd"),
|
|
59565
59504
|
contactSshLog: sshLog,
|
|
59566
59505
|
// inbox:sendDm 用:sessionId → session 出身(复用 attachment 同款 findOwnedSessionScope)
|
|
59567
59506
|
getSessionScope: (sid) => manager.findOwnedSessionScope(sid),
|
|
@@ -59652,11 +59591,11 @@ async function startDaemon(config) {
|
|
|
59652
59591
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2):
|
|
59653
59592
|
// appBuilderPersonaRoot 用于拼 publish.sh 绝对路径(persona-app-builder 安装在
|
|
59654
59593
|
// dataDir/personas/persona-app-builder 之下,extension-kit/scripts/publish.sh 是相对路径)。
|
|
59655
|
-
appBuilderPersonaRoot:
|
|
59594
|
+
appBuilderPersonaRoot: import_node_path63.default.join(config.dataDir, "personas", "persona-app-builder"),
|
|
59656
59595
|
// 共享 deploy-kit 根:scaffold/publish 脚本骨架 + 阿里云凭证单一真源。
|
|
59657
|
-
deployKitRoot:
|
|
59596
|
+
deployKitRoot: import_node_path63.default.join(config.dataDir, "deploy-kit"),
|
|
59658
59597
|
// scaffold/publish 按当前 session 的 persona 解析其安装根,让每个 persona 用自己的模板/注入配置。
|
|
59659
|
-
resolvePersonaRoot: (personaId) =>
|
|
59598
|
+
resolvePersonaRoot: (personaId) => import_node_path63.default.join(config.dataDir, "personas", personaId),
|
|
59660
59599
|
// 发布上线脚手架化 (spec 2026-06-03 §5.2.2):
|
|
59661
59600
|
// 复用 SessionManagerDeps.broadcastFrame 同款 dispatch 逻辑 —— runner 调 manager.send
|
|
59662
59601
|
// 取回 broadcast 帧后逐帧 push 到 transport,跟 manager 自身的 deps 一致。
|
|
@@ -59699,7 +59638,7 @@ async function startDaemon(config) {
|
|
|
59699
59638
|
}
|
|
59700
59639
|
let sourceJsonlPath = "(no transcript yet \u2014 operate from the task description alone)";
|
|
59701
59640
|
if (sourceFile && sourceFile.toolSessionId) {
|
|
59702
|
-
sourceJsonlPath =
|
|
59641
|
+
sourceJsonlPath = import_node_path63.default.join(
|
|
59703
59642
|
import_node_os21.default.homedir(),
|
|
59704
59643
|
".claude",
|
|
59705
59644
|
"projects",
|
|
@@ -60029,8 +59968,8 @@ async function startDaemon(config) {
|
|
|
60029
59968
|
const lines = [
|
|
60030
59969
|
`Tunnel: ${r.url}`,
|
|
60031
59970
|
...resolvedAuthToken ? [`Connect: ${connectUrl}`] : [],
|
|
60032
|
-
`Frpc config: ${
|
|
60033
|
-
`Frpc log: ${
|
|
59971
|
+
`Frpc config: ${import_node_path63.default.join(config.dataDir, "frpc.toml")}`,
|
|
59972
|
+
`Frpc log: ${import_node_path63.default.join(config.dataDir, "frpc.log")}`
|
|
60034
59973
|
];
|
|
60035
59974
|
const width = Math.max(...lines.map((l) => l.length));
|
|
60036
59975
|
const bar = "\u2550".repeat(width + 4);
|
|
@@ -60043,8 +59982,8 @@ ${bar}
|
|
|
60043
59982
|
|
|
60044
59983
|
`);
|
|
60045
59984
|
try {
|
|
60046
|
-
const connectPath =
|
|
60047
|
-
|
|
59985
|
+
const connectPath = import_node_path63.default.join(config.dataDir, "connect.txt");
|
|
59986
|
+
import_node_fs50.default.writeFileSync(connectPath, lines.join("\n") + "\n", { mode: 384 });
|
|
60048
59987
|
} catch {
|
|
60049
59988
|
}
|
|
60050
59989
|
} catch (err) {
|
|
@@ -60078,7 +60017,7 @@ ${bar}
|
|
|
60078
60017
|
});
|
|
60079
60018
|
try {
|
|
60080
60019
|
await sshdMgr.start();
|
|
60081
|
-
rebuildAuthorizedKeys(contactStore,
|
|
60020
|
+
rebuildAuthorizedKeys(contactStore, import_node_path63.default.join(config.dataDir, "sshd"));
|
|
60082
60021
|
logger.info("sshd: contact-ssh sandbox ready", { port: config.sshdPort });
|
|
60083
60022
|
} catch (err) {
|
|
60084
60023
|
logger.warn("sshd start failed; contact SSH grant will not work until fixed", {
|
|
@@ -60146,9 +60085,9 @@ ${bar}
|
|
|
60146
60085
|
};
|
|
60147
60086
|
}
|
|
60148
60087
|
function migrateDropPersonsDir(dataDir) {
|
|
60149
|
-
const dir =
|
|
60088
|
+
const dir = import_node_path63.default.join(dataDir, "persons");
|
|
60150
60089
|
try {
|
|
60151
|
-
|
|
60090
|
+
import_node_fs50.default.rmSync(dir, { recursive: true, force: true });
|
|
60152
60091
|
} catch {
|
|
60153
60092
|
}
|
|
60154
60093
|
}
|