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