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